, 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 DateInterval; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; class ContingentViewHelper extends AbstractViewHelper { use CompileWithRenderStatic; /** * @var bool */ protected $escapeOutput = false; private const LEVEL_GREEN = 1; private const LEVEL_YELLOW = 2; private const LEVEL_RED = 3; public function initializeArguments() { parent::initializeArguments(); $this->registerArgument('day', \DateTimeInterface::class, 'The day', true); $this->registerArgument('calendar', 'array', 'The calendar payload', true); } /** * @param array $arguments * @param \Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * @return mixed */ public static function renderStatic( array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext ) { $day = $arguments['day']; $calendar = $arguments['calendar']; $now = new \DateTimeImmutable('now'); $dayDate = new \DateTimeImmutable($day->format('Y-m-d H:i:s'), $day->getTimezone()); $dayDate = $dayDate->setTime(0, 0, 0); if (!empty($calendar['error'])) { $class = [ 'text-zinc-400' ]; return static::getHtml($class, $dayDate->format('d')); } if ($now > $dayDate) { $class = [ 'text-zinc-400' ]; return static::getHtml($class, $dayDate->format('d')); } $statusMap = static::getStatusMap($calendar); $status = static::normalizeStatus($statusMap[$dayDate->format('Y-m-d')] ?? 'OK'); $previousStatus = static::normalizeStatus($statusMap[$dayDate->sub(new DateInterval('P1D'))->format('Y-m-d')] ?? 'OK'); $level = static::getOccupancyLevel($status); $previousLevel = static::getOccupancyLevel($previousStatus); if ($previousLevel !== $level) { $class = static::getTransientLabelClasses($previousStatus, $status); } else { $class = static::getLabelClasses($status); } return static::getHtml($class, $dayDate->format('d')); } /** * @return array */ protected static function getLabelClasses(string $status): array { return [ 'block p-1 leading-none text-sm text-white', static::getStatusClass($status), ]; } /** * @return array */ protected static function getTransientLabelClasses(string $statusFrom, ?string $statusTo = null): array { $classes = [ 'block p-1 leading-none text-sm text-white' ]; $class = static::getStatusClass($statusFrom); if ($statusTo !== null) { $class .= '-to-' . static::getStatusSuffix($statusTo); } $classes[] = $class; return $classes; } /** * @return int */ protected static function getOccupancyLevel(string $status): int { if ($status === 'BLOCKED') { return static::LEVEL_RED; } if ($status === 'ON_REQUEST') { return static::LEVEL_YELLOW; } return static::LEVEL_GREEN; } /** * @return array */ protected static function getStatusMap(array $calendar): array { $statusMap = []; foreach (($calendar['data'] ?? []) as $row) { if (!isset($row['date'])) { continue; } $statusMap[$row['date']] = static::normalizeStatus((string)($row['status'] ?? 'OK')); } return $statusMap; } protected static function normalizeStatus(string $status): string { $status = strtoupper(trim($status)); if ($status === 'ONREQUEST') { return 'ON_REQUEST'; } if (in_array($status, [ 'OK', 'ON_REQUEST', 'BLOCKED' ], true)) { return $status; } return 'OK'; } protected static function getStatusClass(string $status): string { if ($status === 'BLOCKED') { return 'availability-none'; } if ($status === 'ON_REQUEST') { return 'availability-partial'; } return 'availability-full'; } protected static function getStatusSuffix(string $status): string { if ($status === 'BLOCKED') { return 'none'; } if ($status === 'ON_REQUEST') { return 'partial'; } return 'full'; } /** * @param array $class * @param string $label * @return string */ protected static function getHtml(array $class, $label) { $cssClass = ' class="' . implode(' ', $class) . '"'; return sprintf('%s', $cssClass, $label); } }