Passed
Push — master ( 497376...b53e1e )
by Jean-Christophe
02:08
created

BaseHtml::asFileDropZone()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 24
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 19
c 0
b 0
f 0
nc 8
nop 5
dl 0
loc 24
rs 9.6333
1
<?php
2
namespace Ajax\common\html;
3
4
use Ajax\common\components\SimpleExtComponent;
5
use Ajax\JsUtils;
6
use Ajax\common\html\traits\BaseHtmlEventsTrait;
7
use Ajax\common\html\traits\BaseHtmlPropertiesTrait;
8
use Ajax\semantic\html\modules\HtmlProgress;
9
use Ajax\service\Javascript;
10
11
/**
12
 * BaseHtml for HTML components
13
 *
14
 * @author jc
15
 * @version 1.3.2
16
 */
17
abstract class BaseHtml extends BaseWidget {
18
	use BaseHtmlEventsTrait,BaseHtmlPropertiesTrait;
19
20
	protected $_template;
21
22
	protected $tagName;
23
24
	protected $_wrapBefore = array();
25
26
	protected $_wrapAfter = array();
27
28
	protected $_bsComponent;
29
30
	protected $_compiled = false;
31
32
	protected $_runned = false;
33
34
	protected $_postCompile;
35
36
	protected $_preCompile;
37
38
	/**
39
	 *
40
	 * @param JsUtils $js
41
	 * @return SimpleExtComponent
42
	 */
43
	abstract public function run(JsUtils $js);
44
45
	private function _callSetter($setter, $key, $value, &$array) {
46
		$result = false;
47
		if (method_exists($this, $setter) && substr($setter, 0, 1) !== "_") {
48
			try {
49
				$this->$setter($value);
50
				unset($array[$key]);
51
				$result = true;
52
			} catch (\Exception $e) {
53
				$result = false;
54
			}
55
		}
56
		return $result;
57
	}
58
59
	protected function getTemplate(JsUtils $js = NULL, $view = null) {
60
		return PropertyWrapper::wrap($this->_wrapBefore, $js, $view) . $this->_template . PropertyWrapper::wrap($this->_wrapAfter, $js, $view);
61
	}
62
63
	protected function ctrl($name, $value, $typeCtrl) {
64
		if (\is_array($typeCtrl)) {
65
			if (array_search($value, $typeCtrl) === false) {
66
				throw new \Exception("La valeur passée `" . $value . "` à la propriété `" . $name . "` ne fait pas partie des valeurs possibles : {" . implode(",", $typeCtrl) . "}");
67
			}
68
		} else {
69
			if (! $typeCtrl($value)) {
70
				throw new \Exception("La fonction " . $typeCtrl . " a retourné faux pour l'affectation de la propriété " . $name);
71
			}
72
		}
73
		return true;
74
	}
75
76
	protected function setMemberCtrl(&$name, $value, $typeCtrl) {
77
		$this->ctrl($name, $value, $typeCtrl);
78
		$name = $value;
79
		return $this;
80
	}
81
82
	protected function addToMemberUnique(&$name, $value, $typeCtrl, $separator = " ") {
83
		if (\is_array($typeCtrl)) {
84
			$this->removeOldValues($name, $typeCtrl);
85
			$name .= $separator . $value;
86
		}
87
		return $this;
88
	}
89
90
	protected function addToMemberCtrl(&$name, $value, $typeCtrl, $separator = " ") {
91
		$this->ctrl($name, $value, $typeCtrl);
92
		if (\is_array($typeCtrl)) {
93
			$this->removeOldValues($name, $typeCtrl);
94
		}
95
		$name .= $separator . $value;
96
		return $this;
97
	}
98
99
	protected function addToMember(&$name, $value, $separator = " ") {
100
		$name = str_ireplace($value, "", $name) . $separator . $value;
0 ignored issues
show
Bug introduced by
Are you sure str_ireplace($value, '', $name) of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

100
		$name = /** @scrutinizer ignore-type */ str_ireplace($value, "", $name) . $separator . $value;
Loading history...
101
		return $this;
102
	}
103
104
	protected function removeOldValues(&$oldValue, $allValues) {
105
		$oldValue = str_ireplace($allValues, "", $oldValue);
106
		$oldValue = trim($oldValue);
0 ignored issues
show
Bug introduced by
It seems like $oldValue can also be of type array; however, parameter $string of trim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

106
		$oldValue = trim(/** @scrutinizer ignore-type */ $oldValue);
Loading history...
107
	}
108
109
	protected function _getElementBy($callback, $elements) {
110
		if (\is_array($elements)) {
111
			$elements = \array_values($elements);
112
			$flag = false;
113
			$index = 0;
114
			while (! $flag && $index < sizeof($elements)) {
115
				if ($elements[$index] instanceof BaseHtml)
116
					$flag = ($callback($elements[$index]));
117
				$index ++;
118
			}
119
			if ($flag === true)
120
				return $elements[$index - 1];
121
		} elseif ($elements instanceof BaseHtml) {
122
			if ($callback($elements))
123
				return $elements;
124
		}
125
		return null;
126
	}
127
128
	protected function setWrapBefore($wrapBefore) {
129
		$this->_wrapBefore = $wrapBefore;
130
		return $this;
131
	}
132
133
	protected function setWrapAfter($wrapAfter) {
134
		$this->_wrapAfter = $wrapAfter;
135
		return $this;
136
	}
137
138
	public function getTagName() {
139
		return $this->tagName;
140
	}
141
142
	public function setTagName($tagName) {
143
		$this->tagName = $tagName;
144
		return $this;
145
	}
146
147
	public function fromArray($array) {
148
		foreach ($this as $key => $value) {
149
			if (array_key_exists($key, $array) === true)
150
				$this->_callSetter("set" . ucfirst($key), $key, $array[$key], $array);
151
		}
152
		foreach ($array as $key => $value) {
153
			if ($this->_callSetter($key, $key, $value, $array) === false) {
154
				$this->_callSetter("set" . ucfirst($key), $key, $value, $array);
155
			}
156
		}
157
		return $array;
158
	}
159
160
	public function fromDatabaseObjects($objects, $function) {
161
		if (isset($objects)) {
162
			foreach ($objects as $object) {
163
				$this->fromDatabaseObject($object, $function);
164
			}
165
		}
166
		return $this;
167
	}
168
169
	public function fromDatabaseObject($object, $function) {}
170
171
	public function wrap($before, $after = "") {
172
		if (isset($before)) {
173
			array_unshift($this->_wrapBefore, $before);
174
		}
175
		$this->_wrapAfter[] = $after;
176
		return $this;
177
	}
178
179
	public function getElementById($identifier, $elements) {
180
		return $this->_getElementBy(function (BaseWidget $element) use ($identifier) {
181
			return $element->getIdentifier() === $identifier;
182
		}, $elements);
183
	}
184
185
	public function getBsComponent() {
186
		return $this->_bsComponent;
187
	}
188
189
	public function setBsComponent($bsComponent) {
190
		$this->_bsComponent = $bsComponent;
191
		return $this;
192
	}
193
194
	protected function compile_once(JsUtils $js = NULL, &$view = NULL) {
195
		if (! $this->_compiled) {
196
			if (isset($js)) {
197
				$beforeCompile = $js->getParam("beforeCompileHtml");
198
				if (\is_callable($beforeCompile)) {
199
					$beforeCompile($this, $js, $view);
200
				}
201
			}
202
			$this->callCallback($this->_preCompile);
203
			unset($this->properties["jsCallback"]);
204
			$this->_compiled = true;
205
		}
206
	}
207
208
	public function compile(JsUtils $js = NULL, &$view = NULL) {
209
		$this->compile_once($js, $view);
210
		$result = $this->getTemplate($js, $view);
211
		foreach ($this as $key => $value) {
212
			if (\strstr($result, "%{$key}%") !== false) {
213
				if (\is_array($value)) {
214
					$v = PropertyWrapper::wrap($value, $js, $view);
215
				} elseif ($value instanceof \stdClass) {
216
					$v = \print_r($value, true);
217
				} elseif ($value instanceof BaseHtml) {
218
					$v = $value->compile($js, $view);
219
				} else {
220
					$v = $value;
221
				}
222
				$result = str_replace("%{$key}%", $v, $result);
223
			}
224
		}
225
		if (isset($js) === true) {
226
			$this->run($js);
227
			if (isset($view) === true) {
228
				$js->addViewElement($this->getLibraryId(), $result, $view);
229
			}
230
		}
231
232
		if (\is_callable($this->_postCompile)) {
233
			$pc = $this->_postCompile;
234
			$pc($this);
235
		}
236
		return $result;
237
	}
238
239
	/**
240
	 * Sets the element draggable, and eventualy defines the dropzone (HTML5 drag and drop)
241
	 *
242
	 * @param string $attr
243
	 *        	default: "id"
244
	 * @param BaseHtml $dropZone
245
	 *        	the dropzone element
246
	 * @param array $parameters
247
	 *        	default: ["jsCallback"=>"","jqueryDone"=>"append"]
248
	 * @return \Ajax\common\html\BaseHtml
249
	 */
250
	public function setDraggable($attr = "id", $dropZone = null, $parameters = []) {
251
		$this->setProperty("draggable", "true");
252
		$this->addEvent("dragstart", Javascript::draggable($attr));
253
		if (isset($dropZone) && $dropZone instanceof BaseHtml) {
254
			$jqueryDone = "append";
255
			$jsCallback = "";
256
			extract($parameters);
257
			$dropZone->asDropZone($jsCallback, $jqueryDone, $parameters);
258
		}
259
		return $this;
260
	}
261
262
	/**
263
	 * Declares the element as a drop zone (HTML5 drag and drop)
264
	 *
265
	 * @param string $jsCallback
266
	 * @param string $jqueryDone
267
	 * @param array $parameters
268
	 * @return \Ajax\common\html\BaseHtml
269
	 */
270
	public function asDropZone($jsCallback = "", $jqueryDone = "append", $parameters = []) {
271
		$stopPropagation = false;
272
		$this->addEvent("dragover", '', $stopPropagation, true);
273
		extract($parameters);
274
		$this->addEvent("drop", Javascript::dropZone($jqueryDone, $jsCallback), $stopPropagation, true);
275
		return $this;
276
	}
277
278
	/**
279
	 * Declares the element as a drop zone for file uploading (HTML5 drag and drop)
280
	 *
281
	 * @param ?string $responseElement
282
	 * @param ?string $url
283
	 * @param ?string $progress
284
	 * @param string $jsCallback
285
	 * @param array $parameters
286
	 * @return \Ajax\common\html\BaseHtml
287
	 */
288
	public function asFileDropZone($responseElement = null, $url = null, $progress = null, $jsCallback = "", $parameters = []) {
289
		$stopPropagation = false;
290
		$defaultAjaxAttributes = [
291
			'contentType' => 'false',
292
			'processData' => 'false'
293
		];
294
		$this->addEvent("dragover", '', $stopPropagation, true);
295
		extract($parameters);
296
		$this->addEvent("drop", Javascript::fileDropZone($jsCallback), $stopPropagation, true);
297
		if (isset($ajaxAttributes)) {
298
			$ajaxAttributes += $defaultAjaxAttributes;
299
		} else {
300
			$ajaxAttributes = $defaultAjaxAttributes;
301
		}
302
		if (isset($progress)) {
303
			$progress = new HtmlProgress($this->_identifier . '-pg', 0, $progress);
304
			$progress->setTotal(100);
305
			$this->wrap('', $progress);
306
			$ajaxAttributes['upload'] = "$('#" . $this->_identifier . "-pg').progress('set percent', Math.ceil(event.loaded/event.total)*100);";
307
		}
308
		if (isset($url)) {
309
			$this->postOn('upload', $url, 'event.target.upload', $responseElement, $ajaxAttributes);
310
		}
311
		return $progress ?? $this;
312
	}
313
314
	public function __toString() {
315
		return $this->compile();
316
	}
317
318
	public function onPostCompile($callback) {
319
		$this->_postCompile = $callback;
320
	}
321
322
	public function onPreCompile($callback) {
323
		$this->_preCompile = $this->addCallback($this->_preCompile, $callback);
324
	}
325
326
	private function addCallback($originalValue, $callback) {
327
		if (isset($originalValue)) {
328
			if (! is_array($originalValue)) {
329
				$result = [
330
					$originalValue
331
				];
332
			}
333
			$result[] = $callback;
334
			return $result;
335
		}
336
		return $callback;
337
	}
338
339
	private function callCallback($callable) {
340
		if (\is_callable($callable)) {
341
			return $callable($this);
342
		}
343
		if (is_array($callable)) {
344
			foreach ($callable as $call) {
345
				$this->callCallback($call);
346
			}
347
		}
348
	}
349
}
350