CRM_Core_Resources - Move addCoreResources to 'coreResources' bundle
[civicrm-core.git] / CRM / Core / Resources / Common.php
CommitLineData
b2d8361e
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12/**
13 * Define some common, global lists of resources.
14 */
15class CRM_Core_Resources_Common {
16
17 const REGION = 'html-header';
18
19 /**
20 * The 'bundle.coreStyles' service is a collection of resources used on some
21 * non-Civi pages (wherein Civi may be mixed-in).
22 *
23 * @param string $name
24 * i.e. 'coreStyles'
25 * @return \CRM_Core_Resources_Bundle
26 */
27 public static function createStyleBundle($name) {
28 $bundle = new CRM_Core_Resources_Bundle($name);
5526ab4d
TO
29
30 // Load custom or core css
31 $config = CRM_Core_Config::singleton();
32 if (!empty($config->customCSSURL)) {
33 $customCSSURL = Civi::resources()->addCacheCode($config->customCSSURL);
34 $bundle->addStyleUrl($customCSSURL, 99);
35 }
36 if (!Civi::settings()->get('disable_core_css')) {
37 $bundle->addStyleFile('civicrm', 'css/civicrm.css', -99);
38 }
39 // crm-i.css added ahead of other styles so it can be overridden by FA.
40 $bundle->addStyleFile('civicrm', 'css/crm-i.css', -101);
41
b2d8361e
TO
42 CRM_Utils_Hook::alterBundle($bundle);
43 self::useRegion($bundle, self::REGION);
44 return $bundle;
45 }
46
47 /**
48 * The 'bundle.coreResources' service is a collection of resources
49 * shared by Civi pages (ie pages where Civi controls rendering).
50 *
51 * @param string $name
52 * i.e. 'coreResources'
53 * @return \CRM_Core_Resources_Bundle
54 */
55 public static function createFullBundle($name) {
56 $bundle = new CRM_Core_Resources_Bundle($name);
8d469336
TO
57 $config = CRM_Core_Config::singleton();
58
59 // Add resources from coreResourceList
60 $jsWeight = -9999;
61 foreach (self::coreResourceList(self::REGION) as $item) {
62 if (is_array($item)) {
63 $bundle->addSetting($item);
64 }
65 elseif (strpos($item, '.css')) {
66 Civi::resources()->isFullyFormedUrl($item) ? $bundle->addStyleUrl($item, -100) : $bundle->addStyleFile('civicrm', $item, -100);
67 }
68 elseif (Civi::resources()->isFullyFormedUrl($item)) {
69 $bundle->addScriptUrl($item, $jsWeight++);
70 }
71 else {
72 // Don't bother looking for ts() calls in packages, there aren't any
73 $translate = (substr($item, 0, 3) == 'js/');
74 $bundle->addScriptFile('civicrm', $item, [
75 'weight' => $jsWeight++,
76 'translate' => $translate,
77 ]);
78 }
79 }
80 // Add global settings
81 $settings = [
82 'config' => [
83 'isFrontend' => $config->userFrameworkFrontend,
84 ],
85 ];
86 // Disable profile creation if user lacks permission
87 if (!CRM_Core_Permission::check('edit all contacts') && !CRM_Core_Permission::check('add contacts')) {
88 $settings['config']['entityRef']['contactCreate'] = FALSE;
89 }
90 $bundle->addSetting($settings);
91
92 // Give control of jQuery and _ back to the CMS - this loads last
93 $bundle->addScriptFile('civicrm', 'js/noconflict.js', [
94 'weight' => 9999,
95 'translate' => FALSE,
96 ]);
97
b2d8361e
TO
98 CRM_Utils_Hook::alterBundle($bundle);
99 self::useRegion($bundle, self::REGION);
100 return $bundle;
101 }
102
8d469336
TO
103 /**
104 * List of core resources we add to every CiviCRM page.
105 *
106 * Note: non-compressed versions of .min files will be used in debug mode
107 *
108 * @param string $region
109 * @return array
110 */
111 protected static function coreResourceList($region) {
112 $config = CRM_Core_Config::singleton();
113
114 // Scripts needed by everyone, everywhere
115 // FIXME: This is too long; list needs finer-grained segmentation
116 $items = [
117 "bower_components/jquery/dist/jquery.min.js",
118 "bower_components/jquery-ui/jquery-ui.min.js",
119 "bower_components/jquery-ui/themes/smoothness/jquery-ui.min.css",
120 "bower_components/lodash-compat/lodash.min.js",
121 "packages/jquery/plugins/jquery.mousewheel.min.js",
122 "bower_components/select2/select2.min.js",
123 "bower_components/select2/select2.min.css",
124 "bower_components/font-awesome/css/font-awesome.min.css",
125 "packages/jquery/plugins/jquery.form.min.js",
126 "packages/jquery/plugins/jquery.timeentry.min.js",
127 "packages/jquery/plugins/jquery.blockUI.min.js",
128 "bower_components/datatables/media/js/jquery.dataTables.min.js",
129 "bower_components/datatables/media/css/jquery.dataTables.min.css",
130 "bower_components/jquery-validation/dist/jquery.validate.min.js",
131 "bower_components/jquery-validation/dist/additional-methods.min.js",
132 "packages/jquery/plugins/jquery.ui.datepicker.validation.min.js",
133 "js/Common.js",
134 "js/crm.datepicker.js",
135 "js/crm.ajax.js",
136 "js/wysiwyg/crm.wysiwyg.js",
137 ];
138
139 // Dynamic localization script
140 $items[] = Civi::resources()->addCacheCode(
141 CRM_Utils_System::url('civicrm/ajax/l10n-js/' . CRM_Core_I18n::getLocale(),
142 ['cid' => CRM_Core_Session::getLoggedInContactID()], FALSE, NULL, FALSE)
143 );
144
145 // add wysiwyg editor
146 $editor = Civi::settings()->get('editor_id');
147 if ($editor == "CKEditor") {
148 CRM_Admin_Form_CKEditorConfig::setConfigDefault();
149 $items[] = [
150 'config' => [
151 'wysisygScriptLocation' => Civi::paths()->getUrl("[civicrm.root]/js/wysiwyg/crm.ckeditor.js"),
152 'CKEditorCustomConfig' => CRM_Admin_Form_CKEditorConfig::getConfigUrl(),
153 ],
154 ];
155 }
156
157 // These scripts are only needed by back-office users
158 if (CRM_Core_Permission::check('access CiviCRM')) {
159 $items[] = "packages/jquery/plugins/jquery.tableHeader.js";
160 $items[] = "packages/jquery/plugins/jquery.notify.min.js";
161 }
162
163 $contactID = CRM_Core_Session::getLoggedInContactID();
164
165 // Menubar
166 $position = 'none';
167 if (
168 $contactID && !$config->userFrameworkFrontend
169 && CRM_Core_Permission::check('access CiviCRM')
170 && !@constant('CIVICRM_DISABLE_DEFAULT_MENU')
171 && !CRM_Core_Config::isUpgradeMode()
172 ) {
173 $position = Civi::settings()->get('menubar_position') ?: 'over-cms-menu';
174 }
175 if ($position !== 'none') {
176 $items[] = 'bower_components/smartmenus/dist/jquery.smartmenus.min.js';
177 $items[] = 'bower_components/smartmenus/dist/addons/keyboard/jquery.smartmenus.keyboard.min.js';
178 $items[] = 'js/crm.menubar.js';
179 // @see CRM_Core_Resources::renderMenubarStylesheet
180 $items[] = Civi::service('asset_builder')->getUrl('crm-menubar.css', [
181 'menubarColor' => Civi::settings()->get('menubar_color'),
182 'height' => 40,
183 'breakpoint' => 768,
184 ]);
185 // Variables for crm.menubar.js
186 $items[] = [
187 'menubar' => [
188 'position' => $position,
189 'qfKey' => CRM_Core_Key::get('CRM_Contact_Controller_Search', TRUE),
190 'cacheCode' => CRM_Core_BAO_Navigation::getCacheKey($contactID),
191 ],
192 ];
193 }
194
195 // JS for multilingual installations
196 if (!empty($config->languageLimit) && count($config->languageLimit) > 1 && CRM_Core_Permission::check('translate CiviCRM')) {
197 $items[] = "js/crm.multilingual.js";
198 }
199
200 // Enable administrators to edit option lists in a dialog
201 if (CRM_Core_Permission::check('administer CiviCRM') && Civi::settings()->get('ajaxPopupsEnabled')) {
202 $items[] = "js/crm.optionEdit.js";
203 }
204
205 $tsLocale = CRM_Core_I18n::getLocale();
206 // Add localized jQuery UI files
207 if ($tsLocale && $tsLocale != 'en_US') {
208 // Search for i18n file in order of specificity (try fr-CA, then fr)
209 list($lang) = explode('_', $tsLocale);
210 $path = "bower_components/jquery-ui/ui/i18n";
211 foreach ([str_replace('_', '-', $tsLocale), $lang] as $language) {
212 $localizationFile = "$path/datepicker-{$language}.js";
213 if (Civi::resources()->getPath('civicrm', $localizationFile)) {
214 $items[] = $localizationFile;
215 break;
216 }
217 }
218 }
219
220 // Allow hooks to modify this list
221 CRM_Utils_Hook::coreResourceList($items, $region);
222
223 // Oof, existing listeners would expect $items to typically begin with 'bower_components/' or 'packages/'
224 // (using an implicit base of `[civicrm.root]`). We preserve the hook contract and cleanup $items post-hook.
225 $map = [
226 'bower_components' => rtrim(Civi::paths()->getUrl('[civicrm.bower]/.', 'absolute'), '/'),
227 'packages' => rtrim(Civi::paths()->getUrl('[civicrm.packages]/.', 'absolute'), '/'),
228 ];
229 $filter = function($m) use ($map) {
230 return $map[$m[1]] . $m[2];
231 };
232 $items = array_map(function($item) use ($filter) {
233 return is_array($item) ? $item : preg_replace_callback(';^(bower_components|packages)(/.*);', $filter, $item);
234 }, $items);
235
236 return $items;
237 }
238
b2d8361e
TO
239 /**
240 * Ensure that all elements of the bundle are in the same region.
241 *
242 * @param CRM_Core_Resources_Bundle $bundle
243 * @param string $region
244 * @return CRM_Core_Resources_Bundle
245 */
246 protected static function useRegion($bundle, $region) {
247 $bundle->filter(function ($s) use ($region) {
248 if ($s['type'] !== 'settings' && !isset($s['region'])) {
249 $s['region'] = $region;
250 }
251 return $s;
252 });
253 return $bundle;
254 }
255
256}