<?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\Service;
use Elements\Bundle\SeoHelperBundle\Templating\Helper\PrettyUrl;
use Pimcore\Http\Request\Resolver\SiteResolver;
use Pimcore\Http\RequestHelper;
use Pimcore\Model\DataObject\AbstractObject;
use Pimcore\Tool;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Elements\Demi\Frontend\Service\Configuration;
class DemiUrl
{
public function __construct(protected PrettyUrl $prettyUrl, protected RequestHelper $requestHelper, protected Configuration $configuration, protected SiteResolver $siteResolver, protected ContainerBagInterface $parameterBag)
{
}
public function getName(): string
{
return 'demiUrl';
}
public function getCheckoutUrl(string $controller, string $action, ?array $params = null, ?string $alternateActionLongCheckout = null): string
{
$uri = method_exists( $this->requestHelper, 'getMainRequest' ) ? $this->requestHelper->getMainRequest()->getRequestUri() : '';
if (str_contains($uri, '/affiliate-booking/')) {
$routeName = 'demi_checkout_affiliate';
} else {
$routeName = 'demi_checkout';
}
$params = $params ?: [];
$params['controller'] = $controller;
$params['action'] = $action;
if (!empty($alternateActionLongCheckout) && $controller === 'checkout' && $action === 'step2'
&& $this->parameterBag->has('elements_demi.checkout')
&& $this->parameterBag->get('elements_demi.checkout') === 'long') {
$params['action'] = $alternateActionLongCheckout;
}
$params['path'] = $params['pathOverride'] ?? $this->configuration->getCheckoutPath()?->getFullPath();
unset($params['pathOverride']);
return $this->invoke($params, $routeName, true);
}
public function invoke(array $params, string $routeName, bool $reset = false, bool $encode = true, $toLanguage = null): string
{
try {
$toLanguage = $locale = $toLanguage ?: $this->requestHelper->getCurrentRequest()->getLocale();
} catch (\Throwable $exception) {
$toLanguage = $locale = 'en';
}
$pathPrepend = '';
if ($routeName === 'demi_acco_detail_page'
|| $routeName === 'demi_acco_ajax'
|| $routeName === 'demi_acco_ajax_affiliate'
|| $routeName === 'demi_acco_package_ajax'
|| $routeName === 'demi_acco_package_ajax_affiliate'
|| $routeName === 'demi_acco_detail_package_page'
|| $routeName === 'demi_acco_affiliate_detail_page'
|| $routeName === 'demi_acco_affiliate_detail_package_page'
|| $routeName === 'demi_acco_detail_tvbpackage_page'
|| $routeName === 'demi_acco_detail_tvbpackage_enquire_page'
|| $routeName === 'demi_acco_detail_package_enquire_page'
|| $routeName === 'demi_acco_detail_enquire_page') {
$accommodation = $params['accommodation'];
unset($params['accommodation']);
$params['id'] = $accommodation ? $accommodation->getId() : $params['id'];
if (!$accommodation) {
$accommodation = AbstractObject::getById($params['id']);
}
$params['name'] = '';
if (!empty($accommodation)) {
if ($this->configuration->getAccoDetailRouteIncludesName()) {
$params['name'] .= $accommodation->getName($toLanguage);
}
if ($this->configuration->getAccoDetailRouteIncludesCategory()) {
$params['name'] .= ' '.$accommodation->getCategoryNames(1, '', $toLanguage);
}
if ($this->configuration->getAccoDetailRouteIncludesTown() && $accommodation->getTown()) {
$params['name'] .= ' '.$accommodation->getTown()->getName($toLanguage);
}
}
$parent = $this->configuration->getAccoParentDocument($toLanguage);
$matches = [];
if ($parent) {
$path = $parent->getFullPath();
if (preg_match('/^(https:\/\/(([a-zA-ZÖÄÜöäüß-]+\.)+[\w|-]+))\/(.*)/i', $path, $matches) || preg_match('/^(http:\/\/(([a-zA-ZÖÄÜöäüß-]+\.)+[\w|-]+))\/(.*)/i', $path, $matches)) {
$pathPrepend = $matches[1];
$params['path'] = str_replace($pathPrepend, '', $path);
} else {
$params['path'] = $path;
}
} else {
throw new NotFoundHttpException('Not found');
}
//in case the seo routing config is not set yet
if (empty($params['name'])) {
$params['name'] = 'CHECK-CONFIG';
}
$package = $params['package'] ?? null;
if ($package) {
unset($params['package']);
$params['pid'] = $package->getId();
$params['pname'] = $package->getName($toLanguage);
if (empty($params['pname'])) {
//feratel bug - name should not be empty, there should be a fallback present for every language!
//in case name is still empty - use "package" as fallback to avoid routing error
$params['pname'] = 'package';
}
}
} elseif (!isset($params['path'])) {
$params['path'] = $this->requestHelper->getMainRequest()->getPathInfo();
}
//prepend https + main domain / main site in checkout
if ((!array_key_exists('ignorePrependingDomain', $params) || !$params['ignorePrependingDomain']) && str_starts_with($routeName, 'demi_checkout')) {
if ($site = $this->siteResolver->getSite()) {
$pathPrepend = 'https://'.$site->getMainDomain();
} else {
$pathPrepend = str_replace('http://', 'https://', Tool::getHostUrl());
}
}
//replace / in Names -> causes error in routing
if (isset($params['name'])) {
$params['name'] = str_replace(['/', '_'], '-', $params['name']);
}
if (isset($params['pname'])) {
$params['pname'] = str_replace(['/', '_'], '-', $params['pname']);
}
if ($locale && isset($params['path'])) {
$params['_locale'] = $toLanguage;
$pathPos = strpos($params['path'], '/' . $locale . '/');
if ($pathPos === 0 || $pathPos === false) {
$matches = [];
$tmpLocale = $locale;
if ($pathPos === false && preg_match('@^/([a-zA-Z]{...})/@', $params['path'], $matches) != false) {
$params['_locale'] = $tmpLocale = $matches[1];
}
$params['path'] = preg_replace('@^/' . preg_quote($tmpLocale) . '/@', '', $params['path']);
}
if ($toLanguage !== $locale) {
$params['path'] = preg_replace('@^/' . preg_quote($toLanguage) . '/@', '', $params['path']);
}
}
return $pathPrepend.$this->prettyUrl->__invoke($params, $routeName, $reset, $encode, $toLanguage);
}
/**
* @param array $params
* @param string $routeName
* @param bool $reset
* @param bool $encode
* @param null $toLanguage
* @param string|null $paramsToUse
*
* @return string
*
* For Compatibility reasons
*/
public function __invoke(array $params, string $routeName, bool $reset = false, bool $encode = true, $toLanguage = null, string $paramsToUse = null): string
{
return $this->invoke($params, $routeName, $reset, $encode, $toLanguage);
}
}