Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3823445

Browse files
authoredJun 15, 2021
Merge pull request #44 from bakaphp/hotfix-sort-injection
2 parents 5ea7d96 + 5b3f773 commit 3823445

File tree

1 file changed

+47
-8
lines changed

1 file changed

+47
-8
lines changed
 

‎src/QueryParserCustomFields.php

+47-8
Original file line numberDiff line numberDiff line change
@@ -169,21 +169,60 @@ public function request() : array
169169
$sort = '';
170170
if (array_key_exists('sort', $this->request)) {
171171
$sort = $this->request['sort'];
172+
$columnsData = $this->getTableColumns();
172173

173-
if (!empty($sort)) {
174+
if (!empty($sort) && strpos($sort, '|') !== false) {
174175
// Get the model, column and sort order from the sent parameter.
175-
$modelColumn = $sort;
176-
if (strpos($sort, '|') !== false) {
177-
list($modelColumn, $order) = explode('|', $sort);
178-
}
176+
list($modelColumn, $order) = explode('|', $sort);
179177
$order = strtolower($order) === 'asc' ? 'ASC' : 'DESC';
180178

181179
$modelColumn = preg_replace("/[^a-zA-Z0-9_\s]/", '', $modelColumn);
182-
$columnsData = $this->getTableColumns();
180+
// Check to see whether this is a related sorting by looking for a
183181
if (isset($columnsData[$modelColumn])) {
184-
$sort = " ORDER BY {$modelColumn} {$order}";
182+
if (strpos($modelColumn, '.') !== false) {
183+
// We are using a related sort.
184+
// Get the namespace for the models from the configuration.
185+
$modelNamespace = \Phalcon\Di::getDefault()->getConfig()->namespace->models;
186+
// Get the model name and the sort column from the sent parameter
187+
list($model, $column) = explode('.', $modelColumn);
188+
// Convert the model name into camel case.
189+
$modelName = str_replace(' ', '', ucwords(str_replace('_', ' ', $model)));
190+
// Create the model name with the appended namespace.
191+
$modelName = $modelNamespace . '\\' . $modelName;
192+
193+
// Make sure the model exists.
194+
if (!class_exists($modelName)) {
195+
throw new \Exception('Related model does not exist.');
196+
}
197+
198+
// Instance the model so we have access to the getSource() function.
199+
$modelObject = new $modelName();
200+
// Instance meta data memory to access the primary keys for the table.
201+
$metaData = new \Phalcon\Mvc\Model\MetaData\Memory();
202+
// Get the first matching primary key.
203+
// @TODO This will hurt on compound primary keys.
204+
$primaryKey = $metaData->getPrimaryKeyAttributes($modelObject)[0];
205+
if ($metaData->hasAttribute($modelObject, $column)) {
206+
// We need the table to exist in the query in order for the related sort to work.
207+
// Therefore we add it to comply with this by comparing the primary key to not being NULL.
208+
$this->relationSearchFields[$modelName][] = [
209+
$primaryKey, ':', '$$',
210+
];
211+
212+
$sort = " ORDER BY {$modelObject->getSource()}.{$column} {$order}";
213+
}
214+
unset($modelObject);
215+
} else {
216+
$sort = " ORDER BY {$modelColumn} {$order}";
217+
}
218+
} else {
219+
$sort = null;
220+
}
221+
} else {
222+
if (isset($columnsData[$sort])) {
223+
$sort = " ORDER BY {$sort} DESC";
185224
} else {
186-
$sort = '';
225+
$sort = null;
187226
}
188227
}
189228
}

0 commit comments

Comments
 (0)
Please sign in to comment.