Completed
Push — master ( 71e984...d2ae2e )
by Mihail
03:24
created

Translate::lexer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Ffcms\Core\I18n;
4
5
use Ffcms\Core\App;
6
use Ffcms\Core\Helper\Type\Arr;
7
use Ffcms\Core\Helper\FileSystem\Directory;
8
use Ffcms\Core\Helper\FileSystem\File;
9
use Ffcms\Core\Helper\FileSystem\Normalize;
10
use Ffcms\Core\Helper\Type\Obj;
11
use Ffcms\Core\Helper\Type\Str;
12
13
/**
14
 * Class Translate. Provide methods to work with internalization data in ffcms.
15
 * @package Ffcms\Core\I18n
16
 */
17
class Translate
18
{
19
20
    protected $cached = [];
21
    protected $indexes = [];
22
23
    public function __construct()
24
    {
25
        if (App::$Request->getLanguage() !== App::$Properties->get('baseLanguage')) {
26
            $this->cached = $this->load('Default');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->load('Default') can be null. However, the property $cached is declared as array. Maybe change the type of the property to array|null or add a type check?

Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.

To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.

function aContainsB(array $needle = null, array  $haystack) {
    if (!$needle) {
        return false;
    }

    return array_intersect($haystack, $needle) == $haystack;
}

The function can be called with either null or an array for the parameter $needle but will only accept an array as $haystack.

Loading history...
27
            $this->indexes[] = 'Default';
28
        }
29
    }
30
31
32
    /**
33
     * Get internalization of current text from i18n
34
     * @param string $index
35
     * @param string $text
36
     * @param array|null $params
37
     * @return string
38
     */
39
    public function get($index, $text, array $params = null)
40
    {
41
        if (App::$Request->getLanguage() !== App::$Properties->get('baseLanguage')) {
42
            if ($index !== null && !Arr::in($index, $this->indexes)) {
43
                $this->cached = Arr::merge($this->cached, $this->load($index));
44
                $this->indexes[] = $index;
45
            }
46
47
            if ($this->cached !== null && Obj::isString($text) && isset($this->cached[$text])) {
48
                $text = $this->cached[$text];
49
            }
50
        }
51
52
        if (Obj::isArray($params) && count($params) > 0) {
53
            foreach ($params as $var => $value) {
0 ignored issues
show
Bug introduced by
The expression $params of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
54
                $text = Str::replace('%' . $var . '%', $value, $text);
55
            }
56
        }
57
        return $text;
58
    }
59
60
    /**
61
     * Get internalization based on called controller
62
     * @param string $text
63
     * @param array $params
64
     * @return string
65
     */
66
    public function translate($text, array $params = [])
67
    {
68
        $index = null;
69
        $namespace = 'Apps\\Controller\\' . env_name . '\\';
70
        foreach (debug_backtrace() as $caller) {
71
            if (isset($caller['class']) && Str::startsWith($namespace, $caller['class'])) {
72
                $index = Str::sub((string)$caller['class'], Str::length($namespace));
73
            }
74
        }
75
        return $this->get($index, $text, $params);
76
    }
77
78
    /**
79
     * Load locale file from local storage
80
     * @param string $index
81
     * @return array|null
82
     */
83
    protected function load($index)
84
    {
85
        $file = root . '/I18n/' . env_name . '/' . App::$Request->getLanguage() . '/' . $index . '.php';
86
        if (!File::exist($file)) {
87
            return [];
88
        }
89
        return require_once($file);
90
    }
91
92
    /**
93
     * Append translation data from exist full path
94
     * @param string $path
95
     * @return bool
96
     */
97
    public function append($path)
98
    {
99
        $path = Normalize::diskFullPath($path);
100
        // check if file exist
101
        if (!File::exist($path)) {
102
            return false;
103
        }
104
105
        // load file translations
106
        $addTranslation = require($path);
107
        if (!Obj::isArray($addTranslation)) {
108
            return false;
109
        }
110
111
        // merge data
112
        $this->cached = Arr::merge($this->cached, $addTranslation);
113
        return true;
114
    }
115
116
    /**
117
     * Get available languages in the filesystem
118
     * @return array
119
     */
120
    public function getAvailableLangs()
121
    {
122
        $langs = ['en'];
123
        $scan = Directory::scan(root . '/I18n/' . env_name . '/', GLOB_ONLYDIR, true);
124
        foreach ($scan as $row) {
0 ignored issues
show
Bug introduced by
The expression $scan of type false|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
125
            $langs[] = trim($row, '/');
126
        }
127
        return $langs;
128
    }
129
}