Passed
Push — master ( 468e47...0bebef )
by Jean-Christophe
02:09
created

InstanceViewer::getIdentifier()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 6
nop 1
dl 0
loc 11
rs 9.2
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
		return $func($name,$value,$index,$this->instance);
89
	}
90
91
	protected function _getPropertyValue(\ReflectionProperty $property){
92
		$property->setAccessible(true);
93
		return $property->getValue($this->instance);
94
	}
95
96
	protected function _getValue($property,$index){
97
		$value=null;
98
		$propertyName=$property;
99
		if($property instanceof \ReflectionProperty){
100
			$value=$this->_getPropertyValue($property);
101
			$propertyName=$property->getName();
102
		}elseif(\is_callable($property) && array_search($property, ["system"])===false)
103
			$value=$property($this->instance);
104
		elseif(\is_array($property)){
105
			$values=\array_map(function($v) use ($index){return $this->_getValue($v, $index);}, $property);
106
			$value=\implode("", $values);
107
		}elseif(\is_string($property)){
108
			$value=$property;
109
			if(isset($this->instance->{$property})){
110
				$value=$this->instance->{$property};
111
			}elseif(\method_exists($this->instance, $getter=JReflection::getterName($property))){
112
				$value=JReflection::callMethod($this->instance, $getter, []);
113
			}
114
		}
115
		return $this->_postGetValue($index, $propertyName, $value);
116
	}
117
118
	protected function _postGetValue($index,$propertyName,$value){
119
		if(isset($this->values[$index])){
120
			$value= $this->values[$index]($value,$this->instance,$index,self::$index);
121
		}else{
122
			$value=$this->_getDefaultValue($propertyName,$value, $index);
123
		}
124
		if(isset($this->afterCompile[$index])){
125
			if(\is_callable($this->afterCompile[$index])){
126
				$this->afterCompile[$index]($value,$this->instance,self::$index);
127
			}
128
		}
129
		return $value;
130
	}
131
132
	public function insertField($index,$field,$key=null){
133
		if(isset($key)){
134
			array_splice( $this->visibleProperties, $index, 0, [$key=>$field] );
135
		}else{
136
			array_splice( $this->visibleProperties, $index, 0, $field );
137
		}
138
		return $this;
139
	}
140
	
141
	public function sortColumnContent($index,$array){
142
		if(isset($this->visibleProperties[$index])){
143
			if(is_array($this->visibleProperties[$index])){
144
				$this->visibleProperties[$index]=JArray::sortAssociative($this->visibleProperties[$index],$array);
145
			}
146
		}
147
		return $this;
148
	}
149
150
	public function insertInField($index,$field,$key=null){
151
		$vb=$this->visibleProperties;
152
		if(isset($vb[$index])){
153
			if(isset($key)){
154
				if(\is_array($vb[$index])){
155
					$this->visibleProperties[$index][$key]=$field;
156
				}else{
157
					$this->visibleProperties[$index]=[$vb[$index],$key=>$field];
158
				}
159
			}else{
160
				if(\is_array($vb[$index])){
161
					$this->visibleProperties[$index][]=$field;
162
				}else{
163
					$this->visibleProperties[$index]=[$vb[$index],$field];
164
				}
165
			}
166
		}else{
167
			return $this->insertField($index, $field);
168
		}
169
		return $this;
170
	}
171
172
	public function addField($field,$key=null){
173
		if(isset($key)){
174
			$this->visibleProperties[]=[$key=>$field];
175
		}else{
176
			$this->visibleProperties[]=$field;
177
		}
178
		return $this;
179
	}
180
181
	public function addFields($fields){
182
		$this->visibleProperties=\array_merge($this->visibleProperties,$fields);
183
		return $this;
184
	}
185
186
	public function count(){
187
		return \sizeof($this->properties);
188
	}
189
190
	public function visiblePropertiesCount(){
191
		return \sizeof($this->visibleProperties);
192
	}
193
194
	public function getProperty($index){
195
		return $this->properties[$index];
196
	}
197
198
	public function getFieldName($index){
199
		$property=$this->getProperty($index);
200
		if($property instanceof \ReflectionProperty){
201
			$result=$property->getName();
202
		}elseif(\is_callable($property)){
203
			$result=$this->visibleProperties[$index];
204
		}else{
205
			$result=$property;
206
		}
207
		return $result;
208
	}
209
210
211
	protected function showableProperty(\ReflectionProperty $rProperty){
212
		return JString::startswith($rProperty->getName(),"_")===false;
213
	}
214
215
	public function setInstance($instance) {
216
		if(\is_string($instance)){
217
			$instance=new $instance();
218
		}
219
		$this->instance=$instance;
220
		$this->properties=[];
221
		$this->reflect=new \ReflectionClass($instance);
222
		if(JArray::count($this->visibleProperties)===0){
223
			$this->properties=$this->getDefaultProperties();
224
		}else{
225
			foreach ($this->visibleProperties as $property){
226
				$this->setInstanceProperty($property);
227
			}
228
		}
229
		return $this;
230
	}
231
232
	private function setInstanceProperty($property){
233
		if(\is_callable($property)){
234
			$this->properties[]=$property;
235
		}elseif(\is_string($property)){
236
			try{
237
				$this->_beforeAddProperty(\sizeof($this->properties), $property);
238
				$rProperty=$this->reflect->getProperty($property);
239
				$this->properties[]=$rProperty;
240
			}catch(\Exception $e){
241
				$this->_beforeAddProperty(\sizeof($this->properties), $property);
242
				$this->properties[]=$property;
243
			}
244
		}elseif(\is_int($property)){
245
			$props=$this->getDefaultProperties();
246
			if(isset($props[$property]))
247
				$this->properties[]=$props[$property];
248
				else
249
					$this->properties[]=$property;
250
		}else{
251
			$this->properties[]=$property;
252
		}
253
	}
254
255
	protected function getDefaultProperties(){
256
		$result=[];
257
		$properties=$this->reflect->getProperties();
258
		foreach ($properties as $property){
259
			$showable=$this->showableProperty($property);
260
			if($showable!==false){
261
				$result[]=$property;
262
			}
263
		}
264
		return $result;
265
	}
266
267
	public function setVisibleProperties($visibleProperties) {
268
		$this->visibleProperties=$visibleProperties;
269
		return $this;
270
	}
271
272
	public function setValueFunction($index,$callback){
273
		$this->values[$index]=$callback;
274
		return $this;
275
	}
276
277
	public function setIdentifierFunction($callback){
278
		$this->values["identifier"]=$callback;
279
		return $this;
280
	}
281
282
	public static function setIndex($index) {
283
		self::$index=$index;
284
	}
285
286
	public function getProperties() {
287
		return $this->properties;
288
	}
289
290
	public function getCaption($index){
291
		if(isset($this->captions[$index])){
292
			return $this->captions[$index];
293
		}
294
		if($this->properties[$index] instanceof \ReflectionProperty)
295
			return $this->properties[$index]->getName();
296
		elseif(\is_callable($this->properties[$index]))
297
			return "";
298
		else
299
			return $this->properties[$index];
300
	}
301
302
	public function getCaptions(){
303
		$count=$this->count();
304
		if(isset($this->captions)){
305
			$captions= \array_values($this->captions);
306
			$captionsSize=\sizeof($captions);
307
			for($i=$captionsSize;$i<$count;$i++){
308
				$captions[]="";
309
			}
310
		}else{
311
			$captions=[];
312
			$index=0;
313
			while($index<$count){
314
				$captions[]=$this->getCaption($index++);
315
			}
316
		}
317
		if(isset($this->captionCallback) && \is_callable($this->captionCallback)){
318
			$callback=$this->captionCallback;
319
			$callback($captions,$this->instance);
320
		}
321
		return $captions;
322
	}
323
324
	public function setCaption($index,$caption){
325
		if(isset($this->captions)===false)
326
			$this->captions=[];
327
		$this->captions[$index]=$caption;
328
		return $this;
329
	}
330
331
	public function setCaptions($captions) {
332
		$this->captions=$captions;
333
		return $this;
334
	}
335
336
	/**
337
	 * Associates a $callback function after the compilation of the field at $index position
338
	 * The $callback function can take the following arguments : $field=>the compiled field, $instance : the active instance of the object, $index: the field position
339
	 * @param int $index postion of the compiled field
340
	 * @param callable $callback function called after the field compilation
341
	 * @return InstanceViewer
342
	 */
343
	public function afterCompile($index,$callback){
344
		$this->afterCompile[$index]=$callback;
345
		return $this;
346
	}
347
348
	/**
349
	 * Defines a callback function to call for modifying captions
350
	 * function parameters are $captions: the captions to modify and $instance: the active model instance
351
	 * @param callable $captionCallback
352
	 * @return \Ajax\semantic\widgets\base\InstanceViewer
353
	 */
354
	public function setCaptionCallback($captionCallback) {
355
		$this->captionCallback=$captionCallback;
356
		return $this;
357
	}
358
359
	/**
360
	 * Defines the default function which displays fields value
361
	 * @param callable $defaultValueFunction function parameters are : $name : the field name, $value : the field value ,$index : the field index, $instance : the active instance of model
362
	 * @return \Ajax\semantic\widgets\base\InstanceViewer
363
	 */
364
	public function setDefaultValueFunction($defaultValueFunction) {
365
		$this->defaultValueFunction=$defaultValueFunction;
366
		return $this;
367
	}
368
369
	public function getVisibleProperties() {
370
		return $this->visibleProperties;
371
	}
372
	
373
	public function getSimpleProperties() {
374
		return array_filter($this->visibleProperties,function($item){
375
			return !(is_array($item) || is_object($item));
376
		});
377
	}
378
379
	/**
380
	 * @return callable
381
	 */
382
	public function getDefaultValueFunction() {
383
		return $this->defaultValueFunction;
384
	}
385
}
386