[ 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_contenthistory 6 * 7 * @copyright (C) 2013 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\Contenthistory\Administrator\Model; 12 13 use Joomla\CMS\Access\Exception\NotAllowed; 14 use Joomla\CMS\Component\ComponentHelper; 15 use Joomla\CMS\Factory; 16 use Joomla\CMS\Helper\CMSHelper; 17 use Joomla\CMS\Language\Text; 18 use Joomla\CMS\Log\Log; 19 use Joomla\CMS\MVC\Factory\MVCFactoryInterface; 20 use Joomla\CMS\MVC\Model\ListModel; 21 use Joomla\CMS\Table\ContentHistory; 22 use Joomla\CMS\Table\ContentType; 23 use Joomla\CMS\Table\Table; 24 use Joomla\Database\ParameterType; 25 26 // phpcs:disable PSR1.Files.SideEffects 27 \defined('_JEXEC') or die; 28 // phpcs:enable PSR1.Files.SideEffects 29 30 /** 31 * Methods supporting a list of contenthistory records. 32 * 33 * @since 3.2 34 */ 35 class HistoryModel extends ListModel 36 { 37 /** 38 * Constructor. 39 * 40 * @param array $config An optional associative array of configuration settings. 41 * @param MVCFactoryInterface $factory The factory. 42 * 43 * @see \Joomla\CMS\MVC\Model\BaseDatabaseModel 44 * @since 3.2 45 */ 46 public function __construct($config = array(), MVCFactoryInterface $factory = null) 47 { 48 if (empty($config['filter_fields'])) { 49 $config['filter_fields'] = array( 50 'version_id', 51 'h.version_id', 52 'version_note', 53 'h.version_note', 54 'save_date', 55 'h.save_date', 56 'editor_user_id', 57 'h.editor_user_id', 58 ); 59 } 60 61 parent::__construct($config, $factory); 62 } 63 64 /** 65 * Method to test whether a record is editable 66 * 67 * @param ContentHistory $record A Table object. 68 * 69 * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. 70 * 71 * @since 3.2 72 */ 73 protected function canEdit($record) 74 { 75 if (empty($record->item_id)) { 76 return false; 77 } 78 79 /** 80 * Make sure user has edit privileges for this content item. Note that we use edit permissions 81 * for the content item, not delete permissions for the content history row. 82 */ 83 $user = Factory::getUser(); 84 85 if ($user->authorise('core.edit', $record->item_id)) { 86 return true; 87 } 88 89 // Finally try session (this catches edit.own case too) 90 /** @var ContentType $contentTypeTable */ 91 $contentTypeTable = $this->getTable('ContentType'); 92 93 $typeAlias = explode('.', $record->item_id); 94 $id = array_pop($typeAlias); 95 $typeAlias = implode('.', $typeAlias); 96 $contentTypeTable->load(array('type_alias' => $typeAlias)); 97 $typeEditables = (array) Factory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); 98 $result = in_array((int) $id, $typeEditables); 99 100 return $result; 101 } 102 103 /** 104 * Method to test whether a history record can be deleted. Note that we check whether we have edit permissions 105 * for the content item row. 106 * 107 * @param ContentHistory $record A Table object. 108 * 109 * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. 110 * 111 * @since 3.6 112 */ 113 protected function canDelete($record) 114 { 115 return $this->canEdit($record); 116 } 117 118 /** 119 * Method to delete one or more records from content history table. 120 * 121 * @param array $pks An array of record primary keys. 122 * 123 * @return boolean True if successful, false if an error occurs. 124 * 125 * @since 3.2 126 */ 127 public function delete(&$pks) 128 { 129 $pks = (array) $pks; 130 $table = $this->getTable(); 131 132 // Iterate the items to delete each one. 133 foreach ($pks as $i => $pk) { 134 if ($table->load($pk)) { 135 if ((int) $table->keep_forever === 1) { 136 unset($pks[$i]); 137 continue; 138 } 139 140 if ($this->canEdit($table)) { 141 if (!$table->delete($pk)) { 142 $this->setError($table->getError()); 143 144 return false; 145 } 146 } else { 147 // Prune items that you can't change. 148 unset($pks[$i]); 149 $error = $this->getError(); 150 151 if ($error) { 152 try { 153 Log::add($error, Log::WARNING, 'jerror'); 154 } catch (\RuntimeException $exception) { 155 Factory::getApplication()->enqueueMessage($error, 'warning'); 156 } 157 158 return false; 159 } else { 160 try { 161 Log::add(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), Log::WARNING, 'jerror'); 162 } catch (\RuntimeException $exception) { 163 Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 'warning'); 164 } 165 166 return false; 167 } 168 } 169 } else { 170 $this->setError($table->getError()); 171 172 return false; 173 } 174 } 175 176 // Clear the component's cache 177 $this->cleanCache(); 178 179 return true; 180 } 181 182 /** 183 * Method to get an array of data items. 184 * 185 * @return mixed An array of data items on success, false on failure. 186 * 187 * @since 3.4.5 188 * 189 * @throws NotAllowed Thrown if not authorised to edit an item 190 */ 191 public function getItems() 192 { 193 $items = parent::getItems(); 194 $user = Factory::getUser(); 195 196 if ($items === false) { 197 return false; 198 } 199 200 // This should be an array with at least one element 201 if (!is_array($items) || !isset($items[0])) { 202 return $items; 203 } 204 205 // Access check 206 if (!$user->authorise('core.edit', $items[0]->item_id) && !$this->canEdit($items[0])) { 207 throw new NotAllowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); 208 } 209 210 return $items; 211 } 212 213 /** 214 * Method to get a table object, load it if necessary. 215 * 216 * @param string $type The table name. Optional. 217 * @param string $prefix The class prefix. Optional. 218 * @param array $config Configuration array for model. Optional. 219 * 220 * @return Table A Table object 221 * 222 * @since 3.2 223 */ 224 public function getTable($type = 'ContentHistory', $prefix = 'Joomla\\CMS\\Table\\', $config = array()) 225 { 226 return Table::getInstance($type, $prefix, $config); 227 } 228 /** 229 * Method to toggle on and off the keep forever value for one or more records from content history table. 230 * 231 * @param array $pks An array of record primary keys. 232 * 233 * @return boolean True if successful, false if an error occurs. 234 * 235 * @since 3.2 236 */ 237 public function keep(&$pks) 238 { 239 $pks = (array) $pks; 240 $table = $this->getTable(); 241 242 // Iterate the items to delete each one. 243 foreach ($pks as $i => $pk) { 244 if ($table->load($pk)) { 245 if ($this->canEdit($table)) { 246 $table->keep_forever = $table->keep_forever ? 0 : 1; 247 248 if (!$table->store()) { 249 $this->setError($table->getError()); 250 251 return false; 252 } 253 } else { 254 // Prune items that you can't change. 255 unset($pks[$i]); 256 $error = $this->getError(); 257 258 if ($error) { 259 try { 260 Log::add($error, Log::WARNING, 'jerror'); 261 } catch (\RuntimeException $exception) { 262 Factory::getApplication()->enqueueMessage($error, 'warning'); 263 } 264 265 return false; 266 } else { 267 try { 268 Log::add(Text::_('COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED'), Log::WARNING, 'jerror'); 269 } catch (\RuntimeException $exception) { 270 Factory::getApplication()->enqueueMessage(Text::_('COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED'), 'warning'); 271 } 272 273 return false; 274 } 275 } 276 } else { 277 $this->setError($table->getError()); 278 279 return false; 280 } 281 } 282 283 // Clear the component's cache 284 $this->cleanCache(); 285 286 return true; 287 } 288 289 /** 290 * Method to auto-populate the model state. 291 * 292 * Note. Calling getState in this method will result in recursion. 293 * 294 * @param string $ordering An optional ordering field. 295 * @param string $direction An optional direction (asc|desc). 296 * 297 * @return void 298 * 299 * @since 3.2 300 */ 301 protected function populateState($ordering = 'h.save_date', $direction = 'DESC') 302 { 303 $input = Factory::getApplication()->input; 304 $itemId = $input->get('item_id', '', 'string'); 305 306 $this->setState('item_id', $itemId); 307 $this->setState('sha1_hash', $this->getSha1Hash()); 308 309 // Load the parameters. 310 $params = ComponentHelper::getParams('com_contenthistory'); 311 $this->setState('params', $params); 312 313 // List state information. 314 parent::populateState($ordering, $direction); 315 } 316 317 /** 318 * Build an SQL query to load the list data. 319 * 320 * @return \Joomla\Database\DatabaseQuery 321 * 322 * @since 3.2 323 */ 324 protected function getListQuery() 325 { 326 // Create a new query object. 327 $db = $this->getDatabase(); 328 $query = $db->getQuery(true); 329 $itemId = $this->getState('item_id'); 330 331 // Select the required fields from the table. 332 $query->select( 333 $this->getState( 334 'list.select', 335 [ 336 $db->quoteName('h.version_id'), 337 $db->quoteName('h.item_id'), 338 $db->quoteName('h.version_note'), 339 $db->quoteName('h.save_date'), 340 $db->quoteName('h.editor_user_id'), 341 $db->quoteName('h.character_count'), 342 $db->quoteName('h.sha1_hash'), 343 $db->quoteName('h.version_data'), 344 $db->quoteName('h.keep_forever'), 345 ] 346 ) 347 ) 348 ->from($db->quoteName('#__history', 'h')) 349 ->where($db->quoteName('h.item_id') . ' = :itemid') 350 ->bind(':itemid', $itemId, ParameterType::STRING) 351 352 // Join over the users for the editor 353 ->select($db->quoteName('uc.name', 'editor')) 354 ->join( 355 'LEFT', 356 $db->quoteName('#__users', 'uc'), 357 $db->quoteName('uc.id') . ' = ' . $db->quoteName('h.editor_user_id') 358 ); 359 360 // Add the list ordering clause. 361 $orderCol = $this->state->get('list.ordering'); 362 $orderDirn = $this->state->get('list.direction'); 363 $query->order($db->quoteName($orderCol) . $orderDirn); 364 365 return $query; 366 } 367 368 /** 369 * Get the sha1 hash value for the current item being edited. 370 * 371 * @return string sha1 hash of row data 372 * 373 * @since 3.2 374 */ 375 protected function getSha1Hash() 376 { 377 $result = false; 378 $item_id = Factory::getApplication()->input->getCmd('item_id', ''); 379 $typeAlias = explode('.', $item_id); 380 Table::addIncludePath(JPATH_ADMINISTRATOR . '/components/' . $typeAlias[0] . '/tables'); 381 $typeTable = $this->getTable('ContentType'); 382 $typeTable->load(['type_alias' => $typeAlias[0] . '.' . $typeAlias[1]]); 383 $contentTable = $typeTable->getContentTable(); 384 385 if ($contentTable && $contentTable->load($typeAlias[2])) { 386 $helper = new CMSHelper(); 387 388 $dataObject = $helper->getDataObject($contentTable); 389 $result = $this->getTable('ContentHistory')->getSha1(json_encode($dataObject), $typeTable); 390 } 391 392 return $result; 393 } 394 }
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 |