ILIAS  trunk Revision v11.0_alpha-1731-gff9cd7e2bd3
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilRoleMailboxAddress.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
28 {
30  protected ilDBInterface $db;
31  protected ilLanguage $lng;
32 
33  public function __construct(
34  protected int $roleId,
35  protected bool $localize = true,
36  ?ilMailRfc822AddressParserFactory $parserFactory = null,
37  ?ilDBInterface $db = null,
38  ?ilLanguage $lng = null
39  ) {
40  global $DIC;
41 
42  if (null === $db) {
43  $db = $DIC->database();
44  }
45  $this->db = $db;
46 
47  if (null === $lng) {
48  $lng = $DIC->language();
49  }
50  $this->lng = $lng;
51 
52  if (null === $parserFactory) {
53  $parserFactory = new ilMailRfc822AddressParserFactory();
54  }
55  $this->parserFactory = $parserFactory;
56  }
57 
116  public function value(): string
117  {
118  // Retrieve the role title and the object title.
119  $query = "SELECT rdat.title role_title,odat.title object_title, " .
120  " oref.ref_id object_ref " .
121  "FROM object_data rdat " .
122  "JOIN rbac_fa fa ON fa.rol_id = rdat.obj_id " .
123  "JOIN tree rtree ON rtree.child = fa.parent " .
124  "JOIN object_reference oref ON oref.ref_id = rtree.child " .
125  "JOIN object_data odat ON odat.obj_id = oref.obj_id " .
126  "WHERE rdat.obj_id = " . $this->db->quote($this->roleId, 'integer') . " " .
127  "AND fa.assign = 'y' ";
128  $res = $this->db->query($query);
129  if (($row = $this->db->fetchObject($res)) === null) {
130  return '';
131  }
132 
133  $object_title = $row->object_title;
134  $object_ref = (int) $row->object_ref;
135  $role_title = $row->role_title;
136 
137  // In a perfect world, we could use the object_title in the
138  // domain part of the mailbox address, and the role title
139  // with prefix '#' in the local part of the mailbox address.
140  $domain = $object_title;
141  $local_part = $role_title;
142 
143  // Determine if the object title is unique
144  $q = "SELECT COUNT(DISTINCT dat.obj_id) count " .
145  "FROM object_data dat " .
146  "JOIN object_reference ref ON ref.obj_id = dat.obj_id " .
147  "JOIN tree ON tree.child = ref.ref_id " .
148  "WHERE title = " . $this->db->quote($object_title, 'text') . " " .
149  "AND tree.tree = 1 ";
150  $res = $this->db->query($q);
151  $row = $this->db->fetchObject($res);
152 
153  // If the object title is not unique, we get rid of the domain.
154  if ($row->count > 1) {
155  $domain = null;
156  }
157 
158  // If the domain contains illegal characters, we get rid of it.
159  //if (domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]/',$domain))
160  // Fix for Mantis Bug: 7429 sending mail fails because of brakets
161  // Fix for Mantis Bug: 9978 sending mail fails because of semicolon
162  if ($domain !== null && preg_match('/[\[\]\\]|[\x00-\x1f]|[\x28-\x29]|[;]/', (string) $domain)) {
163  $domain = null;
164  }
165 
166  // If the domain contains special characters, we put square
167  // brackets around it.
168  if ($domain !== null &&
169  (preg_match('/[()<>@,;:\\".\[\]]/', (string) $domain) ||
170  preg_match('/[^\x21-\x8f]/', (string) $domain))
171  ) {
172  $domain = '[' . $domain . ']';
173  }
174 
175  // If the role title is one of the ILIAS reserved role titles,
176  // we can use a shorthand version of it for the local part
177  // of the mailbox address.
178  if ($domain !== null && str_starts_with($role_title, 'il_')) {
179  $unambiguous_role_title = $role_title;
180 
181  $pos = strpos($role_title, '_', 3) + 1;
182  $local_part = substr(
183  $role_title,
184  $pos,
185  strrpos($role_title, '_') - $pos
186  );
187  } else {
188  $unambiguous_role_title = 'il_role_' . $this->roleId;
189  }
190 
191  // Determine if the local part is unique. If we don't have a
192  // domain, the local part must be unique within the whole repositry.
193  // If we do have a domain, the local part must be unique for that
194  // domain.
195  if ($domain === null) {
196  $q = "SELECT COUNT(DISTINCT dat.obj_id) count " .
197  "FROM object_data dat " .
198  "JOIN object_reference ref ON ref.obj_id = dat.obj_id " .
199  "JOIN tree ON tree.child = ref.ref_id " .
200  "WHERE title = " . $this->db->quote($local_part, 'text') . " " .
201  "AND tree.tree = 1 ";
202  } else {
203  $q = "SELECT COUNT(rd.obj_id) count " .
204  "FROM object_data rd " .
205  "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id " .
206  "JOIN tree t ON t.child = fa.parent " .
207  "WHERE fa.assign = 'y' " .
208  "AND t.child = " . $this->db->quote($object_ref, 'integer') . " " .
209  "AND rd.title LIKE " . $this->db->quote(
210  '%' . preg_replace('/([_%])/', '\\\\$1', $local_part) . '%',
211  'text'
212  ) . " ";
213  }
214 
215  $res = $this->db->query($q);
216  $row = $this->db->fetchObject($res);
217 
218  // if the local_part is not unique, we use the unambiguous role title
219  // instead for the local part of the mailbox address
220  if ($row->count > 1) {
221  $local_part = $unambiguous_role_title;
222  }
223 
224  $use_phrase = true;
225 
226  // If the local part contains illegal characters, we use
227  // the unambiguous role title instead.
228  if (preg_match('/[\\"\x00-\x1f]/', (string) $local_part)) {
229  $local_part = $unambiguous_role_title;
230  } elseif (!preg_match('/^[\\x00-\\x7E]+$/i', (string) $local_part)) {
231  // 2013-12-05: According to #12283, we do not accept umlauts in the local part
232  $local_part = $unambiguous_role_title;
233  $use_phrase = false;
234  }
235 
236  // Add a "#" prefix to the local part
237  $local_part = '#' . $local_part;
238 
239  // Put quotes around the role title, if needed
240  if (preg_match('/[()<>@,;:.\[\]\x20]/', $local_part)) {
241  $local_part = '"' . $local_part . '"';
242  }
243 
244  $mailbox = ($domain === null) ?
245  $local_part :
246  $local_part . '@' . $domain;
247 
248  if ($this->localize) {
249  if (str_starts_with($role_title, 'il_')) {
250  $phrase = $this->lng->txt(substr($role_title, 0, strrpos($role_title, '_')));
251  } else {
252  $phrase = $role_title;
253  }
254 
255  if ($use_phrase) {
256  // make phrase RFC 822 conformant:
257  // - strip excessive whitespace
258  // - strip special characters
259  $phrase = preg_replace('/\s\s+/', ' ', $phrase);
260  $phrase = preg_replace('/[()<>@,;:\\".\[\]]/', '', $phrase);
261 
262  $mailbox = $phrase . ' <' . $mailbox . '>';
263  }
264  }
265 
266  try {
267  $parser = $this->parserFactory->getParser($mailbox);
268  $parser->parse();
269 
270  return $mailbox;
271  } catch (ilMailException) {
272  $res = $this->db->query("SELECT title FROM object_data WHERE obj_id = " . $this->db->quote(
273  $this->roleId,
274  'integer'
275  ));
276  if (($row = $this->db->fetchObject($res)) !== null) {
277  return '#' . $row->title;
278  }
279 
280  return '';
281  }
282  }
283 }
value()
Returns the mailbox address of a role.
$res
Definition: ltiservices.php:66
Class ilRoleMailboxAddress.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
Class ilMailRfc822AddressParserFactory.
global $DIC
Definition: shib_login.php:22
__construct(protected int $roleId, protected bool $localize=true, ?ilMailRfc822AddressParserFactory $parserFactory=null, ?ilDBInterface $db=null, ?ilLanguage $lng=null)
$q
Definition: shib_logout.php:21
ilMailRfc822AddressParserFactory $parserFactory