PageRenderTime 60ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/components/com_content/models/article.php

https://github.com/cholalabs/CholaApps2.0
PHP | 306 lines | 188 code | 49 blank | 69 comment | 42 complexity | 75807245f8dde691d7d5ad921c287c66 MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id: article.php 20810 2011-02-21 20:01:22Z dextercowley $
  4. * @package Chola.Site
  5. * @subpackage com_content
  6. * @copyright Copyright (C) 2005 - 2011 Cholalabs Software LLP. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE.txt
  8. */
  9. // No direct access
  10. defined('_JEXEC') or die;
  11. jimport('chola.application.component.modelitem');
  12. /**
  13. * Content Component Article Model
  14. *
  15. * @package Chola.Site
  16. * @subpackage com_content
  17. * @since 1.5
  18. */
  19. class ContentModelArticle extends JModelItem
  20. {
  21. /**
  22. * Model context string.
  23. *
  24. * @var string
  25. */
  26. protected $_context = 'com_content.article';
  27. /**
  28. * Method to auto-populate the model state.
  29. *
  30. * Note. Calling getState in this method will result in recursion.
  31. *
  32. * @since 1.6
  33. */
  34. protected function populateState()
  35. {
  36. $app = JFactory::getApplication('site');
  37. // Load state from the request.
  38. $pk = JRequest::getInt('id');
  39. $this->setState('article.id', $pk);
  40. $offset = JRequest::getInt('limitstart');
  41. $this->setState('list.offset', $offset);
  42. // Load the parameters.
  43. $params = $app->getParams();
  44. $this->setState('params', $params);
  45. // TODO: Tune these values based on other permissions.
  46. $user = JFactory::getUser();
  47. if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content'))){
  48. $this->setState('filter.published', 1);
  49. $this->setState('filter.archived', 2);
  50. }
  51. }
  52. /**
  53. * Method to get article data.
  54. *
  55. * @param integer The id of the article.
  56. *
  57. * @return mixed Menu item data object on success, false on failure.
  58. */
  59. public function &getItem($pk = null)
  60. {
  61. // Initialise variables.
  62. $pk = (!empty($pk)) ? $pk : (int) $this->getState('article.id');
  63. if ($this->_item === null) {
  64. $this->_item = array();
  65. }
  66. if (!isset($this->_item[$pk])) {
  67. try {
  68. $db = $this->getDbo();
  69. $query = $db->getQuery(true);
  70. $query->select($this->getState(
  71. 'item.select', 'a.id, a.asset_id, a.title, a.alias, a.title_alias, a.introtext, a.fulltext, ' .
  72. // If badcats is not null, this means that the article is inside an unpublished category
  73. // In this case, the state is set to 0 to indicate Unpublished (even if the article state is Published)
  74. 'CASE WHEN badcats.id is null THEN a.state ELSE 0 END AS state, ' .
  75. 'a.mask, a.catid, a.created, a.created_by, a.created_by_alias, ' .
  76. 'a.modified, a.modified_by, a.checked_out, a.checked_out_time, a.publish_up, a.publish_down, ' .
  77. 'a.images, a.urls, a.attribs, a.version, a.parentid, a.ordering, ' .
  78. 'a.metakey, a.metadesc, a.access, a.hits, a.metadata, a.featured, a.language, a.xreference'
  79. )
  80. );
  81. $query->from('#__content AS a');
  82. // Join on category table.
  83. $query->select('c.title AS category_title, c.alias AS category_alias, c.access AS category_access');
  84. $query->join('LEFT', '#__categories AS c on c.id = a.catid');
  85. // Join on user table.
  86. $query->select('u.name AS author');
  87. $query->join('LEFT', '#__users AS u on u.id = a.created_by');
  88. // Join on contact table
  89. $query->select('contact.id as contactid' ) ;
  90. $query->join('LEFT','#__contact_details AS contact on contact.user_id = a.created_by');
  91. // Join over the categories to get parent category titles
  92. $query->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias');
  93. $query->join('LEFT', '#__categories as parent ON parent.id = c.parent_id');
  94. // Join on voting table
  95. $query->select('ROUND( v.rating_sum / v.rating_count ) AS rating, v.rating_count as rating_count');
  96. $query->join('LEFT', '#__content_rating AS v ON a.id = v.content_id');
  97. $query->where('a.id = ' . (int) $pk);
  98. // Filter by start and end dates.
  99. $nullDate = $db->Quote($db->getNullDate());
  100. $nowDate = $db->Quote(JFactory::getDate()->toMySQL());
  101. $query->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')');
  102. $query->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')');
  103. // Join to check for category published state in parent categories up the tree
  104. // If all categories are published, badcats.id will be null, and we just use the article state
  105. $subquery = ' (SELECT cat.id as id FROM #__categories AS cat JOIN #__categories AS parent ';
  106. $subquery .= 'ON cat.lft BETWEEN parent.lft AND parent.rgt ';
  107. $subquery .= 'WHERE parent.extension = ' . $db->quote('com_content');
  108. $subquery .= ' AND parent.published <= 0 GROUP BY cat.id)';
  109. $query->join('LEFT OUTER', $subquery . ' AS badcats ON badcats.id = c.id');
  110. // Filter by published state.
  111. $published = $this->getState('filter.published');
  112. $archived = $this->getState('filter.archived');
  113. if (is_numeric($published)) {
  114. $query->where('(a.state = ' . (int) $published . ' OR a.state =' . (int) $archived . ')');
  115. }
  116. $db->setQuery($query);
  117. $data = $db->loadObject();
  118. if ($error = $db->getErrorMsg()) {
  119. throw new Exception($error);
  120. }
  121. if (empty($data)) {
  122. return JError::raiseError(404,JText::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND'));
  123. }
  124. // Check for published state if filter set.
  125. if (((is_numeric($published)) || (is_numeric($archived))) && (($data->state != $published) && ($data->state != $archived))) {
  126. return JError::raiseError(404,JText::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND'));
  127. }
  128. // Convert parameter fields to objects.
  129. $registry = new JRegistry;
  130. $registry->loadJSON($data->attribs);
  131. $data->params = clone $this->getState('params');
  132. $data->params->merge($registry);
  133. $registry = new JRegistry;
  134. $registry->loadJSON($data->metadata);
  135. $data->metadata = $registry;
  136. // Compute selected asset permissions.
  137. $user = JFactory::getUser();
  138. // Technically guest could edit an article, but lets not check that to improve performance a little.
  139. if (!$user->get('guest')) {
  140. $userId = $user->get('id');
  141. $asset = 'com_content.article.'.$data->id;
  142. // Check general edit permission first.
  143. if ($user->authorise('core.edit', $asset)) {
  144. $data->params->set('access-edit', true);
  145. }
  146. // Now check if edit.own is available.
  147. else if (!empty($userId) && $user->authorise('core.edit.own', $asset)) {
  148. // Check for a valid user and that they are the owner.
  149. if ($userId == $data->created_by) {
  150. $data->params->set('access-edit', true);
  151. }
  152. }
  153. }
  154. // Compute view access permissions.
  155. if ($access = $this->getState('filter.access')) {
  156. // If the access filter has been set, we already know this user can view.
  157. $data->params->set('access-view', true);
  158. }
  159. else {
  160. // If no access filter is set, the layout takes some responsibility for display of limited information.
  161. $user = JFactory::getUser();
  162. $groups = $user->getAuthorisedViewLevels();
  163. if ($data->catid == 0 || $data->category_access === null) {
  164. $data->params->set('access-view', in_array($data->access, $groups));
  165. }
  166. else {
  167. $data->params->set('access-view', in_array($data->access, $groups) && in_array($data->category_access, $groups));
  168. }
  169. }
  170. $this->_item[$pk] = $data;
  171. }
  172. catch (JException $e)
  173. {
  174. if ($e->getCode() == 404) {
  175. // Need to go thru the error handler to allow Redirect to work.
  176. JError::raiseError(404, $e->getMessage());
  177. }
  178. else {
  179. $this->setError($e);
  180. $this->_item[$pk] = false;
  181. }
  182. }
  183. }
  184. return $this->_item[$pk];
  185. }
  186. /**
  187. * Increment the hit counter for the article.
  188. *
  189. * @param int Optional primary key of the article to increment.
  190. *
  191. * @return boolean True if successful; false otherwise and internal error set.
  192. */
  193. public function hit($pk = 0)
  194. {
  195. $hitcount = JRequest::getInt('hitcount', 1);
  196. if ($hitcount)
  197. {
  198. // Initialise variables.
  199. $pk = (!empty($pk)) ? $pk : (int) $this->getState('article.id');
  200. $db = $this->getDbo();
  201. $db->setQuery(
  202. 'UPDATE #__content' .
  203. ' SET hits = hits + 1' .
  204. ' WHERE id = '.(int) $pk
  205. );
  206. if (!$db->query()) {
  207. $this->setError($db->getErrorMsg());
  208. return false;
  209. }
  210. }
  211. return true;
  212. }
  213. public function storeVote($pk = 0, $rate = 0)
  214. {
  215. if ( $rate >= 1 && $rate <= 5 && $pk > 0 )
  216. {
  217. $userIP = $_SERVER['REMOTE_ADDR'];
  218. $db = $this->getDbo();
  219. $db->setQuery(
  220. 'SELECT *' .
  221. ' FROM #__content_rating' .
  222. ' WHERE content_id = '.(int) $pk
  223. );
  224. $rating = $db->loadObject();
  225. if (!$rating)
  226. {
  227. // There are no ratings yet, so lets insert our rating
  228. $db->setQuery(
  229. 'INSERT INTO #__content_rating ( content_id, lastip, rating_sum, rating_count )' .
  230. ' VALUES ( '.(int) $pk.', '.$db->Quote($userIP).', '.(int) $rate.', 1 )'
  231. );
  232. if (!$db->query()) {
  233. $this->setError($db->getErrorMsg());
  234. return false;
  235. }
  236. } else {
  237. if ($userIP != ($rating->lastip))
  238. {
  239. $db->setQuery(
  240. 'UPDATE #__content_rating' .
  241. ' SET rating_count = rating_count + 1, rating_sum = rating_sum + '.(int) $rate.', lastip = '.$db->Quote($userIP) .
  242. ' WHERE content_id = '.(int) $pk
  243. );
  244. if (!$db->query()) {
  245. $this->setError($db->getErrorMsg());
  246. return false;
  247. }
  248. } else {
  249. return false;
  250. }
  251. }
  252. return true;
  253. }
  254. JError::raiseWarning( 'SOME_ERROR_CODE', JText::sprintf('COM_CONTENT_INVALID_RATING', $rate), "JModelArticle::storeVote($rate)");
  255. return false;
  256. }
  257. }