Setting template for static blocks in Magento footer

Hi!
Today I had a task to insert static blocks into footer area of Magento web page. Since there are some troubles with WYSIWYG editor and html code I opted to make it more secure for future editing so I wanted to give the static blocks their template. I’m guessing that you know how to add static block into footer area. (Hint! Add it in local.xml).
In order for static blocks to be able to have template you have to call them as a type cms/widget_block instead of cms/block. This will allow your blocks to have template because by default static blocks don’t have a template. Here’s how the footer part of my local.xml looked like:

    <reference name="footer">
      <block type="cms/widget_block" name="cms_footer_socials" template="cms/footer_area.phtml">
          <action method="setBlockId">
               <blockId>identifier</blockId>
          </action>
      </block>
    </reference>

And in my theme I added cms/footer_area.phtml that with this code. Edit it to suit your needs:

<?php 
$id = $this->getBlockId();
$block = Mage::getModel('cms/block')->load($id);
?>
<div class="block">
    <div class="title"><?php echo $block->getTitle() ?></div>
    <div class="content"><?php echo $block->getContent() ?></div>
</div>

And now my static blocks in footer area have their template 🙂 .

Ajax, ZF2 action and json return

Hi!
On the first project with Zend 2 I needed to incorporate Ajax. I made my view action, view script and in it added ajax that had set url to another action in the same controller. On the click of the button the data had to be sent via ajax and then new set of data had to be returned in form of json. Here came the problem. No matter what I did, the returned data wasn’t in json format. It contained, exept the json, the entire layout script from Zend 2. Naturally I resorted to doc Google to search for remedy to my problems.
I didn’t find much, expect the way to incorporate Json view. But after some time I gave up on the idea – didn’t seem really practical. I just wanted something simple and quick. During my search I stumbled upon the advice to get response and set its content. So I tried it and it worked!

Here is the simplest way to set json as your response:

    // some controller

   public function myajaxAction(){
    //....parsing of the received data

    $return=$object->fetchData();

    return $this->getResponse()->setContent(json_encode($return));
  }

Voila! 🙂

AW Blog different layout for posts view

Hi,
I had some trouble recently with Magento 1.7.0.2. and AW Blog. I couldn’t set different layout for blog posts view. My Blog listing needed to have 1-column layout and blog posts view 2columns-right layout.

Naturally I resorted to normal solution – add this lines inside aw_blog.xml file, in blog_post_view section:

// inside aw_blog.xml layout file
<blog_post_view>
    <!-- ... -->
        <reference name="root">
            <action method="setTemplate"><template>page/2columns-right.phtml</template></action>
        </reference>

        <reference name="content">
          <!-- ... -->
        </reference>
</blog_post_view>

Nothing happened.
After a bit of file searching I found AW_Blog_Helper_Post of AW Blog extension. I simply commented out a line at the end of renderPage function:

 // inside AW_Blog_Helper_Post of AW Blog extension

public function renderPage(Mage_Core_Controller_Front_Action $action, $identifier=null) {

/*...*/

  //$action->getLayout()->getBlock('root')->setTemplate(Mage::getStoreConfig('blog/blog/layout'));
  //above line was rewriting set layout in aw_blog.xml
  $action->renderLayout();

 return true;

And voila! It now changes the layout of blog posts view to my desired layout.

Hope this helps,
Iva

Admin area and module activation – Part 2

Hello!

In the last article I showed you how we solved the problem of activating modules in admin area of our Zend web application. In Part 1 I presented the logic behind the activation, now let’s list our modules in admin area and change their states.

For modules listing I’ve made a new model called Application_Models_Module and I’ve situated it inside application/models/ folder in Module.php file. This model will have functions for activating my module and listing all modules. I wanted to make the process as automatic as possible, so here is how my function look like:

//this goes into application/models/Module.php file
class Application_Model_Module {

     protected $_mod;
     protected $_name;
     protected $_active;

     // basic constructor, setters and getters go here
     // ...

     public function getModules($path){                                // function to get all modules, it takes modules path as it's variable
          $directories = glob($path. '/*' , GLOB_ONLYDIR);                  //get directory listing 
          $directories = str_replace($path.'/','', $directories);           //get only directory names

          $config = new Zend_Config_Ini(APPLICATION_PATH.'/modules/config/modules.ini');  //get my modules.ini file with basic module info

          $mods = array();
          foreach($directories as $mod):
               $conf = $config->$mod;                  //get configuration from modules.ini file for single module

               $this->setMod($mod);                    //setting data inside model's variables
               $this->setName($conf->module->name);
               $this->setActive($conf->module->active);

               $mods[$mod] = $this;                             //add modules setting to mods array

          endforeach;

          return $mods;                                         //return all modules' data
     }
}

Ok, we have function that gets our modules. Now we’ll create the function to activate our modules. This function has to read the contents of modules.ini file and then edit them accordingly:

//appending application/models/Module.php file
class Application_Model_Module {

     //right below the getModules() function
     
     public function changeState($mod, $state){                                    //takes as parameters module and the future state (0 or 1)
         $config = new Zend_Config_Ini(APPLICATION_PATH.'/modules/config/modules.ini', null,          //read the contents of modules.ini and allow modifications
                    array('skipExtends'  => true,
                    'allowModifications' => true));
		
         $config->$mod->module->active = $state;                       //set module's state
		
         $writer = new Zend_Config_Writer_Ini(array('config'   => $config,               
				'filename' => APPLICATION_PATH.'/modules/config/modules.ini'));

         try{                  //try to write the state in the file if not successful return error
             $writer->write();                                   
             return $state;
         }catch (Exception $e){
             return $e;
         }
     }
}

All of needed function are now complete and we’re going to edit our view. In my admin area module controllers folder I’m going to make a controller Settings and inside it I’m going to add action modulesAction(). In it we’re going to list all of our modules.

// Settings controller inside admin module

class Admin_SettingsController extends Zend_Controller_Action {

     public function modulesAction(){
          $mods = new Application_Models_Module();

          $mods = $mods->getModules(LOCAL_PATH); //LOCAL_PATH is path to my modules/local folder, you can define it as a global in index.php

          $this->view->mods = $mods;     // put the list of mods in the view variable
     }
}

We’re going to use our view variable to show the modules and edit their states with a little bit of ajax magic inside the view file. Here’s my view file:

 <!-- contents of application/modules/admin/views/scripts/settings/modules.phtml file -->
<?php
$mods = $this->mods;
?>
<div class="title">
	<h1>Installed Modules</h1>
</div>

<table class="mods">                        //simple table to show our modules list with enabled/disabled information
    <tr>
        <th>Module</th>
        <th>State</th>
    </tr>

<?php foreach($mods as $mod):?>
    <tr>

        <td>
	<a href="/admin/settings/module?mod=<?php echo $mod->getMod();?>" class="<?php echo $mod->getMod()?>"><?php  echo $mod->getName()?></a>
        </td>

        <td>
	    <?php $state = $mod->getActive()?>
	    <select class="sel-mod">                                               //select if the module is enable or disabled
		<option value="0" <?php if(!$state) echo 'selected = "selected"' ?>>Disabled</option>
		<option value="1" <?php if($state) echo 'selected = "selected"' ?>>Enabled</option>
	    </select>
	<small class="message"></small>                                            //message area for "Module disabled/enabled." message
	<img style="display: none;" src="<?php echo $this->baseUrl('path_to_small.gif');?>"/> //small gif for loading
</td>
</tr>
<?php endforeach;?>
</table>
</div>

As you can see we have made a simple table that shows us some basic data. Now let’s make the script needed for changing the state using ajax.

//add this to the bottom of view file or make a new script file and add it at the bottom
<script>
	$('.sel-mod').on('change',function(){                                         //when select state changes
		var mess = $(this).parent().find('.message');
		var img = $(this).parent().find('img');

		$.ajax({
			url:'/admin/settings/modulestate?format=json',                //where to send the data
			beforeSend: function(e){
				img.attr('style','display:block');                    //before sending show the loading gif
			},
			data: {                                                       //data we need to send
				mod: $(this).parent().prev().find('a').attr('class'),
				name: jQuery.trim($(this).parent().prev().text()),
				state: $(this).val()},
			success: function(e){                                          //what to do on success
				var res = e.result;
				var text;
				if(res==1) text = 'Module enabled.';                  
				else text = 'Module disabled.'

				mess.text(text);                                      //inject message into message div
				
				setTimeout(function(){img.attr('style','display:none')},500);  //disable gif when not needed
			},
			error: function(e){                                           //what to do on error
				mess.text('Something went wrong, please try again later');
			},
			dataType: 'json'                                             //type of data to use
		});	
    });
</script>

We need to make another action in our settings controller, the one that saves data into the modules.ini file. It’s the action that ajax uses as url to which to send data. Since we’ve already completed our model all we need is to instantiate the right object and call changeState() function.

 //this goes inside our Settings controller

   public function modulestateAction(){
    	
        $mods = new Application_Model_Module();            //our object
    	 
        $params = $this->getRequest()->getParams();        //get the request params
        $mod = $params['mod'];                             
        $state = $params['state'];
    	
        $this->view->result=$mods->changeState($mod, $state);    //change the state and return result into new view variable
    }

Don’t forget to make the view file of your new action. And you’re all set. All that needs to be done is to style your table to your liking and add gif file of your choice.

Cheers! 🙂

Admin area and module activation – Part 1

Hello,
I recently needed to make module activation in the admin area of our online booking system that we’re developing. Here is how I solved it.

Our online booking system is based on Zend framework, and for now doesn’t deviate much from Zend’s project structure. Our modules are situated in application/modules folder. We’ve already made admin area as a module when we started to work on incorporating other modules with our system. And now the question was asked – how do we enable and disable modules from our admin area? Our admin area is already a module itself so we cannot make new modules as a part of our admin module. New module itself also has to show certain information (forms) on the frontend and backend, how to include it to do exactly what we need? I then stumbled on the solution to make admin area as admin controller but discarded it after some thought. We already have working admin area of our system so why should we change it? Do all the work again and then come to basically almost the same point. So I played a bit with various versions of module activation and files, and came up with this idea.

I’m going to make a config file that has some basic information about the module that is going to be filled during the installation process of the module itself. At that time I filled it by hand, and I oped for .ini type of file. But you can easly make it as a yaml or xml file. The following code is situated in modules.ini file in application/modules/config folder. My booking module is situated in application/modules/local folder.
Basic info in .ini file is consisted of module folder name, module name and is module active info. Here’s how my basic info looks like:

<code class="language-php">// this code goes into modules.ini file
[booking]                                           // marks new part of modules.ini file, same as module folder name
module.name = "Booking"
module.active = "1"
</code>

Now that was the easy part 🙂 . Let’s get on to the hard part.
We want our application to show enabled and not show disabled modules, so we need to write something in our bootstrap file. I presume you know how to detect modules in /modules folder using your application.ini file. Since our module is situated in /local folder inside the /modules folder we have to designate that folder also as our modules folder. First we’ll make public function _initMods() in our Bootstrap.php file. Since we’re going to need some things for module activation we’re going to put them at the beginning. We’re going to instance our front controller for later use and then ‘read’ the names from /local folder.

<code class="language-php">// this code goes into application/Bootstrap.php file
public function _initMods(){
        
        $config = new Zend_Config_Ini(APPLICATION_PATH. '/modules/config/modules.ini');  // new object of Zend_Config_Ini, 
        //we use it to read our modules.ini file
        
        $directories = glob(APPLICATION_PATH .'/modules/local/*' , GLOB_ONLYDIR); //grab our module directories from /modules/local folder
        $directories = str_replace(APPLICATION_PATH .'/modules/local/','', $directories); // we'll need only names, not paths
        
        $this->bootstrap('FrontController');                      // we need FrontController to add new module directory
        $frontctrl = $this->getResource('FrontController');       //  get FrontController and all of its current properties
}
</code>

now we have everything we need to add new module. We bootstrap the FrontController in order to get everything that is currently set in it. This proved to be crutial for adding new modules folder. Here’s the code for adding new active module. I’ll explain it in comments and further bellow:

<code class="language-php">// this code goes into application/Bootstrap.php file
public function _initMods(){
        
// .....
foreach($directories as $name){
        	
        	if($name != "admin" &&  $name != "local" && $name != "config" ){ // we don't need to activate these modules
        		
        		$active = $config->$name->module->active;            //here we get the module.active = ? value
        			if($active){                                 // if module.active = 1 
        			$frontctrl->addModuleDirectory(APPLICATION_PATH .'/modules');
        			$frontctrl->addControllerDirectory(APPLICATION_PATH .'/modules/local/'. $name  .'/controllers',$name);     // add module directory into the list of controler directories
        			
// in order for our module to be fully functional we have to bootstrap it's Bootstrap.php file. Only then our module
// is seen as a module by Zend Framework
        			require_once APPLICATION_PATH .'/modules/local/'. $name .'/Bootstrap.php';  // get the contents of our modules's Bootstrap.php
        			$className = ucfirst($name) .'_Bootstrap'; 
        			$moduleBootstrap = new $className($this);   // make new instance of our module's Bootstrap.php
        			$moduleBootstrap->bootstrap();              // bootstrap our module's Bootstrap.php
        				
        				
        			}
        		}
        }

}
</code>

And now we have initialized our active modules. If we try to access the modules with module.active=0 we’ll get an error. If a module has module.active=1 it is initialized and we can access our modules functions and controllers.
For the next part I’ll show you how to make activation from admin area.

Cheers! 🙂

Magento upgrade theme trouble

Magento + Upgrade == Lots of trouble.
Everyone who ever tried to upgrade their Magento store knows what I am talking about. Lots of (un)expected errors, troubles, headaches.
Such was the case with our upgrade. Recently we had a client who had a shop set on Magento 1.3.2.3 and wanted to upgrade to the latest version (at the time of writing the latest version is 1.7.0.2) because he bought a premium theme that only worked on Magento 1.7.x version.
We did the upgrade and it worked, with no trouble and no errors at all or so we thought 🙂
“Its a miracle” I thought to myself, but our happiness was short lived.
As soon as we installed the new theme it didn’t work as intended, javascript and CSS where broken.
With Firebug I discovered that upon page reload some javascript and other files where missing.
The strange thing is we didn’t knew where he was requesting those files.
After many hours of searching we discovered that he was requesting them from the database but with Magento having 300+ tables the tricky part was finding out from which table.
After many hours of search we found out that the table responsible for this is core_config_data.
I emptied the table and refreshed the page. The theme loaded flawlessly, no more errors, but upon entering the admin area some settings where missing.
So in order to fix this we created a new database called “donor” and redirected our Magento project to it.

<code class="language-xml">
  <connection>
   <host><![CDATA[localhost]]></host>
   <username><![CDATA[root]]></username>
   <password><![CDATA[]]></password>
   <dbname><![CDATA[old]]></dbname>
   <initStatements><![CDATA[SET NAMES utf8]]></initStatements>
   <model><![CDATA[mysql4]]></model>
   <type><![CDATA[pdo_mysql]]></type>
   <pdoType><![CDATA[]]></pdoType>
    <active>1</active>
  </connection></code>
<code class="language-xml">
  <connection>
   <host><![CDATA[localhost]]></host>
   <username><![CDATA[root]]></username>
   <password><![CDATA[]]></password>
   <dbname><![CDATA[donor]]></dbname>
   <initStatements><![CDATA[SET NAMES utf8]]></initStatements>
   <model><![CDATA[mysql4]]></model>
   <type><![CDATA[pdo_mysql]]></type>
   <pdoType><![CDATA[]]></pdoType>
    <active>1</active>
  </connection></code>

Refreshing our homepage started a fresh Magento installation.
We completed the installation and dumped the core_config_data table from the “donor” database, and replaced our “old” core_config_data table with data from the “donor” table.
After we returned our database path to the “old” database and reactivated the theme our problems where solved.
I wrote this article in hope that it will spare you hours upon hours of frustration and suffering.
Good luck with your update 🙂

Looking for …

Programmer (m/f) on specialization without establishing employment . We preffer candidates who already know a bit about HTML, CSS, JavaScript, PHP, MySQL. We’re offering comfy 🙂 work environment with specialization on various php platforms. During specialization you will work with Magento, Zend and WordPress frameworks and platforms, and learn the secrets of HTML/CSS styling 🙂 .

If interested, send us your CV and work request on email: iva.korlevic@prood-os.com. If you have any other question, feel free to contact us. This offer is open till 22nd April 2013.

See you on your job interview!