‪TYPO3CMS  11.5
ReferenceIndexUpdater.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 TYPO3\CMS\Backend\Utility\BackendUtility;
25 
35 {
41  protected $updateRegistry = [];
42 
51  protected $updateRegistryToItem = [];
52 
58  protected $dropRegistry = [];
59 
67  public function registerForUpdate(string $table, int $uid, int $workspace): void
68  {
69  if ($workspace && !BackendUtility::isTableWorkspaceEnabled($table)) {
70  // If a user is in some workspace and changes relations of not workspace aware
71  // records, the reference index update needs to be performed as if the user
72  // is in live workspace. This is detected here and the update is registered for live.
73  $workspace = 0;
74  }
75  if (!isset($this->updateRegistry[$workspace][$table])) {
76  $this->updateRegistry[$workspace][$table] = [];
77  }
78  if (!in_array($uid, $this->updateRegistry[$workspace][$table], true)) {
79  $this->updateRegistry[$workspace][$table][] = $uid;
80  }
81  }
82 
94  public function registerUpdateForReferencesToItem(string $table, int $uid, int $workspace, int $targetWorkspace = null): void
95  {
96  if ($workspace && !BackendUtility::isTableWorkspaceEnabled($table)) {
97  // If a user is in some workspace and changes relations of not workspace aware
98  // records, the reference index update needs to be performed as if the user
99  // is in live workspace. This is detected here and the update is registered for live.
100  $workspace = 0;
101  }
102  if ($targetWorkspace === null) {
103  $targetWorkspace = $workspace;
104  }
105  if (!isset($this->‪updateRegistryToItem[$workspace][$table])) {
106  $this->‪updateRegistryToItem[$workspace][$table] = [];
107  }
109  'uid' => $uid,
110  'targetWorkspace' => $targetWorkspace,
111  ];
112  if (!in_array(‪$recordAndTargetWorkspace, $this->‪updateRegistryToItem[$workspace][$table], true)) {
113  $this->‪updateRegistryToItem[$workspace][$table][] = ‪$recordAndTargetWorkspace;
114  }
115  }
116 
127  public function ‪registerForDrop(string $table, int $uid, int $workspace): void
128  {
129  if ($workspace && !BackendUtility::isTableWorkspaceEnabled($table)) {
130  // If a user is in some workspace and changes relations of not workspace aware
131  // records, the reference index update needs to be performed as if the user
132  // is in live workspace. This is detected here and the update is registered for live.
133  $workspace = 0;
134  }
135  if (!isset($this->dropRegistry[$workspace][$table])) {
136  $this->dropRegistry[$workspace][$table] = [];
137  }
138  if (!in_array($uid, $this->dropRegistry[$workspace][$table], true)) {
139  $this->dropRegistry[$workspace][$table][] = $uid;
140  }
141  }
142 
146  public function ‪update(): void
147  {
148  // Register updates to an item for update
149  foreach ($this->‪updateRegistryToItem as $workspace => $tableArray) {
150  foreach ($tableArray as $table => $recordArray) {
151  foreach ($recordArray as $item) {
152  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex');
153  $statement = $queryBuilder
154  ->select('tablename', 'recuid')
155  ->from('sys_refindex')
156  ->where(
157  $queryBuilder->expr()->eq('ref_table', $queryBuilder->createNamedParameter($table)),
158  $queryBuilder->expr()->eq('ref_uid', $queryBuilder->createNamedParameter($item['uid'], ‪Connection::PARAM_INT)),
159  $queryBuilder->expr()->eq('workspace', $queryBuilder->createNamedParameter($workspace, ‪Connection::PARAM_INT))
160  )
161  ->executeQuery();
162  while ($row = $statement->fetchAssociative()) {
163  $this->registerForUpdate($row['tablename'], (int)$row['recuid'], (int)$item['targetWorkspace']);
164  }
165  }
166  }
167  }
168  $this->‪updateRegistryToItem = [];
169 
170  // Drop rows from reference index if requested. Note this is performed *after* update-to-item, to
171  // find rows pointing to a record and register updates before rows are dropped. Needed if a record
172  // changes the workspace during publish: In this case all records pointing to the record in a workspace
173  // need to be registered for update for live workspace and after that the workspace rows can be dropped.
174  foreach ($this->dropRegistry as $workspace => $tableArray) {
175  foreach ($tableArray as $table => $uidArray) {
176  foreach ($uidArray as $uid) {
177  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex');
178  $queryBuilder->delete('sys_refindex')
179  ->where(
180  $queryBuilder->expr()->eq('workspace', $queryBuilder->createNamedParameter($workspace, ‪Connection::PARAM_INT)),
181  $queryBuilder->expr()->orX(
182  $queryBuilder->expr()->andX(
183  $queryBuilder->expr()->eq('tablename', $queryBuilder->createNamedParameter($table)),
184  $queryBuilder->expr()->eq('recuid', $queryBuilder->createNamedParameter($uid, ‪Connection::PARAM_INT))
185  ),
186  $queryBuilder->expr()->andX(
187  $queryBuilder->expr()->eq('ref_table', $queryBuilder->createNamedParameter($table)),
188  $queryBuilder->expr()->eq('ref_uid', $queryBuilder->createNamedParameter($uid, ‪Connection::PARAM_INT))
189  )
190  )
191  )
192  ->executeStatement();
193  }
194  }
195  }
196  $this->dropRegistry = [];
197 
198  // Perform reference index updates
199  $referenceIndex = GeneralUtility::makeInstance(ReferenceIndex::class);
200  foreach ($this->updateRegistry as $workspace => $tableArray) {
201  $referenceIndex->setWorkspaceId($workspace);
202  foreach ($tableArray as $table => $uidArray) {
203  foreach ($uidArray as $uid) {
204  $referenceIndex->updateRefIndexTable($table, $uid);
205  }
206  }
207  }
208  $this->updateRegistry = [];
209  }
210 }
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:49
‪TYPO3\CMS\Core\DataHandling\ReferenceIndexUpdater\updateRegistryToItem
‪array< int, $updateRegistry=array();protected array< int, $updateRegistryToItem=array();protected array< int, $dropRegistry=array();public function registerForUpdate(string $table, int $uid, int $workspace):void { if( $workspace &&!BackendUtility::isTableWorkspaceEnabled( $table)) { $workspace=0;} if(!isset( $this->updateRegistry[ $workspace][ $table])) { $this->updateRegistry[ $workspace][ $table]=[];} if(!in_array( $uid, $this->updateRegistry[ $workspace][ $table], true)) { $this->updateRegistry[ $workspace][ $table][]=$uid;} } public function registerUpdateForReferencesToItem(string $table, int $uid, int $workspace, int $targetWorkspace=null):void { if( $workspace &&!BackendUtility::isTableWorkspaceEnabled( $table)) { $workspace=0;} if( $targetWorkspace===null) { $targetWorkspace=$workspace;} if(!isset( $this->updateRegistryToItem[ $workspace][ $table])) { $this-> updateRegistryToItem[$workspace][$table]
Definition: ReferenceIndexUpdater.php:103
‪TYPO3\CMS\Core\Database\ReferenceIndex
Definition: ReferenceIndex.php:42
‪TYPO3\CMS\Core\DataHandling
Definition: DataHandler.php:16
‪TYPO3\CMS\Core\DataHandling\ReferenceIndexUpdater\registerForDrop
‪if(!in_array($recordAndTargetWorkspace, $this->updateRegistryToItem[$workspace][$table], true)) registerForDrop(string $table, int $uid, int $workspace)
Definition: ReferenceIndexUpdater.php:124
‪TYPO3\CMS\Core\DataHandling\ReferenceIndexUpdater\$recordAndTargetWorkspace
‪$recordAndTargetWorkspace
Definition: ReferenceIndexUpdater.php:105
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\DataHandling\ReferenceIndexUpdater
Definition: ReferenceIndexUpdater.php:35
‪TYPO3\CMS\Core\DataHandling\ReferenceIndexUpdater\update
‪update()
Definition: ReferenceIndexUpdater.php:143