mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge pull request #496 from sminnee/dataquery-aggregate
Dataquery aggregate
This commit is contained in:
commit
a93dd9459e
@ -57,6 +57,11 @@ class GridField extends FormField {
|
||||
*/
|
||||
protected $columnDispatch = null;
|
||||
|
||||
/**
|
||||
* Map of callbacks for custom data fields
|
||||
*/
|
||||
protected $customDataFields = array();
|
||||
|
||||
protected $name = '';
|
||||
|
||||
/**
|
||||
@ -412,6 +417,30 @@ class GridField extends FormField {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional calculated data fields to be used on this GridField
|
||||
* @param array $fields a map of fieldname to callback. The callback will bed passed the record as an argument.
|
||||
*/
|
||||
public function addDataFields($fields) {
|
||||
if($this->customDataFields) $this->customDataFields = array_merge($this->customDataFields, $fields);
|
||||
else $this->customDataFields = $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a named field on the given record.
|
||||
* Use of this method ensures that any special rules around the data for this gridfield are followed.
|
||||
*/
|
||||
public function getDataFieldValue($record, $fieldName) {
|
||||
// Custom callbacks
|
||||
if(isset($this->customDataFields[$fieldName])) {
|
||||
$callback = $this->customDataFields[$fieldName];
|
||||
return $callback($record);
|
||||
}
|
||||
|
||||
// Default implementation
|
||||
return $record->relField($fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extra columns attributes used as HTML attributes
|
||||
*
|
||||
|
@ -118,11 +118,18 @@ class GridFieldDataColumns implements GridField_ColumnProvider {
|
||||
* @return string HTML for the column. Return NULL to skip.
|
||||
*/
|
||||
public function getColumnContent($gridField, $record, $columnName) {
|
||||
// Find the data column for the given named column
|
||||
$columns = $this->getDisplayFields($gridField);
|
||||
$columnInfo = $columns[$columnName];
|
||||
|
||||
// Allow callbacks
|
||||
if(is_array($columnInfo) && isset($columnInfo['callback'])) {
|
||||
$method = $columnInfo['callback'];
|
||||
$value = Convert::raw2xml($method($record));
|
||||
|
||||
// This supports simple FieldName syntax
|
||||
if(strpos($columnName, '.') === false) {
|
||||
$value = $record->XML_val($columnName);
|
||||
} else {
|
||||
$value = $this->getValueFromRelation($record, $columnName);
|
||||
$value = Convert::raw2xml($gridField->getDataFieldValue($record, $columnName));
|
||||
}
|
||||
|
||||
$value = $this->castValue($gridField, $columnName, $value);
|
||||
@ -154,8 +161,16 @@ class GridFieldDataColumns implements GridField_ColumnProvider {
|
||||
*/
|
||||
public function getColumnMetadata($gridField, $column) {
|
||||
$columns = $this->getDisplayFields($gridField);
|
||||
|
||||
$title = null;
|
||||
if(is_string($columns[$column])) {
|
||||
$title = $columns[$column];
|
||||
} else if(is_array($columns[$column]) && isset($columns[$column]['title'])) {
|
||||
$title = $columns[$column]['title'];
|
||||
}
|
||||
|
||||
return array(
|
||||
'title' => $columns[$column],
|
||||
'title' => $title,
|
||||
);
|
||||
}
|
||||
|
||||
@ -212,7 +227,7 @@ class GridFieldDataColumns implements GridField_ColumnProvider {
|
||||
|
||||
$spec = $this->fieldFormatting[$fieldName];
|
||||
if(is_callable($spec)) {
|
||||
return $spec($item);
|
||||
return $spec($value, $item);
|
||||
} else {
|
||||
$format = str_replace('$value', "__VAL__", $spec);
|
||||
$format = preg_replace('/\$([A-Za-z0-9-_]+)/', '$item->$1', $format);
|
||||
|
@ -138,7 +138,7 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
|
||||
|
||||
$value = $columnHeader($relObj);
|
||||
} else {
|
||||
$value = $item->relField($columnSource);
|
||||
$value = $gridField->getDataFieldValue($item, $columnSource);
|
||||
}
|
||||
|
||||
$value = str_replace(array("\r", "\n"), "\n", $value);
|
||||
|
@ -115,7 +115,7 @@ class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionPr
|
||||
foreach($items as $item) {
|
||||
$itemRow = new ArrayList();
|
||||
foreach($printColumns as $field => $label) {
|
||||
$value = $item->relField($field);
|
||||
$value = $gridField->getDataFieldValue($item, $field);
|
||||
$itemRow->push(
|
||||
new ArrayData(array(
|
||||
"CellString" => $value,
|
||||
|
@ -220,18 +220,26 @@ class DataList extends ViewableData implements SS_List, SS_Filterable, SS_Sortab
|
||||
* @return DataList
|
||||
*/
|
||||
public function filter() {
|
||||
$numberFuncArgs = count(func_get_args());
|
||||
$whereArguments = array();
|
||||
if($numberFuncArgs == 1 && is_array(func_get_arg(0))) {
|
||||
$whereArguments = func_get_arg(0);
|
||||
} elseif($numberFuncArgs == 2) {
|
||||
$whereArguments[func_get_arg(0)] = func_get_arg(1);
|
||||
} else {
|
||||
throw new InvalidArgumentException('Incorrect number of arguments passed to filter()');
|
||||
// Validate and process arguments
|
||||
$arguments = func_get_args();
|
||||
switch(sizeof($arguments)) {
|
||||
case 1: $filters = $arguments[0]; break;
|
||||
case 2: $filters = array($arguments[0] => $arguments[1]); break;
|
||||
default:
|
||||
throw new InvalidArgumentException('Incorrect number of arguments passed to filter()');
|
||||
}
|
||||
|
||||
$clone = clone $this;
|
||||
$clone->addFilter($filters);
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify this DataList, adding a filter
|
||||
*/
|
||||
public function addFilter($filterArray) {
|
||||
$SQL_Statements = array();
|
||||
foreach($whereArguments as $field => $value) {
|
||||
foreach($filterArray as $field => $value) {
|
||||
if(is_array($value)) {
|
||||
$customQuery = 'IN (\''.implode('\',\'',Convert::raw2sql($value)).'\')';
|
||||
} else {
|
||||
@ -256,6 +264,24 @@ class DataList extends ViewableData implements SS_List, SS_Filterable, SS_Sortab
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter this DataList by a callback function.
|
||||
* The function will be passed each record of the DataList in turn, and must return true for the record to be included.
|
||||
* Returns the filtered list.
|
||||
*
|
||||
* Note that, in the current implementation, the filtered list will be an ArrayList, but this may change in a future
|
||||
* implementation.
|
||||
*/
|
||||
public function filterByCallback($callback) {
|
||||
if(!is_callable($callback)) throw new LogicException("DataList::filterByCallback() must be passed something callable.");
|
||||
|
||||
$output = new ArrayList;
|
||||
foreach($this as $item) {
|
||||
if($callback($item)) $output->push($item);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a Object relation name to a Database name and apply the relation join to
|
||||
* the query. Throws an InvalidArgumentException if the $field doesn't correspond to a relation
|
||||
|
@ -329,8 +329,8 @@ class DataQuery {
|
||||
*
|
||||
* @param String $field Unquoted database column name (will be escaped automatically)
|
||||
*/
|
||||
function max($field) {
|
||||
return $this->getFinalisedQuery()->aggregate(sprintf('MAX("%s")', Convert::raw2sql($field)))->execute()->value();
|
||||
function max($field) {
|
||||
return $this->aggregate(sprintf('MAX("%s")', Convert::raw2sql($field)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -339,7 +339,7 @@ class DataQuery {
|
||||
* @param String $field Unquoted database column name (will be escaped automatically)
|
||||
*/
|
||||
function min($field) {
|
||||
return $this->getFinalisedQuery()->aggregate(sprintf('MIN("%s")', Convert::raw2sql($field)))->execute()->value();
|
||||
return $this->aggregate(sprintf('MIN("%s")', Convert::raw2sql($field)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -348,7 +348,7 @@ class DataQuery {
|
||||
* @param String $field Unquoted database column name (will be escaped automatically)
|
||||
*/
|
||||
function avg($field) {
|
||||
return $this->getFinalisedQuery()->aggregate(sprintf('AVG("%s")', Convert::raw2sql($field)))->execute()->value();
|
||||
return $this->aggregate(sprintf('AVG("%s")', Convert::raw2sql($field)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -357,7 +357,14 @@ class DataQuery {
|
||||
* @param String $field Unquoted database column name (will be escaped automatically)
|
||||
*/
|
||||
function sum($field) {
|
||||
return $this->getFinalisedQuery()->aggregate(sprintf('SUM("%s")', Convert::raw2sql($field)))->execute()->value();
|
||||
return $this->aggregate(sprintf('SUM("%s")', Convert::raw2sql($field)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a raw aggregate expression. Please handle escaping yourself
|
||||
*/
|
||||
function aggregate($expression) {
|
||||
return $this->getFinalisedQuery()->aggregate($expression)->execute()->value();
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user