TYPO3  7.6
AdministrationRepository.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\IndexedSearch\Domain\Repository;
3 
29 
34 {
40  public $external_parsers = array();
41 
45  protected $allPhashListed = array();
46 
50  protected $iconFileNameCache = array();
51 
58  public function getGrlistRecord($phash)
59  {
60  $db = $this->getDatabaseConnection();
61  $res = $db->exec_SELECTquery('index_grlist.*', 'index_grlist', 'phash=' . (int)$phash);
62  $allRows = array();
63  $numberOfRows = $db->sql_num_rows($res);
64  while ($row = $db->sql_fetch_assoc($res)) {
65  $row['pcount'] = $numberOfRows;
66  $allRows[] = $row;
67  }
68  $db->sql_free_result($res);
69  return $allRows;
70  }
71 
78  public function getNumberOfFulltextRecords($phash)
79  {
80  return $this->getDatabaseConnection()->exec_SELECTcountRows('phash', 'index_fulltext', 'phash=' . (int)$phash);
81  }
82 
89  public function getNumberOfWords($phash)
90  {
91  return $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'index_rel', 'phash=' . (int)$phash);
92  }
93 
100  {
101  $result = array();
102 
103  $db = $this->getDatabaseConnection();
104  $res = $db->exec_SELECTquery(
105  'count(*) AS pcount,index_phash.*',
106  'index_phash',
107  'item_type<>\'0\'',
108  'phash_grouping,phash,cHashParams,data_filename,data_page_id,data_page_reg1,data_page_type,data_page_mp,gr_list,item_type,item_title,item_description,item_mtime,tstamp,item_size,contentHash,crdate,parsetime,sys_language_uid,item_crdate,externalUrl,recordUid,freeIndexUid,freeIndexSetId',
109  'item_type'
110  );
111  while ($row = $db->sql_fetch_assoc($res)) {
112  $this->addAdditionalInformation($row);
113 
114  $result[] = $row;
115 
116  if ($row['pcount'] > 1) {
117  $res2 = $db->exec_SELECTquery(
118  'index_phash.*',
119  'index_phash',
120  'phash_grouping=' . (int)$row['phash_grouping'] . ' AND phash<>' . (int)$row['phash']
121  );
122  while ($row2 = $db->sql_fetch_assoc($res2)) {
123  $this->addAdditionalInformation($row2);
124  $result[] = $row2;
125  }
126  $db->sql_free_result($res2);
127  }
128  }
129  $db->sql_free_result($res);
130 
131  return $result;
132  }
133 
139  public function getRecordsNumbers()
140  {
141  $tables = array(
142  'index_phash',
143  'index_words',
144  'index_rel',
145  'index_grlist',
146  'index_section',
147  'index_fulltext',
148  );
149  $recordList = array();
150  foreach ($tables as $tableName) {
151  $recordList[$tableName] = $this->getDatabaseConnection()->exec_SELECTcountRows('*', $tableName);
152  }
153  return $recordList;
154  }
155 
161  public function getPageHashTypes()
162  {
163  $counts = array();
164  $types = array(
165  'html' => 1,
166  'htm' => 1,
167  'pdf' => 2,
168  'doc' => 3,
169  'txt' => 4
170  );
171  $revTypes = array_flip($types);
172  $revTypes[0] = 'TYPO3 page';
173  $db = $this->getDatabaseConnection();
174  $res = $db->exec_SELECTquery('count(*),item_type', 'index_phash', '', 'item_type', 'item_type');
175  while ($row = $db->sql_fetch_row($res)) {
176  $itemType = $row[1];
177  $counts[] = array(
178  'count' => $row[0],
179  'name' => $revTypes[$itemType],
180  'type' => $itemType,
181  'uniqueCount' => $this->countUniqueTypes($itemType),
182  );
183  }
184  $db->sql_free_result($res);
185 
186  return $counts;
187  }
188 
195  protected function countUniqueTypes($itemType)
196  {
197  $db = $this->getDatabaseConnection();
198  $res = $db->exec_SELECTquery(
199  'count(*)',
200  'index_phash',
201  'item_type=' . $db->fullQuoteStr($itemType, 'index_phash'),
202  'phash_grouping'
203  );
204  $items = array();
205  while ($row = $db->sql_fetch_row($res)) {
206  $items[] = $row;
207  }
208  $db->sql_free_result($res);
209 
210  return count($items);
211  }
212 
219  public function getNumberOfSections($pageHash)
220  {
221  return $this->getDatabaseConnection()->exec_SELECTcountRows('phash', 'index_section', 'phash=' . (int)$pageHash);
222  }
223 
229  public function getPageStatistic()
230  {
231  $result = array();
232  $db = $this->getDatabaseConnection();
233  $res = $db->exec_SELECTquery(
234  'count(*) AS pcount,index_phash.*',
235  'index_phash',
236  'data_page_id<>0',
237  'phash_grouping,phash,cHashParams,data_filename,data_page_id,data_page_reg1,data_page_type,data_page_mp,gr_list,item_type,item_title,item_description,item_mtime,tstamp,item_size,contentHash,crdate,parsetime,sys_language_uid,item_crdate,externalUrl,recordUid,freeIndexUid,freeIndexSetId',
238  'data_page_id'
239  );
240  while ($row = $db->sql_fetch_assoc($res)) {
241  $this->addAdditionalInformation($row);
242  $result[] = $row;
243 
244  if ($row['pcount'] > 1) {
245  $res2 = $db->exec_SELECTquery(
246  'index_phash.*',
247  'index_phash',
248  'phash_grouping=' . (int)$row['phash_grouping'] . ' AND phash<>' . (int)$row['phash']
249  );
250  while ($row2 = $db->sql_fetch_assoc($res2)) {
251  $this->addAdditionalInformation($row2);
252  $result[] = $row2;
253  }
254  $db->sql_free_result($res2);
255  }
256  }
257  $db->sql_free_result($res);
258 
259  return $result;
260  }
261 
270  public function getGeneralSearchStatistic($additionalWhere, $pageUid, $max = 50)
271  {
272  $queryParts = array(
273  'SELECT' => 'word, COUNT(*) AS c',
274  'FROM' => 'index_stat_word',
275  'WHERE' => sprintf('pageid= %d ' . $additionalWhere, $pageUid),
276  'GROUPBY' => 'word',
277  'ORDERBY' => '',
278  'LIMIT' => (int)$max
279  );
280  $db = $this->getDatabaseConnection();
281  $res = $db->exec_SELECTquery(
282  $queryParts['SELECT'],
283  $queryParts['FROM'],
284  $queryParts['WHERE'],
285  $queryParts['GROUPBY'],
286  $queryParts['ORDERBY'],
287  $queryParts['LIMIT']
288  );
289 
290  $count = 0;
291  if ($res) {
292  $count = $db->sql_num_rows($res);
293  }
294 
295  $db->sql_free_result($res);
296 
297  // exist several statistics for this page?
298  if ($count == 0) {
299  // Limit access to pages of the current site
300  $secureAddWhere = ' AND pageid IN (' . $this->extGetTreeList((int)$pageUid, 100, 0, '1=1') . ') ';
301  $queryParts['WHERE'] = '1=1 ' . $additionalWhere . $secureAddWhere;
302  }
303 
304  return $db->exec_SELECTgetRows(
305  $queryParts['SELECT'],
306  $queryParts['FROM'],
307  $queryParts['WHERE'],
308  $queryParts['GROUPBY'],
309  $queryParts['ORDERBY'],
310  $queryParts['LIMIT']
311  );
312  }
313 
320  protected function addAdditionalInformation(array &$row)
321  {
322  $grListRec = $this->getGrlistRecord($row['phash']);
323  $unserializedCHashParams = unserialize($row['cHashParams']);
324 
325  $row['numberOfWords'] = $this->getNumberOfWords($row['phash']);
326  $row['numberOfSections'] = $this->getNumberOfSections($row['phash']);
327  $row['numberOfFulltext'] = $this->getNumberOfFulltextRecords($row['phash']);
328  $row['cHashParams'] = !empty($unserializedCHashParams) ? $unserializedCHashParams : '';
329  $row['grList'] = $grListRec;
330  }
331 
340  public function getTree($pageId, $depth = 4, $mode)
341  {
342  $allLines = array();
343  $pageRecord = BackendUtility::getRecord('pages', (int)$pageId);
344  if (!$pageRecord) {
345  return $allLines;
346  }
348  $tree = GeneralUtility::makeInstance(PageTreeView::class);
349  $perms_clause = $this->getBackendUserAuthentication()->getPagePermsClause(1);
350  $tree->init('AND ' . $perms_clause);
351  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
352  $HTML = '<span title="' . htmlspecialchars($pageRecord['title']) . '">' . $iconFactory->getIconForRecord('pages', $pageRecord, Icon::SIZE_SMALL)->render() . '</span>';
353  $tree->tree[] = array(
354  'row' => $pageRecord,
355  'HTML' => $HTML
356  );
357 
358  if ($depth > 0) {
359  $tree->getTree((int)$pageId, $depth, '');
360  }
361  $db = $this->getDatabaseConnection();
362  foreach ($tree->tree as $singleLine) {
363  $res = $db->exec_SELECTquery(
364  'ISEC.phash_t3, ISEC.rl0, ISEC.rl1, ISEC.rl2, ISEC.page_id, ISEC.uniqid, ' .
365  'IP.phash, IP.phash_grouping, IP.cHashParams, IP.data_filename, IP.data_page_id, ' .
366  'IP.data_page_reg1, IP.data_page_type, IP.data_page_mp, IP.gr_list, IP.item_type, ' .
367  'IP.item_title, IP.item_description, IP.item_mtime, IP.tstamp, IP.item_size, ' .
368  'IP.contentHash, IP.crdate, IP.parsetime, IP.sys_language_uid, IP.item_crdate, ' .
369  'IP.externalUrl, IP.recordUid, IP.freeIndexUid, IP.freeIndexSetId, count(*) AS count_val',
370  'index_phash IP, index_section ISEC',
371  'IP.phash = ISEC.phash AND ISEC.page_id = ' . (int)$singleLine['row']['uid'],
372  'IP.phash,IP.phash_grouping,IP.cHashParams,IP.data_filename,IP.data_page_id,IP.data_page_reg1,IP.data_page_type,IP.data_page_mp,IP.gr_list,IP.item_type,IP.item_title,IP.item_description,IP.item_mtime,IP.tstamp,IP.item_size,IP.contentHash,IP.crdate,IP.parsetime,IP.sys_language_uid,IP.item_crdate,ISEC.phash,ISEC.phash_t3,ISEC.rl0,ISEC.rl1,ISEC.rl2,ISEC.page_id,ISEC.uniqid,IP.externalUrl,IP.recordUid,IP.freeIndexUid,IP.freeIndexSetId',
373  'IP.item_type, IP.tstamp',
374  10 + 1
375  );
376  $lines = array();
377  // Collecting phash values (to remove local indexing for)
378  // Traverse the result set of phash rows selected:
379  while ($row = $db->sql_fetch_assoc($res)) {
380  $this->allPhashListed[] = $row['phash'];
381  // Adds a display row:
382  $row['icon'] = $this->makeItemTypeIcon($row['item_type']);
383  $row['wordCount'] = count($db->exec_SELECTgetRows(
384  'index_words.baseword, index_rel.*',
385  'index_rel, index_words',
386  'index_rel.phash = ' . (int)$row['phash'] . ' AND index_words.wid = index_rel.wid',
387  '',
388  '',
389  '',
390  'baseword'
391  ));
392 
393  if ($mode === 'content') {
394  $row['fulltextData'] = $db->exec_SELECTgetSingleRow(
395  '*',
396  'index_fulltext',
397  'phash = ' . $row['phash']);
398  $wordRecords = $db->exec_SELECTgetRows(
399  'index_words.baseword, index_rel.*',
400  'index_rel, index_words',
401  'index_rel.phash = ' . (int)$row['phash'] . ' AND index_words.wid = index_rel.wid',
402  '', '', '', 'baseword');
403  if (is_array($wordRecords)) {
404  $indexed_words = array_keys($wordRecords);
405  sort($indexed_words);
406  $row['allWords'] = $indexed_words;
407  }
408  }
409 
410  $lines[] = $row;
411  }
412 
413  $singleLine['lines'] = $lines;
414  $allLines[] = $singleLine;
415  }
416 
417  return $allLines;
418  }
419 
430  protected function extGetTreeList($id, $depth, $begin = 0, $perms_clause)
431  {
432  $list = GeneralUtility::makeInstance(FrontendBackendUserAuthentication::class)->extGetTreeList($id, $depth, $begin, $perms_clause);
433 
434  if (empty($list)) {
435  $list = $id;
436  } else {
437  $list = rtrim($list, ',') . ',' . $id;
438  }
439 
440  return $list;
441  }
442 
451  public function removeIndexedPhashRow($phashList, $pageId, $depth = 4)
452  {
453  if ($phashList === 'ALL') {
454  $this->getTree($pageId, $depth, '');
455  $phashRows = $this->allPhashListed;
456  $this->allPhashListed = array();
457  } else {
458  $phashRows = GeneralUtility::trimExplode(',', $phashList, true);
459  }
460 
461  $db = $this->getDatabaseConnection();
462  foreach ($phashRows as $phash) {
463  $phash = (int)$phash;
464  if ($phash > 0) {
465  $idList = array();
466  $res = $db->exec_SELECTquery('page_id', 'index_section', 'phash=' . $phash);
467  while ($row = $db->sql_fetch_assoc($res)) {
468  $idList[] = (int)$row['page_id'];
469  }
470  $db->sql_free_result($res);
471 
472  if (!empty($idList)) {
474  $pageCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_pages');
475  foreach ($idList as $pageId) {
476  $pageCache->flushByTag('pageId_' . $pageId);
477  }
478  }
479 
480  // Removing old registrations for all tables.
481  $tableArr = array('index_phash', 'index_rel', 'index_section', 'index_grlist', 'index_fulltext', 'index_debug');
482  foreach ($tableArr as $table) {
483  $db->exec_DELETEquery($table, 'phash=' . $phash);
484  }
485  }
486  }
487  }
488 
495  public function saveStopWords(array $words)
496  {
497  foreach ($words as $wid => $state) {
498  $fieldArray = array(
499  'is_stopword' => (int)$state
500  );
501  $this->getDatabaseConnection()->exec_UPDATEquery('index_words', 'wid=' . (int)$wid, $fieldArray);
502  }
503  }
504 
512  public function saveKeywords(array $words, $pageId)
513  {
514  // Get pages current keywords
515  $pageRec = BackendUtility::getRecord('pages', $pageId);
516  if (!is_array($pageRec)) {
517  return;
518  }
519  $keywords = array_flip(GeneralUtility::trimExplode(',', $pageRec['keywords'], true));
520  // Merge keywords:
521  foreach ($words as $key => $v) {
522  if ($v) {
523  $keywords[$key] = 1;
524  } else {
525  unset($keywords[$key]);
526  }
527  }
528  // Compile new list:
529  $data = array();
530  $data['pages'][$pageId]['keywords'] = implode(', ', array_keys($keywords));
531  $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
532  $dataHandler->stripslashes_values = 0;
533  $dataHandler->start($data, array());
534  $dataHandler->process_datamap();
535  }
536 
543  protected function makeItemTypeIcon($itemType)
544  {
545  if (!isset($this->iconFileNameCache[$itemType])) {
546  $icon = '';
547  if ($itemType === '0') {
548  $icon = 'EXT:indexed_search/Resources/Public/Icons/FileTypes/pages.gif';
549  } elseif ($this->external_parsers[$itemType]) {
550  $icon = $this->external_parsers[$itemType]->getIcon($itemType);
551  }
552  $this->iconFileNameCache[$itemType] = $icon;
553  }
554  return $this->iconFileNameCache[$itemType];
555  }
556 
560  protected function getDatabaseConnection()
561  {
562  return $GLOBALS['TYPO3_DB'];
563  }
564 
568  protected function getBackendUserAuthentication()
569  {
570  return $GLOBALS['BE_USER'];
571  }
572 }