ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
class.ilSoapUtils.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
23
29{
30 public function ignoreUserAbort(): int
31 {
32 return ignore_user_abort(true);
33 }
34
35 public function disableSOAPCheck(): void
36 {
37 $this->soap_check = false;
38 }
39
43 public function saveTempFileAsMediaObject(string $sid, string $name, string $tmp_name)
44 {
45 $this->initAuth($sid);
46 $this->initIlias();
47
48 if (!$this->checkSession($sid)) {
49 return $this->raiseError($this->getMessage(), $this->getMessageCode());
50 }
51
52 return ilObjMediaObject::_saveTempFileAsMediaObject($name, $tmp_name);
53 }
54
58 public function getMobsOfObject(string $sid, string $a_type, int $a_id)
59 {
60 $this->initAuth($sid);
61 $this->initIlias();
62
63 if (!$this->checkSession($sid)) {
64 return $this->raiseError($this->getMessage(), $this->getMessageCode());
65 }
66
67 return ilObjMediaObject::_getMobsOfObject($a_type, $a_id);
68 }
69
73 public function ilCloneDependencies(string $sid, int $copy_identifier, bool $is_initialized = false)
74 {
75 if (!$is_initialized) {
76 $this->initAuth($sid);
77 $this->initIlias();
78
79 if (!$this->checkSession($sid)) {
80 return $this->raiseError($this->getMessage(), $this->getMessageCode());
81 }
82 }
83
84 global $DIC;
85
86 $ilLog = $DIC['ilLog'];
87 $ilUser = $DIC['ilUser'];
88
89 $cp_options = ilCopyWizardOptions::_getInstance($copy_identifier);
90
91 // Check owner of copy procedure
92 if (!$cp_options->checkOwner($ilUser->getId())) {
93 ilLoggerFactory::getLogger('obj')->error('Permission check failed for user id: ' . $ilUser->getId() . ', copy id: ' . $copy_identifier);
94 return false;
95 }
96
97 // Fetch first node
98 if (($node = $cp_options->fetchFirstDependenciesNode()) === null) {
99 $cp_options->deleteAll();
100 ilLoggerFactory::getLogger('obj')->info('Finished copy step 2. Copy completed');
101 return true;
102 }
103
104 // Check options of this node
105 $options = $cp_options->getOptions((int) $node['child']);
106 $new_ref_id = 0;
107 switch ($options['type']) {
109 ilLoggerFactory::getLogger('obj')->debug(': Omitting node: ' . $node['obj_id'] . ', ' . $node['title'] . ', ' . $node['type']);
110 $this->callNextDependency($sid, $cp_options);
111 break;
112
114 ilLoggerFactory::getLogger('obj')->debug(': Start cloning dependencies for node: ' . $node['obj_id'] . ', ' . $node['title'] . ', ' . $node['type']);
115 $this->cloneDependencies($node, $cp_options);
116 $this->callNextDependency($sid, $cp_options);
117 break;
118
120 ilLoggerFactory::getLogger('obj')->debug(': Start cloning dependencies: ' . $node['obj_id'] . ', ' . $node['title'] . ', ' . $node['type']);
121 $this->cloneDependencies($node, $cp_options);
122 $this->callNextDependency($sid, $cp_options);
123 break;
124
125 default:
126 ilLoggerFactory::getLogger('obj')->warning('No valid action type given for node: ' . $node['obj_id'] . ', ' . $node['title'] . ', ' . $node['type']);
127 $this->callNextDependency($sid, $cp_options);
128 break;
129 }
130 return true;
131 }
132
136 public function ilClone(string $sid, int $copy_identifier)
137 {
138 $this->initAuth($sid);
139 $this->initIlias();
140
141 if (!$this->checkSession($sid)) {
142 ilLoggerFactory::getLogger('obj')->error('Object cloning failed. Invalid session given: ' . $this->getMessage());
143 }
144
145 global $DIC;
146
147 $ilUser = $DIC->user();
148
149 $cp_options = ilCopyWizardOptions::_getInstance($copy_identifier);
150
151 // Check owner of copy procedure
152 if (!$cp_options->checkOwner($ilUser->getId())) {
153 ilLoggerFactory::getLogger('obj')->error('Permission check failed for user id: ' . $ilUser->getId() . ', copy id: ' . $copy_identifier);
154 return false;
155 }
156
157 // Fetch first node
158 if (($node = $cp_options->fetchFirstNode()) === null) {
159 ilLoggerFactory::getLogger('obj')->info('Finished copy step 1. Starting copying of object dependencies...');
160 return $this->ilCloneDependencies($sid, $copy_identifier, true);
161 }
162 // Check options of this node
163 $options = $cp_options->getOptions((int) $node['child']);
164
165 $action = $this->rewriteActionForNode($cp_options, $node, $options);
166
167 $new_ref_id = 0;
168 switch ($action) {
170 ilLoggerFactory::getLogger('obj')->debug(': Omitting node: ' . $node['obj_id'] . ', ' . $node['title'] . ', ' . $node['type']);
171 // set mapping to zero
172 $cp_options->appendMapping($node['child'], 0);
173 $this->callNextNode($sid, $cp_options);
174 break;
175
177
178 ilLoggerFactory::getLogger('obj')->debug('Start cloning node: ' . $node['obj_id'] . ', ' . $node['title'] . ', ' . $node['type']);
179 $new_ref_id = $this->cloneNode($node, $cp_options);
180 $this->callNextNode($sid, $cp_options);
181 break;
182
184 ilLoggerFactory::getLogger('obj')->debug('Start linking node: ' . $node['obj_id'] . ', ' . $node['title'] . ', ' . $node['type']);
185 $new_ref_id = $this->linkNode($node, $cp_options);
186 $this->callNextNode($sid, $cp_options);
187 break;
188
189 case \ilCopyWizardOptions::COPY_WIZARD_LINK_TO_TARGET:
190 ilLoggerFactory::getLogger('obj')->debug('Start creating internal link for: ' . $node['obj_id'] . ', ' . $node['title'] . ', ' . $node['type']);
191 $new_ref_id = $this->internalLinkNode($node, $cp_options);
192 $this->callNextNode($sid, $cp_options);
193 break;
194
195 default:
196 ilLoggerFactory::getLogger('obj')->warning('No valid action type given for: ' . $node['obj_id'] . ', ' . $node['title'] . ', ' . $node['type']);
197 $this->callNextNode($sid, $cp_options);
198 break;
199 }
200 return $new_ref_id;
201 }
202
203 protected function rewriteActionForNode(ilCopyWizardOptions $cpo, array $node, array $options): int
204 {
206 if (array_key_exists('type', $options)) {
207 $default_mode = (int) $options['type'];
208 }
209 if (
210 array_key_exists('child', $node) &&
211 $cpo->isRootNode((int) $node['child'])
212 ) {
213 return $default_mode;
214 }
215
216 if ($this->findMappedReferenceForNode($cpo, $node) && $default_mode == \ilCopyWizardOptions::COPY_WIZARD_COPY) {
217 return \ilCopyWizardOptions::COPY_WIZARD_LINK_TO_TARGET;
218 }
219 return $default_mode;
220 }
221
222 protected function findMappedReferenceForNode(\ilCopyWizardOptions $cpo, array $node): ?int
223 {
224 global $DIC;
225
226 $logger = $DIC->logger()->obj();
227 $tree = $DIC->repositoryTree();
228 $root = $cpo->getRootNode();
229 $obj_id = (int) $node['obj_id'];
230
231 $mappings = $cpo->getMappings();
232 foreach (\ilObject::_getAllReferences($obj_id) as $ref_id => $also_ref_id) {
233 $logger->debug('Validating node: ' . $ref_id . ' and root ' . $root);
234 $logger->dump($DIC->repositoryTree()->getRelation($ref_id, $root));
235
236 if ($DIC->repositoryTree()->getRelation($ref_id, $root) !== \ilTree::RELATION_CHILD) {
237 $logger->debug('Ignoring non child relation');
238 continue;
239 }
240 // check if mapping is already available
241 $logger->dump($mappings);
242 if (array_key_exists($ref_id, $mappings)) {
243 $logger->debug('Found existing mapping for linked node.');
244 return $mappings[$ref_id];
245 }
246 }
247 $logger->info('Nothing found');
248 return null;
249 }
250
251 private function callNextNode(string $sid, ilCopyWizardOptions $cp_options): void
252 {
253 global $DIC;
254
255 $ilLog = $DIC->logger()->obj();
256
257 $cp_options->dropFirstNode();
258 if ($cp_options->isSOAPEnabled()) {
259 // Start next soap call
260 $soap_client = new ilSoapClient();
261 $soap_client->setResponseTimeout(1);
262 $soap_client->enableWSDL(true);
263 $soap_client->init();
264 $soap_client->call('ilClone', array($sid, $cp_options->getCopyId()));
265 } else {
266 ilLoggerFactory::getLogger('obj')->warning('SOAP clone call failed. Calling clone method manually');
267 $cp_options->read();
268 $res = ilSoapFunctions::ilClone($sid, $cp_options->getCopyId());
269 }
270 }
271
272 private function callNextDependency(string $sid, ilCopyWizardOptions $cp_options): void
273 {
274 $cp_options->dropFirstDependenciesNode();
275
276 if ($cp_options->isSOAPEnabled()) {
277 // Start next soap call
278 $soap_client = new ilSoapClient();
279 $soap_client->setResponseTimeout(1);
280 $soap_client->enableWSDL(true);
281 $soap_client->init();
282 $soap_client->call('ilCloneDependencies', array($sid, $cp_options->getCopyId()));
283 } else {
284 ilLoggerFactory::getLogger('obj')->warning('SOAP clone call failed. Calling clone method manually');
285 $cp_options->read();
287 }
288 }
289
290 private function cloneNode(array $node, ilCopyWizardOptions $cp_options): int
291 {
292 global $DIC;
293
294 $ilLog = $DIC['ilLog'];
295 $tree = $DIC['tree'];
296 $ilAccess = $DIC['ilAccess'];
297 $rbacreview = $DIC['rbacreview'];
298 $source_id = (int) $node['child'];
299 $parent_id = (int) $node['parent'];
300 $options = $cp_options->getOptions((int) $node['child']);
301 $mappings = $cp_options->getMappings();
302
303 if (!$ilAccess->checkAccess('copy', '', (int) $node['child'])) {
304 ilLoggerFactory::getLogger('obj')->error('No copy permission granted: ' . $source_id . ', ' . $node['title'] . ', ' . $node['type']);
305 return 0;
306 }
307 if (!isset($mappings[$parent_id])) {
308 ilLoggerFactory::getLogger('obj')->info('Omitting node ' . $source_id . ', ' . $node['title'] . ', ' . $node['type'] . '. No target found.');
309 return 0;
310 }
311 $target_id = $mappings[$parent_id];
312
313 if (!$tree->isInTree($target_id)) {
314 ilLoggerFactory::getLogger('obj')->notice('Omitting node ' . $source_id . ', ' . $node['title'] . ', ' . $node['type'] . '. Object has been deleted.');
315 return 0;
316 }
317
318 $orig = ilObjectFactory::getInstanceByRefId($source_id);
319 $new_obj = $orig->cloneObject((int) $target_id, $cp_options->getCopyId());
320
321 if (!is_object($new_obj)) {
322 ilLoggerFactory::getLogger('obj')->error('Error copying ' . $source_id . ', ' . $node['title'] . ', ' . $node['type'] . '. No target found.');
323 return 0;
324 }
325
326 // rbac log
327 $rbac_log_roles = $rbacreview->getParentRoleIds($new_obj->getRefId(), false);
328 $rbac_log = ilRbacLog::gatherFaPa($new_obj->getRefId(), array_keys($rbac_log_roles), true);
329 ilRbacLog::add(ilRbacLog::COPY_OBJECT, $new_obj->getRefId(), $rbac_log, true);
330
331 // Finally add new mapping entry
332 $cp_options->appendMapping($source_id, $new_obj->getRefId());
333 return $new_obj->getRefId();
334 }
335
336 private function cloneDependencies(array $node, ilCopyWizardOptions $cp_options): void
337 {
338 global $DIC;
339
340 $ilLog = $DIC['ilLog'];
341
342 $source_id = (int) $node['child'];
343 $mappings = $cp_options->getMappings();
344
345 if (!isset($mappings[$source_id])) {
346 ilLoggerFactory::getLogger('obj')->debug('Omitting node ' . $source_id . ', ' . $node['title'] . ', ' . $node['type'] . '. No mapping found.');
347 return;
348 }
349 $target_id = $mappings[$source_id];
350
351 $orig = ilObjectFactory::getInstanceByRefId($source_id);
352 $orig->cloneDependencies($target_id, $cp_options->getCopyId());
353 }
354
355 private function internalLinkNode(array $node, ilCopyWizardOptions $cp_options): int
356 {
357 global $DIC;
358
359 $ilAccess = $DIC->access();
360 $logger = $DIC->logger()->obj();
361 $rbacreview = $DIC->rbac()->review();
362 $tree = $DIC->repositoryTree();
363 $mappings = $cp_options->getMappings();
364
365 $source_id = $this->findMappedReferenceForNode($cp_options, $node);
366 try {
367 $orig = ilObjectFactory::getInstanceByRefId((int) $source_id);
368 if (!$orig instanceof \ilObject) {
369 $logger->error('Cannot create object instance.');
370 return 0;
371 }
372 } catch (\ilObjectNotFoundException $e) {
373 $logger->error('Cannot create object instance for ref_id: ' . $source_id);
374 $logger->error($e->getMessage());
375 return 0;
376 }
377
378 // target (parent id) is the mapped parent id of the current node
379 $node_parent = $node['parent'];
380 if (!array_key_exists($node_parent, $mappings)) {
381 $logger->error('Cannot new parent id for node: ' . $node['parent']);
382 return 0;
383 }
384 $parent_id = $mappings[$node_parent];
385
386 $new_ref_id = $orig->createReference();
387 $orig->putInTree($parent_id);
388 $orig->setPermissions($parent_id);
389
390 if (!($new_ref_id)) {
391 $logger->warning('Creating internal link failed.');
392 return 0;
393 }
394
395 // rbac log
396 $rbac_log_roles = $rbacreview->getParentRoleIds($new_ref_id, false);
397 $rbac_log = ilRbacLog::gatherFaPa($new_ref_id, array_keys($rbac_log_roles), true);
398 ilRbacLog::add(ilRbacLog::LINK_OBJECT, $new_ref_id, $rbac_log, true);
399
400 // Finally add new mapping entry
401 $cp_options->appendMapping($node['child'], $new_ref_id);
402
403 $logger->notice('Added mapping for ' . $node['child'] . ' ' . $new_ref_id);
404 return $new_ref_id;
405 }
406
407 private function linkNode(array $node, ilCopyWizardOptions $cp_options): int
408 {
409 global $DIC;
410
411 $ilLog = $DIC['ilLog'];
412 $ilAccess = $DIC['ilAccess'];
413 $rbacreview = $DIC['rbacreview'];
414
415 $source_id = (int) $node['child'];
416 $parent_id = (int) $node['parent'];
417 $options = $cp_options->getOptions((int) $node['child']);
418 $mappings = $cp_options->getMappings();
419
420 if (!$ilAccess->checkAccess('delete', '', (int) $node['child'])) {
421 ilLoggerFactory::getLogger('obj')->warning('No delete permission granted: ' . $source_id . ', ' . $node['title'] . ', ' . $node['type']);
422 return 0;
423 }
424 if (!isset($mappings[$parent_id])) {
425 ilLoggerFactory::getLogger('obj')->warning('Omitting node ' . $source_id . ', ' . $node['title'] . ', ' . $node['type'] . '. No target found.');
426 return 0;
427 }
428 $target_id = $mappings[$parent_id];
429
430 $orig = ilObjectFactory::getInstanceByRefId($source_id);
431 $new_ref_id = $orig->createReference();
432 $orig->putInTree($target_id);
433 $orig->setPermissions($target_id);
434
435 if (!($new_ref_id)) {
436 ilLoggerFactory::getLogger('obj')->error('Error linking ' . $source_id . ', ' . $node['title'] . ', ' . $node['type'] . '. No target found.');
437 return 0;
438 }
439
440 // rbac log
441 $rbac_log_roles = $rbacreview->getParentRoleIds($new_ref_id, false);
442 $rbac_log = ilRbacLog::gatherFaPa($new_ref_id, array_keys($rbac_log_roles), true);
443 ilRbacLog::add(ilRbacLog::LINK_OBJECT, $new_ref_id, $rbac_log, true);
444
445 // Finally add new mapping entry
446 $cp_options->appendMapping($source_id, $new_ref_id);
447 return $new_ref_id;
448 }
449
454 public function deleteExpiredDualOptInUserObjects(string $sid, int $usr_id): bool
455 {
456 $this->initAuth($sid);
457 $this->initIlias();
458
459 // Session check not possible -> anonymous user is the trigger
460
461 global $DIC;
462
463 $dual_opt_in_service = new DualOptInServiceImpl(
466 $DIC->database(),
467 $DIC->logger()->user(),
468 (new \ILIAS\Data\Factory())->clock()
469 );
470 $dual_opt_in_service->deleteExpiredUserObjects($usr_id);
471
472 return true;
473 }
474}
@phpstan-type PendingRegistrationRecord array{id: string, usr_id: int, reg_hash: string,...
isRootNode(int $a_root)
Is root node @access public.
dropFirstNode()
Drop first node (for cloneObject())
appendMapping($a_source_id, $a_target_id)
Add mapping of source -> target.
dropFirstDependenciesNode()
Drop first node (for cloneDependencies())
static _getInstance(int $a_copy_id)
isSOAPEnabled()
Check if SOAP calls are disabled.
getOptions(int $a_source_id)
Get entry by source @access public.
static getLogger(string $a_component_id)
Get component logger.
static _saveTempFileAsMediaObject(string $name, string $tmp_name, bool $upload=true)
static _getMobsOfObject(string $a_type, int $a_id, int|false $a_usage_hist_nr=0, string $a_lang="-")
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
Class ilObject Basic functions for all objects.
static _getAllReferences(int $id)
get all reference ids for object ID
const COPY_OBJECT
static add(int $action, int $ref_id, array $diff, bool $source_ref_id=false)
static gatherFaPa(int $ref_id, array $role_ids, bool $add_action=false)
const LINK_OBJECT
Class ilObjAuthSettingsGUI.
raiseError(string $a_message, $a_code)
static ilCloneDependencies(string $sid, int $copy_identifier)
static ilClone(string $sid, int $copy_identifier)
Soap utitliy functions.
cloneDependencies(array $node, ilCopyWizardOptions $cp_options)
deleteExpiredDualOptInUserObjects(string $sid, int $usr_id)
Method for soap webservice: deleteExpiredDualOptInUserObjects This service will run in background.
callNextDependency(string $sid, ilCopyWizardOptions $cp_options)
internalLinkNode(array $node, ilCopyWizardOptions $cp_options)
getMobsOfObject(string $sid, string $a_type, int $a_id)
rewriteActionForNode(ilCopyWizardOptions $cpo, array $node, array $options)
saveTempFileAsMediaObject(string $sid, string $name, string $tmp_name)
findMappedReferenceForNode(\ilCopyWizardOptions $cpo, array $node)
ilClone(string $sid, int $copy_identifier)
linkNode(array $node, ilCopyWizardOptions $cp_options)
ilCloneDependencies(string $sid, int $copy_identifier, bool $is_initialized=false)
cloneNode(array $node, ilCopyWizardOptions $cp_options)
callNextNode(string $sid, ilCopyWizardOptions $cp_options)
const RELATION_CHILD
$ref_id
Definition: ltiauth.php:66
$res
Definition: ltiservices.php:69
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
global $DIC
Definition: shib_login.php:26