[ 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_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 }
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 |