ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilRbacReview.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
34 {
35  public const FILTER_ALL = 1;
36  public const FILTER_ALL_GLOBAL = 2;
37  public const FILTER_ALL_LOCAL = 3;
38  public const FILTER_INTERNAL = 4;
39  public const FILTER_NOT_INTERNAL = 5;
40  public const FILTER_TEMPLATES = 6;
41 
42  // Cache operation ids
43  private static ?array $_opsCache = null;
44 
45  protected static array $assigned_users_cache = [];
46  protected static array $is_assigned_cache = [];
47 
48  protected ilLogger $log;
49  protected ilDBInterface $db;
50 
55  public function __construct()
56  {
57  global $DIC;
58 
59  $this->log = ilLoggerFactory::getLogger('ac');
60  $this->db = $DIC->database();
61  }
62 
70  public function roleExists(string $a_title, int $a_id = 0): ?int
71  {
72  $clause = ($a_id) ? " AND obj_id != " . $this->db->quote($a_id, ilDBConstants::T_TEXT) . " " : "";
73 
74  $q = "SELECT DISTINCT(obj_id) obj_id FROM object_data " .
75  "WHERE title =" . $this->db->quote($a_title, ilDBConstants::T_TEXT) . " " .
76  "AND type IN('role','rolt')" .
77  $clause . " ";
78  $r = $this->db->query($q);
79  while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
80  return (int) $row->obj_id;
81  }
82  return null;
83  }
84 
95  protected function __getParentRoles(array $a_path, bool $a_templates): array
96  {
97  $parent_roles = [];
98  $role_hierarchy = [];
99  foreach ($a_path as $ref_id) {
100  $roles = $this->getRoleListByObject($ref_id, $a_templates);
101  foreach ($roles as $role) {
102  $id = (int) $role["obj_id"];
103  $role["parent"] = (int) $ref_id;
104  $parent_roles[$id] = $role;
105 
106  if (!array_key_exists($role['obj_id'], $role_hierarchy)) {
107  $role_hierarchy[$id] = $ref_id;
108  }
109  }
110  }
111  return $this->__setProtectedStatus($parent_roles, $role_hierarchy, (int) reset($a_path));
112  }
113 
122  public function getParentRoleIds(int $a_endnode_id, bool $a_templates = false): array
123  {
124  global $DIC;
125 
126  $tree = $DIC->repositoryTree();
127 
128  $pathIds = $tree->getPathId($a_endnode_id);
129 
130  // add system folder since it may not in the path
131  //$pathIds[0] = SYSTEM_FOLDER_ID;
132  $pathIds[0] = ROLE_FOLDER_ID;
133  return $this->__getParentRoles($pathIds, $a_templates);
134  }
135 
140  public function getRoleListByObject(int $a_ref_id, bool $a_templates = false): array
141  {
142  $role_list = [];
143  $where = $this->__setTemplateFilter($a_templates);
144 
145  $query = "SELECT * FROM object_data " .
146  "JOIN rbac_fa ON obj_id = rol_id " .
147  $where .
148  "AND object_data.obj_id = rbac_fa.rol_id " .
149  "AND rbac_fa.parent = " . $this->db->quote($a_ref_id, 'integer') . " ";
150 
151  $res = $this->db->query($query);
152  while ($row = $this->db->fetchAssoc($res)) {
153  $row["desc"] = $row["description"];
154  $row["user_id"] = (int) $row["owner"];
155  $row['obj_id'] = (int) $row['obj_id'];
156  $row['rol_id'] = (int) $row['rol_id'];
157  $row['parent'] = (int) $row['parent'];
158  $role_list[] = $row;
159  }
160 
161  return $this->__setRoleType($role_list);
162  }
163 
168  public function getAssignableRoles(
169  bool $a_templates = false,
170  bool $a_internal_roles = false,
171  string $title_filter = ''
172  ): array {
173  return iterator_to_array(
175  $a_templates,
176  $a_internal_roles,
177  $title_filter
178  )
179  );
180  }
181 
185  private function getAssignableRolesGenerator(
186  bool $a_templates = false,
187  bool $a_internal_roles = false,
188  string $title_filter = ''
189  ): Generator {
190  $where = $this->__setTemplateFilter($a_templates);
191  $query = "SELECT * FROM object_data " .
192  "JOIN rbac_fa ON obj_id = rol_id " .
193  $where .
194  "AND rbac_fa.assign = 'y' ";
195 
196  if (strlen($title_filter)) {
197  $query .= (' AND ' . $this->db->like(
198  'title',
199  'text',
200  $title_filter . '%'
201  ));
202  }
203  $res = $this->db->query($query);
204 
205  while ($row = $this->db->fetchAssoc($res)) {
206  $row["description"] = (string) $row["description"];
207  $row["desc"] = $row["description"];
208  $row["user_id"] = (int) $row["owner"];
209  $row['obj_id'] = (int) $row['obj_id'];
210  $row['parent'] = (int) $row['parent'];
211  yield $this->setRoleTypeAndProtection($row);
212  }
213  }
214 
220  public function getAssignableRolesInSubtree(int $ref_id): array
221  {
222  global $DIC;
223 
224  $tree = $DIC->repositoryTree();
225  $query = 'SELECT rol_id FROM rbac_fa fa ' .
226  'JOIN tree t1 ON t1.child = fa.parent ' .
227  'JOIN object_data obd ON fa.rol_id = obd.obj_id ' .
228  'WHERE assign = ' . $this->db->quote('y', 'text') . ' ' .
229  'AND obd.type = ' . $this->db->quote('role', 'text') . ' ' .
230  'AND t1.child IN (' .
231  $tree->getSubTreeQuery($ref_id, ['child']) . ' ' .
232  ') ';
233 
234  $res = $this->db->query($query);
235 
236  $role_list = [];
237  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
238  $role_list[] = (int) $row->rol_id;
239  }
240  return $role_list;
241  }
242 
246  public function getAssignableChildRoles(int $a_ref_id): array
247  {
248  $query = "SELECT fa.*, rd.* " .
249  "FROM object_data rd " .
250  "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id " .
251  "WHERE fa.assign = 'y' " .
252  "AND fa.parent = " . $this->db->quote($a_ref_id, 'integer') . " ";
253 
254  $res = $this->db->query($query);
255  $roles_data = [];
256  while ($row = $this->db->fetchAssoc($res)) {
257  $row['rol_id'] = (int) $row['rol_id'];
258  $row['obj_id'] = (int) $row['obj_id'];
259 
260  $roles_data[] = $row;
261  }
262 
263  return $roles_data;
264  }
265 
269  protected function __setTemplateFilter(bool $a_templates): string
270  {
271  if ($a_templates) {
272  $where = "WHERE " . $this->db->in('object_data.type', ['role', 'rolt'], false, 'text') . " ";
273  } else {
274  $where = "WHERE " . $this->db->in('object_data.type', ['role'], false, 'text') . " ";
275  }
276  return $where;
277  }
278 
286  protected function __setRoleType(array $a_role_list): array
287  {
288  foreach ($a_role_list as $key => $val) {
289  $a_role_list[$key] = $this->setRoleTypeAndProtection($val);
290  }
291  return $a_role_list;
292  }
293 
294  private function setRoleTypeAndProtection(array $role_list_entry): array
295  {
296  $role_list_entry['role_type'] = $this->buildRoleType($role_list_entry);
297  $role_list_entry['protected'] = $this->buildProtectionByStringValue($role_list_entry['protected']);
298  return $role_list_entry;
299  }
300 
301  private function buildRoleType(array $role_list_entry): string
302  {
303  if ($role_list_entry['type'] === 'rolt') {
304  return 'template';
305  }
306 
307  if ($role_list_entry['assign'] !== 'y') {
308  return 'linked';
309  }
310 
311  if ($role_list_entry['parent'] === ROLE_FOLDER_ID) {
312  return 'global';
313  }
314 
315  return 'local';
316  }
317 
318  private function buildProtectionByStringValue(string $value): bool
319  {
320  if ($value === 'y') {
321  return true;
322  }
323  return false;
324  }
325 
330  public function getNumberOfAssignedUsers(array $a_roles): int
331  {
332  $query = 'select count(distinct(ua.usr_id)) as num from rbac_ua ua ' .
333  'join object_data on ua.usr_id = obj_id ' .
334  'join usr_data ud on ua.usr_id = ud.usr_id ' .
335  'where ' . $this->db->in('rol_id', $a_roles, false, 'integer');
336 
337  $res = $this->db->query($query);
338  if ($res->numRows() > 0) {
339  $row = $res->fetchRow(\ilDBConstants::FETCHMODE_OBJECT);
340  return isset($row->num) && is_numeric($row->num) ? (int) $row->num : 0;
341  }
342  return 0;
343  }
344 
349  public function assignedUsers(int $a_rol_id): array
350  {
351  if (isset(self::$assigned_users_cache[$a_rol_id])) {
352  return self::$assigned_users_cache[$a_rol_id];
353  }
354 
355  $result_arr = [];
356  $query = "SELECT usr_id FROM rbac_ua WHERE rol_id= " . $this->db->quote($a_rol_id, 'integer');
357  $res = $this->db->query($query);
358  while ($row = $this->db->fetchAssoc($res)) {
359  $result_arr[] = (int) $row["usr_id"];
360  }
361  self::$assigned_users_cache[$a_rol_id] = $result_arr;
362  return $result_arr;
363  }
364 
368  public function isAssigned(int $a_usr_id, int $a_role_id): bool
369  {
370  if (isset(self::$is_assigned_cache[$a_role_id][$a_usr_id])) {
371  return self::$is_assigned_cache[$a_role_id][$a_usr_id];
372  }
373  // Quickly determine if user is assigned to a role
374  $this->db->setLimit(1, 0);
375  $query = "SELECT usr_id FROM rbac_ua WHERE " .
376  "rol_id= " . $this->db->quote($a_role_id, 'integer') . " " .
377  "AND usr_id= " . $this->db->quote($a_usr_id, ilDBConstants::T_INTEGER);
378  $res = $this->db->query($query);
379  $is_assigned = $res->numRows() == 1;
380  self::$is_assigned_cache[$a_role_id][$a_usr_id] = $is_assigned;
381  return $is_assigned;
382  }
383 
392  public function isAssignedToAtLeastOneGivenRole(int $a_usr_id, array $a_role_ids): bool
393  {
394  global $DIC;
395 
396  $this->db = $DIC['ilDB'];
397 
398  $this->db->setLimit(1, 0);
399  $query = "SELECT usr_id FROM rbac_ua WHERE " .
400  $this->db->in('rol_id', $a_role_ids, false, 'integer') .
401  " AND usr_id= " . $this->db->quote($a_usr_id, ilDBConstants::T_INTEGER);
402  $res = $this->db->query($query);
403 
404  return $this->db->numRows($res) == 1;
405  }
406 
411  public function assignedRoles(int $a_usr_id): array
412  {
413  $query = "SELECT rol_id FROM rbac_ua WHERE usr_id = " . $this->db->quote($a_usr_id, 'integer');
414 
415  $res = $this->db->query($query);
416  $role_arr = [];
417  while ($row = $this->db->fetchObject($res)) {
418  $role_arr[] = (int) $row->rol_id;
419  }
420  return $role_arr;
421  }
422 
427  public function assignedGlobalRoles(int $a_usr_id): array
428  {
429  $query = "SELECT ua.rol_id FROM rbac_ua ua " .
430  "JOIN rbac_fa fa ON ua.rol_id = fa.rol_id " .
431  "WHERE usr_id = " . $this->db->quote($a_usr_id, 'integer') . ' ' .
432  "AND parent = " . $this->db->quote(ROLE_FOLDER_ID, ilDBConstants::T_INTEGER) . " " .
433  "AND assign = 'y' ";
434 
435  $res = $this->db->query($query);
436  $role_arr = [];
437  while ($row = $this->db->fetchObject($res)) {
438  $role_arr[] = (int) $row->rol_id;
439  }
440 
441  return $role_arr;
442  }
443 
447  public function isAssignable(int $a_rol_id, int $a_ref_id): bool
448  {
449  // exclude system role from rbac
450  if ($a_rol_id == SYSTEM_ROLE_ID) {
451  return true;
452  }
453 
454  $query = "SELECT * FROM rbac_fa " .
455  "WHERE rol_id = " . $this->db->quote($a_rol_id, 'integer') . " " .
456  "AND parent = " . $this->db->quote($a_ref_id, 'integer') . " ";
457  $res = $this->db->query($query);
458  while ($row = $this->db->fetchObject($res)) {
459  return $row->assign == 'y';
460  }
461  return false;
462  }
463 
464  public function hasMultipleAssignments(int $a_role_id): bool
465  {
466  $query = "SELECT * FROM rbac_fa WHERE rol_id = " . $this->db->quote($a_role_id, 'integer') . ' ' .
467  "AND assign = " . $this->db->quote('y', 'text');
468  $res = $this->db->query($query);
469  return $res->numRows() > 1;
470  }
471 
481  public function getFoldersAssignedToRole(int $a_rol_id, bool $a_assignable = false): array
482  {
483  $where = '';
484  if ($a_assignable) {
485  $where = " AND assign ='y'";
486  }
487 
488  $query = "SELECT DISTINCT parent FROM rbac_fa " .
489  "WHERE rol_id = " . $this->db->quote($a_rol_id, 'integer') . " " . $where . " ";
490 
491  $res = $this->db->query($query);
492  $folders = [];
493  while ($row = $this->db->fetchObject($res)) {
494  $folders[] = (int) $row->parent;
495  }
496  return $folders;
497  }
498 
503  public function getRolesOfObject(int $a_ref_id, bool $a_assignable_only = false): array
504  {
505  $and = '';
506  if ($a_assignable_only === true) {
507  $and = 'AND assign = ' . $this->db->quote('y', 'text');
508  }
509  $query = "SELECT rol_id FROM rbac_fa " .
510  "WHERE parent = " . $this->db->quote($a_ref_id, 'integer') . " " .
511  $and;
512 
513  $res = $this->db->query($query);
514 
515  $role_ids = [];
516  while ($row = $this->db->fetchObject($res)) {
517  $role_ids[] = (int) $row->rol_id;
518  }
519  return $role_ids;
520  }
521 
529  public function getRolesOfRoleFolder(int $a_ref_id, bool $a_nonassignable = true): array
530  {
531  $and = '';
532  if ($a_nonassignable === false) {
533  $and = " AND assign='y'";
534  }
535 
536  $query = "SELECT rol_id FROM rbac_fa " .
537  "WHERE parent = " . $this->db->quote($a_ref_id, 'integer') . " " .
538  $and;
539 
540  $res = $this->db->query($query);
541  $rol_id = [];
542  while ($row = $this->db->fetchObject($res)) {
543  $rol_id[] = (int) $row->rol_id;
544  }
545 
546  return $rol_id;
547  }
548 
554  public function getGlobalRoles(): array
555  {
556  return $this->getRolesOfRoleFolder(ROLE_FOLDER_ID, false);
557  }
558 
563  public function getLocalRoles(int $a_ref_id): array
564  {
565  $lroles = [];
566  foreach ($this->getRolesOfRoleFolder($a_ref_id) as $role_id) {
567  if ($this->isAssignable($role_id, $a_ref_id)) {
568  $lroles[] = $role_id;
569  }
570  }
571  return $lroles;
572  }
573 
578  public function getLocalPolicies(int $a_ref_id): array
579  {
580  $lroles = [];
581  foreach ($this->getRolesOfRoleFolder($a_ref_id) as $role_id) {
582  $lroles[] = $role_id;
583  }
584  return $lroles;
585  }
586 
591  public function getGlobalRolesArray(): array
592  {
593  $ga = [];
594  foreach ($this->getRolesOfRoleFolder(ROLE_FOLDER_ID, false) as $role_id) {
595  $ga[] = ['obj_id' => $role_id,
596  'role_type' => 'global'
597  ];
598  }
599  return $ga;
600  }
601 
606  public function getGlobalAssignableRoles(): array
607  {
608  $ga = [];
609  foreach ($this->getGlobalRoles() as $role_id) {
610  if (ilObjRole::_getAssignUsersStatus($role_id)) {
611  $ga[] = ['obj_id' => $role_id,
612  'role_type' => 'global'
613  ];
614  }
615  }
616  return $ga;
617  }
618 
622  public function isRoleAssignedToObject(int $a_role_id, int $a_parent_id): bool
623  {
624  $query = 'SELECT * FROM rbac_fa ' .
625  'WHERE rol_id = ' . $this->db->quote($a_role_id, 'integer') . ' ' .
626  'AND parent = ' . $this->db->quote($a_parent_id, 'integer');
627  $res = $this->db->query($query);
628  return (bool) $res->numRows();
629  }
630 
635  public function getOperations(): array
636  {
637  $query = 'SELECT * FROM rbac_operations ORDER BY ops_id ';
638  $res = $this->db->query($query);
639  $ops = [];
640  while ($row = $this->db->fetchObject($res)) {
641  $ops[] = ['ops_id' => (int) $row->ops_id,
642  'operation' => $row->operation,
643  'description' => $row->description
644  ];
645  }
646  return $ops;
647  }
648 
653  public function getOperation(int $ops_id): array
654  {
655  $query = 'SELECT * FROM rbac_operations WHERE ops_id = ' . $this->db->quote($ops_id, 'integer');
656  $res = $this->db->query($query);
657  $ops = [];
658  while ($row = $this->db->fetchObject($res)) {
659  $ops = ['ops_id' => (int) $row->ops_id,
660  'operation' => $row->operation,
661  'description' => $row->description
662  ];
663  }
664  return $ops;
665  }
666 
672  public function getAllOperationsOfRole(int $a_rol_id, int $a_parent = 0): array
673  {
674  if (!$a_parent) {
675  $a_parent = ROLE_FOLDER_ID;
676  }
677  $query = "SELECT ops_id,type FROM rbac_templates " .
678  "WHERE rol_id = " . $this->db->quote($a_rol_id, 'integer') . " " .
679  "AND parent = " . $this->db->quote($a_parent, 'integer');
680  $res = $this->db->query($query);
681 
682  $ops_arr = [];
683  while ($row = $this->db->fetchObject($res)) {
684  $ops_arr[$row->type][] = (int) $row->ops_id;
685  }
686  return $ops_arr;
687  }
688 
692  public function getActiveOperationsOfRole(int $a_ref_id, int $a_role_id): array
693  {
694  $query = 'SELECT * FROM rbac_pa ' .
695  'WHERE ref_id = ' . $this->db->quote($a_ref_id, 'integer') . ' ' .
696  'AND rol_id = ' . $this->db->quote($a_role_id, 'integer') . ' ';
697 
698  $res = $this->db->query($query);
699  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
700  return $row['ops_id'] === ':' ? [] : unserialize($row['ops_id'], ['allowed_classes' => false]);
701  }
702  return [];
703  }
704 
710  public function getOperationsOfRole(int $a_rol_id, string $a_type, int $a_parent = 0): array
711  {
712  $ops_arr = [];
713  // if no rolefolder id is given, assume global role folder as target
714  if ($a_parent == 0) {
715  $a_parent = ROLE_FOLDER_ID;
716  }
717 
718  $query = "SELECT ops_id FROM rbac_templates " .
719  "WHERE type =" . $this->db->quote($a_type, 'text') . " " .
720  "AND rol_id = " . $this->db->quote($a_rol_id, 'integer') . " " .
721  "AND parent = " . $this->db->quote($a_parent, 'integer');
722  $res = $this->db->query($query);
723  while ($row = $this->db->fetchObject($res)) {
724  $ops_arr[] = $row->ops_id;
725  }
726  return $ops_arr;
727  }
728 
732  public function getRoleOperationsOnObject(int $a_role_id, int $a_ref_id): array
733  {
734  $query = "SELECT ops_id FROM rbac_pa " .
735  "WHERE rol_id = " . $this->db->quote($a_role_id, 'integer') . " " .
736  "AND ref_id = " . $this->db->quote($a_ref_id, 'integer') . " ";
737 
738  $res = $this->db->query($query);
739  $ops = [];
740  while ($row = $this->db->fetchObject($res)) {
741  if ($row->ops_id !== ':') {
742  $ops = unserialize($row->ops_id, ['allowed_classes' => false]);
743  }
744  }
745 
746  return $ops;
747  }
748 
753  public function getOperationsOnType(int $a_typ_id): array
754  {
755  $query = 'SELECT ta.ops_id FROM rbac_ta ta JOIN rbac_operations o ON ta.ops_id = o.ops_id ' .
756  'WHERE typ_id = ' . $this->db->quote($a_typ_id, 'integer') . ' ' .
757  'ORDER BY op_order';
758 
759  $res = $this->db->query($query);
760  $ops_id = [];
761  while ($row = $this->db->fetchObject($res)) {
762  $ops_id[] = (int) $row->ops_id;
763  }
764  return $ops_id;
765  }
766 
771  public function getOperationsOnTypeString(string $a_type): array
772  {
773  $query = "SELECT * FROM object_data WHERE type = 'typ' AND title = " . $this->db->quote($a_type, 'text') . " ";
774  $res = $this->db->query($query);
775  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
776  return $this->getOperationsOnType((int) $row->obj_id);
777  }
778  return [];
779  }
780 
785  public function getOperationsByTypeAndClass(string $a_type, string $a_class): array
786  {
787  if ($a_class != 'create') {
788  $condition = "AND class != " . $this->db->quote('create', 'text');
789  } else {
790  $condition = "AND class = " . $this->db->quote('create', 'text');
791  }
792 
793  $query = "SELECT ro.ops_id FROM rbac_operations ro " .
794  "JOIN rbac_ta rt ON ro.ops_id = rt.ops_id " .
795  "JOIN object_data od ON rt.typ_id = od.obj_id " .
796  "WHERE type = " . $this->db->quote('typ', 'text') . " " .
797  "AND title = " . $this->db->quote($a_type, 'text') . " " .
798  $condition . " " .
799  "ORDER BY op_order ";
800 
801  $res = $this->db->query($query);
802  $ops = [];
803  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
804  $ops[] = (int) $row->ops_id;
805  }
806  return $ops;
807  }
808 
814  public function getObjectsWithStopedInheritance(int $a_rol_id, array $a_filter = []): array
815  {
816  $query = 'SELECT parent p FROM rbac_fa ' .
817  'WHERE assign = ' . $this->db->quote('n', 'text') . ' ' .
818  'AND rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ';
819 
820  if ($a_filter !== []) {
821  $query .= ('AND ' . $this->db->in('parent', (array) $a_filter, false, 'integer'));
822  }
823 
824  $res = $this->db->query($query);
825  $parent = [];
826  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
827  $parent[] = (int) $row->p;
828  }
829  return $parent;
830  }
831 
836  public function isDeleted(int $a_node_id): bool
837  {
838  $q = "SELECT tree FROM tree WHERE child =" . $this->db->quote($a_node_id, ilDBConstants::T_INTEGER) . " ";
839  $r = $this->db->query($q);
840  $row = $r->fetchRow(ilDBConstants::FETCHMODE_OBJECT);
841 
842  if (!$row) {
843  $message = sprintf(
844  '%s::isDeleted(): Role folder with ref_id %s not found!',
845  get_class($this),
846  $a_node_id
847  );
848  $this->log->warning($message);
849  return true;
850  }
851  return $row->tree < 0;
852  }
853 
857  public function isGlobalRole(int $a_role_id): bool
858  {
859  return in_array($a_role_id, $this->getGlobalRoles());
860  }
861 
865  public function getRolesByFilter(int $a_filter = 0, int $a_user_id = 0, string $title_filter = ''): Generator
866  {
867  $assign = "y";
868  switch ($a_filter) {
869  case self::FILTER_ALL:
870  return yield from $this->getAssignableRolesGenerator(true, true, $title_filter);
871 
872  case self::FILTER_ALL_GLOBAL:
873  $where = 'WHERE ' . $this->db->in('rbac_fa.rol_id', $this->getGlobalRoles(), false, 'integer') . ' ';
874  break;
875 
876  case self::FILTER_ALL_LOCAL:
877  case self::FILTER_INTERNAL:
878  case self::FILTER_NOT_INTERNAL:
879  $where = 'WHERE ' . $this->db->in('rbac_fa.rol_id', $this->getGlobalRoles(), true, 'integer');
880  break;
881 
882  case self::FILTER_TEMPLATES:
883  $where = "WHERE object_data.type = 'rolt'";
884  $assign = "n";
885  break;
886 
887  case 0:
888  default:
889  if (!$a_user_id) {
890  return;
891  }
892 
893  $where = 'WHERE ' . $this->db->in(
894  'rbac_fa.rol_id',
895  $this->assignedRoles($a_user_id),
896  false,
897  'integer'
898  ) . ' ';
899  break;
900  }
901 
902  $query = "SELECT * FROM object_data " .
903  "JOIN rbac_fa ON obj_id = rol_id " .
904  $where .
905  "AND rbac_fa.assign = " . $this->db->quote($assign, 'text') . " ";
906 
907  if (strlen($title_filter)) {
908  $query .= (' AND ' . $this->db->like(
909  'title',
910  'text',
911  '%' . $title_filter . '%'
912  ));
913  }
914 
915  $res = $this->db->query($query);
916  while ($row = $this->db->fetchAssoc($res)) {
917  $row['title'] = $row['title'] ?? '';
918  $prefix = str_starts_with($row['title'], "il_");
919 
920  // all (assignable) internal local roles only
921  if ($a_filter == 4 && !$prefix) {
922  continue;
923  }
924 
925  // all (assignable) non internal local roles only
926  if ($a_filter == 5 && $prefix) {
927  continue;
928  }
929 
930  $row['description'] = $row['description'] ?? '';
931  $row["desc"] = $row["description"];
932  $row["user_id"] = (int) $row["owner"];
933  $row['obj_id'] = (int) $row['obj_id'];
934  $row['rol_id'] = (int) $row['rol_id'];
935  $row['parent'] = (int) $row['parent'];
936 
937  yield $this->setRoleTypeAndProtection($row);
938  }
939  }
940 
941  public function getTypeId(string $a_type): int
942  {
943  $q = "SELECT obj_id FROM object_data " .
944  "WHERE title=" . $this->db->quote($a_type, 'text') . " AND type='typ'";
945  $r = $this->db->query($q);
946  while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
947  return (int) $row->obj_id;
948  }
949  return 0;
950  }
951 
958  public static function _getOperationIdsByName(array $operations): array
959  {
960  global $DIC;
961 
962  $ilDB = $DIC->database();
963  if ($operations === []) {
964  return [];
965  }
966 
967  $query = 'SELECT ops_id FROM rbac_operations ' .
968  'WHERE ' . $ilDB->in('operation', $operations, false, 'text');
969 
970  $res = $ilDB->query($query);
971  $ops_ids = [];
972  while ($row = $ilDB->fetchObject($res)) {
973  $ops_ids[] = (int) $row->ops_id;
974  }
975  return $ops_ids;
976  }
977 
981  public static function _getOperationIdByName(string $a_operation): int
982  {
983  global $DIC;
984 
985  $ilDB = $DIC->database();
986 
987  // Cache operation ids
988  if (!is_array(self::$_opsCache)) {
989  self::$_opsCache = [];
990 
991  $q = "SELECT ops_id, operation FROM rbac_operations";
992  $r = $ilDB->query($q);
993  while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
994  self::$_opsCache[$row->operation] = (int) $row->ops_id;
995  }
996  }
997 
998  // Get operation ID by name from cache
999  if (array_key_exists($a_operation, self::$_opsCache)) {
1000  return self::$_opsCache[$a_operation];
1001  }
1002  return 0;
1003  }
1004 
1010  public static function lookupCreateOperationIds(array $a_type_arr): array
1011  {
1012  global $DIC;
1013 
1014  $ilDB = $DIC->database();
1015 
1016  $operations = [];
1017  foreach ($a_type_arr as $type) {
1018  $operations[] = ('create_' . $type);
1019  }
1020 
1021  if ($operations === []) {
1022  return [];
1023  }
1024 
1025  $query = 'SELECT ops_id, operation FROM rbac_operations ' .
1026  'WHERE ' . $ilDB->in('operation', $operations, false, 'text');
1027 
1028  $res = $ilDB->query($query);
1029 
1030  $ops_ids = [];
1031  while ($row = $ilDB->fetchObject($res)) {
1032  $type_arr = explode('_', $row->operation);
1033  $type = $type_arr[1];
1034 
1035  $ops_ids[$type] = (int) $row->ops_id;
1036  }
1037  return $ops_ids;
1038  }
1039 
1043  public function isProtected(int $a_ref_id, int $a_role_id): bool
1044  {
1045  $query = 'SELECT protected FROM rbac_fa ' .
1046  'WHERE rol_id = ' . $this->db->quote($a_role_id, ilDBConstants::T_INTEGER);
1047  $res = $this->db->query($query);
1048  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1049  if ($row->protected === 'y') {
1050  return true;
1051  }
1052  }
1053  return false;
1054  }
1055 
1056  public function isBlockedAtPosition(int $a_role_id, int $a_ref_id): bool
1057  {
1058  $query = 'SELECT blocked from rbac_fa ' .
1059  'WHERE rol_id = ' . $this->db->quote($a_role_id, 'integer') . ' ' .
1060  'AND parent = ' . $this->db->quote($a_ref_id, 'integer');
1061  $res = $this->db->query($query);
1062  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1063  return (bool) $row->blocked;
1064  }
1065  return false;
1066  }
1067 
1072  public function isBlockedInUpperContext(int $a_role_id, int $a_ref_id): bool
1073  {
1074  global $DIC;
1075 
1076  $tree = $DIC['tree'];
1077 
1078  if ($this->isBlockedAtPosition($a_role_id, $a_ref_id)) {
1079  return false;
1080  }
1081  $query = 'SELECT parent from rbac_fa ' .
1082  'WHERE rol_id = ' . $this->db->quote($a_role_id, 'integer') . ' ' .
1083  'AND blocked = ' . $this->db->quote(1, 'integer');
1084  $res = $this->db->query($query);
1085 
1086  $parent_ids = [];
1087  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1088  $parent_ids[] = (int) $row->parent;
1089  }
1090 
1091  foreach ($parent_ids as $parent_id) {
1092  if ($tree->isGrandChild($parent_id, $a_ref_id)) {
1093  return true;
1094  }
1095  }
1096  return false;
1097  }
1098 
1099  // this method alters the protected status of role regarding the current user's role assignment
1100  // and current postion in the hierarchy.
1101  protected function __setProtectedStatus(array $a_parent_roles, array $a_role_hierarchy, int $a_ref_id): array
1102  {
1103  global $DIC;
1104 
1105  $rbacsystem = $DIC->rbac()->system();
1106  $ilUser = $DIC->user();
1107  if (in_array(SYSTEM_ROLE_ID, $this->assignedRoles($ilUser->getId()))) {
1108  $leveladmin = true;
1109  } else {
1110  $leveladmin = false;
1111  }
1112  foreach ($a_role_hierarchy as $role_id => $rolf_id) {
1113  if ($leveladmin == true) {
1114  $a_parent_roles[$role_id]['protected'] = false;
1115  continue;
1116  }
1117 
1118  if ($a_parent_roles[$role_id]['protected'] == true) {
1119  $arr_lvl_roles_user = array_intersect(
1120  $this->assignedRoles($ilUser->getId()),
1121  array_keys($a_role_hierarchy, $rolf_id)
1122  );
1123 
1124  foreach ($arr_lvl_roles_user as $lvl_role_id) {
1125  // check if role grants 'edit_permission' to parent
1126  $rolf = $a_parent_roles[$role_id]['parent'];
1127  if ($rbacsystem->checkPermission($rolf, $lvl_role_id, 'edit_permission')) {
1128  $a_parent_roles[$role_id]['protected'] = false;
1129  }
1130  }
1131  }
1132  }
1133  return $a_parent_roles;
1134  }
1135 
1140  public static function _getOperationList(string $a_type = ''): array
1141  {
1142  global $DIC;
1143 
1144  $ilDB = $DIC->database();
1145  $arr = [];
1146  if ($a_type) {
1147  $query = sprintf(
1148  'SELECT * FROM rbac_operations ' .
1149  'JOIN rbac_ta ON rbac_operations.ops_id = rbac_ta.ops_id ' .
1150  'JOIN object_data ON rbac_ta.typ_id = object_data.obj_id ' .
1151  'WHERE object_data.title = %s ' .
1152  'AND object_data.type = %s ' .
1153  'ORDER BY op_order ASC',
1154  $ilDB->quote($a_type, 'text'),
1155  $ilDB->quote('typ', 'text')
1156  );
1157  } else {
1158  $query = 'SELECT * FROM rbac_operations ORDER BY op_order ASC';
1159  }
1160  $res = $ilDB->query($query);
1161  while ($row = $ilDB->fetchAssoc($res)) {
1162  $arr[] = [
1163  "ops_id" => (int) $row['ops_id'],
1164  "operation" => $row['operation'],
1165  "desc" => $row['description'],
1166  "class" => $row['class'],
1167  "order" => (int) $row['op_order']
1168  ];
1169  }
1170  return $arr;
1171  }
1172 
1176  public static function _groupOperationsByClass(array $a_ops_arr): array
1177  {
1178  $arr = [];
1179  foreach ($a_ops_arr as $ops) {
1180  $arr[$ops['class']][] = ['ops_id' => (int) $ops['ops_id'],
1181  'name' => $ops['operation']
1182  ];
1183  }
1184  return $arr;
1185  }
1186 
1191  public function getObjectOfRole(int $a_role_id): int
1192  {
1193  // internal cache
1194  static $obj_cache = [];
1195 
1196  if (isset($obj_cache[$a_role_id]) && $obj_cache[$a_role_id]) {
1197  return $obj_cache[$a_role_id];
1198  }
1199 
1200  $query = 'SELECT obr.obj_id FROM rbac_fa rfa ' .
1201  'JOIN object_reference obr ON rfa.parent = obr.ref_id ' .
1202  'WHERE assign = ' . $this->db->quote('y', 'text') . ' ' .
1203  'AND rol_id = ' . $this->db->quote($a_role_id, 'integer') . ' ' .
1204  'AND deleted IS NULL';
1205 
1206  $res = $this->db->query($query);
1207  $obj_cache[$a_role_id] = 0;
1208  while ($row = $this->db->fetchObject($res)) {
1209  $obj_cache[$a_role_id] = (int) $row->obj_id;
1210  }
1211  return $obj_cache[$a_role_id];
1212  }
1213 
1214  public function getObjectReferenceOfRole(int $a_role_id): int
1215  {
1216  $query = 'SELECT parent p_ref FROM rbac_fa ' .
1217  'WHERE rol_id = ' . $this->db->quote($a_role_id, 'integer') . ' ' .
1218  'AND assign = ' . $this->db->quote('y', 'text');
1219 
1220  $res = $this->db->query($query);
1221  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1222  return (int) $row->p_ref;
1223  }
1224  return 0;
1225  }
1226 
1230  public function isRoleDeleted(int $a_role_id): bool
1231  {
1232  $rolf_list = $this->getFoldersAssignedToRole($a_role_id, false);
1233  $deleted = true;
1234  if ($rolf_list !== []) {
1235  foreach ($rolf_list as $rolf) {
1236  // only list roles that are not set to status "deleted"
1237  if (!$this->isDeleted($rolf)) {
1238  $deleted = false;
1239  break;
1240  }
1241  }
1242  }
1243  return $deleted;
1244  }
1245 
1246  public function getRolesForIDs(array $role_ids, bool $use_templates): array
1247  {
1248  $where = $this->__setTemplateFilter($use_templates);
1249  $query = "SELECT * FROM object_data " .
1250  "JOIN rbac_fa ON object_data.obj_id = rbac_fa.rol_id " .
1251  $where .
1252  "AND rbac_fa.assign = 'y' " .
1253  'AND ' . $this->db->in('object_data.obj_id', $role_ids, false, 'integer');
1254 
1255  $res = $this->db->query($query);
1256  $role_list = [];
1257  while ($row = $this->db->fetchAssoc($res)) {
1258  $row["desc"] = $row["description"];
1259  $row["user_id"] = (int) $row["owner"];
1260  $role_list[] = $row;
1261  }
1262  return $this->__setRoleType($role_list);
1263  }
1264 
1269  public function getOperationAssignment(): array
1270  {
1271  global $DIC;
1272 
1273  $this->db = $DIC['ilDB'];
1274 
1275  $query = 'SELECT ta.typ_id, obj.title, ops.ops_id, ops.operation FROM rbac_ta ta ' .
1276  'JOIN object_data obj ON obj.obj_id = ta.typ_id ' .
1277  'JOIN rbac_operations ops ON ops.ops_id = ta.ops_id ';
1278  $res = $this->db->query($query);
1279 
1280  $counter = 0;
1281  $info = [];
1282  while ($row = $this->db->fetchObject($res)) {
1283  $info[$counter]['typ_id'] = (int) $row->typ_id;
1284  $info[$counter]['type'] = $row->title;
1285  $info[$counter]['ops_id'] = (int) $row->ops_id;
1286  $info[$counter]['operation'] = $row->operation;
1287  $counter++;
1288  }
1289 
1290  return array_values($info);
1291  }
1292 
1296  public function isDeleteable(int $a_role_id, int $a_rolf_id): bool
1297  {
1298  if (!$this->isAssignable($a_role_id, $a_rolf_id)) {
1299  return false;
1300  }
1301  if ($a_role_id == SYSTEM_ROLE_ID or $a_role_id == ANONYMOUS_ROLE_ID) {
1302  return false;
1303  }
1304  if (str_starts_with(ilObject::_lookupTitle($a_role_id), 'il_')) {
1305  return false;
1306  }
1307  return true;
1308  }
1309 
1313  public function isSystemGeneratedRole(int $a_role_id): bool
1314  {
1315  $title = ilObject::_lookupTitle($a_role_id);
1316  return substr($title, 0, 3) == 'il_';
1317  }
1318 
1319  public function getParentOfRole(int $role_id, ?int $object_ref = null): ?int
1320  {
1321  global $DIC;
1323  $tree = $DIC['tree'];
1324 
1325  if ($object_ref === null || $object_ref === ROLE_FOLDER_ID) {
1326  return $this->getRoleFolderOfRole($role_id);
1327  }
1328 
1329 
1330  $path_ids = $tree->getPathId($object_ref);
1331  array_unshift($path_ids, ROLE_FOLDER_ID);
1332 
1333  while ($ref_id = array_pop($path_ids)) {
1334  $roles = $this->getRoleListByObject($ref_id, false);
1335  foreach ($roles as $role) {
1336  if ((int) $role['obj_id'] === $role_id) {
1337  return $ref_id;
1338  }
1339  }
1340  }
1341 
1342  return null;
1343  }
1344 
1345 
1346  public function getRoleFolderOfRole(int $a_role_id): int
1347  {
1348  if (ilObject::_lookupType($a_role_id) == 'role') {
1349  $and = ('AND assign = ' . $this->db->quote('y', 'text'));
1350  } else {
1351  $and = '';
1352  }
1353 
1354  $query = 'SELECT * FROM rbac_fa ' .
1355  'WHERE rol_id = ' . $this->db->quote($a_role_id, 'integer') . ' ' .
1356  $and;
1357  $res = $this->db->query($query);
1358  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1359  return (int) $row->parent;
1360  }
1361  return 0;
1362  }
1363 
1368  public function getUserPermissionsOnObject(int $a_user_id, int $a_ref_id): array
1369  {
1370  $query = "SELECT ops_id FROM rbac_pa JOIN rbac_ua " .
1371  "ON (rbac_pa.rol_id = rbac_ua.rol_id) " .
1372  "WHERE rbac_ua.usr_id = " . $this->db->quote($a_user_id, 'integer') . " " .
1373  "AND rbac_pa.ref_id = " . $this->db->quote($a_ref_id, 'integer') . " ";
1374 
1375  $res = $this->db->query($query);
1376  $all_ops = [];
1377  while ($row = $this->db->fetchObject($res)) {
1378  $ops = unserialize($row->ops_id, ['allowed_classes' => false]);
1379  $all_ops = array_merge($all_ops, $ops);
1380  }
1381  $all_ops = array_unique($all_ops);
1382 
1383  $set = $this->db->query("SELECT operation FROM rbac_operations " .
1384  " WHERE " . $this->db->in("ops_id", $all_ops, false, "integer"));
1385  $perms = [];
1386  while ($rec = $this->db->fetchAssoc($set)) {
1387  $perms[] = $rec["operation"];
1388  }
1389 
1390  return array_values(array_filter($perms));
1391  }
1392 
1396  public function setAssignedCacheEntry(int $a_role_id, int $a_user_id, bool $a_value): void
1397  {
1398  self::$is_assigned_cache[$a_role_id][$a_user_id] = $a_value;
1399  }
1400 
1401  public function getAssignedCacheEntry(int $a_role_id, int $a_user_id): bool
1402  {
1403  return self::$is_assigned_cache[$a_role_id][$a_user_id];
1404  }
1405 
1409  public function clearCaches(): void
1410  {
1411  self::$is_assigned_cache = [];
1412  self::$assigned_users_cache = [];
1413  }
1414 
1415  public static function _getCustomRBACOperationId(string $operation, \ilDBInterface $ilDB = null): ?int
1416  {
1417  if (!$ilDB) {
1418  global $DIC;
1419  $ilDB = $DIC->database();
1420  }
1421 
1422  $sql =
1423  "SELECT ops_id" . PHP_EOL
1424  . "FROM rbac_operations" . PHP_EOL
1425  . "WHERE operation = " . $ilDB->quote($operation, "text") . PHP_EOL
1426  ;
1427 
1428  $res = $ilDB->query($sql);
1429  if ($ilDB->numRows($res) == 0) {
1430  return null;
1431  }
1432 
1433  $row = $ilDB->fetchAssoc($res);
1434  return (int) $row["ops_id"] ?? null;
1435  }
1436 
1437  public static function _isRBACOperation(int $type_id, int $ops_id, \ilDBInterface $ilDB = null): bool
1438  {
1439  if (!$ilDB) {
1440  global $DIC;
1441  $ilDB = $DIC->database();
1442  }
1443 
1444  $sql =
1445  "SELECT typ_id" . PHP_EOL
1446  . "FROM rbac_ta" . PHP_EOL
1447  . "WHERE typ_id = " . $ilDB->quote($type_id, "integer") . PHP_EOL
1448  . "AND ops_id = " . $ilDB->quote($ops_id, "integer") . PHP_EOL
1449  ;
1450 
1451  return (bool) $ilDB->numRows($ilDB->query($sql));
1452  }
1453 } // END class.ilRbacReview
getRoleListByObject(int $a_ref_id, bool $a_templates=false)
Returns a list of roles in an container.
clearCaches()
Clear assigned users caches.
getOperationsOnType(int $a_typ_id)
all possible operations of a type
$res
Definition: ltiservices.php:69
getRolesForIDs(array $role_ids, bool $use_templates)
roleExists(string $a_title, int $a_id=0)
Checks if a role already exists.
static getLogger(string $a_component_id)
Get component logger.
getRoleOperationsOnObject(int $a_role_id, int $a_ref_id)
assignedUsers(int $a_rol_id)
get all assigned users to a given role
getOperation(int $ops_id)
get one operation by operation id
isBlockedAtPosition(int $a_role_id, int $a_ref_id)
getUserPermissionsOnObject(int $a_user_id, int $a_ref_id)
Get all user permissions on an object.
getRolesOfObject(int $a_ref_id, bool $a_assignable_only=false)
Get roles of object.
setRoleTypeAndProtection(array $role_list_entry)
const SYSTEM_ROLE_ID
Definition: constants.php:29
getOperationsOnTypeString(string $a_type)
all possible operations of a type
getLocalRoles(int $a_ref_id)
Get local roles of object.
__setTemplateFilter(bool $a_templates)
get roles and templates or only roles; returns string for where clause
isSystemGeneratedRole(int $a_role_id)
Check if the role is system generate role or role template.
static _getOperationIdsByName(array $operations)
get ops_id&#39;s by name.
getObjectReferenceOfRole(int $a_role_id)
getOperationAssignment()
get operation assignments
__setRoleType(array $a_role_list)
computes role type in role list array: global: roles in ROLE_FOLDER_ID local: assignable roles in oth...
isDeleted(int $a_node_id)
Checks if a rolefolder is set as deleted (negative tree_id)
getAllOperationsOfRole(int $a_rol_id, int $a_parent=0)
get all possible operations of a specific role The ref_id of the role folder (parent object) is neces...
setAssignedCacheEntry(int $a_role_id, int $a_user_id, bool $a_value)
set entry of assigned_chache
getLocalPolicies(int $a_ref_id)
Get all roles with local policies.
__getParentRoles(array $a_path, bool $a_templates)
Note: This function performs faster than the new getParentRoles function, because it uses database in...
static _getOperationList(string $a_type='')
get operation list by object type
static lookupCreateOperationIds(array $a_type_arr)
Lookup operation ids.
getOperationsByTypeAndClass(string $a_type, string $a_class)
Get operations by type and class.
getFoldersAssignedToRole(int $a_rol_id, bool $a_assignable=false)
Returns an array of objects assigned to a role.
static array $is_assigned_cache
getGlobalRolesArray()
get only &#39;global&#39; roles
getAssignableChildRoles(int $a_ref_id)
Get all assignable roles directly under a specific node.
$ref_id
Definition: ltiauth.php:66
static _lookupTitle(int $obj_id)
isRoleAssignedToObject(int $a_role_id, int $a_parent_id)
Check if role is assigned to an object.
ilDBInterface $db
getTypeId(string $a_type)
buildRoleType(array $role_list_entry)
getParentRoleIds(int $a_endnode_id, bool $a_templates=false)
Get an array of parent role ids of all parent roles, if last parameter is set true you get also all p...
global $DIC
Definition: shib_login.php:25
isAssigned(int $a_usr_id, int $a_role_id)
check if a specific user is assigned to specific role
isDeleteable(int $a_role_id, int $a_rolf_id)
Check if role is deleteable at a specific position.
getGlobalRoles()
get only &#39;global&#39; roles
getAssignableRolesInSubtree(int $ref_id)
Returns a list of assignable roles in a subtree of the repository.
getNumberOfAssignedUsers(array $a_roles)
Get the number of assigned users to roles (not properly deleted user accounts are not counted) ...
__setProtectedStatus(array $a_parent_roles, array $a_role_hierarchy, int $a_ref_id)
const ROLE_FOLDER_ID
Definition: constants.php:34
hasMultipleAssignments(int $a_role_id)
static _getCustomRBACOperationId(string $operation, \ilDBInterface $ilDB=null)
isBlockedInUpperContext(int $a_role_id, int $a_ref_id)
Check if role is blocked in upper context.
isGlobalRole(int $a_role_id)
Check if role is a global role.
static _getOperationIdByName(string $a_operation)
get operation id by name of operation
getGlobalAssignableRoles()
get only &#39;global&#39; roles (with flag &#39;assign_users&#39;)
const ANONYMOUS_ROLE_ID
Definition: constants.php:28
__construct()
Constructor public.
getOperations()
get all possible operations
static _groupOperationsByClass(array $a_ops_arr)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:24
getAssignableRolesGenerator(bool $a_templates=false, bool $a_internal_roles=false, string $title_filter='')
getAssignedCacheEntry(int $a_role_id, int $a_user_id)
getRolesOfRoleFolder(int $a_ref_id, bool $a_nonassignable=true)
get all roles of a role folder including linked local roles that are created due to stopped inheritan...
$q
Definition: shib_logout.php:18
assignedGlobalRoles(int $a_usr_id)
Get assigned global roles for an user.
getActiveOperationsOfRole(int $a_ref_id, int $a_role_id)
static array $_opsCache
isRoleDeleted(int $a_role_id)
return if role is only attached to deleted role folders
static _isRBACOperation(int $type_id, int $ops_id, \ilDBInterface $ilDB=null)
static _getAssignUsersStatus(int $a_role_id)
isAssignable(int $a_rol_id, int $a_ref_id)
Check if its possible to assign users.
static _lookupType(int $id, bool $reference=false)
getRolesByFilter(int $a_filter=0, int $a_user_id=0, string $title_filter='')
getOperationsOfRole(int $a_rol_id, string $a_type, int $a_parent=0)
get all possible operations of a specific role The ref_id of the role folder (parent object) is neces...
getRoleFolderOfRole(int $a_role_id)
getAssignableRoles(bool $a_templates=false, bool $a_internal_roles=false, string $title_filter='')
Returns a list of all assignable roles.
getObjectsWithStopedInheritance(int $a_rol_id, array $a_filter=[])
get all objects in which the inheritance of role with role_id was stopped the function returns all re...
buildProtectionByStringValue(string $value)
assignedRoles(int $a_usr_id)
get all assigned roles to a given user
getObjectOfRole(int $a_role_id)
Get object id of objects a role is assigned to.
static array $assigned_users_cache
isAssignedToAtLeastOneGivenRole(int $a_usr_id, array $a_role_ids)
check if a specific user is assigned to at least one of the given role ids.
isProtected(int $a_ref_id, int $a_role_id)
ref_id not used yet.
$r