Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
LoadDefault18nCommand
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 2
240
0.00% covered (danger)
0.00%
0 / 1
 execute
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
20
 parsePoFile
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
132
1<?php
2declare(strict_types=1);
3
4namespace App\Command;
5
6use Cake\Command\Command;
7use Cake\Console\Arguments;
8use Cake\Console\ConsoleIo;
9use Cake\ORM\TableRegistry;
10use Exception;
11
12/**
13 * Class LoadDefault18nCommand
14 *
15 * This command processes teh default.pot file and updates the database with translation records per supported locale.
16 */
17class LoadDefault18nCommand extends Command
18{
19    /**
20     * Executes the command to update internationalisation records.
21     *
22     * @param \Cake\Console\Arguments $args The command line arguments.
23     * @param \Cake\Console\ConsoleIo $io The console input/output.
24     * @return void
25     */
26    public function execute(Arguments $args, ConsoleIo $io): void
27    {
28        $potFile = 'resources/locales/default.pot';
29        $translations = $this->parsePoFile($potFile);
30
31        // Assuming you have an InternationalisationsTable to handle translation records
32        $internationalisationsTable = TableRegistry::getTableLocator()->get('Internationalisations');
33
34        // Define the locales you want to support
35        $locales = [
36            'de_DE', // German (Germany)
37            'fr_FR', // French (France)
38            'es_ES', // Spanish (Spain)
39            'it_IT', // Italian (Italy)
40            'pt_PT', // Portuguese (Portugal)
41            'nl_NL', // Dutch (Netherlands)
42            'pl_PL', // Polish (Poland)
43            'ru_RU', // Russian (Russia)
44            'sv_SE', // Swedish (Sweden)
45            'da_DK', // Danish (Denmark)
46            'fi_FI', // Finnish (Finland)
47            'no_NO', // Norwegian (Norway)
48            'el_GR', // Greek (Greece)
49            'tr_TR', // Turkish (Turkey)
50            'cs_CZ', // Czech (Czech Republic)
51            'hu_HU', // Hungarian (Hungary)
52            'ro_RO', // Romanian (Romania)
53            'sk_SK', // Slovak (Slovakia)
54            'sl_SI', // Slovenian (Slovenia)
55            'bg_BG', // Bulgarian (Bulgaria)
56            'hr_HR', // Croatian (Croatia)
57            'et_EE', // Estonian (Estonia)
58            'lv_LV', // Latvian (Latvia)
59            'lt_LT', // Lithuanian (Lithuania)
60            'uk_UA', // Ukrainian (Ukraine)
61        ];
62
63        foreach ($translations as $messageId => $messageStr) {
64            foreach ($locales as $locale) {
65                // Check if the message ID exists in the database for the given locale
66                $internationalisation = $internationalisationsTable->find()
67                    ->where(['message_id' => $messageId, 'locale' => $locale])
68                    ->first();
69
70                if (!$internationalisation) {
71                    // If not, add it with an empty translation for each locale
72                    $internationalisation = $internationalisationsTable->newEntity([
73                        'message_id' => $messageId,
74                        'locale' => $locale,
75                        'message_str' => '',
76                    ]);
77                    $internationalisationsTable->save($internationalisation);
78                }
79            }
80        }
81
82        $io->success('Internationalisations updated successfully.');
83    }
84
85    /**
86     * Parses a .po file to extract translations.
87     *
88     * @param string $file The path to the .po file.
89     * @return array An associative array of message IDs and their corresponding translations.
90     * @throws \Exception If the file does not exist.
91     */
92    private function parsePoFile(string $file): array
93    {
94        if (!file_exists($file)) {
95            throw new Exception("The file {$file} does not exist.");
96        }
97
98        $translations = [];
99        $currentMsgId = null;
100        $currentMsgStr = '';
101
102        $lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
103        foreach ($lines as $line) {
104            $line = trim($line);
105
106            if (strpos($line, 'msgid "') === 0) {
107                if ($currentMsgId !== null) {
108                    $translations[$currentMsgId] = $currentMsgStr;
109                    $currentMsgStr = '';
110                }
111                $currentMsgId = substr($line, 7, -1);
112            } elseif (strpos($line, 'msgstr "') === 0) {
113                $currentMsgStr = substr($line, 8, -1);
114            } elseif ($currentMsgId !== null && strpos($line, '"') === 0) {
115                if (strpos($line, 'msgid') === false && strpos($line, 'msgstr') === false) {
116                    $currentMsgStr .= substr($line, 1, -1);
117                }
118            }
119        }
120
121        // Add the last translation
122        if ($currentMsgId !== null) {
123            $translations[$currentMsgId] = $currentMsgStr;
124        }
125
126        return $translations;
127    }
128}