Completed
Pull Request — master (#143)
by
unknown
02:18
created

Facet::facetFunction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
c 0
b 0
f 0
rs 9.4285
cc 2
eloc 5
nc 2
nop 2
1
<?php
2
3
namespace Foolz\SphinxQL;
4
5
use Foolz\SphinxQL\Drivers\ConnectionInterface;
6
use Foolz\SphinxQL\Exception\SphinxQLException;
7
8
/**
9
 * Query Builder class for Facet statements.
10
 * @package Foolz\SphinxQL
11
 * @author Vicent Valls
12
 */
13
class Facet
14
{
15
    /**
16
     * A non-static connection for the current Facet object
17
     *
18
     * @var ConnectionInterface
19
     */
20
    protected $connection;
21
22
    /**
23
     * An SQL query that is not yet executed or "compiled"
24
     *
25
     * @var string
26
     */
27
    protected $query;
28
29
    /**
30
     * Array of select elements that will be comma separated.
31
     *
32
     * @var array
33
     */
34
    protected $facet = array();
35
36
    /**
37
     * BY array to be comma separated
38
     *
39
     * @var array
40
     */
41
    protected $by = array();
42
43
    /**
44
     * ORDER BY array
45
     *
46
     * @var array
47
     */
48
    protected $order_by = array();
49
50
    /**
51
     * When not null it adds an offset
52
     *
53
     * @var null|int
54
     */
55
    protected $offset;
56
57
    /**
58
     * When not null it adds a limit
59
     *
60
     * @var null|int
61
     */
62
    protected $limit;
63
64
    /**
65
     * @param ConnectionInterface|null $connection
66
     */
67
    public function __construct(ConnectionInterface $connection = null)
68
    {
69
        $this->connection = $connection;
70
    }
71
72
    /**
73
     * Returns the currently attached connection
74
     *
75
     * @returns ConnectionInterface|null
76
     */
77
    public function getConnection()
78
    {
79
        return $this->connection;
80
    }
81
82
    /**
83
     * Sets the connection to be used
84
     *
85
     * @param ConnectionInterface $connection
86
     * @return Facet
87
     */
88
    public function setConnection(ConnectionInterface $connection = null)
89
    {
90
        $this->connection = $connection;
91
        return $this;
92
    }
93
94
    /**
95
     * Facet the columns
96
     *
97
     * Gets the arguments passed as $facet->facet('one', 'two')
98
     * Using it with array maps values as column names
99
     *
100
     * Examples:
101
     *    $query->facet('idCategory');
102
     *    // FACET idCategory
103
     *
104
     *    $query->facet('idCategory', 'year');
105
     *    // FACET idCategory, year
106
     *
107
     *    $query->facet(array('categories' => 'idCategory', 'year', 'type' => 'idType'));
108
     *    // FACET idCategory AS categories, year, idType AS type
109
     *
110
     * @param array|string $columns Array or multiple string arguments containing column names
111
     *
112
     * @return Facet
113
     */
114
    public function facet($columns = null)
115
    {
116
        if (!is_array($columns)) {
117
            $columns = \func_get_args();
118
        }
119
120
        foreach ($columns as $key => $column) {
121
            if (is_int($key)) {
122
                if (is_array($column)) {
123
                    $this->facet($column);
124
                } else {
125
                    $this->facet[] = array($column, null);
126
                }
127
            } else {
128
                $this->facet[] = array($column, $key);
129
            }
130
        }
131
132
        return $this;
133
    }
134
135
    /**
136
     * Facet a function
137
     *
138
     * Gets the function passed as $facet->facetFunction('FUNCTION', array('param1', 'param2', ...))
139
     *
140
     * Examples:
141
     *    $query->facetFunction('category');
142
     *
143
     * @param string       $function Function name
144
     * @param array|string $params   Array or multiple string arguments containing column names
145
     *
146
     * @return Facet
147
     */
148
    public function facetFunction($function, $params = null)
149
    {
150
        if (is_array($params)) {
151
            $params = implode(',', $params);
152
        }
153
154
        $this->facet[] = new Expression($function.'('.$params.')');
155
156
        return $this;
157
    }
158
159
    /**
160
     * GROUP BY clause
161
     * Adds to the previously added columns
162
     *
163
     * @param string $column A column to group by
164
     *
165
     * @return Facet
166
     */
167
    public function by($column)
168
    {
169
        $this->by = $column;
0 ignored issues
show
Documentation Bug introduced by
It seems like $column of type string is incompatible with the declared type array of property $by.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
170
171
        return $this;
172
    }
173
174
    /**
175
     * ORDER BY clause
176
     * Adds to the previously added columns
177
     *
178
     * @param string $column    The column to order on
179
     * @param string $direction The ordering direction (asc/desc)
180
     *
181
     * @return Facet
182
     */
183
    public function orderBy($column, $direction = null)
184
    {
185
        $this->order_by[] = array('column' => $column, 'direction' => $direction);
186
187
        return $this;
188
    }
189
190
    /**
191
     * Facet a function
192
     *
193
     * Gets the function passed as $facet->facetFunction('FUNCTION', array('param1', 'param2', ...))
194
     *
195
     * Examples:
196
     *    $query->facetFunction('category');
197
     *
198
     * @param string       $function  Function name
199
     * @param array        $params    Array  string arguments containing column names
200
     * @param string       $direction The ordering direction (asc/desc)
201
     *
202
     * @return Facet
203
     */
204
    public function orderByFunction($function, $params = null, $direction = null)
205
    {
206
        if (is_array($params)) {
207
            $params = implode(',', $params);
208
        }
209
210
        $this->order_by[] = array('column' => new Expression($function.'('.$params.')'), 'direction' => $direction);
211
212
        return $this;
213
    }
214
215
    /**
216
     * LIMIT clause
217
     * Supports also LIMIT offset, limit
218
     *
219
     * @param int      $offset Offset if $limit is specified, else limit
220
     * @param null|int $limit  The limit to set, null for no limit
221
     *
222
     * @return Facet
223
     */
224
    public function limit($offset, $limit = null)
225
    {
226
        if ($limit === null) {
227
            $this->limit = (int) $offset;
228
            return $this;
229
        }
230
231
        $this->offset($offset);
232
        $this->limit = (int) $limit;
233
234
        return $this;
235
    }
236
237
    /**
238
     * OFFSET clause
239
     *
240
     * @param int $offset The offset
241
     *
242
     * @return Facet
243
     */
244
    public function offset($offset)
245
    {
246
        $this->offset = (int) $offset;
247
248
        return $this;
249
    }
250
251
    /**
252
     * Compiles the statements for FACET
253
     *
254
     * @return Facet
255
     * @throws SphinxQLException In case no column in facet
256
     */
257
    public function compileFacet()
258
    {
259
        $query = 'FACET ';
260
261
        if (!empty($this->facet)) {
262
            $facets = array();
263
            foreach ($this->facet as $array) {
264
                if ($array instanceof Expression) {
265
                    $facets[] = $array;
266
                } else if ($array[1] === null) {
267
                    $facets[] = $array[0];
268
                } else {
269
                    $facets[] = $array[0].' AS '.$array[1];
270
                }
271
            }
272
            $query .= implode(', ', $facets).' ';
273
        } else {
274
            throw new SphinxQLException('There is no column in facet.');
275
        }
276
277
        if (!empty($this->by)) {
278
            $query .= 'BY '.$this->by.' ';
279
        }
280
281
        if (!empty($this->order_by)) {
282
            $query .= 'ORDER BY ';
283
284
            $order_arr = array();
285
286
            foreach ($this->order_by as $order) {
287
                $order_sub = $order['column'].' ';
288
                $order_sub .= ((strtolower($order['direction']) === 'desc') ? 'DESC' : 'ASC');
289
290
                $order_arr[] = $order_sub;
291
            }
292
293
            $query .= implode(', ', $order_arr).' ';
294
        }
295
296
        if ($this->limit !== null || $this->offset !== null) {
297
            if ($this->offset === null) {
298
                $this->offset = 0;
299
            }
300
301
            if ($this->limit === null) {
302
                $this->limit = 9999999999999;
303
            }
304
305
            $query .= 'LIMIT '.((int) $this->offset).', '.((int) $this->limit).' ';
306
        }
307
308
        $this->query = trim($query);
309
310
        return $this;
311
    }
312
313
    /**
314
     * Get String with SQL facet
315
     *
316
     * @return string
317
     */
318
    public function getFacet()
319
    {
320
        return $this->compileFacet()->query;
321
    }
322
}
323