4

I wondering if anybody can provide a known reason why customer prefix_options is scope to website level:

<show_in_store>0</show_in_store>

In: app/code/core/Mage/Customer/etc/system.xml

I would like to scope customer prefix values at the store view level and not just website level.

Imagine you have a a website called "Beligum" and in that website you have two store views: be_FR (Beligum-French) and be_NL (Beligum-Dutch). If you wanted to control the customer prefixes at the store view level you can't currently as show_in_store is 0.

Creating a custom module that depends on with a system.xml file to override the value allows me to scope it to the store view level:

<customer>
    <groups>
        <address>
            <fields>
                <prefix_show>
                    <show_in_store>1</show_in_store>
                </prefix_show>
                <prefix_options>
                    <show_in_store>1</show_in_store>
                </prefix_options>
            </fields>
        </address>
    </groups>
</customer>

What I'm interested in is there is any negative side affects that I should look for? Or is this simply not scoped to store view level because Customers in Magento belong to websites?

Thanks

1
  • Good question; hopefully this doesn't get flagged as too broad or opinion-based :) – Rick Buczynski Dec 2 '14 at 18:46
3

It's not entirely safe:

  1. `Mage::helper('customer')->getNamePrefixOptions() delegates to the customer/address helper.

  2. In Mage::helper('customer/address')->getConfig() you can see that it does not actually use the website model and it's getConfig() method, but uses a per-request cache, which it sets to the value of the current store or given store object.

Where this would go wrong is imports collections. Once it's set it's tied to the website ID and any subsequent invocations of the method for another store in the same website, would get the wrong value:

// Mage_Customer_Helper_Address
/**
 * Return customer address config value by key and store
 *
 * @param string $key
 * @param Mage_Core_Model_Store|int|string $store
 * @return string|null
 */
public function getConfig($key, $store = null)
{
    $websiteId = Mage::app()->getStore($store)->getWebsiteId();

    if (!isset($this->_config[$websiteId])) {
        $this->_config[$websiteId] = Mage::getStoreConfig('customer/address', $store);
    }
    return isset($this->_config[$websiteId][$key]) ? (string)$this->_config[$websiteId][$key] : null;
}

Aside: getNamePrefixOptions() is used in the Customer/Name widget, but this would go ok in the normal usage, as the store wouldn't switch within a request.

Edit: Not sure why I wrote imports late last night, but it's collections obviously. Think the newsletter, wishlist and other reminder emails and since 1.9.1 also the transactional emails as they're also being grouped now.

0
5

I can confirm @Melvyn's observation and add some of my own:

The reason is probably by design, as you presumed: Customers are associated to websites, not to store views. It is saved, which store view was used to register, but you can still switch the store view when logged in, go to your account settings and change your prefix.

So, what happens when you change the scope of the prefix configuration?

  1. The customer can switch store views and select different prefixes based on the current store view. The good thing is, that Magento always adds the current value to the dropdown even if it's not in the list. See Mage_Customer_Block_Widget_Name:

    /**
     * Retrieve name prefix drop-down options
     *
     * @return array|bool
     */
    public function getPrefixOptions()
    {
        $prefixOptions = $this->helper('customer')->getNamePrefixOptions();
    
        if ($this->getObject() && !empty($prefixOptions)) {
            $oldPrefix = $this->escapeHtml(trim($this->getObject()->getPrefix()));
            $prefixOptions[$oldPrefix] = $oldPrefix;
        }
        return $prefixOptions;
    }
    
  2. Unexpected behavior due to caching by website, as described in the abovementioned answer. I was able to fix this with a rewrite, where I changed the caching scope from website to store. This was possible because getConfig() receives a store id as parameter, I basically changed store->getWebsiteId() to store->getId():

    class IntegerNet_PrefixByStore_Helper_Address extends Mage_Customer_Helper_Address
    {
        /**
         * Customer address config node per STORE
         *
         * @var array
         */
        protected $_config = array();
    
        /**
         * Overridden to use config per STORE
         *
         * @param string $key
         * @param null $store
         * @return null|string
         */
        public function getConfig($key, $store = null)
        {
            $storeId = Mage::app()->getStore($store)->getId();
    
            if (!isset($this->_config[$storeId])) {
                $this->_config[$storeId] = Mage::getStoreConfig('customer/address', $store);
            }
            return isset($this->_config[$storeId][$key]) ? (string)$this->_config[$storeId][$key] : null;
        }
    
    }
    
  3. In the customer administration panel getConfig() is called with the id of the customer website's default store view. Again, the current value is always added to the dropdown, so this might be okay for you. If you want to show the values of the store view where the customer registered, a less elegant rewrite of Mage_Adminhtml_Block_Customer_Edit_Tab_Account is necessary where you change these lines of initForm():

    if ($customer->getId()) {
        $customerStoreId = Mage::app()->getWebsite($customer->getWebsiteId())->getDefaultStore()->getId();
    }
    

    to

    if ($customer->getId()) {
        //REWRITE: use store id of customer for values of prefix and suffix dropdown
        $customerStoreId = $customer->getStoreId();
    }
    if (! $customerStoreId) {
        $customerStoreId = Mage::app()->getWebsite($customer->getWebsiteId())->getDefaultStore()->getId();
    }
    

    (it's a long method and you have to make changes in the middle, so I didn't past the whole rewritten class)

TL;DR: Use the XML as described in the question with an additional rewrite of Mage_Customer_Helper_Address to change the scope without side effects.

1
  • Fabian thanks for providing more context to this. This is a great summary. – Tegan Snyder Apr 30 '15 at 22:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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