Completed
Push — prado-3.3 ( e90646...0b76d5 )
by Fabio
23:37 queued 03:01
created

ClassDefinition   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 260
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 260
rs 6
c 0
b 0
f 0
wmc 55
lcom 2
cbo 3

24 Methods

Rating   Name   Duplication   Size   Complexity  
A reset() 0 11 1
A render() 0 5 1
A renderComments() 0 21 4
A renderClass() 0 13 3
A getVariableName() 0 4 1
A renderVariables() 0 13 3
B getValueAsString() 0 28 8
B getValueConversionString() 0 12 7
B renderProperties() 0 37 7
A renderEvents() 0 21 4
A getClassName() 0 4 1
A setClassName() 0 4 1
A getParentClass() 0 4 1
A setParentClass() 0 4 1
A getInterfaces() 0 4 1
A setInterfaces() 0 4 1
A getProperties() 0 6 2
A getEvents() 0 6 2
A getComments() 0 4 1
A setComments() 0 4 1
A getAuthor() 0 4 1
A setAuthor() 0 4 1
A getEmail() 0 4 1
A setEmail() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like ClassDefinition 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 ClassDefinition, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
class ClassDefinition extends TComponent
4
{
5
	private $_className='ClassName';
6
	private $_parentClass='TWebControl';
7
	private $_interfaces='';
8
	private $_properties=null;
9
	private $_events=null;
10
	private $_email='';
11
	private $_author='';
12
	private $_comments='';
13
14
	public function reset()
15
	{
16
		$this->_className='ClassName';
17
		$this->_parentClass='TWebControl';
18
		$this->_interfaces='';
19
		$this->_properties=new TList;
20
		$this->_events=new TList;
21
		$this->_email='';
22
		$this->_author='';
23
		$this->_comments='';
24
	}
25
26
	public function render($writer)
27
	{
28
		$this->renderComments($writer);
29
		$this->renderClass($writer);
30
	}
31
32
	protected function renderComments($writer)
33
	{
34
		$str ="/**\n";
35
		$str.=" * Class {$this->ClassName}.\n";
0 ignored issues
show
Bug introduced by
The property ClassName does not seem to exist. Did you mean _className?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
36
		if($this->Comments!=='')
0 ignored issues
show
Bug introduced by
The property Comments does not seem to exist. Did you mean _comments?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
37
		{
38
			$str.=" *\n";
39
			$str.=" * ".implode("\n * ",explode("\n",wordwrap($this->Comments)));
0 ignored issues
show
Bug introduced by
The property Comments does not seem to exist. Did you mean _comments?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
40
			$str.="\n *\n";
41
		}
42
		if($this->Author!=='')
0 ignored issues
show
Bug introduced by
The property Author does not seem to exist. Did you mean _author?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
43
		{
44
			$str.=" * @author {$this->Author}";
0 ignored issues
show
Bug introduced by
The property Author does not seem to exist. Did you mean _author?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
45
			if($this->Email!=='')
46
				$str.=" <{$this->Email}>";
47
			$str.="\n";
48
		}
49
		$str.=" * @version \$Revision: \$  \$Date: \$\n";
50
		$str.=" */\n";
51
		$writer->write($str);
52
	}
53
54
	protected function renderClass($writer)
55
	{
56
		$writer->write("class {$this->ClassName}");
0 ignored issues
show
Bug introduced by
The property ClassName does not seem to exist. Did you mean _className?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
57
		if($this->ParentClass!=='')
0 ignored issues
show
Bug introduced by
The property ParentClass does not seem to exist. Did you mean _parentClass?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
58
			$writer->write(" extends {$this->ParentClass}");
0 ignored issues
show
Bug introduced by
The property ParentClass does not seem to exist. Did you mean _parentClass?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
59
		if($this->Interfaces!=='')
0 ignored issues
show
Bug introduced by
The property Interfaces does not seem to exist. Did you mean _interfaces?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
60
			$writer->write(" implements {$this->Interfaces}");
0 ignored issues
show
Bug introduced by
The property Interfaces does not seem to exist. Did you mean _interfaces?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
61
		$writer->write("\n{\n");
62
		$this->renderVariables($writer);
63
		$this->renderProperties($writer);
64
		$this->renderEvents($writer);
65
		$writer->write("}\n");
66
	}
67
68
	private function getVariableName($propertyName)
69
	{
70
		return '_'.strtolower($propertyName[0]).substr($propertyName,1);
71
	}
72
73
	protected function renderVariables($writer)
74
	{
75
		foreach($this->Properties as $property)
0 ignored issues
show
Bug introduced by
The property Properties does not seem to exist. Did you mean _properties?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
76
		{
77
			if($property->Storage==='Memory')
78
			{
79
				$name=$this->getVariableName($property->Name);
80
				$value=$this->getValueAsString($property->DefaultValue,$property->Type);
81
				$writer->write("\t/**\n\t * @var {$property->Type} {$property->Comments}\n\t */\n");
82
				$writer->write("\tprivate \$$name=$value;\n");
83
			}
84
		}
85
	}
86
87
	private function getValueAsString($value,$type)
88
	{
89
		switch($type)
90
		{
91
			case 'integer':
92
				$value=TPropertyValue::ensureInteger($value);
93
				break;
94
			case 'float':
95
				$value=TPropertyValue::ensureFloat($value);
96
				break;
97
			case 'boolean':
98
				if(TPropertyValue::ensureBoolean($value))
99
					$value='true';
100
				else
101
					$value='false';
102
				break;
103
			case 'enumerable':
104
				$value="'$value'";
105
				break;
106
			case 'mixed':
107
				$value='null';
108
				break;
109
			case 'string':
110
				$value="'$value'";
111
				break;
112
		}
113
		return "$value";
114
	}
115
116
	private function getValueConversionString($type)
117
	{
118
		switch($type)
119
		{
120
			case 'integer': return 'TPropertyValue::ensureInteger($value)';
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
121
			case 'float': return 'TPropertyValue::ensureFloat($value)';
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
122
			case 'boolean': return 'TPropertyValue::ensureBoolean($value)';
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
123
			case 'enumerable': return 'TPropertyValue::ensureEnum($value)';
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
124
			case 'mixed': return '$value';
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
125
			case 'string': return 'TPropertyValue::ensureString($value)';
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
126
		}
127
	}
128
129
	protected function renderProperties($writer)
130
	{
131
		foreach($this->Properties as $property)
0 ignored issues
show
Bug introduced by
The property Properties does not seem to exist. Did you mean _properties?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
132
		{
133
			$name=$property->Name;
134
			if($name==='')
135
				continue;
136
			$comments=implode("\n\t * ",explode("\n",wordwrap($property->Comments)));
137
			$access=$property->IsProtected?'protected':'public';
138
			$setter='set'.$property->Name.'($value)';
139
			$getter='get'.$property->Name.'()';
140
			$value=$this->getValueAsString($property->DefaultValue,$property->Type);
141
			if($property->Storage==='ViewState')
142
			{
143
				$readStatement="return \$this->getViewState('$name',$value);";
144
				$writeStatement="\$this->setViewState('$name',".$this->getValueConversionString($property->Type).",$value);";
145
			}
146
			else if($property->Storage==='ControlState')
147
			{
148
				$readStatement="return \$this->getControlState('$name',$value);";
149
				$writeStatement="\$this->setControlState('$name',".$this->getValueConversionString($property->Type).",$value);";
150
			}
151
			else
152
			{
153
				$varname=$this->getVariableName($property->Name);
154
				$readStatement="return \$this->$varname;";
155
				$writeStatement="\$this->$varname=".$this->getValueConversionString($property->Type).";";
156
			}
157
			$writer->write("\n\t/**\n\t * @return {$property->Type} $comments Defaults to $value.\n\t */\n");
158
			$writer->write("\t$access function $getter\n\t{\n\t\t$readStatement\n\t}\n");
159
			if(!$property->ReadOnly)
160
			{
161
				$writer->write("\n\t/**\n\t * @param {$property->Type} $comments\n\t */\n");
162
				$writer->write("\t$access function $setter\n\t{\n\t\t$writeStatement\n\t}\n");
163
			}
164
		}
165
	}
166
167
	protected function renderEvents($writer)
168
	{
169
		foreach($this->Events as $event)
0 ignored issues
show
Bug introduced by
The property Events does not seem to exist. Did you mean _events?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
170
		{
171
			$name=$event->Name;
172
			if($name==='')
173
				continue;
174
			if(strncasecmp($name,'on',2)!==0)
175
				$name='On'.$name;
176
			else
177
			{
178
				$name[0]='O';
179
				$name[1]='n';
180
			}
181
			$methodName=$name;
182
			$methodName[0]='o';
183
			$comments=implode("\n\t * ",explode("\n",wordwrap($event->Comments)));
184
			$writer->write("\n\t/**\n\t * Raises <b>$name</b> event.\n\t * $comments\n\t * @param TEventParameter event parameter\n\t */\n");
185
			$writer->write("\tpublic function $methodName(\$param)\n\t{\n\t\t\$this->raiseEvent('$name',\$this,\$param);\n\t}\n");
186
		}
187
	}
188
189
	public function getClassName()
190
	{
191
		return $this->_className;
192
	}
193
194
	public function setClassName($value)
195
	{
196
		$this->_className=trim($value);
197
	}
198
199
	public function getParentClass()
200
	{
201
		return $this->_parentClass;
202
	}
203
204
	public function setParentClass($value)
205
	{
206
		$this->_parentClass=trim($value);
207
	}
208
209
	public function getInterfaces()
210
	{
211
		return $this->_interfaces;
212
	}
213
214
	public function setInterfaces($value)
215
	{
216
		$this->_interfaces=$value;
217
	}
218
219
	public function getProperties()
220
	{
221
		if(!$this->_properties)
222
			$this->_properties=new TList;
223
		return $this->_properties;
224
	}
225
226
	public function getEvents()
227
	{
228
		if(!$this->_events)
229
			$this->_events=new TList;
230
		return $this->_events;
231
	}
232
233
	public function getComments()
234
	{
235
		return $this->_comments;
236
	}
237
238
	public function setComments($value)
239
	{
240
		$this->_comments=$value;
241
	}
242
243
	public function getAuthor()
244
	{
245
		return $this->_author;
246
	}
247
248
	public function setAuthor($value)
249
	{
250
		$this->_author=trim($value);
251
	}
252
253
	public function getEmail()
254
	{
255
		return $this->_email;
256
	}
257
258
	public function setEmail($value)
259
	{
260
		$this->_email=trim($value);
261
	}
262
}
263
264
class EventDefinition extends TComponent
265
{
266
	private $_name='';
267
	private $_comments='';
268
269
	public function getName()
270
	{
271
		return $this->_name;
272
	}
273
274
	public function setName($value)
275
	{
276
		$this->_name=ucfirst(trim($value));
277
	}
278
279
	public function getComments()
280
	{
281
		return $this->_comments;
282
	}
283
284
	public function setComments($value)
285
	{
286
		$this->_comments=$value;
287
	}
288
}
289
290
class PropertyDefinition extends TComponent
291
{
292
	private $_name='';
293
	private $_type='string';
294
	private $_default='';
295
	private $_readOnly=false;
296
	private $_protected=false;
297
	private $_storage='ViewState';
298
	private $_comments='';
299
300
	public function getName()
301
	{
302
		return $this->_name;
303
	}
304
305
	public function setName($value)
306
	{
307
		$this->_name=ucfirst(trim($value));
308
	}
309
310
	public function getType()
311
	{
312
		return $this->_type;
313
	}
314
315
	public function setType($value)
316
	{
317
		$this->_type=trim($value);
318
	}
319
320
	public function getDefaultValue()
321
	{
322
		return $this->_default;
323
	}
324
325
	public function setDefaultValue($value)
326
	{
327
		$this->_default=trim($value);
328
	}
329
330
	public function getReadOnly()
331
	{
332
		return $this->_readOnly;
333
	}
334
335
	public function setReadOnly($value)
336
	{
337
		$this->_readOnly=TPropertyValue::ensureBoolean($value);
338
	}
339
340
	public function getIsProtected()
341
	{
342
		return $this->_protected;
343
	}
344
345
	public function setIsProtected($value)
346
	{
347
		$this->_protected=TPropertyValue::ensureBoolean($value);
348
	}
349
350
	public function getStorage()
351
	{
352
		return $this->_storage;
353
	}
354
355
	public function setStorage($value)
356
	{
357
		$this->_storage=trim($value);
358
	}
359
360
	public function getComments()
361
	{
362
		return $this->_comments;
363
	}
364
365
	public function setComments($value)
366
	{
367
		$this->_comments=$value;
368
	}
369
}
370
371