diff --git a/src/commands/TranslateFilesCommand.php b/src/commands/TranslateFilesCommand.php deleted file mode 100644 index 19002e5..0000000 --- a/src/commands/TranslateFilesCommand.php +++ /dev/null @@ -1,376 +0,0 @@ -base_locale = $base_locale; - $this->locales = array_filter(explode(",", $locales)); - $this->target_files = array_filter(explode(",", $target_files)); - $this->force = $force; - $this->json = $json; - $this->verbose = $verbose; - $this->excluded_files = array_filter(explode(",", $excluded_files)); - } - - /** - * @throws \Exception - */ - public function handle() - { - //Collect input - $this->base_locale = $this->ask('What is base locale?',config('app.locale','en')); - $this->locales = array_filter(explode(",", $this->ask('What are the target locales? Comma seperate each lang key','tr,it'))); - $should_force = $this->choice('Force overwrite existing translations?',['No','Yes'],'No'); - $this->force = false; - if($should_force === 'Yes'){ - $this->force = true; - } - $mode = $this->choice('Use text exploration and json translation or php files?',['json','php'],'php'); - $this->json = false; - if($mode === 'json'){ - $this->json = true; - } - if(!$this->json){ - $this->target_files = array_filter(explode(",", $this->ask('Are there specific target files to translate only? ex: file1,file2',''))); - foreach ($this->target_files as $key=>$target_file){ - $this->target_files[$key] = $target_file.'.php'; - } - $this->excluded_files = array_filter(explode(",", $this->ask('Are there specific files to exclude?','auth,pagination,validation,passwords'))); - } - $should_verbose = $this->choice('Verbose each translation?',['No','Yes'],'Yes'); - $this->verbose = false; - if($should_verbose === 'Yes'){ - $this->verbose = true; - } - //Start Translating - $bar = $this->output->createProgressBar(count($this->locales)); - $bar->start(); - $this->line(""); - // loop target locales - if($this->json){ - $this->line("Exploring strings..."); - $stringKeys = $this->explore_strings(); - $this->line('Exploration completed. Let\'s get started'); - } - foreach ($this->locales as $locale) { - if ($locale == $this->base_locale) { - continue; - } - $this->line($this->base_locale . " -> " . $locale . " translating..."); - if($this->json){ - $this->translate_json_array_file($locale,$stringKeys); - } - else if ($locale !== 'vendor') { - if(!is_dir(resource_path('lang/' . $locale))){ - mkdir(resource_path('lang/' . $locale)); - } - $this->translate_php_array_files($locale); - } - $bar->advance(); - $this->line(""); - } - $bar->finish(); - $this->line(""); - $this->line("Translations Completed."); - } - - /** - * @param $base_locale - * @param $locale - * @param $text - * @return mixed|null|string - * @throws \ErrorException - * @throws \Exception - */ - public static function translate($base_locale, $locale, $text) - { - preg_match_all("/(^:|([\s|\:])\:)([a-zA-z])+/",$text,$matches); - $parameter_map = []; - $i = 1; - foreach($matches[0] as $match){ - $parameter_map ["x".$i]= $match; - $text = str_replace($match," x".$i,$text); - $i++; - } - if(config('laravel_google_translate.google_translate_api_key', false)){ - $translated = self::translate_via_api_key($base_locale, $locale, $text); - }else{ - $translated = self::translate_via_stichoza($base_locale, $locale, $text); - } - foreach ($parameter_map as $key=>$attribute){ - $combinations = [ - $key, - substr($key,0,1)." ".substr($key,1), - strtoupper(substr($key,0,1))." ".substr($key,1), - strtoupper(substr($key,0,1)).substr($key,1) - ]; - foreach ($combinations as $combination){ - $translated = str_replace($combination,$attribute,$translated,$count); - if($count > 0) - break; - } - } - $translated = str_replace(" :"," :",$translated); - return $translated; - } - - /** - * @param $base_locale - * @param $locale - * @param $text - * @return null|string - * @throws \ErrorException - */ - private static function translate_via_stichoza($base_locale, $locale, $text){ - $tr = new GoogleTranslate(); - $tr->setSource($base_locale); - $tr->setTarget($locale); - return $tr->translate($text); - } - - /** - * @param $base_locale - * @param $locale - * @param $text - * @return mixed - * @throws \Exception - */ - private static function translate_via_api_key($base_locale, $locale, $text){ - $apiKey = config('laravel_google_translate.google_translate_api_key', false); - $url = 'https://www.googleapis.com/language/translate/v2?key=' . $apiKey . '&q=' . rawurlencode($text) . '&source=' . substr($base_locale, 0, strpos($base_locale."_", "_")) . '&target=' . substr($locale, 0, strpos($locale."_", "_")); - $handle = curl_init(); - curl_setopt($handle, CURLOPT_URL, $url); - curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); - $response = curl_exec($handle); - if ($response === false) { - throw new \Exception(curl_error($handle), curl_errno($handle)); - } - $responseDecoded = json_decode($response, true); - curl_close($handle); - - if (isset($responseDecoded['error'])) { - /*$this->error("Google Translate API returned error"); - if (isset($responseDecoded["error"]["message"])) { - $this->error($responseDecoded["error"]["message"]); - }*/ - var_dump($responseDecoded); - exit; - } - - return $responseDecoded['data']['translations'][0]['translatedText']; - } - - /** - * @param $locale - * @throws \Exception - */ - public function translate_php_array_files($locale) - { - $files = preg_grep('/^([^.])/', scandir(resource_path('lang/' . $this->base_locale))); - - if (count($this->target_files) > 0) { - $files = $this->target_files; - } - foreach ($files as $file) { - $file = substr($file, 0, -4); - $already_translateds = []; - if (file_exists(resource_path('lang/' . $locale . '/' . $file . '.php'))) { - if($this->verbose) - $this->line('File already exists: lang/' . $locale . '/' . $file . '.php. Checking missing translations'); - $already_translateds = trans($file, [], $locale); - } - if (in_array($file, $this->excluded_files)) { - continue; - } - $to_be_translateds = trans($file, [], $this->base_locale); - $new_lang = []; - if(is_array($to_be_translateds)){ - foreach ($to_be_translateds as $key => $to_be_translated) { - if (isset($already_translateds[$key]) && $already_translateds[$key] != '' && !$this->force) { - $new_lang[$key] = $already_translateds[$key]; - if ($this->verbose) { - $this->line('Exists Skipping -> ' . $to_be_translated . ' : ' . $new_lang[$key]); - } - continue; - } - $new_lang[$key] = $this->translate_attribute($to_be_translated,$locale); - } - } - //save new lang to new file - if(!file_exists(resource_path('lang/' . $locale ))){ - mkdir(resource_path('lang/' . $locale )); - } - $file = fopen(resource_path('lang/' . $locale . '/' . $file . '.php'), "w+"); - $write_text = " $t){ - $return[$k] = $this->translate_attribute($t,$locale); - } - return $return; - }else{ - $translated = self::translate($this->base_locale, $locale, $attribute); - if ($this->verbose) { - $this->line($attribute . ' : ' . $translated); - } - return $translated; - } - } - - /** - * @return array - */ - public function explore_strings(){ - $groupKeys = []; - $stringKeys = []; - $functions = config('laravel_google_translate.trans_functions', [ - 'trans', - 'trans_choice', - 'Lang::get', - 'Lang::choice', - 'Lang::trans', - 'Lang::transChoice', - '@lang', - '@choice', - '__', - '\$trans.get', - '\$t' - ]); - $groupPattern = // See https://regex101.com/r/WEJqdL/6 - "[^\w|>]" . // Must not have an alphanum or _ or > before real method - '(' . implode( '|', $functions ) . ')' . // Must start with one of the functions - "\(" . // Match opening parenthesis - "[\'\"]" . // Match " or ' - '(' . // Start a new group to match: - '[a-zA-Z0-9_-]+' . // Must start with group - "([.](?! )[^\1)]+)+" . // Be followed by one or more items/keys - ')' . // Close group - "[\'\"]" . // Closing quote - "[\),]"; // Close parentheses or new parameter - $stringPattern = - "[^\w]" . // Must not have an alphanum before real method - '(' . implode( '|', $functions ) . ')' . // Must start with one of the functions - "\(" . // Match opening parenthesis - "(?P['\"])" . // Match " or ' and store in {quote} - "(?P(?:\\\k{quote}|(?!\k{quote}).)*)" . // Match any string that can be {quote} escaped - "\k{quote}" . // Match " or ' previously matched - "[\),]"; // Close parentheses or new parameter - $finder = new Finder(); - $finder->in( base_path() )->exclude( 'storage' )->exclude( 'vendor' )->name( '*.php' )->name( '*.twig' )->name( '*.vue' )->files(); - /** @var \Symfony\Component\Finder\SplFileInfo $file */ - foreach ( $finder as $file ) { - // Search the current file for the pattern - if ( preg_match_all( "/$groupPattern/siU", $file->getContents(), $matches ) ) { - // Get all matches - foreach ( $matches[ 2 ] as $key ) { - $groupKeys[] = $key; - } - } - if ( preg_match_all( "/$stringPattern/siU", $file->getContents(), $matches ) ) { - foreach ( $matches[ 'string' ] as $key ) { - if ( preg_match( "/(^[a-zA-Z0-9_-]+([.][^\1)\ ]+)+$)/siU", $key, $groupMatches ) ) { - // group{.group}.key format, already in $groupKeys but also matched here - // do nothing, it has to be treated as a group - continue; - } - //TODO: This can probably be done in the regex, but I couldn't do it. - //skip keys which contain namespacing characters, unless they also contain a - //space, which makes it JSON. - if ( !( mb_strpos( $key, '::' ) !== FALSE && mb_strpos( $key, '.' ) !== FALSE ) - || mb_strpos( $key, ' ' ) !== FALSE ) { - $stringKeys[] = $key; - if($this->verbose){ - $this->line('Found : '.$key); - } - } - } - } - } - // Remove duplicates - $groupKeys = array_unique( $groupKeys ); // todo: not supporting group keys for now add this feature! - $stringKeys = array_unique( $stringKeys ); - return $stringKeys; - } - - /** - * @param $locale - * @param $stringKeys - * @throws \ErrorException - * @throws \Exception - */ - public function translate_json_array_file($locale,$stringKeys) - { - $new_lang = []; - $json_existing_translations = []; - if(file_exists(resource_path('lang/' . $locale . '.json'))){ - $json_translations_string = file_get_contents(resource_path('lang/' . $locale . '.json')); - $json_existing_translations = json_decode($json_translations_string, true); - } - foreach ($stringKeys as $to_be_translated){ - //check existing translations - if(isset($json_existing_translations[$to_be_translated]) && - $json_existing_translations[$to_be_translated]!='' && - !$this->force) - { - $new_lang[$to_be_translated] = $json_existing_translations[$to_be_translated]; - if($this->verbose) - $this->line('Exists Skipping -> ' . $to_be_translated . ' : ' . $new_lang[$to_be_translated]); - continue; - } - $new_lang[$to_be_translated] = addslashes(self::translate($this->base_locale, $locale, $to_be_translated)); - if ($this->verbose) { - $this->line($to_be_translated . ' : ' . $new_lang[$to_be_translated]); - } - } - $file = fopen(resource_path('lang/' . $locale . '.json'), "w+"); - $write_text = json_encode($new_lang, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); - fwrite($file, $write_text); - fclose($file); - } -}