Merge branch '4.6' into master
[civicrm-core.git] / Civi / Angular / Page / Modules.php
CommitLineData
e5afbdad
TO
1<?php
2
3namespace Civi\Angular\Page;
4
5/**
27a90ef6
TO
6 * This page aggregates data from Angular modules.
7 *
8 * Example: Aggregate metadata about all modules in JSON format.
9 * civicrm/ajax/angular-modules?format=json
10 *
11 * Example: Aggregate metadata for crmUi and crmUtil modules.
12 * civicrm/ajax/angular-modules?format=json&modules=crmUi,crmUtil
13 *
14 * Example: Aggregate *.js files for all modules.
15 * civicrm/ajax/angular-modules?format=js
16 *
17 * Example: Aggregate *.css files for all modules.
18 * civicrm/ajax/angular-modules?format=css
e5afbdad
TO
19 */
20class Modules extends \CRM_Core_Page {
21
22 /**
27a90ef6 23 * See class description.
e5afbdad
TO
24 */
25 public function run() {
e5afbdad
TO
26 /**
27 * @var \Civi\Angular\Manager $angular
28 */
048222df 29 $angular = \Civi::service('angular');
27a90ef6
TO
30 $moduleNames = $this->parseModuleNames(\CRM_Utils_Request::retrieve('modules', 'String'), $angular);
31
32 switch (\CRM_Utils_Request::retrieve('format', 'String')) {
33 case 'json':
34 case '':
35 $this->send(
36 'application/javascript',
37 json_encode($this->getMetadata($moduleNames, $angular))
38 );
39 break;
40
41 case 'js':
42 $this->send(
43 'application/javascript',
ad295ca9 44 $this->digestJs($angular->getResources($moduleNames, 'js', 'path'))
27a90ef6
TO
45 );
46 break;
47
48 case 'css':
49 $this->send(
50 'text/css',
51 \CRM_Utils_File::concat($angular->getResources($moduleNames, 'css', 'path'), "\n")
52 );
53 break;
54
55 default:
56 \CRM_Core_Error::fatal("Unrecognized format");
57 }
58
59 \CRM_Utils_System::civiExit();
60 }
e5afbdad 61
ad295ca9
TO
62 /**
63 * @param array $files
64 * File paths.
65 * @return string
66 */
67 public function digestJs($files) {
68 $scripts = array();
69 foreach ($files as $file) {
70 $scripts[] = file_get_contents($file);
71 }
72 $scripts = \CRM_Utils_JS::dedupeClosures(
73 $scripts,
74 array('angular', '$', '_'),
75 array('angular', 'CRM.$', 'CRM._')
76 );
b047e061
TO
77 // This impl of stripComments currently adds 10-20ms and cuts ~7%
78 return \CRM_Utils_JS::stripComments(implode("\n", $scripts));
ad295ca9
TO
79 }
80
27a90ef6
TO
81 /**
82 * @param string $modulesExpr
83 * Comma-separated list of module names.
84 * @param \Civi\Angular\Manager $angular
85 * @return array
86 * Any well-formed module names. All if moduleExpr is blank.
87 */
88 public function parseModuleNames($modulesExpr, $angular) {
e5afbdad
TO
89 if ($modulesExpr) {
90 $moduleNames = preg_grep(
91 '/^[a-zA-Z0-9\-_\.]+$/',
92 explode(',', $modulesExpr)
93 );
27a90ef6 94 return $moduleNames;
e5afbdad
TO
95 }
96 else {
27a90ef6
TO
97 $moduleNames = array_keys($angular->getModules());
98 return $moduleNames;
e5afbdad 99 }
27a90ef6 100 }
e5afbdad 101
27a90ef6
TO
102 /**
103 * @param array $moduleNames
104 * List of module names.
105 * @param \Civi\Angular\Manager $angular
106 * @return array
107 */
108 public function getMetadata($moduleNames, $angular) {
109 $modules = $angular->getModules();
e5afbdad
TO
110 $result = array();
111 foreach ($moduleNames as $moduleName) {
112 if (isset($modules[$moduleName])) {
113 $result[$moduleName] = array();
e3d90d6c 114 $result[$moduleName]['domain'] = $modules[$moduleName]['ext'];
27a90ef6
TO
115 $result[$moduleName]['js'] = $angular->getResources($moduleName, 'js', 'rawUrl');
116 $result[$moduleName]['css'] = $angular->getResources($moduleName, 'css', 'rawUrl');
e5afbdad
TO
117 $result[$moduleName]['partials'] = $angular->getPartials($moduleName);
118 $result[$moduleName]['strings'] = $angular->getTranslatedStrings($moduleName);
119 }
120 }
27a90ef6
TO
121 return $result;
122 }
e5afbdad 123
27a90ef6
TO
124 /**
125 * Send a response.
126 *
127 * @param string $type
128 * Content type.
129 * @param string $data
130 * Content.
131 */
132 public function send($type, $data) {
133 // Encourage browsers to cache for a long time - 1 year
134 $ttl = 60 * 60 * 24 * 364;
956d2f84
CW
135 \CRM_Utils_System::setHttpHeader('Expires', gmdate('D, d M Y H:i:s \G\M\T', time() + $ttl));
136 \CRM_Utils_System::setHttpHeader("Content-Type", $type);
137 \CRM_Utils_System::setHttpHeader("Cache-Control", "max-age=$ttl, public");
27a90ef6 138 echo $data;
e5afbdad
TO
139 }
140
141}