You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

137 lines
3.9 KiB

  1. <?php
  2. namespace dokuwiki\Action;
  3. use dokuwiki\Action\Exception\ActionAbort;
  4. /**
  5. * Class Search
  6. *
  7. * Search for pages and content
  8. *
  9. * @package dokuwiki\Action
  10. */
  11. class Search extends AbstractAction
  12. {
  13. protected $pageLookupResults = [];
  14. protected $fullTextResults = [];
  15. protected $highlight = [];
  16. /** @inheritdoc */
  17. public function minimumPermission()
  18. {
  19. return AUTH_NONE;
  20. }
  21. /**
  22. * we only search if a search word was given
  23. *
  24. * @inheritdoc
  25. */
  26. public function checkPreconditions()
  27. {
  28. parent::checkPreconditions();
  29. }
  30. public function preProcess()
  31. {
  32. global $QUERY, $ID, $conf, $INPUT;
  33. $s = cleanID($QUERY);
  34. if ($ID !== $conf['start'] && !$INPUT->has('q')) {
  35. parse_str($INPUT->server->str('QUERY_STRING'), $urlParts);
  36. $urlParts['q'] = $urlParts['id'];
  37. unset($urlParts['id']);
  38. $url = wl($ID, $urlParts, true, '&');
  39. send_redirect($url);
  40. }
  41. if ($s === '') throw new ActionAbort();
  42. $this->adjustGlobalQuery();
  43. }
  44. /** @inheritdoc */
  45. public function tplContent()
  46. {
  47. $this->execute();
  48. $search = new \dokuwiki\Ui\Search($this->pageLookupResults, $this->fullTextResults, $this->highlight);
  49. $search->show();
  50. }
  51. /**
  52. * run the search
  53. */
  54. protected function execute()
  55. {
  56. global $INPUT, $QUERY;
  57. $after = $INPUT->str('min');
  58. $before = $INPUT->str('max');
  59. $this->pageLookupResults = ft_pageLookup($QUERY, true, useHeading('navigation'), $after, $before);
  60. $this->fullTextResults = ft_pageSearch($QUERY, $highlight, $INPUT->str('srt'), $after, $before);
  61. $this->highlight = $highlight;
  62. }
  63. /**
  64. * Adjust the global query accordingly to the config search_nslimit and search_fragment
  65. *
  66. * This will only do something if the search didn't originate from the form on the searchpage itself
  67. */
  68. protected function adjustGlobalQuery()
  69. {
  70. global $conf, $INPUT, $QUERY, $ID;
  71. if ($INPUT->bool('sf')) {
  72. return;
  73. }
  74. $Indexer = idx_get_indexer();
  75. $parsedQuery = ft_queryParser($Indexer, $QUERY);
  76. if (empty($parsedQuery['ns']) && empty($parsedQuery['notns'])) {
  77. if ($conf['search_nslimit'] > 0) {
  78. if (getNS($ID) !== false) {
  79. $nsParts = explode(':', getNS($ID));
  80. $ns = implode(':', array_slice($nsParts, 0, $conf['search_nslimit']));
  81. $QUERY .= " @$ns";
  82. }
  83. }
  84. }
  85. if ($conf['search_fragment'] !== 'exact') {
  86. if (empty(array_diff($parsedQuery['words'], $parsedQuery['and']))) {
  87. if (strpos($QUERY, '*') === false) {
  88. $queryParts = explode(' ', $QUERY);
  89. $queryParts = array_map(function ($part) {
  90. if (strpos($part, '@') === 0) {
  91. return $part;
  92. }
  93. if (strpos($part, 'ns:') === 0) {
  94. return $part;
  95. }
  96. if (strpos($part, '^') === 0) {
  97. return $part;
  98. }
  99. if (strpos($part, '-ns:') === 0) {
  100. return $part;
  101. }
  102. global $conf;
  103. if ($conf['search_fragment'] === 'starts_with') {
  104. return $part . '*';
  105. }
  106. if ($conf['search_fragment'] === 'ends_with') {
  107. return '*' . $part;
  108. }
  109. return '*' . $part . '*';
  110. }, $queryParts);
  111. $QUERY = implode(' ', $queryParts);
  112. }
  113. }
  114. }
  115. }
  116. }