I wonder how to check that a particular CMS block is active or not.
So far I have found that CMS block are Mage_Cms_Block_Block class that inherits from Mage_Cms_Block_Abstract class
Mage::log(get_class(Mage::app()->getLayout()->createBlock('cms/block')->setBlockId('promo_space')
Neither of the two classes have methods that would check wether the block is active or not. How do I do it?
Mage::getModel('cms/block')->load('static_block_identifier')->getIsActive()
Replace static_block_identifier with the identifier you assigned to your CMS static block.
Got this myself
I created a method isActive(Identifiere, Value) in helper "Block" in the Mage/Cms local Module.
This is how the method looks
public function isActive($attribute, $value){
$col = Mage::getModel('cms/block')->getCollection();
$col->addFieldToFilter($attribute, $value);
$item = $col->getFirstItem();
$id = $item->getData('is_active');
if($id == 1){
return true;
}else{
return false;
}
}
parameter $attribute is table(cms-block) field such as 'identifier' or 'title' and value can be the name of the static block or identifier itself. Both used to filter down the particular static block you are interested in
Here is how i call the helper
if(Mage::helper('cms/block')->isActive('identifier','promo_space')){
//do that
}
I have also updated the config.xml file for Cms block to read my new helper and the method.
I hope its useful.
This code works for me:
if ( $this->getLayout()->createBlock('cms/block')->setBlockId('YOUR-BLOCK-ID')->toHtml() !== '' ) {}
Maybe this is old, but I use another method that works not only for cms blocks but for any other block loaded on the layout. If you need to check if a block has been loaded:
if($this->getLayout()->getBlock('your_block_name'))
//Do whatever you need here
It's pretty easy!
A better way to do this is to add observer to this event: controller_action_layout_generate_blocks_after which happens right after Magento has initialized and generated Block objects. You have access to the layout and action classes and to all generated blocks before HTML is rendered
//You can check if the block exists in the layout
$layout = $observer->getEvent()->getObserver();
$cmsBlock = $layout->getBlock($identifier);//Returns false if doesn't exist.
//You can check it in the database too:
$cmsModel = Mage::getModel('cms/page')->load($identifier);
if($cmsModel->getId() AND $cmsModel->getIsActive() == 1)
{
//CMS block is active
}
Related
I'm calling a product's information field, as you can see below:
$product->attributes->first()->attributeValues->where('locale',$iso);
Basically in the $product variable already have information regarding the product.
I use $product->attributes->first() to get his attributes, and after getting them I go get his values with ->attributeValues->where('locale',$iso) with the specific language.
The data it outputs is good, but only if attributes exist, because in case there isn't any it doesn't and because of the attributeValues method the page fails.
How can I handle in this situation?
You may check it with a simple empty() or even count() if you prefer.
$attributes = $product->attributes->first()->attributeValues->where('locale',$iso);
if (count($attributes) == 0) {
// There is no attribute, do something
}
Split up your line
$attributes = $product->attributes->first(); // placeholder
if(isset($attributes) { // check if we have one
$attributes->attributeValues->where('locale',$iso); // if so.. do the dance
} else {// go home }
Where and how I am overriding the save method in Joomla 3.0 custom component ?
Current situation:
Custom administrator component.
I have a list view that displays all people stored in table.
Clicking on one entry I get to the detailed view where a form is loaded and it's fields can be edited.
On save, the values are stored in the database. This all works fine.However, ....
When hitting save I wish to modify a field before storing it into the database. How do I override the save function and where? I have been searching this forum and googled quiet a bit to find ways to implement this. Anyone who give me a simple example or point me into the right direction ?
Thanks.
Just adding this for anyone who wants to know the answer to the question itself - this works if you explicitly wish to override the save function. However, look at the actual solution of how to manipulate values!
You override it in the controller, like this:
/**
* save a record (and redirect to main page)
* #return void
*/
function save()
{
$model = $this->getModel('hello');
if ($model->store()) {
$msg = JText::_( 'Greeting Saved!' );
} else {
$msg = JText::_( 'Error Saving Greeting' );
}
// Check the table in so it can be edited.... we are done with it anyway
$link = 'index.php?option=com_hello';
$this->setRedirect($link, $msg);
}
More details here: Joomla Docs - Adding Backend Actions
The prepareTable in the model (as mentioned above) is intended for that (prepare and sanitise the table prior to saving). In case you want to us the ID, though, you should consider using the postSaveHook in the controller:
protected function postSaveHook($model, $validData) {
$item = $model->getItem();
$itemid = $item->get('id');
}
The postSaveHook is called after save is done, thus allowing for newly inserted ID's to be used.
You can use the prepareTable function in the model file (administrator/components/yourComponent/models/yourComponent.php)
protected function prepareTable($table)
{
$table->fieldname = newvalue;
}
isn't this the right method to get Name of logged in customer?
<?php echo Mage::helper('customer')->getCustomer()->getName(); ?>
I have a website with live chat functionality. Yesterday I have been asked to pass email address and the name of the logged into the user into the Javascript Tracking variable code placed in the head section of the website. So that the operators could see who is on the website and whom are they talking to without any need to ask about their information.
So I passed the information from Magento into the Javascript code but now I see this very strange thing happening. For example,
If I am logged in with credentials Name = John Email =
john12#yahoo.com
Then This name and email variable values are changing with the change of pages. For example if I click on any product page the variable values which I am passing changes to some other user's information.
Name becomes Ricky Email becomes ricky23#gmail.com
this variable values are kept on changing back to john and from john to something else with the change of pages. So operator does not have any idea whom are they talking because the values are kept on changing. Also, user ricky or who ever it changes to also exist in the database. so it is picking up random person from the database.
This is what i did to pass the code to javascript. Please let me know if that is not the right code to pass the information. Please check the php code I am using to fetch information from Magento. Roughly, I receive incorrect value once in 5 times. Please provide some assistance. Thanks in advance.
<?php
$customer = Mage::getSingleton('customer/session')->getCustomer();
$email = $customer->getEmail();
$firstname = $customer->getFirstname();
$lastname= $customer->getLastname();
$name = $firstname . ' ' . $lastname;
?>
<script type="text/javascript">
if (typeof(lpMTagConfig) == "undefined"){ lpMTagConfig = {};}
if (typeof(lpMTagConfig.visitorVar) == "undefined"){ lpMTagConfig.visitorVar = [];}
lpMTagConfig.visitorVar[lpMTagConfig.visitorVar.length] = 'Email=<?php echo $email; ?>';
lpMTagConfig.visitorVar[lpMTagConfig.visitorVar.length] = 'Name=<?php echo $name; ?>';
</script>
I'm also attaching a snap shot
I'd be interested to hear how you're adding this code to the page? Is it in it's own block, or are you adding it to footer.phtml, or similar? If your adding to an existing block be sure to check the block caching settings of that template.
To confirm the caching hypothesis I'd ask the following:
Do you get the same name, all the time, on the same page? When you refresh the page, do you get the same name and email in the Javascript?
Does the problem persist with caching disabled?
This doesn't sound like a singleton problem at all. Each execution of the PHP script is isolated from the others, serving one page request. There's no chance of another customer's object moving between invokations of the script.
It is a matter of understanding the singleton pattern. If you call your code twice:
$customer_1 = Mage::helper('customer')->getCustomer()->getName();
$customer_2 = Mage::helper('customer')->getCustomer()->getName();
you get two different instances of the object. But... if one of them has already implemented a singleton pattern in its constructor or has implemented a singleton getInstance then both objects will actually point to the same thing.
Looking at the customer/helper/Data.php code you can see the function
public function getCustomer()
{
if (empty($this->_customer)) {
$this->_customer = Mage::getSingleton('customer/session')->getCustomer();
}
return $this->_customer;
}
That means that in one of the cases singleton is already implemented/called and in other one - not as the property is already set.
The correct way to work with quote/customer/cart in order to get always the correct data is always to use the singleton pattern.
So using this:
$customer = Mage::getSingleton('customer/session')->getCustomer();
always guarantee that you get the correct customer in that session. And as may be you know singleton pattern is based on registry pattern in app/Mage.php:
public static function getSingleton($modelClass='', array $arguments=array())
{
$registryKey = '_singleton/'.$modelClass;
if (!self::registry($registryKey)) {
self::register($registryKey, self::getModel($modelClass, $arguments));
}
return self::registry($registryKey);
}
and looking at app/Mage.php:
public static function register($key, $value, $graceful = false)
{
if (isset(self::$_registry[$key])) {
if ($graceful) {
return;
}
self::throwException('Mage registry key "'.$key.'" already exists');
}
self::$_registry[$key] = $value;
}
...
public static function registry($key)
{
if (isset(self::$_registry[$key])) {
return self::$_registry[$key];
}
return null;
}
you can see that Magento checks is it is already set. If so, Magento will either throw an Exception, which is the default behavior or return null.
Hope this will help you to understand the issue you face.
I have sorted this out. I have moved the code from footer.phtml to head.phtml and it's working fine now.Values are not changing anymore. If anyone know the logic behind please post and I will change my answer. So far this is working.
I have a custom module that displays data on my product pages. My module needs to get the current product id. I tried using:
Mage::registry('current_product');
This works on the first load but when I refresh, current_product no longer has data with full page caching on.
Any ideas?
The catalog product action controller isn't dispatched, when the full page cache handles the request (which makes sense to keep things fast).
So, the registry variables are never set.
I assume you are generating the block dynamically on the otherwise fully cached page.
My recommendation is to try to avoid expensive loads, since that would undermine the speed improvements by the full page cache. You really want to cache the block if at all possible, even if it's a separate cache entry for each customer and each product.
That said, here is how to do that:
In the container, implement the _getIdentifier() method:
protected function _getIdentifier()
{
return $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER, '');
}
Also expand the _getCacheId() method to include the return value of the method _getIdentifier() and a new placeholder attribute: product_id
protected function _getCacheId()
{
return 'HOMEPAGE_PRODUCTS' . md5($this->_placeholder->getAttribute('cache_id') . ',' . $this->_placeholder->getAttribute('product_id')) . '_' . $this->_getIdentifier();
}
Next, in the block class, extend the method getCacheKeyInfo(). All entries in the cache_key_info array with a string index are set on the placeholder as attributes. That is how we can pass the product id to the placeholder.
public function getCacheKeyInfo()
{
$info = parent::getCacheKeyInfo();
if (Mage::registry('current_product'))
{
$info['product_id'] = Mage::registry('current_product')->getId();
}
return $info;
}
Then enable the method _saveCache() by not overriding it in your container class and returning false.
So now, because the container returns a valid id from _getCacheId(), and _saveCache() is inherited from the parent class, the the block can be cached, and applied to the content in an efficient manner in Enterprise_PageCache_Model_Container_Abstract::applyWithoutApp().
You can set the lifetime of the cache entry by having your container extend from Enterprise_PageCache_Model_Container_Customer instead of Enterprise_PageCache_Model_Container_Abstract.
If you still need to pass the product_id to the block (even though it's cached now), you can do so in the _renderBlock() method of your container:
protected function _renderBlock()
{
$blockClass = $this->_placeholder->getAttribute('block');
$template = $this->_placeholder->getAttribute('template');
$block = new $blockClass;
$block->setTemplate($template)
->setProductId($this->_placeholder->getAttribute('product_id'));
return $block->toHtml();
}
you should have in the controller of your module something which init the registration of the current product. You will need to post between the page visited by a user the id of your product (recommended) or save it in a session. Here is an example of what you can do in a controller:
protected function _initAction(){
if(! Mage::registry('current_product')){
Mage::register('current_product', Mage::getModel('catalog/product'));
}
$id = $this->getRequest()->getParam('id');
if (!is_null($id)) {
$model = Mage::registry('current_product')->load($id);
if (! $model->getId()) {
$this->_getSession()->addError(Mage::helper('catalog')->__('This product item no longer exists'));
$this->_redirect('*/*/');
return;
}
}
return $this;
}
public function indexAction()
{
$this->_initAction();
// your code below
}
Ok so Ive created static blocks in my CMS area, and Im trying to output them inside of a custom homepage template Ive built.
Every document I can find says to output the block as follows
<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('my-block-identifier')->toHtml() ?>
That didnt work for me, so then I tried another way. --
<?php $block = Mage::getSingleton('core/layout')->createBlock('cms/block')->setBlockId('my-block-identifier');
echo $block->toHtml();
All the sites referencing this tell me to use the actual blocks identifier to get the block. So then I decide to manually lookup the block_id in my cms_block table and see if using the block_id number in place of the literal my-block-identifier name will work - and it did. So I am confused... Can anyone tell me how I can get the block by the actual identifier, or look up the blocks id by the identifier so that I can grab the block by block name?
Any help much appreciated.
Looking at the cms/block block source, those tutorials have mislead you, or you misinterpreted them.
#File: app/code/core/Mage/Cms/Block/Block.php
class Mage_Cms_Block_Block extends Mage_Core_Block_Abstract
{
protected function _toHtml()
{
if (!$this->_beforeToHtml()) {
return '';
}
$html = '';
if ($blockId = $this->getBlockId()) {
$block = Mage::getModel('cms/block')
->setStoreId(Mage::app()->getStore()->getId())
->load($blockId);
if (!$block->getIsActive()) {
$html = '';
} else {
$content = $block->getContent();
$processor = Mage::getModel('core/email_template_filter');
$html = $processor->filter($content);
}
}
return $html;
}
}
The block content is always loaded with ->load($blockId); -- load with one parameter always means loding by a database ID.
So, with no supported way of doing this built into the block, you'll need to look up the block ID.
$model = Mage::getModel('cms/block')->getCollection()
->addFieldToFilter('identifier','footer_links')
->getFirstItem();
var_dump($model->getBlockId());
In the admin, when you are editing the contents of the static block, you will see a field called Identifier second from the top. Copy the value of that field, and insert it into your code. So if your Block is called contact-info in the admin, then your code will look like:
<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('contact-info')->toHtml() ?>
The value in that Identifier textbox in the admin is also what will be saved into the cms_block table, as you're worked out.
HTH,
JD