Erykai /
translate
| 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
Loading history...
|
|||||||||
| 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
Loading history...
|
|||||||||
| 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
Loading history...
|
|||||||||
| 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
Loading history...
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
Loading history...
|
|||||||||
| 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
Loading history...
|
|||||||||
| 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
Loading history...
|
|||||||||
| 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
Loading history...
|
|||||||||
| 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
Loading history...
|
|||||||||
| 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
Loading history...
|
|||||||||
| 188 | } |
||||||||
| 189 | return trim($this->replacePlaceholders($text, $this->getDynamic())); |
||||||||
| 190 | } |
||||||||
| 191 | |||||||||
| 192 | } |