These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace translator\classes; |
||
4 | |||
5 | use Gettext\Translations; |
||
6 | |||
7 | class PoFileManager |
||
8 | { |
||
9 | |||
10 | /** |
||
11 | * Templates folder path |
||
12 | * @var string |
||
13 | */ |
||
14 | const TEMPLATES_PATH = './templates/'; |
||
15 | |||
16 | /** |
||
17 | * Main lang folder path |
||
18 | * @var string |
||
19 | */ |
||
20 | const MAIN_PATH = './application/language/main/'; |
||
21 | |||
22 | /** |
||
23 | * Errors holder array |
||
24 | * @var array |
||
25 | */ |
||
26 | private static $ERRORS = []; |
||
27 | |||
28 | /** |
||
29 | * Po-file settings array |
||
30 | * @var array |
||
31 | */ |
||
32 | private $po_settings = []; |
||
33 | |||
34 | /** |
||
35 | * Po-file settings keys |
||
36 | * @var array |
||
37 | */ |
||
38 | private $po_settings_keys = [ |
||
39 | 'Project-Id-Version', |
||
40 | 'Last-Translator', |
||
41 | 'Language-Team', |
||
42 | 'Basepath', |
||
43 | 'X-Poedit-Language', |
||
44 | 'X-Poedit-Country', |
||
45 | 'SearchPath', |
||
46 | ]; |
||
47 | |||
48 | /** |
||
49 | * @var string |
||
50 | */ |
||
51 | private static $SAAS_URL = ''; |
||
52 | |||
53 | /** |
||
54 | * @var array |
||
55 | */ |
||
56 | private static $CURRENT_TEMPLATE_PATHS = []; |
||
57 | |||
58 | /** |
||
59 | * PoFileManager constructor. |
||
60 | */ |
||
61 | public function __construct() { |
||
62 | |||
63 | } |
||
64 | |||
65 | /** |
||
66 | * Set error message |
||
67 | * @param string $error - error message |
||
68 | */ |
||
69 | private function setError($error) { |
||
70 | if ($error) { |
||
71 | self::$ERRORS[] = $error; |
||
72 | } |
||
73 | } |
||
74 | |||
75 | /** |
||
76 | * Get errors |
||
77 | * @return array |
||
78 | */ |
||
79 | public function getErrors() { |
||
80 | return self::$ERRORS; |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * Set saas url |
||
85 | * @param string $url - url value |
||
86 | */ |
||
87 | public function setSaasUrl($url) { |
||
88 | if ($url) { |
||
89 | self::$SAAS_URL = $url; |
||
90 | } else { |
||
91 | self::$SAAS_URL = ''; |
||
92 | } |
||
93 | } |
||
94 | |||
95 | public function exchangeTranslation($data) { |
||
96 | $langExchanger = $data['langExchanger']; |
||
97 | $langReceiver = $data['langReceiver']; |
||
98 | |||
99 | $typeExchanger = $data['typeExchanger']; |
||
100 | $typeReceiver = $data['typeReceiver']; |
||
101 | |||
102 | $modules_templatesExchanger = $data['modules_templatesExchanger']; |
||
103 | $modules_templatesReceiver = $data['modules_templatesReceiver']; |
||
104 | |||
105 | if ($langExchanger && $langReceiver && $typeExchanger && $typeReceiver) { |
||
106 | $resultExchanger = $this->toArray($modules_templatesExchanger, $typeExchanger, $langExchanger); |
||
107 | $exchangerPoArray = $resultExchanger['po_array']; |
||
108 | |||
109 | $resultReceiver = $this->toArray($modules_templatesReceiver, $typeReceiver, $langReceiver); |
||
110 | $receiverPoArray = $resultReceiver['po_array']; |
||
111 | |||
112 | View Code Duplication | foreach ($exchangerPoArray as $origin => $value) { |
|
113 | if ($receiverPoArray[$origin]) { |
||
114 | $receiverPoArray[$origin]['translation'] = $value['translation']; |
||
115 | } |
||
116 | } |
||
117 | |||
118 | $receiverPoArray['po_array'] = $receiverPoArray; |
||
119 | $receiverPoArray['settings'] = $this->prepareUpdateSettings($resultExchanger['settings']); |
||
120 | return $this->save($modules_templatesReceiver, $typeReceiver, $langReceiver, $receiverPoArray); |
||
121 | } |
||
122 | return FALSE; |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * Prepare correct domain name |
||
127 | * @param string $domain - domain name |
||
128 | * @return string |
||
129 | */ |
||
130 | public function prepareDomain($domain) { |
||
131 | $CI = &get_instance(); |
||
132 | $template = $CI->config->item('template'); |
||
133 | |||
134 | if ($template != 'administrator') { |
||
135 | if (file_exists($this->getPoFileUrl($template, 'templates', CUR_LOCALE))) { |
||
136 | if (!self::$CURRENT_TEMPLATE_PATHS) { |
||
137 | $po_array = $this->toArray($template, 'templates', CUR_LOCALE, FALSE); |
||
138 | self::$CURRENT_TEMPLATE_PATHS = $po_array['settings']['SearchPath']; |
||
139 | } |
||
140 | |||
141 | switch ($this->getDomainType($domain)) { |
||
142 | View Code Duplication | case 'modules': |
|
143 | $contains = array_filter( |
||
144 | self::$CURRENT_TEMPLATE_PATHS, |
||
145 | function ($path, $domain) { |
||
146 | return strstr($path, 'modules/' . $domain) ? TRUE : FALSE; |
||
147 | } |
||
148 | ); |
||
149 | |||
150 | return (!empty($contains)) ? $template : $domain; |
||
151 | View Code Duplication | case 'main': |
|
152 | $contains = array_filter( |
||
153 | self::$CURRENT_TEMPLATE_PATHS, |
||
154 | function ($path) { |
||
155 | $main_path = 'system/language/form_validation'; |
||
156 | return strstr($path, $main_path) ? TRUE : FALSE; |
||
157 | } |
||
158 | ); |
||
159 | |||
160 | return (!empty($contains)) ? $template : $domain; |
||
161 | default : |
||
162 | return $domain; |
||
163 | } |
||
164 | } |
||
165 | } |
||
166 | |||
167 | return $domain; |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * Get domain type name |
||
172 | * @param string $domain - domain name |
||
173 | * @return string |
||
174 | */ |
||
175 | public function getDomainType($domain) { |
||
176 | if (moduleExists($domain)) { |
||
177 | return 'modules'; |
||
178 | } |
||
179 | |||
180 | if (is_dir(self::TEMPLATES_PATH . $domain)) { |
||
181 | return 'templates'; |
||
182 | } |
||
183 | |||
184 | return 'main'; |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * Prepare po-file url |
||
189 | * @param string $name - module or template name |
||
190 | * @param string $type - type of po-file(modules, templates, main) |
||
191 | * @param string $lang - language locale |
||
192 | * @return string |
||
193 | */ |
||
194 | public function getPoFileUrl($name, $type, $lang) { |
||
195 | switch ($type) { |
||
196 | case 'modules': |
||
197 | $url = getModulePathForTranslator($name) . 'language/' . $lang . '/LC_MESSAGES/' . $name . '.po'; |
||
198 | break; |
||
199 | case 'templates': |
||
200 | $url = self::TEMPLATES_PATH . $name . '/language/' . $name . '/' . $lang . '/LC_MESSAGES/' . $name . '.po'; |
||
201 | break; |
||
202 | case 'main': |
||
203 | $url = self::MAIN_PATH . $lang . '/LC_MESSAGES/' . $type . '.po'; |
||
204 | break; |
||
205 | default : |
||
206 | $url = ''; |
||
207 | } |
||
208 | |||
209 | if (self::$SAAS_URL) { |
||
210 | $url = str_replace('./', self::$SAAS_URL . '/', $url); |
||
211 | } |
||
212 | return $url; |
||
213 | } |
||
214 | |||
215 | /** |
||
216 | * Prepare settings array |
||
217 | * @param array $data - settings array |
||
218 | * @return string |
||
219 | */ |
||
220 | private function prepareSettingsArray($data = []) { |
||
221 | if (!isset($data['projectName']) || !$data['projectName']) { |
||
222 | $data['projectName'] = ''; |
||
223 | } |
||
224 | |||
225 | if (!isset($data['translatorName']) || !$data['translatorName']) { |
||
226 | $data['translatorName'] = ''; |
||
227 | } |
||
228 | |||
229 | View Code Duplication | if (!isset($data['translatorEmail']) || !$data['translatorEmail']) { |
|
230 | $data['translatorEmail'] = ''; |
||
231 | } else { |
||
232 | str_replace('<', '', $data['translatorEmail']); |
||
233 | str_replace('>', '', $data['translatorEmail']); |
||
234 | } |
||
235 | |||
236 | if (!isset($data['langaugeTeamName']) || !$data['langaugeTeamName']) { |
||
237 | $data['langaugeTeamName'] = ''; |
||
238 | } |
||
239 | |||
240 | View Code Duplication | if (!isset($data['langaugeTeamEmail']) || !$data['langaugeTeamEmail']) { |
|
241 | $data['langaugeTeamEmail'] = ''; |
||
242 | } else { |
||
243 | str_replace('<', '', $data['langaugeTeamEmail']); |
||
244 | str_replace('>', '', $data['langaugeTeamEmail']); |
||
245 | } |
||
246 | |||
247 | View Code Duplication | if (!isset($data['lang']) || !$data['lang']) { |
|
248 | $data['lang'] = ''; |
||
249 | } |
||
250 | |||
251 | if (!isset($data['basepath']) || !$data['basepath']) { |
||
252 | $data['basepath'] = ''; |
||
253 | } |
||
254 | |||
255 | if (!isset($data['language']) || !$data['language']) { |
||
256 | $data['language'] = ''; |
||
257 | } |
||
258 | |||
259 | if (!isset($data['country']) || !$data['country']) { |
||
260 | $data['country'] = ''; |
||
261 | } |
||
262 | |||
263 | return $data; |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * Make po-file settings formated string |
||
268 | * @param array $data - settings array |
||
269 | * @return string|false |
||
270 | */ |
||
271 | private function makePoFileSettings($data = []) { |
||
272 | if (!empty($data)) { |
||
273 | $data = $this->prepareSettingsArray($data); |
||
274 | $settings = [ |
||
275 | 'msgid ""', |
||
276 | 'msgstr ""', |
||
277 | '"Project-Id-Version: ' . $data['projectName'] . '\n"', |
||
278 | '"Report-Msgid-Bugs-To: \n"', |
||
279 | '"POT-Creation-Date: ' . date('Y-m-d h:iO', time()) . '\n"', |
||
280 | '"PO-Revision-Date: ' . date('Y-m-d h:iO', time()) . '\n"', |
||
281 | '"Last-Translator: ' . $data['translatorName'] . ' <' . $data['translatorEmail'] . '>\n"', |
||
282 | '"Language-Team: ' . $data['langaugeTeamName'] . ' <' . $data['langaugeTeamEmail'] . '>\n"', |
||
283 | '"Language: ' . $data['lang'] . '\n"', |
||
284 | '"MIME-Version: 1.0\n"', |
||
285 | '"Content-Type: text/plain; charset=UTF-8\n"', |
||
286 | '"Content-Transfer-Encoding: 8bit\n"', |
||
287 | '"X-Poedit-KeywordsList: _;gettext;gettext_noop;lang\n"', |
||
288 | '"X-Poedit-Basepath: ' . $data['basepath'] . '\n"', |
||
289 | '"X-Poedit-SourceCharset: utf-8\n"', |
||
290 | '"X-Generator: Poedit 1.5.7\n"', |
||
291 | '"X-Poedit-Language: ' . $data['language'] . '\n"', |
||
292 | '"X-Poedit-Country: ' . $data['country'] . '\n"', |
||
293 | ]; |
||
294 | |||
295 | if (isset($data['paths']) && count($data['paths']) > 0) { |
||
296 | foreach ($data['paths'] as $number => $path) { |
||
297 | $settings[] = '"X-Poedit-SearchPath-' . $number . ': ' . $path . '\n"'; |
||
298 | } |
||
299 | } |
||
300 | |||
301 | return implode("\n", $settings); |
||
302 | } else { |
||
303 | self::$ERRORS[] = lang('Settings array is empty', 'translator'); |
||
304 | return FALSE; |
||
305 | } |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * Create po-file |
||
310 | * @param string $name - module or template name |
||
311 | * @param string $type - type of po-file(modules, templates, main) |
||
312 | * @param string $lang - language locale |
||
313 | * @param array $settings - settings array |
||
314 | * @return boolean|null |
||
315 | */ |
||
316 | public function create($name, $type, $lang, $settings) { |
||
317 | if ($name && $type && $lang) { |
||
318 | $url = $this->getPoFileUrl($name, $type, $lang); |
||
319 | |||
320 | if (file_exists($url)) { |
||
321 | $this->setError(lang('File is already exists.', 'translator')); |
||
322 | return FALSE; |
||
323 | } |
||
324 | |||
325 | if (!@fopen($url, 'wb')) { |
||
326 | $this->setError(lang('Can not create file. Check if path to the file is correct - ', 'translator') . $url); |
||
327 | return FALSE; |
||
328 | } |
||
329 | |||
330 | $settings = $this->makePoFileSettings($settings); |
||
331 | if (file_put_contents($url, b"\xEF\xBB\xBF" . $settings)) { |
||
332 | return TRUE; |
||
333 | } else { |
||
334 | $this->setError(lang('Can not create file. Check if path to the file is correct - ', 'translator') . $url); |
||
335 | return FALSE; |
||
336 | } |
||
337 | } |
||
338 | } |
||
339 | |||
340 | public function getModules() { |
||
341 | $modules = getModulesPaths(); |
||
342 | $data = []; |
||
343 | foreach ($modules as $moduleName => $modulePath) { |
||
344 | if ($moduleName != 'admin' && $moduleName != 'shop') { |
||
345 | $lang = new \MY_Lang(); |
||
346 | $lang->load($moduleName); |
||
347 | |||
348 | include $modulePath . 'module_info.php'; |
||
349 | $name = isset($com_info['menu_name']) ? $com_info['menu_name'] : $moduleName; |
||
350 | $data[$moduleName] = $name; |
||
351 | } |
||
352 | } |
||
353 | |||
354 | return $data; |
||
355 | } |
||
356 | |||
357 | /** |
||
358 | * @param string $name |
||
359 | * @param string $type |
||
360 | * @param string $lang |
||
361 | * @param string $domain_path |
||
362 | * @return bool |
||
363 | */ |
||
364 | public function saas_update_one($name, $type, $lang, $domain_path) { |
||
365 | $this->setSaasUrl('/var/www/saas_data/mainsaas'); |
||
366 | $saas_file = $this->toArray($name, $type, $lang); |
||
367 | |||
368 | if (isset($saas_file['po_array'])) { |
||
369 | $this->setSaasUrl($domain_path); |
||
370 | $user_file = $this->toArray($name, $type, $lang); |
||
371 | |||
372 | if ($user_file) { |
||
373 | $updation = []; |
||
374 | foreach ($saas_file['po_array'] as $origin => $value) { |
||
375 | if (!isset($user_file['po_array'][$origin])) { |
||
376 | $updation[$origin] = $value; |
||
377 | } |
||
378 | } |
||
379 | |||
380 | if ($updation) { |
||
381 | $this->update($name, $type, $lang, $updation); |
||
382 | } |
||
383 | } |
||
384 | $this->setSaasUrl(''); |
||
385 | } |
||
386 | return TRUE; |
||
387 | } |
||
388 | |||
389 | /** |
||
390 | * @param string $name |
||
391 | * @param string $type |
||
392 | * @param string $lang |
||
393 | * @param array $data |
||
394 | * @return bool |
||
395 | */ |
||
396 | public function update($name, $type, $lang, $data) { |
||
397 | $po_data = $this->toArray($name, $type, $lang); |
||
398 | |||
399 | if ($po_data && array_key_exists('po_array', $po_data)) { |
||
400 | foreach ($data as $origin => $values) { |
||
401 | |||
402 | if (isset($po_data['po_array'][$origin])) { |
||
403 | |||
404 | if ($values['translation']) { |
||
405 | $po_data['po_array'][$origin]['translation'] = $values['translation']; |
||
406 | } |
||
407 | |||
408 | if ($values['comment']) { |
||
409 | $po_data['po_array'][$origin]['comment'] = $values['comment']; |
||
410 | } |
||
411 | } else { |
||
412 | |||
413 | if ($values['translation']) { |
||
414 | $po_data['po_array'][$origin] = [ |
||
415 | 'translation' => $values['translation'], |
||
416 | 'comment' => $values['comment'] ? $values['comment'] : '', |
||
417 | 'links' => $values['links'] ? $values['links'] : ['tmpLink'], |
||
418 | 'fuzzy' => FALSE, |
||
419 | ]; |
||
420 | } |
||
421 | } |
||
422 | } |
||
423 | |||
424 | if (isset($po_data['settings'])) { |
||
425 | $data = $po_data['po_array']; |
||
426 | $data['settings'] = $this->prepareUpdateSettings($po_data['settings']); |
||
427 | |||
428 | return $this->save($name, $type, $lang, $data); |
||
429 | } |
||
430 | } |
||
431 | return FALSE; |
||
432 | } |
||
433 | |||
434 | /** |
||
435 | * @param array $data |
||
436 | * @return mixed |
||
437 | */ |
||
438 | public function prepareUpdateSettings($data) { |
||
439 | if (!isset($data['Project-Id-Version']) || !$data['Project-Id-Version']) { |
||
440 | $data['projectName'] = ''; |
||
441 | } else { |
||
442 | $data['projectName'] = $data['Project-Id-Version']; |
||
443 | } |
||
444 | |||
445 | unset($data['Project-Id-Version']); |
||
446 | |||
447 | if (!isset($data['Last-Translator-Name']) || !$data['Last-Translator-Name']) { |
||
448 | $data['translatorName'] = ''; |
||
449 | } else { |
||
450 | $data['translatorName'] = $data['Last-Translator-Name']; |
||
451 | } |
||
452 | |||
453 | unset($data['Last-Translator-Name']); |
||
454 | |||
455 | if (!isset($data['Last-Translator-Email']) || !$data['Last-Translator-Email']) { |
||
456 | $data['translatorEmail'] = ''; |
||
457 | } else { |
||
458 | $data['translatorEmail'] = $data['Last-Translator-Email']; |
||
459 | } |
||
460 | |||
461 | unset($data['Last-Translator-Email']); |
||
462 | |||
463 | if (!isset($data['Language-Team-Name']) || !$data['Language-Team-Name']) { |
||
464 | $data['langaugeTeamName'] = ''; |
||
465 | } else { |
||
466 | $data['langaugeTeamName'] = $data['Language-Team-Name']; |
||
467 | } |
||
468 | |||
469 | unset($data['Language-Team-Name']); |
||
470 | |||
471 | if (!isset($data['Language-Team-Email']) || !$data['Language-Team-Email']) { |
||
472 | $data['langaugeTeamEmail'] = ''; |
||
473 | } else { |
||
474 | $data['langaugeTeamEmail'] = $data['Language-Team-Email']; |
||
475 | } |
||
476 | |||
477 | unset($data['Language-Team-Email']); |
||
478 | |||
479 | View Code Duplication | if (!isset($data['lang']) || !$data['lang']) { |
|
480 | $data['lang'] = ''; |
||
481 | } |
||
482 | |||
483 | if (!isset($data['Basepath']) || !$data['Basepath']) { |
||
484 | $data['basepath'] = ''; |
||
485 | } else { |
||
486 | $data['basepath'] = $data['Basepath']; |
||
487 | } |
||
488 | |||
489 | unset($data['Basepath']); |
||
490 | |||
491 | if (!isset($data['SearchPath']) || !$data['SearchPath']) { |
||
492 | $data['paths'][] = '.'; |
||
493 | } else { |
||
494 | foreach ($data['SearchPath'] as $path) { |
||
495 | $data['paths'][] = $path; |
||
496 | } |
||
497 | } |
||
498 | |||
499 | unset($data['SearchPath']); |
||
500 | |||
501 | if (!isset($data['X-Poedit-Language']) || !$data['X-Poedit-Language']) { |
||
502 | $data['language'] = ''; |
||
503 | } else { |
||
504 | $data['language'] = $data['X-Poedit-Language']; |
||
505 | } |
||
506 | |||
507 | unset($data['X-Poedit-Language']); |
||
508 | |||
509 | if (!isset($data['X-Poedit-Country']) || !$data['X-Poedit-Country']) { |
||
510 | $data['country'] = ''; |
||
511 | } else { |
||
512 | $data['country'] = $data['X-Poedit-Country']; |
||
513 | } |
||
514 | |||
515 | unset($data['X-Poedit-Country']); |
||
516 | |||
517 | return $data; |
||
518 | } |
||
519 | |||
520 | /** |
||
521 | * Save po-file from array |
||
522 | * @param string $name - module or template name |
||
523 | * @param string $type - type of po-file(modules, templates, main) |
||
524 | * @param string $lang - language locale |
||
525 | * @param array $data - po-file data |
||
526 | * @return boolean |
||
527 | */ |
||
528 | public function save($name, $type, $lang, $data) { |
||
529 | $url = $this->getPoFileUrl($name, $type, $lang); |
||
530 | |||
531 | if (!$url) { |
||
532 | $this->setError(lang('Wrong po-file path', 'translator')); |
||
533 | return FALSE; |
||
534 | } |
||
535 | |||
536 | if (!FileOperator::getInstatce()->checkFile($url)) { |
||
537 | $errors = FileOperator::getInstatce()->getErrors(); |
||
538 | $this->setError($errors['error']); |
||
539 | return FALSE; |
||
540 | } |
||
541 | |||
542 | $settings = $this->makePoFileSettings((array) $data['settings']); |
||
543 | unset($data['settings']); |
||
544 | |||
545 | $po_file_data = $this->makePoFileData($data); |
||
546 | $po_file_content = b"\xEF\xBB\xBF" . $settings . "\n\n" . $po_file_data; |
||
547 | if (file_put_contents($url, $po_file_content)) { |
||
548 | if ($this->convertToMO($url)) { |
||
549 | return TRUE; |
||
550 | } else { |
||
551 | $this->setError(lang('Operation failed. Can not convert to mo-file.', 'translator')); |
||
552 | return FALSE; |
||
553 | } |
||
554 | } else { |
||
555 | $this->setError(lang('Can not save po-file.', 'translator')); |
||
556 | return FALSE; |
||
557 | } |
||
558 | } |
||
559 | |||
560 | /** |
||
561 | * Prepare correct po-file data |
||
562 | * @param array $data |
||
563 | * @return string |
||
564 | */ |
||
565 | private function preparePoFileData($data) { |
||
566 | if (!isset($data['comment']) || !$data['comment']) { |
||
567 | $data['comment'] = ''; |
||
568 | } |
||
569 | |||
570 | if (!isset($data['links']) || !$data['links']) { |
||
571 | $data['links'] = ''; |
||
572 | } |
||
573 | |||
574 | if (!isset($data['fuzzy']) || !$data['fuzzy']) { |
||
575 | $data['fuzzy'] = ''; |
||
576 | } |
||
577 | |||
578 | if (!isset($data['translation']) || !$data['translation']) { |
||
579 | $data['translation'] = ''; |
||
580 | } |
||
581 | return $data; |
||
582 | } |
||
583 | |||
584 | /** |
||
585 | * Make po-file data |
||
586 | * @param array $data - po-file data |
||
587 | * @return string |
||
588 | */ |
||
589 | private function makePoFileData($data = []) { |
||
590 | $resultData = []; |
||
591 | foreach ($data as $key => $po) { |
||
592 | if ($po) { |
||
593 | $po = $this->preparePoFileData((array) $po); |
||
594 | |||
595 | if ($po['comment']) { |
||
596 | $resultData[] = '# ' . $po['comment']; |
||
597 | } |
||
598 | |||
599 | if ($po['links']) { |
||
600 | foreach ($po['links'] as $link) { |
||
601 | $resultData[] = '#: ' . $link; |
||
602 | } |
||
603 | } |
||
604 | |||
605 | if ($po['fuzzy']) { |
||
606 | $resultData[] = '#, fuzzy'; |
||
607 | } |
||
608 | |||
609 | if ($key) { |
||
610 | $resultData[] = 'msgid "' . $key . '"'; |
||
611 | } |
||
612 | |||
613 | if ($po['translation']) { |
||
614 | $resultData[] = 'msgstr "' . $po['translation'] . '"' . "\n"; |
||
615 | } else { |
||
616 | $resultData[] = 'msgstr ""' . "\n"; |
||
617 | } |
||
618 | } |
||
619 | } |
||
620 | return implode("\n", $resultData); |
||
621 | } |
||
622 | |||
623 | /** |
||
624 | * Convert po-file to mo-file |
||
625 | * @param string $url - url to file |
||
626 | * @return boolean|null |
||
627 | */ |
||
628 | public function convertToMO($url = '') { |
||
629 | if ($url) { |
||
630 | $translations = Translations::fromPoFile($url); |
||
631 | |||
632 | array_map('unlink', glob(str_replace('.po', '_*.mo', $url))); |
||
633 | |||
634 | return $translations->toMoFile(str_replace('.po', '_' . time() . '.mo', $url)); |
||
635 | } |
||
636 | } |
||
637 | |||
638 | /** |
||
639 | * @param string $name |
||
640 | * @param string $type |
||
641 | * @param string $lang |
||
642 | * @param bool $langOn |
||
643 | * @return array|bool |
||
644 | */ |
||
645 | public function toArray($name, $type, $lang, $langOn = TRUE) { |
||
646 | $path = $this->getPoFileUrl($name, $type, $lang); |
||
647 | |||
648 | if (!FileOperator::getInstatce()->checkFile($path, $langOn)) { |
||
649 | $error = FileOperator::getInstatce()->getErrors(); |
||
650 | $this->setError($error['error']); |
||
651 | return FALSE; |
||
652 | } else { |
||
653 | $po = file($path); |
||
654 | } |
||
655 | |||
656 | $origin = null; |
||
657 | $this->po_settings = []; |
||
658 | |||
659 | foreach ($po as $key => $line) { |
||
660 | if (!($key > 2 && $origin)) { |
||
661 | $this->prepareSettingsValues($line); |
||
662 | } |
||
663 | |||
664 | $first2symbols = substr($line, 0, 2); |
||
665 | if (substr($line, 0, 1) == '#' && $first2symbols != '#:' && $first2symbols != '#,') { |
||
666 | $comment = trim(substr($line, 2, -1)); |
||
667 | continue; |
||
668 | } |
||
669 | if ($first2symbols == '#,') { |
||
670 | $fuzzy = TRUE; |
||
671 | continue; |
||
672 | } |
||
673 | |||
674 | View Code Duplication | if ($first2symbols == '#:') { |
|
675 | $links[] = trim(substr($line, 2, -1)); |
||
676 | continue; |
||
677 | } |
||
678 | |||
679 | View Code Duplication | if (substr($line, 0, 5) == 'msgid') { |
|
680 | if (preg_match('/"(.*?)"$/', trim($line), $matches)) { |
||
681 | $origin = $matches[1]; |
||
682 | if (!strlen($origin)) { |
||
683 | $origin = 0; |
||
684 | } |
||
685 | } |
||
686 | |||
687 | continue; |
||
688 | } |
||
689 | |||
690 | if (substr($line, 0, 6) == 'msgstr') { |
||
691 | if ($origin) { |
||
692 | preg_match('/"(.*?)"$/', trim($line), $translation); |
||
693 | $translations[$origin] = [ |
||
694 | 'translation' => isset($translation[1]) ? $translation[1] : '', |
||
695 | 'comment' => $comment, |
||
696 | 'links' => $links, |
||
697 | 'fuzzy' => $fuzzy, |
||
698 | ]; |
||
699 | } |
||
700 | $fuzzy = FALSE; |
||
701 | $comment = ''; |
||
702 | unset($links); |
||
703 | } |
||
704 | } |
||
705 | |||
706 | $translations = $translations ?: []; |
||
707 | $result = [ |
||
708 | 'settings' => $this->po_settings, |
||
709 | 'po_array' => $translations, |
||
710 | ]; |
||
711 | |||
712 | return $result; |
||
713 | } |
||
714 | |||
715 | /** |
||
716 | * @param string $line |
||
717 | * @return array |
||
718 | */ |
||
719 | private function prepareSettingsValues($line) { |
||
720 | foreach ($this->po_settings_keys as $key) { |
||
721 | if (preg_match('/' . $key . '/', $line)) { |
||
722 | $from = strpos($line, ':'); |
||
723 | |||
724 | if (substr($line, -5, -4) == '\\') { |
||
725 | $value = substr($line, $from + 2, -5); |
||
726 | } else { |
||
727 | $value = substr($line, $from + 2, -4); |
||
728 | } |
||
729 | |||
730 | switch ($key) { |
||
731 | case 'SearchPath': |
||
732 | $this->po_settings['SearchPath'][] = $value; |
||
733 | break 2; |
||
0 ignored issues
–
show
Coding Style
introduced
by
Loading history...
|
|||
734 | View Code Duplication | case 'Last-Translator': |
|
735 | $value = explode(' ', $value); |
||
736 | $this->po_settings['Last-Translator-Name'] = isset($value[0]) ? $value[0] : ''; |
||
737 | $value[1] = isset($value[1]) ? $value[1] : ''; |
||
738 | $value[1] = str_replace('<', '', $value[1]); |
||
739 | $value[1] = str_replace('>', '', $value[1]); |
||
740 | $this->po_settings['Last-Translator-Email'] = $value[1]; |
||
741 | break 2; |
||
0 ignored issues
–
show
|
|||
742 | View Code Duplication | case 'Language-Team': |
|
743 | $value = explode(' ', $value); |
||
744 | $this->po_settings['Language-Team-Name'] = isset($value[0]) ? $value[0] : ''; |
||
745 | $value[1] = isset($value[1]) ? $value[1] : ''; |
||
746 | $value[1] = str_replace('<', '', $value[1]); |
||
747 | $value[1] = str_replace('>', '', $value[1]); |
||
748 | $this->po_settings['Language-Team-Email'] = $value[1]; |
||
749 | break 2; |
||
0 ignored issues
–
show
|
|||
750 | case 'Basepath': |
||
751 | $this->po_settings['Basepath'] = $value; |
||
752 | break 2; |
||
0 ignored issues
–
show
|
|||
753 | default : |
||
0 ignored issues
–
show
|
|||
754 | $this->po_settings[$key] = $value; |
||
755 | break 2; |
||
756 | } |
||
757 | } |
||
758 | } |
||
759 | return $this->po_settings; |
||
760 | } |
||
761 | |||
762 | /** |
||
763 | * @param string $name |
||
764 | * @param string $type |
||
765 | * @param string $lang |
||
766 | * @param string $searchString |
||
767 | * @return array |
||
768 | */ |
||
769 | public function searchPoFileAutocomplete($name, $type, $lang, $searchString) { |
||
770 | $poFile = $this->toArray($name, $type, $lang); |
||
771 | $poFileData = $poFile['po_array']; |
||
772 | $searchString = mb_strtolower(trim($searchString)); |
||
773 | |||
774 | $results = []; |
||
775 | foreach ($poFileData as $origin => $data) { |
||
776 | $translation = $data['translation']; |
||
777 | |||
778 | $positionSearch = mb_stripos($origin, $searchString); |
||
779 | if ($positionSearch !== false) { |
||
780 | $results[$positionSearch][] = $origin; |
||
781 | } |
||
782 | |||
783 | $positionSearch = mb_stripos($translation, $searchString); |
||
784 | if ($positionSearch !== false) { |
||
785 | $results[$positionSearch][] = $translation; |
||
786 | } |
||
787 | |||
788 | } |
||
789 | ksort($results); |
||
790 | $resultsData = []; |
||
791 | foreach ($results as $result) { |
||
792 | natcasesort($result); |
||
793 | $resultsData = array_merge($resultsData, $result); |
||
794 | } |
||
795 | return $resultsData ?: []; |
||
796 | } |
||
797 | |||
798 | } |