1 | <?php |
||||||||
2 | /* |
||||||||
3 | * SPDX-License-Identifier: AGPL-3.0-only |
||||||||
4 | * SPDX-FileCopyrightText: Copyright 2007-2016 Zarafa Deutschland GmbH |
||||||||
5 | * SPDX-FileCopyrightText: Copyright 2020-2024 grommunio GmbH |
||||||||
6 | * |
||||||||
7 | * Several utility functions |
||||||||
8 | */ |
||||||||
9 | |||||||||
10 | class Utils { |
||||||||
11 | /** |
||||||||
12 | * Prints a variable as string |
||||||||
13 | * If a boolean is sent, 'true' or 'false' is displayed. |
||||||||
14 | * |
||||||||
15 | * @param string $var |
||||||||
16 | * |
||||||||
17 | * @return string |
||||||||
18 | */ |
||||||||
19 | public static function PrintAsString($var) { |
||||||||
20 | return ($var) ? (($var === true) ? 'true' : $var) : (($var === false) ? 'false' : (($var === '') ? 'empty' : (($var === null) ? 'null' : $var))); |
||||||||
0 ignored issues
–
show
introduced
by
![]() |
|||||||||
21 | } |
||||||||
22 | |||||||||
23 | /** |
||||||||
24 | * Splits a "domain\user" string into two values |
||||||||
25 | * If the string contains only the user, domain is returned empty. |
||||||||
26 | * |
||||||||
27 | * @param string $domainuser |
||||||||
28 | * |
||||||||
29 | * @return array index 0: user 1: domain |
||||||||
30 | */ |
||||||||
31 | public static function SplitDomainUser($domainuser) { |
||||||||
32 | $pos = strrpos($domainuser, '\\'); |
||||||||
33 | if ($pos === false) { |
||||||||
34 | $user = $domainuser; |
||||||||
35 | $domain = ''; |
||||||||
36 | } |
||||||||
37 | else { |
||||||||
38 | $domain = substr($domainuser, 0, $pos); |
||||||||
39 | $user = substr($domainuser, $pos + 1); |
||||||||
40 | } |
||||||||
41 | |||||||||
42 | return [$user, $domain]; |
||||||||
43 | } |
||||||||
44 | |||||||||
45 | /** |
||||||||
46 | * Build an address string from the components. |
||||||||
47 | * |
||||||||
48 | * @param string $street the street |
||||||||
49 | * @param string $zip the zip code |
||||||||
50 | * @param string $city the city |
||||||||
51 | * @param string $state the state |
||||||||
52 | * @param string $country the country |
||||||||
53 | * |
||||||||
54 | * @return string the address string or null |
||||||||
55 | */ |
||||||||
56 | public static function BuildAddressString($street, $zip, $city, $state, $country) { |
||||||||
57 | $out = $country ?? ""; |
||||||||
58 | |||||||||
59 | $zcs = $zip ?? ""; |
||||||||
60 | if ($city != "") { |
||||||||
61 | $zcs .= (($zcs) ? " " : "") . $city; |
||||||||
62 | } |
||||||||
63 | if ($state != "") { |
||||||||
64 | $zcs .= (($zcs) ? " " : "") . $state; |
||||||||
65 | } |
||||||||
66 | if ($zcs) { |
||||||||
67 | $out = $zcs . "\r\n" . $out; |
||||||||
68 | } |
||||||||
69 | |||||||||
70 | if ($street != "") { |
||||||||
71 | $out = $street . (($out) ? "\r\n\r\n" . $out : ""); |
||||||||
72 | } |
||||||||
73 | |||||||||
74 | return $out ?? null; |
||||||||
75 | } |
||||||||
76 | |||||||||
77 | /** |
||||||||
78 | * Build the fileas string from the components according to the configuration. |
||||||||
79 | * |
||||||||
80 | * @param string $lastname |
||||||||
81 | * @param string $firstname |
||||||||
82 | * @param string $middlename |
||||||||
83 | * @param string $company |
||||||||
84 | * |
||||||||
85 | * @return string fileas |
||||||||
86 | */ |
||||||||
87 | public static function BuildFileAs($lastname = "", $firstname = "", $middlename = "", $company = "") { |
||||||||
88 | if (defined('FILEAS_ORDER')) { |
||||||||
89 | $fileas = $lastfirst = $firstlast = ""; |
||||||||
90 | $names = trim($firstname . " " . $middlename); |
||||||||
91 | $lastname = trim($lastname); |
||||||||
92 | $company = trim($company); |
||||||||
93 | |||||||||
94 | // lastfirst is "lastname, firstname middlename" |
||||||||
95 | // firstlast is "firstname middlename lastname" |
||||||||
96 | if (strlen($lastname) > 0) { |
||||||||
97 | $lastfirst = $lastname; |
||||||||
98 | if (strlen($names) > 0) { |
||||||||
99 | $lastfirst .= ", {$names}"; |
||||||||
100 | $firstlast = "{$names} {$lastname}"; |
||||||||
101 | } |
||||||||
102 | else { |
||||||||
103 | $firstlast = $lastname; |
||||||||
104 | } |
||||||||
105 | } |
||||||||
106 | elseif (strlen($names) > 0) { |
||||||||
107 | $lastfirst = $firstlast = $names; |
||||||||
108 | } |
||||||||
109 | |||||||||
110 | // if fileas with a company is selected |
||||||||
111 | // but company is empty then it will |
||||||||
112 | // fallback to firstlast or lastfirst |
||||||||
113 | // (depending on which is selected for company) |
||||||||
114 | switch (FILEAS_ORDER) { |
||||||||
115 | case SYNC_FILEAS_COMPANYONLY: |
||||||||
116 | if (strlen($company) > 0) { |
||||||||
117 | $fileas = $company; |
||||||||
118 | } |
||||||||
119 | elseif (strlen($firstlast) > 0) { |
||||||||
120 | $fileas = $lastfirst; |
||||||||
121 | } |
||||||||
122 | break; |
||||||||
123 | |||||||||
124 | case SYNC_FILEAS_COMPANYLAST: |
||||||||
125 | if (strlen($company) > 0) { |
||||||||
126 | $fileas = $company; |
||||||||
127 | if (strlen($lastfirst) > 0) { |
||||||||
128 | $fileas .= "({$lastfirst})"; |
||||||||
129 | } |
||||||||
130 | } |
||||||||
131 | elseif (strlen($lastfirst) > 0) { |
||||||||
132 | $fileas = $lastfirst; |
||||||||
133 | } |
||||||||
134 | break; |
||||||||
135 | |||||||||
136 | case SYNC_FILEAS_COMPANYFIRST: |
||||||||
137 | if (strlen($company) > 0) { |
||||||||
138 | $fileas = $company; |
||||||||
139 | if (strlen($firstlast) > 0) { |
||||||||
140 | $fileas .= " ({$firstlast})"; |
||||||||
141 | } |
||||||||
142 | } |
||||||||
143 | elseif (strlen($firstlast) > 0) { |
||||||||
144 | $fileas = $firstlast; |
||||||||
145 | } |
||||||||
146 | break; |
||||||||
147 | |||||||||
148 | case SYNC_FILEAS_FIRSTCOMPANY: |
||||||||
149 | if (strlen($firstlast) > 0) { |
||||||||
150 | $fileas = $firstlast; |
||||||||
151 | if (strlen($company) > 0) { |
||||||||
152 | $fileas .= " ({$company})"; |
||||||||
153 | } |
||||||||
154 | } |
||||||||
155 | elseif (strlen($company) > 0) { |
||||||||
156 | $fileas = $company; |
||||||||
157 | } |
||||||||
158 | break; |
||||||||
159 | |||||||||
160 | case SYNC_FILEAS_LASTCOMPANY: |
||||||||
161 | if (strlen($lastfirst) > 0) { |
||||||||
162 | $fileas = $lastfirst; |
||||||||
163 | if (strlen($company) > 0) { |
||||||||
164 | $fileas .= " ({$company})"; |
||||||||
165 | } |
||||||||
166 | } |
||||||||
167 | elseif (strlen($company) > 0) { |
||||||||
168 | $fileas = $company; |
||||||||
169 | } |
||||||||
170 | break; |
||||||||
171 | |||||||||
172 | case SYNC_FILEAS_LASTFIRST: |
||||||||
173 | if (strlen($lastfirst) > 0) { |
||||||||
174 | $fileas = $lastfirst; |
||||||||
175 | } |
||||||||
176 | break; |
||||||||
177 | |||||||||
178 | default: |
||||||||
179 | $fileas = $firstlast; |
||||||||
180 | break; |
||||||||
181 | } |
||||||||
182 | if (strlen($fileas) == 0) { |
||||||||
183 | SLog::Write(LOGLEVEL_DEBUG, "Fileas is empty."); |
||||||||
184 | } |
||||||||
185 | |||||||||
186 | return $fileas; |
||||||||
187 | } |
||||||||
188 | SLog::Write(LOGLEVEL_DEBUG, "FILEAS_ORDER not defined. Add it to your config.php."); |
||||||||
189 | |||||||||
190 | return null; |
||||||||
191 | } |
||||||||
192 | |||||||||
193 | /** |
||||||||
194 | * Extracts the basedate of the GlobalObjectID and the RecurStartTime. |
||||||||
195 | * |
||||||||
196 | * @param string $goid OL compatible GlobalObjectID |
||||||||
197 | * @param long $recurStartTime |
||||||||
0 ignored issues
–
show
The type
long was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||||||
198 | * |
||||||||
199 | * @return long basedate |
||||||||
200 | */ |
||||||||
201 | public static function ExtractBaseDate($goid, $recurStartTime) { |
||||||||
202 | $hexbase = substr(bin2hex($goid), 32, 8); |
||||||||
203 | $day = hexdec(substr($hexbase, 6, 2)); |
||||||||
204 | $month = hexdec(substr($hexbase, 4, 2)); |
||||||||
205 | $year = hexdec(substr($hexbase, 0, 4)); |
||||||||
206 | |||||||||
207 | if ($day && $month && $year) { |
||||||||
208 | $h = $recurStartTime >> 12; |
||||||||
209 | $m = ($recurStartTime - $h * 4096) >> 6; |
||||||||
210 | $s = $recurStartTime - $h * 4096 - $m * 64; |
||||||||
211 | |||||||||
212 | return gmmktime($h, $m, $s, $month, $day, $year); |
||||||||
0 ignored issues
–
show
It seems like
$month can also be of type double ; however, parameter $month of gmmktime() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$day can also be of type double ; however, parameter $day of gmmktime() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$year can also be of type double ; however, parameter $year of gmmktime() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
213 | } |
||||||||
214 | |||||||||
215 | return false; |
||||||||
0 ignored issues
–
show
|
|||||||||
216 | } |
||||||||
217 | |||||||||
218 | /** |
||||||||
219 | * Converts SYNC_FILTERTYPE into a timestamp. |
||||||||
220 | * |
||||||||
221 | * @param int $filtertype Filtertype |
||||||||
222 | * |
||||||||
223 | * @return long |
||||||||
224 | */ |
||||||||
225 | public static function GetCutOffDate($filtertype) { |
||||||||
226 | $back = Utils::GetFiltertypeInterval($filtertype); |
||||||||
227 | |||||||||
228 | if ($back === false) { |
||||||||
229 | return 0; // unlimited |
||||||||
0 ignored issues
–
show
|
|||||||||
230 | } |
||||||||
231 | |||||||||
232 | return time() - $back; |
||||||||
0 ignored issues
–
show
|
|||||||||
233 | } |
||||||||
234 | |||||||||
235 | /** |
||||||||
236 | * Returns the interval indicated by the filtertype. |
||||||||
237 | * |
||||||||
238 | * @param int $filtertype |
||||||||
239 | * |
||||||||
240 | * @return bool|long returns false on invalid filtertype |
||||||||
241 | */ |
||||||||
242 | public static function GetFiltertypeInterval($filtertype) { |
||||||||
243 | $back = false; |
||||||||
244 | |||||||||
245 | switch ($filtertype) { |
||||||||
246 | case SYNC_FILTERTYPE_1DAY: |
||||||||
247 | $back = 60 * 60 * 24; |
||||||||
248 | break; |
||||||||
249 | |||||||||
250 | case SYNC_FILTERTYPE_3DAYS: |
||||||||
251 | $back = 60 * 60 * 24 * 3; |
||||||||
252 | break; |
||||||||
253 | |||||||||
254 | case SYNC_FILTERTYPE_1WEEK: |
||||||||
255 | $back = 60 * 60 * 24 * 7; |
||||||||
256 | break; |
||||||||
257 | |||||||||
258 | case SYNC_FILTERTYPE_2WEEKS: |
||||||||
259 | $back = 60 * 60 * 24 * 14; |
||||||||
260 | break; |
||||||||
261 | |||||||||
262 | case SYNC_FILTERTYPE_1MONTH: |
||||||||
263 | $back = 60 * 60 * 24 * 31; |
||||||||
264 | break; |
||||||||
265 | |||||||||
266 | case SYNC_FILTERTYPE_3MONTHS: |
||||||||
267 | $back = 60 * 60 * 24 * 31 * 3; |
||||||||
268 | break; |
||||||||
269 | |||||||||
270 | case SYNC_FILTERTYPE_6MONTHS: |
||||||||
271 | $back = 60 * 60 * 24 * 31 * 6; |
||||||||
272 | break; |
||||||||
273 | |||||||||
274 | default: |
||||||||
275 | $back = false; |
||||||||
276 | } |
||||||||
277 | |||||||||
278 | return $back; |
||||||||
0 ignored issues
–
show
|
|||||||||
279 | } |
||||||||
280 | |||||||||
281 | /** |
||||||||
282 | * Converts SYNC_TRUNCATION into bytes. |
||||||||
283 | * |
||||||||
284 | * @param int SYNC_TRUNCATION |
||||||||
0 ignored issues
–
show
The type
SYNC_TRUNCATION was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||||||
285 | * @param mixed $truncation |
||||||||
286 | * |
||||||||
287 | * @return long |
||||||||
288 | */ |
||||||||
289 | public static function GetTruncSize($truncation) { |
||||||||
290 | switch ($truncation) { |
||||||||
291 | case SYNC_TRUNCATION_HEADERS: |
||||||||
292 | return 0; |
||||||||
0 ignored issues
–
show
|
|||||||||
293 | |||||||||
294 | case SYNC_TRUNCATION_512B: |
||||||||
295 | return 512; |
||||||||
0 ignored issues
–
show
|
|||||||||
296 | |||||||||
297 | case SYNC_TRUNCATION_1K: |
||||||||
298 | return 1024; |
||||||||
0 ignored issues
–
show
|
|||||||||
299 | |||||||||
300 | case SYNC_TRUNCATION_2K: |
||||||||
301 | return 2 * 1024; |
||||||||
0 ignored issues
–
show
|
|||||||||
302 | |||||||||
303 | case SYNC_TRUNCATION_5K: |
||||||||
304 | return 5 * 1024; |
||||||||
0 ignored issues
–
show
|
|||||||||
305 | |||||||||
306 | case SYNC_TRUNCATION_10K: |
||||||||
307 | return 10 * 1024; |
||||||||
0 ignored issues
–
show
|
|||||||||
308 | |||||||||
309 | case SYNC_TRUNCATION_20K: |
||||||||
310 | return 20 * 1024; |
||||||||
0 ignored issues
–
show
|
|||||||||
311 | |||||||||
312 | case SYNC_TRUNCATION_50K: |
||||||||
313 | return 50 * 1024; |
||||||||
0 ignored issues
–
show
|
|||||||||
314 | |||||||||
315 | case SYNC_TRUNCATION_100K: |
||||||||
316 | return 100 * 1024; |
||||||||
0 ignored issues
–
show
|
|||||||||
317 | |||||||||
318 | case SYNC_TRUNCATION_ALL: |
||||||||
319 | return 1024 * 1024; // We'll limit to 1MB anyway |
||||||||
0 ignored issues
–
show
|
|||||||||
320 | |||||||||
321 | default: |
||||||||
322 | return 1024; // Default to 1Kb |
||||||||
0 ignored issues
–
show
|
|||||||||
323 | } |
||||||||
324 | } |
||||||||
325 | |||||||||
326 | /** |
||||||||
327 | * Truncate an UTF-8 encoded string correctly. |
||||||||
328 | * |
||||||||
329 | * If it's not possible to truncate properly, an empty string is returned |
||||||||
330 | * |
||||||||
331 | * @param string $string the string |
||||||||
332 | * @param string $length position where string should be cut |
||||||||
333 | * @param bool $htmlsafe doesn't cut html tags in half, doesn't ensure correct html - default: false |
||||||||
334 | * |
||||||||
335 | * @return string truncated string |
||||||||
336 | */ |
||||||||
337 | public static function Utf8_truncate($string, $length, $htmlsafe = false) { |
||||||||
338 | // skip empty strings |
||||||||
339 | if (empty($string)) { |
||||||||
340 | return ""; |
||||||||
341 | } |
||||||||
342 | |||||||||
343 | // make sure length is always an integer |
||||||||
344 | $length = (int) $length; |
||||||||
345 | |||||||||
346 | // if the input string is shorter then the trunction, make sure it's valid UTF-8! |
||||||||
347 | if (strlen($string) <= $length) { |
||||||||
348 | $length = strlen($string) - 1; |
||||||||
349 | } |
||||||||
350 | |||||||||
351 | // The intent is not to cut HTML tags in half which causes displaying issues. |
||||||||
352 | // The used method just tries to cut outside of tags, without checking tag validity and closing tags. |
||||||||
353 | if ($htmlsafe) { |
||||||||
354 | $offset = 0 - strlen($string) + $length; |
||||||||
355 | $validPos = strrpos($string, "<", $offset); |
||||||||
356 | if ($validPos > strrpos($string, ">", $offset)) { |
||||||||
357 | $length = $validPos; |
||||||||
358 | } |
||||||||
359 | } |
||||||||
360 | |||||||||
361 | while ($length >= 0) { |
||||||||
362 | if ((ord($string[$length]) < 0x80) || (ord($string[$length]) >= 0xC0)) { |
||||||||
363 | return substr($string, 0, $length); |
||||||||
364 | } |
||||||||
365 | --$length; |
||||||||
366 | } |
||||||||
367 | |||||||||
368 | return ""; |
||||||||
369 | } |
||||||||
370 | |||||||||
371 | /** |
||||||||
372 | * Indicates if the specified folder type is a system folder. |
||||||||
373 | * |
||||||||
374 | * @param int $foldertype |
||||||||
375 | * |
||||||||
376 | * @return bool |
||||||||
377 | */ |
||||||||
378 | public static function IsSystemFolder($foldertype) { |
||||||||
379 | return ( |
||||||||
380 | $foldertype == SYNC_FOLDER_TYPE_INBOX || |
||||||||
381 | $foldertype == SYNC_FOLDER_TYPE_DRAFTS || |
||||||||
382 | $foldertype == SYNC_FOLDER_TYPE_WASTEBASKET || |
||||||||
383 | $foldertype == SYNC_FOLDER_TYPE_SENTMAIL || |
||||||||
384 | $foldertype == SYNC_FOLDER_TYPE_OUTBOX || |
||||||||
385 | $foldertype == SYNC_FOLDER_TYPE_TASK || |
||||||||
386 | $foldertype == SYNC_FOLDER_TYPE_APPOINTMENT || |
||||||||
387 | $foldertype == SYNC_FOLDER_TYPE_CONTACT || |
||||||||
388 | $foldertype == SYNC_FOLDER_TYPE_NOTE || |
||||||||
389 | $foldertype == SYNC_FOLDER_TYPE_JOURNAL |
||||||||
390 | ) ? true : false; |
||||||||
391 | } |
||||||||
392 | |||||||||
393 | /** |
||||||||
394 | * Checks for valid email addresses |
||||||||
395 | * The used regex actually only checks if a valid email address is part of the submitted string |
||||||||
396 | * it also returns true for the mailbox format, but this is not checked explicitly. |
||||||||
397 | * |
||||||||
398 | * @param string $email address to be checked |
||||||||
399 | * |
||||||||
400 | * @return bool |
||||||||
401 | */ |
||||||||
402 | public static function CheckEmail($email) { |
||||||||
403 | return strpos($email, '@') !== false ? true : false; |
||||||||
404 | } |
||||||||
405 | |||||||||
406 | /** |
||||||||
407 | * Checks if a string is base64 encoded. |
||||||||
408 | * |
||||||||
409 | * @param string $string the string to be checked |
||||||||
410 | * |
||||||||
411 | * @return bool |
||||||||
412 | */ |
||||||||
413 | public static function IsBase64String($string) { |
||||||||
414 | return (bool) preg_match("#^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+/]{4})?$#", $string); |
||||||||
415 | } |
||||||||
416 | |||||||||
417 | /** |
||||||||
418 | * Returns a command string for a given command code. |
||||||||
419 | * |
||||||||
420 | * @param int $code |
||||||||
421 | * |
||||||||
422 | * @return string or false if code is unknown |
||||||||
423 | */ |
||||||||
424 | public static function GetCommandFromCode($code) { |
||||||||
425 | switch ($code) { |
||||||||
426 | case GSync::COMMAND_SYNC: return 'Sync'; |
||||||||
427 | |||||||||
428 | case GSync::COMMAND_SENDMAIL: return 'SendMail'; |
||||||||
429 | |||||||||
430 | case GSync::COMMAND_SMARTFORWARD: return 'SmartForward'; |
||||||||
431 | |||||||||
432 | case GSync::COMMAND_SMARTREPLY: return 'SmartReply'; |
||||||||
433 | |||||||||
434 | case GSync::COMMAND_GETATTACHMENT: return 'GetAttachment'; |
||||||||
435 | |||||||||
436 | case GSync::COMMAND_FOLDERSYNC: return 'FolderSync'; |
||||||||
437 | |||||||||
438 | case GSync::COMMAND_FOLDERCREATE: return 'FolderCreate'; |
||||||||
439 | |||||||||
440 | case GSync::COMMAND_FOLDERDELETE: return 'FolderDelete'; |
||||||||
441 | |||||||||
442 | case GSync::COMMAND_FOLDERUPDATE: return 'FolderUpdate'; |
||||||||
443 | |||||||||
444 | case GSync::COMMAND_MOVEITEMS: return 'MoveItems'; |
||||||||
445 | |||||||||
446 | case GSync::COMMAND_GETITEMESTIMATE: return 'GetItemEstimate'; |
||||||||
447 | |||||||||
448 | case GSync::COMMAND_MEETINGRESPONSE: return 'MeetingResponse'; |
||||||||
449 | |||||||||
450 | case GSync::COMMAND_SEARCH: return 'Search'; |
||||||||
451 | |||||||||
452 | case GSync::COMMAND_SETTINGS: return 'Settings'; |
||||||||
453 | |||||||||
454 | case GSync::COMMAND_PING: return 'Ping'; |
||||||||
455 | |||||||||
456 | case GSync::COMMAND_ITEMOPERATIONS: return 'ItemOperations'; |
||||||||
457 | |||||||||
458 | case GSync::COMMAND_PROVISION: return 'Provision'; |
||||||||
459 | |||||||||
460 | case GSync::COMMAND_RESOLVERECIPIENTS: return 'ResolveRecipients'; |
||||||||
461 | |||||||||
462 | case GSync::COMMAND_VALIDATECERT: return 'ValidateCert'; |
||||||||
463 | |||||||||
464 | // Deprecated commands |
||||||||
465 | case GSync::COMMAND_GETHIERARCHY: return 'GetHierarchy'; |
||||||||
466 | |||||||||
467 | case GSync::COMMAND_CREATECOLLECTION: return 'CreateCollection'; |
||||||||
468 | |||||||||
469 | case GSync::COMMAND_DELETECOLLECTION: return 'DeleteCollection'; |
||||||||
470 | |||||||||
471 | case GSync::COMMAND_MOVECOLLECTION: return 'MoveCollection'; |
||||||||
472 | |||||||||
473 | case GSync::COMMAND_NOTIFY: return 'Notify'; |
||||||||
474 | |||||||||
475 | case GSync::COMMAND_FIND: return 'Find'; |
||||||||
476 | } |
||||||||
477 | |||||||||
478 | return false; |
||||||||
0 ignored issues
–
show
|
|||||||||
479 | } |
||||||||
480 | |||||||||
481 | /** |
||||||||
482 | * Returns a command code for a given command. |
||||||||
483 | * |
||||||||
484 | * @param string $command |
||||||||
485 | * |
||||||||
486 | * @return int or false if command is unknown |
||||||||
487 | */ |
||||||||
488 | public static function GetCodeFromCommand($command) { |
||||||||
489 | switch ($command) { |
||||||||
490 | case 'Sync': return GSync::COMMAND_SYNC; |
||||||||
491 | |||||||||
492 | case 'SendMail': return GSync::COMMAND_SENDMAIL; |
||||||||
493 | |||||||||
494 | case 'SmartForward': return GSync::COMMAND_SMARTFORWARD; |
||||||||
495 | |||||||||
496 | case 'SmartReply': return GSync::COMMAND_SMARTREPLY; |
||||||||
497 | |||||||||
498 | case 'GetAttachment': return GSync::COMMAND_GETATTACHMENT; |
||||||||
499 | |||||||||
500 | case 'FolderSync': return GSync::COMMAND_FOLDERSYNC; |
||||||||
501 | |||||||||
502 | case 'FolderCreate': return GSync::COMMAND_FOLDERCREATE; |
||||||||
503 | |||||||||
504 | case 'FolderDelete': return GSync::COMMAND_FOLDERDELETE; |
||||||||
505 | |||||||||
506 | case 'FolderUpdate': return GSync::COMMAND_FOLDERUPDATE; |
||||||||
507 | |||||||||
508 | case 'MoveItems': return GSync::COMMAND_MOVEITEMS; |
||||||||
509 | |||||||||
510 | case 'GetItemEstimate': return GSync::COMMAND_GETITEMESTIMATE; |
||||||||
511 | |||||||||
512 | case 'MeetingResponse': return GSync::COMMAND_MEETINGRESPONSE; |
||||||||
513 | |||||||||
514 | case 'Search': return GSync::COMMAND_SEARCH; |
||||||||
515 | |||||||||
516 | case 'Settings': return GSync::COMMAND_SETTINGS; |
||||||||
517 | |||||||||
518 | case 'Ping': return GSync::COMMAND_PING; |
||||||||
519 | |||||||||
520 | case 'ItemOperations': return GSync::COMMAND_ITEMOPERATIONS; |
||||||||
521 | |||||||||
522 | case 'Provision': return GSync::COMMAND_PROVISION; |
||||||||
523 | |||||||||
524 | case 'ResolveRecipients': return GSync::COMMAND_RESOLVERECIPIENTS; |
||||||||
525 | |||||||||
526 | case 'ValidateCert': return GSync::COMMAND_VALIDATECERT; |
||||||||
527 | |||||||||
528 | // Deprecated commands |
||||||||
529 | case 'GetHierarchy': return GSync::COMMAND_GETHIERARCHY; |
||||||||
530 | |||||||||
531 | case 'CreateCollection': return GSync::COMMAND_CREATECOLLECTION; |
||||||||
532 | |||||||||
533 | case 'DeleteCollection': return GSync::COMMAND_DELETECOLLECTION; |
||||||||
534 | |||||||||
535 | case 'MoveCollection': return GSync::COMMAND_MOVECOLLECTION; |
||||||||
536 | |||||||||
537 | case 'Notify': return GSync::COMMAND_NOTIFY; |
||||||||
538 | |||||||||
539 | case 'Find': return GSync::COMMAND_FIND; |
||||||||
540 | } |
||||||||
541 | |||||||||
542 | return false; |
||||||||
0 ignored issues
–
show
|
|||||||||
543 | } |
||||||||
544 | |||||||||
545 | /** |
||||||||
546 | * Normalize the given timestamp to the start of the day. |
||||||||
547 | * |
||||||||
548 | * @param long $timestamp |
||||||||
549 | * |
||||||||
550 | * @return long |
||||||||
551 | */ |
||||||||
552 | public static function getDayStartOfTimestamp($timestamp) { |
||||||||
553 | return $timestamp - ($timestamp % (60 * 60 * 24)); |
||||||||
0 ignored issues
–
show
|
|||||||||
554 | } |
||||||||
555 | |||||||||
556 | /** |
||||||||
557 | * Returns a formatted string output from an optional timestamp. |
||||||||
558 | * If no timestamp is sent, NOW is used. |
||||||||
559 | * |
||||||||
560 | * @param long $timestamp |
||||||||
561 | * |
||||||||
562 | * @return string |
||||||||
563 | */ |
||||||||
564 | public static function GetFormattedTime($timestamp = false) { |
||||||||
565 | if (!$timestamp) { |
||||||||
566 | $timestamp = time(); |
||||||||
567 | } |
||||||||
568 | |||||||||
569 | return date("d/m/Y H:i:s", $timestamp); |
||||||||
0 ignored issues
–
show
It seems like
$timestamp can also be of type long ; however, parameter $timestamp of date() does only seem to accept integer|null , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
570 | } |
||||||||
571 | |||||||||
572 | /** |
||||||||
573 | * Get charset name from a codepage. |
||||||||
574 | * |
||||||||
575 | * @see http://msdn.microsoft.com/en-us/library/dd317756(VS.85).aspx |
||||||||
576 | * |
||||||||
577 | * Table taken from common/codepage.cpp |
||||||||
578 | * |
||||||||
579 | * @param int codepage Codepage |
||||||||
0 ignored issues
–
show
The type
codepage was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||||||
580 | * @param mixed $codepage |
||||||||
581 | * |
||||||||
582 | * @return string iconv-compatible charset name |
||||||||
583 | */ |
||||||||
584 | public static function GetCodepageCharset($codepage) { |
||||||||
585 | $codepages = [ |
||||||||
586 | 20106 => "DIN_66003", |
||||||||
587 | 20108 => "NS_4551-1", |
||||||||
588 | 20107 => "SEN_850200_B", |
||||||||
589 | 950 => "big5", |
||||||||
590 | 50221 => "csISO2022JP", |
||||||||
591 | 51932 => "euc-jp", |
||||||||
592 | 51936 => "euc-cn", |
||||||||
593 | 51949 => "euc-kr", |
||||||||
594 | 949 => "euc-kr", |
||||||||
595 | 936 => "gb18030", |
||||||||
596 | 52936 => "csgb2312", |
||||||||
597 | 852 => "ibm852", |
||||||||
598 | 866 => "ibm866", |
||||||||
599 | 50220 => "iso-2022-jp", |
||||||||
600 | 50222 => "iso-2022-jp", |
||||||||
601 | 50225 => "iso-2022-kr", |
||||||||
602 | 1252 => "windows-1252", |
||||||||
603 | 28591 => "iso-8859-1", |
||||||||
604 | 28592 => "iso-8859-2", |
||||||||
605 | 28593 => "iso-8859-3", |
||||||||
606 | 28594 => "iso-8859-4", |
||||||||
607 | 28595 => "iso-8859-5", |
||||||||
608 | 28596 => "iso-8859-6", |
||||||||
609 | 28597 => "iso-8859-7", |
||||||||
610 | 28598 => "iso-8859-8", |
||||||||
611 | 28599 => "iso-8859-9", |
||||||||
612 | 28603 => "iso-8859-13", |
||||||||
613 | 28605 => "iso-8859-15", |
||||||||
614 | 20866 => "koi8-r", |
||||||||
615 | 21866 => "koi8-u", |
||||||||
616 | 932 => "shift-jis", |
||||||||
617 | 1200 => "unicode", |
||||||||
618 | 1201 => "unicodebig", |
||||||||
619 | 65000 => "utf-7", |
||||||||
620 | 65001 => "utf-8", |
||||||||
621 | 1250 => "windows-1250", |
||||||||
622 | 1251 => "windows-1251", |
||||||||
623 | 1253 => "windows-1253", |
||||||||
624 | 1254 => "windows-1254", |
||||||||
625 | 1255 => "windows-1255", |
||||||||
626 | 1256 => "windows-1256", |
||||||||
627 | 1257 => "windows-1257", |
||||||||
628 | 1258 => "windows-1258", |
||||||||
629 | 874 => "windows-874", |
||||||||
630 | 20127 => "us-ascii", |
||||||||
631 | ]; |
||||||||
632 | |||||||||
633 | if (isset($codepages[$codepage])) { |
||||||||
634 | return $codepages[$codepage]; |
||||||||
635 | } |
||||||||
636 | |||||||||
637 | // Defaulting to iso-8859-15 since it is more likely for someone to make a mistake in the codepage |
||||||||
638 | // when using west-european charsets then when using other charsets since utf-8 is binary compatible |
||||||||
639 | // with the bottom 7 bits of west-european |
||||||||
640 | return "iso-8859-15"; |
||||||||
641 | } |
||||||||
642 | |||||||||
643 | /** |
||||||||
644 | * Converts a string encoded with codepage into an UTF-8 string. |
||||||||
645 | * |
||||||||
646 | * @param int $codepage |
||||||||
647 | * @param string $string |
||||||||
648 | * |
||||||||
649 | * @return string |
||||||||
650 | */ |
||||||||
651 | public static function ConvertCodepageStringToUtf8($codepage, $string) { |
||||||||
652 | if (function_exists("iconv")) { |
||||||||
653 | $charset = self::GetCodepageCharset($codepage); |
||||||||
654 | |||||||||
655 | return iconv($charset, "utf-8", $string); |
||||||||
656 | } |
||||||||
657 | |||||||||
658 | SLog::Write(LOGLEVEL_WARN, "Utils::ConvertCodepageStringToUtf8() 'iconv' is not available. Charset conversion skipped."); |
||||||||
659 | |||||||||
660 | return $string; |
||||||||
661 | } |
||||||||
662 | |||||||||
663 | /** |
||||||||
664 | * Converts a string to another charset. |
||||||||
665 | * |
||||||||
666 | * @param int $in |
||||||||
667 | * @param int $out |
||||||||
668 | * @param string $string |
||||||||
669 | * |
||||||||
670 | * @return string |
||||||||
671 | */ |
||||||||
672 | public static function ConvertCodepage($in, $out, $string) { |
||||||||
673 | // do nothing if both charsets are the same |
||||||||
674 | if ($in == $out) { |
||||||||
675 | return $string; |
||||||||
676 | } |
||||||||
677 | |||||||||
678 | if (function_exists("iconv")) { |
||||||||
679 | $inCharset = self::GetCodepageCharset($in); |
||||||||
680 | $outCharset = self::GetCodepageCharset($out); |
||||||||
681 | |||||||||
682 | return iconv($inCharset, $outCharset, $string); |
||||||||
683 | } |
||||||||
684 | |||||||||
685 | SLog::Write(LOGLEVEL_WARN, "Utils::ConvertCodepage() 'iconv' is not available. Charset conversion skipped."); |
||||||||
686 | |||||||||
687 | return $string; |
||||||||
688 | } |
||||||||
689 | |||||||||
690 | /** |
||||||||
691 | * Returns the best match of preferred body preference types. |
||||||||
692 | * |
||||||||
693 | * @param array $bpTypes |
||||||||
694 | * |
||||||||
695 | * @return int |
||||||||
696 | */ |
||||||||
697 | public static function GetBodyPreferenceBestMatch($bpTypes) { |
||||||||
698 | if ($bpTypes === false) { |
||||||||
0 ignored issues
–
show
|
|||||||||
699 | return SYNC_BODYPREFERENCE_PLAIN; |
||||||||
700 | } |
||||||||
701 | // The bettter choice is HTML and then MIME in order to save bandwidth |
||||||||
702 | // because MIME is a complete message including the headers and attachments |
||||||||
703 | if (in_array(SYNC_BODYPREFERENCE_HTML, $bpTypes)) { |
||||||||
704 | return SYNC_BODYPREFERENCE_HTML; |
||||||||
705 | } |
||||||||
706 | if (in_array(SYNC_BODYPREFERENCE_MIME, $bpTypes)) { |
||||||||
707 | return SYNC_BODYPREFERENCE_MIME; |
||||||||
708 | } |
||||||||
709 | |||||||||
710 | return SYNC_BODYPREFERENCE_PLAIN; |
||||||||
711 | } |
||||||||
712 | |||||||||
713 | /** |
||||||||
714 | * Returns AS-style LastVerbExecuted value from the server value. |
||||||||
715 | * |
||||||||
716 | * @param int $verb |
||||||||
717 | * |
||||||||
718 | * @return int |
||||||||
719 | */ |
||||||||
720 | public static function GetLastVerbExecuted($verb) { |
||||||||
721 | switch ($verb) { |
||||||||
722 | case NOTEIVERB_REPLYTOSENDER: return AS_REPLYTOSENDER; |
||||||||
723 | |||||||||
724 | case NOTEIVERB_REPLYTOALL: return AS_REPLYTOALL; |
||||||||
725 | |||||||||
726 | case NOTEIVERB_FORWARD: return AS_FORWARD; |
||||||||
727 | } |
||||||||
728 | |||||||||
729 | return 0; |
||||||||
730 | } |
||||||||
731 | |||||||||
732 | /** |
||||||||
733 | * Returns the local part from email address. |
||||||||
734 | * |
||||||||
735 | * @param string $email |
||||||||
736 | * |
||||||||
737 | * @return string |
||||||||
738 | */ |
||||||||
739 | public static function GetLocalPartFromEmail($email) { |
||||||||
740 | $pos = strpos($email, '@'); |
||||||||
741 | if ($pos === false) { |
||||||||
742 | return $email; |
||||||||
743 | } |
||||||||
744 | |||||||||
745 | return substr($email, 0, $pos); |
||||||||
746 | } |
||||||||
747 | |||||||||
748 | /** |
||||||||
749 | * Format bytes to a more human readable value. |
||||||||
750 | * |
||||||||
751 | * @param int $bytes |
||||||||
752 | * @param int $precision |
||||||||
753 | * |
||||||||
754 | * @return string|void |
||||||||
755 | */ |
||||||||
756 | public static function FormatBytes($bytes, $precision = 2) { |
||||||||
757 | if ($bytes <= 0) { |
||||||||
758 | return '0 B'; |
||||||||
759 | } |
||||||||
760 | |||||||||
761 | $units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB']; |
||||||||
762 | $base = log($bytes, 1024); |
||||||||
763 | $fBase = floor($base); |
||||||||
764 | $pow = pow(1024, $base - $fBase); |
||||||||
765 | |||||||||
766 | return sprintf("%.{$precision}f %s", $pow, $units[$fBase]); |
||||||||
767 | } |
||||||||
768 | |||||||||
769 | /** |
||||||||
770 | * Returns folder origin identifier from its id. |
||||||||
771 | * |
||||||||
772 | * @param string $folderid |
||||||||
773 | * |
||||||||
774 | * @return bool|string matches values of DeviceManager::FLD_ORIGIN_* |
||||||||
775 | */ |
||||||||
776 | public static function GetFolderOriginFromId($folderid) { |
||||||||
777 | $origin = substr($folderid, 0, 1); |
||||||||
778 | |||||||||
779 | switch ($origin) { |
||||||||
780 | case DeviceManager::FLD_ORIGIN_CONFIG: |
||||||||
781 | case DeviceManager::FLD_ORIGIN_GAB: |
||||||||
782 | case DeviceManager::FLD_ORIGIN_SHARED: |
||||||||
783 | case DeviceManager::FLD_ORIGIN_USER: |
||||||||
784 | case DeviceManager::FLD_ORIGIN_IMPERSONATED: |
||||||||
785 | return $origin; |
||||||||
786 | } |
||||||||
787 | SLog::Write(LOGLEVEL_WARN, sprintf("Utils->GetFolderOriginFromId(): Unknown folder origin for folder with id '%s'", $folderid)); |
||||||||
788 | |||||||||
789 | return false; |
||||||||
790 | } |
||||||||
791 | |||||||||
792 | /** |
||||||||
793 | * Returns folder origin as string from its id. |
||||||||
794 | * |
||||||||
795 | * @param string $folderid |
||||||||
796 | * |
||||||||
797 | * @return string |
||||||||
798 | */ |
||||||||
799 | public static function GetFolderOriginStringFromId($folderid) { |
||||||||
800 | $origin = substr($folderid, 0, 1); |
||||||||
801 | |||||||||
802 | switch ($origin) { |
||||||||
803 | case DeviceManager::FLD_ORIGIN_CONFIG: |
||||||||
804 | return 'configured'; |
||||||||
805 | |||||||||
806 | case DeviceManager::FLD_ORIGIN_GAB: |
||||||||
807 | return 'GAB'; |
||||||||
808 | |||||||||
809 | case DeviceManager::FLD_ORIGIN_SHARED: |
||||||||
810 | return 'shared'; |
||||||||
811 | |||||||||
812 | case DeviceManager::FLD_ORIGIN_USER: |
||||||||
813 | return 'user'; |
||||||||
814 | |||||||||
815 | case DeviceManager::FLD_ORIGIN_IMPERSONATED: |
||||||||
816 | return 'impersonated'; |
||||||||
817 | } |
||||||||
818 | SLog::Write(LOGLEVEL_WARN, sprintf("Utils->GetFolderOriginStringFromId(): Unknown folder origin for folder with id '%s'", $folderid)); |
||||||||
819 | |||||||||
820 | return 'unknown'; |
||||||||
821 | } |
||||||||
822 | |||||||||
823 | /** |
||||||||
824 | * Splits the id into folder id and message id parts. A colon in the $id indicates |
||||||||
825 | * that the id has folderid:messageid format. |
||||||||
826 | * |
||||||||
827 | * @param string $id |
||||||||
828 | * |
||||||||
829 | * @return array |
||||||||
830 | */ |
||||||||
831 | public static function SplitMessageId($id) { |
||||||||
832 | if (strpos($id, ':') !== false) { |
||||||||
833 | return explode(':', $id); |
||||||||
834 | } |
||||||||
835 | |||||||||
836 | return [null, $id]; |
||||||||
837 | } |
||||||||
838 | |||||||||
839 | /** |
||||||||
840 | * Transforms an AS timestamp into a unix timestamp. |
||||||||
841 | * |
||||||||
842 | * @param string $ts |
||||||||
843 | * |
||||||||
844 | * @return long |
||||||||
845 | */ |
||||||||
846 | public static function ParseDate($ts) { |
||||||||
847 | if (preg_match("/(\\d{4})[^0-9]*(\\d{2})[^0-9]*(\\d{2})(T(\\d{2})[^0-9]*(\\d{2})[^0-9]*(\\d{2})(.\\d+)?Z){0,1}$/", $ts, $matches)) { |
||||||||
848 | if ($matches[1] >= 2038) { |
||||||||
849 | $matches[1] = 2038; |
||||||||
850 | $matches[2] = 1; |
||||||||
851 | $matches[3] = 18; |
||||||||
852 | $matches[5] = $matches[6] = $matches[7] = 0; |
||||||||
853 | } |
||||||||
854 | |||||||||
855 | if (!isset($matches[5])) { |
||||||||
856 | $matches[5] = 0; |
||||||||
857 | } |
||||||||
858 | if (!isset($matches[6])) { |
||||||||
859 | $matches[6] = 0; |
||||||||
860 | } |
||||||||
861 | if (!isset($matches[7])) { |
||||||||
862 | $matches[7] = 0; |
||||||||
863 | } |
||||||||
864 | |||||||||
865 | return gmmktime($matches[5], $matches[6], $matches[7], $matches[2], $matches[3], $matches[1]); |
||||||||
0 ignored issues
–
show
|
|||||||||
866 | } |
||||||||
867 | |||||||||
868 | return 0; |
||||||||
0 ignored issues
–
show
|
|||||||||
869 | } |
||||||||
870 | |||||||||
871 | /** |
||||||||
872 | * Transforms an unix timestamp into an AS timestamp or a human readable format. |
||||||||
873 | * |
||||||||
874 | * Oh yeah, this is beautiful. Exchange outputs date fields differently in calendar items |
||||||||
875 | * and emails. We could just always send one or the other, but unfortunately nokia's 'Mail for |
||||||||
876 | * exchange' depends on this quirk. So we have to send a different date type depending on where |
||||||||
877 | * it's used. Sigh. |
||||||||
878 | * |
||||||||
879 | * @param int $ts |
||||||||
880 | * @param int $type int (StreamerType) (optional) if not set a human readable format is returned |
||||||||
881 | * |
||||||||
882 | * @return string |
||||||||
883 | */ |
||||||||
884 | public static function FormatDate($ts, $type = "") { |
||||||||
885 | // fallback to a human readable format (used for logging) |
||||||||
886 | $formatString = "yyyy-MM-dd HH:mm:SS' UTC'"; |
||||||||
887 | if ($type == Streamer::STREAMER_TYPE_DATE) { |
||||||||
888 | $formatString = "yyyyMMdd'T'HHmmSS'Z'"; |
||||||||
889 | } |
||||||||
890 | elseif ($type == Streamer::STREAMER_TYPE_DATE_DASHES) { |
||||||||
891 | $formatString = "yyyy-MM-dd'T'HH:mm:SS'.000Z'"; |
||||||||
892 | } |
||||||||
893 | |||||||||
894 | $formatter = datefmt_create( |
||||||||
895 | 'en_US', |
||||||||
896 | IntlDateFormatter::FULL, |
||||||||
897 | IntlDateFormatter::FULL, |
||||||||
898 | 'UTC', |
||||||||
899 | IntlDateFormatter::GREGORIAN, |
||||||||
900 | $formatString |
||||||||
901 | ); |
||||||||
902 | |||||||||
903 | return datefmt_format($formatter, $ts); |
||||||||
904 | } |
||||||||
905 | |||||||||
906 | /** |
||||||||
907 | * Returns the appropriate SyncObjectResponse object based on message class. |
||||||||
908 | * |
||||||||
909 | * @param string $messageClass |
||||||||
910 | * |
||||||||
911 | * @return object |
||||||||
912 | */ |
||||||||
913 | public static function GetResponseFromMessageClass($messageClass) { |
||||||||
914 | $messageClass = strtolower($messageClass); |
||||||||
915 | |||||||||
916 | switch ($messageClass) { |
||||||||
917 | case 'syncappointment': |
||||||||
918 | return new SyncAppointmentResponse(); |
||||||||
919 | |||||||||
920 | case 'synccontact': |
||||||||
921 | return new SyncContactResponse(); |
||||||||
922 | |||||||||
923 | case 'syncnote': |
||||||||
924 | return new SyncNoteResponse(); |
||||||||
925 | |||||||||
926 | case 'synctask': |
||||||||
927 | return new SyncTaskResponse(); |
||||||||
928 | |||||||||
929 | default: |
||||||||
930 | return new SyncMailResponse(); |
||||||||
931 | } |
||||||||
932 | |||||||||
933 | return new SyncMailResponse(); |
||||||||
0 ignored issues
–
show
return new SyncMailResponse() is not reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||||||||
934 | } |
||||||||
935 | } |
||||||||
936 |