‪TYPO3CMS  ‪main
IndexedSearchCTypeMigration.php
Go to the documentation of this file.
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 
19 
20 use Doctrine\DBAL\Schema\Column;
22 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
26 
31 #[UpgradeWizard('indexedSearchCTypeMigration')]
33 {
34  protected const ‪TABLE_CONTENT = 'tt_content';
35  protected const ‪TABLE_BACKEND_USER_GROUPS = 'be_groups';
36 
37  public function ‪__construct(
38  private readonly ‪Registry $registry,
39  private readonly ‪ConnectionPool $connectionPool,
40  ) {}
41 
42  public function ‪getTitle(): string
43  {
44  return 'Migrate "Indexed Search" plugins to content elements.';
45  }
46 
47  public function ‪getDescription(): string
48  {
49  return 'The "Indexed Search" plugin is now registered as content elements. Update migrates existing records and backend user permissions.';
50  }
51 
52  public function ‪getPrerequisites(): array
53  {
54  return [
55  DatabaseUpdatedPrerequisite::class,
56  ];
57  }
58 
59  public function ‪updateNecessary(): bool
60  {
62  || (
66  );
67  }
68 
69  public function ‪executeUpdate(): bool
70  {
72  $this->‪updateContentElements();
73  }
77  ) {
79  }
80 
81  return true;
82  }
83 
84  protected function ‪columnsExistInContentTable(): bool
85  {
86  $schemaManager = $this->connectionPool
87  ->getConnectionForTable(self::TABLE_CONTENT)
88  ->createSchemaManager();
89 
90  $tableColumnNames = array_flip(
91  array_map(
92  static fn(Column $column) => $column->getName(),
93  $schemaManager->listTableColumns(self::TABLE_CONTENT)
94  )
95  );
96 
97  foreach (['CType', 'list_type'] as $column) {
98  if (!isset($tableColumnNames[$column])) {
99  return false;
100  }
101  }
102 
103  return true;
104  }
105 
106  protected function ‪columnsExistInBackendUserGroupsTable(): bool
107  {
108  $schemaManager = $this->connectionPool
109  ->getConnectionForTable(self::TABLE_BACKEND_USER_GROUPS)
110  ->createSchemaManager();
111 
112  return isset($schemaManager->listTableColumns(self::TABLE_BACKEND_USER_GROUPS)['explicit_allowdeny']);
113  }
114 
115  protected function ‪hasContentElementsToUpdate(): bool
116  {
117  return (bool)$this->‪getPreparedQueryBuilderForContentElements()->count('uid')->executeQuery()->fetchOne();
118  }
119 
120  protected function ‪hasBackendUserGroupsToUpdate(): bool
121  {
122  return (bool)$this->‪getPreparedQueryBuilderForBackendUserGroups()->count('uid')->executeQuery()->fetchOne();
123  }
124 
126  {
127  return (bool)$this->registry->get('installUpdate', BackendGroupsExplicitAllowDenyMigration::class, false);
128  }
129 
130  protected function ‪getContentElementsToUpdate(): array
131  {
132  return $this->‪getPreparedQueryBuilderForContentElements()->select('uid', 'CType', 'list_type')->executeQuery()->fetchAllAssociative();
133  }
134 
135  protected function ‪getBackendUserGroupsToUpdate(): array
136  {
137  return $this->‪getPreparedQueryBuilderForBackendUserGroups()->select('uid', 'explicit_allowdeny')->executeQuery()->fetchAllAssociative();
138  }
139 
140  protected function ‪getPreparedQueryBuilderForContentElements(): QueryBuilder
141  {
142  $queryBuilder = $this->connectionPool->getQueryBuilderForTable(self::TABLE_CONTENT);
143  $queryBuilder->getRestrictions()->removeAll();
144  $queryBuilder
145  ->from(self::TABLE_CONTENT)
146  ->where(
147  $queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('list')),
148  $queryBuilder->expr()->eq('list_type', $queryBuilder->createNamedParameter('indexedsearch_pi2')),
149  );
150 
151  return $queryBuilder;
152  }
153 
154  protected function ‪getPreparedQueryBuilderForBackendUserGroups(): QueryBuilder
155  {
156  $queryBuilder = $this->connectionPool->getQueryBuilderForTable(self::TABLE_BACKEND_USER_GROUPS);
157  $queryBuilder->getRestrictions()->removeAll();
158  $queryBuilder
159  ->from(self::TABLE_BACKEND_USER_GROUPS)
160  ->where(
161  $queryBuilder->expr()->like(
162  'explicit_allowdeny',
163  $queryBuilder->createNamedParameter(
164  '%' . $queryBuilder->escapeLikeWildcards('tt_content:list_type:indexedsearch_pi2') . '%'
165  )
166  ),
167  );
168 
169  return $queryBuilder;
170  }
171 
172  protected function ‪updateContentElements(): void
173  {
174  $connection = $this->connectionPool->getConnectionForTable(self::TABLE_CONTENT);
175 
176  foreach ($this->‪getContentElementsToUpdate() as ‪$record) {
177  $connection->update(
178  self::TABLE_CONTENT,
179  [
180  'CType' => 'indexedsearch_pi2',
181  'list_type' => '',
182  ],
183  ['uid' => (int)‪$record['uid']]
184  );
185  }
186  }
187 
188  protected function ‪updateBackendUserGroups(): void
189  {
190  $connection = $this->connectionPool->getConnectionForTable(self::TABLE_BACKEND_USER_GROUPS);
191 
192  foreach ($this->‪getBackendUserGroupsToUpdate() as ‪$record) {
193  ‪$fields = ‪GeneralUtility::trimExplode(',', ‪$record['explicit_allowdeny'], true);
194  foreach (‪$fields as $key => $field) {
195  if ($field === 'tt_content:list_type:indexedsearch_pi2') {
196  unset(‪$fields[$key]);
197  ‪$fields[] = 'tt_content:CType:indexedsearch_pi2';
198  }
199  }
200 
201  $connection->update(
202  self::TABLE_BACKEND_USER_GROUPS,
203  [
204  'explicit_allowdeny' => implode(',', array_unique(‪$fields)),
205  ],
206  ['uid' => (int)‪$record['uid']]
207  );
208  }
209  }
210 }
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\getTitle
‪getTitle()
Definition: IndexedSearchCTypeMigration.php:42
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\columnsExistInContentTable
‪columnsExistInContentTable()
Definition: IndexedSearchCTypeMigration.php:84
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration
Definition: IndexedSearchCTypeMigration.php:33
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\getDescription
‪getDescription()
Definition: IndexedSearchCTypeMigration.php:47
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\hasBackendUserGroupsToUpdate
‪hasBackendUserGroupsToUpdate()
Definition: IndexedSearchCTypeMigration.php:120
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\TABLE_BACKEND_USER_GROUPS
‪const TABLE_BACKEND_USER_GROUPS
Definition: IndexedSearchCTypeMigration.php:35
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\columnsExistInBackendUserGroupsTable
‪columnsExistInBackendUserGroupsTable()
Definition: IndexedSearchCTypeMigration.php:106
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\updateBackendUserGroups
‪updateBackendUserGroups()
Definition: IndexedSearchCTypeMigration.php:188
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\getPreparedQueryBuilderForContentElements
‪getPreparedQueryBuilderForContentElements()
Definition: IndexedSearchCTypeMigration.php:140
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\__construct
‪__construct(private readonly Registry $registry, private readonly ConnectionPool $connectionPool,)
Definition: IndexedSearchCTypeMigration.php:37
‪TYPO3\CMS\Core\Registry
Definition: Registry.php:33
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\TABLE_CONTENT
‪const TABLE_CONTENT
Definition: IndexedSearchCTypeMigration.php:34
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\getBackendUserGroupsToUpdate
‪getBackendUserGroupsToUpdate()
Definition: IndexedSearchCTypeMigration.php:135
‪TYPO3\CMS\Install\Attribute\UpgradeWizard
Definition: UpgradeWizard.php:25
‪$fields
‪$fields
Definition: pages.php:5
‪TYPO3\CMS\Install\Updates
Definition: LegacyClassesForIde.php:22
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\getPrerequisites
‪getPrerequisites()
Definition: IndexedSearchCTypeMigration.php:52
‪TYPO3\CMS\Webhooks\Message\$record
‪identifier readonly int readonly array $record
Definition: PageModificationMessage.php:36
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\backendGroupsExplicitAllowDenyMigrationHasBeenExecuted
‪backendGroupsExplicitAllowDenyMigrationHasBeenExecuted()
Definition: IndexedSearchCTypeMigration.php:125
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\updateContentElements
‪updateContentElements()
Definition: IndexedSearchCTypeMigration.php:172
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\hasContentElementsToUpdate
‪hasContentElementsToUpdate()
Definition: IndexedSearchCTypeMigration.php:115
‪TYPO3\CMS\Install\Updates\UpgradeWizardInterface
Definition: UpgradeWizardInterface.php:24
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\executeUpdate
‪executeUpdate()
Definition: IndexedSearchCTypeMigration.php:69
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\getContentElementsToUpdate
‪getContentElementsToUpdate()
Definition: IndexedSearchCTypeMigration.php:130
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\getPreparedQueryBuilderForBackendUserGroups
‪getPreparedQueryBuilderForBackendUserGroups()
Definition: IndexedSearchCTypeMigration.php:154
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822
‪TYPO3\CMS\Install\Updates\IndexedSearchCTypeMigration\updateNecessary
‪updateNecessary()
Definition: IndexedSearchCTypeMigration.php:59