diff --git a/CRM/ConstituentsOnly/BAO/ConstituentsOnly.php b/CRM/ConstituentsOnly/BAO/ConstituentsOnly.php index 0b117f5..10e1210 100644 --- a/CRM/ConstituentsOnly/BAO/ConstituentsOnly.php +++ b/CRM/ConstituentsOnly/BAO/ConstituentsOnly.php @@ -2,11 +2,87 @@ class CRM_ConstituentsOnly_BAO_ConstituentsOnly { + + /** + * Get Suported Report Classes. + * + * @return array + * + */ + public static function getSuportedReportClasses() { + return [ + 'CRM_Report_Form_Contact_Summary', + ]; + } + + /** + * Get sql. + * + * @return string + * + */ + public static function getCommonSql() { + return " + SELECT MAX(contact_a.id) AS contact_id + FROM civicrm_contact contact_a + LEfT JOIN civicrm_relationship cr + ON (cr.contact_id_a = contact_a.id) + LEFT JOIN civicrm_contact cc + ON (cr.contact_id_b = cc.id) + AND cc.is_deleted = 0 + AND (cc.do_not_trade IS NULL OR cc.do_not_trade = 0) + AND cr.is_active = 1 + WHERE contact_a.do_not_trade = 1 + AND cc.id IS NOT NULL + GROUP BY contact_a.id + + UNION + SELECT MAX(contact_a.id) AS contact_id + FROM civicrm_contact contact_a + LEfT JOIN civicrm_relationship cr + ON (cr.contact_id_b = contact_a.id) + LEFT JOIN civicrm_contact cc + ON (cr.contact_id_a = cc.id) + AND cc.is_deleted = 0 + AND (cc.do_not_trade IS NULL OR cc.do_not_trade = 0) + AND cr.is_active = 1 + WHERE contact_a.do_not_trade = 1 + AND cc.id IS NOT NULL + GROUP BY contact_a.id + "; + } + + /** + * Get Constituent Sql. + * + * @param array $contactIds + * + * @return string + */ + public static function getConstituentSql($contactIds) { + return " + SELECT MAX(contact_a.id) AS contact_id, cc.id AS og_contact_id + FROM civicrm_contact contact_a + INNER JOIN civicrm_relationship cr + ON (cr.contact_id_a = contact_a.id OR cr.contact_id_b = contact_a.id) + AND contact_a.is_deleted = 0 + AND (contact_a.do_not_trade = 0 OR contact_a.do_not_trade IS NULL) + AND cr.is_active = 1 + INNER JOIN civicrm_contact cc + ON (cr.contact_id_a = cc.id OR cr.contact_id_b = cc.id) + AND contact_a.id <> cc.id + AND cc.id IN (" . implode(',', $contactIds) . ") + AND cc.do_not_trade = 1 + GROUP BY cc.id + "; + } + /** * Alter Quick search query. * * @param string $query * + * @return string */ public static function getQuickSearchQuery($query) { $joinQuery = str_replace('WHERE ', 'WHERE (cc.do_not_trade = 1) AND ', $query); @@ -63,25 +139,15 @@ class CRM_ConstituentsOnly_BAO_ConstituentsOnly { /** * Rebuild search result rows. * - * @param string $query + * @param array $rows + * @param array $headers * + * @return array */ public static function updateSearchRows($rows, $headers) { $contactIds = array_keys($rows); - $sql = "SELECT MAX(contact_a.id) AS contact_id, cc.id AS og_contact_id - FROM civicrm_contact contact_a - INNER JOIN civicrm_relationship cr - ON (cr.contact_id_a = contact_a.id OR cr.contact_id_b = contact_a.id) - AND contact_a.is_deleted = 0 - AND (contact_a.do_not_trade = 0 OR contact_a.do_not_trade IS NULL) - AND cr.is_active = 1 - INNER JOIN civicrm_contact cc - ON (cr.contact_id_a = cc.id OR cr.contact_id_b = cc.id) - AND contact_a.id <> cc.id - AND cc.id IN (" . implode(',', $contactIds) . ") - AND cc.do_not_trade = 1 - GROUP BY cc.id - "; + $sql = self::getConstituentSql($contactIds); + $result = CRM_Core_DAO::executeQuery($sql); $relContactIds = []; @@ -131,4 +197,93 @@ class CRM_ConstituentsOnly_BAO_ConstituentsOnly { return $rows; } + /** + * Rebuild report result rows. + * + * @param array $rows + * @param CRM_Core_Report $object + * + * @return array + */ + public static function updateReportRows($rows, &$object) { + if (property_exists($object, '_donotTradeRowBuilding') + && $object->_donotTradeRowBuilding + ) { + return $rows; + } + + $contactIds = []; + foreach ($rows as $id => $row) { + if (CRM_Utils_Array::value( + 'civicrm_contact_do_not_trade_alter', $row) == 'Yes' + ) { + $contactIds[$id] = $row['civicrm_contact_id']; + } + } + if (empty($contactIds)) { + return $rows; + } + + $sql = self::getConstituentSql($contactIds); + $result = CRM_Core_DAO::executeQuery($sql); + $relContactIds = []; + while ($result->fetch()) { + $relContactIds[$result->og_contact_id] = $result->contact_id; + } + + if (!empty($relContactIds)) { + $object->_donotTradeRowBuilding = TRUE; + + $select = $object->getVar('_select'); + $from = $object->getVar('_from'); + $dbAliases = $object->getVar('_aliases'); + $contactAlias = "`{$dbAliases['civicrm_contact']}`"; + $query = " + {$select} + {$from} + WHERE {$contactAlias}.id IN (" . implode(',', $relContactIds) . ") + "; + + $newRows = []; + $tempObj = $object; + $tempObj->_columnHeaders = $object->_backupHeader; + $tempObj->buildRows($query, $newRows); + $tempObj->formatDisplay($newRows); + foreach ($newRows as $id => $newRow) { + $contactId = $newRow['civicrm_contact_id']; + while (in_array($contactId, $relContactIds)) { + $ogContactId = array_search($contactId, $relContactIds); + $ogId = array_search($ogContactId, $contactIds); + $newRow['civicrm_contact_sort_name'] .= " ({$rows[$ogId]['civicrm_contact_sort_name']})"; + $rows[$ogId] = $newRow; + unset($relContactIds[$ogContactId]); + } + } + } + return $rows; + } + + /** + * Update sql for report. + * + * @param CRM_Core_Report $object + * + */ + public static function updateReportSql(&$object) { + $where = $object->getVar('_where'); + $sql = self::getCommonSql(); + + $dbAliases = $object->getVar('_aliases'); + $contactAlias = "`{$dbAliases['civicrm_contact']}`"; + $searchFrom = "{$contactAlias}.`do_not_trade` IS NULL OR ({$contactAlias}.`do_not_trade` = 0)"; + $replaceFrom = "IF ( + {$contactAlias}.`do_not_trade` = 1, + {$contactAlias}.id IN ({$sql}), + 1 + )"; + $where = str_replace($searchFrom, $replaceFrom, $where); + $object->setVar('_where', $where); + $object->_backupHeader = $object->getVar('_columnHeaders'); + } + } diff --git a/constituentsonly.php b/constituentsonly.php index 502b2f3..9f5fd23 100644 --- a/constituentsonly.php +++ b/constituentsonly.php @@ -144,10 +144,35 @@ function constituentsonly_civicrm_contactListQuery(&$query, $queryText, $context } /** - * Implements hook_civicrm_selectWhereClause(). + * Implements hook_civicrm_alterReportVar(). * - * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_selectWhereClause + * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterReportVar */ +function constituentsonly_civicrm_alterReportVar($varType, &$var, &$object) { + $reportClassName = get_class($object); + $supportedClassNames = CRM_ConstituentsOnly_BAO_ConstituentsOnly::getSuportedReportClasses(); + if (!in_array($reportClassName, $supportedClassNames)) { + return; + } + + if ('columns' == $varType) { + $var['civicrm_contact']['fields']['do_not_trade_alter'] = [ + 'title' => ts('Case ID'), + 'no_display' => TRUE, + 'required' => TRUE, + 'name' => 'do_not_trade', + ]; + } + + if ($varType == 'sql') { + CRM_ConstituentsOnly_BAO_ConstituentsOnly::updateReportSql($object); + } + + if ($varType == 'rows') { + $var = CRM_ConstituentsOnly_BAO_ConstituentsOnly::updateReportRows($var, $object); + } +} + function constituentsonly_civicrm_selectWhereClause($entity, &$clauses) { if ($entity == 'Contact') { $url = CRM_Utils_Array::value('q', $_GET);