diff --git a/handlers/views_handler_relationship_groupwise_max.inc b/handlers/views_handler_relationship_groupwise_max.inc index e1adbaa77190f8cff61a5fb26ebc54ea97d0f5db..10f69711be1e3509b8035a49cbd74496d264eca6 100644 --- a/handlers/views_handler_relationship_groupwise_max.inc +++ b/handlers/views_handler_relationship_groupwise_max.inc @@ -198,11 +198,7 @@ class views_handler_relationship_groupwise_max extends views_handler_relationshi $temp_view = $this->get_temporary_view(); // Add the sort from the options to the default display. - // This is broken, in that the sort order field also gets added as a - // select field. See http://drupal.org/node/844910. - // We work around this further down. - $sort = $options['subquery_sort']; - list($sort_table, $sort_field) = explode('.', $sort); + list($sort_table, $sort_field) = explode('.', $options['subquery_sort']); $sort_options = array('order' => $options['subquery_order']); $temp_view->add_item('default', 'sort', $sort_table, $sort_field, $sort_options); } @@ -273,40 +269,45 @@ class views_handler_relationship_groupwise_max extends views_handler_relationshi // wrong -- needs attention from someone who understands it. // In the meantime, this works, but with a leap of faith. $orders =& $subquery->getOrderBy(); + $orders_tmp = array(); foreach ($orders as $order_key => $order) { - // But if we're using a whole view, we don't know what we have! - if ($options['subquery_view']) { - list($sort_table, $sort_field) = explode('.', $order_key); - } - $orders[$sort_table . $this->subquery_namespace . '.' . $sort_field] = $order; - unset($orders[$order_key]); + // Until http://drupal.org/node/844910 is fixed, $order_key is a field + // alias from SELECT. De-alias it using the View object. + $sort_table = $temp_view->query->fields[$order_key]['table']; + $sort_field = $temp_view->query->fields[$order_key]['field']; + $orders_tmp[$sort_table . $this->subquery_namespace . '.' . $sort_field] = $order; } + $orders = $orders_tmp; // The query we get doesn't include the LIMIT, so add it here. $subquery->range(0, 1); + // Clone the query object to force recompilation of the underlying where and + // having objects on the next step. + $subquery = clone $subquery; + + // Add in Views Query Substitutions such as ***CURRENT_TIME***. + views_query_views_alter($subquery); // Extract the SQL the temporary view built. $subquery_sql = $subquery->__toString(); - // Replace the placeholder with the outer, correlated field. For example, - // change the placeholder ':users_uid' into the outer field 'users.uid'. It - // is necessary to work directly with the SQL, because putting a name of a - // field into a SelectQuery that it does not recognize (because it's outer) - // just makes it treat it as a string. Using this handler on a view with a - // base table that isn't the one defined in the outer field causes SQL - // errors since the base table is hard-coded in the handler data. So - // replace the outer field base table with the relationship. We use the - // argument table since it will always match the outer field's table. - // @see https://www.drupal.org/node/2295379 - if ($this->relationship) { - $outer_field = str_replace($this->definition['argument table'], $this->relationship, $this->definition['outer field']); - } - else { - // Just use the default outer field. - $outer_field = $this->definition['outer field']; + // Replace subquery argument placeholders. + $quoted = $subquery->getArguments(); + $connection = Database::getConnection(); + foreach ($quoted as $key => $val) { + if (is_array($val)) { + $quoted[$key] = implode(', ', array_map(array($connection, 'quote'), $val)); + } + // If the correlated placeholder has been located, replace it with the + // outer field name. + elseif ($val === '**CORRELATED**') { + $quoted[$key] = $this->definition['outer field']; + } + else { + $quoted[$key] = $connection->quote($val); + } } - $outer_placeholder = ':' . str_replace('.', '_', $this->definition['outer field']); - $subquery_sql = str_replace($outer_placeholder, $outer_field, $subquery_sql); + $subquery_sql = strtr($subquery_sql, $quoted); return $subquery_sql; }