From 568a094693e4a3f0e943b176bde1d502a0dcb4b5 Mon Sep 17 00:00:00 2001 From: eileen Date: Fri, 22 Jan 2016 15:10:38 +1300 Subject: [PATCH] Add additional of customFieldTableJoins to be calculated for filters separately to select queries This means that if the report runs 2 queries, one to get the filtered list of subjects and a second to render the appropriate fields for them the first query (likely to be bigger) can avoid joining in tables that are only used for rendering results Change-Id: Iee0078054abe8b5e63435e66f9215fc2fd9cd62f Change-Id: Ic4e9ed36cf1a186aeeb1c44d59661e8971612022 --- CRM/Report/Form.php | 49 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/CRM/Report/Form.php b/CRM/Report/Form.php index 9bf3f30445..8e2327a780 100644 --- a/CRM/Report/Form.php +++ b/CRM/Report/Form.php @@ -296,12 +296,21 @@ class CRM_Report_Form extends CRM_Core_Form { protected $_aclWhere = NULL; /** - * Array of DAO tables having columns included in SELECT or ORDER BY clause + * Array of DAO tables having columns included in SELECT or ORDER BY clause. + * + * Where has also been added to this although perhaps the 'includes both' array should have a different name. * * @var array */ protected $_selectedTables; + /** + * Array of DAO tables having columns included in WHERE or HAVING clause + * + * @var array + */ + protected $filteredTables; + /** * Output mode e.g 'print', 'csv', 'pdf'. * @@ -3628,8 +3637,11 @@ ORDER BY cg.weight, cf.weight"; /** * Build custom data from clause. + * + * @param bool $joinsForFiltersOnly + * Only include joins to support filters. This would be used if creating a table of contacts to include first. */ - public function customDataFrom() { + public function customDataFrom($joinsForFiltersOnly = FALSE) { if (empty($this->_customGroupExtends)) { return; } @@ -3639,9 +3651,8 @@ ORDER BY cg.weight, cf.weight"; foreach ($this->_columns as $table => $prop) { if (in_array($table, $customTables)) { $extendsTable = $mapper[$prop['extends']]; - - // check field is in params - if (!$this->isFieldSelected($prop)) { + // Check field is required for rendering the report. + if ((!$this->isFieldSelected($prop)) || ($joinsForFiltersOnly && !$this->isFieldFiltered($prop))) { continue; } $baseJoin = CRM_Utils_Array::value($prop['extends'], $this->_customGroupExtendsJoin, "{$this->_aliases[$extendsTable]}.id"); @@ -3716,7 +3727,18 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a } } } + return $this->isFieldFiltered($prop); + + } + /** + * Check if the field is used as a filter. + * + * @param string $prop + * + * @return bool + */ + protected function isFieldFiltered($prop) { if (!empty($prop['filters']) && $this->_customGroupFilters) { foreach ($prop['filters'] as $fieldAlias => $val) { foreach (array( @@ -3802,6 +3824,22 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a return in_array($tableName, $this->selectedTables()); } + /** + * Check if table name has columns in WHERE or HAVING clause. + * + * @param string $tableName + * Name of table (index of $this->_columns array). + * + * @return bool + */ + public function isTableFiltered($tableName) { + // Cause the array to be generated if not previously done. + if (!$this->_selectedTables && !$this->filteredTables) { + $this->selectedTables(); + } + return in_array($tableName, $this->filteredTables); + } + /** * Fetch array of DAO tables having columns included in SELECT or ORDER BY clause. * @@ -3849,6 +3887,7 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a 'nnll' ) { $this->_selectedTables[] = $tableName; + $this->filteredTables[] = $tableName; break; } } -- 2.25.1