1<?php 2 3namespace dokuwiki\plugin\struct\meta; 4 5/** 6 * Manage dynamic parameters for aggregations 7 * 8 * @package dokuwiki\plugin\struct\meta 9 */ 10class SearchConfigParameters 11{ 12 /** @var string parameter name to pass filters */ 13 public static $PARAM_FILTER = 'flt'; 14 /** @var string parameter name to pass offset */ 15 public static $PARAM_OFFSET = 'ofs'; 16 /** @var string parameter name to pass srt */ 17 public static $PARAM_SORT = 'srt'; 18 19 /** @var SearchConfig */ 20 protected $searchConfig; 21 22 /** @var null|array */ 23 protected $sort; 24 /** @var int */ 25 protected $offset = 0; 26 /** @var array */ 27 protected $filters = []; 28 29 /** 30 * Initializes the dynamic parameters from $INPUT 31 * 32 * @param SearchConfig $searchConfig 33 */ 34 public function __construct(SearchConfig $searchConfig) 35 { 36 global $INPUT; 37 $this->searchConfig = $searchConfig; 38 /** @var \helper_plugin_struct_config $confHlp */ 39 $confHlp = plugin_load('helper', 'struct_config'); 40 41 if ($INPUT->has(self::$PARAM_SORT)) { 42 [$colname, $sort] = $confHlp->parseSort($INPUT->str(self::$PARAM_SORT)); 43 $this->setSort($colname, $sort); 44 } 45 46 if ($INPUT->has(self::$PARAM_FILTER)) { 47 foreach ($INPUT->arr(self::$PARAM_FILTER) as $colcomp => $filter) { 48 [$colname, $comp, $value, ] = $confHlp->parseFilterLine('AND', $colcomp . $filter); 49 $this->addFilter($colname, $comp, $value); 50 } 51 } 52 53 if ($INPUT->has(self::$PARAM_OFFSET)) { 54 $this->setOffset($INPUT->int(self::$PARAM_OFFSET)); 55 } 56 } 57 58 /** 59 * Returns the full qualified name for a given column 60 * 61 * @param string|Column $column 62 * @return false|string 63 */ 64 protected function resolveColumn($column) 65 { 66 if (!is_a($column, Column::class)) { 67 $column = $this->searchConfig->findColumn($column); 68 if (!$column) return false; 69 } 70 /** @var Column $column */ 71 return $column->getFullQualifiedLabel(); 72 } 73 74 /** 75 * Sets the sorting column 76 * 77 * @param string|Column $column 78 * @param bool $asc 79 */ 80 public function setSort($column, $asc = true) 81 { 82 $column = $this->resolveColumn($column); 83 if (!$column) return; 84 $this->sort = [$column, $asc]; 85 } 86 87 /** 88 * Remove the sorting column 89 */ 90 public function removeSort() 91 { 92 $this->sort = null; 93 } 94 95 /** 96 * Set the offset 97 * 98 * @param int $offset 99 */ 100 public function setOffset($offset) 101 { 102 $this->offset = $offset; 103 } 104 105 /** 106 * Removes the offset 107 */ 108 public function removeOffset() 109 { 110 $this->offset = 0; 111 } 112 113 /** 114 * Adds another filter 115 * 116 * When there is a filter for that column already, the new filter overwrites it. Setting a 117 * blank value is the same as calling removeFilter() 118 * 119 * @param string|Column $column 120 * @param string $comp the comparator 121 * @param string $value the value to compare against 122 */ 123 public function addFilter($column, $comp, $value) 124 { 125 $column = $this->resolveColumn($column); 126 if (!$column) return; 127 128 if (trim($value) === '') { 129 $this->removeFilter($column); 130 } else { 131 $this->filters[$column] = [$comp, $value]; 132 } 133 } 134 135 /** 136 * Removes the filter for the given column 137 * 138 * @param $column 139 */ 140 public function removeFilter($column) 141 { 142 $column = $this->resolveColumn($column); 143 if (!$column) return; 144 if (isset($this->filters[$column])) unset($this->filters[$column]); 145 } 146 147 /** 148 * Remove all filter 149 */ 150 public function clearFilters() 151 { 152 $this->filters = []; 153 } 154 155 /** 156 * @return array the current filters 157 */ 158 public function getFilters() 159 { 160 return $this->filters; 161 } 162 163 /** 164 * Get the current parameters 165 * 166 * It creates a flat key value in a form that can be used to 167 * create URLs or Form parameters 168 * 169 * 170 * @return array 171 */ 172 public function getURLParameters() 173 { 174 $params = []; 175 if ($this->offset) { 176 $params[self::$PARAM_OFFSET] = $this->offset; 177 } 178 179 if ($this->sort) { 180 [$column, $asc] = $this->sort; 181 if (!$asc) $column = "^$column"; 182 $params[self::$PARAM_SORT] = $column; 183 } 184 185 if ($this->filters) { 186 foreach ($this->filters as $column => $filter) { 187 [$comp, $value] = $filter; 188 $key = self::$PARAM_FILTER . '[' . $column . $comp . ']'; 189 $params[$key] = $value; 190 } 191 } 192 193 return $params; 194 } 195 196 /** 197 * Applies the dynamic filter settings to the SearchConfig 198 */ 199 public function apply() 200 { 201 if ($this->offset) { 202 $this->searchConfig->setOffset($this->offset); 203 } 204 205 if ($this->sort) { 206 $this->searchConfig->clearSort(); // remove any existing sort 207 $this->searchConfig->addSort($this->sort[0], $this->sort[1]); 208 } 209 210 foreach ($this->filters as $colName => $filter) { 211 [$comp, $value] = $filter; 212 $this->searchConfig->addDynamicFilter($colName, $value, $comp, 'AND'); 213 } 214 } 215} 216