66
77use Doctrine \DBAL \Exception ;
88use Doctrine \DBAL \Result ;
9+ use ElementareTeilchen \Unduplicator \Exception \UnduplicatorException ;
10+ use ElementareTeilchen \Unduplicator \Metadata \MetadataUpdateHandler ;
911use Symfony \Component \Console \Command \Command ;
1012use Symfony \Component \Console \Input \InputInterface ;
1113use Symfony \Component \Console \Input \InputOption ;
1618use TYPO3 \CMS \Core \Database \Connection ;
1719use TYPO3 \CMS \Core \Database \ConnectionPool ;
1820use TYPO3 \CMS \Core \Database \ReferenceIndex ;
21+ use TYPO3 \CMS \Core \Resource \StorageRepository ;
1922use TYPO3 \CMS \Core \Utility \ExtensionManagementUtility ;
2023use TYPO3 \CMS \Core \Utility \GeneralUtility ;
21- use ElementareTeilchen \Unduplicator \Metadata \MetadataUpdateHandler ;
22- use ElementareTeilchen \Unduplicator \Exception \UnduplicatorException ;
2324
2425/***************************************************************
2526 * Copyright notice
5859 */
5960class UnduplicateCommand extends Command
6061{
61- /**
62- * @var ConnectionPool
63- */
64- private $ connectionPool ;
6562
6663 /**
6764 * @var bool
@@ -73,6 +70,11 @@ class UnduplicateCommand extends Command
7370 */
7471 private $ keepOldest = false ;
7572
73+ /**
74+ * @var int
75+ */
76+ private $ storage = -1 ;
77+
7678 /**
7779 * @var SymfonyStyle
7880 */
@@ -93,10 +95,12 @@ class UnduplicateCommand extends Command
9395 */
9496 private $ metadataHandler ;
9597
96- public function __construct ($ name = null , ConnectionPool $ connectionPool = null )
98+ public function __construct (
99+ private readonly ConnectionPool $ connectionPool ,
100+ private readonly StorageRepository $ storageRepository
101+ )
97102 {
98- parent ::__construct ($ name );
99- $ this ->connectionPool = $ connectionPool ?: GeneralUtility::makeInstance (ConnectionPool::class);
103+ parent ::__construct ();
100104 }
101105
102106 /**
@@ -206,7 +210,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
206210 $ this ->dryRun = $ input ->getOption ("dry-run " );
207211 $ this ->keepOldest = $ input ->getOption ("keep-oldest " );
208212 $ onlyThisIdentifier = $ input ->getOption ("identifier " );
209- $ onlyThisStorage = (int )$ input ->getOption ("storage " );
213+ $ this -> storage = (int )$ input ->getOption ("storage " ) ?? - 1 ;
210214
211215 if ($ input ->hasArgument ("meta-fields " )) {
212216 $ this ->fieldsToCheck = array_map ("trim " , explode (", " , $ input ->getOption ("meta-fields " )));
@@ -220,7 +224,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
220224 $ this ->metadataHandler = new MetadataUpdateHandler ($ this ->dryRun , $ this ->input , $ this ->output , $ this ->fieldsToCheck , $ this ->connectionPool );
221225
222226 try {
223- $ this ->runOn ($ onlyThisIdentifier, $ onlyThisStorage );
227+ $ this ->runOn ($ onlyThisIdentifier );
224228 } catch (UnduplicatorException $ e ) {
225229 $ this ->output ->writeln ("<error> " . $ e ->getMessage () . "</error> " );
226230 }
@@ -233,20 +237,21 @@ protected function execute(InputInterface $input, OutputInterface $output): int
233237 * @return void
234238 * @throws Exception
235239 */
236- public function runOn (mixed $ onlyThisIdentifier, int $ onlyThisStorage ): void
240+ public function runOn (mixed $ onlyThisIdentifier ): void
237241 {
238242 $ hasConflicts = false ;
239- $ statement = $ this ->findDuplicates ($ onlyThisIdentifier, $ onlyThisStorage );
243+ $ statement = $ this ->findDuplicates ($ onlyThisIdentifier );
240244 $ foundDuplicates = 0 ;
241245 while ($ row = $ statement ->fetchAssociative ()) {
242246 $ identifier = $ row ['identifier ' ] ?? "" ;
243247 if ($ identifier === "" ) {
244248 $ this ->output ->warning ("Found empty identifier " );
245249 continue ;
246250 }
247- $ storage = (int )$ row ['storage ' ];
248251
252+ $ storage = (int )$ row ['storage ' ];
249253 $ files = $ this ->findDuplicateFilesForIdentifier ($ identifier , $ storage );
254+
250255 $ masterMetadataRecords = null ;
251256 $ masterFileIdentifier = null ;
252257 $ masterFileUid = null ;
@@ -284,10 +289,10 @@ public function runOn(mixed $onlyThisIdentifier, int $onlyThisStorage): void
284289 * Database may be case-insensitive, e.g. charset "utf8mb5", collation "utf8mb4_unicode_ci".
285290 *
286291 * @param mixed $onlyThisIdentifier
287- * @param int $onlyThisStorage
292+ * @param int $storage
288293 * @return Result
289294 */
290- public function findDuplicates (mixed $ onlyThisIdentifier, int $ onlyThisStorage ): Result
295+ public function findDuplicates (mixed $ onlyThisIdentifier ): Result
291296 {
292297 $ queryBuilder = $ this ->connectionPool ->getQueryBuilderForTable ("sys_file " );
293298 $ queryBuilder ->count ("* " )
@@ -300,10 +305,10 @@ public function findDuplicates(mixed $onlyThisIdentifier, int $onlyThisStorage):
300305 $ queryBuilder ->createNamedParameter ($ onlyThisIdentifier , \PDO ::PARAM_STR )
301306 );
302307 }
303- if ($ onlyThisStorage > -1 ) {
308+ if ($ this -> storage > -1 ) {
304309 $ whereExpressions [] = $ queryBuilder ->expr ()->eq (
305310 "storage " ,
306- $ queryBuilder ->createNamedParameter ($ onlyThisStorage , Connection::PARAM_INT )
311+ $ queryBuilder ->createNamedParameter ($ this -> storage , Connection::PARAM_INT )
307312 );
308313 }
309314 if ($ whereExpressions ) {
@@ -578,7 +583,7 @@ private function markOldFileReferenceRecordDeleted(int $oldFileUid)
578583 private function findAndDeleteOldProcessedFile (int $ oldFileUid ): void
579584 {
580585 $ recordQueryBuilder = $ this ->connectionPool ->getQueryBuilderForTable ('sys_file_processedfile ' );
581- $ results = $ recordQueryBuilder ->select ('identifier ' )
586+ $ results = $ recordQueryBuilder ->select ('identifier ' , ' storage ' )
582587 ->from ('sys_file_processedfile ' )
583588 ->where (
584589 $ recordQueryBuilder ->expr ()->eq (
@@ -590,7 +595,7 @@ private function findAndDeleteOldProcessedFile(int $oldFileUid): void
590595 while ($ record = $ results ->fetchAssociative ()) {
591596 // delete each file from file system
592597 $ this ->output ->writeln ('<info>Deleting processed file ' . $ record ['identifier ' ] . '</info> ' );
593- $ this ->deleteProcessedFile ($ record ['identifier ' ]);
598+ $ this ->deleteProcessedFile ($ record ['identifier ' ], $ record [ ' storage ' ] );
594599 }
595600 // delete all records in sys_file_processedfile
596601 $ recordQueryBuilder ->delete ('sys_file_processedfile ' )
@@ -603,14 +608,18 @@ private function findAndDeleteOldProcessedFile(int $oldFileUid): void
603608 ->executeStatement ();
604609 }
605610
606- private function deleteProcessedFile (mixed $ identifier ): void
611+ private function deleteProcessedFile (mixed $ identifier, int $ storageId ): void
607612 {
608- $ file = Environment::getPublicPath () . '/fileadmin ' . $ identifier ;
613+ $ storage = $ this ->storageRepository ->getStorageObject ($ storageId );
614+ $ storagePath = Environment::getPublicPath () . DIRECTORY_SEPARATOR . $ storage ->getRootLevelFolder ()->getPublicUrl ();
615+ $ storagePath = rtrim ($ storagePath , '/ ' );
616+ //$this->output->writeln('<info>Deleting processed file ' . $storagePath . $identifier . '</info>');
617+ $ file = $ storagePath . $ identifier ;
609618 if (file_exists ($ file )) {
610619 unlink ($ file );
611620 // delete all empty parent folders
612621 $ dir = dirname ($ file );
613- while ($ dir !== Environment:: getPublicPath () . ' /fileadmin ' && count (scandir ($ dir )) === 2 ) {
622+ while ($ dir !== $ storagePath && count (scandir ($ dir )) === 2 ) {
614623 rmdir ($ dir );
615624 $ dir = dirname ($ dir );
616625 }
0 commit comments