开发者

Magento backend customer account DOB update issue

I am trying to update the DOB of a customer from the backend of magneto. The year of DOB I am going to set is 1967. Ok, Well, The record is updated successfully but when I go inside the database table and see the DOB it contains the year 2067. I am surprised how this happened.

I again go in to the backend and set it to 1971 and update the customer reco开发者_开发百科rd. But this time DOB is ok in the database table. It is 1971.

I reached at the conclusion that the DOB less than 1970 is stored wrongly in the database.

Is it magento bug or something wrong with my magento copy.

Thanks


This is a bug in Magento, and there's some chance that this bug will be fixed in next release 1.5.0.0. But I'd not rely on that.

Currently there's no easy way to cope with it, as logic for this is hidden and separated across abstract EAV and Customer attributes models. The basic approach is to
1) Show date in backend in medium format with YYYY instead of YY

and then either
2) Write your custom input validation filter that will validate date in medium format for DOB
3) Change input validation filter from default 'date' to yours (it's done in table customer_eav_attribute)

or
2) write code to set _dateFilterFormat of 'dob' attribute to medium


As of 1.5.1 this still applies. Andrey may be correct but does not provide any details on how to implement that. I've tried to do it and since I can't comment on his answer yet I'll post it here:

  1. In app\code\core\Mage\Adminhtml\Block\Widget\Form.php _setFieldset where it says "FORMAT_TYPE_MEDIUM" add afterwards

    if($attribute->getName() == 'dob') $element->setFormat(Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM));
    
  2. In app\code\core\Mage\Customer\Model\Attribute\Data\Abstract.php _dateFilterFormat after is_null($format)

    $a = $this->getAttribute();
    if(!empty($a) && $a->getName() == 'dob') {
        $this->_dateFilterFormat = Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM;
        return Mage::app()->getLocale()->getDateFormat($this->_dateFilterFormat);
    }
    
  3. Changing app\code\core\Mage\Customer\Block\Widget\Dob.php getDateFormat to FORMAT_TYPE_MEDIUM doesn't really help. The JavaScript will still accept two number years because the validation replaces the date pattern's "y" ignoring case and uses "new Date()" which interprets a two number year just the same. The year sanity check then works on the interpreted year which will be at least 1901.

    If you want hard coded four number years just uncomment (in 1.5.1) the part in js\varien\js.js in DateElement.validate where it says year<1900 and throw out the !this.validateData. Or if you want to make sure you only affect DOB use this:

    Varien.DOB = Class.create();
    Varien.DOB.prototype = {
      initialize: function(selector, required, format) {
        var el = $$(selector)[0];
        var container       = {};
        container.day       = Element.select(el, '.dob-day input')[0];
        container.month     = Element.select(el, '.dob-month input')[0];
        container.year      = Element.select(el, '.dob-year input')[0];
        container.full      = Element.select(el, '.dob-full input')[0];
        container.advice    = Element.select(el, '.validation-advice')[0];
    
        this.child = new Varien.DateElement('container', container, required, format);
    
        container.day.validate = this.validate.bind(this);
        container.month.validate = this.validate.bind(this);
        container.year.validate = this.validate.bind(this);
      },
      validate: function() {
         if(this.child.validate()) {
           var year = parseInt(this.child.year.value, 10);
           if (!isNaN(year) && (year<1900 || year>this.child.curyear) ) {
                errorType = this.child.validateDataErrorType;
                valueError = this.child.validateDataErrorText;
                error = valueError;
                try {
                    error = Translator.translate(error);
                }
                catch (e) {}
                this.child.advice.innerHTML = this.child.errorTextModifier(error);
                this.child.advice.show();
                return false;
           }
           return true;
        }
        return false;
      },
    };
    
  4. Finally Magento will still not be able to output a DOB smaller than 13th December 1901 in the frontend because it overflows the return value of strtotime. So you'll have to change app\code\core\Mage\Customer\Block\Widget\Dob.php functions:

        public function setDate($date)
        {
            $this->setTime($date ? strtotime($date) : false);
            $this->setData('date', $date);
            try {
                $this->setDateTime(new DateTime($date));
            }catch(Exception $e){}
    
            return $this;
        }
    
        public function getDay()
        {
            return $this->getTime() ? date('d', $this->getTime()) : ($this->getDateTime() ? $this->getDateTime()->format('d') : '');
        }
    
        public function getMonth()
        {
            return $this->getTime() ? date('m', $this->getTime()) : ($this->getDateTime() ? $this->getDateTime()->format('m') : '');
        }
    
        public function getYear()
        {
            return $this->getTime() ? date('Y', $this->getTime()) : ($this->getDateTime() ? $this->getDateTime()->format('Y') : '');
        }
    

I hope I got everything... though it still isn't a very clean way to do this ;).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜