Completed
Push — master ( da7bd7...a4feba )
by Jean-Christophe
03:22
created

InstanceViewer::getVisibleProperties()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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