Passed
Pull Request — master (#786)
by
unknown
06:41
created

TApplicationConfiguration::getProperties()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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

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

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

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

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

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

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

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