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.

ViewA   A
last analyzed

Complexity

Total Complexity 40

Size/Duplication

Total Lines 281
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 81%

Importance

Changes 0
Metric Value
dl 0
loc 281
ccs 81
cts 100
cp 0.81
rs 9.2
c 0
b 0
f 0
wmc 40
lcom 1
cbo 11

19 Methods

Rating   Name   Duplication   Size   Complexity  
A setMainTemplate() 0 6 2
A getMainTemplate() 0 3 1
A getContentType() 0 3 1
A getViewFolder() 0 3 1
A getTitle() 0 18 5
A setModel() 0 3 1
A getMap() 0 7 2
A setMap() 0 3 1
A registerHelper() 0 3 1
A __call() 0 11 3
A __get() 0 10 2
A getModel() 0 6 2
A fetch() 0 36 5
A getOutput() 0 13 3
A getTemplatePath() 0 16 4
A getTemplate() 0 7 2
A setTemplate() 0 7 2
A getCurrentSiteUri() 0 3 1
A getCurrentUri() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like ViewA often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ViewA, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @package presentation
4
 * @subpackage views
5
 * @author marius orcsik <[email protected]>
6
 * @date 09.08.30
7
 */
8
namespace vsc\presentation\views;
9
10
use vsc\application\sitemaps\ClassMap;
11
use vsc\application\sitemaps\MappingA;
12
use vsc\domain\models\EmptyModel;
13
use vsc\domain\models\HttpModelInterface;
14
use vsc\domain\models\ModelA;
15
use vsc\infrastructure\urls\UrlParserA;
16
use vsc\infrastructure\vsc;
17
use vsc\infrastructure\Base;
18
use vsc\infrastructure\BaseObject;
19
use vsc\presentation\helpers\ViewHelperA;
20
use vsc\ExceptionPath;
21
22
abstract class ViewA extends BaseObject implements ViewInterface {
23
	/**
24
	 * @var string
25
	 */
26
	private $sTitle;
27
28
	/**
29
	 * @var ModelA
30
	 */
31
	private $oModel;
32
33
	/**
34
	 * @var ViewHelperA[]
35
	 */
36
	private $aHelpers = array();
37
38
	/**
39
	 * @var string
40
	 */
41
	private $sMainTemplate;
42
43
	/**
44
	 * @var ClassMap
45
	 */
46
	private $oCurrentMap;
47
48
	/**
49
	 * type of view (html, rss, etc)
50
	 * @var string
51
	 */
52
	protected $sContentType;
53
54
	/**
55
	 * @var string
56
	 */
57
	protected $sFolder;
58
59
	/**
60
	 * @param $sPath
61
	 * @throws ExceptionPath
62
	 */
63 3
	public function setMainTemplate($sPath) {
64 3
		if (!is_file($sPath)) {
65 2
			throw new ExceptionPath('The main template [' . $sPath . '] is not accessible.');
66
		}
67 2
		$this->sMainTemplate = $sPath;
68 2
	}
69
70
	/**
71
	 * @return string
72
	 */
73 1
	public function getMainTemplate() {
74 1
		return $this->sMainTemplate;
75
	}
76
77
	/**
78
	 * @return string
79
	 */
80 1
	public function getContentType() {
81 1
		return $this->sContentType;
82
	}
83
84
	/**
85
	 * @return string
86
	 */
87 3
	public function getViewFolder() {
88 3
		return $this->sFolder;
89
	}
90
91
	/**
92
	 * @return string
93
	 * @throws ExceptionView
94
	 */
95 2
	public function getTitle() {
96
		try {
97
			/** @var EmptyModel $oModel */
98 2
			$oModel = $this->getModel();
99 2
			if (($oModel instanceof HttpModelInterface) && $oModel->getPageTitle() != '') {
100 2
				return  $oModel->getPageTitle();
101
			}
102
		} catch (\Exception $e) {
103
			//
104
		}
105
106 2
		$sStaticTitle = $this->getMap()->getTitle();
107 2
		if (!empty ($sStaticTitle)) {
108 1
			return $sStaticTitle;
109
		}
110
111 2
		return $this->sTitle;
112
	}
113
114
	/**
115
	 * @param ModelA $oModel
116
	 */
117 2
	public function setModel(ModelA $oModel) {
118 2
		$this->oModel = $oModel;
119 2
	}
120
121
	/**
122
	 * @throws ExceptionView
123
	 * @returns ClassMap
124
	 */
125 1
	public function getMap() {
126 1
		if (MappingA::isValid($this->oCurrentMap)) {
127
			return $this->oCurrentMap;
128
		} else {
129 1
			throw new ExceptionView('Make sure the current map is correctly set.');
130
		}
131
	}
132
133
	/**
134
	 * @param ClassMap $oMap
135
	 */
136 2
	public function setMap($oMap) {
137 2
		$this->oCurrentMap = $oMap;
138 2
	}
139
140 1
	public function registerHelper(ViewHelperA $oHelper) {
141 1
		$this->getMap()->registerHelper($oHelper);
142 1
	}
143
144 1
	public function __call($sMethodName, $aParameters = array()) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
145
		// to be used with helpers
146 1
		foreach ($this->getMap()->getViewHelpers() as $key => $oHelper) {
147
			$oReflection = new \ReflectionClass($oHelper);
148
			if ($oReflection->hasMethod($sMethodName)) {
149
				$oMethod = $oReflection->getMethod($sMethodName);
150
				return $oMethod->invokeArgs($oHelper, $aParameters);
151
			}
152
		}
153
		return $aParameters;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $aParameters; (array) is incompatible with the return type of the parent method vsc\infrastructure\BaseObject::__call of type vsc\infrastructure\Base.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
154
	}
155
156
	/**
157
	 * @param $sVarName
158
	 * @return Base
159
	 */
160 1
	public function __get($sVarName) {
161
		try {
162
			// TODO: use proper reflection
163 1
			return $this->getModel()->$sVarName;
164
		} catch (\Exception $e) {
165
			// most likely the variable doesn't exist
166
			vsc::d($e->getTraceAsString());
167
		}
168
		return null;
169
	}
170
171
	/**
172
	 * @returns ModelA
173
	 */
174 1
	public function getModel() {
175 1
		if (!ModelA::isValid($this->oModel)) {
176 1
			$this->oModel = new EmptyModel();
177
		}
178 1
		return $this->oModel;
179
	}
180
181
//	public function setBody ($sText) {
182
//		$this->sBody = $sText;
183
//	}
184
185
	/**
186
	 * @param string $includePath
187
	 * @return string
188
	 * @throws ExceptionPath
189
	 * @throws ExceptionView
190
	 */
191 1
	public function fetch($includePath) {
192 1
		if (empty($includePath)) {
193 1
			throw new ExceptionPath('Template could not be located');
194
		}
195
196 1
		ob_start();
197 1
		if (!is_file($includePath)) {
198 1
			$includePath = $this->getTemplatePath() . $includePath;
199 1
			if (!is_file($includePath)) {
200
				ob_end_clean();
201
				throw new ExceptionPath('Template [' . $includePath . '] could not be located');
202
			}
203
		}
204
		// outputting the model's content into the local scope
205 1
		$model = $this->getModel();
206 1
		extract(
207
			array(
0 ignored issues
show
Bug introduced by
array('model' => $model,...nv()->getHttpRequest()) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
208 1
				'model'     => $model,
209 1
				'view'      => $this,
210 1
				'helper'    => $this->getMap(),
211 1
				'request'   => vsc::getEnv()->getHttpRequest()
212
			),
213 1
			EXTR_SKIP
214
		);
215
216 1
		$bIncluded = include ($includePath);
217
218 1
		if (!$bIncluded) {
219
			ob_end_clean();
220
			throw new ExceptionView('Template [' . $includePath . '] could not be included');
221
		} else {
222 1
			$sContent = ob_get_contents();
223 1
			ob_end_clean();
224 1
			return $sContent;
225
		}
226
	}
227
228
	/**
229
	 * @return string
230
	 * @throws ExceptionView
231
	 */
232 1
	public function getOutput() {
233
		try {
234
			// by default try to load the main template
235 1
			return $this->fetch($this->getMainTemplate());
236 1
		} catch (ExceptionPath $e) {
237
			// if it fails, we load the regular template.
238
			try {
239 1
				return $this->fetch($this->getTemplatePath() . DIRECTORY_SEPARATOR . $this->getMap()->getTemplate());
240 1
			} catch (ExceptionPath $e) {
241
				return '';
242
			}
243
		}
244
	}
245
246
	/**
247
	 * @return string
248
	 * @throws ExceptionView
249
	 */
250 1
	public function getTemplatePath() {
251 1
		$sTemplatePath = $this->getMap()->getTemplatePath();
252 1
		$sViewFolder = $this->getViewFolder();
253
254 1
		if (!empty($sViewFolder)) {
255
			$sTemplatePath .= DIRECTORY_SEPARATOR . $sViewFolder;
256
		}
257
258 1
		if (!is_dir($sTemplatePath)) {
259 1
			return '';
260
		}
261
		if (!UrlParserA::hasGoodTermination($sTemplatePath, DIRECTORY_SEPARATOR)) {
262
			$sTemplatePath .= DIRECTORY_SEPARATOR;
263
		}
264
		return $sTemplatePath;
265
	}
266
267
	/**
268
	 * @return string
269
	 */
270 1
	public function getTemplate() {
271
		try {
272 1
			return $this->getMap()->getTemplate();
273 1
		} catch (ExceptionView $e) {
274 1
			return '';
275
		}
276
	}
277
278
	/**
279
	 * @param string $sPath
280
	 */
281 1
	public function setTemplate($sPath) {
282
		try {
283 1
			$this->getMap()->setTemplate($sPath);
284 1
		} catch (ExceptionView $e) {
285
			//
286
		}
287 1
	}
288
289
	/**
290
	 * @return string
291
	 */
292 1
	public static function getCurrentSiteUri() {
293 1
		return htmlspecialchars(UrlParserA::getCurrentUrl()->getUrl());
294
	}
295
296
	/**
297
	 * @return string
298
	 */
299 1
	public static function getCurrentUri() {
300 1
		return htmlspecialchars(vsc::getEnv()->getHttpRequest()->getUri(true));
301
	}
302
}
303