Passed
Push — master ( 9bc0b7...38c90a )
by
unknown
15:07
created

SynchronizeFolderRelations::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
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
namespace TYPO3\CMS\Core\Resource;
19
20
use TYPO3\CMS\Core\Database\Connection;
21
use TYPO3\CMS\Core\Database\ConnectionPool;
22
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
23
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
24
use TYPO3\CMS\Core\Localization\LanguageService;
25
use TYPO3\CMS\Core\Messaging\FlashMessage;
26
use TYPO3\CMS\Core\Messaging\FlashMessageService;
27
use TYPO3\CMS\Core\Resource\Event\AfterFolderRenamedEvent;
28
use TYPO3\CMS\Core\Utility\GeneralUtility;
29
30
/**
31
 * Event listeners to synchronize folder relations after some
32
 * action like renaming or moving of a folder, took place.
33
 *
34
 * @internal
35
 */
36
class SynchronizeFolderRelations
37
{
38
    protected ConnectionPool $connectionPool;
39
    protected FlashMessageService $flashMessageService;
40
41
    public function __construct(ConnectionPool $connectionPool, FlashMessageService $flashMessageService)
42
    {
43
        $this->connectionPool = $connectionPool;
44
        $this->flashMessageService = $flashMessageService;
45
    }
46
47
    /**
48
     * Synchronize file collection relations after a folder was renamed
49
     *
50
     * @param AfterFolderRenamedEvent $event
51
     *
52
     * @throws \TYPO3\CMS\Core\Exception
53
     */
54
    public function synchronizeFileCollectionsAfterRename(AfterFolderRenamedEvent $event): void
55
    {
56
        $storageId = $event->getSourceFolder()->getStorage()->getUid();
57
        $sourceIdentifier = $event->getSourceFolder()->getIdentifier();
58
        $targetIdentifier = $event->getFolder()->getIdentifier();
59
60
        $synchronized = 0;
61
        $queryBuilder = $this->getPreparedQueryBuilder('sys_file_collection');
62
        $statement = $queryBuilder
63
            ->select('uid', 'folder')
64
            ->from('sys_file_collection')
65
            ->where(
66
                $queryBuilder->expr()->like('folder', $queryBuilder->quote($sourceIdentifier . '%')),
67
                $queryBuilder->expr()->eq('storage', $queryBuilder->createNamedParameter($storageId, Connection::PARAM_INT)),
68
                $queryBuilder->expr()->eq('type', $queryBuilder->createNamedParameter('folder'))
69
            )
70
            ->execute();
71
72
        while ($row = $statement->fetch()) {
73
            $folder = preg_replace(sprintf('/^%s/', preg_quote($sourceIdentifier, '/')), $targetIdentifier, $row['folder']) ?? '';
74
            if ($folder !== '') {
75
                $queryBuilder = $this->getPreparedQueryBuilder('sys_file_collection');
76
                $synchronized += (int)$queryBuilder
77
                    ->update('sys_file_collection')
78
                    ->set('folder', $folder)
79
                    ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter((int)$row['uid'], Connection::PARAM_INT)))
80
                    ->execute();
81
            }
82
        }
83
84
        if ($synchronized) {
85
            $this->addFlashMessage($synchronized, 'sys_file_collection', 'afterFolderRenamed');
86
        }
87
    }
88
89
    /**
90
     * Synchronize file mount relations after a folder was renamed
91
     *
92
     * @param AfterFolderRenamedEvent $event
93
     *
94
     * @throws \TYPO3\CMS\Core\Exception
95
     */
96
    public function synchronizeFilemountsAfterRename(AfterFolderRenamedEvent $event): void
97
    {
98
        $storageId = $event->getSourceFolder()->getStorage()->getUid();
99
        $sourceIdentifier = $event->getSourceFolder()->getIdentifier();
100
        $targetIdentifier = $event->getFolder()->getIdentifier();
101
102
        $synchronized = 0;
103
        $queryBuilder = $this->getPreparedQueryBuilder('sys_filemounts');
104
        $statement = $queryBuilder
105
            ->select('uid', 'path')
106
            ->from('sys_filemounts')
107
            ->where(
108
                $queryBuilder->expr()->like('path', $queryBuilder->quote($sourceIdentifier . '%')),
109
                $queryBuilder->expr()->eq('base', $queryBuilder->createNamedParameter((string)$storageId))
110
            )
111
            ->execute();
112
113
        while ($row = $statement->fetch()) {
114
            $path = preg_replace(sprintf('/^%s/', preg_quote($sourceIdentifier, '/')), $targetIdentifier, $row['path']) ?? '';
115
            if ($path !== '') {
116
                $queryBuilder = $this->getPreparedQueryBuilder('sys_filemounts');
117
                $synchronized += (int)$queryBuilder
118
                    ->update('sys_filemounts')
119
                    ->set('path', $path)
120
                    ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter((int)$row['uid'], Connection::PARAM_INT)))
121
                    ->execute();
122
            }
123
        }
124
125
        if ($synchronized) {
126
            $this->addFlashMessage($synchronized, 'sys_filemounts', 'afterFolderRenamed');
127
        }
128
    }
129
130
    /**
131
     * Add a flash message for a successfully performed synchronization
132
     *
133
     * @param int $updatedRelationsCount The amount of relations synchronized
134
     * @param string $table The relation table the synchronization was performed on
135
     * @param string $event The event after which the synchronization was performed
136
     *
137
     * @throws \TYPO3\CMS\Core\Exception
138
     */
139
    protected function addFlashMessage(int $updatedRelationsCount, string $table, string $event): void
140
    {
141
        $languageService = $this->getLanguageServcie();
142
        $message = sprintf(
143
            $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:synchronizeFolderRelations.' . $event),
144
            $updatedRelationsCount,
145
            $languageService->sL($GLOBALS['TCA'][$table]['ctrl']['title']),
146
        );
147
148
        $this->flashMessageService
149
            ->getMessageQueueByIdentifier()
150
            ->enqueue(GeneralUtility::makeInstance(FlashMessage::class, $message, '', FlashMessage::OK, true));
151
    }
152
153
    protected function getPreparedQueryBuilder(string $table): QueryBuilder
154
    {
155
        $queryBuilder = $this->connectionPool->getQueryBuilderForTable($table);
156
        $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
157
        return $queryBuilder;
158
    }
159
160
    protected function getLanguageServcie(): LanguageService
161
    {
162
        return $GLOBALS['LANG'];
163
    }
164
}
165