When running multiple Magento stores off one install, you will probably want to have your session data share between stores. This of course includes, your cart and login status amongst other things. If you looked at System→Configuration→Web→Session Validation Settings in admin, you would be forgiven for thinking all you need to do is enable Use SID on Frontend to get this working. Unfortunately for many stores this seems often to be buggy and ineffective. In my own experience I have found it sometimes to append, and sometimes not to append the session id to the store switch urls, and when it has been appended and you switch stores it doesn't actually carry the session data over at all.
Buggy and frustrating, however with not too many lines of code you can get your stores sharing the cart and other session data reliably even if they are on different domains.
The first thing we want to do is disable the Use SID on Frontend setting as detailed above, we'll be adding the session id to the store change URL's ourselves.
Next copy
app/design/frontend/base/default/template/page/switch/stores.phtmlto
app/design/yourpackagename/yourtheme/default/template/page/switch/stores.phtmlif it isn't already there, but obviously replace yourpackagename and yourtheme with whatever package name and theme you are using on your particular store.
A lot of people will want to edit the way store switching happens as by default it's a not very exciting drop down form menu, so if you have changed this on your store you just need to target the equivalent url generation code for your store. For the sake of this tutorial I will be referring to the standard, unchanged, store code. So, open the file you just copied and in there you should see a select element:
<select id="select-store" title="<?php echo $this->__('Select Store') ?>" onchange="location.href=this.value">and then a foreach loop creating the select options:
<?php foreach ($this->getGroups() as $_group): ?> <?php $_selected = ($_group->getId()==$this->getCurrentGroupId()) ? ' selected="selected"' : '' ?> <option value="<?php echo $_group->getHomeUrl() ?>"<?php echo $_selected ?>><?php echo $this->htmlEscape($_group->getName()) ?></option> <?php endforeach; ?>So when we select an option the onchange event handler takes us to the url being the value attribute of the option we have selected, this value attribute is what we need to edit.
To do this replace the line:
<option value="<?php echo $_group->getHomeUrl() ?>"<?php echo $_selected ?>><?php echo $this->htmlEscape($_group->getName()) ?></option>with this:
<?php $this_session_id = Mage::getSingleton('core/session', array('name' => 'frontend'))->getSessionId(); $this_store_url = explode('?', $_group->getHomeUrl()); $this_store_url = $this_store_url[0] . '?SID=' . $this_session_id . '&___store=' . $_group->getCode(); ?> <option value="<?php echo $this_store_url ?>"<?php echo $_selected ?>><?php echo $this->htmlEscape($_group->getName()) ?></option>The first line of code stores the current session id, the second line stores the url that would have been used for the value attribute, and the third line takes the value attribute url without any GET arguments and appends the session id followed by the store code. The last line of code uses the rebuilt URL as the value attribute in place of the original value.
These are all the changes we are going to need to correctly generate the store switching URLs so you can save and close this file.
Now copy
app/code/core/Mage/Core/Model/Session/Abstract/Varien.phpto
app/code/local/Mage/Core/Model/Session/Abstract/Varien.phpIf you have read this post before, this is the updated section with a solution to allow the session to be properly passed across in the first page load.
In this file we are going to be making use of a one liner that is already present in this file but has not been implemented by default for some reason. This allows us to change the session id before the session is initialised so that when session_start() is called data is pulled from the previous stores session rather than a new session.
Open the file you just copied and look for the following line:
$this->setSessionId();All we need to do here is pass the session id we have appended to the store switch url's to this method and it will set the session id for us, so change that line to the following:
if (isset($_GET['SID'])): $this->setSessionId($_GET['SID']); endif;So a few workarounds needed to patch up Magento's less than complete session handling when switching stores, but these changes should allow you to correctly pass the cart and other session data between stores even when they are on different domains.