1<?php 2 3namespace dokuwiki\Ui; 4 5use dokuwiki\Search\Query\QueryParser; 6 7class SearchState 8{ 9 /** 10 * @var array 11 */ 12 protected $parsedQuery = []; 13 14 /** 15 * SearchState constructor. 16 * 17 * @param array $parsedQuery 18 */ 19 public function __construct(array $parsedQuery) 20 { 21 global $INPUT; 22 23 $this->parsedQuery = $parsedQuery; 24 if (!isset($parsedQuery['after'])) { 25 $this->parsedQuery['after'] = $INPUT->str('min'); 26 } 27 if (!isset($parsedQuery['before'])) { 28 $this->parsedQuery['before'] = $INPUT->str('max'); 29 } 30 if (!isset($parsedQuery['sort'])) { 31 $this->parsedQuery['sort'] = $INPUT->str('srt'); 32 } 33 } 34 35 /** 36 * Get a search state for the current search limited to a new namespace 37 * 38 * @param string $ns the namespace to which to limit the search, falsy to remove the limitation 39 * @param array $notns 40 * 41 * @return SearchState 42 */ 43 public function withNamespace($ns, array $notns = []) 44 { 45 $parsedQuery = $this->parsedQuery; 46 $parsedQuery['ns'] = $ns ? [$ns] : []; 47 $parsedQuery['notns'] = $notns; 48 49 return new SearchState($parsedQuery); 50 } 51 52 /** 53 * Get a search state for the current search with new search fragments and optionally phrases 54 * 55 * @param array $and 56 * @param array $not 57 * @param array $phrases 58 * 59 * @return SearchState 60 */ 61 public function withFragments(array $and, array $not, array $phrases = []) 62 { 63 $parsedQuery = $this->parsedQuery; 64 $parsedQuery['and'] = $and; 65 $parsedQuery['not'] = $not; 66 $parsedQuery['phrases'] = $phrases; 67 68 return new SearchState($parsedQuery); 69 } 70 71 /** 72 * Get a search state for the current search with with adjusted time limitations 73 * 74 * @param $after 75 * @param $before 76 * 77 * @return SearchState 78 */ 79 public function withTimeLimitations($after, $before) 80 { 81 $parsedQuery = $this->parsedQuery; 82 $parsedQuery['after'] = $after; 83 $parsedQuery['before'] = $before; 84 85 return new SearchState($parsedQuery); 86 } 87 88 /** 89 * Get a search state for the current search with adjusted sort preference 90 * 91 * @param $sort 92 * 93 * @return SearchState 94 */ 95 public function withSorting($sort) 96 { 97 $parsedQuery = $this->parsedQuery; 98 $parsedQuery['sort'] = $sort; 99 100 return new SearchState($parsedQuery); 101 } 102 103 /** 104 * Get a link that represents the current search state 105 * 106 * Note that this represents only a simplified version of the search state. 107 * Grouping with braces and "OR" conditions are not supported. 108 * 109 * @param $label 110 * 111 * @return string 112 */ 113 public function getSearchLink($label) 114 { 115 global $ID, $conf; 116 $parsedQuery = $this->parsedQuery; 117 118 $tagAttributes = [ 119 'target' => $conf['target']['wiki'], 120 ]; 121 122 $newQuery = (new QueryParser)->revert( 123 $parsedQuery['and'], 124 $parsedQuery['not'], 125 $parsedQuery['phrases'], 126 $parsedQuery['ns'], 127 $parsedQuery['notns'] 128 ); 129 $hrefAttributes = ['do' => 'search', 'sf' => '1', 'q' => $newQuery]; 130 if ($parsedQuery['after']) { 131 $hrefAttributes['min'] = $parsedQuery['after']; 132 } 133 if ($parsedQuery['before']) { 134 $hrefAttributes['max'] = $parsedQuery['before']; 135 } 136 if ($parsedQuery['sort']) { 137 $hrefAttributes['srt'] = $parsedQuery['sort']; 138 } 139 140 $href = wl($ID, $hrefAttributes, false, '&'); 141 return "<a href='$href' " . buildAttributes($tagAttributes, true) . ">$label</a>"; 142 } 143} 144