PageRenderTime 33ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/libraries/joomla/application/component/model.php

http://github.com/joomla/joomla-platform
PHP | 525 lines | 227 code | 59 blank | 239 comment | 26 complexity | b4409e2540a3bd132198af8640d1c220 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Application
  5. *
  6. * @copyright Copyright (C) 2005 - 2012 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. * @package Joomla.Platform
  17. * @subpackage Application
  18. * @since 11.1
  19. */
  20. abstract class JModel extends JObject
  21. {
  22. /**
  23. * Indicates if the internal state has been set
  24. *
  25. * @var boolean
  26. * @since 11.1
  27. */
  28. protected $stateSet = null;
  29. /**
  30. * Indicates if the internal state has been set
  31. *
  32. * @var boolean
  33. * @since 11.1
  34. * @deprecated use $stateSet declare as private
  35. */
  36. protected $__state_set = null;
  37. /**
  38. * Database Connector
  39. *
  40. * @var object
  41. * @since 11.1
  42. */
  43. protected $db;
  44. /**
  45. * Database Connector
  46. *
  47. * @var object
  48. * @since 11.1
  49. * @deprecated use $db declare as private
  50. */
  51. protected $_db;
  52. /**
  53. * The model (base) name
  54. *
  55. * @var string
  56. * @note Replaces _name variable in 11.1
  57. * @since 11.1
  58. */
  59. protected $name;
  60. /**
  61. * The URL option for the component.
  62. *
  63. * @var string
  64. * @since 11.1
  65. */
  66. protected $option = null;
  67. /**
  68. * A state object
  69. *
  70. * @var string
  71. * @note Replaces _state variable in 11.1
  72. * @since 11.1
  73. */
  74. protected $state;
  75. /**
  76. * The event to trigger when cleaning cache.
  77. *
  78. * @var string
  79. * @since 11.1
  80. */
  81. protected $event_clean_cache = null;
  82. /**
  83. * Add a directory where JModel should search for models. You may
  84. * either pass a string or an array of directories.
  85. *
  86. * @param mixed $path A path or array[sting] of paths to search.
  87. * @param string $prefix A prefix for models.
  88. *
  89. * @return array An array with directory elements. If prefix is equal to '', all directories are returned.
  90. *
  91. * @since 11.1
  92. */
  93. public static function addIncludePath($path = '', $prefix = '')
  94. {
  95. static $paths;
  96. if (!isset($paths))
  97. {
  98. $paths = array();
  99. }
  100. if (!isset($paths[$prefix]))
  101. {
  102. $paths[$prefix] = array();
  103. }
  104. if (!isset($paths['']))
  105. {
  106. $paths[''] = array();
  107. }
  108. if (!empty($path))
  109. {
  110. jimport('joomla.filesystem.path');
  111. if (!in_array($path, $paths[$prefix]))
  112. {
  113. array_unshift($paths[$prefix], JPath::clean($path));
  114. }
  115. if (!in_array($path, $paths['']))
  116. {
  117. array_unshift($paths[''], JPath::clean($path));
  118. }
  119. }
  120. return $paths[$prefix];
  121. }
  122. /**
  123. * Adds to the stack of model table paths in LIFO order.
  124. *
  125. * @param mixed $path The directory as a string or directories as an array to add.
  126. *
  127. * @return void
  128. *
  129. * @since 11.1
  130. */
  131. public static function addTablePath($path)
  132. {
  133. JTable::addIncludePath($path);
  134. }
  135. /**
  136. * Create the filename for a resource
  137. *
  138. * @param string $type The resource type to create the filename for.
  139. * @param array $parts An associative array of filename information.
  140. *
  141. * @return string The filename
  142. *
  143. * @since 11.1
  144. */
  145. protected static function _createFileName($type, $parts = array())
  146. {
  147. $filename = '';
  148. switch ($type)
  149. {
  150. case 'model':
  151. $filename = strtolower($parts['name']) . '.php';
  152. break;
  153. }
  154. return $filename;
  155. }
  156. /**
  157. * Returns a Model object, always creating it
  158. *
  159. * @param string $type The model type to instantiate
  160. * @param string $prefix Prefix for the model class name. Optional.
  161. * @param array $config Configuration array for model. Optional.
  162. *
  163. * @return mixed A model object or false on failure
  164. *
  165. * @since 11.1
  166. */
  167. public static function getInstance($type, $prefix = '', $config = array())
  168. {
  169. $type = preg_replace('/[^A-Z0-9_\.-]/i', '', $type);
  170. $modelClass = $prefix . ucfirst($type);
  171. if (!class_exists($modelClass))
  172. {
  173. jimport('joomla.filesystem.path');
  174. $path = JPath::find(JModel::addIncludePath(null, $prefix), JModel::_createFileName('model', array('name' => $type)));
  175. if (!$path)
  176. {
  177. $path = JPath::find(JModel::addIncludePath(null, ''), JModel::_createFileName('model', array('name' => $type)));
  178. }
  179. if ($path)
  180. {
  181. require_once $path;
  182. if (!class_exists($modelClass))
  183. {
  184. JError::raiseWarning(0, JText::sprintf('JLIB_APPLICATION_ERROR_MODELCLASS_NOT_FOUND', $modelClass));
  185. return false;
  186. }
  187. }
  188. else
  189. {
  190. return false;
  191. }
  192. }
  193. return new $modelClass($config);
  194. }
  195. /**
  196. * Constructor
  197. *
  198. * @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request).
  199. *
  200. * @since 11.1
  201. */
  202. public function __construct($config = array())
  203. {
  204. // Guess the option from the class name (Option)Model(View).
  205. if (empty($this->option))
  206. {
  207. $r = null;
  208. if (!preg_match('/(.*)Model/i', get_class($this), $r))
  209. {
  210. JError::raiseError(500, JText::_('JLIB_APPLICATION_ERROR_MODEL_GET_NAME'));
  211. }
  212. $this->option = 'com_' . strtolower($r[1]);
  213. }
  214. // Set the view name
  215. if (empty($this->name))
  216. {
  217. if (array_key_exists('name', $config))
  218. {
  219. $this->name = $config['name'];
  220. }
  221. else
  222. {
  223. $this->name = $this->getName();
  224. }
  225. }
  226. // Set the model state
  227. if (array_key_exists('state', $config))
  228. {
  229. $this->state = $config['state'];
  230. }
  231. else
  232. {
  233. $this->state = new JObject;
  234. }
  235. // Set the model dbo
  236. if (array_key_exists('dbo', $config))
  237. {
  238. $this->_db = $config['dbo'];
  239. }
  240. else
  241. {
  242. $this->_db = JFactory::getDbo();
  243. }
  244. // Set the default view search path
  245. if (array_key_exists('table_path', $config))
  246. {
  247. $this->addTablePath($config['table_path']);
  248. }
  249. elseif (defined('JPATH_COMPONENT_ADMINISTRATOR'))
  250. {
  251. $this->addTablePath(JPATH_COMPONENT_ADMINISTRATOR . '/tables');
  252. }
  253. // Set the internal state marker - used to ignore setting state from the request
  254. if (!empty($config['ignore_request']))
  255. {
  256. $this->__state_set = true;
  257. }
  258. // Set the clean cache event
  259. if (isset($config['event_clean_cache']))
  260. {
  261. $this->event_clean_cache = $config['event_clean_cache'];
  262. }
  263. elseif (empty($this->event_clean_cache))
  264. {
  265. $this->event_clean_cache = 'onContentCleanCache';
  266. }
  267. }
  268. /**
  269. * Gets an array of objects from the results of database query.
  270. *
  271. * @param string $query The query.
  272. * @param integer $limitstart Offset.
  273. * @param integer $limit The number of records.
  274. *
  275. * @return array An array of results.
  276. *
  277. * @since 11.1
  278. */
  279. protected function _getList($query, $limitstart = 0, $limit = 0)
  280. {
  281. $this->_db->setQuery($query, $limitstart, $limit);
  282. $result = $this->_db->loadObjectList();
  283. return $result;
  284. }
  285. /**
  286. * Returns a record count for the query
  287. *
  288. * @param string $query The query.
  289. *
  290. * @return integer Number of rows for query
  291. *
  292. * @since 11.1
  293. */
  294. protected function _getListCount($query)
  295. {
  296. $this->_db->setQuery($query);
  297. $this->_db->query();
  298. return $this->_db->getNumRows();
  299. }
  300. /**
  301. * Method to load and return a model object.
  302. *
  303. * @param string $name The name of the view
  304. * @param string $prefix The class prefix. Optional.
  305. * @param array $config Configuration settings to pass to JTable::getInstance
  306. *
  307. * @return mixed Model object or boolean false if failed
  308. *
  309. * @since 11.1
  310. * @see JTable::getInstance
  311. */
  312. protected function _createTable($name, $prefix = 'Table', $config = array())
  313. {
  314. // Clean the model name
  315. $name = preg_replace('/[^A-Z0-9_]/i', '', $name);
  316. $prefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix);
  317. // Make sure we are returning a DBO object
  318. if (!array_key_exists('dbo', $config))
  319. {
  320. $config['dbo'] = $this->getDbo();
  321. }
  322. return JTable::getInstance($name, $prefix, $config);
  323. }
  324. /**
  325. * Method to get the database connector object
  326. *
  327. * @return JDatabase JDatabase connector object
  328. */
  329. public function getDbo()
  330. {
  331. return $this->_db;
  332. }
  333. /**
  334. * Method to get the model name
  335. *
  336. * The model name. By default parsed using the classname or it can be set
  337. * by passing a $config['name'] in the class constructor
  338. *
  339. * @return string The name of the model
  340. *
  341. * @since 11.1
  342. */
  343. public function getName()
  344. {
  345. if (empty($this->name))
  346. {
  347. $r = null;
  348. if (!preg_match('/Model(.*)/i', get_class($this), $r))
  349. {
  350. JError::raiseError(500, JText::_('JLIB_APPLICATION_ERROR_MODEL_GET_NAME'));
  351. }
  352. $this->name = strtolower($r[1]);
  353. }
  354. return $this->name;
  355. }
  356. /**
  357. * Method to get model state variables
  358. *
  359. * @param string $property Optional parameter name
  360. * @param mixed $default Optional default value
  361. *
  362. * @return object The property where specified, the state object where omitted
  363. *
  364. * @since 11.1
  365. */
  366. public function getState($property = null, $default = null)
  367. {
  368. if (!$this->__state_set)
  369. {
  370. // Protected method to auto-populate the model state.
  371. $this->populateState();
  372. // Set the model state set flag to true.
  373. $this->__state_set = true;
  374. }
  375. return $property === null ? $this->state : $this->state->get($property, $default);
  376. }
  377. /**
  378. * Method to get a table object, load it if necessary.
  379. *
  380. * @param string $name The table name. Optional.
  381. * @param string $prefix The class prefix. Optional.
  382. * @param array $options Configuration array for model. Optional.
  383. *
  384. * @return JTable A JTable object
  385. *
  386. * @since 11.1
  387. */
  388. public function getTable($name = '', $prefix = 'Table', $options = array())
  389. {
  390. if (empty($name))
  391. {
  392. $name = $this->getName();
  393. }
  394. if ($table = $this->_createTable($name, $prefix, $options))
  395. {
  396. return $table;
  397. }
  398. JError::raiseError(0, JText::sprintf('JLIB_APPLICATION_ERROR_TABLE_NAME_NOT_SUPPORTED', $name));
  399. return null;
  400. }
  401. /**
  402. * Method to auto-populate the model state.
  403. *
  404. * This method should only be called once per instantiation and is designed
  405. * to be called on the first call to the getState() method unless the model
  406. * configuration flag to ignore the request is set.
  407. *
  408. * @return void
  409. *
  410. * @note Calling getState in this method will result in recursion.
  411. * @since 11.1
  412. */
  413. protected function populateState()
  414. {
  415. }
  416. /**
  417. * Method to set the database connector object
  418. *
  419. * @param object &$db A JDatabase based object
  420. *
  421. * @return void
  422. *
  423. * @since 11.1
  424. */
  425. public function setDbo(&$db)
  426. {
  427. $this->_db = &$db;
  428. }
  429. /**
  430. * Method to set model state variables
  431. *
  432. * @param string $property The name of the property.
  433. * @param mixed $value The value of the property to set or null.
  434. *
  435. * @return mixed The previous value of the property or null if not set.
  436. *
  437. * @since 11.1
  438. */
  439. public function setState($property, $value = null)
  440. {
  441. return $this->state->set($property, $value);
  442. }
  443. /**
  444. * Clean the cache
  445. *
  446. * @param string $group The cache group
  447. * @param integer $client_id The ID of the client
  448. *
  449. * @return void
  450. *
  451. * @since 11.1
  452. */
  453. protected function cleanCache($group = null, $client_id = 0)
  454. {
  455. // Initialise variables;
  456. $conf = JFactory::getConfig();
  457. $dispatcher = JDispatcher::getInstance();
  458. $options = array(
  459. 'defaultgroup' => ($group) ? $group : (isset($this->option) ? $this->option : JRequest::getCmd('option')),
  460. 'cachebase' => ($client_id) ? JPATH_ADMINISTRATOR . '/cache' : $conf->get('cache_path', JPATH_SITE . '/cache'));
  461. $cache = JCache::getInstance('callback', $options);
  462. $cache->clean();
  463. // Trigger the onContentCleanCache event.
  464. $dispatcher->trigger($this->event_clean_cache, $options);
  465. }
  466. }