1 | <?php |
||
18 | class SoqlQuery |
||
19 | { |
||
20 | /** |
||
21 | * The default delimiter used to separate multiple values. |
||
22 | */ |
||
23 | const DELIMITER = ','; |
||
24 | |||
25 | /** |
||
26 | * The SELECT clause in SoQL |
||
27 | */ |
||
28 | const SELECT_KEY = '$select'; |
||
29 | |||
30 | /** |
||
31 | * The WHERE clause in SoQL |
||
32 | */ |
||
33 | const WHERE_KEY = '$where'; |
||
34 | |||
35 | /** |
||
36 | * The ORDER clause in SoQL |
||
37 | */ |
||
38 | const ORDER_KEY = '$order'; |
||
39 | |||
40 | /** |
||
41 | * The GROUP clause in SoQL |
||
42 | */ |
||
43 | const GROUP_KEY = '$group'; |
||
44 | |||
45 | /** |
||
46 | * The LIMIT clause in SoQL |
||
47 | */ |
||
48 | const LIMIT_KEY = '$limit'; |
||
49 | |||
50 | /** |
||
51 | * The HAVING clause in SoQL |
||
52 | */ |
||
53 | const HAVING_KEY = '$having'; |
||
54 | |||
55 | /** |
||
56 | * The OFFSET clause in SoQL |
||
57 | */ |
||
58 | const OFFSET_KEY = '$offset'; |
||
59 | |||
60 | /** |
||
61 | * The SEARCH clause in SoQL |
||
62 | */ |
||
63 | const SEARCH_KEY = '$q'; |
||
64 | |||
65 | /** |
||
66 | * The default value for the `$select` clause in a SoQL query. By default, select all the columns |
||
67 | */ |
||
68 | const DEFAULT_SELECT = '*'; |
||
69 | |||
70 | /** |
||
71 | * The default order for the `$order` clause in a SoQL query. By default, order in ascending order |
||
72 | */ |
||
73 | const DEFAULT_ORDER_DIRECTION = SoqlOrderDirection::ASC; |
||
74 | |||
75 | /** |
||
76 | * This array contains all of the parts to a SoqlQuery being converted into a URL where the key of an element is the |
||
77 | * SoQL clause (e.g. $select) and the value of an element is the value to the SoQL clause (e.g. *). |
||
78 | * |
||
79 | * @var string[] |
||
80 | */ |
||
81 | private $queryElements; |
||
82 | |||
83 | /** |
||
84 | * Write a SoQL query by chaining functions. This object will handle encoding the final query in order for it to be |
||
85 | * used properly as a URL. By default a SoqlQuery will select all columns (excluding socrata columns; e.g. :id) and |
||
86 | * sort by `:id` in ascending order. |
||
87 | * |
||
88 | * @since 0.1.0 |
||
89 | */ |
||
90 | public function __construct () {} |
||
91 | |||
92 | /** |
||
93 | * Convert the current information into a URL encoded query that can be appended to the domain |
||
94 | * |
||
95 | * @since 0.1.0 |
||
96 | * |
||
97 | * @return string The SoQL query ready to be appended to a URL |
||
98 | */ |
||
99 | public function __tostring () |
||
100 | { |
||
101 | if (is_null($this->queryElements)) |
||
102 | { |
||
103 | return ""; |
||
104 | } |
||
105 | |||
106 | $query = []; |
||
107 | |||
108 | foreach ($this->queryElements as $soqlKey => $value) |
||
109 | { |
||
110 | $value = (is_array($value)) ? implode(self::DELIMITER, $value) : $value; |
||
111 | |||
112 | $query[] = sprintf("%s=%s", $soqlKey, $value); |
||
113 | } |
||
114 | |||
115 | return implode("&", $query); |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Select only specific columns in your Soql Query. When this function is given no parameters or is not used in a |
||
120 | * query, the Soql Query will return all of the columns by default. |
||
121 | * |
||
122 | * ```php |
||
123 | * // These are all valid usages |
||
124 | * $soqlQuery->select(); |
||
125 | * $soqlQuery->select("foo", "bar", "baz"); |
||
126 | * $soqlQuery->select(array("foo" => "foo_alias", "bar" => "bar_alias", "baz")); |
||
127 | * ``` |
||
128 | * |
||
129 | * @link https://dev.socrata.com/docs/queries/select.html SoQL $select Parameter |
||
130 | * |
||
131 | * @param array|mixed $columns The columns to select from the dataset. The columns can be specified as an array |
||
132 | * of values or it can be specified as multiple parameters separated by commas. |
||
133 | * |
||
134 | * @since 0.1.0 |
||
135 | * |
||
136 | * @return $this A SoqlQuery object that can continue to be chained |
||
137 | */ |
||
138 | public function select ($columns = self::DEFAULT_SELECT) |
||
139 | { |
||
140 | if (func_num_args() == 1) |
||
141 | { |
||
142 | $this->queryElements[self::SELECT_KEY] = (is_array($columns)) ? $this->formatAssociativeArray("%s AS %s", $columns) : array($columns); |
||
143 | } |
||
144 | else if (func_num_args() > 1) |
||
145 | { |
||
146 | $this->queryElements[self::SELECT_KEY] = func_get_args(); |
||
147 | } |
||
148 | |||
149 | return $this; |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * Create an array of values that have already been formatted and are ready to be converted into a comma separated |
||
154 | * list that will be used as a parameter for selectors such was `$select`, `$order`, or `$group` in SoQL |
||
155 | * |
||
156 | * @param string $format The format used in sprintf() for keys and values of an array to be formatted to |
||
157 | * @param array $array The array that will be formatted appropriately for usage within this class |
||
158 | * |
||
159 | * @since 0.1.0 |
||
160 | * |
||
161 | * @return array |
||
162 | */ |
||
163 | private function formatAssociativeArray ($format, $array) |
||
164 | { |
||
165 | $formattedValues = array(); |
||
166 | |||
167 | foreach ($array as $key => $value) |
||
168 | { |
||
169 | $formattedValues[] = (is_string($key) && (!is_null($value))) ? rawurlencode(sprintf($format, trim($key), trim($value))) : (is_string($key) ? $key : $value); |
||
170 | } |
||
171 | |||
172 | return $formattedValues; |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * Create a filter to selectively choose data based on certain parameters. |
||
177 | * |
||
178 | * Multiple calls to this function in a chain will overwrite the previous statement. To combine multiple where |
||
179 | * clauses, use the supported SoQL operators; e.g. `magnitude > 3.0 AND source = 'pr'` |
||
180 | * |
||
181 | * @link https://dev.socrata.com/docs/queries/where.html SoQL $where Parameter |
||
182 | * |
||
183 | * @param string $statement The `where` clause that will be used to filter data |
||
184 | * |
||
185 | * @since 0.1.0 |
||
186 | * |
||
187 | * @return $this A SoqlQuery object that can continue to be chained |
||
188 | */ |
||
189 | public function where ($statement) |
||
190 | { |
||
191 | $this->queryElements[self::WHERE_KEY] = rawurlencode($statement); |
||
192 | |||
193 | return $this; |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * Create a filter to aggregate your results using boolean operators, similar to the HAVING clause in SQL. |
||
198 | * |
||
199 | * @link https://dev.socrata.com/docs/queries/having.html SoQL $having Parameter |
||
200 | * |
||
201 | * @param string $statement The `having` clause that will be used to filter data |
||
202 | * |
||
203 | * @since 0.2.0 |
||
204 | * |
||
205 | * @return $this A SoqlQuery object that can continue to be chained |
||
206 | */ |
||
207 | public function having ($statement) |
||
213 | |||
214 | /** |
||
215 | * Determines the order and the column the results should be sorted by. This function may be used more than once in |
||
216 | * a chain so duplicate entries in the first column will be sorted by the second specified column specified. If |
||
217 | * this |
||
218 | * function is called more than once in a chain, the order does matter in which order() you call first. |
||
219 | * |
||
220 | * @link https://dev.socrata.com/changelog/2015/04/27/new-higher-performance-apis.html New Higher Performance API |
||
221 | * @link https://dev.socrata.com/docs/queries/order.html SoQL $order Parameter |
||
222 | * |
||
223 | * @param string $column The column(s) that determines how the results should be sorted. This information |
||
224 | * can be given as an array of values, a single column, or a comma separated string. |
||
225 | * In order to support sorting by multiple columns, you need to use the latest version |
||
226 | * of the dataset API. |
||
227 | * @param string $direction The direction the results should be sorted in, either ascending or descending. The |
||
228 | * {@link SoqlOrderDirection} class provides constants to use should these values ever |
||
229 | * change in the future. The only accepted values are: `ASC` and `DESC` |
||
230 | * |
||
231 | * @see SoqlOrderDirection View convenience constants |
||
232 | * |
||
233 | * @since 0.1.0 |
||
234 | * |
||
235 | * @return $this A SoqlQuery object that can continue to be chained |
||
236 | */ |
||
237 | public function order ($column, $direction = self::DEFAULT_ORDER_DIRECTION) |
||
238 | { |
||
239 | $this->queryElements[self::ORDER_KEY][] = rawurlencode($column . " " . $direction); |
||
240 | |||
241 | return $this; |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * Group the resulting dataset based on a specific column. This function must be used in conjunction with |
||
246 | * `select()`. |
||
247 | * |
||
248 | * For example, to find the strongest earthquake by region, we want to group() by region and provide a select of |
||
249 | * region, MAX(magnitude). |
||
250 | * |
||
251 | * ```php |
||
252 | * $soql->select("region", "MAX(magnitude)")->group("region"); |
||
253 | * ``` |
||
254 | * |
||
255 | * @link https://dev.socrata.com/docs/queries/group.html The $group Parameter |
||
256 | * |
||
257 | * @param string $column The column that will be used to group the dataset |
||
258 | * |
||
259 | * @since 0.1.0 |
||
260 | * |
||
261 | * @return $this A SoqlQuery object that can continue to be chained |
||
262 | */ |
||
263 | public function group ($column) |
||
269 | |||
270 | /** |
||
271 | * Set the amount of results that can be retrieved from a dataset per query. |
||
272 | * |
||
273 | * @link https://dev.socrata.com/docs/queries/limit.html SoQL $limit Parameter |
||
274 | * |
||
275 | * @param int $limit The number of results the dataset should be limited to when returned |
||
276 | * |
||
277 | * @throws \InvalidArgumentException If the given argument is not an integer |
||
278 | * @throws \OutOfBoundsException If the given argument is less than 0 |
||
279 | * |
||
280 | * @since 0.1.0 |
||
281 | * |
||
282 | * @return $this A SoqlQuery object that can continue to be chained |
||
283 | */ |
||
284 | public function limit ($limit) |
||
292 | |||
293 | /** |
||
294 | * Analyze a given value and ensure the value fits the criteria set by the Socrata API |
||
295 | * |
||
296 | * @param string $variable The literal name of this field |
||
297 | * @param int $number The value to analyze |
||
298 | * |
||
299 | * @since 0.1.0 |
||
300 | * |
||
301 | * @throws \InvalidArgumentException If the given argument is not an integer |
||
302 | * @throws \OutOfBoundsException If the given argument is less than 0 |
||
303 | */ |
||
304 | private function handleInteger ($variable, $number) |
||
318 | |||
319 | /** |
||
320 | * The offset is the number of records into a dataset that you want to start, indexed at 0. For example, to retrieve |
||
321 | * the “4th page” of records (records 151 - 200) where you are using limit() to page 50 records at a time, you’d ask |
||
322 | * for an $offset of 150. |
||
323 | * |
||
324 | * @link https://dev.socrata.com/docs/queries/offset.html SoQL $offset Parameter |
||
325 | * |
||
326 | * @param int $offset The number of results the dataset should be offset to when returned |
||
327 | * |
||
328 | * @throws \InvalidArgumentException If the given argument is not an integer |
||
329 | * @throws \OutOfBoundsException If the given argument is less than 0 |
||
330 | * |
||
331 | * @since 0.1.0 |
||
332 | * |
||
333 | * @return $this A SoqlQuery object that can continue to be chained |
||
334 | */ |
||
335 | public function offset ($offset) |
||
343 | |||
344 | /** |
||
345 | * Search the entire dataset for a specified string. Think of this as a search engine instead of performing a SQL |
||
346 | * query. |
||
347 | * |
||
348 | * @param string $needle The phrase to search for |
||
349 | * |
||
350 | * @since 0.1.0 |
||
351 | * |
||
352 | * @return $this A SoqlQuery object that can continue to be chained |
||
353 | */ |
||
354 | public function fullTextSearch ($needle) |
||
360 | } |
||
361 |