Passed
Push — master ( 331007...008e10 )
by Jean-Christophe
02:18
created

InstanceViewer::setInstanceProperty()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 20
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 18
nc 8
nop 1
dl 0
loc 20
rs 8.8571
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
	protected $groupByFields;
19
20
21
	public static $index=0;
22
23
	public function __construct($identifier,$instance=NULL,$captions=NULL){
24
		$this->widgetIdentifier=$identifier;
25
		$this->values=[];
26
		$this->afterCompile=[];
27
		if(isset($instance))
28
			$this->setInstance($instance);
29
		$this->setCaptions($captions);
30
		$this->captionCallback=NULL;
31
		$this->defaultValueFunction=function($name,$value){return $value;};
32
	}
33
34
	public function moveFieldTo($from,$to){
35
		if(JArray::moveElementTo($this->visibleProperties, $from, $to)){
36
			return JArray::moveElementTo($this->values, $from, $to);
37
		}
38
		return false;
39
	}
40
41
	public function swapFields($index1,$index2){
42
		if(JArray::swapElements($this->visibleProperties, $index1, $index2)){
43
			return JArray::swapElements($this->values, $index1, $index2);
44
		}
45
		return false;
46
	}
47
48
	public function removeField($index){
49
		\array_splice($this->visibleProperties,$index,1);
50
		\array_splice($this->values,$index,1);
51
		\array_splice($this->captions,$index,1);
52
		return $this;
53
	}
54
55
	public function getValues(){
56
		$values=[];
57
		$index=0;
58
		$count=$this->count();
59
		$hasGroupby=is_array($this->groupByFields);
60
		if(!$hasGroupby){
61
			while($index<$count){
62
					$values[]=$this->getValue($index++);
63
			}
64
		}else{
65
			while($index<$count){
66
				if(array_search($index, $this->groupByFields)===false){
67
					$values[]=$this->getValue($index);
68
				}
69
				$index++;
70
			}
71
		}
72
		return $values;
73
	}
74
75
	public function getIdentifier($index=NULL){
76
		if(!isset($index))
77
			$index=self::$index;
78
		$value=$index;
79
		if(isset($this->values["identifier"])){
80
			if(\is_string($this->values["identifier"]))
81
				$value=JReflection::callMethod($this->instance, $this->values["identifier"], []);
82
			else
83
				$value=$this->values["identifier"]($index,$this->instance);
84
		}
85
		return $value;
86
	}
87
88
	public function getValue($index){
89
		$property=$this->properties[$index];
90
		return $this->_getValue($property, $index);
91
	}
92
93
	protected function _beforeAddProperty($index,&$field){
94
95
	}
96
97
	protected function _getDefaultValue($name,$value,$index){
98
		$func=$this->defaultValueFunction;
99
		return $func($name,$value,$index,$this->instance);
100
	}
101
102
	protected function _getPropertyValue(\ReflectionProperty $property){
103
		$property->setAccessible(true);
104
		return $property->getValue($this->instance);
105
	}
106
107
	protected function _getValue($property,$index){
108
		$value=null;
109
		$propertyName=$property;
110
		if($property instanceof \ReflectionProperty){
111
			$value=$this->_getPropertyValue($property);
112
			$propertyName=$property->getName();
113
		}elseif(\is_callable($property) && array_search($property, ["system"])===false)
114
			$value=$property($this->instance);
115
		elseif(\is_array($property)){
116
			$values=\array_map(function($v) use ($index){return $this->_getValue($v, $index);}, $property);
117
			$value=\implode("", $values);
118
		}elseif(\is_string($property)){
119
			$value=$property;
120
			if(isset($this->instance->{$property})){
121
				$value=$this->instance->{$property};
122
			}elseif(\method_exists($this->instance, $getter=JReflection::getterName($property))){
123
				$value=JReflection::callMethod($this->instance, $getter, []);
124
			}
125
		}
126
		return $this->_postGetValue($index, $propertyName, $value);
127
	}
128
129
	protected function _postGetValue($index,$propertyName,$value){
130
		if(isset($this->values[$index])){
131
			$value= $this->values[$index]($value,$this->instance,$index,self::$index);
132
		}else{
133
			$value=$this->_getDefaultValue($propertyName,$value, $index);
134
		}
135
		if(isset($this->afterCompile[$index])){
136
			if(\is_callable($this->afterCompile[$index])){
137
				$this->afterCompile[$index]($value,$this->instance,self::$index);
138
			}
139
		}
140
		return $value;
141
	}
142
143
	public function insertField($index,$field,$key=null){
144
		if(isset($key)){
145
			array_splice( $this->visibleProperties, $index, 0, [$key=>$field] );
146
		}else{
147
			array_splice( $this->visibleProperties, $index, 0, $field );
148
		}
149
		return $this;
150
	}
151
	
152
	public function sortColumnContent($index,$array){
153
		if(isset($this->visibleProperties[$index])){
154
			if(is_array($this->visibleProperties[$index])){
155
				$this->visibleProperties[$index]=JArray::sortAssociative($this->visibleProperties[$index],$array);
156
			}
157
		}
158
		return $this;
159
	}
160
161
	public function insertInField($index,$field,$key=null){
162
		$vb=$this->visibleProperties;
163
		if(isset($vb[$index])){
164
			if(isset($key)){
165
				if(\is_array($vb[$index])){
166
					$this->visibleProperties[$index][$key]=$field;
167
				}else{
168
					$this->visibleProperties[$index]=[$vb[$index],$key=>$field];
169
				}
170
			}else{
171
				if(\is_array($vb[$index])){
172
					$this->visibleProperties[$index][]=$field;
173
				}else{
174
					$this->visibleProperties[$index]=[$vb[$index],$field];
175
				}
176
			}
177
		}else{
178
			return $this->insertField($index, $field);
179
		}
180
		return $this;
181
	}
182
183
	public function addField($field,$key=null){
184
		if(isset($key)){
185
			$this->visibleProperties[]=[$key=>$field];
186
		}else{
187
			$this->visibleProperties[]=$field;
188
		}
189
		return $this;
190
	}
191
192
	public function addFields($fields){
193
		$this->visibleProperties=\array_merge($this->visibleProperties,$fields);
194
		return $this;
195
	}
196
197
	public function count(){
198
		return \sizeof($this->properties);
199
	}
200
201
	public function visiblePropertiesCount(){
202
		return \sizeof($this->visibleProperties);
203
	}
204
205
	public function getProperty($index){
206
		return $this->properties[$index];
207
	}
208
209
	public function getFieldName($index){
210
		$property=$this->getProperty($index);
211
		if($property instanceof \ReflectionProperty){
212
			$result=$property->getName();
213
		}elseif(\is_callable($property)){
214
			$result=$this->visibleProperties[$index];
215
		}else{
216
			$result=$property;
217
		}
218
		return $result;
219
	}
220
221
222
	protected function showableProperty(\ReflectionProperty $rProperty){
223
		return JString::startswith($rProperty->getName(),"_")===false;
224
	}
225
226
	public function setInstance($instance) {
227
		if(\is_string($instance)){
228
			$instance=new $instance();
229
		}
230
		$this->instance=$instance;
231
		$this->properties=[];
232
		$this->reflect=new \ReflectionClass($instance);
233
		if(JArray::count($this->visibleProperties)===0){
234
			$this->properties=$this->getDefaultProperties();
235
		}else{
236
			foreach ($this->visibleProperties as $property){
237
				$this->setInstanceProperty($property);
238
			}
239
		}
240
		return $this;
241
	}
242
243
	private function setInstanceProperty($property){
244
		if(\is_callable($property)){
245
			$this->properties[]=$property;
246
		}elseif(\is_string($property)){
247
			try{
248
				$this->_beforeAddProperty(\sizeof($this->properties), $property);
249
				$rProperty=$this->reflect->getProperty($property);
250
				$this->properties[]=$rProperty;
251
			}catch(\Exception $e){
252
				$this->_beforeAddProperty(\sizeof($this->properties), $property);
253
				$this->properties[]=$property;
254
			}
255
		}elseif(\is_int($property)){
256
			$props=$this->getDefaultProperties();
257
			if(isset($props[$property]))
258
				$this->properties[]=$props[$property];
259
				else
260
					$this->properties[]=$property;
261
		}else{
262
			$this->properties[]=$property;
263
		}
264
	}
265
266
	protected function getDefaultProperties(){
267
		$result=[];
268
		$properties=$this->reflect->getProperties();
269
		foreach ($properties as $property){
270
			$showable=$this->showableProperty($property);
271
			if($showable!==false){
272
				$result[]=$property;
273
			}
274
		}
275
		return $result;
276
	}
277
278
	public function setVisibleProperties($visibleProperties) {
279
		$this->visibleProperties=$visibleProperties;
280
		return $this;
281
	}
282
283
	public function setValueFunction($index,$callback){
284
		$this->values[$index]=$callback;
285
		return $this;
286
	}
287
288
	public function setIdentifierFunction($callback){
289
		$this->values["identifier"]=$callback;
290
		return $this;
291
	}
292
293
	public static function setIndex($index) {
294
		self::$index=$index;
295
	}
296
297
	public function getProperties() {
298
		return $this->properties;
299
	}
300
301
	public function getCaption($index){
302
		if(isset($this->captions[$index])){
303
			return $this->captions[$index];
304
		}
305
		if($this->properties[$index] instanceof \ReflectionProperty)
306
			return $this->properties[$index]->getName();
307
		elseif(\is_callable($this->properties[$index]))
308
			return "";
309
		else
310
			return $this->properties[$index];
311
	}
312
313
	public function getCaptions(){
314
		$hasGroupby=is_array($this->groupByFields);
315
		$count=$this->count()-$this->getGroupByFieldsCount();
316
		if(isset($this->captions)){
317
			$captions= \array_values($this->captions);
318
			$captionsSize=\sizeof($captions);
319
			for($i=$captionsSize;$i<$count;$i++){
320
				$captions[]="";
321
			}
322
		}else{
323
			$captions=[];
324
			$index=0;
325
			if(!$hasGroupby){
326
				while($index<$count){
327
						$captions[]=$this->getCaption($index++);
328
				}
329
			}else{
330
				while($index<$count){
331
					if($hasGroupby && array_search($index, $this->groupByFields)===false){
332
						$captions[]=$this->getCaption($index);
333
					}
334
					$index++;
335
				}
336
			}
337
		}
338
		if(isset($this->captionCallback) && \is_callable($this->captionCallback)){
339
			$callback=$this->captionCallback;
340
			$callback($captions,$this->instance);
341
		}
342
		return $captions;
343
	}
344
345
	public function setCaption($index,$caption){
346
		if(isset($this->captions)===false)
347
			$this->captions=[];
348
		$this->captions[$index]=$caption;
349
		return $this;
350
	}
351
352
	public function setCaptions($captions) {
353
		$this->captions=$captions;
354
		return $this;
355
	}
356
357
	/**
358
	 * Associates a $callback function after the compilation of the field at $index position
359
	 * The $callback function can take the following arguments : $field=>the compiled field, $instance : the active instance of the object, $index: the field position
360
	 * @param int $index postion of the compiled field
361
	 * @param callable $callback function called after the field compilation
362
	 * @return InstanceViewer
363
	 */
364
	public function afterCompile($index,$callback){
365
		$this->afterCompile[$index]=$callback;
366
		return $this;
367
	}
368
369
	/**
370
	 * Defines a callback function to call for modifying captions
371
	 * function parameters are $captions: the captions to modify and $instance: the active model instance
372
	 * @param callable $captionCallback
373
	 * @return \Ajax\semantic\widgets\base\InstanceViewer
374
	 */
375
	public function setCaptionCallback($captionCallback) {
376
		$this->captionCallback=$captionCallback;
377
		return $this;
378
	}
379
380
	/**
381
	 * Defines the default function which displays fields value
382
	 * @param callable $defaultValueFunction function parameters are : $name : the field name, $value : the field value ,$index : the field index, $instance : the active instance of model
383
	 * @return \Ajax\semantic\widgets\base\InstanceViewer
384
	 */
385
	public function setDefaultValueFunction($defaultValueFunction) {
386
		$this->defaultValueFunction=$defaultValueFunction;
387
		return $this;
388
	}
389
390
	public function getVisibleProperties() {
391
		return $this->visibleProperties;
392
	}
393
	
394
	public function getSimpleProperties() {
395
		return array_filter($this->visibleProperties,function($item){
396
			return !(is_array($item) || is_object($item));
397
		});
398
	}
399
400
	/**
401
	 * @return callable
402
	 */
403
	public function getDefaultValueFunction() {
404
		return $this->defaultValueFunction;
405
	}
406
	/**
407
	 * @return mixed
408
	 */
409
	public function getGroupByFields() {
410
		return $this->groupByFields;
411
	}
412
413
	/**
414
	 * @param mixed $groupByFields
415
	 */
416
	public function setGroupByFields($groupByFields) {
417
		$this->groupByFields = $groupByFields;
418
	}
419
	
420
	public function getGroupByFieldsCount(){
421
		if(is_array($this->groupByFields)){
422
			return sizeof($this->groupByFields);
423
		}
424
		return 0;
425
	}
426
427
}
428