ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilDidacticTemplateLocalPolicyAction.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
26{
27 public const TPL_ACTION_OVERWRITE = 1;
28 public const TPL_ACTION_INTERSECT = 2;
29 public const TPL_ACTION_ADD = 3;
30 public const TPL_ACTION_SUBTRACT = 4;
31 public const TPL_ACTION_UNION = 5;
32
34 private array $pattern = [];
37 private int $role_template_id = 0;
38
39 public function __construct(int $action_id = 0)
40 {
42 }
43
45 {
46 $this->pattern[] = $pattern;
47 }
48
53 public function setFilterPatterns(array $patterns): void
54 {
55 $this->pattern = $patterns;
56 }
57
62 public function getFilterPattern(): array
63 {
64 return $this->pattern;
65 }
66
67 public function setFilterType(int $a_type): void
68 {
69 $this->filter_type = $a_type;
70 }
71
72 public function getFilterType(): int
73 {
74 return $this->filter_type;
75 }
76
77 public function setRoleTemplateType(int $a_tpl_type): void
78 {
79 $this->role_template_type = $a_tpl_type;
80 }
81
82 public function getRoleTemplateType(): int
83 {
85 }
86
87 public function setRoleTemplateId(int $a_id): void
88 {
89 $this->role_template_id = $a_id;
90 }
91
92 public function getRoleTemplateId(): int
93 {
95 }
96
97 public function save(): int
98 {
99 if (!parent::save()) {
100 return 0;
101 }
102
103 $query = 'INSERT INTO didactic_tpl_alp (action_id,filter_type,template_type,template_id) ' .
104 'VALUES( ' .
105 $this->db->quote($this->getActionId(), 'integer') . ', ' .
106 $this->db->quote($this->getFilterType(), 'integer') . ', ' .
107 $this->db->quote($this->getRoleTemplateType(), 'integer') . ', ' .
108 $this->db->quote($this->getRoleTemplateId(), 'integer') . ' ' .
109 ')';
110 $this->db->manipulate($query);
111
112 foreach ($this->getFilterPattern() as $pattern) {
113 /* @var ilDidacticTemplateFilterPattern $pattern */
114 $pattern->setParentId($this->getActionId());
115 $pattern->setParentType(self::PATTERN_PARENT_TYPE);
116 $pattern->save();
117 }
118
119 return $this->getActionId();
120 }
121
122 public function delete(): void
123 {
124 parent::delete();
125 $query = 'DELETE FROM didactic_tpl_alp ' .
126 'WHERE action_id = ' . $this->db->quote($this->getActionId(), 'integer');
127 $this->db->manipulate($query);
128
129 foreach ($this->getFilterPattern() as $pattern) {
130 $pattern->delete();
131 }
132 }
133
134 public function apply(): bool
135 {
136 $source = $this->initSourceObject();
137 // Create a role folder for the new local policies
138 $roles = $this->filterRoles($source);
139
140 // Create local policy for filtered roles
141 foreach ($roles as $role_id => $role) {
142 $this->getLogger()->debug('Apply to role: ' . $role['title']);
143 $this->getLogger()->debug('Role parent: ' . $role['parent']);
144 $this->getLogger()->debug('Source ref_id: ' . $source->getRefId());
145
146 // No local policies for protected roles of higher context
147 if (
148 (int) $role['parent'] !== $source->getRefId() &&
149 $this->review->isProtected($role['parent'], $role_id)
150 ) {
151 $this->getLogger()->debug('Ignoring protected role.');
152 continue;
153 }
154 $this->createLocalPolicy($source, $role);
155 }
156
157 return true;
158 }
159
160 public function revert(): bool
161 {
162 $source = $this->initSourceObject();
163 $roles = $this->filterRoles($source);
164
165 // Delete local policy for filtered roles
166 foreach ($roles as $role_id => $role) {
167 // Do not delete local policies of auto generated roles
168 if (!$this->review->isGlobalRole($role['obj_id']) &&
169 $this->review->isAssignable($role['obj_id'], $source->getRefId()) &&
170 $this->review->isSystemGeneratedRole($role['obj_id'])) {
171 $this->getLogger()->debug('Reverting local policy of auto generated role: ' . $role['title']);
172 $this->revertLocalPolicy($source, $role);
173 } else {
174 $this->getLogger()->debug('Reverting local policy and deleting local role: ' . $role['title']);
175
176 // delete local role and change exiting objects
177 $this->admin->deleteLocalRole($role_id, $source->getRefId());
178
179 // Change existing object
180 $role_obj = new ilObjRole($role_id);
181
182 $protected = $this->review->isProtected($role['parent'], $role['rol_id']);
183
184 $role_obj->changeExistingObjects(
185 $source->getRefId(),
186 $protected ?
189 ['all']
190 );
191 }
192 }
193
194 return true;
195 }
196
197 public function getType(): int
198 {
200 }
201
202 public function toXml(ilXmlWriter $writer): void
203 {
204 $writer->xmlStartTag('localPolicyAction');
205
206 switch ($this->getFilterType()) {
208 $writer->xmlStartTag('roleFilter', ['source' => 'objId']);
209 break;
210
212 $writer->xmlStartTag('roleFilter', ['source' => 'parentRoles']);
213 break;
214
216 $writer->xmlStartTag('roleFilter', ['source' => 'localRoles']);
217 break;
218
220 default:
221 $writer->xmlStartTag('roleFilter', ['source' => 'title']);
222 break;
223 }
224
225 foreach ($this->getFilterPattern() as $pattern) {
226 $pattern->toXml($writer);
227 }
228 $writer->xmlEndTag('roleFilter');
229
230 $il_role_id = 'il_' . IL_INST_ID . '_' . ilObject::_lookupType($this->getRoleTemplateId()) . '_' . $this->getRoleTemplateId();
231
232 switch ($this->getRoleTemplateType()) {
234 $writer->xmlStartTag(
235 'localPolicyTemplate',
236 [
237 'type' => 'overwrite',
238 'id' => $il_role_id
239 ]
240 );
241 break;
242
244 $writer->xmlStartTag(
245 'localPolicyTemplate',
246 [
247 'type' => 'intersect',
248 'id' => $il_role_id
249 ]
250 );
251 break;
252
254 $writer->xmlStartTag(
255 'localPolicyTemplate',
256 [
257 'type' => 'union',
258 'id' => $il_role_id
259 ]
260 );
261 break;
262 }
263
264 $exp = new ilRoleXmlExport();
265 $exp->setMode(ilRoleXmlExport::MODE_DTPL);
266 $exp->addRole($this->getRoleTemplateId(), ROLE_FOLDER_ID);
267 $exp->write();
268 $writer->appendXML($exp->xmlDumpMem(false));
269 $writer->xmlEndTag('localPolicyTemplate');
270 $writer->xmlEndTag('localPolicyAction');
271 }
272
273 public function __clone()
274 {
275 parent::__clone();
276
277 $clones = [];
278 foreach ($this->getFilterPattern() as $pattern) {
279 $clones[] = clone $pattern;
280 }
281 $this->setFilterPatterns($clones);
282 }
283
284 public function read(): void
285 {
286 parent::read();
287 $query = 'SELECT * FROM didactic_tpl_alp ' .
288 'WHERE action_id = ' . $this->db->quote($this->getActionId(), ilDBConstants::T_INTEGER);
289 $res = $this->db->query($query);
290 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
291 $this->setFilterType((int) $row->filter_type);
292 $this->setRoleTemplateType((int) $row->template_type);
293 $this->setRoleTemplateId((int) $row->template_id);
294 }
295 // Read filter
297 $this->getActionId(),
298 self::PATTERN_PARENT_TYPE
299 ) as $pattern) {
300 $this->addFilterPattern($pattern);
301 }
302 }
303
304 protected function createLocalPolicy(ilObject $source, array $role): bool
305 {
306 // fetch role information
307 $role_data = [];
308 foreach ($this->review->getParentRoleIds($source->getRefId()) as $role_id => $tmp_role) {
309 if ((int) $role_id === (int) $role['obj_id']) {
310 $role_data = $tmp_role;
311 }
312 }
313
314 // Add local policy
315 if (!$this->review->isRoleAssignedToObject((int) $role['obj_id'], $source->getRefId())) {
316 $this->admin->assignRoleToFolder(
317 (int) $role['obj_id'],
318 $source->getRefId(),
319 'n'
320 );
321 }
322
323 // do nothing if role is protected in higher context
324 if (
325 (int) $role['parent'] !== $source->getRefId() &&
326 $this->review->isProtected($source->getRefId(), (int) $role['obj_id'])
327 ) {
328 $this->getLogger()->info('Ignoring protected role: ' . $role['title']);
329 return false;
330 }
331
332 switch ($this->getRoleTemplateType()) {
334
335 $this->logger->info('Using ilRbacAdmin::copyRolePermissionUnion()');
336 $this->admin->copyRolePermissionUnion(
337 (int) $role_data['obj_id'],
338 (int) $role_data['parent'],
339 $this->getRoleTemplateId(),
341 (int) $role_data['obj_id'],
342 $source->getRefId()
343 );
344 break;
345
347
348 $this->logger->info('Using ilRbacAdmin::copyRoleTemplatePermission()');
349 $this->admin->copyRoleTemplatePermissions(
350 $this->getRoleTemplateId(),
352 $source->getRefId(),
353 (int) $role_data['obj_id'],
354 true
355 );
356 break;
357
359
360 $this->logger->info('Using ilRbacAdmin::copyRolePermissionIntersection()' . $this->getRoleTemplateId());
361 $this->admin->copyRolePermissionIntersection(
362 (int) $role_data['obj_id'],
363 (int) $role_data['parent'],
364 $this->getRoleTemplateId(),
366 $source->getRefId(),
367 (int) $role_data['obj_id']
368 );
369 break;
370 }
371 // Change existing object
372 $role_obj = new ilObjRole((int) $role_data['obj_id']);
373 $role_obj->changeExistingObjects(
374 $source->getRefId(),
376 ['all']
377 );
378
379 return true;
380 }
381
382 protected function revertLocalPolicy(ilObject $source, array $role): bool
383 {
384 $this->logger->info('Reverting policy for role ' . $role['title']);
385 // Local policies can only be reverted for auto generated roles. Otherwise the
386 // original role settings are unknown
387 if (strpos($role['title'], 'il_') !== 0) {
388 $this->logger->warning('Cannot revert local policy for role ' . $role['title']);
389 return false;
390 }
391
392 // No local policies
393 if (!$this->review->getLocalPolicies($source->getRefId())) {
394 return false;
395 }
396
397 $exploded_title = explode('_', $role['title']);
398 $rolt_title = $exploded_title[0] . '_' . $exploded_title[1] . '_' . $exploded_title[2];
399
400 // Lookup role template
401 $query = 'SELECT obj_id FROM object_data ' .
402 'WHERE title = ' . $this->db->quote($rolt_title, 'text') . ' ' .
403 'AND type = ' . $this->db->quote('rolt', 'text');
404 $res = $this->db->query($query);
405 $rolt_id = 0;
406 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
407 $rolt_id = (int) $row->obj_id;
408 }
409
410 // No template found
411 if (!$rolt_id) {
412 return false;
413 }
414
415 $this->admin->copyRoleTemplatePermissions(
416 $rolt_id,
418 $source->getRefId(),
419 (int) $role['obj_id'],
420 true
421 );
422
423 // Change existing object
424 $role_obj = new ilObjRole((int) $role['obj_id']);
425 $role_obj->changeExistingObjects(
426 $source->getRefId(),
428 ['all']
429 );
430
431 return true;
432 }
433}
Abstract class for template actions.
static lookupPatternsByParentId(int $a_parent_id, string $a_parent_type)
Represents a filter pattern for didactic template actions.
revert()
Implement everthing that is necessary to revert a didactic template return bool.
save()
Write action to db Overwrite for filling additional db fields.
addFilterPattern(ilDidacticTemplateFilterPattern $pattern)
Class ilObjRole.
const MODE_PROTECTED_DELETE_LOCAL_POLICIES
const MODE_UNPROTECTED_DELETE_LOCAL_POLICIES
Class ilObject Basic functions for all objects.
static _lookupType(int $id, bool $reference=false)
Xml export of roles and role templates.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
xmlEndTag(string $tag)
Writes an endtag.
appendXML(string $a_str)
append xml string to document
xmlStartTag(string $tag, ?array $attrs=null, bool $empty=false, bool $encode=true, bool $escape=true)
Writes a starttag.
const IL_INST_ID
Definition: constants.php:40
const ROLE_FOLDER_ID
Definition: constants.php:34
$res
Definition: ltiservices.php:69
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc