ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilECSCmsCourseMemberCommandQueueHandler.php
Go to the documentation of this file.
1 <?php
2 
18 declare(strict_types=1);
25 {
26  protected ilLogger $log;
27 
29  private int $mid = 0;
30 
31  private ?ilECSnodeMappingSettings $mapping = null;
32 
36  public function __construct(ilECSSetting $server)
37  {
38  global $DIC;
39  $this->log = $DIC->logger()->wsrv();
40  $this->server = $server;
41  }
42 
46  public function getServer(): \ilECSSetting
47  {
48  return $this->server;
49  }
50 
54  public function getMid(): int
55  {
56  return $this->mid;
57  }
58 
62  public function checkAllocationActivation(ilECSSetting $server, $a_content_id): bool
63  {
64  try {
65  $crsm_reader = new ilECSCourseMemberConnector($server);
66  $details = $crsm_reader->getCourseMember($a_content_id, true);
67  $this->mid = $details->getMySender();
68 
69  // Check if import is enabled
70  $part = ilECSParticipantSetting::getInstance($this->getServer()->getServerId(), $this->getMid());
71  if (!$part->isImportEnabled()) {
72  $this->log->warning('Import disabled for mid ' . $this->getMid());
73  return false;
74  }
75  // Check course allocation setting
77  $this->getServer()->getServerId(),
78  $this->getMid()
79  );
80  return $this->mapping->isCourseAllocationEnabled();
81  } catch (ilECSConnectorException $e) {
82  $this->log->error('Reading course member details failed with message ' . $e->getMessage());
83  return false;
84  }
85  }
86 
87 
91  public function handleCreate(ilECSSetting $server, $a_content_id): bool
92  {
93  if (!$this->checkAllocationActivation($server, $a_content_id)) {
94  return true;
95  }
96  try {
97  //$course = $this->readCourse($server, $a_content_id);
98  $course_member = $this->readCourseMember($server, $a_content_id);
99  $this->doUpdate($a_content_id, $course_member);
100  return true;
101  } catch (ilECSConnectorException $e) {
102  $this->log->error('Course member creation failed with mesage ' . $e->getMessage());
103  return false;
104  }
105  return true;
106  }
107 
111  public function handleDelete(ilECSSetting $server, $a_content_id): bool
112  {
113  // nothing todo
114  return true;
115  }
116 
120  public function handleUpdate(ilECSSetting $server, $a_content_id): bool
121  {
122  if (!$this->checkAllocationActivation($server, $a_content_id)) {
123  return true;
124  }
125 
126  try {
127  $course_member = $this->readCourseMember($server, $a_content_id);
128  $this->doUpdate($a_content_id, $course_member);
129  return true;
130  } catch (ilECSConnectorException $e) {
131  $this->log->error('Course member update failed with mesage ' . $e->getMessage());
132  return false;
133  }
134  return true;
135  }
136 
137 
141  protected function doUpdate($a_content_id, $course_member): bool
142  {
143  $this->log->debug('Starting ecs member update');
144 
145  $course_id = (int) $course_member->lectureID;
146  if (!$course_id) {
147  $this->log->warning('Missing course id');
148  return false;
149  }
150  $this->log->debug('sid: ' . $this->getServer()->getServerId() . ' course_id: ' . $course_id . ' mid: ' . $this->mid);
151  //$crs_obj_id = ilECSImportManager::getInstance()->_lookupObjId($this->getServer()->getServerId(), $course_id, $this->mid);
152  $crs_obj_id = ilECSImportManager::getInstance()->lookupObjIdByContentId($this->getServer()->getServerId(), $this->mid, $course_id);
153 
154  if (!$crs_obj_id) {
155  $this->log->info('No main course created. Group scenario >= 3 ?');
156  }
157 
158  $course = $this->readCourse($course_member);
159  if (is_null($course)) {
160  $this->log->info('No course found, skip processing' . print_r($course_member, true));
161  return true;
162  }
163  // Lookup already imported users and update their status
164  $assignments = $this->readAssignments($course, $course_member);
165 
166  $this->log->debug('Parallel group assignments');
167  $this->log->dump($assignments, ilLogLevel::DEBUG);
168  $this->log->debug('------------------ End assignemtns');
169 
170  // iterate through all parallel groups
171  foreach ($assignments as $cms_id => $assigned) {
172  $sub_id = ($cms_id === $course_id) ? null : (string) $cms_id;
173 
174  $this->log->debug('sub id is ' . is_null($sub_id) ? "<null>" : $sub_id . ' for ' . $cms_id);
175 
176  $obj_id = ilECSImportManager::getInstance()->lookupObjIdByContentId(
177  $this->getServer()->getServerId(),
178  $this->getMid(),
179  $course_id,
180  $sub_id
181  );
182 
183  $this->refreshAssignmentStatus($course_member, $obj_id, $sub_id, $assigned);
184  }
185  return true;
186  }
187 
191  protected function readAssignments($course, $course_member): array
192  {
193  //TODO check if this switch is still needed
194  switch ((int) $course->groupScenario) {
196  $this->log->debug('Parallel group scenario one course.');
197  break;
198 
200  $this->log->debug('Parallel group scenario groups in courses.');
201  break;
202 
204  $this->log->debug('Parallel group scenario only courses.');
205  break;
206 
207  default:
208  $this->log->debug('Parallel group scenario undefined.');
209  break;
210  }
211 
212  $course_id = $course_member->lectureID;
213  $assigned = array();
214  foreach ((array) $course_member->members as $member) {
215  $assigned[$course_id][$member->personID] = array(
216  'id' => $member->personID,
217  'role' => $member->role
218  );
219  if ((int) $course->groupScenario === ilECSMappingUtils::PARALLEL_ONE_COURSE) {
220  $this->log->debug('Group scenarion "one course". Ignoring group assignments');
221  continue;
222  }
223 
224  foreach ((array) $member->groups as $pgroup) {
225  // the sequence number in the course ressource
226  $sequence_number = (int) $pgroup->num;
227  // find parallel group with by sequence number
228  $tmp_pgroup = $course->groups[$sequence_number];
229  if (is_object($tmp_pgroup) && $tmp_pgroup->id !== '') {
230  $this->log->debug('Found parallel group with id: ' . $tmp_pgroup->id . ': for sequence number: ' . $sequence_number);
231 
232  // @todo check hierarchy of roles
233  $assigned[$tmp_pgroup->id][$member->personID] = array(
234  'id' => $member->personID,
235  'role' => $pgroup->role
236  );
237  } else {
238  $this->log->warning('Cannot find parallel group with sequence id: ' . $sequence_number);
239  }
240  }
241  }
242  $this->log->debug('ECS member assignments ' . print_r($assigned, true));
243  return $assigned;
244  }
245 
246 
247 
251  protected function refreshAssignmentStatus(object $course_member, int $obj_id, ?string $sub_id, $assigned): bool
252  {
253  $this->log->debug('Currrent sub_id = ' . $sub_id . ', obj_id = ' . $obj_id);
254 
255  $type = ilObject::_lookupType($obj_id);
256  if ($type === 'crs') {
258  } elseif ($type === 'grp') {
260  } else {
261  $this->log->warning('Invalid object type given for obj_id: ' . $obj_id);
262  return false;
263  }
264 
265  $course_id = (int) $course_member->lectureID;
267  $course_id,
268  is_null($sub_id) ? $sub_id : (int) $sub_id,
269  $obj_id
270  );
271 
272  // Delete remote deleted
273  foreach ($usr_ids as $usr_id) {
274  if (!isset($assigned[$usr_id])) {
275  $ass = ilECSCourseMemberAssignment::lookupAssignment($course_id, is_null($sub_id) ? $sub_id : (int) $sub_id, $obj_id, $usr_id);
276  if ($ass instanceof ilECSCourseMemberAssignment) {
278  $this->mapping->getAuthMode(),
279  (string) $usr_id
280  );
281 
282  $this->log->debug('Local user assignment: ' . $usr_id . ' <-> ' . $login);
283 
284  if ($il_usr_id = ilObjUser::_lookupId($login)) {
285  // this removes also admin, tutor roles
286  $part->delete($il_usr_id);
287  $this->log->info('Deassigning user ' . $usr_id . ' ' . 'from course ' . ilObject::_lookupTitle($obj_id));
288  } else {
289  $this->log->notice('Deassigning unknown ILIAS user ' . $usr_id . ' ' . 'from course ' . ilObject::_lookupTitle($obj_id));
290  }
291 
292  $ass->delete();
293  }
294  }
295  }
296 
297  $this->log->debug('Handled assignmnent...');
298 
299  // Assign new participants
300  foreach ((array) $assigned as $person_id => $person) {
301  $role = $this->lookupRole((string) $person['role'], $type);
302  $role_info = ilECSMappingUtils::getRoleMappingInfo($role);
303 
304  $this->log->debug('Using role info...');
306  $this->mapping->getAuthMode(),
307  (string) $person_id
308  );
309  $this->log->info('Handling user ' . $person_id);
310  if (in_array($person_id, $usr_ids)) {
311  if ($il_usr_id = ilObjUser::_lookupId($login)) {
312  $this->log->info('User exists, Updating role assignment for existing user: ' . $person_id);
313  $part->updateRoleAssignments($il_usr_id, array($part->getAutoGeneratedRoleId($role)));
314  } elseif ($role_info['create']) {
315  $this->createMember($person_id);
316  $this->log->info('Creating new user for' . $person_id);
318  $this->mapping->getAuthMode(),
319  (string) $person_id
320  );
321  if ($role && $il_usr_id = ilObjUser::_lookupId($login)) {
322  $part->add($il_usr_id, $role);
323  $part->sendNotification(ilCourseMembershipMailNotification::TYPE_ADMISSION_MEMBER, $il_usr_id);
324  }
325  }
326  } else {
327  if ($il_usr_id = ilObjUser::_lookupId($login)) {
328  // user exists => assign to course/group
329  if ($role) {
330  // Assign user
331  $this->log->info('Assigning new user ' . $person_id . ' ' . 'to ' . ilObject::_lookupTitle($obj_id) . ' using role: ' . $role);
332  $part->add($il_usr_id, $role);
333  $part->sendNotification(ilCourseMembershipMailNotification::TYPE_ADMISSION_MEMBER, $il_usr_id);
334  }
335  } else {
336  // no local user exists
337  if ($role_info['create']) {
338  $this->createMember($person_id);
339  $this->log->info('Created new user ' . $person_id);
341  $this->mapping->getAuthMode(),
342  (string) $person_id
343  );
344  }
345  // Assign to role
346  if ($role && $il_usr_id = ilObjUser::_lookupId($login)) {
347  $this->log->info('Assigning new user ' . $person_id . ' ' . 'to ' . ilObject::_lookupTitle($obj_id) . ' using role: ' . $role);
348  $part->add($il_usr_id, $role);
349  $part->sendNotification(ilCourseMembershipMailNotification::TYPE_ADMISSION_MEMBER, $il_usr_id);
350  }
351  }
352 
353  $assignment = new ilECSCourseMemberAssignment();
354  $assignment->setServer($this->getServer()->getServerId());
355  $assignment->setMid($this->mid);
356  $assignment->setCmsId($course_id);
357  $assignment->setCmsSubId((int) $sub_id);
358  $assignment->setObjId($obj_id);
359  $assignment->setUid((string) $person_id);
360  $assignment->save();
361  }
362  }
363  return true;
364  }
365 
369  protected function lookupRole(string $role_value, $a_obj_type): int
370  {
371  $role_mappings = $this->mapping->getRoleMappings();
372 
373  /* Zero is an allowed value */
374  if (!$role_value) {
375  $this->log->debug('No role assignment attribute: role');
376  }
377  foreach ($role_mappings as $name => $map) {
378  // map is a string of ids seperated by ","
379  $exploded_map = (array) explode(',', $map);
380  if (in_array($role_value, $exploded_map, true)) {
381  switch ($name) {
385  if ($a_obj_type === 'crs') {
386  $this->log->debug('Role: ' . $role_value . ' maps: ' . $map);
387  return $name;
388  }
389  break;
390 
393  if ($a_obj_type === 'grp') {
394  $this->log->debug('Role: ' . $role_value . ' maps: ' . $map);
395  return $name;
396  }
397  break;
398  }
399  }
400  }
401  $this->log->info('No role assignment mapping for role ' . $role_value);
402  return 0;
403  }
404 
408  private function createMember($a_person_id): void
409  {
410  if (!$this->mapping instanceof ilECSNodeMappingSettings) {
411  $this->log->warning('Node mapping settings not initialized.');
412  }
413  $auth_mode = $this->mapping->getAuthMode();
414 
415  if (
416  $this->mapping->getAuthMode() ===
418  ) {
419  $this->log->info('Not handling direct user creation for auth mode: ' . $auth_mode);
420  return;
421  }
422  if (strpos($auth_mode, 'ldap') !== 0) {
423  $this->log->info('Not handling direct user creation for auth mode: ' . $auth_mode);
424  return;
425  }
426 
427  try {
429  $server->doConnectionCheck();
430 
431  $query = new ilLDAPQuery($server);
433 
434  $users = $query->fetchUser($a_person_id);
435  if ($users) {
437 
438  $xml = new ilLDAPAttributeToUser($server);
439  $xml->setNewUserAuthMode($server->getAuthenticationMappingKey());
440  $xml->setUserData($users);
441  $xml->refresh();
442  }
443  } catch (ilLDAPQueryException $exc) {
444  $this->log->error($exc->getMessage());
445  }
446  }
447 
448 
452  private function readCourseMember(ilECSSetting $server, $a_content_id)
453  {
454  return (new ilECSCourseMemberConnector($server))->getCourseMember($a_content_id);
455  }
456 
460  private function readCourse($course_member)
461  {
462  $ecs_id = ilECSImportManager::getInstance()->lookupEContentIdByContentId(
463  $this->getServer()->getServerId(),
464  $this->getMid(),
465  $course_member->lectureID
466  );
467  if (0 === $ecs_id) {
468  return null;
469  }
470  return (new ilECSCourseConnector($this->getServer()))->getCourse($ecs_id);
471  }
472 }
handleCreate(ilECSSetting $server, $a_content_id)
Handle create.
static _getFirstActiveServer()
Get first active server.
static getInstance(int $a_server_id, int $mid)
Get instance by server id and mid.
static getRoleMappingInfo($a_role_type_info=0)
Get role mapping info.
$type
static getInstanceByServerId(int $a_server_id)
Get instance by server id.
static getInstanceByServerMid(int $a_server_id, int $a_mid)
Get instance.
static _lookupId($a_user_str)
lookupRole(string $role_value, $a_obj_type)
Lookup local role by assignment.
static _checkExternalAuthAccount(string $a_auth, string $a_account, bool $tryFallback=true)
check whether external account and authentication method matches with a user
checkAllocationActivation(ilECSSetting $server, $a_content_id)
Check if course allocation is activated for one recipient of the.
static _getAuthModeName($a_auth_key)
Interface for all command queue handler classes.
handleDelete(ilECSSetting $server, $a_content_id)
Handle delete.
global $DIC
Definition: feed.php:28
static lookupAssignment(int $a_cms_id, ?int $a_cms_sub_id, int $a_obj_id, string $a_usr_id)
Lookup assignment of user.
array $details
Details for error message relating to last request processed.
Definition: System.php:109
if($format !==null) $name
Definition: metadata.php:247
static getInstance()
Get the singleton instance of this ilECSImportManager.
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: confirmReg.php:20
static _lookupTitle(int $obj_id)
static _getInstanceByObjId(int $a_obj_id)
readAssignments($course, $course_member)
Read assignments for all parallel groups.
$xml
Definition: metadata.php:351
$query
static lookupUserIds(int $a_cms_id, ?int $a_cms_sub_id, int $a_obj_id)
Lookup user ids.
Connector for course member ressource.
Storage of ecs course assignments.
static _getInstanceByObjId(int $a_obj_id)
Get singleton instance.
readCourseMember(ilECSSetting $server, $a_content_id)
Read course from ecs.
handleUpdate(ilECSSetting $server, $a_content_id)
Handle update.
Update/create ILIAS user account by given LDAP attributes according to user attribute mapping setting...
refreshAssignmentStatus(object $course_member, int $obj_id, ?string $sub_id, $assigned)
Refresh status of course member assignments.
static _lookupType(int $id, bool $reference=false)