Passed
Push — main ( f60044...6eca2e )
by Alex
11:23
created

TraitTranslate::array()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 25
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
c 0
b 0
f 0
dl 0
loc 25
rs 9.3222
cc 5
nc 16
nop 1
1
<?php
2
3
namespace Erykai\Translate;
4
5
use JsonSchema\Exception\RuntimeException;
0 ignored issues
show
Bug introduced by
The type JsonSchema\Exception\RuntimeException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
7
/**
8
 * TraitTranslate
9
 */
10
trait TraitTranslate
11
{
12
    /**
13
     * @param string $dir
14
     * create dir
15
     */
16
    private function create(string $dir): void
17
    {
18
        if (!is_dir($dir) && !mkdir($dir, 0755, true) && !is_dir($dir)) {
19
            throw new RuntimeException(sprintf('Directory "%s" was not created', $dir));
20
        }
21
    }
22
23
    /**
24
     * create dir defaults
25
     */
26
    protected function dir($module): void
27
    {
28
        $this->create($this->getPath());
0 ignored issues
show
Bug introduced by
It seems like getPath() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

28
        $this->create($this->/** @scrutinizer ignore-call */ getPath());
Loading history...
29
        $this->create("{$this->getPath()}/{$this->getSource()}");
0 ignored issues
show
Bug introduced by
It seems like getSource() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

29
        $this->create("{$this->getPath()}/{$this->/** @scrutinizer ignore-call */ getSource()}");
Loading history...
30
        if ($module) {
31
            $this->create("{$this->getPath()}/{$this->getSource()}/public");
32
        }
33
34
        $this->create("{$this->getPath()}/{$this->getTarget()}");
0 ignored issues
show
Bug introduced by
It seems like getTarget() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

34
        $this->create("{$this->getPath()}/{$this->/** @scrutinizer ignore-call */ getTarget()}");
Loading history...
35
        if ($module) {
36
            $this->create("{$this->getPath()}/{$this->getTarget()}/public");
37
        }
38
    }
39
40
    /**
41
     * create files
42
     */
43
    protected function file(string $module = null, ?string $keyArray = null): void
44
    {
45
        if ($module) {
46
            $modulePath = dirname(__DIR__, 4) . "/modules/{$module}/translate";
47
            $this->create("{$modulePath}/{$this->getSource()}");
48
            $this->create("{$modulePath}/{$this->getSource()}/public");
49
            $this->create("{$modulePath}/{$this->getTarget()}");
50
            $this->create("{$modulePath}/{$this->getTarget()}/public");
51
            $this->setSourceFile("{$modulePath}/{$this->getSource()}/{$this->getData()->file}." . TRANSLATE_EXT);
0 ignored issues
show
Bug introduced by
It seems like getData() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

51
            $this->setSourceFile("{$modulePath}/{$this->getSource()}/{$this->/** @scrutinizer ignore-call */ getData()->file}." . TRANSLATE_EXT);
Loading history...
Bug introduced by
It seems like setSourceFile() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

51
            $this->/** @scrutinizer ignore-call */ 
52
                   setSourceFile("{$modulePath}/{$this->getSource()}/{$this->getData()->file}." . TRANSLATE_EXT);
Loading history...
52
            $this->setTargetFile("{$modulePath}/{$this->getTarget()}/{$this->getData()->file}." . TRANSLATE_EXT);
0 ignored issues
show
Bug introduced by
It seems like setTargetFile() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

52
            $this->/** @scrutinizer ignore-call */ 
53
                   setTargetFile("{$modulePath}/{$this->getTarget()}/{$this->getData()->file}." . TRANSLATE_EXT);
Loading history...
53
        } else {
54
            $this->setSourceFile("{$this->getPath()}/{$this->getSource()}/{$this->getData()->file}." . TRANSLATE_EXT);
55
            $this->setTargetFile("{$this->getPath()}/{$this->getTarget()}/{$this->getData()->file}." . TRANSLATE_EXT);
56
        }
57
        if ($keyArray) {
58
            $this->array($keyArray);
59
        } else {
60
            $this->line();
61
        }
62
63
    }
64
65
    /**
66
     * @return void
67
     */
68
    protected function line(): void
69
    {
70
        if (!is_file($this->getSourceFile())) {
0 ignored issues
show
Bug introduced by
It seems like getSourceFile() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

70
        if (!is_file($this->/** @scrutinizer ignore-call */ getSourceFile())) {
Loading history...
71
            file_put_contents($this->getSourceFile(), $this->getData()->text . PHP_EOL);
72
        } else if (!in_array($this->getData()->text . PHP_EOL, array_filter(file($this->getSourceFile())), true)) {
73
            file_put_contents($this->getSourceFile(), $this->getData()->text . PHP_EOL, FILE_APPEND);
74
        }
75
76
        if (!is_file($this->getTargetFile())) {
0 ignored issues
show
Bug introduced by
It seems like getTargetFile() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

76
        if (!is_file($this->/** @scrutinizer ignore-call */ getTargetFile())) {
Loading history...
77
            file_put_contents($this->getTargetFile(), $this->translate(file_get_contents($this->getSourceFile())) . PHP_EOL);
78
        } else {
79
            $source = array_filter(file($this->getSourceFile()));
80
            $target = array_filter(file($this->getTargetFile()));
81
            $result = array_diff_key($source, $target);
82
            $implode = implode("", $result);
83
            if (count(array_filter(file($this->getSourceFile()))) > count(array_filter(file($this->getTargetFile())))) {
84
                file_put_contents($this->getTargetFile(), $this->translate($implode) . PHP_EOL, FILE_APPEND);
85
            }
86
87
        }
88
    }
89
90
    /**
91
     * @param string $keyArray
92
     * @return void
93
     */
94
    protected function array(string $keyArray): void
95
    {
96
        $text = $this->getData()->text;
97
        $sourceFile = $this->getSourceFile();
98
99
        $contentSource = [];
100
        if (is_file($sourceFile)) {
101
            $contentSource = include $sourceFile;
102
        }
103
        if (!preg_match("/'$keyArray'\s*=>/", var_export($contentSource, true))) {
104
            $this->insertNestedArrayValue($contentSource, $keyArray, $text);
105
            $sourceContent = "<?php\n\nreturn " . $this->formatArraySyntax(var_export($contentSource, true)) . ";\n";
106
            file_put_contents($sourceFile, $sourceContent);
107
        }
108
109
        $targetFile = $this->getTargetFile();
110
        $contentTarget = [];
111
        if (is_file($targetFile)) {
112
            $contentTarget = include $targetFile;
113
        }
114
        if (!preg_match("/'$keyArray'\s*=>/", var_export($contentTarget, true))) {
115
            $translatedText = $this->translate($text);
116
            $this->insertNestedArrayValue($contentTarget, $keyArray, $translatedText);
117
            $targetContent = "<?php\n\nreturn " . $this->formatArraySyntax(var_export($contentTarget, true)) . ";\n";
118
            file_put_contents($targetFile, $targetContent);
119
        }
120
    }
121
122
    /**
123
     * @param $array
124
     * @param $path
125
     * @param $value
126
     * @return void
127
     */
128
    private function insertNestedArrayValue(&$array, $path, $value): void
129
    {
130
        $keys = explode('.', $path);
131
        while (count($keys) > 1) {
132
            $key = array_shift($keys);
133
            if (!isset($array[$key]) || !is_array($array[$key])) {
134
                $array[$key] = [];
135
            }
136
            $array = &$array[$key];
137
        }
138
        $array[array_shift($keys)] = $value;
139
    }
140
141
    /**
142
     * @param $content
143
     * @return array|string
144
     */
145
    private function formatArraySyntax($content): array|string
146
    {
147
        return str_replace(['array (', ')'], ['[', ']'], $content);
148
    }
149
150
    /**
151
     * @param string $text
152
     * @return mixed
153
     * send server translate
154
     */
155
    private function translate(string $text): mixed
156
    {
157
        $url = TRANSLATE_API_URL;
158
        $ch = curl_init($url);
159
        curl_setopt_array($ch, [
160
            CURLOPT_FOLLOWLOCATION => 1,
161
            CURLOPT_RETURNTRANSFER => 1,
162
            CURLOPT_POSTFIELDS => http_build_query([
163
                "key" => TRANSLATE_API_KEY,
164
                "source" => "en",
165
                "target" => $this->getTarget(),
166
                "text" => $text,
167
                "route" => $this->getData()->file
168
            ])
169
        ]);
170
        $response = curl_exec($ch);
171
        curl_close($ch);
172
        if (!$response) {
173
            return $text;
174
        }
175
        $data = json_decode($response);
0 ignored issues
show
Bug introduced by
It seems like $response can also be of type true; however, parameter $json of json_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

175
        $data = json_decode(/** @scrutinizer ignore-type */ $response);
Loading history...
176
        if ($data->status === "success") {
177
            return $data->translate;
178
        }
179
        return $text;
180
    }
181
182
}