Passed
Push — master ( 4ca170...784f70 )
by Julito
12:58
created

api_format_date()   F

Complexity

Conditions 18
Paths 209

Size

Total Lines 121
Code Lines 79

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
eloc 79
nc 209
nop 3
dl 0
loc 121
rs 3.9208
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Framework\Container;
5
use ChamiloSession as Session;
6
use Patchwork\Utf8;
7
use Westsworld\TimeAgo;
8
9
/**
10
 * File: internationalization.lib.php
11
 * Internationalization library for Chamilo 1.x LMS
12
 * A library implementing internationalization related functions.
13
 * License: GNU General Public License Version 3 (Free Software Foundation)ww.
14
 *
15
 * @author Ivan Tcholakov, <[email protected]>, 2009, 2010
16
 * @author More authors, mentioned in the correpsonding fragments of this source.
17
 */
18
// Predefined date formats in Chamilo provided by the language sub-system.
19
// To be used as a parameter for the function api_format_date()
20
define('TIME_NO_SEC_FORMAT', 0); // 15:23
21
define('DATE_FORMAT_SHORT', 1); // Aug 25, 09
22
define('DATE_FORMAT_LONG', 2); // Monday August 25, 09
23
define('DATE_FORMAT_LONG_NO_DAY', 10); // August 25, 2009
24
define('DATE_TIME_FORMAT_LONG', 3); // Monday August 25, 2009 at 03:28 PM
25
26
define('DATE_FORMAT_NUMBER', 4); // 25.08.09
27
define('DATE_TIME_FORMAT_LONG_24H', 5); // August 25, 2009 at 15:28
28
define('DATE_TIME_FORMAT_SHORT', 6); // Aug 25, 2009 at 03:28 PM
29
define('DATE_TIME_FORMAT_SHORT_TIME_FIRST', 7); // 03:28 PM, Aug 25 2009
30
define('DATE_FORMAT_NUMBER_NO_YEAR', 8); // 25.08 dd-mm
31
define('DATE_FORMAT_ONLY_DAYNAME', 9); // Monday, Sunday, etc
32
33
// Formatting person's name.
34
// Formatting a person's name using the pattern as it has been
35
// configured in the internationalization database for every language.
36
// This (default) option would be the most used.
37
define('PERSON_NAME_COMMON_CONVENTION', 0);
38
// The following options may be used in limited number of places for overriding the common convention:
39
40
// Formatting a person's name in Western order: first_name last_name
41
define('PERSON_NAME_WESTERN_ORDER', 1);
42
// Formatting a person's name in Eastern order: last_name first_name
43
define('PERSON_NAME_EASTERN_ORDER', 2);
44
// Contextual: formatting person's name in library order: last_name, first_name
45
define('PERSON_NAME_LIBRARY_ORDER', 3);
46
// Contextual: formatting a person's name assotiated with an email-address.
47
// Ivan: I am not sure how seems email servers an clients would interpret name order, so I assign the Western order.
48
define('PERSON_NAME_EMAIL_ADDRESS', PERSON_NAME_WESTERN_ORDER);
49
// Contextual: formatting a person's name for data-exporting operations.
50
// For backward compatibility this format has been set to Eastern order.
51
define('PERSON_NAME_DATA_EXPORT', PERSON_NAME_EASTERN_ORDER);
52
53
/**
54
 * Returns a translated (localized) string.
55
 *
56
 * @param string $variable
57
 *
58
 * @return string
59
 */
60
function get_lang($variable)
61
{
62
    $translator = Container::getTranslator();
63
64
    if (!$translator) {
0 ignored issues
show
introduced by
$translator is of type Symfony\Contracts\Translation\TranslatorInterface, thus it always evaluated to true.
Loading history...
65
        return $variable;
66
    }
67
68
    // Using symfony
69
    $defaultDomain = 'messages';
70
    $locale = api_get_language_isocode();
71
72
    return $translator->trans(
73
        $variable,
74
        [],
75
        $defaultDomain,
76
        $locale
77
    );
78
}
79
80
/**
81
 * Gets the current interface language.
82
 *
83
 * @param bool $purified              (optional)    When it is true, a purified (refined)
84
 *                                    language value will be returned, for example 'french' instead of 'french_unicode'
85
 * @param bool $setParentLanguageName
86
 *
87
 * @return string the current language of the interface
88
 */
89
function api_get_interface_language(
90
    $purified = false,
0 ignored issues
show
Unused Code introduced by
The parameter $purified is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

90
    /** @scrutinizer ignore-unused */ $purified = false,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
91
    $check_sub_language = false,
0 ignored issues
show
Unused Code introduced by
The parameter $check_sub_language is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

91
    /** @scrutinizer ignore-unused */ $check_sub_language = false,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
92
    $setParentLanguageName = true
0 ignored issues
show
Unused Code introduced by
The parameter $setParentLanguageName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

92
    /** @scrutinizer ignore-unused */ $setParentLanguageName = true

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
93
) {
94
    return api_get_language_isocode();
95
}
96
97
/**
98
 * Returns a purified language id, without possible suffixes that will disturb language identification in certain cases.
99
 *
100
 * @param string the same purified or filtered language id, for example 'french'
101
 *
102
 * @return string
103
 */
104
function api_purify_language_id($language)
105
{
106
    static $purified = [];
107
    if (!isset($purified[$language])) {
108
        $purified[$language] = trim(
109
            str_replace(
110
                ['_unicode', '_latin', '_corporate', '_org', '_km'],
111
                '',
112
                strtolower($language)
113
            )
114
        );
115
    }
116
117
    return $purified[$language];
118
}
119
120
/**
121
 * Gets language iso code.
122
 */
123
function api_get_language_isocode()
124
{
125
    $request = Container::getRequest();
126
    if ($request) {
127
        return $request->getLocale();
128
    }
129
130
    return 'en';
131
}
132
133
/**
134
 * Gets language iso code column from the language table.
135
 *
136
 * @return array An array with the current isocodes
137
 *
138
 * */
139
function api_get_platform_isocodes()
140
{
141
    $list = [];
142
    $sql = "SELECT isocode
143
            FROM ".Database::get_main_table(TABLE_MAIN_LANGUAGE)."
144
            ORDER BY isocode ";
145
    $result = Database::query($sql);
146
    if (Database::num_rows($result)) {
147
        while ($row = Database::fetch_array($result)) {
148
            $list[] = trim($row['isocode']);
149
        }
150
    }
151
152
    return $list;
153
}
154
155
/**
156
 * Gets text direction according to the given language.
157
 *
158
 * @param string $language This is the name of the
159
 *                         folder containing translations for the corresponding language (e.g 'arabic', 'english', ...).
160
 *                         ISO-codes are acceptable too ('ar', 'en', ...).
161
 *                         If $language is omitted, interface language is assumed then.
162
 *
163
 * @return string the correspondent to the language text direction ('ltr' or 'rtl')
164
 */
165
function api_get_text_direction($language = null)
166
{
167
    static $text_direction = [];
168
169
    if (empty($language)) {
170
        $language = api_get_interface_language();
171
    }
172
    if (!isset($text_direction[$language])) {
173
        $text_direction[$language] = in_array(
174
            api_purify_language_id($language),
175
            [
176
                'arabic',
177
                'ar',
178
                'dari',
179
                'prs',
180
                'hebrew',
181
                'he',
182
                'iw',
183
                'pashto',
184
                'ps',
185
                'persian',
186
                'fa',
187
                'ur',
188
                'yiddish',
189
                'yid',
190
            ]
191
        ) ? 'rtl' : 'ltr';
192
    }
193
194
    return $text_direction[$language];
195
}
196
197
/**
198
 * Returns an alphabetized list of timezones in an associative array
199
 * that can be used to populate a select.
200
 *
201
 * @return array List of timezone identifiers
202
 *
203
 * @author Guillaume Viguier <[email protected]>
204
 */
205
function api_get_timezones()
206
{
207
    $timezone_identifiers = DateTimeZone::listIdentifiers();
208
    sort($timezone_identifiers);
209
    $out = [];
210
    foreach ($timezone_identifiers as $tz) {
211
        $out[$tz] = $tz;
212
    }
213
    $null_option = ['' => ''];
214
    $result = array_merge($null_option, $out);
215
216
    return $result;
217
}
218
219
/**
220
 * Returns the timezone to be converted to/from, based on user or admin preferences.
221
 *
222
 * @return string The timezone chosen
223
 */
224
function api_get_timezone()
225
{
226
    $timezone = Session::read('system_timezone');
227
    if (empty($timezone)) {
228
        // First, get the default timezone of the server
229
        $timezone = date_default_timezone_get();
230
        // Second, see if a timezone has been chosen for the platform
231
        $timezoneFromSettings = api_get_setting('timezone_value', 'timezones');
232
233
        if (null != $timezoneFromSettings) {
234
            $timezone = $timezoneFromSettings;
235
        }
236
237
        // If allowed by the administrator
238
        $allowUserTimezones = api_get_setting('use_users_timezone', 'timezones');
239
240
        if ('true' === $allowUserTimezones) {
241
            $userId = api_get_user_id();
242
            // Get the timezone based on user preference, if it exists
243
            $newExtraField = new ExtraFieldValue('user');
244
            $data = $newExtraField->get_values_by_handler_and_field_variable($userId, 'timezone');
245
            if (!empty($data) && isset($data['timezone']) && !empty($data['timezone'])) {
246
                $timezone = $data['timezone'];
247
            }
248
        }
249
        Session::write('system_timezone', $timezone);
250
    }
251
252
    return $timezone;
253
}
254
255
/**
256
 * Returns the given date as a DATETIME in UTC timezone.
257
 * This function should be used before entering any date in the DB.
258
 *
259
 * @param mixed $time                    Date to be converted (can be a string supported by date() or a timestamp)
260
 * @param bool  $returnNullIfInvalidDate If the date is not correct return null instead of the current date
261
 * @param bool  $returnObj               Returns a DateTime object
262
 *
263
 * @return string|DateTime The DATETIME in UTC to be inserted in the DB,
264
 *                         or null if the format of the argument is not supported
265
 *
266
 * @author Julio Montoya - Adding the 2nd parameter
267
 * @author Guillaume Viguier <[email protected]>
268
 */
269
function api_get_utc_datetime(
270
    $time = null,
271
    $returnNullIfInvalidDate = false,
272
    $returnObj = false
273
) {
274
    if (is_null($time) || empty($time) || '0000-00-00 00:00:00' === $time) {
275
        if ($returnNullIfInvalidDate) {
276
            return null;
277
        }
278
        if ($returnObj) {
279
            return new DateTime(gmdate('Y-m-d H:i:s'), new DateTimeZone('UTC'));
280
        }
281
282
        return gmdate('Y-m-d H:i:s');
283
    }
284
285
    // If time is a timestamp, return directly in utc
286
    if (is_numeric($time)) {
287
        $time = (int) $time;
288
289
        $time = gmdate('Y-m-d H:i:s', $time);
290
        if ($returnObj) {
291
            return new DateTime($time, new DateTimeZone('UTC'));
292
        }
293
294
        return $time;
295
    }
296
    try {
297
        $fromTimezone = api_get_timezone();
298
        $date = new DateTime($time, new DateTimezone($fromTimezone));
299
        $date->setTimezone(new DateTimeZone('UTC'));
300
        if ($returnObj) {
301
            return $date;
302
        } else {
303
            return $date->format('Y-m-d H:i:s');
304
        }
305
    } catch (Exception $e) {
306
        return null;
307
    }
308
}
309
310
/**
311
 * Returns a DATETIME string converted to the right timezone.
312
 *
313
 * @param mixed  $time                    The time to be converted
314
 * @param string $to_timezone             The timezone to be converted to.
315
 *                                        If null, the timezone will be determined based on user preference,
316
 *                                        or timezone chosen by the admin for the platform.
317
 * @param string $from_timezone           The timezone to be converted from. If null, UTC will be assumed.
318
 * @param bool   $returnNullIfInvalidDate
319
 * @param bool   $showTime
320
 * @param bool   $humanForm
321
 * @param string $format
322
 *
323
 * @return string The converted time formatted as Y-m-d H:i:s
324
 *
325
 * @author Guillaume Viguier <[email protected]>
326
 */
327
function api_get_local_time(
328
    $time = null,
329
    $to_timezone = null,
330
    $from_timezone = null,
331
    $returnNullIfInvalidDate = false,
332
    $showTime = true,
333
    $humanForm = false,
334
    $format = ''
335
) {
336
    // Determining the timezone to be converted from
337
    if (is_null($from_timezone)) {
338
        $from_timezone = 'UTC';
339
    }
340
341
    // If time is a timestamp, convert it to a string
342
    if (is_null($time) || empty($time) || '0000-00-00 00:00:00' == $time) {
343
        if ($returnNullIfInvalidDate) {
344
            return null;
345
        }
346
        $from_timezone = 'UTC';
347
        $time = gmdate('Y-m-d H:i:s');
348
    }
349
350
    if (is_numeric($time)) {
351
        $time = (int) $time;
352
        if ($returnNullIfInvalidDate) {
353
            if (strtotime(date('d-m-Y H:i:s', $time)) !== (int) $time) {
354
                return null;
355
            }
356
        }
357
358
        $from_timezone = 'UTC';
359
        $time = gmdate('Y-m-d H:i:s', $time);
360
    }
361
362
    if ($time instanceof DateTime) {
363
        $time = $time->format('Y-m-d H:i:s');
364
        $from_timezone = 'UTC';
365
    }
366
367
    try {
368
        // Determining the timezone to be converted to
369
        if (is_null($to_timezone)) {
370
            $to_timezone = api_get_timezone();
371
        }
372
373
        $date = new DateTime($time, new DateTimezone($from_timezone));
374
        $date->setTimezone(new DateTimeZone($to_timezone));
375
376
        if (!empty($format)) {
377
            return $date->format($format);
378
        }
379
380
        return api_get_human_date_time($date, $showTime, $humanForm);
381
    } catch (Exception $e) {
382
        return '';
383
    }
384
}
385
386
/**
387
 * Converts a string into a timestamp safely (handling timezones), using strtotime.
388
 *
389
 * @param string $time     to be converted
390
 * @param string $timezone (if null, the timezone will be determined based
391
 *                         on user preference, or timezone chosen by the admin for the platform)
392
 *
393
 * @return int Timestamp
394
 *
395
 * @author Guillaume Viguier <[email protected]>
396
 */
397
function api_strtotime($time, $timezone = null)
398
{
399
    $system_timezone = date_default_timezone_get();
400
    if (!empty($timezone)) {
401
        date_default_timezone_set($timezone);
402
    }
403
    $timestamp = strtotime($time);
404
    if (!empty($timezone)) {
405
        // only reset timezone if it was changed
406
        date_default_timezone_set($system_timezone);
407
    }
408
409
    return $timestamp;
410
}
411
412
/**
413
 * Returns formatted date/time, correspondent to a given language.
414
 * The given date should be in the timezone chosen by the administrator
415
 * and/or user. Use api_get_local_time to get it.
416
 *
417
 * @author Patrick Cool <[email protected]>, Ghent University
418
 * @author Christophe Gesche<[email protected]>
419
 *         originally inspired from from PhpMyAdmin
420
 * @author Ivan Tcholakov, 2009, code refactoring, adding support for predefined date/time formats.
421
 * @author Guillaume Viguier <[email protected]>
422
 *
423
 * @param mixed $time Timestamp or datetime string
424
 * @param string|int Date format (see date formats in the Chamilo system:
425
 * TIME_NO_SEC_FORMAT,
426
 * DATE_FORMAT_SHORT,
427
 * DATE_FORMAT_LONG,
428
 * DATE_TIME_FORMAT_LONG
429
 * @param string $language (optional) Language id
430
 *                         If it is omitted, the current interface language is assumed
431
 *
432
 * @return string returns the formatted date
433
 *
434
 * @see http://php.net/manual/en/function.strftime.php
435
 */
436
function api_format_date($time, $format = null, $language = null)
437
{
438
    if (empty($time)) {
439
        return '';
440
    }
441
442
    $system_timezone = date_default_timezone_get();
443
    date_default_timezone_set(api_get_timezone());
444
445
    if (is_string($time)) {
446
        $time = strtotime($time);
447
    }
448
449
    if (is_null($format)) {
450
        $format = DATE_TIME_FORMAT_LONG;
451
    }
452
    if ($time instanceof DateTime) {
453
        $time = $time->format('Y-m-d H:i:s');
454
    }
455
456
    $datetype = null;
457
    $timetype = null;
458
459
    if (is_int($format)) {
460
        switch ($format) {
461
            case DATE_FORMAT_ONLY_DAYNAME:
462
                $date_format = get_lang('dateFormatOnlyDayName', '', $language);
463
464
                $datetype = IntlDateFormatter::SHORT;
465
                $timetype = IntlDateFormatter::NONE;
466
467
                break;
468
            case DATE_FORMAT_NUMBER_NO_YEAR:
469
                $date_format = get_lang('dateFormatShortNumberNoYear', '', $language);
470
471
                $datetype = IntlDateFormatter::SHORT;
472
                $timetype = IntlDateFormatter::NONE;
473
474
                break;
475
            case DATE_FORMAT_NUMBER:
476
                $date_format = get_lang('dateFormatShortNumber', '', $language);
477
478
                $datetype = IntlDateFormatter::SHORT;
479
                $timetype = IntlDateFormatter::NONE;
480
481
                break;
482
            case TIME_NO_SEC_FORMAT:
483
                $date_format = get_lang('timeNoSecFormat', '', $language);
484
485
                $datetype = IntlDateFormatter::NONE;
486
                $timetype = IntlDateFormatter::SHORT;
487
488
                break;
489
            case DATE_FORMAT_SHORT:
490
                $date_format = get_lang('dateFormatShort', '', $language);
491
492
                $datetype = IntlDateFormatter::LONG;
493
                $timetype = IntlDateFormatter::NONE;
494
495
                break;
496
            case DATE_FORMAT_LONG:
497
                $date_format = get_lang('dateFormatLong', '', $language);
498
499
                $datetype = IntlDateFormatter::FULL;
500
                $timetype = IntlDateFormatter::NONE;
501
502
                break;
503
            case DATE_TIME_FORMAT_LONG:
504
                $date_format = get_lang('dateTimeFormatLong', '', $language);
505
506
                $datetype = IntlDateFormatter::FULL;
507
                $timetype = IntlDateFormatter::SHORT;
508
509
                break;
510
            case DATE_FORMAT_LONG_NO_DAY:
511
                $date_format = get_lang('dateFormatLongNoDay', '', $language);
512
513
                $datetype = IntlDateFormatter::FULL;
514
                $timetype = IntlDateFormatter::SHORT;
515
516
                break;
517
            case DATE_TIME_FORMAT_SHORT:
518
                $date_format = get_lang('dateTimeFormatShort', '', $language);
519
520
                $datetype = IntlDateFormatter::FULL;
521
                $timetype = IntlDateFormatter::SHORT;
522
523
                break;
524
            case DATE_TIME_FORMAT_SHORT_TIME_FIRST:
525
                $date_format = get_lang('dateTimeFormatShortTimeFirst', '', $language);
526
527
                $datetype = IntlDateFormatter::FULL;
528
                $timetype = IntlDateFormatter::SHORT;
529
530
                break;
531
            case DATE_TIME_FORMAT_LONG_24H:
532
                $date_format = get_lang('dateTimeFormatLong24H', '', $language);
533
534
                $datetype = IntlDateFormatter::FULL;
535
                $timetype = IntlDateFormatter::SHORT;
536
537
                break;
538
            default:
539
                $date_format = get_lang('dateTimeFormatLong', '', $language);
540
541
                $datetype = IntlDateFormatter::FULL;
542
                $timetype = IntlDateFormatter::SHORT;
543
        }
544
    }
545
546
    // Use ICU
547
    if (is_null($language)) {
548
        $language = api_get_language_isocode();
549
    }
550
    $date_formatter = new IntlDateFormatter($language, $datetype, $timetype, date_default_timezone_get());
551
    //$date_formatter->setPattern($date_format);
552
    $formatted_date = api_to_system_encoding($date_formatter->format($time), 'UTF-8');
553
554
    date_default_timezone_set($system_timezone);
555
556
    return $formatted_date;
557
}
558
559
/**
560
 * Returns the difference between the current date (date(now)) with the parameter
561
 * $date in a string format like "2 days ago, 1 hour ago".
562
 * You can use it like this:
563
 * Display::dateToStringAgoAndLongDate($dateInUtc);.
564
 *
565
 * @param string $date                 Result of a date function in this format -> date('Y-m-d H:i:s', time());
566
 * @param string $timeZone
567
 * @param bool   $returnDateDifference
568
 *
569
 * @return string
570
 *
571
 * @author Julio Montoya
572
 */
573
function date_to_str_ago($date, $timeZone = 'UTC', $returnDateDifference = false)
0 ignored issues
show
Unused Code introduced by
The parameter $timeZone is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

573
function date_to_str_ago($date, /** @scrutinizer ignore-unused */ $timeZone = 'UTC', $returnDateDifference = false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
574
{
575
    if ('0000-00-00 00:00:00' === $date) {
576
        return '';
577
    }
578
579
    $getOldTimezone = api_get_timezone();
580
    $isoCode = api_get_language_isocode();
581
    if ('pt' === $isoCode) {
582
        $isoCode = 'pt-BR';
583
    }
584
    $isoCode = ucfirst($isoCode);
585
    $class = "Westsworld\TimeAgo\Translations\\".$isoCode;
586
587
    if (class_exists($class)) {
588
        $language = new $class();
589
    } else {
590
        $language = new Westsworld\TimeAgo\Translations\En();
591
    }
592
    $timeAgo = new TimeAgo($language);
593
    $date = api_get_utc_datetime($date, null, true);
594
    $value = $timeAgo->inWords($date);
595
    date_default_timezone_set($getOldTimezone);
596
597
    if ($returnDateDifference) {
598
        $value = $timeAgo->dateDifference($date);
599
    }
600
601
    return $value;
602
}
603
604
/**
605
 * Converts a date to the right timezone and localizes it in the format given as an argument.
606
 *
607
 * @param mixed The time to be converted
608
 * @param mixed Format to be used (TIME_NO_SEC_FORMAT, DATE_FORMAT_SHORT, DATE_FORMAT_LONG, DATE_TIME_FORMAT_LONG)
609
 * @param string Timezone to be converted from. If null, UTC will be assumed.
610
 *
611
 * @return string Converted and localized date
612
 *
613
 * @author Guillaume Viguier <[email protected]>
614
 */
615
function api_convert_and_format_date($time = null, $format = null, $from_timezone = null)
616
{
617
    // First, convert the datetime to the right timezone
618
    $time = api_get_local_time($time, null, $from_timezone, true);
619
    // Second, localize the date
620
    return api_format_date($time, $format);
621
}
622
623
/**
624
 * Returns an array of translated week days in short names.
625
 *
626
 * @param string $language (optional) Language id. If it is omitted, the current interface language is assumed.
627
 *
628
 * @return string Returns an array of week days (short names).
629
 *                Example: api_get_week_days_short('english') means array('Sun', 'Mon', ... 'Sat').
630
 *                Note: For all languges returned days are in the English order.
631
 */
632
function api_get_week_days_short($language = null)
633
{
634
    $days = &_api_get_day_month_names($language);
635
636
    return $days['days_short'];
637
}
638
639
/**
640
 * Returns an array of translated week days.
641
 *
642
 * @param string $language (optional) Language id. If it is omitted,
643
 *                         the current interface language is assumed.
644
 *
645
 * @return string Returns an array of week days.
646
 *                Example: api_get_week_days_long('english') means array('Sunday, 'Monday', ... 'Saturday').
647
 *                Note: For all languges returned days are in the English order.
648
 */
649
function api_get_week_days_long($language = null)
650
{
651
    $days = &_api_get_day_month_names($language);
652
653
    return $days['days_long'];
654
}
655
656
/**
657
 * Returns an array of translated months in short names.
658
 *
659
 * @param string $language (optional)    Language id.
660
 *                         If it is omitted, the current interface language is assumed.
661
 *
662
 * @return string Returns an array of months (short names).
663
 *                Example: api_get_months_short('english') means array('Jan', 'Feb', ... 'Dec').
664
 */
665
function api_get_months_short($language = null)
666
{
667
    $months = &_api_get_day_month_names($language);
668
669
    return $months['months_short'];
670
}
671
672
/**
673
 * Returns an array of translated months.
674
 *
675
 * @param string $language (optional)    Language id.
676
 *                         If it is omitted, the current interface language is assumed.
677
 *
678
 * @return string Returns an array of months.
679
 *                Example: api_get_months_long('english') means array('January, 'February' ... 'December').
680
 */
681
function api_get_months_long($language = null)
682
{
683
    $months = &_api_get_day_month_names($language);
684
685
    return $months['months_long'];
686
}
687
688
/**
689
 * Name order conventions.
690
 */
691
692
/**
693
 * Builds a person (full) name depending on the convention for a given language.
694
 *
695
 * @param string     $first_name the first name of the person
696
 * @param string     $last_name  the last name of the person
697
 * @param string     $title      the title of the person
698
 * @param int|string $format     (optional) The person name format.
699
 *                               It may be a pattern-string (for example '%t %l, %f' or '%T %F %L', ...) or
700
 *                               some of the constants
701
 *                               PERSON_NAME_COMMON_CONVENTION (default),
702
 *                               PERSON_NAME_WESTERN_ORDER,
703
 *                               PERSON_NAME_EASTERN_ORDER,
704
 *                               PERSON_NAME_LIBRARY_ORDER.
705
 * @param string     $language   (optional)
706
 *                               The language id. If it is omitted, the current interface language is assumed.
707
 *                               This parameter has meaning with the format PERSON_NAME_COMMON_CONVENTION only.
708
 * @param string     $username
709
 *
710
 * @return string The result is sort of full name of the person.
711
 *                Sample results:
712
 *                Peter Ustinoff or Dr. Peter Ustinoff     - the Western order
713
 *                Ustinoff Peter or Dr. Ustinoff Peter     - the Eastern order
714
 *                Ustinoff, Peter or - Dr. Ustinoff, Peter - the library order
715
 *                Note: See the file main/inc/lib/internationalization_database/name_order_conventions.php
716
 *                where you can check the convention for your language.
717
 *
718
 * @author Carlos Vargas <[email protected]> - initial implementation.
719
 * @author Ivan Tcholakov
720
 */
721
function api_get_person_name(
722
    $first_name,
723
    $last_name,
724
    $title = null,
725
    $format = null,
726
    $language = null,
727
    $username = null
728
) {
729
    static $valid = [];
730
    if (empty($format)) {
731
        $format = PERSON_NAME_COMMON_CONVENTION;
732
    }
733
    // We check if the language is supported, otherwise we check the
734
    // interface language of the parent language of sublanguage
735
    if (empty($language)) {
736
        // Do not set $setParentLanguageName because this function is called before
737
        // the main language is loaded in global.inc.php
738
        $language = api_get_interface_language(false, true, false);
739
    }
740
741
    if (!isset($valid[$format][$language])) {
742
        if (is_int($format)) {
743
            switch ($format) {
744
                case PERSON_NAME_COMMON_CONVENTION:
745
                    $valid[$format][$language] = _api_get_person_name_convention($language, 'format');
746
                    $usernameOrderFromDatabase = api_get_setting('user_name_order');
747
                    if (isset($usernameOrderFromDatabase) && !empty($usernameOrderFromDatabase)) {
748
                        $valid[$format][$language] = $usernameOrderFromDatabase;
749
                    }
750
                    break;
751
                case PERSON_NAME_WESTERN_ORDER:
752
                    $valid[$format][$language] = '%t %f %l';
753
                    break;
754
                case PERSON_NAME_EASTERN_ORDER:
755
                    $valid[$format][$language] = '%t %l %f';
756
                    break;
757
                case PERSON_NAME_LIBRARY_ORDER:
758
                    $valid[$format][$language] = '%t %l, %f';
759
                    break;
760
                default:
761
                    $valid[$format][$language] = '%t %f %l';
762
                    break;
763
            }
764
        } else {
765
            $valid[$format][$language] = _api_validate_person_name_format($format);
766
        }
767
    }
768
769
    $format = $valid[$format][$language];
770
771
    $keywords = [
772
        '%firstname',
773
        '%f',
774
        '%F',
775
        '%lastname',
776
        '%l',
777
        '%L',
778
        '%title',
779
        '%t',
780
        '%T',
781
        '%username',
782
        '%u',
783
        '%U',
784
    ];
785
786
    $values = [
787
        $first_name,
788
        $first_name,
789
        api_strtoupper($first_name),
790
        $last_name,
791
        $last_name,
792
        api_strtoupper($last_name),
793
        $title,
794
        $title,
795
        api_strtoupper($title),
796
        $username,
797
        $username,
798
        api_strtoupper($username),
799
    ];
800
    $person_name = str_replace($keywords, $values, $format);
801
802
    return _api_clean_person_name($person_name);
803
}
804
805
/**
806
 * Checks whether a given format represents person name in Western order (for which first name is first).
807
 *
808
 * @param int|string $format   (optional)    The person name format.
809
 *                             It may be a pattern-string (for example '%t. %l, %f') or some of the constants
810
 *                             PERSON_NAME_COMMON_CONVENTION (default),
811
 *                             PERSON_NAME_WESTERN_ORDER,
812
 *                             PERSON_NAME_EASTERN_ORDER,
813
 *                             PERSON_NAME_LIBRARY_ORDER.
814
 * @param string     $language (optional) The language id. If it is omitted,
815
 *                             the current interface language is assumed. This parameter has meaning with the
816
 *                             format PERSON_NAME_COMMON_CONVENTION only.
817
 *
818
 * @return bool The result TRUE means that the order is first_name last_name,
819
 *              FALSE means last_name first_name.
820
 *              Note: You may use this function for determining the order of the fields or
821
 *              columns "First name" and "Last name" in forms, tables and reports.
822
 *
823
 * @author Ivan Tcholakov
824
 */
825
function api_is_western_name_order($format = null, $language = null)
826
{
827
    static $order = [];
828
    if (empty($format)) {
829
        $format = PERSON_NAME_COMMON_CONVENTION;
830
    }
831
832
    if (empty($language)) {
833
        $language = api_get_interface_language(false, true);
834
    }
835
    if (!isset($order[$format][$language])) {
836
        $test_name = api_get_person_name('%f', '%l', '%t', $format, $language);
837
        $order[$format][$language] = stripos($test_name, '%f') <= stripos($test_name, '%l');
838
    }
839
840
    return $order[$format][$language];
841
}
842
843
/**
844
 * Returns a directive for sorting person names depending on a given language
845
 * and based on the options in the internationalization "database".
846
 *
847
 * @param string $language (optional) The input language.
848
 *                         If it is omitted, the current interface language is assumed.
849
 *
850
 * @return bool Returns boolean value. TRUE means ORDER BY first_name, last_name
851
 *              FALSE means ORDER BY last_name, first_name.
852
 *              Note: You may use this function:
853
 *              2. for constructing the ORDER clause of SQL queries, related to first_name and last_name;
854
 *              3. for adjusting php-implemented sorting in tables and reports.
855
 *
856
 * @author Ivan Tcholakov
857
 */
858
function api_sort_by_first_name($language = null)
859
{
860
    static $sort_by_first_name = [];
861
862
    if (empty($language)) {
863
        $language = api_get_interface_language(false, true);
864
    }
865
    if (!isset($sort_by_first_name[$language])) {
866
        $sort_by_first_name[$language] = _api_get_person_name_convention($language, 'sort_by');
867
    }
868
869
    return $sort_by_first_name[$language];
870
}
871
872
/**
873
 * Multibyte string conversion functions.
874
 */
875
876
/**
877
 * Converts character encoding of a given string.
878
 *
879
 * @param string $string        the string being converted
880
 * @param string $to_encoding   the encoding that $string is being converted to
881
 * @param string $from_encoding (optional)    The encoding that $string is being converted from.
882
 *                              If it is omitted, the platform character set is assumed.
883
 *
884
 * @return string Returns the converted string.
885
 *                This function is aimed at replacing the function mb_convert_encoding() for human-language strings.
886
 *
887
 * @see http://php.net/manual/en/function.mb-convert-encoding
888
 */
889
function api_convert_encoding($string, $to_encoding, $from_encoding = 'UTF-8')
890
{
891
    if (strtoupper($to_encoding) === strtoupper($from_encoding)) {
892
        return $string;
893
    }
894
895
    return mb_convert_encoding($string, $to_encoding, $from_encoding);
896
}
897
898
/**
899
 * Converts a given string into UTF-8 encoded string.
900
 *
901
 * @param string $string        the string being converted
902
 * @param string $from_encoding (optional) The encoding that $string is being converted from.
903
 *                              If it is omitted, the platform character set is assumed.
904
 *
905
 * @return string Returns the converted string.
906
 *                This function is aimed at replacing the function utf8_encode() for human-language strings.
907
 *
908
 * @see http://php.net/manual/en/function.utf8-encode
909
 */
910
function api_utf8_encode($string, $from_encoding = 'UTF-8')
911
{
912
    return mb_convert_encoding($string, 'UTF-8', $from_encoding);
913
}
914
915
/**
916
 * Converts a given string from UTF-8 encoding to a specified encoding.
917
 *
918
 * @param string $string      the string being converted
919
 * @param string $to_encoding (optional)    The encoding that $string is being converted to.
920
 *                            If it is omitted, the platform character set is assumed.
921
 *
922
 * @return string Returns the converted string.
923
 *                This function is aimed at replacing the function utf8_decode() for human-language strings.
924
 *
925
 * @see http://php.net/manual/en/function.utf8-decode
926
 */
927
function api_utf8_decode($string, $to_encoding = null)
928
{
929
    return mb_convert_encoding($string, $to_encoding, 'UTF-8');
930
}
931
932
/**
933
 * Converts a given string into the system encoding (or platform character set).
934
 * When $from encoding is omitted on UTF-8 platforms then language dependent encoding
935
 * is guessed/assumed. On non-UTF-8 platforms omitted $from encoding is assumed as UTF-8.
936
 * When the parameter $check_utf8_validity is true the function checks string's
937
 * UTF-8 validity and decides whether to try to convert it or not.
938
 * This function is useful for problem detection or making workarounds.
939
 *
940
 * @param string $string              the string being converted
941
 * @param string $from_encoding       (optional) The encoding that $string is being converted from.
942
 *                                    It is guessed when it is omitted.
943
 * @param bool   $check_utf8_validity (optional)    A flag for UTF-8 validity check as condition for making conversion
944
 *
945
 * @return string returns the converted string
946
 */
947
function api_to_system_encoding($string, $from_encoding = null, $check_utf8_validity = false)
0 ignored issues
show
Unused Code introduced by
The parameter $check_utf8_validity is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

947
function api_to_system_encoding($string, $from_encoding = null, /** @scrutinizer ignore-unused */ $check_utf8_validity = false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
948
{
949
    $system_encoding = api_get_system_encoding();
950
951
    return api_convert_encoding($string, $system_encoding, $from_encoding);
952
}
953
954
/**
955
 * Converts all applicable characters to HTML entities.
956
 *
957
 * @param string $string      the input string
958
 * @param int    $quote_style (optional)    The quote style - ENT_COMPAT (default), ENT_QUOTES, ENT_NOQUOTES
959
 * @param string $encoding    (optional)    The encoding (of the input string) used in conversion.
960
 *                            If it is omitted, the platform character set is assumed.
961
 *
962
 * @return string Returns the converted string.
963
 *                This function is aimed at replacing the function htmlentities() for human-language strings.
964
 *
965
 * @see http://php.net/manual/en/function.htmlentities
966
 */
967
function api_htmlentities($string, $quote_style = ENT_COMPAT)
968
{
969
    switch ($quote_style) {
970
        case ENT_COMPAT:
971
            $string = str_replace(['&', '"', '<', '>'], ['&amp;', '&quot;', '&lt;', '&gt;'], $string);
972
            break;
973
        case ENT_QUOTES:
974
            $string = str_replace(['&', '\'', '"', '<', '>'], ['&amp;', '&#039;', '&quot;', '&lt;', '&gt;'], $string);
975
            break;
976
    }
977
978
    return mb_convert_encoding($string, 'HTML-ENTITIES', 'UTF-8');
979
}
980
981
/**
982
 * Converts HTML entities into normal characters.
983
 *
984
 * @param string $string      the input string
985
 * @param int    $quote_style (optional)    The quote style - ENT_COMPAT (default), ENT_QUOTES, ENT_NOQUOTES
986
 * @param string $encoding    (optional)    The encoding (of the result) used in conversion.
987
 *                            If it is omitted, the platform character set is assumed.
988
 *
989
 * @return string Returns the converted string.
990
 *                This function is aimed at replacing the function html_entity_decode() for human-language strings.
991
 *
992
 * @see http://php.net/html_entity_decode
993
 */
994
function api_html_entity_decode($string, $quote_style = ENT_COMPAT, $encoding = 'UTF-8')
995
{
996
    if (empty($encoding)) {
997
        $encoding = _api_mb_internal_encoding();
998
    }
999
    if (api_is_encoding_supported($encoding)) {
1000
        if (!api_is_utf8($encoding)) {
1001
            $string = api_utf8_encode($string, $encoding);
1002
        }
1003
        $string = html_entity_decode($string, $quote_style, 'UTF-8');
1004
        if (!api_is_utf8($encoding)) {
1005
            return api_utf8_decode($string, $encoding);
1006
        }
1007
1008
        return $string;
1009
    }
1010
1011
    return $string; // Here the function gives up.
1012
}
1013
1014
/**
1015
 * This function encodes (conditionally) a given string to UTF-8 if XmlHttp-request has been detected.
1016
 *
1017
 * @param string $string        the string being converted
1018
 * @param string $from_encoding (optional)    The encoding that $string is being converted from.
1019
 *                              If it is omitted, the platform character set is assumed.
1020
 *
1021
 * @return string returns the converted string
1022
 */
1023
function api_xml_http_response_encode($string, $from_encoding = 'UTF8')
1024
{
1025
    if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && 'xmlhttprequest' == strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])) {
1026
        if (empty($from_encoding)) {
1027
            $from_encoding = _api_mb_internal_encoding();
1028
        }
1029
        if (!api_is_utf8($from_encoding)) {
1030
            return api_utf8_encode($string, $from_encoding);
1031
        }
1032
    }
1033
1034
    return $string;
1035
}
1036
1037
/**
1038
 * Transliterates a string with arbitrary encoding into a plain ASCII string.
1039
 *
1040
 * Example:
1041
 * echo api_transliterate(api_html_entity_decode(
1042
 *    '&#1060;&#1105;&#1076;&#1086;&#1088; '.
1043
 *    '&#1052;&#1080;&#1093;&#1072;&#1081;&#1083;&#1086;&#1074;&#1080;&#1095; '.
1044
 *    '&#1044;&#1086;&#1089;&#1090;&#1086;&#1077;&#1074;&#1082;&#1080;&#1081;',
1045
 *    ENT_QUOTES, 'UTF-8'), 'X', 'UTF-8');
1046
 * The output should be: Fyodor Mihaylovich Dostoevkiy
1047
 *
1048
 * @param string $string        the input string
1049
 * @param string $unknown       (optional) Replacement character for unknown characters and illegal UTF-8 sequences
1050
 * @param string $from_encoding (optional) The encoding of the input string.
1051
 *                              If it is omitted, the platform character set is assumed.
1052
 *
1053
 * @return string plain ASCII output
1054
 */
1055
function api_transliterate($string, $unknown = '?', $from_encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $from_encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1055
function api_transliterate($string, $unknown = '?', /** @scrutinizer ignore-unused */ $from_encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $unknown is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1055
function api_transliterate($string, /** @scrutinizer ignore-unused */ $unknown = '?', $from_encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1056
{
1057
    return URLify::transliterate($string);
1058
}
1059
1060
/**
1061
 * Takes the first character in a string and returns its Unicode codepoint.
1062
 *
1063
 * @param string $character the input string
1064
 * @param string $encoding  (optional) The encoding of the input string.
1065
 *                          If it is omitted, the platform character set will be used by default.
1066
 *
1067
 * @return int Returns: the codepoint of the first character; or 0xFFFD (unknown character) when the input string is empty.
1068
 *             This is a multibyte aware version of the function ord().
1069
 *
1070
 * @see http://php.net/manual/en/function.ord.php
1071
 * Note the difference with the original funtion ord(): ord('') returns 0, api_ord('') returns 0xFFFD (unknown character).
1072
 */
1073
function api_ord($character, $encoding = 'UTF-8')
1074
{
1075
    return Utf8::ord(api_utf8_encode($character, $encoding));
1076
}
1077
1078
/**
1079
 * This function returns a string or an array with all occurrences of search
1080
 * in subject (ignoring case) replaced with the given replace value.
1081
 *
1082
 * @param mixed  $search   string or array of strings to be found
1083
 * @param mixed  $replace  string or array of strings used for replacement
1084
 * @param mixed  $subject  string or array of strings being searched
1085
 * @param int    $count    (optional) The number of matched and replaced needles
1086
 *                         will be returned in count, which is passed by reference
1087
 * @param string $encoding (optional) The used internally by this function character encoding.
1088
 *                         If it is omitted, the platform character set will be used by default.
1089
 *
1090
 * @return mixed String or array as a result.
1091
 *               Notes:
1092
 *               If $subject is an array, then the search and replace is performed with
1093
 *               every entry of subject, the return value is an array.
1094
 *               If $search and $replace are arrays, then the function takes a value from
1095
 *               each array and uses it to do search and replace on subject.
1096
 *               If $replace has fewer values than search, then an empty string is used for the rest of replacement values.
1097
 *               If $search is an array and $replace is a string, then this replacement string is used for every value of search.
1098
 *               This function is aimed at replacing the function str_ireplace() for human-language strings.
1099
 *
1100
 * @see http://php.net/manual/en/function.str-ireplace
1101
 *
1102
 * @author Henri Sivonen, mailto:[email protected]
1103
 *
1104
 * @see http://hsivonen.iki.fi/php-utf8/
1105
 * Adaptation for Chamilo 1.8.7, 2010
1106
 * Initial implementation Dokeos LMS, August 2009
1107
 *
1108
 * @author Ivan Tcholakov
1109
 */
1110
function api_str_ireplace($search, $replace, $subject, &$count = null, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1110
function api_str_ireplace($search, $replace, $subject, &$count = null, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1111
{
1112
    return Utf8::str_ireplace($search, $replace, $subject, $count);
1113
}
1114
1115
/**
1116
 * Converts a string to an array.
1117
 *
1118
 * @param string $string       the input string
1119
 * @param int    $split_length maximum character-length of the chunk, one character by default
1120
 * @param string $encoding     (optional) The used internally by this function
1121
 *                             character encoding. If it is omitted, the platform character set will be used by default.
1122
 *
1123
 * @return array The result array of chunks with the spcified length.
1124
 *               Notes:
1125
 *               If the optional split_length parameter is specified, the returned array will be broken down into chunks
1126
 *               with each being split_length in length, otherwise each chunk will be one character in length.
1127
 *               FALSE is returned if split_length is less than 1.
1128
 *               If the split_length length exceeds the length of string, the entire string is returned as the first (and only) array element.
1129
 *               This function is aimed at replacing the function str_split() for human-language strings.
1130
 *
1131
 * @see http://php.net/str_split
1132
 */
1133
function api_str_split($string, $split_length = 1, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1133
function api_str_split($string, $split_length = 1, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1134
{
1135
    return Utf8::str_split($string, $split_length);
1136
}
1137
1138
/**
1139
 * Finds position of first occurrence of a string within another, case insensitive.
1140
 *
1141
 * @param string $haystack the string from which to get the position of the first occurrence
1142
 * @param string $needle   the string to be found
1143
 * @param int    $offset   The position in $haystack to start searching from.
1144
 *                         If it is omitted, searching starts from the beginning.
1145
 * @param string $encoding (optional) The used internally by this function
1146
 *                         character encoding. If it is omitted, the platform character set will be used by default.
1147
 *
1148
 * @return mixed Returns the numeric position of the first occurrence of
1149
 *               $needle in the $haystack, or FALSE if $needle is not found.
1150
 *               Note: The first character's position is 0, the second character position is 1, and so on.
1151
 *               This function is aimed at replacing the functions stripos() and mb_stripos() for human-language strings.
1152
 *
1153
 * @see http://php.net/manual/en/function.stripos
1154
 * @see http://php.net/manual/en/function.mb-stripos
1155
 */
1156
function api_stripos($haystack, $needle, $offset = 0, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1156
function api_stripos($haystack, $needle, $offset = 0, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1157
{
1158
    return Utf8::stripos($haystack, $needle, $offset);
1159
}
1160
1161
/**
1162
 * Finds first occurrence of a string within another, case insensitive.
1163
 *
1164
 * @param string $haystack      the string from which to get the first occurrence
1165
 * @param mixed  $needle        the string to be found
1166
 * @param bool   $before_needle (optional) Determines which portion of $haystack
1167
 *                              this function returns. The default value is FALSE.
1168
 * @param string $encoding      (optional) The used internally by this function
1169
 *                              character encoding. If it is omitted, the platform character set will be used by default.
1170
 *
1171
 * @return mixed Returns the portion of $haystack, or FALSE if $needle is not found.
1172
 *               Notes:
1173
 *               If $needle is not a string, it is converted to an integer and applied as the
1174
 *               ordinal value (codepoint if the encoding is UTF-8) of a character.
1175
 *               If $before_needle is set to TRUE, the function returns all of $haystack
1176
 *               from the beginning to the first occurrence of $needle.
1177
 *               If $before_needle is set to FALSE, the function returns all of $haystack f
1178
 *               rom the first occurrence of $needle to the end.
1179
 *               This function is aimed at replacing the functions stristr() and mb_stristr() for human-language strings.
1180
 *
1181
 * @see http://php.net/manual/en/function.stristr
1182
 * @see http://php.net/manual/en/function.mb-stristr
1183
 */
1184
function api_stristr($haystack, $needle, $before_needle = false, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1184
function api_stristr($haystack, $needle, $before_needle = false, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1185
{
1186
    return Utf8::stristr($haystack, $needle, $before_needle);
1187
}
1188
1189
/**
1190
 * Returns length of the input string.
1191
 *
1192
 * @param string $string   the string which length is to be calculated
1193
 * @param string $encoding (optional) The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1194
 *
1195
 * @return int Returns the number of characters within the string. A multi-byte character is counted as 1.
1196
 *             This function is aimed at replacing the functions strlen() and mb_strlen() for human-language strings.
1197
 *
1198
 * @see http://php.net/manual/en/function.strlen
1199
 * @see http://php.net/manual/en/function.mb-strlen
1200
 * Note: When you use strlen() to test for an empty string, you needn't change it to api_strlen().
1201
 * For example, in lines like the following:
1202
 * if (strlen($string) > 0)
1203
 * if (strlen($string) != 0)
1204
 * there is no need the original function strlen() to be changed, it works correctly and faster for these cases.
1205
 */
1206
function api_strlen($string, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1206
function api_strlen($string, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1207
{
1208
    return Utf8::strlen($string);
1209
}
1210
1211
/**
1212
 * Finds position of first occurrence of a string within another.
1213
 *
1214
 * @param string $haystack the string from which to get the position of the first occurrence
1215
 * @param string $needle   the string to be found
1216
 * @param int    $offset   (optional) The position in $haystack to start searching from. If it is omitted, searching starts from the beginning.
1217
 * @param string $encoding (optional)    The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1218
 *
1219
 * @return mixed Returns the numeric position of the first occurrence of $needle in the $haystack, or FALSE if $needle is not found.
1220
 *               Note: The first character's position is 0, the second character position is 1, and so on.
1221
 *               This function is aimed at replacing the functions strpos() and mb_strpos() for human-language strings.
1222
 *
1223
 * @see http://php.net/manual/en/function.strpos
1224
 * @see http://php.net/manual/en/function.mb-strpos
1225
 */
1226
function api_strpos($haystack, $needle, $offset = 0, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1226
function api_strpos($haystack, $needle, $offset = 0, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1227
{
1228
    return Utf8::strpos($haystack, $needle, $offset);
1229
}
1230
1231
/**
1232
 * Finds the last occurrence of a character in a string.
1233
 *
1234
 * @param string $haystack      the string from which to get the last occurrence
1235
 * @param mixed  $needle        the string which first character is to be found
1236
 * @param bool   $before_needle (optional) Determines which portion of $haystack this function returns. The default value is FALSE.
1237
 * @param string $encoding      (optional) The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1238
 *
1239
 * @return mixed Returns the portion of $haystack, or FALSE if the first character from $needle is not found.
1240
 *               Notes:
1241
 *               If $needle is not a string, it is converted to an integer and applied as the ordinal value (codepoint if the encoding is UTF-8) of a character.
1242
 *               If $before_needle is set to TRUE, the function returns all of $haystack from the beginning to the first occurrence.
1243
 *               If $before_needle is set to FALSE, the function returns all of $haystack from the first occurrence to the end.
1244
 *               This function is aimed at replacing the functions strrchr() and mb_strrchr() for human-language strings.
1245
 *
1246
 * @see http://php.net/manual/en/function.strrchr
1247
 * @see http://php.net/manual/en/function.mb-strrchr
1248
 */
1249
function api_strrchr($haystack, $needle, $before_needle = false, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $before_needle is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1249
function api_strrchr($haystack, $needle, /** @scrutinizer ignore-unused */ $before_needle = false, $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1249
function api_strrchr($haystack, $needle, $before_needle = false, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1250
{
1251
    return Utf8::strrchr($haystack, $needle);
1252
}
1253
1254
/**
1255
 * Reverses a string.
1256
 *
1257
 * @param string $string   the string to be reversed
1258
 * @param string $encoding (optional)    The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1259
 *
1260
 * @return string Returns the reversed string.
1261
 *                This function is aimed at replacing the function strrev() for human-language strings.
1262
 *
1263
 * @see http://php.net/manual/en/function.strrev
1264
 */
1265
function api_strrev($string, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1265
function api_strrev($string, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1266
{
1267
    return Utf8::strrev($string);
1268
}
1269
1270
/**
1271
 * Finds the position of last occurrence (case insensitive) of a string in a string.
1272
 *
1273
 * @param string $haystack the string from which to get the position of the last occurrence
1274
 * @param string $needle   the string to be found
1275
 * @param int    $offset   (optional) $offset may be specified to begin searching an arbitrary position. Negative values will stop searching at an arbitrary point prior to the end of the string.
1276
 * @param string $encoding (optional) The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1277
 *
1278
 * @return mixed Returns the numeric position of the first occurrence (case insensitive) of $needle in the $haystack, or FALSE if $needle is not found.
1279
 *               Note: The first character's position is 0, the second character position is 1, and so on.
1280
 *               This function is aimed at replacing the functions strripos() and mb_strripos() for human-language strings.
1281
 *
1282
 * @see http://php.net/manual/en/function.strripos
1283
 * @see http://php.net/manual/en/function.mb-strripos
1284
 */
1285
function api_strripos($haystack, $needle, $offset = 0, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1285
function api_strripos($haystack, $needle, $offset = 0, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1286
{
1287
    return Utf8::strripos($haystack, $needle, $offset);
1288
}
1289
1290
/**
1291
 * Finds the position of last occurrence of a string in a string.
1292
 *
1293
 * @param string $haystack the string from which to get the position of the last occurrence
1294
 * @param string $needle   the string to be found
1295
 * @param int    $offset   (optional) $offset may be specified to begin searching an arbitrary position. Negative values will stop searching at an arbitrary point prior to the end of the string.
1296
 * @param string $encoding (optional) The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1297
 *
1298
 * @return mixed Returns the numeric position of the first occurrence of $needle in the $haystack, or FALSE if $needle is not found.
1299
 *               Note: The first character's position is 0, the second character position is 1, and so on.
1300
 *               This function is aimed at replacing the functions strrpos() and mb_strrpos() for human-language strings.
1301
 *
1302
 * @see http://php.net/manual/en/function.strrpos
1303
 * @see http://php.net/manual/en/function.mb-strrpos
1304
 */
1305
function api_strrpos($haystack, $needle, $offset = 0, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1305
function api_strrpos($haystack, $needle, $offset = 0, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1306
{
1307
    return Utf8::strrpos($haystack, $needle, $offset);
1308
}
1309
1310
/**
1311
 * Finds first occurrence of a string within another.
1312
 *
1313
 * @param string $haystack      the string from which to get the first occurrence
1314
 * @param mixed  $needle        the string to be found
1315
 * @param bool   $before_needle (optional) Determines which portion of $haystack this function returns. The default value is FALSE.
1316
 * @param string $encoding      (optional) The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1317
 *
1318
 * @return mixed Returns the portion of $haystack, or FALSE if $needle is not found.
1319
 *               Notes:
1320
 *               If $needle is not a string, it is converted to an integer and applied as the ordinal value (codepoint if the encoding is UTF-8) of a character.
1321
 *               If $before_needle is set to TRUE, the function returns all of $haystack from the beginning to the first occurrence of $needle.
1322
 *               If $before_needle is set to FALSE, the function returns all of $haystack from the first occurrence of $needle to the end.
1323
 *               This function is aimed at replacing the functions strstr() and mb_strstr() for human-language strings.
1324
 *
1325
 * @see http://php.net/manual/en/function.strstr
1326
 * @see http://php.net/manual/en/function.mb-strstr
1327
 */
1328
function api_strstr($haystack, $needle, $before_needle = false, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1328
function api_strstr($haystack, $needle, $before_needle = false, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1329
{
1330
    return Utf8::strstr($haystack, $needle, $before_needle);
1331
}
1332
1333
/**
1334
 * Makes a string lowercase.
1335
 *
1336
 * @param string $string   the string being lowercased
1337
 * @param string $encoding (optional)	The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1338
 *
1339
 * @return string Returns the string with all alphabetic characters converted to lowercase.
1340
 *                This function is aimed at replacing the functions strtolower() and mb_strtolower() for human-language strings.
1341
 *
1342
 * @see http://php.net/manual/en/function.strtolower
1343
 * @see http://php.net/manual/en/function.mb-strtolower
1344
 */
1345
function api_strtolower($string, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1345
function api_strtolower($string, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1346
{
1347
    return Utf8::strtolower($string);
1348
}
1349
1350
/**
1351
 * Makes a string uppercase.
1352
 *
1353
 * @param string $string   the string being uppercased
1354
 * @param string $encoding (optional)	The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1355
 *
1356
 * @return string Returns the string with all alphabetic characters converted to uppercase.
1357
 *                This function is aimed at replacing the functions strtoupper() and mb_strtoupper() for human-language strings.
1358
 *
1359
 * @see http://php.net/manual/en/function.strtoupper
1360
 * @see http://php.net/manual/en/function.mb-strtoupper
1361
 */
1362
function api_strtoupper($string, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1362
function api_strtoupper($string, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1363
{
1364
    return Utf8::strtoupper($string);
1365
}
1366
1367
/**
1368
 * // Gets part of a string.
1369
 *
1370
 * @param string $string   the input string
1371
 * @param int    $start    the first position from which the extracted part begins
1372
 * @param int    $length   the length in character of the extracted part
1373
 * @param string $encoding (optional) The used internally by this function
1374
 *                         character encoding. If it is omitted, the platform character set will be used by default.
1375
 *
1376
 * @return string Returns the part of the string specified by the start and length parameters.
1377
 *                Note: First character's position is 0. Second character position is 1, and so on.
1378
 *                This function is aimed at replacing the functions substr() and mb_substr() for human-language strings.
1379
 *
1380
 * @see http://php.net/manual/en/function.substr
1381
 * @see http://php.net/manual/en/function.mb-substr
1382
 */
1383
function api_substr($string, $start, $length = null, $encoding = null)
1384
{
1385
    if (is_null($length)) {
1386
        $length = api_strlen($string, $encoding);
1387
    }
1388
1389
    return Utf8::substr($string, $start, $length);
1390
}
1391
1392
/**
1393
 * Counts the number of substring occurrences.
1394
 *
1395
 * @param string $haystack the string being checked
1396
 * @param string $needle   the string being found
1397
 * @param string $encoding (optional) The used internally by this function character encoding.
1398
 *                         If it is omitted, the platform character set will be used by default.
1399
 *
1400
 * @return int the number of times the needle substring occurs in the haystack string
1401
 *
1402
 * @see http://php.net/manual/en/function.mb-substr-count.php
1403
 */
1404
function api_substr_count($haystack, $needle, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1404
function api_substr_count($haystack, $needle, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1405
{
1406
    return Utf8::substr_count($haystack, $needle);
1407
}
1408
1409
/**
1410
 * Replaces text within a portion of a string.
1411
 *
1412
 * @param string $string      the input string
1413
 * @param string $replacement the replacement string
1414
 * @param int    $start       The position from which replacing will begin.
1415
 *                            Notes:
1416
 *                            If $start is positive, the replacing will begin at the $start'th offset into the string.
1417
 *                            If $start is negative, the replacing will begin at the $start'th character from the end of the string.
1418
 * @param int    $length      (optional) The position where replacing will end.
1419
 *                            Notes:
1420
 *                            If given and is positive, it represents the length of the portion of the string which is to be replaced.
1421
 *                            If it is negative, it represents the number of characters from the end of string at which to stop replacing.
1422
 *                            If it is not given, then it will default to api_strlen($string); i.e. end the replacing at the end of string.
1423
 *                            If $length is zero, then this function will have the effect of inserting replacement into the string at the given start offset.
1424
 * @param string $encoding    (optional)    The used internally by this function character encoding.
1425
 *                            If it is omitted, the platform character set will be used by default.
1426
 *
1427
 * @return string The result string is returned.
1428
 *                This function is aimed at replacing the function substr_replace() for human-language strings.
1429
 *
1430
 * @see http://php.net/manual/function.substr-replace
1431
 */
1432
function api_substr_replace($string, $replacement, $start, $length = null, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1432
function api_substr_replace($string, $replacement, $start, $length = null, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1433
{
1434
    if (is_null($length)) {
1435
        $length = api_strlen($string);
1436
    }
1437
1438
    return UTf8::substr_replace($string, $replacement, $start, $length);
1439
}
1440
1441
/**
1442
 * Makes a string's first character uppercase.
1443
 *
1444
 * @param string $string   the input string
1445
 * @param string $encoding (optional)    The used internally by this function character encoding.
1446
 *                         If it is omitted, the platform character set will be used by default.
1447
 *
1448
 * @return string Returns a string with the first character capitalized, if that character is alphabetic.
1449
 *                This function is aimed at replacing the function ucfirst() for human-language strings.
1450
 *
1451
 * @see http://php.net/manual/en/function.ucfirst
1452
 */
1453
function api_ucfirst($string, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1453
function api_ucfirst($string, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1454
{
1455
    return Utf8::ucfirst($string);
1456
}
1457
1458
/**
1459
 * Uppercases the first character of each word in a string.
1460
 *
1461
 * @param string $string   the input string
1462
 * @param string $encoding (optional) The used internally by this function character encoding.
1463
 *                         If it is omitted, the platform character set will be used by default.
1464
 *
1465
 * @return string Returns the modified string.
1466
 *                This function is aimed at replacing the function ucwords() for human-language strings.
1467
 *
1468
 * @see http://php.net/manual/en/function.ucwords
1469
 */
1470
function api_ucwords($string, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1470
function api_ucwords($string, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1471
{
1472
    return Utf8::ucwords($string);
1473
}
1474
1475
/**
1476
 * Performs a regular expression match, UTF-8 aware when it is applicable.
1477
 *
1478
 * @param string $pattern  the pattern to search for, as a string
1479
 * @param string $subject  the input string
1480
 * @param array  &$matches (optional) If matches is provided,
1481
 *                         then it is filled with the results of search (as an array).
1482
 *                         $matches[0] will contain the text that matched the full pattern, $matches[1] will have the text that matched the first captured parenthesized subpattern, and so on.
1483
 * @param int    $flags    (optional) Could be PREG_OFFSET_CAPTURE. If this flag is passed, for every occurring match the appendant string offset will also be returned.
1484
 *                         Note that this changes the return value in an array where every element is an array consisting of the matched string at index 0 and its string offset into subject at index 1.
1485
 * @param int    $offset   (optional)        Normally, the search starts from the beginning of the subject string. The optional parameter offset can be used to specify the alternate place from which to start the search.
1486
 * @param string $encoding (optional)    The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1487
 *
1488
 * @return int|bool returns the number of times pattern matches or FALSE if an error occurred
1489
 *
1490
 * @see http://php.net/preg_match
1491
 */
1492
function api_preg_match(
1493
    $pattern,
1494
    $subject,
1495
    &$matches = null,
1496
    $flags = 0,
1497
    $offset = 0,
1498
    $encoding = null
1499
) {
1500
    if (empty($encoding)) {
1501
        $encoding = _api_mb_internal_encoding();
1502
    }
1503
1504
    return preg_match(api_is_utf8($encoding) ? $pattern.'u' : $pattern, $subject, $matches, $flags, $offset);
1505
}
1506
1507
/**
1508
 * Performs a global regular expression match, UTF-8 aware when it is applicable.
1509
 *
1510
 * @param string $pattern  the pattern to search for, as a string
1511
 * @param string $subject  the input string
1512
 * @param array  &$matches (optional)    Array of all matches in multi-dimensional array ordered according to $flags
1513
 * @param int    $flags    (optional)            Can be a combination of the following flags (note that it doesn't make sense to use PREG_PATTERN_ORDER together with PREG_SET_ORDER):
1514
 *                         PREG_PATTERN_ORDER - orders results so that $matches[0] is an array of full pattern matches, $matches[1] is an array of strings matched by the first parenthesized subpattern, and so on;
1515
 *                         PREG_SET_ORDER - orders results so that $matches[0] is an array of first set of matches, $matches[1] is an array of second set of matches, and so on;
1516
 *                         PREG_OFFSET_CAPTURE - If this flag is passed, for every occurring match the appendant string offset will also be returned. Note that this changes the value of matches
1517
 *                         in an array where every element is an array consisting of the matched string at offset 0 and its string offset into subject at offset 1.
1518
 *                         If no order flag is given, PREG_PATTERN_ORDER is assumed.
1519
 * @param int    $offset   (optional)		Normally, the search starts from the beginning of the subject string. The optional parameter offset can be used to specify the alternate place from which to start the search.
1520
 * @param string $encoding (optional)	The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1521
 *
1522
 * @return int|bool returns the number of full pattern matches (which might be zero), or FALSE if an error occurred
1523
 *
1524
 * @see http://php.net/preg_match_all
1525
 */
1526
function api_preg_match_all($pattern, $subject, &$matches, $flags = PREG_PATTERN_ORDER, $offset = 0, $encoding = null)
1527
{
1528
    if (empty($encoding)) {
1529
        $encoding = _api_mb_internal_encoding();
1530
    }
1531
    if (is_null($flags)) {
1532
        $flags = PREG_PATTERN_ORDER;
1533
    }
1534
1535
    return preg_match_all(api_is_utf8($encoding) ? $pattern.'u' : $pattern, $subject, $matches, $flags, $offset);
1536
}
1537
1538
/**
1539
 * Performs a regular expression search and replace, UTF-8 aware when it is applicable.
1540
 *
1541
 * @param string|array $pattern     The pattern to search for. It can be either a string or an array with strings.
1542
 * @param string|array $replacement the string or an array with strings to replace
1543
 * @param string|array $subject     the string or an array with strings to search and replace
1544
 * @param int          $limit       The maximum possible replacements for each pattern in each subject string. Defaults to -1 (no limit).
1545
 * @param int          &$count      If specified, this variable will be filled with the number of replacements done
1546
 * @param string       $encoding    (optional)	The used internally by this function character encoding.
1547
 *                                  If it is omitted, the platform character set will be used by default.
1548
 *
1549
 * @return array|string|null returns an array if the subject parameter is an array, or a string otherwise.
1550
 *                           If matches are found, the new subject will be returned, otherwise subject will be returned unchanged or NULL if an error occurred.
1551
 *
1552
 * @see http://php.net/preg_replace
1553
 */
1554
function api_preg_replace($pattern, $replacement, $subject, $limit = -1, &$count = 0, $encoding = null)
1555
{
1556
    if (empty($encoding)) {
1557
        $encoding = _api_mb_internal_encoding();
1558
    }
1559
    $is_utf8 = api_is_utf8($encoding);
1560
    if (is_array($pattern)) {
1561
        foreach ($pattern as &$p) {
1562
            $p = $is_utf8 ? $p.'u' : $p;
1563
        }
1564
    } else {
1565
        $pattern = $is_utf8 ? $pattern.'u' : $pattern;
1566
    }
1567
1568
    return preg_replace($pattern, $replacement, $subject, $limit, $count);
1569
}
1570
1571
/**
1572
 * Splits a string by a regular expression, UTF-8 aware when it is applicable.
1573
 *
1574
 * @param string $pattern  the pattern to search for, as a string
1575
 * @param string $subject  the input string
1576
 * @param int    $limit    (optional)			If specified, then only substrings up to $limit are returned with the rest of the string being placed in the last substring. A limit of -1, 0 or null means "no limit" and, as is standard across PHP.
1577
 * @param int    $flags    (optional)			$flags can be any combination of the following flags (combined with bitwise | operator):
1578
 *                         PREG_SPLIT_NO_EMPTY - if this flag is set, only non-empty pieces will be returned;
1579
 *                         PREG_SPLIT_DELIM_CAPTURE - if this flag is set, parenthesized expression in the delimiter pattern will be captured and returned as well;
1580
 *                         PREG_SPLIT_OFFSET_CAPTURE - If this flag is set, for every occurring match the appendant string offset will also be returned.
1581
 *                         Note that this changes the return value in an array where every element is an array consisting of the matched string at offset 0 and its string offset into subject at offset 1.
1582
 * @param string $encoding (optional)	The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1583
 *
1584
 * @return array returns an array containing substrings of $subject split along boundaries matched by $pattern
1585
 *
1586
 * @see http://php.net/preg_split
1587
 */
1588
function api_preg_split($pattern, $subject, $limit = -1, $flags = 0, $encoding = null)
1589
{
1590
    if (empty($encoding)) {
1591
        $encoding = _api_mb_internal_encoding();
1592
    }
1593
1594
    return preg_split(api_is_utf8($encoding) ? $pattern.'u' : $pattern, $subject, $limit, $flags);
0 ignored issues
show
Bug Best Practice introduced by
The expression return preg_split(api_is...ubject, $limit, $flags) could also return false which is incompatible with the documented return type array. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
1595
}
1596
1597
/**
1598
 * String comparison.
1599
 */
1600
1601
/**
1602
 * Performs string comparison, case insensitive, language sensitive, with extended multibyte support.
1603
 *
1604
 * @param string $string1  the first string
1605
 * @param string $string2  the second string
1606
 * @param string $language (optional) The language in which comparison is to be made. If language is omitted, interface language is assumed then.
1607
 * @param string $encoding (optional) The used internally by this function character encoding. If it is omitted, the platform character set will be used by default.
1608
 *
1609
 * @return int Returns < 0 if $string1 is less than $string2; > 0 if $string1 is greater than $string2; and 0 if the strings are equal.
1610
 *             This function is aimed at replacing the function strcasecmp() for human-language strings.
1611
 *
1612
 * @see http://php.net/manual/en/function.strcasecmp
1613
 */
1614
function api_strcasecmp($string1, $string2, $language = null, $encoding = null)
1615
{
1616
    return api_strcmp(api_strtolower($string1, $encoding), api_strtolower($string2, $encoding), $language, $encoding);
1617
}
1618
1619
/**
1620
 * Performs string comparison, case sensitive, language sensitive, with extended multibyte support.
1621
 *
1622
 * @param string $string1  the first string
1623
 * @param string $string2  the second string
1624
 * @param string $language (optional)	The language in which comparison is to be made. If language is omitted, interface language is assumed then.
1625
 * @param string $encoding (optional)	The used internally by this function character encoding.
1626
 *                         If it is omitted, the platform character set will be used by default.
1627
 *
1628
 * @return int Returns < 0 if $string1 is less than $string2; > 0 if $string1 is greater than $string2; and 0 if the strings are equal.
1629
 *             This function is aimed at replacing the function strcmp() for human-language strings.
1630
 *
1631
 * @see http://php.net/manual/en/function.strcmp.php
1632
 * @see http://php.net/manual/en/collator.compare.php
1633
 */
1634
function api_strcmp($string1, $string2, $language = null, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1634
function api_strcmp($string1, $string2, $language = null, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $language is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1634
function api_strcmp($string1, $string2, /** @scrutinizer ignore-unused */ $language = null, $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1635
{
1636
    return strcmp($string1, $string2);
1637
}
1638
1639
/**
1640
 * Performs string comparison in so called "natural order", case sensitive, language sensitive, with extended multibyte support.
1641
 *
1642
 * @param string $string1  the first string
1643
 * @param string $string2  the second string
1644
 * @param string $language (optional)	The language in which comparison is to be made. If language is omitted, interface language is assumed then.
1645
 * @param string $encoding (optional)	The used internally by this function character encoding.
1646
 *                         If it is omitted, the platform character set will be used by default.
1647
 *
1648
 * @return int Returns < 0 if $string1 is less than $string2; > 0 if $string1 is greater than $string2; and 0 if the strings are equal.
1649
 *             This function is aimed at replacing the function strnatcmp() for human-language strings.
1650
 *
1651
 * @see http://php.net/manual/en/function.strnatcmp.php
1652
 * @see http://php.net/manual/en/collator.compare.php
1653
 */
1654
function api_strnatcmp($string1, $string2, $language = null, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $language is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1654
function api_strnatcmp($string1, $string2, /** @scrutinizer ignore-unused */ $language = null, $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1654
function api_strnatcmp($string1, $string2, $language = null, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1655
{
1656
    return strnatcmp($string1, $string2);
1657
}
1658
1659
/**
1660
 * Sorting arrays.
1661
 */
1662
1663
/**
1664
 * Sorts an array using natural order algorithm.
1665
 *
1666
 * @param array  $array    the input array
1667
 * @param string $language (optional)	The language in which comparison is to be made. If language is omitted, interface language is assumed then.
1668
 * @param string $encoding (optional)	The used internally by this function character encoding.
1669
 *                         If it is omitted, the platform character set will be used by default.
1670
 *
1671
 * @return bool Returns TRUE on success, FALSE on error.
1672
 *              This function is aimed at replacing the function natsort() for sorting human-language strings.
1673
 *
1674
 * @see http://php.net/manual/en/function.natsort.php
1675
 */
1676
function api_natsort(&$array, $language = null, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $language is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1676
function api_natsort(&$array, /** @scrutinizer ignore-unused */ $language = null, $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1676
function api_natsort(&$array, $language = null, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1677
{
1678
    return natsort($array);
1679
}
1680
1681
/**
1682
 * Sorts an array using natural order algorithm in reverse order.
1683
 *
1684
 * @param array  $array    the input array
1685
 * @param string $language (optional)	The language in which comparison is to be made. If language is omitted, interface language is assumed then.
1686
 * @param string $encoding (optional)	The used internally by this function character encoding.
1687
 *                         If it is omitted, the platform character set will be used by default.
1688
 *
1689
 * @return bool returns TRUE on success, FALSE on error
1690
 */
1691
function api_natrsort(&$array, $language = null, $encoding = null)
0 ignored issues
show
Unused Code introduced by
The parameter $encoding is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1691
function api_natrsort(&$array, $language = null, /** @scrutinizer ignore-unused */ $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $language is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1691
function api_natrsort(&$array, /** @scrutinizer ignore-unused */ $language = null, $encoding = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1692
{
1693
    return uasort($array, '_api_strnatrcmp');
1694
}
1695
1696
/**
1697
 * Encoding management functions.
1698
 */
1699
1700
/**
1701
 * This function unifies the encoding identificators, so they could be compared.
1702
 *
1703
 * @param string|array $encoding the specified encoding
1704
 *
1705
 * @return string returns the encoding identificator modified in suitable for comparison way
1706
 */
1707
function api_refine_encoding_id($encoding)
1708
{
1709
    if (is_array($encoding)) {
1710
        return array_map('api_refine_encoding_id', $encoding);
0 ignored issues
show
Bug Best Practice introduced by
The expression return array_map('api_re...ncoding_id', $encoding) returns the type array which is incompatible with the documented return type string.
Loading history...
1711
    }
1712
1713
    return strtoupper(str_replace('_', '-', $encoding));
1714
}
1715
1716
/**
1717
 * This function checks whether two $encoding are equal (same, equvalent).
1718
 *
1719
 * @param string|array $encoding1 The first encoding
1720
 * @param string|array $encoding2 The second encoding
1721
 * @param bool         $strict    When this parameter is TRUE the comparison ignores aliases of encodings.
1722
 *                                When the parameter is FALSE, aliases are taken into account.
1723
 *
1724
 * @return bool returns TRUE if the encodings are equal, FALSE otherwise
1725
 */
1726
function api_equal_encodings($encoding1, $encoding2, $strict = false)
1727
{
1728
    static $equal_encodings = [];
1729
    if (is_array($encoding1)) {
1730
        foreach ($encoding1 as $encoding) {
1731
            if (api_equal_encodings($encoding, $encoding2, $strict)) {
1732
                return true;
1733
            }
1734
        }
1735
1736
        return false;
1737
    } elseif (is_array($encoding2)) {
1738
        foreach ($encoding2 as $encoding) {
1739
            if (api_equal_encodings($encoding1, $encoding, $strict)) {
1740
                return true;
1741
            }
1742
        }
1743
1744
        return false;
1745
    }
1746
    if (!isset($equal_encodings[$encoding1][$encoding2][$strict])) {
1747
        $encoding_1 = api_refine_encoding_id($encoding1);
1748
        $encoding_2 = api_refine_encoding_id($encoding2);
1749
        if ($encoding_1 == $encoding_2) {
1750
            $result = true;
1751
        } else {
1752
            if ($strict) {
1753
                $result = false;
1754
            } else {
1755
                $alias1 = _api_get_character_map_name($encoding_1);
1756
                $alias2 = _api_get_character_map_name($encoding_2);
1757
                $result = !empty($alias1) && !empty($alias2) && $alias1 == $alias2;
1758
            }
1759
        }
1760
        $equal_encodings[$encoding1][$encoding2][$strict] = $result;
1761
    }
1762
1763
    return $equal_encodings[$encoding1][$encoding2][$strict];
1764
}
1765
1766
/**
1767
 * This function checks whether a given encoding is UTF-8.
1768
 *
1769
 * @param string $encoding the tested encoding
1770
 *
1771
 * @return bool returns TRUE if the given encoding id means UTF-8, otherwise returns false
1772
 */
1773
function api_is_utf8($encoding)
1774
{
1775
    static $result = [];
1776
    if (!isset($result[$encoding])) {
1777
        $result[$encoding] = api_equal_encodings($encoding, 'UTF-8');
1778
    }
1779
1780
    return $result[$encoding];
1781
}
1782
1783
/**
1784
 * This function returns the encoding, currently used by the system.
1785
 *
1786
 * @return string The system's encoding.
1787
 *                Note: The value of api_get_setting('platform_charset') is tried to be returned first,
1788
 *                on the second place the global variable $charset is tried to be returned. If for some
1789
 *                reason both attempts fail, then the libraly's internal value will be returned.
1790
 */
1791
function api_get_system_encoding()
1792
{
1793
    return 'UTF-8';
1794
}
1795
1796
/**
1797
 * Checks whether a specified encoding is supported by this API.
1798
 *
1799
 * @param string $encoding the specified encoding
1800
 *
1801
 * @return bool returns TRUE when the specified encoding is supported, FALSE othewise
1802
 */
1803
function api_is_encoding_supported($encoding)
1804
{
1805
    static $supported = [];
1806
    if (!isset($supported[$encoding])) {
1807
        $supported[$encoding] = _api_mb_supports($encoding) || _api_iconv_supports($encoding) || _api_convert_encoding_supports($encoding);
1808
    }
1809
1810
    return $supported[$encoding];
1811
}
1812
1813
/**
1814
 * Detects encoding of plain text.
1815
 *
1816
 * @param string $string   the input text
1817
 * @param string $language (optional) The language of the input text, provided if it is known
1818
 *
1819
 * @return string returns the detected encoding
1820
 */
1821
function api_detect_encoding($string, $language = null)
0 ignored issues
show
Unused Code introduced by
The parameter $language is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1821
function api_detect_encoding($string, /** @scrutinizer ignore-unused */ $language = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1822
{
1823
    // Testing against valid UTF-8 first.
1824
    if (api_is_valid_utf8($string)) {
1825
        return 'UTF-8';
1826
    }
1827
1828
    return mb_detect_encoding($string);
1829
}
1830
1831
/**
1832
 * String validation functions concerning certain encodings.
1833
 */
1834
1835
/**
1836
 * Checks a string for UTF-8 validity.
1837
 *
1838
 * @param string $string
1839
 *
1840
 * @return string
1841
 */
1842
function api_is_valid_utf8($string)
1843
{
1844
    return Utf8::isUtf8($string);
1845
}
1846
1847
/**
1848
 * Checks whether a string contains 7-bit ASCII characters only.
1849
 *
1850
 * @param string $string the string to be tested/validated
1851
 *
1852
 * @return bool returns TRUE when the tested string contains 7-bit
1853
 *              ASCII characters only, FALSE othewise
1854
 */
1855
function api_is_valid_ascii(&$string)
1856
{
1857
    return 'ASCII' == mb_detect_encoding($string, 'ASCII', true) ? true : false;
1858
}
1859
1860
/**
1861
 * Return true a date is valid.
1862
 *
1863
 * @param string $date   example: 2014-06-30 13:05:05
1864
 * @param string $format example: "Y-m-d H:i:s"
1865
 *
1866
 * @return bool
1867
 */
1868
function api_is_valid_date($date, $format = 'Y-m-d H:i:s')
1869
{
1870
    $d = DateTime::createFromFormat($format, $date);
1871
1872
    return $d && $d->format($format) == $date;
1873
}
1874
1875
/**
1876
 * Returns the variable translated.
1877
 *
1878
 * @param string $variable   the string to translate
1879
 * @param string $pluginName the Plugin name
1880
 *
1881
 * @return string the variable translated
1882
 */
1883
function get_plugin_lang($variable, $pluginName)
1884
{
1885
    $plugin = $pluginName::create();
1886
1887
    return $plugin->get_lang($variable);
1888
}
1889
1890
/**
1891
 * Returns an array of translated week days and months, short and normal names.
1892
 *
1893
 * @param string $language (optional Language id. If it is omitted,
1894
 *                         the current interface language is assumed.
1895
 *
1896
 * @return array returns a multidimensional array with translated week days and months
1897
 */
1898
function &_api_get_day_month_names($language = null)
1899
{
1900
    static $date_parts = [];
1901
    if (empty($language)) {
1902
        $language = api_get_interface_language();
1903
    }
1904
    if (!isset($date_parts[$language])) {
1905
        $week_day = [
1906
            'Sunday',
1907
            'Monday',
1908
            'Tuesday',
1909
            'Wednesday',
1910
            'Thursday',
1911
            'Friday',
1912
            'Saturday',
1913
        ];
1914
        $month = [
1915
            'January',
1916
            'February',
1917
            'March',
1918
            'April',
1919
            'May',
1920
            'June',
1921
            'July',
1922
            'August',
1923
            'September',
1924
            'October',
1925
            'November',
1926
            'December',
1927
        ];
1928
        for ($i = 0; $i < 7; $i++) {
1929
            $date_parts[$language]['days_short'][] = get_lang(
1930
                $week_day[$i].'Short',
1931
                '',
1932
                $language
1933
            );
1934
            $date_parts[$language]['days_long'][] = get_lang(
1935
                $week_day[$i].'Long',
1936
                '',
1937
                $language
1938
            );
1939
        }
1940
        for ($i = 0; $i < 12; $i++) {
1941
            $date_parts[$language]['months_short'][] = get_lang(
1942
                $month[$i].'Short',
1943
                '',
1944
                $language
1945
            );
1946
            $date_parts[$language]['months_long'][] = get_lang(
1947
                $month[$i].'Long',
1948
                '',
1949
                $language
1950
            );
1951
        }
1952
    }
1953
1954
    return $date_parts[$language];
1955
}
1956
1957
/**
1958
 * Returns returns person name convention for a given language.
1959
 *
1960
 * @param string $language the input language
1961
 * @param string $type     The type of the requested convention.
1962
 *                         It may be 'format' for name order convention or 'sort_by' for name sorting convention.
1963
 *
1964
 * @return mixed Depending of the requested type,
1965
 *               the returned result may be string or boolean; null is returned on error;
1966
 */
1967
function _api_get_person_name_convention($language, $type)
1968
{
1969
    static $conventions;
1970
1971
    $language = api_get_language_from_iso($language);
1972
    $languageName = 'english';
1973
    if (!empty($language)) {
1974
        $languageName = $language->getEnglishName();
1975
    }
1976
1977
    if (!isset($conventions)) {
1978
        $file = __DIR__.'/internationalization_database/name_order_conventions.php';
1979
        if (file_exists($file)) {
1980
            $conventions = include $file;
1981
        } else {
1982
            $conventions = [
1983
                'english' => [
1984
                    'format' => 'title first_name last_name',
1985
                    'sort_by' => 'first_name',
1986
                ],
1987
            ];
1988
        }
1989
        // Overwrite classic conventions
1990
        $customConventions = api_get_configuration_value('name_order_conventions');
1991
1992
        if (!empty($customConventions)) {
1993
            foreach ($customConventions as $key => $data) {
1994
                $conventions[$key] = $data;
1995
            }
1996
        }
1997
1998
        $search1 = ['FIRST_NAME', 'LAST_NAME', 'TITLE'];
1999
        $replacement1 = ['%F', '%L', '%T'];
2000
        $search2 = ['first_name', 'last_name', 'title'];
2001
        $replacement2 = ['%f', '%l', '%t'];
2002
        foreach (array_keys($conventions) as $key) {
2003
            $conventions[$key]['format'] = str_replace($search1, $replacement1, $conventions[$key]['format']);
2004
            $conventions[$key]['format'] = _api_validate_person_name_format(
2005
                _api_clean_person_name(
2006
                    str_replace(
2007
                        '%',
2008
                        ' %',
2009
                        str_ireplace(
2010
                            $search2,
2011
                            $replacement2,
2012
                            $conventions[$key]['format']
2013
                        )
2014
                    )
2015
                )
2016
            );
2017
            $conventions[$key]['sort_by'] = 'last_name' != strtolower($conventions[$key]['sort_by']) ? true : false;
2018
        }
2019
    }
2020
    switch ($type) {
2021
        case 'format':
2022
            return is_string($conventions[$languageName]['format']) ? $conventions[$languageName]['format'] : '%t %f %l';
2023
        case 'sort_by':
2024
            return is_bool($conventions[$languageName]['sort_by']) ? $conventions[$languageName]['sort_by'] : true;
2025
    }
2026
2027
    return null;
2028
}
2029
2030
/**
2031
 * Replaces non-valid formats for person names with the default (English) format.
2032
 *
2033
 * @param string $format the input format to be verified
2034
 *
2035
 * @return bool returns the same format if is is valid, otherwise returns a valid English format
2036
 */
2037
function _api_validate_person_name_format($format)
2038
{
2039
    if (empty($format) || false === stripos($format, '%f') || false === stripos($format, '%l')) {
2040
        return '%t %f %l';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '%t %f %l' returns the type string which is incompatible with the documented return type boolean.
Loading history...
2041
    }
2042
2043
    return $format;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $format returns the type string which is incompatible with the documented return type boolean.
Loading history...
2044
}
2045
2046
/**
2047
 * Removes leading, trailing and duplicate whitespace and/or commas in a full person name.
2048
 * Cleaning is needed for the cases when not all parts of the name are available
2049
 * or when the name is constructed using a "dirty" pattern.
2050
 *
2051
 * @param string $person_name the input person name
2052
 *
2053
 * @return string returns cleaned person name
2054
 */
2055
function _api_clean_person_name($person_name)
2056
{
2057
    return preg_replace(['/\s+/', '/, ,/', '/,+/', '/^[ ,]/', '/[ ,]$/'], [' ', ', ', ',', '', ''], $person_name);
2058
}
2059
2060
/**
2061
 * Appendix to "Multibyte string conversion functions".
2062
 */
2063
2064
/**
2065
 * This is a php-implementation of a function that is similar to mb_convert_encoding() from mbstring extension.
2066
 * The function converts a given string from one to another character encoding.
2067
 *
2068
 * @param string $string        the string being converted
2069
 * @param string $to_encoding   the encoding that $string is being converted to
2070
 * @param string $from_encoding the encoding that $string is being converted from
2071
 *
2072
 * @return string returns the converted string
2073
 */
2074
function _api_convert_encoding(&$string, $to_encoding, $from_encoding)
2075
{
2076
    return mb_convert_encoding($string, $to_encoding, $from_encoding);
2077
}
2078
2079
/**
2080
 * This function determines the name of corresponding to a given encoding conversion table.
2081
 * It is able to deal with some aliases of the encoding.
2082
 *
2083
 * @param string $encoding the given encoding identificator, for example 'WINDOWS-1252'
2084
 *
2085
 * @return string returns the name of the corresponding conversion table, for the same example - 'CP1252'
2086
 */
2087
function _api_get_character_map_name($encoding)
2088
{
2089
    static $character_map_selector;
2090
    if (!isset($character_map_selector)) {
2091
        $file = __DIR__.'/internationalization_database/conversion/character_map_selector.php';
2092
        if (file_exists($file)) {
2093
            $character_map_selector = include $file;
2094
        } else {
2095
            $character_map_selector = [];
2096
        }
2097
    }
2098
2099
    return isset($character_map_selector[$encoding]) ? $character_map_selector[$encoding] : '';
2100
}
2101
2102
/**
2103
 * Appendix to "String comparison".
2104
 */
2105
2106
/**
2107
 * A reverse function from php-core function strnatcmp(),
2108
 * performs string comparison in reverse natural (alpha-numerical) order.
2109
 *
2110
 * @param string $string1 the first string
2111
 * @param string $string2 the second string
2112
 *
2113
 * @return int returns 0 if $string1 = $string2; >0 if $string1 < $string2; <0 if $string1 > $string2
2114
 */
2115
function _api_strnatrcmp($string1, $string2)
2116
{
2117
    return strnatcmp($string2, $string1);
2118
}
2119
2120
/**
2121
 * Sets/Gets internal character encoding of the common string functions within the PHP mbstring extension.
2122
 *
2123
 * @param string $encoding (optional)    When this parameter is given, the function sets the internal encoding
2124
 *
2125
 * @return string When $encoding parameter is not given, the function returns the internal encoding.
2126
 *                Note: This function is used in the global initialization script for setting the
2127
 *                internal encoding to the platform's character set.
2128
 *
2129
 * @see http://php.net/manual/en/function.mb-internal-encoding
2130
 */
2131
function _api_mb_internal_encoding($encoding = 'UTF-8')
2132
{
2133
    return mb_internal_encoding($encoding);
0 ignored issues
show
Bug Best Practice introduced by
The expression return mb_internal_encoding($encoding) also could return the type boolean which is incompatible with the documented return type string.
Loading history...
2134
}
2135
2136
/**
2137
 * Checks whether the specified encoding is supported by the PHP mbstring extension.
2138
 *
2139
 * @param string $encoding the specified encoding
2140
 *
2141
 * @return bool returns TRUE when the specified encoding is supported, FALSE othewise
2142
 */
2143
function _api_mb_supports($encoding)
2144
{
2145
    static $supported = [];
2146
    if (!isset($supported[$encoding])) {
2147
        if (MBSTRING_INSTALLED) {
2148
            $supported[$encoding] = api_equal_encodings($encoding, mb_list_encodings(), true);
2149
        } else {
2150
            $supported[$encoding] = false;
2151
        }
2152
    }
2153
2154
    return $supported[$encoding];
2155
}
2156
2157
/**
2158
 * Checks whether the specified encoding is supported by the PHP iconv extension.
2159
 *
2160
 * @param string $encoding the specified encoding
2161
 *
2162
 * @return bool returns TRUE when the specified encoding is supported, FALSE othewise
2163
 */
2164
function _api_iconv_supports($encoding)
2165
{
2166
    static $supported = [];
2167
    if (!isset($supported[$encoding])) {
2168
        if (ICONV_INSTALLED) {
2169
            $enc = api_refine_encoding_id($encoding);
2170
            if ('HTML-ENTITIES' != $enc) {
2171
                $test_string = '';
2172
                for ($i = 32; $i < 128; $i++) {
2173
                    $test_string .= chr($i);
2174
                }
2175
                $supported[$encoding] = (@iconv_strlen($test_string, $enc)) ? true : false;
2176
            } else {
2177
                $supported[$encoding] = false;
2178
            }
2179
        } else {
2180
            $supported[$encoding] = false;
2181
        }
2182
    }
2183
2184
    return $supported[$encoding];
2185
}
2186
2187
// This function checks whether the function _api_convert_encoding() (the php-
2188
// implementation) is able to convert from/to a given encoding.
2189
function _api_convert_encoding_supports($encoding)
2190
{
2191
    static $supports = [];
2192
    if (!isset($supports[$encoding])) {
2193
        $supports[$encoding] = '' != _api_get_character_map_name(api_refine_encoding_id($encoding));
2194
    }
2195
2196
    return $supports[$encoding];
2197
}
2198
2199
/**
2200
 * Given a date object, return a human or ISO format, with or without h:m:s.
2201
 *
2202
 * @param object $date      The Date object
2203
 * @param bool   $showTime  Whether to show the time and date (true) or only the date (false)
2204
 * @param bool   $humanForm Whether to show day-month-year (true) or year-month-day (false)
2205
 *
2206
 * @return string Formatted date
2207
 */
2208
function api_get_human_date_time($date, $showTime = true, $humanForm = false)
2209
{
2210
    if ($showTime) {
2211
        if ($humanForm) {
2212
            return $date->format('j M Y H:i:s');
2213
        } else {
2214
            return $date->format('Y-m-d H:i:s');
2215
        }
2216
    } else {
2217
        if ($humanForm) {
2218
            return $date->format('j M Y');
2219
        } else {
2220
            return $date->format('Y-m-d');
2221
        }
2222
    }
2223
}
2224