feat: api endpoints to fetch product and hotel data in json format
This commit is contained in:
@@ -0,0 +1,203 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace EP\EpProducts\Controller;
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Copyright notice
|
||||||
|
*
|
||||||
|
* (c) 2025 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 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -241,3 +241,38 @@ lib.bookingWidget {
|
|||||||
settings =< plugin.tx_epproducts.settings
|
settings =< plugin.tx_epproducts.settings
|
||||||
view =< plugin.tx_epproducts.view
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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'] =
|
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['ep_products'] =
|
||||||
\EP\EpProducts\Hooks\PageLayoutView::class;
|
\EP\EpProducts\Hooks\PageLayoutView::class;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user