[ 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_finder 6 * 7 * @copyright (C) 2011 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\Finder\Administrator\Model; 12 13 use Joomla\CMS\Component\ComponentHelper; 14 use Joomla\CMS\Factory; 15 use Joomla\CMS\Language\Text; 16 use Joomla\CMS\MVC\Factory\MVCFactoryInterface; 17 use Joomla\CMS\MVC\Model\ListModel; 18 use Joomla\CMS\Plugin\PluginHelper; 19 use Joomla\Database\DatabaseQuery; 20 21 // phpcs:disable PSR1.Files.SideEffects 22 \defined('_JEXEC') or die; 23 // phpcs:enable PSR1.Files.SideEffects 24 25 /** 26 * Maps model for the Finder package. 27 * 28 * @since 2.5 29 */ 30 class MapsModel extends ListModel 31 { 32 /** 33 * Constructor. 34 * 35 * @param array $config An optional associative array of configuration settings. 36 * @param MVCFactoryInterface $factory The factory. 37 * 38 * @see \Joomla\CMS\MVC\Model\BaseDatabaseModel 39 * @since 3.7 40 */ 41 public function __construct($config = array(), MVCFactoryInterface $factory = null) 42 { 43 if (empty($config['filter_fields'])) { 44 $config['filter_fields'] = array( 45 'state', 'a.state', 46 'title', 'a.title', 47 'branch', 48 'branch_title', 'd.branch_title', 49 'level', 'd.level', 50 'language', 'a.language', 51 ); 52 } 53 54 parent::__construct($config, $factory); 55 } 56 57 /** 58 * Method to test whether a record can be deleted. 59 * 60 * @param object $record A record object. 61 * 62 * @return boolean True if allowed to delete the record. Defaults to the permission for the component. 63 * 64 * @since 2.5 65 */ 66 protected function canDelete($record) 67 { 68 return Factory::getUser()->authorise('core.delete', $this->option); 69 } 70 71 /** 72 * Method to test whether a record can have its state changed. 73 * 74 * @param object $record A record object. 75 * 76 * @return boolean True if allowed to change the state of the record. Defaults to the permission for the component. 77 * 78 * @since 2.5 79 */ 80 protected function canEditState($record) 81 { 82 return Factory::getUser()->authorise('core.edit.state', $this->option); 83 } 84 85 /** 86 * Method to delete one or more records. 87 * 88 * @param array $pks An array of record primary keys. 89 * 90 * @return boolean True if successful, false if an error occurs. 91 * 92 * @since 2.5 93 */ 94 public function delete(&$pks) 95 { 96 $pks = (array) $pks; 97 $table = $this->getTable(); 98 99 // Include the content plugins for the on delete events. 100 PluginHelper::importPlugin('content'); 101 102 // Iterate the items to check if all of them exist. 103 foreach ($pks as $i => $pk) { 104 if (!$table->load($pk)) { 105 // Item is not in the table. 106 $this->setError($table->getError()); 107 108 return false; 109 } 110 } 111 112 // Iterate the items to delete each one. 113 foreach ($pks as $i => $pk) { 114 if ($table->load($pk)) { 115 if ($this->canDelete($table)) { 116 $context = $this->option . '.' . $this->name; 117 118 // Trigger the onContentBeforeDelete event. 119 $result = Factory::getApplication()->triggerEvent('onContentBeforeDelete', array($context, $table)); 120 121 if (in_array(false, $result, true)) { 122 $this->setError($table->getError()); 123 124 return false; 125 } 126 127 if (!$table->delete($pk)) { 128 $this->setError($table->getError()); 129 130 return false; 131 } 132 133 // Trigger the onContentAfterDelete event. 134 Factory::getApplication()->triggerEvent('onContentAfterDelete', array($context, $table)); 135 } else { 136 // Prune items that you can't change. 137 unset($pks[$i]); 138 $error = $this->getError(); 139 140 if ($error) { 141 $this->setError($error); 142 } else { 143 $this->setError(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); 144 } 145 } 146 } 147 } 148 149 // Clear the component's cache 150 $this->cleanCache(); 151 152 return true; 153 } 154 155 /** 156 * Build an SQL query to load the list data. 157 * 158 * @return \Joomla\Database\DatabaseQuery 159 * 160 * @since 2.5 161 */ 162 protected function getListQuery() 163 { 164 $db = $this->getDatabase(); 165 166 // Select all fields from the table. 167 $query = $db->getQuery(true) 168 ->select('a.id, a.parent_id, a.lft, a.rgt, a.level, a.path, a.title, a.alias, a.state, a.access, a.language') 169 ->from($db->quoteName('#__finder_taxonomy', 'a')) 170 ->where('a.parent_id != 0'); 171 172 // Join to get the branch title 173 $query->select([$db->quoteName('b.id', 'branch_id'), $db->quoteName('b.title', 'branch_title')]) 174 ->leftJoin($db->quoteName('#__finder_taxonomy', 'b') . ' ON b.level = 1 AND b.lft <= a.lft AND a.rgt <= b.rgt'); 175 176 // Join to get the map links. 177 $stateQuery = $db->getQuery(true) 178 ->select('m.node_id') 179 ->select('COUNT(NULLIF(l.published, 0)) AS count_published') 180 ->select('COUNT(NULLIF(l.published, 1)) AS count_unpublished') 181 ->from($db->quoteName('#__finder_taxonomy_map', 'm')) 182 ->leftJoin($db->quoteName('#__finder_links', 'l') . ' ON l.link_id = m.link_id') 183 ->group('m.node_id'); 184 185 $query->select('COALESCE(s.count_published, 0) AS count_published'); 186 $query->select('COALESCE(s.count_unpublished, 0) AS count_unpublished'); 187 $query->leftJoin('(' . $stateQuery . ') AS s ON s.node_id = a.id'); 188 189 // If the model is set to check item state, add to the query. 190 $state = $this->getState('filter.state'); 191 192 if (is_numeric($state)) { 193 $query->where('a.state = ' . (int) $state); 194 } 195 196 // Filter over level. 197 $level = $this->getState('filter.level'); 198 199 if (is_numeric($level) && (int) $level === 1) { 200 $query->where('a.parent_id = 1'); 201 } 202 203 // Filter the maps over the branch if set. 204 $branchId = $this->getState('filter.branch'); 205 206 if (is_numeric($branchId)) { 207 $query->where('a.parent_id = ' . (int) $branchId); 208 } 209 210 // Filter the maps over the search string if set. 211 if ($search = $this->getState('filter.search')) { 212 $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); 213 $query->where('a.title LIKE ' . $search); 214 } 215 216 // Add the list ordering clause. 217 $query->order($db->escape($this->getState('list.ordering', 'branch_title, a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); 218 219 return $query; 220 } 221 222 /** 223 * Returns a record count for the query. 224 * 225 * @param \Joomla\Database\DatabaseQuery|string 226 * 227 * @return integer Number of rows for query. 228 * 229 * @since 3.0 230 */ 231 protected function _getListCount($query) 232 { 233 $query = clone $query; 234 $query->clear('select')->clear('join')->clear('order')->clear('limit')->clear('offset')->select('COUNT(*)'); 235 236 return (int) $this->getDatabase()->setQuery($query)->loadResult(); 237 } 238 239 /** 240 * Method to get a store id based on model configuration state. 241 * 242 * This is necessary because the model is used by the component and 243 * different modules that might need different sets of data or different 244 * ordering requirements. 245 * 246 * @param string $id A prefix for the store id. [optional] 247 * 248 * @return string A store id. 249 * 250 * @since 2.5 251 */ 252 protected function getStoreId($id = '') 253 { 254 // Compile the store id. 255 $id .= ':' . $this->getState('filter.search'); 256 $id .= ':' . $this->getState('filter.state'); 257 $id .= ':' . $this->getState('filter.branch'); 258 $id .= ':' . $this->getState('filter.level'); 259 260 return parent::getStoreId($id); 261 } 262 263 /** 264 * Returns a Table object, always creating it. 265 * 266 * @param string $type The table type to instantiate. [optional] 267 * @param string $prefix A prefix for the table class name. [optional] 268 * @param array $config Configuration array for model. [optional] 269 * 270 * @return \Joomla\CMS\Table\Table A database object 271 * 272 * @since 2.5 273 */ 274 public function getTable($type = 'Map', $prefix = 'Administrator', $config = array()) 275 { 276 return parent::getTable($type, $prefix, $config); 277 } 278 279 /** 280 * Method to auto-populate the model state. Calling getState in this method will result in recursion. 281 * 282 * @param string $ordering An optional ordering field. [optional] 283 * @param string $direction An optional direction. [optional] 284 * 285 * @return void 286 * 287 * @since 2.5 288 */ 289 protected function populateState($ordering = 'branch_title, a.lft', $direction = 'ASC') 290 { 291 // Load the filter state. 292 $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); 293 $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); 294 $this->setState('filter.branch', $this->getUserStateFromRequest($this->context . '.filter.branch', 'filter_branch', '', 'cmd')); 295 $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); 296 297 // Load the parameters. 298 $params = ComponentHelper::getParams('com_finder'); 299 $this->setState('params', $params); 300 301 // List state information. 302 parent::populateState($ordering, $direction); 303 } 304 305 /** 306 * Method to change the published state of one or more records. 307 * 308 * @param array $pks A list of the primary keys to change. 309 * @param integer $value The value of the published state. [optional] 310 * 311 * @return boolean True on success. 312 * 313 * @since 2.5 314 */ 315 public function publish(&$pks, $value = 1) 316 { 317 $user = Factory::getUser(); 318 $table = $this->getTable(); 319 $pks = (array) $pks; 320 321 // Include the content plugins for the change of state event. 322 PluginHelper::importPlugin('content'); 323 324 // Access checks. 325 foreach ($pks as $i => $pk) { 326 $table->reset(); 327 328 if ($table->load($pk) && !$this->canEditState($table)) { 329 // Prune items that you can't change. 330 unset($pks[$i]); 331 $this->setError(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); 332 333 return false; 334 } 335 } 336 337 // Attempt to change the state of the records. 338 if (!$table->publish($pks, $value, $user->get('id'))) { 339 $this->setError($table->getError()); 340 341 return false; 342 } 343 344 $context = $this->option . '.' . $this->name; 345 346 // Trigger the onContentChangeState event. 347 $result = Factory::getApplication()->triggerEvent('onContentChangeState', array($context, $pks, $value)); 348 349 if (in_array(false, $result, true)) { 350 $this->setError($table->getError()); 351 352 return false; 353 } 354 355 // Clear the component's cache 356 $this->cleanCache(); 357 358 return true; 359 } 360 361 /** 362 * Method to purge all maps from the taxonomy. 363 * 364 * @return boolean Returns true on success, false on failure. 365 * 366 * @since 2.5 367 */ 368 public function purge() 369 { 370 $db = $this->getDatabase(); 371 $query = $db->getQuery(true) 372 ->delete($db->quoteName('#__finder_taxonomy')) 373 ->where($db->quoteName('parent_id') . ' > 1'); 374 $db->setQuery($query); 375 $db->execute(); 376 377 $query->clear() 378 ->delete($db->quoteName('#__finder_taxonomy_map')); 379 $db->setQuery($query); 380 $db->execute(); 381 382 return true; 383 } 384 385 /** 386 * Manipulate the query to be used to evaluate if this is an Empty State to provide specific conditions for this extension. 387 * 388 * @return DatabaseQuery 389 * 390 * @since 4.0.0 391 */ 392 protected function getEmptyStateQuery() 393 { 394 $query = parent::getEmptyStateQuery(); 395 396 $title = 'ROOT'; 397 398 $query->where($this->getDatabase()->quoteName('title') . ' <> :title') 399 ->bind(':title', $title); 400 401 return $query; 402 } 403 }
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 |