Last active
August 2, 2016 21:51
-
-
Save colepacak/0f9ff0e31cdb0d1aa6ba5282119a2b7d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/plugins/views_plugin_query_default.inc b/plugins/views_plugin_query_default.inc | |
index 8a15e8d..03183ba 100644 | |
--- a/plugins/views_plugin_query_default.inc | |
+++ b/plugins/views_plugin_query_default.inc | |
@@ -1195,10 +1195,16 @@ class views_plugin_query_default extends views_plugin_query { | |
if (!empty($field['function'])) { | |
$info = $this->get_aggregation_info(); | |
- if (!empty($info[$field['function']]['method']) && function_exists($info[$field['function']]['method'])) { | |
- $string = $info[$field['function']]['method']($field['function'], $string); | |
+ $group_type = $field['function']; | |
+ if (!empty($info[$group_type]['extender']) && class_exists($info[$group_type]['extender'])) { | |
+ // Only extend the query object once. | |
+ // NB: this only works because our extender is the only one around. | |
+ // See ViewsAggregateQuery for more details. | |
+ if (!$this->has_aggregate) { | |
+ $query = $query->extend($info[$group_type]['extender']); | |
+ } | |
$placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array(); | |
- $query->addExpression($string, $fieldname, $placeholders); | |
+ call_user_func(array($query, $info[$group_type]['method']), $group_type, $string, $fieldname, $placeholders); | |
} | |
$this->has_aggregate = TRUE; | |
@@ -1515,6 +1521,21 @@ class views_plugin_query_default extends views_plugin_query { | |
$view->query->add_field(NULL, "'" . $view->name . ':' . $view->current_display . "'", 'view_name'); | |
} | |
+ /** | |
+ * Define aggregate functions and how to apply them to a query. | |
+ * | |
+ * @return | |
+ * An array of information about aggregate functions, keyed by the SQL | |
+ * function name. Each item may have the following properties: | |
+ * - 'title': The title used in the UI. | |
+ * - 'is aggregate': @todo Does not appear to be used. | |
+ * - 'extender': The class of a query extender which must be added to the | |
+ * query. | |
+ * - 'method': The method to call on the query once it has been extended | |
+ * with the above. | |
+ * - 'handler': An array of handlers of each type to replace the original | |
+ * handler which has this aggregate function applied. | |
+ */ | |
function get_aggregation_info() { | |
// @todo -- need a way to get database specific and customized aggregation | |
// functions into here. | |
@@ -1525,7 +1546,8 @@ class views_plugin_query_default extends views_plugin_query { | |
), | |
'count' => array( | |
'title' => t('Count'), | |
- 'method' => 'views_query_default_aggregation_method_simple', | |
+ 'extender' => 'ViewsAggregateQuery', | |
+ 'method' => 'addAggregateSimple', | |
'handler' => array( | |
'argument' => 'views_handler_argument_group_by_numeric', | |
'field' => 'views_handler_field_numeric', | |
@@ -1535,7 +1557,8 @@ class views_plugin_query_default extends views_plugin_query { | |
), | |
'count_distinct' => array( | |
'title' => t('Count DISTINCT'), | |
- 'method' => 'views_query_default_aggregation_method_distinct', | |
+ 'extender' => 'ViewsAggregateQuery', | |
+ 'method' => 'addAggregateDistinct', | |
'handler' => array( | |
'argument' => 'views_handler_argument_group_by_numeric', | |
'field' => 'views_handler_field_numeric', | |
@@ -1545,7 +1568,8 @@ class views_plugin_query_default extends views_plugin_query { | |
), | |
'sum' => array( | |
'title' => t('Sum'), | |
- 'method' => 'views_query_default_aggregation_method_simple', | |
+ 'extender' => 'ViewsAggregateQuery', | |
+ 'method' => 'addAggregateSimple', | |
'handler' => array( | |
'argument' => 'views_handler_argument_group_by_numeric', | |
'filter' => 'views_handler_filter_group_by_numeric', | |
@@ -1554,7 +1578,8 @@ class views_plugin_query_default extends views_plugin_query { | |
), | |
'avg' => array( | |
'title' => t('Average'), | |
- 'method' => 'views_query_default_aggregation_method_simple', | |
+ 'extender' => 'ViewsAggregateQuery', | |
+ 'method' => 'addAggregateSimple', | |
'handler' => array( | |
'argument' => 'views_handler_argument_group_by_numeric', | |
'filter' => 'views_handler_filter_group_by_numeric', | |
@@ -1563,7 +1588,8 @@ class views_plugin_query_default extends views_plugin_query { | |
), | |
'min' => array( | |
'title' => t('Minimum'), | |
- 'method' => 'views_query_default_aggregation_method_simple', | |
+ 'extender' => 'ViewsAggregateQuery', | |
+ 'method' => 'addAggregateSimple', | |
'handler' => array( | |
'argument' => 'views_handler_argument_group_by_numeric', | |
'filter' => 'views_handler_filter_group_by_numeric', | |
@@ -1572,7 +1598,18 @@ class views_plugin_query_default extends views_plugin_query { | |
), | |
'max' => array( | |
'title' => t('Maximum'), | |
- 'method' => 'views_query_default_aggregation_method_simple', | |
+ 'extender' => 'ViewsAggregateQuery', | |
+ 'method' => 'addAggregateSimple', | |
+ 'handler' => array( | |
+ 'argument' => 'views_handler_argument_group_by_numeric', | |
+ 'filter' => 'views_handler_filter_group_by_numeric', | |
+ 'sort' => 'views_handler_sort_group_by_numeric', | |
+ ), | |
+ ), | |
+ 'group_concat' => array( | |
+ 'title' => t('Group concat'), | |
+ 'extender' => 'ViewsAggregateQuery', | |
+ 'method' => 'addAggregateGroupConcat', | |
'handler' => array( | |
'argument' => 'views_handler_argument_group_by_numeric', | |
'filter' => 'views_handler_filter_group_by_numeric', | |
@@ -1581,7 +1618,8 @@ class views_plugin_query_default extends views_plugin_query { | |
), | |
'stddev_pop' => array( | |
'title' => t('Standard deviation'), | |
- 'method' => 'views_query_default_aggregation_method_simple', | |
+ 'extender' => 'ViewsAggregateQuery', | |
+ 'method' => 'addAggregateSimple', | |
'handler' => array( | |
'argument' => 'views_handler_argument_group_by_numeric', | |
'filter' => 'views_handler_filter_group_by_numeric', | |
@@ -1636,15 +1674,6 @@ class views_plugin_query_default extends views_plugin_query { | |
} | |
} | |
-function views_query_default_aggregation_method_simple($group_type, $field) { | |
- return strtoupper($group_type) . '(' . $field . ')'; | |
-} | |
- | |
-function views_query_default_aggregation_method_distinct($group_type, $field) { | |
- $group_type = str_replace('_distinct', '', $group_type); | |
- return strtoupper($group_type) . '(DISTINCT ' . $field . ')'; | |
-} | |
- | |
/** | |
* Validation callback for query tags. | |
*/ | |
@@ -1657,3 +1686,61 @@ function views_element_validate_tags($element, &$form_state) { | |
} | |
} | |
} | |
+ | |
+/** | |
+ * Query extender for aggregate expressions. | |
+ * | |
+ * Provides methods for adding aggregate expressions to query. Each method name | |
+ * follows the pattern addAggretateTYPE() and has the same parameters: see | |
+ * addAggregateSimple() for these. | |
+ * | |
+ * This all works because we're the only extender being used here. | |
+ * Should get_aggregation_info() be opened up to let other modules define | |
+ * aggregation methods (which is http://drupal.org/node/1359298), we'll need a | |
+ * way to make sure we only extend by each class once (for which there is proof | |
+ * of concept code here: http://drupal.org/node/1365210). | |
+ */ | |
+class ViewsAggregateQuery extends SelectQueryExtender { | |
+ /** | |
+ * Add a simple aggregate expression to a query. | |
+ * | |
+ * @param $group_type | |
+ * The grouping function name, eg 'count'. | |
+ * Note that all our aggregate expression methods have this parameter but | |
+ * methods that are specialized to just one SQL aggregate function will not | |
+ * need to make use of it. | |
+ * @param $column_name | |
+ * The column name to aggregate, in the form 'table.column'. | |
+ * @param $fieldname | |
+ * The alias to give the expression, that Views will consider to be the | |
+ * name of the field. | |
+ * @param $placeholders | |
+ * The arguments for the expression. | |
+ */ | |
+ function addAggregateSimple($group_type, $column_name, $fieldname, $placeholders) { | |
+ // Create the aggregate expression. | |
+ $function = strtoupper($group_type); | |
+ $expression = "$function($column_name)"; | |
+ $this->query->addExpression($expression, $fieldname, $placeholders); | |
+ return $this; | |
+ } | |
+ | |
+ /** | |
+ * Add a DISTINCT aggregate expression to a query. | |
+ */ | |
+ function addAggregateDistinct($group_type, $column_name, $fieldname, $placeholders) { | |
+ $group_type = str_replace('_distinct', '', $group_type); | |
+ $expression = strtoupper($group_type) . '(DISTINCT ' . $column_name . ')'; | |
+ $this->query->addExpression($expression, $fieldname, $placeholders); | |
+ return $this; | |
+ } | |
+ | |
+ /** | |
+ * Add a GROUP_CONCAT() expression to a query. | |
+ */ | |
+ function addAggregateGroupConcat($group_type, $column_name, $fieldname, $placeholders) { | |
+ $expression = "(GROUP_CONCAT($column_name SEPARATOR '|'))"; | |
+ $this->query->addExpression($expression, $fieldname, $placeholders); | |
+ return $this; | |
+ } | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment