Symfony 2: Обновление до 2.3

Категория: Symfony2
Обновление Symfony до 2.3 версии.

Обновление Symfony 2.0 до 2.1

  1. The merging strategy for assets_base_urls and base_urls has changed;
  2. Переместили DoctrineBundle из Symfony репозитория в Doctrine репозиторий. Нужно изменить namespace в app/AppKernel.php:
    new Symfony\Bundle\DoctrineBundle\DoctrineBundle()
    // заменить на:
    new Doctrine\Bundle\DoctrineBundle\DoctrineBundle()
  3. Менеджер локали перенесен из Session класса в Request класс:
    # былоframework:  session:
    default_locale: fr

    # теперьframework: default_locale: fr
  4. Получение локали в Twig и PHP шаблонах:
    {{ app.request.session.locale }} >> {{ app.request.locale }} или $view['request']->getLocale()
  5. Безопасность. Перемещен метод equals() (подробнее):
    Symfony\Component\Security\Core\User\UserInterface::equals()// вSymfony\Component\Security\Core\User\EquatableInterface::isEqualTo()
    Можно просто переименовать ваш equals(), реализованный в User классе, в isEqualTo() и реализовать EquatableInterface.
  6. Изменен способ регистрации кастомных фабрик для настройки firewall. Теперь они регистрируются в bundle классе (подробнее)
  7. Firewall listener теперь регистрируется после Router listener. Теперь все защищенные URL должны иметь соответствующие роуты в настройке маршрутов. Также, при использовании кастомной 404 страницы убедитесь, что вы не используете функции, связанные с безопасностью, как то is_granted.
  8. Изменена настройка провайдеров пользователей:
    # Былоsecurity:  providers:    my_chain_provider:      providers: [my_memory_provider, my_doctrine_provider]    my_memory_provider:      users:        toto: { password: foobar, roles: [ROLE_USER] }        foo: { password: bar, roles: [ROLE_USER, ROLE_ADMIN] }
    # Сейчасsecurity: providers: my_chain_provider: chain: providers: [my_memory_provider, my_doctrine_provider] my_memory_provider: memory: users: toto: { password: foobar, roles: [ROLE_USER] } foo: { password: bar, roles: [ROLE_USER, ROLE_ADMIN] }
  9. MutableAclInterface::setParentAcl теперь принимает null;
  10. UserPassword перемещен из Security Bundle в Security Component:
    // до
    use Symfony\Bundle\SecurityBundle\Validator\Constraint\UserPassword;
    use Symfony\Bundle\SecurityBundle\Validator\Constraint as SecurityAssert;
    // после
    use Symfony\Component\Security\Core\Validator\Constraint\UserPassword;
    use Symfony\Component\Security\Core\Validator\Constraint as SecurityAssert;
  11. Формы... Метод buildViewBottomUp() переименован в finishView();
  12. Методы buildView() и finishView() принимают $options третим аргументом, а все "строительные" методы этих типов принимают FormBuilderInterface вместо FormBuilder. At last, all methods in these types now receive instances of where they received instances of FormBuilder before.

    # Было
    use Symfony\Component\Form\FormBuilder;
    public function buildForm(FormBuilder $builder, array $options)

    # Теперь
    use Symfony\Component\Form\FormBuilderInterface;
    public function buildForm(FormBuilderInterface $builder, array $options)
  13. Метод createBuilder был удален из FormTypeInterface для повышения производительности. It is now not possible anymore to use custom implementations of FormBuilderInterface for specific form types. Возможно, вы захотите реализовать свой собственный ResolvedFormTypeInterface.
  14. Кастомные типы полей. Вместо FieldType нужно наследовать FormType, а опцию compaund нужно установить в false, если ваше поле не содержит дочерние поля.
    // до
    public function getParent(array $options)
    {
    return 'field';
    }

    // теперь
    public function getParent(/* !ни какие опции не передаются! */)
    {
    return 'form';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
    $resolver->setDefaults(array(
    'compound' => false,
    ));
    }
  15. Опция data_class теперь должна быть установлена, если форма мапится на объект. Если установить null, тогда форма будет ожидать объект типа ArrayAccess (If you leave it empty, the form will expect an array, an instance of \ArrayAccess or a scalar value and fail with a corresponding exception).
  16. The mapping of property paths to arrays has changed. Previously, a property path "street" mapped to both a field $street of a class (or its accessors getStreet() and setStreet()) and an index ['street'] of an array or an object implementing \ArrayAccess. Now, the property path "street" only maps to a class field (or accessors), while the property path "[street]" only maps to indices. If you defined property paths manually in the "property_path" option, you should revise them and adjust them if necessary.
    // раньше
    $builder->add('name', 'text', array(
    'property_path' => 'address.street',
    ));

    // сейчас
    $builder->add('name', 'text', array(
    'property_path' => 'address[street]',
    ));
    If address is an object in this case, the code given in "Before" works without changes.
  17. Формы и поля в Symfony 2.3 должны именоваться с буквы, цифры или подчеркивания и содержать только буквы, цифры, подчеркивания, тире и двоеточия.
  18. В prototype-шаблоне "заглушка" в части имени и id теперь именуется, как __name__ вместо $$name$$;
  19. Опция read_only рендерит readonly="readonly", для отключения choise поля нужно использовать disabled;
  20. Вложенные формы не валлидируются автоматически, необходимо явно задать Valid ограничения в модели. Если вы не хотите использовать Valid ограничения или из родительской формы нет ссылки на дочернюю - можно включить валидацию вложенных форм опцией cascade_validation = true;
  21. FormType и FieldType были объединены и требуют адаптации вашей темы.
    Блок field_widget переименован в form_widget_simple.
    Все прочие field_* (field_row, field_error, etc) блоки переименованы в form_*.
    Объединены блоки generic_label и form_label в один - form_label.
    Блок widget_choice_options переименован в choice_widget_options.
    Использовать так:
    {% block url_widget %}
    {% spaceless %}
    {% set type = type|default('url') %}
    {{ block('form_widget_simple') }}
    {% endspaceless %}
    {% endblock url_widget %}
    Если вы использовали разные темы для field_* и form_* блоков, вы можете объединить их в form_* блок и внутри него добавить {% if compound %} условие. Если тип поля - форма, compaund = true.
  22. Новый формат генерации имен для name и id атрибутов полей. Теперь значение (value) находится в атрибуте value, а к вместо него к этим атрибутам добавляется индекс (целое число).
  23. Для получения выбранного значения в шаблоне choise поля теперь используется фильтр selectedchoice. Как и _form_is_choice_group используется для ... (Similarly, the _form_is_choice_group method used to check if a choice is grouped has been removed and can be checked with the iterable test):
    {% for label, choice in choices %}
      {% if choice is iterable %}
        < optgroup label="{{ label|trans({}, translation_domain) }}" >
        {% for nestedChoice, nestedLabel in choice %}
          ... options tags ...
        {% endfor %}
        </optgroup>
      {% else %}
        < option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>
          {{ label }}
        </option>
      {% endif %}
    {% endfor %}
  24. Создание дефолтных label вынесли на уровень шаблона, теперь нужно самому описать что показывать пользователю, если метка отсутствует:
    {% block form_label %}
    {% if label is empty %}
    {% set label = name|humanize %}
    {% endif %}
    {# ... #}
    {% endblock %}
  25. Удалены кастомные темы для каждой строки коллекции для повышения производительности. Теперь нужно использовать ключевое слово entry в имени строк коллекции, которое заменяет индекс строки:
    {% block _author_tags_entry_label %}
    {# ... #}
    {% endblock %}
  26. Метод renderBlock() хелпера PHP Templating переименован в block(). Первым аргументом ожидается объект класса FormView:
    <?php echo $view['form']->block($form, 'widget_attributes') ?>
  27. Изменен порядок аргументов в методах createNamed и createNamedBuilder в FormFactoryInterface:
    $form = $factory->createNamed('firstName', 'text');
  28. Много изменений в реализации ChoiceList., в результате заменили ArrayChoiceList. Если вы расширяли эти классы кастомными - вы должны расширить SimpleChoiceList и передать опции выбора в parent конструктор (подробнее):
    class MyChoiceList extends SimpleChoiceList
    {
    public function __construct()
    {
    // load choices
    parent::__construct($choices);
    }
    }
    Если есть необходимость ленивой подгрузки опций, т.е. как только они доступны впервые - вы можете расширить LazyChoiceList вместо переопределения loadChoiceList():
    class MyChoiceList extends LazyChoiceList
    {
    protected function loadChoiceList()
    {
    // load choices
    return new SimpleChoiceList($choices);
    }
    }
    Удалены PaddedChoiceList, MonthChoiceList и TimezoneChoiceList. Их функции объединены с DateType, TimeType и TimezoneType.
    Был адаптирован EntityChoiceList. Методы getEntities(), getEntitiesByKeys(), getIdentifier() и getIdentifierValues() были удалены или скрыты (сделаны приватными). Вместо getEntities*() используйте getChoices() и getChoicesByValues().
  29. Для form_label функции атрибуты теперь устанавливаются с ключем label_attr:
    {{ form_label(form.name, 'Your Name', { 'label_attr': {'class': 'foo'} }) }}
  30. EntitiesToArrayTransformer заменили на CollectionToArrayTransformer в сочетании с EntityChoiceList;
    EntityToIdTransformer удален и больше не требуется
  31. Переименованы трансформеры в соответствии с ChoiceListInterface:
    ArrayToBooleanChoicesTransformer >> ChoicesToBooleanArrayTransformer
    ScalarToBooleanChoicesTransformer >> ChoiceToBooleanArrayTransformer
    ArrayToChoicesTransformer >> ChoicesToValuesTransformer
    ScalarToChoiceTransformer >> ChoiceToValueTransformer
  32. FormUtil::toArrayKey() и FormUtil::toArrayKeys() были объединены внутри ChoiceList и не имеют аналогов;
  33. Методы add(), remove(), setParent(), bind() and setData() бросают исключение если форма уже связана (form is already bound);
  34. Если вы использовали FormEvents::PRE_BIND or FormEvents::BIND для связывания форм (on bound forms) - вы должны перести вашу логику в слушатели событий (event listener);
  35. Методы getDefaultOptions() и getAllowedOptionValues() (в Symfony 2.3) интерфейсов FormTypeInterface и FormTypeExtensionInterface заменили на один setDefaultOptions():
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
    $resolver->setDefaults(array(
    'gender' => 'male',
    ));

    $resolver->setAllowedValues(array(
    'gender' => array('male', 'female'),
    ));
    }
    Используйте замыкания чтобы установить зависимые параметры:
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
    $resolver->setDefaults(array(
    'empty_data' => function (Options $options, $value) {
    return $options['multiple'] ? array() : $value;
    }
    ));
    }
    Второй аргумент $value содержит текущие дефолтные значения и не должен передаваться без необходимости.
  36. Переименованы методы в FormBuilder'е:
    prependClientTransformer() >> addViewTransformer(), передать true вторым аргументом
    appendClientTransformer() >> addViewTransformer()
    getClientTransformers() >> getViewTransformers()
    resetClientTransformers() >> resetViewTransformers()
    prependNormTransformer() >> addModelTransformer()
    appendNormTransformer() >> addModelTransformer(), передать true вторым аргументом
    getNormTransformers() >> getModelTransformers()
    resetNormTransformers() >> resetModelTransformers()
  37. Переименованы события:
    FormEvents::SET_DATA >> FormEvents::PRE_SET_DATA
    FormEvents::BIND_CLIENT_DATA >> FormEvents::PRE_BIND
    FormEvents::BIND_NORM_DATA >> FormEvents::BIND
    Также классы событий DataEvent и FilterDataEvent заменили на FormEvent:
    $builder->addListener(FormEvents::PRE_BIND, function (FormEvent $event) {
    // ...
    });
  38. Удален FormValidatorInterface. Для реализации кастомной валидации используйте event listeners и слушайте FormEvents::POST_BIND событие (или другое *BIND событие). Если вы использовали класс CallbackValidator - передайте его непосредственно в addEventListener.
  39. Метод guessMinLength() для FormTypeGuesserInterface заменили на guessPattern(). Этот метод может возвращать регулярку, которая вставляется в HTML5 атрибут pattern:
    public function guessPattern($class, $property)
    {
    if (/* condition */) {
    return new ValueGuess('.{'.$minLength.',}', Guess::LOW_CONFIDENCE);
    }
    }
  40. В Symfony 2.3 больше не поддерживается значение false для опции property_path. Используйте mapped, для установки мапинга поля на parent данные:
    $builder->add('termsAccepted', 'checkbox', array(
    // 'property_path' => false, << deprecated!
    'mapped' => false,
    ));
  41. Удалены или заменеы следующие методы:
    getTypes()
    getErrorBubbling()      >> $form->getConfig()->getErrorBubbling();
    getNormTransformers()
    getClientTransformers()
    getAttribute()
    hasAttribute()
    getClientData()         >> getViewData()
    getChildren()           >> all()
    hasChildren()           >> count()
    bindRequest()           >> bind()
    К другим методам можно получить доступ через FormConfigInterface объект.
  42. Опция validation_constraint переименована на constraints, которой вы можете задать один или несколько ограничений (условий) для формы.
    Ограничения будут применены только если они принадлежат валидируемой группе (в данном случае Custom):
    $builder->add('name', 'text', array(
    'constraints' => new NotBlank() // можете передать массив ограничений
    // or
    'constraints' => array(
    new NotBlank(array('groups' => 'Custom')),
    new MinLength(3),
    )
    ));
  43. Переименованы опции data_timezone >> model_timezone и user_timezone >> view_timezone из DateType, DateTimeType и TimeType:
    $builder->add('scheduledFor', 'date', array(
    'model_timezone' => 'UTC',
    'view_timezone' => 'America/New_York',
    ));
  44. Методы addType, hasType и getType фабрики формы (FormFactory) теперь нужно вызывать из FormRegistry (form.registry):
    # до
    $this->get('form.factory')->addType(new MyFormType());

    # в Symfony 2.3
    $registry = $this->get('form.registry');
    $registry->addType($registry->resolveType(new MyFormType()));
  45. Удалены следующие методы из FormView класса: set(), has(), get(), all(), getVars(), addChild(), getChild(), getChildren(), removeChild(), hasChild(), hasChildren(), getParent(), hasParent(), setParent(). Вместо этого, вы получаете доступ к публичным свойствам vars, children и parent.
    # ранее
    $view->set('help', 'A text longer than six characters');
    $view->set('error_class', 'max_length_error');

    # сейчас
    $view->vars = array_replace($view->vars, array(
    'help' => 'A text longer than six characters',
    'error_class' => 'max_length_error',
    ));
    $view->hasChildren() >> count($view->children)
    $view->get('error_class') >> $view->vars['error_class']
  46. продолжение... https://github.com/symfony/symfony/blob/2.3/UPGRADE-2.1.md#validator

категория: Symfony2