Sylius - 如何添加自定义促销活动?

Sylius - How to add a custom promotion action?

我已按照列出的教程进行操作 [输入 link 说明 here

但是,当我尝试通过此操作添加促销时,出现此错误:

Could not load type "AppBundle\Promotion\Action\CheapestProductDiscountPromotionActionCommand"

经过进一步调查,CheapestProductDiscountPromotionActionCommand.php 遍历 FormRegistry.php 中的以下代码块:

if (class_exists($name) && in_array('Symfony\Component\Form\FormTypeInterface', class_implements($name))) {
    $type = new $name();
} else {
    throw new InvalidArgumentException(sprintf('Could not load type "%s"', $name));
}

据我所知,它正在检查 CheapestProductDiscountPromotionActionCommand.php 是否实现了 FormTypeInterface,但我不完全确定为什么?我认为 CheapestProductDiscountConfigurationType 扩展了 AbstractType 实现了 FormTypeInterface?也许我错了,但我认为 CheapestProductDiscountPromotionActionCommand.php 不应该通过上面的代码块?

我的堆栈跟踪如下:

Stack Trace

    in vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php at line 87   +

    at FormRegistry ->getType ('AppBundle\Promotion\Action\CheapestProductDiscountPromotionActionCommand')
    in vendor/symfony/symfony/src/Symfony/Component/Form/FormFactory.php at line 83   +

    at FormFactory ->createNamedBuilder ('UK_WEB', 'AppBundle\Promotion\Action\CheapestProductDiscountPromotionActionCommand', array(), array('auto_initialize' => false, 'label' => 'UK Web Store', 'currency' => 'GBP'))
    in vendor/symfony/symfony/src/Symfony/Component/Form/FormFactory.php at line 47   +

    at FormFactory ->createNamed ('UK_WEB', 'AppBundle\Promotion\Action\CheapestProductDiscountPromotionActionCommand', array(), array('auto_initialize' => false, 'label' => 'UK Web Store', 'currency' => 'GBP'))
    in vendor/sylius/sylius/src/Sylius/Bundle/CoreBundle/Form/EventSubscriber/BuildChannelBasedPromotionActionFormSubscriber.php at line 114   +

    at BuildChannelBasedPromotionActionFormSubscriber ->createConfigurationFieldForChannel (object(Channel), 'AppBundle\Promotion\Action\CheapestProductDiscountPromotionActionCommand', array())
    in vendor/sylius/sylius/src/Sylius/Bundle/CoreBundle/Form/EventSubscriber/BuildChannelBasedPromotionActionFormSubscriber.php at line 74   +

    at BuildChannelBasedPromotionActionFormSubscriber ->addConfigurationFields (object(Form), 'cheapest_product_discount', array())
    in vendor/sylius/sylius/src/Sylius/Bundle/PromotionBundle/Form/EventListener/AbstractConfigurationSubscriber.php at line 72   +

    at AbstractConfigurationSubscriber ->preSetData (object(FormEvent), 'form.pre_set_data', object(EventDispatcher))

    at call_user_func (array(object(BuildChannelBasedPromotionActionFormSubscriber), 'preSetData'), object(FormEvent), 'form.pre_set_data', object(EventDispatcher))

    in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php at line 174   +

    at EventDispatcher ->doDispatch (array(array(object(BuildChannelBasedPromotionActionFormSubscriber), 'preSetData')), 'form.pre_set_data', object(FormEvent))
    in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php at line 43   +

    at EventDispatcher ->dispatch ('form.pre_set_data', object(FormEvent))
    in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php at line 43   +

    at ImmutableEventDispatcher ->dispatch ('form.pre_set_data', object(FormEvent))
    in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 341   +

    at Form ->setData (null)
    in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 477   +

    at Form ->initialize ()
    in vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php at line 226   +

    at FormBuilder ->getForm ()
    in vendor/sylius/sylius/src/Sylius/Bundle/PromotionBundle/Form/Type/Core/AbstractConfigurationCollectionType.php at line 54   +

    at AbstractConfigurationCollectionType ->buildForm (object(FormBuilder), array('block_name' => null, 'disabled' => false, 'label_format' => null, 'translation_domain' => null, 'auto_initialize' => true, 'trim' => true, 'required' => true, 'property_path' => null, 'mapped' => true, 'by_reference' => false, 'inherit_data' => false, 'compound' => true, 'method' => 'POST', 'action' => '', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'allow_add' => true, 'allow_delete' => true, 'prototype' => true, 'prototype_data' => null, 'prototype_name' => '__name__', 'entry_type' => 'Sylius\Bundle\PromotionBundle\Form\Type\PromotionActionType', 'delete_empty' => false, 'button_delete_label' => 'sylius.form.collection.delete', 'label' => 'sylius.form.promotion.actions', 'attr' => array(), 'data_class' => null, 'empty_data' => object(Closure), 'error_bubbling' => true, 'label_attr' => array(), 'upload_max_size_message' => object(Closure), 'validation_groups' => null, 'constraints' => array(), 'entry_options' => array('block_name' => 'entry'), 'button_add_label' => 'sylius.form.promotion.add_action'))
    in vendor/symfony/symfony/src/Symfony/Component/Form/ResolvedFormType.php at line 126   +

    at ResolvedFormType ->buildForm (object(FormBuilder), array('block_name' => null, 'disabled' => false, 'label_format' => null, 'translation_domain' => null, 'auto_initialize' => true, 'trim' => true, 'required' => true, 'property_path' => null, 'mapped' => true, 'by_reference' => false, 'inherit_data' => false, 'compound' => true, 'method' => 'POST', 'action' => '', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'allow_add' => true, 'allow_delete' => true, 'prototype' => true, 'prototype_data' => null, 'prototype_name' => '__name__', 'entry_type' => 'Sylius\Bundle\PromotionBundle\Form\Type\PromotionActionType', 'delete_empty' => false, 'button_delete_label' => 'sylius.form.collection.delete', 'label' => 'sylius.form.promotion.actions', 'attr' => array(), 'data_class' => null, 'empty_data' => object(Closure), 'error_bubbling' => true, 'label_attr' => array(), 'upload_max_size_message' => object(Closure), 'validation_groups' => null, 'constraints' => array(), 'entry_options' => array('block_name' => 'entry'), 'button_add_label' => 'sylius.form.promotion.add_action'))
    in vendor/symfony/symfony/src/Symfony/Component/Form/Extension/DataCollector/Proxy/ResolvedTypeDataCollectorProxy.php at line 102   +

    at ResolvedTypeDataCollectorProxy ->buildForm (object(FormBuilder), array('block_name' => null, 'disabled' => false, 'label_format' => null, 'translation_domain' => null, 'auto_initialize' => true, 'trim' => true, 'required' => true, 'property_path' => null, 'mapped' => true, 'by_reference' => false, 'inherit_data' => false, 'compound' => true, 'method' => 'POST', 'action' => '', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'allow_add' => true, 'allow_delete' => true, 'prototype' => true, 'prototype_data' => null, 'prototype_name' => '__name__', 'entry_type' => 'Sylius\Bundle\PromotionBundle\Form\Type\PromotionActionType', 'delete_empty' => false, 'button_delete_label' => 'sylius.form.collection.delete', 'label' => 'sylius.form.promotion.actions', 'attr' => array(), 'data_class' => null, 'empty_data' => object(Closure), 'error_bubbling' => true, 'label_attr' => array(), 'upload_max_size_message' => object(Closure), 'validation_groups' => null, 'constraints' => array(), 'entry_options' => array('block_name' => 'entry'), 'button_add_label' => 'sylius.form.promotion.add_action'))
    in vendor/symfony/symfony/src/Symfony/Component/Form/FormFactory.php at line 89   +

    at FormFactory ->createNamedBuilder ('actions', 'Sylius\Bundle\PromotionBundle\Form\Type\PromotionActionCollectionType', null, array('label' => 'sylius.form.promotion.actions', 'button_add_label' => 'sylius.form.promotion.add_action'))
    in vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php at line 106   +

    at FormBuilder ->create ('actions', 'Sylius\Bundle\PromotionBundle\Form\Type\PromotionActionCollectionType', array('label' => 'sylius.form.promotion.actions', 'button_add_label' => 'sylius.form.promotion.add_action'))
    in vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php at line 269   +

    at FormBuilder ->resolveChildren ()
    in vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php at line 215   +

    at FormBuilder ->getForm ()
    in vendor/symfony/symfony/src/Symfony/Component/Form/FormFactory.php at line 39   +

    at FormFactory ->create ('Sylius\Bundle\PromotionBundle\Form\Type\PromotionType', object(Promotion), array())
    in vendor/sylius/sylius/src/Sylius/Bundle/ResourceBundle/Controller/ResourceFormFactory.php at line 44   +

    at ResourceFormFactory ->create (object(RequestConfiguration), object(Promotion))
    in vendor/sylius/sylius/src/Sylius/Bundle/ResourceBundle/Controller/ResourceController.php at line 245   +

    at ResourceController ->createAction (object(Request))

    at call_user_func_array (array(object(ResourceController), 'createAction'), array(object(Request)))
    in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 153   +

    at HttpKernel ->handleRaw (object(Request), 1)
    in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 68   +

    at HttpKernel ->handle (object(Request), 1, true)
    in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php at line 168   +

    at Kernel ->handle (object(Request))
    in web/app_dev.php at line 43   +

    at require ('/Users/camerona/Documents/Projects/CheshireRaw/web/app_dev.php')
    in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php at line 40   +

我在 CheapestProductDiscountPromotionActionCommand 中发现了问题。

在列出的 sylius 文档中 here:

/**
    * {@inheritdoc}
*/
public function getConfigurationFormType()
{
    return CheapestProductDiscountPromotionActionCommand::class;
}

然而这应该是:

/**
    * {@inheritdoc}
*/
public function getConfigurationFormType()
{
    return CheapestProductDiscountConfigurationType::class;
}

这就是代码检查 CheapestProductDiscountPromotionActionCommand.php 实现 FormTypeInterface 的原因。

我已经成功地添加了我的自定义操作并且它运行良好。 sylius 文档有几个问题,但实现有效:)。