[FEATURE] Add HTML5 date form element
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / Mvc / Property / PropertyMappingConfiguration.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Form\Mvc\Property;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use TYPO3\CMS\Core\Resource\ResourceFactory;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20 use TYPO3\CMS\Core\Utility\PathUtility;
21 use TYPO3\CMS\Extbase\Object\ObjectManager;
22 use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
23 use TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator;
24 use TYPO3\CMS\Form\Domain\Model\FormElements\FileUpload;
25 use TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface;
26 use TYPO3\CMS\Form\Mvc\Property\TypeConverter\UploadedFileReferenceConverter;
27 use TYPO3\CMS\Form\Mvc\Validation\MimeTypeValidator;
28
29 /**
30 * Scope: frontend
31 */
32 class PropertyMappingConfiguration
33 {
34
35 /**
36 * This hook is called for each form element after the class
37 * TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory has built the entire form.
38 *
39 * @param RenderableInterface $renderable
40 * @internal
41 */
42 public function afterBuildingFinished(RenderableInterface $renderable)
43 {
44 if ($renderable instanceof FileUpload) {
45 // Set the property mapping configuration for the file upload element.
46 // * Add the UploadedFileReferenceConverter to convert an uploaded file to a
47 // FileReference.
48 // * Add the MimeTypeValidator to the UploadedFileReferenceConverter to
49 // delete non-valid file types directly.
50 // * Setup the storage:
51 // If the property "saveToFileMount" exist for this element it will be used.
52 // If this file mount or the property "saveToFileMount" does not exist
53 // the folder in which the form definition lies (persistence identifier) will be used.
54 // If the form is generated programmatically and therefore no
55 // persistence identifier exist the default storage "1:/user_upload/" will be used.
56
57 /** @var \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration $propertyMappingConfiguration */
58 $propertyMappingConfiguration = $renderable->getRootForm()->getProcessingRule($renderable->getIdentifier())->getPropertyMappingConfiguration();
59
60 $allowedMimeTypes = [];
61 $validators = [];
62 if (isset($renderable->getProperties()['allowedMimeTypes']) && \is_array($renderable->getProperties()['allowedMimeTypes'])) {
63 $allowedMimeTypes = array_filter($renderable->getProperties()['allowedMimeTypes']);
64 }
65 if (!empty($allowedMimeTypes)) {
66 $mimeTypeValidator = GeneralUtility::makeInstance(ObjectManager::class)
67 ->get(MimeTypeValidator::class, ['allowedMimeTypes' => $allowedMimeTypes]);
68 $validators = [$mimeTypeValidator];
69 }
70
71 $processingRule = $renderable->getRootForm()->getProcessingRule($renderable->getIdentifier());
72 foreach ($processingRule->getValidators() as $validator) {
73 if (!($validator instanceof NotEmptyValidator)) {
74 $validators[] = $validator;
75 $processingRule->removeValidator($validator);
76 }
77 }
78
79 $uploadConfiguration = [
80 UploadedFileReferenceConverter::CONFIGURATION_FILE_VALIDATORS => $validators,
81 UploadedFileReferenceConverter::CONFIGURATION_UPLOAD_CONFLICT_MODE => 'rename',
82 ];
83
84 $saveToFileMountIdentifier = $renderable->getProperties()['saveToFileMount'] ?? '';
85 if ($this->checkSaveFileMountAccess($saveToFileMountIdentifier)) {
86 $uploadConfiguration[UploadedFileReferenceConverter::CONFIGURATION_UPLOAD_FOLDER] = $saveToFileMountIdentifier;
87 } else {
88 $persistenceIdentifier = $renderable->getRootForm()->getPersistenceIdentifier();
89 if (!empty($persistenceIdentifier)) {
90 $pathinfo = PathUtility::pathinfo($persistenceIdentifier);
91 $saveToFileMountIdentifier = $pathinfo['dirname'];
92 if ($this->checkSaveFileMountAccess($saveToFileMountIdentifier)) {
93 $uploadConfiguration[UploadedFileReferenceConverter::CONFIGURATION_UPLOAD_FOLDER] = $saveToFileMountIdentifier;
94 }
95 }
96 }
97
98 $propertyMappingConfiguration->setTypeConverterOptions(UploadedFileReferenceConverter::class, $uploadConfiguration);
99 return;
100 }
101
102 if ($renderable->getType() === 'Date') {
103 // Set the property mapping configuration for the `Date` element.
104
105 /** @var \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration $propertyMappingConfiguration */
106 $propertyMappingConfiguration = $renderable->getRootForm()->getProcessingRule($renderable->getIdentifier())->getPropertyMappingConfiguration();
107 // @see https://www.w3.org/TR/2011/WD-html-markup-20110405/input.date.html#input.date.attrs.value
108 // 'Y-m-d' = https://tools.ietf.org/html/rfc3339#section-5.6 -> full-date
109 $propertyMappingConfiguration->setTypeConverterOption(DateTimeConverter::class, DateTimeConverter::CONFIGURATION_DATE_FORMAT, 'Y-m-d');
110 }
111 }
112
113 /**
114 * @param string $saveToFileMountIdentifier
115 * @return bool
116 * @internal
117 */
118 protected function checkSaveFileMountAccess(string $saveToFileMountIdentifier): bool
119 {
120 if (empty($saveToFileMountIdentifier)) {
121 return false;
122 }
123
124 $resourceFactory = GeneralUtility::makeInstance(ObjectManager::class)
125 ->get(ResourceFactory::class);
126
127 try {
128 $resourceFactory->getFolderObjectFromCombinedIdentifier($saveToFileMountIdentifier);
129 return true;
130 } catch (\InvalidArgumentException $e) {
131 return false;
132 }
133 }
134 }