bool). * * @var array */ protected $addedBundles = []; /** * Added core resources. * * Format is ($regionName => bool). * * @var array */ protected $addedCoreResources = []; /** * Added core styles. * * Format is ($regionName => bool). * * @var array */ protected $addedCoreStyles = []; /** * Added settings. * * Format is ($regionName => bool). * * @var array */ protected $addedSettings = []; /** * 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_Core_Resources_Strings $strings * 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, $strings, $cacheCodeKey = NULL) { $this->extMapper = $extMapper; $this->strings = $strings; $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(); } /** * Assimilate all the resources listed in a bundle. * * @param iterable|string|\CRM_Core_Resources_Bundle $bundle * Either bundle object, or the symbolic name of a bundle, or a list of budnles. * Note: For symbolic names, the bundle must be a container service ('bundle.FOO'). * @return static */ public function addBundle($bundle) { if (is_iterable($bundle)) { foreach ($bundle as $b) { $this->addBundle($b); return $this; } } if (is_string($bundle)) { $bundle = Civi::service('bundle.' . $bundle); } if (isset($this->addedBundles[$bundle->name])) { return $this; } $this->addedBundles[$bundle->name] = TRUE; // If an item is already assigned to a region, we'll respect that. // Otherwise, we'll use defaults. $pickRegion = function ($snippet) { if (isset($snippet['settings'])) { return $this->getSettingRegion($snippet['region'] ?? NULL)->_name; } else { return $snippet['region'] ?? self::DEFAULT_REGION; } }; $byRegion = []; foreach ($bundle->getAll() as $snippet) { $snippet['region'] = $pickRegion($snippet); $byRegion[$snippet['region']][$snippet['name']] = $snippet; } foreach ($byRegion as $regionName => $snippets) { CRM_Core_Region::instance($regionName)->merge($snippets); } return $this; } /** * 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 string|iterable $permNames * List of permission names to check/export. * @return CRM_Core_Resources */ public function addPermissions($permNames) { $this->getSettingRegion()->addPermissions($permNames); return $this; } /** * Add a JavaScript file to the current page using