2 declare(strict_types = 1);
120 $this->formSettings = GeneralUtility::makeInstance(ObjectManager::class)
121 ->get(ConfigurationManagerInterface::class)
123 $this->runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache(
'cache_runtime');
136 public function load(
string $persistenceIdentifier): array
138 $cacheKey =
'formLoad' . md5($persistenceIdentifier);
140 $yaml = $this->runtimeCache->get($cacheKey);
141 if ($yaml !==
false) {
148 $yaml = $this->yamlSource->load([$file]);
150 }
catch (\Exception $e) {
153 'identifier' => $persistenceIdentifier,
154 'label' => $e->getMessage(),
158 $this->runtimeCache->set($cacheKey, $yaml);
176 public function save(
string $persistenceIdentifier, array $formDefinition)
179 throw new PersistenceManagerException(sprintf(
'The file "%s" could not be saved.', $persistenceIdentifier), 1477679820);
183 if (!$this->formSettings[
'persistenceManager'][
'allowSaveToExtensionPaths']) {
184 throw new PersistenceManagerException(
'Save to extension paths is not allowed.', 1477680881);
187 $message = sprintf(
'The file "%s" could not be saved. Please check your configuration option "persistenceManager.allowedExtensionPaths"', $persistenceIdentifier);
188 throw new PersistenceManagerException($message, 1484073571);
190 $fileToSave = GeneralUtility::getFileAbsFileName($persistenceIdentifier);
196 $this->yamlSource->save($fileToSave, $formDefinition);
197 }
catch (FileWriteException $e) {
198 throw new PersistenceManagerException(sprintf(
199 'The file "%s" could not be saved: %s',
200 $persistenceIdentifier,
214 public function delete(
string $persistenceIdentifier)
217 throw new PersistenceManagerException(sprintf(
'The file "%s" could not be removed.', $persistenceIdentifier), 1472239534);
219 if (!$this->
exists($persistenceIdentifier)) {
220 throw new PersistenceManagerException(sprintf(
'The file "%s" could not be removed.', $persistenceIdentifier), 1472239535);
223 if (!$this->formSettings[
'persistenceManager'][
'allowDeleteFromExtensionPaths']) {
224 throw new PersistenceManagerException(sprintf(
'The file "%s" could not be removed.', $persistenceIdentifier), 1472239536);
227 $message = sprintf(
'The file "%s" could not be removed. Please check your configuration option "persistenceManager.allowedExtensionPaths"', $persistenceIdentifier);
228 throw new PersistenceManagerException($message, 1484073878);
230 $fileToDelete = GeneralUtility::getFileAbsFileName($persistenceIdentifier);
231 unlink($fileToDelete);
233 list($storageUid, $fileIdentifier) = explode(
':', $persistenceIdentifier, 2);
235 $file = $storage->getFile($fileIdentifier);
236 if (!$storage->checkFileActionPermission(
'delete', $file)) {
237 throw new PersistenceManagerException(sprintf(
'No delete access to file "%s".', $persistenceIdentifier), 1472239516);
239 $storage->deleteFile($file);
250 public function exists(
string $persistenceIdentifier): bool
256 $exists = file_exists(GeneralUtility::getFileAbsFileName($persistenceIdentifier));
259 list($storageUid, $fileIdentifier) = explode(
':', $persistenceIdentifier, 2);
261 $exists = $storage->hasFile($fileIdentifier);
284 $folder = $file->getParentFolder();
286 $formReadOnly = $folder->getCombinedIdentifier() ===
'1:/user_upload/';
294 $persistenceIdentifier = $file->getCombinedIdentifier();
297 'identifier' => $form[
'identifier'],
298 'name' => $form[
'label'] ?? $form[
'identifier'],
299 'persistenceIdentifier' => $persistenceIdentifier,
300 'readOnly' => $formReadOnly,
302 'location' =>
'storage',
303 'duplicateIdentifier' =>
false,
304 'invalid' => $form[
'invalid'],
305 'fileUid' => $form[
'fileUid'],
307 $identifiers[$form[
'identifier']]++;
310 'identifier' => $form[
'identifier'],
311 'name' => $form[
'label'] ?? $form[
'identifier'],
312 'persistenceIdentifier' => $persistenceIdentifier,
314 'removable' =>
false,
315 'location' =>
'storage',
316 'duplicateIdentifier' =>
false,
318 'deprecatedFileExtension' =>
true,
319 'fileUid' => $form[
'fileUid'],
330 'identifier' => $form[
'identifier'],
331 'name' => $form[
'label'] ?? $form[
'identifier'],
332 'persistenceIdentifier' => $fullPath,
333 'readOnly' => $this->formSettings[
'persistenceManager'][
'allowSaveToExtensionPaths'] ?
false:
true,
334 'removable' => $this->formSettings[
'persistenceManager'][
'allowDeleteFromExtensionPaths'] ?
true:
false,
335 'location' =>
'extension',
336 'duplicateIdentifier' =>
false,
337 'invalid' => $form[
'invalid'],
338 'fileUid' => $form[
'fileUid'],
340 $identifiers[$form[
'identifier']]++;
343 'identifier' => $form[
'identifier'],
344 'name' => $form[
'label'] ?? $form[
'identifier'],
345 'persistenceIdentifier' => $fullPath,
347 'removable' =>
false,
348 'location' =>
'extension',
349 'duplicateIdentifier' =>
false,
351 'deprecatedFileExtension' =>
true,
352 'fileUid' => $form[
'fileUid'],
358 foreach ($identifiers as $identifier => $count) {
360 foreach ($forms as &$formDefinition) {
361 if ($formDefinition[
'identifier'] === $identifier) {
362 $formDefinition[
'duplicateIdentifier'] =
true;
380 $filesFromStorageFolders = [];
382 $fileExtensionFilter = GeneralUtility::makeInstance(FileExtensionFilter::class);
383 $fileExtensionFilter->setAllowedFileExtensions([
'yaml']);
386 $storage = $folder->getStorage();
387 $storage->setFileAndFolderNameFilters([
388 [$fileExtensionFilter,
'filterFileList']
391 $files = $folder->getFiles(
397 $filesFromStorageFolders = array_merge($filesFromStorageFolders, array_values($files));
398 $storage->resetFileAndFolderNameFiltersToDefault();
401 return $filesFromStorageFolders;
413 $filesFromExtensionFolders = [];
416 foreach (
new \DirectoryIterator($fullPath) as $fileInfo) {
417 if ($fileInfo->getExtension() !==
'yaml') {
420 $filesFromExtensionFolders[$relativePath . $fileInfo->getFilename()] = $fileInfo->getFilename();
424 return $filesFromExtensionFolders;
440 $storageFolders = [];
443 !isset($this->formSettings[
'persistenceManager'][
'allowedFileMounts'])
444 || !is_array($this->formSettings[
'persistenceManager'][
'allowedFileMounts'])
445 || empty($this->formSettings[
'persistenceManager'][
'allowedFileMounts'])
447 return $storageFolders;
450 foreach ($this->formSettings[
'persistenceManager'][
'allowedFileMounts'] as $allowedFileMount) {
451 $allowedFileMount = rtrim($allowedFileMount,
'/') .
'/';
453 [$storageUid, $fileMountPath] = explode(
':', $allowedFileMount, 2);
457 }
catch (PersistenceManagerException $e) {
461 $isStorageFileMount =
false;
462 $parentFolder = $storage->getRootLevelFolder(
false);
464 foreach ($storage->getFileMounts() as $storageFileMount) {
466 $storageFileMountFolder = $storageFileMount[
'folder'];
470 $isStorageFileMount =
true;
471 $parentFolder = $storageFileMountFolder;
477 $fileMountFolder = $storage->getFolder($fileMountPath);
478 }
catch (InsufficientFolderAccessPermissionsException $e) {
480 }
catch (FolderDoesNotExistException $e) {
481 if ($isStorageFileMount) {
482 $fileMountPath = substr(
484 strlen($parentFolder->getIdentifier())
489 $fileMountFolder = $storage->createFolder($fileMountPath, $parentFolder);
490 }
catch (InsufficientFolderAccessPermissionsException $e) {
495 $storageFolders[$allowedFileMount] = $fileMountFolder;
497 return $storageFolders;
512 $extensionFolders = $this->runtimeCache->get(
'formAccessibleExtensionFolders');
514 if ($extensionFolders !==
false) {
515 return $extensionFolders;
518 $extensionFolders = [];
520 !isset($this->formSettings[
'persistenceManager'][
'allowedExtensionPaths'])
521 || !is_array($this->formSettings[
'persistenceManager'][
'allowedExtensionPaths'])
522 || empty($this->formSettings[
'persistenceManager'][
'allowedExtensionPaths'])
524 $this->runtimeCache->set(
'formAccessibleExtensionFolders', $extensionFolders);
525 return $extensionFolders;
528 foreach ($this->formSettings[
'persistenceManager'][
'allowedExtensionPaths'] as $allowedExtensionPath) {
533 $allowedExtensionFullPath = GeneralUtility::getFileAbsFileName($allowedExtensionPath);
534 if (!file_exists($allowedExtensionFullPath)) {
537 $allowedExtensionPath = rtrim($allowedExtensionPath,
'/') .
'/';
538 $extensionFolders[$allowedExtensionPath] = $allowedExtensionFullPath;
541 $this->runtimeCache->set(
'formAccessibleExtensionFolders', $extensionFolders);
542 return $extensionFolders;
558 $savePath = rtrim($savePath,
'/') .
'/';
560 if (!$this->
exists($formPersistenceIdentifier)) {
561 return $formPersistenceIdentifier;
563 for ($attempts = 1; $attempts < 100; $attempts++) {
565 if (!$this->
exists($formPersistenceIdentifier)) {
566 return $formPersistenceIdentifier;
570 if (!$this->
exists($formPersistenceIdentifier)) {
571 return $formPersistenceIdentifier;
574 throw new NoUniquePersistenceIdentifierException(
575 sprintf(
'Could not find a unique persistence identifier for form identifier "%s" after %d attempts', $formIdentifier, $attempts),
592 $originalIdentifier = $identifier;
594 for ($attempts = 1; $attempts < 100; $attempts++) {
595 $identifier = sprintf(
'%s_%d', $originalIdentifier, $attempts);
600 $identifier = $originalIdentifier .
'_' . time();
602 throw new NoUniqueIdentifierException(
603 sprintf(
'Could not find a unique identifier for form identifier "%s" after %d attempts', $identifier, $attempts),
620 $identifierUsed =
false;
621 foreach ($this->
listForms() as $formDefinition) {
622 if ($formDefinition[
'identifier'] === $identifier) {
623 $identifierUsed =
true;
627 return $identifierUsed;
644 $persistencePathIsFile = isset($pathinfo[
'extension']);
647 $persistencePathIsFile
655 $persistencePathIsFile
663 !$persistencePathIsFile
670 !$persistencePathIsFile
686 return strpos($path,
'EXT:') === 0;
699 [$storageUid, $pathIdentifier] = explode(
':', $path, 2);
700 if (empty($storageUid) || empty($pathIdentifier)) {
718 list($storageUid, $fileIdentifier) = explode(
':', $persistenceIdentifier, 2);
722 if (!$storage->hasFolder($pathinfo[
'dirname'])) {
723 throw new PersistenceManagerException(sprintf(
'Could not create folder "%s".', $pathinfo[
'dirname']), 1471630579);
727 $folder = $storage->getFolder($pathinfo[
'dirname']);
728 }
catch (InsufficientFolderAccessPermissionsException $e) {
729 throw new PersistenceManagerException(sprintf(
'No read access to folder "%s".', $pathinfo[
'dirname']), 1512583307);
732 if (!$storage->checkFolderActionPermission(
'write', $folder)) {
733 throw new PersistenceManagerException(sprintf(
'No write access to folder "%s".', $pathinfo[
'dirname']), 1471630580);
736 if (!$storage->hasFile($fileIdentifier)) {
737 $this->filePersistenceSlot->allowInvocation(
739 $folder->getCombinedIdentifier() . $pathinfo[
'basename']
741 $file = $folder->createFile($pathinfo[
'basename']);
743 $file = $storage->getFile($fileIdentifier);
757 $storage = $this->storageRepository->findByUid($storageUid);
759 !$storage instanceof ResourceStorage
760 || !$storage->isBrowsable()
762 throw new PersistenceManagerException(sprintf(
'Could not access storage with uid "%d".', $storageUid), 1471630581);
772 protected function loadMetaData($persistenceIdentifier): array
774 if ($persistenceIdentifier instanceof
File) {
775 $file = $persistenceIdentifier;
776 $persistenceIdentifier = $file->getCombinedIdentifier();
782 $rawYamlContent = $file->getContents();
784 if ($rawYamlContent ===
false) {
785 throw new NoSuchFileException(sprintf(
'YAML file "%s" could not be loaded', $persistenceIdentifier), 1524684462);
790 $yaml[
'fileUid'] = $file->getUid();
794 'identifier' => $persistenceIdentifier,
795 'label' => $e->getMessage(),
809 $metaDataProperties = [
'identifier',
'type',
'label',
'prototypeName'];
811 foreach (explode(LF, $maybeRawFormDefinition) as $line) {
812 if (empty($line) || $line[0] ===
' ') {
816 [$key, $value] = explode(
':', $line);
820 || !in_array($key, $metaDataProperties,
true)
825 $value = trim($value,
" '\"\r");
826 $metaData[$key] = $value;
843 if (strpos($persistenceIdentifier,
'EXT:') === 0) {
845 'Form definition file name ("' . $persistenceIdentifier .
'") which does not end with ".form.yaml" will not be supported in TYPO3 v10.0.',
848 } elseif (strpos($persistenceIdentifier,
'EXT:') !== 0) {
849 throw new PersistenceManagerException(sprintf(
'Form definition "%s" does not end with ".form.yaml".', $persistenceIdentifier), 1531160649);
862 if (pathinfo($persistenceIdentifier, PATHINFO_EXTENSION) !==
'yaml') {
870 $message = sprintf(
'The file "%s" could not be loaded. Please check your configuration option "persistenceManager.allowedExtensionPaths"', $persistenceIdentifier);
871 throw new PersistenceManagerException($message, 1484071985);
875 $file = $this->resourceFactory->retrieveFileOrFolderObject($persistenceIdentifier);
876 }
catch (\Exception $e) {
881 if ($file ===
null) {
882 throw new NoSuchFileException(sprintf(
'YAML file "%s" could not be loaded', $persistenceIdentifier), 1524684442);
885 if (!$file->getStorage()->checkFileActionPermission(
'read', $file)) {
886 throw new PersistenceManagerException(sprintf(
'No read access to file "%s".', $persistenceIdentifier), 1471630578);
918 $pathInfo = is_string($pathInfo) ? $pathInfo :
'';
919 $dirName = rtrim($pathInfo,
'/') .
'/';
929 $folderName = rtrim($folderName,
'/') .
'/';
939 $folderName = rtrim($folderName,
'/') .
'/';
949 return isset($data[
'identifier'], $data[
'type']) && !empty($data[
'identifier']) && $data[
'type'] ===
'Form';