ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
ilMailRoleAddressType Class Reference

Class ilMailRoleAddressType. More...

+ Inheritance diagram for ilMailRoleAddressType:
+ Collaboration diagram for ilMailRoleAddressType:

Public Member Functions

 isValid ($a_sender_id)
 {
Parameters
$a_sender_idinteger
Returns
boolean
} More...
 
 resolve ()
 {Returns an array of resolved user ids.
Returns
int[]
} More...
 
- Public Member Functions inherited from ilBaseMailAddressType
 __construct (\ilMailAddress $a_address)
 ilBaseMailAddressType constructor. More...
 
 validate ($a_sender_id)
 {
Parameters
$a_sender_idinteger
Returns
bool
} More...
 
 getErrors ()
 
 resolve ()
 Returns an array of resolved user ids. More...
 
 validate ($a_sender_id)
 

Static Public Member Functions

static searchRolesByMailboxAddressList ( $a_address_list, ilMailRfc822AddressParserFactory $parserFactory=null, ilMailRfc822AddressParser $parser=null)
 Finds all role ids that match the specified user friendly role mailbox address list. More...
 
static getRoleMailboxAddress ( $a_role_id, $is_localize=true, ilMailRfc822AddressParserFactory $mailAddressParserFactory=null)
 Returns the mailbox address of a role. More...
 

Protected Member Functions

 maySendToGlobalRole ($a_sender_id)
 
- Protected Member Functions inherited from ilBaseMailAddressType
 init ()
 
 isValid ($a_sender_id)
 

Static Protected Member Functions

static getRoleIdsByAddress (ilMailAddress $a_address)
 

Static Protected Attributes

static $role_ids_by_address = array()
 
static $may_send_to_global_roles = array()
 

Additional Inherited Members

- Protected Attributes inherited from ilBaseMailAddressType
 $address
 
 $rbacsystem
 
 $rbacreview
 
 $errors = array()
 

Detailed Description

Member Function Documentation

◆ getRoleIdsByAddress()

static ilMailRoleAddressType::getRoleIdsByAddress ( ilMailAddress  $a_address)
staticprotected
Parameters
ilMailAddress$a_address
Returns
array

Definition at line 29 of file class.ilMailRoleAddressType.php.

30 {
31 $address = $a_address->getMailbox() . '@' . $a_address->getHost();
32
33 if (!isset(self::$role_ids_by_address[$address])) {
34 self::$role_ids_by_address[$address] = self::searchRolesByMailboxAddressList($address);
35 }
36
37 return self::$role_ids_by_address[$address];
38 }
static searchRolesByMailboxAddressList( $a_address_list, ilMailRfc822AddressParserFactory $parserFactory=null, ilMailRfc822AddressParser $parser=null)
Finds all role ids that match the specified user friendly role mailbox address list.

References ilBaseMailAddressType\$address, ilMailAddress\getHost(), ilMailAddress\getMailbox(), and searchRolesByMailboxAddressList().

Referenced by isValid(), and resolve().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRoleMailboxAddress()

static ilMailRoleAddressType::getRoleMailboxAddress (   $a_role_id,
  $is_localize = true,
ilMailRfc822AddressParserFactory  $mailAddressParserFactory = null 
)
static

Returns the mailbox address of a role.

Example 1: Mailbox address for an ILIAS reserved role name

The il_crs_member_345 role of the course object "English Course 1" is returned as one of the following mailbox addresses:

a) Course Member <#member@[English Course 1]> b) Course Member <#il_crs_member_345@[English Course 1]> c) Course Member <#il_crs_member_345>

Address a) is returned, if the title of the object is unique, and if there is only one local role with the substring "member" defined for the object.

Address b) is returned, if the title of the object is unique, but there is more than one local role with the substring "member" in its title.

Address c) is returned, if the title of the course object is not unique.

Example 2: Mailbox address for a manually defined role name

The "Admin" role of the category object "Courses" is returned as one of the following mailbox addresses:

a) Course Administrator <#Admin@Courses> b) Course Administrator <#Admin> c) Course Adminstrator <#il_role_34211>

Address a) is returned, if the title of the object is unique, and if there is only one local role with the substring "Admin" defined for the course object.

Address b) is returned, if the title of the object is not unique, but the role title is unique.

Address c) is returned, if neither the role title nor the title of the course object is unique.

Example 3: Mailbox address for a manually defined role title that can contains special characters in the local-part of a

mailbox address

The "Author Courses" role of the category object "Courses" is returned as one of the following mailbox addresses:

a) "#Author Courses"@Courses b) Author Courses <#il_role_34234>

Address a) is returned, if the title of the role is unique.

Address b) is returned, if neither the role title nor the title of the course object is unique, or if the role title contains a quote or a backslash.

Parameters
$a_role_id
bool$is_localizeis_localize whether mailbox addresses should be localized
ilMailRfc822AddressParserFactory | null$mailAddressParserFactory
Returns
String mailbox address or null, if role does not exist.

Definition at line 357 of file class.ilMailRoleAddressType.php.

361 {
362 global $DIC;
363
364 if ($mailAddressParserFactory === null) {
365 $mailAddressParserFactory = new ilMailRfc822AddressParserFactory();
366 }
367
368 // Retrieve the role title and the object title.
369 $query = "SELECT rdat.title role_title,odat.title object_title, " .
370 " oref.ref_id object_ref " .
371 "FROM object_data rdat " .
372 "JOIN rbac_fa fa ON fa.rol_id = rdat.obj_id " .
373 "JOIN tree rtree ON rtree.child = fa.parent " .
374 "JOIN object_reference oref ON oref.ref_id = rtree.child " .
375 "JOIN object_data odat ON odat.obj_id = oref.obj_id " .
376 "WHERE rdat.obj_id = " . $DIC->database()->quote($a_role_id, 'integer') . " " .
377 "AND fa.assign = 'y' ";
378 $res = $DIC->database()->query($query);
379 if (!$row = $DIC->database()->fetchObject($res)) {
380 return null;
381 }
382
383 $object_title = $row->object_title;
384 $object_ref = $row->object_ref;
385 $role_title = $row->role_title;
386
387 // In a perfect world, we could use the object_title in the
388 // domain part of the mailbox address, and the role title
389 // with prefix '#' in the local part of the mailbox address.
390 $domain = $object_title;
391 $local_part = $role_title;
392
393
394 // Determine if the object title is unique
395 $q = "SELECT COUNT(DISTINCT dat.obj_id) count " .
396 "FROM object_data dat " .
397 "JOIN object_reference ref ON ref.obj_id = dat.obj_id " .
398 "JOIN tree ON tree.child = ref.ref_id " .
399 "WHERE title = " . $DIC->database()->quote($object_title, 'text') . " " .
400 "AND tree.tree = 1 ";
401 $res = $DIC->database()->query($q);
402 $row = $DIC->database()->fetchObject($res);
403
404 // If the object title is not unique, we get rid of the domain.
405 if ($row->count > 1) {
406 $domain = null;
407 }
408
409 // If the domain contains illegal characters, we get rid of it.
410 //if (domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]/',$domain))
411 // Fix for Mantis Bug: 7429 sending mail fails because of brakets
412 // Fix for Mantis Bug: 9978 sending mail fails because of semicolon
413 if ($domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]|[\x28-\x29]|[;]/', $domain)) {
414 $domain = null;
415 }
416
417 // If the domain contains special characters, we put square
418 // brackets around it.
419 if ($domain != null &&
420 (preg_match('/[()<>@,;:\\".\[\]]/', $domain) ||
421 preg_match('/[^\x21-\x8f]/', $domain))
422 ) {
423 $domain = '[' . $domain . ']';
424 }
425
426 // If the role title is one of the ILIAS reserved role titles,
427 // we can use a shorthand version of it for the local part
428 // of the mailbox address.
429 if (strpos($role_title, 'il_') === 0 && $domain != null) {
430 $unambiguous_role_title = $role_title;
431
432 $pos = strpos($role_title, '_', 3) + 1;
433 $local_part = substr(
434 $role_title,
435 $pos,
436 strrpos($role_title, '_') - $pos
437 );
438 } else {
439 $unambiguous_role_title = 'il_role_' . $a_role_id;
440 }
441
442 // Determine if the local part is unique. If we don't have a
443 // domain, the local part must be unique within the whole repositry.
444 // If we do have a domain, the local part must be unique for that
445 // domain.
446 if ($domain == null) {
447 $q = "SELECT COUNT(DISTINCT dat.obj_id) count " .
448 "FROM object_data dat " .
449 "JOIN object_reference ref ON ref.obj_id = dat.obj_id " .
450 "JOIN tree ON tree.child = ref.ref_id " .
451 "WHERE title = " . $DIC->database()->quote($local_part, 'text') . " " .
452 "AND tree.tree = 1 ";
453 } else {
454 $q = "SELECT COUNT(rd.obj_id) count " .
455 "FROM object_data rd " .
456 "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id " .
457 "JOIN tree t ON t.child = fa.parent " .
458 "WHERE fa.assign = 'y' " .
459 "AND t.child = " . $DIC->database()->quote($object_ref, 'integer') . " " .
460 "AND rd.title LIKE " . $DIC->database()->quote(
461 '%' . preg_replace('/([_%])/', '\\\\$1', $local_part) . '%',
462 'text'
463 ) . " ";
464 }
465
466 $res = $DIC->database()->query($q);
467 $row = $DIC->database()->fetchObject($res);
468
469 // if the local_part is not unique, we use the unambiguous role title
470 // instead for the local part of the mailbox address
471 if ($row->count > 1) {
472 $local_part = $unambiguous_role_title;
473 }
474
475 $use_phrase = true;
476
477 // If the local part contains illegal characters, we use
478 // the unambiguous role title instead.
479 if (preg_match('/[\\"\x00-\x1f]/', $local_part)) {
480 $local_part = $unambiguous_role_title;
481 } elseif (!preg_match('/^[\\x00-\\x7E]+$/i', $local_part)) {
482 // 2013-12-05: According to #12283, we do not accept umlauts in the local part
483 $local_part = $unambiguous_role_title;
484 $use_phrase = false;
485 }
486
487 // Add a "#" prefix to the local part
488 $local_part = '#' . $local_part;
489
490 // Put quotes around the role title, if needed
491 if (preg_match('/[()<>@,;:.\[\]\x20]/', $local_part)) {
492 $local_part = '"' . $local_part . '"';
493 }
494
495 $mailbox = ($domain == null) ?
496 $local_part :
497 $local_part . '@' . $domain;
498
499 if ($is_localize) {
500 if (substr($role_title, 0, 3) == 'il_') {
501 $phrase = $DIC->language()->txt(substr($role_title, 0, strrpos($role_title, '_')));
502 } else {
503 $phrase = $role_title;
504 }
505
506 if ($use_phrase) {
507 // make phrase RFC 822 conformant:
508 // - strip excessive whitespace
509 // - strip special characters
510 $phrase = preg_replace('/\s\s+/', ' ', $phrase);
511 $phrase = preg_replace('/[()<>@,;:\\".\[\]]/', '', $phrase);
512
513 $mailbox = $phrase . ' <' . $mailbox . '>';
514 }
515 }
516
517 try {
518 $parser = $mailAddressParserFactory->getParser($mailbox);
519 $parser->parse();
520
521 return $mailbox;
522 } catch (ilException $e) {
523 $res = $DIC->database()->query("SELECT title FROM object_data WHERE obj_id = " . $DIC->database()->quote($a_role_id, 'integer'));
524 if ($row = $DIC->database()->fetchObject($res)) {
525 return '#' . $row->title;
526 } else {
527 return null;
528 }
529 }
530 }
$parser
Definition: BPMN2Parser.php:23
if(!array_key_exists('domain', $_REQUEST)) $domain
Definition: resume.php:8
Base class for ILIAS Exception handling.
Class ilMailRfc822AddressParserFactory.
$query
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res

References $DIC, $domain, $parser, $query, $res, and $row.

Referenced by ilAbstractMailMemberRoles\getMailboxRoleAddress(), ilObjUserFolderGUI\importUserRoleAssignmentObject(), ilMailSearchCoursesGUI\mailCourses(), ilMailSearchGroupsGUI\mailGroups(), and ilObjRoleGUI\mailToRoleObject().

+ Here is the caller graph for this function:

◆ isValid()

ilMailRoleAddressType::isValid (   $a_sender_id)

{

Parameters
$a_sender_idinteger
Returns
boolean
}

Reimplemented from ilBaseMailAddressType.

Definition at line 65 of file class.ilMailRoleAddressType.php.

66 {
67 $role_ids = self::getRoleIdsByAddress($this->address);
68 if (!self::maySendToGlobalRole($a_sender_id)) {
69 foreach ($role_ids as $role_id) {
70 if ($this->rbacreview->isGlobalRole($role_id)) {
71 $this->errors[] = array('mail_to_global_roles_not_allowed', $this->address->getMailbox());
72 return false;
73 }
74 }
75 }
76
77 if (count($role_ids) == 0) {
78 $this->errors[] = array('mail_recipient_not_found', $this->address->getMailbox());
79 return false;
80 } elseif (count($role_ids) > 1) {
81 $this->errors[] = array('mail_multiple_role_recipients_found', $this->address->getMailbox(), implode(',', $role_ids));
82 return false;
83 }
84
85 return true;
86 }
static getRoleIdsByAddress(ilMailAddress $a_address)

References getRoleIdsByAddress().

+ Here is the call graph for this function:

◆ maySendToGlobalRole()

ilMailRoleAddressType::maySendToGlobalRole (   $a_sender_id)
protected
Parameters
int$a_sender_id
Returns
bool

Definition at line 44 of file class.ilMailRoleAddressType.php.

45 {
46 if (!isset(self::$may_send_to_global_roles[$a_sender_id])) {
47 if ($a_sender_id == ANONYMOUS_USER_ID) {
48 self::$may_send_to_global_roles[$a_sender_id] = true;
49 } else {
50 require_once 'Services/Mail/classes/class.ilMailGlobalServices.php';
51 self::$may_send_to_global_roles[$a_sender_id] = $this->rbacsystem->checkAccessOfUser(
52 $a_sender_id,
53 'mail_to_global_roles',
55 );
56 }
57 }
58
59 return self::$may_send_to_global_roles[$a_sender_id];
60 }
static getMailObjectRefId()
Determines the reference id of the mail object and stores this information in a local cache variable.

References ilMailGlobalServices\getMailObjectRefId().

+ Here is the call graph for this function:

◆ resolve()

ilMailRoleAddressType::resolve ( )

{Returns an array of resolved user ids.

Returns
int[]
}

Implements ilMailAddressType.

Definition at line 91 of file class.ilMailRoleAddressType.php.

92 {
93 $usr_ids = array();
94
95 $role_ids = self::getRoleIdsByAddress($this->address);
96
97 if (count($role_ids) > 0) {
99 "Found the following role ids for address '%s': %s",
100 $this->address->getMailbox() . '@' . $this->address->getHost(),
101 implode(', ', array_unique($role_ids))
102 ));
103
104 foreach ($role_ids as $role_id) {
105 foreach ($this->rbacreview->assignedUsers($role_id) as $usr_id) {
106 $usr_ids[] = $usr_id;
107 }
108 }
109
110 if (count($usr_ids) > 0) {
111 ilLoggerFactory::getLogger('mail')->debug(sprintf(
112 "Found the following user ids for roles determined by address '%s': %s",
113 $this->address->getMailbox() . '@' . $this->address->getHost(),
114 implode(', ', array_unique($usr_ids))
115 ));
116 } else {
117 ilLoggerFactory::getLogger('mail')->debug(sprintf(
118 "Did not find any assigned users for roles determined by '%s'",
119 $this->address->getMailbox() . '@' . $this->address->getHost()
120 ));
121 }
122 } else {
123 ilLoggerFactory::getLogger('mail')->debug(sprintf(
124 "Did not find any role (and user ids) for address '%s'",
125 $this->address->getMailbox() . '@' . $this->address->getHost()
126 ));
127 }
128
129 return array_unique($usr_ids);
130 }
sprintf('%.4f', $callTime)
static getLogger($a_component_id)
Get component logger.

References ilLoggerFactory\getLogger(), getRoleIdsByAddress(), and sprintf.

+ Here is the call graph for this function:

◆ searchRolesByMailboxAddressList()

static ilMailRoleAddressType::searchRolesByMailboxAddressList (   $a_address_list,
ilMailRfc822AddressParserFactory  $parserFactory = null,
ilMailRfc822AddressParser  $parser = null 
)
static

Finds all role ids that match the specified user friendly role mailbox address list.

The role mailbox name address list is an e-mail address list according to IETF RFC 822:

address list = role mailbox, {"," role mailbox } ; role mailbox = "#", local part, ["@" domain] ;

Examples: The following role mailbox names are all resolved to the role il_crs_member_123:

#Course.A #member@Course.A #il_crs_member_123@Course.A #il_crs_member_123 #il_crs_member_123@ilias

Examples: The following role mailbox names are all resolved to the role il_crs_member_345:

#member@[English Course] #il_crs_member_345@[English Course] #il_crs_member_345 #il_crs_member_345@ilias

If only the local part is specified, or if domain is equal to "ilias", ILIAS compares the title of role objects with local part. Only roles that are not in a trash folder are considered for the comparison.

If a domain is specified, and if the domain is not equal to "ilias", ILIAS compares the title of objects with the domain. Only objects that are not in a trash folder are considered for the comparison. Then ILIAS searches for local roles which contain the local part in their title. This allows for abbreviated role names, e.g. instead of having to specify #il_grp_member_345@MyGroup, it is sufficient to specify #member@MyGroup.

The address list may contain addresses thate are not role mailboxes. These addresses are ignored.

If a role mailbox address is ambiguous, this function returns the ID's of all role objects that are possible recipients for the role mailbox address.

If Pear Mail is not installed, then the mailbox address

Parameters
$a_address_list
ilMailRfc822AddressParserFactory | null$parserFactory
ilMailRfc822AddressParser | null$parser
Returns
int[] Array with role ids that were found

Definition at line 179 of file class.ilMailRoleAddressType.php.

183 {
184 global $DIC;
185
186 if ($parserFactory === null) {
187 $parserFactory = new ilMailRfc822AddressParserFactory();
188 }
189
190 if ($parser === null) {
191 $parser = $parserFactory->getParser($a_address_list);
192 }
193
194 $role_ids = array();
195 $parsedList = $parser->parse();
196
197 foreach ($parsedList as $address) {
198 $local_part = $address->getMailbox();
199 if (strpos($local_part, '#') !== 0 && !($local_part{0} == '"' && $local_part{1} == "#")) {
200 // A local-part which doesn't start with a '#' doesn't denote a role.
201 // Therefore we can skip it.
202 continue;
203 }
204
205 $local_part = substr($local_part, 1);
206
207 /* If role contains spaces, eg. 'foo role', double quotes are added which have to be removed here.*/
208 if ($local_part{0} == '#' && $local_part{strlen($local_part) - 1} == '"') {
209 $local_part = substr($local_part, 1);
210 $local_part = substr($local_part, 0, strlen($local_part) - 1);
211 }
212
213 if (substr($local_part, 0, 8) == 'il_role_') {
214 $role_id = substr($local_part, 8);
215 $query = "SELECT t.tree " .
216 "FROM rbac_fa fa " .
217 "JOIN tree t ON t.child = fa.parent " .
218 "WHERE fa.rol_id = " . $DIC->database()->quote($role_id, 'integer') . " " .
219 "AND fa.assign = 'y' " .
220 "AND t.tree = 1";
221 $res = $DIC->database()->query($query);
222 if ($DIC->database()->numRows($res) > 0) {
223 $role_ids[] = $role_id;
224 }
225 continue;
226 }
227
228 $domain = $address->getHost();
229 if (strpos($domain, '[') == 0 && strrpos($domain, ']')) {
230 $domain = substr($domain, 1, strlen($domain) - 2);
231 }
232 if (strlen($local_part) == 0) {
233 $local_part = $domain;
236 }
237
238 if (strtolower($address->getHost()) == ilMail::ILIAS_HOST) {
239 // Search for roles = local-part in the whole repository
240 $query = "SELECT dat.obj_id " .
241 "FROM object_data dat " .
242 "JOIN rbac_fa fa ON fa.rol_id = dat.obj_id " .
243 "JOIN tree t ON t.child = fa.parent " .
244 "WHERE dat.title =" . $DIC->database()->quote($local_part, 'text') . " " .
245 "AND dat.type = 'role' " .
246 "AND fa.assign = 'y' " .
247 "AND t.tree = 1";
248 } else {
249 // Search for roles like local-part in objects = host
250 $query = "SELECT rdat.obj_id " .
251 "FROM object_data odat " .
252 "JOIN object_reference oref ON oref.obj_id = odat.obj_id " .
253 "JOIN tree otree ON otree.child = oref.ref_id " .
254 "JOIN rbac_fa rfa ON rfa.parent = otree.child " .
255 "JOIN object_data rdat ON rdat.obj_id = rfa.rol_id " .
256 "WHERE odat.title = " . $DIC->database()->quote($domain, 'text') . " " .
257 "AND otree.tree = 1 " .
258 "AND rfa.assign = 'y' " .
259 "AND rdat.title LIKE " .
260 $DIC->database()->quote('%' . preg_replace('/([_%])/', '\\\\$1', $local_part) . '%', 'text');
261 }
262 $res = $DIC->database()->query($query);
263
264 $count = 0;
265 while ($row = $DIC->database()->fetchAssoc($res)) {
266 $role_ids[] = $row['obj_id'];
267
268 $count++;
269 }
270
271 // Nothing found?
272 // In this case, we search for roles = host.
273 if ($count == 0 && strtolower($address->getHost()) == ilMail::ILIAS_HOST) {
274 $q = "SELECT dat.obj_id " .
275 "FROM object_data dat " .
276 "JOIN object_reference ref ON ref.obj_id = dat.obj_id " .
277 "JOIN tree t ON t.child = ref.ref_id " .
278 "WHERE dat.title = " . $DIC->database()->quote($domain, 'text') . " " .
279 "AND dat.type = 'role' " .
280 "AND t.tree = 1 ";
281 $res = $DIC->database()->query($q);
282
283 while ($row = $DIC->database()->fetchAssoc($res)) {
284 $role_ids[] = $row['obj_id'];
285 }
286 }
287 }
288
289 return $role_ids;
290 }
const ILIAS_HOST

References ilBaseMailAddressType\$address, $DIC, $domain, $parser, $query, $res, $row, and ilMail\ILIAS_HOST.

Referenced by getRoleIdsByAddress(), and ilObjUserFolderGUI\importUserRoleAssignmentObject().

+ Here is the caller graph for this function:

Field Documentation

◆ $may_send_to_global_roles

ilMailRoleAddressType::$may_send_to_global_roles = array()
staticprotected

Definition at line 23 of file class.ilMailRoleAddressType.php.

◆ $role_ids_by_address

ilMailRoleAddressType::$role_ids_by_address = array()
staticprotected

Definition at line 18 of file class.ilMailRoleAddressType.php.


The documentation for this class was generated from the following file: