3 namespace Civi\Angular\Page
;
6 * This page aggregates data from Angular modules.
8 * Example: Aggregate metadata about all modules in JSON format.
9 * civicrm/ajax/angular-modules?format=json
11 * Example: Aggregate metadata for crmUi and crmUtil modules.
12 * civicrm/ajax/angular-modules?format=json&modules=crmUi,crmUtil
14 * Example: Aggregate *.js files for all modules.
15 * civicrm/ajax/angular-modules?format=js
17 * Example: Aggregate *.css files for all modules.
18 * civicrm/ajax/angular-modules?format=css
20 class Modules
extends \CRM_Core_Page
{
23 * Generate asset content (when accessed via older, custom
24 * "civicrm/ajax/anulgar-modules" route).
28 * @throws \CRM_Core_Exception
30 public function run() {
32 * @var \Civi\Angular\Manager $angular
34 $angular = \Civi
::service('angular');
35 $moduleNames = $this->parseModuleNames(\CRM_Utils_Request
::retrieve('modules', 'String'), $angular);
37 switch (\CRM_Utils_Request
::retrieve('format', 'String')) {
41 'application/javascript',
42 json_encode($this->getMetadata($moduleNames, $angular))
48 'application/javascript',
49 $this->digestJs($angular->getResources($moduleNames, 'js', 'path'))
56 \CRM_Utils_File
::concat($angular->getResources($moduleNames, 'css', 'path'), "\n")
61 throw new \
CRM_Core_Exception("Unrecognized format");
64 \CRM_Utils_System
::civiExit();
68 * Generate asset content (when accessed via AssetBuilder).
70 * @param \Civi\Core\Event\GenericHookEvent $event
71 * @see CRM_Utils_hook::buildAsset()
72 * @see \Civi\Core\AssetBuilder
74 public static function buildAngularModules($event) {
75 $page = new Modules();
76 $angular = \Civi
::service('angular');
78 switch ($event->asset
) {
79 case 'angular-modules.json':
80 $moduleNames = $page->parseModuleNames($event->params
['modules'] ??
NULL, $angular);
81 $event->mimeType
= 'application/json';
82 $event->content
= json_encode($page->getMetadata($moduleNames, $angular));
85 case 'angular-modules.js':
86 $moduleNames = $page->parseModuleNames($event->params
['modules'] ??
NULL, $angular);
87 $event->mimeType
= 'application/javascript';
89 // FIXME: The `resetLocationProviderHashPrefix.js` has to stay in sync with `\Civi\Angular\AngularLoader::load()`.
90 [\Civi
::resources()->getPath('civicrm', 'ang/resetLocationProviderHashPrefix.js')],
91 $angular->getResources($moduleNames, 'js', 'path')
93 $event->content
= $page->digestJs($files);
96 case 'angular-modules.css':
97 $moduleNames = $page->parseModuleNames($event->params
['modules'] ??
NULL, $angular);
98 $event->mimeType
= 'text/css';
99 $event->content
= \CRM_Utils_File
::concat($angular->getResources($moduleNames, 'css', 'path'), "\n");
107 * @param array $files
111 public function digestJs($files) {
113 foreach ($files as $file) {
114 $scripts[] = \CRM_Utils_JS
::stripComments(file_get_contents($file));
116 $scripts = \CRM_Utils_JS
::dedupeClosures(
118 ['angular', '$', '_'],
119 ['angular', 'CRM.$', 'CRM._']
121 return implode("\n", $scripts);
125 * @param string $modulesExpr
126 * Comma-separated list of module names.
127 * @param \Civi\Angular\Manager $angular
129 * Any well-formed module names. All if moduleExpr is blank.
131 public function parseModuleNames($modulesExpr, $angular) {
133 $moduleNames = preg_grep(
134 '/^[a-zA-Z0-9\-_\.]+$/',
135 explode(',', $modulesExpr)
140 $moduleNames = array_keys($angular->getModules());
146 * @param array $moduleNames
147 * List of module names.
148 * @param \Civi\Angular\Manager $angular
151 public function getMetadata($moduleNames, $angular) {
152 $modules = $angular->getModules();
154 foreach ($moduleNames as $moduleName) {
155 if (isset($modules[$moduleName])) {
156 $result[$moduleName] = [];
157 $result[$moduleName]['domain'] = $modules[$moduleName]['ext'];
158 $result[$moduleName]['js'] = $angular->getResources($moduleName, 'js', 'rawUrl');
159 $result[$moduleName]['css'] = $angular->getResources($moduleName, 'css', 'rawUrl');
160 $result[$moduleName]['partials'] = $angular->getPartials($moduleName);
161 $result[$moduleName]['strings'] = $angular->getTranslatedStrings($moduleName);
170 * @param string $type
172 * @param string $data
175 public function send($type, $data) {
176 // Encourage browsers to cache for a long time - 1 year
177 $ttl = 60 * 60 * 24 * 364;
178 \CRM_Utils_System
::setHttpHeader('Expires', gmdate('D, d M Y H:i:s \G\M\T', time() +
$ttl));
179 \CRM_Utils_System
::setHttpHeader("Content-Type", $type);
180 \CRM_Utils_System
::setHttpHeader("Cache-Control", "max-age=$ttl, public");