diff --git a/Classes/Driver/AmazonS3Driver.php b/Classes/Driver/AmazonS3Driver.php index eda319cb..1c902c06 100644 --- a/Classes/Driver/AmazonS3Driver.php +++ b/Classes/Driver/AmazonS3Driver.php @@ -31,6 +31,7 @@ use TYPO3\CMS\Core\Log\LogManager; use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Messaging\FlashMessageService; +use TYPO3\CMS\Core\Resource\Capabilities; use TYPO3\CMS\Core\Resource\Driver\AbstractHierarchicalFilesystemDriver; use TYPO3\CMS\Core\Resource\Driver\StreamableDriverInterface; use TYPO3\CMS\Core\Resource\Exception; @@ -43,7 +44,6 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\PathUtility; use TYPO3\CMS\Extbase\Utility\LocalizationUtility; -use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; /** * Class AmazonS3Driver @@ -184,17 +184,20 @@ class AmazonS3Driver extends AbstractHierarchicalFilesystemDriver implements Str * @param array $configuration * @param S3Client $s3Client */ - public function __construct(array $configuration = [], $s3Client = null, ?EventDispatcherInterface $eventDispatcher = null) + public function __construct(array $configuration = [], $s3Client = null, EventDispatcherInterface $eventDispatcher = null) { parent::__construct($configuration); $this->eventDispatcher = $eventDispatcher ?? GeneralUtility::makeInstance(EventDispatcherInterface::class); $this->compatibilityService = GeneralUtility::makeInstance(CompatibilityService::class); // The capabilities default of this driver. See CAPABILITY_* constants for possible values - $this->capabilities = - ResourceStorage::CAPABILITY_BROWSABLE - | ResourceStorage::CAPABILITY_PUBLIC - | ResourceStorage::CAPABILITY_WRITABLE - | ResourceStorage::CAPABILITY_HIERARCHICAL_IDENTIFIERS; + + $this->capabilities = GeneralUtility::makeInstance(Capabilities::class)->addCapabilities( + Capabilities::CAPABILITY_BROWSABLE, + Capabilities::CAPABILITY_PUBLIC, + Capabilities::CAPABILITY_WRITABLE, + Capabilities::CAPABILITY_HIERARCHICAL_IDENTIFIERS + ); + $this->streamWrapperProtocol = 's3-' . substr(md5(uniqid()), 0, 7); $this->s3Client = $s3Client; $this->metaInfoCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('ausdriveramazons3_metainfocache'); @@ -218,7 +221,7 @@ public function __destruct() * loadExternalClasses * @throws \Exception */ - public static function loadExternalClasses() + public static function loadExternalClasses(): void { // Backwards compatibility: for TYPO3 versions lower than 10.0 $loadSdk = !Environment::isComposerMode() && !function_exists('Aws\\manifest'); @@ -230,14 +233,14 @@ public static function loadExternalClasses() /** * @return void */ - public function processConfiguration() + public function processConfiguration(): void { } /** * @return void */ - public function initialize() + public function initialize(): void { $this->initializeSettings() ->initializeClient(); @@ -254,7 +257,7 @@ public function initialize() * @param string $identifier * @return string */ - public function getPublicUrl($identifier) + public function getPublicUrl(string $identifier): ?string { $uriParts = GeneralUtility::trimExplode('/', ltrim($identifier, '/'), true); $uriParts = array_map('rawurlencode', $uriParts); @@ -268,7 +271,7 @@ public function getPublicUrl($identifier) * @param string $hashAlgorithm * @return string */ - public function hash($fileIdentifier, $hashAlgorithm) + public function hash(string $fileIdentifier, string $hashAlgorithm): string { if ($this->fileContentHash) { $result = $this->s3Client->headObject([ @@ -312,7 +315,7 @@ public function hash($fileIdentifier, $hashAlgorithm) * * @return string */ - public function getDefaultFolder() + public function getDefaultFolder(): string { return $this->getRootLevelFolder(); } @@ -322,7 +325,7 @@ public function getDefaultFolder() * * @return string */ - public function getRootLevelFolder() + public function getRootLevelFolder(): string { return '/'; } @@ -336,7 +339,7 @@ public function getRootLevelFolder() * @return array * @throws \InvalidArgumentException If the file does not exist */ - public function getFileInfoByIdentifier($fileIdentifier, array $propertiesToExtract = []) + public function getFileInfoByIdentifier(string $fileIdentifier, array $propertiesToExtract = []): array { if (count($propertiesToExtract) === 0 || in_array('mimetype', $propertiesToExtract)) { // force to reload the infos from S3 if the mime type was requested @@ -358,7 +361,7 @@ public function getFileInfoByIdentifier($fileIdentifier, array $propertiesToExtr * @param string $identifier * @return bool */ - public function fileExists($identifier) + public function fileExists(string $identifier): bool { if (substr($identifier, -1) === '/' || $identifier === '') { return false; @@ -372,7 +375,7 @@ public function fileExists($identifier) * @param string $identifier * @return bool */ - public function folderExists($identifier) + public function folderExists(string $identifier): bool { if ($identifier === self::ROOT_FOLDER_IDENTIFIER) { return true; @@ -388,7 +391,7 @@ public function folderExists($identifier) * @param string $folderIdentifier * @return bool */ - public function fileExistsInFolder($fileName, $folderIdentifier) + public function fileExistsInFolder(string $fileName, string $folderIdentifier): bool { return $this->objectExists(rtrim($folderIdentifier, '/') . '/' . $fileName); } @@ -400,7 +403,7 @@ public function fileExistsInFolder($fileName, $folderIdentifier) * @param string $folderIdentifier Parent folder * @return bool */ - public function folderExistsInFolder($folderName, $folderIdentifier) + public function folderExistsInFolder(string $folderName, string $folderIdentifier): bool { $identifier = rtrim($folderIdentifier, '/') . '/' . $folderName; $this->normalizeFolderIdentifier($identifier); @@ -414,7 +417,7 @@ public function folderExistsInFolder($folderName, $folderIdentifier) * @param string $folderIdentifier * @return string */ - public function getFolderInFolder($folderName, $folderIdentifier) + public function getFolderInFolder(string $folderName, string $folderIdentifier): string { $identifier = $folderIdentifier . '/' . $folderName; $this->normalizeFolderIdentifier($identifier); @@ -430,7 +433,7 @@ public function getFolderInFolder($folderName, $folderIdentifier) * @return string the identifier of the new file * @throws \Exception */ - public function addFile($localFilePath, $targetFolderIdentifier, $newFileName = '', $removeOriginal = true) + public function addFile(string $localFilePath, string $targetFolderIdentifier, string $newFileName = '', bool $removeOriginal = true): string { $newFileName = $this->sanitizeFileName($newFileName !== '' ? $newFileName : PathUtility::basename($localFilePath)); $targetIdentifier = $targetFolderIdentifier . $newFileName; @@ -480,7 +483,7 @@ public function addFile($localFilePath, $targetFolderIdentifier, $newFileName = * * @return string */ - public function moveFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $newFileName) + public function moveFileWithinStorage(string $fileIdentifier, string $targetFolderIdentifier, string $newFileName): string { $this->normalizeFolderIdentifier($targetFolderIdentifier); $targetIdentifier = $targetFolderIdentifier . $newFileName; @@ -498,7 +501,7 @@ public function moveFileWithinStorage($fileIdentifier, $targetFolderIdentifier, * @param string $fileName * @return string the Identifier of the new file */ - public function copyFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $fileName) + public function copyFileWithinStorage(string $fileIdentifier, string $targetFolderIdentifier, string $fileName): string { $targetIdentifier = $targetFolderIdentifier . $fileName; $this->copyObject($fileIdentifier, $targetIdentifier); @@ -513,7 +516,7 @@ public function copyFileWithinStorage($fileIdentifier, $targetFolderIdentifier, * @return bool TRUE if the operation succeeded * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException */ - public function replaceFile($fileIdentifier, $localFilePath) + public function replaceFile(string $fileIdentifier, string $localFilePath): bool { $contents = file_get_contents($localFilePath); $written = $this->setFileContents($fileIdentifier, $contents); @@ -529,7 +532,7 @@ public function replaceFile($fileIdentifier, $localFilePath) * @param string $fileIdentifier * @return bool TRUE if deleting the file succeeded */ - public function deleteFile($fileIdentifier) + public function deleteFile(string $fileIdentifier): bool { return $this->deleteObject($fileIdentifier); } @@ -541,7 +544,7 @@ public function deleteFile($fileIdentifier) * @param bool $deleteRecursively * @return bool */ - public function deleteFolder($folderIdentifier, $deleteRecursively = false) + public function deleteFolder(string $folderIdentifier, bool $deleteRecursively = false): bool { if ($deleteRecursively) { $items = $this->getListObjects($folderIdentifier); @@ -577,14 +580,23 @@ public function deleteFolder($folderIdentifier, $deleteRecursively = false) * @throws \RuntimeException * @todo take care of replacing the file on change */ - public function getFileForLocalProcessing($fileIdentifier, $writable = true) + public function getFileForLocalProcessing(string $fileIdentifier, bool $writable = true): string { $temporaryPath = $this->getTemporaryPathForFile($fileIdentifier); - $this->s3Client->getObject([ - 'Bucket' => $this->configuration['bucket'], - 'Key' => $this->addBaseFolder($fileIdentifier), - 'SaveAs' => $temporaryPath, - ]); + try { + $this->s3Client->getObject([ + 'Bucket' => $this->configuration['bucket'], + 'Key' => $this->addBaseFolder($fileIdentifier), + 'SaveAs' => $temporaryPath, + ]); + } catch (\Aws\S3\Exception\S3Exception $exception) { + if (!$exception->getPrevious() || $exception->getPrevious()->getCode() !== 404) { + throw $exception; + } + + // Just prevent the exception content to be written in the temporary file. See next condition below + } + if (!is_file($temporaryPath)) { throw new \RuntimeException('Copying file ' . $fileIdentifier . ' to temporary path failed.', 1320577649); } @@ -606,7 +618,7 @@ public function getFileForLocalProcessing($fileIdentifier, $writable = true) * @param string $parentFolderIdentifier * @return string */ - public function createFile($fileName, $parentFolderIdentifier) + public function createFile(string $fileName, string $parentFolderIdentifier): string { $parentFolderIdentifier = $this->canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier); $identifier = $this->canonicalizeAndCheckFileIdentifier( @@ -625,7 +637,7 @@ public function createFile($fileName, $parentFolderIdentifier) * @param bool $recursive * @return string the Identifier of the new folder */ - public function createFolder($newFolderName, $parentFolderIdentifier = '', $recursive = false) + public function createFolder(string $newFolderName, string $parentFolderIdentifier = '', bool $recursive = false): string { $parentFolderIdentifier = $this->canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier); $newFolderName = trim($newFolderName, '/'); @@ -653,7 +665,7 @@ public function createFolder($newFolderName, $parentFolderIdentifier = '', $recu * @param string $fileIdentifier * @return string The file contents */ - public function getFileContents($fileIdentifier) + public function getFileContents(string $fileIdentifier): string { $result = $this->s3Client->getObject([ 'Bucket' => $this->configuration['bucket'], @@ -669,7 +681,7 @@ public function getFileContents($fileIdentifier) * @param string $contents * @return int The number of bytes written to the file */ - public function setFileContents($fileIdentifier, $contents) + public function setFileContents(string $fileIdentifier, string $contents): int { return file_put_contents($this->getStreamWrapperPath($fileIdentifier), $contents); } @@ -681,7 +693,7 @@ public function setFileContents($fileIdentifier, $contents) * @param string $newName The target path (including the file name!) * @return string The identifier of the file after renaming */ - public function renameFile($fileIdentifier, $newName) + public function renameFile(string $fileIdentifier, string $newName): string { $newName = $this->sanitizeFileName($newName); $newIdentifier = rtrim(PathUtility::dirname($fileIdentifier), '/') . '/' . $newName; @@ -697,7 +709,7 @@ public function renameFile($fileIdentifier, $newName) * @param string $newName * @return array A map of old to new file identifiers of all affected resources */ - public function renameFolder($folderIdentifier, $newName) + public function renameFolder(string $folderIdentifier, string $newName): array { $this->resetIdentifierMap(); $newName = $this->sanitizeFileName($newName); @@ -733,7 +745,7 @@ public function renameFolder($folderIdentifier, $newName) * * @return array All files which are affected, map of old => new file identifiers */ - public function moveFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName) + public function moveFolderWithinStorage(string $sourceFolderIdentifier, string $targetFolderIdentifier, string $newFolderName): array { $this->resetIdentifierMap(); @@ -762,7 +774,7 @@ public function moveFolderWithinStorage($sourceFolderIdentifier, $targetFolderId * * @return bool */ - public function copyFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName) + public function copyFolderWithinStorage(string $sourceFolderIdentifier, string $targetFolderIdentifier, string $newFolderName): bool { $newIdentifier = $targetFolderIdentifier . $newFolderName . '/'; $this->copyObject($sourceFolderIdentifier, $newIdentifier); @@ -787,7 +799,7 @@ public function copyFolderWithinStorage($sourceFolderIdentifier, $targetFolderId * @param string $folderIdentifier * @return bool TRUE if there are no files and folders within $folder */ - public function isFolderEmpty($folderIdentifier) + public function isFolderEmpty(string $folderIdentifier): bool { $result = $this->getListObjects( $folderIdentifier, @@ -824,7 +836,7 @@ public function isFolderEmpty($folderIdentifier) * @param string $identifier identifier to be checked against $folderIdentifier * @return bool TRUE if $content is within or matches $folderIdentifier */ - public function isWithin($folderIdentifier, $identifier) + public function isWithin(string $folderIdentifier, string $identifier): bool { $folderIdentifier = $this->canonicalizeAndCheckFileIdentifier($folderIdentifier); $entryIdentifier = $this->canonicalizeAndCheckFileIdentifier($identifier); @@ -845,7 +857,7 @@ public function isWithin($folderIdentifier, $identifier) * * @param string $folderIdentifier */ - public function getFolderInfoByIdentifier($folderIdentifier): array + public function getFolderInfoByIdentifier(string $folderIdentifier): array { $this->normalizeIdentifier($folderIdentifier); @@ -865,7 +877,7 @@ public function getFolderInfoByIdentifier($folderIdentifier): array * @param string $folderIdentifier * @return string File Identifier */ - public function getFileInFolder($fileName, $folderIdentifier) + public function getFileInFolder(string $fileName, string $folderIdentifier): string { $folderIdentifier = $folderIdentifier . '/' . $fileName; $this->normalizeIdentifier($folderIdentifier); @@ -890,7 +902,7 @@ public function getFileInFolder($fileName, $folderIdentifier) * @return array of FileIdentifiers * @toDo: Implement $start, $numberOfItems, $sort and $sortRev */ - public function getFilesInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = false, array $filenameFilterCallbacks = [], $sort = '', $sortRev = false) + public function getFilesInFolder(string $folderIdentifier, int $start = 0, int $numberOfItems = 0, bool $recursive = false, array $filenameFilterCallbacks = [], string $sort = '', bool $sortRev = false): array { $this->normalizeFolderIdentifier($folderIdentifier); $files = []; @@ -946,7 +958,7 @@ public function getFilesInFolder($folderIdentifier, $start = 0, $numberOfItems = * @param array $filenameFilterCallbacks callbacks for filtering the items * @return int Number of files in folder */ - public function countFilesInFolder($folderIdentifier, $recursive = false, array $filenameFilterCallbacks = []) + public function countFilesInFolder(string $folderIdentifier, bool $recursive = false, array $filenameFilterCallbacks = []): int { return count($this->getFilesInFolder($folderIdentifier, 0, 0, $recursive, $filenameFilterCallbacks)); } @@ -968,7 +980,7 @@ public function countFilesInFolder($folderIdentifier, $recursive = false, array * @return array of Folder Identifier * @toDo: Implement params $start, $numberOfItems, $sort, $sortRev */ - public function getFoldersInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = false, array $folderNameFilterCallbacks = [], $sort = '', $sortRev = false) + public function getFoldersInFolder(string $folderIdentifier, int $start = 0, int $numberOfItems = 0, bool $recursive = false, array $folderNameFilterCallbacks = [], string $sort = '', bool $sortRev = false): array { $this->normalizeIdentifier($folderIdentifier); $folders = []; @@ -1025,7 +1037,7 @@ public function getFoldersInFolder($folderIdentifier, $start = 0, $numberOfItems * @param array $folderNameFilterCallbacks callbacks for filtering the items * @return int Number of folders in folder */ - public function countFoldersInFolder($folderIdentifier, $recursive = false, array $folderNameFilterCallbacks = []) + public function countFoldersInFolder(string $folderIdentifier, bool $recursive = false, array $folderNameFilterCallbacks = []): int { return count($this->getFoldersInFolder($folderIdentifier, 0, 0, $recursive, $folderNameFilterCallbacks)); } @@ -1038,7 +1050,7 @@ public function countFoldersInFolder($folderIdentifier, $recursive = false, arra * @param string $identifier * @return void */ - public function dumpFileContents($identifier) + public function dumpFileContents(string $identifier): void { $fileContents = $this->getFileContents($identifier); echo $fileContents; @@ -1052,7 +1064,7 @@ public function dumpFileContents($identifier) * @param string $identifier * @return array */ - public function getPermissions($identifier) + public function getPermissions(string $identifier): array { return $this->getObjectPermissions($identifier); } @@ -1061,14 +1073,22 @@ public function getPermissions($identifier) * Merges the capabilites merged by the user at the storage * configuration into the actual capabilities of the driver * and returns the result. - * - * @param int $capabilities - * - * @return int */ - public function mergeConfigurationCapabilities($capabilities) + public function mergeConfigurationCapabilities(Capabilities $capabilities): Capabilities { - $this->capabilities &= $capabilities; + $allCapabilities = [ + Capabilities::CAPABILITY_BROWSABLE, + Capabilities::CAPABILITY_PUBLIC, + Capabilities::CAPABILITY_WRITABLE, + Capabilities::CAPABILITY_HIERARCHICAL_IDENTIFIERS, + ]; + + foreach ($allCapabilities as $capability) { + if ($capabilities->hasCapability($capability)) { + $this->capabilities->addCapabilities($capability); + } + } + return $this->capabilities; } @@ -1284,7 +1304,7 @@ protected function testConnection() FlashMessage::class, LocalizationUtility::translate($localizationPrefix . 'connectionTestSuccessful.message', static::EXTENSION_NAME), LocalizationUtility::translate($localizationPrefix . 'connectionTestSuccessful.title', static::EXTENSION_NAME), - FlashMessage::OK + \TYPO3\CMS\Core\Type\ContextualFeedbackSeverity::OK ); $messageQueue->addMessage($message); } catch (\Exception $exception) { @@ -1293,7 +1313,7 @@ protected function testConnection() FlashMessage::class, $exception->getMessage(), LocalizationUtility::translate($localizationPrefix . 'connectionTestFailed.title', static::EXTENSION_NAME), - FlashMessage::WARNING + \TYPO3\CMS\Core\Type\ContextualFeedbackSeverity::WARNING ); $messageQueue->addMessage($message); } @@ -1326,7 +1346,7 @@ protected function removeBaseFolder(string $identifier): string /** * @return \TYPO3\CMS\Core\Messaging\FlashMessageQueue */ - protected function getMessageQueue() + protected function getMessageQueue(): \TYPO3\CMS\Core\Messaging\FlashMessageQueue { return GeneralUtility::makeInstance(FlashMessageService::class)->getMessageQueueByIdentifier(); } @@ -1405,7 +1425,7 @@ protected function getMetaInfo($identifier): ?array * @param array $parameter * @return array */ - protected function getCachedResponse($function, $parameter) + protected function getCachedResponse($function, $parameter): array { $cacheIdentifier = $this->cachePrefix . md5($function) . '-' . md5(serialize($parameter)); @@ -1442,7 +1462,7 @@ protected function flushMetaInfoCache($identifier): void * * @return void */ - protected function resetRequestCache() + protected function resetRequestCache(): void { $this->requestCache->flush(); } @@ -1491,7 +1511,7 @@ protected function getObjectPermissions($identifier) FlashMessage::class, $exception->getMessage(), '', - FlashMessage::WARNING + \TYPO3\CMS\Core\Type\ContextualFeedbackSeverity::WARNING ); $messageQueue->addMessage($message); } @@ -1535,7 +1555,7 @@ protected function getFolder($identifier) * @param string $body * @param array $overrideArgs */ - protected function createObject($identifier, $body = '', $overrideArgs = []) + protected function createObject($identifier, $body = '', $overrideArgs = []): void { $this->normalizeIdentifier($identifier); $args = [ @@ -1555,7 +1575,7 @@ protected function createObject($identifier, $body = '', $overrideArgs = []) * @param string $newIdentifier * @return void */ - protected function renameObject($identifier, $newIdentifier) + protected function renameObject($identifier, $newIdentifier): void { rename($this->getStreamWrapperPath($identifier), $this->getStreamWrapperPath($newIdentifier)); $this->identifierMap[$identifier] = $newIdentifier; @@ -1573,7 +1593,7 @@ protected function renameObject($identifier, $newIdentifier) * @return string Output string with any characters not matching [.a-zA-Z0-9_-] is substituted by '_' and trailing dots removed * @throws Exception\InvalidFileNameException */ - public function sanitizeFileName($fileName, $charset = '') + public function sanitizeFileName(string $fileName, string $charset = ''): string { return GeneralUtility::makeInstance(FileNameService::class) ->sanitizeFileName((string)$fileName, (string)$charset); @@ -1586,7 +1606,7 @@ public function sanitizeFileName($fileName, $charset = '') * @return string * @throws \RuntimeException */ - protected function getStreamWrapperPath($file) + protected function getStreamWrapperPath($file): string { $basePath = $this->streamWrapperProtocol . '://' . $this->configuration['bucket'] . '/'; if ($file instanceof FileInterface) { @@ -1605,7 +1625,7 @@ protected function getStreamWrapperPath($file) /** * @param string &$identifier */ - protected function normalizeIdentifier(&$identifier) + protected function normalizeIdentifier(&$identifier): void { $identifier = str_replace('//', '/', $identifier); if ($identifier !== '/') { @@ -1632,7 +1652,7 @@ protected function normalizeFolderIdentifier(&$identifier) /** * @return void */ - protected function resetIdentifierMap() + protected function resetIdentifierMap(): void { $this->identifierMap = []; } @@ -1646,13 +1666,13 @@ protected function resetIdentifierMap() * @param string $filter * @return array */ - protected function getSubObjects($identifier, $recursive = true, $filter = self::FILTER_ALL) + protected function getSubObjects($identifier, $recursive = true, $filter = self::FILTER_ALL): array { $result = $this->getListObjects($identifier); if (!is_array($result['Contents'] ?? null)) { return []; } - return array_filter($result['Contents'], function ($object) use ($identifier, $recursive, $filter) { + return array_filter($result['Contents'], function (&$object) use ($identifier, $recursive, $filter) { return ( $object['Key'] !== $identifier && ( @@ -1675,7 +1695,7 @@ protected function getSubObjects($identifier, $recursive = true, $filter = self: * @param array $overrideArgs * @return array */ - protected function getListObjects($identifier, $overrideArgs = []) + protected function getListObjects($identifier, $overrideArgs = []): array { $args = [ 'Bucket' => $this->configuration['bucket'] ?? '', @@ -1740,7 +1760,7 @@ protected function getListObjects($identifier, $overrideArgs = []) * @param string $newDirName The new directory name the folder will reside in * @return void */ - protected function renameSubFolder(Folder $folder, $newDirName) + protected function renameSubFolder(Folder $folder, $newDirName): void { foreach ($this->getSubObjects($folder->getIdentifier(), false) as $subObject) { $subObjectIdentifier = $subObject['Key']; @@ -1761,7 +1781,7 @@ protected function renameSubFolder(Folder $folder, $newDirName) * @param string $identifier * @param string $targetIdentifier */ - protected function copyObject($identifier, $targetIdentifier) + protected function copyObject($identifier, $targetIdentifier): void { $this->s3Client->copyObject([ 'Bucket' => $this->configuration['bucket'], @@ -1776,7 +1796,7 @@ protected function copyObject($identifier, $targetIdentifier) * @param array $objects S3 Objects as arrays with at least the Key field set * @return void */ - protected function sortObjectsForNestedFolderOperations(array &$objects) + protected function sortObjectsForNestedFolderOperations(array &$objects): void { usort($objects, function ($object1, $object2) { if (substr($object1['Key'], -1) === '/') { @@ -1803,7 +1823,7 @@ protected function sortObjectsForNestedFolderOperations(array &$objects) * @param string $pathAndFilename * @return string */ - protected function getCacheControl($pathAndFilename) + protected function getCacheControl($pathAndFilename): string { $cacheControl = $this->configuration['cacheHeaderDuration'] ? 'max-age=' . $this->configuration['cacheHeaderDuration'] : ''; $cacheControlHooks = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][self::EXTENSION_KEY]['getCacheControl'] ?? null; @@ -1825,7 +1845,7 @@ protected function getCacheControl($pathAndFilename) /** * @return ResourceStorage */ - protected function getStorage() + protected function getStorage(): ResourceStorage { if (!$this->storage) { /** @var $storageRepository \TYPO3\CMS\Core\Resource\StorageRepository */ @@ -1838,7 +1858,7 @@ protected function getStorage() /** * @return string */ - protected function getProcessingFolder() + protected function getProcessingFolder(): string { if (!$this->processingFolder) { $confProcessingFolder = $this->getStorage()->getProcessingFolder()->getName(); @@ -1853,7 +1873,7 @@ protected function getProcessingFolder() * @param string $identifier * @return bool */ - protected function isDir($identifier) + protected function isDir($identifier): bool { return substr($identifier, -1) === '/'; } diff --git a/Classes/Index/Extractor.php b/Classes/Index/Extractor.php index 6132b28c..188cd69d 100644 --- a/Classes/Index/Extractor.php +++ b/Classes/Index/Extractor.php @@ -20,6 +20,7 @@ use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface; use TYPO3\CMS\Core\Resource\File; use TYPO3\CMS\Core\Resource\FileInterface; +use TYPO3\CMS\Core\Resource\FileType; use TYPO3\CMS\Core\Resource\Index\ExtractorInterface; use TYPO3\CMS\Core\Type\File\ImageInfo; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -51,7 +52,7 @@ public function __construct() */ public function getFileTypeRestrictions() { - return [File::FILETYPE_IMAGE]; + return [FileType::IMAGE]; } /** @@ -104,7 +105,7 @@ public function getExecutionPriority() */ public function canProcess(File $file) { - return $file->getType() == File::FILETYPE_IMAGE && $file->getStorage()->getDriverType() === AmazonS3Driver::DRIVER_TYPE; + return $file->isImage() && $file->getStorage()->getDriverType() === AmazonS3Driver::DRIVER_TYPE; } /** diff --git a/Classes/Service/MetaDataUpdateService.php b/Classes/Service/MetaDataUpdateService.php index 1831fc20..5ae4cb16 100644 --- a/Classes/Service/MetaDataUpdateService.php +++ b/Classes/Service/MetaDataUpdateService.php @@ -19,6 +19,7 @@ use AUS\AusDriverAmazonS3\Index\Extractor; use TYPO3\CMS\Core\Resource\AbstractFile; use TYPO3\CMS\Core\Resource\Exception\InvalidUidException; +use TYPO3\CMS\Core\Resource\FileType; use TYPO3\CMS\Core\Resource\Index\MetaDataRepository; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Resource\ResourceStorage; @@ -35,7 +36,7 @@ class MetaDataUpdateService implements SingletonInterface */ public function updateMetadata(array $fileProperties): void { - if ($fileProperties['type'] !== AbstractFile::FILETYPE_IMAGE) { + if ($fileProperties['type'] !== FileType::IMAGE->value) { return; } diff --git a/Configuration/FlexForm/AmazonS3DriverFlexForm.xml b/Configuration/FlexForm/AmazonS3DriverFlexForm.xml index d53aa672..c10c3bd6 100644 --- a/Configuration/FlexForm/AmazonS3DriverFlexForm.xml +++ b/Configuration/FlexForm/AmazonS3DriverFlexForm.xml @@ -1,298 +1,313 @@ - - 1 - - - array - - - - - - input - 30 - - - - - - - - select - selectSingle - - - US East (Ohio) - us-east-2 - us-east-2 - - - US East (N. Virginia) - us-east-1 - us-east-1 - - - US West (N. California) - us-west-1 - us-west-1 - - - US West (Oregon) - us-west-2 - us-west-2 - - - Africa (Cape Town) - af-south-1 - af-south-1 - - - Asia Pacific (Hong Kong) - ap-east-1 - ap-east-1 - - - Asia Pacific (Jakarta) - ap-southeast-3 - ap-southeast-3 - - - Asia Pacific (Mumbai) - ap-south-1 - ap-south-1 - - - Asia Pacific (Osaka) - ap-northeast-3 - ap-northeast-3 - - - Asia Pacific (Seoul) - ap-northeast-2 - ap-northeast-2 - - - Asia Pacific (Singapore) - ap-southeast-1 - ap-southeast-1 - - - Asia Pacific (Sydney) - ap-southeast-2 - ap-southeast-2 - - - Asia Pacific (Tokyo) - ap-northeast-1 - ap-northeast-1 - - - Canada (Central) - ca-central-1 - ca-central-1 - - - China (Beijing) - cn-north-1 - cn-north-1 - - - China (Ningxia) - cn-northwest-1 - cn-northwest-1 - - - Europe (Frankfurt) - eu-central-1 - eu-central-1 - - - Europe (Ireland) - eu-west-1 - eu-west-1 - - - Europe (London) - eu-west-2 - eu-west-2 - - - Europe (Milan) - eu-south-1 - eu-south-1 - - - Europe (Paris) - eu-west-3 - eu-west-3 - - - Europe (Stockholm) - eu-north-1 - eu-north-1 - - - South America (São Paulo) - sa-east-1 - sa-east-1 - - - Middle East (Bahrain) - me-south-1 - me-south-1 - - - Middle East (UAE) - me-central-1 - me-central-1 - - - AWS GovCloud (US-East) - us-gov-east-1 - us-gov-east-1 - - - AWS GovCloud (US-West) - us-gov-west-1 - us-gov-west-1 - - - 1 - 1 - 1 - - - - - - - LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.customHost-description - - input - inputLink - 30 - - - - - - - LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.pathStyleEndpoint-description - - check - 0 - - - - - - - - input - 30 - - - - - - - - input - 30 - password - - - - - - - LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.publicBaseUrl-description - - input - 30 - - - - - - - LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.baseFolder-description - - input - 30 - - - - - - - - input - 30 - int - - 0 - - - - - - - - - select - selectSingle - 1 - 1 - 1 - - - LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.protocol.auto - auto - - - https:// - https:// - - - http:// - http:// - - - - - - - - - - select - selectSingle - 1 - 1 - 1 - - - LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.signature.auto - 0 - - - v4 - v4 - - - - - - - - - - check - 1 - - - - - - - - select - selectSingle - 1 - 1 - 1 - - - LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.fileContentHash.ignore - ignore - - - LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.fileContentHash.receive - receive - - - LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.fileContentHash.force - force - - - - - - - + + array + + + + + input + 30 + + + + + + select + selectSingle + + + US East (Ohio) - us-east-2 + us-east-2 + + + US East (N. Virginia) - us-east-1 + us-east-1 + + + US West (N. California) - us-west-1 + us-west-1 + + + US West (Oregon) - us-west-2 + us-west-2 + + + Africa (Cape Town) - af-south-1 + af-south-1 + + + Asia Pacific (Hong Kong) - ap-east-1 + ap-east-1 + + + Asia Pacific (Jakarta) - ap-southeast-3 + ap-southeast-3 + + + Asia Pacific (Mumbai) - ap-south-1 + ap-south-1 + + + Asia Pacific (Osaka) - ap-northeast-3 + ap-northeast-3 + + + Asia Pacific (Seoul) - ap-northeast-2 + ap-northeast-2 + + + Asia Pacific (Singapore) - ap-southeast-1 + ap-southeast-1 + + + Asia Pacific (Sydney) - ap-southeast-2 + ap-southeast-2 + + + Asia Pacific (Tokyo) - ap-northeast-1 + ap-northeast-1 + + + Canada (Central) - ca-central-1 + ca-central-1 + + + China (Beijing) - cn-north-1 + cn-north-1 + + + China (Ningxia) - cn-northwest-1 + cn-northwest-1 + + + Europe (Frankfurt) - eu-central-1 + eu-central-1 + + + Europe (Ireland) - eu-west-1 + eu-west-1 + + + Europe (London) - eu-west-2 + eu-west-2 + + + Europe (Milan) - eu-south-1 + eu-south-1 + + + Europe (Paris) - eu-west-3 + eu-west-3 + + + Europe (Stockholm) - eu-north-1 + eu-north-1 + + + South America (São Paulo) - sa-east-1 + sa-east-1 + + + Middle East (Bahrain) - me-south-1 + me-south-1 + + + Middle East (UAE) - me-central-1 + me-central-1 + + + AWS GovCloud (US-East) - us-gov-east-1 + us-gov-east-1 + + + AWS GovCloud (US-West) - us-gov-west-1 + us-gov-west-1 + + + 1 + 1 + 1 + + + + + + LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.customHost-description + + + input + inputLink + 30 + + + + + + LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.pathStyleEndpoint-description + + + check + 0 + + + + + + input + 30 + + + + + + input + 30 + password + + + + + + LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.publicBaseUrl-description + + + input + 30 + + + + + + LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.baseFolder-description + + + input + 30 + + + + + + input + 30 + int + + 0 + + + + + + + select + selectSingle + 1 + 1 + 1 + + + + LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.protocol.auto + + auto + + + https:// + https:// + + + http:// + http:// + + + + + + + + select + selectSingle + 1 + 1 + 1 + + + + LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.signature.auto + + 0 + + + v4 + v4 + + + + + + + + check + 1 + + + + + + select + selectSingle + 1 + 1 + 1 + + + + LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.fileContentHash.ignore + + ignore + + + + LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.fileContentHash.receive + + receive + + + + LLL:EXT:aus_driver_amazon_s3/Resources/Private/Language/locallang_flexform.xlf:driverConfiguration.fileContentHash.force + + force + + + + + + diff --git a/Resources/Private/Language/locallang_flexform.xlf b/Resources/Private/Language/locallang_flexform.xlf index 089da377..63d9ccdd 100644 --- a/Resources/Private/Language/locallang_flexform.xlf +++ b/Resources/Private/Language/locallang_flexform.xlf @@ -87,7 +87,7 @@ Receive from AWS if possible - Receive frolm AWS with a fallback to download and calculate (slowest, might download large files) + Receive from AWS with a fallback to download and calculate (slowest, might download large files) diff --git a/Tests/Unit/Index/ExtractorTest.php b/Tests/Unit/Index/ExtractorTest.php index dba3dad3..d5c94d55 100644 --- a/Tests/Unit/Index/ExtractorTest.php +++ b/Tests/Unit/Index/ExtractorTest.php @@ -53,7 +53,8 @@ public function testCanProcessImageFileType() $storage->getDriverType()->willReturn(AmazonS3Driver::DRIVER_TYPE)->shouldBeCalled(); $file = $this->prophesize(File::class); $file->getStorage()->willReturn($storage->reveal()); - $file->getType()->willReturn(File::FILETYPE_IMAGE)->shouldBeCalled(); + $file->getType()->willReturn(File::FILETYPE_IMAGE); + $file->isImage()->willReturn(true); $this->assertEquals(true, $this->extractor->canProcess($file->reveal())); } @@ -68,6 +69,7 @@ public function testCanNotProcessOtherDriverType() $file = $this->prophesize(File::class); $file->getStorage()->willReturn($storage->reveal()); $file->getType()->willReturn(File::FILETYPE_IMAGE); + $file->isImage()->willReturn(true); $this->assertEquals(false, $this->extractor->canProcess($file->reveal())); } @@ -81,7 +83,8 @@ public function testCanNotProcessUnknownFileType() $storage->getDriverType()->willReturn(AmazonS3Driver::DRIVER_TYPE); $file = $this->prophesize(File::class); $file->getStorage()->willReturn($storage->reveal()); - $file->getType()->willReturn(File::FILETYPE_UNKNOWN)->shouldBeCalled(); + $file->getType()->willReturn(File::FILETYPE_UNKNOWN); + $file->isImage()->willReturn(false); $this->assertEquals(false, $this->extractor->canProcess($file->reveal())); } @@ -95,7 +98,8 @@ public function testCanNotProcessApplicationFileType() $storage->getDriverType()->willReturn(AmazonS3Driver::DRIVER_TYPE); $file = $this->prophesize(File::class); $file->getStorage()->willReturn($storage->reveal()); - $file->getType()->willReturn(File::FILETYPE_APPLICATION)->shouldBeCalled(); + $file->getType()->willReturn(File::FILETYPE_APPLICATION); + $file->isImage()->willReturn(false); $this->assertEquals(false, $this->extractor->canProcess($file->reveal())); } @@ -109,7 +113,8 @@ public function testCanNotProcessVideoFileType() $storage->getDriverType()->willReturn(AmazonS3Driver::DRIVER_TYPE); $file = $this->prophesize(File::class); $file->getStorage()->willReturn($storage->reveal()); - $file->getType()->willReturn(File::FILETYPE_VIDEO)->shouldBeCalled(); + $file->getType()->willReturn(File::FILETYPE_VIDEO); + $file->isImage()->willReturn(false); $this->assertEquals(false, $this->extractor->canProcess($file->reveal())); } @@ -123,7 +128,8 @@ public function testCanNotProcessAudioFileType() $storage->getDriverType()->willReturn(AmazonS3Driver::DRIVER_TYPE); $file = $this->prophesize(File::class); $file->getStorage()->willReturn($storage->reveal()); - $file->getType()->willReturn(File::FILETYPE_AUDIO)->shouldBeCalled(); + $file->getType()->willReturn(File::FILETYPE_AUDIO); + $file->isImage()->willReturn(false); $this->assertEquals(false, $this->extractor->canProcess($file->reveal())); } @@ -137,7 +143,8 @@ public function testCanNotProcessTextFileType() $storage->getDriverType()->willReturn(AmazonS3Driver::DRIVER_TYPE); $file = $this->prophesize(File::class); $file->getStorage()->willReturn($storage->reveal()); - $file->getType()->willReturn(File::FILETYPE_TEXT)->shouldBeCalled(); + $file->getType()->willReturn(File::FILETYPE_TEXT); + $file->isImage()->willReturn(false); $this->assertEquals(false, $this->extractor->canProcess($file->reveal())); } diff --git a/composer.json b/composer.json index f5ed5fd3..78400c86 100644 --- a/composer.json +++ b/composer.json @@ -9,17 +9,16 @@ }, "license": "LGPL-3.0-or-later", "require": { - "php": ">=8.2.0 <8.5.0", - "typo3/cms-core": "~v11.5.41 || ~v12.4.36", + "typo3/cms-core": "^13.4", "aws/aws-sdk-php": "^3.288" }, "require-dev": { - "pluswerk/grumphp-config": "^5.0", - "typo3/testing-framework": "^7.1.1 || ^8.2.7", - "phpspec/prophecy": "^1.22.0", - "phpspec/prophecy-phpunit": "^2.4.0", - "saschaegerer/phpstan-typo3": "^1.10.2", - "ssch/typo3-rector": "^1.3.5" + "pluswerk/grumphp-config": "^10.1.3", + "typo3/testing-framework": "^8.0", + "phpspec/prophecy": "dev-master", + "phpspec/prophecy-phpunit": "dev-master", + "saschaegerer/phpstan-typo3": "^2.0.0", + "ssch/typo3-rector": "^3.1.0" }, "autoload": { "psr-4": { @@ -61,12 +60,6 @@ "extension-key": "aus_driver_amazon_s3", "cms-package-dir": "{$vendor-dir}/typo3/cms", "web-dir": ".Build/Web" - }, - "pluswerk/grumphp-config": { - "auto-setting": true - }, - "grumphp": { - "config-default-path": "vendor/pluswerk/grumphp-config/grumphp.yml" } } } diff --git a/ext_emconf.php b/ext_emconf.php index 4bc1df71..e05afe5d 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -5,7 +5,7 @@ 'title' => 'Amazon AWS S3 FAL driver (CDN)', 'description' => 'Provides a FAL driver for the Amazon Web Service S3.', 'category' => 'be', - 'version' => '1.12.1', + 'version' => '1.13.500', 'state' => 'stable', 'uploadfolder' => false, 'createDirs' => '', @@ -17,7 +17,7 @@ [ 'depends' => [ - 'typo3' => '11.5.30-12.4.99', + 'typo3' => '13.4.0-13.4.99', ], 'conflicts' => [], 'suggests' => [], diff --git a/ext_localconf.php b/ext_localconf.php index 0d3612bc..c51ec09d 100755 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -13,12 +13,23 @@ // register extractor \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Index\ExtractorRegistry::class)->registerExtractionService(\AUS\AusDriverAmazonS3\Index\Extractor::class); -$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_metainfocache'] = [ - 'backend' => \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class, - 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, -]; +if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_metainfocache'])) { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_metainfocache'] = []; +} +if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_requestcache'])) { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_requestcache'] = []; +} -$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_requestcache'] = [ - 'backend' => \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class, - 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, -]; +if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_metainfocache']['backend'])) { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_metainfocache']['backend'] = \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class; +} +if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_requestcache']['backend'])) { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_requestcache']['backend'] = \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class; +} + +if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_metainfocache']['frontend'])) { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_metainfocache']['frontend'] = \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class; +} +if (!isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_requestcache']['frontend'])) { + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['ausdriveramazons3_requestcache']['frontend'] = \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class; +} \ No newline at end of file diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 00000000..6236ff8c --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,19 @@ +parameters: + ignoreErrors: + - + message: '#^Call to function assert\(\) with true will always evaluate to true\.$#' + identifier: function.alreadyNarrowedType + count: 3 + path: packages/grumphp-xliff-task/src/XliffLinter.php + + - + message: '#^Instanceof between DOMElement and DOMElement will always evaluate to true\.$#' + identifier: instanceof.alwaysTrue + count: 3 + path: packages/grumphp-xliff-task/src/XliffLinter.php + + - + message: '#^Method Andersundsehr\\RectorP\\PartialCommand\:\:getAllFiles\(\) should return list\ but returns array\\.$#' + identifier: return.type + count: 1 + path: packages/rector-p/src/PartialCommand.php diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..e178ba6a --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,7 @@ +includes: + - phpstan-baseline.neon + - vendor/andersundsehr/phpstan-git-files/extension.php + +parameters: + level: 8 + reportUnmatchedIgnoredErrors: false diff --git a/rector.php b/rector.php new file mode 100644 index 00000000..0f267f78 --- /dev/null +++ b/rector.php @@ -0,0 +1,42 @@ +parallel(); + $rectorConfig->importNames(); + $rectorConfig->importShortClasses(); + $rectorConfig->cacheClass(FileCacheStorage::class); + $rectorConfig->cacheDirectory('./var/cache/rector'); + + $rectorConfig->paths( + array_filter(explode("\n", (string)shell_exec("git ls-files | xargs ls -d 2>/dev/null | grep -E '\.(php)$'"))) + ); + + // define sets of rules + $rectorConfig->sets( + [ + ...RectorSettings::sets(true), + ...RectorSettings::setsTypo3(false), + ] + ); + + // remove some rules + // ignore some files + $rectorConfig->skip( + [ + ...RectorSettings::skip(), + ...RectorSettings::skipTypo3(), + + /** + * rector should not touch these files + */ + //__DIR__ . '/src/Example', + //__DIR__ . '/src/Example.php', + ] + ); +};