Completed
Push — master ( 04d259...772d83 )
by Jean-Christophe
03:54
created

InstanceViewer::_getValue()   D

Complexity

Conditions 9
Paths 21

Size

Total Lines 33
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 33
rs 4.909
cc 9
eloc 25
nc 21
nop 2
1
<?php
2
namespace Ajax\semantic\widgets\base;
3
use Ajax\service\JString;
4
5
class InstanceViewer {
6
	protected $widgetIdentifier;
7
	protected $instance;
8
	protected $reflect;
9
	protected $properties;
10
	protected $visibleProperties;
11
	protected $values;
12
	protected $afterCompile;
13
	protected $captions;
14
	protected $captionCallback;
15
	protected $defaultValueFunction;
16
17
18
	public static $index=0;
19
20
	public function __construct($identifier,$instance=NULL,$captions=NULL){
21
		$this->widgetIdentifier=$identifier;
22
		$this->values=[];
23
		$this->afterCompile=[];
24
		if(isset($instance))
25
			$this->setInstance($instance);
26
		$this->setCaptions($captions);
27
		$this->captionCallback=NULL;
28
		$this->defaultValueFunction=function($name,$value){return $value;};
29
	}
30
31
	public function getValues(){
32
		$values=[];
33
		$index=0;
34
		$count=$this->count();
35
		while($index<$count){
36
			$values[]=$this->getValue($index++);
37
		}
38
		return $values;
39
	}
40
41
	public function getIdentifier($index=NULL){
42
		if(!isset($index))
43
			$index=self::$index;
44
		$value=$index;
45
		if(isset($this->values["identifier"]))
46
			$value=$this->values["identifier"]($index,$this->instance);
47
		return $value;
48
	}
49
50
	public function getValue($index){
51
		$property=$this->properties[$index];
52
		return $this->_getValue($property, $index);
53
	}
54
55
	protected function _beforeAddProperty($index,&$field){
56
57
	}
58
59
	protected function _getDefaultValue($name,$value,$index){
60
		$func=$this->defaultValueFunction;
61
		return $func($name,$value,$index,$this->instance);
62
	}
63
64
	protected function _getValue($property,$index){
65
		if($property instanceof \ReflectionProperty){
66
			$property->setAccessible(true);
67
			$value=$property->getValue($this->instance);
68
			if(isset($this->values[$index])){
69
				$value= $this->values[$index]($value,$this->instance,$index);
70
			}else{
71
				$value=$this->_getDefaultValue($property->getName(),$value, $index);
72
			}
73
		}else{
74
			if(\is_callable($property))
75
				$value=$property($this->instance);
76
			elseif(\is_array($property)){
77
				$values=\array_map(function($v) use ($index){return $this->_getValue($v, $index);}, $property);
78
				$value=\implode("", $values);
79
			}else{
80
				if(isset($this->values[$index])){
81
					$value= $this->values[$index]($property,$this->instance,$index);
82
				}elseif(isset($this->instance->{$property})){
83
					$value=$this->instance->{$property};
84
				}
85
				else{
86
					$value=null;
87
				}
88
			}
89
		}
90
		if(isset($this->afterCompile[$index])){
91
			if(\is_callable($this->afterCompile[$index])){
92
				$this->afterCompile[$index]($value,$this->instance,$index);
93
			}
94
		}
95
		return $value;
96
	}
97
98
	public function insertField($index,$field){
99
		array_splice( $this->visibleProperties, $index, 0, $field );
100
		return $this;
101
	}
102
103
	public function insertInField($index,$field){
104
		$vb=$this->visibleProperties;
105
		if(isset($vb[$index])){
106
			if(\is_array($vb[$index])){
107
				$this->visibleProperties[$index][]=$field;
108
			}else{
109
				$this->visibleProperties[$index]=[$vb[$index],$field];
110
			}
111
		}else{
112
			return $this->insertField($index, $field);
113
		}
114
		return $this;
115
	}
116
117
	public function addField($field){
118
		$this->visibleProperties[]=$field;
119
		return $this;
120
	}
121
122
	public function count(){
123
		return \sizeof($this->properties);
124
	}
125
126
	public function visiblePropertiesCount(){
127
		return \sizeof($this->visibleProperties);
128
	}
129
130
	public function getProperty($index){
131
		return $this->properties[$index];
132
	}
133
134
	public function getFieldName($index){
135
		$property=$this->getProperty($index);
136
		if($property instanceof \ReflectionProperty){
137
			$result=$property->getName();
138
		}elseif(\is_callable($property)){
139
			$result=$this->visibleProperties[$index];
140
		}else{
141
			$result=$property;
142
		}
143
		return $result;
144
	}
145
146
147
	protected function showableProperty(\ReflectionProperty $rProperty){
148
		return JString::startswith($rProperty->getName(),"_")===false;
149
	}
150
151
	public function setInstance($instance) {
152
		if(\is_string($instance)){
153
			$instance=new $instance();
154
		}
155
		$this->instance=$instance;
156
		$this->properties=[];
157
		$this->reflect=new \ReflectionClass($instance);
158
		if(\sizeof($this->visibleProperties)===0){
159
			$this->properties=$this->getDefaultProperties();
160
		}else{
161
			foreach ($this->visibleProperties as $property){
162
				$this->setInstanceProperty($property);
163
			}
164
		}
165
		return $this;
166
	}
167
168
	private function setInstanceProperty($property){
169
		if(\is_callable($property)){
170
			$this->properties[]=$property;
171
		}elseif(\is_string($property)){
172
			try{
173
				$this->_beforeAddProperty(\sizeof($this->properties), $property);
174
				$rProperty=$this->reflect->getProperty($property);
175
				$this->properties[]=$rProperty;
176
			}catch(\Exception $e){
177
				$this->_beforeAddProperty(\sizeof($this->properties), $property);
178
				$this->properties[]=$property;
179
			}
180
		}elseif(\is_int($property)){
181
			$props=$this->getDefaultProperties();
182
			if(isset($props[$property]))
183
				$this->properties[]=$props[$property];
184
				else
185
					$this->properties[]=$property;
186
		}else{
187
			$this->properties[]=$property;
188
		}
189
	}
190
191
	protected function getDefaultProperties(){
192
		$result=[];
193
		$properties=$this->reflect->getProperties();
194
		foreach ($properties as $property){
195
			$showable=$this->showableProperty($property);
196
			if($showable!==false){
197
				$result[]=$property;
198
			}
199
		}
200
		return $result;
201
	}
202
203
	public function setVisibleProperties($visibleProperties) {
204
		$this->visibleProperties=$visibleProperties;
205
		return $this;
206
	}
207
208
	public function setValueFunction($index,$callback){
209
		$this->values[$index]=$callback;
210
		return $this;
211
	}
212
213
	public function setIdentifierFunction($callback){
214
		$this->values["identifier"]=$callback;
215
		return $this;
216
	}
217
218
	public static function setIndex($index) {
219
		self::$index=$index;
220
	}
221
222
	public function getProperties() {
223
		return $this->properties;
224
	}
225
226
	public function getCaption($index){
227
		if(isset($this->captions[$index])){
228
			return $this->captions[$index];
229
		}
230
		if($this->properties[$index] instanceof \ReflectionProperty)
231
			return $this->properties[$index]->getName();
232
		elseif(\is_callable($this->properties[$index]))
233
			return "";
234
		else
235
			return $this->properties[$index];
236
	}
237
238
	public function getCaptions(){
239
		if(isset($this->captions)){
240
			$captions= $this->captions;
241
			for($i=\sizeof($captions);$i<$this->count();$i++){
242
				$captions[]="";
243
			}
244
		}else{
245
			$captions=[];
246
			$index=0;
247
			$count=$this->count();
248
			while($index<$count){
249
				$captions[]=$this->getCaption($index++);
250
			}
251
		}
252
		if(isset($this->captionCallback) && \is_callable($this->captionCallback)){
253
			$callback=$this->captionCallback;
254
			$callback($captions,$this->instance);
255
		}
256
		return $captions;
257
	}
258
259
	public function setCaption($index,$caption){
260
		if(isset($this->captions)===false)
261
			$this->captions=[];
262
		$this->captions[$index]=$caption;
263
		return $this;
264
	}
265
266
	public function setCaptions($captions) {
267
		$this->captions=$captions;
268
		return $this;
269
	}
270
271
	/**
272
	 * Associates a $callback function after the compilation of the field at $index position
273
	 * The $callback function can take the following arguments : $field=>the compiled field, $instance : the active instance of the object, $index: the field position
274
	 * @param int $index postion of the compiled field
275
	 * @param callable $callback function called after the field compilation
276
	 * @return \Ajax\semantic\widgets\datatable\InstanceViewer
277
	 */
278
	public function afterCompile($index,$callback){
279
		$this->afterCompile[$index]=$callback;
280
		return $this;
281
	}
282
283
	/**
284
	 * Defines a callback function to call for modifying captions
285
	 * function parameters are $captions: the captions to modify and $instance: the active model instance
286
	 * @param callable $captionCallback
287
	 * @return \Ajax\semantic\widgets\base\InstanceViewer
288
	 */
289
	public function setCaptionCallback($captionCallback) {
290
		$this->captionCallback=$captionCallback;
291
		return $this;
292
	}
293
294
	public function setDefaultValueFunction($defaultValueFunction) {
295
		$this->defaultValueFunction=$defaultValueFunction;
296
		return $this;
297
	}
298
299
300
}