‪TYPO3CMS  ‪main
WorkspaceNewPlaceholderRemovalMigration.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 Psr\Log\LoggerAwareInterface;
21 use Psr\Log\LoggerAwareTrait;
22 use TYPO3\CMS\Backend\Utility\BackendUtility;
26 
44 {
45  use LoggerAwareTrait;
46 
47  public function ‪getTitle(): string
48  {
49  return 'Scan for new versioned records of workspaces and migrate the placeholder and versioned records into one record.';
50  }
51 
56  public function ‪hasPotentialUpdateForTable(string $tableName): bool
57  {
58  return BackendUtility::isTableWorkspaceEnabled($tableName);
59  }
60 
61  public function ‪updateTableRow(string $tableName, array $row): array
62  {
63  $versionState = (int)($row['t3ver_state'] ?? 0);
64  if ($versionState === 1) {
65  $versionedRecord = $this->‪fetchVersionedRecord($tableName, (int)$row['uid']);
66  if ($versionedRecord === null) {
67  return $row;
68  }
69  foreach ($versionedRecord as $fieldName => $value) {
70  if (in_array($fieldName, ['uid', 'pid', 'deleted', 't3ver_state', 't3ver_oid'], true)) {
71  continue;
72  }
73  if ($this->‪isMMField($tableName, (string)$fieldName)) {
74  $this->‪transferMMValues($tableName, (string)$fieldName, (int)$versionedRecord['uid'], (int)$row['uid']);
75  continue;
76  }
77  $row[$fieldName] = $value;
78  }
79  } elseif ($versionState === -1) {
80  // Delete this row, as it has no use anymore.
81  // This is safe to do since the uid of the t3ver_state=1 record is always lower than the -1 one,
82  // so the record has been handled already. Rows are always sorted by uid in the row updater.
83  $row['deleted'] = 1;
84  }
85  return $row;
86  }
87 
93  protected function ‪fetchVersionedRecord(string $tableName, int ‪$uid): ?array
94  {
95  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($tableName);
96  $queryBuilder->getRestrictions()->removeAll();
97  $row = $queryBuilder
98  ->select('*')
99  ->from($tableName)
100  ->where(
101  $queryBuilder->expr()->eq('t3ver_state', $queryBuilder->createNamedParameter(-1, ‪Connection::PARAM_INT)),
102  $queryBuilder->expr()->eq('t3ver_oid', $queryBuilder->createNamedParameter(‪$uid, ‪Connection::PARAM_INT))
103  )
104  ->executeQuery()
105  ->fetchAssociative();
106  return is_array($row) ? $row : null;
107  }
108 
109  protected function ‪isMMField(string $tableName, string $fieldName): bool
110  {
111  $fieldConfig = ‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'] ?? null;
112  if (!is_array($fieldConfig)) {
113  return false;
114  }
115  if (isset($fieldConfig['MM'])) {
116  return true;
117  }
118  return false;
119  }
120 
126  protected function ‪transferMMValues(string $tableName, string $fieldName, int $originalUid, int $newUid): void
127  {
128  $fieldConfig = ‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'] ?? null;
129 
130  $mmTable = $fieldConfig['MM'];
131  $matchMMFields = $fieldConfig['MM_match_fields'] ?? null;
132  $matchMMFieldsMultiple = $fieldConfig['MM_oppositeUsage'] ?? null;
133  $isOnRightSide = is_array($matchMMFieldsMultiple);
134  $relationFieldName = $isOnRightSide ? 'uid_local' : 'uid_foreign';
135  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($mmTable);
136  $queryBuilder->update($mmTable)
137  ->set($relationFieldName, $newUid, true, ‪Connection::PARAM_INT)
138  ->where(
139  $queryBuilder->expr()->eq($relationFieldName, $queryBuilder->createNamedParameter($originalUid, ‪Connection::PARAM_INT))
140  );
141  if ($matchMMFields) {
142  foreach ($matchMMFields as $matchMMFieldName => $matchMMFieldValue) {
143  $queryBuilder->andWhere(
144  $queryBuilder->expr()->eq($matchMMFieldName, $queryBuilder->createNamedParameter($matchMMFieldValue))
145  );
146  }
147  }
148  $queryBuilder->executeStatement();
149  }
150 }
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:47
‪TYPO3\CMS\Install\Updates\RowUpdater\WorkspaceNewPlaceholderRemovalMigration\fetchVersionedRecord
‪array null fetchVersionedRecord(string $tableName, int $uid)
Definition: WorkspaceNewPlaceholderRemovalMigration.php:93
‪TYPO3\CMS\Install\Updates\RowUpdater\RowUpdaterInterface
Definition: RowUpdaterInterface.php:24
‪TYPO3\CMS\Install\Updates\RowUpdater\WorkspaceNewPlaceholderRemovalMigration\isMMField
‪isMMField(string $tableName, string $fieldName)
Definition: WorkspaceNewPlaceholderRemovalMigration.php:109
‪TYPO3\CMS\Install\Updates\RowUpdater\WorkspaceNewPlaceholderRemovalMigration
Definition: WorkspaceNewPlaceholderRemovalMigration.php:44
‪TYPO3\CMS\Install\Updates\RowUpdater
Definition: L18nDiffsourceToJsonMigration.php:18
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:36
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Install\Updates\RowUpdater\WorkspaceNewPlaceholderRemovalMigration\updateTableRow
‪updateTableRow(string $tableName, array $row)
Definition: WorkspaceNewPlaceholderRemovalMigration.php:61
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:51
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Install\Updates\RowUpdater\WorkspaceNewPlaceholderRemovalMigration\transferMMValues
‪transferMMValues(string $tableName, string $fieldName, int $originalUid, int $newUid)
Definition: WorkspaceNewPlaceholderRemovalMigration.php:126
‪TYPO3\CMS\Install\Updates\RowUpdater\WorkspaceNewPlaceholderRemovalMigration\getTitle
‪getTitle()
Definition: WorkspaceNewPlaceholderRemovalMigration.php:47
‪TYPO3\CMS\Install\Updates\RowUpdater\WorkspaceNewPlaceholderRemovalMigration\hasPotentialUpdateForTable
‪bool hasPotentialUpdateForTable(string $tableName)
Definition: WorkspaceNewPlaceholderRemovalMigration.php:56