f01c19fba46d3d1502f37238ccfcdb0292e78a2a
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / Category / Collection / CategoryCollection.php
1 <?php
2 namespace TYPO3\CMS\Frontend\Category\Collection;
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
17 use TYPO3\CMS\Core\Database\ConnectionPool;
18 use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20
21 /**
22 * Extend category collection for the frontend, to collect related records
23 * while respecting language, enable fields, etc.
24 */
25 class CategoryCollection extends \TYPO3\CMS\Core\Category\Collection\CategoryCollection
26 {
27 /**
28 * Creates a new collection objects and reconstitutes the
29 * given database record to the new object.
30 *
31 * Overrides the parent method to create a *frontend* category collection.
32 *
33 * @param array $collectionRecord Database record
34 * @param bool $fillItems Populates the entries directly on load, might be bad for memory on large collections
35 * @return \TYPO3\CMS\Frontend\Category\Collection\CategoryCollection
36 */
37 public static function create(array $collectionRecord, $fillItems = false)
38 {
39 /** @var $collection \TYPO3\CMS\Frontend\Category\Collection\CategoryCollection */
40 $collection = GeneralUtility::makeInstance(
41 __CLASS__,
42 $collectionRecord['table_name'],
43 $collectionRecord['field_name']
44 );
45 $collection->fromArray($collectionRecord);
46 if ($fillItems) {
47 $collection->loadContents();
48 }
49 return $collection;
50 }
51
52 /**
53 * Loads the collection with the given id from persistence
54 * For memory reasons, only data for the collection itself is loaded by default.
55 * Entries can be loaded on first access or straightaway using the $fillItems flag.
56 *
57 * Overrides the parent method because of the call to "self::create()" which otherwise calls up
58 * \TYPO3\CMS\Core\Category\Collection\CategoryCollection
59 *
60 * @param int $id Id of database record to be loaded
61 * @param bool $fillItems Populates the entries directly on load, might be bad for memory on large collections
62 * @param string $tableName the table name
63 * @param string $fieldName Name of the categories relation field
64 * @return \TYPO3\CMS\Core\Collection\CollectionInterface
65 */
66 public static function load($id, $fillItems = false, $tableName = '', $fieldName = '')
67 {
68 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
69 ->getQueryBuilderForTable(static::$storageTableName);
70 $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
71
72 $collectionRecord = $queryBuilder
73 ->select('*')
74 ->from(static::$storageTableName)
75 ->where(
76 $queryBuilder->expr()->eq('uid', (int)$id)
77 )
78 ->setMaxResults(1)
79 ->execute()
80 ->fetch();
81
82 $collectionRecord['table_name'] = $tableName;
83 $collectionRecord['field_name'] = $fieldName;
84
85 return self::create($collectionRecord, $fillItems);
86 }
87
88 /**
89 * Gets the collected records in this collection, by
90 * looking up the MM relations of this record to the
91 * table name defined in the local field 'table_name'.
92 *
93 * Overrides its parent method to implement usage of language,
94 * enable fields, etc. Also performs overlays.
95 *
96 * @return array
97 */
98 protected function getCollectedRecords()
99 {
100 $relatedRecords = [];
101
102 $queryBuilder = $this->getCollectedRecordsQueryBuilder();
103 $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
104 $tsfe = self::getTypoScriptFrontendController();
105
106 // If language handling is defined for item table, add language condition
107 if (isset($GLOBALS['TCA'][$this->getItemTableName()]['ctrl']['languageField'])) {
108 // Consider default or "all" language
109 $languageField = sprintf(
110 '%s.%s',
111 $this->getItemTableName(),
112 $GLOBALS['TCA'][$this->getItemTableName()]['ctrl']['languageField']
113 );
114
115 $languageConstraint = $queryBuilder->expr()->in($languageField, [0, -1]);
116
117 // If not in default language, also consider items in current language with no original
118 if ($tsfe->sys_language_content > 0) {
119 $transOrigPointerField = sprintf(
120 '%s.%s',
121 $this->getItemTableName(),
122 $GLOBALS['TCA'][$this->getItemTableName()]['ctrl']['transOrigPointerField']
123 );
124
125 $languageConstraint = $queryBuilder->expr()->orX(
126 $languageConstraint,
127 $queryBuilder->expr()->andX(
128 $queryBuilder->expr()->eq($languageField, (int)$tsfe->sys_language_content),
129 $queryBuilder->expr()->eq($transOrigPointerField, 0)
130 )
131 );
132 }
133
134 $queryBuilder->andWhere($languageConstraint);
135 }
136
137 // Get the related records from the database
138 $result = $queryBuilder->execute();
139
140 while ($record = $result->fetch()) {
141 // Overlay the record for workspaces
142 $tsfe->sys_page->versionOL(
143 $this->getItemTableName(),
144 $record
145 );
146
147 // Overlay the record for translations
148 if (is_array($record) && $tsfe->sys_language_contentOL) {
149 if ($this->getItemTableName() === 'pages') {
150 $record = $tsfe->sys_page->getPageOverlay($record);
151 } else {
152 $record = $tsfe->sys_page->getRecordOverlay(
153 $this->getItemTableName(),
154 $record,
155 $tsfe->sys_language_content,
156 $tsfe->sys_language_contentOL
157 );
158 }
159 }
160
161 // Record may have been unset during the overlay process
162 if (is_array($record)) {
163 $relatedRecords[] = $record;
164 }
165 }
166
167 return $relatedRecords;
168 }
169
170 /**
171 * Gets the TSFE object.
172 *
173 * @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
174 */
175 protected static function getTypoScriptFrontendController()
176 {
177 return $GLOBALS['TSFE'];
178 }
179
180 /**
181 * Returns the database connection
182 *
183 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
184 */
185 protected static function getDatabaseConnection()
186 {
187 return $GLOBALS['TYPO3_DB'];
188 }
189 }