Вход Регистрация
Файл: framework/security/PermissionCheckboxSetField.php
Строк: 399
<?php
/**
 * Shows a categorized list of available permissions (through {@link Permission::get_codes()}).
 * Permissions which are assigned to a given {@link Group} record
 * (either directly, inherited from parent groups, or through a {@link PermissionRole})
 * will be checked automatically. All checkboxes for "inherited" permissions will be readonly.
 *
 * The field can gets its assignment data either from {@link Group} or {@link PermissionRole} records.
 *
 * @package framework
 * @subpackage security
 */
class PermissionCheckboxSetField extends FormField {

    
/**
     * @var Array Filter certain permission codes from the output.
     * Useful to simplify the interface
     */
    
protected $hiddenPermissions = array();

    
/**
     * @var SS_List
     */
    
protected $records null;

    
/**
     * @var array Array Nested array in same notation as {@link CheckboxSetField}.
     */
    
protected $source null;

    
/**
     * @param String $name
     * @param String $title
     * @param String $managedClass
     * @param String $filterField
     * @param Group|SS_List $records One or more {@link Group} or {@link PermissionRole} records
     *  used to determine permission checkboxes.
     *  Caution: saveInto() can only be used with a single record, all inherited permissions will be marked readonly.
     *  Setting multiple groups only makes sense in a readonly context. (Optional)
     */
    
public function __construct($name$title$managedClass$filterField$records null) {
        
$this->filterField $filterField;
        
$this->managedClass $managedClass;

        if(
$records instanceof SS_List) {
            
$this->records $records;
        } elseif(
$records instanceof Group) {
            
$this->records = new ArrayList(array($records));
        } elseif(
$records) {
            throw new 
InvalidArgumentException(
                
'$record should be either a Group record, or a SS_List of Group records');
        }

        
// Get all available codes in the system as a categorized nested array
        
$this->source Permission::get_codes(true);

        
parent::__construct($name$title);
    }

    
/**
     * @param Array $codes
     */
    
public function setHiddenPermissions($codes) {
        
$this->hiddenPermissions $codes;
    }

    
/**
     * @return Array
     */
    
public function getHiddenPermissions() {
        return 
$this->hiddenPermissions;
    }

    
/**
     * @param array $properties
     * @return HTMLText
     */
    
public function Field($properties = array()) {
        
Requirements::css(FRAMEWORK_DIR '/css/CheckboxSetField.css');
        
Requirements::javascript(FRAMEWORK_DIR '/javascript/PermissionCheckboxSetField.js');

        
$uninheritedCodes = array();
        
$inheritedCodes = array();
        
$records = ($this->records) ? $this->records : new ArrayList();

        
// Get existing values from the form record (assuming the formfield name is a join field on the record)
        
if(is_object($this->form)) {
            
$record $this->form->getRecord();
            if(
                
$record
                
&& (is_a($record'Group') || is_a($record'PermissionRole'))
                && !
$records->find('ID'$record->ID)
            ) {
                
$records->push($record);
            }
        }

        
// Get all 'inherited' codes not directly assigned to the group (which is stored in $values)
        
foreach($records as $record) {
            
// Get all uninherited permissions
            
$relationMethod $this->name;
            foreach(
$record->$relationMethod() as $permission) {
                if(!isset(
$uninheritedCodes[$permission->Code])) $uninheritedCodes[$permission->Code] = array();
                
$uninheritedCodes[$permission->Code][] = _t(
                    
'PermissionCheckboxSetField.AssignedTo''assigned to "{title}"',
                    array(
'title' => $record->dbObject('Title')->forTemplate())
                );
            }

            
// Special case for Group records (not PermissionRole):
            // Determine inherited assignments
            
if(is_a($record'Group')) {
                
// Get all permissions from roles
                
if ($record->Roles()->Count()) {
                    foreach(
$record->Roles() as $role) {
                        foreach(
$role->Codes() as $code) {
                            if (!isset(
$inheritedCodes[$code->Code])) $inheritedCodes[$code->Code] = array();
                            
$inheritedCodes[$code->Code][] = _t(
                                
'PermissionCheckboxSetField.FromRole',
                                
'inherited from role "{title}"',
                                
'A permission inherited from a certain permission role',
                                array(
'title' => $role->dbObject('Title')->forTemplate())
                            );
                        }
                    }
                }

                
// Get from parent groups
                
$parentGroups $record->getAncestors();
                if (
$parentGroups) {
                    foreach (
$parentGroups as $parent) {
                        if (!
$parent->Roles()->Count()) continue;
                        foreach(
$parent->Roles() as $role) {
                            if (
$role->Codes()) {
                                foreach(
$role->Codes() as $code) {
                                    if (!isset(
$inheritedCodes[$code->Code])) $inheritedCodes[$code->Code] = array();
                                    
$inheritedCodes[$code->Code][] = _t(
                                        
'PermissionCheckboxSetField.FromRoleOnGroup',
                                        
'inherited from role "%s" on group "%s"',
                                        
'A permission inherited from a role on a certain group',
                                        array(
'roletitle' => $role->dbObject('Title')->forTemplate(), 'grouptitle' => $parent->dbObject('Title')->forTemplate())
                                    );
                                }
                            }
                        }
                        if (
$parent->Permissions()->Count()) {
                            foreach(
$parent->Permissions() as $permission) {
                                if (!isset(
$inheritedCodes[$permission->Code])) {
                                    
$inheritedCodes[$permission->Code] = array();
                                }
                                
$inheritedCodes[$permission->Code][] =
                                
_t(
                                    
'PermissionCheckboxSetField.FromGroup',
                                    
'inherited from group "{title}"',
                                    
'A permission inherited from a certain group',
                                    array(
'title' => $parent->dbObject('Title')->forTemplate())
                                );
                            }
                        }
                    }
                }
            }
        }

        
$odd 0;
        
$options '';
        
$globalHidden = (array)Config::inst()->get('Permission''hidden_permissions');
        if(
$this->source) {
            
$privilegedPermissions Permission::config()->privileged_permissions;

            
// loop through all available categorized permissions and see if they're assigned for the given groups
            
foreach($this->source as $categoryName => $permissions) {
                
$options .= "<li><h5>$categoryName</h5></li>";
                foreach(
$permissions as $code => $permission) {
                    if(
in_array($code$this->hiddenPermissions)) continue;
                    if(
in_array($code$globalHidden)) continue;

                    
$value $permission['name'];

                    
$odd = ($odd 1) % 2;
                    
$extraClass $odd 'odd' 'even';
                    
$extraClass .= ' val' str_replace(' '''$code);
                    
$itemID $this->id() . '_' preg_replace('/[^a-zA-Z0-9]+/'''$code);
                    
$checked $disabled $inheritMessage '';
                    
$checked = (isset($uninheritedCodes[$code]) || isset($inheritedCodes[$code]))
                        ? 
' checked="checked"'
                        
'';
                    
$title $permission['help']
                        ? 
'title="' htmlentities($permission['help'], ENT_COMPAT'UTF-8') . '" '
                        
'';

                    if (isset(
$inheritedCodes[$code])) {
                        
// disable inherited codes, as any saving logic would be too complicate to express in this
                        // interface
                        
$disabled ' disabled="true"';
                        
$inheritMessage ' (' join(', '$inheritedCodes[$code]) . ')';
                    } elseif(
$this->records && $this->records->Count() > && isset($uninheritedCodes[$code])) {
                        
// If code assignments are collected from more than one "source group",
                        // show its origin automatically
                        
$inheritMessage ' (' join(', '$uninheritedCodes[$code]).')';
                    }

                    
// Disallow modification of "privileged" permissions unless currently logged-in user is an admin
                    
if(!Permission::check('ADMIN') && in_array($code$privilegedPermissions)) {
                        
$disabled ' disabled="true"';
                    }

                    
// If the field is readonly, always mark as "disabled"
                    
if($this->readonly$disabled ' disabled="true"';

                    
$inheritMessage '<small>' $inheritMessage '</small>';
                    
$icon = ($checked) ? 'accept' 'decline';

                    
// If the field is readonly, add a span that will replace the disabled checkbox input
                    
if($this->readonly) {
                        
$options .= "<li class="$extraClass">"
                            
"<input id="$itemID"$disabled name="$this->name[$code]" type="checkbox""
                            
" value="$code"$checked class="checkbox" />"
                            
"<label {$title}for="$itemID">"
                            
"<span class="ui-button-icon-primary ui-icon btn-icon-$icon"></span>"
                            
"$value$inheritMessage</label>"
                            
"</li>n";
                    } else {
                        
$options .= "<li class="$extraClass">"
                            
"<input id="$itemID"$disabled name="$this->name[$code]" type="checkbox""
                            
" value="$code"$checked class="checkbox" />"
                            
"<label {$title}for="$itemID">$value$inheritMessage</label>"
                            
"</li>n";
                    }
                }
            }
        }
        if(
$this->readonly) {
            return 
DBField::create_field('HTMLText',
                
"<ul id="{$this->id()}" class="optionset checkboxsetfield{$this->extraClass()}">n" .
                
"<li class="help">" .
                
_t(
                    
'Permissions.UserPermissionsIntro',
                    
'Assigning groups to this user will adjust the permissions they have.'
                    
' See the groups section for details of permissions on individual groups.'
                
) .
                
"</li>" .
                
$options .
                
"</ul>n"
            
);
        } else {
            return 
DBField::create_field('HTMLText',
                
"<ul id="{$this->id()}" class="optionset checkboxsetfield{$this->extraClass()}">n" .
                
$options .
                
"</ul>n"
            
);
        }
    }

    
/**
     * Update the permission set associated with $record DataObject
     *
     * @param DataObject $record
     */
    
public function saveInto(DataObjectInterface $record) {
        
$fieldname $this->name;
        
$managedClass $this->managedClass;

        
// Remove all "privileged" permissions if the currently logged-in user is not an admin
        
$privilegedPermissions Permission::config()->privileged_permissions;
        if(!
Permission::check('ADMIN')) {
            foreach(
$this->value as $id => $bool) {
                if(
in_array($id$privilegedPermissions)) {
                    unset(
$this->value[$id]);
                }
            }
        }

        
// remove all permissions and re-add them afterwards
        
$permissions $record->$fieldname();
        foreach ( 
$permissions as $permission ) {
            
$permission->delete();
        }

        if(
$fieldname && $record && ($record->hasManyComponent($fieldname) || $record->manyManyComponent($fieldname))) {

            if(!
$record->ID$record->write(); // We need a record ID to write permissions

            
$idList = array();
            if(
$this->value) foreach($this->value as $id => $bool) {
                if(
$bool) {
                    
$perm = new $managedClass();
                    
$perm->{$this->filterField} = $record->ID;
                    
$perm->Code $id;
                    
$perm->write();
                }
            }
        }
    }

    
/**
     * @return PermissionCheckboxSetField_Readonly
     */
    
public function performReadonlyTransformation() {
        
$readonly = new PermissionCheckboxSetField_Readonly(
            
$this->name,
            
$this->title,
            
$this->managedClass,
            
$this->filterField,
            
$this->records
        
);

        return 
$readonly;
    }

    
/**
     * Retrieves all permission codes for the currently set records
     *
     * @return array
     */
    
public function getAssignedPermissionCodes() {
        if(!
$this->records) return false;

        
// TODO

        
return $codes;
    }
}

/**
 * Readonly version of a {@link PermissionCheckboxSetField} -
 * uses the same structure, but has all checkboxes disabled.
 *
 * @package framework
 * @subpackage security
 */
class PermissionCheckboxSetField_Readonly extends PermissionCheckboxSetField {

    protected 
$readonly true;

    public function 
saveInto(DataObjectInterface $record) {
        return 
false;
    }
}
Онлайн: 0
Реклама