feat: extended api endpoint for hotel data consumed by myep
This commit is contained in:
+132
-12
@@ -2,18 +2,58 @@
|
|||||||
|
|
||||||
namespace EP\EpProducts\Middleware;
|
namespace EP\EpProducts\Middleware;
|
||||||
|
|
||||||
use EP\EpProducts\Service\HotelImageService;
|
use EP\EpProducts\Service\MyEpImageService;
|
||||||
use EP\EpProducts\Service\ProductImageService;
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Server\MiddlewareInterface;
|
use Psr\Http\Server\MiddlewareInterface;
|
||||||
use Psr\Http\Server\RequestHandlerInterface;
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||||
use TYPO3\CMS\Core\Http\JsonResponse;
|
use TYPO3\CMS\Core\Http\JsonResponse;
|
||||||
|
use TYPO3\CMS\Core\Resource\FileRepository;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
use TYPO3\CMS\Extbase\Service\ImageService;
|
||||||
|
|
||||||
class ProductApiMiddleware implements MiddlewareInterface
|
class ApiMiddleware implements MiddlewareInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var MyEpImageService
|
||||||
|
*/
|
||||||
|
private $hotelImageService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MyEpImageService
|
||||||
|
*/
|
||||||
|
private $productImageService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MyEpImageService
|
||||||
|
*/
|
||||||
|
private $regionImageService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FileRepository
|
||||||
|
*/
|
||||||
|
private $fileRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ImageService
|
||||||
|
*/
|
||||||
|
private $imageService;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
MyEpImageService $hotelImageService,
|
||||||
|
MyEpImageService $productImageService,
|
||||||
|
MyEpImageService $regionImageService,
|
||||||
|
FileRepository $fileRepository,
|
||||||
|
ImageService $imageService
|
||||||
|
) {
|
||||||
|
$this->hotelImageService = $hotelImageService;
|
||||||
|
$this->productImageService = $productImageService;
|
||||||
|
$this->regionImageService = $regionImageService;
|
||||||
|
$this->fileRepository = $fileRepository;
|
||||||
|
$this->imageService = $imageService;
|
||||||
|
}
|
||||||
|
|
||||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||||
{
|
{
|
||||||
$path = $request->getUri()->getPath();
|
$path = $request->getUri()->getPath();
|
||||||
@@ -91,15 +131,15 @@ class ProductApiMiddleware implements MiddlewareInterface
|
|||||||
|
|
||||||
$data = $queryBuilder
|
$data = $queryBuilder
|
||||||
->select(
|
->select(
|
||||||
|
'product.uid as productUid',
|
||||||
'product.name as productName',
|
'product.name as productName',
|
||||||
'product.code as productCode',
|
'product.code as productCode',
|
||||||
|
'product.region as regionUid',
|
||||||
'country.name as countryName',
|
'country.name as countryName',
|
||||||
'region.name as regionName',
|
|
||||||
'city.name as cityName',
|
'city.name as cityName',
|
||||||
)
|
)
|
||||||
->from('tx_epproducts_domain_model_product', 'product')
|
->from('tx_epproducts_domain_model_product', 'product')
|
||||||
->leftJoin('product', 'tx_epproducts_domain_model_country', 'country', 'product.country = country.uid')
|
->leftJoin('product', 'tx_epproducts_domain_model_country', 'country', 'product.country = country.uid')
|
||||||
->leftJoin('product', 'tx_epproducts_domain_model_region', 'region', 'product.region = region.uid')
|
|
||||||
->leftJoin('product', 'tx_epproducts_domain_model_city', 'city', 'product.city = city.uid')
|
->leftJoin('product', 'tx_epproducts_domain_model_city', 'city', 'product.city = city.uid')
|
||||||
->leftJoin('product', 'tx_epproducts_domain_model_matchcode', 'matchcode', 'product.uid = matchcode.entity AND matchcode.entity_type="hotel"')
|
->leftJoin('product', 'tx_epproducts_domain_model_matchcode', 'matchcode', 'product.uid = matchcode.entity AND matchcode.entity_type="hotel"')
|
||||||
->where($queryBuilder->expr()->eq('product.code', $queryBuilder->createNamedParameter($productCode)))
|
->where($queryBuilder->expr()->eq('product.code', $queryBuilder->createNamedParameter($productCode)))
|
||||||
@@ -113,8 +153,7 @@ class ProductApiMiddleware implements MiddlewareInterface
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$images = GeneralUtility::makeInstance(ProductImageService::class)
|
$images = $this->serializeImages($this->productImageService->getImages((int) $data['productUid']));
|
||||||
->getImages((int) $data['uid']);
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'product' => [
|
'product' => [
|
||||||
@@ -125,9 +164,7 @@ class ProductApiMiddleware implements MiddlewareInterface
|
|||||||
'country' => [
|
'country' => [
|
||||||
'name' => $data['countryName'],
|
'name' => $data['countryName'],
|
||||||
],
|
],
|
||||||
'region' => [
|
'region' => $this->fetchRegionData((int) $data['regionUid']),
|
||||||
'name' => $data['regionName'],
|
|
||||||
],
|
|
||||||
'city' => [
|
'city' => [
|
||||||
'name' => $data['cityName'],
|
'name' => $data['cityName'],
|
||||||
],
|
],
|
||||||
@@ -159,6 +196,7 @@ class ProductApiMiddleware implements MiddlewareInterface
|
|||||||
'hotel.wifi',
|
'hotel.wifi',
|
||||||
'hotel.distance_bus',
|
'hotel.distance_bus',
|
||||||
'hotel.distance_lift',
|
'hotel.distance_lift',
|
||||||
|
'hotel.region',
|
||||||
)
|
)
|
||||||
->from('tx_epproducts_domain_model_hotel', 'hotel')
|
->from('tx_epproducts_domain_model_hotel', 'hotel')
|
||||||
->leftJoin('hotel', 'tx_epproducts_domain_model_matchcode', 'alias', 'hotel.uid = alias.entity AND alias.entity_type="hotel"')
|
->leftJoin('hotel', 'tx_epproducts_domain_model_matchcode', 'alias', 'hotel.uid = alias.entity AND alias.entity_type="hotel"')
|
||||||
@@ -177,8 +215,7 @@ class ProductApiMiddleware implements MiddlewareInterface
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$images = GeneralUtility::makeInstance(HotelImageService::class)
|
$images = $this->serializeImages($this->hotelImageService->getImages((int) $hotel['uid']));
|
||||||
->getImages((int) $hotel['uid']);
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'name' => $hotel['name'],
|
'name' => $hotel['name'],
|
||||||
@@ -201,6 +238,89 @@ class ProductApiMiddleware implements MiddlewareInterface
|
|||||||
'distanceBus' => $hotel['distance_bus'],
|
'distanceBus' => $hotel['distance_bus'],
|
||||||
'distanceLift' => $hotel['distance_lift'],
|
'distanceLift' => $hotel['distance_lift'],
|
||||||
],
|
],
|
||||||
|
'region' => $this->fetchRegionData((int) $hotel['region']),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function fetchRegionData(int $regionUid): array
|
||||||
|
{
|
||||||
|
if (0 === $regionUid) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||||
|
->getQueryBuilderForTable('tx_epproducts_domain_model_region');
|
||||||
|
|
||||||
|
$region = $queryBuilder
|
||||||
|
->select(
|
||||||
|
'region.uid',
|
||||||
|
'region.name',
|
||||||
|
'region.latitude',
|
||||||
|
'region.longitude',
|
||||||
|
'region.ski_area',
|
||||||
|
'region.ski_area_extended',
|
||||||
|
'region.description',
|
||||||
|
'region.news',
|
||||||
|
'region.length',
|
||||||
|
'region.height',
|
||||||
|
'region.lifts',
|
||||||
|
'webcam.url as webcamUrl',
|
||||||
|
)
|
||||||
|
->from('tx_epproducts_domain_model_region', 'region')
|
||||||
|
->leftJoin('region', 'tx_epproducts_domain_model_webcam', 'webcam', 'region.webcam = webcam.uid')
|
||||||
|
->where($queryBuilder->expr()->eq('region.uid', $queryBuilder->createNamedParameter($regionUid, \PDO::PARAM_INT)))
|
||||||
|
->setMaxResults(1)
|
||||||
|
->execute()
|
||||||
|
->fetchAssociative()
|
||||||
|
;
|
||||||
|
|
||||||
|
if (false === $region) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$images = $this->serializeImages($this->regionImageService->getImages((int) $region['uid']));
|
||||||
|
$regionMaps = $this->serializeFileReferences(
|
||||||
|
$this->fileRepository->findByRelation('tx_epproducts_domain_model_region', 'region_maps', (int) $region['uid'])
|
||||||
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'name' => $region['name'],
|
||||||
|
'latitude' => $region['latitude'],
|
||||||
|
'longitude' => $region['longitude'],
|
||||||
|
'webcam' => $region['webcamUrl'],
|
||||||
|
'ski_area' => $region['ski_area'],
|
||||||
|
'ski_area_extended' => $region['ski_area_extended'],
|
||||||
|
'description' => $region['description'],
|
||||||
|
'news' => $region['news'],
|
||||||
|
'length' => $region['length'],
|
||||||
|
'altitude' => $region['height'],
|
||||||
|
'lifts' => $region['lifts'],
|
||||||
|
'images' => $images,
|
||||||
|
'region_maps' => $regionMaps,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 'original' entry of AbstractImageService::getImages() holds raw FileReference objects,
|
||||||
|
* which are needed by Fluid templates elsewhere but serialize to empty objects in JSON responses.
|
||||||
|
* We replace it with the same {url, alt, title} shape used for 'region_maps'.
|
||||||
|
*/
|
||||||
|
private function serializeImages(array $images): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'original' => $this->serializeFileReferences($images['original']),
|
||||||
|
'resized' => $images['resized'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function serializeFileReferences(array $files): array
|
||||||
|
{
|
||||||
|
return array_map(function ($file) {
|
||||||
|
return [
|
||||||
|
'url' => $this->imageService->getImageUri($file, true),
|
||||||
|
'alt' => $file->getProperty('alternative'),
|
||||||
|
'title' => $file->getProperty('title'),
|
||||||
|
];
|
||||||
|
}, $files);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
namespace EP\EpProducts\Service;
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Copyright notice
|
||||||
|
*
|
||||||
|
* (c) 2018 Björn Fromme <[email protected]>, dreipunktnull
|
||||||
|
*
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||||
|
* free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The GNU General Public License can be found at
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
*
|
||||||
|
* This script is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
|
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
|
||||||
|
use TYPO3\CMS\Core\Resource\FileRepository;
|
||||||
|
use TYPO3\CMS\Extbase\Service\ImageService;
|
||||||
|
|
||||||
|
class MyEpImageService extends AbstractImageService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $field = 'images';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $imageSizes = [
|
||||||
|
's' => [
|
||||||
|
'width' => '480',
|
||||||
|
'height' => '360c-100',
|
||||||
|
],
|
||||||
|
'm' => [
|
||||||
|
'width' => '768',
|
||||||
|
'height' => '576c-100',
|
||||||
|
],
|
||||||
|
'l' => [
|
||||||
|
'width' => '1280',
|
||||||
|
'height' => '960c-100',
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct(FileRepository $fileRepository, ImageService $imageService, FrontendInterface $cache, string $table = 'tx_epproducts_domain_model_hotel')
|
||||||
|
{
|
||||||
|
parent::__construct($fileRepository, $imageService, $cache);
|
||||||
|
$this->table = $table;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ return [
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
'ep/productapi' => [
|
'ep/productapi' => [
|
||||||
'target' => \EP\EpProducts\Middleware\ProductApiMiddleware::class,
|
'target' => \EP\EpProducts\Middleware\ApiMiddleware::class,
|
||||||
'before' => [
|
'before' => [
|
||||||
'typo3/cms-frontend/page-resolver',
|
'typo3/cms-frontend/page-resolver',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -31,3 +31,31 @@ services:
|
|||||||
EP\EpProducts\Controller\AjaxCalendarController:
|
EP\EpProducts\Controller\AjaxCalendarController:
|
||||||
arguments:
|
arguments:
|
||||||
$cache: '@cache.ep_cache'
|
$cache: '@cache.ep_cache'
|
||||||
|
|
||||||
|
EP\EpProducts\Service\MyEpImageService:
|
||||||
|
arguments:
|
||||||
|
$cache: '@cache.ep_cache'
|
||||||
|
|
||||||
|
ep_products.image_service.hotel:
|
||||||
|
class: EP\EpProducts\Service\MyEpImageService
|
||||||
|
arguments:
|
||||||
|
$cache: '@cache.ep_cache'
|
||||||
|
$table: 'tx_epproducts_domain_model_hotel'
|
||||||
|
|
||||||
|
ep_products.image_service.product:
|
||||||
|
class: EP\EpProducts\Service\MyEpImageService
|
||||||
|
arguments:
|
||||||
|
$cache: '@cache.ep_cache'
|
||||||
|
$table: 'tx_epproducts_domain_model_product'
|
||||||
|
|
||||||
|
ep_products.image_service.region:
|
||||||
|
class: EP\EpProducts\Service\MyEpImageService
|
||||||
|
arguments:
|
||||||
|
$cache: '@cache.ep_cache'
|
||||||
|
$table: 'tx_epproducts_domain_model_region'
|
||||||
|
|
||||||
|
EP\EpProducts\Middleware\ApiMiddleware:
|
||||||
|
arguments:
|
||||||
|
$hotelImageService: '@ep_products.image_service.hotel'
|
||||||
|
$productImageService: '@ep_products.image_service.product'
|
||||||
|
$regionImageService: '@ep_products.image_service.region'
|
||||||
|
|||||||
Reference in New Issue
Block a user