TYPO3 CMS  TYPO3_8-7
PlainDataResolver.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
23 
32 {
36  protected $tableName;
37 
41  protected $liveIds;
42 
46  protected $sortingStatement;
47 
51  protected $workspaceId;
52 
56  protected $keepLiveIds = false;
57 
61  protected $keepDeletePlaceholder = false;
62 
66  protected $keepMovePlaceholder = true;
67 
71  protected $resolvedIds;
72 
78  public function __construct($tableName, array $liveIds, array $sortingStatement = null)
79  {
80  $this->tableName = $tableName;
81  $this->liveIds = $this->reindex($liveIds);
82  $this->sortingStatement = $sortingStatement;
83  }
84 
90  public function setWorkspaceId($workspaceId)
91  {
92  $this->workspaceId = (int)$workspaceId;
93  }
94 
101  public function setKeepLiveIds($keepLiveIds)
102  {
103  $this->keepLiveIds = (bool)$keepLiveIds;
104  return $this;
105  }
106 
114  {
115  $this->keepDeletePlaceholder = (bool)$keepDeletePlaceholder;
116  return $this;
117  }
118 
126  {
127  $this->keepMovePlaceholder = (bool)$keepMovePlaceholder;
128  return $this;
129  }
130 
134  public function get()
135  {
136  if (isset($this->resolvedIds)) {
137  return $this->resolvedIds;
138  }
139 
140  $this->resolvedIds = $this->processVersionOverlays($this->liveIds);
141  if ($this->resolvedIds !== $this->liveIds) {
142  $this->resolvedIds = $this->reindex($this->resolvedIds);
143  }
144 
145  $tempIds = $this->processSorting($this->resolvedIds);
146  if ($tempIds !== $this->resolvedIds) {
147  $this->resolvedIds = $this->reindex($tempIds);
148  }
149 
150  $tempIds = $this->applyLiveIds($this->resolvedIds);
151  if ($tempIds !== $this->resolvedIds) {
152  $this->resolvedIds = $this->reindex($tempIds);
153  }
154 
155  return $this->resolvedIds;
156  }
157 
165  public function processVersionOverlays(array $ids)
166  {
167  if (empty($this->workspaceId) || !$this->isWorkspaceEnabled() || empty($ids)) {
168  return $ids;
169  }
170 
171  $ids = $this->reindex(
172  $this->processVersionMovePlaceholders($ids)
173  );
174  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
175  ->getQueryBuilderForTable($this->tableName);
176 
177  $queryBuilder->getRestrictions()->removeAll();
178 
179  $result = $queryBuilder
180  ->select('uid', 't3ver_oid', 't3ver_state')
181  ->from($this->tableName)
182  ->where(
183  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
184  $queryBuilder->expr()->in(
185  't3ver_oid',
186  $queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY)
187  ),
188  $queryBuilder->expr()->eq(
189  't3ver_wsid',
190  $queryBuilder->createNamedParameter($this->workspaceId, \PDO::PARAM_INT)
191  )
192  )
193  ->execute();
194 
195  while ($version = $result->fetch()) {
196  $liveReferenceId = $version['t3ver_oid'];
197  $versionId = $version['uid'];
198  if (isset($ids[$liveReferenceId])) {
199  if (!$this->keepDeletePlaceholder
200  && VersionState::cast($version['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)
201  ) {
202  unset($ids[$liveReferenceId]);
203  } else {
204  $ids[$liveReferenceId] = $versionId;
205  }
206  }
207  }
208 
209  return $ids;
210  }
211 
219  public function processVersionMovePlaceholders(array $ids)
220  {
221  // Early return on insufficient data-set
222  if (empty($this->workspaceId) || !$this->isWorkspaceEnabled() || empty($ids)) {
223  return $ids;
224  }
225 
226  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
227  ->getQueryBuilderForTable($this->tableName);
228 
229  $queryBuilder->getRestrictions()->removeAll();
230 
231  $result = $queryBuilder
232  ->select('uid', 't3ver_move_id')
233  ->from($this->tableName)
234  ->where(
235  $queryBuilder->expr()->neq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
236  $queryBuilder->expr()->eq(
237  't3ver_state',
238  $queryBuilder->createNamedParameter((string)VersionState::MOVE_PLACEHOLDER, \PDO::PARAM_INT)
239  ),
240  $queryBuilder->expr()->eq(
241  't3ver_wsid',
242  $queryBuilder->createNamedParameter($this->workspaceId, \PDO::PARAM_INT)
243  ),
244  $queryBuilder->expr()->in(
245  't3ver_move_id',
246  $queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY)
247  )
248  )
249  ->execute();
250 
251  while ($movePlaceholder = $result->fetch()) {
252  $liveReferenceId = $movePlaceholder['t3ver_move_id'];
253  $movePlaceholderId = $movePlaceholder['uid'];
254  // Substitute MOVE_PLACEHOLDER and purge live reference
255  if (isset($ids[$movePlaceholderId])) {
256  $ids[$movePlaceholderId] = $liveReferenceId;
257  unset($ids[$liveReferenceId]);
258  } elseif (!$this->keepMovePlaceholder) {
259  // Just purge live reference
260  unset($ids[$liveReferenceId]);
261  }
262  }
263 
264  return $ids;
265  }
266 
275  public function processSorting(array $ids)
276  {
277  // Early return on missing sorting statement or insufficient data-set
278  if (empty($this->sortingStatement) || count($ids) < 2) {
279  return $ids;
280  }
281 
282  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
283  ->getQueryBuilderForTable($this->tableName);
284 
285  $queryBuilder->getRestrictions()->removeAll();
286 
287  $queryBuilder
288  ->select('uid')
289  ->from($this->tableName)
290  ->where(
291  $queryBuilder->expr()->in(
292  'uid',
293  $queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY)
294  )
295  );
296 
297  if (!empty($this->sortingStatement)) {
298  foreach ($this->sortingStatement as $sortingStatement) {
299  $queryBuilder->add('orderBy', $sortingStatement, true);
300  }
301  }
302 
303  $sortedIds = $queryBuilder->execute()->fetchAll();
304 
305  return array_column($sortedIds, 'uid');
306  }
307 
317  public function applyLiveIds(array $ids)
318  {
319  if (!$this->keepLiveIds || !$this->isWorkspaceEnabled() || empty($ids)) {
320  return $ids;
321  }
322 
323  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
324  ->getQueryBuilderForTable($this->tableName);
325 
326  $queryBuilder->getRestrictions()->removeAll();
327 
328  $result = $queryBuilder
329  ->select('uid', 't3ver_oid')
330  ->from($this->tableName)
331  ->where(
332  $queryBuilder->expr()->in(
333  'uid',
334  $queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY)
335  )
336  )
337  ->execute();
338 
339  $versionIds = [];
340  while ($record = $result->fetch()) {
341  $liveId = $record['uid'];
342  $versionIds[$liveId] = $record['t3ver_oid'];
343  }
344 
345  foreach ($ids as $id) {
346  if (!empty($versionIds[$id])) {
347  $ids[$id] = $versionIds[$id];
348  }
349  }
350 
351  return $ids;
352  }
353 
360  protected function reindex(array $ids)
361  {
362  if (empty($ids)) {
363  return $ids;
364  }
365  $ids = array_values($ids);
366  $ids = array_combine($ids, $ids);
367  return $ids;
368  }
369 
373  protected function isWorkspaceEnabled()
374  {
375  if (ExtensionManagementUtility::isLoaded('version')) {
376  return BackendUtility::isTableWorkspaceEnabled($this->tableName);
377  }
378  return false;
379  }
380 
384  protected function isLocalizationEnabled()
385  {
386  return BackendUtility::isTableLocalizable($this->tableName);
387  }
388 }
static makeInstance($className,... $constructorArguments)
__construct($tableName, array $liveIds, array $sortingStatement=null)