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