Sylius - переопределение CartItemType прерывает представление продукта

Силиус 1.0.0-dev

Я пытаюсь изменить поле Quantity CartItemType.

Следуя старым документам, я создал новый FormType в своем Bundle и расширяет оригинал в Symfony/Bundle/CartBundle/Form/Type/CartItemType.

Мой пользовательский CartItemType выглядит следующим образом:

use Sylius\Bundle\CartBundle\Form\Type\CartItemType as BaseType;
use Symfony\Component\Form\FormBuilderInterface;


class CartItemType extends BaseType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->remove('quantity')
            ->add('quantity', 'hidden', [
                'attr' => ['min' => 1, 'max' => 1],
                'data' => '1',
                'label' => 'sylius.form.cart_item.quantity',
            ])
            ->setDataMapper($this->orderItemQuantityDataMapper);
    }
}

Я хочу, чтобы вы не могли покупать более одного количества товара за заказ.

Мой конфиг выглядит так:

sylius_cart:
    resources:
        cart_item:
            classes:
                form:
                    default: Dinamic\Bundle\SyliusRibBundle\Form\Type\CartItemType

Когда я открываю какой-либо вид продукта, я получаю эту ошибку:

Варианта «товар» не существует. [...] в @SyliusShop/Product/Show/_inventory.html.twig в строке 4

Любая идея о том, почему это происходит?


person Borja Pombo    schedule 12.09.2016    source источник


Ответы (2)


Вместо расширения CartBundle CartItemType используйте это:

use Sylius\Bundle\CoreBundle\Form\Type\CartItemType as BaseType;

Класс CoreBundle CartItemType расширяет CartBundle CartItemType, поэтому, если вы расширите неправильный класс, это сломает все.

person Brett    schedule 12.09.2016

Не расширяйте типы форм Symfony таким образом — вместо этого расширяйте Symfony\Component\Form\AbstractType и реализуйте getParent() в своем пользовательском типе:

public function getParent()
{
    return BaseType::class;
}

Таким образом, родительские параметры будут доступны и для вашего пользовательского типа, и все будет правильно отображаться/инициализироваться.

Редактировать:

Технически оба подхода должны работать. Однако использование наследования полностью переопределит поведение родительской формы, а использование getParent() добавит ваше собственное поведение к родительской форме.

getParent() сообщит Symfony сначала создать форму, определенную в этом методе, а затем использовать ее в качестве основы для собственной реализации. Таким образом, при его использовании FormBuilder в вашем методе buildForm() уже будет содержать полную родительскую форму, готовую для ваших собственных модификаций, OptionsResolver в вашем методе configureOptions() уже будет иметь определенные параметры родительской формы и значения по умолчанию и т. д., что, по-видимому, именно то, что вы хотите (иначе ваш вызов $builder->remove() имеет очень мало смысла). При использовании наследования вам нужно позаботиться о том, чтобы сделать все, что делает родительская форма, что вы хотите сделать, что вполне может сломаться при изменении родительской формы.

Еще одно отличие заключается в форме Symfony расширения. При реализации getParent() любые расширения формы, примененные к родительской форме, будут применяться и к вашей пользовательской форме. При использовании наследования это не так.

С первым пунктом легко работать (например, parent::buildForm() гарантирует, что у вас будут правильные поля), но со вторым не так просто. Как правило, вы хотите, чтобы эти расширения также применялись к вашему пользовательскому типу формы - в этом случае на самом деле есть неплохая вероятность того, что ошибка вызвана тем, что расширение формы не применяется к вашему пользовательскому типу.

В общем, используйте getParent(), когда это возможно. Используйте наследование для типов форм, только если вы хотите полностью переопределить поведение или явно хотите, чтобы расширения форм не применялись к вашему пользовательскому типу.

person YamiTenshi    schedule 12.09.2016
comment
Спасибо за подсказку, но это не развеяло мои сомнения :) - person Borja Pombo; 12.09.2016
comment
Я на самом деле только что понял, что оба должны работать, но есть несколько отличий. Я отредактирую их в своем посте. - person YamiTenshi; 13.09.2016