‪TYPO3CMS  ‪main
Typo3DbBackend.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\Exception as DBALException;
21 use Doctrine\DBAL\Query\From;
22 use Psr\Http\Message\ServerRequestInterface;
23 use TYPO3\CMS\Backend\Utility\BackendUtility;
29 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
51 
57 {
61 
63  {
64  $this->cacheService = ‪$cacheService;
65  $this->reflectionService = ‪$reflectionService;
66  $this->connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
67  }
68 
78  public function ‪addRow(string $tableName, array $fieldValues, bool $isRelation = false): int
79  {
80  if (isset($fieldValues['uid'])) {
81  unset($fieldValues['uid']);
82  }
83  try {
84  $connection = $this->connectionPool->getConnectionForTable($tableName);
85  $connection->insert($tableName, $fieldValues);
86  } catch (DBALException $e) {
87  throw new ‪SqlErrorException($e->getPrevious()->getMessage(), 1470230766, $e);
88  }
89 
90  ‪$uid = 0;
91  if (!$isRelation) {
92  // Relation tables have no auto_increment column, so no retrieval must be tried.
93  ‪$uid = (int)$connection->lastInsertId();
94  $this->cacheService->clearCacheForRecord($tableName, ‪$uid);
95  }
96  return ‪$uid;
97  }
98 
108  public function ‪updateRow(string $tableName, array $fieldValues, bool $isRelation = false): void
109  {
110  if (!isset($fieldValues['uid'])) {
111  throw new \InvalidArgumentException('The given row must contain a value for "uid".', 1476045164);
112  }
113 
114  ‪$uid = (int)$fieldValues['uid'];
115  unset($fieldValues['uid']);
116 
117  try {
118  $connection = $this->connectionPool->getConnectionForTable($tableName);
119  $connection->update($tableName, $fieldValues, ['uid' => ‪$uid]);
120  } catch (DBALException $e) {
121  throw new ‪SqlErrorException($e->getPrevious()->getMessage(), 1470230767, $e);
122  }
123 
124  if (!$isRelation) {
125  $this->cacheService->clearCacheForRecord($tableName, ‪$uid);
126  }
127  }
128 
137  public function ‪updateRelationTableRow(string $tableName, array $fieldValues): void
138  {
139  if (!isset($fieldValues['uid_local']) && !isset($fieldValues['uid_foreign'])) {
140  throw new \InvalidArgumentException(
141  'The given fieldValues must contain a value for "uid_local" and "uid_foreign".',
142  1360500126
143  );
144  }
145 
146  $where = [];
147  $where['uid_local'] = (int)$fieldValues['uid_local'];
148  $where['uid_foreign'] = (int)$fieldValues['uid_foreign'];
149  unset($fieldValues['uid_local']);
150  unset($fieldValues['uid_foreign']);
151 
152  if (!empty($fieldValues['tablenames'])) {
153  $where['tablenames'] = $fieldValues['tablenames'];
154  unset($fieldValues['tablenames']);
155  }
156  if (!empty($fieldValues['fieldname'])) {
157  $where['fieldname'] = $fieldValues['fieldname'];
158  unset($fieldValues['fieldname']);
159  }
160 
161  try {
162  $this->connectionPool->getConnectionForTable($tableName)->update($tableName, $fieldValues, $where);
163  } catch (DBALException $e) {
164  throw new ‪SqlErrorException($e->getPrevious()->getMessage(), 1470230768, $e);
165  }
166  }
167 
176  public function ‪removeRow(string $tableName, array $where, bool $isRelation = false): void
177  {
178  try {
179  $this->connectionPool->getConnectionForTable($tableName)->delete($tableName, $where);
180  } catch (DBALException $e) {
181  throw new ‪SqlErrorException($e->getPrevious()->getMessage(), 1470230769, $e);
182  }
183 
184  if (!$isRelation && isset($where['uid'])) {
185  $this->cacheService->clearCacheForRecord($tableName, (int)$where['uid']);
186  }
187  }
188 
194  public function ‪getObjectDataByQuery(‪QueryInterface $query): array
195  {
196  $statement = $query->‪getStatement();
197  // todo: remove instanceof checks as soon as getStatement() strictly returns Qom\Statement only
198  if ($statement instanceof ‪Statement
199  && !$statement->‪getStatement() instanceof QueryBuilder
200  ) {
201  $rows = $this->‪getObjectDataByRawQuery($statement);
202  } else {
203  $queryParser = GeneralUtility::makeInstance(Typo3DbQueryParser::class);
204  if ($statement instanceof ‪Statement
205  && $statement->‪getStatement() instanceof QueryBuilder
206  ) {
207  $queryBuilder = $statement->getStatement();
208  } else {
209  $queryBuilder = $queryParser->convertQueryToDoctrineQueryBuilder($query);
210  }
211  $selectParts = $queryBuilder->getSelect();
212  if ($queryParser->isDistinctQuerySuggested() && !empty($selectParts)) {
213  $selectParts[0] = 'DISTINCT ' . $selectParts[0];
214  $queryBuilder->selectLiteral(...$selectParts);
215  }
216  if ($query->‪getOffset()) {
217  $queryBuilder->setFirstResult($query->‪getOffset());
218  }
219  if ($query->‪getLimit()) {
220  $queryBuilder->setMaxResults($query->‪getLimit());
221  }
222  try {
223  $rows = $queryBuilder->executeQuery()->fetchAllAssociative();
224  } catch (DBALException $e) {
225  throw new ‪SqlErrorException($e->getPrevious()->getMessage(), 1472074485, $e);
226  }
227  }
228 
229  if (!empty($rows)) {
230  $rows = $this->‪overlayLanguageAndWorkspace($query->‪getSource(), $rows, $query);
231  }
232 
233  return $rows;
234  }
235 
241  protected function ‪getObjectDataByRawQuery(‪Statement $statement): array
242  {
243  $realStatement = $statement->‪getStatement();
244  $parameters = $statement->‪getBoundVariables();
245 
246  // The real statement is an instance of the Doctrine DBAL QueryBuilder, so fetching
247  // this directly is possible
248  if ($realStatement instanceof QueryBuilder) {
249  try {
250  $result = $realStatement->executeQuery();
251  } catch (DBALException $e) {
252  throw new ‪SqlErrorException($e->getPrevious()->getMessage(), 1472064721, $e);
253  }
254  $rows = $result->fetchAllAssociative();
255  // Prepared Doctrine DBAL statement
256  } elseif ($realStatement instanceof \Doctrine\DBAL\‪Statement) {
257  try {
258  foreach ($parameters as $parameterIdentifier => $parameterValue) {
259  $realStatement->bindValue($parameterIdentifier, $parameterValue);
260  }
261  $result = $realStatement->executeQuery();
262  } catch (DBALException $e) {
263  throw new ‪SqlErrorException($e->getPrevious()->getMessage(), 1481281404, $e);
264  }
265  $rows = $result->fetchAllAssociative();
266  } else {
267  // Do a real raw query. This is very stupid, as it does not allow to use DBAL's real power if
268  // several tables are on different databases, so this is used with caution and could be removed
269  // in the future
270  try {
271  $connection = $this->connectionPool->getConnectionByName(‪ConnectionPool::DEFAULT_CONNECTION_NAME);
272  $statement = $connection->executeQuery($realStatement, $parameters);
273  } catch (DBALException $e) {
274  throw new ‪SqlErrorException($e->getPrevious()->getMessage(), 1472064775, $e);
275  }
276 
277  $rows = $statement->fetchAllAssociative();
278  }
279 
280  return $rows;
281  }
282 
290  public function ‪getObjectCountByQuery(‪QueryInterface $query): int
291  {
292  if ($query->‪getConstraint() instanceof ‪Statement) {
293  throw new ‪BadConstraintException('Could not execute count on queries with a constraint of type TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Qom\\Statement', 1256661045);
294  }
295 
296  $statement = $query->‪getStatement();
297  if ($statement instanceof ‪Statement
298  && !$statement->‪getStatement() instanceof QueryBuilder
299  ) {
300  $rows = $this->‪getObjectDataByQuery($query);
301  $count = count($rows);
302  } else {
303  $queryParser = GeneralUtility::makeInstance(Typo3DbQueryParser::class);
304  $queryBuilder = $queryParser
305  ->convertQueryToDoctrineQueryBuilder($query)
306  ->resetOrderBy();
307 
308  if ($queryParser->isDistinctQuerySuggested()) {
309  $source = $queryBuilder->getFrom()[0];
310  // Tablename is already quoted for the DBMS, we need to treat table and field names separately
311  $tableName = $source->alias ?: $source->table;
312  $fieldName = $queryBuilder->quoteIdentifier('uid');
313  $queryBuilder
314  ->resetGroupBy()
315  ->selectLiteral(sprintf('COUNT(DISTINCT %s.%s)', $tableName, $fieldName));
316  } else {
317  $queryBuilder->count('*');
318  }
319  // Ensure to count only records in the current workspace
320  $context = GeneralUtility::makeInstance(Context::class);
321  $workspaceUid = (int)$context->getPropertyFromAspect('workspace', 'id');
322  $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $workspaceUid));
323 
324  try {
325  $count = $queryBuilder->executeQuery()->fetchOne();
326  } catch (DBALException $e) {
327  throw new ‪SqlErrorException($e->getPrevious()->getMessage(), 1472074379, $e);
328  }
329  if ($query->‪getOffset()) {
330  $count -= $query->‪getOffset();
331  }
332  if ($query->‪getLimit()) {
333  $count = min($count, $query->‪getLimit());
334  }
335  }
336  return (int)max(0, $count);
337  }
338 
347  {
348  $className = get_class($object);
350  $dataMapper = GeneralUtility::makeInstance(DataMapper::class);
351  $dataMap = $dataMapper->getDataMap($className);
352  $tableName = $dataMap->getTableName();
353  $queryBuilder = $this->connectionPool->getQueryBuilderForTable($tableName);
354  if ((‪$GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface
355  && ‪ApplicationType::fromRequest(‪$GLOBALS['TYPO3_REQUEST'])->isFrontend()
356  ) {
357  $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
358  }
359  $whereClause = [];
360  // loop over all properties of the object to exactly set the values of each database field
361  $classSchema = $this->reflectionService->getClassSchema($className);
362  foreach ($classSchema->getDomainObjectProperties() as $property) {
363  $propertyName = $property->getName();
364  // @todo We couple the Backend to the Entity implementation (uid, isClone); changes there breaks this method
365  if ($dataMap->isPersistableProperty($propertyName) && $propertyName !== ‪AbstractDomainObject::PROPERTY_UID && $propertyName !== ‪AbstractDomainObject::PROPERTY_PID && $propertyName !== 'isClone') {
366  $propertyValue = $object->‪_getProperty($propertyName);
367  $fieldName = $dataMap->getColumnMap($propertyName)->getColumnName();
368  if ($propertyValue === null) {
369  $whereClause[] = $queryBuilder->expr()->isNull($fieldName);
370  } else {
371  $whereClause[] = $queryBuilder->expr()->eq($fieldName, $queryBuilder->createNamedParameter($dataMapper->getPlainValue($propertyValue)));
372  }
373  }
374  }
375  $queryBuilder
376  ->select('uid')
377  ->from($tableName)
378  ->where(...$whereClause);
379 
380  try {
381  ‪$uid = (int)$queryBuilder
382  ->executeQuery()
383  ->fetchOne();
384  if (‪$uid > 0) {
385  return ‪$uid;
386  }
387  return null;
388  } catch (DBALException $e) {
389  throw new ‪SqlErrorException($e->getPrevious()->getMessage(), 1470231748, $e);
390  }
391  }
392 
401  protected function ‪overlayLanguageAndWorkspace(‪SourceInterface $source, array $rows, ‪QueryInterface $query, int $workspaceUid = null): array
402  {
403  // A custom query is needed for the language, so a custom context is cloned
404  $context = clone GeneralUtility::makeInstance(Context::class);
405  $context->setAspect('language', $query->‪getQuerySettings()->‪getLanguageAspect());
406  if ($workspaceUid === null) {
407  $workspaceUid = (int)$context->getPropertyFromAspect('workspace', 'id');
408  } else {
409  $context->setAspect('workspace', GeneralUtility::makeInstance(WorkspaceAspect::class, $workspaceUid));
410  }
411 
412  $pageRepository = GeneralUtility::makeInstance(PageRepository::class, $context);
413  if ($source instanceof ‪SelectorInterface) {
414  $tableName = $source->getSelectorName();
415  $rows = $this->‪resolveMovedRecordsInWorkspace($tableName, $rows, $workspaceUid);
416  return $this->‪overlayLanguageAndWorkspaceForSelect($tableName, $rows, $pageRepository, $query);
417  }
418  if ($source instanceof ‪JoinInterface) {
419  $tableName = $source->getRight()->getSelectorName();
420  // Special handling of joined select is only needed when doing workspace overlays, which does not happen
421  // in live workspace
422  if ($workspaceUid === 0) {
423  return $this->‪overlayLanguageAndWorkspaceForSelect($tableName, $rows, $pageRepository, $query);
424  }
425  return $this->‪overlayLanguageAndWorkspaceForJoinedSelect($tableName, $rows, $pageRepository, $query);
426  }
427  // No proper source, so we do not have a table name here
428  // we cannot do an overlay and return the original rows instead.
429  return $rows;
430  }
431 
437  protected function ‪overlayLanguageAndWorkspaceForSelect(string $tableName, array $rows, ‪PageRepository $pageRepository, ‪QueryInterface $query): array
438  {
439  $overlaidRows = [];
440  foreach ($rows as $row) {
441  $row = $this->‪overlayLanguageAndWorkspaceForSingleRecord($tableName, $row, $pageRepository, $query);
442  if (is_array($row)) {
443  $overlaidRows[] = $row;
444  }
445  }
446  return $overlaidRows;
447  }
448 
456  protected function ‪overlayLanguageAndWorkspaceForJoinedSelect(string $tableName, array $rows, ‪PageRepository $pageRepository, ‪QueryInterface $query): array
457  {
458  // No valid rows, so this is skipped
459  if (!isset($rows[0]['uid'])) {
460  return $rows;
461  }
462  // First, find out the fields that belong to the "main" selected table which is defined by TCA, and take the first
463  // record to find out all possible fields in this database table
464  $fieldsOfMainTable = $pageRepository->‪getRawRecord($tableName, (int)$rows[0]['uid']);
465  $overlaidRows = [];
466  if (is_array($fieldsOfMainTable)) {
467  foreach ($rows as $row) {
468  $mainRow = array_intersect_key($row, $fieldsOfMainTable);
469  $joinRow = array_diff_key($row, $mainRow);
470  $mainRow = $this->‪overlayLanguageAndWorkspaceForSingleRecord($tableName, $mainRow, $pageRepository, $query);
471  if (is_array($mainRow)) {
472  $overlaidRows[] = array_replace($joinRow, $mainRow);
473  }
474  }
475  }
476  return $overlaidRows;
477  }
478 
484  protected function ‪overlayLanguageAndWorkspaceForSingleRecord(string $tableName, array $row, ‪PageRepository $pageRepository, ‪QueryInterface $query)
485  {
486  $querySettings = $query->‪getQuerySettings();
487  $languageAspect = $querySettings->‪getLanguageAspect();
488  $languageUid = $languageAspect->getContentId();
489  // If current row is a translation select its parent
490  $languageOfCurrentRecord = 0;
491  if ((‪$GLOBALS['TCA'][$tableName]['ctrl']['languageField'] ?? null)
492  && ($row[‪$GLOBALS['TCA'][$tableName]['ctrl']['languageField']] ?? false)
493  ) {
494  $languageOfCurrentRecord = $row[‪$GLOBALS['TCA'][$tableName]['ctrl']['languageField']];
495  }
496  // Note #1: In case of ->findByUid([uid-of-translated-record]) the translated record should be fetched at all times
497  // Example: you've fetched a translation directly via findByUid(11) which is a translated record, but the
498  // request was to do overlays. In this case, the default record is loaded again, and then reapplied again.
499  // Note #2: We cannot use $languageAspect->doOverlays() as it also checks for ID > 0
500  $fetchLocalizedRecord = $languageAspect->getOverlayType() !== ‪LanguageAspect::OVERLAYS_OFF;
501  // We have a translated record from the DB, but we do overlays, so let's take the default language record
502  // and do overlays again later-on
503  if ($languageOfCurrentRecord > 0
504  && $fetchLocalizedRecord
505  && isset(‪$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'])
506  && ($row[‪$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] ?? 0) > 0
507  ) {
508  $row = $pageRepository->‪getRawRecord(
509  $tableName,
510  (int)$row[‪$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']]
511  );
512  $languageUid = $languageOfCurrentRecord;
513  }
514 
515  // Handle workspace overlays
516  $pageRepository->‪versionOL($tableName, $row, true, $querySettings->getIgnoreEnableFields());
517  if (is_array($row) && $fetchLocalizedRecord) {
518  if ($tableName === 'pages') {
519  $row = $pageRepository->‪getLanguageOverlay($tableName, $row);
520  } else {
521  if (!$querySettings->getRespectSysLanguage()
522  && $languageOfCurrentRecord > 0
523  && (!$query instanceof ‪Query || !$query->getParentQuery())
524  ) {
525  // No parent query means we're processing the aggregate root.
526  // respectSysLanguage is false which means that records returned by the query
527  // might be from different languages (which is desired).
528  // So we must set the language used for overlay to the language of the current record
529  $languageUid = $languageOfCurrentRecord;
530  }
531  if (isset(‪$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'])
532  && ($row[‪$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] ?? 0) > 0
533  && $languageOfCurrentRecord > 0
534  ) {
535  // Force overlay by faking default language record, as getRecordOverlay can only handle default language records
536  $row['uid'] = $row[‪$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']];
537  $row[‪$GLOBALS['TCA'][$tableName]['ctrl']['languageField']] = 0;
538  }
539  // Currently this needs to return the default record (OVERLAYS_MIXED) if no translation is found
540  //however this is a hack and should actually use the overlay functionality as given in the original LanguageAspect.
541  $customLanguageAspect = new ‪LanguageAspect($languageUid, $languageUid, ‪LanguageAspect::OVERLAYS_MIXED);
542  $row = $pageRepository->‪getLanguageOverlay($tableName, $row, $customLanguageAspect);
543  }
544  } elseif (is_array($row)) {
545  // If an already localized record is fetched, the "uid" of the default language is used
546  // as the record is re-fetched in the DataMapper
547  if (isset(‪$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'])
548  && ($row[‪$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']] ?? 0) > 0
549  && $languageOfCurrentRecord > 0
550  ) {
551  $row['_LOCALIZED_UID'] = (int)$row['uid'];
552  $row['uid'] = $row[‪$GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField']];
553  }
554  }
555  return $row;
556  }
557 
565  protected function ‪resolveMovedRecordsInWorkspace(string $tableName, array $rows, int $workspaceUid): array
566  {
567  if ($workspaceUid === 0) {
568  return $rows;
569  }
570  if (!BackendUtility::isTableWorkspaceEnabled($tableName)) {
571  return $rows;
572  }
573  if (count($rows) !== 1) {
574  return $rows;
575  }
576  $queryBuilder = $this->connectionPool->getQueryBuilderForTable($tableName);
577  $queryBuilder->getRestrictions()->removeAll();
578  $movedRecords = $queryBuilder
579  ->select('*')
580  ->from($tableName)
581  ->where(
582  $queryBuilder->expr()->eq('t3ver_state', $queryBuilder->createNamedParameter(VersionState::MOVE_POINTER->value, ‪Connection::PARAM_INT)),
583  $queryBuilder->expr()->eq('t3ver_wsid', $queryBuilder->createNamedParameter($workspaceUid, ‪Connection::PARAM_INT)),
584  $queryBuilder->expr()->eq('t3ver_oid', $queryBuilder->createNamedParameter($rows[0]['uid'], ‪Connection::PARAM_INT))
585  )
586  ->setMaxResults(1)
587  ->executeQuery()
588  ->fetchAllAssociative();
589  if (!empty($movedRecords)) {
590  $rows = $movedRecords;
591  }
592  return $rows;
593  }
594 }
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getConstraint
‪ConstraintInterface null getConstraint()
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\getRawRecord
‪array null getRawRecord(string $table, int $uid, array $fields=[' *'])
Definition: PageRepository.php:1385
‪TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface\getLanguageAspect
‪getLanguageAspect()
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:52
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getLimit
‪int getLimit()
‪TYPO3\CMS\Core\Context\WorkspaceAspect
Definition: WorkspaceAspect.php:31
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend
Definition: Typo3DbBackend.php:57
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getOffset
‪int getOffset()
‪TYPO3\CMS\Core\Context\LanguageAspect\OVERLAYS_MIXED
‪const OVERLAYS_MIXED
Definition: LanguageAspect.php:75
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement\getStatement
‪string Doctrine DBAL Statement TYPO3 CMS Core Database Query QueryBuilder getStatement()
Definition: Statement.php:52
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\$cacheService
‪CacheService $cacheService
Definition: Typo3DbBackend.php:60
‪TYPO3\CMS\Extbase\Persistence\QueryInterface
Definition: QueryInterface.php:30
‪TYPO3\CMS\Core\Versioning\VersionState
‪VersionState
Definition: VersionState.php:22
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\overlayLanguageAndWorkspaceForSingleRecord
‪array int mixed null overlayLanguageAndWorkspaceForSingleRecord(string $tableName, array $row, PageRepository $pageRepository, QueryInterface $query)
Definition: Typo3DbBackend.php:484
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\overlayLanguageAndWorkspaceForJoinedSelect
‪overlayLanguageAndWorkspaceForJoinedSelect(string $tableName, array $rows, PageRepository $pageRepository, QueryInterface $query)
Definition: Typo3DbBackend.php:456
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\updateRelationTableRow
‪updateRelationTableRow(string $tableName, array $fieldValues)
Definition: Typo3DbBackend.php:137
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\getUidOfAlreadyPersistedValueObject
‪int null getUidOfAlreadyPersistedValueObject(AbstractValueObject $object)
Definition: Typo3DbBackend.php:346
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\removeRow
‪removeRow(string $tableName, array $where, bool $isRelation=false)
Definition: Typo3DbBackend.php:176
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\__construct
‪__construct(CacheService $cacheService, ReflectionService $reflectionService)
Definition: Typo3DbBackend.php:62
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject\_getProperty
‪_getProperty(string $propertyName)
Definition: AbstractDomainObject.php:132
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject\PROPERTY_PID
‪const PROPERTY_PID
Definition: AbstractDomainObject.php:33
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface
Definition: SourceInterface.php:23
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getQuerySettings
‪QuerySettingsInterface getQuerySettings()
‪TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper
Definition: DataMapper.php:59
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement
Definition: Statement.php:26
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Core\Database\ConnectionPool\DEFAULT_CONNECTION_NAME
‪const DEFAULT_CONNECTION_NAME
Definition: ConnectionPool.php:50
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\addRow
‪int addRow(string $tableName, array $fieldValues, bool $isRelation=false)
Definition: Typo3DbBackend.php:78
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\$reflectionService
‪ReflectionService $reflectionService
Definition: Typo3DbBackend.php:59
‪TYPO3\CMS\Extbase\Reflection\ReflectionService
Definition: ReflectionService.php:28
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\getObjectCountByQuery
‪int getObjectCountByQuery(QueryInterface $query)
Definition: Typo3DbBackend.php:290
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\overlayLanguageAndWorkspaceForSelect
‪overlayLanguageAndWorkspaceForSelect(string $tableName, array $rows, PageRepository $pageRepository, QueryInterface $query)
Definition: Typo3DbBackend.php:437
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\versionOL
‪versionOL(string $table, &$row, bool $unsetMovePointers=false, bool $bypassEnableFieldsCheck=false)
Definition: PageRepository.php:1644
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getSource
‪TYPO3 CMS Extbase Persistence Generic Qom SourceInterface getSource()
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface
Definition: SelectorInterface.php:32
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Exception\SqlErrorException
Definition: SqlErrorException.php:25
‪TYPO3\CMS\Extbase\DomainObject\AbstractValueObject
Definition: AbstractValueObject.php:26
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\getObjectDataByRawQuery
‪getObjectDataByRawQuery(Statement $statement)
Definition: Typo3DbBackend.php:241
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject
Definition: AbstractDomainObject.php:31
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\getStatement
‪TYPO3 CMS Extbase Persistence Generic Qom Statement getStatement()
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage
Definition: BackendInterface.php:18
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\JoinInterface
Definition: JoinInterface.php:24
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Exception\BadConstraintException
Definition: BadConstraintException.php:25
‪TYPO3\CMS\Core\Context\LanguageAspect
Definition: LanguageAspect.php:57
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\resolveMovedRecordsInWorkspace
‪resolveMovedRecordsInWorkspace(string $tableName, array $rows, int $workspaceUid)
Definition: Typo3DbBackend.php:565
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom
Definition: AndInterface.php:16
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Extbase\Service\CacheService
Definition: CacheService.php:34
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\updateRow
‪updateRow(string $tableName, array $fieldValues, bool $isRelation=false)
Definition: Typo3DbBackend.php:108
‪TYPO3\CMS\Extbase\Persistence\Generic\Query
Definition: Query.php:41
‪TYPO3\CMS\Core\Context\LanguageAspect\OVERLAYS_OFF
‪const OVERLAYS_OFF
Definition: LanguageAspect.php:74
‪TYPO3\CMS\Core\Http\fromRequest
‪@ fromRequest
Definition: ApplicationType.php:67
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:69
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject\PROPERTY_UID
‪const PROPERTY_UID
Definition: AbstractDomainObject.php:32
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\BackendInterface
Definition: BackendInterface.php:27
‪TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer
Definition: FrontendRestrictionContainer.php:30
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\getLanguageOverlay
‪array null getLanguageOverlay(string $table, array $originalRow, LanguageAspect $languageAspect=null)
Definition: PageRepository.php:325
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\getObjectDataByQuery
‪getObjectDataByQuery(QueryInterface $query)
Definition: Typo3DbBackend.php:194
‪TYPO3\CMS\Core\Http\ApplicationType
‪ApplicationType
Definition: ApplicationType.php:56
‪TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement\getBoundVariables
‪array getBoundVariables()
Definition: Statement.php:62
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\overlayLanguageAndWorkspace
‪overlayLanguageAndWorkspace(SourceInterface $source, array $rows, QueryInterface $query, int $workspaceUid=null)
Definition: Typo3DbBackend.php:401
‪TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend\$connectionPool
‪ConnectionPool $connectionPool
Definition: Typo3DbBackend.php:58
‪TYPO3\CMS\Core\Database\Query\Restriction\WorkspaceRestriction
Definition: WorkspaceRestriction.php:39