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