<?php declare(strict_types=1);
/**
* gb media
* All Rights Reserved.
*
* Unauthorized copying of this file, via any medium is strictly prohibited.
* The content of this file is proprietary and confidential.
*
* @category Shopware
* @package Shopware_Plugins
* @subpackage GbmedEnev
* @copyright Copyright (c) 2019, gb media
* @license proprietary
* @author Giuseppe Bottino
* @link http://www.gb-media.biz
*/
namespace Gbmed\Enev\Service;
use Gbmed\Enev\Core\Content\Enev\EnevCollection;
use Gbmed\Enev\Core\Content\Enev\EnevEntity;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\Api\Response\Type\Api\JsonApiType;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
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\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\RequestCriteriaBuilder;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\Request;
class Product
{
/** @var EntityRepositoryInterface */
private $gbmedEnevRepository;
/** @var EntityRepositoryInterface */
private $productRepository;
/** @var RequestCriteriaBuilder */
private $searchCriteriaBuilder;
private JsonApiType $responseFactory;
private Eprel $serviceEprel;
/**
* Product constructor.
*
* @param EntityRepositoryInterface $gbmedEnevRepository
* @param EntityRepositoryInterface $productRepository
* @param RequestCriteriaBuilder $searchCriteriaBuilder
* @param JsonApiType $responseFactory
* @param Eprel $serviceEprel
*/
public function __construct(
EntityRepositoryInterface $gbmedEnevRepository,
EntityRepositoryInterface $productRepository,
RequestCriteriaBuilder $searchCriteriaBuilder,
JsonApiType $responseFactory,
Eprel $serviceEprel
) {
$this->gbmedEnevRepository = $gbmedEnevRepository;
$this->productRepository = $productRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->responseFactory = $responseFactory;
$this->serviceEprel = $serviceEprel;
}
/**
* find products ex gbmedEnev products
*
* @param Request $request
* @param Context $context
*
* @return EntitySearchResult
* @throws InconsistentCriteriaIdsException
*/
public function products(Request $request, Context $context): EntitySearchResult
{
$products = $this->enevProducts($context);
$criteria = new Criteria();
$criteria = $this->searchCriteriaBuilder->handleRequest(
$request,
$criteria,
$this->productRepository->getDefinition(),
$context
);
if (count($products)) {
$criteria->addFilter(new NotFilter(NotFilter::CONNECTION_AND,
[new EqualsAnyFilter('product.id', $products)]));
}
return $this->productRepository->search($criteria, $context);
}
/**
* get product IDs from EnEV
*
* @param Context $context
*
* @return array
* @throws InconsistentCriteriaIdsException
*/
public function enevProducts(Context $context): array
{
$enevs = $this->gbmedEnevRepository->search(new Criteria(), $context);
$products = [];
/**
* @var EnevCollection $enev
*/
foreach ($enevs->getElements() as $index => $enev) {
$products[] = $enev->get('product')->getId();
}
return $products;
}
/**
* find enev by product
*
* @param $productId
* @param Context $context
* @param bool $activeOnly
* @return EntitySearchResult
* @throws InconsistentCriteriaIdsException
*/
public function findEnevByProductId(
$productId,
Context $context,
$activeOnly = true
): EntitySearchResult {
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('gbmed_enev.productId', $productId))
->addSorting(new FieldSorting('position'))
->addAssociation('media')
->addAssociation('datasheet')
->addAssociation('icon');
if ($activeOnly) {
$criteria->addFilter(new EqualsFilter('gbmed_enev.active', true));
}
return $this->gbmedEnevRepository->search($criteria, $context);
}
/**
* @param $productId
* @param Context $context
* @return ProductEntity|null
*/
public function findProductById(
$productId,
Context $context
) {
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $productId));
return $this->productRepository->search($criteria, $context)->first();
}
/**
* @param $productNumber
* @param Context $context
* @return ProductEntity|null
*/
public function findProductByNumber(
$productNumber,
Context $context
) {
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('productNumber', $productNumber));
return $this->productRepository->search($criteria, $context)->first();
}
/**
* add EPREL data
*
* @param EntityCollection $result
* @param SalesChannelContext $salesChannelContext
* @return EntityCollection
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function prepareEprel(EntityCollection $result, SalesChannelContext $salesChannelContext): EntityCollection
{
/** @var \Gbmed\Enev\Core\Content\Enev\EnevEntity $element */
foreach ($result->getElements() as $element) {
$this->setElementEprelData($element);
if (!$element->getEprelGroup() || !$element->getEprelId()) {
continue;
}
try {
if ($eprelData = $this->serviceEprel->getEprelDataFromElement($element)) {
$this->setElementEprelData(
$element,
$this->serviceEprel->getGbmedEnev($eprelData, $salesChannelContext)
);
}
} catch (\Exception $e) {
}
}
return $result;
}
/**
* @param EnevEntity $element
* @param array|null $data
*/
private function setElementEprelData(EnevEntity $element, ?array $data = null)
{
if (is_callable([$element, '__set'])) {
$element->__set('eprelData', $data);
} else {
$element->eprelData = $data;
}
}
/**
* @return EntityRepositoryInterface
*/
public function getGbmedEnevRepository(): EntityRepositoryInterface
{
return $this->gbmedEnevRepository;
}
/**
* @return EntityRepositoryInterface
*/
public function getProductRepository(): EntityRepositoryInterface
{
return $this->productRepository;
}
/**
* @return RequestCriteriaBuilder
*/
public function getSearchCriteriaBuilder(): RequestCriteriaBuilder
{
return $this->searchCriteriaBuilder;
}
}