Commit | Line | Data |
---|---|---|
16072ce1 TO |
1 | <?php |
2 | namespace Civi\Angular; | |
3 | ||
4 | /** | |
5 | * Manage Angular resources. | |
6 | * | |
7 | * @package Civi\Angular | |
8 | */ | |
9 | class Manager { | |
10 | ||
11 | /** | |
12 | * @var \CRM_Core_Resources | |
13 | */ | |
14 | protected $res = NULL; | |
15 | ||
16 | /** | |
17 | * @var array|NULL | |
18 | * Each item has some combination of these keys: | |
19 | * - ext: string | |
8671b4f2 | 20 | * The Civi extension which defines the Angular module. |
16072ce1 | 21 | * - js: array(string $relativeFilePath) |
8671b4f2 | 22 | * List of JS files (relative to the extension). |
16072ce1 | 23 | * - css: array(string $relativeFilePath) |
8671b4f2 | 24 | * List of CSS files (relative to the extension). |
16072ce1 | 25 | * - partials: array(string $relativeFilePath) |
8671b4f2 TO |
26 | * A list of partial-HTML folders (relative to the extension). |
27 | * This will be mapped to "~/moduleName" by crmResource. | |
1da632e0 TO |
28 | * - settings: array(string $key => mixed $value) |
29 | * List of settings to preload. | |
16072ce1 TO |
30 | */ |
31 | protected $modules = NULL; | |
32 | ||
33 | /** | |
34 | * @param \CRM_Core_Resources $res | |
35 | * The resource manager. | |
36 | */ | |
37 | public function __construct($res) { | |
38 | $this->res = $res; | |
39 | } | |
40 | ||
41 | /** | |
fe482240 | 42 | * Get a list of AngularJS modules which should be autoloaded. |
16072ce1 TO |
43 | * |
44 | * @return array | |
8671b4f2 TO |
45 | * Each item has some combination of these keys: |
46 | * - ext: string | |
47 | * The Civi extension which defines the Angular module. | |
48 | * - js: array(string $relativeFilePath) | |
49 | * List of JS files (relative to the extension). | |
50 | * - css: array(string $relativeFilePath) | |
51 | * List of CSS files (relative to the extension). | |
52 | * - partials: array(string $relativeFilePath) | |
53 | * A list of partial-HTML folders (relative to the extension). | |
54 | * This will be mapped to "~/moduleName" by crmResource. | |
1da632e0 TO |
55 | * - settings: array(string $key => mixed $value) |
56 | * List of settings to preload. | |
16072ce1 TO |
57 | */ |
58 | public function getModules() { | |
59 | if ($this->modules === NULL) { | |
1da632e0 | 60 | $config = \CRM_Core_Config::singleton(); |
8456e727 | 61 | global $civicrm_root; |
16072ce1 | 62 | |
8456e727 TO |
63 | // Note: It would be nice to just glob("$civicrm_root/ang/*.ang.php"), but at time |
64 | // of writing CiviMail and CiviCase have special conditionals. | |
16072ce1 | 65 | |
8456e727 TO |
66 | $angularModules = array(); |
67 | $angularModules['angularFileUpload'] = include "$civicrm_root/ang/angularFileUpload.ang.php"; | |
68 | $angularModules['crmApp'] = include "$civicrm_root/ang/crmApp.ang.php"; | |
69 | $angularModules['crmAttachment'] = include "$civicrm_root/ang/crmAttachment.ang.php"; | |
70 | $angularModules['crmAutosave'] = include "$civicrm_root/ang/crmAutosave.ang.php"; | |
71 | $angularModules['crmCxn'] = include "$civicrm_root/ang/crmCxn.ang.php"; | |
72 | // $angularModules['crmExample'] = include "$civicrm_root/ang/crmExample.ang.php"; | |
73 | $angularModules['crmResource'] = include "$civicrm_root/ang/crmResource.ang.php"; | |
74 | $angularModules['crmUi'] = include "$civicrm_root/ang/crmUi.ang.php"; | |
75 | $angularModules['crmUtil'] = include "$civicrm_root/ang/crmUtil.ang.php"; | |
76 | $angularModules['dialogService'] = include "$civicrm_root/ang/dialogService.ang.php"; | |
77 | $angularModules['ngRoute'] = include "$civicrm_root/ang/ngRoute.ang.php"; | |
78 | $angularModules['ngSanitize'] = include "$civicrm_root/ang/ngSanitize.ang.php"; | |
79 | $angularModules['ui.utils'] = include "$civicrm_root/ang/ui.utils.ang.php"; | |
80 | $angularModules['ui.sortable'] = include "$civicrm_root/ang/ui.sortable.ang.php"; | |
81 | $angularModules['unsavedChanges'] = include "$civicrm_root/ang/unsavedChanges.ang.php"; | |
82 | $angularModules['statuspage'] = include "$civicrm_root/ang/crmStatusPage.ang.php"; | |
c0f7f681 | 83 | |
16072ce1 TO |
84 | foreach (\CRM_Core_Component::getEnabledComponents() as $component) { |
85 | $angularModules = array_merge($angularModules, $component->getAngularModules()); | |
86 | } | |
87 | \CRM_Utils_Hook::angularModules($angularModules); | |
88 | $this->modules = $this->resolvePatterns($angularModules); | |
89 | } | |
90 | ||
91 | return $this->modules; | |
92 | } | |
93 | ||
94 | /** | |
95 | * Get the descriptor for an Angular module. | |
96 | * | |
97 | * @param string $name | |
98 | * Module name. | |
99 | * @return array | |
100 | * Details about the module: | |
101 | * - ext: string, the name of the Civi extension which defines the module | |
102 | * - js: array(string $relativeFilePath). | |
103 | * - css: array(string $relativeFilePath). | |
104 | * - partials: array(string $relativeFilePath). | |
105 | * @throws \Exception | |
106 | */ | |
107 | public function getModule($name) { | |
108 | $modules = $this->getModules(); | |
109 | if (!isset($modules[$name])) { | |
110 | throw new \Exception("Unrecognized Angular module"); | |
111 | } | |
112 | return $modules[$name]; | |
113 | } | |
114 | ||
115 | /** | |
116 | * Convert any globs in an Angular module to file names. | |
117 | * | |
118 | * @param array $modules | |
119 | * List of Angular modules. | |
120 | * @return array | |
121 | * Updated list of Angular modules | |
122 | */ | |
123 | protected function resolvePatterns($modules) { | |
124 | $newModules = array(); | |
125 | ||
126 | foreach ($modules as $moduleKey => $module) { | |
127 | foreach (array('js', 'css', 'partials') as $fileset) { | |
128 | if (!isset($module[$fileset])) { | |
129 | continue; | |
130 | } | |
131 | $module[$fileset] = $this->res->glob($module['ext'], $module[$fileset]); | |
132 | } | |
133 | $newModules[$moduleKey] = $module; | |
134 | } | |
135 | ||
136 | return $newModules; | |
137 | } | |
138 | ||
139 | /** | |
140 | * Get the partial HTML documents for a module. | |
141 | * | |
142 | * @param string $name | |
143 | * Angular module name. | |
144 | * @return array | |
145 | * Array(string $extFilePath => string $html) | |
a2dc0f82 TO |
146 | * @throws \Exception |
147 | * Invalid partials configuration. | |
16072ce1 TO |
148 | */ |
149 | public function getPartials($name) { | |
150 | $module = $this->getModule($name); | |
151 | $result = array(); | |
152 | if (isset($module['partials'])) { | |
a2dc0f82 TO |
153 | foreach ($module['partials'] as $partialDir) { |
154 | $partialDir = $this->res->getPath($module['ext']) . '/' . $partialDir; | |
155 | $files = \CRM_Utils_File::findFiles($partialDir, '*.html', TRUE); | |
156 | foreach ($files as $file) { | |
157 | $filename = '~/' . $name . '/' . $file; | |
158 | $result[$filename] = file_get_contents($partialDir . '/' . $file); | |
159 | } | |
16072ce1 TO |
160 | } |
161 | } | |
162 | return $result; | |
163 | } | |
164 | ||
16072ce1 TO |
165 | /** |
166 | * Get list of translated strings for a module. | |
167 | * | |
168 | * @param string $name | |
169 | * Angular module name. | |
170 | * @return array | |
171 | * Translated strings: array(string $orig => string $translated). | |
172 | */ | |
173 | public function getTranslatedStrings($name) { | |
e3d90d6c | 174 | $module = $this->getModule($name); |
16072ce1 TO |
175 | $result = array(); |
176 | $strings = $this->getStrings($name); | |
177 | foreach ($strings as $string) { | |
178 | // TODO: should we pass translation domain based on $module[ext] or $module[tsDomain]? | |
179 | // It doesn't look like client side really supports the domain right now... | |
e3d90d6c TO |
180 | $translated = ts($string, array( |
181 | 'domain' => array($module['ext'], NULL), | |
182 | )); | |
16072ce1 TO |
183 | if ($translated != $string) { |
184 | $result[$string] = $translated; | |
185 | } | |
186 | } | |
187 | return $result; | |
188 | } | |
189 | ||
190 | /** | |
191 | * Get list of translatable strings for a module. | |
192 | * | |
193 | * @param string $name | |
194 | * Angular module name. | |
195 | * @return array | |
196 | * Translatable strings. | |
197 | */ | |
198 | public function getStrings($name) { | |
199 | $module = $this->getModule($name); | |
200 | $result = array(); | |
201 | if (isset($module['js'])) { | |
202 | foreach ($module['js'] as $file) { | |
203 | $strings = $this->res->getStrings()->get( | |
204 | $module['ext'], | |
205 | $this->res->getPath($module['ext'], $file), | |
206 | 'text/javascript' | |
207 | ); | |
208 | $result = array_unique(array_merge($result, $strings)); | |
209 | } | |
210 | } | |
211 | if (isset($module['partials'])) { | |
a2dc0f82 TO |
212 | foreach ($module['partials'] as $partialDir) { |
213 | $partialDir = $this->res->getPath($module['ext']) . '/' . $partialDir; | |
214 | $files = \CRM_Utils_File::findFiles($partialDir, '*.html'); | |
215 | foreach ($files as $file) { | |
216 | $strings = $this->res->getStrings()->get( | |
217 | $module['ext'], | |
218 | $file, | |
219 | 'text/html' | |
220 | ); | |
221 | $result = array_unique(array_merge($result, $strings)); | |
222 | } | |
16072ce1 TO |
223 | } |
224 | } | |
225 | return $result; | |
226 | } | |
227 | ||
228 | /** | |
27a90ef6 TO |
229 | * Get resources for one or more modules. |
230 | * | |
231 | * @param string|array $moduleNames | |
232 | * List of module names. | |
233 | * @param string $resType | |
1da632e0 | 234 | * Type of resource ('js', 'css', 'settings'). |
27a90ef6 | 235 | * @param string $refType |
1da632e0 | 236 | * Type of reference to the resource ('cacheUrl', 'rawUrl', 'path', 'settings'). |
16072ce1 | 237 | * @return array |
27a90ef6 TO |
238 | * List of URLs or paths. |
239 | * @throws \CRM_Core_Exception | |
16072ce1 | 240 | */ |
27a90ef6 | 241 | public function getResources($moduleNames, $resType, $refType) { |
16072ce1 | 242 | $result = array(); |
27a90ef6 TO |
243 | $moduleNames = (array) $moduleNames; |
244 | foreach ($moduleNames as $moduleName) { | |
245 | $module = $this->getModule($moduleName); | |
246 | if (isset($module[$resType])) { | |
247 | foreach ($module[$resType] as $file) { | |
248 | switch ($refType) { | |
249 | case 'path': | |
250 | $result[] = $this->res->getPath($module['ext'], $file); | |
251 | break; | |
16072ce1 | 252 | |
27a90ef6 TO |
253 | case 'rawUrl': |
254 | $result[] = $this->res->getUrl($module['ext'], $file); | |
255 | break; | |
256 | ||
257 | case 'cacheUrl': | |
258 | $result[] = $this->res->getUrl($module['ext'], $file, TRUE); | |
259 | break; | |
260 | ||
1da632e0 TO |
261 | case 'settings': |
262 | if (!empty($module[$resType])) { | |
263 | $result[$moduleName] = $module[$resType]; | |
264 | } | |
265 | break; | |
266 | ||
27a90ef6 TO |
267 | default: |
268 | throw new \CRM_Core_Exception("Unrecognized resource format"); | |
269 | } | |
270 | } | |
16072ce1 TO |
271 | } |
272 | } | |
273 | return $result; | |
274 | } | |
8671b4f2 | 275 | |
16072ce1 | 276 | } |