Zend Framework, Magento and WordPress – sitting in a tree…
Off the back of a recent site launch, I wanted to talk about how we combine some of the industry standard, award-winning software that we use – and some of the issues we face at a technical level.
We’re constantly finding new and innovative ways of tackling issues raised by clients, but it’s important to remember that there’s no point contstantly re-inventing the wheel, when combining the powers of such software can achieve so much.
This platform involved the integration of two great offerings. A stable blogging platform, WordPress, and a powerful ecommerce platform – Magento. The issue with integrating this system was that we also needed a platform to fill in the gaps. The client has great imagery and a great message, and needed to be able to deliver this in a visually interesting and interactive way.
As a team, we decided a bespoke Zend Framework app would fill in the gaps nicely – meaning we could give the client the precise control they needed without handing over control to a blogging or ecommerce platform which isn’t designed to handle it.
One of the questions that came up early on in the project was how to make the three elements interact. For the main part, we wanted to keep them completely separate – we wanted each core technology to be solely responsible for itself so that we didn’t break down the functionality or integrity of any single part. However, we were aware of several instances where the systems would need to interact.
If you visit many ecommerce websites, you’ll notice that the header and footer are the same across the entire site. Rather than having three seperate headers and three seperate footers, we wanted one that we could share across all three applications. The main issue here was that we need to show if the user is logged in or not, and give a nice welcome message if they were. This meant that all three components would need to share something with Magento.
The first hurdle was how to integrate the three offerings. We decided that the global header file should include Magento functionality (instead of trying to load it via an AJAX call or some such). This should improve customer experience, usability and site speed on a whole – however the CMS and WordPress systems may have a slight dip in performance as they load MAGE (Magento).
Including MAGE
Including MAGE outside of the application is fairly straight-forward.
include_once '/shop/app/Mage.php';Mage::app(); |
Next, we’re gonna want to grab information from Magento’s session. We want to know if a user is logged in, so we grab the customer session. Magento has differing levels of session data, so we state this is to come from the “frontend”.
Mage::getSingleton('core/session', array('name'=>'frontend'));$session = Mage::getSingleton('customer/session', array('name'=>'frontend')); |
Now, we’re in a position where we can check if the user is logged in:
if (Mage::getSingleton('customer/session')->isLoggedIn()) { // do something} |
It’s all about sessions….
The issue now is that we’re talking about Magento’s session, and Zend and WordPress have sessions too.
By default, PHP would probably keep its session data in /tmp
. The set up described above is fine if we never use sessions in WordPress or Zend, and let’s face it, there are probably many of those occasions. It also works if WordPress and Zend don’t need to share session data with Magento.
Magento stores its session details in its own folder to keep everything nice and neat. How nice of it.
/var/session/ |
If we do want to use Zend and WordPress and Magento together, then we need to make sure that they all keep their session information in the same place. It’s easiest if we get Zend and WordPress to use the same location as Magento.
So, how do we get Zend and WordPress to change their session location?
We can use the same process on both. We simply have to tell PHP where to store them in both apps.
Where is the best place in WordPress?
The best place in WordPress is the wp-config.php
file. Keeping it here means that you can update WordPress to a new version and don’t need to keep anything else updated.
So what do we do?
Our wp-config.php
file needs to start with the following:
/* INTEGRATE ALL THE SESSIONS WITH MAGENTO */ini_set("session.save_handler", "files");if (strstr(getcwd(),'wp-admin')) { session_save_path(getcwd() . "/../../var/session");} else { session_save_path(getcwd() . "/../var/session");}if (array_key_exists('frontend', $_COOKIE)) { if ($_COOKIE['frontend']) { session_id($_COOKIE['frontend']); }} session_start(); // ** MySQL settings - You can get this info from your web host ** //// ETC... |
Where in a Zend app?
The best idea with a Zend app would be to bootstrap it.
So what do we do?
This code is pretty much the same as the WordPress code. We’re doing pretty much the same thing here, just in a different place.
/*** Initialise the Autoloader** @access protected* @return void*/protected function _initAutoloader(){ /* * Set up the session handler / save path to be the same as Magento * so that they can share session data */ ini_set("session.save_handler", "files"); if (array_key_exists('frontend', $_COOKIE)) { if ($_COOKIE['frontend']) { session_id($_COOKIE['frontend']); } } $sessionOptions = array('save_path' => getcwd() . "/../../var/session"); if (!Zend_Session::isStarted()) { Zend_Session::setOptions($sessionOptions); Zend_Session::start(); } ...} |
Is this it?
Yes, thats pretty much it! The only bit here that isn’t just telling PHP where to put the sessions, is the following:
if (array_key_exists('frontend', $_COOKIE)) { if ($_COOKIE['frontend']) { session_id($_COOKIE['frontend']); }} |
As mentioned earlier, Magento has differing levels of session data, and we need to be sharing the frontend. Luckily, Magento makes this available through a cookie, so we can merge the session information using the $_COOKIE
.
First, we check that the frontend cookie value is available and then, if it is – and isn’t blank – we set the session_id to the same as the Magento session.