Passed
Push — dependabot/npm_and_yarn/nanoid... ( aaf2c9...c4aa90 )
by
unknown
14:37 queued 06:22
created

check_if_exist_language_by_id()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 3
nop 1
dl 0
loc 15
rs 9.8666
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A SubLanguageManager::get_name_of_language_by_id() 0 12 2
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\Language;
5
use Doctrine\ORM\Exception\NotSupported;
6
7
/**
8
 * This is used in some scripts inside tests.
9
 */
10
class SubLanguageManager
11
{
12
13
    const SUBLANGUAGE_TRANS_PATH = '../var/translations/';
14
    const LANGUAGE_TRANS_PATH = '../translations/';
15
16
    public function __construct()
17
    {
18
    }
19
20
    /**
21
     * Get all the languages.
22
     *
23
     * @param bool $onlyActive Whether to return only active languages (default false)
24
     *
25
     * @return array All information about sub-language
26
     */
27
    public static function getAllLanguages($onlyActive = false)
28
    {
29
        $table = Database::get_main_table(TABLE_MAIN_LANGUAGE);
30
        $sql = 'SELECT * FROM '.$table;
31
        if ($onlyActive) {
32
            $sql .= ' WHERE available = 1';
33
        }
34
        $rs = Database::query($sql);
35
        $all_languages = [];
36
        while ($row = Database::fetch_assoc($rs)) {
37
            $all_languages[$row['english_name']] = $row;
38
        }
39
40
        return $all_languages;
41
    }
42
43
    /**
44
     * Get all files of lang folder (forum.inc.php,gradebook.inc.php,notebook.inc.php).
45
     *
46
     * @param string $path           The lang path folder  (/var/www/my_lms/main/lang/spanish)
47
     * @param bool   $only_main_name true if we only want the "subname" trad4all instead of trad4all.inc.php
48
     *
49
     * @return array All file of lang folder
50
     */
51
    public static function get_lang_folder_files_list($path, $only_main_name = false)
52
    {
53
        $content_dir = [];
54
        if (is_dir($path)) {
55
            if ($dh = opendir($path)) {
56
                while (false !== ($file = readdir($dh))) {
57
                    if ('.' != $file[0] && '.php' == substr($file, -4, strlen($file))) {
58
                        if ($only_main_name) {
59
                            if ('' != $file && strpos($file, '.inc.php')) {
60
                                $content_dir[] = substr($file, 0, strpos($file, '.inc.php'));
61
                            }
62
                        } else {
63
                            $content_dir[] = $file;
64
                        }
65
                    }
66
                }
67
            }
68
            closedir($dh);
69
        }
70
71
        return $content_dir;
72
    }
73
74
    /**
75
     * Get all information of language.
76
     *
77
     * @param int $parent_id The parent id(Language father id)
78
     *
79
     * @return array All information about language
80
     */
81
    public static function get_all_information_of_language($parent_id)
82
    {
83
        $table = Database::get_main_table(TABLE_MAIN_LANGUAGE);
84
        $sql = 'SELECT * FROM '.$table.' WHERE id = "'.intval($parent_id).'"';
85
        $rs = Database::query($sql);
86
        $all_information = [];
87
        while ($row = Database::fetch_assoc($rs)) {
88
            $all_information = $row;
89
        }
90
91
        return $all_information;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $all_information also could return the type true which is incompatible with the documented return type array.
Loading history...
92
    }
93
94
    /**
95
     * Get all information of chamilo file.
96
     *
97
     * @param string $system_path_file    The chamilo path file (/var/www/chamilo/main/lang/spanish/gradebook.inc.php)
98
     * @param bool   $get_as_string_index Whether we want to remove the '$' prefix in the results or not
99
     *
100
     * @return array Contains all information of chamilo file
101
     */
102
    public static function get_all_language_variable_in_file($system_path_file, $get_as_string_index = false)
103
    {
104
        $res_list = [];
105
        if (!is_readable($system_path_file)) {
106
            return $res_list;
107
        }
108
        $info_file = file($system_path_file);
109
        foreach ($info_file as $line) {
110
            if ('$' != substr($line, 0, 1)) {
111
                continue;
112
            }
113
            list($var, $val) = explode('=', $line, 2);
114
            $var = trim($var);
115
            $val = trim($val);
116
            if ($get_as_string_index) { //remove the prefix $
117
                $var = substr($var, 1);
118
            }
119
            $res_list[$var] = $val;
120
        }
121
122
        return $res_list;
123
    }
124
125
    /**
126
     * Add file in sub-language directory and add header(tag php).
127
     *
128
     * @param string $system_path_file The chamilo path file (/var/www/chamilo/main/lang/spanish/gradebook.inc.php)
129
     *
130
     * @return bool
131
     */
132
    public static function add_file_in_language_directory($system_path_file)
133
    {
134
        $return_value = @file_put_contents($system_path_file, '<?php'.PHP_EOL);
135
136
        return $return_value;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $return_value also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
137
    }
138
139
    /**
140
     * Write in file of sub-language.
141
     *
142
     * @param string $path_file    The path file (/var/www/chamilo/main/lang/spanish/gradebook.inc.php)
143
     * @param string $new_term     The new sub-language
144
     * @param string $new_variable The language variable
145
     *
146
     * @return bool True on success, False on error
147
     */
148
    public static function write_data_in_file($path_file, $new_term, $new_variable)
149
    {
150
        $return_value = false;
151
        $new_data = $new_variable.'='.$new_term;
152
        $resource = @fopen($path_file, "a");
153
        if (file_exists($path_file) && $resource) {
0 ignored issues
show
introduced by
$resource is of type false|resource, thus it always evaluated to false.
Loading history...
154
            if (false === fwrite($resource, $new_data.PHP_EOL)) {
155
                //not allow to write
156
                $return_value = false;
157
            } else {
158
                $return_value = true;
159
            }
160
            fclose($resource);
161
        }
162
163
        return $return_value;
164
    }
165
166
    /**
167
     * Add a .po file for a sub-language using its ISO code.
168
     *
169
     * @param string $subLanguageIsoCode The ISO code of the sub-language (e.g., 'es_CO')
170
     *
171
     * @return bool True on success, false on failure
172
     */
173
    public static function addPoFileForSubLanguage($subLanguageIsoCode)
174
    {
175
        if (empty($subLanguageIsoCode)) {
176
            return false;
177
        }
178
179
        // Path for the .po file you want to create
180
        $poFilePath = api_get_path(SYS_PATH) . self::SUBLANGUAGE_TRANS_PATH . 'messages.' . $subLanguageIsoCode . '.po';
181
        $translationsDir = dirname($poFilePath);
182
183
        // Check if the translations directory is writable
184
        if (!is_writable($translationsDir)) {
185
            // Attempt to set writable permissions
186
            if (!@chmod($translationsDir, 0775)) {
187
                error_log("Failed to set writable permissions for $translationsDir");
188
                return false;
189
            }
190
        }
191
192
        // If the .po file doesn't exist, create it
193
        if (!file_exists($poFilePath)) {
194
            $initialContent = "# Translation file for $subLanguageIsoCode\nmsgid \"\"\nmsgstr \"\"\n";
195
            if (false === file_put_contents($poFilePath, $initialContent)) {
196
                error_log("Failed to write the initial content to $poFilePath");
197
                return false;
198
            }
199
        }
200
201
        return true;
202
    }
203
204
    /**
205
     * Get name of language by id.
206
     *
207
     * @param int $language_id The language id
208
     *
209
     * @return string The original name of language
210
     */
211
    public static function get_name_of_language_by_id($language_id)
212
    {
213
        $table = Database::get_main_table(TABLE_MAIN_LANGUAGE);
214
        $language_id = intval($language_id);
215
        $sql = "SELECT original_name
216
                FROM $table
217
                WHERE id = $language_id";
218
        $rs = Database::query($sql);
219
        if (Database::num_rows($rs) > 0) {
220
            return Database::result($rs, 0, 'original_name');
221
        } else {
222
            return '';
223
        }
224
    }
225
226
    /**
227
     * Verified if language is sub-language.
228
     *
229
     * @param int $language_id
230
     *
231
     * @return bool
232
     */
233
    public static function check_if_language_is_sub_language($language_id)
234
    {
235
        $table = Database::get_main_table(TABLE_MAIN_LANGUAGE);
236
        $sql = 'SELECT count(*) AS count FROM '.$table.'
237
                WHERE id = '.intval($language_id).' AND NOT ISNULL(parent_id)';
238
        $rs = Database::query($sql);
239
240
        if (Database::num_rows($rs) > 0 && 1 == Database::result($rs, '0', 'count')) {
241
            return true;
242
        } else {
243
            return false;
244
        }
245
    }
246
247
    /**
248
     * @param int $language_id
249
     *
250
     * @return bool
251
     */
252
    public static function check_if_language_is_used(int $language_id): bool
253
    {
254
        $language_info = self::get_all_information_of_language($language_id);
255
        $table = Database::get_main_table(TABLE_MAIN_USER);
256
        $sql = 'SELECT count(*) AS count FROM '.$table.'
257
                WHERE locale ="'.Database::escape_string($language_info['english_name']).'" AND active <> '.USER_SOFT_DELETED;
258
        $rs = Database::query($sql);
259
        if (Database::num_rows($rs) > 0 && Database::result($rs, '0', 'count') >= 1) {
260
            return true;
261
        } else {
262
            return false;
263
        }
264
    }
265
266
    /**
267
     * Verified if language is father of an sub-language.
268
     *
269
     * @param int $language_id The language id
270
     *
271
     * @return bool
272
     */
273
    public static function check_if_language_is_father($language_id)
274
    {
275
        $table = Database::get_main_table(TABLE_MAIN_LANGUAGE);
276
        $sql = 'SELECT count(*) AS count FROM '.$table.'
277
                WHERE parent_id= '.intval($language_id).' AND NOT ISNULL(parent_id);';
278
        $rs = Database::query($sql);
279
280
        if (Database::num_rows($rs) > 0 && 1 == Database::result($rs, '0', 'count')) {
281
            return true;
282
        } else {
283
            return false;
284
        }
285
    }
286
287
    /**
288
     * Make unavailable the language.
289
     *
290
     * @param int $language_id The language id
291
     *
292
     * @return bool
293
     */
294
    public static function make_unavailable_language($language_id)
295
    {
296
        $tbl_admin_languages = Database::get_main_table(TABLE_MAIN_LANGUAGE);
297
        $sql = "UPDATE $tbl_admin_languages SET available='0'
298
                WHERE id = ".intval($language_id)."";
299
        $result = Database::query($sql);
300
301
        return false !== $result; //only return false on sql error
302
    }
303
304
    /**
305
     * Make available the language.
306
     *
307
     * @param int $language_id language id
308
     *
309
     * @return bool
310
     */
311
    public static function make_available_language($language_id)
312
    {
313
        $tbl_admin_languages = Database::get_main_table(TABLE_MAIN_LANGUAGE);
314
        $sql = "UPDATE $tbl_admin_languages SET available='1'
315
                WHERE id = ".intval($language_id)."";
316
        $result = Database::query($sql);
317
318
        return false !== $result; //only return false on sql error
319
    }
320
321
    /**
322
     * Set platform language.
323
     *
324
     * @param int $language_id The language id
325
     *
326
     * @return bool
327
     */
328
    public static function set_platform_language($language_id)
329
    {
330
        if (empty($language_id) || (intval($language_id) != $language_id)) {
331
            return false;
332
        }
333
        $language_id = intval($language_id);
334
        $tbl_admin_languages = Database::get_main_table(TABLE_MAIN_LANGUAGE);
335
        $tbl_settings_current = Database::get_main_table(TABLE_MAIN_SETTINGS);
336
        $sql = "SELECT * FROM $tbl_admin_languages
337
                WHERE id = $language_id";
338
        $result = Database::query($sql);
339
        $lang = Database::fetch_array($result);
340
        $sql_update_2 = "UPDATE $tbl_settings_current SET selected_value = '".$lang['isocode']."'
341
                         WHERE variable = 'platform_language'";
342
        $result_2 = Database::query($sql_update_2);
343
        Event::addEvent(
0 ignored issues
show
Bug introduced by
The method addEvent() does not exist on Event. ( Ignorable by Annotation )

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

343
        Event::/** @scrutinizer ignore-call */ 
344
               addEvent(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
344
            LOG_PLATFORM_LANGUAGE_CHANGE,
345
            LOG_PLATFORM_LANGUAGE,
346
            $lang['english_name']
347
        );
348
349
        return false !== $result_2;
350
    }
351
352
    /**
353
     * Get platform language ID.
354
     *
355
     * @return int The platform language ID
356
     */
357
    public static function get_platform_language_id()
358
    {
359
        $name = api_get_setting('platformLanguage');
360
        $tbl_admin_languages = Database::get_main_table(TABLE_MAIN_LANGUAGE);
361
        $sql = "SELECT id FROM $tbl_admin_languages WHERE english_name ='$name'";
362
        $res = Database::query($sql);
363
        if (Database::num_rows($res) < 1) {
364
            return false;
365
        }
366
        $row = Database::fetch_array($res);
367
368
        return (int) $row['id'];
369
    }
370
371
    /**
372
     * Get parent language path (or null if no parent).
373
     *
374
     * @deprecated
375
     *
376
     * @param string $language_path Children language path
377
     *
378
     * @return string Parent language path or null
379
     */
380
    public static function get_parent_language_path($language_path)
381
    {
382
        $tbl_admin_languages = Database::get_main_table(TABLE_MAIN_LANGUAGE);
383
        $sql = "SELECT dokeos_folder
384
                FROM ".$tbl_admin_languages."
385
                WHERE id = (
386
                    SELECT parent_id FROM ".$tbl_admin_languages."
387
                    WHERE dokeos_folder = '".Database::escape_string($language_path)."'
388
                )
389
                ";
390
        $result = Database::query($sql);
391
        if (0 == Database::num_rows($result)) {
392
            return null;
393
        }
394
        $row = Database::fetch_array($result);
395
396
        return $row['dokeos_folder'];
397
    }
398
399
    /**
400
     * Get language matching isocode.
401
     *
402
     * @param string $isocode The language isocode (en, es, fr, zh-TW, etc)
403
     *
404
     * @return mixed English name of the matching language, or false if no active language could be found
405
     */
406
    public static function getLanguageFromIsocode($isocode)
407
    {
408
        $isocode = Database::escape_string($isocode);
409
        $adminLanguagesTable = Database::get_main_table(TABLE_MAIN_LANGUAGE);
410
        // select language - if case several languages match, get the last (more recent) one
411
        $sql = "SELECT english_name
412
                FROM ".$adminLanguagesTable."
413
                WHERE
414
                    isocode ='$isocode' AND
415
                    available = 1
416
                ORDER BY id
417
                DESC LIMIT 1";
418
        $res = Database::query($sql);
419
        if (Database::num_rows($res) < 1) {
420
            return false;
421
        }
422
        $row = Database::fetch_assoc($res);
423
424
        return $row['english_name'];
425
    }
426
427
    /**
428
     * Get best language in browser preferences.
429
     *
430
     * @param string $preferences The browser-configured language preferences (e.g. "en,es;q=0.7;en-us;q=0.3", etc)
431
     *
432
     * @return mixed English name of the matching language, or false if no active language could be found
433
     */
434
    public static function getLanguageFromBrowserPreference($preferences)
435
    {
436
        if (empty($preferences)) {
437
            return false;
438
        }
439
440
        $preferencesArray = explode(',', $preferences);
441
442
        if (count($preferencesArray) > 0) {
443
            foreach ($preferencesArray as $pref) {
444
                $s = strpos($pref, ';');
445
                if ($s >= 2) {
446
                    $code = substr($pref, 0, $s);
447
                } else {
448
                    $code = $pref;
449
                }
450
                $name = self::getLanguageFromIsocode($code);
451
452
                if (false !== $name) {
453
                    return $name;
454
                }
455
            }
456
        }
457
458
        return false;
459
    }
460
461
    /**
462
     * Convert a string to a valid PHP camelCase variable name.
463
     *
464
     * @param string $string
465
     * @return string
466
     */
467
    public static function stringToCamelCaseVariableName($string)
468
    {
469
        $varName = preg_replace('/[^a-z0-9_]/i', '_', $string);  // Replace invalid characters with '_'
470
        $varName = trim($varName, '_');  // Trim any '_' from the beginning and end
471
        $varName = ucwords(str_replace('_', ' ', $varName));  // Convert to camel case
472
        $varName = lcfirst(str_replace(' ', '', $varName));  // Remove spaces and convert the first character to lowercase
473
        return substr($varName, 0, 25);  // Limit to 15 characters
474
    }
475
476
    /**
477
     * Retrieve the iso_code for a given language ID and its parent.
478
     *
479
     * @param int $languageId
480
     * @return array [childIsoCode, parentIsoCode]
481
     */
482
    public static function getIsoCodes($languageId)
483
    {
484
        $em = Database::getManager();
485
        $language = $em->getRepository('Chamilo\CoreBundle\Entity\Language')->find($languageId);
486
487
        if (!$language) {
488
            return [null, null];
489
        }
490
491
        $childIsoCode = $language->getIsoCode();
492
        $parentIsoCode = null;
493
494
        if ($language->getParent()) {
495
            $parentLanguage = $em->getRepository('Chamilo\CoreBundle\Entity\Language')->find($language->getParent());
496
            if ($parentLanguage) {
497
                $parentIsoCode = $parentLanguage->getIsoCode();
498
            }
499
        }
500
501
        return [$childIsoCode, $parentIsoCode];
502
    }
503
504
    /**
505
     * Search for translations based on a term and language ID.
506
     *
507
     * @param string $term        The term to search for.
508
     * @param int    $languageId  The ID of the language to search in.
509
     *
510
     * @return array An array of matched translations.
511
     */
512
    public static function searchTranslations($term, $languageId): array
513
    {
514
        // Retrieve the ISO codes for the provided language ID.
515
        list($childIsoCode, $parentIsoCode) = self::getIsoCodes($languageId);
516
517
        // Define the files to search in based on the ISO codes.
518
        $files = ['en' => 'messages.en.po', $parentIsoCode => "messages.$parentIsoCode.po", $childIsoCode => "messages.$childIsoCode.po"];
519
520
        $results = [];
521
522
        // Step 1: Search for all matches in messages.en.po.
523
        $matchedMsgids = self::searchMsgidInFile($term, $files['en']);
524
525
        // Step 2: For each matched msgid, search for its translation in the other files.
526
        foreach ($matchedMsgids as $msgid) {
527
            $entry = [
528
                'file' => $files['en'],
529
                'variable' => $msgid,
530
                'phpVarName' => self::stringToCamelCaseVariableName($msgid),
531
                'en' => self::getTranslationForVariable($msgid, $files['en'])
532
            ];
533
            $entry[$parentIsoCode] = self::getTranslationForVariable($msgid, $files[$parentIsoCode]);
534
            $entry[$childIsoCode] = self::getTranslationForVariable($msgid, $files[$childIsoCode], true);
535
536
            $results[] = $entry;
537
        }
538
539
        return $results;
540
    }
541
542
    /**
543
     * Search for a specific term inside a given .po file and return the msgids that match.
544
     *
545
     * @param string $term      The term to search for.
546
     * @param string $filename  The name of the .po file to search in.
547
     *
548
     * @return array An array of msgids that match the given term.
549
     */
550
    private static function searchMsgidInFile($term, $filename)
551
    {
552
        $poFilePath = api_get_path(SYS_PATH) . self::LANGUAGE_TRANS_PATH . $filename;
553
        $matchedMsgids = [];
554
555
        if (file_exists($poFilePath)) {
556
            $lines = file($poFilePath, FILE_IGNORE_NEW_LINES);
557
            $currentVariable = null;
558
559
            foreach ($lines as $line) {
560
                if (strpos($line, 'msgid "') === 0) {
561
                    $currentVariable = str_replace('msgid "', '', $line);
562
                    $currentVariable = rtrim($currentVariable, '"');
563
564
                    if (stripos($currentVariable, $term) !== false) {
565
                        $matchedMsgids[] = $currentVariable;
566
                    }
567
                }
568
            }
569
        }
570
571
        return $matchedMsgids;
572
    }
573
574
    /**
575
     * Retrieve the translation (msgstr) for a given variable (msgid) from a specified .po file.
576
     *
577
     * @param string $variable  The variable (msgid) to search for.
578
     * @param string $filename  The name of the .po file to retrieve the translation from.
579
     *
580
     * @return string The translation (msgstr) for the provided variable, or an empty string if not found.
581
     */
582
    private static function getTranslationForVariable(string $variable, string $filename, $checkSubLanguagePath = false): string
583
    {
584
        $poFilePath = self::getPoFilePath($filename, $checkSubLanguagePath);
585
        if (!file_exists($poFilePath)) {
586
            $shortLanguageCode = self::getShortLanguageCode($filename);
587
            $poFilePath = self::getPoFilePath($shortLanguageCode . '.po', $checkSubLanguagePath);
588
589
            if (!file_exists($poFilePath)) {
590
                return '';
591
            }
592
        }
593
594
        $content = file_get_contents($poFilePath);
595
        $pattern = '/msgid "' . preg_quote($variable, '/') . '"\nmsgstr "(.*?)"/';
596
        if (preg_match($pattern, $content, $match)) {
597
            return $match[1];
598
        }
599
600
        return '';
601
    }
602
603
    private static function getPoFilePath(string $filename, bool $checkSubLanguagePath): string
604
    {
605
        $path = $checkSubLanguagePath ? self::SUBLANGUAGE_TRANS_PATH : self::LANGUAGE_TRANS_PATH;
606
        return api_get_path(SYS_PATH) . $path . $filename;
607
    }
608
609
    private static function getShortLanguageCode(string $filename): string
610
    {
611
        $parts = explode('.', $filename);
612
        $languageCodeParts = explode('_', $parts[1]);
613
        return $parts[0].'.'.$languageCodeParts[0];
614
    }
615
616
    /**
617
     * Updates or adds a msgid in the specified .po file.
618
     *
619
     * @param string $filename  Name of the .po file
620
     * @param string $msgid     Message identifier to search or add
621
     * @param string $content   Associated message content
622
     *
623
     * @return array Returns true if the operation was successful, otherwise returns false
624
     */
625
    public static function updateOrAddMsgid($filename, $msgid, $content): array
626
    {
627
        $filePath = api_get_path(SYS_PATH) . self::SUBLANGUAGE_TRANS_PATH .  $filename;
628
629
        if (!file_exists($filePath)) {
630
            return ['success' => false, 'error' => 'File does not exist'];
631
        }
632
633
        if (!is_writable($filePath)) {
634
            try {
635
                if (!chmod($filePath, 0664)) {
636
                    return ['success' => false, 'error' => 'Unable to set the file to writable'];
637
                }
638
            } catch (Exception $e) {
639
640
                return ['success' => false, 'error' => 'Failed to change file permissions: ' . $e->getMessage()];
641
            }
642
        }
643
644
        $fileContents = file_get_contents($filePath);
645
        if ($fileContents === false) {
646
            return ['success' => false, 'error' => 'Failed to read file contents'];
647
        }
648
649
        $pattern = '/msgid "' . preg_quote($msgid, '/') . '"' . PHP_EOL . 'msgstr "(.*?)"/';
650
        if (preg_match($pattern, $fileContents)) {
651
            $replacement = 'msgid "' . $msgid . '"' . PHP_EOL . 'msgstr "' . $content . '"';
652
            $fileContents = preg_replace($pattern, $replacement, $fileContents);
653
        } else {
654
            $appendString = PHP_EOL . PHP_EOL . 'msgid "' . $msgid . '"' . PHP_EOL . 'msgstr "' . $content . '"';
655
            $fileContents .= $appendString;
656
        }
657
658
        if (file_put_contents($filePath, $fileContents) === false) {
659
            return ['success' => false, 'error' => 'Failed to write to file'];
660
        }
661
662
        return ['success' => true];
663
    }
664
665
    /**
666
     * Delete sub-language.
667
     * In order to avoid deletion of main languages, we check the existence of a parent.
668
     */
669
    public static function removeSubLanguage(int $parentId, int $subLanguageId): bool
670
    {
671
        $entityManager = Database::getManager();
672
        $subLanguage = $entityManager->getRepository(Language::class)->find($subLanguageId);
673
        $parentLanguage = $subLanguage ? $subLanguage->getParent() : null;
674
675
        if (!$subLanguage || !$parentLanguage || $parentLanguage->getId() != $parentId) {
676
            return false;
677
        }
678
679
        // Locate and delete the .po file of the sub-language
680
        $subLanguageIsoCode = $subLanguage->getIsocode();
681
        $poFilePath = api_get_path(SYS_PATH) . self::SUBLANGUAGE_TRANS_PATH .  "messages.$subLanguageIsoCode.po";
682
        if (file_exists($poFilePath)) {
683
             unlink($poFilePath);
684
        }
685
686
        $entityManager->remove($subLanguage);
687
        $entityManager->flush();
688
689
        return true;
690
    }
691
692
    /**
693
     * Add a sub-language.
694
     */
695
    public static function addSubLanguage(string $originalName, string $englishName, bool $isAvailable, int $parentId, string $isoCode): bool|int
696
    {
697
        $entityManager = Database::getManager();
698
        $parentLanguage = $entityManager->getRepository(Language::class)->find($parentId);
699
        if (!$parentLanguage) {
700
            return false;
701
        }
702
703
        $subLanguage = new Language();
704
        $subLanguage->setOriginalName($originalName)
705
            ->setEnglishName($englishName)
706
            ->setIsocode($isoCode)
707
            ->setAvailable($isAvailable)
708
            ->setParent($parentLanguage);
709
710
        try {
711
            $entityManager->persist($subLanguage);
712
            $entityManager->flush();
713
        } catch (\Exception $e) {
714
            // Handle exception if needed
715
            return false;
716
        }
717
718
        return $subLanguage->getId();
719
    }
720
721
    /**
722
     * Remove a .po file for a sub-language.
723
     *
724
     * @param string $isoCode The ISO code of the sub-language (e.g., 'es_CO')
725
     *
726
     * @return bool True on success, false on failure
727
     */
728
    public static function removePoFileForSubLanguage(string $isoCode): bool
729
    {
730
        if (empty($isoCode)) {
731
            return false;
732
        }
733
734
        // Path for the .po file you want to remove
735
        $poFilePath = api_get_path(SYS_PATH) . self::SUBLANGUAGE_TRANS_PATH . "messages.$isoCode.po";
736
737
        if (file_exists($poFilePath)) {
738
            return unlink($poFilePath);
739
        }
740
741
        // File does not exist, consider it a successful removal
742
        return true;
743
    }
744
745
    /**
746
     * Check if a language exists by its ID.
747
     *
748
     * @throws NotSupported
749
     */
750
    public static function languageExistsById(int $languageId): bool
751
    {
752
        $entityManager = Database::getManager();
753
        $language = $entityManager->getRepository(Language::class)->find($languageId);
754
755
        return $language !== null;
756
    }
757
758
    /**
759
     * Check if the given language is a parent of any sub-language.
760
     */
761
    public static function isParentOfSubLanguage(int $parentId): bool
762
    {
763
        $entityManager = Database::getManager();
764
        $languageRepository = $entityManager->getRepository(Language::class);
765
766
        $childrenCount = $languageRepository->count(['parent' => $parentId]);
767
768
        return $childrenCount > 0;
769
    }
770
771
    /**
772
     * Get all information of a sub-language.
773
     *
774
     * @throws NotSupported
775
     */
776
    public static function getAllInformationOfSubLanguage(int $parentId, int $subLanguageId): ?Language
777
    {
778
        $entityManager = Database::getManager();
779
        $languageRepository = $entityManager->getRepository(Language::class);
780
781
        return $languageRepository->findOneBy([
782
            'parent' => $parentId,
783
            'id' => $subLanguageId
784
        ]);
785
    }
786
787
    /**
788
     * Convert a Language entity to an array.
789
     */
790
    private static function convertLanguageToArray(Language $language): array
0 ignored issues
show
Unused Code introduced by
The method convertLanguageToArray() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
791
    {
792
        return [
793
            'id' => $language->getId(),
794
            'original_name' => $language->getOriginalName(),
795
            'english_name' => $language->getEnglishName(),
796
            'isocode' => $language->getIsocode(),
797
            'available' => $language->getAvailable(),
798
            // Add other fields as needed
799
        ];
800
    }
801
802
    /**
803
     * Check if a language exists.
804
     */
805
    public static function checkIfLanguageExists(string $originalName, string $englishName, string $isoCode): array
806
    {
807
        $entityManager = Database::getManager();
808
        $languageRepository = $entityManager->getRepository(Language::class);
809
810
        $messageInformation = [
811
            'original_name' => false,
812
            'english_name' => false,
813
            'isocode' => false,
814
            'execute_add' => true
815
        ];
816
817
        if ($languageRepository->count(['originalName' => $originalName]) > 0) {
818
            $messageInformation['original_name'] = true;
819
            $messageInformation['execute_add'] = false;
820
        }
821
822
        if ($languageRepository->count(['englishName' => $englishName]) > 0) {
823
            $messageInformation['english_name'] = true;
824
            $messageInformation['execute_add'] = false;
825
        }
826
827
        $isoList = api_get_platform_isocodes(); // Assuming this is an existing function
828
        if (!in_array($isoCode, array_values($isoList))) {
829
            $messageInformation['isocode'] = true;
830
            $messageInformation['execute_add'] = false;
831
        }
832
833
        return $messageInformation;
834
    }
835
836
    /**
837
     * Gets the ISO code of the parent language for a given language.
838
     */
839
    public static function getParentLocale(string $childIsoCode): ?string
840
    {
841
        $em = Database::getManager();
842
        $languageRepository = $em->getRepository('Chamilo\CoreBundle\Entity\Language');
843
844
        // Find the language by its ISO code
845
        $language = $languageRepository->findOneBy(['isocode' => $childIsoCode]);
846
847
        if (!$language) {
848
            return null; // Language not found
849
        }
850
851
        // Get the parent language if it exists
852
        $parentLanguage = $language->getParent();
853
        if ($parentLanguage) {
854
            return $parentLanguage->getIsocode();
855
        }
856
857
        return null; // No parent language
858
    }
859
860
    public static function generateSublanguageCode(string $parentCode, string $variant, int $maxLength = 10): string
861
    {
862
        $parentCode = strtolower(trim($parentCode));
863
        $variant = strtolower(trim($variant));
864
865
        // Generate a variant code by truncating the variant name
866
        $variantCode = substr($variant, 0, $maxLength - strlen($parentCode) - 1);
867
868
        // Build the complete code
869
        $fullCode = substr($parentCode . '_' . $variantCode, 0, $maxLength);
870
871
        return $fullCode;
872
    }
873
}
874