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