<?php
/**
* Elements DeMI
*
* This source file is available under the elements DeMI license version 1
*
* @copyright Copyright (c) elements.at New Media Solutions GmbH (https://www.elements.at/)
* @license elements DeMI Lizenz Version 1 (https://www.elements.at/de/demi-lizenz)
*/
namespace Elements\Bundle\DemiFrontendBundle\Controller;
use Carbon\Carbon;
use Elements\Bundle\CmsToolsBundle\Tool\Helper\ElementsCustomDateFormat;
use Elements\Bundle\DemiFrontendBundle\Service\DemiUrl;
use Elements\Demi\Frontend\Service\Configuration;
use Elements\Bundle\DemiFrontendBundle\Service\ConnectedEntryProvider;
use Elements\Bundle\DemiFrontendBundle\Service\InfrastructureHelper;
use Elements\Bundle\DemiFrontendBundle\Service\PaginatorHelper;
use Elements\Bundle\SeoHelperBundle\Templating\Helper\Robots;
use Elements\Demi\Deskline\Constant\FacilityGroupTypeInterface;
use Elements\Demi\Model\Infrastructure;
use Elements\Demi\Model\Listing\Infrastructure as InfrastructureListing;
use Pimcore\Model\DataObject\DemiFilterObject;
use Pimcore\Model\Document;
use Pimcore\Model\Document\Editable\Areablock;
use Pimcore\Model\Document\Editable\Checkbox;
use Pimcore\Model\Document\Editable\Multiselect;
use Pimcore\Model\Document\Editable\Relations;
use Pimcore\Model\Document\Editable\Select;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\GoneHttpException;
class InfrastructureController extends AbstractDemiController
{
protected ?InfrastructureListing $listing = null;
public function __construct(protected Robots $robots,
protected InfrastructureHelper $infraHelper,
protected ConnectedEntryProvider $connectedEntryProvider,
ElementsCustomDateFormat $elementsCustomDateFormat,
protected PaginatorHelper $paginatorHelper,
Configuration $configuration,
protected DemiUrl $demiUrl)
{
$this->setConfiguration($configuration);
$this->setElementsCustomDateFormat($elementsCustomDateFormat);
if ($this->listing === null) {
$this->listing = new InfrastructureListing();
}
}
public function overviewAction(Request $request)
{
// is Ajax Request
$isAjax = $request->isXmlHttpRequest();
$viewParams["isAjax"] = $isAjax;
$editablePrefix = $this->findEditablePrefix($this->document);
if ($request->get('isArea')){
$viewParams = $this->infraHelper->getInfrastructureListAreaViewParams($request, $viewParams, $this->document);
} else {
$this->setParams($request, $editablePrefix);
$this->infraHelper->applyCustomFilters($this->listing, $request);
$resarr = $this->listing->load();
$today = new Carbon();
usort($resarr, function (Infrastructure $a, Infrastructure $b) use ($today) {
$opena = $this->infraHelper->getIsOpened($a, $today);
$openb = $this->infraHelper->getIsOpened($b, $today);
if (($opena === 'open' && $openb === 'open') || ($opena !== 'open' && $openb !== 'open')) {
$orderkey = $this->listing->getOrderkey()[0];
if ($orderkey === 'name ASC') {
return strcmp($a->getName(), $b->getName());
}
if ($orderkey === 'name DESC') {
return strcmp($b->getName(), $a->getName());
}
$randa = mt_rand();
$randb = mt_rand();
return $randa - $randb;
}
if ($opena === 'open' && $openb !== 'open') {
return -1;
}
return 1;
});
$this->infraHelper->applyCustomSorting($resarr, $request);
$entriesPerPage = $this->document->getEditable($editablePrefix . 'perPage')->getNumber() ?: 12;
$list = new InfrastructureListing();
if (count($resarr) > 0) {
$list->addConditionParam('o_id IN (' . implode(',', array_map(static function ($infra) {
return $infra->getId();
}, $resarr)) . ')'); //recreate listing for knp paginator after recurring dates filtering
} else {
$list->addConditionParam('o_id = -1');
}
if ($request->get('nopaging')) {
$infrastructurePaginator = $this->paginatorHelper->getPaginator($list, 0);
} else {
$infrastructurePaginator = $this->paginatorHelper->getPaginator($list, $entriesPerPage, (int)$request->get('page', 1));
}
$viewParams["infrastructureList"] = $infrastructurePaginator;
}
// Ausgabe Templates
if ($isAjax) {
$this->robots->setNoIndex();
if ($request->headers->get('format') === 'json' && $request->get('mapPois')) {
$jsonArray = [];
foreach ($viewParams["infrastructureList"] as $searchObj) {
if (!is_null($searchObj->getPosition())) {
$pos = $searchObj->getPosition();
$jsonArray['pois'][] = [
'id' => $searchObj->getId(),
'geo' => ['latitude' => $pos->getLatitude(), 'longitude' => $pos->getLongitude()],
'infoboxUrl' => '/' . $request->getLocale() . '/map-teaser__' . $searchObj->getId(),
'labelClass' => $request->get('labelClass'),
'labelColor' => $request->get('labelColor')
];
}
}
return new JsonResponse($jsonArray);
}
if ($request->get('useTemplate') === 'list') {
if ($request->headers->get('format') === 'json') {
$response = [
'success' => true,
'content' => $this->renderTemplate('@ElementsDemiFrontend/Infrastructure/infrastructure-list-result.html.twig', $viewParams)->getContent()
];
return $this->json($response);
}
return $this->renderTemplate('@ElementsDemiFrontend/Infrastructure/infrastructure-list-result.html.twig', $viewParams);
}
if ($request->headers->get('format') === 'json') {
$response = [
'status' => 'success',
'html' => $this->renderTemplate('@ElementsDemiFrontend/Infrastructure/infrastructure-result.html.twig', $viewParams)->getContent()
];
return $this->json($response);
}
return $this->renderTemplate('@ElementsDemiFrontend/Infrastructure/infrastructure-result.html.twig', $viewParams);
} else {
throw new GoneHttpException('Only accessible for ajax calls');
}
}
protected function setParams(Request $request, string $editablePrefix): void
{
// Keyword setzen wenn nach einem Wort gesucht wird.
$this->listing->setKeyword($request->get('keyword'));
// Predefined HolidayThemes
$holidayThemeEditable = $this->document->getEditable($editablePrefix . 'urlaubsthemen');
if ($holidayThemeEditable instanceof Select && !$holidayThemeEditable->isEmpty() && $holidayThemeEditable->getData() !== 'undefined') {
$this->listing->setHolidayThemes($holidayThemeEditable->getData());
}
$predefinedSortOrder = $this->document->getEditable($editablePrefix . 'sortorder');
if ($predefinedSortOrder instanceof Select) {
if ($predefinedSortOrder->getValue() === 'rand') {
// Random Seed
$seed = mktime(date('H'), 0, 0);
$sortOrder = 'RAND(' . $seed . ')';
$this->listing->setOrderKey($sortOrder, false);
mt_srand($seed);
} elseif ($predefinedSortOrder->getValue() === 'name DESC') {
$this->listing->setOrderKey('name DESC', false);
} else {
$this->listing->setOrderKey('name ASC', false);
}
}
if ($request->get('demiInfraTown', 0)) {
$this->listing->setRegions([$request->get('demiInfraTown')]);
}
$regionFilter = $request->get('region', []);
$regionIds = null;
if (!empty($regionFilter) && !empty(current($regionFilter))) {
$this->listing->setRegions($regionFilter);
} elseif ($this->document->getEditable($editablePrefix . 'regions') instanceof Relations) {
foreach ($this->document->getEditable($editablePrefix . 'regions')->getElements() as $region) {
if ($region instanceof DemiFilterObject) {
$regions = $region->getFilterElements();
foreach ($regions as $foRegion) {
$regionIds[] = $foRegion->getId();
}
} else {
$regionIds[] = $region->getId();
}
}
if ($regionIds !== null) {
$this->listing->setRegions($regionIds);
}
}
// filter cat from request
$catFilter = $request->get('filter');
$catEditable = $this->document->getEditable($editablePrefix . 'category');
if (!empty($catFilter) && !empty(current($catFilter))) {
$this->listing->setCategory($catFilter);
} elseif ($catEditable instanceof Multiselect && !$catEditable->isEmpty()) {
$this->listing->setCategory($catEditable->getData());
}
if ($this->configuration->getContentScoreFilterInfrastructure() > 0) {
$this->listing->setContentScore($this->configuration->getContentScoreFilterInfrastructure());
}
$this->listing->addConditionParam("name != '' AND active = 1");
}
public function detailAction(Request $request, int $id): Response
{
if ($this->document->getProperty('infrastructure')) {
$object = $this->document->getProperty('infrastructure');
} else {
$object = Infrastructure::getById($id);
}
if (!$object) {
throw new GoneHttpException('Not found');
}
if($object && !$object->isPublished() && $object->getProperty('feratelId')){
return $this->forward(self::class. '::redirectViaFeratelIdProperty', [
'request' => $request,
'object' => $object,
'demiUrl' => $this->demiUrl
]);
}
if (!isset($_COOKIE['pimcore_admin_sid']) && !$this->editmode && !$object->isPublished() && !$request->get('pimcore_object_preview')) {
return $this->forward(self::class. '::unavailableAction', [
'request' => $request,
'unavailableType' => 'infrastructure'
]);
}
// Facilities
if (method_exists($object, 'getFacilitiesFeratel')) {
$facilities = $object->getFacilitiesFeratel();
} else {
$facilities = $object->getFacilities();
}
$sortedHealthMeasures = [];
if (!empty($facilities)) {
foreach ($facilities as $facility) {
$facGroup = $facility->getFacilityGroup();
if ($facGroup && $facGroup->getFacilityGroupType() == FacilityGroupTypeInterface::FACILITY_GROUP_TYPE_HEALTH) {
if (!isset($sortedHealthMeasures[$facGroup->getId()])) {
$data = [
'name' => $facGroup->getName(),
'keyname' => $facGroup->getDemiIconClass(),
'facilities' => []
];
$sortedHealthMeasures[$facGroup->getId()] = $data;
}
$facName = $facility->getName();
$sortedHealthMeasures[$facGroup->getId()]['facilities'][] = $facName;
}
}
}
$viewParams["sortedHealthMeasures"] = $sortedHealthMeasures;
$viewParams["connectedEntries"] = $this->connectedEntryProvider->getConnectedEntriesForInfrastructure($object, $request);
$viewParams["infrastructure"] = $object;
return $this->renderTemplate('@ElementsDemiFrontend/Infrastructure/detail.html.twig', $viewParams);
}
protected function findEditablePrefix(Document $document): string
{
if ($document->getEditables() !== null) {
$areaBlock = current(array_filter($document->getEditables(), static function ($editable) {
return $editable instanceof Areablock;
}));
if ($areaBlock && !empty($areaBlock->getIndices())) {
$correctIndex = array_filter($areaBlock->getIndices(), static function ($index) {
return $index['type'] === 'demi-infrastructure-list' ||
$index['type'] === 'demi-infrastructure-teaser-grid';
});
return $areaBlock->getName() . ':' . current($correctIndex)['key'] . '.';
}
}
// Fallback for overriden documents
if ($document->getContentMasterDocument() !== null) {
return $this->findEditablePrefix($document->getContentMasterDocument());
}
return '';
}
}