Я только что обновился до 2.8, и теперь я получаю следующую ошибку при вызове функции создания фабрики форм.
Error: Class Symfony\Component\Form\Extension\Core\Type\FormType contains 1
abstract method and must therefore be declared abstract or implement the
remaining methods (Symfony\Component\Form\FormTypeInterface::setDefaultOptions)
Вызов FormFactory выглядит так:
$this->formFactory->create(
get_class(new ProductType()),
$product,
[
'method' => 'POST',
'type' => $type,
'locales' => $context->shop->getLocales(),
'product' => $product,
'numberDataTransformer' => $this->numberTransformerFactory->createFromLocale(
$context->user->getLocale(),
$context->shop->getDefaultLocale()
),
'priceType' => $context->shop->getConfiguration()->getProductConfiguration()->getPricesBackend(),
'isShortDescriptionEnabled' => $context->shop->getConfiguration()->getProductConfiguration()->isShortDescriptionEnabled()
]);
Я попробовал несколько способов передать ProductType функции, но ни один из них не работает. Я всегда получаю один из двух результатов: либо результат заключается в том, что тип не может быть найден, либо возвращается ошибка, что FormType не реализует setDefaultOptions.
Что я упустил?
РЕДАКТИРОВАТЬ:
Вот дополнительный код:
Объявление параметра formFactory:
public function __construct(Request $request, FormFactoryInterface $formFactory)
{
$this->request = $request;
$this->formFactory = $formFactory;
}
Класс ProductType
<?php
namespace CustomNamespace\BackendBundle\Product\Form;
use CustomNamespace\BackendBundle\Common\NumberDataTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use CustomNamespace\BackendBundle\Product\Form\ImageType;
use ShopwareEasy\BackendBundle\Product\Form\AttachmentType;
use Symfony\Component\Validator\Exception\InvalidOptionsException;
/**
* Form element type for products.
*/
class ProductType extends AbstractType
{
/**
* @var string
*/
private $method;
/**
* @var string
*/
private $type;
/**
* @var array
*/
private $locales;
/**
* @var Product
*/
private $product;
/**
* @var \CustomNamespace\BackendBundle\Common\NumberDataTransformer
*/
private $numberDataTransformer;
/**
* @var string
*/
private $priceType;
/**
* @var bool
*/
private $isShortDescriptionEnabled;
/**
* @param FormBuilderInterface $builder
* @param array $options
* @return void
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->setMethod($this->method);
$regionType = new RegionShippingTimeType();
if ($this->type == 'download') {
$regionType->enableForDownloadableProduct();
}
$builder->add('regions', 'collection', array(
'type' => $regionType,
'label' => false,
'options' => array(
'required' => false,
'attr' => array('class' => 'email-box')
),
));
$builder->add('vendor', 'text', ['label' => 'form_product_vendor']);
if ($this->type == 'normal') {
$builder->add(
'mainVariant',
new MainVariantNormalType(
$this->method,
$this->locales,
$this->product,
$this->numberDataTransformer,
$this->priceType,
$this->isShortDescriptionEnabled
),
['error_bubbling' => false, 'label' => false]
);
} elseif ($this->type == 'download') {
$builder->add(
'mainVariant',
new MainVariantDownloadType(
$this->method,
$this->locales,
$this->product,
$this->numberDataTransformer,
$this->priceType,
$this->isShortDescriptionEnabled
),
['error_bubbling' => false, 'label' => false]
);
} elseif ($this->type == 'variant') {
$builder->add(
'mainVariant',
new MainVariantVariantType(
$this->method,
$this->locales,
$this->product,
$this->numberDataTransformer,
$this->priceType,
$this->isShortDescriptionEnabled
),
['error_bubbling' => false, 'label' => false]
);
}
if ($this->method == 'PUT') {
$builder->add(
'images',
new ImageType(),
['error_bubbling' => true, 'label' => false]
);
$builder->add(
'attachments',
new AttachmentType(),
['error_bubbling' => true, 'label' => false]
);
}
}
/**
* @param \Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver
*/
public function configureOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'CustomNamespace\\BackendBundle\\Product\\Product',
'csrf_protection' => false,
'error_bubbling' => false,
'cascade_validation' => true,
'method' => 'POST',
'type' => 'normal'
)
);
parent::configureOptions($resolver);
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
/** @var OptionResolver $resolver */
$this->configureOptions($resolver);
}
public function getName() {
return get_class($this);
}
}
ProductType
. Что у тебя в$this->formFactory
? Где вы его загрузили? - person Michael Sivolobov   schedule 15.12.2015product
и используйте его. - person Michael Sivolobov   schedule 15.12.2015setDefaultOptions
при реализацииconfigureOptions
- person Michael Sivolobov   schedule 15.12.2015FormType
, а не сProductType
, и поэтому она возникает. Вам нужно перейти на обычное имя вашей фабрики. Почему вы не хотите использовать обычные имена? И насчет BC: если у вас уже есть Symfony 2.8 и вашProductType
реализует новый интерфейс, он всегда будет зависеть от Symfony 2.8. Таким образом, любой старый компонент, который использует вашу форму, делает это через компонент Symfony Forms версии 2.8, поэтому ваш метод BC никогда не будет использоваться. - person Michael Sivolobov   schedule 15.12.2015getName()
из типа формы. Вам это больше не нужно. Кроме того, создание экземпляра объекта для получения пространства имен класса действительно странно и расточительно. Я бы просто использовалProductType::class
. - person Jakub Zalas   schedule 15.12.2015setDefaultOptions()
, заменитеconfigureOptions(OptionsResolverInterface $resolver)
наpublic function configureOptions(OptionsResolver $resolver)
и избавьтесь от вызоваparent::configureOptions($resolver);
- person Jason Roman   schedule 17.12.2015