| Server IP : 213.186.33.4 / Your IP : 216.73.216.193 Web Server : Apache System : Linux webm006.cluster103.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64 User : awebpaca ( 35430) PHP Version : 8.5.0 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/awebpaca/blog/libraries/kunena/forum/category/ |
Upload File : |
<?php
/**
* Kunena Component
* @package Kunena.Framework
* @subpackage Forum.Category
*
* @copyright (C) 2008 - 2018 Kunena Team. All rights reserved.
* @license https://www.gnu.org/copyleft/gpl.html GNU/GPL
* @link https://www.kunena.org
**/
defined('_JEXEC') or die();
/**
* Class KunenaForumCategory
*
* @property int $id
* @property int $parent_id
* @property string $name
* @property string $alias
* @property int $icon_id
* @property int $locked
* @property string $accesstype
* @property int $access
* @property int $pub_access
* @property int $pub_recurse
* @property int $admin_access
* @property int $admin_recurse
* @property int $ordering
* @property int $published
* @property string $channels
* @property int $checked_out
* @property string $checked_out_time
* @property int $review
* @property int $allow_anonymous
* @property int $post_anonymous
* @property int $hits
* @property string $description
* @property string $headerdesc
* @property string $class_sfx
* @property int $allow_polls
* @property string $topic_ordering
* @property string $iconset
* @property int $numTopics
* @property int $numPosts
* @property int $last_topic_id
* @property int $last_post_id
* @property int $last_post_time
* @property string $params
*/
class KunenaForumCategory extends KunenaDatabaseObject
{
public $id = null;
public $level = 0;
protected $authorised = array();
protected $_aliases = null;
protected $_alias = null;
/**
* @var KunenaForumCategory[]
*/
protected $_channels = false;
protected $_topics = false;
protected $_posts = false;
protected $_lastcat = false;
protected $_authcache = array();
protected $_authfcache = array();
protected $_new = 0;
protected $_table = 'KunenaCategories';
protected static $actions = array(
'none' => array(),
'read' => array('Read'),
'subscribe' => array('Read', 'CatSubscribe', 'NotBanned', 'NotSection'),
'moderate' => array('Read', 'NotBanned', 'Moderate'),
'admin' => array('NotBanned', 'Admin'),
'topic.read' => array('Read'),
'topic.create' => array('Read', 'GuestWrite', 'NotBanned', 'NotSection', 'Unlocked', 'Channel'),
'topic.reply' => array('Read', 'GuestWrite', 'NotBanned', 'NotSection', 'Unlocked'),
'topic.edit' => array('Read', 'NotBanned', 'Unlocked'),
'topic.move' => array('Read', 'NotBanned', 'Moderate', 'Channel'),
'topic.approve' => array('Read','NotBanned', 'Moderate'),
'topic.delete' => array('Read', 'NotBanned', 'Moderate'),
'topic.undelete' => array('Read', 'NotBanned', 'Moderate'),
'topic.permdelete' => array('Read', 'NotBanned', 'Moderate'),
'topic.favorite' => array('Read','NotBanned', 'Favorite'),
'topic.subscribe' => array('Read','NotBanned', 'Subscribe'),
'topic.sticky' => array('Read','NotBanned', 'Moderate'),
'topic.lock' => array('Read','NotBanned', 'Moderate'),
'topic.poll.read' => array('Read', 'Poll'),
'topic.poll.create' => array('Read', 'GuestWrite', 'NotBanned', 'Unlocked', 'Poll'),
'topic.poll.edit' => array('Read', 'NotBanned', 'Unlocked', 'Poll', 'Vote'),
'topic.poll.delete' => array('Read', 'NotBanned', 'Unlocked', 'Poll', 'Vote'),
'topic.poll.vote' => array('Read', 'NotBanned', 'Unlocked', 'Poll', 'Vote'),
'topic.post.read' => array('Read'),
'topic.post.reply' => array('Read', 'GuestWrite', 'NotBanned', 'NotSection', 'Unlocked'),
'topic.post.thankyou' => array('Read', 'NotBanned'), 'Unlocked',
'topic.post.unthankyou' => array('Read', 'NotBanned'), 'Unlocked',
'topic.post.edit' => array('Read', 'NotBanned', 'Unlocked'),
'topic.post.move' => array('Read', 'NotBanned', 'Moderate', 'Channel'),
'topic.post.approve' => array('Read', 'NotBanned', 'Moderate'),
'topic.post.delete' => array('Read', 'NotBanned', 'Unlocked'),
'topic.post.undelete' => array('Read', 'NotBanned', 'Moderate'),
'topic.post.permdelete' => array('Read', 'NotBanned', 'Admin'),
'topic.post.attachment.read' => array('Read'),
'topic.post.attachment.createimage' => array('Read', 'GuestWrite', 'NotBanned', 'Unlocked', 'Upload'),
'topic.post.attachment.createfile' => array('Read', 'GuestWrite', 'NotBanned', 'Unlocked', 'Upload'),
'topic.post.attachment.delete' => array('NotBanned'),
// TODO: In the future we might want to restrict this: array('Read', 'NotBanned', 'Unlocked'),
);
/**
* @param mixed|array $properties
*/
public function __construct($properties = null)
{
if (!empty($this->id))
{
$this->_exists = true;
}
elseif ($properties !== null)
{
$this->setProperties($properties);
}
$registry = new JRegistry();
if (!empty($this->params))
{
$registry->loadString($this->params);
}
$this->params = $registry;
if (!$this->_name)
{
$this->_name = get_class($this);
}
$this->_alias = $this->get('alias', '');
}
/**
* Returns the global KunenaForumCategory object.
*
* @param null $identifier The category id to load.
* @param bool $reload Force reload from the database.
*
* @return KunenaForumCategory
*/
static public function getInstance($identifier = null, $reload = false)
{
return KunenaForumCategoryHelper::get($identifier, $reload);
}
/**
* Returns list of children of this category.
*
* @param int $levels How many levels to search.
*
* @return array List of KunenaForumCategory objects.
*/
public function getChildren($levels = 0)
{
return KunenaForumCategoryHelper::getChildren($this->id, $levels);
}
/**
* Returns object containing user information from this category.
*
* @param mixed $user
*
* @return KunenaForumCategoryUser
*/
public function getUserInfo($user = null)
{
return KunenaForumCategoryUserHelper::get($this->id, $user);
}
/**
* Subscribe / Unsubscribe user to this category.
*
* @param boolean $value True for subscribe, false for unsubscribe.
* @param mixed $user
*
* @return boolean
*/
public function subscribe($value = true, $user = null)
{
$usercategory = KunenaForumCategoryUserHelper::get($this->id, $user);
$usercategory->subscribed = (int) $value;
if (!$usercategory->save())
{
$this->setError($usercategory->getError());
}
return !$this->getError();
}
/**
* Returns new topics count from this category for current user.
*
* @todo Currently new topics needs to be calculated manually, make it automatic.
*
* @param mixed $count Internal parameter to set new count.
*
* @return int New topics count.
*/
public function getNewCount($count = null)
{
if ($count !== null)
{
$this->_new = $count;
}
return $this->_new;
}
/**
* @return boolean
*/
public function isSection()
{
$this->buildInfo();
return $this->parent_id == 0;
}
/**
* @return string
*/
public function getIcon()
{
return KunenaFactory::getTemplate()->getCategoryIcon($this);
}
/**
* @param mixed $category Fake category (or null).
* @param bool $xhtml True if URL needs to be escaped for XHTML.
* @param int|null $action Limitstart.
*
* @return string
*/
public function getUrl($category = null, $xhtml = true, $action = null)
{
$category = $category ? KunenaForumCategoryHelper::get($category) : $this;
if (!$category->exists())
{
return '';
}
return KunenaRoute::getCategoryUrl($category, $xhtml);
}
/**
* @param bool $xhtml
*
* @return boolean|null
*/
public function getNewTopicUrl($xhtml = true)
{
if (!$this->getNewTopicCategory()->exists())
{
return null;
}
$catid = $this->id ? "&catid={$this->id}" : '';
return KunenaRoute::_("index.php?option=com_kunena&view=topic&layout=create{$catid}", $xhtml);
}
/**
* @param bool $children
* @param bool $xhtml
*
* @return boolean|null
*/
public function getMarkReadUrl($children = false, $xhtml = true)
{
if (!KunenaUserHelper::getMyself()->exists())
{
return null;
}
$children = $children ? "&children=1" : '';
$catid = $this->id ? "&catid={$this->id}" : '';
$token = '&' . JSession::getFormToken() . '=1';
return KunenaRoute::_("index.php?option=com_kunena&view=category&task=markread{$catid}{$children}{$token}", $xhtml);
}
/**
* Method which return the RSS feed URL for the actual category
*
* @param bool|string $xhtml
*
* @return boolean|null
* @result string
*
*/
public function getRSSUrl($xhtml = true)
{
if (KunenaFactory::getConfig()->enablerss)
{
$params = '&catid=' . (int) $this->id;
return KunenaRoute::_("index.php?option=com_kunena&view=rss&format=feed{$params}", $xhtml);
}
return null;
}
/**
* @param mixed $category Fake category (or null).
* @param int|null $action Limitstart.
*
* @return JUri
*/
public function getUri($category = null, $action = null)
{
if (!$category)
{
$category = $this;
}
else
{
$category = KunenaForumCategoryHelper::get($category);
}
$uri = JUri::getInstance("index.php?option=com_kunena&view=category&catid={$category->id}");
if ((string) $action === (string) (int) $action)
{
$uri->setVar('limitstart', $action);
}
return $uri;
}
/**
* @param string $field Field to be displayed.
*
* @return integer|string
*/
public function displayField($field)
{
switch ($field)
{
case 'id':
return intval($this->id);
case 'name':
case 'icon':
return KunenaHtmlParser::parseText($this->name);
case 'description':
case 'headerdesc':
return KunenaHtmlParser::parseBBCode($this->$field);
}
return '';
}
/**
* @return $this
*/
public function getCategory()
{
return $this;
}
/**
* @return array Array of Kunena aliases.
*/
public function getAliases()
{
if (!isset($this->_aliases))
{
$db = JFactory::getDbo();
$query = "SELECT * FROM #__kunena_aliases WHERE type='catid' AND item={$db->Quote($this->id)}";
$db->setQuery($query);
$this->_aliases = (array) $db->loadObjectList('alias');
}
return $this->_aliases;
}
/**
* @param string $alias
*
* @return boolean|string
*/
public function checkAlias($alias)
{
// Check if category is already using the alias.
if ($this->_alias && $this->_alias == $alias)
{
return true;
}
// Check if alias is valid in current configuration.
if (KunenaRoute::stringURLSafe($alias) != $alias)
{
return false;
}
$item = KunenaRoute::resolveAlias($alias);
// Is alias free to be used?
if (!$item)
{
return 'insert';
}
// Fail if alias is reserved or used by another category.
if (empty($item['catid']) || $item['catid'] != $this->id)
{
return false;
}
return 'update';
}
/**
* @param string $alias
*
* @return boolean
*/
public function addAlias($alias)
{
if (!$this->exists())
{
return false;
}
$alias = KunenaRoute::stringURLSafe($alias);
if (!$alias)
{
$alias = $this->id;
}
$check = $this->checkAlias($alias);
// Cannot add alias?
if ($check === false)
{
return false;
}
// Did alias change?
if ($check === true)
{
return true;
}
$db = JFactory::getDbo();
$query = "REPLACE INTO #__kunena_aliases (alias, type, item) VALUES ({$db->Quote($alias)},'catid',{$db->Quote($this->id)})";
$db->setQuery($query);
try
{
$db->execute();
}
catch (JDatabaseExceptionExecuting $e)
{
KunenaError::displayDatabaseError($e);
return false;
}
}
/**
* @param string $alias
*
* @return boolean
*/
public function deleteAlias($alias)
{
// Do not delete valid alias.
if (Joomla\String\StringHelper::strtolower($this->alias) == Joomla\String\StringHelper::strtolower($alias))
{
return false;
}
$db = JFactory::getDbo();
$query = "DELETE FROM #__kunena_aliases WHERE type='catid' AND item={$db->Quote($this->id)} AND alias={$db->Quote($alias)}";
$db->setQuery($query);
try
{
$db->execute();
}
catch (JDatabaseExceptionExecuting $e)
{
KunenaError::displayDatabaseError($e);
}
return (bool) $db->getAffectedRows();
}
/**
* Get published state in text.
*
* @return string
*
* @since K4.0
*/
public function getState()
{
switch ($this->hold)
{
case 0:
return 'published';
case 1:
return 'unapproved';
case 2:
case 3:
return 'deleted';
}
return 'unknown';
}
/**
* @return integer
*/
public function getTopics()
{
$this->buildInfo();
return $this->_topics;
}
/**
* @return integer
*/
public function getPosts()
{
$this->buildInfo();
return $this->_posts;
}
/**
* @return integer
*/
public function getReplies()
{
$this->buildInfo();
return max($this->_posts - $this->_topics, 0);
}
/**
* @return KunenaForumCategory
*/
public function getLastCategory()
{
$this->buildInfo();
return $this->_lastcat;
}
/**
* @return KunenaForumTopic
*/
public function getLastTopic()
{
return KunenaForumTopicHelper::get($this->getLastCategory()->last_topic_id);
}
/**
* @param string $action
*
* @return KunenaForumCategory[]
*/
public function getChannels($action='read')
{
KUNENA_PROFILER ? KunenaProfiler::instance()->start('function ' . __CLASS__ . '::' . __FUNCTION__ . '()') : null;
if ($this->_channels === false)
{
$this->_channels['none'] = array();
if ($this->published != 1 || $this->parent_id == 0 || (!$this->numTopics && $this->locked))
{
// Unpublished categories and sections do not have channels
}
elseif (empty($this->channels) || $this->channels == $this->id)
{
// No channels defined
$this->_channels['none'][$this->id] = $this;
}
else
{
// Fetch all channels
$ids = array_flip(explode(',', $this->channels));
if (isset($ids[0]) || isset($ids['THIS']))
{
// Handle current category
$this->_channels['none'][$this->id] = $this;
}
if (!empty($ids))
{
// More category channels
$this->_channels['none'] += KunenaForumCategoryHelper::getCategories(array_keys($ids), null, 'none');
}
if (isset($ids['CHILDREN']))
{
// Children category channels
$this->_channels['none'] += KunenaForumCategoryHelper::getChildren($this->id, 1, array($action => 'none'));
}
}
}
if (!isset($this->_channels[$action]))
{
$this->_channels[$action] = array();
foreach ($this->_channels['none'] as $channel)
{
// @var KunenaForumCategory $channel
if (($channel->id == $this->id && $action == 'read') || $channel->authorise($action, null, false))
{
$this->_channels[$action][$channel->id] = $channel;
}
}
}
KUNENA_PROFILER ? KunenaProfiler::instance()->stop('function ' . __CLASS__ . '::' . __FUNCTION__ . '()') : null;
return $this->_channels[$action];
}
/**
* @param mixed $user
*
* @return KunenaForumCategory
*/
public function getNewTopicCategory($user = null)
{
foreach ($this->getChannels() as $category)
{
if ($category->authorise('topic.create', $user, true))
{
return $category;
}
}
$categories = KunenaForumCategoryHelper::getChildren(intval($this->id), -1, array('action' => 'topic.create'));
if ($categories) { foreach ($categories as $category)
{
if ($category->authorise('topic.create', null, true))
{
return $category;
}
}
}
return new KunenaForumCategory();
}
/**
* @param array $fields
* @param mixed $user
* @param array $safefields
*
* @return array
*/
public function newTopic(array $fields = null, $user = null, array $safefields = null)
{
$catid = isset($safefields['category_id']) ? $safefields['category_id'] : $this->getNewTopicCategory($user)->id;
$user = KunenaUserHelper::get($user);
$message = new KunenaForumMessage();
$message->catid = $catid;
$message->name = $user->getName('');
$message->userid = $user->userid;
$message->ip = !empty($_SERVER ['REMOTE_ADDR']) ? $_SERVER ['REMOTE_ADDR'] : '';
$message->hold = $this->review ? (int) !$this->authorise('moderate', $user, true) : 0;
if ($safefields)
{
$message->bind($safefields);
}
if ($fields)
{
$message->bind($fields, array ('name', 'email', 'subject', 'message'), true);
}
$topic = new KunenaForumTopic();
$topic->category_id = $catid;
$topic->hold = KunenaForum::TOPIC_CREATION;
if ($safefields)
{
$topic->bind($safefields);
}
if ($fields)
{
$topic->bind($fields, array ('subject','icon_id'), true);
}
$message->setTopic($topic);
return array($topic, $message);
}
/**
* @return KunenaForumCategory
*/
public function getParent()
{
$parent = KunenaForumCategoryHelper::get(intval($this->parent_id));
if (!$parent->exists())
{
$parent->name = JText::_('COM_KUNENA_TOPLEVEL');
$parent->_exists = true;
}
return $parent;
}
/**
* Returns true if user is authorised to do the action.
*
* @param string $action
* @param KunenaUser $user
*
* @return boolean
*
* @since K4.0
*/
public function isAuthorised($action='read', KunenaUser $user = null)
{
if (KunenaFactory::getConfig()->read_only)
{
// Special case to ignore authorisation.
if ($action != 'read')
{
return null;
}
}
return !$this->tryAuthorise($action, $user, false);
}
/**
* Throws an exception if user isn't authorised to do the action.
*
* @param string $action
* @param KunenaUser $user
* @param bool $throw
*
* @return KunenaExceptionAuthorise|null
* @throws null
* @since K4.0
*/
public function tryAuthorise($action='read', KunenaUser $user = null, $throw = true)
{
// Special case to ignore authorisation.
if ($action == 'none')
{
return null;
}
// Load user if not given.
if ($user === null)
{
$user = KunenaUserHelper::getMyself();
}
// Optimise read access check.
if ($action == 'read')
{
$exception = $this->authoriseRead($user);
if ($throw && $exception)
{
throw $exception;
}
return $exception;
}
// Use local authentication cache to speed up the authentication calls.
if (empty($this->_authcache[$user->userid][$action]))
{
// Unknown action - throw invalid argument exception.
if (!isset(self::$actions[$action]))
{
throw new InvalidArgumentException(JText::sprintf('COM_KUNENA_LIB_AUTHORISE_INVALID_ACTION', $action), 500);
}
// Load custom authorisation from the plugins (except for admins and moderators).
if (!$user->isModerator($this) && !isset($this->authorised[$user->userid]))
{
$this->authorised[$user->userid] = KunenaAccess::getInstance()->authoriseActions($this, $user->userid);
}
if (isset($this->authorised[$user->userid][$action])
&& $this->authorised[$user->userid][$action] === false
)
{
// Plugin forces authorisation to fail.
// TODO: allow plugin to customise the error.
$this->_authcache[$user->userid][$action] = new KunenaExceptionAuthorise(JText::_('COM_KUNENA_NO_ACCESS'), $user->userid ? 403 : 401);
}
else
{
// Do the authorisation.
$this->_authcache[$user->userid][$action] = null;
foreach (self::$actions[$action] as $function)
{
if (!isset($this->_authfcache[$user->userid][$function]))
{
$authFunction = 'authorise' . $function;
$this->_authfcache[$user->userid][$function] = $this->$authFunction($user);
}
$error = $this->_authfcache[$user->userid][$function];
if ($error)
{
$this->_authcache[$user->userid][$action] = $error;
break;
}
}
}
}
$exception = $this->_authcache[$user->userid][$action];
// Throw or return the exception.
if ($throw && $exception)
{
throw $exception;
}
return $exception;
}
/**
* @param string $action
* @param mixed $user
* @param bool $silent
*
* @return boolean
*
*/
public function authorise($action = 'read', $user = null, $silent = false)
{
KUNENA_PROFILER ? KunenaProfiler::instance()->start('function ' . __CLASS__ . '::' . __FUNCTION__ . '()') : null;
if ($user === null)
{
$user = KunenaUserHelper::getMyself();
}
elseif (!($user instanceof KunenaUser))
{
$user = KunenaUserHelper::get($user);
}
$exception = $this->tryAuthorise($action, $user, false);
if ($silent === false && $exception)
{
$this->setError($exception->getMessage());
}
KUNENA_PROFILER ? KunenaProfiler::instance()->stop('function ' . __CLASS__ . '::' . __FUNCTION__ . '()') : null;
if ($silent !== null)
{
return !$exception;
}
return $exception ? $exception->getMessage() : null;
}
/**
* Get users, who can administrate this category.
*
* @param bool $includeGlobal
*
* @return array
*/
public function getAdmins($includeGlobal = true)
{
$access = KunenaAccess::getInstance();
$userlist = array();
if (!empty($this->catid))
{
$userlist = $access->getAdmins($this->catid);
}
if ($includeGlobal)
{
$userlist += $access->getAdmins();
}
return $userlist;
}
/**
* Get users, who can moderate this category.
*
* @param bool $includeGlobal
* @param bool $objects
*
* @return array
*/
public function getModerators($includeGlobal = true, $objects = true)
{
$access = KunenaAccess::getInstance();
$userlist = array();
if (!empty($this->id))
{
$userlist += $access->getModerators($this->id);
}
if ($includeGlobal)
{
$userlist += $access->getModerators();
}
if (empty($userlist))
{
return $userlist;
}
$userlist = array_keys($userlist);
return $objects ? KunenaUserHelper::loadUsers($userlist) : array_combine($userlist, $userlist);
}
/**
* Add or remove moderator from this category.
*
* @param mixed $user
* @param bool $value
*
* @return boolean
*
* @example if ($category->authorise('admin')) $category->setModerator($user, true);
*/
public function setModerator($user = null, $value = false)
{
return KunenaAccess::getInstance()->setModerator($this, $user, $value);
}
/**
* Add moderator to this category.
*
* @param mixed $user
*
* @return boolean
*
* @example if ($category->authorise('admin')) $category->addModerator($user);
*/
public function addModerator($user = null)
{
return $this->setModerator($user, true);
}
/**
* Add multiple moderators to this category.
*
* @param array $users
*
* @example if ($category->authorise('admin')) $category->addModerators(array($user1, $user2, $user3));
*/
public function addModerators($users = array())
{
if (empty($users))
{
return;
}
foreach($users as $user)
{
$user_inst = KunenaUserHelper::get($user);
$this->setModerator($user_inst, true);
}
}
/**
* Remove moderator from this category.
*
* @param mixed $user
*
* @return boolean
*
* @example if ($category->authorise('admin')) $category->removeModerator($user);
*/
public function removeModerator($user = null)
{
return $this->setModerator($user, false);
}
/**
* @see KunenaDatabaseObject::bind()
*
* @param array $src
* @param array $fields
* @param bool $include
*
* @return boolean
*/
public function bind(array $src = null, array $fields = null, $include = false)
{
if (isset($src['channels']) && is_array($src['channels']))
{
$src['channels'] = implode(',', $src['channels']);
}
$result = parent::bind($src, $fields, $include);
if (!($this->params instanceof JRegistry))
{
$registry = new JRegistry();
if (is_array($this->params))
{
$registry->loadArray($this->params);
}
else
{
$registry->loadString($this->params);
}
$this->params = $registry;
}
return $result;
}
/**
* @see KunenaDatabaseObject::load()
*
* @param null $id
*
* @return boolean
*/
public function load($id = null)
{
$exists = parent::load($id);
if (!$this->_saving)
{
$this->_alias = $this->get('alias', '');
}
$registry = new JRegistry();
if ($this->params)
{
$registry->loadString($this->params);
}
$this->params = $registry;
// Register category if it exists
if ($exists)
{
KunenaForumCategoryHelper::register($this);
}
return $exists;
}
/**
* @see KunenaDatabaseObject::check()
*/
public function check()
{
$this->alias = trim($this->alias);
if (empty($this->alias))
{
$this->alias = $this->name;
}
if ($this->alias != $this->_alias)
{
$this->alias = KunenaRoute::stringURLSafe($this->alias);
if ($this->checkAlias($this->alias) === false)
{
$this->setError(JText::sprintf('COM_KUNENA_LIB_FORUM_CATEGORY_ERROR_ALIAS_RESERVED', $this->alias));
return false;
}
}
return true;
}
/**
* @see KunenaDatabaseObject::saveInternal()
*/
protected function saveInternal()
{
// Reorder categories
$table = $this->getTable();
$table->bind($this->getProperties());
$table->exists($this->_exists);
// Update alias
$success = $this->addAlias($this->get('alias'));
if ($success)
{
$this->_alias = $this->alias;
}
// TODO: remove this hack...
if (!isset($this->_noreorder))
{
$table->reorder();
$this->ordering = $table->ordering;
unset($this->_noreorder);
}
// Clear cache
$access = KunenaAccess::getInstance();
$access->clearCache();
KunenaCacheHelper::clear();
return true;
}
/**
* Purge old topics from this category. Removes topics from the database.
*
* @param $time
* @param array $params
* @param int $limit
*
* @return int Number of purged topics.
*/
public function purge($time, $params = array(), $limit = 1000)
{
// FIXME: why time isn't used?
if (!$this->exists())
{
return 0;
}
$where = isset($params['where']) ? (string) $params['where'] : '';
$db = JFactory::getDBO();
$query = "SELECT id FROM #__kunena_topics AS tt WHERE tt.category_id={$this->id} {$where} ORDER BY tt.last_post_time ASC";
$db->setQuery($query, 0, $limit);
try
{
$ids = $db->loadColumn();
}
catch (JDatabaseExceptionExecuting $e)
{
KunenaError::displayDatabaseError($e);
}
if (empty($ids))
{
return 0;
}
$count = KunenaForumTopicHelper::delete($ids);
KunenaUserHelper::recount();
KunenaForumCategoryHelper::recount($this->id);
KunenaAttachmentHelper::cleanup();
return $count;
}
/**
* Trash old topics in this category. Changes topic state to deleted.
*
* @param $time
* @param array $params
* @param int $limit
*
* @return int Number of trashed topics.
*/
public function trash($time, $params = array(), $limit = 1000)
{
// FIXME: why time isn't used?
if (!$this->exists())
{
return 0;
}
$where = isset($params['where']) ? (string) $params['where'] : '';
$db = JFactory::getDBO();
$query = "SELECT id FROM #__kunena_topics AS tt WHERE tt.category_id={$this->id} AND tt.hold!=2 {$where} ORDER BY tt.last_post_time ASC";
$db->setQuery($query, 0, $limit);
try
{
$ids = $db->loadColumn();
}
catch (JDatabaseExceptionExecuting $e)
{
KunenaError::displayDatabaseError($e);
}
if (empty($ids))
{
return 0;
}
$count = KunenaForumTopicHelper::trash($ids);
KunenaUserHelper::recount();
KunenaForumCategoryHelper::recount($this->id);
return $count;
}
/**
* Delete this category and all related information from the database.
*
* @return bool True on success
*/
public function delete()
{
if (!$this->exists())
{
return true;
}
if (!parent::delete())
{
return false;
}
$access = KunenaAccess::getInstance();
$access->clearCache();
$db = JFactory::getDBO();
$queries[] = "DELETE FROM #__kunena_aliases WHERE type='catid' AND item={$db->quote($this->id)}";
// Delete user topics
$queries[] = "DELETE FROM #__kunena_user_topics WHERE category_id={$db->quote($this->id)}";
// Delete user categories
$queries[] = "DELETE FROM #__kunena_user_categories WHERE category_id={$db->quote($this->id)}";
// Delete user read
$queries[] = "DELETE FROM #__kunena_user_read WHERE category_id={$db->quote($this->id)}";
// Delete thank yous
$queries[] = "DELETE t FROM #__kunena_thankyou AS t INNER JOIN #__kunena_messages AS m ON m.id=t.postid WHERE m.catid={$db->quote($this->id)}";
// Delete poll users
$queries[] = "DELETE p FROM #__kunena_polls_users AS p INNER JOIN #__kunena_topics AS tt ON tt.poll_id=p.pollid WHERE tt.category_id={$db->quote($this->id)} AND tt.moved_id=0";
// Delete poll options
$queries[] = "DELETE p FROM #__kunena_polls_options AS p INNER JOIN #__kunena_topics AS tt ON tt.poll_id=p.pollid WHERE tt.category_id={$db->quote($this->id)} AND tt.moved_id=0";
// Delete polls
$queries[] = "DELETE p FROM #__kunena_polls AS p INNER JOIN #__kunena_topics AS tt ON tt.poll_id=p.id WHERE tt.category_id={$db->quote($this->id)} AND tt.moved_id=0";
// Delete messages
$queries[] = "DELETE m, t FROM #__kunena_messages AS m INNER JOIN #__kunena_messages_text AS t ON m.id=t.mesid WHERE m.catid={$db->quote($this->id)}";
// TODO: delete attachments
// Delete topics
$queries[] = "DELETE FROM #__kunena_topics WHERE category_id={$db->quote($this->id)}";
foreach ($queries as $query)
{
$db->setQuery($query);
try
{
$db->execute();
}
catch (JDatabaseExceptionExecuting $e)
{
KunenaError::displayDatabaseError($e);
}
}
KunenaUserHelper::recount();
KunenaForumMessageThankyouHelper::recount();
$this->id = null;
KunenaForumCategoryHelper::register($this);
return true;
}
/**
* Method to check out the KunenaForumCategory object.
*
* @param integer $who
*
* @return boolean True if checked out by somebody else.
*
* @since 1.6
*/
public function checkout($who)
{
if (!$this->_exists)
{
return false;
}
// Create the user table object
$table = $this->getTable();
$table->bind($this->getProperties());
$table->exists($this->_exists);
$result = $table->checkout($who);
// Assuming all is well at this point lets bind the data
$params = $this->params;
$this->setProperties($table->getProperties());
$this->params = $params;
return $result;
}
/**
* Method to check in the KunenaForumCategory object.
*
* @return boolean True on success.
*
* @since 1.6
*/
public function checkin()
{
if (!$this->_exists)
{
return true;
}
// Create the user table object
$table = $this->getTable();
$table->bind($this->getProperties());
$table->exists($this->_exists);
$result = $table->checkin();
// Assuming all is well at this point lets bind the data
$params = $this->params;
$this->setProperties($table->getProperties());
$this->params = $params;
$cache = JFactory::getCache('com_kunena', 'output');
// FIXME: enable caching after fixing the issues
//$cache->clean('categories');
return $result;
}
/**
* Method to check if an item is checked out.
*
* @param string $with
*
* @return boolean
*
* @since 1.6
*/
public function isCheckedOut($with)
{
if (!$this->_exists)
{
return false;
}
// Create the user table object
$table = $this->getTable();
$table->bind($this->getProperties());
$table->exists($this->_exists);
$result = $table->isCheckedOut($with);
return $result;
}
/**
* @param KunenaForumTopic $topic
* @param int $topicdelta
* @param int $postdelta
*
* @return boolean
*/
public function update($topic, $topicdelta = 0, $postdelta = 0)
{
if (!$topic->id)
{
return false;
}
$update = false;
if ($topicdelta || $postdelta)
{
// Update topic and post count
$this->numTopics += (int) $topicdelta;
$this->numPosts += (int) $postdelta;
$update = true;
}
if ($topic->exists() && $topic->hold == 0 && $topic->moved_id == 0 && $topic->category_id == $this->id
&& ($this->last_post_time < $topic->last_post_time || ($this->last_post_time == $topic->last_post_time && $this->last_post_id <= $topic->last_post_id))
) {
// If topic has new post or last topic changed, we need to update cache
$this->last_topic_id = $topic->id;
$this->last_post_id = $topic->last_post_id;
$this->last_post_time = $topic->last_post_time;
$update = true;
}
elseif ($this->last_topic_id == $topic->id)
{
// If last topic/post got moved or deleted, we need to find last post
$db = JFactory::getDBO();
$query = "SELECT * FROM #__kunena_topics WHERE category_id={$db->quote($this->id)} AND hold=0 AND moved_id=0 ORDER BY last_post_time DESC, last_post_id DESC";
$db->setQuery($query, 0, 1);
try
{
$topic = $db->loadObject();
}
catch (JDatabaseExceptionExecuting $e)
{
KunenaError::displayDatabaseError($e);
}
if ($topic)
{
$this->last_topic_id = $topic->id;
$this->last_post_id = $topic->last_post_id;
$this->last_post_time = $topic->last_post_time;
$update = true;
}
else
{
$this->numTopics = 0;
$this->numPosts = 0;
$this->last_topic_id = 0;
$this->last_post_id = 0;
$this->last_post_time = 0;
$update = true;
}
}
if (!$update)
{
return true;
}
// TODO: remove this hack...
$this->_noreorder = true;
return $this->save();
}
/**
* Get if the user has subscribed on this category.
*
* @param mixed $userid
*
* @return boolean
*
* @since 2.0.0
*/
public function getSubscribed($userid = null )
{
if (!$this->exists())
{
return false;
}
if (!$userid)
{
return false;
}
$usercategory = KunenaForumCategoryUserHelper::get($this->id, $userid);
return (bool) $usercategory->subscribed;
}
// Internal functions
protected function buildInfo()
{
if ($this->_topics !== false)
{
return;
}
$this->_topics = 0;
$this->_posts = 0;
$this->_lastcat = $this;
// @var array|KunenaForumCategory[] $categories
$categories[$this->id] = $this;
// TODO: support channels
//$categories += $this->getChannels();
$categories += KunenaForumCategoryHelper::getChildren($this->id);
foreach ($categories as $category)
{
$category->buildInfo();
$lastCategory = $category->getLastCategory();
$this->_topics += $category->_topics ? $category->_topics : max($category->numTopics, 0);
$this->_posts += $category->_posts ? $category->_posts : max($category->numPosts, 0);
if ($lastCategory->last_post_time && $this->_lastcat->last_post_time < $lastCategory->last_post_time)
{
$this->_lastcat = $lastCategory;
}
}
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseRead(KunenaUser $user)
{
static $catids = false;
if ($catids === false)
{
$catids = KunenaAccess::getInstance()->getAllowedCategories($user);
}
// Checks if user can read category
if (!$this->exists())
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_NO_ACCESS'), 404);
}
if (empty($catids[$this->id]))
{
if ($user->exists())
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_NO_ACCESS'), 403);
}
else
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_NO_ACCESS'), 401);
}
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseNotBanned(KunenaUser $user)
{
$banned = $user->isBanned();
if ($banned)
{
$banned = KunenaUserBan::getInstanceByUserid($user->userid, true);
if (!$banned->isLifetime())
{
return new KunenaExceptionAuthorise(JText::sprintf('COM_KUNENA_POST_ERROR_USER_BANNED_NOACCESS_EXPIRY', KunenaDate::getInstance($banned->expiration)->toKunena()), 403);
}
else
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_POST_ERROR_USER_BANNED_NOACCESS'), 403);
}
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseGuestWrite(KunenaUser $user)
{
// Check if user is guest and they can create or reply topics
if ($user->userid == 0 && !KunenaFactory::getConfig()->pubwrite)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_POST_ERROR_ANONYMOUS_FORBITTEN'), 401);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseSubscribe(KunenaUser $user)
{
// Check if user is guest and they can create or reply topics
$config = KunenaFactory::getConfig();
if (!$config->allowsubscriptions || $config->topic_subscriptions == 'disabled')
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_LIB_CATEGORY_AUTHORISE_FAILED_SUBSCRIPTIONS'), 403);
}
if ($user->userid == 0)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_LIB_CATEGORY_AUTHORISE_FAILED_SUBSCRIPTIONS'), 401);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseCatSubscribe(KunenaUser $user)
{
// Check if user is guest and they can create or reply topics
$config = KunenaFactory::getConfig();
if (!$config->allowsubscriptions || $config->category_subscriptions == 'disabled')
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_LIB_CATEGORY_AUTHORISE_FAILED_SUBSCRIPTIONS'), 403);
}
if ($user->userid == 0)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_LIB_CATEGORY_AUTHORISE_FAILED_SUBSCRIPTIONS'), 401);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseFavorite(KunenaUser $user)
{
// Check if user is guest and they can create or reply topics
if (!KunenaFactory::getConfig()->allowfavorites)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_LIB_CATEGORY_AUTHORISE_FAILED_FAVORITES'), 403);
}
if ($user->userid == 0)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_LIB_CATEGORY_AUTHORISE_FAILED_FAVORITES'), 401);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseNotSection(KunenaUser $user)
{
// Check if category is not a section
if ($this->isSection())
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_POST_ERROR_IS_SECTION'), 403);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseChannel(KunenaUser $user)
{
// Check if category is alias
$channels = $this->getChannels('none');
if (!isset($channels[$this->id]))
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_POST_ERROR_IS_ALIAS'), 403);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseUnlocked(KunenaUser $user)
{
// Check that category is not locked or that user is a moderator
if ($this->locked && (!$user->userid || !$user->isModerator($this)))
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_POST_ERROR_CATEGORY_LOCKED'), 403);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseModerate(KunenaUser $user)
{
// Check that user is moderator
if (!$user->userid)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_POST_NOT_MODERATOR'), 401);
}
if (!$user->isModerator($this))
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_POST_NOT_MODERATOR'), 403);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseGlobalModerate(KunenaUser $user)
{
// Check that user is a global moderator
if (!$user->userid)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_POST_NOT_GLOBAL_MODERATOR'), 401);
}
if (!$user->isModerator())
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_POST_NOT_GLOBAL_MODERATOR'), 403);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseAdmin(KunenaUser $user)
{
// Check that user is admin
if (!$user->userid)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_MODERATION_ERROR_NOT_ADMIN'), 401);
}
if (!$user->isAdmin($this))
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_MODERATION_ERROR_NOT_ADMIN'), 403);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authorisePoll(KunenaUser $user)
{
// Check if polls are enabled at all
if (!KunenaFactory::getConfig()->pollenabled)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_LIB_CATEGORY_AUTHORISE_FAILED_POLLS_DISABLED'), 403);
}
// Check if polls are not enabled in this category
if (!$this->allow_polls)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_LIB_CATEGORY_AUTHORISE_FAILED_POLLS_NOT_ALLOWED'), 403);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseVote(KunenaUser $user)
{
// Check if user is guest
if ($user->userid == 0)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_POLL_NOT_LOGGED'), 401);
}
return null;
}
/**
* @param KunenaUser $user
*
* @return KunenaExceptionAuthorise|null
*/
protected function authoriseUpload(KunenaUser $user)
{
// Check if attachments are allowed
if (KunenaAttachmentHelper::getExtensions($this, $user) === false)
{
return new KunenaExceptionAuthorise(JText::_('COM_KUNENA_LIB_CATEGORY_AUTHORISE_FAILED_UPLOAD_NOT_ALLOWED'), 403);
}
return null;
}
/**
* @param $count
*
* @return int
*
* @since Kunena 5.0.13
*/
public function totalCount($count)
{
if ($count)
{
if ($count > 1)
{
return JText::plural('COM_KUNENA_X_TOPICS_MORE', $this->formatLargeNumber($count));
}
else
{
return JText::plural('COM_KUNENA_X_TOPICS_1', $count);
}
}
return JText::_('COM_KUNENA_X_TOPICS_0');
}
/**
* This function formats a number to n significant digits when above
* 10,000. Starting at 10,0000 the out put changes to 10k, starting
* at 1,000,000 the output switches to 1m. Both k and m are defined
* in the language file. The significant digits are used to limit the
* number of digits displayed when in 10k or 1m mode.
*
* @param int $number Number to be formated
* @param int $precision Significant digits for output
*
* @return string
*/
public function formatLargeNumber($number, $precision = 3)
{
// Do we need to reduce the number of significant digits?
if ($number >= 10000)
{
// Round the number to n significant digits
$number = round($number, -1 * (log10($number) + 1) + $precision);
}
if ($number < 10000)
{
$output = $number;
}
elseif ($number >= 1000000)
{
$output = $number / 1000000 . JText::_('COM_KUNENA_MILLION');
}
else
{
$output = $number / 1000 . JText::_('COM_KUNENA_THOUSAND');
}
return $output;
}
}