[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/administrator/components/com_contenthistory/src/Model/ -> HistoryModel.php (source)

   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  }


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