* This adds CiviCRM's standard css and js to the specified region of the document.
* It will only run once.
*
- * TODO: Separate the functional code (like addStyle/addScript) from the policy code
- * (like addCoreResources/addCoreStyles).
- *
* @param string $region
* @return CRM_Core_Resources
*/
// it appears that all callers use 'html-header' (either implicitly or explicitly).
throw new \CRM_Core_Exception("Error: addCoreResources only supports html-header");
}
- if (!isset($this->addedCoreResources[$region]) && !self::isAjaxMode()) {
- $this->addedCoreResources[$region] = TRUE;
- $config = CRM_Core_Config::singleton();
-
- // Add resources from coreResourceList
- $jsWeight = -9999;
- foreach ($this->coreResourceList($region) as $item) {
- if (is_array($item)) {
- $this->addSetting($item);
- }
- elseif (strpos($item, '.css')) {
- $this->isFullyFormedUrl($item) ? $this->addStyleUrl($item, -100, $region) : $this->addStyleFile('civicrm', $item, -100, $region);
- }
- elseif ($this->isFullyFormedUrl($item)) {
- $this->addScriptUrl($item, $jsWeight++, $region);
- }
- else {
- // Don't bother looking for ts() calls in packages, there aren't any
- $translate = (substr($item, 0, 3) == 'js/');
- $this->addScriptFile('civicrm', $item, $jsWeight++, $region, $translate);
- }
- }
- // Add global settings
- $settings = [
- 'config' => [
- 'isFrontend' => $config->userFrameworkFrontend,
- ],
- ];
- // Disable profile creation if user lacks permission
- if (!CRM_Core_Permission::check('edit all contacts') && !CRM_Core_Permission::check('add contacts')) {
- $settings['config']['entityRef']['contactCreate'] = FALSE;
- }
- $this->addSetting($settings);
-
- // Give control of jQuery and _ back to the CMS - this loads last
- $this->addScriptFile('civicrm', 'js/noconflict.js', 9999, $region, FALSE);
-
+ if (!self::isAjaxMode()) {
+ $this->addBundle('coreResources');
$this->addCoreStyles($region);
}
return $this;
CRM_Utils_System::civiExit();
}
- /**
- * List of core resources we add to every CiviCRM page.
- *
- * Note: non-compressed versions of .min files will be used in debug mode
- *
- * @param string $region
- * @return array
- */
- public function coreResourceList($region) {
- $config = CRM_Core_Config::singleton();
-
- // Scripts needed by everyone, everywhere
- // FIXME: This is too long; list needs finer-grained segmentation
- $items = [
- "bower_components/jquery/dist/jquery.min.js",
- "bower_components/jquery-ui/jquery-ui.min.js",
- "bower_components/jquery-ui/themes/smoothness/jquery-ui.min.css",
- "bower_components/lodash-compat/lodash.min.js",
- "packages/jquery/plugins/jquery.mousewheel.min.js",
- "bower_components/select2/select2.min.js",
- "bower_components/select2/select2.min.css",
- "bower_components/font-awesome/css/font-awesome.min.css",
- "packages/jquery/plugins/jquery.form.min.js",
- "packages/jquery/plugins/jquery.timeentry.min.js",
- "packages/jquery/plugins/jquery.blockUI.min.js",
- "bower_components/datatables/media/js/jquery.dataTables.min.js",
- "bower_components/datatables/media/css/jquery.dataTables.min.css",
- "bower_components/jquery-validation/dist/jquery.validate.min.js",
- "bower_components/jquery-validation/dist/additional-methods.min.js",
- "packages/jquery/plugins/jquery.ui.datepicker.validation.min.js",
- "js/Common.js",
- "js/crm.datepicker.js",
- "js/crm.ajax.js",
- "js/wysiwyg/crm.wysiwyg.js",
- ];
-
- // Dynamic localization script
- $items[] = $this->addCacheCode(
- CRM_Utils_System::url('civicrm/ajax/l10n-js/' . CRM_Core_I18n::getLocale(),
- ['cid' => CRM_Core_Session::getLoggedInContactID()], FALSE, NULL, FALSE)
- );
-
- // add wysiwyg editor
- $editor = Civi::settings()->get('editor_id');
- if ($editor == "CKEditor") {
- CRM_Admin_Form_CKEditorConfig::setConfigDefault();
- $items[] = [
- 'config' => [
- 'wysisygScriptLocation' => Civi::paths()->getUrl("[civicrm.root]/js/wysiwyg/crm.ckeditor.js"),
- 'CKEditorCustomConfig' => CRM_Admin_Form_CKEditorConfig::getConfigUrl(),
- ],
- ];
- }
-
- // These scripts are only needed by back-office users
- if (CRM_Core_Permission::check('access CiviCRM')) {
- $items[] = "packages/jquery/plugins/jquery.tableHeader.js";
- $items[] = "packages/jquery/plugins/jquery.notify.min.js";
- }
-
- $contactID = CRM_Core_Session::getLoggedInContactID();
-
- // Menubar
- $position = 'none';
- if (
- $contactID && !$config->userFrameworkFrontend
- && CRM_Core_Permission::check('access CiviCRM')
- && !@constant('CIVICRM_DISABLE_DEFAULT_MENU')
- && !CRM_Core_Config::isUpgradeMode()
- ) {
- $position = Civi::settings()->get('menubar_position') ?: 'over-cms-menu';
- }
- if ($position !== 'none') {
- $items[] = 'bower_components/smartmenus/dist/jquery.smartmenus.min.js';
- $items[] = 'bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.min.js';
- $items[] = 'js/crm.menubar.js';
- // @see CRM_Core_Resources::renderMenubarStylesheet
- $items[] = Civi::service('asset_builder')->getUrl('crm-menubar.css', [
- 'menubarColor' => Civi::settings()->get('menubar_color'),
- 'height' => 40,
- 'breakpoint' => 768,
- ]);
- // Variables for crm.menubar.js
- $items[] = [
- 'menubar' => [
- 'position' => $position,
- 'qfKey' => CRM_Core_Key::get('CRM_Contact_Controller_Search', TRUE),
- 'cacheCode' => CRM_Core_BAO_Navigation::getCacheKey($contactID),
- ],
- ];
- }
-
- // JS for multilingual installations
- if (!empty($config->languageLimit) && count($config->languageLimit) > 1 && CRM_Core_Permission::check('translate CiviCRM')) {
- $items[] = "js/crm.multilingual.js";
- }
-
- // Enable administrators to edit option lists in a dialog
- if (CRM_Core_Permission::check('administer CiviCRM') && $this->ajaxPopupsEnabled) {
- $items[] = "js/crm.optionEdit.js";
- }
-
- $tsLocale = CRM_Core_I18n::getLocale();
- // Add localized jQuery UI files
- if ($tsLocale && $tsLocale != 'en_US') {
- // Search for i18n file in order of specificity (try fr-CA, then fr)
- list($lang) = explode('_', $tsLocale);
- $path = "bower_components/jquery-ui/ui/i18n";
- foreach ([str_replace('_', '-', $tsLocale), $lang] as $language) {
- $localizationFile = "$path/datepicker-{$language}.js";
- if ($this->getPath('civicrm', $localizationFile)) {
- $items[] = $localizationFile;
- break;
- }
- }
- }
-
- // Allow hooks to modify this list
- CRM_Utils_Hook::coreResourceList($items, $region);
-
- // Oof, existing listeners would expect $items to typically begin with 'bower_components/' or 'packages/'
- // (using an implicit base of `[civicrm.root]`). We preserve the hook contract and cleanup $items post-hook.
- $map = [
- 'bower_components' => rtrim(Civi::paths()->getUrl('[civicrm.bower]/.', 'absolute'), '/'),
- 'packages' => rtrim(Civi::paths()->getUrl('[civicrm.packages]/.', 'absolute'), '/'),
- ];
- $filter = function($m) use ($map) {
- return $map[$m[1]] . $m[2];
- };
- $items = array_map(function($item) use ($filter) {
- return is_array($item) ? $item : preg_replace_callback(';^(bower_components|packages)(/.*);', $filter, $item);
- }, $items);
-
- return $items;
- }
-
/**
* @return bool
* is this page request an ajax snippet?
*/
public static function createFullBundle($name) {
$bundle = new CRM_Core_Resources_Bundle($name);
- // TODO
+ $config = CRM_Core_Config::singleton();
+
+ // Add resources from coreResourceList
+ $jsWeight = -9999;
+ foreach (self::coreResourceList(self::REGION) as $item) {
+ if (is_array($item)) {
+ $bundle->addSetting($item);
+ }
+ elseif (strpos($item, '.css')) {
+ Civi::resources()->isFullyFormedUrl($item) ? $bundle->addStyleUrl($item, -100) : $bundle->addStyleFile('civicrm', $item, -100);
+ }
+ elseif (Civi::resources()->isFullyFormedUrl($item)) {
+ $bundle->addScriptUrl($item, $jsWeight++);
+ }
+ else {
+ // Don't bother looking for ts() calls in packages, there aren't any
+ $translate = (substr($item, 0, 3) == 'js/');
+ $bundle->addScriptFile('civicrm', $item, [
+ 'weight' => $jsWeight++,
+ 'translate' => $translate,
+ ]);
+ }
+ }
+ // Add global settings
+ $settings = [
+ 'config' => [
+ 'isFrontend' => $config->userFrameworkFrontend,
+ ],
+ ];
+ // Disable profile creation if user lacks permission
+ if (!CRM_Core_Permission::check('edit all contacts') && !CRM_Core_Permission::check('add contacts')) {
+ $settings['config']['entityRef']['contactCreate'] = FALSE;
+ }
+ $bundle->addSetting($settings);
+
+ // Give control of jQuery and _ back to the CMS - this loads last
+ $bundle->addScriptFile('civicrm', 'js/noconflict.js', [
+ 'weight' => 9999,
+ 'translate' => FALSE,
+ ]);
+
CRM_Utils_Hook::alterBundle($bundle);
self::useRegion($bundle, self::REGION);
return $bundle;
}
+ /**
+ * List of core resources we add to every CiviCRM page.
+ *
+ * Note: non-compressed versions of .min files will be used in debug mode
+ *
+ * @param string $region
+ * @return array
+ */
+ protected static function coreResourceList($region) {
+ $config = CRM_Core_Config::singleton();
+
+ // Scripts needed by everyone, everywhere
+ // FIXME: This is too long; list needs finer-grained segmentation
+ $items = [
+ "bower_components/jquery/dist/jquery.min.js",
+ "bower_components/jquery-ui/jquery-ui.min.js",
+ "bower_components/jquery-ui/themes/smoothness/jquery-ui.min.css",
+ "bower_components/lodash-compat/lodash.min.js",
+ "packages/jquery/plugins/jquery.mousewheel.min.js",
+ "bower_components/select2/select2.min.js",
+ "bower_components/select2/select2.min.css",
+ "bower_components/font-awesome/css/font-awesome.min.css",
+ "packages/jquery/plugins/jquery.form.min.js",
+ "packages/jquery/plugins/jquery.timeentry.min.js",
+ "packages/jquery/plugins/jquery.blockUI.min.js",
+ "bower_components/datatables/media/js/jquery.dataTables.min.js",
+ "bower_components/datatables/media/css/jquery.dataTables.min.css",
+ "bower_components/jquery-validation/dist/jquery.validate.min.js",
+ "bower_components/jquery-validation/dist/additional-methods.min.js",
+ "packages/jquery/plugins/jquery.ui.datepicker.validation.min.js",
+ "js/Common.js",
+ "js/crm.datepicker.js",
+ "js/crm.ajax.js",
+ "js/wysiwyg/crm.wysiwyg.js",
+ ];
+
+ // Dynamic localization script
+ $items[] = Civi::resources()->addCacheCode(
+ CRM_Utils_System::url('civicrm/ajax/l10n-js/' . CRM_Core_I18n::getLocale(),
+ ['cid' => CRM_Core_Session::getLoggedInContactID()], FALSE, NULL, FALSE)
+ );
+
+ // add wysiwyg editor
+ $editor = Civi::settings()->get('editor_id');
+ if ($editor == "CKEditor") {
+ CRM_Admin_Form_CKEditorConfig::setConfigDefault();
+ $items[] = [
+ 'config' => [
+ 'wysisygScriptLocation' => Civi::paths()->getUrl("[civicrm.root]/js/wysiwyg/crm.ckeditor.js"),
+ 'CKEditorCustomConfig' => CRM_Admin_Form_CKEditorConfig::getConfigUrl(),
+ ],
+ ];
+ }
+
+ // These scripts are only needed by back-office users
+ if (CRM_Core_Permission::check('access CiviCRM')) {
+ $items[] = "packages/jquery/plugins/jquery.tableHeader.js";
+ $items[] = "packages/jquery/plugins/jquery.notify.min.js";
+ }
+
+ $contactID = CRM_Core_Session::getLoggedInContactID();
+
+ // Menubar
+ $position = 'none';
+ if (
+ $contactID && !$config->userFrameworkFrontend
+ && CRM_Core_Permission::check('access CiviCRM')
+ && !@constant('CIVICRM_DISABLE_DEFAULT_MENU')
+ && !CRM_Core_Config::isUpgradeMode()
+ ) {
+ $position = Civi::settings()->get('menubar_position') ?: 'over-cms-menu';
+ }
+ if ($position !== 'none') {
+ $items[] = 'bower_components/smartmenus/dist/jquery.smartmenus.min.js';
+ $items[] = 'bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.min.js';
+ $items[] = 'js/crm.menubar.js';
+ // @see CRM_Core_Resources::renderMenubarStylesheet
+ $items[] = Civi::service('asset_builder')->getUrl('crm-menubar.css', [
+ 'menubarColor' => Civi::settings()->get('menubar_color'),
+ 'height' => 40,
+ 'breakpoint' => 768,
+ ]);
+ // Variables for crm.menubar.js
+ $items[] = [
+ 'menubar' => [
+ 'position' => $position,
+ 'qfKey' => CRM_Core_Key::get('CRM_Contact_Controller_Search', TRUE),
+ 'cacheCode' => CRM_Core_BAO_Navigation::getCacheKey($contactID),
+ ],
+ ];
+ }
+
+ // JS for multilingual installations
+ if (!empty($config->languageLimit) && count($config->languageLimit) > 1 && CRM_Core_Permission::check('translate CiviCRM')) {
+ $items[] = "js/crm.multilingual.js";
+ }
+
+ // Enable administrators to edit option lists in a dialog
+ if (CRM_Core_Permission::check('administer CiviCRM') && Civi::settings()->get('ajaxPopupsEnabled')) {
+ $items[] = "js/crm.optionEdit.js";
+ }
+
+ $tsLocale = CRM_Core_I18n::getLocale();
+ // Add localized jQuery UI files
+ if ($tsLocale && $tsLocale != 'en_US') {
+ // Search for i18n file in order of specificity (try fr-CA, then fr)
+ list($lang) = explode('_', $tsLocale);
+ $path = "bower_components/jquery-ui/ui/i18n";
+ foreach ([str_replace('_', '-', $tsLocale), $lang] as $language) {
+ $localizationFile = "$path/datepicker-{$language}.js";
+ if (Civi::resources()->getPath('civicrm', $localizationFile)) {
+ $items[] = $localizationFile;
+ break;
+ }
+ }
+ }
+
+ // Allow hooks to modify this list
+ CRM_Utils_Hook::coreResourceList($items, $region);
+
+ // Oof, existing listeners would expect $items to typically begin with 'bower_components/' or 'packages/'
+ // (using an implicit base of `[civicrm.root]`). We preserve the hook contract and cleanup $items post-hook.
+ $map = [
+ 'bower_components' => rtrim(Civi::paths()->getUrl('[civicrm.bower]/.', 'absolute'), '/'),
+ 'packages' => rtrim(Civi::paths()->getUrl('[civicrm.packages]/.', 'absolute'), '/'),
+ ];
+ $filter = function($m) use ($map) {
+ return $map[$m[1]] . $m[2];
+ };
+ $items = array_map(function($item) use ($filter) {
+ return is_array($item) ? $item : preg_replace_callback(';^(bower_components|packages)(/.*);', $filter, $item);
+ }, $items);
+
+ return $items;
+ }
+
/**
* Ensure that all elements of the bundle are in the same region.
*