1 | <?php |
||||||||
2 | |||||||||
3 | namespace Erykai\Translate; |
||||||||
4 | |||||||||
5 | /** |
||||||||
6 | * |
||||||||
7 | */ |
||||||||
8 | trait TraitTranslate |
||||||||
9 | { |
||||||||
10 | /** |
||||||||
11 | * @param string $dir |
||||||||
12 | * create dir |
||||||||
13 | */ |
||||||||
14 | private function create(string $dir): void |
||||||||
15 | { |
||||||||
16 | if (!is_dir($dir) && !mkdir($dir, 0755, true) && !is_dir($dir)) { |
||||||||
17 | throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir)); |
||||||||
18 | } |
||||||||
19 | } |
||||||||
20 | |||||||||
21 | /** |
||||||||
22 | * create dir defaults |
||||||||
23 | */ |
||||||||
24 | protected function dir($module): void |
||||||||
25 | { |
||||||||
26 | $this->create($this->getPath()); |
||||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||||
27 | $this->create("{$this->getPath()}/{$this->getSource()}"); |
||||||||
0 ignored issues
–
show
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
![]() |
|||||||||
28 | if ($module) { |
||||||||
29 | $this->create("{$this->getPath()}/{$this->getSource()}/public"); |
||||||||
30 | } |
||||||||
31 | |||||||||
32 | $this->create("{$this->getPath()}/{$this->getTarget()}"); |
||||||||
0 ignored issues
–
show
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
![]() |
|||||||||
33 | if ($module) { |
||||||||
34 | $this->create("{$this->getPath()}/{$this->getTarget()}/public"); |
||||||||
35 | } |
||||||||
36 | } |
||||||||
37 | |||||||||
38 | /** |
||||||||
39 | * create files .translate |
||||||||
40 | */ |
||||||||
41 | protected function file(string $module = null, ?string $keyArray = null): void |
||||||||
42 | { |
||||||||
43 | if ($module) { |
||||||||
44 | $modulePath = dirname(__DIR__, 4) . "/modules/{$module}/translate"; |
||||||||
45 | $this->create("{$modulePath}/{$this->getSource()}"); |
||||||||
46 | $this->create("{$modulePath}/{$this->getSource()}/public"); |
||||||||
47 | $this->create("{$modulePath}/{$this->getTarget()}"); |
||||||||
48 | $this->create("{$modulePath}/{$this->getTarget()}/public"); |
||||||||
49 | $this->setSourceFile("{$modulePath}/{$this->getSource()}/{$this->getData()->file}." . TRANSLATE_EXT); |
||||||||
0 ignored issues
–
show
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
![]() 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
![]() |
|||||||||
50 | $this->setTargetFile("{$modulePath}/{$this->getTarget()}/{$this->getData()->file}." . TRANSLATE_EXT); |
||||||||
0 ignored issues
–
show
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
![]() |
|||||||||
51 | } else { |
||||||||
52 | $this->setSourceFile("{$this->getPath()}/{$this->getSource()}/{$this->getData()->file}." . TRANSLATE_EXT); |
||||||||
53 | $this->setTargetFile("{$this->getPath()}/{$this->getTarget()}/{$this->getData()->file}." . TRANSLATE_EXT); |
||||||||
54 | } |
||||||||
55 | if ($keyArray) { |
||||||||
56 | $this->array($keyArray); |
||||||||
57 | } else { |
||||||||
58 | $this->line(); |
||||||||
59 | } |
||||||||
60 | |||||||||
61 | } |
||||||||
62 | |||||||||
63 | /** |
||||||||
64 | * @return void |
||||||||
65 | */ |
||||||||
66 | protected function line(): void |
||||||||
67 | { |
||||||||
68 | if (!is_file($this->getSourceFile())) { |
||||||||
0 ignored issues
–
show
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
![]() |
|||||||||
69 | file_put_contents($this->getSourceFile(), $this->getData()->text . PHP_EOL); |
||||||||
70 | } else if (!in_array($this->getData()->text . PHP_EOL, array_filter(file($this->getSourceFile())), true)) { |
||||||||
71 | file_put_contents($this->getSourceFile(), $this->getData()->text . PHP_EOL, FILE_APPEND); |
||||||||
72 | } |
||||||||
73 | |||||||||
74 | if (!is_file($this->getTargetFile())) { |
||||||||
0 ignored issues
–
show
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
![]() |
|||||||||
75 | file_put_contents($this->getTargetFile(), $this->translate(file_get_contents($this->getSourceFile())) . PHP_EOL); |
||||||||
76 | } else { |
||||||||
77 | $source = array_filter(file($this->getSourceFile())); |
||||||||
78 | $target = array_filter(file($this->getTargetFile())); |
||||||||
79 | $result = array_diff_key($source, $target); |
||||||||
80 | $implode = implode("", $result); |
||||||||
81 | if (count(array_filter(file($this->getSourceFile()))) > count(array_filter(file($this->getTargetFile())))) { |
||||||||
82 | file_put_contents($this->getTargetFile(), $this->translate($implode) . PHP_EOL, FILE_APPEND); |
||||||||
83 | } |
||||||||
84 | |||||||||
85 | } |
||||||||
86 | } |
||||||||
87 | |||||||||
88 | /** |
||||||||
89 | * @param string $keyArray |
||||||||
90 | * @return void |
||||||||
91 | */ |
||||||||
92 | protected function array(string $keyArray): void |
||||||||
93 | { |
||||||||
94 | $text = $this->getData()->text; |
||||||||
95 | $sourceFile = $this->getSourceFile(); |
||||||||
96 | |||||||||
97 | $contentSource = []; |
||||||||
98 | if (is_file($sourceFile)) { |
||||||||
99 | $contentSource = include $sourceFile; |
||||||||
100 | } |
||||||||
101 | if (!preg_match("/'$keyArray'\s*=>/", var_export($contentSource, true))) { |
||||||||
102 | $this->insertNestedArrayValue($contentSource, $keyArray, $text); |
||||||||
103 | $sourceContent = "<?php\n\nreturn " . $this->formatArraySyntax(var_export($contentSource, true)) . ";\n"; |
||||||||
104 | file_put_contents($sourceFile, $sourceContent); |
||||||||
105 | } |
||||||||
106 | |||||||||
107 | $targetFile = $this->getTargetFile(); |
||||||||
108 | $contentTarget = []; |
||||||||
109 | if (is_file($targetFile)) { |
||||||||
110 | $contentTarget = include $targetFile; |
||||||||
111 | } |
||||||||
112 | if (!preg_match("/'$keyArray'\s*=>/", var_export($contentTarget, true))) { |
||||||||
113 | $translatedText = $this->translate($text); |
||||||||
114 | $this->insertNestedArrayValue($contentTarget, $keyArray, $translatedText); |
||||||||
115 | $targetContent = "<?php\n\nreturn " . $this->formatArraySyntax(var_export($contentTarget, true)) . ";\n"; |
||||||||
116 | file_put_contents($targetFile, $targetContent); |
||||||||
117 | } |
||||||||
118 | } |
||||||||
119 | |||||||||
120 | /** |
||||||||
121 | * @param $array |
||||||||
122 | * @param $path |
||||||||
123 | * @param $value |
||||||||
124 | * @return void |
||||||||
125 | */ |
||||||||
126 | private function insertNestedArrayValue(&$array, $path, $value): void |
||||||||
127 | { |
||||||||
128 | $keys = explode('.', $path); |
||||||||
129 | while (count($keys) > 1) { |
||||||||
130 | $key = array_shift($keys); |
||||||||
131 | if (!isset($array[$key]) || !is_array($array[$key])) { |
||||||||
132 | $array[$key] = []; |
||||||||
133 | } |
||||||||
134 | $array = &$array[$key]; |
||||||||
135 | } |
||||||||
136 | $array[array_shift($keys)] = $value; |
||||||||
137 | } |
||||||||
138 | |||||||||
139 | /** |
||||||||
140 | * @param $content |
||||||||
141 | * @return array|string |
||||||||
142 | */ |
||||||||
143 | private function formatArraySyntax($content): array|string |
||||||||
144 | { |
||||||||
145 | return str_replace(['array (', ')'], ['[', ']'], $content); |
||||||||
146 | } |
||||||||
147 | |||||||||
148 | private function replacePlaceholders($template, $values): string |
||||||||
149 | { |
||||||||
150 | if (!is_array($values)) { |
||||||||
151 | $values = [$values]; |
||||||||
152 | } |
||||||||
153 | |||||||||
154 | foreach ($values as $value) { |
||||||||
155 | $template = preg_replace('/<#>/', $value, $template, 1); |
||||||||
156 | } |
||||||||
157 | return $template; |
||||||||
158 | } |
||||||||
159 | |||||||||
160 | /** |
||||||||
161 | * @param string $text |
||||||||
162 | * @return mixed |
||||||||
163 | * send server translate |
||||||||
164 | */ |
||||||||
165 | private function translate(string $text): mixed |
||||||||
166 | { |
||||||||
167 | $url = TRANSLATE_API_URL; |
||||||||
168 | $ch = curl_init($url); |
||||||||
169 | curl_setopt_array($ch, [ |
||||||||
170 | CURLOPT_FOLLOWLOCATION => 1, |
||||||||
171 | CURLOPT_RETURNTRANSFER => 1, |
||||||||
172 | CURLOPT_POSTFIELDS => http_build_query([ |
||||||||
173 | "key" => TRANSLATE_API_KEY, |
||||||||
174 | "source" => "en", |
||||||||
175 | "target" => $this->getTarget(), |
||||||||
176 | "text" => $text, |
||||||||
177 | "route" => $this->getData()->file |
||||||||
178 | ]) |
||||||||
179 | ]); |
||||||||
180 | $response = curl_exec($ch); |
||||||||
181 | curl_close($ch); |
||||||||
182 | if (!$response) { |
||||||||
183 | return $text; |
||||||||
184 | } |
||||||||
185 | $data = json_decode($response); |
||||||||
0 ignored issues
–
show
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
![]() |
|||||||||
186 | if ($data->status === "success") { |
||||||||
187 | return trim($this->replacePlaceholders($data->translate, $this->getDynamic())); |
||||||||
0 ignored issues
–
show
It seems like
getDynamic() 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
![]() |
|||||||||
188 | } |
||||||||
189 | return trim($this->replacePlaceholders($text, $this->getDynamic())); |
||||||||
190 | } |
||||||||
191 | |||||||||
192 | } |