Translate   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 46
c 1
b 0
f 0
dl 0
loc 139
rs 10
wmc 28

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 2
A translate() 0 10 4
A getAvailableLangs() 0 8 2
A getLocaleText() 0 16 5
A append() 0 17 3
A load() 0 8 2
B get() 0 19 10
1
<?php
2
3
namespace Ffcms\Core\I18n;
4
5
use Ffcms\Core\App;
6
use Ffcms\Core\Helper\FileSystem\Directory;
7
use Ffcms\Core\Helper\FileSystem\File;
8
use Ffcms\Core\Helper\FileSystem\Normalize;
9
use Ffcms\Core\Helper\Serialize;
10
use Ffcms\Core\Helper\Type\Any;
11
use Ffcms\Core\Helper\Type\Arr;
12
use Ffcms\Core\Helper\Type\Obj;
13
use Ffcms\Core\Helper\Type\Str;
14
15
/**
16
 * Class Translate. Provide methods to work with internalization data in ffcms.
17
 * @package Ffcms\Core\I18n
18
 */
19
class Translate
20
{
21
    protected $cached = [];
22
    protected $indexes = [];
23
24
    /**
25
     * Translate constructor. Load default translations.
26
     */
27
    public function __construct()
28
    {
29
        if (App::$Request->getLanguage() !== App::$Properties->get('baseLanguage')) {
30
            $this->cached = $this->load('Default');
31
            $this->indexes[] = 'Default';
32
        }
33
    }
34
35
36
    /**
37
     * Get internalization of current text from i18n
38
     * @param string $index
39
     * @param string $text
40
     * @param array|null $params
41
     * @return string
42
     */
43
    public function get(?string $index, string $text, ?array $params = null)
44
    {
45
        if (App::$Request->getLanguage() !== App::$Properties->get('baseLanguage')) {
46
            if ($index && !Arr::in($index, $this->indexes)) {
47
                $this->cached = Arr::merge($this->cached, $this->load($index));
48
                $this->indexes[] = $index;
49
            }
50
51
            if ($this->cached && Any::isStr($text) && isset($this->cached[$text])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->cached of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
52
                $text = $this->cached[$text];
53
            }
54
        }
55
56
        if (Any::isArray($params) && count($params) > 0) {
57
            foreach ($params as $var => $value) {
58
                $text = Str::replace('%' . $var . '%', $value, $text);
59
            }
60
        }
61
        return $text;
62
    }
63
64
    /**
65
     * Get internalization based on called controller
66
     * @param string $text
67
     * @param array $params
68
     * @return string
69
     */
70
    public function translate(string $text, array $params = null)
71
    {
72
        $index = null;
73
        $namespace = 'Apps\Controller\\' . env_name . '\\';
0 ignored issues
show
Bug introduced by
The constant Ffcms\Core\I18n\env_name was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
74
        foreach (@debug_backtrace() as $caller) {
75
            if (isset($caller['class']) && Str::startsWith($namespace, $caller['class'])) {
76
                $index = Str::sub((string)$caller['class'], Str::length($namespace));
77
            }
78
        }
79
        return $this->get($index, $text, $params);
80
    }
81
82
    /**
83
     * Load locale file from local storage
84
     * @param string $index
85
     * @return array|null
86
     */
87
    protected function load(string $index): ?array
88
    {
89
        $file = root . '/I18n/' . env_name . '/' . App::$Request->getLanguage() . '/' . $index . '.php';
0 ignored issues
show
Bug introduced by
The constant Ffcms\Core\I18n\env_name was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant Ffcms\Core\I18n\root was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
90
        if (!File::exist($file)) {
91
            return [];
92
        }
93
94
        return require($file);
95
    }
96
97
    /**
98
     * Append translation data from exist full path
99
     * @param string $path
100
     * @return bool
101
     */
102
    public function append($path): bool
103
    {
104
        $path = Normalize::diskFullPath($path);
105
        // check if file exist
106
        if (!File::exist($path)) {
107
            return false;
108
        }
109
110
        // load file translations
111
        $addTranslation = require($path);
112
        if (!Any::isArray($addTranslation)) {
113
            return false;
114
        }
115
116
        // merge data
117
        $this->cached = Arr::merge($this->cached, $addTranslation);
118
        return true;
119
    }
120
121
    /**
122
     * Get available languages in the filesystem
123
     * @return array
124
     */
125
    public function getAvailableLangs(): array
126
    {
127
        $langs = ['en'];
128
        $scan = Directory::scan(root . '/I18n/' . env_name . '/', GLOB_ONLYDIR, true);
0 ignored issues
show
Bug introduced by
The constant Ffcms\Core\I18n\env_name was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant Ffcms\Core\I18n\root was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
129
        foreach ($scan as $row) {
130
            $langs[] = trim($row, '/');
131
        }
132
        return $langs;
133
    }
134
135
    /**
136
     * Get locale data from input array or serialized string
137
     * @param array|string $input
138
     * @param string|null $lang
139
     * @param string|null $default
140
     * @return string|null
141
     */
142
    public function getLocaleText($input, ?string $lang = null, ?string $default = null): ?string
143
    {
144
        // define language if empty
145
        if ($lang === null) {
146
            $lang = App::$Request->getLanguage();
147
        }
148
        // unserialize from string to array
149
        if (Any::isStr($input)) {
150
            $input = Serialize::decode($input);
0 ignored issues
show
Bug introduced by
It seems like $input can also be of type array; however, parameter $data of Ffcms\Core\Helper\Serialize::decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

150
            $input = Serialize::decode(/** @scrutinizer ignore-type */ $input);
Loading history...
151
        }
152
153
        if (Any::isArray($input) && array_key_exists($lang, $input)) {
0 ignored issues
show
Bug introduced by
It seems like $input can also be of type false and string; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

153
        if (Any::isArray($input) && array_key_exists($lang, /** @scrutinizer ignore-type */ $input)) {
Loading history...
154
            return $input[$lang];
155
        }
156
157
        return $default;
158
    }
159
}
160