<?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\Demi\Deskline\Accommodation\Search\Service\Vacancies;
use Elements\Demi\Accommodation\Search\Parameter;
use Elements\Demi\Accommodation\Search\Service\Vacancies\AbstractAdapter;
use Elements\Demi\Deskline\SearchParameter\AccommodationInterface;
use Elements\Demi\Deskline\SearchResult\Accommodation\Entry;
use Elements\Demi\Deskline\Service\Search\Accommodation;
use Elements\Demi\Model\AccommodationServiceProvider;
use Elements\Demi\Vacancies\Dependency\VacancyDependencyContainer;
class Live extends AbstractAdapter
{
protected ?\Elements\Demi\Deskline\SearchResult\Accommodation $desklineResult = null;
protected ?int $count = null;
protected string $adapterCachePostFix = 'Live';
protected array $sortOrderMapping = [
Parameter::DEMI_SORT_ORDER_PRICE_ASC => Parameter::SORT_ORDER_PRICE_ASC,
Parameter::DEMI_SORT_ORDER_PRICE_DESC => Parameter::SORT_ORDER_PRICE_DESC,
Parameter::DEMI_SORT_ORDER_RANDOM => Parameter::SORT_ORDER_RANDOM,
Parameter::DEMI_SORT_ORDER_STARS_ASC => Parameter::SORT_ORDER_STARS_ASC,
Parameter::DEMI_SORT_ORDER_BOOKABLE_ASC => Parameter::SORT_ORDER_BOOKABLE_ASC,
Parameter::DEMI_SORT_ORDER_RATING_ASC => Parameter::SORT_ORDER_RATING_ASC,
Parameter::DEMI_SORT_ORDER_RATINGAVERAGE_ASC => Parameter::SORT_ORDER_RATING_ASC,
Parameter::DEMI_SORT_ORDER_RATINGAVERAGE_DESC => Parameter::SORT_ORDER_RATING_DESC,
Parameter::DEMI_SORT_ORDER_CONTENTSCORE => Parameter::SORT_ORDER_BOOKABLE_ASC,
];
public function __construct(VacancyDependencyContainer $dc)
{
parent::__construct($dc);
}
public function getAdapterCachePostFix(): ?string
{
return $this->adapterCachePostFix;
}
public function mapDemiSortOrder(mixed $sortOrder): ?string
{
if (is_array($sortOrder)) {
$sortOrder = current($sortOrder);
}
return $this->sortOrderMapping[$sortOrder] ?? $sortOrder;
}
public function doRequest(): void
{
$searchParams = $this->getSearchParameter();
$sortOrder = $searchParams->getOrderKey();
$searchType = $searchParams->getSearchType();
$ids = $searchParams->getAccoIds();
$fids = $searchParams->getAccoFIds();
if ($searchParams->getTopOnly() && (empty($fids) && empty($ids))) { //needed for getById for detail. otherwise toponly would select more Accommodations even in detail page
$topIds = $this->getTopIds();
$searchParams->setAccoFIds($topIds);
}
$sortOrder = $this->mapDemiSortOrder($sortOrder);
if (!$sortOrder || $sortOrder == 'custom') {
$sortOrder = Parameter::SORT_ORDER_RANDOM;
}
// if searchType ist not set or supported -> fallback to standard
if (!in_array($searchType, [Parameter::SEARCH_TYPE_STANDARD, Parameter::SEARCH_TYPE_EACH_PRODUCT_SEPARATED])) {
$searchType = Parameter::SEARCH_TYPE_STANDARD;
}
$responseType = $searchParams->getResponseType();
//$responseType = \Elements\Demi\Deskline\Constant\SearchParameter\Accommodation::RESPONSE_TYPE_STANDARD;
/** @var $desklineParams AccommodationInterface */
$desklineParams = $this->convertSearchParams();
$page = $searchParams->getCurrentPage();
$searchService = new Accommodation($desklineParams, $page, $searchParams->getCurrentItemCountPerPage(), $sortOrder, $searchType, $responseType);
$time = (round(microtime(true) * 1000));
$this->desklineResult = $searchService->getSearchResult();
$this->setRequestTime((round(microtime(true) * 1000)) - $time);
$singleAccoLiveSearch = is_array($this->searchParameter->getAccoIds()) && count($this->searchParameter->getAccoIds()) == 1 && !$this->searchParameter->getIsCorridor();
//filter locally, Deskline does not support search for multiple product ids
if ((!($singleAccoLiveSearch && in_array('productIds', $this->searchParameter->getIgnoreFiltersInAccoDetailSearch())) && $searchParams->getProductIds() && count($searchParams->getProductIds())) && $this->desklineResult->getEntries()) {
/**
* @var $accommodationEntry Entry
*/
$accommodationEntry = $this->desklineResult->getEntries()[0];
$filteredProducts = [];
foreach ($accommodationEntry->getProducts() as $product) {
if ($product->getProduct()) {
$pimcoreId = $product->getProduct()->getId();
if (in_array($pimcoreId, $searchParams->getProductIds())) {
$filteredProducts[] = $product;
}
}
}
$accommodationEntry->setProducts($filteredProducts);
$this->desklineResult->setTotalAmount(count($filteredProducts));
}
//can't filter free cancellation in by request, let's do it now
if (!($singleAccoLiveSearch && in_array('freeCancellation', $this->searchParameter->getIgnoreFiltersInAccoDetailSearch())) && $this->searchParameter->getFreeCancellation() && $this->desklineResult->getEntries()) {
/**
* @var $accommodationEntry Entry
*/
$accommodationEntry = $this->desklineResult->getEntries()[0];
$filteredProducts = [];
foreach ($accommodationEntry->getProducts() as $product) {
if ($product->getProduct() && $product->getHasFreeCancellation()) {
$filteredProducts[] = $product;
}
}
$accommodationEntry->setProducts($filteredProducts);
$this->desklineResult->setTotalAmount(count($filteredProducts));
}
$this->count = $searchService->count();
}
public function getTopIds(?int $count = null): array
{
$limit = '';
if (!$count) {
$limit = ' LIMIT ' . $count;
}
$serviceProviderDummy = new AccommodationServiceProvider();
$sql = 'select fid from ' . $this->getDc()->getUsedPimcoreDb() . '.object_' . $serviceProviderDummy->getClassId() . ' where isTop = 1 ';
$sql .= $limit;
$result = $this->getDc()->getDb()?->fetchAll($sql);
$ids = [];
foreach ($result as $keyvalue) {
$ids[] = $keyvalue['fid'];
}
return $ids;
}
public function searchVacancies(bool $force = false): array
{
if ($force || $this->desklineResult === null) {
$this->doRequest();
}
return $this->desklineResult->getEntries();
}
public function count(): ?int
{
if ($this->desklineResult === null) {
$this->doRequest();
}
return $this->count;
}
private function convertSearchParams(): array
{
return $this->getSearchParameter()->convertToDesklineParams();
}
public function getResultBuilder(): ResultBuilder
{
$searchParams = $this->getSearchParameter();
return new ResultBuilder($searchParams, $this->getDc());
}
}