/administrator/components/com_users/models/group.php

https://bitbucket.org/eternaware/joomus · PHP · 245 lines · 123 code · 25 blank · 97 comment · 21 complexity · 0345295257e94811944b0cedfb3024c3 MD5 · raw file

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