diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/ApiController.php b/public/typo3conf/ext/ep_products/Classes/Controller/ApiController.php new file mode 100644 index 00000000..d92e333e --- /dev/null +++ b/public/typo3conf/ext/ep_products/Classes/Controller/ApiController.php @@ -0,0 +1,203 @@ +, 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 EP\EpProducts\Service\HotelImageService; +use EP\EpProducts\Service\ProductImageService; +use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; +use TYPO3\CMS\Extbase\Mvc\View\JsonView; + +class ApiController extends ActionController +{ + /** + * @var string + */ + protected $defaultViewObjectName = JsonView::class; + + /** + * @var ProductImageService + */ + private $productImageService; + + /** + * @var HotelImageService + */ + private $hotelImageService; + + /** + * @var ConnectionPool + */ + private $connectionPool; + + public function __construct( + ProductImageService $productImageService, + HotelImageService $hotelImageService, + ConnectionPool $connectionPool + ) { + $this->productImageService = $productImageService; + $this->hotelImageService = $hotelImageService; + $this->connectionPool = $connectionPool; + } + + /** + * Returns product details in JSON format for API consumption. + */ + public function productAction(string $code): void + { + $queryBuilder = $this->connectionPool->getQueryBuilderForTable('tx_epproducts_domain_model_product'); + + $product = $queryBuilder + ->select( + 'uid', + 'name', + 'code', + 'headline', + 'teaser', + 'teaser_long', + 'concept_description', + 'board_description', + 'programme_description', + 'included_services', + 'additional_services', + 'ski_pass_alt_title', + 'ski_pass_description' + ) + ->from('tx_epproducts_domain_model_product') + ->where( + $queryBuilder->expr()->eq( + 'code', + $queryBuilder->createNamedParameter($code) + ) + ) + ->execute() + ->fetchAssociative() + ; + + if (false === $product) { + $this->view->assign('value', ['error' => 'Product not found']); + $this->response->setStatus(404); + + return; + } + + $images = $this->productImageService->getImages((int) $product['uid']); + + $response = [ + 'name' => $product['name'], + 'code' => $product['code'], + 'headline' => $product['headline'], + 'teaser' => $product['teaser'], + 'teaserLong' => $product['teaser_long'], + 'conceptDescription' => $product['concept_description'], + 'boardDescription' => $product['board_description'], + 'programmeDescription' => $product['programme_description'], + 'includedServices' => $product['included_services'], + 'additionalServices' => $product['additional_services'], + 'skiPassAltTitle' => $product['ski_pass_alt_title'], + 'skiPassDescription' => $product['ski_pass_description'], + 'images' => $images['resized'] ?? [], + ]; + + $this->view->assign('value', $response); + } + + /** + * Returns hotel details in JSON format for API consumption. + */ + public function hotelAction(string $code): void + { + $queryBuilder = $this->connectionPool->getQueryBuilderForTable('tx_epproducts_domain_model_hotel'); + + $hotel = $queryBuilder + ->select( + 'uid', + 'name', + 'short_name', + 'code', + 'headline', + 'teaser', + 'header_title', + 'header_subtitle', + 'description', + 'features', + 'room_types', + 'additional_information', + 'address', + 'latitude', + 'longitude', + 'category', + 'type', + 'external_link' + ) + ->from('tx_epproducts_domain_model_hotel') + ->where( + $queryBuilder->expr()->eq( + 'code', + $queryBuilder->createNamedParameter($code) + ) + ) + ->execute() + ->fetchAssociative() + ; + + if (false === $hotel) { + $this->view->assign('value', ['error' => 'Hotel not found']); + $this->response->setStatus(404); + + return; + } + + $images = $this->hotelImageService->getImages((int) $hotel['uid']); + + $response = [ + 'name' => $hotel['name'], + 'shortName' => $hotel['short_name'], + 'code' => $hotel['code'], + 'headline' => $hotel['headline'], + 'teaser' => $hotel['teaser'], + 'headerTitle' => $hotel['header_title'], + 'headerSubtitle' => $hotel['header_subtitle'], + 'description' => $hotel['description'], + 'features' => $hotel['features'], + 'roomTypes' => $hotel['room_types'], + 'additionalInformation' => $hotel['additional_information'], + 'address' => $hotel['address'], + 'latitude' => $hotel['latitude'], + 'longitude' => $hotel['longitude'], + 'category' => $hotel['category'], + 'type' => $hotel['type'], + 'externalLink' => $hotel['external_link'], + 'images' => $images['resized'] ?? [], + ]; + + $this->view->assign('value', $response); + } +} diff --git a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript index 4e2411fc..a494397c 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript +++ b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript @@ -241,3 +241,38 @@ lib.bookingWidget { settings =< plugin.tx_epproducts.settings view =< plugin.tx_epproducts.view } + +# API endpoint for product details (cacheable) +tx_epproducts_api_json = PAGE +tx_epproducts_api_json { + typeNum = 1720 + config { + disableAllHeaderCode = 1 + disablePrefixComment = 1 + additionalHeaders.10.header = Content-type: application/json + additionalHeaders.20.header = Access-Control-Allow-Origin: * + xhtml_cleaning = 0 + admPanel = 0 + debug = 0 + no_cache = 0 + sendCacheHeaders = 1 + } + + 10 = USER + 10 { + userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run + extensionName = EpProducts + pluginName = api + vendorName = EP + controller = Api + action = product + switchableControllerActions { + Api { + 1 = product + 2 = hotel + } + } + settings =< plugin.tx_epproducts.settings + persistence =< plugin.tx_epproducts.persistence + } +} diff --git a/public/typo3conf/ext/ep_products/ext_localconf.php b/public/typo3conf/ext/ep_products/ext_localconf.php index b46c17a7..e3391fee 100644 --- a/public/typo3conf/ext/ep_products/ext_localconf.php +++ b/public/typo3conf/ext/ep_products/ext_localconf.php @@ -294,6 +294,14 @@ $boot = function () { ] ); + \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( + 'EP.ep_products', + 'api', + [ + 'Api' => 'product,hotel', + ] + ); + $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['ep_products'] = \EP\EpProducts\Hooks\PageLayoutView::class;