TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
PlainDataResolver.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\DataHandling;
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 
22 
31 {
35  protected $tableName;
36 
40  protected $liveIds;
41 
45  protected $sortingStatement;
46 
50  protected $workspaceId;
51 
55  protected $keepLiveIds = false;
56 
60  protected $keepDeletePlaceholder = false;
61 
65  protected $keepMovePlaceholder = true;
66 
70  protected $resolvedIds;
71 
77  public function __construct($tableName, array $liveIds, array $sortingStatement = null)
78  {
79  $this->tableName = $tableName;
80  $this->liveIds = $this->reindex($liveIds);
81  $this->sortingStatement = $sortingStatement;
82  }
83 
89  public function setWorkspaceId($workspaceId)
90  {
91  $this->workspaceId = (int)$workspaceId;
92  }
93 
100  public function setKeepLiveIds($keepLiveIds)
101  {
102  $this->keepLiveIds = (bool)$keepLiveIds;
103  return $this;
104  }
105 
113  {
114  $this->keepDeletePlaceholder = (bool)$keepDeletePlaceholder;
115  return $this;
116  }
117 
125  {
126  $this->keepMovePlaceholder = (bool)$keepMovePlaceholder;
127  return $this;
128  }
129 
133  public function get()
134  {
135  if (isset($this->resolvedIds)) {
136  return $this->resolvedIds;
137  }
138 
139  $ids = $this->reindex(
140  $this->processVersionOverlays($this->liveIds)
141  );
142  $ids = $this->reindex(
143  $this->processSorting($ids)
144  );
145  $ids = $this->reindex(
146  $this->applyLiveIds($ids)
147  );
148 
149  $this->resolvedIds = $ids;
150  return $this->resolvedIds;
151  }
152 
160  public function processVersionOverlays(array $ids)
161  {
162  if (empty($this->workspaceId) || !$this->isWorkspaceEnabled() || empty($ids)) {
163  return $ids;
164  }
165 
166  $ids = $this->reindex(
167  $this->processVersionMovePlaceholders($ids)
168  );
169  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
170  ->getQueryBuilderForTable($this->tableName);
171 
172  $queryBuilder->getRestrictions()->removeAll();
173 
174  $result = $queryBuilder
175  ->select('uid', 't3ver_oid', 't3ver_state')
176  ->from($this->tableName)
177  ->where(
178  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
179  $queryBuilder->expr()->in(
180  't3ver_oid',
181  $queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY)
182  ),
183  $queryBuilder->expr()->eq(
184  't3ver_wsid',
185  $queryBuilder->createNamedParameter($this->workspaceId, \PDO::PARAM_INT)
186  )
187  )
188  ->execute();
189 
190  while ($version = $result->fetch()) {
191  $liveReferenceId = $version['t3ver_oid'];
192  $versionId = $version['uid'];
193  if (isset($ids[$liveReferenceId])) {
194  if (!$this->keepDeletePlaceholder
195  && VersionState::cast($version['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)
196  ) {
197  unset($ids[$liveReferenceId]);
198  } else {
199  $ids[$liveReferenceId] = $versionId;
200  }
201  }
202  }
203 
204  return $ids;
205  }
206 
214  public function processVersionMovePlaceholders(array $ids)
215  {
216  // Early return on insufficient data-set
217  if (empty($this->workspaceId) || !$this->isWorkspaceEnabled() || empty($ids)) {
218  return $ids;
219  }
220 
221  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
222  ->getQueryBuilderForTable($this->tableName);
223 
224  $queryBuilder->getRestrictions()->removeAll();
225 
226  $result = $queryBuilder
227  ->select('uid', 't3ver_move_id')
228  ->from($this->tableName)
229  ->where(
230  $queryBuilder->expr()->neq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
231  $queryBuilder->expr()->eq(
232  't3ver_state',
233  $queryBuilder->createNamedParameter((string)VersionState::MOVE_PLACEHOLDER, \PDO::PARAM_INT)
234  ),
235  $queryBuilder->expr()->eq(
236  't3ver_wsid',
237  $queryBuilder->createNamedParameter($this->workspaceId, \PDO::PARAM_INT)
238  ),
239  $queryBuilder->expr()->in(
240  't3ver_move_id',
241  $queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY)
242  )
243  )
244  ->execute();
245 
246  while ($movePlaceholder = $result->fetch()) {
247  $liveReferenceId = $movePlaceholder['t3ver_move_id'];
248  $movePlaceholderId = $movePlaceholder['uid'];
249  // Substitute MOVE_PLACEHOLDER and purge live reference
250  if (isset($ids[$movePlaceholderId])) {
251  $ids[$movePlaceholderId] = $liveReferenceId;
252  unset($ids[$liveReferenceId]);
253  // Just purge live reference
254  } elseif (!$this->keepMovePlaceholder) {
255  unset($ids[$liveReferenceId]);
256  }
257  }
258 
259  return $ids;
260  }
261 
270  public function processSorting(array $ids)
271  {
272  // Early return on missing sorting statement or insufficient data-set
273  if (empty($this->sortingStatement) || count($ids) < 2) {
274  return $ids;
275  }
276 
277  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
278  ->getQueryBuilderForTable($this->tableName);
279 
280  $queryBuilder->getRestrictions()->removeAll();
281 
282  $queryBuilder
283  ->select('uid')
284  ->from($this->tableName)
285  ->where(
286  $queryBuilder->expr()->in(
287  'uid',
288  $queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY)
289  )
290  );
291 
292  if (!empty($this->sortingStatement)) {
293  foreach ($this->sortingStatement as $sortingStatement) {
294  $queryBuilder->add('orderBy', $sortingStatement, true);
295  }
296  }
297 
298  $sortedIds = $queryBuilder->execute()->fetchAll();
299 
300  return array_column($sortedIds, 'uid');
301  }
302 
312  public function applyLiveIds(array $ids)
313  {
314  if (!$this->keepLiveIds || !$this->isWorkspaceEnabled() || empty($ids)) {
315  return $ids;
316  }
317 
318  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
319  ->getQueryBuilderForTable($this->tableName);
320 
321  $queryBuilder->getRestrictions()->removeAll();
322 
323  $result = $queryBuilder
324  ->select('uid', 't3ver_oid')
325  ->from($this->tableName)
326  ->where(
327  $queryBuilder->expr()->in(
328  'uid',
329  $queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY)
330  )
331  )
332  ->execute();
333 
334  $versionIds = [];
335  while ($record = $result->fetch()) {
336  $liveId = $record['uid'];
337  $versionIds[$liveId] = $record['t3ver_oid'];
338  }
339 
340  foreach ($ids as $id) {
341  if (!empty($versionIds[$id])) {
342  $ids[$id] = $versionIds[$id];
343  }
344  }
345 
346  return $ids;
347  }
348 
355  protected function reindex(array $ids)
356  {
357  if (empty($ids)) {
358  return $ids;
359  }
360  $ids = array_values($ids);
361  $ids = array_combine($ids, $ids);
362  return $ids;
363  }
364 
368  protected function isWorkspaceEnabled()
369  {
370  return BackendUtility::isTableWorkspaceEnabled($this->tableName);
371  }
372 
376  protected function isLocalizationEnabled()
377  {
378  return BackendUtility::isTableLocalizable($this->tableName);
379  }
380 }
__construct($tableName, array $liveIds, array $sortingStatement=null)
static makeInstance($className,...$constructorArguments)