<?php declare(strict_types=1);
namespace Ecd\econdCrossSelll\Storefront\Controller;
use Shopware\Core\Content\Product\Exception\ProductNotFoundException;
use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Controller\StorefrontController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
class econdCrossSellController extends StorefrontController
{
public const QUICKVIEW_ROUTE = 'frontend.cms.crosssell';
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var SalesChannelRepositoryInterface
*/
private $productRepository;
/**
* econdCrossSelll constructor.
* @param SalesChannelRepositoryInterface $productRepository
* @param SystemConfigService $systemConfigService
*/
public function __construct(
SystemConfigService $systemConfigService,
SalesChannelRepositoryInterface $productRepository
)
{
$this->systemConfigService = $systemConfigService;
$this->productRepository = $productRepository;
}
/**
* @RouteScope(scopes={"storefront"})
* @Route("/econdacrosssell/", name="frontend.cms.crosssell", options={"seo"=true}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
* @return JsonResponse
*/
public function index(SalesChannelContext $context, Request $request) : Response
{
$ec_datas = (array)json_decode(base64_decode($request->get('ec_data')));
$cs_responses = [];
foreach ($ec_datas as $key => $ec_data) {
$contextPid = 'na';
$ec_data = (array)$ec_data;
$econdaRecoParams = (array)$ec_data["econdaRecoParams"];
$location = $ec_data['location'];
$econdaRecoParams['categoryPath'] = $this->createCategoryPath($ec_data['categories']);
if(isset($ec_data['productid']) && $ec_data['productid'] != "") {
$econdaRecoParams['productid'] = $ec_data['productid'];
$contextPid = $ec_data['productid'];
}
$items = $this->sendRequestToCrossSell($econdaRecoParams);
if ($items !== false) {
$wid = $econdaRecoParams["wid"];
$products = $this->loadProducts($items['items'], $context);
$emcsParams = $this->generateEmcsParams($location, $products, $wid,$contextPid, $items['items']);
$cs_responses['widgetDetails'] = $items['widgetdetails'];
$cs_responses['csConfig'] = (array)json_decode(base64_decode($ec_data['csConfig']));
$cs_responses['elementType'] = $ec_data['elementType'];
$cs_responses['products'] = $products;
$cs_responses['emcsParams'] = $emcsParams;
return $this->renderStorefront('@Storefront/storefront/block/cms-block-econda-cross-sell.html.twig', [
'cs_response' => $cs_responses,
'ecFlag' => 'true',
'ecmsParams' => $emcsParams
]);
}else {
$cs_responses['failure'] = false;
return $this->renderStorefront('@Storefront/storefront/block/cms-block-econda-cross-sell.html.twig', [
'cs_response' => $cs_responses,
'ecFlag' => 'true'
]);
}
}
}
public function createCategoryPath($categories)
{
$categories = (array)json_decode($categories);
$categoryPath = '';
$lastCategory = end($categories);
foreach ($categories as $category) {
if ($lastCategory !== $category) {
$categoryPath .= $category . '^^';
}else {
$categoryPath .= $category;
}
}
return $categoryPath;
}
/**
* Prepares the URL and sends a server side GET request to the CrossSell servers and returns the response as an array
*
* @param $params - values from js sdk
* @return array
*/
public function sendRequestToCrossSell($params)
{
if (!array_key_exists('aid', $params)) {
return false;
}
$urlParams = '';
$url = 'http://widgets.crosssell.info/eps/crosssell/recommendations/' . $params['aid'] . '.do?';
foreach ($params as $key => $param) {
if ($key == 'data' ||
$key == 'currentUrl' ||
$key == 'timestamp' ||
$key == 'csConfig' ||
$key == 'elementType') {
continue;
}
if (is_array($param) && empty($param)) {
continue;
}
if ($key == 'widgetdetails') {
$urlParams .= $key . '=true&';
continue;
}
if($key == 'categoryPath') {
$urlParams .= 'ctxcat.ct=productcategory&ctxcat.pas=' . urlencode($param) . '&ctxcat.pdl=%5E%5E&';
continue;
}
if($key == 'productid' && $param != "") {
$urlParams .= 'pid=sku%3A' . urlencode($param) . '&';
continue;
} elseif($key == 'productid') {
continue;
}
$urlParams .= $key . '=' . urlencode(strval($param)) . '&';
}
$urlParams .= 'timestamp=' . urlencode(strval($params['timestamp']));
$url .= $urlParams;
if(strpos($_SERVER["HTTP_REFERER"],"ec_csdebug=true") ) {
echo '<p hidden class="csdebug">' . urldecode($url) . '</p>';
echo '<p hidden class="csdebug">' . $url . '</p>';
}
$json = file_get_contents($url);
return (array)json_decode($json);
}
public function loadProducts($items, SalesChannelContext $context)
{
$productIds = [];
foreach($items as $item) {
if (isset($item->uuid)) {
array_push($productIds, $item->uuid);
}
else if (isset($item -> id)) {
array_push($productIds, $item->id);
}
}
$products = $this->productRepository->search(
(new Criteria( $productIds)), $context);
return $products->getEntities()->getElements();
}
/**
* @param $location string
* @param $products array
*/
public function generateEmcsParams($location, $products, $wid, $contextPid, $items)
{
$ecmsParams = [];
if($location === '/') {
$location = 'Startseite';
}
/**
* @var $product SalesChannelProductEntity
*/
foreach ($products as $product){
$emcs3 = $this->getEcPid($product, $items);
$ecmsParams[$product->getId()] =
'?emcs0=' . $wid .
'&emcs1=' . $location .
'&emcs2=' . $contextPid .
'&emcs3=' . $emcs3;
}
return $ecmsParams;
}
public function getEcPid($product, $items) {
foreach($items as $item) {
if ($item->id == $product->getId()) {
if (isset($item->pid) && $item->pid != "") {
return $item->pid;
} else {
return $product->getProductNumber();
}
}
}
}
}