Passed
Push — master ( 06f7cb...c3c92a )
by Fabio
05:08
created

TApplicationConfiguration::loadModulesPhp()   B

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

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

272
		foreach (ClassLoader::/** @scrutinizer ignore-call */ getRegisteredLoaders() as $vendorDir => $loader) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

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

312
	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...
313
	{
314
		foreach ($modulesNode as $id => $module) {
315
			if (strpos($id, '/') !== false && ($class = $this->getComposerExtensionClass($id))) {
316
				if (isset($module['class'])) {
317
					throw new TConfigurationException('appconfig_moduletype_inapplicable', $id);
318
				}
319
				$module['class'] = $class;
320
			}
321
			if (!isset($module['class'])) {
322
				throw new TConfigurationException('appconfig_moduletype_required', $id);
323
			}
324
			$type = $module['class'];
325
			unset($module['class']);
326
			$properties = [];
327
			if (isset($module['properties'])) {
328
				$properties = $module['properties'];
329
				unset($module['properties']);
330
			}
331
			$properties['id'] = $id;
332
			$this->_modules[$id] = [$type, $properties, $module];
333
			$this->_empty = false;
334
		}
335
	}
336
337
	/**
338
	 * Loads the modules XML node.
339
	 * @param \Prado\Xml\TXmlElement $modulesNode the modules XML node
340
	 * @param string $configPath the context path (for specifying relative paths)
341
	 */
342
	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

342
	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...
343
	{
344
		foreach ($modulesNode->getElements() as $element) {
345
			if ($element->getTagName() === 'module') {
346
				$properties = $element->getAttributes();
347
				$id = $properties->itemAt('id');
348
				$type = $properties->remove('class');
349
				if (strpos($id, '/') !== false && ($class = $this->getComposerExtensionClass($id))) {
350
					if ($type) {
351
						throw new TConfigurationException('appconfig_moduletype_inapplicable', $id);
352
					}
353
					$type = $class;
354
				}
355
				if ($type === null) {
356
					throw new TConfigurationException('appconfig_moduletype_required', $id);
357
				}
358
				$element->setParent(null);
359
				if ($id === null) {
360
					$this->_modules[] = [$type, $properties->toArray(), $element];
361
				} else {
362
					$this->_modules[$id] = [$type, $properties->toArray(), $element];
363
				}
364
				$this->_empty = false;
365
			} else {
366
				throw new TConfigurationException('appconfig_modules_invalid', $element->getTagName());
367
			}
368
		}
369
	}
370
371
	/**
372
	 * Loads the services PHP array.
373
	 * @param array $servicesNode the services PHP array
374
	 * @param string $configPath the context path (for specifying relative paths)
375
	 */
376
	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

376
	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...
377
	{
378
		foreach ($servicesNode as $id => $service) {
379
			if (!isset($service['class'])) {
380
				throw new TConfigurationException('appconfig_servicetype_required');
381
			}
382
			$type = $service['class'];
383
			$properties = $service['properties'] ?? [];
384
			unset($service['properties']);
385
			$properties['id'] = $id;
386
			$this->_services[$id] = [$type, $properties, $service];
387
			$this->_empty = false;
388
		}
389
	}
390
391
	/**
392
	 * Loads the services XML node.
393
	 * @param \Prado\Xml\TXmlElement $servicesNode the services XML node
394
	 * @param string $configPath the context path (for specifying relative paths)
395
	 */
396
	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

396
	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...
397
	{
398
		foreach ($servicesNode->getElements() as $element) {
399
			if ($element->getTagName() === 'service') {
400
				$properties = $element->getAttributes();
401
				if (($id = $properties->itemAt('id')) === null) {
402
					throw new TConfigurationException('appconfig_serviceid_required');
403
				}
404
				if (($type = $properties->remove('class')) === null) {
405
					throw new TConfigurationException('appconfig_servicetype_required', $id);
406
				}
407
				$element->setParent(null);
408
				$this->_services[$id] = [$type, $properties->toArray(), $element];
409
				$this->_empty = false;
410
			} else {
411
				throw new TConfigurationException('appconfig_services_invalid', $element->getTagName());
412
			}
413
		}
414
	}
415
416
	/**
417
	 * Loads the parameters PHP array.
418
	 * @param array $parametersNode the parameters PHP array
419
	 * @param string $configPath the context path (for specifying relative paths)
420
	 */
421
	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

421
	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...
422
	{
423
		foreach ($parametersNode as $id => $parameter) {
424
			if (is_array($parameter)) {
425
				if (isset($parameter['class'])) {
426
					$type = $parameter['class'];
427
					unset($parameter['class']);
428
					$properties = $parameter['properties'] ?? [];
429
					$properties['id'] = $id;
430
					$this->_parameters[$id] = [$type, $properties];
431
				}
432
			} else {
433
				$this->_parameters[$id] = $parameter;
434
			}
435
		}
436
	}
437
438
	/**
439
	 * Loads the parameters XML node.
440
	 * @param \Prado\Xml\TXmlElement $parametersNode the parameters XML node
441
	 * @param string $configPath the context path (for specifying relative paths)
442
	 */
443
	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

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

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