TYPO3 CMS  TYPO3_8-7
AdministrationRepository.php
Go to the documentation of this file.
1 <?php
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  */
30 
35 {
41  public $external_parsers = [];
42 
46  protected $allPhashListed = [];
47 
51  protected $iconFileNameCache = [];
52 
59  public function getGrlistRecord($phash)
60  {
61  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_grlist');
62  $result = $queryBuilder
63  ->select('*')
64  ->from('index_grlist')
65  ->where(
66  $queryBuilder->expr()->eq(
67  'phash',
68  $queryBuilder->createNamedParameter($phash, \PDO::PARAM_INT)
69  )
70  )
71  ->execute();
72  $numberOfRows = $result->rowCount();
73  $allRows = [];
74  while ($row = $result->fetch()) {
75  $row['pcount'] = $numberOfRows;
76  $allRows[] = $row;
77  }
78  return $allRows;
79  }
80 
87  public function getNumberOfFulltextRecords($phash)
88  {
89  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_fulltext');
90  return $queryBuilder
91  ->count('phash')
92  ->from('index_fulltext')
93  ->where(
94  $queryBuilder->expr()->eq(
95  'phash',
96  $queryBuilder->createNamedParameter($phash, \PDO::PARAM_INT)
97  )
98  )
99  ->execute()
100  ->fetchColumn(0);
101  }
102 
109  public function getNumberOfWords($phash)
110  {
111  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_rel');
112  return $queryBuilder
113  ->count('*')
114  ->from('index_rel')
115  ->where(
116  $queryBuilder->expr()->eq(
117  'phash',
118  $queryBuilder->createNamedParameter($phash, \PDO::PARAM_INT)
119  )
120  )
121  ->execute()
122  ->fetchColumn(0);
123  }
124 
131  {
132  $result = [];
133 
134  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_phash');
135  $res = $queryBuilder
136  ->select('index_phash.*')
137  ->addSelectLiteral($queryBuilder->expr()->count('*', 'pcount'))
138  ->from('index_phash')
139  ->where($queryBuilder->expr()->neq('item_type', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)))
140  ->groupBy(
141  'phash_grouping',
142  'phash',
143  'cHashParams',
144  'data_filename',
145  'data_page_id',
146  'data_page_reg1',
147  'data_page_type',
148  'data_page_mp',
149  'gr_list',
150  'item_type',
151  'item_title',
152  'item_description',
153  'item_mtime',
154  'tstamp',
155  'item_size',
156  'contentHash',
157  'crdate',
158  'parsetime',
159  'sys_language_uid',
160  'item_crdate',
161  'externalUrl',
162  'recordUid',
163  'freeIndexUid',
164  'freeIndexSetId'
165  )
166  ->orderBy('item_type')
167  ->execute();
168 
169  while ($row = $res->fetch()) {
170  $this->addAdditionalInformation($row);
171 
172  $result[] = $row;
173 
174  if ($row['pcount'] > 1) {
175  $res2 = $queryBuilder
176  ->select('*')
177  ->from('index_phash')
178  ->where(
179  $queryBuilder->expr()->eq(
180  'phash_grouping',
181  $queryBuilder->createNamedParameter($row['phash_grouping'], \PDO::PARAM_INT)
182  ),
183  $queryBuilder->expr()->neq(
184  'phash',
185  $queryBuilder->createNamedParameter($row['phash'], \PDO::PARAM_INT)
186  )
187  )
188  ->execute();
189  while ($row2 = $res2->fetch()) {
190  $this->addAdditionalInformation($row2);
191  $result[] = $row2;
192  }
193  }
194  }
195  return $result;
196  }
197 
203  public function getRecordsNumbers()
204  {
205  $tables = [
206  'index_phash',
207  'index_words',
208  'index_rel',
209  'index_grlist',
210  'index_section',
211  'index_fulltext',
212  ];
213  $recordList = [];
214  foreach ($tables as $tableName) {
215  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($tableName);
216  $recordList[$tableName] = $queryBuilder
217  ->count('*')
218  ->from($tableName)
219  ->execute()
220  ->fetchColumn(0);
221  }
222  return $recordList;
223  }
224 
230  public function getPageHashTypes()
231  {
232  $counts = [];
233  $types = [
234  'html' => 1,
235  'htm' => 1,
236  'pdf' => 2,
237  'doc' => 3,
238  'txt' => 4
239  ];
240  $revTypes = array_flip($types);
241  $revTypes[0] = 'TYPO3 page';
242 
243  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_phash');
244  $res = $queryBuilder
245  ->select('item_type')
246  ->addSelectLiteral($queryBuilder->expr()->count('*', 'count'))
247  ->from('index_phash')
248  ->groupBy('item_type')
249  ->orderBy('item_type')
250  ->execute();
251 
252  while ($row = $res->fetch()) {
253  $itemType = $row['item_type'];
254  $counts[] = [
255  'count' => $row['count'],
256  'name' => $revTypes[$itemType],
257  'type' => $itemType,
258  'uniqueCount' => $this->countUniqueTypes($itemType),
259  ];
260  }
261  return $counts;
262  }
263 
270  protected function countUniqueTypes($itemType)
271  {
272  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_phash');
273  $items = $queryBuilder
274  ->count('*')
275  ->from('index_phash')
276  ->where(
277  $queryBuilder->expr()->eq(
278  'item_type',
279  $queryBuilder->createNamedParameter($itemType, \PDO::PARAM_STR)
280  )
281  )
282  ->groupBy('phash_grouping')
283  ->execute()
284  ->fetchAll();
285 
286  return count($items);
287  }
288 
295  public function getNumberOfSections($pageHash)
296  {
297  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_section');
298  return (int)$queryBuilder
299  ->count('phash')
300  ->from('index_section')
301  ->where(
302  $queryBuilder->expr()->eq(
303  'phash',
304  $queryBuilder->createNamedParameter($pageHash, \PDO::PARAM_INT)
305  )
306  )
307  ->execute()
308  ->fetchColumn(0);
309  }
310 
316  public function getPageStatistic()
317  {
318  $result = [];
319  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_phash');
320  $res = $queryBuilder
321  ->select('index_phash.*')
322  ->addSelectLiteral($queryBuilder->expr()->count('*', 'pcount'))
323  ->from('index_phash')
324  ->where($queryBuilder->expr()->neq('data_page_id', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)))
325  ->groupBy(
326  'phash_grouping',
327  'phash',
328  'cHashParams',
329  'data_filename',
330  'data_page_id',
331  'data_page_reg1',
332  'data_page_type',
333  'data_page_mp',
334  'gr_list',
335  'item_type',
336  'item_title',
337  'item_description',
338  'item_mtime',
339  'tstamp',
340  'item_size',
341  'contentHash',
342  'crdate',
343  'parsetime',
344  'sys_language_uid',
345  'item_crdate',
346  'externalUrl',
347  'recordUid',
348  'freeIndexUid',
349  'freeIndexSetId'
350  )
351  ->orderBy('data_page_id')
352  ->execute();
353 
354  while ($row = $res->fetch()) {
355  $this->addAdditionalInformation($row);
356  $result[] = $row;
357 
358  if ($row['pcount'] > 1) {
359  $res2 = $queryBuilder
360  ->select('*')
361  ->from('index_phash')
362  ->where(
363  $queryBuilder->expr()->eq(
364  'phash_grouping',
365  $queryBuilder->createNamedParameter($row['phash_grouping'], \PDO::PARAM_INT)
366  ),
367  $queryBuilder->expr()->neq(
368  'phash',
369  $queryBuilder->createNamedParameter($row['phash'], \PDO::PARAM_INT)
370  )
371  )
372  ->execute();
373  while ($row2 = $res2->fetch()) {
374  $this->addAdditionalInformation($row2);
375  $result[] = $row2;
376  }
377  }
378  }
379  return $result;
380  }
381 
390  public function getGeneralSearchStatistic($additionalWhere, $pageUid, $max = 50)
391  {
392  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
393  ->getQueryBuilderForTable('index_stat_word');
394  $queryBuilder
395  ->select('word')
396  ->from('index_stat_word')
397  ->addSelectLiteral($queryBuilder->expr()->count('*', 'c'))
398  ->where(
399  $queryBuilder->expr()->eq(
400  'pageid',
401  $queryBuilder->createNamedParameter($pageUid, \PDO::PARAM_INT)
402  )
403  )
404  ->groupBy('word')
405  ->setMaxResults((int)$max);
406 
407  if (!empty($additionalWhere)) {
408  $queryBuilder->andWhere(QueryHelper::stripLogicalOperatorPrefix($additionalWhere));
409  }
410 
411  $result = $queryBuilder->execute();
412  $count = (int)$result->rowCount();
413  $result->closeCursor();
414 
415  // exist several statistics for this page?
416  if ($count === 0) {
417  // Limit access to pages of the current site
418  $queryBuilder->where(
419  $queryBuilder->expr()->in(
420  'pageid',
421  $queryBuilder->createNamedParameter(
422  GeneralUtility::intExplode(',', $this->extGetTreeList((int)$pageUid, 100, 0, '1=1'), true),
423  Connection::PARAM_INT_ARRAY
424  )
425  ),
427  );
428  }
429 
430  return $queryBuilder->execute()->fetchAll();
431  }
432 
438  protected function addAdditionalInformation(array &$row)
439  {
440  $grListRec = $this->getGrlistRecord($row['phash']);
441  $unserializedCHashParams = unserialize($row['cHashParams']);
442 
443  $row['numberOfWords'] = $this->getNumberOfWords($row['phash']);
444  $row['numberOfSections'] = $this->getNumberOfSections($row['phash']);
445  $row['numberOfFulltext'] = $this->getNumberOfFulltextRecords($row['phash']);
446  $row['cHashParams'] = !empty($unserializedCHashParams) ? $unserializedCHashParams : '';
447  $row['grList'] = $grListRec;
448  }
449 
458  public function getTree($pageId, $depth = 4, $mode)
459  {
460  $allLines = [];
461  $pageRecord = BackendUtility::getRecord('pages', (int)$pageId);
462  if (!$pageRecord) {
463  return $allLines;
464  }
466  $tree = GeneralUtility::makeInstance(PageTreeView::class);
467  $perms_clause = $this->getBackendUserAuthentication()->getPagePermsClause(1);
468  $tree->init('AND ' . $perms_clause);
469  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
470  $HTML = '<span title="' . htmlspecialchars($pageRecord['title']) . '">' . $iconFactory->getIconForRecord('pages', $pageRecord, Icon::SIZE_SMALL)->render() . '</span>';
471  $tree->tree[] = [
472  'row' => $pageRecord,
473  'HTML' => $HTML
474  ];
475 
476  if ($depth > 0) {
477  $tree->getTree((int)$pageId, $depth, '');
478  }
479 
480  foreach ($tree->tree as $singleLine) {
481  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_phash');
482  $result = $queryBuilder->select(
483  'ISEC.phash_t3',
484  'ISEC.rl0',
485  'ISEC.rl1',
486  'ISEC.rl2',
487  'ISEC.page_id',
488  'ISEC.uniqid',
489  'IP.phash',
490  'IP.phash_grouping',
491  'IP.cHashParams',
492  'IP.data_filename',
493  'IP.data_page_id',
494  'IP.data_page_reg1',
495  'IP.data_page_type',
496  'IP.data_page_mp',
497  'IP.gr_list',
498  'IP.item_type',
499  'IP.item_title',
500  'IP.item_description',
501  'IP.item_mtime',
502  'IP.tstamp',
503  'IP.item_size',
504  'IP.contentHash',
505  'IP.crdate',
506  'IP.parsetime',
507  'IP.sys_language_uid',
508  'IP.item_crdate',
509  'IP.externalUrl',
510  'IP.recordUid',
511  'IP.freeIndexUid',
512  'IP.freeIndexSetId'
513  )
514  ->addSelectLiteral($queryBuilder->expr()->count('*', 'count_val'))
515  ->from('index_phash', 'IP')
516  ->from('index_section', 'ISEC')
517  ->where(
518  $queryBuilder->expr()->eq('IP.phash', $queryBuilder->quoteIdentifier('ISEC.phash')),
519  $queryBuilder->expr()->eq(
520  'ISEC.page_id',
521  $queryBuilder->createNamedParameter($singleLine['row']['uid'], \PDO::PARAM_INT)
522  )
523  )
524  ->groupBy(
525  'IP.phash',
526  'IP.phash_grouping',
527  'IP.cHashParams',
528  'IP.data_filename',
529  'IP.data_page_id',
530  'IP.data_page_reg1',
531  'IP.data_page_type',
532  'IP.data_page_mp',
533  'IP.gr_list',
534  'IP.item_type',
535  'IP.item_title',
536  'IP.item_description',
537  'IP.item_mtime',
538  'IP.tstamp',
539  'IP.item_size',
540  'IP.contentHash',
541  'IP.crdate',
542  'IP.parsetime',
543  'IP.sys_language_uid',
544  'IP.item_crdate',
545  'ISEC.phash',
546  'ISEC.phash_t3',
547  'ISEC.rl0',
548  'ISEC.rl1',
549  'ISEC.rl2',
550  'ISEC.page_id',
551  'ISEC.uniqid',
552  'IP.externalUrl',
553  'IP.recordUid',
554  'IP.freeIndexUid',
555  'IP.freeIndexSetId'
556  )
557  ->orderBy('IP.item_type')
558  ->addOrderBy('IP.tstamp')
559  ->setMaxResults(11)
560  ->execute();
561 
562  $lines = [];
563  // Collecting phash values (to remove local indexing for)
564  // Traverse the result set of phash rows selected:
565  while ($row = $result->fetch()) {
566  $row['icon'] = $this->makeItemTypeIcon($row['item_type']);
567  $this->allPhashListed[] = $row['phash'];
568 
569  // Adds a display row:
570  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
571  ->getQueryBuilderForTable('index_rel');
572  $wordCountResult = $queryBuilder->count('index_words.baseword')
573  ->from('index_rel')
574  ->from('index_words')
575  ->where(
576  $queryBuilder->expr()->eq(
577  'index_rel.phash',
578  $queryBuilder->createNamedParameter($row['phash'], \PDO::PARAM_INT)
579  ),
580  $queryBuilder->expr()->eq('index_words.wid', $queryBuilder->quoteIdentifier('index_rel.wid'))
581  )
582  ->groupBy('index_words.baseword')
583  ->execute();
584 
585  $row['wordCount'] = $wordCountResult->rowCount();
586  $wordCountResult->closeCursor();
587 
588  if ($mode === 'content') {
589  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
590  ->getQueryBuilderForTable('index_fulltext');
591  $row['fulltextData'] = $queryBuilder->select('*')
592  ->from('index_fulltext')
593  ->where(
594  $queryBuilder->expr()->eq(
595  'phash',
596  $queryBuilder->createNamedParameter($row['phash'], \PDO::PARAM_INT)
597  )
598  )
599  ->setMaxResults(1)
600  ->execute()
601  ->fetch();
602 
603  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
604  ->getQueryBuilderForTable('index_rel');
605  $wordRecords = $queryBuilder->select('index_words.baseword')
606  ->from('index_rel')
607  ->from('index_words')
608  ->where(
609  $queryBuilder->expr()->eq(
610  'index_rel.phash',
611  $queryBuilder->createNamedParameter($row['phash'], \PDO::PARAM_INT)
612  ),
613  $queryBuilder->expr()->eq(
614  'index_words.wid',
615  $queryBuilder->quoteIdentifier('index_rel.wid')
616  )
617  )
618  ->groupBy('index_words.baseword')
619  ->orderBy('index_words.baseword')
620  ->execute()
621  ->fetchAll();
622 
623  if (is_array($wordRecords)) {
624  $row['allWords'] = array_column($wordRecords, 'baseword');
625  }
626  }
627 
628  $lines[] = $row;
629  }
630 
631  $singleLine['lines'] = $lines;
632  $allLines[] = $singleLine;
633  }
634 
635  return $allLines;
636  }
637 
648  protected function extGetTreeList($id, $depth, $begin = 0, $perms_clause)
649  {
650  $list = GeneralUtility::makeInstance(FrontendBackendUserAuthentication::class)
651  ->extGetTreeList($id, $depth, $begin, $perms_clause);
652 
653  if (empty($list)) {
654  $list = $id;
655  } else {
656  $list = rtrim($list, ',') . ',' . $id;
657  }
658 
659  return $list;
660  }
661 
669  public function removeIndexedPhashRow($phashList, $pageId, $depth = 4)
670  {
671  if ($phashList === 'ALL') {
672  $this->getTree($pageId, $depth, '');
673  $phashRows = $this->allPhashListed;
674  $this->allPhashListed = [];
675  } else {
676  $phashRows = GeneralUtility::trimExplode(',', $phashList, true);
677  }
678 
679  foreach ($phashRows as $phash) {
680  $phash = (int)$phash;
681  if ($phash > 0) {
682  $idList = [];
683  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
684  ->getQueryBuilderForTable('index_section');
685  $res = $queryBuilder
686  ->select('page_id')
687  ->from('index_section')
688  ->where(
689  $queryBuilder->expr()->eq(
690  'phash',
691  $queryBuilder->createNamedParameter($phash, \PDO::PARAM_INT)
692  )
693  )
694  ->execute();
695  while ($row = $res->fetch()) {
696  $idList[] = (int)$row['page_id'];
697  }
698 
699  if (!empty($idList)) {
701  $pageCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_pages');
702  foreach ($idList as $pageId) {
703  $pageCache->flushByTag('pageId_' . $pageId);
704  }
705  }
706 
707  // Removing old registrations for all tables.
708  $tableArr = [
709  'index_phash',
710  'index_rel',
711  'index_section',
712  'index_grlist',
713  'index_fulltext',
714  'index_debug'
715  ];
716  foreach ($tableArr as $table) {
717  GeneralUtility::makeInstance(ConnectionPool::class)
718  ->getConnectionForTable($table)
719  ->delete($table, ['phash' => (int)$phash]);
720  }
721  }
722  }
723  }
724 
730  public function saveStopWords(array $words)
731  {
732  foreach ($words as $wid => $state) {
733  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_words');
734  $queryBuilder
735  ->update('index_words')
736  ->set('is_stopword', (int)$state)
737  ->where(
738  $queryBuilder->expr()->eq(
739  'wid',
740  $queryBuilder->createNamedParameter($wid, \PDO::PARAM_INT)
741  )
742  )
743  ->execute();
744  }
745  }
746 
753  public function saveKeywords(array $words, $pageId)
754  {
755  // Get pages current keywords
756  $pageRec = BackendUtility::getRecord('pages', $pageId);
757  if (!is_array($pageRec)) {
758  return;
759  }
760  $keywords = array_flip(GeneralUtility::trimExplode(',', $pageRec['keywords'], true));
761  // Merge keywords:
762  foreach ($words as $key => $v) {
763  if ($v) {
764  $keywords[$key] = 1;
765  } else {
766  unset($keywords[$key]);
767  }
768  }
769  // Compile new list:
770  $data = [];
771  $data['pages'][$pageId]['keywords'] = implode(', ', array_keys($keywords));
772  $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
773  $dataHandler->start($data, []);
774  $dataHandler->process_datamap();
775  }
776 
783  protected function makeItemTypeIcon($itemType)
784  {
785  if (!isset($this->iconFileNameCache[$itemType])) {
786  $icon = '';
787  if ($itemType === '0') {
788  $icon = 'EXT:indexed_search/Resources/Public/Icons/FileTypes/pages.gif';
789  } elseif ($this->external_parsers[$itemType]) {
790  $icon = $this->external_parsers[$itemType]->getIcon($itemType);
791  }
792  $this->iconFileNameCache[$itemType] = $icon;
793  }
794  return $this->iconFileNameCache[$itemType];
795  }
796 
800  protected function getBackendUserAuthentication()
801  {
802  return $GLOBALS['BE_USER'];
803  }
804 }
static intExplode($delimiter, $string, $removeEmptyValues=false, $limit=0)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static makeInstance($className,... $constructorArguments)
static stripLogicalOperatorPrefix(string $constraint)
static getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']