GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

ComponentFactory::getModifiedComponent()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 15
Code Lines 7

Duplication

Lines 3
Ratio 20 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 3
nop 2
dl 3
loc 15
ccs 0
cts 7
cp 0
crap 20
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * File containing the ComponentFactory class
4
 *
5
 * This file is part of the MediaWiki skin Chameleon.
6
 *
7
 * @copyright 2013 - 2014, Stephan Gambke
8
 * @license   GNU General Public License, version 3 (or any later version)
9
 *
10
 * The Chameleon skin is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by the Free
12
 * Software Foundation, either version 3 of the License, or (at your option) any
13
 * later version.
14
 *
15
 * The Chameleon skin is distributed in the hope that it will be useful, but
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18
 * details.
19
 *
20
 * You should have received a copy of the GNU General Public License along
21
 * with this program. If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 * @file
24
 * @ingroup   Skins
25
 */
26
27
namespace Skins\Chameleon;
28
29
use DOMDocument;
30
use RuntimeException;
31
use Skins\Chameleon\Components\Component;
32
use Skins\Chameleon\Components\Container;
33
34
/**
35
 * Class ComponentFactory
36
 *
37
 * @author  Stephan Gambke
38
 * @since   1.0
39
 * @ingroup Skins
40
 */
41
class ComponentFactory {
42
43
	// the root component of the page; should be of type Container
44
	private $mRootComponent = null;
45
46
	private $layoutFile;
47
	private $skinTemplate;
48
49
	/**
50
	 * @param string $layoutFileName
51
	 */
52 1
	public function __construct( $layoutFileName ) {
53 1
		$this->setLayoutFile( $layoutFileName );
54
	}
55
56
	/**
57
	 * @return Container
58
	 * @throws \MWException
59
	 */
60
	public function getRootComponent() {
61
62
		if ( $this->mRootComponent === null ) {
63
64
			$doc = new DOMDocument();
65
66
			$doc->load( $this->getLayoutFile() );
67
68
			$doc->normalizeDocument();
69
70
			$roots = $doc->getElementsByTagName( 'structure' );
71
72
			if ( $roots->length > 0 ) {
73
74
				$this->mRootComponent = $this->getComponent( $roots->item( 0 ) );
75
76
			} else {
77
				// TODO: catch other errors, e.g. malformed XML
78
				throw new \MWException( sprintf( '%s: XML description is missing an element: structure.', $this->getLayoutFile() ) );
79
			}
80
		}
81
82
		return $this->mRootComponent;
83
84
	}
85
86
	/**
87
	 * @return string
88
	 */
89
	protected function getLayoutFile() {
90
91
		return $this->layoutFile;
92
	}
93
94
	/**
95
	 * @param string $fileName
96
	 */
97 1
	public function setLayoutFile( $fileName ) {
98
99 1
		$fileName = $this->sanitizeFileName( $fileName );
100
101 1
		if ( !is_readable( $fileName ) ) {
102 1
			throw new RuntimeException( "Expected an accessible {$fileName} layout file" );
103
		}
104
105
		$this->layoutFile = $fileName;
106
	}
107
108
	/**
109
	 * @param \DOMElement $description
110
	 * @param int         $indent
111
	 * @param string      $htmlClassAttribute
112
	 *
113
	 * @throws \MWException
114
	 * @return \Skins\Chameleon\Components\Container
115
	 */
116
	public function getComponent( \DOMElement $description, $indent = 0, $htmlClassAttribute = '' ) {
117
118
		$className = $this->getComponentClassName( $description );
119
		$component = new $className( $this->getSkinTemplate(), $description, $indent, $htmlClassAttribute );
120
121
		$children = $description->childNodes;
122
123
		foreach ( $children as $child ) {
124
			if ( is_a( $child, 'DOMElement' ) && strtolower( $child->nodeName ) === 'modification' ) {
125
				$component = $this->getModifiedComponent( $child, $component );
126
			}
127
		}
128
129
		return $component;
130
	}
131
132
	/**
133
	 * @param \DOMElement $description
134
	 *
135
	 * @return string
136
	 * @throws \MWException
137
	 * @since 1.1
138
	 */
139
	protected function getComponentClassName( \DOMElement $description ) {
140
141
		$className = $this->mapComponentDescriptionToClassName( $description );
142
143 View Code Duplication
		if ( !class_exists( $className ) || !is_subclass_of( $className, 'Skins\\Chameleon\\Components\\Component' ) ) {
144
			throw new \MWException( sprintf( '%s (line %d): Invalid component type: %s.', $this->getLayoutFile(), $description->getLineNo(), $description->getAttribute( 'type' ) ) );
145
		}
146
147
		return $className;
148
	}
149
150
	/**
151
	 * @param \DOMElement $description
152
	 *
153
	 * @return string
154
	 * @throws \MWException
155
	 */
156
	protected function mapComponentDescriptionToClassName( \DOMElement $description ) {
157
158
		$mapOfComponentsToClassNames = array(
159
			'structure'    => 'Structure',
160
			'grid'         => 'Grid',
161
			'row'          => 'Row',
162
			'cell'         => 'Cell',
163
			'modification' => 'Silent',
164
		);
165
166
		$nodeName = strtolower( $description->nodeName );
167
168
		if ( array_key_exists( $nodeName, $mapOfComponentsToClassNames ) ) {
169
170
			$className = $mapOfComponentsToClassNames[ $nodeName ];
171
172
		} elseif ( $nodeName === 'component' ) {
173
174
			if ( $description->hasAttribute( 'type' ) ) {
175
				$className = $description->getAttribute( 'type' );
176
			} else {
177
				$className = 'Container';
178
			}
179
180
		} else {
181
			throw new \MWException( sprintf( '%s (line %d): XML element not allowed here: %s.', $this->getLayoutFile(), $description->getLineNo(), $description->nodeName ) );
182
		}
183
184
		return 'Skins\\Chameleon\\Components\\' . $className;
185
	}
186
187
	/**
188
	 * @return mixed
189
	 */
190
	public function getSkinTemplate() {
191
		return $this->skinTemplate;
192
	}
193
194
	/**
195
	 * @param ChameleonTemplate $skinTemplate
196
	 */
197
	public function setSkinTemplate( ChameleonTemplate $skinTemplate ) {
198
		$this->skinTemplate = $skinTemplate;
199
	}
200
201
	/**
202
	 * @param \DOMElement $description
203
	 * @param Component   $component
204
	 *
205
	 * @return mixed
206
	 * @throws \MWException
207
	 */
208
	protected function getModifiedComponent( \DOMElement $description, Component $component ) {
209
210
		if ( !$description->hasAttribute( 'type' ) ) {
211
			throw new \MWException( sprintf( '%s (line %d): Modification element missing an attribute: type.', $this->getLayoutFile(), $description->getLineNo() ) );
212
		}
213
214
		$className = 'Skins\\Chameleon\\Components\\Modifications\\' . $description->getAttribute( 'type' );
215
216 View Code Duplication
		if ( !class_exists( $className ) || !is_subclass_of( $className, 'Skins\\Chameleon\\Components\\Modifications\\Modification' ) ) {
217
			throw new \MWException( sprintf( '%s (line %d): Invalid modification type: %s.', $this->getLayoutFile(), $description->getLineNo(), $description->getAttribute( 'type' ) ) );
218
		}
219
220
		return new $className( $component, $description );
221
222
	}
223
224
	/**
225
	 * @param string $fileName
226
	 *
227
	 * @return string
228
	 */
229 1
	public function sanitizeFileName( $fileName ) {
230 1
		return str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, $fileName );
231
	}
232
233
234
}
235