bool). * * @var array */ protected $addedCoreResources = []; /** * Added core styles. * * Format is ($regionName => bool). * * @var array */ protected $addedCoreStyles = []; /** * A value to append to JS/CSS URLs to coerce cache resets. * * @var string */ protected $cacheCode = NULL; /** * The name of a setting which persistently stores the cacheCode. * * @var string */ protected $cacheCodeKey = NULL; /** * Are ajax popup screens enabled. * * @var bool */ public $ajaxPopupsEnabled; /** * @var \Civi\Core\Paths */ protected $paths; /** * Get or set the single instance of CRM_Core_Resources. * * @param CRM_Core_Resources $instance * New copy of the manager. * * @return CRM_Core_Resources */ public static function singleton(CRM_Core_Resources $instance = NULL) { if ($instance !== NULL) { self::$_singleton = $instance; } if (self::$_singleton === NULL) { self::$_singleton = Civi::service('resources'); } return self::$_singleton; } /** * Construct a resource manager. * * @param CRM_Extension_Mapper $extMapper * Map extension names to their base path or URLs. * @param CRM_Utils_Cache_Interface $cache * JS-localization cache. * @param string|null $cacheCodeKey Random code to append to resource URLs; changing the code forces clients to reload resources */ public function __construct($extMapper, $cache, $cacheCodeKey = NULL) { $this->extMapper = $extMapper; $this->strings = new CRM_Core_Resources_Strings($cache); $this->cacheCodeKey = $cacheCodeKey; if ($cacheCodeKey !== NULL) { $this->cacheCode = Civi::settings()->get($cacheCodeKey); } if (!$this->cacheCode) { $this->resetCacheCode(); } $this->ajaxPopupsEnabled = (bool) Civi::settings()->get('ajaxPopupsEnabled'); $this->paths = Civi::paths(); } /** * Export permission data to the client to enable smarter GUIs. * * Note: Application security stems from the server's enforcement * of the security logic (e.g. in the API permissions). There's no way * the client can use this info to make the app more secure; however, * it can produce a better-tuned (non-broken) UI. * * @param array $permNames * List of permission names to check/export. * @return CRM_Core_Resources */ public function addPermissions($permNames) { $permNames = (array) $permNames; $perms = []; foreach ($permNames as $permName) { $perms[$permName] = CRM_Core_Permission::check($permName); } return $this->addSetting([ 'permissions' => $perms, ]); } /** * Add a JavaScript file to the current page using \n", $js); */ $js = 'var CRM = ' . json_encode($this->getSettings()) . ';'; //return sprintf("\n", $js); return sprintf("\n", $js); } /** * Add translated string to the js CRM object. * It can then be retrived from the client-side ts() function * Variable substitutions can happen from client-side * * Note: this function rarely needs to be called directly and is mostly for internal use. * See CRM_Core_Resources::addScriptFile which automatically adds translated strings from js files * * Simple example: * // From php: * CRM_Core_Resources::singleton()->addString('Hello'); * // The string is now available to javascript code i.e. * ts('Hello'); * * Example with client-side substitutions: * // From php: * CRM_Core_Resources::singleton()->addString('Your %1 has been %2'); * // ts() in javascript works the same as in php, for example: * ts('Your %1 has been %2', {1: objectName, 2: actionTaken}); * * NOTE: This function does not work with server-side substitutions * (as this might result in collisions and unwanted variable injections) * Instead, use code like: * CRM_Core_Resources::singleton()->addSetting(array('myNamespace' => array('myString' => ts('Your %1 has been %2', array(subs))))); * And from javascript access it at CRM.myNamespace.myString * * @param string|array $text * @param string|null $domain * @return CRM_Core_Resources */ public function addString($text, $domain = 'civicrm') { foreach ((array) $text as $str) { $translated = ts($str, [ 'domain' => ($domain == 'civicrm') ? NULL : [$domain, NULL], 'raw' => TRUE, ]); // We only need to push this string to client if the translation // is actually different from the original if ($translated != $str) { $bucket = $domain == 'civicrm' ? 'strings' : 'strings::' . $domain; $this->addSetting([ $bucket => [$str => $translated], ]); } } return $this; } /** * Add a CSS file to the current page using . * * @param string $ext * extension name; use 'civicrm' for core. * @param string $file * file path -- relative to the extension base dir. * @param int $weight * relative weight within a given region. * @param string $region * location within the file; 'html-header', 'page-header', 'page-footer'. * @return CRM_Core_Resources */ public function addStyleFile($ext, $file, $weight = self::DEFAULT_WEIGHT, $region = self::DEFAULT_REGION) { /** @var Civi\Core\Themes $theme */ $theme = Civi::service('themes'); foreach ($theme->resolveUrls($theme->getActiveThemeKey(), $ext, $file) as $url) { $this->addStyleUrl($url, $weight, $region); } return $this; } /** * Add a CSS file to the current page using . * * @param string $url * @param int $weight * relative weight within a given region. * @param string $region * location within the file; 'html-header', 'page-header', 'page-footer'. * @return CRM_Core_Resources */ public function addStyleUrl($url, $weight = self::DEFAULT_WEIGHT, $region = self::DEFAULT_REGION) { CRM_Core_Region::instance($region)->add([ 'name' => $url, 'type' => 'styleUrl', 'styleUrl' => $url, 'weight' => $weight, 'region' => $region, ]); return $this; } /** * Add a CSS content to the current page using