/administrator/components/com_users/models/group.php
PHP | 245 lines | 123 code | 25 blank | 97 comment | 21 complexity | 0345295257e94811944b0cedfb3024c3 MD5 | raw file
Possible License(s): LGPL-2.1
1<?php 2/** 3 * @package Joomla.Administrator 4 * @subpackage com_users 5 * 6 * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved. 7 * @license GNU General Public License version 2 or later; see LICENSE.txt 8 */ 9 10defined('_JEXEC') or die; 11 12/** 13 * User group model. 14 * 15 * @package Joomla.Administrator 16 * @subpackage com_users 17 * @since 1.6 18 */ 19class UsersModelGroup extends JModelAdmin 20{ 21 /** 22 * @var string The event to trigger after saving the data. 23 * @since 1.6 24 */ 25 protected $event_after_save = 'onUserAfterSaveGroup'; 26 27 /** 28 * @var string The event to trigger after before the data. 29 * @since 1.6 30 */ 31 protected $event_before_save = 'onUserBeforeSaveGroup'; 32 33 /** 34 * Returns a reference to the a Table object, always creating it. 35 * 36 * @param type The table type to instantiate 37 * @param string A prefix for the table class name. Optional. 38 * @param array Configuration array for model. Optional. 39 * @return JTable A database object 40 * @since 1.6 41 */ 42 public function getTable($type = 'Usergroup', $prefix = 'JTable', $config = array()) 43 { 44 $return = JTable::getInstance($type, $prefix, $config); 45 return $return; 46 } 47 48 /** 49 * Method to get the record form. 50 * 51 * @param array $data An optional array of data for the form to interogate. 52 * @param boolean $loadData True if the form is to load its own data (default case), false if not. 53 * @return JForm A JForm object on success, false on failure 54 * @since 1.6 55 */ 56 public function getForm($data = array(), $loadData = true) 57 { 58 $app = JFactory::getApplication(); 59 60 // Get the form. 61 $form = $this->loadForm('com_users.group', 'group', array('control' => 'jform', 'load_data' => $loadData)); 62 if (empty($form)) { 63 return false; 64 } 65 66 return $form; 67 } 68 69 /** 70 * Method to get the data that should be injected in the form. 71 * 72 * @return mixed The data for the form. 73 * @since 1.6 74 */ 75 protected function loadFormData() 76 { 77 // Check the session for previously entered form data. 78 $data = JFactory::getApplication()->getUserState('com_users.edit.group.data', array()); 79 80 if (empty($data)) { 81 $data = $this->getItem(); 82 } 83 84 return $data; 85 } 86 87 /** 88 * Override preprocessForm to load the user plugin group instead of content. 89 * 90 * @param object A form object. 91 * @param mixed The data expected for the form. 92 * @throws Exception if there is an error in the form event. 93 * @since 1.6 94 */ 95 protected function preprocessForm(JForm $form, $data, $groups = '') 96 { 97 $obj = is_array($data) ? JArrayHelper::toObject($data, 'JObject') : $data; 98 if (isset($obj->parent_id) && $obj->parent_id == 0 && $obj->id > 0) { 99 $form->setFieldAttribute('parent_id', 'type', 'hidden'); 100 $form->setFieldAttribute('parent_id', 'hidden', 'true'); 101 } 102 parent::preprocessForm($form, $data, 'user'); 103 } 104 105 /** 106 * Method to save the form data. 107 * 108 * @param array The form data. 109 * @return boolean True on success. 110 * @since 1.6 111 */ 112 public function save($data) 113 { 114 // Include the content plugins for events. 115 JPluginHelper::importPlugin('user'); 116 117 // Check the super admin permissions for group 118 // We get the parent group permissions and then check the group permissions manually 119 // We have to calculate the group permissions manually because we haven't saved the group yet 120 $parentSuperAdmin = JAccess::checkGroup($data['parent_id'], 'core.admin'); 121 // Get core.admin rules from the root asset 122 $rules = JAccess::getAssetRules('root.1')->getData('core.admin'); 123 // Get the value for the current group (will be true (allowed), false (denied), or null (inherit) 124 $groupSuperAdmin = $rules['core.admin']->allow($data['id']); 125 126 // We only need to change the $groupSuperAdmin if the parent is true or false. Otherwise, the value set in the rule takes effect. 127 if ($parentSuperAdmin === false) { 128 // If parent is false (Denied), effective value will always be false 129 $groupSuperAdmin = false; 130 } 131 elseif ($parentSuperAdmin === true) { 132 // If parent is true (allowed), group is true unless explicitly set to false 133 $groupSuperAdmin = ($groupSuperAdmin === false) ? false : true; 134 } 135 136 // Check for non-super admin trying to save with super admin group 137 $iAmSuperAdmin = JFactory::getUser()->authorise('core.admin'); 138 if ((!$iAmSuperAdmin) && ($groupSuperAdmin)) { 139 try 140 { 141 throw new Exception(JText::_('JLIB_USER_ERROR_NOT_SUPERADMIN')); 142 } 143 catch (Exception $e) 144 { 145 $this->setError($e->getMessage()); 146 return false; 147 } 148 } 149 150 // Check for super-admin changing self to be non-super-admin 151 // First, are we a super admin> 152 if ($iAmSuperAdmin) { 153 // Next, are we a member of the current group? 154 $myGroups = JAccess::getGroupsByUser(JFactory::getUser()->get('id'), false); 155 if (in_array($data['id'], $myGroups)) { 156 // Now, would we have super admin permissions without the current group? 157 $otherGroups = array_diff($myGroups, array($data['id'])); 158 $otherSuperAdmin = false; 159 foreach ($otherGroups as $otherGroup) { 160 $otherSuperAdmin = ($otherSuperAdmin) ? $otherSuperAdmin : JAccess::checkGroup($otherGroup, 'core.admin'); 161 } 162 // If we would not otherwise have super admin permissions 163 // and the current group does not have super admin permissions, throw an exception 164 if ((!$otherSuperAdmin) && (!$groupSuperAdmin)) { 165 try 166 { 167 throw new Exception(JText::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF')); 168 } 169 catch (Exception $e) 170 { 171 $this->setError($e->getMessage()); 172 return false; 173 } 174 } 175 } 176 } 177 178 // Proceed with the save 179 return parent::save($data); 180 } 181 182 /** 183 * Method to delete rows. 184 * 185 * @param array An array of item ids. 186 * @return boolean Returns true on success, false on failure. 187 * @since 1.6 188 */ 189 public function delete(&$pks) 190 { 191 // Typecast variable. 192 $pks = (array) $pks; 193 $user = JFactory::getUser(); 194 $groups = JAccess::getGroupsByUser($user->get('id')); 195 196 // Get a row instance. 197 $table = $this->getTable(); 198 199 // Load plugins. 200 JPluginHelper::importPlugin('user'); 201 $dispatcher = JEventDispatcher::getInstance(); 202 203 // Check if I am a Super Admin 204 $iAmSuperAdmin = $user->authorise('core.admin'); 205 206 // do not allow to delete groups to which the current user belongs 207 foreach ($pks as $i => $pk) { 208 if (in_array($pk, $groups)) { 209 JError::raiseWarning(403, JText::_('COM_USERS_DELETE_ERROR_INVALID_GROUP')); 210 return false; 211 } 212 } 213 // Iterate the items to delete each one. 214 foreach ($pks as $i => $pk) { 215 if ($table->load($pk)) { 216 // Access checks. 217 $allow = $user->authorise('core.edit.state', 'com_users'); 218 // Don't allow non-super-admin to delete a super admin 219 $allow = (!$iAmSuperAdmin && JAccess::checkGroup($pk, 'core.admin')) ? false : $allow; 220 221 if ($allow) { 222 // Fire the onUserBeforeDeleteGroup event. 223 $dispatcher->trigger('onUserBeforeDeleteGroup', array($table->getProperties())); 224 225 if (!$table->delete($pk)) { 226 $this->setError($table->getError()); 227 return false; 228 } else { 229 // Trigger the onUserAfterDeleteGroup event. 230 $dispatcher->trigger('onUserAfterDeleteGroup', array($table->getProperties(), true, $this->getError())); 231 } 232 } else { 233 // Prune items that you can't change. 234 unset($pks[$i]); 235 JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); 236 } 237 } else { 238 $this->setError($table->getError()); 239 return false; 240 } 241 } 242 243 return true; 244 } 245}