Passed
Push — master ( 719760...59ab2e )
by Angel Fernando Quiroz
18:35
created

SubLanguageManager::remove_sub_language()   B

Complexity

Conditions 8
Paths 4

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

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

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