From 832eb60a0db787e3d70caa44e8574e811247e008 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Wed, 5 Aug 2020 02:18:21 -0700 Subject: [PATCH] CRM_Core_Resources - Convert 'settings' to a type of snippet --- CRM/Core/Region.php | 25 ++++--- CRM/Core/Resources.php | 87 ++++++++++-------------- tests/phpunit/CRM/Core/ResourcesTest.php | 2 +- 3 files changed, 54 insertions(+), 60 deletions(-) diff --git a/CRM/Core/Region.php b/CRM/Core/Region.php index 06cece6bc9..d87664019d 100644 --- a/CRM/Core/Region.php +++ b/CRM/Core/Region.php @@ -4,7 +4,6 @@ * Maintain a set of markup/templates to inject inside various regions */ class CRM_Core_Region { - static private $_instances = NULL; /** * Obtain the content for a given region. @@ -15,10 +14,10 @@ class CRM_Core_Region { * @return CRM_Core_Region */ public static function &instance($name, $autocreate = TRUE) { - if ($autocreate && !isset(self::$_instances[$name])) { - self::$_instances[$name] = new CRM_Core_Region($name); + if ($autocreate && !isset(Civi::$statics[__CLASS__][$name])) { + Civi::$statics[__CLASS__][$name] = new CRM_Core_Region($name); } - return self::$_instances[$name]; + return Civi::$statics[__CLASS__][$name]; } /** @@ -95,13 +94,14 @@ class CRM_Core_Region { * - script: string, Javascript code * - scriptUrl: string, URL of a Javascript file * - jquery: string, Javascript code which runs inside a jQuery(function($){...}); block + * - settings: array, list of static values to convey. * - style: string, CSS code * - styleUrl: string, URL of a CSS file * * @return array */ public function add($snippet) { - static $types = ['markup', 'template', 'callback', 'scriptUrl', 'script', 'jquery', 'style', 'styleUrl']; + static $types = ['markup', 'template', 'callback', 'scriptUrl', 'script', 'jquery', 'settings', 'style', 'styleUrl']; $defaults = [ 'region' => $this->_name, 'weight' => 1, @@ -139,11 +139,10 @@ class CRM_Core_Region { * Get snippet. * * @param string $name - * - * @return mixed + * @return array|NULL */ - public function get($name) { - return !empty($this->_snippets[$name]) ? $this->_snippets[$name] : NULL; + public function &get($name) { + return $this->_snippets[$name]; } /** @@ -218,6 +217,14 @@ class CRM_Core_Region { } break; + case 'settings': + $settingsData = json_encode(Civi::resources()->getSettings($this->_name), JSON_UNESCAPED_SLASHES); + $js = "(function(vars) { + if (window.CRM) CRM.$.extend(true, CRM, vars); else window.CRM = vars; + })($settingsData)"; + $html .= sprintf("\n", $js); + break; + default: throw new CRM_Core_Exception(ts('Snippet type %1 is unrecognized', [1 => $snippet['type']])); diff --git a/CRM/Core/Resources.php b/CRM/Core/Resources.php index 3e736d3c05..0d086f40c9 100644 --- a/CRM/Core/Resources.php +++ b/CRM/Core/Resources.php @@ -45,20 +45,6 @@ class CRM_Core_Resources { */ private $strings = NULL; - /** - * Settings in free-form data tree. - * - * @var array - */ - protected $settings = []; - - /** - * Setting factories. - * - * @var callable[] - */ - protected $settingsFactories = []; - /** * Added core resources. * @@ -269,9 +255,11 @@ class CRM_Core_Resources { * @return CRM_Core_Resources */ public function addVars($nameSpace, $vars, $region = NULL) { - $existing = CRM_Utils_Array::value($nameSpace, CRM_Utils_Array::value('vars', $this->settings), []); - $vars = $this->mergeSettings($existing, $vars); - $this->addSetting(['vars' => [$nameSpace => $vars]], $region); + $s = &$this->findCreateSettingSnippet($region); + $s['settings']['vars'][$nameSpace] = $this->mergeSettings( + $s['settings']['vars'][$nameSpace] ?? [], + $vars + ); return $this; } @@ -287,22 +275,8 @@ class CRM_Core_Resources { * @return CRM_Core_Resources */ public function addSetting($settings, $region = NULL) { - if (!$region) { - $region = self::isAjaxMode() ? 'ajax-snippet' : 'html-header'; - } - $this->settings = $this->mergeSettings($this->settings, $settings); - if (isset($this->addedSettings[$region])) { - return $this; - } - $resources = $this; - $settingsResource = [ - 'callback' => function (&$snippet, &$html) use ($resources, $region) { - $html .= "\n" . $resources->renderSetting($region); - }, - 'weight' => -100000, - ]; - CRM_Core_Region::instance($region)->add($settingsResource); - $this->addedSettings[$region] = TRUE; + $s = &$this->findCreateSettingSnippet($region); + $s['settings'] = $this->mergeSettings($s['settings'], $settings); return $this; } @@ -310,21 +284,23 @@ class CRM_Core_Resources { * Add JavaScript variables to the global CRM object via a callback function. * * @param callable $callable + * @param string|NULL $region * @return CRM_Core_Resources */ - public function addSettingsFactory($callable) { - // Make sure our callback has been registered - $this->addSetting([]); - $this->settingsFactories[] = $callable; + public function addSettingsFactory($callable, $region = NULL) { + $s = &$this->findCreateSettingSnippet($region); + $s['settingsFactories'][] = $callable; return $this; } /** * Helper fn for addSettingsFactory. + * @deprecated */ - public function getSettings() { - $result = $this->settings; - foreach ($this->settingsFactories as $callable) { + public function getSettings($region = NULL) { + $s = &$this->findCreateSettingSnippet($region); + $result = $s['settings']; + foreach ($s['settingsFactories'] as $callable) { $result = $this->mergeSettings($result, $callable()); } CRM_Utils_Hook::alterResourceSettings($result); @@ -348,17 +324,28 @@ class CRM_Core_Resources { } /** - * Helper fn for addSetting. - * Render JavaScript variables for the global CRM object. - * - * @return string + * @param string $regionName + * @return array */ - public function renderSetting($region = NULL) { - $vars = json_encode($this->getSettings(), JSON_UNESCAPED_SLASHES); - $js = "(function(vars) { - if (window.CRM) CRM.$.extend(true, CRM, vars); else window.CRM = vars; -})($vars)"; - return sprintf("\n", $js); + private function &findCreateSettingSnippet($regionName) { + if (!$regionName) { + $regionName = self::isAjaxMode() ? 'ajax-snippet' : 'html-header'; + } + + $region = CRM_Core_Region::instance($regionName); + $snippet = &$region->get('settings'); + if ($snippet !== NULL) { + return $snippet; + } + + $region->add([ + 'name' => 'settings', + 'type' => 'settings', + 'settings' => [], + 'settingsFactories' => [], + 'weight' => -100000, + ]); + return $region->get('settings'); } /** diff --git a/tests/phpunit/CRM/Core/ResourcesTest.php b/tests/phpunit/CRM/Core/ResourcesTest.php index 629ba4f803..f39a7a329f 100644 --- a/tests/phpunit/CRM/Core/ResourcesTest.php +++ b/tests/phpunit/CRM/Core/ResourcesTest.php @@ -150,7 +150,7 @@ class CRM_Core_ResourcesTest extends CiviUnitTestCase { ['fruit' => ['yours' => 'orange', 'mine' => 'apple']], $this->res->getSettings() ); - $actual = $this->res->renderSetting(); + $actual = CRM_Core_Region::instance('html-header')->render(''); $expected = json_encode(['fruit' => ['yours' => 'orange', 'mine' => 'apple']]); $this->assertTrue(strpos($actual, $expected) !== FALSE); } -- 2.25.1