Доработка отправки email через CodeIgniter

Ответить
Аватара пользователя
Distructor
Администратор
Сообщения: 1607
Зарегистрирован: 28.12.2009
Казалось бы отправить письмо в CodeIgniter проще простого:

Код: Выделить всё

        $CI =& get_instance();
        $CI->load->library('email');
        $CI->email->from( 'no-replay@example.com', 'Вася Пупкин' );
        $CI->email->subject('Очень длинный заголовок отправляемого письма');
        $CI->email->message('Текст Письма');    
        $CI->email->to(  'test@example.com' ); 
        $CI->email->send(); 
Но как выяснилось, если заголовок письма не на латинице и длиннее 20 символов, то происходила его обрезка.

Проблема оказалась в методе _prep_q_encoding в классе CI_Email. Метод некорректно работает со строками в UTF-8.

Для исправления ситуации создадим MY_Email.php в application\libraries со следующим содержимым

Код: Выделить всё

<?php

class MY_Email extends CI_Email {

    // перекрываем метод для вызова исправленной функции _prep_q_encoding
    // неверно дробящей заголовки в utf8
    public function subject($subject)
    {
        $subject = $this->_prep_q_encoding_fix($subject);
        $this->_set_header_fix('Subject', $subject);
        return $this;
    }
    
    // перекрываем метод для вызова исправленной функции _prep_q_encoding
    // неверно дробящей заголовки в utf8
    public function from($from, $name = '')
    {
        if (preg_match( '/\<(.*)\>/', $from, $match))
        {
            $from = $match['1'];
        }

        if ($this->validate)
        {
            $this->validate_email($this->_str_to_array($from));
        }

        // prepare the display name
        if ($name != '')
        {
            // only use Q encoding if there are characters that would require it
            if ( ! preg_match('/[\200-\377]/', $name))
            {
                // add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes
                $name = '"'.addcslashes($name, "\0..\37\177'\"\\").'"';
            }
            else
            {
                $name = $this->_prep_q_encoding_fix($name, TRUE);
            }
        }

        $this->_set_header_fix('From', $name.' <'.$from.'>');
        $this->_set_header_fix('Return-Path', '<'.$from.'>');

        return $this;
    }
    
    // дублируем метод, т.к. обратиться из наследника к защищенному методу родителя нельзя
    private function _set_header_fix($header, $value)
    {
        $this->_headers[$header] = $value;
    }
    
    // доработанная _prep_q_encoding для работы со строками в utf8
    private function _prep_q_encoding_fix($str, $from = FALSE)
    {
        $str = str_replace(array("\r", "\n", "\t"), array('', '', '_'), $str);
        return '=?utf-8?b?' . base64_encode( $str ) . '?=';
    }
    
}
Это позволит исправить обработку перекрытием методов, не вмешиваясь в код ядра.

Ответить