<?php
/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Enterprise License (PEL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PEL
*/
namespace App\Controller;
use App\Model\Product\Book;
use App\Model\Product\Category;
use App\Services\TMSService;
use Pimcore\Model\DataObject\Discipline;
use App\Model\Product\Course;
use App\Model\Product\Module;
use App\Services\SegmentTrackingHelperService;
use App\Website\LinkGenerator\ProductLinkGenerator;
use App\Website\Navigation\BreadcrumbHelperService;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Knp\Component\Pager\PaginatorInterface;
use Pimcore\Bundle\EcommerceFrameworkBundle\Factory;
use Pimcore\Bundle\EcommerceFrameworkBundle\FilterService\ListHelper;
use Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\ProductList\DefaultMysql;
use Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\ProductList\ElasticSearch\AbstractElasticSearch;
use Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\ProductList\ProductListInterface;
use Pimcore\Config;
use Pimcore\Model\DataObject\AbstractObject;
use Pimcore\Model\DataObject\Concrete;
use Pimcore\Model\DataObject\Data\UrlSlug;
use Pimcore\Model\DataObject\FilterDefinition;
use Pimcore\Model\DataObject\SuperCategory;
use Pimcore\Model\Document;
use Pimcore\Translation\Translator;
use Pimcore\Twig\Extension\Templating\HeadTitle;
use Pimcore\Twig\Extension\Templating\Placeholder;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
class ProductController extends BaseController
{
/**
* @param Request $request
* @param AbstractObject $object
* @param UrlSlug $t
* @return Response
*/
public function productDetailSlugAction(Request $request, AbstractObject $object, UrlSlug $urlSlug)
{
return $this->forward('App\Controller\ProductController::detailAction', ['product' => $object]);
}
/**
* @param Request $request
* @param AbstractObject $object
* @param UrlSlug $urlSlug
* @return Response
*/
public function disciplineListingSlugAction(Request $request, AbstractObject $object, UrlSlug $urlSlug)
{
return $this->forward('App\Controller\ProductController::listingAction', ['category' => $object, 'query' => $request->query->all(), 'singleDiscipline' => true]);
}
/**
* @Route("/training/{path}{productname}~p{product}", name="shop-detail", defaults={"path"=""}, requirements={"path"=".*?", "productname"="[\w-]+", "product"="\d+"})
*
* @param Request $request
* @param HeadTitle $headTitleHelper
* @param BreadcrumbHelperService $breadcrumbHelperService
* @param Factory $ecommerceFactory
* @param SegmentTrackingHelperService $segmentTrackingHelperService
* @param Concrete $product built-in parameter conversion, please see https://github.com/pimcore/pimcore/pull/5554
* @param ProductLinkGenerator $productLinkGenerator
*
* @return Response
*
* @throws \Exception
*/
public function detailAction(
Request $request,
HeadTitle $headTitleHelper,
BreadcrumbHelperService $breadcrumbHelperService,
Factory $ecommerceFactory,
SegmentTrackingHelperService $segmentTrackingHelperService,
Concrete $product,
ProductLinkGenerator $productLinkGenerator,
TMSService $tmsService
) {
if (!($product && ($product->isPublished() && ($product instanceof Book || $product instanceof Module || $product instanceof Course) || $this->verifyPreviewRequest($request, $product)))) {
throw new NotFoundHttpException('Product not found.');
}
//redirect to main url
$generatorUrl = $productLinkGenerator->generate($product);
if ($generatorUrl != $request->getPathInfo()) {
$queryString = $request->getQueryString();
return $this->redirect($generatorUrl . ($queryString ? '?' . $queryString : ''));
}
// $breadcrumbHelperService->enrichProductDetailPage($product);
$headTitleHelper($product->getOSName());
$paramBag = $this->getAllParameters($request);
$paramBag['product'] = $product;
/* commmented temporarily
//track segments for personalization
*/
if ($product instanceof Book) {
return $this->render('product/detail_book.html.twig', $paramBag);
} else if ($product instanceof Module) {
return $this->render('product/detail_module.html.twig', $paramBag);
} else if ($product instanceof Course) {
// $params
$paramBag['sessions'] = $this->getCourseSessions($product->getCourseID()); //$tmsService->courseSessions($product->getCourseID());
return $this->render('product/detail_course.html.twig', $paramBag);
}
}
/**
* @Route("/training/{path}{categoryname}~c{category}", name="shop-category", defaults={"path"=""}, requirements={"path"=".*?", "categoryname"="[\w-]+", "category"="\d+"})
*
* @param Request $request
* @param HeadTitle $headTitleHelper
* @param BreadcrumbHelperService $breadcrumbHelperService
* @param Factory $ecommerceFactory
* @param SegmentTrackingHelperService $segmentTrackingHelperService
* @param ListHelper $listHelper
*
* @return Response
*/
public function listingAction(Request $request, HeadTitle $headTitleHelper, BreadcrumbHelperService $breadcrumbHelperService, Factory $ecommerceFactory, SegmentTrackingHelperService $segmentTrackingHelperService, ListHelper $listHelper, PaginatorInterface $paginator, Document $document, array $query = [])
{
$params = array_merge($request->query->all(), $request->attributes->all(), $query);
$params['singleDiscipline'] = isset($params['singleDiscipline']) ? true : false;
$params['sorting'] = isset($params['sorting']) ? true : false;
if ($params['singleDiscipline'] === false) {
$superCategoryList = new \Pimcore\Model\DataObject\SuperCategory\Listing();
$superCategoryList->setOrderKey('categoryName');
$superCategories = $superCategoryList->load();
$i = 0;
$superCatdata = [];
foreach ($superCategories as $superCat) {
$disciplinesList = new \Pimcore\Model\DataObject\Discipline\Listing();
$disciplinesList->setCondition("superCategory like '%" . $superCat->getId() . ",%'");
$superCatId = "k_" . $superCat->getId();
foreach ($disciplinesList as $discipline) {
$superCatdata[$superCatId][] = $discipline->getId();
}
$i++;
}
$params['superCatJs'] = $superCatdata;
}
$disciplineId = NULL;
$category = NULL;
//needed to make sure category filter filters for active category
$params['parentCategoryIds'] = $params['category'] ?? null;
/*
if(isset($params['category'])) {
$category = Discipline::getById($params['category'] ?? null);
$params['category'] = $category;
}else if(isset($params['category-slug'])) {
*/
if (isset($params['category'])) {
$category = Discipline::getById($params['category']->getId() ?? null);
$disciplineId = $params['category']->getId();
$params['category'] = $category;
}
if ($category) {
$headTitleHelper($category->getDisciplineName());
// $breadcrumbHelperService->enrichCategoryPage($category);
}
//setting assortment tenant
$environment = $ecommerceFactory->getEnvironment();
$environment->setCurrentAssortmentTenant("training");
$indexService = $ecommerceFactory->getIndexService();
$productListing = $indexService->getProductListForCurrentTenant();
$productListing->setVariantMode(ProductListInterface::VARIANT_MODE_INCLUDE);
$params['sortingType'] = isset($request->attributes->all()['query']['sorting']) ? $request->attributes->all()['query']['sorting']: null;
if ($params['sorting']) {
if ($request->get('sorting') == 'title_asc' || $params['sortingType'] == 'title_asc') {
$productListing->setOrderKey("name");
$productListing->setOrder("asc");
}
if ($request->get('sorting') == 'title_desc' || $params['sortingType'] == 'title_desc') {
$productListing->setOrderKey("name");
$productListing->setOrder("desc");
}
if ($request->get('sorting') == 'discipline_asc' || $params['sortingType'] == 'discipline_asc') {
$productListing->setOrderKey("primary_discipline_name");
$productListing->setOrder("asc");
}
if ($request->get('sorting') == 'discipline_desc' || $params['sortingType'] == 'discipline_desc') {
$productListing->setOrderKey("primary_discipline_name");
$productListing->setOrder("desc");
}
} else {
$productListing->setOrderKey("name");
$productListing->setOrder("asc");
}
$params['productListing'] = $productListing;
// load current filter
if ($category) {
$filterDefinition = $category->getFilterdefinition();
//track segments for personalization
/*$segmentTrackingHelperService->trackSegmentsForCategory($category);
$trackingManager = $ecommerceFactory->getTrackingManager();
$trackingManager->trackCategoryPageView($category->getName(), null);
*/
}
if ($request->get('filterdefinition') instanceof FilterDefinition) {
$filterDefinition = $request->get('filterdefinition');
}else if($document->getProperty('filter_definition')){
$filterDefinition = $document->getProperty('filter_definition');
}
if (empty($filterDefinition)) {
$filterDefinition = Config::getWebsiteConfig()->get('fallbackFilterdefinition');
}
$filterService = $ecommerceFactory->getFilterService();
$listHelper->setupProductList($filterDefinition, $productListing, $params, $filterService, true);
$params['filterService'] = $filterService;
$params['filterDefinition'] = $filterDefinition;
/** @var SlidingPagination $paginator */
// init pagination
$paginator = $paginator->paginate(
$productListing,
$page = $request->get('page') ? $request->get('page', 1) : (isset($params['page']) ? $params['page'] : 1),
$filterDefinition->getPageLimit()
);
$params['results'] = $paginator;
$params['paginationVariables'] = $paginator->getPaginationData();
$params['showFilters'] = true;
if ($request->attributes->get('noLayout')) {
return $this->render('product/listing_content.html.twig', $params);
}
// track product impressions
$trackingManager = $ecommerceFactory->getTrackingManager();
foreach ($paginator as $product) {
// $trackingManager->trackProductImpression($product, 'grid');
}
return $this->render('product/listing.html.twig', $params);
}
/**
* @Route("/training/scheduled", name="shop-scheduled-category", defaults={"path"=""}, requirements={"path"=".*?", "categoryname"="[\w-]+", "category"="\d+"})
*
* @param Request $request
* @param HeadTitle $headTitleHelper
* @param BreadcrumbHelperService $breadcrumbHelperService
* @param Factory $ecommerceFactory
* @param SegmentTrackingHelperService $segmentTrackingHelperService
* @param ListHelper $listHelper
*
* @return Response
*/
public function listingScheduledAction(Request $request)
{
return $this->render('product/scheduled.html.twig');
}
/**
* @param Request $request
* @param Factory $ecommerceFactory
*
* @return Response
*/
public function productTeaserAction(Request $request, Factory $ecommerceFactory)
{
$paramsBag = [];
if ($request->get('type') == 'object') {
AbstractObject::setGetInheritedValues(true);
$product = AbstractProduct::getById($request->get('id'));
$paramsBag['product'] = $product;
//track product impression
$trackingManager = $ecommerceFactory->getTrackingManager();
$trackingManager->trackProductImpression($product, 'teaser');
return $this->render('product/product_teaser.html.twig', $paramsBag);
}
throw new NotFoundHttpException('Product not found.');
}
/**
* @Route("/search", name="search")
*
* @param Request $request
* @param ListHelper $listHelper
* @param Factory $ecommerceFactory
* @param ProductLinkGenerator $productLinkGenerator
* @param Translator $translator
* @param BreadcrumbHelperService $breadcrumbHelperService
* @param HeadTitle $headTitleHelper
* @param Placeholder $placeholder
*
* @return Response|JsonResponse
*/
public function searchAction(Request $request, ListHelper $listHelper, Factory $ecommerceFactory, ProductLinkGenerator $productLinkGenerator, Translator $translator, BreadcrumbHelperService $breadcrumbHelperService, HeadTitle $headTitleHelper, Placeholder $placeholder, PaginatorInterface $paginator)
{
// dummy results for api
return new JsonResponse(['items' => [
[
'id' => 2910,
'title' => 'Advanced Decision Analysis with Portfolio and Project Modeling - ADA',
'type' => 'Course',
'link' => 'https://petrox1.pimcore.dev/en/training/courses/advanced-decision-analysis-with-portfolio-and-project-modeling---ada~p2910'
],
[
'id' => 1168,
'title' => 'Applied Water Technology',
'type' => 'Book',
'link' => 'https://petrox1.pimcore.dev/en/training/books/applied-water-technology~p1168'
],
[
'id' => 2500,
'title' => 'Amplitude vs Offset Core',
'type' => 'Module',
'link' => 'https://petrox1.pimcore.dev/en/training/modules/amplitude-vs-offset-core~p2500'
]
]]);
$params = $request->query->all();
$environment = $ecommerceFactory->getEnvironment();
$environment->setCurrentAssortmentTenant("ElasticSearch");
$list = \Pimcore\Bundle\EcommerceFrameworkBundle\Factory::getInstance()->getIndexService()->getProductListForCurrentTenant();
// $list->addCondition("OSName = 'acid'", 'name');
// $list->addRelationCondition('category', "dest IN (1024,1025,1026)");
// $list->setOrder("ASC");
// $list->setOrderKey('name');
$list->load();
$indexService = $ecommerceFactory->getIndexService();
$productListing = $indexService->getProductListForCurrentTenant();
$productListing->setVariantMode(ProductListInterface::VARIANT_MODE_VARIANTS_ONLY);
$term = strip_tags($request->get('term'));
if ($productListing instanceof AbstractElasticSearch) {
$query = [
'function_score' => [
'query' => [
'multi_match' => [
"query" => $term,
"type" => "cross_fields",
"operator" => "and",
"fields" => [
"attributes.name^2",
]
]
],
'functions' => [
[
'filter' => ['match' => ['system.o_classId' => 16]],
'weight' => 1
],
[
'filter' => ['match' => ['system.o_classId' => 17]],
'weight' => 2
],
[
'filter' => ['match' => ['system.o_classId' => 10]],
'weight' => 3
]
],
'boost_mode' => 'multiply'
]
];
$productListing->addQueryCondition($query, 'name');
} else {
//default mysql search query condition - would also work for elastic search in that way
$term = trim(preg_replace('/\s+/', ' ', $term));
if (!empty($term)) {
foreach (explode(' ', $term) as $t) {
$productListing->addQueryCondition($t);
}
}
}
if (isset($params['autocomplete'])) {
$resultset = [];
$productListing->setLimit(10);
foreach ($productListing as $product) {
$result['href'] = $productLinkGenerator->generateWithMockup($product, []);
if ($product instanceof Car) {
$result['product'] = $product->getOSName() . ' ' . $product->getOSPrice()[0] . ', ' . $product->getClassName();
} else {
$result['product'] = $product->getOSName();
}
$resultset[] = $result;
}
return new JsonResponse([$params, $resultset]);
return $this->json($resultset);
}
$filterDefinition = $params['filterDefinition'] = Config::getWebsiteConfig()->get('fallbackFilterdefinition');
// create and init filter service
$filterService = Factory::getInstance()->getFilterService();
$listHelper->setupProductList($filterDefinition, $productListing, $params, $filterService, true);
$params['filterService'] = $filterService;
$params['products'] = $productListing;
// init pagination
$paginator = $paginator->paginate(
$productListing,
$request->get('page', 1),
$filterDefinition->getPageLimit()
);
$params['results'] = $paginator;
$params['paginationVariables'] = $paginator->getPaginationData();
$trackingManager = $ecommerceFactory->getTrackingManager();
foreach ($paginator as $product) {
$trackingManager->trackProductImpression($product, 'search-results');
}
//breadcrumbs
$placeholder('addBreadcrumb')->append([
'parentId' => $this->document->getId(),
'id' => 'search-result',
'label' => $translator->trans('shop.search-result', [$term])
]);
$params['language'] = $request->getLocale();
$params['term'] = $term;
$breadcrumbHelperService->enrichGenericDynamicPage($translator->trans('shop.search-result', [$term]));
$headTitleHelper($translator->trans('shop.search-result', [$term]));
return $this->render('product/search.html.twig', $params);
}
public function promoAd()
{
$document = \Pimcore\Model\Document::getById(282);
if ($document) {
$promotitle = $document->getEditable('promotitle');
$promoadimage = $document->getEditable('promoadimage');
$promodescription = $document->getEditable('promodescription');
$promolink = $document->getEditable('promolink');
return ['promotitle' => $promotitle, 'promoadimage' => $promoadimage, 'promodescription' => $promodescription, 'promolink' => $promolink];
}
}
protected function getJsonTMSData()
{
// $posterList = file_get_contents($request->getSchemeAndHttpHost().'/tms-session.json');
// $json = json_decode($posterList, true);
// return $json;
}
/**
* @Route("/courses/scheduled", name="course-scheduled")
*/
public function courseScheduledAction(Request $request)
{
$file = PIMCORE_PROJECT_ROOT . '/public/tms-session.json';
$posterList = file_get_contents($file);
$json = json_decode($posterList, true);
return new JsonResponse([ 'courses' => $json ]);
}
public function getCourseSessions($courseId=null)
{
$sessions = [];
if($courseId){
$file = PIMCORE_PROJECT_ROOT . '/tms-session.json';
$posterList = file_get_contents($file);
$json = json_decode($posterList, true);
foreach ($json['sessionData'] as $session) {
if($session['CourseID'] == $courseId){
$sessions[] = $session;
}
}
}
return $sessions;
}
}