diff --git a/CRM/Utils/Hook.php b/CRM/Utils/Hook.php index e8014d314371..5dbdb614faf5 100644 --- a/CRM/Utils/Hook.php +++ b/CRM/Utils/Hook.php @@ -2101,6 +2101,27 @@ public static function angularModules(&$angularModules) { ); } + /** + * Alter the definition of some Angular HTML partials. + * + * @param \Civi\Angular\HtmlCollection $html + * + * @code + * function example_civicrm_angularPartials(HtmlCollection $html) { + * if ($doc = $html->get('~/crmMailing/EditMailingCtrl/2step.html')) { + * $doc->find('[ng-form="crmMailingSubform"]') + * ->attr('cat-stevens', 'ts(\'wild world\')'); + * } + * } + * @endCode + */ + public static function angularPartials($html) { + $event = \Civi\Core\Event\GenericHookEvent::create(array( + 'html' => $html, + )); + Civi::dispatcher()->dispatch('hook_civicrm_angularPartials', $event); + } + /** * This hook is called whenever the system builds a new copy of * semi-static asset. diff --git a/Civi/Angular/Manager.php b/Civi/Angular/Manager.php index 2f87ee73741d..7dfaf90311f2 100644 --- a/Civi/Angular/Manager.php +++ b/Civi/Angular/Manager.php @@ -202,7 +202,7 @@ protected function resolvePatterns($modules) { } /** - * Get the partial HTML documents for a module. + * Get the partial HTML documents for a module (unfiltered). * * @param string $name * Angular module name. @@ -211,12 +211,7 @@ protected function resolvePatterns($modules) { * @throws \Exception * Invalid partials configuration. */ - public function getPartials($name) { - $cacheKey = "angular-partials::$name"; - $cacheValue = $this->cache->get($cacheKey); - if ($cacheValue !== NULL) { - return $cacheValue; - } + public function getRawPartials($name) { $module = $this->getModule($name); $result = array(); if (isset($module['partials'])) { @@ -228,12 +223,36 @@ public function getPartials($name) { $result[$filename] = file_get_contents($partialDir . '/' . $file); } } + return $result; } - - $this->cache->set($cacheKey, $result); return $result; } + /** + * Get the partial HTML documents for a module. + * + * @param string $name + * Angular module name. + * @return array + * Array(string $extFilePath => string $html) + * @throws \Exception + * Invalid partials configuration. + */ + public function getPartials($name) { + $cacheKey = "angular-partials::$name"; + $cacheValue = $this->cache->get($cacheKey); + if ($cacheValue !== NULL) { + return $cacheValue; + } + + $html = new HtmlCollection($this->getRawPartials($name)); + \CRM_Utils_Hook::angularPartials($html); + $cacheValue = $html->getStrings(); + + $this->cache->set($cacheKey, $cacheValue); + return $cacheValue; + } + /** * Get list of translated strings for a module. * diff --git a/tests/phpunit/Civi/Angular/ManagerTest.php b/tests/phpunit/Civi/Angular/ManagerTest.php index 3ab7d8939ded..ba3c2d26ae81 100644 --- a/tests/phpunit/Civi/Angular/ManagerTest.php +++ b/tests/phpunit/Civi/Angular/ManagerTest.php @@ -109,7 +109,17 @@ public function testGetModules() { */ public function testGetPartials() { $partials = $this->angular->getPartials('crmMailing'); - $this->assertRegExp('/ng-form="crmMailing/', $partials['~/crmMailing/EditMailingCtrl/2step.html']); + $this->assertRegExp('/ng-form="crmMailingSubform">/', $partials['~/crmMailing/EditMailingCtrl/2step.html']); + // If crmMailing changes, feel free to use a different example. + } + + /** + * Get HTML fragments from an example module. The HTML is modified via hook. + */ + public function testGetPartials_Hooked() { + \CRM_Utils_Hook::singleton()->setHook('civicrm_angularPartials', array($this, 'hook_civicrm_angularPartials')); + $partials = $this->angular->getPartials('crmMailing'); + $this->assertRegExp('/ng-form="crmMailingSubform" cat-stevens="ts\\(\'wild world\'\\)">/', $partials['~/crmMailing/EditMailingCtrl/2step.html']); // If crmMailing changes, feel free to use a different example. } @@ -122,4 +132,21 @@ public function testGetStrings() { // If crmMailing changes, feel free to use a different example. } + /** + * Get a translatable string from an example module. The HTML is modified via hook. + */ + public function testGetStrings_Hooked() { + \CRM_Utils_Hook::singleton()->setHook('civicrm_angularPartials', array($this, 'hook_civicrm_angularPartials')); + $strings = $this->angular->getStrings('crmMailing'); + $this->assertTrue(in_array('wild world', $strings)); + // If crmMailing changes, feel free to use a different example. + } + + public function hook_civicrm_angularPartials(HtmlCollection $html) { + if ($doc = $html->get('~/crmMailing/EditMailingCtrl/2step.html')) { + $doc->find('[ng-form="crmMailingSubform"]') + ->attr('cat-stevens', 'ts(\'wild world\')'); + } + } + }