108 lines
4.6 KiB
PHP
108 lines
4.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* This file is part of the TYPO3 CMS project.
|
|
*
|
|
* It is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU General Public License, either version 2
|
|
* of the License, or any later version.
|
|
*
|
|
* For the full copyright and license information, please read the
|
|
* LICENSE.txt file that was distributed with this source code.
|
|
*
|
|
* The TYPO3 project - inspiring people to share!
|
|
*/
|
|
|
|
namespace TYPO3\CMS\Form\Domain\Model\FormElements;
|
|
|
|
use TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException;
|
|
use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException;
|
|
use TYPO3\CMS\Core\Resource\ResourceFactory;
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|
use TYPO3\CMS\Core\Utility\PathUtility;
|
|
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
|
|
use TYPO3\CMS\Form\Mvc\Property\TypeConverter\UploadedFileReferenceConverter;
|
|
|
|
/**
|
|
* A generic file upload form element
|
|
*
|
|
* Scope: frontend
|
|
*/
|
|
class FileUpload extends AbstractFormElement
|
|
{
|
|
/**
|
|
* Initializes the Form Element by setting the data type to an Extbase File Reference
|
|
* @internal
|
|
*/
|
|
public function initializeFormElement()
|
|
{
|
|
$this->setDataType(FileReference::class);
|
|
|
|
// Set the property mapping configuration for the file upload element.
|
|
// * Add the UploadedFileReferenceConverter to convert an uploaded file to a
|
|
// FileReference (single upload) or ObjectStorage (multiple uploads).
|
|
// * Setup the storage:
|
|
// If the property "saveToFileMount" exist for this element it will be used.
|
|
// If this file mount or the property "saveToFileMount" does not exist
|
|
// the default storage "1:/user_uploads/" will be used. Uploads are placed
|
|
// in a dedicated sub-folder (e.g. ".../form_<40-chars-hash>/actual.file").
|
|
$typeConverter = GeneralUtility::makeInstance(UploadedFileReferenceConverter::class);
|
|
/** @var \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration $propertyMappingConfiguration */
|
|
$propertyMappingConfiguration = $this->getRootForm()
|
|
->getProcessingRule($this->getIdentifier())
|
|
->getPropertyMappingConfiguration()
|
|
->setTypeConverter($typeConverter);
|
|
|
|
$uploadConfiguration = [
|
|
UploadedFileReferenceConverter::CONFIGURATION_UPLOAD_CONFLICT_MODE => 'rename',
|
|
];
|
|
|
|
// In preview mode (Form Editor backend module), skip upload folder resolution
|
|
// entirely. File uploads are non-functional during preview and resolving the
|
|
// target folder may throw access permission exceptions for backend users who
|
|
// do not have access to the configured upload storage.
|
|
if (!($this->getRootForm()->getRenderingOptions()['previewMode'] ?? false)) {
|
|
$saveToFileMountIdentifier = $this->getProperties()['saveToFileMount'] ?? '';
|
|
if ($this->checkSaveFileMountAccess($saveToFileMountIdentifier)) {
|
|
$uploadConfiguration[UploadedFileReferenceConverter::CONFIGURATION_UPLOAD_FOLDER] = $saveToFileMountIdentifier;
|
|
} else {
|
|
// @todo Why should uploaded files be stored to the same directory as the *.form.yaml definitions?
|
|
$persistenceIdentifier = $this->getRootForm()->getPersistenceIdentifier();
|
|
if (!empty($persistenceIdentifier)) {
|
|
$pathinfo = PathUtility::pathinfo($persistenceIdentifier);
|
|
$saveToFileMountIdentifier = $pathinfo['dirname'];
|
|
if ($this->checkSaveFileMountAccess($saveToFileMountIdentifier)) {
|
|
$uploadConfiguration[UploadedFileReferenceConverter::CONFIGURATION_UPLOAD_FOLDER] = $saveToFileMountIdentifier;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$propertyMappingConfiguration->setTypeConverterOptions(UploadedFileReferenceConverter::class, $uploadConfiguration);
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
protected function checkSaveFileMountAccess(string $saveToFileMountIdentifier): bool
|
|
{
|
|
if (empty($saveToFileMountIdentifier)) {
|
|
return false;
|
|
}
|
|
|
|
if (PathUtility::isExtensionPath($saveToFileMountIdentifier)) {
|
|
return false;
|
|
}
|
|
|
|
$resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
|
|
|
|
try {
|
|
$resourceFactory->getFolderObjectFromCombinedIdentifier($saveToFileMountIdentifier);
|
|
return true;
|
|
} catch (\InvalidArgumentException|InsufficientFolderAccessPermissionsException|FolderDoesNotExistException $e) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|