You've already forked joomla_test
first commit
This commit is contained in:
165
components/com_content/models/archive.php
Normal file
165
components/com_content/models/archive.php
Normal file
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
*
|
||||
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
require_once __DIR__ . '/articles.php';
|
||||
|
||||
/**
|
||||
* Content Component Archive Model
|
||||
*
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
* @since 1.5
|
||||
*/
|
||||
class ContentModelArchive extends ContentModelArticles
|
||||
{
|
||||
/**
|
||||
* Model context string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $_context = 'com_content.archive';
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function populateState($ordering = null, $direction = null)
|
||||
{
|
||||
parent::populateState();
|
||||
|
||||
$app = JFactory::getApplication();
|
||||
|
||||
// Add archive properties
|
||||
$params = $this->state->params;
|
||||
|
||||
// Filter on archived articles
|
||||
$this->setState('filter.published', 2);
|
||||
|
||||
// Filter on month, year
|
||||
$this->setState('filter.month', $app->input->getInt('month'));
|
||||
$this->setState('filter.year', $app->input->getInt('year'));
|
||||
|
||||
// Optional filter text
|
||||
$this->setState('list.filter', $app->input->getString('filter-search'));
|
||||
|
||||
// Get list limit
|
||||
$itemid = $app->input->get('Itemid', 0, 'int');
|
||||
$limit = $app->getUserStateFromRequest('com_content.archive.list' . $itemid . '.limit', 'limit', $params->get('display_num'), 'uint');
|
||||
$this->setState('list.limit', $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JDatabaseQuery
|
||||
*/
|
||||
protected function getListQuery()
|
||||
{
|
||||
// Set the archive ordering
|
||||
$params = $this->state->params;
|
||||
$articleOrderby = $params->get('orderby_sec', 'rdate');
|
||||
$articleOrderDate = $params->get('order_date');
|
||||
|
||||
// No category ordering
|
||||
$categoryOrderby = '';
|
||||
$secondary = ContentHelperQuery::orderbySecondary($articleOrderby, $articleOrderDate) . ', ';
|
||||
$primary = ContentHelperQuery::orderbyPrimary($categoryOrderby);
|
||||
|
||||
$orderby = $primary . ' ' . $secondary . ' a.created DESC ';
|
||||
$this->setState('list.ordering', $orderby);
|
||||
$this->setState('list.direction', '');
|
||||
// Create a new query object.
|
||||
$query = parent::getListQuery();
|
||||
|
||||
// Add routing for archive
|
||||
//sqlsrv changes
|
||||
$case_when = ' CASE WHEN ';
|
||||
$case_when .= $query->charLength('a.alias', '!=', '0');
|
||||
$case_when .= ' THEN ';
|
||||
$a_id = $query->castAsChar('a.id');
|
||||
$case_when .= $query->concatenate(array($a_id, 'a.alias'), ':');
|
||||
$case_when .= ' ELSE ';
|
||||
$case_when .= $a_id.' END as slug';
|
||||
|
||||
$query->select($case_when);
|
||||
|
||||
$case_when = ' CASE WHEN ';
|
||||
$case_when .= $query->charLength('c.alias', '!=', '0');
|
||||
$case_when .= ' THEN ';
|
||||
$c_id = $query->castAsChar('c.id');
|
||||
$case_when .= $query->concatenate(array($c_id, 'c.alias'), ':');
|
||||
$case_when .= ' ELSE ';
|
||||
$case_when .= $c_id.' END as catslug';
|
||||
$query->select($case_when);
|
||||
|
||||
// Filter on month, year
|
||||
// First, get the date field
|
||||
$queryDate = ContentHelperQuery::getQueryDate($articleOrderDate);
|
||||
|
||||
if ($month = $this->getState('filter.month'))
|
||||
{
|
||||
$query->where('MONTH('. $queryDate . ') = ' . $month);
|
||||
}
|
||||
|
||||
if ($year = $this->getState('filter.year'))
|
||||
{
|
||||
$query->where('YEAR('. $queryDate . ') = ' . $year);
|
||||
}
|
||||
|
||||
//echo nl2br(str_replace('#__','jos_',$query));
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the archived article list
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
$app = JFactory::getApplication();
|
||||
|
||||
// Lets load the content if it doesn't already exist
|
||||
if (empty($this->_data))
|
||||
{
|
||||
// Get the page/component configuration
|
||||
$params = $app->getParams();
|
||||
|
||||
// Get the pagination request variables
|
||||
$limit = $app->input->get('limit', $params->get('display_num', 20), 'uint');
|
||||
$limitstart = $app->input->get('limitstart', 0, 'uint');
|
||||
|
||||
$query = $this->_buildQuery();
|
||||
|
||||
$this->_data = $this->_getList($query, $limitstart, $limit);
|
||||
}
|
||||
|
||||
return $this->_data;
|
||||
}
|
||||
|
||||
// JModelLegacy override to add alternating value for $odd
|
||||
protected function _getList($query, $limitstart=0, $limit=0)
|
||||
{
|
||||
$result = parent::_getList($query, $limitstart, $limit);
|
||||
|
||||
$odd = 1;
|
||||
foreach ($result as $k => $row)
|
||||
{
|
||||
$result[$k]->odd = $odd;
|
||||
$odd = 1 - $odd;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
356
components/com_content/models/article.php
Normal file
356
components/com_content/models/article.php
Normal file
@ -0,0 +1,356 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
*
|
||||
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* Content Component Article Model
|
||||
*
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
* @since 1.5
|
||||
*/
|
||||
class ContentModelArticle extends JModelItem
|
||||
{
|
||||
/**
|
||||
* Model context string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_context = 'com_content.article';
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function populateState()
|
||||
{
|
||||
$app = JFactory::getApplication('site');
|
||||
|
||||
// Load state from the request.
|
||||
$pk = $app->input->getInt('id');
|
||||
$this->setState('article.id', $pk);
|
||||
|
||||
$offset = $app->input->getUInt('limitstart');
|
||||
$this->setState('list.offset', $offset);
|
||||
|
||||
// Load the parameters.
|
||||
$params = $app->getParams();
|
||||
$this->setState('params', $params);
|
||||
|
||||
// TODO: Tune these values based on other permissions.
|
||||
$user = JFactory::getUser();
|
||||
if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content')))
|
||||
{
|
||||
$this->setState('filter.published', 1);
|
||||
$this->setState('filter.archived', 2);
|
||||
}
|
||||
|
||||
$this->setState('filter.language', JLanguageMultilang::isEnabled());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get article data.
|
||||
*
|
||||
* @param integer The id of the article.
|
||||
*
|
||||
* @return mixed Menu item data object on success, false on failure.
|
||||
*/
|
||||
public function getItem($pk = null)
|
||||
{
|
||||
$pk = (!empty($pk)) ? $pk : (int) $this->getState('article.id');
|
||||
|
||||
if ($this->_item === null)
|
||||
{
|
||||
$this->_item = array();
|
||||
}
|
||||
|
||||
if (!isset($this->_item[$pk]))
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
$db = $this->getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select(
|
||||
$this->getState(
|
||||
'item.select', 'a.id, a.asset_id, a.title, a.alias, a.introtext, a.fulltext, ' .
|
||||
// If badcats is not null, this means that the article is inside an unpublished category
|
||||
// In this case, the state is set to 0 to indicate Unpublished (even if the article state is Published)
|
||||
'CASE WHEN badcats.id is null THEN a.state ELSE 0 END AS state, ' .
|
||||
'a.catid, a.created, a.created_by, a.created_by_alias, ' .
|
||||
// use created if modified is 0
|
||||
'CASE WHEN a.modified = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.modified END as modified, ' .
|
||||
'a.modified_by, a.checked_out, a.checked_out_time, a.publish_up, a.publish_down, ' .
|
||||
'a.images, a.urls, a.attribs, a.version, a.ordering, ' .
|
||||
'a.metakey, a.metadesc, a.access, a.hits, a.metadata, a.featured, a.language, a.xreference'
|
||||
)
|
||||
);
|
||||
$query->from('#__content AS a');
|
||||
|
||||
// Join on category table.
|
||||
$query->select('c.title AS category_title, c.alias AS category_alias, c.access AS category_access')
|
||||
->join('LEFT', '#__categories AS c on c.id = a.catid');
|
||||
|
||||
// Join on user table.
|
||||
$query->select('u.name AS author')
|
||||
->join('LEFT', '#__users AS u on u.id = a.created_by');
|
||||
|
||||
// Get contact id
|
||||
$subQuery = $db->getQuery(true)
|
||||
->select('MAX(contact.id) AS id')
|
||||
->from('#__contact_details AS contact')
|
||||
->where('contact.published = 1')
|
||||
->where('contact.user_id = a.created_by');
|
||||
// Filter by language
|
||||
if ($this->getState('filter.language'))
|
||||
{
|
||||
$subQuery->where('(contact.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ') OR contact.language IS NULL)');
|
||||
}
|
||||
$query->select('(' . $subQuery . ') as contactid');
|
||||
|
||||
// Filter by language
|
||||
if ($this->getState('filter.language'))
|
||||
{
|
||||
$query->where('a.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')');
|
||||
}
|
||||
|
||||
// Join over the categories to get parent category titles
|
||||
$query->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias')
|
||||
->join('LEFT', '#__categories as parent ON parent.id = c.parent_id');
|
||||
|
||||
// Join on voting table
|
||||
$query->select('ROUND(v.rating_sum / v.rating_count, 0) AS rating, v.rating_count as rating_count')
|
||||
->join('LEFT', '#__content_rating AS v ON a.id = v.content_id')
|
||||
|
||||
->where('a.id = ' . (int) $pk);
|
||||
|
||||
// Filter by start and end dates.
|
||||
$nullDate = $db->quote($db->getNullDate());
|
||||
$date = JFactory::getDate();
|
||||
|
||||
$nowDate = $db->quote($date->toSql());
|
||||
|
||||
$query->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')')
|
||||
->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')');
|
||||
|
||||
// Join to check for category published state in parent categories up the tree
|
||||
// If all categories are published, badcats.id will be null, and we just use the article state
|
||||
$subquery = ' (SELECT cat.id as id FROM #__categories AS cat JOIN #__categories AS parent ';
|
||||
$subquery .= 'ON cat.lft BETWEEN parent.lft AND parent.rgt ';
|
||||
$subquery .= 'WHERE parent.extension = ' . $db->quote('com_content');
|
||||
$subquery .= ' AND parent.published <= 0 GROUP BY cat.id)';
|
||||
$query->join('LEFT OUTER', $subquery . ' AS badcats ON badcats.id = c.id');
|
||||
|
||||
// Filter by published state.
|
||||
$published = $this->getState('filter.published');
|
||||
$archived = $this->getState('filter.archived');
|
||||
|
||||
if (is_numeric($published))
|
||||
{
|
||||
$query->where('(a.state = ' . (int) $published . ' OR a.state =' . (int) $archived . ')');
|
||||
}
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
$data = $db->loadObject();
|
||||
|
||||
if (empty($data))
|
||||
{
|
||||
return JError::raiseError(404, JText::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND'));
|
||||
}
|
||||
|
||||
// Check for published state if filter set.
|
||||
if (((is_numeric($published)) || (is_numeric($archived))) && (($data->state != $published) && ($data->state != $archived)))
|
||||
{
|
||||
return JError::raiseError(404, JText::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND'));
|
||||
}
|
||||
|
||||
// Convert parameter fields to objects.
|
||||
$registry = new JRegistry;
|
||||
$registry->loadString($data->attribs);
|
||||
|
||||
$data->params = clone $this->getState('params');
|
||||
$data->params->merge($registry);
|
||||
|
||||
$registry = new JRegistry;
|
||||
$registry->loadString($data->metadata);
|
||||
$data->metadata = $registry;
|
||||
|
||||
// Compute selected asset permissions.
|
||||
$user = JFactory::getUser();
|
||||
|
||||
// Technically guest could edit an article, but lets not check that to improve performance a little.
|
||||
if (!$user->get('guest'))
|
||||
{
|
||||
$userId = $user->get('id');
|
||||
$asset = 'com_content.article.' . $data->id;
|
||||
|
||||
// Check general edit permission first.
|
||||
if ($user->authorise('core.edit', $asset))
|
||||
{
|
||||
$data->params->set('access-edit', true);
|
||||
}
|
||||
// Now check if edit.own is available.
|
||||
elseif (!empty($userId) && $user->authorise('core.edit.own', $asset))
|
||||
{
|
||||
// Check for a valid user and that they are the owner.
|
||||
if ($userId == $data->created_by)
|
||||
{
|
||||
$data->params->set('access-edit', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute view access permissions.
|
||||
if ($access = $this->getState('filter.access'))
|
||||
{
|
||||
// If the access filter has been set, we already know this user can view.
|
||||
$data->params->set('access-view', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no access filter is set, the layout takes some responsibility for display of limited information.
|
||||
$user = JFactory::getUser();
|
||||
$groups = $user->getAuthorisedViewLevels();
|
||||
|
||||
if ($data->catid == 0 || $data->category_access === null)
|
||||
{
|
||||
$data->params->set('access-view', in_array($data->access, $groups));
|
||||
}
|
||||
else
|
||||
{
|
||||
$data->params->set('access-view', in_array($data->access, $groups) && in_array($data->category_access, $groups));
|
||||
}
|
||||
}
|
||||
|
||||
$this->_item[$pk] = $data;
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
if ($e->getCode() == 404)
|
||||
{
|
||||
// Need to go thru the error handler to allow Redirect to work.
|
||||
JError::raiseError(404, $e->getMessage());
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->setError($e);
|
||||
$this->_item[$pk] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_item[$pk];
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the hit counter for the article.
|
||||
*
|
||||
* @param integer Optional primary key of the article to increment.
|
||||
*
|
||||
* @return boolean True if successful; false otherwise and internal error set.
|
||||
*/
|
||||
public function hit($pk = 0)
|
||||
{
|
||||
$input = JFactory::getApplication()->input;
|
||||
$hitcount = $input->getInt('hitcount', 1);
|
||||
|
||||
if ($hitcount)
|
||||
{
|
||||
$pk = (!empty($pk)) ? $pk : (int) $this->getState('article.id');
|
||||
$db = $this->getDbo();
|
||||
|
||||
$db->setQuery(
|
||||
|
||||
'UPDATE #__content' .
|
||||
' SET hits = hits + 1' .
|
||||
' WHERE id = ' . (int) $pk
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
$db->execute();
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
$this->setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function storeVote($pk = 0, $rate = 0)
|
||||
{
|
||||
if ($rate >= 1 && $rate <= 5 && $pk > 0)
|
||||
{
|
||||
$userIP = $_SERVER['REMOTE_ADDR'];
|
||||
$db = $this->getDbo();
|
||||
|
||||
$db->setQuery(
|
||||
'SELECT *' .
|
||||
' FROM #__content_rating' .
|
||||
' WHERE content_id = ' . (int) $pk
|
||||
);
|
||||
|
||||
$rating = $db->loadObject();
|
||||
|
||||
if (!$rating)
|
||||
{
|
||||
// There are no ratings yet, so lets insert our rating
|
||||
$db->setQuery(
|
||||
'INSERT INTO #__content_rating ( content_id, lastip, rating_sum, rating_count )' .
|
||||
' VALUES ( ' . (int) $pk . ', ' . $db->quote($userIP) . ', ' . (int) $rate . ', 1 )'
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
$db->execute();
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
$this->setError($e->getMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($userIP != ($rating->lastip))
|
||||
{
|
||||
$db->setQuery(
|
||||
'UPDATE #__content_rating' .
|
||||
' SET rating_count = rating_count + 1, rating_sum = rating_sum + ' . (int) $rate . ', lastip = ' . $db->quote($userIP) .
|
||||
' WHERE content_id = ' . (int) $pk
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
$db->execute();
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
$this->setError($e->getMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
JError::raiseWarning('SOME_ERROR_CODE', JText::sprintf('COM_CONTENT_INVALID_RATING', $rate), "JModelArticle::storeVote($rate)");
|
||||
return false;
|
||||
}
|
||||
}
|
653
components/com_content/models/articles.php
Normal file
653
components/com_content/models/articles.php
Normal file
@ -0,0 +1,653 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
*
|
||||
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* This models supports retrieving lists of articles.
|
||||
*
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
* @since 1.6
|
||||
*/
|
||||
class ContentModelArticles extends JModelList
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array An optional associative array of configuration settings.
|
||||
* @see JController
|
||||
* @since 1.6
|
||||
*/
|
||||
public function __construct($config = array())
|
||||
{
|
||||
if (empty($config['filter_fields']))
|
||||
{
|
||||
$config['filter_fields'] = array(
|
||||
'id', 'a.id',
|
||||
'title', 'a.title',
|
||||
'alias', 'a.alias',
|
||||
'checked_out', 'a.checked_out',
|
||||
'checked_out_time', 'a.checked_out_time',
|
||||
'catid', 'a.catid', 'category_title',
|
||||
'state', 'a.state',
|
||||
'access', 'a.access', 'access_level',
|
||||
'created', 'a.created',
|
||||
'created_by', 'a.created_by',
|
||||
'ordering', 'a.ordering',
|
||||
'featured', 'a.featured',
|
||||
'language', 'a.language',
|
||||
'hits', 'a.hits',
|
||||
'publish_up', 'a.publish_up',
|
||||
'publish_down', 'a.publish_down',
|
||||
'images', 'a.images',
|
||||
'urls', 'a.urls',
|
||||
);
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @return void
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function populateState($ordering = 'ordering', $direction = 'ASC')
|
||||
{
|
||||
$app = JFactory::getApplication();
|
||||
|
||||
// List state information
|
||||
$value = $app->input->get('limit', $app->getCfg('list_limit', 0), 'uint');
|
||||
$this->setState('list.limit', $value);
|
||||
|
||||
$value = $app->input->get('limitstart', 0, 'uint');
|
||||
$this->setState('list.start', $value);
|
||||
|
||||
$orderCol = $app->input->get('filter_order', 'a.ordering');
|
||||
if (!in_array($orderCol, $this->filter_fields))
|
||||
{
|
||||
$orderCol = 'a.ordering';
|
||||
}
|
||||
$this->setState('list.ordering', $orderCol);
|
||||
|
||||
$listOrder = $app->input->get('filter_order_Dir', 'ASC');
|
||||
if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', '')))
|
||||
{
|
||||
$listOrder = 'ASC';
|
||||
}
|
||||
$this->setState('list.direction', $listOrder);
|
||||
|
||||
$params = $app->getParams();
|
||||
$this->setState('params', $params);
|
||||
$user = JFactory::getUser();
|
||||
|
||||
if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content')))
|
||||
{
|
||||
// filter on published for those who do not have edit or edit.state rights.
|
||||
$this->setState('filter.published', 1);
|
||||
}
|
||||
|
||||
$this->setState('filter.language', JLanguageMultilang::isEnabled());
|
||||
|
||||
// process show_noauth parameter
|
||||
if (!$params->get('show_noauth'))
|
||||
{
|
||||
$this->setState('filter.access', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->setState('filter.access', false);
|
||||
}
|
||||
|
||||
$this->setState('layout', $app->input->get('layout'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a store id based on model configuration state.
|
||||
*
|
||||
* This is necessary because the model is used by the component and
|
||||
* different modules that might need different sets of data or different
|
||||
* ordering requirements.
|
||||
*
|
||||
* @param string $id A prefix for the store id.
|
||||
*
|
||||
* @return string A store id.
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function getStoreId($id = '')
|
||||
{
|
||||
// Compile the store id.
|
||||
$id .= ':' . serialize($this->getState('filter.published'));
|
||||
$id .= ':' . $this->getState('filter.access');
|
||||
$id .= ':' . $this->getState('filter.featured');
|
||||
$id .= ':' . $this->getState('filter.article_id');
|
||||
$id .= ':' . $this->getState('filter.article_id.include');
|
||||
$id .= ':' . serialize($this->getState('filter.category_id'));
|
||||
$id .= ':' . $this->getState('filter.category_id.include');
|
||||
$id .= ':' . serialize($this->getState('filter.author_id'));
|
||||
$id .= ':' . $this->getState('filter.author_id.include');
|
||||
$id .= ':' . serialize($this->getState('filter.author_alias'));
|
||||
$id .= ':' . $this->getState('filter.author_alias.include');
|
||||
$id .= ':' . $this->getState('filter.date_filtering');
|
||||
$id .= ':' . $this->getState('filter.date_field');
|
||||
$id .= ':' . $this->getState('filter.start_date_range');
|
||||
$id .= ':' . $this->getState('filter.end_date_range');
|
||||
$id .= ':' . $this->getState('filter.relative_date');
|
||||
|
||||
return parent::getStoreId($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the master query for retrieving a list of articles subject to the model state.
|
||||
*
|
||||
* @return JDatabaseQuery
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function getListQuery()
|
||||
{
|
||||
// Create a new query object.
|
||||
$db = $this->getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
// Select the required fields from the table.
|
||||
$query->select(
|
||||
$this->getState(
|
||||
'list.select',
|
||||
'a.id, a.title, a.alias, a.introtext, ' .
|
||||
'a.checked_out, a.checked_out_time, ' .
|
||||
'a.catid, a.created, a.created_by, a.created_by_alias, ' .
|
||||
// use created if modified is 0
|
||||
'CASE WHEN a.modified = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.modified END as modified, ' .
|
||||
'a.modified_by, uam.name as modified_by_name,' .
|
||||
// use created if publish_up is 0
|
||||
'CASE WHEN a.publish_up = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.publish_up END as publish_up,' .
|
||||
'a.publish_down, a.images, a.urls, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, ' .
|
||||
'a.hits, a.xreference, a.featured,' . ' ' . $query->length('a.fulltext') . ' AS readmore'
|
||||
)
|
||||
);
|
||||
|
||||
// Process an Archived Article layout
|
||||
if ($this->getState('filter.published') == 2)
|
||||
{
|
||||
// If badcats is not null, this means that the article is inside an archived category
|
||||
// In this case, the state is set to 2 to indicate Archived (even if the article state is Published)
|
||||
$query->select($this->getState('list.select', 'CASE WHEN badcats.id is null THEN a.state ELSE 2 END AS state'));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Process non-archived layout
|
||||
// If badcats is not null, this means that the article is inside an unpublished category
|
||||
// In this case, the state is set to 0 to indicate Unpublished (even if the article state is Published)
|
||||
$query->select($this->getState('list.select', 'CASE WHEN badcats.id is not null THEN 0 ELSE a.state END AS state'));
|
||||
}
|
||||
|
||||
$query->from('#__content AS a');
|
||||
|
||||
// Join over the frontpage articles.
|
||||
if ($this->context != 'com_content.featured')
|
||||
{
|
||||
$query->join('LEFT', '#__content_frontpage AS fp ON fp.content_id = a.id');
|
||||
}
|
||||
|
||||
// Join over the categories.
|
||||
$query->select('c.title AS category_title, c.path AS category_route, c.access AS category_access, c.alias AS category_alias')
|
||||
->join('LEFT', '#__categories AS c ON c.id = a.catid');
|
||||
|
||||
// Join over the users for the author and modified_by names.
|
||||
$query->select("CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE ua.name END AS author")
|
||||
->select("ua.email AS author_email")
|
||||
|
||||
->join('LEFT', '#__users AS ua ON ua.id = a.created_by')
|
||||
->join('LEFT', '#__users AS uam ON uam.id = a.modified_by');
|
||||
|
||||
// Get contact id
|
||||
$subQuery = $db->getQuery(true)
|
||||
->select('MAX(contact.id) AS id')
|
||||
->from('#__contact_details AS contact')
|
||||
->where('contact.published = 1')
|
||||
->where('contact.user_id = a.created_by');
|
||||
// Filter by language
|
||||
if ($this->getState('filter.language'))
|
||||
{
|
||||
$subQuery->where('(contact.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ') OR contact.language IS NULL)');
|
||||
}
|
||||
$query->select('(' . $subQuery . ') as contactid');
|
||||
|
||||
// Join over the categories to get parent category titles
|
||||
$query->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias')
|
||||
->join('LEFT', '#__categories as parent ON parent.id = c.parent_id');
|
||||
|
||||
// Join on voting table
|
||||
$query->select('ROUND(v.rating_sum / v.rating_count, 0) AS rating, v.rating_count as rating_count')
|
||||
->join('LEFT', '#__content_rating AS v ON a.id = v.content_id');
|
||||
|
||||
// Join to check for category published state in parent categories up the tree
|
||||
$query->select('c.published, CASE WHEN badcats.id is null THEN c.published ELSE 0 END AS parents_published');
|
||||
$subquery = 'SELECT cat.id as id FROM #__categories AS cat JOIN #__categories AS parent ';
|
||||
$subquery .= 'ON cat.lft BETWEEN parent.lft AND parent.rgt ';
|
||||
$subquery .= 'WHERE parent.extension = ' . $db->quote('com_content');
|
||||
|
||||
if ($this->getState('filter.published') == 2)
|
||||
{
|
||||
// Find any up-path categories that are archived
|
||||
// If any up-path categories are archived, include all children in archived layout
|
||||
$subquery .= ' AND parent.published = 2 GROUP BY cat.id ';
|
||||
// Set effective state to archived if up-path category is archived
|
||||
$publishedWhere = 'CASE WHEN badcats.id is null THEN a.state ELSE 2 END';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find any up-path categories that are not published
|
||||
// If all categories are published, badcats.id will be null, and we just use the article state
|
||||
$subquery .= ' AND parent.published != 1 GROUP BY cat.id ';
|
||||
// Select state to unpublished if up-path category is unpublished
|
||||
$publishedWhere = 'CASE WHEN badcats.id is null THEN a.state ELSE 0 END';
|
||||
}
|
||||
$query->join('LEFT OUTER', '(' . $subquery . ') AS badcats ON badcats.id = c.id');
|
||||
|
||||
// Filter by access level.
|
||||
if ($access = $this->getState('filter.access'))
|
||||
{
|
||||
$user = JFactory::getUser();
|
||||
$groups = implode(',', $user->getAuthorisedViewLevels());
|
||||
$query->where('a.access IN (' . $groups . ')')
|
||||
->where('c.access IN (' . $groups . ')');
|
||||
}
|
||||
|
||||
// Filter by published state
|
||||
$published = $this->getState('filter.published');
|
||||
|
||||
if (is_numeric($published))
|
||||
{
|
||||
// Use article state if badcats.id is null, otherwise, force 0 for unpublished
|
||||
$query->where($publishedWhere . ' = ' . (int) $published);
|
||||
}
|
||||
elseif (is_array($published))
|
||||
{
|
||||
JArrayHelper::toInteger($published);
|
||||
$published = implode(',', $published);
|
||||
// Use article state if badcats.id is null, otherwise, force 0 for unpublished
|
||||
$query->where($publishedWhere . ' IN (' . $published . ')');
|
||||
}
|
||||
|
||||
// Filter by featured state
|
||||
$featured = $this->getState('filter.featured');
|
||||
switch ($featured)
|
||||
{
|
||||
case 'hide':
|
||||
$query->where('a.featured = 0');
|
||||
break;
|
||||
|
||||
case 'only':
|
||||
$query->where('a.featured = 1');
|
||||
break;
|
||||
|
||||
case 'show':
|
||||
default:
|
||||
// Normally we do not discriminate
|
||||
// between featured/unfeatured items.
|
||||
break;
|
||||
}
|
||||
|
||||
// Filter by a single or group of articles.
|
||||
$articleId = $this->getState('filter.article_id');
|
||||
|
||||
if (is_numeric($articleId))
|
||||
{
|
||||
$type = $this->getState('filter.article_id.include', true) ? '= ' : '<> ';
|
||||
$query->where('a.id ' . $type . (int) $articleId);
|
||||
}
|
||||
elseif (is_array($articleId))
|
||||
{
|
||||
JArrayHelper::toInteger($articleId);
|
||||
$articleId = implode(',', $articleId);
|
||||
$type = $this->getState('filter.article_id.include', true) ? 'IN' : 'NOT IN';
|
||||
$query->where('a.id ' . $type . ' (' . $articleId . ')');
|
||||
}
|
||||
|
||||
// Filter by a single or group of categories
|
||||
$categoryId = $this->getState('filter.category_id');
|
||||
|
||||
if (is_numeric($categoryId))
|
||||
{
|
||||
$type = $this->getState('filter.category_id.include', true) ? '= ' : '<> ';
|
||||
|
||||
// Add subcategory check
|
||||
$includeSubcategories = $this->getState('filter.subcategories', false);
|
||||
$categoryEquals = 'a.catid ' . $type . (int) $categoryId;
|
||||
|
||||
if ($includeSubcategories)
|
||||
{
|
||||
$levels = (int) $this->getState('filter.max_category_levels', '1');
|
||||
// Create a subquery for the subcategory list
|
||||
$subQuery = $db->getQuery(true)
|
||||
->select('sub.id')
|
||||
->from('#__categories as sub')
|
||||
->join('INNER', '#__categories as this ON sub.lft > this.lft AND sub.rgt < this.rgt')
|
||||
->where('this.id = ' . (int) $categoryId);
|
||||
if ($levels >= 0)
|
||||
{
|
||||
$subQuery->where('sub.level <= this.level + ' . $levels);
|
||||
}
|
||||
|
||||
// Add the subquery to the main query
|
||||
$query->where('(' . $categoryEquals . ' OR a.catid IN (' . $subQuery->__toString() . '))');
|
||||
}
|
||||
else
|
||||
{
|
||||
$query->where($categoryEquals);
|
||||
}
|
||||
}
|
||||
elseif (is_array($categoryId) && (count($categoryId) > 0))
|
||||
{
|
||||
JArrayHelper::toInteger($categoryId);
|
||||
$categoryId = implode(',', $categoryId);
|
||||
if (!empty($categoryId))
|
||||
{
|
||||
$type = $this->getState('filter.category_id.include', true) ? 'IN' : 'NOT IN';
|
||||
$query->where('a.catid ' . $type . ' (' . $categoryId . ')');
|
||||
}
|
||||
}
|
||||
|
||||
// Filter by author
|
||||
$authorId = $this->getState('filter.author_id');
|
||||
$authorWhere = '';
|
||||
|
||||
if (is_numeric($authorId))
|
||||
{
|
||||
$type = $this->getState('filter.author_id.include', true) ? '= ' : '<> ';
|
||||
$authorWhere = 'a.created_by ' . $type . (int) $authorId;
|
||||
}
|
||||
elseif (is_array($authorId))
|
||||
{
|
||||
JArrayHelper::toInteger($authorId);
|
||||
$authorId = implode(',', $authorId);
|
||||
|
||||
if ($authorId)
|
||||
{
|
||||
$type = $this->getState('filter.author_id.include', true) ? 'IN' : 'NOT IN';
|
||||
$authorWhere = 'a.created_by ' . $type . ' (' . $authorId . ')';
|
||||
}
|
||||
}
|
||||
|
||||
// Filter by author alias
|
||||
$authorAlias = $this->getState('filter.author_alias');
|
||||
$authorAliasWhere = '';
|
||||
|
||||
if (is_string($authorAlias))
|
||||
{
|
||||
$type = $this->getState('filter.author_alias.include', true) ? '= ' : '<> ';
|
||||
$authorAliasWhere = 'a.created_by_alias ' . $type . $db->quote($authorAlias);
|
||||
}
|
||||
elseif (is_array($authorAlias))
|
||||
{
|
||||
$first = current($authorAlias);
|
||||
|
||||
if (!empty($first))
|
||||
{
|
||||
JArrayHelper::toString($authorAlias);
|
||||
|
||||
foreach ($authorAlias as $key => $alias)
|
||||
{
|
||||
$authorAlias[$key] = $db->quote($alias);
|
||||
}
|
||||
|
||||
$authorAlias = implode(',', $authorAlias);
|
||||
|
||||
if ($authorAlias)
|
||||
{
|
||||
$type = $this->getState('filter.author_alias.include', true) ? 'IN' : 'NOT IN';
|
||||
$authorAliasWhere = 'a.created_by_alias ' . $type . ' (' . $authorAlias .
|
||||
')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($authorWhere) && !empty($authorAliasWhere))
|
||||
{
|
||||
$query->where('(' . $authorWhere . ' OR ' . $authorAliasWhere . ')');
|
||||
}
|
||||
elseif (empty($authorWhere) && empty($authorAliasWhere))
|
||||
{
|
||||
// If both are empty we don't want to add to the query
|
||||
}
|
||||
else
|
||||
{
|
||||
// One of these is empty, the other is not so we just add both
|
||||
$query->where($authorWhere . $authorAliasWhere);
|
||||
}
|
||||
|
||||
// Filter by start and end dates.
|
||||
$nullDate = $db->quote($db->getNullDate());
|
||||
$nowDate = $db->quote(JFactory::getDate()->toSql());
|
||||
|
||||
$query->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')')
|
||||
->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')');
|
||||
|
||||
// Filter by Date Range or Relative Date
|
||||
$dateFiltering = $this->getState('filter.date_filtering', 'off');
|
||||
$dateField = $this->getState('filter.date_field', 'a.created');
|
||||
|
||||
switch ($dateFiltering)
|
||||
{
|
||||
case 'range':
|
||||
$startDateRange = $db->quote($this->getState('filter.start_date_range', $nullDate));
|
||||
$endDateRange = $db->quote($this->getState('filter.end_date_range', $nullDate));
|
||||
$query->where(
|
||||
'(' . $dateField . ' >= ' . $startDateRange . ' AND ' . $dateField .
|
||||
' <= ' . $endDateRange . ')'
|
||||
);
|
||||
break;
|
||||
|
||||
case 'relative':
|
||||
$relativeDate = (int) $this->getState('filter.relative_date', 0);
|
||||
$query->where(
|
||||
$dateField . ' >= DATE_SUB(' . $nowDate . ', INTERVAL ' .
|
||||
$relativeDate . ' DAY)'
|
||||
);
|
||||
break;
|
||||
|
||||
case 'off':
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// process the filter for list views with user-entered filters
|
||||
$params = $this->getState('params');
|
||||
|
||||
if ((is_object($params)) && ($params->get('filter_field') != 'hide') && ($filter = $this->getState('list.filter')))
|
||||
{
|
||||
// clean filter variable
|
||||
$filter = JString::strtolower($filter);
|
||||
$hitsFilter = (int) $filter;
|
||||
$filter = $db->quote('%' . $db->escape($filter, true) . '%', false);
|
||||
|
||||
switch ($params->get('filter_field'))
|
||||
{
|
||||
case 'author':
|
||||
$query->where(
|
||||
'LOWER( CASE WHEN a.created_by_alias > ' . $db->quote(' ') .
|
||||
' THEN a.created_by_alias ELSE ua.name END ) LIKE ' . $filter . ' '
|
||||
);
|
||||
break;
|
||||
|
||||
case 'hits':
|
||||
$query->where('a.hits >= ' . $hitsFilter . ' ');
|
||||
break;
|
||||
|
||||
case 'title':
|
||||
default: // default to 'title' if parameter is not valid
|
||||
$query->where('LOWER( a.title ) LIKE ' . $filter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter by language
|
||||
if ($this->getState('filter.language'))
|
||||
{
|
||||
$query->where('a.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')');
|
||||
}
|
||||
|
||||
// Add the list ordering clause.
|
||||
$query->order($this->getState('list.ordering', 'a.ordering') . ' ' . $this->getState('list.direction', 'ASC'));
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a list of articles.
|
||||
*
|
||||
* Overriden to inject convert the attribs field into a JParameter object.
|
||||
*
|
||||
* @return mixed An array of objects on success, false on failure.
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getItems()
|
||||
{
|
||||
$items = parent::getItems();
|
||||
$user = JFactory::getUser();
|
||||
$userId = $user->get('id');
|
||||
$guest = $user->get('guest');
|
||||
$groups = $user->getAuthorisedViewLevels();
|
||||
$input = JFactory::getApplication()->input;
|
||||
|
||||
// Get the global params
|
||||
$globalParams = JComponentHelper::getParams('com_content', true);
|
||||
|
||||
// Convert the parameter fields into objects.
|
||||
foreach ($items as &$item)
|
||||
{
|
||||
$articleParams = new JRegistry;
|
||||
$articleParams->loadString($item->attribs);
|
||||
|
||||
// Unpack readmore and layout params
|
||||
$item->alternative_readmore = $articleParams->get('alternative_readmore');
|
||||
$item->layout = $articleParams->get('layout');
|
||||
|
||||
$item->params = clone $this->getState('params');
|
||||
|
||||
// For blogs, article params override menu item params only if menu param = 'use_article'
|
||||
// Otherwise, menu item params control the layout
|
||||
// If menu item is 'use_article' and there is no article param, use global
|
||||
if (($input->getString('layout') == 'blog') || ($input->getString('view') == 'featured')
|
||||
|| ($this->getState('params')->get('layout_type') == 'blog')
|
||||
)
|
||||
{
|
||||
// create an array of just the params set to 'use_article'
|
||||
$menuParamsArray = $this->getState('params')->toArray();
|
||||
$articleArray = array();
|
||||
|
||||
foreach ($menuParamsArray as $key => $value)
|
||||
{
|
||||
if ($value === 'use_article')
|
||||
{
|
||||
// if the article has a value, use it
|
||||
if ($articleParams->get($key) != '')
|
||||
{
|
||||
// get the value from the article
|
||||
$articleArray[$key] = $articleParams->get($key);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise, use the global value
|
||||
$articleArray[$key] = $globalParams->get($key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// merge the selected article params
|
||||
if (count($articleArray) > 0)
|
||||
{
|
||||
$articleParams = new JRegistry;
|
||||
$articleParams->loadArray($articleArray);
|
||||
$item->params->merge($articleParams);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For non-blog layouts, merge all of the article params
|
||||
$item->params->merge($articleParams);
|
||||
}
|
||||
|
||||
// get display date
|
||||
switch ($item->params->get('list_show_date'))
|
||||
{
|
||||
case 'modified':
|
||||
$item->displayDate = $item->modified;
|
||||
break;
|
||||
|
||||
case 'published':
|
||||
$item->displayDate = ($item->publish_up == 0) ? $item->created : $item->publish_up;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'created':
|
||||
$item->displayDate = $item->created;
|
||||
break;
|
||||
}
|
||||
|
||||
// Compute the asset access permissions.
|
||||
// Technically guest could edit an article, but lets not check that to improve performance a little.
|
||||
if (!$guest)
|
||||
{
|
||||
$asset = 'com_content.article.' . $item->id;
|
||||
|
||||
// Check general edit permission first.
|
||||
if ($user->authorise('core.edit', $asset))
|
||||
{
|
||||
$item->params->set('access-edit', true);
|
||||
}
|
||||
// Now check if edit.own is available.
|
||||
elseif (!empty($userId) && $user->authorise('core.edit.own', $asset))
|
||||
{
|
||||
// Check for a valid user and that they are the owner.
|
||||
if ($userId == $item->created_by)
|
||||
{
|
||||
$item->params->set('access-edit', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$access = $this->getState('filter.access');
|
||||
|
||||
if ($access)
|
||||
{
|
||||
// If the access filter has been set, we already have only the articles this user can view.
|
||||
$item->params->set('access-view', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no access filter is set, the layout takes some responsibility for display of limited information.
|
||||
if ($item->catid == 0 || $item->category_access === null)
|
||||
{
|
||||
$item->params->set('access-view', in_array($item->access, $groups));
|
||||
}
|
||||
else
|
||||
{
|
||||
$item->params->set('access-view', in_array($item->access, $groups) && in_array($item->category_access, $groups));
|
||||
}
|
||||
}
|
||||
|
||||
// Get the tags
|
||||
$item->tags = new JHelperTags;
|
||||
$item->tags->getItemTags('com_content.article', $item->id);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function getStart()
|
||||
{
|
||||
return $this->getState('list.start');
|
||||
}
|
||||
}
|
132
components/com_content/models/categories.php
Normal file
132
components/com_content/models/categories.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
*
|
||||
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* This models supports retrieving lists of article categories.
|
||||
*
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
* @since 1.6
|
||||
*/
|
||||
class ContentModelCategories extends JModelList
|
||||
{
|
||||
/**
|
||||
* Model context string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $_context = 'com_content.categories';
|
||||
|
||||
/**
|
||||
* The category context (allows other extensions to derived from this model).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_extension = 'com_content';
|
||||
|
||||
private $_parent = null;
|
||||
|
||||
private $_items = null;
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function populateState($ordering = null, $direction = null)
|
||||
{
|
||||
$app = JFactory::getApplication();
|
||||
$this->setState('filter.extension', $this->_extension);
|
||||
|
||||
// Get the parent id if defined.
|
||||
$parentId = $app->input->getInt('id');
|
||||
$this->setState('filter.parentId', $parentId);
|
||||
|
||||
$params = $app->getParams();
|
||||
$this->setState('params', $params);
|
||||
|
||||
$this->setState('filter.published', 1);
|
||||
$this->setState('filter.access', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a store id based on model configuration state.
|
||||
*
|
||||
* This is necessary because the model is used by the component and
|
||||
* different modules that might need different sets of data or different
|
||||
* ordering requirements.
|
||||
*
|
||||
* @param string $id A prefix for the store id.
|
||||
*
|
||||
* @return string A store id.
|
||||
*/
|
||||
protected function getStoreId($id = '')
|
||||
{
|
||||
// Compile the store id.
|
||||
$id .= ':'.$this->getState('filter.extension');
|
||||
$id .= ':'.$this->getState('filter.published');
|
||||
$id .= ':'.$this->getState('filter.access');
|
||||
$id .= ':'.$this->getState('filter.parentId');
|
||||
|
||||
return parent::getStoreId($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redefine the function an add some properties to make the styling more easy
|
||||
*
|
||||
* @param bool $recursive True if you want to return children recursively.
|
||||
*
|
||||
* @return mixed An array of data items on success, false on failure.
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getItems($recursive = false)
|
||||
{
|
||||
if (!count($this->_items))
|
||||
{
|
||||
$app = JFactory::getApplication();
|
||||
$menu = $app->getMenu();
|
||||
$active = $menu->getActive();
|
||||
$params = new JRegistry;
|
||||
|
||||
if ($active)
|
||||
{
|
||||
$params->loadString($active->params);
|
||||
}
|
||||
|
||||
$options = array();
|
||||
$options['countItems'] = $params->get('show_cat_num_articles_cat', 1) || !$params->get('show_empty_categories_cat', 0);
|
||||
$categories = JCategories::getInstance('Content', $options);
|
||||
$this->_parent = $categories->get($this->getState('filter.parentId', 'root'));
|
||||
|
||||
if (is_object($this->_parent))
|
||||
{
|
||||
$this->_items = $this->_parent->getChildren($recursive);
|
||||
}
|
||||
else {
|
||||
$this->_items = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_items;
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
{
|
||||
if (!is_object($this->_parent))
|
||||
{
|
||||
$this->getItems();
|
||||
}
|
||||
|
||||
return $this->_parent;
|
||||
}
|
||||
}
|
471
components/com_content/models/category.php
Normal file
471
components/com_content/models/category.php
Normal file
@ -0,0 +1,471 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
*
|
||||
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* This models supports retrieving a category, the articles associated with the category,
|
||||
* sibling, child and parent categories.
|
||||
*
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
* @since 1.5
|
||||
*/
|
||||
class ContentModelCategory extends JModelList
|
||||
{
|
||||
/**
|
||||
* Category items data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_item = null;
|
||||
|
||||
protected $_articles = null;
|
||||
|
||||
protected $_siblings = null;
|
||||
|
||||
protected $_children = null;
|
||||
|
||||
protected $_parent = null;
|
||||
|
||||
/**
|
||||
* Model context string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_context = 'com_content.category';
|
||||
|
||||
/**
|
||||
* The category that applies.
|
||||
*
|
||||
* @access protected
|
||||
* @var object
|
||||
*/
|
||||
protected $_category = null;
|
||||
|
||||
/**
|
||||
* The list of other newfeed categories.
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $_categories = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array An optional associative array of configuration settings.
|
||||
* @see JController
|
||||
* @since 1.6
|
||||
*/
|
||||
public function __construct($config = array())
|
||||
{
|
||||
if (empty($config['filter_fields']))
|
||||
{
|
||||
$config['filter_fields'] = array(
|
||||
'id', 'a.id',
|
||||
'title', 'a.title',
|
||||
'alias', 'a.alias',
|
||||
'checked_out', 'a.checked_out',
|
||||
'checked_out_time', 'a.checked_out_time',
|
||||
'catid', 'a.catid', 'category_title',
|
||||
'state', 'a.state',
|
||||
'access', 'a.access', 'access_level',
|
||||
'created', 'a.created',
|
||||
'created_by', 'a.created_by',
|
||||
'modified', 'a.modified',
|
||||
'ordering', 'a.ordering',
|
||||
'featured', 'a.featured',
|
||||
'language', 'a.language',
|
||||
'hits', 'a.hits',
|
||||
'publish_up', 'a.publish_up',
|
||||
'publish_down', 'a.publish_down',
|
||||
'author', 'a.author'
|
||||
);
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* return void
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function populateState($ordering = null, $direction = null)
|
||||
{
|
||||
$app = JFactory::getApplication('site');
|
||||
$pk = $app->input->getInt('id');
|
||||
|
||||
$this->setState('category.id', $pk);
|
||||
|
||||
// Load the parameters. Merge Global and Menu Item params into new object
|
||||
$params = $app->getParams();
|
||||
$menuParams = new JRegistry;
|
||||
|
||||
if ($menu = $app->getMenu()->getActive())
|
||||
{
|
||||
$menuParams->loadString($menu->params);
|
||||
}
|
||||
|
||||
$mergedParams = clone $menuParams;
|
||||
$mergedParams->merge($params);
|
||||
|
||||
$this->setState('params', $mergedParams);
|
||||
$user = JFactory::getUser();
|
||||
// Create a new query object.
|
||||
$db = $this->getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content'))){
|
||||
// limit to published for people who can't edit or edit.state.
|
||||
$this->setState('filter.published', 1);
|
||||
// Filter by start and end dates.
|
||||
$nullDate = $db->quote($db->getNullDate());
|
||||
$nowDate = $db->quote(JFactory::getDate()->toSQL());
|
||||
|
||||
$query->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')')
|
||||
->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->setState('filter.published', array(0, 1, 2));
|
||||
}
|
||||
|
||||
// process show_noauth parameter
|
||||
if (!$params->get('show_noauth'))
|
||||
{
|
||||
$this->setState('filter.access', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->setState('filter.access', false);
|
||||
}
|
||||
|
||||
// Optional filter text
|
||||
$this->setState('list.filter', $app->input->getString('filter-search'));
|
||||
|
||||
// filter.order
|
||||
$itemid = $app->input->get('id', 0, 'int') . ':' . $app->input->get('Itemid', 0, 'int');
|
||||
$orderCol = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order', 'filter_order', '', 'string');
|
||||
if (!in_array($orderCol, $this->filter_fields))
|
||||
{
|
||||
$orderCol = 'a.ordering';
|
||||
}
|
||||
$this->setState('list.ordering', $orderCol);
|
||||
|
||||
$listOrder = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order_Dir',
|
||||
'filter_order_Dir', '', 'cmd');
|
||||
if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', '')))
|
||||
{
|
||||
$listOrder = 'ASC';
|
||||
}
|
||||
$this->setState('list.direction', $listOrder);
|
||||
|
||||
$this->setState('list.start', $app->input->get('limitstart', 0, 'uint'));
|
||||
|
||||
// set limit for query. If list, use parameter. If blog, add blog parameters for limit.
|
||||
if (($app->input->get('layout') == 'blog') || $params->get('layout_type') == 'blog')
|
||||
{
|
||||
$limit = $params->get('num_leading_articles') + $params->get('num_intro_articles') + $params->get('num_links');
|
||||
$this->setState('list.links', $params->get('num_links'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$limit = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.limit', 'limit', $params->get('display_num'), 'uint');
|
||||
}
|
||||
|
||||
$this->setState('list.limit', $limit);
|
||||
|
||||
// set the depth of the category query based on parameter
|
||||
$showSubcategories = $params->get('show_subcategory_content', '0');
|
||||
|
||||
if ($showSubcategories)
|
||||
{
|
||||
$this->setState('filter.max_category_levels', $params->get('show_subcategory_content', '1'));
|
||||
$this->setState('filter.subcategories', true);
|
||||
}
|
||||
|
||||
$this->setState('filter.language', JLanguageMultilang::isEnabled());
|
||||
|
||||
$this->setState('layout', $app->input->get('layout'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the articles in the category
|
||||
*
|
||||
* @return mixed An array of articles or false if an error occurs.
|
||||
* @since 1.5
|
||||
*/
|
||||
function getItems()
|
||||
{
|
||||
$limit = $this->getState('list.limit');
|
||||
|
||||
if ($this->_articles === null && $category = $this->getCategory())
|
||||
{
|
||||
$model = JModelLegacy::getInstance('Articles', 'ContentModel', array('ignore_request' => true));
|
||||
$model->setState('params', JFactory::getApplication()->getParams());
|
||||
$model->setState('filter.category_id', $category->id);
|
||||
$model->setState('filter.published', $this->getState('filter.published'));
|
||||
$model->setState('filter.access', $this->getState('filter.access'));
|
||||
$model->setState('filter.language', $this->getState('filter.language'));
|
||||
$model->setState('list.ordering', $this->_buildContentOrderBy());
|
||||
$model->setState('list.start', $this->getState('list.start'));
|
||||
$model->setState('list.limit', $limit);
|
||||
$model->setState('list.direction', $this->getState('list.direction'));
|
||||
$model->setState('list.filter', $this->getState('list.filter'));
|
||||
// filter.subcategories indicates whether to include articles from subcategories in the list or blog
|
||||
$model->setState('filter.subcategories', $this->getState('filter.subcategories'));
|
||||
$model->setState('filter.max_category_levels', $this->setState('filter.max_category_levels'));
|
||||
$model->setState('list.links', $this->getState('list.links'));
|
||||
|
||||
if ($limit >= 0)
|
||||
{
|
||||
$this->_articles = $model->getItems();
|
||||
|
||||
if ($this->_articles === false)
|
||||
{
|
||||
$this->setError($model->getError());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_articles = array();
|
||||
}
|
||||
|
||||
$this->_pagination = $model->getPagination();
|
||||
}
|
||||
|
||||
return $this->_articles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the orderby for the query
|
||||
*
|
||||
* @return string $orderby portion of query
|
||||
* @since 1.5
|
||||
*/
|
||||
protected function _buildContentOrderBy()
|
||||
{
|
||||
$app = JFactory::getApplication('site');
|
||||
$db = $this->getDbo();
|
||||
$params = $this->state->params;
|
||||
$itemid = $app->input->get('id', 0, 'int') . ':' . $app->input->get('Itemid', 0, 'int');
|
||||
$orderCol = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order', 'filter_order', '', 'string');
|
||||
$orderDirn = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order_Dir', 'filter_order_Dir', '', 'cmd');
|
||||
$orderby = ' ';
|
||||
|
||||
if (!in_array($orderCol, $this->filter_fields))
|
||||
{
|
||||
$orderCol = null;
|
||||
}
|
||||
|
||||
if (!in_array(strtoupper($orderDirn), array('ASC', 'DESC', '')))
|
||||
{
|
||||
$orderDirn = 'ASC';
|
||||
}
|
||||
|
||||
if ($orderCol && $orderDirn)
|
||||
{
|
||||
$orderby .= $db->escape($orderCol) . ' ' . $db->escape($orderDirn) . ', ';
|
||||
}
|
||||
|
||||
$articleOrderby = $params->get('orderby_sec', 'rdate');
|
||||
$articleOrderDate = $params->get('order_date');
|
||||
$categoryOrderby = $params->def('orderby_pri', '');
|
||||
$secondary = ContentHelperQuery::orderbySecondary($articleOrderby, $articleOrderDate) . ', ';
|
||||
$primary = ContentHelperQuery::orderbyPrimary($categoryOrderby);
|
||||
|
||||
$orderby .= $primary . ' ' . $secondary . ' a.created ';
|
||||
|
||||
return $orderby;
|
||||
}
|
||||
|
||||
public function getPagination()
|
||||
{
|
||||
if (empty($this->_pagination))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return $this->_pagination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get category data for the current category
|
||||
*
|
||||
* @param integer An optional ID
|
||||
*
|
||||
* @return object
|
||||
* @since 1.5
|
||||
*/
|
||||
public function getCategory()
|
||||
{
|
||||
if (!is_object($this->_item))
|
||||
{
|
||||
if ( isset( $this->state->params ) )
|
||||
{
|
||||
$params = $this->state->params;
|
||||
$options = array();
|
||||
$options['countItems'] = $params->get('show_cat_num_articles', 1) || !$params->get('show_empty_categories_cat', 0);
|
||||
}
|
||||
else {
|
||||
$options['countItems'] = 0;
|
||||
}
|
||||
|
||||
$categories = JCategories::getInstance('Content', $options);
|
||||
$this->_item = $categories->get($this->getState('category.id', 'root'));
|
||||
|
||||
// Compute selected asset permissions.
|
||||
if (is_object($this->_item))
|
||||
{
|
||||
$user = JFactory::getUser();
|
||||
$asset = 'com_content.category.'.$this->_item->id;
|
||||
|
||||
// Check general create permission.
|
||||
if ($user->authorise('core.create', $asset))
|
||||
{
|
||||
$this->_item->getParams()->set('access-create', true);
|
||||
}
|
||||
|
||||
// TODO: Why aren't we lazy loading the children and siblings?
|
||||
$this->_children = $this->_item->getChildren();
|
||||
$this->_parent = false;
|
||||
|
||||
if ($this->_item->getParent())
|
||||
{
|
||||
$this->_parent = $this->_item->getParent();
|
||||
}
|
||||
|
||||
$this->_rightsibling = $this->_item->getSibling();
|
||||
$this->_leftsibling = $this->_item->getSibling(false);
|
||||
}
|
||||
else {
|
||||
$this->_children = false;
|
||||
$this->_parent = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent category.
|
||||
*
|
||||
* @param integer An optional category id. If not supplied, the model state 'category.id' will be used.
|
||||
*
|
||||
* @return mixed An array of categories or false if an error occurs.
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
if (!is_object($this->_item))
|
||||
{
|
||||
$this->getCategory();
|
||||
}
|
||||
|
||||
return $this->_parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the left sibling (adjacent) categories.
|
||||
*
|
||||
* @return mixed An array of categories or false if an error occurs.
|
||||
* @since 1.6
|
||||
*/
|
||||
function &getLeftSibling()
|
||||
{
|
||||
if (!is_object($this->_item))
|
||||
{
|
||||
$this->getCategory();
|
||||
}
|
||||
|
||||
return $this->_leftsibling;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the right sibling (adjacent) categories.
|
||||
*
|
||||
* @return mixed An array of categories or false if an error occurs.
|
||||
* @since 1.6
|
||||
*/
|
||||
function &getRightSibling()
|
||||
{
|
||||
if (!is_object($this->_item))
|
||||
{
|
||||
$this->getCategory();
|
||||
}
|
||||
|
||||
return $this->_rightsibling;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the child categories.
|
||||
*
|
||||
* @param integer An optional category id. If not supplied, the model state 'category.id' will be used.
|
||||
*
|
||||
* @return mixed An array of categories or false if an error occurs.
|
||||
* @since 1.6
|
||||
*/
|
||||
function &getChildren()
|
||||
{
|
||||
if (!is_object($this->_item))
|
||||
{
|
||||
$this->getCategory();
|
||||
}
|
||||
|
||||
// Order subcategories
|
||||
if (count($this->_children))
|
||||
{
|
||||
$params = $this->getState()->get('params');
|
||||
if ($params->get('orderby_pri') == 'alpha' || $params->get('orderby_pri') == 'ralpha')
|
||||
{
|
||||
jimport('joomla.utilities.arrayhelper');
|
||||
JArrayHelper::sortObjects($this->_children, 'title', ($params->get('orderby_pri') == 'alpha') ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the hit counter for the category.
|
||||
*
|
||||
* @param int $pk Optional primary key of the category to increment.
|
||||
*
|
||||
* @return boolean True if successful; false otherwise and internal error set.
|
||||
*/
|
||||
public function hit($pk = 0)
|
||||
{
|
||||
// Initialise variables.
|
||||
$pk = (!empty($pk)) ? $pk : (int) $this->getState('category.id');
|
||||
|
||||
$db = $this->getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->update('#__categories')
|
||||
->set('hits = hits + 1')
|
||||
->where('id = ' . (int) $pk);
|
||||
$db->setQuery($query);
|
||||
|
||||
try
|
||||
{
|
||||
$db->execute();
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
$this->setError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
142
components/com_content/models/featured.php
Normal file
142
components/com_content/models/featured.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
*
|
||||
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
require_once __DIR__ . '/articles.php';
|
||||
|
||||
/**
|
||||
* Frontpage Component Model
|
||||
*
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
* @since 1.5
|
||||
*/
|
||||
class ContentModelFeatured extends ContentModelArticles
|
||||
{
|
||||
/**
|
||||
* Model context string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $_context = 'com_content.frontpage';
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function populateState($ordering = null, $direction = null)
|
||||
{
|
||||
parent::populateState($ordering, $direction);
|
||||
|
||||
$input = JFactory::getApplication()->input;
|
||||
$user = JFactory::getUser();
|
||||
|
||||
// List state information
|
||||
$limitstart = $input->getUInt('limitstart', 0);
|
||||
$this->setState('list.start', $limitstart);
|
||||
|
||||
$params = $this->state->params;
|
||||
$limit = $params->get('num_leading_articles') + $params->get('num_intro_articles') + $params->get('num_links');
|
||||
$this->setState('list.limit', $limit);
|
||||
$this->setState('list.links', $params->get('num_links'));
|
||||
|
||||
$this->setState('filter.frontpage', true);
|
||||
|
||||
if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content'))){
|
||||
// filter on published for those who do not have edit or edit.state rights.
|
||||
$this->setState('filter.published', 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->setState('filter.published', array(0, 1, 2));
|
||||
}
|
||||
|
||||
// check for category selection
|
||||
if ($params->get('featured_categories') && implode(',', $params->get('featured_categories')) == true)
|
||||
{
|
||||
$featuredCategories = $params->get('featured_categories');
|
||||
$this->setState('filter.frontpage.categories', $featuredCategories);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a list of articles.
|
||||
*
|
||||
* @return mixed An array of objects on success, false on failure.
|
||||
*/
|
||||
public function getItems()
|
||||
{
|
||||
$params = clone $this->getState('params');
|
||||
$limit = $params->get('num_leading_articles') + $params->get('num_intro_articles') + $params->get('num_links');
|
||||
if ($limit > 0)
|
||||
{
|
||||
$this->setState('list.limit', $limit);
|
||||
return parent::getItems();
|
||||
}
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a store id based on model configuration state.
|
||||
*
|
||||
* This is necessary because the model is used by the component and
|
||||
* different modules that might need different sets of data or different
|
||||
* ordering requirements.
|
||||
*
|
||||
* @param string $id A prefix for the store id.
|
||||
*
|
||||
* @return string A store id.
|
||||
*/
|
||||
protected function getStoreId($id = '')
|
||||
{
|
||||
// Compile the store id.
|
||||
$id .= $this->getState('filter.frontpage');
|
||||
|
||||
return parent::getStoreId($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JDatabaseQuery
|
||||
*/
|
||||
protected function getListQuery()
|
||||
{
|
||||
// Set the blog ordering
|
||||
$params = $this->state->params;
|
||||
$articleOrderby = $params->get('orderby_sec', 'rdate');
|
||||
$articleOrderDate = $params->get('order_date');
|
||||
$categoryOrderby = $params->def('orderby_pri', '');
|
||||
$secondary = ContentHelperQuery::orderbySecondary($articleOrderby, $articleOrderDate) . ', ';
|
||||
$primary = ContentHelperQuery::orderbyPrimary($categoryOrderby);
|
||||
|
||||
$orderby = $primary . ' ' . $secondary . ' a.created DESC ';
|
||||
$this->setState('list.ordering', $orderby);
|
||||
$this->setState('list.direction', '');
|
||||
// Create a new query object.
|
||||
$query = parent::getListQuery();
|
||||
|
||||
// Filter by frontpage.
|
||||
if ($this->getState('filter.frontpage'))
|
||||
{
|
||||
$query->join('INNER', '#__content_frontpage AS fp ON fp.content_id = a.id');
|
||||
}
|
||||
|
||||
// Filter by categories
|
||||
if (is_array($featuredCategories = $this->getState('filter.frontpage.categories')))
|
||||
{
|
||||
$query->where('a.catid IN (' . implode(',', $featuredCategories) . ')');
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
177
components/com_content/models/form.php
Normal file
177
components/com_content/models/form.php
Normal file
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
*
|
||||
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
// Base this model on the backend version.
|
||||
require_once JPATH_ADMINISTRATOR.'/components/com_content/models/article.php';
|
||||
|
||||
/**
|
||||
* Content Component Article Model
|
||||
*
|
||||
* @package Joomla.Site
|
||||
* @subpackage com_content
|
||||
* @since 1.5
|
||||
*/
|
||||
class ContentModelForm extends ContentModelArticle
|
||||
{
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function populateState()
|
||||
{
|
||||
$app = JFactory::getApplication();
|
||||
|
||||
// Load state from the request.
|
||||
$pk = $app->input->getInt('a_id');
|
||||
$this->setState('article.id', $pk);
|
||||
|
||||
$this->setState('article.catid', $app->input->getInt('catid'));
|
||||
|
||||
$return = $app->input->get('return', null, 'base64');
|
||||
$this->setState('return_page', base64_decode($return));
|
||||
|
||||
// Load the parameters.
|
||||
$params = $app->getParams();
|
||||
$this->setState('params', $params);
|
||||
|
||||
$this->setState('layout', $app->input->get('layout'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get article data.
|
||||
*
|
||||
* @param integer The id of the article.
|
||||
*
|
||||
* @return mixed Content item data object on success, false on failure.
|
||||
*/
|
||||
public function getItem($itemId = null)
|
||||
{
|
||||
|
||||
$itemId = (int) (!empty($itemId)) ? $itemId : $this->getState('article.id');
|
||||
|
||||
// Get a row instance.
|
||||
$table = $this->getTable();
|
||||
|
||||
// Attempt to load the row.
|
||||
$return = $table->load($itemId);
|
||||
|
||||
// Check for a table object error.
|
||||
if ($return === false && $table->getError())
|
||||
{
|
||||
$this->setError($table->getError());
|
||||
return false;
|
||||
}
|
||||
|
||||
$properties = $table->getProperties(1);
|
||||
$value = JArrayHelper::toObject($properties, 'JObject');
|
||||
|
||||
// Convert attrib field to Registry.
|
||||
$value->params = new JRegistry;
|
||||
$value->params->loadString($value->attribs);
|
||||
|
||||
// Compute selected asset permissions.
|
||||
$user = JFactory::getUser();
|
||||
$userId = $user->get('id');
|
||||
$asset = 'com_content.article.'. $value->id;
|
||||
|
||||
// Check general edit permission first.
|
||||
if ($user->authorise('core.edit', $asset))
|
||||
{
|
||||
$value->params->set('access-edit', true);
|
||||
}
|
||||
// Now check if edit.own is available.
|
||||
elseif (!empty($userId) && $user->authorise('core.edit.own', $asset))
|
||||
{
|
||||
// Check for a valid user and that they are the owner.
|
||||
if ($userId == $value->created_by)
|
||||
{
|
||||
$value->params->set('access-edit', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Check edit state permission.
|
||||
if ($itemId)
|
||||
{
|
||||
// Existing item
|
||||
$value->params->set('access-change', $user->authorise('core.edit.state', $asset));
|
||||
}
|
||||
else
|
||||
{
|
||||
// New item.
|
||||
$catId = (int) $this->getState('article.catid');
|
||||
|
||||
if ($catId)
|
||||
{
|
||||
$value->params->set('access-change', $user->authorise('core.edit.state', 'com_content.category.'.$catId));
|
||||
$value->catid = $catId;
|
||||
}
|
||||
else
|
||||
{
|
||||
$value->params->set('access-change', $user->authorise('core.edit.state', 'com_content'));
|
||||
}
|
||||
}
|
||||
|
||||
$value->articletext = $value->introtext;
|
||||
if (!empty($value->fulltext))
|
||||
{
|
||||
$value->articletext .= '<hr id="system-readmore" />'.$value->fulltext;
|
||||
}
|
||||
|
||||
// Convert the metadata field to an array.
|
||||
$registry = new JRegistry;
|
||||
$registry->loadString($value->metadata);
|
||||
$value->metadata = $registry->toArray();
|
||||
|
||||
if ($itemId)
|
||||
{
|
||||
$value->tags = new JHelperTags;
|
||||
$value->tags->getTagIds($value->id, 'com_content.article');
|
||||
$value->metadata['tags'] = $value->tags;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the return URL.
|
||||
*
|
||||
* @return string The return URL.
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getReturnPage()
|
||||
{
|
||||
return base64_encode($this->getState('return_page'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to save the form data.
|
||||
*
|
||||
* @param array $data The form data.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function save($data)
|
||||
{
|
||||
// Prevent deleting multilang associations
|
||||
$app = JFactory::getApplication();
|
||||
$assoc = isset($app->item_associations) ? $app->item_associations : 0;
|
||||
$app->item_associations = 0;
|
||||
$result = parent::save($data);
|
||||
$app->item_associations = $assoc;
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
345
components/com_content/models/forms/article.xml
Normal file
345
components/com_content/models/forms/article.xml
Normal file
@ -0,0 +1,345 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<form>
|
||||
<fieldset addfieldpath="/administrator/components/com_categories/models/fields">
|
||||
<field
|
||||
id="id"
|
||||
name="id"
|
||||
type="hidden"
|
||||
class="inputbox"
|
||||
label="COM_CONTENT_ID_LABEL"
|
||||
size="10"
|
||||
default="0"
|
||||
readonly="true" />
|
||||
|
||||
<field
|
||||
name="asset_id"
|
||||
type="hidden"
|
||||
filter="unset" />
|
||||
|
||||
<field
|
||||
id="title"
|
||||
name="title"
|
||||
type="text"
|
||||
label="JGLOBAL_TITLE"
|
||||
description="JFIELD_TITLE_DESC"
|
||||
class="inputbox"
|
||||
size="30"
|
||||
required="true" />
|
||||
|
||||
<field
|
||||
id="alias"
|
||||
name="alias"
|
||||
type="text"
|
||||
label="JFIELD_ALIAS_LABEL"
|
||||
description="JFIELD_ALIAS_DESC"
|
||||
class="inputbox"
|
||||
size="45" />
|
||||
|
||||
<field
|
||||
name="articletext"
|
||||
type="editor"
|
||||
buttons="true"
|
||||
label="CONTENT_TEXT_LABEL"
|
||||
description="CONTENT_TEXT_DESC"
|
||||
class="inputbox"
|
||||
filter="JComponentHelper::filterText"
|
||||
asset_id="com_content"
|
||||
/>
|
||||
|
||||
<field
|
||||
id="state"
|
||||
name="state"
|
||||
type="list"
|
||||
label="JSTATUS"
|
||||
description="JFIELD_PUBLISHED_DESC"
|
||||
class="inputbox"
|
||||
size="1"
|
||||
default="1">
|
||||
<option
|
||||
value="1">
|
||||
JPUBLISHED</option>
|
||||
<option
|
||||
value="0">
|
||||
JUNPUBLISHED</option>
|
||||
<option
|
||||
value="2">
|
||||
JARCHIVED</option>
|
||||
<option
|
||||
value="-2">
|
||||
JTRASHED</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
id="featured"
|
||||
name="featured"
|
||||
type="list"
|
||||
label="JGLOBAL_FIELD_FEATURED_LABEL"
|
||||
description="JGLOBAL_FIELD_FEATURED_DESC"
|
||||
class="inputbox"
|
||||
default="0"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
id="catid"
|
||||
name="catid"
|
||||
type="categoryedit"
|
||||
extension="com_content"
|
||||
label="JCATEGORY"
|
||||
description="JFIELD_CATEGORY_DESC"
|
||||
class="inputbox"
|
||||
required="true">
|
||||
</field>
|
||||
|
||||
<field
|
||||
id="created"
|
||||
name="created"
|
||||
type="calendar"
|
||||
filter="unset" />
|
||||
|
||||
<field
|
||||
id="created_by"
|
||||
name="created_by"
|
||||
type="text"
|
||||
filter="unset" />
|
||||
|
||||
<field
|
||||
id="created_by_alias"
|
||||
name="created_by_alias"
|
||||
type="text"
|
||||
label="JGLOBAL_FIELD_CREATED_BY_ALIAS_LABEL"
|
||||
description="JGLOBAL_FIELD_CREATED_BY_ALIAS_DESC"
|
||||
class="inputbox"
|
||||
size="20" />
|
||||
|
||||
<field
|
||||
id="publish_up"
|
||||
name="publish_up"
|
||||
type="calendar"
|
||||
label="JGLOBAL_FIELD_PUBLISH_UP_LABEL"
|
||||
description="JGLOBAL_FIELD_PUBLISH_UP_DESC"
|
||||
class="inputbox"
|
||||
format="%Y-%m-%d %H:%M:%S"
|
||||
size="22"
|
||||
filter="user_utc" />
|
||||
|
||||
<field
|
||||
id="publish_down"
|
||||
name="publish_down"
|
||||
type="calendar"
|
||||
label="JGLOBAL_FIELD_PUBLISH_DOWN_LABEL"
|
||||
description="JGLOBAL_FIELD_PUBLISH_DOWN_DESC"
|
||||
class="inputbox"
|
||||
format="%Y-%m-%d %H:%M:%S"
|
||||
size="22"
|
||||
filter="user_utc" />
|
||||
|
||||
<field
|
||||
name="language"
|
||||
type="contentlanguage"
|
||||
label="JFIELD_LANGUAGE_LABEL"
|
||||
description="JFIELD_LANGUAGE_DESC"
|
||||
class="inputbox">
|
||||
<option value="*">JALL</option>
|
||||
</field>
|
||||
|
||||
<field name="tags"
|
||||
type="tag"
|
||||
label="JTAG"
|
||||
description="JTAG_DESC"
|
||||
class="inputbox span12 small"
|
||||
multiple="true"
|
||||
>
|
||||
</field>
|
||||
|
||||
<field
|
||||
id="metakey"
|
||||
name="metakey"
|
||||
type="textarea"
|
||||
label="JFIELD_META_KEYWORDS_LABEL"
|
||||
description="JFIELD_META_KEYWORDS_DESC"
|
||||
class="inputbox"
|
||||
rows="5"
|
||||
cols="50" />
|
||||
|
||||
<field
|
||||
id="metadesc"
|
||||
name="metadesc"
|
||||
type="textarea"
|
||||
label="JFIELD_META_DESCRIPTION_LABEL"
|
||||
description="JFIELD_META_DESCRIPTION_DESC"
|
||||
class="inputbox"
|
||||
rows="5"
|
||||
cols="50" />
|
||||
|
||||
|
||||
<field
|
||||
id="access"
|
||||
name="access"
|
||||
type="accesslevel"
|
||||
label="JFIELD_ACCESS_LABEL"
|
||||
description="JFIELD_ACCESS_DESC"
|
||||
class="inputbox"
|
||||
size="1" />
|
||||
</fieldset>
|
||||
<fields name="images">
|
||||
<fieldset name="image-intro">
|
||||
<field
|
||||
name="image_intro"
|
||||
type="media"
|
||||
label="COM_CONTENT_FIELD_INTRO_LABEL"
|
||||
description="COM_CONTENT_FIELD_INTRO_DESC" />
|
||||
<field name="image_intro_alt"
|
||||
type="text"
|
||||
label="COM_CONTENT_FIELD_IMAGE_ALT_LABEL"
|
||||
description="COM_CONTENT_FIELD_IMAGE_ALT_DESC"
|
||||
class="inputbox"
|
||||
size="20" />
|
||||
<field name="image_intro_caption"
|
||||
type="text"
|
||||
label="COM_CONTENT_FIELD_IMAGE_CAPTION_LABEL"
|
||||
description="COM_CONTENT_FIELD_IMAGE_CAPTION_DESC"
|
||||
class="inputbox"
|
||||
size="20" />
|
||||
<field
|
||||
name="float_intro"
|
||||
type="list"
|
||||
label="COM_CONTENT_FLOAT_INTRO_LABEL"
|
||||
description="COM_CONTENT_FLOAT_DESC">
|
||||
<option value="">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="right">COM_CONTENT_RIGHT</option>
|
||||
<option value="left">COM_CONTENT_LEFT</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
<fieldset name="image-full">
|
||||
<field
|
||||
name="image_fulltext"
|
||||
type="media"
|
||||
label="COM_CONTENT_FIELD_FULL_LABEL"
|
||||
description="COM_CONTENT_FIELD_FULL_DESC" />
|
||||
<field name="image_fulltext_alt"
|
||||
type="text"
|
||||
label="COM_CONTENT_FIELD_IMAGE_ALT_LABEL"
|
||||
description="COM_CONTENT_FIELD_IMAGE_ALT_DESC"
|
||||
class="inputbox"
|
||||
size="20" />
|
||||
<field name="image_fulltext_caption"
|
||||
type="text"
|
||||
label="COM_CONTENT_FIELD_IMAGE_CAPTION_LABEL"
|
||||
description="COM_CONTENT_FIELD_IMAGE_CAPTION_DESC"
|
||||
class="inputbox"
|
||||
size="20" />
|
||||
<field
|
||||
name="float_fulltext"
|
||||
type="list"
|
||||
label="COM_CONTENT_FLOAT_FULLTEXT_LABEL"
|
||||
description="COM_CONTENT_FLOAT_DESC">
|
||||
<option value="">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="right">COM_CONTENT_RIGHT</option>
|
||||
<option value="left">COM_CONTENT_LEFT</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
<fields name="urls">
|
||||
<field
|
||||
name="urla"
|
||||
type="url"
|
||||
validate="url"
|
||||
label="COM_CONTENT_FIELD_URLA_LABEL"
|
||||
description="COM_CONTENT_FIELD_URL_DESC" />
|
||||
<field name="urlatext"
|
||||
type="text"
|
||||
label="COM_CONTENT_FIELD_URLA_LINK_TEXT_LABEL"
|
||||
description="COM_CONTENT_FIELD_URL_LINK_TEXT_DESC"
|
||||
class="inputbox"
|
||||
size="20" />
|
||||
<field
|
||||
name="targeta"
|
||||
type="hidden"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="urlb"
|
||||
type="url"
|
||||
validate="url"
|
||||
label="COM_CONTENT_FIELD_URLB_LABEL"
|
||||
description="COM_CONTENT_FIELD_URL_DESC" />
|
||||
<field name="urlbtext"
|
||||
type="text"
|
||||
label="COM_CONTENT_FIELD_URLB_LINK_TEXT_LABEL"
|
||||
description="COM_CONTENT_FIELD_URL_LINK_TEXT_DESC"
|
||||
class="inputbox"
|
||||
size="20" />
|
||||
<field
|
||||
name="targetb"
|
||||
type="hidden"
|
||||
/>
|
||||
<field
|
||||
name="urlc"
|
||||
type="url"
|
||||
validate="url"
|
||||
label="COM_CONTENT_FIELD_URLC_LABEL"
|
||||
description="COM_CONTENT_FIELD_URL_DESC" />
|
||||
<field
|
||||
name="urlctext"
|
||||
type="text"
|
||||
label="COM_CONTENT_FIELD_URLC_LINK_TEXT_LABEL"
|
||||
description="COM_CONTENT_FIELD_URL_LINK_TEXT_DESC"
|
||||
class="inputbox"
|
||||
size="20" />
|
||||
<field
|
||||
name="targetc"
|
||||
type="hidden"
|
||||
/>
|
||||
</fields>
|
||||
<fields name="metadata">
|
||||
<fieldset name="jmetadata"
|
||||
label="JGLOBAL_FIELDSET_METADATA_OPTIONS">
|
||||
|
||||
<field name="robots"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
label="JFIELD_METADATA_ROBOTS_LABEL"
|
||||
description="JFIELD_METADATA_ROBOTS_DESC"
|
||||
labelclass="control-label"
|
||||
>
|
||||
<option value="">JGLOBAL_USE_GLOBAL</option>
|
||||
<option value="index, follow">JGLOBAL_INDEX_FOLLOW</option>
|
||||
<option value="noindex, follow">JGLOBAL_NOINDEX_FOLLOW</option>
|
||||
<option value="index, nofollow">JGLOBAL_INDEX_NOFOLLOW</option>
|
||||
<option value="noindex, nofollow">JGLOBAL_NOINDEX_NOFOLLOW</option>
|
||||
</field>
|
||||
|
||||
<field name="author"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
label="JAUTHOR"
|
||||
description="JFIELD_METADATA_AUTHOR_DESC"
|
||||
size="20"
|
||||
labelclass="control-label"
|
||||
/>
|
||||
|
||||
<field name="rights"
|
||||
type="hidden"
|
||||
label="JFIELD_META_RIGHTS_LABEL"
|
||||
filter="unset"
|
||||
description="JFIELD_META_RIGHTS_DESC"
|
||||
required="false"
|
||||
labelclass="control-label"
|
||||
/>
|
||||
|
||||
<field name="xreference"
|
||||
type="hidden"
|
||||
filter="unset"
|
||||
label="COM_CONTENT_FIELD_XREFERENCE_LABEL"
|
||||
description="COM_CONTENT_FIELD_XREFERENCE_DESC"
|
||||
class="inputbox"
|
||||
size="20"
|
||||
labelclass="control-label" />
|
||||
|
||||
</fieldset>
|
||||
</fields>
|
||||
|
||||
</form>
|
1
components/com_content/models/forms/index.html
Normal file
1
components/com_content/models/forms/index.html
Normal file
@ -0,0 +1 @@
|
||||
<!DOCTYPE html><title></title>
|
1
components/com_content/models/index.html
Normal file
1
components/com_content/models/index.html
Normal file
@ -0,0 +1 @@
|
||||
<!DOCTYPE html><title></title>
|
Reference in New Issue
Block a user