[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/administrator/components/com_contact/src/Model/ -> ContactsModel.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Administrator
   5   * @subpackage  com_contact
   6   *
   7   * @copyright   (C) 2008 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\Contact\Administrator\Model;
  12  
  13  use Joomla\CMS\Factory;
  14  use Joomla\CMS\Language\Associations;
  15  use Joomla\CMS\MVC\Model\ListModel;
  16  use Joomla\CMS\Table\Table;
  17  use Joomla\Database\ParameterType;
  18  use Joomla\Utilities\ArrayHelper;
  19  
  20  // phpcs:disable PSR1.Files.SideEffects
  21  \defined('_JEXEC') or die;
  22  // phpcs:enable PSR1.Files.SideEffects
  23  
  24  /**
  25   * Methods supporting a list of contact records.
  26   *
  27   * @since  1.6
  28   */
  29  class ContactsModel extends ListModel
  30  {
  31      /**
  32       * Constructor.
  33       *
  34       * @param   array  $config  An optional associative array of configuration settings.
  35       *
  36       * @since   1.6
  37       */
  38      public function __construct($config = array())
  39      {
  40          if (empty($config['filter_fields'])) {
  41              $config['filter_fields'] = array(
  42                  'id', 'a.id',
  43                  'name', 'a.name',
  44                  'alias', 'a.alias',
  45                  'checked_out', 'a.checked_out',
  46                  'checked_out_time', 'a.checked_out_time',
  47                  'catid', 'a.catid', 'category_id', 'category_title',
  48                  'user_id', 'a.user_id',
  49                  'published', 'a.published',
  50                  'access', 'a.access', 'access_level',
  51                  'created', 'a.created',
  52                  'created_by', 'a.created_by',
  53                  'ordering', 'a.ordering',
  54                  'featured', 'a.featured',
  55                  'language', 'a.language', 'language_title',
  56                  'publish_up', 'a.publish_up',
  57                  'publish_down', 'a.publish_down',
  58                  'ul.name', 'linked_user',
  59                  'tag',
  60                  'level', 'c.level',
  61              );
  62  
  63              if (Associations::isEnabled()) {
  64                  $config['filter_fields'][] = 'association';
  65              }
  66          }
  67  
  68          parent::__construct($config);
  69      }
  70  
  71      /**
  72       * Method to auto-populate the model state.
  73       *
  74       * Note. Calling getState in this method will result in recursion.
  75       *
  76       * @param   string  $ordering   An optional ordering field.
  77       * @param   string  $direction  An optional direction (asc|desc).
  78       *
  79       * @return  void
  80       *
  81       * @since   1.6
  82       */
  83      protected function populateState($ordering = 'a.name', $direction = 'asc')
  84      {
  85          $app = Factory::getApplication();
  86  
  87          $forcedLanguage = $app->input->get('forcedLanguage', '', 'cmd');
  88  
  89          // Adjust the context to support modal layouts.
  90          if ($layout = $app->input->get('layout')) {
  91              $this->context .= '.' . $layout;
  92          }
  93  
  94          // Adjust the context to support forced languages.
  95          if ($forcedLanguage) {
  96              $this->context .= '.' . $forcedLanguage;
  97          }
  98  
  99          // List state information.
 100          parent::populateState($ordering, $direction);
 101  
 102          // Force a language.
 103          if (!empty($forcedLanguage)) {
 104              $this->setState('filter.language', $forcedLanguage);
 105          }
 106      }
 107  
 108      /**
 109       * Method to get a store id based on model configuration state.
 110       *
 111       * This is necessary because the model is used by the component and
 112       * different modules that might need different sets of data or different
 113       * ordering requirements.
 114       *
 115       * @param   string  $id  A prefix for the store id.
 116       *
 117       * @return  string  A store id.
 118       *
 119       * @since   1.6
 120       */
 121      protected function getStoreId($id = '')
 122      {
 123          // Compile the store id.
 124          $id .= ':' . $this->getState('filter.search');
 125          $id .= ':' . $this->getState('filter.published');
 126          $id .= ':' . serialize($this->getState('filter.category_id'));
 127          $id .= ':' . $this->getState('filter.access');
 128          $id .= ':' . $this->getState('filter.language');
 129          $id .= ':' . serialize($this->getState('filter.tag'));
 130          $id .= ':' . $this->getState('filter.level');
 131  
 132          return parent::getStoreId($id);
 133      }
 134  
 135      /**
 136       * Build an SQL query to load the list data.
 137       *
 138       * @return  \Joomla\Database\DatabaseQuery
 139       *
 140       * @since   1.6
 141       */
 142      protected function getListQuery()
 143      {
 144          // Create a new query object.
 145          $db = $this->getDatabase();
 146          $query = $db->getQuery(true);
 147          $user = Factory::getUser();
 148  
 149          // Select the required fields from the table.
 150          $query->select(
 151              $db->quoteName(
 152                  explode(
 153                      ', ',
 154                      $this->getState(
 155                          'list.select',
 156                          'a.id, a.name, a.alias, a.checked_out, a.checked_out_time, a.catid, a.user_id' .
 157                          ', a.published, a.access, a.created, a.created_by, a.ordering, a.featured, a.language' .
 158                          ', a.publish_up, a.publish_down'
 159                      )
 160                  )
 161              )
 162          );
 163          $query->from($db->quoteName('#__contact_details', 'a'));
 164  
 165          // Join over the users for the linked user.
 166          $query->select(
 167              array(
 168                  $db->quoteName('ul.name', 'linked_user'),
 169                  $db->quoteName('ul.email')
 170              )
 171          )
 172              ->join(
 173                  'LEFT',
 174                  $db->quoteName('#__users', 'ul') . ' ON ' . $db->quoteName('ul.id') . ' = ' . $db->quoteName('a.user_id')
 175              );
 176  
 177          // Join over the language
 178          $query->select($db->quoteName('l.title', 'language_title'))
 179              ->select($db->quoteName('l.image', 'language_image'))
 180              ->join(
 181                  'LEFT',
 182                  $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.language')
 183              );
 184  
 185          // Join over the users for the checked out user.
 186          $query->select($db->quoteName('uc.name', 'editor'))
 187              ->join(
 188                  'LEFT',
 189                  $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')
 190              );
 191  
 192          // Join over the asset groups.
 193          $query->select($db->quoteName('ag.title', 'access_level'))
 194              ->join(
 195                  'LEFT',
 196                  $db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->quoteName('ag.id') . ' = ' . $db->quoteName('a.access')
 197              );
 198  
 199          // Join over the categories.
 200          $query->select($db->quoteName('c.title', 'category_title'))
 201              ->join(
 202                  'LEFT',
 203                  $db->quoteName('#__categories', 'c') . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid')
 204              );
 205  
 206          // Join over the associations.
 207          if (Associations::isEnabled()) {
 208              $subQuery = $db->getQuery(true)
 209                  ->select('COUNT(' . $db->quoteName('asso1.id') . ') > 1')
 210                  ->from($db->quoteName('#__associations', 'asso1'))
 211                  ->join('INNER', $db->quoteName('#__associations', 'asso2'), $db->quoteName('asso1.key') . ' = ' . $db->quoteName('asso2.key'))
 212                  ->where(
 213                      [
 214                          $db->quoteName('asso1.id') . ' = ' . $db->quoteName('a.id'),
 215                          $db->quoteName('asso1.context') . ' = ' . $db->quote('com_contact.item'),
 216                      ]
 217                  );
 218  
 219              $query->select('(' . $subQuery . ') AS ' . $db->quoteName('association'));
 220          }
 221  
 222          // Filter by featured.
 223          $featured = (string) $this->getState('filter.featured');
 224  
 225          if (in_array($featured, ['0','1'])) {
 226              $query->where($db->quoteName('a.featured') . ' = ' . (int) $featured);
 227          }
 228  
 229          // Filter by access level.
 230          if ($access = $this->getState('filter.access')) {
 231              $query->where($db->quoteName('a.access') . ' = :access');
 232              $query->bind(':access', $access, ParameterType::INTEGER);
 233          }
 234  
 235          // Implement View Level Access
 236          if (!$user->authorise('core.admin')) {
 237              $query->whereIn($db->quoteName('a.access'), $user->getAuthorisedViewLevels());
 238          }
 239  
 240          // Filter by published state
 241          $published = (string) $this->getState('filter.published');
 242  
 243          if (is_numeric($published)) {
 244              $query->where($db->quoteName('a.published') . ' = :published');
 245              $query->bind(':published', $published, ParameterType::INTEGER);
 246          } elseif ($published === '') {
 247              $query->where('(' . $db->quoteName('a.published') . ' = 0 OR ' . $db->quoteName('a.published') . ' = 1)');
 248          }
 249  
 250          // Filter by search in name.
 251          $search = $this->getState('filter.search');
 252  
 253          if (!empty($search)) {
 254              if (stripos($search, 'id:') === 0) {
 255                  $search = substr($search, 3);
 256                  $query->where($db->quoteName('a.id') . ' = :id');
 257                  $query->bind(':id', $search, ParameterType::INTEGER);
 258              } else {
 259                  $search = '%' . trim($search) . '%';
 260                  $query->where(
 261                      '(' . $db->quoteName('a.name') . ' LIKE :name OR ' . $db->quoteName('a.alias') . ' LIKE :alias)'
 262                  );
 263                  $query->bind(':name', $search);
 264                  $query->bind(':alias', $search);
 265              }
 266          }
 267  
 268          // Filter on the language.
 269          if ($language = $this->getState('filter.language')) {
 270              $query->where($db->quoteName('a.language') . ' = :language');
 271              $query->bind(':language', $language);
 272          }
 273  
 274          // Filter by a single or group of tags.
 275          $tag = $this->getState('filter.tag');
 276  
 277          // Run simplified query when filtering by one tag.
 278          if (\is_array($tag) && \count($tag) === 1) {
 279              $tag = $tag[0];
 280          }
 281  
 282          if ($tag && \is_array($tag)) {
 283              $tag = ArrayHelper::toInteger($tag);
 284  
 285              $subQuery = $db->getQuery(true)
 286                  ->select('DISTINCT ' . $db->quoteName('content_item_id'))
 287                  ->from($db->quoteName('#__contentitem_tag_map'))
 288                  ->where(
 289                      [
 290                          $db->quoteName('tag_id') . ' IN (' . implode(',', $query->bindArray($tag)) . ')',
 291                          $db->quoteName('type_alias') . ' = ' . $db->quote('com_contact.contact'),
 292                      ]
 293                  );
 294  
 295              $query->join(
 296                  'INNER',
 297                  '(' . $subQuery . ') AS ' . $db->quoteName('tagmap'),
 298                  $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
 299              );
 300          } elseif ($tag = (int) $tag) {
 301              $query->join(
 302                  'INNER',
 303                  $db->quoteName('#__contentitem_tag_map', 'tagmap'),
 304                  $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
 305              )
 306                  ->where(
 307                      [
 308                          $db->quoteName('tagmap.tag_id') . ' = :tag',
 309                          $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_contact.contact'),
 310                      ]
 311                  )
 312                  ->bind(':tag', $tag, ParameterType::INTEGER);
 313          }
 314  
 315          // Filter by categories and by level
 316          $categoryId = $this->getState('filter.category_id', array());
 317          $level = $this->getState('filter.level');
 318  
 319          if (!is_array($categoryId)) {
 320              $categoryId = $categoryId ? array($categoryId) : array();
 321          }
 322  
 323          // Case: Using both categories filter and by level filter
 324          if (count($categoryId)) {
 325              $categoryId = ArrayHelper::toInteger($categoryId);
 326              $categoryTable = Table::getInstance('Category', 'JTable');
 327              $subCatItemsWhere = array();
 328  
 329              // @todo: Convert to prepared statement
 330              foreach ($categoryId as $filter_catid) {
 331                  $categoryTable->load($filter_catid);
 332                  $subCatItemsWhere[] = '(' .
 333                      ($level ? 'c.level <= ' . ((int) $level + (int) $categoryTable->level - 1) . ' AND ' : '') .
 334                      'c.lft >= ' . (int) $categoryTable->lft . ' AND ' .
 335                      'c.rgt <= ' . (int) $categoryTable->rgt . ')';
 336              }
 337  
 338              $query->where('(' . implode(' OR ', $subCatItemsWhere) . ')');
 339          } elseif ($level) {
 340              // Case: Using only the by level filter
 341              $query->where($db->quoteName('c.level') . ' <= :level');
 342              $query->bind(':level', $level, ParameterType::INTEGER);
 343          }
 344  
 345          // Add the list ordering clause.
 346          $orderCol = $this->state->get('list.ordering', 'a.name');
 347          $orderDirn = $this->state->get('list.direction', 'asc');
 348  
 349          if ($orderCol == 'a.ordering' || $orderCol == 'category_title') {
 350              $orderCol = $db->quoteName('c.title') . ' ' . $orderDirn . ', ' . $db->quoteName('a.ordering');
 351          }
 352  
 353          $query->order($db->escape($orderCol . ' ' . $orderDirn));
 354  
 355          return $query;
 356      }
 357  }


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