2

I want customers in the wholesale customer group to see our wholesale store, and I want everyone else to see the default retail store. I tried the solution found here, and it successfully showed customers the correct store, but when I tried to change the theme for the wholesale store, it wasn't finding my theme and kept falling back to base/default.

After digging through the core code, I came up with a solution of my own which appears to work just the way I want it to, but I want to make sure that I'm not doing something that will cause problems that I'm not seeing. I also would be interested in better solutions to my problem if anyone has one.

I copied app/code/core/Mage/Core/Model/App.php to app/code/local/Mage/Core/Model/App.php and modified only the function _checkGetStore.

Original:

/**
 * Check get store
 *
 * @return Mage_Core_Model_App
 */
protected function _checkGetStore($type)
{
    if (empty($_GET)) {
        return $this;
    }

    /**
     * @todo check XML_PATH_STORE_IN_URL
     */
    if (!isset($_GET['___store'])) {
        return $this;
    }

    $store = $_GET['___store'];
    if (!isset($this->_stores[$store])) {
        return $this;
    }

    $storeObj = $this->_stores[$store];
    if (!$storeObj->getId() || !$storeObj->getIsActive()) {
        return $this;
    }

    /**
     * prevent running a store from another website or store group,
     * if website or store group was specified explicitly in Mage::run()
     */
    $curStoreObj = $this->_stores[$this->_currentStore];
    if ($type == 'website' && $storeObj->getWebsiteId() == $curStoreObj->getWebsiteId()) {
        $this->_currentStore = $store;
    }
    elseif ($type == 'group' && $storeObj->getGroupId() == $curStoreObj->getGroupId()) {
        $this->_currentStore = $store;
    }
    elseif ($type == 'store') {
        $this->_currentStore = $store;
    }

    if ($this->_currentStore == $store) {
        $store = $this->getStore($store);
        if ($store->getWebsite()->getDefaultStore()->getId() == $store->getId()) {
            $this->getCookie()->delete(Mage_Core_Model_Store::COOKIE_NAME);
        } else {
            $this->getCookie()->set(Mage_Core_Model_Store::COOKIE_NAME, $this->_currentStore, true);
        }
    }
    return $this;
}

Modified:

/**
 * Check get store
 *
 * @return Mage_Core_Model_App
 */
protected function _checkGetStore($type)
{
    $store = "default";
    if(Mage::getSingleton('customer/session')->isLoggedIn())
    {
        $groupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
        $group = Mage::getModel('customer/group')->load($groupId);
        if($group->getCode() == "Wholesale")
        {
            $store = "wholesale_en";
        }
    }

    if (!isset($this->_stores[$store])) {
        return $this;
    }

    $storeObj = $this->_stores[$store];
    if (!$storeObj->getId() || !$storeObj->getIsActive()) {
        return $this;
    }

    /**
     * prevent running a store from another website or store group,
     * if website or store group was specified explicitly in Mage::run()
     */
    $curStoreObj = $this->_stores[$this->_currentStore];
    if ($type == 'website' && $storeObj->getWebsiteId() == $curStoreObj->getWebsiteId()) {
        $this->_currentStore = $store;
    }
    elseif ($type == 'group' && $storeObj->getGroupId() == $curStoreObj->getGroupId()) {
        $this->_currentStore = $store;
    }
    elseif ($type == 'store') {
        $this->_currentStore = $store;
    }

    if ($this->_currentStore == $store) {
        $store = $this->getStore($store);
        if ($store->getWebsite()->getDefaultStore()->getId() == $store->getId()) {
            $this->getCookie()->delete(Mage_Core_Model_Store::COOKIE_NAME);
        } else {
            $this->getCookie()->set(Mage_Core_Model_Store::COOKIE_NAME, $this->_currentStore, true);
        }
    }
    return $this;
}

I removed the check for the variable ___store in GET requests because I don't want the wholesale store to be accessed that way. Will this do everything that I want? I want the wholesale customer group to always see only the wholesale store, and I want everyone else to always see only the retail store (default). And I don't want any method of switching between stores other than logging in as a wholesale customer.

Even if this solution is an effective one, I am interested in a solution that is more upgrade friendly. I couldn't use Magento to rewrite this particular class, so now I'll have to take extra steps to make sure it gets updated during magento updates.

EDIT:

This change has caused these errors every time the magento cron runs:

2014-02-14T11:00:01+00:00 ERR (3): Warning: strpos(): Empty needle  in /###/lib/Zend/Controller/Request/Http.php on line 504
2014-02-14T11:00:01+00:00 ERR (3): Warning: strpos(): Empty needle  in /###/lib/Zend/Controller/Request/Http.php on line 510
2014-02-14T11:00:01+00:00 ERR (3): Warning: session_start(): Cannot send session cookie - headers already sent  in /###/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php on line 123
2014-02-14T11:00:01+00:00 ERR (3): Warning: session_start(): Cannot send session cache limiter - headers already sent  in /###/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php on line 123

Also, another person was unable to access the magento admin until I reverted this change. He said that clicking login just brought him back to the login page with no error message. I was able to log in to admin using the same credentials (from a different IP address).

1 Answer 1

2

Magento's core implementation of store view selection logic leaves a bit to be desired, but as you found out your solution is heavy-handed and has several knock-on effects.

There are several extensions which handle this functionality for you. Outside of moral opposition to using third-party extensions you should look into those as well-tested modifications with dedicated support.

If you want to build this yourself though you should start with an event observer on controller_action_predispatch which is fired on every request.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.