Flo Flo - 3 months ago 26
PHP Question

Sylius: create a taxonomy-based promotion

I need to create a new promotion rule based on taxonomy : for example, 10% off for all products (not whole order) which have a specific taxon.

I read the docs, read the code for the two rules that are shipped with sylius (item count and order total). I started creating a new rule checker (for the moment it only returns true), so now I have a third promotion rule available ("taxonomy"). Then I created its configuration form type. Here I need to create a select listing all taxons configured, to be able to choose which taxon triggers the promotion. And here I'm stucked. What I tried in TaxonomyConfigurationType.php (I injected the entity manager) :

class TaxonomyConfigurationType extends AbstractType
{

protected $em;

public function __construct($em)
{
$this->em = $em;
}

/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('theme', 'choice',
array(
'mapped' => false,
'multiple' => false,
'empty_value' => 'Choose a taxon',
'choices' => $this->buildThemeChoices()
)
);
}

public function getName()
{
return 'ecad_promotion_rule_taxonomy_configuration';
}

protected function buildThemeChoices() {

$choices = array();

/// how can I access the taxonomy repo ?
$r = $this->em->getRepository('BoutiqueBundle:Theme');
$entities = $r->findAll();

foreach ($entities as $e) {
$choices[$e->getId()] = $e->getName();
}

return $choices;
}
}


I override the Taxon class (BoutiqueBundle:Theme) in order to translate my taxons, so I get this error :

Class "Ecad\BoutiqueBundle\Entity\Theme" sub class of "Sylius\Bundle\TaxonomiesBundle\Model\Taxon" is not a valid entity or mapped super class.


Any lead to achieve this ? In the end I need to store a taxon id in $configuration to be able to check if a product is eligible.

One other thing : is it possible to specify only one product as a promotion subject ?

Thanks

Flo Flo
Answer

OK my mistake...

For those interested, I have now a new promotion rule based on taxonomy (I want to use a particular vocabulary called "Thematique") :

class TaxonomyConfigurationType extends AbstractType
{

protected $container;

public function __construct($container)
{
    $this->container = $container;
}

/**
 * {@inheritdoc}
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('taxons', 'choice', array(
        'label' => 'Thème',
        'choices' => $this->getThemeChoices(),
        'multiple' => true,
        'required' => true
    ));
}

public function getName()
{
    return 'promotion_rule_taxonomy_configuration';
}

protected function getThemeChoices() {

    $taxonomyRepository = $this->container->get('sylius.repository.taxonomy');
    $taxonomy = $taxonomyRepository->findOneByName('Thematique');
    $taxons = $taxonomy->getTaxonsAsList($taxonomy);

    $choices = array();
    foreach($taxons as $t) {
        $choices[$t->getId()] = $t->getName();
    }

    return $choices;
}
}

I can select one or more taxon(s) which are correctly serialized, and retrieved when editing the promotion rule. I had to pass @service_container as an argument to this service.

I will update this post for the next steps (rule checking, adjustment on the product price not the whole order...), if this is authorized on SO.