Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Соблазнительные формы в Zend Framework 2

Dd3f18c87b851137000c7427d7bd5d32?s=47 fwdays
November 24, 2012

Соблазнительные формы в Zend Framework 2

— Что такое формы и какую роль они играют в веб приложениях
— Типичная реализация на стороне клиента и на стороне сервера
— Zend_Form в Zend Framework 1
— Zend\Form в Zend Framework 2
* Что изменилось
* Варианты реализации
* Что такое гидраторы и стратегии
* Новые элементы и HTML 5
* Декораторы и Twitter Bootstrap
* Интеграция с Doctrine 2

Dd3f18c87b851137000c7427d7bd5d32?s=128

fwdays

November 24, 2012
Tweet

More Decks by fwdays

Other Decks in Programming

Transcript

  1. Соблазнительные формы Zend Framework 2 Даниил Кожемяко Team Leader, TulaCo

    d.kozhemyako@gmail.com @kozhemyako https://github.com/dannytrue
  2. Что такое формы и какую роль они играют в веб

    приложениях
  3. None
  4. None
  5. None
  6. Типичная реализация на стороне клиента и на стороне сервера

  7. Реализация на стороне сервера:

  8. На стороне клиента:

  9. И это просто отображение!

  10. Та же форма, с заполнением данных И это просто отображение!

  11. В итоге: • Тяжело маштабировать • Неудобно поддерживать • Сложно

    разобраться • Легко запутаться
  12. Zend_Form Zend Framework 1

  13. Zend_Form: • Input элементы • Фильтры • Валидаторы • Sub

    формы • Декораторы • View хелперы
  14. Zend\Form Zend Framework 2

  15. Что изменилось?

  16. Новые HTML 5 элементы: • Color • Date • DateTime

    • DateTimeLocal • Email • Month • Number • Range • Time • Week
  17. None
  18. Collection элемент use Zend\Form\Element; use Zend\Form\Form; $phones = new Element\Collection('collection');

    $phones->setLabel('Phones') ->setCount(2) ->setTargetElement(new Element\Number()) ->setShouldCreateTemplate(true) ->allowAdd(true) ; $form = new Form('my-form'); $form->add($phones);
  19. Collection элемент

  20. Аннотации use Zend\Form\Annotation; /** * @Annotation\Name("user") * @Annotation\Hydrator("Zend\Stdlib\Hydrator\ObjectProperty") */ class

    User { /** * @Annotation\Exclude() */ public $id; /** * @Annotation\Filter({"name":"StringTrim"}) * @Annotation\Validator({"name":"StringLength", "options":{"min":1, "max":25}}) * @Annotation\Validator({"name":"Regex", "options":{"pattern":"/^[a-zA-Z][a-zA-Z0-9_-]{0,24}$/"}}) * @Annotation\Attributes({"type":"text"}) * @Annotation\Options({"label":"Username:"}) */ public $username; /** * @Annotation\Type("Zend\Form\Element\Email") * @Annotation\Options({"label":"Your email address:"}) */ public $email; }
  21. Hydrator & Strategy

  22. Связь модели и представления

  23. Реализация связи $form = new ProductForm(); $product = new Product();

    $form->bind($product);
  24. Передача данных из модели в форму

  25. Запись данных обратно в модель if ($this->getRequest()->isPost()) { $data =

    $this->getRequest()->getPost(); $form->setData($data); if ($form->isValid()) { $this->getEntityManager()->persist($entity); $this->getEntityManager()->flush(); } }
  26. Передача данных из формы в модель

  27. Что же такое гидратор

  28. Интерфейс гидратора interface HydratorInterface { /** @return array */ public

    function extract($object); public function hydrate(array $data, $object); }
  29. Основные функции гидратора 1. Заполнение элементов формы данными из модели

    (extract) 2. Заполнение модели данными из формы (hydrate)
  30. Стандартные гидраторы • ArraySerializable для работы с объектами типа ArrayObject

    • ClassMethods для работы с объектами через методы get и set • ObjectProperty для работы с объектами через их свойства
  31. Стратегии namespace Zend\Stdlib\Hydrator; use Zend\Stdlib\Hydrator\Strategy\StrategyInterface; interface StrategyEnabledInterface { public function

    addStrategy($name, StrategyInterface $strategy); public function getStrategy($name); public function hasStrategy($name); public function removeStrategy($name); }
  32. Интерфейс Стратегии namespace Zend\Stdlib\Hydrator\Strategy; interface StrategyInterface { public function extract($value);

    public function hydrate($value); }
  33. Интеграция с Doctrine 2

  34. Трудности: модели с зависимостями /** * @var PersonGroup * *

    @ORM\ManyToOne(targetEntity="PersonGroup") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="group_id", referencedColumnName="id") * }) */ private $group;
  35. Трудности: модели с зависимостями /** * Set group * @param

    PersonGroup $group * @return Person */ public function setGroup(PersonGroup $group = null) { $this->group = $group; return $this; } /** * Get group * @return PersonGroup */ public function getGroup() { return $this->group; }
  36. Проблемы которые нужно решить 1. Конвертация объектов в строки (Object

    → Id) 2. Конвертация обратно из строк в объекты (Id → Object)
  37. Решение 1. Переопределить стандартный гидратор 2. Добавить стратегию

  38. 1. Переопределить стандартный гидратор $form = new PersonForm(); $form->setHydrator(new \Zend\Stdlib\Hydrator\ClassMethods);

    ИЛИ use Zend\Form\Form; use Zend\Form\Element; use Zend\Stdlib\Hydrator\ClassMethods; class Group extends Form { public function __construct($name = null) { parent::__construct('person_group'); $form->setHydrator(new ClassMethods);
  39. 2. Добавить Стратегию $form = new PersonForm(); $form->setHydrator(new \Zend\Stdlib\Hydrator\ClassMethods); $form->getHydrator()->addStrategy(

    'group', new GroupStrategy($this->getEntityManager()) );
  40. Пример стратегии для работы с Doctrine 2 use Zend\Stdlib\Hydrator\Strategy\DefaultStrategy; use

    Doctrine\ORM\EntityManager; use PhoneBook\Entity\PersonGroup; class Group extends DefaultStrategy { protected $em; public function __construct(EntityManager $em) { $this->em = $em; } public function extract($value) { if ($value instanceof PersonGroup) { return $value->getId(); } return $value; }
  41. Пример стратегии для работы с Doctrine 2 public function hydrate($value)

    { if (!is_null($value)) { return $this->getEntityManager() ->find('PhoneBook\Entity\PersonGroup', $value); } return $value; } /** * return entity manager instance * @return \Doctrine\ORM\EntityManager */ protected function getEntityManager() { return $this->em; } }
  42. Интеграция с Twitter Bootstrap

  43. Стандартные View хелперы • FormInput() Вывод частей элемента по одному

    • FormRow() Вывод всего элемента одной строкой • FormCollection() Вывод всех элементов сразу одной строкой
  44. Вывод частей элемента по одному echo $this->form()->openTag($form); echo $this->formLabel($form->get('first_name')); echo

    $this->formInput($form->get('first_name')); echo $this->formLabel($form->get('last_name')); echo $this->formInput($form->get('last_name')); echo $this->formLabel($form->get('email')); echo $this->formInput($form->get('email')); echo $this->formSubmit($form->get('submit')); echo $this->form()->closeTag($form);
  45. Вывод всего элемента одной строкой echo $this->formLabel($form->get('first_name')); echo $this->formInput($form->get('first_name')); echo

    $this->formElementErrors($form->get('first_name')); = echo $this->formRow($form->get('first_name'));
  46. Вывод всех элементов сразу одной строкой echo $this->formRow($form->get('first_name')); echo $this->formRow($form->get('last_name'));

    echo $this->formRow($form->get('email')); echo $this->formSubmit($form->get('submit')); = echo $this->formCollection($form);
  47. View хелперы от dlu/dlutwbootstrap Git: https://bitbucket.org/dlu/dlutwbootstrap Composer: "dlu/dlutwbootstrap": "dev-master"

  48. None
  49. None
  50. Спасибо за внимание!