PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.8
VikBooking Hotel Booking Engine & PMS v1.6.8
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 / libraries / adapter / mvc / model.php

model.php in VikBooking Hotel Booking Engine & PMS 1.6.8, at libraries/adapter/mvc/model.php

406 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikWP - Libraries
4 * @subpackage adapter.mvc
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2023 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 JLoader::import('adapter.application.object');
15
16 /**
17 * The model class used by the MVC framework.
18 * A model can be used by a controller or a view to handle
19 * a certain entity of the plugin.
20 *
21 * The model can be invoked when the value contained
22 * in $_REQUEST['task'] is equals to 'ComponentModel' + $_REQUEST['task'].
23 *
24 * e.g. $_REQUEST['task'] = 'groups.save' -> ComponentModelGroups
25 *
26 * @since 10.0
27 */
28 abstract class JModel extends JObject
29 {
30 /**
31 * A list of model instances.
32 *
33 * @var array
34 */
35 protected static $instances = array();
36
37 /**
38 * A list of included paths.
39 *
40 * @var array
41 * @since 10.1.24
42 */
43 protected static $paths = array();
44
45 /**
46 * The model name.
47 * e.g. ComponentModel[NAME]
48 *
49 * @var string
50 */
51 protected $_name = null;
52
53 /**
54 * The component name.
55 * e.g. [COMPONENT]ModelName
56 *
57 * @var string
58 */
59 protected $_component = null;
60
61 /**
62 * The application client.
63 *
64 * @var string
65 */
66 protected $_client = null;
67
68 /**
69 * The database table name.
70 *
71 * @var array
72 * @since 10.1.35
73 */
74 protected $_config;
75
76 /**
77 * Tries to load the specified model, only creating it if
78 * it doesn't exist yet.
79 *
80 * @param string $type The model type to instantiate
81 * @param string $prefix Prefix for the model class name.
82 * @param array $config Configuration array for model.
83 *
84 * @return mixed The model instance if found, otherwise null.
85 *
86 * @since 10.1.35 Switch the ordering of $type and $prefix argument.
87 * @since 10.1.35 Added $config argument.
88 * @since 10.1.35 Removed $client, $table and $pk arguments.
89 */
90 public static function getInstance($type, $prefix = '', $config = array())
91 {
92 /**
93 * For backward compatibility, we should check whether the 3rd argument is passed,
94 * meaning that we need to force a client section in which to load the model.
95 *
96 * @since 10.1.35
97 */
98 if (is_string($config))
99 {
100 $config = ['client' => $config];
101 }
102 else
103 {
104 $config = (array) $config;
105 }
106
107 if (empty($config['client']))
108 {
109 $config['client'] = JFactory::getApplication()->isAdmin() ? 'admin' : 'site';
110 }
111
112 /**
113 * The current version of JModel is not using the same arguments as
114 * specified by Joomla, since the model name is always passed as
115 * first argument.
116 *
117 * For this reason, we need to swap the prefix and the name when
118 * passed using Joomla standards. This can be done when at least one
119 * of the following conditions is verified:
120 *
121 * - the name contains 'model' word
122 * - the name is actually the folder name and the prefix isn't
123 *
124 * @since 10.1.24
125 */
126 if (preg_match("/model/i", $type)
127 || (is_dir(WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $type) && !is_dir(WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . strtolower($prefix))))
128 {
129 // swap name with prefix
130 $tmp = $type;
131 $type = $prefix;
132 $prefix = $tmp;
133 }
134
135 // remove 'model' from prefix (if any) and make it lowercase
136 $prefix = strtolower(preg_replace("/model/i", '', $prefix));
137
138 $sign = serialize(array($prefix, $type, $config['client']));
139
140 if (!isset(static::$instances[$sign]))
141 {
142 static::$instances[$sign] = false;
143
144 // create classname
145 $classname = ucfirst($prefix) . 'Model' . ucfirst($type);
146
147 /**
148 * Merge default include path (the fallback) with specified directories.
149 * Then iterate the list to find the first available model.
150 *
151 * @since 10.1.24
152 */
153 $paths = array_merge(
154 // default include path
155 array(
156 /**
157 * Search also inside the libraries folder of the current plugin.
158 * Prioritize this folder to avoid conflicts with deprecated files.
159 *
160 * @since 10.1.35
161 */
162 implode(DIRECTORY_SEPARATOR, array(WP_PLUGIN_DIR, $prefix, 'libraries', 'mvc', $config['client'], 'models')),
163 implode(DIRECTORY_SEPARATOR, array(WP_PLUGIN_DIR, $prefix, $config['client'], 'models')),
164 ),
165 // specified include paths
166 self::addIncludePath()
167 );
168
169 // iterate paths until we find an existing file (or till the list is empty)
170 for ($i = 0, $path = null; $i < count($paths) && !static::$instances[$sign]; $i++)
171 {
172 // create path
173 $path = $paths[$i] . DIRECTORY_SEPARATOR . strtolower($type) . '.php';
174
175 // make sure the file exists
176 if (!JFile::exists($path))
177 {
178 // unset path to keep iterating
179 continue;
180 }
181
182 /**
183 * Keep iterating until we find a valid instance, as different plugins
184 * might implement models with the same name.
185 *
186 * @since 10.1.51
187 */
188
189 try
190 {
191 // include model
192 require_once $path;
193
194 // make sure the class exists
195 if (class_exists($classname))
196 {
197 // cache model instance
198 static::$instances[$sign] = new $classname($config);
199 }
200 }
201 catch (Throwable $error)
202 {
203 // not the correct file
204 }
205 }
206 }
207
208 return static::$instances[$sign];
209 }
210
211 /**
212 * Add a directory where the class should search for models.
213 * You may either pass a string or an array of directories.
214 *
215 * @param mixed $path A path or array of paths to search.
216 *
217 * @return array An array with directory elements.
218 *
219 * @since 10.1.24
220 */
221 public static function addIncludePath($path = null)
222 {
223 if (!empty($path))
224 {
225 JLoader::import('adapter.filesystem.path');
226
227 foreach ((array) $path as $includePath)
228 {
229 $includePath = JPath::clean($includePath);
230
231 // check if the path is a dir
232 if (!is_dir($includePath))
233 {
234 // extract name between component and models
235 if (preg_match("/components[\/\\\\]com_([a-z0-9_]+)[\/\\\\]models/", $includePath, $match))
236 {
237 // access adapters of current plugin
238 $option = JFactory::getApplication()->input->get('option');
239 // strip initial com_ from option name
240 $option = preg_replace("/^com_/", '', $option);
241
242 // rewrite include path
243 $includePath = JPath::clean(WP_PLUGIN_DIR . '/' . $option . '/libraries/adapter/mvc/models/' . end($match));
244 }
245 }
246
247 // make sure the folder is not already in the list
248 if (!in_array($includePath, static::$paths))
249 {
250 // push directory as first
251 array_unshift(static::$paths, $includePath);
252 }
253 }
254 }
255
256 return static::$paths;
257 }
258
259 /**
260 * Class constructor.
261 *
262 * @param array $config An array of configuration options.
263 *
264 * @since 10.1.35 Added $config argument.
265 * @since 10.1.35 Removed $table and $pk arguments.
266 */
267 public function __construct($config = array())
268 {
269 $option = $this->getComponentName();
270
271 if (!array_key_exists('table_path', $config) && $option)
272 {
273 $config['table_path'] = [
274 JPath::clean(WP_PLUGIN_DIR . '/' . $option . '/libraries/mvc/' . $config['client'] . '/tables'),
275 JPath::clean(WP_PLUGIN_DIR . '/' . $option . '/' . $config['client'] . '/tables'),
276 ];
277 }
278
279 // set the default view search path
280 if (!empty($config['table_path']))
281 {
282 $this->addTablePath($config['table_path']);
283 }
284
285 $this->_config = $config;
286 }
287
288 /**
289 * Adds to the stack of model table paths in LIFO order.
290 *
291 * @param mixed $path The directory as a string or directories as an array to add.
292 *
293 * @return void
294 *
295 * @since 10.1.35
296 */
297 public function addTablePath($path)
298 {
299 JTable::addIncludePath($path);
300 }
301
302 /**
303 * Method to get a table object.
304 *
305 * @param string $name The table name.
306 * @param string $prefix The class prefix.
307 * @param array $options Configuration array for table.
308 *
309 * @return JTable A table object.
310 *
311 * @since 10.1.35
312 */
313 public function getTable($name = '', $prefix = 'JTable', $options = array())
314 {
315 if (!$name)
316 {
317 $name = $this->getName();
318 }
319
320 return JTable::getInstance($name, $prefix, $options);
321 }
322
323 /**
324 * Returns the model name.
325 *
326 * @return string Model name.
327 */
328 public function getModelName()
329 {
330 if (is_null($this->_name))
331 {
332 $class = get_class($this);
333
334 if (preg_match("/Model(.*?)$/", $class, $match))
335 {
336 $this->_name = strtolower($match[1]);
337 }
338 else
339 {
340 $this->_name = $class;
341 }
342 }
343
344 return $this->_name;
345 }
346
347 /**
348 * Returns the model name.
349 * Proxy for getModelName() method.
350 *
351 * @return string Model name.
352 *
353 * @since 1.0.1.35
354 */
355 public function getName()
356 {
357 return $this->getModelName();
358 }
359
360 /**
361 * Returns the component name.
362 *
363 * @return string Component name.
364 */
365 public function getComponentName()
366 {
367 if (is_null($this->_component))
368 {
369 $class = get_class($this);
370
371 if (preg_match("/(.*?)Model/", $class, $match))
372 {
373 $this->_component = strtolower($match[1]);
374 }
375 else
376 {
377 $this->_component = $class;
378 }
379 }
380
381 return $this->_component;
382 }
383
384 /**
385 * Returns the application client folder (admin or site).
386 *
387 * @return string The client.
388 */
389 public function getClientFolder()
390 {
391 if (is_null($this->_client))
392 {
393 $this->_client = JFactory::getApplication()->isAdmin() ? 'admin' : 'site';
394 }
395
396 return $this->_client;
397 }
398 }
399
400 /**
401 * Alias for JModel, which is still used by the components.
402 *
403 * @since 10.1.24
404 */
405 class_alias('JModel', 'JModelLegacy');
406