PluginProbe
VikBooking Hotel Booking Engine & PMS / trunk
VikBooking Hotel Booking Engine & PMS vtrunk
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 1.7.3 All 36 releases
vikbooking / libraries / adapter / mvc / model.php

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

406 lines 9.5 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 /**
170 * Iterate paths until we find an existing file (or till the list is empty).
171 *
172 * @since 10.1.54 Keep iterating until we find a compatible class instead of
173 * a compatible file, since different plugins might support the
174 * same file name.
175 */
176 for ($i = 0, $path = null; $i < count($paths) && !static::$instances[$sign]; $i++)
177 {
178 // create path
179 $path = $paths[$i] . DIRECTORY_SEPARATOR . strtolower($type) . '.php';
180
181 // make sure the file exists
182 if (is_file($path))
183 {
184 // include model
185 require_once $path;
186
187 // make sure the class exists
188 if (class_exists($classname))
189 {
190 // cache model instance
191 static::$instances[$sign] = new $classname($config);
192 }
193 }
194 }
195 }
196
197 return static::$instances[$sign];
198 }
199
200 /**
201 * Add a directory where the class should search for models.
202 * You may either pass a string or an array of directories.
203 *
204 * @param mixed $path A path or array of paths to search.
205 *
206 * @return array An array with directory elements.
207 *
208 * @since 10.1.24
209 */
210 public static function addIncludePath($path = null)
211 {
212 if (!empty($path))
213 {
214 JLoader::import('adapter.filesystem.path');
215
216 foreach ((array) $path as $includePath)
217 {
218 $includePath = JPath::clean($includePath);
219
220 // check if the path is a dir
221 if (!is_dir($includePath))
222 {
223 // extract name between component and models
224 if (preg_match("/components[\/\\\\]com_([a-z0-9_]+)[\/\\\\]models/", $includePath, $match))
225 {
226 // access adapters of current plugin
227 $option = JFactory::getApplication()->input->get('option');
228 // strip initial com_ from option name
229 $option = preg_replace("/^com_/", '', $option);
230
231 // rewrite include path
232 $includePath = JPath::clean(WP_PLUGIN_DIR . '/' . $option . '/libraries/adapter/mvc/models/' . end($match));
233 }
234 }
235
236 // make sure the folder is not already in the list
237 if (!in_array($includePath, static::$paths))
238 {
239 // push directory as first
240 array_unshift(static::$paths, $includePath);
241 }
242 }
243 }
244
245 return static::$paths;
246 }
247
248 /**
249 * Class constructor.
250 *
251 * @param array $config An array of configuration options.
252 *
253 * @since 10.1.35 Added $config argument.
254 * @since 10.1.35 Removed $table and $pk arguments.
255 */
256 public function __construct($config = array())
257 {
258 $option = $this->getComponentName();
259
260 if (!array_key_exists('table_path', $config) && $option)
261 {
262 /**
263 * In case the client hasn't been provided, assume we should load the models
264 * from the same path of the current application client (admin or site).
265 *
266 * @since 10.1.55
267 */
268 if (empty($config['client']))
269 {
270 $config['client'] = JFactory::getApplication()->isAdmin() ? 'admin' : 'site';
271 }
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