PageRenderTime 25ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/legacy/model/legacy.php

https://gitlab.com/lankerd/paGO---Testing-Site
PHP | 596 lines | 277 code | 78 blank | 241 comment | 40 complexity | 505c2303fa55f401e3a2b8a6a86ef4b0 MD5 | raw file
  1. <?php
  2. /**
  3. * @package Joomla.Legacy
  4. * @subpackage Model
  5. *
  6. * @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * Base class for a Joomla Model
  12. *
  13. * Acts as a Factory class for application specific objects and
  14. * provides many supporting API functions.
  15. *
  16. * @since 12.2
  17. */
  18. abstract class JModelLegacy extends JObject
  19. {
  20. /**
  21. * Indicates if the internal state has been set
  22. *
  23. * @var boolean
  24. * @since 12.2
  25. */
  26. protected $__state_set = null;
  27. /**
  28. * Database Connector
  29. *
  30. * @var JDatabaseDriver
  31. * @since 12.2
  32. */
  33. protected $_db;
  34. /**
  35. * The model (base) name
  36. *
  37. * @var string
  38. * @since 12.2
  39. */
  40. protected $name;
  41. /**
  42. * The URL option for the component.
  43. *
  44. * @var string
  45. * @since 12.2
  46. */
  47. protected $option = null;
  48. /**
  49. * A state object
  50. *
  51. * @var JObject
  52. * @since 12.2
  53. */
  54. protected $state;
  55. /**
  56. * The event to trigger when cleaning cache.
  57. *
  58. * @var string
  59. * @since 12.2
  60. */
  61. protected $event_clean_cache = null;
  62. /**
  63. * Add a directory where JModelLegacy should search for models. You may
  64. * either pass a string or an array of directories.
  65. *
  66. * @param mixed $path A path or array[sting] of paths to search.
  67. * @param string $prefix A prefix for models.
  68. *
  69. * @return array An array with directory elements. If prefix is equal to '', all directories are returned.
  70. *
  71. * @since 12.2
  72. */
  73. public static function addIncludePath($path = '', $prefix = '')
  74. {
  75. static $paths;
  76. if (!isset($paths))
  77. {
  78. $paths = array();
  79. }
  80. if (!isset($paths[$prefix]))
  81. {
  82. $paths[$prefix] = array();
  83. }
  84. if (!isset($paths['']))
  85. {
  86. $paths[''] = array();
  87. }
  88. if (!empty($path))
  89. {
  90. jimport('joomla.filesystem.path');
  91. if (!is_array($path))
  92. {
  93. $path = array($path);
  94. }
  95. foreach ($path as $includePath)
  96. {
  97. if (!in_array($includePath, $paths[$prefix]))
  98. {
  99. array_unshift($paths[$prefix], JPath::clean($includePath));
  100. }
  101. if (!in_array($includePath, $paths['']))
  102. {
  103. array_unshift($paths[''], JPath::clean($includePath));
  104. }
  105. }
  106. }
  107. return $paths[$prefix];
  108. }
  109. /**
  110. * Adds to the stack of model table paths in LIFO order.
  111. *
  112. * @param mixed $path The directory as a string or directories as an array to add.
  113. *
  114. * @return void
  115. *
  116. * @since 12.2
  117. */
  118. public static function addTablePath($path)
  119. {
  120. JTable::addIncludePath($path);
  121. }
  122. /**
  123. * Create the filename for a resource
  124. *
  125. * @param string $type The resource type to create the filename for.
  126. * @param array $parts An associative array of filename information.
  127. *
  128. * @return string The filename
  129. *
  130. * @since 12.2
  131. */
  132. protected static function _createFileName($type, $parts = array())
  133. {
  134. $filename = '';
  135. switch ($type)
  136. {
  137. case 'model':
  138. $filename = strtolower($parts['name']) . '.php';
  139. break;
  140. }
  141. return $filename;
  142. }
  143. /**
  144. * Returns a Model object, always creating it
  145. *
  146. * @param string $type The model type to instantiate
  147. * @param string $prefix Prefix for the model class name. Optional.
  148. * @param array $config Configuration array for model. Optional.
  149. *
  150. * @return mixed A model object or false on failure
  151. *
  152. * @since 12.2
  153. */
  154. public static function getInstance($type, $prefix = '', $config = array())
  155. {
  156. $type = preg_replace('/[^A-Z0-9_\.-]/i', '', $type);
  157. $modelClass = $prefix . ucfirst($type);
  158. if (!class_exists($modelClass))
  159. {
  160. jimport('joomla.filesystem.path');
  161. $path = JPath::find(self::addIncludePath(null, $prefix), self::_createFileName('model', array('name' => $type)));
  162. if (!$path)
  163. {
  164. $path = JPath::find(self::addIncludePath(null, ''), self::_createFileName('model', array('name' => $type)));
  165. }
  166. if ($path)
  167. {
  168. require_once $path;
  169. if (!class_exists($modelClass))
  170. {
  171. JLog::add(JText::sprintf('JLIB_APPLICATION_ERROR_MODELCLASS_NOT_FOUND', $modelClass), JLog::WARNING, 'jerror');
  172. return false;
  173. }
  174. }
  175. else
  176. {
  177. return false;
  178. }
  179. }
  180. return new $modelClass($config);
  181. }
  182. /**
  183. * Constructor
  184. *
  185. * @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request).
  186. *
  187. * @since 12.2
  188. * @throws Exception
  189. */
  190. public function __construct($config = array())
  191. {
  192. // Guess the option from the class name (Option)Model(View).
  193. if (empty($this->option))
  194. {
  195. $r = null;
  196. if (!preg_match('/(.*)Model/i', get_class($this), $r))
  197. {
  198. throw new Exception(JText::_('JLIB_APPLICATION_ERROR_MODEL_GET_NAME'), 500);
  199. }
  200. $this->option = 'com_' . strtolower($r[1]);
  201. }
  202. // Set the view name
  203. if (empty($this->name))
  204. {
  205. if (array_key_exists('name', $config))
  206. {
  207. $this->name = $config['name'];
  208. }
  209. else
  210. {
  211. $this->name = $this->getName();
  212. }
  213. }
  214. // Set the model state
  215. if (array_key_exists('state', $config))
  216. {
  217. $this->state = $config['state'];
  218. }
  219. else
  220. {
  221. $this->state = new JObject;
  222. }
  223. // Set the model dbo
  224. if (array_key_exists('dbo', $config))
  225. {
  226. $this->_db = $config['dbo'];
  227. }
  228. else
  229. {
  230. $this->_db = JFactory::getDbo();
  231. }
  232. // Set the default view search path
  233. if (array_key_exists('table_path', $config))
  234. {
  235. $this->addTablePath($config['table_path']);
  236. }
  237. // @codeCoverageIgnoreStart
  238. elseif (defined('JPATH_COMPONENT_ADMINISTRATOR'))
  239. {
  240. $this->addTablePath(JPATH_COMPONENT_ADMINISTRATOR . '/tables');
  241. $this->addTablePath(JPATH_COMPONENT_ADMINISTRATOR . '/table');
  242. }
  243. // @codeCoverageIgnoreEnd
  244. // Set the internal state marker - used to ignore setting state from the request
  245. if (!empty($config['ignore_request']))
  246. {
  247. $this->__state_set = true;
  248. }
  249. // Set the clean cache event
  250. if (isset($config['event_clean_cache']))
  251. {
  252. $this->event_clean_cache = $config['event_clean_cache'];
  253. }
  254. elseif (empty($this->event_clean_cache))
  255. {
  256. $this->event_clean_cache = 'onContentCleanCache';
  257. }
  258. }
  259. /**
  260. * Gets an array of objects from the results of database query.
  261. *
  262. * @param string $query The query.
  263. * @param integer $limitstart Offset.
  264. * @param integer $limit The number of records.
  265. *
  266. * @return array An array of results.
  267. *
  268. * @since 12.2
  269. * @throws RuntimeException
  270. */
  271. protected function _getList($query, $limitstart = 0, $limit = 0)
  272. {
  273. $this->_db->setQuery($query, $limitstart, $limit);
  274. $result = $this->_db->loadObjectList();
  275. return $result;
  276. }
  277. /**
  278. * Returns a record count for the query.
  279. *
  280. * @param JDatabaseQuery|string $query The query.
  281. *
  282. * @return integer Number of rows for query.
  283. *
  284. * @since 12.2
  285. */
  286. protected function _getListCount($query)
  287. {
  288. // Use fast COUNT(*) on JDatabaseQuery objects if there is no GROUP BY or HAVING clause:
  289. if ($query instanceof JDatabaseQuery
  290. && $query->type == 'select'
  291. && $query->group === null
  292. && $query->union === null
  293. && $query->unionAll === null
  294. && $query->having === null)
  295. {
  296. $query = clone $query;
  297. $query->clear('select')->clear('order')->clear('limit')->clear('offset')->select('COUNT(*)');
  298. $this->_db->setQuery($query);
  299. return (int) $this->_db->loadResult();
  300. }
  301. // Otherwise fall back to inefficient way of counting all results.
  302. // Remove the limit and offset part if it's a JDatabaseQuery object
  303. if ($query instanceof JDatabaseQuery)
  304. {
  305. $query = clone $query;
  306. $query->clear('limit')->clear('offset');
  307. }
  308. $this->_db->setQuery($query);
  309. $this->_db->execute();
  310. return (int) $this->_db->getNumRows();
  311. }
  312. /**
  313. * Method to load and return a model object.
  314. *
  315. * @param string $name The name of the view
  316. * @param string $prefix The class prefix. Optional.
  317. * @param array $config Configuration settings to pass to JTable::getInstance
  318. *
  319. * @return mixed Model object or boolean false if failed
  320. *
  321. * @since 12.2
  322. * @see JTable::getInstance()
  323. */
  324. protected function _createTable($name, $prefix = 'Table', $config = array())
  325. {
  326. // Clean the model name
  327. $name = preg_replace('/[^A-Z0-9_]/i', '', $name);
  328. $prefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix);
  329. // Make sure we are returning a DBO object
  330. if (!array_key_exists('dbo', $config))
  331. {
  332. $config['dbo'] = $this->getDbo();
  333. }
  334. return JTable::getInstance($name, $prefix, $config);
  335. }
  336. /**
  337. * Method to get the database driver object
  338. *
  339. * @return JDatabaseDriver
  340. */
  341. public function getDbo()
  342. {
  343. return $this->_db;
  344. }
  345. /**
  346. * Method to get the model name
  347. *
  348. * The model name. By default parsed using the classname or it can be set
  349. * by passing a $config['name'] in the class constructor
  350. *
  351. * @return string The name of the model
  352. *
  353. * @since 12.2
  354. * @throws Exception
  355. */
  356. public function getName()
  357. {
  358. if (empty($this->name))
  359. {
  360. $r = null;
  361. if (!preg_match('/Model(.*)/i', get_class($this), $r))
  362. {
  363. throw new Exception(JText::_('JLIB_APPLICATION_ERROR_MODEL_GET_NAME'), 500);
  364. }
  365. $this->name = strtolower($r[1]);
  366. }
  367. return $this->name;
  368. }
  369. /**
  370. * Method to get model state variables
  371. *
  372. * @param string $property Optional parameter name
  373. * @param mixed $default Optional default value
  374. *
  375. * @return object The property where specified, the state object where omitted
  376. *
  377. * @since 12.2
  378. */
  379. public function getState($property = null, $default = null)
  380. {
  381. if (!$this->__state_set)
  382. {
  383. // Protected method to auto-populate the model state.
  384. $this->populateState();
  385. // Set the model state set flag to true.
  386. $this->__state_set = true;
  387. }
  388. return $property === null ? $this->state : $this->state->get($property, $default);
  389. }
  390. /**
  391. * Method to get a table object, load it if necessary.
  392. *
  393. * @param string $name The table name. Optional.
  394. * @param string $prefix The class prefix. Optional.
  395. * @param array $options Configuration array for model. Optional.
  396. *
  397. * @return JTable A JTable object
  398. *
  399. * @since 12.2
  400. * @throws Exception
  401. */
  402. public function getTable($name = '', $prefix = 'Table', $options = array())
  403. {
  404. if (empty($name))
  405. {
  406. $name = $this->getName();
  407. }
  408. if ($table = $this->_createTable($name, $prefix, $options))
  409. {
  410. return $table;
  411. }
  412. throw new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_TABLE_NAME_NOT_SUPPORTED', $name), 0);
  413. }
  414. /**
  415. * Method to load a row for editing from the version history table.
  416. *
  417. * @param integer $version_id Key to the version history table.
  418. * @param JTable &$table Content table object being loaded.
  419. *
  420. * @return boolean False on failure or error, true otherwise.
  421. *
  422. * @since 12.2
  423. */
  424. public function loadHistory($version_id, JTable &$table)
  425. {
  426. // Only attempt to check the row in if it exists, otherwise do an early exit.
  427. if (!$version_id)
  428. {
  429. return false;
  430. }
  431. // Get an instance of the row to checkout.
  432. $historyTable = JTable::getInstance('Contenthistory');
  433. if (!$historyTable->load($version_id))
  434. {
  435. $this->setError($historyTable->getError());
  436. return false;
  437. }
  438. $rowArray = JArrayHelper::fromObject(json_decode($historyTable->version_data));
  439. $typeId = JTable::getInstance('Contenttype')->getTypeId($this->typeAlias);
  440. if ($historyTable->ucm_type_id != $typeId)
  441. {
  442. $this->setError(JText::_('JLIB_APPLICATION_ERROR_HISTORY_ID_MISMATCH'));
  443. $key = $table->getKeyName();
  444. if (isset($rowArray[$key]))
  445. {
  446. $table->checkIn($rowArray[$key]);
  447. }
  448. return false;
  449. }
  450. $this->setState('save_date', $historyTable->save_date);
  451. $this->setState('version_note', $historyTable->version_note);
  452. return $table->bind($rowArray);
  453. }
  454. /**
  455. * Method to auto-populate the model state.
  456. *
  457. * This method should only be called once per instantiation and is designed
  458. * to be called on the first call to the getState() method unless the model
  459. * configuration flag to ignore the request is set.
  460. *
  461. * @return void
  462. *
  463. * @note Calling getState in this method will result in recursion.
  464. * @since 12.2
  465. */
  466. protected function populateState()
  467. {
  468. }
  469. /**
  470. * Method to set the database driver object
  471. *
  472. * @param JDatabaseDriver $db A JDatabaseDriver based object
  473. *
  474. * @return void
  475. *
  476. * @since 12.2
  477. */
  478. public function setDbo($db)
  479. {
  480. $this->_db = $db;
  481. }
  482. /**
  483. * Method to set model state variables
  484. *
  485. * @param string $property The name of the property.
  486. * @param mixed $value The value of the property to set or null.
  487. *
  488. * @return mixed The previous value of the property or null if not set.
  489. *
  490. * @since 12.2
  491. */
  492. public function setState($property, $value = null)
  493. {
  494. return $this->state->set($property, $value);
  495. }
  496. /**
  497. * Clean the cache
  498. *
  499. * @param string $group The cache group
  500. * @param integer $client_id The ID of the client
  501. *
  502. * @return void
  503. *
  504. * @since 12.2
  505. */
  506. protected function cleanCache($group = null, $client_id = 0)
  507. {
  508. $conf = JFactory::getConfig();
  509. $dispatcher = JEventDispatcher::getInstance();
  510. $options = array(
  511. 'defaultgroup' => ($group) ? $group : (isset($this->option) ? $this->option : JFactory::getApplication()->input->get('option')),
  512. 'cachebase' => ($client_id) ? JPATH_ADMINISTRATOR . '/cache' : $conf->get('cache_path', JPATH_SITE . '/cache'));
  513. $cache = JCache::getInstance('callback', $options);
  514. $cache->clean();
  515. // Trigger the onContentCleanCache event.
  516. $dispatcher->trigger($this->event_clean_cache, $options);
  517. }
  518. }