TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
AdministrationRepository.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\IndexedSearch\Domain\Repository;
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 
439  protected function addAdditionalInformation(array &$row)
440  {
441  $grListRec = $this->getGrlistRecord($row['phash']);
442  $unserializedCHashParams = unserialize($row['cHashParams']);
443 
444  $row['numberOfWords'] = $this->getNumberOfWords($row['phash']);
445  $row['numberOfSections'] = $this->getNumberOfSections($row['phash']);
446  $row['numberOfFulltext'] = $this->getNumberOfFulltextRecords($row['phash']);
447  $row['cHashParams'] = !empty($unserializedCHashParams) ? $unserializedCHashParams : '';
448  $row['grList'] = $grListRec;
449  }
450 
459  public function getTree($pageId, $depth = 4, $mode)
460  {
461  $allLines = [];
462  $pageRecord = BackendUtility::getRecord('pages', (int)$pageId);
463  if (!$pageRecord) {
464  return $allLines;
465  }
467  $tree = GeneralUtility::makeInstance(PageTreeView::class);
468  $perms_clause = $this->getBackendUserAuthentication()->getPagePermsClause(1);
469  $tree->init('AND ' . $perms_clause);
470  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
471  $HTML = '<span title="' . htmlspecialchars($pageRecord['title']) . '">' . $iconFactory->getIconForRecord('pages', $pageRecord, Icon::SIZE_SMALL)->render() . '</span>';
472  $tree->tree[] = [
473  'row' => $pageRecord,
474  'HTML' => $HTML
475  ];
476 
477  if ($depth > 0) {
478  $tree->getTree((int)$pageId, $depth, '');
479  }
480 
481  foreach ($tree->tree as $singleLine) {
482  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_phash');
483  $result = $queryBuilder->select(
484  'ISEC.phash_t3',
485  'ISEC.rl0',
486  'ISEC.rl1',
487  'ISEC.rl2',
488  'ISEC.page_id',
489  'ISEC.uniqid',
490  'IP.phash',
491  'IP.phash_grouping',
492  'IP.cHashParams',
493  'IP.data_filename',
494  'IP.data_page_id',
495  'IP.data_page_reg1',
496  'IP.data_page_type',
497  'IP.data_page_mp',
498  'IP.gr_list',
499  'IP.item_type',
500  'IP.item_title',
501  'IP.item_description',
502  'IP.item_mtime',
503  'IP.tstamp',
504  'IP.item_size',
505  'IP.contentHash',
506  'IP.crdate',
507  'IP.parsetime',
508  'IP.sys_language_uid',
509  'IP.item_crdate',
510  'IP.externalUrl',
511  'IP.recordUid',
512  'IP.freeIndexUid',
513  'IP.freeIndexSetId'
514  )
515  ->addSelectLiteral($queryBuilder->expr()->count('*', 'count_val'))
516  ->from('index_phash', 'IP')
517  ->from('index_section', 'ISEC')
518  ->where(
519  $queryBuilder->expr()->eq('IP.phash', $queryBuilder->quoteIdentifier('ISEC.phash')),
520  $queryBuilder->expr()->eq(
521  'ISEC.page_id',
522  $queryBuilder->createNamedParameter($singleLine['row']['uid'], \PDO::PARAM_INT)
523  )
524  )
525  ->groupBy(
526  'IP.phash',
527  'IP.phash_grouping',
528  'IP.cHashParams',
529  'IP.data_filename',
530  'IP.data_page_id',
531  'IP.data_page_reg1',
532  'IP.data_page_type',
533  'IP.data_page_mp',
534  'IP.gr_list',
535  'IP.item_type',
536  'IP.item_title',
537  'IP.item_description',
538  'IP.item_mtime',
539  'IP.tstamp',
540  'IP.item_size',
541  'IP.contentHash',
542  'IP.crdate',
543  'IP.parsetime',
544  'IP.sys_language_uid',
545  'IP.item_crdate',
546  'ISEC.phash',
547  'ISEC.phash_t3',
548  'ISEC.rl0',
549  'ISEC.rl1',
550  'ISEC.rl2',
551  'ISEC.page_id',
552  'ISEC.uniqid',
553  'IP.externalUrl',
554  'IP.recordUid',
555  'IP.freeIndexUid',
556  'IP.freeIndexSetId'
557  )
558  ->orderBy('IP.item_type')
559  ->addOrderBy('IP.tstamp')
560  ->setMaxResults(11)
561  ->execute();
562 
563  $lines = [];
564  // Collecting phash values (to remove local indexing for)
565  // Traverse the result set of phash rows selected:
566  while ($row = $result->fetch()) {
567  $row['icon'] = $this->makeItemTypeIcon($row['item_type']);
568  $this->allPhashListed[] = $row['phash'];
569 
570  // Adds a display row:
571  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
572  ->getQueryBuilderForTable('index_rel');
573  $wordCountResult = $queryBuilder->count('index_words.baseword')
574  ->from('index_rel')
575  ->from('index_words')
576  ->where(
577  $queryBuilder->expr()->eq(
578  'index_rel.phash',
579  $queryBuilder->createNamedParameter($row['phash'], \PDO::PARAM_INT)
580  ),
581  $queryBuilder->expr()->eq('index_words.wid', $queryBuilder->quoteIdentifier('index_rel.wid'))
582  )
583  ->groupBy('index_words.baseword')
584  ->execute();
585 
586  $row['wordCount'] = $wordCountResult->rowCount();
587  $wordCountResult->closeCursor();
588 
589  if ($mode === 'content') {
590  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
591  ->getQueryBuilderForTable('index_fulltext');
592  $row['fulltextData'] = $queryBuilder->select('*')
593  ->from('index_fulltext')
594  ->where(
595  $queryBuilder->expr()->eq(
596  'phash',
597  $queryBuilder->createNamedParameter($row['phash'], \PDO::PARAM_INT)
598  )
599  )
600  ->setMaxResults(1)
601  ->execute()
602  ->fetch();
603 
604  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
605  ->getQueryBuilderForTable('index_rel');
606  $wordRecords = $queryBuilder->select('index_words.baseword')
607  ->from('index_rel')
608  ->from('index_words')
609  ->where(
610  $queryBuilder->expr()->eq(
611  'index_rel.phash',
612  $queryBuilder->createNamedParameter($row['phash'], \PDO::PARAM_INT)
613  ),
614  $queryBuilder->expr()->eq(
615  'index_words.wid',
616  $queryBuilder->quoteIdentifier('index_rel.wid')
617  )
618  )
619  ->groupBy('index_words.baseword')
620  ->orderBy('index_words.baseword')
621  ->execute()
622  ->fetchAll();
623 
624  if (is_array($wordRecords)) {
625  $row['allWords'] = array_column($wordRecords, 'baseword');
626  }
627  }
628 
629  $lines[] = $row;
630  }
631 
632  $singleLine['lines'] = $lines;
633  $allLines[] = $singleLine;
634  }
635 
636  return $allLines;
637  }
638 
649  protected function extGetTreeList($id, $depth, $begin = 0, $perms_clause)
650  {
651  $list = GeneralUtility::makeInstance(FrontendBackendUserAuthentication::class)
652  ->extGetTreeList($id, $depth, $begin, $perms_clause);
653 
654  if (empty($list)) {
655  $list = $id;
656  } else {
657  $list = rtrim($list, ',') . ',' . $id;
658  }
659 
660  return $list;
661  }
662 
671  public function removeIndexedPhashRow($phashList, $pageId, $depth = 4)
672  {
673  if ($phashList === 'ALL') {
674  $this->getTree($pageId, $depth, '');
675  $phashRows = $this->allPhashListed;
676  $this->allPhashListed = [];
677  } else {
678  $phashRows = GeneralUtility::trimExplode(',', $phashList, true);
679  }
680 
681  foreach ($phashRows as $phash) {
682  $phash = (int)$phash;
683  if ($phash > 0) {
684  $idList = [];
685  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
686  ->getQueryBuilderForTable('index_section');
687  $res = $queryBuilder
688  ->select('page_id')
689  ->from('index_section')
690  ->where(
691  $queryBuilder->expr()->eq(
692  'phash',
693  $queryBuilder->createNamedParameter($phash, \PDO::PARAM_INT)
694  )
695  )
696  ->execute();
697  while ($row = $res->fetch()) {
698  $idList[] = (int)$row['page_id'];
699  }
700 
701  if (!empty($idList)) {
703  $pageCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_pages');
704  foreach ($idList as $pageId) {
705  $pageCache->flushByTag('pageId_' . $pageId);
706  }
707  }
708 
709  // Removing old registrations for all tables.
710  $tableArr = [
711  'index_phash',
712  'index_rel',
713  'index_section',
714  'index_grlist',
715  'index_fulltext',
716  'index_debug'
717  ];
718  foreach ($tableArr as $table) {
719  GeneralUtility::makeInstance(ConnectionPool::class)
720  ->getConnectionForTable($table)
721  ->delete($table, ['phash' => (int)$phash]);
722  }
723  }
724  }
725  }
726 
733  public function saveStopWords(array $words)
734  {
735  foreach ($words as $wid => $state) {
736  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_words');
737  $queryBuilder
738  ->update('index_words')
739  ->set('is_stopword', (int)$state)
740  ->where(
741  $queryBuilder->expr()->eq(
742  'wid',
743  $queryBuilder->createNamedParameter($wid, \PDO::PARAM_INT)
744  )
745  )
746  ->execute();
747  }
748  }
749 
757  public function saveKeywords(array $words, $pageId)
758  {
759  // Get pages current keywords
760  $pageRec = BackendUtility::getRecord('pages', $pageId);
761  if (!is_array($pageRec)) {
762  return;
763  }
764  $keywords = array_flip(GeneralUtility::trimExplode(',', $pageRec['keywords'], true));
765  // Merge keywords:
766  foreach ($words as $key => $v) {
767  if ($v) {
768  $keywords[$key] = 1;
769  } else {
770  unset($keywords[$key]);
771  }
772  }
773  // Compile new list:
774  $data = [];
775  $data['pages'][$pageId]['keywords'] = implode(', ', array_keys($keywords));
776  $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
777  $dataHandler->start($data, []);
778  $dataHandler->process_datamap();
779  }
780 
787  protected function makeItemTypeIcon($itemType)
788  {
789  if (!isset($this->iconFileNameCache[$itemType])) {
790  $icon = '';
791  if ($itemType === '0') {
792  $icon = 'EXT:indexed_search/Resources/Public/Icons/FileTypes/pages.gif';
793  } elseif ($this->external_parsers[$itemType]) {
794  $icon = $this->external_parsers[$itemType]->getIcon($itemType);
795  }
796  $this->iconFileNameCache[$itemType] = $icon;
797  }
798  return $this->iconFileNameCache[$itemType];
799  }
800 
804  protected function getBackendUserAuthentication()
805  {
806  return $GLOBALS['BE_USER'];
807  }
808 }
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
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']
static makeInstance($className,...$constructorArguments)
static stripLogicalOperatorPrefix(string $constraint)
static intExplode($delimiter, $string, $removeEmptyValues=false, $limit=0)