From 1256c13903e01a94063bff1f84b0b09c0d010638 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Wed, 21 May 2014 01:34:56 -0700 Subject: [PATCH] CRM-14478 - Add CRM_Core_DAO::getReferenceCounts() --- CRM/Core/DAO.php | 15 ++++++++++ CRM/Core/Reference/Basic.php | 20 ++++++++++++++ CRM/Core/Reference/Dynamic.php | 27 ++++++++++++++++++ CRM/Core/Reference/Interface.php | 10 +++++++ CRM/Core/Reference/OptionValue.php | 11 ++++++++ tests/phpunit/CRM/Core/DAOTest.php | 44 ++++++++++++++++++++++++++++++ 6 files changed, 127 insertions(+) diff --git a/CRM/Core/DAO.php b/CRM/Core/DAO.php index cceb90211f..b475f23b28 100644 --- a/CRM/Core/DAO.php +++ b/CRM/Core/DAO.php @@ -1779,6 +1779,21 @@ SELECT contact_id return $occurrences; } + function getReferenceCounts() { + $links = self::getReferencesToTable(static::getTableName()); + + $counts = array(); + foreach ($links as $refSpec) { + /** @var $refSpec CRM_Core_Reference_Interface */ + $count = $refSpec->getReferenceCount($this); + if ($count['count'] != 0) { + $counts[] = $count; + } + } + + return $counts; + } + /** * List all tables which have hard foreign keys to this table. * diff --git a/CRM/Core/Reference/Basic.php b/CRM/Core/Reference/Basic.php index f72a664bd7..f0c897e268 100644 --- a/CRM/Core/Reference/Basic.php +++ b/CRM/Core/Reference/Basic.php @@ -59,4 +59,24 @@ EOS; $result = CRM_Core_DAO::executeQuery($sql, $params, TRUE, $daoName); return $result; } + + public function getReferenceCount($targetDao) { + $targetColumn = $this->getTargetKey(); + $params = array( + 1 => array($targetDao->$targetColumn, 'String') + ); + $sql = <<getReferenceTable()} +WHERE {$this->getReferenceKey()} = %1 +EOS; + + return array( + 'name' => implode(':', array('sql', $this->getReferenceTable(), $this->getReferenceKey())), + 'type' => get_class($this), + 'table' => $this->getReferenceTable(), + 'key' => $this->getReferenceKey(), + 'count' => CRM_Core_DAO::singleValueQuery($sql, $params) + ); + } } diff --git a/CRM/Core/Reference/Dynamic.php b/CRM/Core/Reference/Dynamic.php index fdcf77546f..85c5d00f33 100644 --- a/CRM/Core/Reference/Dynamic.php +++ b/CRM/Core/Reference/Dynamic.php @@ -40,4 +40,31 @@ EOS; $result = CRM_Core_DAO::executeQuery($sql, $params, TRUE, $daoName); return $result; } + + public function getReferenceCount($targetDao) { + $targetColumn = $this->getTargetKey(); + $params = array( + 1 => array($targetDao->$targetColumn, 'String'), + + // If anyone complains about $targetDao::getTableName(), then could use + // "{get_class($targetDao)}::getTableName();" + 2 => array($targetDao::getTableName(), 'String'), + ); + + $sql = <<getReferenceTable()} +WHERE {$this->getReferenceKey()} = %1 +AND {$this->getTypeColumn()} = %2 +EOS; + + return array( + 'name' => implode(':', array('sql', $this->getReferenceTable(), $this->getReferenceKey())), + 'type' => get_class($this), + 'table' => $this->getReferenceTable(), + 'key' => $this->getReferenceKey(), + 'count' => CRM_Core_DAO::singleValueQuery($sql, $params) + ); + } + } diff --git a/CRM/Core/Reference/Interface.php b/CRM/Core/Reference/Interface.php index f949994c3b..e4cb7e5ecb 100644 --- a/CRM/Core/Reference/Interface.php +++ b/CRM/Core/Reference/Interface.php @@ -19,4 +19,14 @@ interface CRM_Core_Reference_Interface { * @return CRM_Core_DAO|NULL a query-handle (like the result of CRM_Core_DAO::executeQuery) */ public function findReferences($targetDao); + + /** + * Create a query to find references to a particular record + * + * @param CRM_Core_DAO $targetDao the instance for which we want references + * @return array a record describing the reference; must include the keys: + * - 'type': string (not necessarily unique) + * - 'count': int + */ + public function getReferenceCount($targetDao); } diff --git a/CRM/Core/Reference/OptionValue.php b/CRM/Core/Reference/OptionValue.php index 7c97972afc..6c983ba337 100644 --- a/CRM/Core/Reference/OptionValue.php +++ b/CRM/Core/Reference/OptionValue.php @@ -30,6 +30,17 @@ class CRM_Core_Reference_OptionValue extends CRM_Core_Reference_Basic { } } + public function getReferenceCount($targetDao) { + if (! ($targetDao instanceof CRM_Core_DAO_OptionValue)) { + throw new CRM_Core_Exception("Mismatched reference: expected OptionValue but received " . get_class($targetDao)); + } + if ($targetDao->option_group_id == $this->getTargetOptionGroupId()) { + return parent::getReferenceCount($targetDao); + } else { + return NULL; + } + } + public function getTargetOptionGroupId() { if ($this->targetOptionGroupId === NULL) { $this->targetOptionGroupId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', $this->targetOptionGroupName, 'id', 'name'); diff --git a/tests/phpunit/CRM/Core/DAOTest.php b/tests/phpunit/CRM/Core/DAOTest.php index b564829365..55ea4e5ed8 100644 --- a/tests/phpunit/CRM/Core/DAOTest.php +++ b/tests/phpunit/CRM/Core/DAOTest.php @@ -69,6 +69,50 @@ class CRM_Core_DAOTest extends CiviUnitTestCase { $this->assertEquals($contact->id, $refDao->contact_id); } + function testGetReferenceCounts() { + $result = $this->callAPISuccess('Contact', 'create', array( + 'first_name' => 'Testily', + 'last_name' => 'McHaste', + 'contact_type' => 'Individual', + 'api.Email.replace' => array( + 'values' => array( + array( + 'email' => 'spam@dev.null', + 'is_primary' => 0, + 'location_type_id' => 1, + ) + ), + ), + 'api.Phone.replace' => array( + 'values' => array( + array( + 'phone' => '234-567-0001', + 'is_primary' => 1, + 'location_type_id' => 1, + ), + array( + 'phone' => '234-567-0002', + 'is_primary' => 0, + 'location_type_id' => 1, + ), + ), + ), + )); + + $dao = new CRM_Contact_BAO_Contact(); + $dao->id = $result['id']; + $this->assertTrue((bool) $dao->find(TRUE)); + + $refCounts = $dao->getReferenceCounts(); + $this->assertTrue(is_array($refCounts)); + $refCountsIdx = CRM_Utils_Array::index(array('name'), $refCounts); + $this->assertEquals(1, $refCountsIdx['sql:civicrm_email:contact_id']['count']); + $this->assertEquals('civicrm_email', $refCountsIdx['sql:civicrm_email:contact_id']['table']); + $this->assertEquals(2, $refCountsIdx['sql:civicrm_phone:contact_id']['count']); + $this->assertEquals('civicrm_phone', $refCountsIdx['sql:civicrm_phone:contact_id']['table']); + $this->assertTrue(!isset($refCountsIdx['sql:civicrm_address:contact_id'])); + } + function composeQueryExamples() { $cases = array(); // $cases[] = array('Input-SQL', 'Input-Params', 'Expected-SQL'); -- 2.25.1