[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/administrator/components/com_users/src/Model/ -> GroupModel.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Administrator
   5   * @subpackage  com_users
   6   *
   7   * @copyright   (C) 2009 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\Users\Administrator\Model;
  12  
  13  use Joomla\CMS\Access\Access;
  14  use Joomla\CMS\Factory;
  15  use Joomla\CMS\Form\Form;
  16  use Joomla\CMS\Language\Text;
  17  use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
  18  use Joomla\CMS\MVC\Model\AdminModel;
  19  use Joomla\CMS\Object\CMSObject;
  20  use Joomla\CMS\Plugin\PluginHelper;
  21  use Joomla\CMS\Table\Table;
  22  use Joomla\String\StringHelper;
  23  use Joomla\Utilities\ArrayHelper;
  24  
  25  // phpcs:disable PSR1.Files.SideEffects
  26  \defined('_JEXEC') or die;
  27  // phpcs:enable PSR1.Files.SideEffects
  28  
  29  /**
  30   * User group model.
  31   *
  32   * @since  1.6
  33   */
  34  class GroupModel extends AdminModel
  35  {
  36      /**
  37       * Override parent constructor.
  38       *
  39       * @param   array                $config   An optional associative array of configuration settings.
  40       * @param   MVCFactoryInterface  $factory  The factory.
  41       *
  42       * @see     \Joomla\CMS\MVC\Model\BaseDatabaseModel
  43       * @since   3.2
  44       */
  45      public function __construct($config = array(), MVCFactoryInterface $factory = null)
  46      {
  47          $config = array_merge(
  48              array(
  49                  'event_after_delete'  => 'onUserAfterDeleteGroup',
  50                  'event_after_save'    => 'onUserAfterSaveGroup',
  51                  'event_before_delete' => 'onUserBeforeDeleteGroup',
  52                  'event_before_save'   => 'onUserBeforeSaveGroup',
  53                  'events_map'          => array('delete' => 'user', 'save' => 'user')
  54              ),
  55              $config
  56          );
  57  
  58          parent::__construct($config, $factory);
  59      }
  60  
  61      /**
  62       * Returns a reference to the a Table object, always creating it.
  63       *
  64       * @param   string  $type    The table type to instantiate
  65       * @param   string  $prefix  A prefix for the table class name. Optional.
  66       * @param   array   $config  Configuration array for model. Optional.
  67       *
  68       * @return  Table   A database object
  69       *
  70       * @since   1.6
  71       */
  72      public function getTable($type = 'Usergroup', $prefix = 'Joomla\\CMS\\Table\\', $config = array())
  73      {
  74          $return = Table::getInstance($type, $prefix, $config);
  75  
  76          return $return;
  77      }
  78  
  79      /**
  80       * Method to get the record form.
  81       *
  82       * @param   array    $data      An optional array of data for the form to interrogate.
  83       * @param   boolean  $loadData  True if the form is to load its own data (default case), false if not.
  84       *
  85       * @return  Form|bool  A Form object on success, false on failure
  86       *
  87       * @since   1.6
  88       */
  89      public function getForm($data = array(), $loadData = true)
  90      {
  91          // Get the form.
  92          $form = $this->loadForm('com_users.group', 'group', array('control' => 'jform', 'load_data' => $loadData));
  93  
  94          if (empty($form)) {
  95              return false;
  96          }
  97  
  98          return $form;
  99      }
 100  
 101      /**
 102       * Method to get the data that should be injected in the form.
 103       *
 104       * @return  mixed  The data for the form.
 105       *
 106       * @since   1.6
 107       * @throws  \Exception
 108       */
 109      protected function loadFormData()
 110      {
 111          // Check the session for previously entered form data.
 112          $data = Factory::getApplication()->getUserState('com_users.edit.group.data', array());
 113  
 114          if (empty($data)) {
 115              $data = $this->getItem();
 116          }
 117  
 118          $this->preprocessData('com_users.group', $data);
 119  
 120          return $data;
 121      }
 122  
 123      /**
 124       * Override preprocessForm to load the user plugin group instead of content.
 125       *
 126       * @param   Form    $form   A form object.
 127       * @param   mixed   $data   The data expected for the form.
 128       * @param   string  $group  The name of the plugin group to import (defaults to "content").
 129       *
 130       * @return  void
 131       *
 132       * @since   1.6
 133       * @throws  \Exception if there is an error loading the form.
 134       */
 135      protected function preprocessForm(Form $form, $data, $group = '')
 136      {
 137          $obj = is_array($data) ? ArrayHelper::toObject($data, CMSObject::class) : $data;
 138  
 139          if (isset($obj->parent_id) && $obj->parent_id == 0 && $obj->id > 0) {
 140              $form->setFieldAttribute('parent_id', 'type', 'hidden');
 141              $form->setFieldAttribute('parent_id', 'hidden', 'true');
 142          }
 143  
 144          parent::preprocessForm($form, $data, 'user');
 145      }
 146  
 147      /**
 148       * Method to save the form data.
 149       *
 150       * @param   array  $data  The form data.
 151       *
 152       * @return  boolean  True on success.
 153       *
 154       * @since   1.6
 155       */
 156      public function save($data)
 157      {
 158          // Include the user plugins for events.
 159          PluginHelper::importPlugin($this->events_map['save']);
 160  
 161          /**
 162           * Check the super admin permissions for group
 163           * We get the parent group permissions and then check the group permissions manually
 164           * We have to calculate the group permissions manually because we haven't saved the group yet
 165           */
 166          $parentSuperAdmin = Access::checkGroup($data['parent_id'], 'core.admin');
 167  
 168          // Get core.admin rules from the root asset
 169          $rules = Access::getAssetRules('root.1')->getData('core.admin');
 170  
 171          // Get the value for the current group (will be true (allowed), false (denied), or null (inherit)
 172          $groupSuperAdmin = $rules['core.admin']->allow($data['id']);
 173  
 174          // We only need to change the $groupSuperAdmin if the parent is true or false. Otherwise, the value set in the rule takes effect.
 175          if ($parentSuperAdmin === false) {
 176              // If parent is false (Denied), effective value will always be false
 177              $groupSuperAdmin = false;
 178          } elseif ($parentSuperAdmin === true) {
 179              // If parent is true (allowed), group is true unless explicitly set to false
 180              $groupSuperAdmin = ($groupSuperAdmin === false) ? false : true;
 181          }
 182  
 183          // Check for non-super admin trying to save with super admin group
 184          $iAmSuperAdmin = Factory::getUser()->authorise('core.admin');
 185  
 186          if (!$iAmSuperAdmin && $groupSuperAdmin) {
 187              $this->setError(Text::_('JLIB_USER_ERROR_NOT_SUPERADMIN'));
 188  
 189              return false;
 190          }
 191  
 192          /**
 193           * Check for super-admin changing self to be non-super-admin
 194           * First, are we a super admin
 195           */
 196          if ($iAmSuperAdmin) {
 197              // Next, are we a member of the current group?
 198              $myGroups = Access::getGroupsByUser(Factory::getUser()->get('id'), false);
 199  
 200              if (in_array($data['id'], $myGroups)) {
 201                  // Now, would we have super admin permissions without the current group?
 202                  $otherGroups = array_diff($myGroups, array($data['id']));
 203                  $otherSuperAdmin = false;
 204  
 205                  foreach ($otherGroups as $otherGroup) {
 206                      $otherSuperAdmin = $otherSuperAdmin ?: Access::checkGroup($otherGroup, 'core.admin');
 207                  }
 208  
 209                  /**
 210                   * If we would not otherwise have super admin permissions
 211                   * and the current group does not have super admin permissions, throw an exception
 212                   */
 213                  if ((!$otherSuperAdmin) && (!$groupSuperAdmin)) {
 214                      $this->setError(Text::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF'));
 215  
 216                      return false;
 217                  }
 218              }
 219          }
 220  
 221          if (Factory::getApplication()->input->get('task') == 'save2copy') {
 222              $data['title'] = $this->generateGroupTitle($data['parent_id'], $data['title']);
 223          }
 224  
 225          // Proceed with the save
 226          return parent::save($data);
 227      }
 228  
 229      /**
 230       * Method to delete rows.
 231       *
 232       * @param   array  &$pks  An array of item ids.
 233       *
 234       * @return  boolean  Returns true on success, false on failure.
 235       *
 236       * @since   1.6
 237       * @throws  \Exception
 238       */
 239      public function delete(&$pks)
 240      {
 241          // Typecast variable.
 242          $pks    = (array) $pks;
 243          $user   = Factory::getUser();
 244          $groups = Access::getGroupsByUser($user->get('id'));
 245  
 246          // Get a row instance.
 247          $table = $this->getTable();
 248  
 249          // Load plugins.
 250          PluginHelper::importPlugin($this->events_map['delete']);
 251  
 252          // Check if I am a Super Admin
 253          $iAmSuperAdmin = $user->authorise('core.admin');
 254  
 255          foreach ($pks as $pk) {
 256              // Do not allow to delete groups to which the current user belongs
 257              if (in_array($pk, $groups)) {
 258                  Factory::getApplication()->enqueueMessage(Text::_('COM_USERS_DELETE_ERROR_INVALID_GROUP'), 'error');
 259  
 260                  return false;
 261              } elseif (!$table->load($pk)) {
 262                  // Item is not in the table.
 263                  $this->setError($table->getError());
 264  
 265                  return false;
 266              }
 267          }
 268  
 269          // Iterate the items to delete each one.
 270          foreach ($pks as $i => $pk) {
 271              if ($table->load($pk)) {
 272                  // Access checks.
 273                  $allow = $user->authorise('core.edit.state', 'com_users');
 274  
 275                  // Don't allow non-super-admin to delete a super admin
 276                  $allow = (!$iAmSuperAdmin && Access::checkGroup($pk, 'core.admin')) ? false : $allow;
 277  
 278                  if ($allow) {
 279                      // Fire the before delete event.
 280                      Factory::getApplication()->triggerEvent($this->event_before_delete, array($table->getProperties()));
 281  
 282                      if (!$table->delete($pk)) {
 283                          $this->setError($table->getError());
 284  
 285                          return false;
 286                      } else {
 287                          // Trigger the after delete event.
 288                          Factory::getApplication()->triggerEvent($this->event_after_delete, array($table->getProperties(), true, $this->getError()));
 289                      }
 290                  } else {
 291                      // Prune items that you can't change.
 292                      unset($pks[$i]);
 293                      Factory::getApplication()->enqueueMessage(Text::_('JERROR_CORE_DELETE_NOT_PERMITTED'), 'error');
 294                  }
 295              }
 296          }
 297  
 298          return true;
 299      }
 300  
 301      /**
 302       * Method to generate the title of group on Save as Copy action
 303       *
 304       * @param   integer  $parentId  The id of the parent.
 305       * @param   string   $title     The title of group
 306       *
 307       * @return  string  Contains the modified title.
 308       *
 309       * @since   3.3.7
 310       */
 311      protected function generateGroupTitle($parentId, $title)
 312      {
 313          // Alter the title & alias
 314          $table = $this->getTable();
 315  
 316          while ($table->load(array('title' => $title, 'parent_id' => $parentId))) {
 317              if ($title == $table->title) {
 318                  $title = StringHelper::increment($title);
 319              }
 320          }
 321  
 322          return $title;
 323      }
 324  }


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