Completed
Push — master ( 0964f5...56617a )
by Oscar
03:10
created

SearchQuery   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 214
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 0

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 35
c 2
b 0
f 1
lcom 2
cbo 0
dl 0
loc 214
rs 9

15 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 20 6
B getQuery() 0 19 5
A getPage() 0 4 1
A setPage() 0 4 1
A getId() 0 4 2
A getIds() 0 4 1
A setIds() 0 4 1
A getWords() 0 4 1
A setWords() 0 4 1
A getCondition() 0 4 2
A setCondition() 0 4 1
A getConditions() 0 4 1
A getSort() 0 4 1
A getDirection() 0 4 2
D parseQuery() 0 27 9
1
<?php
2
3
namespace Folk;
4
5
/**
6
 * Class to manage a query to search rows.
7
 */
8
class SearchQuery
9
{
10
    protected $page;
11
    protected $ids = [];
12
    protected $conditions = [];
13
    protected $words = [];
14
    protected $sort;
15
    protected $direction;
16
17
    /**
18
     * @param array $query
19
     */
20
    public function __construct(array $query = [])
21
    {
22
        if (!empty($query['query'])) {
23
            $this->parseQuery($query['query']);
24
        }
25
26
        if (!empty($query['page'])) {
27
            $this->page = (int) $query['page'];
28
        }
29
30
        if (!empty($query['sort'])) {
31
            $this->sort = $query['sort'];
32
            
33
            if (!empty($query['direction'])) {
34
                $this->direction = strtoupper($query['direction']) === 'DESC' ? 'DESC' : 'ASC';
35
            } else {
36
                $this->direction = 'ASC';
37
            }
38
        }
39
    }
40
41
    /**
42
     * Returns the query as string.
43
     *
44
     * @return string
45
     */
46
    public function getQuery()
47
    {
48
        $query = implode(' ', $this->words);
49
50
        foreach ($this->ids as $id) {
51
            $query .= " #{$id}";
52
        }
53
        foreach ($this->conditions as $name => $values) {
54
            foreach ($values as $value) {
55
                if (strpos($value, ' ') === false) {
56
                    $query .= " {$name}:{$value}";
57
                } else {
58
                    $query .= " {$name}:\"{$value}\"";
59
                }
60
            }
61
        }
62
63
        return trim($query);
64
    }
65
66
    /**
67
     * Returns the page number.
68
     *
69
     * @return null|int
70
     */
71
    public function getPage()
72
    {
73
        return $this->page;
74
    }
75
76
    /**
77
     * Set the page.
78
     *
79
     * @param null|int $page
80
     */
81
    public function setPage($page)
82
    {
83
        $this->page = $page;
84
    }
85
86
    /**
87
     * Returns the first id.
88
     *
89
     * @return string|null
90
     */
91
    public function getId()
92
    {
93
        return isset($this->ids[0]) ? $this->ids[0] : null;
94
    }
95
96
    /**
97
     * Returns all ids found.
98
     *
99
     * @return array
100
     */
101
    public function getIds()
102
    {
103
        return $this->ids;
104
    }
105
106
    /**
107
     * Set new ids.
108
     *
109
     * @param array $ids
110
     */
111
    public function setIds(array $ids)
112
    {
113
        $this->ids = $ids;
114
    }
115
116
    /**
117
     * Returns all words in the query.
118
     *
119
     * @return array
120
     */
121
    public function getWords()
122
    {
123
        return $this->words;
124
    }
125
126
    /**
127
     * Set new words.
128
     *
129
     * @param array $words
130
     */
131
    public function setWords(array $words)
132
    {
133
        $this->words = $words;
134
    }
135
136
    /**
137
     * Return a condition.
138
     *
139
     * @return array|null
140
     */
141
    public function getCondition($name)
142
    {
143
        return isset($this->conditions[$name]) ? $this->conditions[$name] : null;
144
    }
145
146
    /**
147
     * Set a new condition.
148
     *
149
     * @param string $name
150
     * @param array  $value
151
     */
152
    public function setCondition($name, array $value)
153
    {
154
        return $this->conditions[$name] = $value;
155
    }
156
157
    /**
158
     * Return all conditions.
159
     *
160
     * @return array
161
     */
162
    public function getConditions()
163
    {
164
        return $this->conditions;
165
    }
166
167
    /**
168
     * Return the sort field.
169
     *
170
     * @return string|null
171
     */
172
    public function getSort()
173
    {
174
        return $this->sort;
175
    }
176
177
    /**
178
     * Return the sort direction in UPPERCASE.
179
     *
180
     * @return string|null
181
     */
182
    public function getDirection()
183
    {
184
        return isset($this->direction) ? strtoupper($this->direction) : null;
185
    }
186
187
    /**
188
     * Split a query in pieces.
189
     *
190
     * @param string $query
191
     *
192
     * @return array
193
     */
194
    protected function parseQuery($query)
195
    {
196
        preg_match_all('/([\w]+:)?("([^"]*)"|([^ ]*))/', trim($query), $pieces, PREG_SET_ORDER);
197
198
        if (is_array($pieces)) {
199
            foreach ($pieces as $piece) {
200
                if (empty($piece[0])) {
201
                    continue;
202
                }
203
204
                $name = $piece[1] ? substr($piece[1], 0, -1) : null;
205
                $value = isset($piece[4]) ? $piece[4] : $piece[3];
206
207
                if ($name !== null) {
208
                    if (!isset($this->conditions[$name])) {
209
                        $this->conditions[$name] = [$value];
210
                    } else {
211
                        $this->conditions[$name][] = $value;
212
                    }
213
                } elseif (preg_match('/^#[\w-]+$/', $value)) {
214
                    $this->ids[] = substr($value, 1);
215
                } else {
216
                    $this->words[] = $value;
217
                }
218
            }
219
        }
220
    }
221
}
222