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

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

fwdays
November 24, 2012

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

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

fwdays

November 24, 2012
Tweet

More Decks by fwdays

Other Decks in Programming

Transcript

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

    формы • Декораторы • View хелперы
  2. Новые HTML 5 элементы: • Color • Date • DateTime

    • DateTimeLocal • Email • Month • Number • Range • Time • Week
  3. 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);
  4. Аннотации 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; }
  5. Запись данных обратно в модель if ($this->getRequest()->isPost()) { $data =

    $this->getRequest()->getPost(); $form->setData($data); if ($form->isValid()) { $this->getEntityManager()->persist($entity); $this->getEntityManager()->flush(); } }
  6. Интерфейс гидратора interface HydratorInterface { /** @return array */ public

    function extract($object); public function hydrate(array $data, $object); }
  7. Стандартные гидраторы • ArraySerializable для работы с объектами типа ArrayObject

    • ClassMethods для работы с объектами через методы get и set • ObjectProperty для работы с объектами через их свойства
  8. Стратегии 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); }
  9. Трудности: модели с зависимостями /** * @var PersonGroup * *

    @ORM\ManyToOne(targetEntity="PersonGroup") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="group_id", referencedColumnName="id") * }) */ private $group;
  10. Трудности: модели с зависимостями /** * 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; }
  11. Проблемы которые нужно решить 1. Конвертация объектов в строки (Object

    → Id) 2. Конвертация обратно из строк в объекты (Id → Object)
  12. 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);
  13. Пример стратегии для работы с 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; }
  14. Пример стратегии для работы с 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; } }
  15. Стандартные View хелперы • FormInput() Вывод частей элемента по одному

    • FormRow() Вывод всего элемента одной строкой • FormCollection() Вывод всех элементов сразу одной строкой
  16. Вывод частей элемента по одному 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);
  17. Вывод всех элементов сразу одной строкой 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);