[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package Joomla.Site 5 * @subpackage com_content 6 * 7 * @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org> 8 * @license GNU General Public License version 2 or later; see LICENSE.txt 9 */ 10 11 namespace Joomla\Component\Content\Site\Model; 12 13 use Joomla\CMS\Factory; 14 use Joomla\CMS\Language\Multilanguage; 15 use Joomla\CMS\Language\Text; 16 use Joomla\CMS\MVC\Model\ItemModel; 17 use Joomla\CMS\Table\Table; 18 use Joomla\Component\Content\Administrator\Extension\ContentComponent; 19 use Joomla\Database\ParameterType; 20 use Joomla\Registry\Registry; 21 use Joomla\Utilities\IpHelper; 22 23 // phpcs:disable PSR1.Files.SideEffects 24 \defined('_JEXEC') or die; 25 // phpcs:enable PSR1.Files.SideEffects 26 27 /** 28 * Content Component Article Model 29 * 30 * @since 1.5 31 */ 32 class ArticleModel extends ItemModel 33 { 34 /** 35 * Model context string. 36 * 37 * @var string 38 */ 39 protected $_context = 'com_content.article'; 40 41 /** 42 * Method to auto-populate the model state. 43 * 44 * Note. Calling getState in this method will result in recursion. 45 * 46 * @since 1.6 47 * 48 * @return void 49 */ 50 protected function populateState() 51 { 52 $app = Factory::getApplication(); 53 54 // Load state from the request. 55 $pk = $app->input->getInt('id'); 56 $this->setState('article.id', $pk); 57 58 $offset = $app->input->getUint('limitstart'); 59 $this->setState('list.offset', $offset); 60 61 // Load the parameters. 62 $params = $app->getParams(); 63 $this->setState('params', $params); 64 65 $user = Factory::getUser(); 66 67 // If $pk is set then authorise on complete asset, else on component only 68 $asset = empty($pk) ? 'com_content' : 'com_content.article.' . $pk; 69 70 if ((!$user->authorise('core.edit.state', $asset)) && (!$user->authorise('core.edit', $asset))) { 71 $this->setState('filter.published', ContentComponent::CONDITION_PUBLISHED); 72 $this->setState('filter.archived', ContentComponent::CONDITION_ARCHIVED); 73 } 74 75 $this->setState('filter.language', Multilanguage::isEnabled()); 76 } 77 78 /** 79 * Method to get article data. 80 * 81 * @param integer $pk The id of the article. 82 * 83 * @return object|boolean Menu item data object on success, boolean false 84 */ 85 public function getItem($pk = null) 86 { 87 $user = Factory::getUser(); 88 89 $pk = (int) ($pk ?: $this->getState('article.id')); 90 91 if ($this->_item === null) { 92 $this->_item = array(); 93 } 94 95 if (!isset($this->_item[$pk])) { 96 try { 97 $db = $this->getDatabase(); 98 $query = $db->getQuery(true); 99 100 $query->select( 101 $this->getState( 102 'item.select', 103 [ 104 $db->quoteName('a.id'), 105 $db->quoteName('a.asset_id'), 106 $db->quoteName('a.title'), 107 $db->quoteName('a.alias'), 108 $db->quoteName('a.introtext'), 109 $db->quoteName('a.fulltext'), 110 $db->quoteName('a.state'), 111 $db->quoteName('a.catid'), 112 $db->quoteName('a.created'), 113 $db->quoteName('a.created_by'), 114 $db->quoteName('a.created_by_alias'), 115 $db->quoteName('a.modified'), 116 $db->quoteName('a.modified_by'), 117 $db->quoteName('a.checked_out'), 118 $db->quoteName('a.checked_out_time'), 119 $db->quoteName('a.publish_up'), 120 $db->quoteName('a.publish_down'), 121 $db->quoteName('a.images'), 122 $db->quoteName('a.urls'), 123 $db->quoteName('a.attribs'), 124 $db->quoteName('a.version'), 125 $db->quoteName('a.ordering'), 126 $db->quoteName('a.metakey'), 127 $db->quoteName('a.metadesc'), 128 $db->quoteName('a.access'), 129 $db->quoteName('a.hits'), 130 $db->quoteName('a.metadata'), 131 $db->quoteName('a.featured'), 132 $db->quoteName('a.language'), 133 ] 134 ) 135 ) 136 ->select( 137 [ 138 $db->quoteName('fp.featured_up'), 139 $db->quoteName('fp.featured_down'), 140 $db->quoteName('c.title', 'category_title'), 141 $db->quoteName('c.alias', 'category_alias'), 142 $db->quoteName('c.access', 'category_access'), 143 $db->quoteName('c.language', 'category_language'), 144 $db->quoteName('fp.ordering'), 145 $db->quoteName('u.name', 'author'), 146 $db->quoteName('parent.title', 'parent_title'), 147 $db->quoteName('parent.id', 'parent_id'), 148 $db->quoteName('parent.path', 'parent_route'), 149 $db->quoteName('parent.alias', 'parent_alias'), 150 $db->quoteName('parent.language', 'parent_language'), 151 'ROUND(' . $db->quoteName('v.rating_sum') . ' / ' . $db->quoteName('v.rating_count') . ', 1) AS ' 152 . $db->quoteName('rating'), 153 $db->quoteName('v.rating_count', 'rating_count'), 154 ] 155 ) 156 ->from($db->quoteName('#__content', 'a')) 157 ->join( 158 'INNER', 159 $db->quoteName('#__categories', 'c'), 160 $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid') 161 ) 162 ->join('LEFT', $db->quoteName('#__content_frontpage', 'fp'), $db->quoteName('fp.content_id') . ' = ' . $db->quoteName('a.id')) 163 ->join('LEFT', $db->quoteName('#__users', 'u'), $db->quoteName('u.id') . ' = ' . $db->quoteName('a.created_by')) 164 ->join('LEFT', $db->quoteName('#__categories', 'parent'), $db->quoteName('parent.id') . ' = ' . $db->quoteName('c.parent_id')) 165 ->join('LEFT', $db->quoteName('#__content_rating', 'v'), $db->quoteName('a.id') . ' = ' . $db->quoteName('v.content_id')) 166 ->where( 167 [ 168 $db->quoteName('a.id') . ' = :pk', 169 $db->quoteName('c.published') . ' > 0', 170 ] 171 ) 172 ->bind(':pk', $pk, ParameterType::INTEGER); 173 174 // Filter by language 175 if ($this->getState('filter.language')) { 176 $query->whereIn($db->quoteName('a.language'), [Factory::getLanguage()->getTag(), '*'], ParameterType::STRING); 177 } 178 179 if ( 180 !$user->authorise('core.edit.state', 'com_content.article.' . $pk) 181 && !$user->authorise('core.edit', 'com_content.article.' . $pk) 182 ) { 183 // Filter by start and end dates. 184 $nowDate = Factory::getDate()->toSql(); 185 186 $query->extendWhere( 187 'AND', 188 [ 189 $db->quoteName('a.publish_up') . ' IS NULL', 190 $db->quoteName('a.publish_up') . ' <= :publishUp', 191 ], 192 'OR' 193 ) 194 ->extendWhere( 195 'AND', 196 [ 197 $db->quoteName('a.publish_down') . ' IS NULL', 198 $db->quoteName('a.publish_down') . ' >= :publishDown', 199 ], 200 'OR' 201 ) 202 ->bind([':publishUp', ':publishDown'], $nowDate); 203 } 204 205 // Filter by published state. 206 $published = $this->getState('filter.published'); 207 $archived = $this->getState('filter.archived'); 208 209 if (is_numeric($published)) { 210 $query->whereIn($db->quoteName('a.state'), [(int) $published, (int) $archived]); 211 } 212 213 $db->setQuery($query); 214 215 $data = $db->loadObject(); 216 217 if (empty($data)) { 218 throw new \Exception(Text::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND'), 404); 219 } 220 221 // Check for published state if filter set. 222 if ((is_numeric($published) || is_numeric($archived)) && ($data->state != $published && $data->state != $archived)) { 223 throw new \Exception(Text::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND'), 404); 224 } 225 226 // Convert parameter fields to objects. 227 $registry = new Registry($data->attribs); 228 229 $data->params = clone $this->getState('params'); 230 $data->params->merge($registry); 231 232 $data->metadata = new Registry($data->metadata); 233 234 // Technically guest could edit an article, but lets not check that to improve performance a little. 235 if (!$user->get('guest')) { 236 $userId = $user->get('id'); 237 $asset = 'com_content.article.' . $data->id; 238 239 // Check general edit permission first. 240 if ($user->authorise('core.edit', $asset)) { 241 $data->params->set('access-edit', true); 242 } elseif (!empty($userId) && $user->authorise('core.edit.own', $asset)) { 243 // Now check if edit.own is available. 244 // Check for a valid user and that they are the owner. 245 if ($userId == $data->created_by) { 246 $data->params->set('access-edit', true); 247 } 248 } 249 } 250 251 // Compute view access permissions. 252 if ($access = $this->getState('filter.access')) { 253 // If the access filter has been set, we already know this user can view. 254 $data->params->set('access-view', true); 255 } else { 256 // If no access filter is set, the layout takes some responsibility for display of limited information. 257 $user = Factory::getUser(); 258 $groups = $user->getAuthorisedViewLevels(); 259 260 if ($data->catid == 0 || $data->category_access === null) { 261 $data->params->set('access-view', in_array($data->access, $groups)); 262 } else { 263 $data->params->set('access-view', in_array($data->access, $groups) && in_array($data->category_access, $groups)); 264 } 265 } 266 267 $this->_item[$pk] = $data; 268 } catch (\Exception $e) { 269 if ($e->getCode() == 404) { 270 // Need to go through the error handler to allow Redirect to work. 271 throw $e; 272 } else { 273 $this->setError($e); 274 $this->_item[$pk] = false; 275 } 276 } 277 } 278 279 return $this->_item[$pk]; 280 } 281 282 /** 283 * Increment the hit counter for the article. 284 * 285 * @param integer $pk Optional primary key of the article to increment. 286 * 287 * @return boolean True if successful; false otherwise and internal error set. 288 */ 289 public function hit($pk = 0) 290 { 291 $input = Factory::getApplication()->input; 292 $hitcount = $input->getInt('hitcount', 1); 293 294 if ($hitcount) { 295 $pk = (!empty($pk)) ? $pk : (int) $this->getState('article.id'); 296 297 $table = Table::getInstance('Content', 'JTable'); 298 $table->hit($pk); 299 } 300 301 return true; 302 } 303 304 /** 305 * Save user vote on article 306 * 307 * @param integer $pk Joomla Article Id 308 * @param integer $rate Voting rate 309 * 310 * @return boolean Return true on success 311 */ 312 public function storeVote($pk = 0, $rate = 0) 313 { 314 $pk = (int) $pk; 315 $rate = (int) $rate; 316 317 if ($rate >= 1 && $rate <= 5 && $pk > 0) { 318 $userIP = IpHelper::getIp(); 319 320 // Initialize variables. 321 $db = $this->getDatabase(); 322 $query = $db->getQuery(true); 323 324 // Create the base select statement. 325 $query->select('*') 326 ->from($db->quoteName('#__content_rating')) 327 ->where($db->quoteName('content_id') . ' = :pk') 328 ->bind(':pk', $pk, ParameterType::INTEGER); 329 330 // Set the query and load the result. 331 $db->setQuery($query); 332 333 // Check for a database error. 334 try { 335 $rating = $db->loadObject(); 336 } catch (\RuntimeException $e) { 337 Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); 338 339 return false; 340 } 341 342 // There are no ratings yet, so lets insert our rating 343 if (!$rating) { 344 $query = $db->getQuery(true); 345 346 // Create the base insert statement. 347 $query->insert($db->quoteName('#__content_rating')) 348 ->columns( 349 [ 350 $db->quoteName('content_id'), 351 $db->quoteName('lastip'), 352 $db->quoteName('rating_sum'), 353 $db->quoteName('rating_count'), 354 ] 355 ) 356 ->values(':pk, :ip, :rate, 1') 357 ->bind(':pk', $pk, ParameterType::INTEGER) 358 ->bind(':ip', $userIP) 359 ->bind(':rate', $rate, ParameterType::INTEGER); 360 361 // Set the query and execute the insert. 362 $db->setQuery($query); 363 364 try { 365 $db->execute(); 366 } catch (\RuntimeException $e) { 367 Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); 368 369 return false; 370 } 371 } else { 372 if ($userIP != $rating->lastip) { 373 $query = $db->getQuery(true); 374 375 // Create the base update statement. 376 $query->update($db->quoteName('#__content_rating')) 377 ->set( 378 [ 379 $db->quoteName('rating_count') . ' = ' . $db->quoteName('rating_count') . ' + 1', 380 $db->quoteName('rating_sum') . ' = ' . $db->quoteName('rating_sum') . ' + :rate', 381 $db->quoteName('lastip') . ' = :ip', 382 ] 383 ) 384 ->where($db->quoteName('content_id') . ' = :pk') 385 ->bind(':rate', $rate, ParameterType::INTEGER) 386 ->bind(':ip', $userIP) 387 ->bind(':pk', $pk, ParameterType::INTEGER); 388 389 // Set the query and execute the update. 390 $db->setQuery($query); 391 392 try { 393 $db->execute(); 394 } catch (\RuntimeException $e) { 395 Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); 396 397 return false; 398 } 399 } else { 400 return false; 401 } 402 } 403 404 $this->cleanCache(); 405 406 return true; 407 } 408 409 Factory::getApplication()->enqueueMessage(Text::sprintf('COM_CONTENT_INVALID_RATING', $rate), 'error'); 410 411 return false; 412 } 413 414 /** 415 * Cleans the cache of com_content and content modules 416 * 417 * @param string $group The cache group 418 * @param integer $clientId @deprecated 5.0 No longer used. 419 * 420 * @return void 421 * 422 * @since 3.9.9 423 */ 424 protected function cleanCache($group = null, $clientId = 0) 425 { 426 parent::cleanCache('com_content'); 427 parent::cleanCache('mod_articles_archive'); 428 parent::cleanCache('mod_articles_categories'); 429 parent::cleanCache('mod_articles_category'); 430 parent::cleanCache('mod_articles_latest'); 431 parent::cleanCache('mod_articles_news'); 432 parent::cleanCache('mod_articles_popular'); 433 } 434 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |