[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/components/com_content/src/Model/ -> CategoryModel.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Site
   5   * @subpackage  com_content
   6   *
   7   * @copyright   (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9   */
  10  
  11  namespace Joomla\Component\Content\Site\Model;
  12  
  13  use Joomla\CMS\Categories\Categories;
  14  use Joomla\CMS\Categories\CategoryNode;
  15  use Joomla\CMS\Factory;
  16  use Joomla\CMS\Language\Multilanguage;
  17  use Joomla\CMS\MVC\Model\ListModel;
  18  use Joomla\CMS\Table\Table;
  19  use Joomla\Component\Content\Site\Helper\QueryHelper;
  20  use Joomla\Registry\Registry;
  21  use Joomla\Utilities\ArrayHelper;
  22  
  23  // phpcs:disable PSR1.Files.SideEffects
  24  \defined('_JEXEC') or die;
  25  // phpcs:enable PSR1.Files.SideEffects
  26  
  27  /**
  28   * This models supports retrieving a category, the articles associated with the category,
  29   * sibling, child and parent categories.
  30   *
  31   * @since  1.5
  32   */
  33  class CategoryModel extends ListModel
  34  {
  35      /**
  36       * Category items data
  37       *
  38       * @var  array
  39       */
  40      protected $_item = null;
  41  
  42      /**
  43       * Array of articles in the category
  44       *
  45       * @var \stdClass[]
  46       */
  47      protected $_articles = null;
  48  
  49      /**
  50       * Category left and right of this one
  51       *
  52       * @var  CategoryNode[]|null
  53       */
  54      protected $_siblings = null;
  55  
  56      /**
  57       * Array of child-categories
  58       *
  59       * @var  CategoryNode[]|null
  60       */
  61      protected $_children = null;
  62  
  63      /**
  64       * Parent category of the current one
  65       *
  66       * @var  CategoryNode|null
  67       */
  68      protected $_parent = null;
  69  
  70      /**
  71       * Model context string.
  72       *
  73       * @var  string
  74       */
  75      protected $_context = 'com_content.category';
  76  
  77      /**
  78       * The category that applies.
  79       *
  80       * @var  object
  81       */
  82      protected $_category = null;
  83  
  84      /**
  85       * The list of categories.
  86       *
  87       * @var  array
  88       */
  89      protected $_categories = null;
  90  
  91      /**
  92       * @param   array  $config  An optional associative array of configuration settings.
  93       *
  94       * @since   1.6
  95       */
  96      public function __construct($config = array())
  97      {
  98          if (empty($config['filter_fields'])) {
  99              $config['filter_fields'] = array(
 100                  'id', 'a.id',
 101                  'title', 'a.title',
 102                  'alias', 'a.alias',
 103                  'checked_out', 'a.checked_out',
 104                  'checked_out_time', 'a.checked_out_time',
 105                  'catid', 'a.catid', 'category_title',
 106                  'state', 'a.state',
 107                  'access', 'a.access', 'access_level',
 108                  'created', 'a.created',
 109                  'created_by', 'a.created_by',
 110                  'modified', 'a.modified',
 111                  'ordering', 'a.ordering',
 112                  'featured', 'a.featured',
 113                  'language', 'a.language',
 114                  'hits', 'a.hits',
 115                  'publish_up', 'a.publish_up',
 116                  'publish_down', 'a.publish_down',
 117                  'author', 'a.author',
 118                  'filter_tag'
 119              );
 120          }
 121  
 122          parent::__construct($config);
 123      }
 124  
 125      /**
 126       * Method to auto-populate the model state.
 127       *
 128       * Note. Calling getState in this method will result in recursion.
 129       *
 130       * @param   string  $ordering   The field to order on.
 131       * @param   string  $direction  The direction to order on.
 132       *
 133       * @return  void
 134       *
 135       * @since   1.6
 136       */
 137      protected function populateState($ordering = null, $direction = null)
 138      {
 139          $app = Factory::getApplication();
 140          $pk  = $app->input->getInt('id');
 141  
 142          $this->setState('category.id', $pk);
 143  
 144          // Load the parameters. Merge Global and Menu Item params into new object
 145          $params = $app->getParams();
 146  
 147          if ($menu = $app->getMenu()->getActive()) {
 148              $menuParams = $menu->getParams();
 149          } else {
 150              $menuParams = new Registry();
 151          }
 152  
 153          $mergedParams = clone $menuParams;
 154          $mergedParams->merge($params);
 155  
 156          $this->setState('params', $mergedParams);
 157          $user  = Factory::getUser();
 158  
 159          $asset = 'com_content';
 160  
 161          if ($pk) {
 162              $asset .= '.category.' . $pk;
 163          }
 164  
 165          if ((!$user->authorise('core.edit.state', $asset)) &&  (!$user->authorise('core.edit', $asset))) {
 166              // Limit to published for people who can't edit or edit.state.
 167              $this->setState('filter.published', 1);
 168          } else {
 169              $this->setState('filter.published', [0, 1]);
 170          }
 171  
 172          // Process show_noauth parameter
 173          if (!$params->get('show_noauth')) {
 174              $this->setState('filter.access', true);
 175          } else {
 176              $this->setState('filter.access', false);
 177          }
 178  
 179          $itemid = $app->input->get('id', 0, 'int') . ':' . $app->input->get('Itemid', 0, 'int');
 180  
 181          $value = $this->getUserStateFromRequest('com_content.category.filter.' . $itemid . '.tag', 'filter_tag', 0, 'int', false);
 182          $this->setState('filter.tag', $value);
 183  
 184          // Optional filter text
 185          $search = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter-search', 'filter-search', '', 'string');
 186          $this->setState('list.filter', $search);
 187  
 188          // Filter.order
 189          $orderCol = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order', 'filter_order', '', 'string');
 190  
 191          if (!in_array($orderCol, $this->filter_fields)) {
 192              $orderCol = 'a.ordering';
 193          }
 194  
 195          $this->setState('list.ordering', $orderCol);
 196  
 197          $listOrder = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order_Dir', 'filter_order_Dir', '', 'cmd');
 198  
 199          if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', ''))) {
 200              $listOrder = 'ASC';
 201          }
 202  
 203          $this->setState('list.direction', $listOrder);
 204  
 205          $this->setState('list.start', $app->input->get('limitstart', 0, 'uint'));
 206  
 207          // Set limit for query. If list, use parameter. If blog, add blog parameters for limit.
 208          if (($app->input->get('layout') === 'blog') || $params->get('layout_type') === 'blog') {
 209              $limit = $params->get('num_leading_articles') + $params->get('num_intro_articles') + $params->get('num_links');
 210              $this->setState('list.links', $params->get('num_links'));
 211          } else {
 212              $limit = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.limit', 'limit', $params->get('display_num'), 'uint');
 213          }
 214  
 215          $this->setState('list.limit', $limit);
 216  
 217          // Set the depth of the category query based on parameter
 218          $showSubcategories = $params->get('show_subcategory_content', '0');
 219  
 220          if ($showSubcategories) {
 221              $this->setState('filter.max_category_levels', $params->get('show_subcategory_content', '1'));
 222              $this->setState('filter.subcategories', true);
 223          }
 224  
 225          $this->setState('filter.language', Multilanguage::isEnabled());
 226  
 227          $this->setState('layout', $app->input->getString('layout'));
 228  
 229          // Set the featured articles state
 230          $this->setState('filter.featured', $params->get('show_featured'));
 231      }
 232  
 233      /**
 234       * Get the articles in the category
 235       *
 236       * @return  array|bool  An array of articles or false if an error occurs.
 237       *
 238       * @since   1.5
 239       */
 240      public function getItems()
 241      {
 242          $limit = $this->getState('list.limit');
 243  
 244          if ($this->_articles === null && $category = $this->getCategory()) {
 245              $model = $this->bootComponent('com_content')->getMVCFactory()
 246                  ->createModel('Articles', 'Site', ['ignore_request' => true]);
 247              $model->setState('params', Factory::getApplication()->getParams());
 248              $model->setState('filter.category_id', $category->id);
 249              $model->setState('filter.published', $this->getState('filter.published'));
 250              $model->setState('filter.access', $this->getState('filter.access'));
 251              $model->setState('filter.language', $this->getState('filter.language'));
 252              $model->setState('filter.featured', $this->getState('filter.featured'));
 253              $model->setState('list.ordering', $this->_buildContentOrderBy());
 254              $model->setState('list.start', $this->getState('list.start'));
 255              $model->setState('list.limit', $limit);
 256              $model->setState('list.direction', $this->getState('list.direction'));
 257              $model->setState('list.filter', $this->getState('list.filter'));
 258              $model->setState('filter.tag', $this->getState('filter.tag'));
 259  
 260              // Filter.subcategories indicates whether to include articles from subcategories in the list or blog
 261              $model->setState('filter.subcategories', $this->getState('filter.subcategories'));
 262              $model->setState('filter.max_category_levels', $this->getState('filter.max_category_levels'));
 263              $model->setState('list.links', $this->getState('list.links'));
 264  
 265              if ($limit >= 0) {
 266                  $this->_articles = $model->getItems();
 267  
 268                  if ($this->_articles === false) {
 269                      $this->setError($model->getError());
 270                  }
 271              } else {
 272                  $this->_articles = array();
 273              }
 274  
 275              $this->_pagination = $model->getPagination();
 276          }
 277  
 278          return $this->_articles;
 279      }
 280  
 281      /**
 282       * Build the orderby for the query
 283       *
 284       * @return  string  $orderby portion of query
 285       *
 286       * @since   1.5
 287       */
 288      protected function _buildContentOrderBy()
 289      {
 290          $app       = Factory::getApplication();
 291          $db        = $this->getDatabase();
 292          $params    = $this->state->params;
 293          $itemid    = $app->input->get('id', 0, 'int') . ':' . $app->input->get('Itemid', 0, 'int');
 294          $orderCol  = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order', 'filter_order', '', 'string');
 295          $orderDirn = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order_Dir', 'filter_order_Dir', '', 'cmd');
 296          $orderby   = ' ';
 297  
 298          if (!in_array($orderCol, $this->filter_fields)) {
 299              $orderCol = null;
 300          }
 301  
 302          if (!in_array(strtoupper($orderDirn), array('ASC', 'DESC', ''))) {
 303              $orderDirn = 'ASC';
 304          }
 305  
 306          if ($orderCol && $orderDirn) {
 307              $orderby .= $db->escape($orderCol) . ' ' . $db->escape($orderDirn) . ', ';
 308          }
 309  
 310          $articleOrderby   = $params->get('orderby_sec', 'rdate');
 311          $articleOrderDate = $params->get('order_date');
 312          $categoryOrderby  = $params->def('orderby_pri', '');
 313          $secondary        = QueryHelper::orderbySecondary($articleOrderby, $articleOrderDate, $this->getDatabase()) . ', ';
 314          $primary          = QueryHelper::orderbyPrimary($categoryOrderby);
 315  
 316          $orderby .= $primary . ' ' . $secondary . ' a.created ';
 317  
 318          return $orderby;
 319      }
 320  
 321      /**
 322       * Method to get a JPagination object for the data set.
 323       *
 324       * @return  \Joomla\CMS\Pagination\Pagination  A JPagination object for the data set.
 325       *
 326       * @since   3.0.1
 327       */
 328      public function getPagination()
 329      {
 330          if (empty($this->_pagination)) {
 331              return null;
 332          }
 333  
 334          return $this->_pagination;
 335      }
 336  
 337      /**
 338       * Method to get category data for the current category
 339       *
 340       * @return  object
 341       *
 342       * @since   1.5
 343       */
 344      public function getCategory()
 345      {
 346          if (!is_object($this->_item)) {
 347              if (isset($this->state->params)) {
 348                  $params = $this->state->params;
 349                  $options = array();
 350                  $options['countItems'] = $params->get('show_cat_num_articles', 1) || !$params->get('show_empty_categories_cat', 0);
 351                  $options['access']     = $params->get('check_access_rights', 1);
 352              } else {
 353                  $options['countItems'] = 0;
 354              }
 355  
 356              $categories = Categories::getInstance('Content', $options);
 357              $this->_item = $categories->get($this->getState('category.id', 'root'));
 358  
 359              // Compute selected asset permissions.
 360              if (is_object($this->_item)) {
 361                  $user  = Factory::getUser();
 362                  $asset = 'com_content.category.' . $this->_item->id;
 363  
 364                  // Check general create permission.
 365                  if ($user->authorise('core.create', $asset)) {
 366                      $this->_item->getParams()->set('access-create', true);
 367                  }
 368  
 369                  // @todo: Why aren't we lazy loading the children and siblings?
 370                  $this->_children = $this->_item->getChildren();
 371                  $this->_parent = false;
 372  
 373                  if ($this->_item->getParent()) {
 374                      $this->_parent = $this->_item->getParent();
 375                  }
 376  
 377                  $this->_rightsibling = $this->_item->getSibling();
 378                  $this->_leftsibling = $this->_item->getSibling(false);
 379              } else {
 380                  $this->_children = false;
 381                  $this->_parent = false;
 382              }
 383          }
 384  
 385          return $this->_item;
 386      }
 387  
 388      /**
 389       * Get the parent category.
 390       *
 391       * @return  mixed  An array of categories or false if an error occurs.
 392       *
 393       * @since   1.6
 394       */
 395      public function getParent()
 396      {
 397          if (!is_object($this->_item)) {
 398              $this->getCategory();
 399          }
 400  
 401          return $this->_parent;
 402      }
 403  
 404      /**
 405       * Get the left sibling (adjacent) categories.
 406       *
 407       * @return  mixed  An array of categories or false if an error occurs.
 408       *
 409       * @since   1.6
 410       */
 411      public function &getLeftSibling()
 412      {
 413          if (!is_object($this->_item)) {
 414              $this->getCategory();
 415          }
 416  
 417          return $this->_leftsibling;
 418      }
 419  
 420      /**
 421       * Get the right sibling (adjacent) categories.
 422       *
 423       * @return  mixed  An array of categories or false if an error occurs.
 424       *
 425       * @since   1.6
 426       */
 427      public function &getRightSibling()
 428      {
 429          if (!is_object($this->_item)) {
 430              $this->getCategory();
 431          }
 432  
 433          return $this->_rightsibling;
 434      }
 435  
 436      /**
 437       * Get the child categories.
 438       *
 439       * @return  mixed  An array of categories or false if an error occurs.
 440       *
 441       * @since   1.6
 442       */
 443      public function &getChildren()
 444      {
 445          if (!is_object($this->_item)) {
 446              $this->getCategory();
 447          }
 448  
 449          // Order subcategories
 450          if ($this->_children) {
 451              $params = $this->getState()->get('params');
 452  
 453              $orderByPri = $params->get('orderby_pri');
 454  
 455              if ($orderByPri === 'alpha' || $orderByPri === 'ralpha') {
 456                  $this->_children = ArrayHelper::sortObjects($this->_children, 'title', ($orderByPri === 'alpha') ? 1 : (-1));
 457              }
 458          }
 459  
 460          return $this->_children;
 461      }
 462  
 463      /**
 464       * Increment the hit counter for the category.
 465       *
 466       * @param   int  $pk  Optional primary key of the category to increment.
 467       *
 468       * @return  boolean True if successful; false otherwise and internal error set.
 469       */
 470      public function hit($pk = 0)
 471      {
 472          $input = Factory::getApplication()->input;
 473          $hitcount = $input->getInt('hitcount', 1);
 474  
 475          if ($hitcount) {
 476              $pk = (!empty($pk)) ? $pk : (int) $this->getState('category.id');
 477  
 478              $table = Table::getInstance('Category', 'JTable');
 479              $table->hit($pk);
 480          }
 481  
 482          return true;
 483      }
 484  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer