mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
BUGFIX DataQuery: ensuring ORDER BY columns are set in SELECT clauses
This commit is contained in:
parent
f4643e1b4a
commit
3bf983200b
@ -297,7 +297,7 @@ class DataList extends ViewableData implements SS_List {
|
||||
*/
|
||||
function setByIDList($idList) {
|
||||
$has = array();
|
||||
|
||||
|
||||
// Index current data
|
||||
foreach($this->column() as $id) {
|
||||
$has[$id] = true;
|
||||
@ -310,7 +310,9 @@ class DataList extends ViewableData implements SS_List {
|
||||
// $id is the database ID of the record
|
||||
if($idList) foreach($idList as $id) {
|
||||
unset($itemsToDelete[$id]);
|
||||
if($id && !isset($has[$id])) $this->add($id);
|
||||
if($id && !isset($has[$id])) {
|
||||
$this->add($id);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any items that haven't been mentioned
|
||||
@ -468,5 +470,3 @@ class DataList extends ViewableData implements SS_List {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -2699,11 +2699,11 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
if(is_numeric($id)) {
|
||||
if(is_subclass_of($callerClass, 'DataObject')) {
|
||||
$baseClass = ClassInfo::baseDataClass($callerClass);
|
||||
return DataObject::get_one($callerClass,"\"$baseClass\".\"ID\" = $id", $cache, 1);
|
||||
return DataObject::get_one($callerClass,"\"$baseClass\".\"ID\" = $id", $cache);
|
||||
|
||||
// This simpler code will be used by non-DataObject classes that implement DataObjectInterface
|
||||
} else {
|
||||
return DataObject::get_one($callerClass,"\"ID\" = $id", $cache, 1);
|
||||
return DataObject::get_one($callerClass,"\"ID\" = $id", $cache);
|
||||
}
|
||||
} else {
|
||||
user_error("DataObject::get_by_id passed a non-numeric ID #$id", E_USER_WARNING);
|
||||
|
@ -111,7 +111,7 @@ class DataQuery {
|
||||
$baseClass = array_shift($tableClasses);
|
||||
|
||||
$collidingFields = array();
|
||||
|
||||
|
||||
// Join all the tables
|
||||
if($this->querySubclasses) {
|
||||
foreach($tableClasses as $tableClass) {
|
||||
@ -152,13 +152,72 @@ class DataQuery {
|
||||
|
||||
$query->select[] = "\"$baseClass\".\"ID\"";
|
||||
$query->select[] = "CASE WHEN \"$baseClass\".\"ClassName\" IS NOT NULL THEN \"$baseClass\".\"ClassName\" ELSE '$baseClass' END AS \"RecordClassName\"";
|
||||
|
||||
|
||||
// TODO: Versioned, Translatable, SiteTreeSubsites, etc, could probably be better implemented as subclasses of DataQuery
|
||||
singleton($this->dataClass)->extend('augmentSQL', $query, $this);
|
||||
|
||||
|
||||
$this->ensureSelectContainsOrderbyColumns($query);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ensure that if a query has an order by clause, those columns are present in the select.
|
||||
*
|
||||
* @param SQLQuery $query
|
||||
* @return null
|
||||
*/
|
||||
protected function ensureSelectContainsOrderbyColumns($query) {
|
||||
$tableClasses = ClassInfo::dataClassesFor($this->dataClass);
|
||||
$baseClass = array_shift($tableClasses);
|
||||
|
||||
if($query->orderby) {
|
||||
$orderByFields = explode(',', $query->orderby);
|
||||
foreach($orderByFields as $ob => $col) {
|
||||
$col = trim($col);
|
||||
|
||||
// don't touch functions in the ORDER BY
|
||||
if(strpos($col, '(') !== false) continue;
|
||||
|
||||
$columnParts = explode(' ', $col);
|
||||
if (count($columnParts) == 2) {
|
||||
$dir = $columnParts[1];
|
||||
$col = $columnParts[0];
|
||||
} else {
|
||||
$dir = '';
|
||||
}
|
||||
|
||||
$orderByFields[$ob] = $col;
|
||||
$col = str_replace('"', '', $col);
|
||||
$parts = explode('.', $col);
|
||||
|
||||
if(count($parts) == 1) {
|
||||
$databaseFields = DataObject::database_fields($baseClass);
|
||||
// database_fields() doesn't return ID, so we need to manually add it here
|
||||
$databaseFields['ID'] = true;
|
||||
|
||||
if(isset($databaseFields[$parts[0]])) {
|
||||
$qualCol = "\"$baseClass\".\"{$parts[0]}\"";
|
||||
$orderByFields[$ob] = trim($qualCol . " " . $dir);
|
||||
} else {
|
||||
$qualCol = "\"$parts[0]\"";
|
||||
}
|
||||
|
||||
if(!isset($query->select[$parts[0]]) && !in_array($qualCol, $query->select)) {
|
||||
$query->select[] = $qualCol;
|
||||
}
|
||||
} else {
|
||||
$qualCol = '"' . implode('"."', $parts) . '"';
|
||||
if(!in_array($qualCol, $query->select)) {
|
||||
$query->select[] = $qualCol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$query->orderby = implode(',', $orderByFields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query and return the result as {@link Query} object.
|
||||
*/
|
||||
@ -444,7 +503,9 @@ class DataQuery {
|
||||
public function column($field = 'ID') {
|
||||
$query = $this->getFinalisedQuery();
|
||||
$query->select($this->expressionForField($field, $query));
|
||||
return $query->execute()->column();
|
||||
$this->ensureSelectContainsOrderbyColumns($query);
|
||||
|
||||
return $query->execute()->column($field);
|
||||
}
|
||||
|
||||
protected function expressionForField($field, $query) {
|
||||
@ -499,5 +560,3 @@ class DataQuery {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
Loading…
Reference in New Issue
Block a user