PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.9
VikBooking Hotel Booking Engine & PMS v1.6.9
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
vikbooking / admin / helpers / src / params / rendering.php

rendering.php in VikBooking Hotel Booking Engine & PMS 1.6.9, at admin/helpers/src/params/rendering.php

383 lines 17.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - E4J srl
6 * @copyright Copyright (C) 2024 E4J srl. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 * @link https://vikwp.com
9 */
10
11 defined('ABSPATH') or die('No script kiddies please!');
12
13 /**
14 * Helper class to render specific param types.
15 *
16 * @since 1.16.9 (J) - 1.6.9 (WP)
17 */
18 final class VBOParamsRendering
19 {
20 /**
21 * @var array
22 */
23 private $params = [];
24
25 /**
26 * @var array
27 */
28 private $settings = [];
29
30 /**
31 * @var array
32 */
33 private $scripts = [];
34
35 /**
36 * @var array
37 */
38 private $assets = [];
39
40 /**
41 * @var string
42 */
43 private $inputName = 'vboparams';
44
45 /**
46 * @var int
47 */
48 private static $instance_counter = -1;
49
50 /**
51 * Class constructor is protected.
52 *
53 * @param array $params The form params to bind.
54 * @param array $settings The form settings to bind.
55 *
56 * @see getInstance()
57 */
58 private function __construct(array $params, array $settings)
59 {
60 // bind values
61 $this->params = $params;
62 $this->settings = $settings;
63
64 // increase instance counter
65 static::$instance_counter++;
66 }
67
68 /**
69 * Proxy for immediately accessing the object and bind data.
70 *
71 * @param array $params The form params to bind.
72 * @param array $settings The form settings to bind.
73 *
74 * @return VBOParamsRendering
75 */
76 public static function getInstance(array $params = [], array $settings = [])
77 {
78 return new static($params, $settings);
79 }
80
81 /**
82 * Sets the name to be used for rendering the param fields.
83 *
84 * @param string $name The name to use.
85 *
86 * @return self
87 */
88 public function setInputName($name)
89 {
90 $this->inputName = (string) $name;
91
92 return $this;
93 }
94
95 /**
96 * Renders the injected form params and returns the HTML code.
97 *
98 * @param bool $load_assets Whether to load the necessary assets.
99 *
100 * @return string
101 */
102 public function getHtml($load_assets = true)
103 {
104 if (!$this->params) {
105 return '';
106 }
107
108 $html = '';
109
110 foreach ($this->params as $param_name => $param_config) {
111 if (empty($param_name)) {
112 continue;
113 }
114
115 $labelparts = explode('//', (isset($param_config['label']) ? $param_config['label'] : ''));
116 $label = $labelparts[0];
117 $labelhelp = isset($labelparts[1]) ? $labelparts[1] : '';
118 if (!empty($param_config['help'])) {
119 $labelhelp = $param_config['help'];
120 }
121
122 $nested_style = (isset($param_config['nested']) && $param_config['nested']);
123 $hidden_wrapper = false;
124 if (isset($param_config['conditional']) && isset($this->params[$param_config['conditional']])) {
125 $check_cond = isset($this->params[$param_config['conditional']]['default']) ? $this->params[$param_config['conditional']]['default'] : null;
126 $check_cond = isset($this->settings[$param_config['conditional']]) ? $this->settings[$param_config['conditional']] : $check_cond;
127 if (!is_null($check_cond) && (!$check_cond || !strcasecmp($check_cond, 'off'))) {
128 // hide current field because the field to who this is dependant is "off" or disabled (i.e. 0)
129 $hidden_wrapper = true;
130 }
131 }
132
133 $html .= '<div class="vbo-param-container' . (in_array($param_config['type'], ['textarea', 'visual_html']) ? ' vbo-param-container-full' : '') . ($nested_style ? ' vbo-param-nested' : '') . '"' . ($hidden_wrapper ? ' style="display: none;"' : '') . '>';
134 if (strlen($label) > 0 && (!isset($param_config['hidden']) || $param_config['hidden'] != true)) {
135 $html .= '<div class="vbo-param-label">' . $label . '</div>';
136 }
137 $html .= '<div class="vbo-param-setting">';
138
139 // render field
140 $html .= $this->getField($param_name, $param_config);
141
142 // check for assets to be loaded, only once to obtain individual setups
143 if ($load_assets) {
144 $this->loadAssets($load_once = true);
145 }
146
147 if ($labelhelp) {
148 $html .= '<span class="vbo-param-setting-comment">' . $labelhelp . '</span>';
149 }
150
151 $html .= '</div>';
152 $html .= '</div>';
153 }
154
155 // JS helper functions
156 $html .= $this->getScripts();
157
158 return $html;
159 }
160
161 /**
162 * Loads the requested assets, if any.
163 *
164 * @param bool $load_once True to unset the assets after loading.
165 *
166 * @return void
167 */
168 public function loadAssets($load_once = false)
169 {
170 $doc = JFactory::getDocument();
171 foreach ($this->assets as $asset_type => $asset_elements) {
172 if ($asset_type === 'select2') {
173 // build list of selectors
174 $ids_list = implode(', ', array_map(function($el) {
175 return "#{$el}";
176 }, $asset_elements));
177
178 // check for asset options
179 $asset_options = $this->assets['select2_options'] ?? null;
180 $asset_options_str = $asset_options ? json_encode($asset_options) : '';
181
182 // add script declaration
183 VikBooking::getVboApplication()->loadSelect2();
184 $doc->addScriptDeclaration(
185 <<<JS
186 jQuery(function() {
187 jQuery('$ids_list').select2($asset_options_str);
188 });
189 JS
190 );
191 }
192
193 if ($load_once) {
194 unset($this->assets[$asset_type]);
195 }
196 }
197 }
198
199 /**
200 * Gets the necessary script tags.
201 *
202 * @return string
203 */
204 public function getScripts()
205 {
206 $html = '';
207
208 if (in_array('password', $this->scripts)) {
209 // toggle the password fields
210 $html .= "\n" . '<script>' . "\n";
211 $html .= 'function vboParamTogglePwd(elem) {' . "\n";
212 $html .= ' var btn = jQuery(elem), inp = btn.parent().find("input").first();' . "\n";
213 $html .= ' if (!inp || !inp.length) {return false;}' . "\n";
214 $html .= ' var inp_type = inp.attr("type");' . "\n";
215 $html .= ' inp.attr("type", (inp_type == "password" ? "text" : "password"));' . "\n";
216 $html .= '}' . "\n";
217 $html .= "\n" . '</script>' . "\n";
218 }
219
220 return $html;
221 }
222
223 /**
224 * Renders the given param name according to config.
225 * Eventually populates the assets and scripts to be loaded.
226 *
227 * @param string $param_name The param name.
228 * @param array $param_config The param configuration.
229 *
230 * @return string
231 */
232 public function getField($param_name, $param_config)
233 {
234 $html = '';
235
236 $inp_attr = '';
237 if (isset($param_config['attributes']) && is_array($param_config['attributes'])) {
238 foreach ($param_config['attributes'] as $inpk => $inpv) {
239 $inp_attr .= $inpk . '="' . $inpv . '" ';
240 }
241 $inp_attr = ' ' . rtrim($inp_attr);
242 }
243
244 $default_paramv = $param_config['default'] ?? null;
245
246 switch ($param_config['type']) {
247 case 'custom':
248 $html .= $param_config['html'];
249 break;
250 case 'select':
251 $options = isset($param_config['options']) && is_array($param_config['options']) ? $param_config['options'] : [];
252 $is_assoc = (array_keys($options) !== range(0, count($options) - 1));
253 $element_id = 'vik-select-' . static::$instance_counter . '-' . preg_replace("/[^A-Z0-9]+/i", '', $param_name);
254 $set_attr = true;
255 if (isset($param_config['attributes']) && is_array($param_config['attributes']) && isset($param_config['attributes']['id'])) {
256 $element_id = $param_config['attributes']['id'];
257 $set_attr = false;
258 }
259 if (isset($param_config['assets']) && $param_config['assets']) {
260 if (!isset($this->assets['select2'])) {
261 $this->assets['select2'] = [];
262 }
263 $this->assets['select2'][] = $element_id;
264 $this->assets['select2_options'] = $param_config['asset_options'] ?? null;
265 }
266 if (isset($param_config['multiple']) && $param_config['multiple']) {
267 $html .= '<select name="' . $this->inputName . '[' . $param_name . '][]" multiple="multiple"' . $inp_attr . ($set_attr ? ' id="' . $element_id . '"' : '') . '>' . "\n";
268 } else {
269 $html .= '<select name="' . $this->inputName . '[' . $param_name . ']"' . $inp_attr . ($set_attr ? ' id="' . $element_id . '"' : '') . '>' . "\n";
270 }
271 foreach ($options as $optind => $optval) {
272 // support nested array values for the option-group tags
273 $group = null;
274 $sel_opts = [$optind => $optval];
275 if (is_array($optval)) {
276 $group = $optind;
277 $sel_opts = $optval;
278 }
279 if ($group) {
280 $html .= '<optgroup label="' . JHtml::fetch('esc_attr', JText::translate($group)) . '">' . "\n";
281 }
282 foreach ($sel_opts as $optkey => $poption) {
283 $checkval = $is_assoc ? $optkey : $poption;
284 $selected = false;
285 if (isset($this->settings[$param_name])) {
286 if (is_array($this->settings[$param_name])) {
287 $selected = in_array($checkval, $this->settings[$param_name]);
288 } else {
289 $selected = ($checkval == $this->settings[$param_name]);
290 }
291 } elseif (isset($default_paramv)) {
292 if (is_array($default_paramv)) {
293 $selected = in_array($checkval, $default_paramv);
294 } else {
295 $selected = ($checkval == $default_paramv);
296 }
297 }
298 $html .= '<option value="' . ($is_assoc ? $optkey : $poption) . '"'.($selected ? ' selected="selected"' : '').'>'.$poption.'</option>' . "\n";
299 }
300 if ($group) {
301 $html .= '</optgroup>' . "\n";
302 }
303 }
304 $html .= '</select>' . "\n";
305 break;
306 case 'password':
307 $html .= '<div class="btn-wrapper input-append">';
308 $html .= '<input type="password" name="' . $this->inputName . '[' . $param_name . ']" value="'.(isset($this->settings[$param_name]) ? JHtml::fetch('esc_attr', $this->settings[$param_name]) : JHtml::fetch('esc_attr', $default_paramv)).'" size="20"' . $inp_attr . '/>';
309 $html .= '<button type="button" class="btn btn-primary" onclick="vboParamTogglePwd(this);"><i class="' . VikBookingIcons::i('eye') . '"></i></button>';
310 $html .= '</div>';
311 // set flag for JS helper
312 $$this->scripts[] = $param_config['type'];
313 break;
314 case 'number':
315 $number_attr = [];
316 if (isset($param_config['min'])) {
317 $number_attr[] = 'min="' . JHtml::fetch('esc_attr', $param_config['min']) . '"';
318 }
319 if (isset($param_config['max'])) {
320 $number_attr[] = 'max="' . JHtml::fetch('esc_attr', $param_config['max']) . '"';
321 }
322 if (isset($param_config['step'])) {
323 $number_attr[] = 'step="' . JHtml::fetch('esc_attr', $param_config['step']) . '"';
324 }
325 $html .= '<input type="number" name="' . $this->inputName . '[' . $param_name . ']" value="'.(isset($this->settings[$param_name]) ? JHtml::fetch('esc_attr', $this->settings[$param_name]) : JHtml::fetch('esc_attr', $default_paramv)).'" ' . implode(' ', $number_attr) . $inp_attr . '/>';
326 break;
327 case 'textarea':
328 $html .= '<textarea name="' . $this->inputName . '[' . $param_name . ']"' . $inp_attr . '>'.(isset($this->settings[$param_name]) ? JHtml::fetch('esc_textarea', $this->settings[$param_name]) : JHtml::fetch('esc_textarea', $default_paramv)).'</textarea>';
329 break;
330 case 'visual_html':
331 $tarea_cont = isset($this->settings[$param_name]) ? JHtml::fetch('esc_textarea', $this->settings[$param_name]) : JHtml::fetch('esc_textarea', $default_paramv);
332 $tarea_attr = isset($param_config['attributes']) && is_array($param_config['attributes']) ? $param_config['attributes'] : [];
333 $editor_opts = isset($param_config['editor_opts']) && is_array($param_config['editor_opts']) ? $param_config['editor_opts'] : [];
334 $editor_btns = isset($param_config['editor_btns']) && is_array($param_config['editor_btns']) ? $param_config['editor_btns'] : [];
335 $html .= VikBooking::getVboApplication()->renderVisualEditor($this->inputName . '[' . $param_name . ']', $tarea_cont, $tarea_attr, $editor_opts, $editor_btns);
336 break;
337 case 'codemirror':
338 $editor = JEditor::getInstance('codemirror');
339 $e_options = isset($param_config['options']) && is_array($param_config['options']) ? $param_config['options'] : [];
340 $e_name = $this->inputName . '[' . $param_name . ']';
341 $e_value = isset($this->settings[$param_name]) ? $this->settings[$param_name] : $default_paramv;
342 $e_width = isset($e_options['width']) ? $e_options['width'] : '100%';
343 $e_height = isset($e_options['height']) ? $e_options['height'] : 300;
344 $e_col = isset($e_options['col']) ? $e_options['col'] : 70;
345 $e_row = isset($e_options['row']) ? $e_options['row'] : 20;
346 $e_buttons = isset($e_options['buttons']) ? (bool)$e_options['buttons'] : true;
347 $e_id = isset($e_options['id']) ? $e_options['id'] : $this->inputName . '_' . $param_name;
348 $e_params = isset($e_options['params']) && is_array($e_options['params']) ? $e_options['params'] : [];
349 if (interface_exists('Throwable')) {
350 /**
351 * With PHP >= 7 supporting throwable exceptions for Fatal Errors
352 * we try to avoid issues with third party plugins that make use
353 * of the WP native function get_current_screen().
354 *
355 * @wponly
356 */
357 try {
358 $html .= $editor->display($e_name, $e_value, $e_width, $e_height, $e_col, $e_row, $e_buttons, $e_id, $e_asset = null, $e_autor = null, $e_params);
359 } catch (Throwable $t) {
360 $html .= $t->getMessage() . ' in ' . $t->getFile() . ':' . $t->getLine() . '<br/>';
361 $html .= '<textarea name="' . $this->inputName . '[' . $param_name . ']"' . $inp_attr . '>' . (isset($this->settings[$param_name]) ? JHtml::fetch('esc_textarea', $this->settings[$param_name]) : JHtml::fetch('esc_textarea', $default_paramv)) . '</textarea>';
362 }
363 } else {
364 $html .= $editor->display($e_name, $e_value, $e_width, $e_height, $e_col, $e_row, $e_buttons, $e_id, $e_asset = null, $e_autor = null, $e_params);
365 }
366 break;
367 case 'hidden':
368 $html .= '<input type="hidden" name="' . $this->inputName . '[' . $param_name . ']" value="'.(isset($this->settings[$param_name]) ? JHtml::fetch('esc_attr', $this->settings[$param_name]) : JHtml::fetch('esc_attr', $default_paramv)).'"' . $inp_attr . '/>';
369 break;
370 case 'checkbox':
371 // always display a hidden input value turned off before the actual checkbox to support the "off" (0) status
372 $html .= '<input type="hidden" name="' . $this->inputName . '[' . $param_name . ']" value="0" />';
373 $html .= VikBooking::getVboApplication()->printYesNoButtons($this->inputName . '['.$param_name.']', JText::translate('VBYES'), JText::translate('VBNO'), (isset($this->settings[$param_name]) ? (int)$this->settings[$param_name] : (int)$default_paramv), 1, 0);
374 break;
375 default:
376 $html .= '<input type="text" name="' . $this->inputName . '[' . $param_name . ']" value="'.(isset($this->settings[$param_name]) ? JHtml::fetch('esc_attr', $this->settings[$param_name]) : JHtml::fetch('esc_attr', $default_paramv)).'" size="20"' . $inp_attr . '/>';
377 break;
378 }
379
380 return $html;
381 }
382 }
383