ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilRoleMailboxAddress.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22{
24 protected ilDBInterface $db;
25 protected ilLanguage $lng;
26
27 public function __construct(
28 protected int $role_id,
29 protected bool $localize = true,
31 ?ilDBInterface $db = null,
32 ?ilLanguage $lng = null
33 ) {
34 global $DIC;
35
36 $this->db = $db ?? $DIC->database();
37 $this->lng = $lng ?? $DIC->language();
38 $this->parser_factory = $parser_factory ?? new ilMailRfc822AddressParserFactory();
39 }
40
99 public function value(): string
100 {
101 // Retrieve the role title and the object title.
102 $query = 'SELECT rdat.title role_title, odat.title object_title, ' .
103 ' oref.ref_id object_ref ' .
104 'FROM object_data rdat ' .
105 'INNER JOIN role_data roledat ON roledat.role_id = rdat.obj_id ' .
106 'INNER JOIN rbac_fa fa ON fa.rol_id = rdat.obj_id AND fa.assign = ' . $this->db->quote('y', ilDBConstants::T_TEXT) . ' ' .
107 'INNER JOIN tree rtree ON rtree.child = fa.parent ' .
108 'INNER JOIN object_reference oref ON oref.ref_id = rtree.child ' .
109 'INNER JOIN object_data odat ON odat.obj_id = oref.obj_id ' .
110 'WHERE rdat.obj_id = ' . $this->db->quote($this->role_id, ilDBConstants::T_INTEGER);
111 $res = $this->db->query($query);
112 if (($row = $this->db->fetchObject($res)) === null) {
113 return '';
114 }
115
116 $object_title = $row->object_title;
117 $object_ref = (int) $row->object_ref;
118 $role_title = $row->role_title;
119
120 // In a perfect world, we could use the object_title in the
121 // domain part of the mailbox address, and the role title
122 // with prefix '#' in the local part of the mailbox address.
123 $domain = $object_title;
124 $local_part = $role_title;
125
126 // Determine if the object title is unique (we exclude trashed obects)
127 $q = 'SELECT COUNT(DISTINCT dat.obj_id) AS count ' .
128 'FROM object_data dat ' .
129 'INNER JOIN object_reference ref ON ref.obj_id = dat.obj_id AND ref.deleted IS NULL ' .
130 'INNER JOIN tree ON tree.child = ref.ref_id AND tree.tree = ' . $this->db->quote(1, ilDBConstants::T_INTEGER) . ' ' .
131 'WHERE dat.title = ' . $this->db->quote($object_title, ilDBConstants::T_TEXT);
132 $res = $this->db->query($q);
133 $row = $this->db->fetchObject($res);
134
135 // If the object title is not unique/does not exists, we get rid of the domain.
136 if ($row->count !== 1) {
137 $domain = null;
138 }
139
140 // If the domain contains illegal characters, we get rid of it.
141 //if (domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]/',$domain))
142 // Fix for Mantis Bug: 7429 sending mail fails because of brakets
143 // Fix for Mantis Bug: 9978 sending mail fails because of semicolon
144 if ($domain !== null && preg_match('/[\[\]\\]|[\x00-\x1f]|[\x28-\x29]|[;]/', (string) $domain)) {
145 $domain = null;
146 }
147
148 // If the domain contains special characters, we put square
149 // brackets around it.
150 if ($domain !== null &&
151 (preg_match('/[()<>@,;:\\".\[\]]/', (string) $domain) ||
152 preg_match('/[^\x21-\x8f]/', (string) $domain))
153 ) {
154 $domain = '[' . $domain . ']';
155 }
156
157 // If the role title is one of the ILIAS reserved role titles,
158 // we can use a shorthand version of it for the local part
159 // of the mailbox address.
160 if ($domain !== null && str_starts_with($role_title, 'il_')) {
161 $unambiguous_role_title = $role_title;
162
163 $pos = strpos($role_title, '_', 3) + 1;
164 $local_part = substr(
165 $role_title,
166 $pos,
167 strrpos($role_title, '_') - $pos
168 );
169 } else {
170 $unambiguous_role_title = 'il_role_' . $this->role_id;
171 }
172
173 // Determine if the local part is unique. If we don't have a
174 // domain, the local part must be unique within the whole repositry.
175 // If we do have a domain, the local part must be unique for that
176 // domain.
177 if ($domain === null) {
178 // https://mantis.ilias.de/view.php?id=45319
179 $q = 'SELECT COUNT(DISTINCT rdat.role_id) AS count ' .
180 'FROM object_data dat ' .
181 'INNER JOIN role_data rdat ON rdat.role_id = dat.obj_id ' .
182 'INNER JOIN rbac_fa fa ON fa.rol_id = rdat.role_id ' .
183 'INNER JOIN tree t ON t.child = fa.parent ' .
184 'INNER JOIN object_reference oref ON oref.ref_id = t.child ' .
185 'WHERE dat.title = ' . $this->db->quote($local_part, ilDBConstants::T_TEXT);
186 } else {
187 $q = 'SELECT COUNT(rd.obj_id) AS count ' .
188 'FROM object_data rd ' .
189 'INNER JOIN rbac_fa fa ON fa.rol_id = rd.obj_id AND fa.assign = ' . $this->db->quote('y', ilDBConstants::T_TEXT) . ' ' .
190 'INNER JOIN tree t ON t.child = fa.parent AND t.child = ' . $this->db->quote($object_ref, ilDBConstants::T_INTEGER) . ' ' .
191 'WHERE rd.title LIKE ' . $this->db->quote(
192 '%' . preg_replace('/([_%])/', '\\\\$1', $local_part) . '%',
194 ) . ' ';
195 }
196
197 $res = $this->db->query($q);
198 $row = $this->db->fetchObject($res);
199
200 // if the local_part is not unique, we use the unambiguous role title
201 // instead for the local part of the mailbox address
202 if ($row->count !== 1) {
203 $local_part = $unambiguous_role_title;
204 }
205
206 $use_phrase = true;
207
208 // If the local part contains illegal characters, we use
209 // the unambiguous role title instead.
210 if (preg_match('/[\\"\x00-\x1f]/', (string) $local_part)) {
211 $local_part = $unambiguous_role_title;
212 } elseif (!preg_match('/^[\\x00-\\x7E]+$/i', (string) $local_part)) {
213 // 2013-12-05: According to #12283, we do not accept umlauts in the local part
214 $local_part = $unambiguous_role_title;
215 $use_phrase = false;
216 }
217
218 // Add a "#" prefix to the local part
219 $local_part = '#' . $local_part;
220
221 // Put quotes around the role title, if needed
222 if (preg_match('/[()<>@,;:.\[\]\x20]/', $local_part)) {
223 $local_part = '"' . $local_part . '"';
224 }
225
226 $mailbox = ($domain === null) ?
227 $local_part :
228 $local_part . '@' . $domain;
229
230 if ($this->localize) {
231 if (str_starts_with($role_title, 'il_')) {
232 $phrase = $this->lng->txt(substr($role_title, 0, strrpos($role_title, '_')));
233 } else {
234 $phrase = $role_title;
235 }
236
237 if ($use_phrase) {
238 // make phrase RFC 822 conformant:
239 // - strip excessive whitespace
240 // - strip special characters
241 $phrase = preg_replace('/\s\s+/', ' ', $phrase);
242 $phrase = preg_replace('/[()<>@,;:\\".\[\]]/', '', $phrase);
243
244 $mailbox = $phrase . ' <' . $mailbox . '>';
245 }
246 }
247
248 try {
249 $parser = $this->parser_factory->getParser($mailbox);
250 $parser->parse();
251
252 return $mailbox;
253 } catch (ilMailException) {
254 $res = $this->db->query(
255 'SELECT od.title
256 FROM object_data od
257 INNER JOIN role_data rd ON rd.role_id = od.obj_id
258 WHERE od.obj_id = ' . $this->db->quote($this->role_id, ilDBConstants::T_INTEGER) . '
259 AND NOT EXISTS (
260 SELECT 1
261 FROM object_data maybe_same_role_od
262 INNER JOIN role_data maybe_same_role_rd ON maybe_same_role_rd.role_id = maybe_same_role_od.obj_id
263 WHERE maybe_same_role_od.title = od.title
264 AND maybe_same_role_od.obj_id != od.obj_id
265 )'
266 );
267 if (($row = $this->db->fetchObject($res)) !== null) {
268 return '#' . $row->title;
269 }
270
271 return '#il_role_' . $this->role_id;
272 }
273 }
274}
language handling
__construct(protected int $role_id, protected bool $localize=true, ?ilMailRfc822AddressParserFactory $parser_factory=null, ?ilDBInterface $db=null, ?ilLanguage $lng=null)
value()
Returns the mailbox address of a role.
ilMailRfc822AddressParserFactory $parser_factory
Interface ilDBInterface.
$res
Definition: ltiservices.php:69
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:23