TApplicationConfiguration::loadModulesPhp()   B
last analyzed

Complexity

Conditions 7
Paths 8

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 16
c 2
b 0
f 0
nc 8
nop 2
dl 0
loc 22
ccs 0
cts 18
cp 0
crap 56
rs 8.8333
1
<?php
2
3
/**
4
 * TApplication class file
5
 *
6
 * @author Qiang Xue <[email protected]>
7
 * @link https://github.com/pradosoft/prado
8
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
9
 */
10
11
namespace Prado;
12
13
use Composer\Autoload\ClassLoader;
14
use Prado\Caching\TChainedCacheDependency;
15
use Prado\Caching\TFileCacheDependency;
16
use Prado\Exceptions\TConfigurationException;
17
use Prado\Prado;
18
use Prado\Xml\TXmlDocument;
19
20
/**
21
 * TApplicationConfiguration class.
22
 *
23
 * This class is used internally by TApplication to parse and represent application configuration.
24
 *
25
 * @author Qiang Xue <[email protected]>
26
 * @author Carl G. Mathisen <[email protected]>
27
 * @since 3.0
28
 */
29
class TApplicationConfiguration extends \Prado\TComponent
30
{
31
	/**
32
	 * The cache name for installed Prado composer packages
33
	 */
34
	public const COMPOSER_INSTALLED_CACHE = 'prado:composer:installedcache';
35
	/**
36
	 * Name of the Extra field to look for Prado Extension Class
37
	 */
38
	public const COMPOSER_EXTRA_CLASS = 'bootstrap';
39
	/**
40
	 * @var array list of application initial property values, indexed by property names
41
	 */
42
	private $_properties = [];
43
	/**
44
	 * @var array list of namespaces to be used
45
	 */
46
	private $_usings = [];
47
	/**
48
	 * @var array list of path aliases, indexed by alias names
49
	 */
50
	private $_aliases = [];
51
	/**
52
	 * @var array list of module configurations
53
	 */
54
	private $_modules = [];
55
	/**
56
	 * @var array list of service configurations
57
	 */
58
	private $_services = [];
59
	/**
60
	 * @var array list of parameters
61
	 */
62
	private $_parameters = [];
63
	/**
64
	 * @var array list of included configurations
65
	 */
66
	private $_includes = [];
67
	/**
68
	 * @var bool whether this configuration contains actual stuff
69
	 */
70
	private $_empty = true;
71
	/**
72
	 * @var array<string, string> name/id of the composer extension and class for extension
73
	 */
74
	private static $_composerPlugins;
75
76
	/**
77
	 * Parses the application configuration file.
78
	 * @param string $fname configuration file name
79
	 * @throws TConfigurationException if there is any parsing error
80
	 */
81
	public function loadFromFile($fname)
82
	{
83
		if (Prado::getApplication()->getConfigurationType() == TApplication::CONFIG_TYPE_PHP) {
84
			$fcontent = include $fname;
85
			$this->loadFromPhp($fcontent, dirname($fname));
86
		} else {
87
			$dom = new TXmlDocument();
88
			$dom->loadFromFile($fname);
89
			$this->loadFromXml($dom, dirname($fname));
90
		}
91
	}
92
93
	/**
94
	 * @return bool whether this configuration contains actual stuff
95
	 */
96
	public function getIsEmpty()
97
	{
98
		return $this->_empty;
99
	}
100
101
	/**
102
	 * Parses the application configuration given in terms of a PHP array.
103
	 * @param array $config the PHP array
104
	 * @param string $configPath the context path (for specifying relative paths)
105
	 */
106
	public function loadFromPhp($config, $configPath)
107
	{
108
		// application properties
109
		if (isset($config['application'])) {
110
			foreach ($config['application'] as $name => $value) {
111
				$this->_properties[$name] = $value;
112
			}
113
			$this->_empty = false;
114
		}
115
116
		if (isset($config['paths']) && is_array($config['paths'])) {
117
			$this->loadPathsPhp($config['paths'], $configPath);
118
		}
119
120
		if (isset($config['modules']) && is_array($config['modules'])) {
121
			$this->loadModulesPhp($config['modules'], $configPath);
122
		}
123
124
		if (isset($config['services']) && is_array($config['services'])) {
125
			$this->loadServicesPhp($config['services'], $configPath);
126
		}
127
128
		if (isset($config['parameters']) && is_array($config['parameters'])) {
129
			$this->loadParametersPhp($config['parameters'], $configPath);
130
		}
131
132
		if (isset($config['includes']) && is_array($config['includes'])) {
133
			$this->loadExternalXml($config['includes'], $configPath);
134
		}
135
	}
136
137
	/**
138
	 * Parses the application configuration given in terms of a TXmlElement.
139
	 * @param \Prado\Xml\TXmlElement $dom the XML element
140
	 * @param string $configPath the context path (for specifying relative paths)
141
	 */
142
	public function loadFromXml($dom, $configPath)
143
	{
144
		// application properties
145
		foreach ($dom->getAttributes() as $name => $value) {
146
			$this->_properties[$name] = $value;
147
			$this->_empty = false;
148
		}
149
150
		foreach ($dom->getElements() as $element) {
151
			switch ($element->getTagName()) {
152
				case 'paths':
153
					$this->loadPathsXml($element, $configPath);
154
					break;
155
				case 'modules':
156
					$this->loadModulesXml($element, $configPath);
157
					break;
158
				case 'services':
159
					$this->loadServicesXml($element, $configPath);
160
					break;
161
				case 'parameters':
162
					$this->loadParametersXml($element, $configPath);
163
					break;
164
				case 'include':
165
					$this->loadExternalXml($element, $configPath);
166
					break;
167
				default:
168
					//throw new TConfigurationException('appconfig_tag_invalid',$element->getTagName());
169
					break;
170
			}
171
		}
172
	}
173
174
	/**
175
	 * Loads the paths PHP array
176
	 * @param array $pathsNode the paths PHP array
177
	 * @param string $configPath the context path (for specifying relative paths)
178
	 */
179
	protected function loadPathsPhp($pathsNode, $configPath)
180
	{
181
		if (isset($pathsNode['aliases']) && is_array($pathsNode['aliases'])) {
182
			foreach ($pathsNode['aliases'] as $id => $path) {
183
				$path = str_replace('\\', '/', $path);
184
				if (preg_match('/^\\/|.:\\/|.:\\\\/', $path)) {	// if absolute path
185
					$p = realpath($path);
186
				} else {
187
					$p = realpath($configPath . DIRECTORY_SEPARATOR . $path);
188
				}
189
				if ($p === false || !is_dir($p)) {
190
					throw new TConfigurationException('appconfig_aliaspath_invalid', $id, $path);
191
				}
192
				if (isset($this->_aliases[$id])) {
193
					throw new TConfigurationException('appconfig_alias_redefined', $id);
194
				}
195
				$this->_aliases[$id] = $p;
196
			}
197
		}
198
199
		if (isset($pathsNode['using']) && is_array($pathsNode['using'])) {
200
			foreach ($pathsNode['using'] as $namespace) {
201
				$this->_usings[] = $namespace;
202
			}
203
		}
204
	}
205
206
	/**
207
	 * Loads the paths XML node.
208
	 * @param \Prado\Xml\TXmlElement $pathsNode the paths XML node
209
	 * @param string $configPath the context path (for specifying relative paths)
210
	 */
211
	protected function loadPathsXml($pathsNode, $configPath)
212
	{
213
		foreach ($pathsNode->getElements() as $element) {
214
			switch ($element->getTagName()) {
215
				case 'alias':
216
					{
217
						if (($id = $element->getAttribute('id')) !== null && ($path = $element->getAttribute('path')) !== null) {
218
							$path = str_replace('\\', '/', $path);
219
							if (preg_match('/^\\/|.:\\/|.:\\\\/', $path)) {	// if absolute path
220
								$p = realpath($path);
221
							} else {
222
								$p = realpath($configPath . DIRECTORY_SEPARATOR . $path);
223
							}
224
							if ($p === false || !is_dir($p)) {
225
								throw new TConfigurationException('appconfig_aliaspath_invalid', $id, $path);
226
							}
227
							if (isset($this->_aliases[$id])) {
228
								throw new TConfigurationException('appconfig_alias_redefined', $id);
229
							}
230
							$this->_aliases[$id] = $p;
231
						} else {
232
							throw new TConfigurationException('appconfig_alias_invalid');
233
						}
234
						$this->_empty = false;
235
						break;
236
					}
237
				case 'using':
238
					{
239
						if (($namespace = $element->getAttribute('namespace')) !== null) {
240
							$this->_usings[] = $namespace;
241
						} else {
242
							throw new TConfigurationException('appconfig_using_invalid');
243
						}
244
						$this->_empty = false;
245
						break;
246
					}
247
				default:
248
					throw new TConfigurationException('appconfig_paths_invalid', $element->getTagName());
249
			}
250
		}
251
	}
252
253
	/**
254
	 * Reads the Composer static RegisteredLoaders for their Vendor Directory. Reads the Vendor
255
	 * Directory composer file 'installed.json' (accumulated extensions composer.json) for the project.
256
	 * The ['extra']['bootstrap'] field is read for each extension, if it's there.
257
	 * @return array<string, string> the extension name and bootstrap class.
258
	 * @since 4.2.0
259
	 */
260
	protected function getComposerExtensionBootStraps()
261
	{
262
		if ($cache = Prado::getApplication()->getCache()) {
263
			$plugins = $cache->get(self::COMPOSER_INSTALLED_CACHE);
264
			if ($plugins !== null) {
265
				return $plugins;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $plugins could also return false which is incompatible with the documented return type array<string,string>. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
266
			}
267
		}
268
		$dependencies = new TChainedCacheDependency();
269
		$listDeps = $dependencies->getDependencies();
270
		$plugins = [];
271
		foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
272
			$file = $vendorDir . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . 'installed.json';
273
			$manifests = json_decode(file_get_contents($file), true, 512, JSON_THROW_ON_ERROR);
274
275
			// Loop through the installed packages
276
			foreach ($manifests['packages'] as $package) {
277
				$name = $package['name'];
278
				if (isset($package['extra']) && isset($package['extra'][self::COMPOSER_EXTRA_CLASS])) {
279
					$plugins[$name] = $package['extra'][self::COMPOSER_EXTRA_CLASS];
280
					//$packagepath =  realpath($vendorDir . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . $package['install-path']);
281
				}
282
			}
283
			$listDeps[] = new TFileCacheDependency($file);
284
		}
285
		if ($cache) {
0 ignored issues
show
introduced by
$cache is of type Prado\Caching\ICache, thus it always evaluated to true.
Loading history...
286
			$cache->set(self::COMPOSER_INSTALLED_CACHE, $plugins, null, $dependencies);
287
		}
288
		return $plugins;
289
	}
290
291
	/**
292
	 * Given a module id as a composer package name, returns the extension bootstrap
293
	 * {@see \Prado\TModule} class.
294
	 * @param string $name the name of the Composer Extension.
295
	 * @return null|string the bootstrap class of the Composer Extension.
296
	 * @since 4.2.0
297
	 */
298
	public function getComposerExtensionClass($name)
299
	{
300
		if (self::$_composerPlugins === null) {
0 ignored issues
show
introduced by
The condition self::_composerPlugins === null is always false.
Loading history...
301
			self::$_composerPlugins = $this->getComposerExtensionBootStraps();
302
		}
303
		return self::$_composerPlugins[$name] ?? null;
304
	}
305
306
	/**
307
	 * Loads the modules PHP array.
308
	 * @param array $modulesNode the modules PHP array
309
	 * @param string $configPath the context path (for specifying relative paths)
310
	 */
311
	protected function loadModulesPhp($modulesNode, $configPath)
0 ignored issues
show
Unused Code introduced by
The parameter $configPath is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

311
	protected function loadModulesPhp($modulesNode, /** @scrutinizer ignore-unused */ $configPath)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
312
	{
313
		foreach ($modulesNode as $id => $module) {
314
			if (strpos($id, '/') !== false && ($class = $this->getComposerExtensionClass($id))) {
315
				if (isset($module['class'])) {
316
					throw new TConfigurationException('appconfig_moduletype_inapplicable', $id);
317
				}
318
				$module['class'] = $class;
319
			}
320
			if (!isset($module['class'])) {
321
				throw new TConfigurationException('appconfig_moduletype_required', $id);
322
			}
323
			$type = $module['class'];
324
			unset($module['class']);
325
			$properties = [];
326
			if (isset($module['properties'])) {
327
				$properties = $module['properties'];
328
				unset($module['properties']);
329
			}
330
			$properties['id'] = $id;
331
			$this->_modules[$id] = [$type, $properties, $module];
332
			$this->_empty = false;
333
		}
334
	}
335
336
	/**
337
	 * Loads the modules XML node.
338
	 * @param \Prado\Xml\TXmlElement $modulesNode the modules XML node
339
	 * @param string $configPath the context path (for specifying relative paths)
340
	 */
341
	protected function loadModulesXml($modulesNode, $configPath)
0 ignored issues
show
Unused Code introduced by
The parameter $configPath is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

341
	protected function loadModulesXml($modulesNode, /** @scrutinizer ignore-unused */ $configPath)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
342
	{
343
		foreach ($modulesNode->getElements() as $element) {
344
			if ($element->getTagName() === 'module') {
345
				$properties = $element->getAttributes();
346
				$id = $properties->itemAt('id');
347
				$type = $properties->remove('class');
348
				if (strpos($id ?? '', '/') !== false && ($class = $this->getComposerExtensionClass($id))) {
349
					if ($type) {
350
						throw new TConfigurationException('appconfig_moduletype_inapplicable', $id);
351
					}
352
					$type = $class;
353
				}
354
				if ($type === null) {
355
					throw new TConfigurationException('appconfig_moduletype_required', $id);
356
				}
357
				$element->setParent(null);
358
				if ($id === null) {
359
					$this->_modules[] = [$type, $properties->toArray(), $element];
360
				} else {
361
					$this->_modules[$id] = [$type, $properties->toArray(), $element];
362
				}
363
				$this->_empty = false;
364
			} else {
365
				throw new TConfigurationException('appconfig_modules_invalid', $element->getTagName());
366
			}
367
		}
368
	}
369
370
	/**
371
	 * Loads the services PHP array.
372
	 * @param array $servicesNode the services PHP array
373
	 * @param string $configPath the context path (for specifying relative paths)
374
	 */
375
	protected function loadServicesPhp($servicesNode, $configPath)
0 ignored issues
show
Unused Code introduced by
The parameter $configPath is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

375
	protected function loadServicesPhp($servicesNode, /** @scrutinizer ignore-unused */ $configPath)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
376
	{
377
		foreach ($servicesNode as $id => $service) {
378
			if (!isset($service['class'])) {
379
				throw new TConfigurationException('appconfig_servicetype_required');
380
			}
381
			$type = $service['class'];
382
			$properties = $service['properties'] ?? [];
383
			unset($service['properties']);
384
			$properties['id'] = $id;
385
			$this->_services[$id] = [$type, $properties, $service];
386
			$this->_empty = false;
387
		}
388
	}
389
390
	/**
391
	 * Loads the services XML node.
392
	 * @param \Prado\Xml\TXmlElement $servicesNode the services XML node
393
	 * @param string $configPath the context path (for specifying relative paths)
394
	 */
395
	protected function loadServicesXml($servicesNode, $configPath)
0 ignored issues
show
Unused Code introduced by
The parameter $configPath is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

395
	protected function loadServicesXml($servicesNode, /** @scrutinizer ignore-unused */ $configPath)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
396
	{
397
		foreach ($servicesNode->getElements() as $element) {
398
			if ($element->getTagName() === 'service') {
399
				$properties = $element->getAttributes();
400
				if (($id = $properties->itemAt('id')) === null) {
401
					throw new TConfigurationException('appconfig_serviceid_required');
402
				}
403
				if (($type = $properties->remove('class')) === null) {
404
					throw new TConfigurationException('appconfig_servicetype_required', $id);
405
				}
406
				$element->setParent(null);
407
				$this->_services[$id] = [$type, $properties->toArray(), $element];
408
				$this->_empty = false;
409
			} else {
410
				throw new TConfigurationException('appconfig_services_invalid', $element->getTagName());
411
			}
412
		}
413
	}
414
415
	/**
416
	 * Loads the parameters PHP array.
417
	 * @param array $parametersNode the parameters PHP array
418
	 * @param string $configPath the context path (for specifying relative paths)
419
	 */
420
	protected function loadParametersPhp($parametersNode, $configPath)
0 ignored issues
show
Unused Code introduced by
The parameter $configPath is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

420
	protected function loadParametersPhp($parametersNode, /** @scrutinizer ignore-unused */ $configPath)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
421
	{
422
		foreach ($parametersNode as $id => $parameter) {
423
			if (is_array($parameter)) {
424
				if (isset($parameter['class'])) {
425
					$type = $parameter['class'];
426
					unset($parameter['class']);
427
					$properties = $parameter['properties'] ?? [];
428
					$properties['id'] = $id;
429
					$this->_parameters[$id] = [$type, $properties, $parameter];
430
				}
431
			} else {
432
				$this->_parameters[$id] = $parameter;
433
			}
434
		}
435
	}
436
437
	/**
438
	 * Loads the parameters XML node.
439
	 * @param \Prado\Xml\TXmlElement $parametersNode the parameters XML node
440
	 * @param string $configPath the context path (for specifying relative paths)
441
	 */
442
	protected function loadParametersXml($parametersNode, $configPath)
0 ignored issues
show
Unused Code introduced by
The parameter $configPath is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

442
	protected function loadParametersXml($parametersNode, /** @scrutinizer ignore-unused */ $configPath)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
443
	{
444
		foreach ($parametersNode->getElements() as $element) {
445
			if ($element->getTagName() === 'parameter') {
446
				$properties = $element->getAttributes();
447
				if (($id = $properties->remove('id')) === null) {
448
					throw new TConfigurationException('appconfig_parameterid_required');
449
				}
450
				if (($type = $properties->remove('class')) === null) {
451
					if (($value = $properties->remove('value')) === null) {
452
						$this->_parameters[$id] = $element;
453
					} else {
454
						$this->_parameters[$id] = $value;
455
					}
456
				} else {
457
					$this->_parameters[$id] = [$type, $properties->toArray(), $element];
458
				}
459
				$this->_empty = false;
460
			} else {
461
				throw new TConfigurationException('appconfig_parameters_invalid', $element->getTagName());
462
			}
463
		}
464
	}
465
466
	/**
467
	 * Loads the external PHP array.
468
	 * @param array $includeNode the application PHP array
469
	 * @param string $configPath the context path (for specifying relative paths)
470
	 */
471
	protected function loadExternalPhp($includeNode, $configPath)
472
	{
473
		foreach ($includeNode as $include) {
474
			$when = isset($include['when']) ? true : false;
475
			if (!isset($include['file'])) {
476
				throw new TConfigurationException('appconfig_includefile_required');
477
			}
478
			$filePath = $include['file'];
479
			if (isset($this->_includes[$filePath])) {
480
				$this->_includes[$filePath] = '(' . $this->_includes[$filePath] . ') || (' . $when . ')';
481
			} else {
482
				$$this->_includes[$filePath] = $when;
483
			}
484
			$this->_empty = false;
485
		}
486
	}
487
488
	/**
489
	 * Loads the external XML configurations.
490
	 * @param \Prado\Xml\TXmlElement $includeNode the application DOM element
491
	 * @param string $configPath the context path (for specifying relative paths)
492
	 */
493
	protected function loadExternalXml($includeNode, $configPath)
0 ignored issues
show
Unused Code introduced by
The parameter $configPath is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

493
	protected function loadExternalXml($includeNode, /** @scrutinizer ignore-unused */ $configPath)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
494
	{
495
		if (($when = $includeNode->getAttribute('when')) === null) {
496
			$when = true;
497
		}
498
		if (($filePath = $includeNode->getAttribute('file')) === null) {
499
			throw new TConfigurationException('appconfig_includefile_required');
500
		}
501
		if (isset($this->_includes[$filePath])) {
502
			$this->_includes[$filePath] = '(' . $this->_includes[$filePath] . ') || (' . $when . ')';
0 ignored issues
show
Bug introduced by
Are you sure $when of type string|true can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

502
			$this->_includes[$filePath] = '(' . $this->_includes[$filePath] . ') || (' . /** @scrutinizer ignore-type */ $when . ')';
Loading history...
503
		} else {
504
			$this->_includes[$filePath] = $when;
505
		}
506
		$this->_empty = false;
507
	}
508
509
	/**
510
	 * Returns list of page initial property values.
511
	 * Each array element represents a single property with the key
512
	 * being the property name and the value the initial property value.
513
	 * @return array list of page initial property values
514
	 */
515
	public function getProperties()
516
	{
517
		return $this->_properties;
518
	}
519
520
	/**
521
	 * Returns list of path alias definitions.
522
	 * The definitions are aggregated (top-down) from configuration files along the path
523
	 * to the specified page. Each array element represents a single alias definition,
524
	 * with the key being the alias name and the value the absolute path.
525
	 * @return array list of path alias definitions
526
	 */
527
	public function getAliases()
528
	{
529
		return $this->_aliases;
530
	}
531
532
	/**
533
	 * Returns list of namespaces to be used.
534
	 * The namespaces are aggregated (top-down) from configuration files along the path
535
	 * to the specified page. Each array element represents a single namespace usage,
536
	 * with the value being the namespace to be used.
537
	 * @return array list of namespaces to be used
538
	 */
539
	public function getUsings()
540
	{
541
		return $this->_usings;
542
	}
543
544
	/**
545
	 * Returns list of module configurations.
546
	 * The module configurations are aggregated (top-down) from configuration files
547
	 * along the path to the specified page. Each array element represents
548
	 * a single module configuration, with the key being the module ID and
549
	 * the value the module configuration. Each module configuration is
550
	 * stored in terms of an array with the following content
551
	 * ([0]=>module type, [1]=>module properties, [2]=>complete module configuration)
552
	 * The module properties are an array of property values indexed by property names.
553
	 * The complete module configuration is a TXmlElement object representing
554
	 * the raw module configuration which may contain contents enclosed within
555
	 * module tags.
556
	 * @return array list of module configurations to be used
557
	 */
558
	public function getModules()
559
	{
560
		return $this->_modules;
561
	}
562
563
	/**
564
	 * @return array list of service configurations
565
	 */
566
	public function getServices()
567
	{
568
		return $this->_services;
569
	}
570
571
	/**
572
	 * Returns list of parameter definitions.
573
	 * The parameter definitions are aggregated (top-down) from configuration files
574
	 * along the path to the specified page. Each array element represents
575
	 * a single parameter definition, with the key being the parameter ID and
576
	 * the value the parameter definition. A parameter definition can be either
577
	 * a string representing a string-typed parameter, or an array.
578
	 * The latter defines a component-typed parameter whose format is as follows,
579
	 * ([0]=>component type, [1]=>component properties)
580
	 * The component properties are an array of property values indexed by property names.
581
	 * @return array list of parameter definitions to be used
582
	 */
583
	public function getParameters()
584
	{
585
		return $this->_parameters;
586
	}
587
588
	/**
589
	 * @return array list of external configuration files. Each element is like $filePath=>$condition
590
	 */
591
	public function getExternalConfigurations()
592
	{
593
		return $this->_includes;
594
	}
595
}
596