Фильтр ресурсов и доктрины Sylius

Я новичок в Силиусе и пытаюсь расширить его для своего бизнеса. В настоящее время у меня проблема с администратором, которую я не знаю, как решить.

У меня есть сущность Корзина, которая однозначно связана с сущностью Sylius Product:

/**
 * @ORM\Entity
 * @ORM\Table(name="app_basket")
 */
class Basket implements ResourceInterface, BasketInterface
{
    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Product\Product", inversedBy="basket", cascade={"persist", "remove"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $product;
}

Я создал это отношение, чтобы иметь возможность гораздо проще справляться с управлением заказами Sylius. Я не хочу смешивать объекты корзины и продукта в своем бизнесе, поэтому я создал фильтр Doctrine, чтобы исключить элементы корзины из продуктов:

<?php

namespace App\Doctrine\Filter;

use App\Entity\Product\Product;
use Doctrine\ORM\Mapping\ClassMetadata;
use \Doctrine\ORM\Query\Filter\SQLFilter;

class ProductFilter extends SQLFilter
{

    /**
     * @inheritDoc
     */
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
    {
        if($targetEntity->getName() !== Product::class) {
            return '';
        }

        return "$targetTableAlias.id not in (select product_id from app_basket)";
    }

}

На админке товаров все отлично, корзин нет. Но если я перейду на страницу индекса администрирования корзины, у меня будет следующая ошибка:

Возникло исключение во время отрисовки шаблона ("Сущность типа" App\Entity\Product\Product "для идентификаторов id(4) не найдена").

Это из-за сетки, которую я использую. Я хочу, чтобы отображалось название продукта, включенного в корзину:

sylius_grid:
    grids:
        app_admin_basket:
            driver:
                name: doctrine/orm
                options:
                    class: App\Entity\Basket\Basket
            fields:
                id:
                    type: string
                    label: sylius.ui.id
                product.name:
                    type: string
                    label: sylius.ui.name

Чтобы получить имя корзины.product.name, сгенерированный запрос обращается непосредственно к таблице продуктов, а не к таблице корзины:

SELECT t0.code AS code_1, t0.created_at AS created_at_2, t0.updated_at AS updated_at_3, t0.enabled AS enabled_4, t0.id AS id_5, t0.variant_selection_method AS variant_selection_method_6, t0.average_rating AS average_rating_7, t0.main_taxon_id AS main_taxon_id_8, t9.id AS id_10, t9.product_id AS product_id_11 
--problem here
FROM sylius_product t0 
LEFT JOIN app_basket t9 ON t9.product_id = t0.id 
WHERE t0.id = 4 
--Doctrine SQL FIlter
AND ((t0.id not in (select product_id from app_basket)));

У меня также такое же поведение, если я получаю это в шаблоне веточки:

{{ basket.product.name }}

С аннотацией fetch="EAGER" у меня нет ошибки, но целевая сущность по-прежнему не отражает то, что я хочу.

Есть ли способ заставить Sylius Resource сначала пройти через сущность корзины, а не напрямую во встроенную сущность?

2 ответа

Ваш фильтр всегда будет препятствовать доставке товара из корзины. Вы можете попробовать отключить его хотя бы для этого запроса: https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/filters.html

Попробуй это

sylius_grid:
    grids:
        app_admin_basket:
            driver:
                name: doctrine/orm
                options:
                    class: App\Entity\Basket\Basket
            fields:
                id:
                    type: string
                    label: sylius.ui.id
                product.name:
                    type: twig
                    label: sylius.ui.name
                    path: .
                    options:
                        template: thetemplate.html.twig

В path: .property дает вам доступ ко всей сущности, а не к определенному свойству. Затем вы сможете получить к нему доступ, используяdata.product.name в шаблоне веточки.

Вы также можете попробовать это, хотя я это не тестировал:

sylius_grid:
    grids:
        app_admin_basket:
            driver:
                name: doctrine/orm
                options:
                    class: App\Entity\Basket\Basket
            fields:
                id:
                    type: string
                    label: sylius.ui.id
                product.name:
                    type: string
                    label: sylius.ui.name
                    path: product.name
Другие вопросы по тегам