Skip to content

Commit d4e99ba

Browse files
committed
Merge branch 'master' of bitbucket.org:mctekk/http
2 parents 7699a20 + 76fbfd2 commit d4e99ba

File tree

1 file changed

+105
-13
lines changed

1 file changed

+105
-13
lines changed

src/QueryParser.php

+105-13
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Partials:
1616
* offset=20
1717
*/
18-
class QueryParser
18+
class QueryParser extends \Phalcon\Di\Injectable
1919
{
2020
/**
2121
* @var array
@@ -41,17 +41,28 @@ public function __construct(array $request)
4141
*/
4242
public function request(): array
4343
{
44-
$params = '';
44+
$params = [
45+
'params' => '',
46+
'subquery' => '',
47+
];
48+
4549
$isSearch = false;
50+
$hasSubquery = false;
4651

47-
//verify the user is search for something
52+
//verify the user is searching for something
4853
if (array_key_exists('q', $this->request)) {
49-
$params = $this->request['q'];
54+
$params['params'] = $this->request['q'];
5055
$isSearch = true;
5156
}
5257

58+
//verify the request has a subquery
59+
if (array_key_exists('subq', $this->request)) {
60+
$params['subquery'] = $this->request['subq'];
61+
$hasSubquery = true;
62+
}
63+
5364
//initialize the model params
54-
$modelSearchParams = $this->prepareSearch($params, $isSearch);
65+
$modelSearchParams = $this->prepareSearch($params, $isSearch, $hasSubquery);
5566

5667
//filter the field
5768
if (array_key_exists('fields', $this->request)) {
@@ -114,33 +125,114 @@ protected function parseSearchParameters(string $unparsed): array
114125
return $mapped;
115126
}
116127

128+
/**
129+
* Parses out the subquery parameters from a request.
130+
*
131+
* in = ::, not in = !::
132+
*
133+
* Unparsed, they will look like this:
134+
* internet_special(id::vehicles_id)
135+
* Parsed:
136+
* Array('action' => in, 'firstField' => id, 'secondField' => vehicles_id,'model' => MyDealer\Models\InternetSpecial)
137+
*
138+
* *
139+
* @param string $unparsed Unparsed search string
140+
* @return array An array of fieldname=>value search parameters
141+
*/
142+
protected function parseSubquery(string $unparsed): array
143+
{
144+
$unparsed = urldecode($unparsed);
145+
// Strip parens that come with the request string
146+
$tableName = explode("(", $unparsed, 2);
147+
//print_r($tableName);die();
148+
$tableName = strtolower($tableName[0]);
149+
150+
$modelName = str_replace('_', ' ', $tableName);
151+
$modelName = str_replace(' ', '', ucwords($modelName));
152+
153+
//Add the namespace to the model name
154+
$model = $this->config['namespace']['models'] . '\\' . $modelName;
155+
156+
$unparsed = str_replace($tableName, '', $unparsed);
157+
$unparsed = trim($unparsed, '()');
158+
159+
// Now we have an array of "key:value" strings.
160+
$splitFields = explode(',', $unparsed);
161+
162+
if (strpos($splitFields[0], '!::') !== false) {
163+
$action = 'not in';
164+
$fieldsToRelate = explode('!::', $splitFields[0]);
165+
} elseif (strpos($splitFields[0], '::') !== false) {
166+
$action = 'in';
167+
$fieldsToRelate = explode('::', $splitFields[0]);
168+
} else {
169+
throw new \Exception("Error Processing Subquery", 1);
170+
}
171+
172+
$subquery = [
173+
'action' => $action,
174+
'firstField' => $fieldsToRelate[0],
175+
'secondField' => $fieldsToRelate[1],
176+
'model' => $model,
177+
];
178+
179+
/*// Split the strings at their colon, set left to key, and right to value.
180+
foreach ($splitFields as $field) {
181+
$splitField = explode(':', $field);
182+
$mapped[$splitField[0]] = $splitField[1];
183+
}*/
184+
185+
return $subquery;
186+
}
187+
117188
/**
118189
* Prepare conditions to search in record
119190
*
120191
* @param string $unparsed
121192
* @return array
122193
*/
123-
protected function prepareSearch(string $unparsed, bool $isSearch = false): array
194+
protected function prepareSearch(array $unparsed, bool $isSearch = false, $hasSubquery = false): array
124195
{
125196
$statement = [
126197
'conditions' => "1 = 1",
127198
'bind' => [],
128199
];
129200

130201
if ($isSearch) {
131-
$mapped = $this->parseSearchParameters($unparsed);
202+
$mapped = $this->parseSearchParameters($unparsed['params']);
132203
$conditions = '1 = 1';
133-
$keys = array_keys($mapped);
134-
array_unshift($keys, 1);
135-
unset($keys[0]);
136204

137-
$values = array_values($mapped);
138-
array_unshift($values, 1);
139-
unset($values[0]);
205+
// $between = ' AND year between ?0 AND ?1';
206+
207+
$tmpMapped = $mapped;
208+
209+
foreach ($tmpMapped as $key => $value) {
210+
if (strpos($value, '~') !== false) {
211+
unset($tmpMapped[$key]);
212+
$betweenMap[$key] = explode('~', $value);
213+
}
214+
}
215+
216+
$keys = array_keys($tmpMapped);
217+
$values = array_values($tmpMapped);
218+
140219
foreach ($keys as $key => $field) {
141220
$conditions .= " AND {$field} = ?{$key}";
142221
}
143222

223+
if (isset($betweenMap)) {
224+
foreach ($betweenMap as $key => $fields) {
225+
$binds = count($values);
226+
$conditions .= ' AND ' . $key . ' BETWEEN ?' . $binds . ' AND ?' . ($binds + 1);
227+
$values = array_merge($values, $fields);
228+
}
229+
}
230+
231+
if ($hasSubquery) {
232+
$subquery = $this->parseSubquery($unparsed['subquery']);
233+
$conditions .= ' AND ' . $subquery['firstField'] . ' ' . $subquery['action'] . ' (select ' . $subquery['secondField'] . ' FROM ' . $subquery['model'] . ')';
234+
}
235+
144236
$statement = [
145237
'conditions' => $conditions,
146238
'bind' => $values,

0 commit comments

Comments
 (0)