Skip to content

Instantly share code, notes, and snippets.

@mooror
Created December 31, 2018 02:35
Show Gist options
  • Save mooror/f194e2a1105fc4da557134b2450ac339 to your computer and use it in GitHub Desktop.
Save mooror/f194e2a1105fc4da557134b2450ac339 to your computer and use it in GitHub Desktop.
Silverstripe DataObject with built in permissions functionality
<?php
namespace Sitelease\Core\Model;
use SilverStripe\ORM\DataObject;
use SilverStripe\Core\Config\Config;
use SilverStripe\Security\Permission;
/**
* This class extends the DataObject class and adds extra user permission
* functionality to it
*/
class PermissionsDataObject extends DataObject
{
private static $table_name = 'Core_PermissionsDataObject';
///////////////////////////////////////
// PERMISSIONS //
///////////////////////////////////////
// Permission code for actions will be created from the action
// name with the suffex added on. e.g. ACTION_SUFFIX
//
// REMEMBER: Spaces and underscores in action names will be converted
// to underscores in the permission code.
// Example: "action name" will become "ACTION_NAME_SUFFIX"
private static $api_access = true;
// Permission suffix should start with "SL", be uppercase,
// and contain the model (DataObject) name
private static $permissions_suffix = false;
// The Discriptor is a fully lowercase version of your object name.
// So for a "Products" modal you might use "products"
private static $permissions_descriptor = false;
// The below value will be displayed as a heading on the permissions tab
// We usually use the following format "Modal Name (Sitelease)"
private static $permissions_category = false;
// One action will be created for each item in this array. Make sure to use
// an adjective for your action names as the name will be used in the
// creation of action titles. You can also manually set the title by
// setting the key's value
private static $permissions_config_array = array(
'view' => "",
'edit' => "",
'delete' => "",
'create' => "",
"experimental-access" => "Access Experimental Features - Allow user to use experimental fields and settings"
);
// You can manually add in extra actions to the array below
// using the following syntax
// "ACTIONNAME_SLSUFFIX" => array(
// "name" => "Action Name - Permission description",
// "help" => "Permission Code: ACTIONNAME_SLSUFFIX",
// "category" => "Category Title (Sitelease)",
// "sort" => 99
// )
// Hint: Type start typing: permissionsArrayEntryV4
public $permissionsArray = array();
public function getPermissionsSuffix()
{
$namespace = get_called_class();
$namespaceArray = explode('\\', $namespace);
$className = array_pop($namespaceArray);
$suffix = Config::inst()->get($namespace, "permissions_suffix");
if (!$suffix) {
if (substr($className, 0, strlen("SL")) == "SL") {
$suffix = strtoupper($className);
}else{
$suffix = "SL".strtoupper($className);
}
}
return $suffix;
}
public function getReadableClassName()
{
$namespace = get_called_class();
$namespaceArray = explode('\\', $namespace);
$className = array_pop($namespaceArray);
// Strip "SL" from the start of the class name
if (substr($className, 0, strlen("SL")) == "SL") {
$className = substr($className, strlen("SL"));
}
// Split the class name into words and lowercase it
$readableClassName = preg_split('/(?=[A-Z])/', $className);
$lowerReadableClass = strtolower(implode(" ",$readableClassName));
return trim($lowerReadableClass);
}
public function getPermissionsDescriptor()
{
$namespace = get_called_class();
$readableClass = $this->ReadableClassName;
$descriptor = Config::inst()->get($namespace, "permissions_descriptor");
if (!$descriptor) {
$descriptor = ucfirst($readableClass."s (Sitelease)");
}
return $descriptor;
}
public function getPermissionsCategory()
{
$namespace = get_called_class();
$readableClass = $this->ReadableClassName;
$category = Config::inst()->get($namespace, "permissions_category");
if (!$category) {
$category = ucfirst($readableClass."s (Sitelease)");
}
return $category;
}
public function getPermissionsConfigArray()
{
$namespace = get_called_class();
$permissionsConfigArray = Config::inst()->get($namespace, "permissions_config_array");
if (!$permissionsConfigArray) {
$permissionsConfigArray = self::$permissions_config_array;
}
return $permissionsConfigArray;
}
public function providePermissions() {
$suffix = $this->PermissionsSuffix;
$category = $this->PermissionsCategory;
$descriptor = $this->PermissionsDescriptor;
$actions = $this->PermissionsConfigArray;
$iterations = 0;
foreach ($actions as $actionName => $actionTitle) {
// If the title is empty or falsey, create one
if (empty($actionTitle) || !$actionTitle) {
$actionTitle = ucfirst($actionName)." - ".'Allow user to '.$actionName.' '.$descriptor.' objects';
}
$codeActionName = str_replace("-", "_", $actionName);
$codeActionName = str_replace(" ", "_", $codeActionName);
$permissionCode = strtoupper($codeActionName) . '_' . $suffix;
$this->permissionsArray[$permissionCode] = array(
'name' => $actionTitle,
'help' => 'Permission Code: '.$permissionCode,
'category' => $category,
'sort' => 99-$iterations
);
$iterations++;
}
return $this->permissionsArray;
}
public function canView($member = null) {
return Permission::check('VIEW_' . $this->PermissionsSuffix, 'any', $member);
}
public function canEdit($member = null) {
return Permission::check('EDIT_' . $this->PermissionsSuffix, 'any', $member);
}
public function canDelete($member = null) {
return Permission::check('DELETE_' . $this->PermissionsSuffix, 'any', $member);
}
public function canCreate($member = null, $context = array()) {
return Permission::check('CREATE_' . $this->PermissionsSuffix, 'any', $member);
}
public function canAccessExperimental($member = null)
{
return Permission::check('EXPERIMENTAL_ACCESS_' . $this->PermissionsSuffix, 'any', $member);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment