1

コンテクスト

私の場合、「割引バウチャー」(割引)付きの注文がいくつかあります。割引は、さまざまな条件下で使用できます。たとえば、割引には有効期限があり、限られた数の顧客が使用でき、ユーザー専用にすることができます...

各割引は、複数の注文に添付できます。

私のバックオフィスでは、利用可能な割引のリストを含む「割引」フィールドを注文作成フォームに追加したいと思いますが、適切な割引のみです。

私が作ったもの

  • フィールドmanyToManyを持つエンティティ「order」

    /**
    * @ORM\ManyToMany(targetEntity="PATH\MyBundle\Entity\Discount", inversedBy="orders")
     * @ORM\JoinTable(name="shop_discounts_orders",
     *      joinColumns={@ORM\JoinColumn(name="order_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="discount_id", referencedColumnName="id")}
     *      )
     */
    private $discounts;
    
  • エンティティは、フィールドmanyToManyで「割引」します

     /**
     * @ORM\ManyToMany(targetEntity="PATH\MyBundle\Entity\Order", mappedBy="discounts")
     */
     private $orders;
    
  • フィールド割引のあるフォームOrderType

    $builder->add('discounts', 'entity',
        array( 'label' => 'Discount vouchers',
            'required' => false,
            'expanded' => true,
            'class' => 'PATH\MyBundle\Entity\Discount',
            'property' => 'title',
            'multiple' => true,
            'query_builder' => function(EntityRepository $er) use ($params) {
                        return $er->getQuerySelectType($params);
                    },
        ));
    

このソリューションを使用すると、エンティティリポジトリでリクエストによって定義された特定の割引を返すことができます。たとえば、有効期限のある状態に適しています。

欲しいもの

チェックボックスリストで結果をフィルタリングしたいのですが。実際、割引の使用を専用ユーザーに制限したり、製品のリストに制限したり、使用回数を制限したりしたいのですが...これらの条件は単純なSQLリクエストでは実行できません。

特別なタイプを作成してみます。私の考えは、エンティティの配列を割引して選択リストをロードすることです...その後、dataTransformerを作成しましたが、機能しません!

あなたのアイデアをありがとう!

4

2 に答える 2

1

$optionsたとえば、 fromを使用してとpublic function buildForm(FormBuilderInterface $builder, array $options)を渡すことができます。これらの2つの情報を使用して、割引のリストを(クエリで)絞り込むことができます。userproduct

その場合は、setDefaultValueに追加する必要があります

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
        $resolver->setDefaults(array(
            'user_discount' => null,
            'product_discount' => null,
        ));
}

とあなたのコントローラーで:

$form = $this->formFactory->create(new YourFormType(), $entity, array(
    'user_discount' => $this->getUser(),
    'product_discount' => $product,
));
于 2013-03-14T12:32:26.073 に答える
0

私は解決策を見つけ、誰かが私と同じ問題を抱えている場合はそれを説明します。

  • カスタムタイプを作成する

私のカスタムタイプはSymfony\Bridge \ Doctrine \ Form \ Type\DoctrineTypeに触発されています

class DiscountOrderType extends AbstractType
{
     // overide choiceList callback
     public function setDefaultOptions(OptionsResolverInterface $resolver)
     {
        $choiceListCache =& $this->choiceListCache;
        $type = $this;

        $choiceList = function (Options $options) use (&$choiceListCache, &$time, $container) {

          [[ Copy paste same as Doctrine type ]]
        // Create your own choiceList class (EntityChoiceList)
        if (!isset($choiceListCache[$hash])) {
            $choiceListCache[$hash] = new DiscountChoiceList(
                $options['em'],
                $options['class'],
                $options['property'],
                $options['loader'],
                $options['choices'],
                $options['group_by']
            );
            // If you want add container
            $choiceListCache[$hash]->setContainer($container);
        }

        return $choiceListCache[$hash];
    };

    $resolver->setDefaults(array(
        'choice_list'       => $choiceList,
    ));

}
  • カスタムEntityChoiceListを作成します

私のカスタムタイプはSymfony\Bridge \ Doctrine \ Form \ ChoiceList\EntityChoiceListに触発されています

class EntityChoiceList extends ObjectChoiceList
{
protected function load()
{
    if ($this->entityLoader) {
        $entities = $this->entityLoader->getEntities();
    } else {
        $entities = $this->em->getRepository($this->class)->findAll();
    }

    // You have access to the entities in the choice list
    // Add your custom code here to manipulate the choice list
    // you can do some check not properly possible with sql request (http requests on each result, ...) before add it in choice list
    // you can add some custom cache rules, ...
    // if you use gedmon and want apply a "join" with translate table, you can add $query->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'); before playing request...
    // Possibilities are infinite

    // FOR INSTANCE : you already want unset first entity of the result
    if (isset($entities[0])) {
        unset($entities[0]);
    }
    // END OF CUSTOM CODE
    try {
        // The second parameter $labels is ignored by ObjectChoiceList
        // The third parameter $preferredChoices is currently not supported
        parent::initialize($entities, array(), array());
    } catch (StringCastException $e) {
        throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $e);
    }

    $this->loaded = true;
}

もちろん、beautyfullコードのsymfonyクラスを拡張してみることができます;)。

あなたの助けを@maxwell2022に感謝します!

于 2013-03-15T14:10:41.977 に答える