| [ Index ] |
PHP Cross Reference of Joomla 1.5.26 DE |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @version $Id: article.php 14401 2010-01-26 14:10:00Z louis $ 4 * @package Joomla 5 * @subpackage Content 6 * @copyright Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved. 7 * @license GNU/GPL, see LICENSE.php 8 * Joomla! is free software. This version may have been modified pursuant to the 9 * GNU General Public License, and as distributed it includes or is derivative 10 * of works licensed under the GNU General Public License or other free or open 11 * source software licenses. See COPYRIGHT.php for copyright notices and 12 * details. 13 */ 14 15 // Check to ensure this file is included in Joomla! 16 defined('_JEXEC') or die( 'Restricted access' ); 17 18 jimport('joomla.application.component.model'); 19 20 /** 21 * Content Component Article Model 22 * 23 * @package Joomla 24 * @subpackage Content 25 * @since 1.5 26 */ 27 class ContentModelArticle extends JModel 28 { 29 /** 30 * Article data 31 * 32 * @var object 33 */ 34 var $_article = null; 35 36 /** 37 * Constructor 38 * 39 * @since 1.5 40 */ 41 function __construct() 42 { 43 parent::__construct(); 44 45 $id = JRequest::getVar('id', 0, '', 'int'); 46 $this->setId((int)$id); 47 } 48 49 /** 50 * Method to set the article id 51 * 52 * @access public 53 * @param int Article ID number 54 */ 55 function setId($id) 56 { 57 // Set new article ID and wipe data 58 $this->_id = $id; 59 $this->_article = null; 60 } 61 62 /** 63 * Overridden set method to pass properties on to the article 64 * 65 * @access public 66 * @param string $property The name of the property 67 * @param mixed $value The value of the property to set 68 * @return boolean True on success 69 * @since 1.5 70 */ 71 function set( $property, $value=null ) 72 { 73 if ($this->_loadArticle()) { 74 $this->_article->$property = $value; 75 return true; 76 } else { 77 return false; 78 } 79 } 80 81 /** 82 * Overridden get method to get properties from the article 83 * 84 * @access public 85 * @param string $property The name of the property 86 * @param mixed $value The value of the property to set 87 * @return mixed The value of the property 88 * @since 1.5 89 */ 90 function get($property, $default=null) 91 { 92 if ($this->_loadArticle()) { 93 if(isset($this->_article->$property)) { 94 return $this->_article->$property; 95 } 96 } 97 return $default; 98 } 99 100 /** 101 * Method to get content article data for the frontpage 102 * 103 * @since 1.5 104 */ 105 function &getArticle() 106 { 107 // Load the Category data 108 if ($this->_loadArticle()) 109 { 110 $user = & JFactory::getUser(); 111 112 // Is the category published? 113 if (!$this->_article->cat_pub && $this->_article->catid) { 114 JError::raiseError( 404, JText::_("Article category not published") ); 115 } 116 117 // Is the section published? 118 if ($this->_article->sectionid) 119 { 120 if ($this->_article->sec_pub === null) 121 { 122 // probably a new item 123 // check the sectionid probably passed in the request 124 $db =& $this->getDBO(); 125 $query = 'SELECT published' . 126 ' FROM #__sections' . 127 ' WHERE id = ' . (int) $this->_article->sectionid; 128 $db->setQuery( $query ); 129 $this->_article->sec_pub = $db->loadResult(); 130 } 131 if (!$this->_article->sec_pub) 132 { 133 JError::raiseError( 404, JText::_("Article section not published") ); 134 } 135 } 136 137 // Do we have access to the category? 138 if (($this->_article->cat_access > $user->get('aid', 0)) && $this->_article->catid) { 139 JError::raiseError( 403, JText::_("ALERTNOTAUTH") ); 140 } 141 142 // Do we have access to the section? 143 if (($this->_article->sec_access > $user->get('aid', 0)) && $this->_article->sectionid) { 144 JError::raiseError( 403, JText::_("ALERTNOTAUTH") ); 145 } 146 147 $this->_loadArticleParams(); 148 } 149 else 150 { 151 $user =& JFactory::getUser(); 152 $article =& JTable::getInstance('content'); 153 $article->state = 1; 154 $article->cat_pub = null; 155 $article->sec_pub = null; 156 $article->cat_access = null; 157 $article->sec_access = null; 158 $article->author = null; 159 $article->created_by = $user->get('id'); 160 $article->parameters = new JParameter( '' ); 161 $article->text = ''; 162 $this->_article = $article; 163 } 164 165 return $this->_article; 166 } 167 168 /** 169 * Method to increment the hit counter for the article 170 * 171 * @access public 172 * @return boolean True on success 173 * @since 1.5 174 */ 175 function hit() 176 { 177 global $mainframe; 178 179 if ($this->_id) 180 { 181 $article = & JTable::getInstance('content'); 182 $article->hit($this->_id); 183 return true; 184 } 185 return false; 186 } 187 188 /** 189 * Tests if article is checked out 190 * 191 * @access public 192 * @param int A user id 193 * @return boolean True if checked out 194 * @since 1.5 195 */ 196 function isCheckedOut( $uid=0 ) 197 { 198 if ($this->_loadArticle()) 199 { 200 if ($uid) { 201 return ($this->_article->checked_out && $this->_article->checked_out != $uid); 202 } else { 203 return $this->_article->checked_out; 204 } 205 } elseif ($this->_id < 1) { 206 return false; 207 } else { 208 JError::raiseWarning( 0, 'Unable to Load Data'); 209 return false; 210 } 211 } 212 213 /** 214 * Method to checkin/unlock the article 215 * 216 * @access public 217 * @return boolean True on success 218 * @since 1.5 219 */ 220 function checkin() 221 { 222 if ($this->_id) 223 { 224 $article = & JTable::getInstance('content'); 225 return $article->checkin($this->_id); 226 } 227 return false; 228 } 229 230 /** 231 * Method to checkout/lock the article 232 * 233 * @access public 234 * @param int $uid User ID of the user checking the article out 235 * @return boolean True on success 236 * @since 1.5 237 */ 238 function checkout($uid = null) 239 { 240 if ($this->_id) 241 { 242 // Make sure we have a user id to checkout the article with 243 if (is_null($uid)) { 244 $user =& JFactory::getUser(); 245 $uid = $user->get('id'); 246 } 247 // Lets get to it and checkout the thing... 248 $article = & JTable::getInstance('content'); 249 return $article->checkout($uid, $this->_id); 250 } 251 return false; 252 } 253 254 /** 255 * Method to store the article 256 * 257 * @access public 258 * @return boolean True on success 259 * @since 1.5 260 */ 261 function store($data) 262 { 263 global $mainframe; 264 265 $article =& JTable::getInstance('content'); 266 $user =& JFactory::getUser(); 267 $dispatcher =& JDispatcher::getInstance(); 268 JPluginHelper::importPlugin('content'); 269 270 // Bind the form fields to the web link table 271 if (!$article->bind($data, "published")) { 272 $this->setError($this->_db->getErrorMsg()); 273 return false; 274 } 275 276 // sanitise id field 277 $article->id = (int) $article->id; 278 279 $isNew = ($article->id < 1); 280 if ($isNew) 281 { 282 $article->created = gmdate('Y-m-d H:i:s'); 283 $article->created_by = $user->get('id'); 284 } 285 else 286 { 287 $article->modified = gmdate('Y-m-d H:i:s'); 288 $article->modified_by = $user->get('id'); 289 } 290 291 // Append time if not added to publish date 292 if (strlen(trim($article->publish_up)) <= 10) { 293 $article->publish_up .= ' 00:00:00'; 294 } 295 296 $date =& JFactory::getDate($article->publish_up, $mainframe->getCfg('offset')); 297 $article->publish_up = $date->toMySQL(); 298 299 // Handle never unpublish date 300 if (trim($article->publish_down) == JText::_('Never') || trim( $article->publish_down ) == '') 301 { 302 $article->publish_down = $this->_db->getNullDate();; 303 } 304 else 305 { 306 if (strlen(trim( $article->publish_down )) <= 10) { 307 $article->publish_down .= ' 00:00:00'; 308 } 309 310 $date =& JFactory::getDate($article->publish_down, $mainframe->getCfg('offset')); 311 $article->publish_down = $date->toMySQL(); 312 } 313 314 $article->title = trim( $article->title ); 315 316 // get state and created_by from existing article 317 $originalState = 0; 318 if (!$isNew) 319 { 320 $query = 'SELECT state, created_by' . 321 ' FROM #__content' . 322 ' WHERE id = '.(int) $article->id; 323 $this->_db->setQuery($query); 324 $originalArticle = $this->_db->loadObject(); 325 $originalState = $originalArticle->state; 326 // force the created_by to the existing value 327 $article->created_by = $originalArticle->created_by; 328 } 329 330 // Publishing state hardening for Authors 331 if (!$user->authorize('com_content', 'publish', 'content', 'all')) 332 { 333 if ($isNew) 334 { 335 // For new items - author is not allowed to publish - prevent them from doing so 336 $article->state = 0; 337 } 338 else 339 { 340 // For existing items keep existing state - author is not allowed to change status 341 342 $state = $originalState; 343 344 if ($state) { 345 $article->state = 1; 346 } 347 else { 348 $article->state = 0; 349 } 350 351 // if current user is author, check that the current user is really the author 352 if (!$user->authorize('com_content', 'edit', 'content', 'all')) 353 { 354 if ($originalArticle->created_by != $user->id) 355 { 356 JError::raiseError( 403, JText::_("ALERTNOTAUTH") ); 357 } 358 } 359 } 360 } 361 362 // Search for the {readmore} tag and split the text up accordingly. 363 $text = str_replace('<br>', '<br />', $data['text']); 364 365 $pattern = '#<hr\s+id=("|\')system-readmore("|\')\s*\/*>#i'; 366 $tagPos = preg_match($pattern, $text); 367 368 if ($tagPos == 0) { 369 $article->introtext = $text; 370 } else { 371 list($article->introtext, $article->fulltext) = preg_split($pattern, $text, 2); 372 } 373 374 // Filter settings 375 jimport( 'joomla.application.component.helper' ); 376 $config = JComponentHelper::getParams( 'com_content' ); 377 $user = &JFactory::getUser(); 378 $gid = $user->get( 'gid' ); 379 380 $filterGroups = $config->get( 'filter_groups' ); 381 382 // convert to array if one group selected 383 if ( (!is_array($filterGroups) && (int) $filterGroups > 0) ) { 384 $filterGroups = array($filterGroups); 385 } 386 387 if (is_array($filterGroups) && in_array( $gid, $filterGroups )) 388 { 389 $filterType = $config->get( 'filter_type' ); 390 $filterTags = preg_split( '#[,\s]+#', trim( $config->get( 'filter_tags' ) ) ); 391 $filterAttrs = preg_split( '#[,\s]+#', trim( $config->get( 'filter_attritbutes' ) ) ); 392 switch ($filterType) 393 { 394 case 'NH': 395 $filter = new JFilterInput(); 396 break; 397 case 'WL': 398 $filter = new JFilterInput( $filterTags, $filterAttrs, 0, 0 ); 399 break; 400 case 'BL': 401 default: 402 $filter = new JFilterInput( $filterTags, $filterAttrs, 1, 1 ); 403 break; 404 } 405 $article->introtext = $filter->clean( $article->introtext ); 406 $article->fulltext = $filter->clean( $article->fulltext ); 407 } elseif(empty($filterGroups)) { 408 $filter = new JFilterInput(array(), array(), 1, 1); 409 $article->introtext = $filter->clean( $article->introtext ); 410 $article->fulltext = $filter->clean( $article->fulltext ); 411 } 412 413 // Make sure the article table is valid 414 if (!$article->check()) { 415 $this->setError($article->getError()); 416 return false; 417 } 418 419 $article->version++; 420 421 //Trigger OnBeforeContentSave 422 $result = $dispatcher->trigger('onBeforeContentSave', array(&$article, $isNew)); 423 if(in_array(false, $result, true)) { 424 $this->setError($article->getError()); 425 return false; 426 } 427 428 // Store the article table to the database 429 if (!$article->store()) { 430 $this->setError($this->_db->getErrorMsg()); 431 return false; 432 } 433 434 if ($isNew) 435 { 436 $this->_id = $article->_db->insertId(); 437 } 438 439 $article->reorder("catid = " . (int) $data['catid']); 440 441 //Trigger OnAfterContentSave 442 $dispatcher->trigger('onAfterContentSave', array(&$article, $isNew)); 443 444 $this->_article =& $article; 445 446 return true; 447 } 448 449 /** 450 * Method to store a user rating for a content article 451 * 452 * @access public 453 * @param int $rating Article rating [ 1 - 5 ] 454 * @return boolean True on success 455 * @since 1.5 456 */ 457 function storeVote($rate) 458 { 459 if ( $rate >= 1 && $rate <= 5) 460 { 461 $userIP = $_SERVER['REMOTE_ADDR']; 462 463 $query = 'SELECT *' . 464 ' FROM #__content_rating' . 465 ' WHERE content_id = '.(int) $this->_id; 466 $this->_db->setQuery($query); 467 $rating = $this->_db->loadObject(); 468 469 if (!$rating) 470 { 471 // There are no ratings yet, so lets insert our rating 472 $query = 'INSERT INTO #__content_rating ( content_id, lastip, rating_sum, rating_count )' . 473 ' VALUES ( '.(int) $this->_id.', '.$this->_db->Quote($userIP).', '.(int) $rate.', 1 )'; 474 $this->_db->setQuery($query); 475 if (!$this->_db->query()) { 476 JError::raiseError( 500, $this->_db->stderr()); 477 } 478 } 479 else 480 { 481 if ($userIP != ($rating->lastip)) 482 { 483 // We weren't the last voter so lets add our vote to the ratings totals for the article 484 $query = 'UPDATE #__content_rating' . 485 ' SET rating_count = rating_count + 1, rating_sum = rating_sum + '.(int) $rate.', lastip = '.$this->_db->Quote($userIP) . 486 ' WHERE content_id = '.(int) $this->_id; 487 $this->_db->setQuery($query); 488 if (!$this->_db->query()) { 489 JError::raiseError( 500, $this->_db->stderr()); 490 } 491 } 492 else 493 { 494 return false; 495 } 496 } 497 return true; 498 } 499 JError::raiseWarning( 'SOME_ERROR_CODE', 'Article Rating:: Invalid Rating:' .$rate, "JModelArticle::storeVote($rate)"); 500 return false; 501 } 502 503 /** 504 * Method to load content article data 505 * 506 * @access private 507 * @return boolean True on success 508 * @since 1.5 509 */ 510 function _loadArticle() 511 { 512 global $mainframe; 513 514 if($this->_id == '0') 515 { 516 return false; 517 } 518 519 // Load the content if it doesn't already exist 520 if (empty($this->_article)) 521 { 522 // Get the page/component configuration 523 $params = &$mainframe->getParams(); 524 525 // If voting is turned on, get voting data as well for the article 526 $voting = ContentHelperQuery::buildVotingQuery($params); 527 528 // Get the WHERE clause 529 $where = $this->_buildContentWhere(); 530 531 $query = 'SELECT a.*, u.name AS author, u.usertype, cc.title AS category, s.title AS section,' . 532 ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END as slug,'. 533 ' CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END as catslug,'. 534 ' g.name AS groups, s.published AS sec_pub, cc.published AS cat_pub, s.access AS sec_access, cc.access AS cat_access '.$voting['select']. 535 ' FROM #__content AS a' . 536 ' LEFT JOIN #__categories AS cc ON cc.id = a.catid' . 537 ' LEFT JOIN #__sections AS s ON s.id = cc.section AND s.scope = "content"' . 538 ' LEFT JOIN #__users AS u ON u.id = a.created_by' . 539 ' LEFT JOIN #__groups AS g ON a.access = g.id'. 540 $voting['join']. 541 $where; 542 $this->_db->setQuery($query); 543 $this->_article = $this->_db->loadObject(); 544 545 if ( ! $this->_article ) { 546 return false; 547 } 548 549 if($this->_article->publish_down == $this->_db->getNullDate()) { 550 $this->_article->publish_down = JText::_('Never'); 551 } 552 553 // These attributes need to be defined in order for the voting plugin to work 554 if ( count($voting) && ! isset($this->_article->rating_count) ) { 555 $this->_article->rating_count = 0; 556 $this->_article->rating = 0; 557 } 558 559 return true; 560 } 561 return true; 562 } 563 564 /** 565 * Method to load content article parameters 566 * 567 * @access private 568 * @return void 569 * @since 1.5 570 */ 571 function _loadArticleParams() 572 { 573 global $mainframe; 574 575 // Get the page/component configuration 576 $params = clone($mainframe->getParams('com_content')); 577 578 // Merge article parameters into the page configuration 579 $aparams = new JParameter($this->_article->attribs); 580 $params->merge($aparams); 581 582 // Set the popup configuration option based on the request 583 $pop = JRequest::getVar('pop', 0, '', 'int'); 584 $params->set('popup', $pop); 585 586 // Are we showing introtext with the article 587 if (!$params->get('show_intro') && !empty($this->_article->fulltext)) { 588 $this->_article->text = $this->_article->fulltext; 589 } else { 590 $this->_article->text = $this->_article->introtext . chr(13).chr(13) . $this->_article->fulltext; 591 } 592 593 // Set the article object's parameters 594 $this->_article->parameters = & $params; 595 } 596 597 /** 598 * Method to build the WHERE clause of the query to select a content article 599 * 600 * @access private 601 * @return string WHERE clause 602 * @since 1.5 603 */ 604 function _buildContentWhere() 605 { 606 global $mainframe; 607 608 $user =& JFactory::getUser(); 609 $aid = (int) $user->get('aid', 0); 610 611 $jnow =& JFactory::getDate(); 612 $now = $jnow->toMySQL(); 613 $nullDate = $this->_db->getNullDate(); 614 615 /* 616 * First thing we need to do is assert that the content article is the one 617 * we are looking for and we have access to it. 618 */ 619 $where = ' WHERE a.id = '. (int) $this->_id; 620 // $where .= ' AND a.access <= '. (int) $aid; 621 622 if (!$user->authorize('com_content', 'edit', 'content', 'all')) 623 { 624 $where .= ' AND ( '; 625 $where .= ' ( a.created_by = ' . (int) $user->id . ' ) '; 626 $where .= ' OR '; 627 $where .= ' ( a.state = 1' . 628 ' AND ( a.publish_up = '.$this->_db->Quote($nullDate).' OR a.publish_up <= '.$this->_db->Quote($now).' )' . 629 ' AND ( a.publish_down = '.$this->_db->Quote($nullDate).' OR a.publish_down >= '.$this->_db->Quote($now).' )'; 630 $where .= ' ) '; 631 $where .= ' OR '; 632 $where .= ' ( a.state = -1 ) '; 633 $where .= ' ) '; 634 } 635 636 return $where; 637 } 638 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Mar 28 15:54:07 2012 | Cross-referenced by PHPXref 0.7.1 |