Дек 2

Одним из неудобных моментов при разработке и тестировании локального проекта является невозможность отправки email’ов.
Наш любимый Google поможет решить данную проблему. Письма можно отправлять через Gmail SMTP.
Zend Framework позволяет отправлять письма через SMTP при помощи класса Zend_Mail_Transport_Smtp.
У вас должен быть включен extension OpenSSL.
Вот простой пример отправки письма через GMail SMTP, используя Zend_Mail:

<?php
$options = array(
        ‘auth’     => ‘login’,
        ‘username’ => ‘_username_@gmail.com’,
        ‘password’ => ‘_password_’,
        ’ssl’      => ‘tls’,
        ‘port’ => 587
    );
    $mailTransport = new Zend_Mail_Transport_Smtp(’smtp.gmail.com’, $options);
    Zend_Mail::setDefaultTransport($mailTransport);
    
    $m = new Zend_Mail();
    $m->addTo(’someone@gmail.com’);
    $m->setFrom(‘_username_@gmail.com’, ‘Sender name’);
    $m->setSubject(‘Using Gmail SMTP’);
    $m->setBodyText(‘Hello! I am using Gmail from the localhost :)’);
    $m->send();

При помощи метода Zend_Mail::setDefaultTransport можно легко переключаться между локальным и удаленным (серверным) окружением.

И продолжая актуальную для меня тему ремонта - строительный инструмент Ridgid

P.S.: Вы еще не подписались на мой RSS? Добро пожаловать :)

Окт 5

Мне нравится то, что в Zend Framework постоянно появляются новые фишки. Очень не хватало раньше компонента Zend_Tool. Наконец-то его написали… ну или “почти написали” :-)

Сыровато еще все. При установленном PHPUnit 3.4 Zend tool отказывается работать:

Fatal error: Cannot redeclare class phpunit_framework_testsuite_dataprovider in … PEAR\PHPUnit\Framework\TestSuite\DataProvider.php

Данный баг уже есть в трекере: http://framework.zend.com/issues/browse/ZF-7894, но его пока еще не пофиксили. Если же вы хотите использовать Zend_Tool, то можно установить более раннюю версию PHPUnit. Для этого удаляем PHPUnit 3.4:

pear uninstall phpunit/PHPUnit

и ставим версию 3.3:

pear install phpunit/PHPUnit-3.3.0



Май 21

Zend Framework предоставляет ряд помощников (Helpers), которые используются во view скриптах. К ним относятся, например: хелперы для создания разных HTML элементов, для построения ссылок, для экранирования вывода (escape) и другое. Но иногда возникает необходимость в создании  собственного (custom) view helper. Рассмотрим рекомендации по этому поводу.

Helper представляет собой класс, который должен соблюдать некоторые требования:

  • Имя класса должно заканчиваться именем хелпера
  • Helper должен иметь public метод, имя которого совпадает с именем хелпера
  • Метод не должен использовать echo или print функции - необходимо возвращать значение
  • Необязательная рекомендация: разработчики Zend Framework советуют наследоваьб свой view helper класс от Zend_View_Helper_Abstract или имплементировать интерфейс Zend_View_Helper_Interface (в следующих релизах ZF планируется упростить набор правил для создания custom view helper, которые приведены выше)

Что ж, попробуем написать свой помощник вида.

В Smarty есть модификатор, который отрезает часть текста - truncate. Его можно использовать, например при выводе анонса новостей. Создадим и мы helper, который реализует данный функционал.

  • Создаем класс, который находится по такому пути: library/Custom/View/Helper/Truncate.php (используется классическая структура директорий Zend Framework)
<?php
class Custom_View_Helper_Truncate extends Zend_View_Helper_Abstract
{
    public function truncate($string, $length = 50, $postfix = ‘…’)
    {
        $truncated = trim($string);
        $length = (int)$length;
        if (!$string) {
            return $truncated;
        }
        $fullLength = iconv_strlen($truncated, ‘UTF-8′);
        if ($fullLength > $length) {
            $truncated = trim(iconv_substr($truncated, 0, $length, ‘UTF-8′)) . $postfix;
        }
        return $truncated;   
    }
}
  • Добавляем путь к view хелперам в нашем bootstrap файле
<?php
$layout = Zend_Layout::startMvc(array(‘layoutPath’ => ‘../application/layouts’));
$layout->getView()->addHelperPath(‘Custom/View/Helper’, ‘Custom_View_Helper’);
?>

После этого наш хелпер готов к употреблению ))) В скрипте вида используем его так:

<?php
$this->truncate($this->someBigString, 100);
?>

P.S.: данный helper корректно работает с любой кодировкой (iconv рулит, но можно и заменить на multibyte string functions)

Апр 15

Очень удобная вещь - Zend_Form. Данный компонент предоставляет множество возможностей, таких как фильтрация и валидация данных формы. Zend_Form имеет ряд собственных валидаторов и фильтров, но он достаточно гибок, и есть возможность создавать свои классы для валидации.

Рассмотрим на примере создание собственного валидатора для формы регистрации.

Возьмем простейшую форму для регистрации, с минимальным набором полей:

  • логин
  • email
  • пароль
  • пароль повторно

Требования к полям:

  1. Логин - обязательное поле, строка из цифро-буквенных символов длиною от 3 до 15 символов, уникальное.
  2. email - обязательное поле, имеет правильный формат, уникальное.
  3. Пароль - обязательное поле, строка из любых символов, не короче 6 символов
  4. Пароль повторно - поле должно совпадать с полем ‘пароль’.

Исходя их требований, можно сделать вывод, что нам нужно написать 3 собственных валидатора:

  1. Проверка уникальности логина.
  2. Проверка уникальности email.
  3. Проверка совпадения паролей.

Для создания custom validator, нужно наследовать класс от абстрактного Zend_Validate_Abstract, и реализовать в нем метод isValid.

В своих проектах валидаторы я храню в директории models/validator.

Создание валидатора уникальности логина

Создаем новый файл models/validator/UniqueNickname.php

<?php
class Validator_UniqueNickname extends Zend_Validate_Abstract
{
    const NOT_UNIQUE = ‘notUnique’;
    
    /*
     * Сообщения об ошибках валидации
     */
    protected $_messageTemplates = array(
        self::NOT_UNIQUE => “Username ‘%value%’ has already been taken”
    );
    
    public function isValid($value)
    {
        $this->_setValue($value);
        $isValid = true;
        
        /*
         * Метод User::checkLogin проверяет используется ли в базе такой логин,
         * если да, то возвращает user id
         */  
        $userId = User::checkLogin($value);
        if ($userId) {
            $this->_error(self::NOT_UNIQUE);
            $isValid = false;
        }
        return $isValid;
    }
}

Создание валидатора уникальности email

Создаем новый файл models/validator/UniqueEmail.php

<?php
class Validator_UniqueEmail extends Zend_Validate_Abstract
{
    const NOT_UNIQUE = ‘notUnique’;
    
    protected $_messageTemplates = array(
        self::NOT_UNIQUE => “Email ‘%value%’ has already been taken”
    );
    
    public function isValid($value)
    {
        $this->_setValue($value);
        $isValid = true;
        $userId = User::checkEmail($value);
        if ($userId) {
            $this->_error(self::NOT_UNIQUE);
            $isValid = false;
        }
        return $isValid;
    }
}

Создание валидатора для паролей

С этим валидатором дела обстоят интереснее. Создаем новый файл models/validator/EqualValues.php.

<?php
class Validator_EqualValues extends Zend_Validate_Abstract
{
    const NOT_EQUAL = ‘notEqual’;
    
    protected $_messageTemplates = array(
        self::NOT_EQUAL => ‘Passwords are not equal’
    );
    
    protected $_contextKey;
    
    public function __construct($key)
    {
        $this->_contextKey = $key;
    }
    
    public function isValid($value, $context = null)
    {
        if (is_array($context)) {
            if (isset($context[$this->_contextKey]) && ($value === $context[$this->_contextKey])) {
                return true;
            }
        }
        if ($value === $context) {
            return true;
        }
        $this->_error(self::NOT_EQUAL);
        return false;
    }
}

Форма регистрации

Теперь создаем непосредственно саму форму регистрации (models/form/Register.php)

<?php
class Form_Register extends Zend_Form
{
    public function __construct($options = null)
    {
        parent::__construct($options);
        
        $this->setAction(HOME_URL . ‘register/’)
             ->setMethod(‘post’);
        
        $login = new Zend_Form_Element_Text(‘login’);
        $login->setLabel(‘Логин’)
              ->setRequired(true)
              ->addFilter(‘StripTags’)
              ->addFilter(‘StringTrim’)
              ->addFilter(‘StringToLower’)
              ->addValidator(‘StringLength’, true, array(‘min’ => 3, ‘max’ => 15))
              ->addValidator(‘alnum’)
              ->addValidator(new Validator_UniqueNickname())
              ;
              
        $email = new Zend_Form_Element_Text(‘email’);
        $email->setLabel(‘email’)
              ->setRequired(true)
              ->addFilter(‘StripTags’)
              ->addFilter(‘StringTrim’)
              ->addFilter(‘StringToLower’)
              ->addValidator(new Zend_Validate_EmailAddress())
              ->addValidator(new Validator_UniqueEmail())
              ;
        
        $password = new Zend_Form_Element_Password(‘password’);
        $password->setLabel(‘Пароль’)
                 ->setRequired(true)
                 ->addValidator(‘StringLength’, true, array(‘min’ => 6))
                 ;
        
        $passwordAgain = new Zend_Form_Element_Password(‘passwordAgain’);
        $passwordAgain->setLabel(‘Повторите пароль’);
        
        // Валидатор для совпадения паролей 
        $passwordAgain->addValidator(new Validator_EqualValues(‘password’))
                      ->setAllowEmpty(false);
        
        $submit = new Zend_Form_Element_Submit(’submit’);
        $submit->setLabel(‘Ok’);
        
        $this->addElements(array($login, $email, $password, $passwordAgain, $submit));
    }
}

При добавлении валидатора для паролей нужно вызывать метод setAllowEmpty со значением false. Это делается для того чтобы валидатор паролей срабатывал при пустом значении “Пароль повторно”.

Сам процесс регистрации не входит в рамки данной статьи, возможно позже напишу продолжение данной статьи.

« Previous Entries