Фильтр ресурсов и доктрины 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