[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |