Может ли кто-нибудь помочь установить и получить массив классов подписчика Symfony (Shopware 6) из функции? Вот мой текущий подписчик:
<?php declare(strict_types=1);
namespace CustomFilter\Subscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Context;
use Symfony\Component\HttpFoundation\Request;
use Shopware\Core\Content\Product\SalesChannel\Listing\Filter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Bucket\FilterAggregation;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\MaxAggregation;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter;
use Shopware\Core\Framework\Struct\ArrayEntity;
class Subscriber implements EventSubscriberInterface
{
private $currentProperty1;
public function __construct(array $currentProperty1)
{
$this->currentProperty1 = $currentProperty1;
}
public static function getSubscribedEvents(): array
{
return [
ProductListingResultEvent::class => 'handleResult',
ProductListingCriteriaEvent::class => 'handleRequest'
];
}
public function handleResult(ProductListingResultEvent $event)
{
$properties = $event->getResult();
$this->currentProperty1 = $properties->getCurrentFilter('properties');
}
public function handleRequest(ProductListingCriteriaEvent $event): void
{
$event->getCriteria()->addAssociation('properties');
$event->getCriteria()->addAssociation('properties.group');
$currentProperty1 = $this->currentProperty1;
if (in_array('c0d02d1738fd4293a489695787e06b5c', $currentProperty1)) {
$friteria = $event->getCriteria();
$friteria->addFilter(new MultiFilter(
MultiFilter::CONNECTION_OR,
[
new ContainsFilter('product.properties.name', 'PropertyNameA'),
new ContainsFilter('product.properties.name', 'PropertyNameB')
]
)
);
}
}
}
Я могу установить и получить приватную переменную через __construct, но я не могу установить его из функции с помощью $this->:
class Subscriber implements EventSubscriberInterface
{
private $currentProperty1;
public function handleRequest(ProductListingCriteriaEvent $event): void
{
// Here to get
$array1 = array ($this->currentProperty1);
}
public function handleResult(ProductListingResultEvent $event)
{
// Here to set
$this->currentProperty1 = $currentProperty1;
}
}
--
Если $currentProperty1 в __construct, URL больше не отвечает.
Если $currentProperty1 удален из __construct, URL-адрес будет работать. Кто-нибудь знает проблему?
private $propertyGroupRepository;
private array $currentProperty1;
public function __construct(EntityRepositoryInterface $propertyGroupRepository, array $currentProperty1)
{
$this->propertyGroupRepository = $propertyGroupRepository;
$this->currentProperty1 = $currentProperty1;
}
Я пытался сделать это так и не могу заставить его работать:
class Subscriber implements EventSubscriberInterface {
public function setCurrent()
{
$array1 = array(1 => 'item 1', 2 => 'item 2');
return $array1;
}
private $currentProperty1;
public function __construct()
{
$this->currentProperty1 = new setCurrent();
}
}
Я могу получить к нему доступ из другой функции, если использовать значение типа «[]» вместо «new setCurrent()». Я использую $currentValue = array ($this->currentProperty1); в функции для этого.
Ваш вклад относительно динамически обновляемого массива был очень полезен, и теперь мой код выглядит так. Надеюсь, вы видите, что я стремлюсь изменить Критерии в зависимости от параметра Текущее выбранное свойство.
Хотя я все еще не могу получить массив в onListingCriteria
<?php // declare(strict_types=1);
namespace CustomFilterBasedOnSelectedOption\Subscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Context;
use Symfony\Component\HttpFoundation\Request;
use Shopware\Core\Content\Product\SalesChannel\Listing\Filter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Bucket\FilterAggregation;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\MaxAggregation;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter;
use Shopware\Core\Framework\Struct\ArrayEntity;
class Subscriber implements EventSubscriberInterface
{
private ?array $currentPropertyOptions = null;
public static function getSubscribedEvents(): array
{
return [
ProductListingCriteriaEvent::class => 'onListingCriteria',
ProductListingResultEvent::class => 'onListingResult'
];
}
public function onListingResult(ProductListingResultEvent $event)
{
$this->currentPropertyOptions = ['foo', 'bar', 'baz'];
/*
$properties = $event->getResult();
$currentPropertyOptions = $properties->getCurrentFilter('properties');
*/
}
public function onListingCriteria(ProductListingCriteriaEvent $event): void
{
$event->getCriteria()->addAssociation('properties');
$event->getCriteria()->addAssociation('properties.group');
$currentPropertyOptions = $this->currentPropertyOptions;
/*
if (in_array('c0d02d1738fd4293a489695787e06b5c', $currentPropertyOptions)) {
$criteria = $event->getCriteria();
$criteria->addFilter(new MultiFilter(
MultiFilter::CONNECTION_OR,
[
new ContainsFilter('product.properties.name', 'Option1'),
new ContainsFilter('product.properties.name', 'Option2')
]
)
);
}
*/
$event->getContext()->addExtension('currentPropertyOptionsCriteria', new ArrayEntity($currentPropertyOptions));
}
}






Чего вы пытаетесь достичь? Знаете ли вы, для чего использовать эти события и когда они отправляются? Что такое currenProperty? Это то, что вы получаете от объекта события?
Прежде всего, если у вас есть аргумент в конструкторе, но вы не передаете его при создании экземпляра класса, это вызовет ошибку. Такие службы, как подписчики событий, создаются с аргументами, определенными в определении службы. Это называется внедрением зависимостей. Если вы хотите установить currentProperty динамически на основе какого-либо события, вы, вероятно, не захотите устанавливать его в своем конструкторе.
Обратитесь к документации по как правильно прослушивать события.
Сначала вам нужно определение службы, именно здесь вы определяете аргументы для создания экземпляра класса. Например, если вы хотите внедрить репозиторий:
<service id = "Swag\BasicExample\Subscriber\MySubscriber">
<argument type = "service" id = "property_group_option.repository"/>
<tag name = "kernel.event_subscriber"/>
</service>
В вашем примере вы не реализовали getSubscribedEvents в своем подписчике. Без него ваш подписчик ничего не делает, так как он определяет, какой метод вызывается для какого события. На самом деле это должно вызвать ошибку, если вы не сможете реализовать метод, поскольку этого требует интерфейс. Не уверен, что вы пропустили его случайно или намеренно.
class Subscriber implements EventSubscriberInterface
{
private EntityRepository $repository;
private ?array $currentProperties = null;
public function __construct(EntityRepository $repository)
{
$this->repository = $repository;
}
public static function getSubscribedEvents(): array
{
return [
ProductListingCriteriaEvent::class => 'onListingCriteria',
ProductListingResultEvent::class => 'onListingResult',
];
}
public function onListingCriteria(ProductListingCriteriaEvent $event): void
{
$this->currentProperties = ['foo', 'bar', 'baz'];
}
public function onListingResult(ProductListingResultEvent $event): void
{
$currentProperties = $this->currentProperties;
// ...
}
}
Когда вы устанавливаете свойство для прослушивания одного события и получаете это свойство для другого события, вы также должны учитывать порядок, в котором эти события отправляются. В вашем примере вы получаете свойство на ProductListingCriteriaEvent и устанавливаете его на ProductListingResultEvent. Однако событие критерия всегда должно отправляться до события результата. Это объясняет, почему свойство всегда не инициализируется, когда вы пытаетесь его получить, так как оно еще не установлено. Ознакомьтесь с существующими событиями и выберите их в соответствии с вашими потребностями.
Объяснение остается в силе. Вы не можете установить свойство в конструкторе из аргумента, если вы не предоставите аргумент в определении службы. Откуда должно взяться array $currentProperty1? Каким должно быть его значение? Также, как объяснялось выше, ProductListingResultEvent отправляется в стеке позже, чем ProductListingCriteriaEvent. Вы устанавливаете его после того, как пытаетесь его использовать.
Предполагается, что массив $currentProperty1 исходит из public function handleResult(ProductListingResultEvent $event) У меня также есть public function handleRequest(ProductListingCriteriaEvent $event) позже (после handleResult) в моем текущем коде
Спасибо за быстрый ответ @dneustadt. Я не использую репозиторий. Я стремлюсь добавить фильтр к существующим критериям в зависимости от выбранных параметров текущего фильтра. Я поместил свою идею кода поверх моего ввода. Все работает, просто не могу заставить обмениваться массивами между handleResult и handleRequest, поэтому ставлю $currentProperty1.