Sylius: Insert argument into sylius repository method

Created on 19 Jan 2017  路  9Comments  路  Source: Sylius/Sylius

Hi, I'm trying to override the product admin list view, and I noticed that sylius uses the createListQueryBuilder method in the product repository to retrieve products. I would like to retrieve products by channel but I don't want to do it from the controller, I would like to know if it's possible to just extend the product repository and inject the channel context in my product repository.
I have created my custom repository, I inserted this in my app.config.config:

sylius_product:
    resources:
        product:
            classes:
                repository: AppBundle\Repository\ProductRepository

and in my product repository I've created a new function findAllByChannel:

public function findAllByChannel($locale, ChannelInterface $channel = null)
    {
        $queryBuilder = $this->createQueryBuilder('o');

        $queryBuilder
            ->addSelect('translation')
            ->leftJoin('o.translations', 'translation')
            ->andWhere('translation.locale = :locale')
            ->andWhere('channel = :channel')
            ->setParameter('channel', $channel )
            ->setParameter('locale', $locale)
        ;
        return $queryBuilder;
    }

But now I cannot use my new method, I would like to do something like this:

sylius_grid:
    grids:
        sylius_admin_product:
            driver:
                name: doctrine/orm
                options:
                    class: "%sylius.model.product.class%"
                    repository:
                        method: findAllByChannel
                        arguments: ["%locale%", "expr:service('sylius.context.channel').getChannel()"]

I've edited the product grid file in Sylius/AdminBundle/Resources/config/grids/product.yml to pass the channel as an argument, like above, and it works fine, how can I override that in my AppBundle.

Stale

Most helpful comment

Hi, I'm @igorjacon's coworker,
The issue is that we can't overwrite the driver section of the grid.
In the documentation, there is example where we can edit the "fields" and "actions" block and it work in our project, but not for the "driver" block.

We think this is a bug.
Let us know if you need more informations.

All 9 comments

You should be able to paste the configuration (your last YML block) into app/config/config.yml and it should work. Please let us know if it does not! :) I would also consider renaming the method, because it suggests that return type is results already, while it is a query builder. I'd go with createListByChannelQueryBuilder.

I inserted that code in my app/config/config.yml and it still doesn't work :/

Hi, I'm @igorjacon's coworker,
The issue is that we can't overwrite the driver section of the grid.
In the documentation, there is example where we can edit the "fields" and "actions" block and it work in our project, but not for the "driver" block.

We think this is a bug.
Let us know if you need more informations.

Hi,
What is the next phase for this ticket ?
Thanks

Isn't it related to #7095?

@GuillaumeSTEIN can you check this solution?

@lchrusciel,
Thank you for your answer, it helped us.

Our first workaround was to edit the vendor folder.

But now we added this to the AppKernel file

    protected function getContainerLoader(ContainerInterface $container)
    {
        $locator = new FileLocator($this, $this->getRootDir() . '/Resources');
        $resolver = new LoaderResolver(array(
            new XmlFileLoader($container, $locator),
            new YamlFileLoader($container, $locator),
            new IniFileLoader($container, $locator),
            new PhpFileLoader($container, $locator),
            new DirectoryLoader($container, $locator),
            new ClosureLoader($container),
        ));
        return new DelegatingLoader($resolver);
    }

And created the app/Resources/SyliusAdminBundle/config/grids/product.yml from the original and edited the driver section.

This work but we have to overwrite the entire file. If one day Sylius add new features in this file, we won't have them.
We consider it as a workaround and not final solution.

We think a nice solution would be to put these values in the same config file that contains the sylius_product section.

We already have something like this :

sylius_product:
    resources:
        product:
            classes:
                model: "%app_product_class%"
                repository: App\ProductBundle\Repository\ProductRepository

If sylius could understand this, it would be ideal for us :

sylius_product:
    resources:
        product:
            classes:
                model: "%app_product_class%"
                repository:
                    class: App\ProductBundle\Repository\ProductRepository
                    method: findAllByChannel
                    arguments: ["%locale%", "expr:service('sylius.context.channel').getChannel()"]

@GuillaumeSTEIN we know, that it is not a proper solution, but should work for now. An original issue is still open, as we are looking for appropriate solution. Anyway, %app_product_class% should not be needed ;)

I don't even know how do you want to interpret your ideal config, but we probably won't go this way. You can define method on each action separately.

@pjedrzejewski this one probably can be closed as it is mostly duplication of #7095.

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in a week if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings