<?php declare(strict_types=1); /* * This file is part of contao-weinanlieferung-bundle. * * (c) vonRotenberg * * @license commercial */ namespace vonRotenberg\WeinanlieferungBundle\Controller\Frontend\Ajax; use Contao\Controller; use Contao\CoreBundle\Controller\AbstractController; use Contao\CoreBundle\Exception\PageNotFoundException; use Contao\CoreBundle\Framework\ContaoFramework; use Contao\CoreBundle\Security\Authentication\Token\TokenChecker; use Contao\Environment; use Contao\File; use Contao\FilesModel; use Contao\FormFileUpload; use Contao\Frontend; use Contao\FrontendUser; use Contao\Input; use Contao\StringUtil; use Contao\System; use Doctrine\DBAL\Connection; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Contracts\Translation\TranslatorInterface; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungLeseartModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungRebsorteModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungReservationModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungSlotsModel; /** * @Route("/_ajax/vr_wa/v1/slot", name="vr_wa_slot_ajax", defaults={"_scope" = "frontend", "_token_check" = false}) */ class SlotAjaxController extends AbstractController { private $tokenChecker; private $translator; private $framework; public function __construct(ContaoFramework $framework, TokenChecker $tokenChecker, TranslatorInterface $translator) { $this->framework = $framework; $this->tokenChecker = $tokenChecker; $this->translator = $translator; } public function __invoke(Request $request) { System::loadLanguageFile('default'); if (!$this->tokenChecker->hasFrontendUser()) { return $this->renderUnauthorized(); } if (empty($_REQUEST['do'])) { return new Response('Required parameter missing',412); } $blnModal = true; if (!empty($_REQUEST['modal'])) { $blnModal = !(strtolower($_REQUEST['modal']) == 'false'); } switch ($_REQUEST['do']) { case 'details': return $this->renderDetails($blnModal); case 'booking': return $this->renderBooking($blnModal); case 'reservate': return $this->reservate(); case 'updateReservation': return $this->updateReservation(); case 'delete': return $this->deleteReservation(); } return new Response('',500); } protected function renderDetails(bool $blnModal=true,string $error=null) { if (empty($_REQUEST['id'])) { return new Response('Required parameter missing',412); } if (($Slot = WeinanlieferungSlotsModel::findPublishedById($_REQUEST['id'])) === null) { return new Response('Could not load slot data',500); } // Get slot reservations from user $arrReservations = []; if (($Reservations = WeinanlieferungReservationModel::findBy(["uid = ?","pid = ?"],[FrontendUser::getInstance()->id,$Slot->id])) !== null) { foreach ($Reservations as $reservation) { $arrSortenBooked = []; $SortenLeseart = explode(';',$reservation->sorten); foreach($SortenLeseart as $sorteLeseart) { list($sorte,$leseart) = explode(',',$sorteLeseart); $objSorte = WeinanlieferungRebsorteModel::findByPk($sorte); $objLeseart = WeinanlieferungLeseartModel::findByPk($leseart); $arrSortenBooked[$objSorte->id.','.$objLeseart->id] = ($objSorte !== null ? $objSorte->title : '') . ' ' . ($objLeseart !== null ? $objLeseart->title : ''); } /*if (($Sorten = $reservation->getRelated('sorten')) !== null) { $arrSortenBooked = $Sorten->fetchEach('title'); }*/ $arrReservations[] = array_merge($reservation->row(),[ 'sorten' => $arrSortenBooked ]); } } // Build data $arrSorten = []; $Sorten = StringUtil::deserialize($Slot->sorten,true); foreach($Sorten as $sorte) { $objSorte = WeinanlieferungRebsorteModel::findByPk($sorte['sorte']); $objLeseart = WeinanlieferungLeseartModel::findByPk($sorte['leseart']); $arrSorten[$objSorte->id.','.$objLeseart->id] = ($objSorte !== null ? $objSorte->title : '') . ' ' . ($objLeseart !== null ? $objLeseart->title : ''); } /*if (($Sorten = $Slot->getRelated('sorte')) !== null) { $arrSorten = array_combine($Sorten->fetchEach('id'),$Sorten->fetchEach('title')); }*/ $intAvailableBehaelter = $Slot->getAvailableBehaelter(); $arrData = [ 'modal' => $blnModal, 'id' => $Slot->id, 'slot' => array_merge($Slot->row(),[ 'sorte' => $arrSorten, 'behaelterAvailable' => $intAvailableBehaelter ]), 'standort' => $Slot->getRelated('pid'), 'buchen' => [ 'buchbar' => (boolean) $intAvailableBehaelter, 'behaelter' => range(min($intAvailableBehaelter,1),$intAvailableBehaelter), 'sorten' => $arrSorten ], 'reservations' => $arrReservations ]; if (!empty($error)) { $arrData['toast'] = $error; } return $this->render('@Contao/modal_slot_details.html.twig',$arrData); } protected function renderBooking(bool $blnModal=true) { $arrData = []; if (empty($_REQUEST['id'])) { return new Response('Required parameter missing',412); } /** @var WeinanlieferungSlotsModel $Slot */ if (($Booking = WeinanlieferungReservationModel::findById($_REQUEST['id'])) === null || ($Slot = $Booking->getRelated('pid')) === null) { return new Response('Could not load booking data',500); } $objFile = FilesModel::findByUuid($Booking->upload); if (!empty($_REQUEST['deleteFile']) && $_REQUEST['deleteFile'] && $objFile !== null) { $File = new File($objFile->path); if ($File->delete()) { $objFile->delete(); $objFile = null; } } if (!empty($Booking->upload) && $objFile !== null) { $File = new File($objFile->path); $strHref = Environment::get('request'); // Remove an existing file parameter (see #5683) if (isset($_GET['file'])) { $strHref = preg_replace('/(&(amp;)?|\?)file=[^&]+/', '', $strHref); } $strHref .= (strpos($strHref, '?') !== false ? '&' : '?') . 'file=' . System::urlEncode($File->value); $arrData['file'] = [ 'link' => $strHref, 'filename' => $File->filename, 'extension' => $File->extension, 'name' => $File->name, 'path' => $File->dirname ]; } // Send the file to the browser (see #4632 and #8375) if ($objFile !== null && ($file = Input::get('file', true))) { if ($file == $objFile->path) { Controller::sendFileToBrowser($file); } } $arrSortenAvailable = []; $Sorten = StringUtil::deserialize($Slot->sorten,true); foreach($Sorten as $sorte) { $objSorte = WeinanlieferungRebsorteModel::findByPk($sorte['sorte']); $objLeseart = WeinanlieferungLeseartModel::findByPk($sorte['leseart']); $arrSortenAvailable[$objSorte->id.','.$objLeseart->id] = ($objSorte !== null ? $objSorte->title : '') . ' ' . ($objLeseart !== null ? $objLeseart->title : ''); } $arrSortenBooked = []; $SortenLeseart = explode(';',$Booking->sorten); foreach($SortenLeseart as $sorteLeseart) { list($sorte,$leseart) = explode(',',$sorteLeseart); $objSorte = WeinanlieferungRebsorteModel::findByPk($sorte); $objLeseart = WeinanlieferungLeseartModel::findByPk($leseart); $arrSortenBooked[$objSorte->id.','.$objLeseart->id] = ($objSorte !== null ? $objSorte->title : '') . ' ' . ($objLeseart !== null ? $objLeseart->title : ''); } $intAvailableBehaelter = $Slot->getAvailableBehaelter(); $arrData = array_merge($arrData,[ 'modal' => $blnModal, 'id' => $Booking->id, 'slot' => array_merge($Slot->row(),[ 'sorte' => $arrSortenAvailable, 'behaelterAvailable' => $intAvailableBehaelter ]), 'buchung' => array_merge($Booking->row(),[ 'sorten' => $arrSortenBooked ]), 'standort' => $Slot->getRelated('pid'), 'buchen' => [ 'buchbar' => (boolean) $intAvailableBehaelter, 'behaelter' => range(min($intAvailableBehaelter,1),$intAvailableBehaelter+$Booking->behaelter), 'sorten' => $arrSortenAvailable ] ]); return $this->render('@Contao/modal_booking_details.html.twig',$arrData); } protected function reservate() { Controller::loadDataContainer('tl_vr_wa_reservation'); $arrData = []; if (($rootPage = Frontend::getRootPageFromUrl()) !== null && !empty($rootPage->vr_wa_uploadFolderSRC)) { $File = new FormFileUpload(\Contao\Widget::getAttributesFromDca($GLOBALS['TL_DCA']['tl_vr_wa_reservation']['fields']['upload'], 'upload')); $File->storeFile = true; $File->doNotOverwrite = true; $File->uploadFolder = $rootPage->vr_wa_uploadFolderSRC; $File->validate(); if ($File->hasErrors()) { return $this->renderDetails(false,'<div class="toast toast--danger mx-0">' . $File->getErrorAsHTML() . '</div>'); } $arrData['filename'] = $_SESSION['FILES'][$File->name]['name'] ?? ''; $arrData['upload'] = $_SESSION['FILES'][$File->name]['uuid'] ? StringUtil::uuidToBin($_SESSION['FILES'][$File->name]['uuid']) : null; } if (empty($_REQUEST['id']) || empty(Input::post('behaelter')) || empty(Input::post('sorten'))) { return new Response('Missing parameter',412); } $arrSorten = []; if (!is_array(Input::post('sorten'))) { $arrSorten[] = Input::post('sorten'); } else { $arrSorten = implode(';', Input::post('sorten')); } $Reservation = new WeinanlieferungReservationModel(); $arrData = array_merge($arrData,[ 'pid' => $_REQUEST['id'], 'rootid' => $rootPage !== null ? $rootPage->id : '', 'tstamp' => time(), 'uid' => FrontendUser::getInstance()->id, 'behaelter' => Input::post('behaelter'), 'sorten' => $arrSorten ]); $Reservation->setRow($arrData); $Reservation->save(); return new Response('<div class="toast toast--success mx-0"><p>Reservierung erfolgreich</p></div>',200,['HX-Trigger'=> 'updateWaList']); } protected function updateReservation() { Controller::loadDataContainer('tl_vr_wa_reservation'); if (empty($_REQUEST['id']) || empty(Input::post('behaelter')) || empty(Input::post('sorten'))) { return new Response('Missing parameter',412); } if (($Reservation = WeinanlieferungReservationModel::findById($_REQUEST['id'])) === null) { return new Response('Could not load booking data',500); } if (($rootPage = Frontend::getRootPageFromUrl()) !== null && !empty($rootPage->vr_wa_uploadFolderSRC)) { $File = new FormFileUpload(\Contao\Widget::getAttributesFromDca($GLOBALS['TL_DCA']['tl_vr_wa_reservation']['fields']['upload'], 'upload')); $File->storeFile = true; $File->doNotOverwrite = true; $File->uploadFolder = $rootPage->vr_wa_uploadFolderSRC; $File->validate(); if ($File->hasErrors()) { return $this->renderDetails(false,'<div class="toast toast--danger mx-0">' . $File->getErrorAsHTML() . '</div>'); } $Reservation->filename = $_SESSION['FILES'][$File->name]['name'] ?? ''; $Reservation->upload = $_SESSION['FILES'][$File->name]['uuid'] ? StringUtil::uuidToBin($_SESSION['FILES'][$File->name]['uuid']) : null; } $arrSorten = []; if (!is_array(Input::post('sorten'))) { $arrSorten[] = Input::post('sorten'); } else { $arrSorten = implode(',', Input::post('sorten')); } $Reservation->tstamp = time(); $Reservation->behaelter = Input::post('behaelter'); $Reservation->sorten = $arrSorten; $Reservation->save(); return new Response('<div class="toast toast--success mx-0"><p>Reservierung erfolgreich geändert</p></div>',200,['HX-Trigger'=> 'updateWaBooking']); } protected function deleteReservation() { if (empty($_REQUEST['id'])) { return new Response('Missing parameter',412); } /** @var Connection $db */ $db = Controller::getContainer()->get('database_connection'); $arrCriteria = [ 'uid' => FrontendUser::getInstance()->id, 'id' => $_REQUEST['id'] ]; if ($db->delete('tl_vr_wa_reservation',$arrCriteria)) { return new Response(null,203,['HX-Trigger'=> 'updateWaBooking']); } return new Response('Could not delete',500); } protected function renderUnauthorized() { return $this->render('@Contao/modal_unauthorized.html.twig'); } }