<?php declare(strict_types=1);
namespace Ctnm\FrontendHelper\Subscriber;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
//use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Core\Framework\Struct\ArrayEntity;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Product\Events\ProductSearchResultEvent;
use Shopware\Storefront\Page\Navigation\NavigationPageLoadedEvent;
use Shopware\Core\Content\Category\Tree\Tree;
use Shopware\Core\Content\Cms\SalesChannel\Struct\TextStruct;
class Frontend implements EventSubscriberInterface
{
protected function getSeoUrls()
{
return "test";
}
/** @var ProductEntity */
protected $productRepository;
protected $standardProductRepository;
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class=> 'onProductLoaded',
ProductListingResultEvent::class => 'handleResult',
ProductSearchResultEvent::class => 'handleResult',
NavigationPageLoadedEvent::class=> 'onNavigationLoaded',
];
}
public function __construct(
SalesChannelRepositoryInterface $productRepository,
EntityRepositoryInterface $standardProductRepository
)
{
$this->productRepository = $productRepository;
$this->standardProductRepository = $standardProductRepository;
}
public function onProductLoaded(ProductPageLoadedEvent $event)
{
$page = $event->getPage();
$product = $page->getProduct();
$parentId = $product->getParentId();
//If no parentId -> no variant, early return
if(!$parentId) {
return;
}
$defaultContext = Context::createDefaultContext();
$criteria4Parent = new Criteria;
$criteria4Parent->addFilter(new EqualsFilter('id', $parentId));
$productSearchResult = $this->standardProductRepository->search($criteria4Parent, $defaultContext);
if ( $productSearchResult instanceof EntitySearchResult ) {
$productResults = $productSearchResult->getElements();
if ( is_array($productResults) && count($productResults) == 1 ) {
$productParent = current($productResults);
}
}
$sorting = new FieldSorting('productNumber', 'ASC');
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('parentId', $parentId));
// $criteria->addAssociation('options.group');
$criteria->addAssociation('properties.group');
// $criteria->addAssociation('categories ');
// $criteria->addAssociation('media.cover');
$criteria->addSorting($sorting);
$variantProducts = $this->productRepository->search($criteria, $event->getSalesChannelContext());
//Only add extension when there is more than 1 variant
if($variantProducts->getTotal() > 1) {
$availableGroups = array();
$allVariantsProperties = array();
$productVariants = $variantProducts->getEntities()->getElements();
if ( is_array($productVariants)) {
foreach ($productVariants as $variant) {
if ( is_object($variant) ) {
if ( !isset($allVariantsProperties[$variant->getId()]) ) {
$allVariantsProperties[$variant->getId()] = array('properties'=>array());
}
if ( $variant->getName() != '' ) {
$allVariantsProperties[$variant->getId()]['name'] = $variant->getName();
}
else {
$allVariantsProperties[$variant->getId()]['name'] = $productParent->getName();
}
$allVariantsProperties[$variant->getId()]['product_number'] = $variant->getProductNumber();
$variantProperties = $variant->getProperties();
//var_dump($variantProperties);
if ( is_object($variantProperties) ) {
$variantPropertiesOptions = $variantProperties->getElements();
//$x = $variantProperties->getPosition();
if ( is_array($variantPropertiesOptions) ) {
foreach ($variantPropertiesOptions as $propOpt) {
//echo $propOpt->getName()."<br>";
$propGroup = $propOpt->getGroup();
//var_dump($propGroup);
//echo $propGroup->getPosition()."<br>";
if ( is_object($propGroup) ) {
if ( !isset($availableGroups[$propGroup->getId()]) ) {
$availableGroups[$propGroup->getId()] = array();
}
$availableGroups[$propGroup->getId()]['name'] = $propGroup->getName();
$availableGroups[$propGroup->getId()]['position'] = $propGroup->getPosition();
$allVariantsProperties[$variant->getId()]['properties'][$propGroup->getId()] = $propOpt->getName();
}
}
}
}
}
}
}
//echo '<div style="display:none">';
//print_r($availableGroups);
//print_r($allVariantsProperties);
//echo '</div>';
uasort($availableGroups, function($a, $b){
if ($a['position'] == $b['position']) {
return 0;
}
return ($a['position'] < $b['position']) ? -1 : 1;
});
$ctnmFrontendHelperVariantsProperties = array(
'table_header' => $availableGroups,
'table_content' => $allVariantsProperties,
);
//print_r($productVariants->getElements());
$page->addExtension('CtnmFrontendHelperVariantsProperties', new ArrayEntity($ctnmFrontendHelperVariantsProperties));
$page->addExtension('CtnmFrontendHelperVariants', $variantProducts);
}
}
public function handleResult(ProductListingResultEvent $event)
{
$ids = $event->getResult()->getEntities()->getIds();
$context = Context::createDefaultContext();
if ( is_array($ids) ) {
foreach ($ids as $productId) {
$product = $event->getResult()->getEntities()->get($productId);
if ( !$product instanceof SalesChannelProductEntity ) {
continue;
}
//print_r($product);
$productParentId = $product->getParentId();
if ( $productParentId ) {
//$productParent = $event->getResult()->getEntities()->get($productParentId);
$criteria = new Criteria;
$criteria->addFilter(new EqualsFilter('id', $productParentId));
$productSearchResult = $this->standardProductRepository->search($criteria, $context);
if ( !$productSearchResult instanceof EntitySearchResult ) {
continue;
}
$productResults = $productSearchResult->getElements();
if ( !is_array($productResults) ) {
continue;
}
else {
if ( count($productResults) != 1 ) {
continue;
}
}
$productParent = current($productResults);
//echo "parent id: $productParentId<br>";
/*echo "<pre>";
print_r($productParent);
echo "</pre>";*/
if ( !$productParent instanceof ProductEntity ) {
continue;
}
//echo $productParent->getName()."<br>";
$extension = new TextStruct();
$extension->setContent($productParent->getName());
$product->addExtension('parentProductName', $extension);
}
}
}
/*$resultEntities = $event->getResult()->getEntities();
$productsParentNames = array();
if ( is_object($resultEntities) ) {
$parentIds = $resultEntities->getParentIds();
if ( is_array($parentIds) ) {
foreach ($parentIds as $productId => $parentId) {
//echo $this->getParentName($event, $parentId)."<br>";
$productsParentNames[$productId] = $this->getParentName($event, $parentId);
}
}
}*/
//$page->addExtension('CtnmHeader', $header);
}
protected function getParentName(&$event, $parentId)
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $parentId));
$criteria->addAssociation('properties.group');
$resultProducts = $this->productRepository->search($criteria, $event->getSalesChannelContext());
$resultSingleProduct = $resultProducts->first();
if ( is_object($resultSingleProduct) ) {
return $resultSingleProduct->getName();
}
/*echo "<pre>";
print_r($resultProducts->first());
echo "</pre>";*/
return false;
}
public function onNavigationLoaded(NavigationPageLoadedEvent $event)
{
$page = $event->getPage();
$header = $page->getHeader();
$navigation = $header->getNavigation();
$context = Context::createDefaultContext();
$treeWith2Levels = array();
$treeWith2Levels2 = array();
//$tmpTreeArr = array();
if ( is_object($navigation) ) {
$catTree = $navigation->getTree();
//var_dump($catTree);
$activeCategoryEntity = $navigation->getActive();
$activeTreeItem = $this->find($activeCategoryEntity->getId(), $catTree);
if ( is_object($activeTreeItem) ) {
$treeItemChildren = $activeTreeItem->getChildren();
if ( is_array($treeItemChildren) ) {
foreach ($treeItemChildren as $treeItemChild) {
$childCategory = $treeItemChild->getCategory();
$treeItemChildChildren = $treeItemChild->getChildren();
if ( !isset($treeWith2Levels2[$childCategory->getId()]) ) {
$treeWith2Levels2[$childCategory->getId()] = array();
}
$treeWith2Levels2[$childCategory->getId()]['name'] = $childCategory->getTranslation('name');
//echo $childCategory->getName()."<br>";
$treeWith2Levels2[$childCategory->getId()]['class'] = $childCategory;
if ( isset($treeItemChildChildren) && is_array($treeItemChildChildren) && count($treeItemChildChildren) > 0) {
/*if ( !isset($treeWith2Levels2[$childCategory->getId()]['children']) ) {
$treeWith2Levels2[$childCategory->getId()]['children'] = array();
}*/
$treeWith2Levels2[$childCategory->getId()]['children'] = $treeItemChildChildren;
/*foreach ($treeItemChildChildren as $treeItemChild2) {
$childCategory2 = $treeItemChild2->getCategory();
//echo "<b>".$childCategory2->getName()."</b><br>";
}*/
}
}
}
}
}
//$page->addExtension('CtnmHeader', $navigation);
//$page->addExtension('CtnmHeader', new ArrayEntity($tmpTreeArr));
//$page->addExtension('CtnmHeader', new ArrayEntity($treeWith2Levels));
$page->addExtension('CtnmHeader', new ArrayEntity($treeWith2Levels2));
//$page->addExtension('CtnmHeader2', new ArrayEntity($treeWith2Levels2));
//$page->addExtension('CtnmHeader2', new ArrayEntity($cname));
/*$page->addExtension('CtnmHeader', new ArrayEntity(array(
'active' => $activeCategoryEntity,
'count' => $activeCategoryEntity->getChildCount(),
'children' => $activeCategoryEntity->getChildren(),
)));*/
}
private function find(string $categoryId, array $tree)
{
if (isset($tree[$categoryId])) {
return $tree[$categoryId];
}
foreach ($tree as $item) {
$nested = $this->find($categoryId, $item->getChildren());
if ($nested) {
return $nested;
}
}
return null;
}
}