1 | <?php |
||
45 | class Page extends AbstractInitializer |
||
46 | { |
||
47 | /** |
||
48 | * @var \ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager |
||
49 | */ |
||
50 | protected $logger = null; |
||
51 | |||
52 | /** |
||
53 | * Constructor, sets type and indexingConfigurationName to "pages". |
||
54 | * |
||
55 | */ |
||
56 | 8 | public function __construct() |
|
63 | |||
64 | /** |
||
65 | * Overrides the general setType() implementation, forcing type to "pages". |
||
66 | * |
||
67 | * @param string $type Type to initialize (ignored). |
||
68 | */ |
||
69 | 7 | public function setType($type) |
|
73 | |||
74 | /** |
||
75 | * Initializes Index Queue page items for a site. Includes regular pages |
||
76 | * and mounted pages - no nested mount page structures though. |
||
77 | * |
||
78 | * @return bool TRUE if initialization was successful, FALSE on error. |
||
79 | */ |
||
80 | 7 | public function initialize() |
|
87 | |||
88 | /** |
||
89 | * Initialize a single page that is part of a mounted tree. |
||
90 | * |
||
91 | * @param array $mountProperties Array of mount point properties mountPageSource, mountPageDestination, and mountPageOverlayed |
||
92 | * @param int $mountPageId The ID of the mounted page |
||
93 | */ |
||
94 | 1 | public function initializeMountedPage(array $mountProperties, $mountPageId) |
|
101 | |||
102 | /** |
||
103 | * Initializes Mount Pages to be indexed through the Index Queue. The Mount |
||
104 | * Pages are searched and their mounted virtual sub-trees are then resolved |
||
105 | * and added to the Index Queue as if they were actually present below the |
||
106 | * Mount Page. |
||
107 | * |
||
108 | * @return bool TRUE if initialization of the Mount Pages was successful, FALSE otherwise |
||
109 | */ |
||
110 | 7 | protected function initializeMountPages() |
|
111 | { |
||
112 | 7 | $mountPagesInitialized = false; |
|
113 | 7 | $mountPages = $this->findMountPages(); |
|
114 | |||
115 | 7 | if (empty($mountPages)) { |
|
116 | 4 | $mountPagesInitialized = true; |
|
117 | 4 | return $mountPagesInitialized; |
|
118 | } |
||
119 | |||
120 | 3 | foreach ($mountPages as $mountPage) { |
|
121 | 3 | if (!$this->validateMountPage($mountPage)) { |
|
122 | 3 | continue; |
|
123 | } |
||
124 | |||
125 | 3 | $mountedPages = $this->resolveMountPageTree($mountPage['mountPageSource']); |
|
126 | |||
127 | // handling mount_pid_ol behavior |
||
128 | 3 | if ($mountPage['mountPageOverlayed']) { |
|
129 | // the page shows the mounted page's content |
||
130 | $mountedPages[] = $mountPage['mountPageSource']; |
||
131 | } else { |
||
132 | // Add page like a regular page, as only the sub tree is |
||
133 | // mounted. The page itself has its own content. |
||
134 | 3 | $indexQueue = GeneralUtility::makeInstance(Queue::class); |
|
135 | 3 | $indexQueue->updateItem($this->type, $mountPage['uid']); |
|
136 | } |
||
137 | |||
138 | // This can happen when the mount point does not show the content of the |
||
139 | // mounted page and the mounted page does not have any subpages. |
||
140 | 3 | if (empty($mountedPages)) { |
|
141 | continue; |
||
142 | } |
||
143 | |||
144 | 3 | DatabaseUtility::transactionStart(); |
|
145 | try { |
||
146 | 3 | $this->addMountedPagesToIndexQueue($mountedPages, $mountPage); |
|
147 | 3 | $this->addIndexQueueItemIndexingProperties($mountPage, $mountedPages); |
|
148 | |||
149 | 3 | DatabaseUtility::transactionCommit(); |
|
150 | 3 | $mountPagesInitialized = true; |
|
151 | } catch (\Exception $e) { |
||
152 | DatabaseUtility::transactionRollback(); |
||
153 | |||
154 | $this->logger->log( |
||
155 | SolrLogManager::ERROR, |
||
156 | 'Index Queue initialization failed for mount pages', |
||
157 | [ |
||
158 | $e->__toString() |
||
159 | ] |
||
160 | ); |
||
161 | break; |
||
162 | } |
||
163 | } |
||
164 | |||
165 | 3 | return $mountPagesInitialized; |
|
166 | } |
||
167 | |||
168 | /** |
||
169 | * Checks whether a Mount Page is properly configured. |
||
170 | * |
||
171 | * @param array $mountPage A mount page |
||
172 | * @return bool TRUE if the Mount Page is OK, FALSE otherwise |
||
173 | */ |
||
174 | 3 | protected function validateMountPage(array $mountPage) |
|
208 | |||
209 | /** |
||
210 | * Checks whether the mounted page (mount page source) exists. That is, |
||
211 | * whether it accessible in the frontend. So the record must exist |
||
212 | * (deleted = 0) and must not be hidden (hidden = 0). |
||
213 | * |
||
214 | * @param int $mountedPageId Mounted page ID |
||
215 | * @return bool TRUE if the page is accessible in the frontend, FALSE otherwise. |
||
216 | */ |
||
217 | 3 | protected function mountedPageExists($mountedPageId) |
|
228 | |||
229 | /** |
||
230 | * Adds the virtual / mounted pages to the Index Queue as if they would |
||
231 | * belong to the same site where they are mounted. |
||
232 | * |
||
233 | * @param array $mountedPages An array of mounted page IDs |
||
234 | * @param array $mountProperties Array with mount point properties (mountPageSource, mountPageDestination, mountPageOverlayed) |
||
235 | */ |
||
236 | 4 | protected function addMountedPagesToIndexQueue(array $mountedPages, array $mountProperties) |
|
237 | { |
||
238 | 4 | $mountPointPageIsWithExistingQueueEntry = $this->getPageIdsOfExistingMountPages($mountedPages); |
|
239 | 4 | $mountedPagesThatNeedToBeAdded = array_diff($mountedPages, $mountPointPageIsWithExistingQueueEntry); |
|
240 | |||
241 | 4 | if (count($mountedPagesThatNeedToBeAdded) === 0) { |
|
242 | //nothing to do |
||
243 | 1 | return; |
|
244 | } |
||
245 | |||
246 | 3 | $mountIdentifier = $this->getMountPointIdentifier($mountProperties); |
|
247 | $initializationQuery = 'INSERT INTO tx_solr_indexqueue_item (root, item_type, item_uid, indexing_configuration, indexing_priority, changed, has_indexing_properties, pages_mountidentifier, errors) ' |
||
248 | 3 | . $this->buildSelectStatement() . ', 1, ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($mountIdentifier, |
|
249 | 3 | 'tx_solr_indexqueue_item') . ',""' |
|
250 | . 'FROM pages ' |
||
251 | . 'WHERE ' |
||
252 | 3 | . 'uid IN(' . implode(',', $mountedPagesThatNeedToBeAdded) . ') ' |
|
253 | 3 | . $this->buildTcaWhereClause() |
|
254 | 3 | . $this->buildUserWhereClause(); |
|
255 | |||
256 | 3 | $GLOBALS['TYPO3_DB']->sql_query($initializationQuery); |
|
257 | 3 | $this->logInitialization($initializationQuery); |
|
258 | 3 | } |
|
259 | |||
260 | /** |
||
261 | * Retrieves an array of pageIds from mountPoints that allready have a queue entry. |
||
262 | * |
||
263 | * @param array $mountedPages |
||
264 | * @return array |
||
265 | */ |
||
266 | 4 | protected function getPageIdsOfExistingMountPages($mountedPages) |
|
287 | |||
288 | /** |
||
289 | * Adds Index Queue item indexing properties for mounted pages. The page |
||
290 | * indexer later needs to know that he's dealing with a mounted page, the |
||
291 | * indexing properties will let make it possible for the indexer to |
||
292 | * distinguish the mounted pages. |
||
293 | * |
||
294 | * @param array $mountPage An array with information about the root/destination Mount Page |
||
295 | * @param array $mountedPages An array of mounted page IDs |
||
296 | */ |
||
297 | 4 | protected function addIndexQueueItemIndexingProperties(array $mountPage, array $mountedPages) |
|
298 | { |
||
299 | 4 | $mountIdentifier = $this->getMountPointIdentifier($mountPage); |
|
300 | 4 | $mountPageItems = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( |
|
301 | 4 | '*', |
|
302 | 4 | 'tx_solr_indexqueue_item', |
|
303 | 4 | 'root = ' . intval($this->site->getRootPageId()) . ' ' |
|
304 | . 'AND item_type = \'pages\' ' |
||
305 | 4 | . 'AND item_uid IN(' . implode(',', $mountedPages) . ') ' |
|
306 | . 'AND has_indexing_properties = 1 ' |
||
307 | 4 | . 'AND pages_mountidentifier=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($mountIdentifier, |
|
308 | 4 | 'tx_solr_indexqueue_item') |
|
309 | ); |
||
310 | |||
311 | 4 | if (!is_array($mountPageItems)) { |
|
312 | return; |
||
313 | } |
||
314 | |||
315 | 4 | foreach ($mountPageItems as $mountPageItemRecord) { |
|
316 | 3 | $mountPageItem = GeneralUtility::makeInstance(Item::class, $mountPageItemRecord); |
|
317 | 3 | $mountPageItem->setIndexingProperty('mountPageSource', $mountPage['mountPageSource']); |
|
318 | 3 | $mountPageItem->setIndexingProperty('mountPageDestination', $mountPage['mountPageDestination']); |
|
319 | 3 | $mountPageItem->setIndexingProperty('isMountedPage', '1'); |
|
320 | |||
321 | 3 | $mountPageItem->storeIndexingProperties(); |
|
322 | } |
||
323 | 4 | } |
|
324 | |||
325 | /** |
||
326 | * Builds an identifier of the given mount point properties. |
||
327 | * |
||
328 | * @param array $mountProperties Array with mount point properties (mountPageSource, mountPageDestination, mountPageOverlayed) |
||
329 | * @return string String consisting of mountPageDestination-mountPageSource-mountPageOverlayed |
||
330 | */ |
||
331 | 4 | protected function getMountPointIdentifier(array $mountProperties) |
|
337 | |||
338 | // Mount Page resolution |
||
339 | |||
340 | /** |
||
341 | * Finds the mount pages in the current site. |
||
342 | * |
||
343 | * @return array An array of mount pages |
||
344 | */ |
||
345 | 7 | protected function findMountPages() |
|
359 | |||
360 | /** |
||
361 | * Gets all the pages from a mounted page tree. |
||
362 | * |
||
363 | * @param int $mountPageSourceId |
||
364 | * @return array An array of page IDs in the mounted page tree |
||
365 | */ |
||
366 | 3 | protected function resolveMountPageTree($mountPageSourceId) |
|
373 | } |
||
374 |