Passed
Push — master ( ef609f...421c61 )
by Jean-Christophe
02:48
created

InstanceViewer::setDefaultValueFunction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Ajax\semantic\widgets\base;
3
use Ajax\service\JString;
4
use Ajax\service\JArray;
5
use Ajax\service\JReflection;
6
7
class InstanceViewer {
8
	protected $widgetIdentifier;
9
	protected $instance;
10
	protected $reflect;
11
	protected $properties;
12
	protected $visibleProperties;
13
	protected $values;
14
	protected $afterCompile;
15
	protected $captions;
16
	protected $captionCallback;
17
	protected $defaultValueFunction;
18
19
20
	public static $index=0;
21
22
	public function __construct($identifier,$instance=NULL,$captions=NULL){
23
		$this->widgetIdentifier=$identifier;
24
		$this->values=[];
25
		$this->afterCompile=[];
26
		if(isset($instance))
27
			$this->setInstance($instance);
28
		$this->setCaptions($captions);
29
		$this->captionCallback=NULL;
30
		$this->defaultValueFunction=function($name,$value){return $value;};
31
	}
32
33
	public function moveFieldTo($from,$to){
34
		if(JArray::moveElementTo($this->visibleProperties, $from, $to)){
35
			return JArray::moveElementTo($this->values, $from, $to);
36
		}
37
		return false;
38
	}
39
40
	public function swapFields($index1,$index2){
41
		if(JArray::swapElements($this->visibleProperties, $index1, $index2)){
42
			return JArray::swapElements($this->values, $index1, $index2);
43
		}
44
		return false;
45
	}
46
47
	public function removeField($index){
48
		\array_splice($this->visibleProperties,$index,1);
49
		\array_splice($this->values,$index,1);
50
		\array_splice($this->captions,$index,1);
51
		return $this;
52
	}
53
54
	public function getValues(){
55
		$values=[];
56
		$index=0;
57
		$count=$this->count();
58
		while($index<$count){
59
			$values[]=$this->getValue($index++);
60
		}
61
		return $values;
62
	}
63
64
	public function getIdentifier($index=NULL){
65
		if(!isset($index))
66
			$index=self::$index;
67
		$value=$index;
68
		if(isset($this->values["identifier"])){
69
			if(\is_string($this->values["identifier"]))
70
				$value=JReflection::callMethod($this->instance, $this->values["identifier"], []);
71
			else
72
				$value=$this->values["identifier"]($index,$this->instance);
73
		}
74
		return $value;
75
	}
76
77
	public function getValue($index){
78
		$property=$this->properties[$index];
79
		return $this->_getValue($property, $index);
80
	}
81
82
	protected function _beforeAddProperty($index,&$field){
83
84
	}
85
86
	protected function _getDefaultValue($name,$value,$index){
87
		$func=$this->defaultValueFunction;
88
		//TODO Check bug on index
89
		return $func($name,$value,$index,$this->instance);
90
	}
91
92
	protected function _getPropertyValue(\ReflectionProperty $property,$index){
0 ignored issues
show
Unused Code introduced by
The parameter $index 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

92
	protected function _getPropertyValue(\ReflectionProperty $property,/** @scrutinizer ignore-unused */ $index){

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...
93
		$property->setAccessible(true);
94
		return $property->getValue($this->instance);
95
	}
96
97
	protected function _getValue($property,$index){
98
		$value=null;
99
		$propertyName=$property;
100
		if($property instanceof \ReflectionProperty){
101
			$value=$this->_getPropertyValue($property, $index);
102
			$propertyName=$property->getName();
103
		}elseif(\is_callable($property))
104
			$value=$property($this->instance);
105
		elseif(\is_array($property)){
106
			$values=\array_map(function($v) use ($index){return $this->_getValue($v, $index);}, $property);
107
			$value=\implode("", $values);
108
		}elseif(\is_string($property)){
109
			$value=$property;
110
			if(isset($this->instance->{$property})){
111
				$value=$this->instance->{$property};
112
			}elseif(\method_exists($this->instance, $getter=JReflection::getterName($property))){
113
				$value=JReflection::callMethod($this->instance, $getter, []);
114
			}
115
		}
116
		return $this->_postGetValue($index, $propertyName, $value);
117
	}
118
119
	protected function _postGetValue($index,$propertyName,$value){
120
		if(isset($this->values[$index])){
121
			$value= $this->values[$index]($value,$this->instance,$index,self::$index);
122
		}else{
123
			$value=$this->_getDefaultValue($propertyName,$value, $index,self::$index);
0 ignored issues
show
Unused Code introduced by
The call to Ajax\semantic\widgets\ba...wer::_getDefaultValue() has too many arguments starting with self::index. ( Ignorable by Annotation )

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

123
			/** @scrutinizer ignore-call */ 
124
   $value=$this->_getDefaultValue($propertyName,$value, $index,self::$index);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
124
		}
125
		if(isset($this->afterCompile[$index])){
126
			if(\is_callable($this->afterCompile[$index])){
127
				$this->afterCompile[$index]($value,$this->instance,self::$index);
128
			}
129
		}
130
		return $value;
131
	}
132
133
	public function insertField($index,$field){
134
		array_splice( $this->visibleProperties, $index, 0, $field );
135
		return $this;
136
	}
137
138
	public function insertInField($index,$field){
139
		$vb=$this->visibleProperties;
140
		if(isset($vb[$index])){
141
			if(\is_array($vb[$index])){
142
				$this->visibleProperties[$index][]=$field;
143
			}else{
144
				$this->visibleProperties[$index]=[$vb[$index],$field];
145
			}
146
		}else{
147
			return $this->insertField($index, $field);
148
		}
149
		return $this;
150
	}
151
152
	public function addField($field){
153
		$this->visibleProperties[]=$field;
154
		return $this;
155
	}
156
157
	public function addFields($fields){
158
		$this->visibleProperties=\array_merge($this->visibleProperties,$fields);
159
		return $this;
160
	}
161
162
	public function count(){
163
		return \sizeof($this->properties);
164
	}
165
166
	public function visiblePropertiesCount(){
167
		return \sizeof($this->visibleProperties);
168
	}
169
170
	public function getProperty($index){
171
		return $this->properties[$index];
172
	}
173
174
	public function getFieldName($index){
175
		$property=$this->getProperty($index);
176
		if($property instanceof \ReflectionProperty){
177
			$result=$property->getName();
178
		}elseif(\is_callable($property)){
179
			$result=$this->visibleProperties[$index];
180
		}else{
181
			$result=$property;
182
		}
183
		return $result;
184
	}
185
186
187
	protected function showableProperty(\ReflectionProperty $rProperty){
188
		return JString::startswith($rProperty->getName(),"_")===false;
189
	}
190
191
	public function setInstance($instance) {
192
		if(\is_string($instance)){
193
			$instance=new $instance();
194
		}
195
		$this->instance=$instance;
196
		$this->properties=[];
197
		$this->reflect=new \ReflectionClass($instance);
198
		if(\sizeof($this->visibleProperties)===0){
199
			$this->properties=$this->getDefaultProperties();
200
		}else{
201
			foreach ($this->visibleProperties as $property){
202
				$this->setInstanceProperty($property);
203
			}
204
		}
205
		return $this;
206
	}
207
208
	private function setInstanceProperty($property){
209
		if(\is_callable($property)){
210
			$this->properties[]=$property;
211
		}elseif(\is_string($property)){
212
			try{
213
				$this->_beforeAddProperty(\sizeof($this->properties), $property);
214
				$rProperty=$this->reflect->getProperty($property);
215
				$this->properties[]=$rProperty;
216
			}catch(\Exception $e){
217
				$this->_beforeAddProperty(\sizeof($this->properties), $property);
218
				$this->properties[]=$property;
219
			}
220
		}elseif(\is_int($property)){
221
			$props=$this->getDefaultProperties();
222
			if(isset($props[$property]))
223
				$this->properties[]=$props[$property];
224
				else
225
					$this->properties[]=$property;
226
		}else{
227
			$this->properties[]=$property;
228
		}
229
	}
230
231
	protected function getDefaultProperties(){
232
		$result=[];
233
		$properties=$this->reflect->getProperties();
234
		foreach ($properties as $property){
235
			$showable=$this->showableProperty($property);
236
			if($showable!==false){
237
				$result[]=$property;
238
			}
239
		}
240
		return $result;
241
	}
242
243
	public function setVisibleProperties($visibleProperties) {
244
		$this->visibleProperties=$visibleProperties;
245
		return $this;
246
	}
247
248
	public function setValueFunction($index,$callback){
249
		$this->values[$index]=$callback;
250
		return $this;
251
	}
252
253
	public function setIdentifierFunction($callback){
254
		$this->values["identifier"]=$callback;
255
		return $this;
256
	}
257
258
	public static function setIndex($index) {
259
		self::$index=$index;
260
	}
261
262
	public function getProperties() {
263
		return $this->properties;
264
	}
265
266
	public function getCaption($index){
267
		if(isset($this->captions[$index])){
268
			return $this->captions[$index];
269
		}
270
		if($this->properties[$index] instanceof \ReflectionProperty)
271
			return $this->properties[$index]->getName();
272
		elseif(\is_callable($this->properties[$index]))
273
			return "";
274
		else
275
			return $this->properties[$index];
276
	}
277
278
	public function getCaptions(){
279
		$count=$this->count();
280
		if(isset($this->captions)){
281
			$captions= \array_values($this->captions);
282
			$captionsSize=\sizeof($captions);
283
			for($i=$captionsSize;$i<$count;$i++){
284
				$captions[]="";
285
			}
286
		}else{
287
			$captions=[];
288
			$index=0;
289
			while($index<$count){
290
				$captions[]=$this->getCaption($index++);
291
			}
292
		}
293
		if(isset($this->captionCallback) && \is_callable($this->captionCallback)){
294
			$callback=$this->captionCallback;
295
			$callback($captions,$this->instance);
296
		}
297
		return $captions;
298
	}
299
300
	public function setCaption($index,$caption){
301
		if(isset($this->captions)===false)
302
			$this->captions=[];
303
		$this->captions[$index]=$caption;
304
		return $this;
305
	}
306
307
	public function setCaptions($captions) {
308
		$this->captions=$captions;
309
		return $this;
310
	}
311
312
	/**
313
	 * Associates a $callback function after the compilation of the field at $index position
314
	 * The $callback function can take the following arguments : $field=>the compiled field, $instance : the active instance of the object, $index: the field position
315
	 * @param int $index postion of the compiled field
316
	 * @param callable $callback function called after the field compilation
317
	 * @return \Ajax\semantic\widgets\datatable\InstanceViewer
0 ignored issues
show
Bug introduced by
The type Ajax\semantic\widgets\datatable\InstanceViewer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
318
	 */
319
	public function afterCompile($index,$callback){
320
		$this->afterCompile[$index]=$callback;
321
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Ajax\semantic\widgets\base\InstanceViewer which is incompatible with the documented return type Ajax\semantic\widgets\datatable\InstanceViewer.
Loading history...
322
	}
323
324
	/**
325
	 * Defines a callback function to call for modifying captions
326
	 * function parameters are $captions: the captions to modify and $instance: the active model instance
327
	 * @param callable $captionCallback
328
	 * @return \Ajax\semantic\widgets\base\InstanceViewer
329
	 */
330
	public function setCaptionCallback($captionCallback) {
331
		$this->captionCallback=$captionCallback;
332
		return $this;
333
	}
334
335
	/**
336
	 * Defines the default function which displays fields value
337
	 * @param callable $defaultValueFunction function parameters are : $name : the field name, $value : the field value ,$index : the field index, $instance : the active instance of model
338
	 * @return \Ajax\semantic\widgets\base\InstanceViewer
339
	 */
340
	public function setDefaultValueFunction($defaultValueFunction) {
341
		$this->defaultValueFunction=$defaultValueFunction;
342
		return $this;
343
	}
344
345
	public function getVisibleProperties() {
346
		return $this->visibleProperties;
347
	}
348
349
}
350