Facet::setConnection()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

155
        $this->facet[] = new Expression($function.'('./** @scrutinizer ignore-type */ $params.')');
Loading history...
156
157
        return $this;
158
    }
159
160
    /**
161
     * GROUP BY clause
162
     * Adds to the previously added columns
163
     *
164
     * @param string $column A column to group by
165
     *
166
     * @return Facet
167
     */
168
    public function by($column)
169
    {
170
        $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...
171
172
        return $this;
173
    }
174
175
    /**
176
     * ORDER BY clause
177
     * Adds to the previously added columns
178
     *
179
     * @param string $column    The column to order on
180
     * @param string $direction The ordering direction (asc/desc)
181
     *
182
     * @return Facet
183
     */
184
    public function orderBy($column, $direction = null)
185
    {
186
        $this->order_by[] = array('column' => $column, 'direction' => $direction);
187
188
        return $this;
189
    }
190
191
    /**
192
     * Facet a function
193
     *
194
     * Gets the function passed as $facet->facetFunction('FUNCTION', array('param1', 'param2', ...))
195
     *
196
     * Examples:
197
     *    $query->facetFunction('category');
198
     *
199
     * @param string $function  Function name
200
     * @param array  $params    Array  string arguments containing column names
201
     * @param string $direction The ordering direction (asc/desc)
202
     *
203
     * @return Facet
204
     */
205
    public function orderByFunction($function, $params = null, $direction = null)
206
    {
207
        if (is_array($params)) {
208
            $params = implode(',', $params);
209
        }
210
211
        $this->order_by[] = array('column' => new Expression($function.'('.$params.')'), 'direction' => $direction);
212
213
        return $this;
214
    }
215
216
    /**
217
     * LIMIT clause
218
     * Supports also LIMIT offset, limit
219
     *
220
     * @param int      $offset Offset if $limit is specified, else limit
221
     * @param null|int $limit  The limit to set, null for no limit
222
     *
223
     * @return Facet
224
     */
225
    public function limit($offset, $limit = null)
226
    {
227
        if ($limit === null) {
228
            $this->limit = (int) $offset;
229
230
            return $this;
231
        }
232
233
        $this->offset($offset);
234
        $this->limit = (int) $limit;
235
236
        return $this;
237
    }
238
239
    /**
240
     * OFFSET clause
241
     *
242
     * @param int $offset The offset
243
     *
244
     * @return Facet
245
     */
246
    public function offset($offset)
247
    {
248
        $this->offset = (int) $offset;
249
250
        return $this;
251
    }
252
253
    /**
254
     * Compiles the statements for FACET
255
     *
256
     * @return Facet
257
     * @throws SphinxQLException In case no column in facet
258
     */
259
    public function compileFacet()
260
    {
261
        $query = 'FACET ';
262
263
        if (!empty($this->facet)) {
264
            $facets = array();
265
            foreach ($this->facet as $array) {
266
                if ($array instanceof Expression) {
267
                    $facets[] = $array;
268
                } elseif ($array[1] === null) {
269
                    $facets[] = $array[0];
270
                } else {
271
                    $facets[] = $array[0].' AS '.$array[1];
272
                }
273
            }
274
            $query .= implode(', ', $facets).' ';
275
        } else {
276
            throw new SphinxQLException('There is no column in facet.');
277
        }
278
279
        if (!empty($this->by)) {
280
            $query .= 'BY '.$this->by.' ';
0 ignored issues
show
Bug introduced by
Are you sure $this->by of type array can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

280
            $query .= 'BY './** @scrutinizer ignore-type */ $this->by.' ';
Loading history...
281
        }
282
283
        if (!empty($this->order_by)) {
284
            $query .= 'ORDER BY ';
285
286
            $order_arr = array();
287
288
            foreach ($this->order_by as $order) {
289
                $order_sub = $order['column'].' ';
290
                $order_sub .= ((strtolower($order['direction']) === 'desc') ? 'DESC' : 'ASC');
291
292
                $order_arr[] = $order_sub;
293
            }
294
295
            $query .= implode(', ', $order_arr).' ';
296
        }
297
298
        if ($this->limit !== null || $this->offset !== null) {
299
            if ($this->offset === null) {
300
                $this->offset = 0;
301
            }
302
303
            if ($this->limit === null) {
304
                $this->limit = 9999999999999;
305
            }
306
307
            $query .= 'LIMIT '.((int) $this->offset).', '.((int) $this->limit).' ';
308
        }
309
310
        $this->query = trim($query);
311
312
        return $this;
313
    }
314
315
    /**
316
     * Get String with SQL facet
317
     *
318
     * @return string
319
     * @throws SphinxQLException
320
     */
321
    public function getFacet()
322
    {
323
        return $this->compileFacet()->query;
324
    }
325
}
326