PoFileManager   F
last analyzed

Complexity

Total Complexity 166

Size/Duplication

Total Lines 794
Duplicated Lines 9.07 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 72
loc 794
rs 1.806
c 0
b 0
f 0
wmc 166
lcom 1
cbo 3

22 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A setError() 0 5 2
A getErrors() 0 3 1
A setSaasUrl() 0 7 2
B exchangeTranslation() 5 29 7
B prepareDomain() 19 39 10
A getDomainType() 0 11 3
A getPoFileUrl() 0 20 5
F prepareSettingsArray() 15 45 19
A makePoFileSettings() 0 36 5
B create() 0 23 7
A getModules() 0 16 5
B saas_update_one() 0 24 6
B update() 0 37 11
F prepareUpdateSettings() 3 81 22
A save() 0 33 5
B preparePoFileData() 0 18 9
B makePoFileData() 0 33 9
A convertToMO() 0 9 2
C toArray() 14 69 17
C prepareSettingsValues() 16 42 12
B searchPoFileAutocomplete() 0 28 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like PoFileManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PoFileManager, and based on these observations, apply Extract Interface, too.

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
0 ignored issues
show
Documentation introduced by
Should the return type not be array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
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
        ksort($data, SORT_STRING | SORT_FLAG_CASE);
530
531
        $url = $this->getPoFileUrl($name, $type, $lang);
532
533
        if (!$url) {
534
            $this->setError(lang('Wrong po-file path', 'translator'));
535
            return FALSE;
536
        }
537
538
        if (!FileOperator::getInstatce()->checkFile($url)) {
539
            $errors = FileOperator::getInstatce()->getErrors();
540
            $this->setError($errors['error']);
541
            return FALSE;
542
        }
543
544
        $settings = $this->makePoFileSettings((array) $data['settings']);
545
        unset($data['settings']);
546
547
        $po_file_data = $this->makePoFileData($data);
548
        $po_file_content = b"\xEF\xBB\xBF" . $settings . "\n\n" . $po_file_data;
549
        if (file_put_contents($url, $po_file_content)) {
550
            if ($this->convertToMO($url)) {
551
                return TRUE;
552
            } else {
553
                $this->setError(lang('Operation failed. Can not convert to mo-file.', 'translator'));
554
                return FALSE;
555
            }
556
        } else {
557
            $this->setError(lang('Can not save po-file.', 'translator'));
558
            return FALSE;
559
        }
560
    }
561
562
    /**
563
     * Prepare correct po-file data
564
     * @param array $data
565
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
566
     */
567
    private function preparePoFileData($data) {
568
        if (!isset($data['comment']) || !$data['comment']) {
569
            $data['comment'] = '';
570
        }
571
572
        if (!isset($data['links']) || !$data['links']) {
573
            $data['links'] = '';
574
        }
575
576
        if (!isset($data['fuzzy']) || !$data['fuzzy']) {
577
            $data['fuzzy'] = '';
578
        }
579
580
        if (!isset($data['translation']) || !$data['translation']) {
581
            $data['translation'] = '';
582
        }
583
        return $data;
584
    }
585
586
    /**
587
     * Make po-file data
588
     * @param array $data - po-file data
589
     * @return string
590
     */
591
    private function makePoFileData($data = []) {
592
        $resultData = [];
593
        foreach ($data as $key => $po) {
594
            if ($po) {
595
                $po = $this->preparePoFileData((array) $po);
596
597
                if ($po['comment']) {
598
                    $resultData[] = '# ' . $po['comment'];
599
                }
600
601
                if ($po['links']) {
602
                    foreach ($po['links'] as $link) {
603
                        $resultData[] = '#: ' . $link;
604
                    }
605
                }
606
607
                if ($po['fuzzy']) {
608
                    $resultData[] = '#, fuzzy';
609
                }
610
611
                if ($key) {
612
                    $resultData[] = 'msgid "' . $key . '"';
613
                }
614
615
                if ($po['translation']) {
616
                    $resultData[] = 'msgstr "' . $po['translation'] . '"' . "\n";
617
                } else {
618
                    $resultData[] = 'msgstr ""' . "\n";
619
                }
620
            }
621
        }
622
        return implode("\n", $resultData);
623
    }
624
625
    /**
626
     * Convert po-file to mo-file
627
     * @param string $url - url to file
628
     * @return boolean|null
629
     */
630
    public function convertToMO($url = '') {
631
        if ($url) {
632
            $translations = Translations::fromPoFile($url);
633
634
            array_map('unlink', glob(str_replace('.po', '_*.mo', $url)));
635
636
            return $translations->toMoFile(str_replace('.po', '_' . time() . '.mo', $url));
637
        }
638
    }
639
640
    /**
641
     * @param string $name
642
     * @param string $type
643
     * @param string $lang
644
     * @param bool $langOn
645
     * @return array|bool
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|array<string,array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
646
     */
647
    public function toArray($name, $type, $lang, $langOn = TRUE) {
648
        $path = $this->getPoFileUrl($name, $type, $lang);
649
650
        if (!FileOperator::getInstatce()->checkFile($path, $langOn)) {
651
            $error = FileOperator::getInstatce()->getErrors();
652
            $this->setError($error['error']);
653
            return FALSE;
654
        } else {
655
            $po = file($path);
656
        }
657
658
        $origin = null;
659
        $this->po_settings = [];
660
661
        foreach ($po as $key => $line) {
662
            if (!($key > 2 && $origin)) {
663
                $this->prepareSettingsValues($line);
664
            }
665
666
            $first2symbols = substr($line, 0, 2);
667
            if (substr($line, 0, 1) == '#' && $first2symbols != '#:' && $first2symbols != '#,') {
668
                $comment = trim(substr($line, 2, -1));
669
                continue;
670
            }
671
            if ($first2symbols == '#,') {
672
                $fuzzy = TRUE;
673
                continue;
674
            }
675
676 View Code Duplication
            if ($first2symbols == '#:') {
677
                $links[] = trim(substr($line, 2, -1));
0 ignored issues
show
Coding Style Comprehensibility introduced by
$links was never initialized. Although not strictly required by PHP, it is generally a good practice to add $links = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
678
                continue;
679
            }
680
681 View Code Duplication
            if (substr($line, 0, 5) == 'msgid') {
682
                if (preg_match('/"(.*?)"$/', trim($line), $matches)) {
683
                    $origin = $matches[1];
684
                    if (!strlen($origin)) {
685
                        $origin = 0;
686
                    }
687
                }
688
689
                continue;
690
            }
691
692
            if (substr($line, 0, 6) == 'msgstr') {
693
                if ($origin) {
694
                    preg_match('/"(.*?)"$/', trim($line), $translation);
695
                    $translations[$origin] = [
0 ignored issues
show
Coding Style Comprehensibility introduced by
$translations was never initialized. Although not strictly required by PHP, it is generally a good practice to add $translations = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
696
                                              'translation' => isset($translation[1]) ? $translation[1] : '',
697
                                              'comment'     => $comment,
698
                                              'links'       => $links,
699
                                              'fuzzy'       => $fuzzy,
700
                                             ];
701
                }
702
                $fuzzy = FALSE;
703
                $comment = '';
704
                unset($links);
705
            }
706
        }
707
708
        $translations = $translations ?: [];
709
        $result = [
710
                   'settings' => $this->po_settings,
711
                   'po_array' => $translations,
712
                  ];
713
714
        return $result;
715
    }
716
717
    /**
718
     * @param string $line
719
     * @return array
720
     */
721
    private function prepareSettingsValues($line) {
722
        foreach ($this->po_settings_keys as $key) {
723
            if (preg_match('/' . $key . '/', $line)) {
724
                $from = strpos($line, ':');
725
726
                if (substr($line, -5, -4) == '\\') {
727
                    $value = substr($line, $from + 2, -5);
728
                } else {
729
                    $value = substr($line, $from + 2, -4);
730
                }
731
732
                switch ($key) {
733
                    case 'SearchPath':
734
                        $this->po_settings['SearchPath'][] = $value;
735
                        break 2;
736 View Code Duplication
                    case 'Last-Translator':
737
                        $value = explode(' ', $value);
738
                        $this->po_settings['Last-Translator-Name'] = isset($value[0]) ? $value[0] : '';
739
                        $value[1] = isset($value[1]) ? $value[1] : '';
740
                        $value[1] = str_replace('<', '', $value[1]);
741
                        $value[1] = str_replace('>', '', $value[1]);
742
                        $this->po_settings['Last-Translator-Email'] = $value[1];
743
                        break 2;
744 View Code Duplication
                    case 'Language-Team':
745
                        $value = explode(' ', $value);
746
                        $this->po_settings['Language-Team-Name'] = isset($value[0]) ? $value[0] : '';
747
                        $value[1] = isset($value[1]) ? $value[1] : '';
748
                        $value[1] = str_replace('<', '', $value[1]);
749
                        $value[1] = str_replace('>', '', $value[1]);
750
                        $this->po_settings['Language-Team-Email'] = $value[1];
751
                        break 2;
752
                    case 'Basepath':
753
                        $this->po_settings['Basepath'] = $value;
754
                        break 2;
755
                    default :
756
                        $this->po_settings[$key] = $value;
757
                        break 2;
758
                }
759
            }
760
        }
761
        return $this->po_settings;
762
    }
763
764
    /**
765
     * @param string $name
766
     * @param string $type
767
     * @param string $lang
768
     * @param string $searchString
769
     * @return array
770
     */
771
    public function searchPoFileAutocomplete($name, $type, $lang, $searchString) {
772
        $poFile = $this->toArray($name, $type, $lang);
773
        $poFileData = $poFile['po_array'];
774
        $searchString = mb_strtolower(trim($searchString));
775
776
        $results = [];
777
        foreach ($poFileData as $origin => $data) {
778
            $translation = $data['translation'];
779
780
            $positionSearch = mb_stripos($origin, $searchString);
781
            if ($positionSearch !== false) {
782
                $results[$positionSearch][] = $origin;
783
            }
784
785
            $positionSearch = mb_stripos($translation, $searchString);
786
            if ($positionSearch !== false) {
787
                $results[$positionSearch][] = $translation;
788
            }
789
790
        }
791
        ksort($results);
792
        $resultsData = [];
793
        foreach ($results as $result) {
794
            natcasesort($result);
795
            $resultsData = array_merge($resultsData, $result);
796
        }
797
        return $resultsData ?: [];
798
    }
799
800
}