1 <?php
  2 
  3 /**
  4  * Class for user roles.
  5  *
  6  * @author gharlan
  7  *
  8  * @package redaxo\users
  9  */
 10 class rex_user_role implements rex_user_role_interface
 11 {
 12     /**
 13      * Permissions.
 14      *
 15      * @var array
 16      */
 17     private $perms = [];
 18 
 19     /**
 20      * Complex perm params.
 21      *
 22      * @var array
 23      */
 24     private $complexPermParams = [];
 25 
 26     /**
 27      * Cache for complex perm instances.
 28      *
 29      * @var array
 30      */
 31     private $complexPerms = [];
 32 
 33     /**
 34      * Constructor.
 35      *
 36      * @param array $roles
 37      */
 38     private function __construct(array $roles)
 39     {
 40         foreach ($roles as $role) {
 41             foreach ([rex_perm::GENERAL, rex_perm::OPTIONS, rex_perm::EXTRAS] as $key) {
 42                 $perms = $role[$key] ? explode('|', trim($role[$key], '|')) : [];
 43                 $this->perms = array_merge($this->perms, $perms);
 44                 unset($role[$key]);
 45             }
 46 
 47             foreach ($role as $key => $value) {
 48                 if (rex_complex_perm::ALL === $role[$key]) {
 49                     $perms = rex_complex_perm::ALL;
 50                 } else {
 51                     $perms = explode('|', trim($role[$key], '|'));
 52                     if (count($perms) == 1 && $perms[0] == '') {
 53                         $perms = [];
 54                     }
 55                 }
 56 
 57                 if (!isset($this->complexPermParams[$key])) {
 58                     $this->complexPermParams[$key] = $perms;
 59                 } elseif ($this->complexPermParams[$key] == rex_complex_perm::ALL) {
 60                 } elseif ($perms == rex_complex_perm::ALL) {
 61                     $this->complexPermParams[$key] = $perms;
 62                 } else {
 63                     $this->complexPermParams[$key] = array_merge($perms, $this->complexPermParams[$key]);
 64                 }
 65             }
 66         }
 67     }
 68 
 69     /**
 70      * {@inheritdoc}
 71      */
 72     public function hasPerm($perm)
 73     {
 74         return in_array($perm, $this->perms);
 75     }
 76 
 77     /**
 78      * {@inheritdoc}
 79      */
 80     public function getComplexPerm(rex_user $user, $key)
 81     {
 82         if (isset($this->complexPerms[$key])) {
 83             return $this->complexPerms[$key];
 84         }
 85         if (!isset($this->complexPermParams[$key])) {
 86             $this->complexPermParams[$key] = [];
 87         }
 88         $this->complexPerms[$key] = rex_complex_perm::get($user, $key, $this->complexPermParams[$key]);
 89         return $this->complexPerms[$key];
 90     }
 91 
 92     /**
 93      * {@inheritdoc}
 94      */
 95     public static function get($ids)
 96     {
 97         $sql = rex_sql::factory();
 98         $user_roles = $sql->getArray('SELECT perms FROM ' . rex::getTablePrefix() . 'user_role WHERE FIND_IN_SET(id, ?)', [$ids]);
 99         if (count($user_roles) == 0) {
100             return null;
101         }
102 
103         $roles = [];
104         foreach ($user_roles as $user_role) {
105             $roles[] = json_decode($user_role['perms'], true);
106         }
107 
108         return new self($roles);
109     }
110 
111     public static function removeOrReplaceItem(rex_extension_point $ep)
112     {
113         $params = $ep->getParams();
114         $key = $params['key'];
115         $item = '|' . $params['item'] . '|';
116         $new = isset($params['new']) ? '|' . $params['new'] . '|' : '|';
117         $sql = rex_sql::factory();
118         $sql->setQuery('SELECT id, perms FROM ' . rex::getTable('user_role'));
119         $update = rex_sql::factory();
120         $update->prepareQuery('UPDATE ' . rex::getTable('user_role') . ' SET perms = ? WHERE id = ?');
121         foreach ($sql as $row) {
122             $perms = json_decode($row->getValue('perms'), true);
123             if (isset($perms[$key]) && strpos($perms[$key], $item) !== false) {
124                 $perms[$key] = str_replace($item, $new, $perms[$key]);
125                 $update->execute([json_encode($perms), $row->getValue('id')]);
126             }
127         }
128     }
129 }
130