1 <?php
2
3 /**
4 * Abstract class for complex permissions.
5 *
6 * All permission check methods ("hasPerm()" etc.) in child classes should return "true" for admins
7 *
8 * @author gharlan
9 *
10 * @package redaxo\core\login
11 */
12 abstract class rex_complex_perm
13 {
14 const ALL = 'all';
15
16 /**
17 * User instance.
18 *
19 * @var rex_user
20 */
21 protected $user;
22
23 /**
24 * Array of permissions.
25 *
26 * @var array
27 */
28 protected $perms = [];
29
30 /**
31 * Array of class names.
32 *
33 * @var array
34 */
35 private static $classes = [];
36
37 /**
38 * Constructor.
39 *
40 * @param rex_user $user User instance
41 * @param mixed $perms Permissions
42 */
43 protected function __construct(rex_user $user, $perms)
44 {
45 $this->user = $user;
46 $this->perms = $perms;
47 }
48
49 /**
50 * Returns if the user has the permission for all items.
51 *
52 * @return bool
53 */
54 public function hasAll()
55 {
56 return $this->user->isAdmin() || $this->perms == self::ALL;
57 }
58
59 /**
60 * Returns the field params for the role form.
61 *
62 * @return array
63 */
64 public static function getFieldParams()
65 {
66 return [];
67 }
68
69 /**
70 * Registers a new complex perm class.
71 *
72 * @param string $key Key for the complex perm
73 * @param string $class Class name
74 *
75 * @throws InvalidArgumentException
76 */
77 public static function register($key, $class)
78 {
79 if (!is_subclass_of($class, self::class)) {
80 throw new InvalidArgumentException(sprintf('Class "%s" must be a subclass of "%s"!', $class, self::class));
81 }
82 self::$classes[$key] = $class;
83 }
84
85 /**
86 * Returns all complex perm classes.
87 *
88 * @return array Class names
89 */
90 public static function getAll()
91 {
92 return self::$classes;
93 }
94
95 /**
96 * Returns the complex perm.
97 *
98 * @param rex_user $user User instance
99 * @param string $key Complex perm key
100 * @param mixed $perms Permissions
101 *
102 * @return self
103 */
104 public static function get(rex_user $user, $key, $perms = [])
105 {
106 if (!isset(self::$classes[$key])) {
107 return null;
108 }
109 $class = self::$classes[$key];
110 return new $class($user, $perms);
111 }
112
113 /**
114 * Should be called if an item is removed.
115 *
116 * @param string $key Key
117 * @param string $item Item
118 */
119 public static function removeItem($key, $item)
120 {
121 rex_extension::registerPoint(new rex_extension_point('COMPLEX_PERM_REMOVE_ITEM', '', ['key' => $key, 'item' => $item], true));
122 }
123
124 /**
125 * Should be called if an item is replaced.
126 *
127 * @param string $key Key
128 * @param string $item Old item
129 * @param string $new New item
130 */
131 public static function replaceItem($key, $item, $new)
132 {
133 rex_extension::registerPoint(new rex_extension_point('COMPLEX_PERM_REPLACE_ITEM', '', ['key' => $key, 'item' => $item, 'new' => $new], true));
134 }
135 }
136