PageRenderTime 28ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/concrete/src/Page/Search/IndexedSearch.php

https://gitlab.com/koodersmiikka/operaatio-terveys
PHP | 204 lines | 173 code | 27 blank | 4 comment | 22 complexity | 46267ffadf73cf7992c532ac8be3c25c MD5 | raw file
  1. <?php
  2. namespace Concrete\Core\Page\Search;
  3. use Concrete\Core\Cache\Cache;
  4. use Core;
  5. use Loader;
  6. use Config;
  7. use PageList;
  8. use Collection;
  9. use Area;
  10. use Concrete\Core\Area\SubArea;
  11. use Block;
  12. use stdClass;
  13. class IndexedSearch
  14. {
  15. public $searchBatchSize;
  16. public $searchReindexTimeout;
  17. private $cPathSections = array();
  18. private $searchableAreaNames;
  19. public function __construct() {
  20. $this->searchReindexTimeout = Config::get('concrete.misc.page_search_index_lifetime');
  21. $this->searchBatchSize = Config::get('concrete.limits.page_search_index_batch');
  22. }
  23. public function getSearchableAreaAction()
  24. {
  25. $action = Config::get('concrete.misc.search_index_area_method');
  26. if (!strlen($action)) {
  27. $action = 'blacklist';
  28. }
  29. return $action;
  30. }
  31. public function getSavedSearchableAreas()
  32. {
  33. $areas = Config::get('concrete.misc.search_index_area_list');
  34. $areas = unserialize($areas);
  35. if (!is_array($areas)) {
  36. $areas = array();
  37. }
  38. return $areas;
  39. }
  40. public function clearSearchIndex()
  41. {
  42. $db = Loader::db();
  43. $db->Execute('truncate table PageSearchIndex');
  44. }
  45. public function matchesArea($arHandle)
  46. {
  47. if (!isset($this->arHandles)) {
  48. $searchableAreaNamesInitial = $this->getSavedSearchableAreas();
  49. if ($this->getSearchableAreaAction() == 'blacklist') {
  50. $areas = Area::getHandleList();
  51. foreach ($areas as $arHandle) {
  52. if (!in_array($arHandle, $searchableAreaNamesInitial)) {
  53. $this->searchableAreaNames[] = $arHandle;
  54. }
  55. }
  56. } else {
  57. $this->searchableAreaNames = $searchableAreaNamesInitial;
  58. }
  59. }
  60. foreach ($this->searchableAreaNames as $sarHandle) {
  61. if (preg_match('/^' . preg_quote($sarHandle . SubArea::AREA_SUB_DELIMITER, '/') . '.+/i', $arHandle)) {
  62. return true;
  63. } else {
  64. if (in_array($arHandle, $this->searchableAreaNames)) {
  65. return true;
  66. }
  67. }
  68. }
  69. return false;
  70. }
  71. public function reindexPage($page)
  72. {
  73. $db = Loader::db();
  74. if (is_object($page) && ($page instanceof Collection) && ($page->getAttribute('exclude_search_index') != 1)) {
  75. $datetime = Loader::helper('date')->getOverridableNow();
  76. $db->Replace(
  77. 'PageSearchIndex',
  78. array(
  79. 'cID' => $page->getCollectionID(),
  80. 'cName' => $page->getCollectionName(),
  81. 'cDescription' => $page->getCollectionDescription(),
  82. 'cPath' => $page->getCollectionPath(),
  83. 'cDatePublic' => $page->getCollectionDatePublic(),
  84. 'content' => $this->getBodyContentFromPage($page),
  85. 'cDateLastIndexed' => $datetime
  86. ),
  87. array('cID'),
  88. true
  89. );
  90. } else {
  91. $db->Execute('delete from PageSearchIndex where cID = ?', array($page->getCollectionID()));
  92. }
  93. }
  94. public function getBodyContentFromPage($c)
  95. {
  96. $text = '';
  97. $tagsToSpaces = array(
  98. '<br>',
  99. '<br/>',
  100. '<br />',
  101. '<p>',
  102. '</p>',
  103. '</ p>',
  104. '<div>',
  105. '</div>',
  106. '</ div>',
  107. '&nbsp;'
  108. );
  109. $blarray = array();
  110. $db = Loader::db();
  111. $r = $db->Execute(
  112. 'select bID, arHandle from CollectionVersionBlocks where cID = ? and cvID = ?',
  113. array($c->getCollectionID(), $c->getVersionID())
  114. );
  115. $th = Loader::helper('text');
  116. while ($row = $r->FetchRow()) {
  117. if ($this->matchesArea($row['arHandle'])) {
  118. $b = Block::getByID($row['bID'], $c, $row['arHandle']);
  119. if (!is_object($b)) {
  120. continue;
  121. }
  122. $bi = $b->getInstance();
  123. if (method_exists($bi, 'getSearchableContent')) {
  124. $searchableContent = $bi->getSearchableContent();
  125. if (strlen(trim($searchableContent))) {
  126. $text .= $th->decodeEntities(
  127. strip_tags(str_ireplace($tagsToSpaces, ' ', $searchableContent)),
  128. ENT_QUOTES,
  129. APP_CHARSET
  130. ) . ' ';
  131. }
  132. }
  133. unset($b);
  134. unset($bi);
  135. }
  136. }
  137. return $text;
  138. }
  139. /**
  140. * Reindexes the search engine.
  141. */
  142. public function reindexAll($fullReindex = false)
  143. {
  144. Cache::disableAll();
  145. $db = Loader::db();
  146. if ($fullReindex) {
  147. $db->Execute("truncate table PageSearchIndex");
  148. }
  149. $pl = new PageList();
  150. $pl->ignoreAliases();
  151. $pl->ignorePermissions();
  152. $pl->sortByCollectionIDAscending();
  153. $pl->filter(
  154. false,
  155. '(c.cDateModified > psi.cDateLastIndexed or UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(psi.cDateLastIndexed) > ' . $this->searchReindexTimeout . ' or psi.cID is null or psi.cDateLastIndexed is null)'
  156. );
  157. $pl->filter(false, '(ak_exclude_search_index is null or ak_exclude_search_index = 0)');
  158. $pages = $pl->get($this->searchBatchSize);
  159. $num = 0;
  160. foreach ($pages as $c) {
  161. // make sure something is approved
  162. $cv = $c->getVersionObject();
  163. if (!$cv->cvIsApproved) {
  164. continue;
  165. }
  166. $c->reindex($this, true);
  167. $num++;
  168. unset($c);
  169. }
  170. $pnum = Collection::reindexPendingPages();
  171. $num = $num + $pnum;
  172. Cache::enableAll();
  173. $result = new stdClass;
  174. $result->count = $num;
  175. return $result;
  176. }
  177. }