From 740dd877cde870c7a80d7e0d1b143e5dee8fb37f Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 28 Jul 2016 19:37:55 -0700 Subject: [PATCH] CRM-19130 - xml/templates/dao.tpl - Fire events for fields() and links() --- CRM/Core/DAO/AllCoreTables.php | 33 ++++++++++++++-- CRM/Utils/Hook.php | 2 + .../CRM/Core/DAO/AllCoreTablesTest.php | 39 +++++++++++++++++++ xml/templates/dao.tpl | 32 +++++---------- 4 files changed, 81 insertions(+), 25 deletions(-) diff --git a/CRM/Core/DAO/AllCoreTables.php b/CRM/Core/DAO/AllCoreTables.php index 21fc67e847..2fced2a763 100644 --- a/CRM/Core/DAO/AllCoreTables.php +++ b/CRM/Core/DAO/AllCoreTables.php @@ -44,6 +44,7 @@ class CRM_Core_DAO_AllCoreTables { if ($init && !$fresh) { return; } + Civi::$statics[__CLASS__] = array(); $file = preg_replace('/\.php$/', '.data.php', __FILE__); $entityTypes = require $file; @@ -53,8 +54,13 @@ class CRM_Core_DAO_AllCoreTables { self::$tables = array(); self::$daoToClass = array(); foreach ($entityTypes as $entityType) { - self::registerEntityType($entityType['name'], $entityType['class'], - $entityType['table']); + self::registerEntityType( + $entityType['name'], + $entityType['class'], + $entityType['table'], + isset($entityType['fields_callback']) ? $entityType['fields_callback'] : NULL, + isset($entityType['links_callback']) ? $entityType['links_callback'] : NULL + ); } $init = TRUE; @@ -63,13 +69,15 @@ class CRM_Core_DAO_AllCoreTables { /** * (Quasi-Private) Do not call externally (except for unit-testing) */ - public static function registerEntityType($daoName, $className, $tableName) { + public static function registerEntityType($daoName, $className, $tableName, $fields_callback = NULL, $links_callback = NULL) { self::$daoToClass[$daoName] = $className; self::$tables[$tableName] = $className; self::$entityTypes[$className] = array( 'name' => $daoName, 'class' => $className, 'table' => $tableName, + 'fields_callback' => $fields_callback, + 'links_callback' => $links_callback, ); } @@ -251,4 +259,23 @@ class CRM_Core_DAO_AllCoreTables { return Civi::$statics[__CLASS__][$cacheKey]; } + /** + * (Quasi-Private) Do not call externally. For use by DAOs. + * + * Apply any third-party alterations to the `fields()`. + * + * @param string $className + * @param string $event + * @param mixed $values + */ + public static function invoke($className, $event, &$values) { + self::init(); + if (isset(self::$entityTypes[$className][$event])) { + foreach (self::$entityTypes[$className][$event] as $filter) { + $args = array($className, &$values); + \Civi\Core\Resolver::singleton()->call($filter, $args); + } + } + } + } diff --git a/CRM/Utils/Hook.php b/CRM/Utils/Hook.php index a60b911bcb..7bec5213c0 100644 --- a/CRM/Utils/Hook.php +++ b/CRM/Utils/Hook.php @@ -1740,6 +1740,8 @@ abstract class CRM_Utils_Hook { * - name: string, a unique short name (e.g. "ReportInstance") * - class: string, a PHP DAO class (e.g. "CRM_Report_DAO_Instance") * - table: string, a SQL table name (e.g. "civicrm_report_instance") + * - fields_callback: array, list of callables which manipulates field list + * - links_callback: array, list of callables which manipulates fk list * * @return null * The return value is ignored diff --git a/tests/phpunit/CRM/Core/DAO/AllCoreTablesTest.php b/tests/phpunit/CRM/Core/DAO/AllCoreTablesTest.php index 132e10b1f6..ab9819b37b 100644 --- a/tests/phpunit/CRM/Core/DAO/AllCoreTablesTest.php +++ b/tests/phpunit/CRM/Core/DAO/AllCoreTablesTest.php @@ -9,4 +9,43 @@ class CRM_Core_DAO_AllCoreTablesTest extends CiviUnitTestCase { $this->assertEquals('civicrm_email', CRM_Core_DAO_AllCoreTables::getTableForClass('CRM_Core_DAO_Email')); $this->assertEquals('civicrm_email', CRM_Core_DAO_AllCoreTables::getTableForClass('CRM_Core_BAO_Email')); } + + /** + * Ensure that hook_civicrm_entityTypes runs and correctly handles the + * 'fields_callback' option. + */ + public function testHook() { + // 1. First, check the baseline fields()... + $fields = CRM_Core_DAO_Email::fields(); + $this->assertFalse(isset($fields['location_type_id']['foo'])); + + $exports = CRM_Core_DAO_Email::export(); + $this->assertFalse(isset($exports['contact_id'])); + + // 2. Now, let's hook into it... + $this->hookClass->setHook('civicrm_entityTypes', array($this, '_hook_civicrm_entityTypes')); + unset(Civi::$statics['CRM_Core_DAO_Email']); + CRM_Core_DAO_AllCoreTables::init(1); + + // 3. And see if the data has changed... + $fields = CRM_Core_DAO_Email::fields(); + $this->assertEquals('bar', $fields['location_type_id']['foo']); + + $exports = CRM_Core_DAO_Email::export(); + $this->assertTrue(is_array($exports['contact_id'])); + } + + public function _hook_civicrm_entityTypes(&$entityTypes) { + $entityTypes['CRM_Core_DAO_Email']['fields_callback'][] = function ($class, &$fields) { + $fields['location_type_id']['foo'] = 'bar'; + $fields['contact_id']['export'] = TRUE; + }; + } + + protected function tearDown() { + CRM_Utils_Hook::singleton()->reset(); + CRM_Core_DAO_AllCoreTables::init(1); + parent::tearDown(); + } + } diff --git a/xml/templates/dao.tpl b/xml/templates/dao.tpl index 3519b55ecd..fe5e9f8707 100644 --- a/xml/templates/dao.tpl +++ b/xml/templates/dao.tpl @@ -46,20 +46,6 @@ class {$table.className} extends CRM_Core_DAO {ldelim} */ static $_tableName = '{$table.name}'; - /** - * static instance to hold the field values - * - * @var array - */ - static $_fields = null; - - /** - * static instance to hold the FK relationships - * - * @var string - */ - static $_links = null; - /** * static value to see if we should log any modifications to * this table in the civicrm_log table @@ -99,17 +85,18 @@ class {$table.className} extends CRM_Core_DAO {ldelim} * [CRM_Core_Reference_Interface] */ static function getReferenceColumns() {ldelim} - if (!self::$_links) {ldelim} - self::$_links = static::createReferenceColumns(__CLASS__); + if (!isset(Civi::$statics[__CLASS__]['links'])) {ldelim} + Civi::$statics[__CLASS__]['links'] = static::createReferenceColumns(__CLASS__); {foreach from=$table.foreignKey item=foreign} - self::$_links[] = new CRM_Core_Reference_Basic(self::getTableName(), '{$foreign.name}', '{$foreign.table}', '{$foreign.key}'); + Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName(), '{$foreign.name}', '{$foreign.table}', '{$foreign.key}'); {/foreach} {foreach from=$table.dynamicForeignKey item=foreign} - self::$_links[] = new CRM_Core_Reference_Dynamic(self::getTableName(), '{$foreign.idColumn}', NULL, '{$foreign.key|default:'id'}', '{$foreign.typeColumn}'); + Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Dynamic(self::getTableName(), '{$foreign.idColumn}', NULL, '{$foreign.key|default:'id'}', '{$foreign.typeColumn}'); {/foreach} + CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']); {rdelim} - return self::$_links; + return Civi::$statics[__CLASS__]['links']; {rdelim} {/if} {* table.foreignKey *} @@ -119,8 +106,8 @@ class {$table.className} extends CRM_Core_DAO {ldelim} * @return array */ static function &fields( ) {ldelim} - if ( ! ( self::$_fields ) ) {ldelim} - self::$_fields = array ( + if ( ! isset(Civi::$statics[__CLASS__]['fields']) ) {ldelim} + Civi::$statics[__CLASS__]['fields'] = array ( {foreach from=$table.fields item=field} {if $field.uniqueName} @@ -200,8 +187,9 @@ class {$table.className} extends CRM_Core_DAO {ldelim} {/if} {* field.pseudoconstant *} ), {/foreach} {* table.fields *} ); + CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']); {rdelim} - return self::$_fields; + return Civi::$statics[__CLASS__]['fields']; {rdelim} /** -- 2.25.1