1<?php 2/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4include_once('./Services/Table/classes/class.ilTable2GUI.php'); 5include_once './Services/AccessControl/classes/class.ilPermissionGUI.php'; 6require_once('./Services/Repository/classes/class.ilObjectPlugin.php'); 7 8/** 9* Table for object role permissions 10* 11* @author Stefan Meyer <meyer@leifos.com> 12* 13* @version $Id$ 14* 15* @ingroup ServicesAccessControl 16*/ 17class ilObjectRolePermissionTableGUI extends ilTable2GUI 18{ 19 const ROLE_FILTER_ALL = 1; 20 const ROLE_FILTER_GLOBAL = 2; 21 const ROLE_FILTER_LOCAL = 3; 22 const ROLE_FILTER_LOCAL_POLICY = 4; 23 const ROLE_FILTER_LOCAL_OBJECT = 5; 24 25 private $ref_id = null; 26 private $roles = array(); 27 28 private $tree_path_ids = array(); 29 30 private $activeOperations = array(); 31 private $visible_roles = array(); 32 33 /** 34 * Constructor 35 * @return 36 */ 37 public function __construct($a_parent_obj, $a_parent_cmd, $a_ref_id) 38 { 39 global $DIC; 40 41 $ilCtrl = $DIC['ilCtrl']; 42 $rbacreview = $DIC['rbacreview']; 43 $tpl = $DIC['tpl']; 44 $tree = $DIC['tree']; 45 46 parent::__construct($a_parent_obj, $a_parent_cmd); 47 48 $this->lng->loadLanguageModule('rbac'); 49 50 $this->ref_id = $a_ref_id; 51 $this->tree_path_ids = $tree->getPathId($this->ref_id); 52 53 $this->setId('objroleperm_' . $this->ref_id); 54 55 $tpl->addJavaScript('./Services/AccessControl/js/ilPermSelect.js'); 56 57 $this->setTitle($this->lng->txt('permission_settings')); 58 $this->setEnableHeader(true); 59 $this->disable('sort'); 60 $this->setFormAction($ilCtrl->getFormAction($a_parent_obj, $a_parent_cmd)); 61 $this->disable('numinfo'); 62 $this->setRowTemplate("tpl.obj_role_perm_row.html", "Services/AccessControl"); 63 $this->setLimit(100); 64 $this->setShowRowsSelector(false); 65 $this->setDisableFilterHiding(true); 66 $this->setNoEntriesText($this->lng->txt('msg_no_roles_of_type')); 67 68 $this->addCommandButton('savePermissions', $this->lng->txt('save')); 69 70 $this->initFilter(); 71 } 72 73 74 /** 75 * Get tree path ids 76 * @return array 77 */ 78 public function getPathIds() 79 { 80 return (array) $this->tree_path_ids; 81 } 82 83 /** 84 * Get ref id of current object 85 * @return 86 */ 87 public function getRefId() 88 { 89 return $this->ref_id; 90 } 91 92 /** 93 * Get obj id 94 * @return 95 */ 96 public function getObjId() 97 { 98 return ilObject::_lookupObjId($this->getRefId()); 99 } 100 101 /** 102 * get obj type 103 * @return 104 */ 105 public function getObjType() 106 { 107 return ilObject::_lookupType($this->getObjId()); 108 } 109 110 /** 111 * Add active operation 112 * @param int $a_ops_id 113 * @return 114 */ 115 public function addActiveOperation($a_ops_id) 116 { 117 $this->activeOperations[] = $a_ops_id; 118 } 119 120 /** 121 * get active operations 122 * @return 123 */ 124 public function getActiveOperations() 125 { 126 return (array) $this->activeOperations; 127 } 128 129 /** 130 * Set Visible roles 131 * @param object $a_ar 132 * @return 133 */ 134 public function setVisibleRoles($a_ar) 135 { 136 $this->visible_roles = $a_ar; 137 } 138 139 /** 140 * get visible roles 141 * @return 142 */ 143 public function getVisibleRoles() 144 { 145 return $this->visible_roles; 146 } 147 148 /** 149 * Init role filter 150 * @return 151 */ 152 public function initFilter() 153 { 154 global $DIC; 155 156 $tree = $DIC['tree']; 157 158 $roles = $this->addFilterItemByMetaType( 159 'role', 160 ilTable2GUI::FILTER_SELECT 161 ); 162 163 // Limit filter to local roles only for objects with group or course in path 164 if (!$roles->getValue()) { 165 if ($tree->checkForParentType($this->getRefId(), 'crs') or 166 $tree->checkForParentType($this->getRefId(), 'grp')) { 167 $roles->setValue(self::ROLE_FILTER_LOCAL); 168 } else { 169 $roles->setValue(self::ROLE_FILTER_ALL); 170 } 171 } 172 173 174 $roles->setOptions( 175 array( 176 self::ROLE_FILTER_ALL => $this->lng->txt('filter_all_roles'), 177 self::ROLE_FILTER_GLOBAL => $this->lng->txt('filter_global_roles'), 178 self::ROLE_FILTER_LOCAL => $this->lng->txt('filter_local_roles'), 179 self::ROLE_FILTER_LOCAL_POLICY => $this->lng->txt('filter_roles_local_policy'), 180 self::ROLE_FILTER_LOCAL_OBJECT => $this->lng->txt('filter_local_roles_object') 181 ) 182 ); 183 } 184 185 /** 186 * Fill one permission row 187 * @param object $row 188 * @return 189 */ 190 public function fillRow($row) 191 { 192 global $DIC; 193 194 $objDefinition = $DIC['objDefinition']; 195 196 197 // local policy 198 if (isset($row['show_local_policy_row'])) { 199 foreach ($row['roles'] as $role_id => $role_info) { 200 $this->tpl->setCurrentBlock('role_option'); 201 $this->tpl->setVariable('INHERIT_ROLE_ID', $role_id); 202 $this->tpl->setVariable('INHERIT_CHECKED', $role_info['local_policy'] ? 'checked=checked' : ''); 203 $this->tpl->setVariable('INHERIT_DISABLED', ($role_info['protected'] or $role_info['isLocal'] or $role_info['blocked']) ? 'disabled="disabled"' : ''); 204 $this->tpl->setVariable('TXT_INHERIT', $this->lng->txt('rbac_local_policy')); 205 $this->tpl->setVariable('INHERIT_LONG', $this->lng->txt('perm_use_local_policy_desc')); 206 $this->tpl->parseCurrentBlock(); 207 } 208 return true; 209 } 210 // protected 211 if (isset($row['show_protected_row'])) { 212 foreach ($row['roles'] as $role_id => $role_info) { 213 $this->tpl->setCurrentBlock('role_protect'); 214 $this->tpl->setVariable('PROTECT_ROLE_ID', $role_id); 215 $this->tpl->setVariable('PROTECT_CHECKED', $role_info['protected_status'] ? 'checked=checked' : ''); 216 $this->tpl->setVariable('PROTECT_DISABLED', $role_info['protected_allowed'] ? '' : 'disabled="disabled"'); 217 $this->tpl->setVariable('TXT_PROTECT', $this->lng->txt('role_protect_permissions')); 218 $this->tpl->setVariable('PROTECT_LONG', $this->lng->txt('role_protect_permissions_desc')); 219 $this->tpl->parseCurrentBlock(); 220 } 221 return true; 222 } 223 224 // block role 225 if (isset($row['show_block_row'])) { 226 foreach ($this->getVisibleRoles() as $counter => $role_info) { 227 $this->tpl->setCurrentBlock('role_block'); 228 $this->tpl->setVariable('BLOCK_ROLE_ID', $role_info['obj_id']); 229 $this->tpl->setVariable('TXT_BLOCK', $this->lng->txt('role_block_role')); 230 $this->tpl->setVariable('BLOCK_LONG', $this->lng->txt('role_block_role_desc')); 231 if ($role_info['blocked']) { 232 $this->tpl->setVariable('BLOCK_CHECKED', 'checked="checked"'); 233 } 234 if ( 235 ($role_info['protected'] == 'y') || 236 ($role_info['assign'] == 'y' and ($role_info['parent'] == $this->getRefId())) 237 ) { 238 $this->tpl->setVariable('BLOCK_DISABLED', 'disabled="disabled'); 239 } 240 241 $this->tpl->parseCurrentBlock(); 242 } 243 return true; 244 } 245 246 // Select all 247 if (isset($row['show_select_all'])) { 248 foreach ($this->getVisibleRoles() as $role) { 249 $this->tpl->setCurrentBlock('role_select_all'); 250 $this->tpl->setVariable('JS_ROLE_ID', $role['obj_id']); 251 $this->tpl->setVariable('JS_SUBID', $row['subtype']); 252 $this->tpl->setVariable('JS_ALL_PERMS', "['" . implode("','", $row['ops']) . "']"); 253 $this->tpl->setVariable('JS_FORM_NAME', $this->getFormName()); 254 $this->tpl->setVariable('TXT_SEL_ALL', $this->lng->txt('select_all')); 255 $this->tpl->parseCurrentBlock(); 256 } 257 return true; 258 } 259 260 // Object permissions 261 if (isset($row['show_start_info'])) { 262 $this->tpl->setCurrentBlock('section_info'); 263 $this->tpl->setVariable('SECTION_TITLE', $this->lng->txt('perm_class_object')); 264 $this->tpl->setVariable('SECTION_DESC', $this->lng->txt('perm_class_object_desc')); 265 $this->tpl->parseCurrentBlock(); 266 267 return true; 268 } 269 270 if (isset($row['show_create_info'])) { 271 $this->tpl->setCurrentBlock('section_info'); 272 $this->tpl->setVariable('SECTION_TITLE', $this->lng->txt('perm_class_create')); 273 $this->tpl->setVariable('SECTION_DESC', $this->lng->txt('perm_class_create_desc')); 274 $this->tpl->parseCurrentBlock(); 275 276 return true; 277 } 278 279 foreach ((array) $row['roles'] as $role_id => $role_info) { 280 $perm = ""; 281 $this->tpl->setCurrentBlock('role_td'); 282 $this->tpl->setVariable('PERM_ROLE_ID', $role_id); 283 $this->tpl->setVariable('PERM_PERM_ID', $row['perm']['ops_id']); 284 285 286 if (substr($row['perm']['operation'], 0, 6) == 'create') { 287 if ($objDefinition->isPlugin(substr($row['perm']['operation'], 7))) { 288 $perm = ilObjectPlugin::lookupTxtById( 289 substr($row['perm']['operation'], 7), 290 "obj_" . substr($row['perm']['operation'], 7) 291 ); 292 } else { 293 $perm = $this->lng->txt('obj_' . substr($row['perm']['operation'], 7)); 294 } 295 } else { 296 if ($objDefinition->isPlugin($this->getObjType())) { 297 if (ilPlugin::langExitsById($this->getObjType(), $row['perm']['operation'])) { 298 $perm = ilObjectPlugin::lookupTxtById($this->getObjType(), $row['perm']['operation']); 299 } 300 } 301 302 if (!$perm) { 303 if ($this->lng->exists($this->getObjType() . '_' . $row['perm']['operation'] . '_short')) { 304 $perm = $this->lng->txt($this->getObjType() . '_' . $row['perm']['operation'] . '_short'); 305 } else { 306 $perm = $this->lng->txt($row['perm']['operation']); 307 } 308 } 309 } 310 311 $this->tpl->setVariable('TXT_PERM', $perm); 312 313 if ($objDefinition->isPlugin($this->getObjType())) { 314 $this->tpl->setVariable('PERM_LONG', ilObjectPlugin::lookupTxtById( 315 $this->getObjType(), 316 $this->getObjType() . "_" . $row['perm']['operation'] 317 )); 318 } elseif (substr($row['perm']['operation'], 0, 6) == 'create') { 319 $this->tpl->setVariable('PERM_LONG', $this->lng->txt('rbac_' . $row['perm']['operation'])); 320 } else { 321 $this->tpl->setVariable('PERM_LONG', $this->lng->txt($this->getObjType() . '_' . $row['perm']['operation'])); 322 } 323 324 if ($role_info['protected'] || $role_info['blocked']) { 325 $this->tpl->setVariable('PERM_DISABLED', 'disabled="disabled"'); 326 } 327 if ($role_info['permission_set']) { 328 $this->tpl->setVariable('PERM_CHECKED', 'checked="checked"'); 329 } 330 331 $this->tpl->parseCurrentBlock(); 332 } 333 } 334 335 336 /** 337 * Parse 338 * @return 339 */ 340 public function parse() 341 { 342 global $DIC; 343 344 $rbacreview = $DIC['rbacreview']; 345 $objDefinition = $DIC['objDefinition']; 346 347 $this->initColumns(); 348 349 $perms = array(); 350 $roles = array(); 351 352 if (!count($this->getVisibleRoles())) { 353 return $this->setData(array()); 354 } 355 356 // Read operations of role 357 $operations = array(); 358 foreach ($this->getVisibleRoles() as $role_data) { 359 $operations[$role_data['obj_id']] = $rbacreview->getActiveOperationsOfRole($this->getRefId(), $role_data['obj_id']); 360 } 361 362 $counter = 0; 363 364 // Local policy 365 if (ilPermissionGUI::hasContainerCommands($this->getObjType())) { 366 $roles = array(); 367 $local_roles = $rbacreview->getRolesOfObject($this->getRefId()); 368 foreach ($this->getVisibleRoles() as $role_id => $role_data) { 369 $roles[$role_data['obj_id']] = array( 370 'blocked' => $role_data['blocked'], 371 'protected' => $role_data['protected'], 372 'local_policy' => in_array($role_data['obj_id'], $local_roles), 373 'isLocal' => ($this->getRefId() == $role_data['parent']) && $role_data['assign'] == 'y' 374 ); 375 } 376 $perms[$counter]['roles'] = $roles; 377 $perms[$counter]['show_local_policy_row'] = 1; 378 379 $counter++; 380 } 381 382 // Protect permissions 383 if (ilPermissionGUI::hasContainerCommands($this->getObjType())) { 384 $roles = array(); 385 foreach ($this->getVisibleRoles() as $role_id => $role_data) { 386 $roles[$role_data['obj_id']] = array( 387 'blocked' => $role_data['blocked'], 388 'protected_allowed' => $rbacreview->isAssignable($role_data['obj_id'], $this->getRefId()), 389 'protected_status' => $rbacreview->isProtected($role_data['parent'], $role_data['obj_id']), 390 'isLocal' => ($this->getRefId() == $role_data['parent']) && $role_data['assign'] == 'y' 391 ); 392 } 393 $perms[$counter]['roles'] = $roles; 394 $perms[$counter]['show_protected_row'] = 1; 395 396 $counter++; 397 } 398 // Block role 399 if (ilPermissionGUI::hasContainerCommands($this->getObjType())) { 400 $perms[$counter++]['show_block_row'] = 1; 401 } 402 403 404 if (ilPermissionGUI::hasContainerCommands($this->getObjType())) { 405 $perms[$counter++]['show_start_info'] = true; 406 } 407 408 // no creation permissions 409 $no_creation_operations = array(); 410 foreach ($rbacreview->getOperationsByTypeAndClass($this->getObjType(), 'object') as $operation) { 411 $this->addActiveOperation($operation); 412 $no_creation_operations[] = $operation; 413 414 $roles = array(); 415 foreach ($this->getVisibleRoles() as $role_data) { 416 $roles[$role_data['obj_id']] = 417 array( 418 'blocked' => $role_data['blocked'], 419 'protected' => $role_data['protected'], 420 'permission_set' => in_array($operation, (array) $operations[$role_data['obj_id']]), 421 'isLocal' => ($this->getRefId() == $role_data['parent']) && $role_data['assign'] == 'y' 422 ); 423 } 424 425 $op = $rbacreview->getOperation($operation); 426 427 $perms[$counter]['roles'] = $roles; 428 $perms[$counter]['perm'] = $op; 429 $counter++; 430 } 431 432 /* 433 * Select all 434 */ 435 if ($no_creation_operations) { 436 $perms[$counter]['show_select_all'] = 1; 437 $perms[$counter]['ops'] = $no_creation_operations; 438 $perms[$counter]['subtype'] = 'nocreation'; 439 $counter++; 440 } 441 442 443 if ($objDefinition->isContainer($this->getObjType())) { 444 $perms[$counter++]['show_create_info'] = true; 445 } 446 447 // Get creatable objects 448 $objects = $objDefinition->getCreatableSubObjects($this->getObjType()); 449 $ops_ids = ilRbacReview::lookupCreateOperationIds(array_keys($objects)); 450 $creation_operations = array(); 451 foreach ($objects as $type => $info) { 452 $ops_id = $ops_ids[$type]; 453 454 if (!$ops_id) { 455 continue; 456 } 457 458 $this->addActiveOperation($ops_id); 459 $creation_operations[] = $ops_id; 460 461 $roles = array(); 462 foreach ($this->getVisibleRoles() as $role_data) { 463 $roles[$role_data['obj_id']] = 464 array( 465 'blocked' => $role_data['blocked'], 466 'protected' => $role_data['protected'], 467 'permission_set' => in_array($ops_id, (array) $operations[$role_data['obj_id']]), 468 'isLocal' => ($this->getRefId() == $role_data['parent']) && $role_data['assign'] == 'y' 469 470 ); 471 } 472 473 $op = $rbacreview->getOperation($ops_id); 474 475 $perms[$counter]['roles'] = $roles; 476 $perms[$counter]['perm'] = $op; 477 $counter++; 478 } 479 480 481 482 // Select all 483 if (count($creation_operations)) { 484 $perms[$counter]['show_select_all'] = 1; 485 $perms[$counter]['ops'] = $creation_operations; 486 $perms[$counter]['subtype'] = 'creation'; 487 $counter++; 488 } 489 490 $this->setData($perms); 491 } 492 493 /** 494 * init Columns 495 * @return 496 */ 497 protected function initColumns() 498 { 499 global $DIC; 500 501 $rbacreview = $DIC['rbacreview']; 502 $ilCtrl = $DIC['ilCtrl']; 503 504 $roles = $rbacreview->getParentRoleIds($this->getRefId()); 505 $roles = $this->getParentObject()->applyRoleFilter( 506 $roles, 507 $this->getFilterItemByPostVar('role')->getValue() 508 ); 509 510 $possible_roles = array(); 511 foreach ($roles as $role) { 512 if ($rbacreview->isBlockedInUpperContext($role['obj_id'], $this->getRefId())) { 513 ilLoggerFactory::getLogger('ac')->debug('Ignoring blocked role: ' . $role['obj_id']); 514 continue; 515 } 516 $possible_roles[] = $role; 517 } 518 519 520 if (count($possible_roles)) { 521 $column_width = 100 / count($possible_roles); 522 $column_width .= '%'; 523 } else { 524 $column_widht = "0%"; 525 } 526 527 $all_roles = array(); 528 foreach ($possible_roles as $role) { 529 if ($role['obj_id'] == SYSTEM_ROLE_ID) { 530 continue; 531 } 532 533 $role['blocked'] = (bool) $rbacreview->isBlockedAtPosition($role['obj_id'], $this->getRefId()); 534 $role['role_type'] = $rbacreview->isGlobalRole($role['obj_id']) ? 'global' : 'local'; 535 536 // TODO check filter 537 $this->addColumn( 538 $this->createTitle($role), 539 $role['obj_id'], 540 '', 541 '', 542 false, 543 $this->createTooltip($role) 544 ); 545 $all_roles[] = $role; 546 } 547 548 $this->setVisibleRoles($all_roles); 549 return true; 550 } 551 552 /** 553 * Create a linked title for roles with local policy 554 * @param object $role 555 * @return 556 */ 557 protected function createTooltip($role) 558 { 559 global $DIC; 560 561 $rbacreview = $DIC['rbacreview']; 562 $tree = $DIC['tree']; 563 $objDefinition = $DIC['objDefinition']; 564 565 #vd($role); 566 $protected_status = $rbacreview->isProtected($role['parent'], $role['obj_id']) ? 'protected_' : ''; 567 if ($role['role_type'] == 'global') { 568 $tp = $this->lng->txt('perm_' . $protected_status . 'global_role'); 569 } else { 570 $tp = $this->lng->txt('perm_' . $protected_status . 'local_role'); 571 } 572 573 $inheritance_seperator = ': '; 574 575 // Show create at info 576 if ( 577 ($role['assign'] == 'y' and $role['role_type'] != 'global') or 578 ($role['assign'] == 'n' and $role['role_type'] != 'global') 579 ) { 580 $tp .= ': '; 581 582 $obj = $rbacreview->getObjectOfRole($role['obj_id']); 583 if ($obj) { 584 $type = ilObject::_lookupType($this->getRefId(), true); 585 if ($objDefinition->isPlugin($type)) { 586 $type_text = ilObjectPlugin::lookupTxtById($type, 'obj_' . $type); 587 } else { 588 $type_text = $this->lng->txt('obj_' . ilObject::_lookupType($obj)); 589 } 590 591 $tp .= sprintf( 592 $this->lng->txt('perm_role_path_info_created'), 593 $type_text, 594 ilObject::_lookupTitle($obj) 595 ); 596 $inheritance_seperator = ', '; 597 } 598 } 599 600 $path_hierarchy = $rbacreview->getObjectsWithStopedInheritance( 601 $role['obj_id'], 602 $tree->getPathId($this->getRefId()) 603 ); 604 605 $reduced_path_hierarchy = (array) array_diff( 606 $path_hierarchy, 607 array( 608 $this->getRefId(), 609 $rbacreview->getObjectReferenceOfRole($role['obj_id']) 610 ) 611 ); 612 613 614 // Inheritance 615 if ($role['assign'] == 'n' and count($reduced_path_hierarchy)) { 616 $tp .= $inheritance_seperator; 617 618 $parent = end($reduced_path_hierarchy); 619 $p_type = ilObject::_lookupType(ilObject::_lookupObjId($parent)); 620 $p_title = ilObject::_lookupTitle(ilObject::_lookupObjId($parent)); 621 $tp .= sprintf($this->lng->txt('perm_role_path_info_inheritance'), $this->lng->txt('obj_' . $p_type), $p_title); 622 } 623 624 return $tp; 625 } 626 627 /** 628 * Create (linked) title 629 * @param array $role 630 * @return 631 */ 632 protected function createTitle($role) 633 { 634 global $DIC; 635 636 $ilCtrl = $DIC['ilCtrl']; 637 $objDefinition = $DIC['objDefinition']; 638 639 include_once './Services/AccessControl/classes/class.ilObjRole.php'; 640 $role_title = ilObjRole::_getTranslation($role['title']); 641 642 // No local policies 643 if ($role['parent'] != $this->getRefId()) { 644 return $role_title; 645 } 646 647 $type = ilObject::_lookupType($this->getRefId(), true); 648 if ($objDefinition->isPlugin($type)) { 649 if (preg_match("/^il_./", $role["title"])) { 650 $role_title = ilObjectPlugin::lookupTxtById($type, ilObjRole::_removeObjectId($role["title"])); 651 } 652 } 653 654 if ($role['blocked']) { 655 return $role_title; 656 } 657 $ilCtrl->setParameterByClass('ilobjrolegui', 'obj_id', $role['obj_id']); 658 659 return '<a class="tblheader" href="' . $ilCtrl->getLinkTargetByClass('ilobjrolegui', '') . '" >' . $role_title . '</a>'; 660 } 661} 662