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

262 lines
7.4 KiB
PHP
Raw Permalink Normal View History

2020-01-02 22:20:31 +07:00
<?php
/**
* @package Joomla.Administrator
* @subpackage com_users
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* User group model.
*
* @package Joomla.Administrator
* @subpackage com_users
* @since 1.6
*/
class UsersModelGroup extends JModelAdmin
{
/**
* @var string The event to trigger after saving the data.
* @since 1.6
*/
protected $event_after_save = 'onUserAfterSaveGroup';
/**
* @var string The event to trigger after before the data.
* @since 1.6
*/
protected $event_before_save = 'onUserBeforeSaveGroup';
/**
* Returns a reference to the a Table object, always creating it.
*
* @param type The table type to instantiate
* @param string A prefix for the table class name. Optional.
* @param array Configuration array for model. Optional.
* @return JTable A database object
* @since 1.6
*/
public function getTable($type = 'Usergroup', $prefix = 'JTable', $config = array())
{
$return = JTable::getInstance($type, $prefix, $config);
return $return;
}
/**
* Method to get the record form.
*
* @param array $data An optional array of data for the form to interogate.
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
* @return JForm A JForm object on success, false on failure
* @since 1.6
*/
public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_users.group', 'group', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form))
{
return false;
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return mixed The data for the form.
* @since 1.6
*/
protected function loadFormData()
{
// Check the session for previously entered form data.
$data = JFactory::getApplication()->getUserState('com_users.edit.group.data', array());
if (empty($data))
{
$data = $this->getItem();
}
$this->preprocessData('com_users.group', $data);
return $data;
}
/**
* Override preprocessForm to load the user plugin group instead of content.
*
* @param object A form object.
* @param mixed The data expected for the form.
* @throws Exception if there is an error in the form event.
* @since 1.6
*/
protected function preprocessForm(JForm $form, $data, $groups = '')
{
$obj = is_array($data) ? JArrayHelper::toObject($data, 'JObject') : $data;
if (isset($obj->parent_id) && $obj->parent_id == 0 && $obj->id > 0)
{
$form->setFieldAttribute('parent_id', 'type', 'hidden');
$form->setFieldAttribute('parent_id', 'hidden', 'true');
}
parent::preprocessForm($form, $data, 'user');
}
/**
* Method to save the form data.
*
* @param array The form data.
* @return boolean True on success.
* @since 1.6
*/
public function save($data)
{
// Include the content plugins for events.
JPluginHelper::importPlugin('user');
// Check the super admin permissions for group
// We get the parent group permissions and then check the group permissions manually
// We have to calculate the group permissions manually because we haven't saved the group yet
$parentSuperAdmin = JAccess::checkGroup($data['parent_id'], 'core.admin');
// Get core.admin rules from the root asset
$rules = JAccess::getAssetRules('root.1')->getData('core.admin');
// Get the value for the current group (will be true (allowed), false (denied), or null (inherit)
$groupSuperAdmin = $rules['core.admin']->allow($data['id']);
// We only need to change the $groupSuperAdmin if the parent is true or false. Otherwise, the value set in the rule takes effect.
if ($parentSuperAdmin === false)
{
// If parent is false (Denied), effective value will always be false
$groupSuperAdmin = false;
}
elseif ($parentSuperAdmin === true)
{
// If parent is true (allowed), group is true unless explicitly set to false
$groupSuperAdmin = ($groupSuperAdmin === false) ? false : true;
}
// Check for non-super admin trying to save with super admin group
$iAmSuperAdmin = JFactory::getUser()->authorise('core.admin');
if ((!$iAmSuperAdmin) && ($groupSuperAdmin))
{
try
{
throw new Exception(JText::_('JLIB_USER_ERROR_NOT_SUPERADMIN'));
}
catch (Exception $e)
{
$this->setError($e->getMessage());
return false;
}
}
// Check for super-admin changing self to be non-super-admin
// First, are we a super admin>
if ($iAmSuperAdmin)
{
// Next, are we a member of the current group?
$myGroups = JAccess::getGroupsByUser(JFactory::getUser()->get('id'), false);
if (in_array($data['id'], $myGroups))
{
// Now, would we have super admin permissions without the current group?
$otherGroups = array_diff($myGroups, array($data['id']));
$otherSuperAdmin = false;
foreach ($otherGroups as $otherGroup)
{
$otherSuperAdmin = ($otherSuperAdmin) ? $otherSuperAdmin : JAccess::checkGroup($otherGroup, 'core.admin');
}
// If we would not otherwise have super admin permissions
// and the current group does not have super admin permissions, throw an exception
if ((!$otherSuperAdmin) && (!$groupSuperAdmin))
{
try
{
throw new Exception(JText::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF'));
}
catch (Exception $e)
{
$this->setError($e->getMessage());
return false;
}
}
}
}
// Proceed with the save
return parent::save($data);
}
/**
* Method to delete rows.
*
* @param array An array of item ids.
* @return boolean Returns true on success, false on failure.
* @since 1.6
*/
public function delete(&$pks)
{
// Typecast variable.
$pks = (array) $pks;
$user = JFactory::getUser();
$groups = JAccess::getGroupsByUser($user->get('id'));
// Get a row instance.
$table = $this->getTable();
// Load plugins.
JPluginHelper::importPlugin('user');
$dispatcher = JEventDispatcher::getInstance();
// Check if I am a Super Admin
$iAmSuperAdmin = $user->authorise('core.admin');
// do not allow to delete groups to which the current user belongs
foreach ($pks as $pk)
{
if (in_array($pk, $groups))
{
JError::raiseWarning(403, JText::_('COM_USERS_DELETE_ERROR_INVALID_GROUP'));
return false;
}
}
// Iterate the items to delete each one.
foreach ($pks as $i => $pk)
{
if ($table->load($pk))
{
// Access checks.
$allow = $user->authorise('core.edit.state', 'com_users');
// Don't allow non-super-admin to delete a super admin
$allow = (!$iAmSuperAdmin && JAccess::checkGroup($pk, 'core.admin')) ? false : $allow;
if ($allow)
{
// Fire the onUserBeforeDeleteGroup event.
$dispatcher->trigger('onUserBeforeDeleteGroup', array($table->getProperties()));
if (!$table->delete($pk))
{
$this->setError($table->getError());
return false;
} else {
// Trigger the onUserAfterDeleteGroup event.
$dispatcher->trigger('onUserAfterDeleteGroup', array($table->getProperties(), true, $this->getError()));
}
} else {
// Prune items that you can't change.
unset($pks[$i]);
JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED'));
}
} else {
$this->setError($table->getError());
return false;
}
}
return true;
}
}