1259e327488985cb798323c52128a5bab6fc9416
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / ViewHelpers / Form / TimePickerViewHelper.php
1 <?php
2 declare(strict_types=1);
3 namespace TYPO3\CMS\Form\ViewHelpers\Form;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It originated from the Neos.Form package (www.neos.io)
9 *
10 * It is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU General Public License, either version 2
12 * of the License, or any later version.
13 *
14 * For the full copyright and license information, please read the
15 * LICENSE.txt file that was distributed with this source code.
16 *
17 * The TYPO3 project - inspiring people to share!
18 */
19
20 use TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFieldViewHelper;
21 use TYPO3\CMS\Form\ViewHelpers\RenderRenderableViewHelper;
22
23 /**
24 * Displays two select-boxes for hour and minute selection.
25 *
26 * Scope: frontend
27 * @api
28 */
29 class TimePickerViewHelper extends AbstractFormFieldViewHelper
30 {
31
32 /**
33 * @var string
34 */
35 protected $tagName = 'select';
36
37 /**
38 * @var \TYPO3\CMS\Extbase\Property\PropertyMapper
39 */
40 protected $propertyMapper;
41
42 /**
43 * @param \TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper
44 * @internal
45 */
46 public function injectPropertyMapper(\TYPO3\CMS\Extbase\Property\PropertyMapper $propertyMapper)
47 {
48 $this->propertyMapper = $propertyMapper;
49 }
50
51 /**
52 * Initialize the arguments.
53 *
54 * @internal
55 */
56 public function initializeArguments()
57 {
58 parent::initializeArguments();
59 $this->registerTagAttribute('size', 'int', 'The size of the select field');
60 $this->registerTagAttribute('placeholder', 'string', 'Specifies a short hint that describes the expected value of an input element');
61 $this->registerTagAttribute('disabled', 'string', 'Specifies that the select element should be disabled when the page loads');
62 $this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this view helper', false, 'f3-form-error');
63 $this->registerArgument('initialDate', 'string', 'Initial time (@see http://www.php.net/manual/en/datetime.formats.php for supported formats)');
64 $this->registerArgument('timeType', 'string', '"hour" or "minute"');
65 $this->registerUniversalTagAttributes();
66 }
67
68 /**
69 * Renders the select fields for hour & minute
70 *
71 * @return string
72 * @api
73 */
74 public function render()
75 {
76 $name = $this->getName();
77 $this->registerFieldNameForFormTokenGeneration($name);
78 $this->tag->addAttribute('name', $name . '[hour]');
79
80 $date = $this->getSelectedDate();
81 $this->setErrorClassAttribute();
82
83 $content = '';
84
85 if ($this->arguments['timeType'] === 'hour') {
86 $content .= $this->buildHourSelector($date);
87 } else {
88 $content .= $this->buildMinuteSelector($date);
89 }
90
91 return $content;
92 }
93
94 /**
95 * @return null|\DateTime
96 */
97 protected function getSelectedDate()
98 {
99 /** @var FormRuntime $formRuntime */
100 $formRuntime = $this->renderingContext
101 ->getViewHelperVariableContainer()
102 ->get(RenderRenderableViewHelper::class, 'formRuntime');
103
104 $date = $formRuntime[$this->arguments['property']];
105 if ($date instanceof \DateTime) {
106 return $date;
107 }
108 if ($date !== null) {
109 $date = $this->propertyMapper->convert($date, 'DateTime');
110 if (!$date instanceof \DateTime) {
111 return null;
112 }
113 return $date;
114 }
115 if ($this->hasArgument('initialDate')) {
116 return new \DateTime($this->arguments['initialDate']);
117 }
118 }
119
120 /**
121 * @param \DateTime $date
122 * @return string
123 */
124 protected function buildHourSelector(\DateTime $date = null): string
125 {
126 $value = $date !== null ? $date->format('H') : null;
127 $hourSelector = clone $this->tag;
128 $hourSelector->addAttribute('name', sprintf('%s[hour]', $this->getName()));
129 $options = '';
130 foreach (range(0, 23) as $hour) {
131 $hour = str_pad((string)$hour, 2, '0', STR_PAD_LEFT);
132 $selected = $hour === $value ? ' selected="selected"' : '';
133 $options .= '<option value="' . $hour . '"' . $selected . '>' . $hour . '</option>';
134 }
135 $hourSelector->setContent($options);
136 return $hourSelector->render();
137 }
138
139 /**
140 * @param \DateTime $date
141 * @return string
142 */
143 protected function buildMinuteSelector(\DateTime $date = null): string
144 {
145 $value = $date !== null ? $date->format('i') : null;
146 $minuteSelector = clone $this->tag;
147 if ($this->hasArgument('id')) {
148 $minuteSelector->addAttribute('id', $this->arguments['id'] . '-minute');
149 }
150 $minuteSelector->addAttribute('name', sprintf('%s[minute]', $this->getName()));
151 $options = '';
152 foreach (range(0, 59) as $minute) {
153 $minute = str_pad((string)$minute, 2, '0', STR_PAD_LEFT);
154 $selected = $minute === $value ? ' selected="selected"' : '';
155 $options .= '<option value="' . $minute . '"' . $selected . '>' . $minute . '</option>';
156 }
157 $minuteSelector->setContent($options);
158 return $minuteSelector->render();
159 }
160 }