I recently came a cross an issue where a one or more customer attributes wont save. This turned out to be a for a number of reasons.
The only condition that Magento tells you about is that a customer attribute must be less than 21 characters. A client had made several new customer attributes one of which was alt_customer_f_name_1
I quickly realised that the first issue is that attribute codes can not contain numbers. Magento doesn’t like numbers for a many reasons but in this case it’s to do with Magento’s magic getters and setters.
Secondly I found out that if you have _f_ it wouldn’t save. If it was changed to _fr_ it did. Strange right ? But actually it makes sense. Magento’s magic methods strip out the underscores and camel case. For example – in this case it would become altCustomerFName() due to the two uppercase characters next to each other Magento can translate this back to underscores.
Annoyingly Magento doesn’t validate any of this when you save your new attributes.
For more details you can see the __call and_underscores methods inside the class Varien_Object located in lib/Varien/Object.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
/** * Set/Get attribute wrapper * * @param string $method * @param array $argsx * @return mixed */ public function __call($method, $args) { switch (substr($method, 0, 3)) { case 'get' : //Varien_Profiler::start('GETTER: '.get_class($this).'::'.$method); $key = $this->_underscore(substr($method,3)); $data = $this->getData($key, isset($args[0]) ? $args[0] : null); //Varien_Profiler::stop('GETTER: '.get_class($this).'::'.$method); return $data; case 'set' : //Varien_Profiler::start('SETTER: '.get_class($this).'::'.$method); $key = $this->_underscore(substr($method,3)); $result = $this->setData($key, isset($args[0]) ? $args[0] : null); //Varien_Profiler::stop('SETTER: '.get_class($this).'::'.$method); return $result; case 'uns' : //Varien_Profiler::start('UNS: '.get_class($this).'::'.$method); $key = $this->_underscore(substr($method,3)); $result = $this->unsetData($key); //Varien_Profiler::stop('UNS: '.get_class($this).'::'.$method); return $result; case 'has' : //Varien_Profiler::start('HAS: '.get_class($this).'::'.$method); $key = $this->_underscore(substr($method,3)); //Varien_Profiler::stop('HAS: '.get_class($this).'::'.$method); return isset($this->_data[$key]); } throw new Varien_Exception("Invalid method ".get_class($this)."::".$method."(".print_r($args,1).")"); } ...... /** * Converts field names for setters and geters * * $this->setMyField($value) === $this->setData('my_field', $value) * Uses cache to eliminate unneccessary preg_replace * * @param string $name * @return string */ protected function _underscore($name) { if (isset(self::$_underscoreCache[$name])) { return self::$_underscoreCache[$name]; } #Varien_Profiler::start('underscore'); $result = strtolower(preg_replace('/(.)([A-Z])/', "$1_$2", $name)); #Varien_Profiler::stop('underscore'); self::$_underscoreCache[$name] = $result; return $result; }<br> |