<?php declare(strict_types=1);
namespace H1web\Blog\Blog\Cms;
use H1web\Blog\Blog\Events\BlogListingResultEvent;
use H1web\Blog\Blog\Listing\BlogListingFeaturesSubscriber;
use H1web\Blog\Blog\Listing\BlogListingGateway;
use H1web\Blog\Blog\Listing\BlogListingResult;
use H1web\Blog\Blog\SalesChannel\BlogAvailableFilter;
use H1web\Blog\Blog\SalesChannel\SalesChannelBlogDefinition;
use H1web\Blog\Blog\Struct\BlogListingStruct;
use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
use Shopware\Core\Content\Cms\DataResolver\CriteriaCollection;
use Shopware\Core\Content\Cms\DataResolver\Element\AbstractCmsElementResolver;
use Shopware\Core\Content\Cms\DataResolver\Element\ElementDataCollection;
use Shopware\Core\Content\Cms\DataResolver\ResolverContext\ResolverContext;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Bucket\TermsAggregation;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class BlogListingCmsElementResolver extends AbstractCmsElementResolver
{
/**
* @var BlogListingGateway
*/
private $listingGateway;
/**
* @var BlogListingFeaturesSubscriber
*/
private $listingSubscriber;
/**
* @var EventDispatcherInterface
*/
private $dispatcher;
public function __construct(BlogListingGateway $listingGateway, BlogListingFeaturesSubscriber $listingSubscriber, EventDispatcherInterface $dispatcher)
{
$this->listingGateway = $listingGateway;
$this->listingSubscriber = $listingSubscriber;
$this->dispatcher = $dispatcher;
}
public function getType(): string
{
return 'h1webblog-listing';
}
public function collect(CmsSlotEntity $slot, ResolverContext $resolverContext): ?CriteriaCollection
{
$config = $slot->getFieldConfig();
$onlyRecentConfig = $config->get('onlyRecent');
$filterTagsConfig = $config->get('filterTags');
if (
(!$filterTagsConfig || empty($filterTagsConfig->getValue()))
&& (!$onlyRecentConfig || intval($onlyRecentConfig->getValue()) === 0)
) {
return null;
}
$criteria = new Criteria();
$criteria->addFilter(new BlogAvailableFilter($resolverContext->getSalesChannelContext()->getSalesChannelId()))
->addAssociation('tags')
->addAssociation('properties')
->addAssociation('options')
->addAssociation('visibilities')
->addSorting(new FieldSorting('publishedAt', FieldSorting::DESCENDING));
$criteria->addAggregation(new TermsAggregation('properties', 'h1webblog_blog.properties.id'));
$criteria->addAggregation(new TermsAggregation('options', 'h1webblog_blog.options.id'));
if (intval($onlyRecentConfig->getValue()) !== 0) {
$criteria->setLimit(intval($onlyRecentConfig->getValue()));
}
if (!$criteria->getLimit()) {
$criteria->setLimit($this->listingSubscriber->getDefaultPageSize());
}
if ($filterTagsConfig && !empty($filterTagsConfig->getValue())) {
$criteria->addFilter(new EqualsAnyFilter('tagIds', $filterTagsConfig->getValue()));
}
$criteriaCollection = new CriteriaCollection();
$criteriaCollection->add('blog_slot_' . $slot->getUniqueIdentifier(), SalesChannelBlogDefinition::class, $criteria);
return $criteriaCollection;
}
public function enrich(CmsSlotEntity $slot, ResolverContext $resolverContext, ElementDataCollection $result): void
{
$data = new BlogListingStruct();
$slot->setData($data);
/** @var EntitySearchResult|null $searchResult */
$searchResult = $result->get('blog_slot_' . $slot->getUniqueIdentifier());
if ($searchResult) {
$this->dispatchListingEvent($resolverContext, $searchResult);
}
$listing = $searchResult ??
$this->listingGateway->search($resolverContext->getRequest(), $resolverContext->getSalesChannelContext());
$data->setListing($listing);
}
private function dispatchListingEvent(ResolverContext $resolverContext, EntitySearchResult $result): void
{
$this->dispatcher->dispatch(
new BlogListingResultEvent(
$resolverContext->getRequest(),
BlogListingResult::createFrom($result),
$resolverContext->getSalesChannelContext()
)
);
}
}