/** * Execute the console command. * * @return mixed */ public function fire() { $folders = $this->manager->getPath($this->folders); $this->display = !$this->option('silent'); $extension = $this->option('php-file-extension'); $obsolete_prefix = empty($this->obsolete_array_key) ? '' : $this->obsolete_array_key . '.'; ////////////////////////////////////////////////// // Display where translations are searched in // ////////////////////////////////////////////////// if ($this->option('verbose')) { $this->writeLine("Lemmas will be searched in the following directories:"); foreach ($folders as $path) { $this->writeLine(' <info>' . $path . '</info>'); } $this->writeLine(''); } //////////////////////////////// // Parse all lemmas from code // //////////////////////////////// $lemmas = $this->manager->extractTranslationsFromFolders($folders, $this->trans_methods, $extension); if (count($lemmas) === 0) { $this->writeComment("No lemma has been found in code."); $this->writeLine("I have searched recursively in PHP files in these directories:"); foreach ($this->manager->getPath($this->folders) as $path) { $this->writeLine(" " . $path); } $this->writeLine("for these functions/methods:"); foreach ($this->trans_methods as $k => $v) { $this->writeLine(" " . $k); } return self::SUCCESS; } $this->writeLine(count($lemmas) > 1 ? count($lemmas) . " lemmas have been found in code" : "1 lemma has been found in code"); if ($this->option('verbose')) { foreach ($lemmas as $key => $value) { if (strpos($key, '.') !== false) { $this->writeLine(' <info>' . $key . '</info> in file <comment>' . $this->manager->getShortPath($value) . '</comment>'); } } } ///////////////////////////////////////////// // Convert dot lemmas to structured lemmas // ///////////////////////////////////////////// if ($this->option('output-flat')) { $lemmas_structured = $this->manager->convertLemmaToFlatArray($lemmas); } else { $lemmas_structured = $this->manager->convertLemmaToStructuredArray($lemmas); } $this->writeLine(''); ///////////////////////////////////// // Generate lang files : // // - add missing lemmas on top // // - keep already defined lemmas // // - add obsolete lemmas on bottom // ///////////////////////////////////// try { $dir_lang = $this->manager->getLangPath($this->lang_folder_path); } catch (Exception $e) { switch ($e->getCode()) { //@codeCoverageIgnoreStart case Localization::NO_LANG_FOLDER_FOUND_IN_THESE_PATHS: $this->writeError("No lang folder found in these paths:"); foreach ($e->getParameter() as $path) { $this->writeError("- " . $path); } break; //@codeCoverageIgnoreEnd //@codeCoverageIgnoreEnd case Localization::NO_LANG_FOLDER_FOUND_IN_YOUR_CUSTOM_PATH: $this->writeError('No lang folder found in your custom path: "' . $e->getParameter() . '"'); break; } $this->writeLine(''); return self::ERROR; } $job = array(); $there_are_new = false; $this->writeLine('Scan files:'); foreach (scandir($dir_lang) as $lang) { if (Tools::isValidDirectory($dir_lang, $lang)) { foreach ($lemmas_structured as $family => $array) { if (in_array($family, $this->ignore_lang_files)) { if ($this->option('verbose')) { $this->writeLine(''); $this->writeInfo(" ! Skip lang file '{$family}' !"); } continue; } $file_lang_path = $dir_lang . DIRECTORY_SEPARATOR . $lang . DIRECTORY_SEPARATOR . $family . '.php'; if ($this->option('verbose')) { $this->writeLine(''); } $this->writeLine(' ' . $this->manager->getShortPath($file_lang_path)); if (!is_writable(dirname($file_lang_path))) { // @codeCoverageIgnoreStart $this->writeError(" > Unable to write file in directory " . dirname($file_lang_path)); return self::ERROR; // @codeCoverageIgnoreEnd } if (!file_exists($file_lang_path)) { // @codeCoverageIgnoreStart $this->writeInfo(" > File has been created"); // @codeCoverageIgnoreEnd } if (!touch($file_lang_path)) { // @codeCoverageIgnoreStart $this->writeError(" > Unable to touch file {$file_lang_path}"); return self::ERROR; // @codeCoverageIgnoreEnd } if (!is_readable($file_lang_path)) { // @codeCoverageIgnoreStart $this->writeError(" > Unable to read file {$file_lang_path}"); return self::ERROR; // @codeCoverageIgnoreEnd } if (!is_writable($file_lang_path)) { // @codeCoverageIgnoreStart $this->writeError(" > Unable to write in file {$file_lang_path}"); return self::ERROR; // @codeCoverageIgnoreEnd } /** @noinspection PhpIncludeInspection */ $a = (include $file_lang_path); $old_lemmas_with_obsolete = is_array($a) ? array_dot($a) : array(); $new_lemmas = array_dot($array); $final_lemmas = array(); $display_already_comment = false; $something_to_do = false; $i = 0; // Remove the obsolete prefix key $old_lemmas = array(); $obsolete_prefix_length = strlen($obsolete_prefix); foreach ($old_lemmas_with_obsolete as $key => $value) { if (starts_with($key, $obsolete_prefix)) { $key = substr($key, $obsolete_prefix_length); if (!isset($old_lemmas[$key])) { $old_lemmas[$key] = $value; } } else { $old_lemmas[$key] = $value; } } $obsolete_lemmas = array_diff_key($old_lemmas, $new_lemmas); $welcome_lemmas = array_diff_key($new_lemmas, $old_lemmas); $already_lemmas = array_intersect_key($old_lemmas, $new_lemmas); // disable check for obsolete lemma and consolidate with already_lemmas if ($this->option('disable-obsolete-check')) { $already_lemmas = array_unique($obsolete_lemmas + $already_lemmas); $obsolete_lemmas = array(); } ksort($obsolete_lemmas); ksort($welcome_lemmas); ksort($already_lemmas); ////////////////////////// // Deal with new lemmas // ////////////////////////// if (count($welcome_lemmas) > 0) { $display_already_comment = true; $something_to_do = true; $there_are_new = true; $final_lemmas["POTSKY___NEW___POTSKY"] = "POTSKY___NEW___POTSKY"; $this->writeInfo(' ' . ($c = count($welcome_lemmas)) . ' new string' . Tools::getPlural($c) . ' to translate'); foreach ($welcome_lemmas as $key => $value) { if ($this->option('verbose')) { $this->writeLine(" <info>" . $key . "</info> in " . $this->manager->getShortPath($value)); } if (!$this->option('no-comment')) { $final_lemmas['POTSKY___COMMENT___POTSKY' . $i] = "Defined in file {$value}"; $i = $i + 1; } $key_last_token = explode('.', $key); if ($this->option('translation')) { $translation = $this->manager->translate(end($key_last_token), $lang); } else { $translation = end($key_last_token); } if (strtolower($this->option('new-value')) === 'null') { $translation = null; } else { $translation = str_replace('%LEMMA', $translation, $this->option('new-value')); } array_set($final_lemmas, $key, $translation); } } /////////////////////////////// // Deal with existing lemmas // /////////////////////////////// if (count($already_lemmas) > 0) { if ($this->option('verbose')) { $this->writeLine(' ' . ($c = count($already_lemmas)) . ' already translated string' . Tools::getPlural($c)); } $final_lemmas["POTSKY___OLD___POTSKY"] = "POTSKY___OLD___POTSKY"; foreach ($already_lemmas as $key => $value) { array_set($final_lemmas, $key, $value); } } /////////////////////////////// // Deal with obsolete lemmas // /////////////////////////////// if (count($obsolete_lemmas) > 0) { $protected_already_included = false; // Remove all dynamic fields foreach ($obsolete_lemmas as $key => $value) { foreach ($this->never_obsolete_keys as $remove) { if (strpos($key, '.' . $remove . '.') !== false || starts_with($key, $remove . '.')) { if ($this->option('verbose')) { $this->writeLine(" <comment>" . $key . "</comment> is protected as a dynamic lemma"); } unset($obsolete_lemmas[$key]); if ($protected_already_included === false) { $final_lemmas["POTSKY___PROTECTED___POTSKY"] = "POTSKY___PROTECTED___POTSKY"; $protected_already_included = true; } // Given that this lemma is never obsolete, we need to send it back to the final lemma array array_set($final_lemmas, $key, $value); } } } } ///////////////////////////////////// // Fill the final lemmas array now // ///////////////////////////////////// if (count($obsolete_lemmas) > 0) { $display_already_comment = true; $something_to_do = true; if ($this->option('no-obsolete')) { $this->writeComment(" " . ($c = count($obsolete_lemmas)) . ' obsolete string' . Tools::getPlural($c) . ' (will be deleted)'); } else { $this->writeComment(" " . ($c = count($obsolete_lemmas)) . ' obsolete string' . Tools::getPlural($c) . ' (can be deleted manually in the generated file)'); $final_lemmas["POTSKY___OBSOLETE___POTSKY"] = "POTSKY___OBSOLETE___POTSKY"; foreach ($obsolete_lemmas as $key => $value) { if ($this->option('verbose')) { $this->writeLine(" <comment>" . $key . "</comment>"); } array_set($final_lemmas, $obsolete_prefix . $key, $value); } } } // Flat style if ($this->option('output-flat')) { $final_lemmas = array_dot($final_lemmas); } if ($something_to_do === true || $this->option('force')) { $content = var_export($final_lemmas, true); $content = preg_replace("@'POTSKY___COMMENT___POTSKY[0-9]*' => '(.*)',@", '// $1', $content); $content = str_replace(array("'POTSKY___NEW___POTSKY' => 'POTSKY___NEW___POTSKY',", "'POTSKY___OLD___POTSKY' => 'POTSKY___OLD___POTSKY',", "'POTSKY___PROTECTED___POTSKY' => 'POTSKY___PROTECTED___POTSKY',", "'POTSKY___OBSOLETE___POTSKY' => 'POTSKY___OBSOLETE___POTSKY',"), array('//============================== New strings to translate ==============================//', $display_already_comment === true ? '//==================================== Translations ====================================//' : '', '//============================== Dynamic protected strings =============================//', '//================================== Obsolete strings ==================================//'), $content); $file_content = "<?php\n"; if (!$this->option('no-date')) { $a = " Generated via \"php artisan " . $this->argument('command') . "\" at " . date("Y/m/d H:i:s") . " "; $file_content .= "/" . str_repeat('*', strlen($a)) . "\n" . $a . "\n" . str_repeat('*', strlen($a)) . "/\n"; } $file_content .= "\nreturn " . $content . ";"; $job[$file_lang_path] = $file_content; } else { if ($this->option('verbose')) { $this->writeLine(" > <comment>Nothing to do for this file</comment>"); } } } } } /////////////////////////////////////////// // Silent mode // // only return an exit code on new lemma // /////////////////////////////////////////// if ($this->option('silent')) { if ($there_are_new === true) { return self::ERROR; } else { // @codeCoverageIgnoreStart return self::SUCCESS; // @codeCoverageIgnoreEnd } } /////////////////////////////////////////// // Normal mode // /////////////////////////////////////////// if (count($job) > 0) { if ($this->option('no-interaction')) { $do = true; } else { $this->writeLine(''); $do = $this->ask('Do you wish to apply these changes now? [yes|no]') === 'yes'; $this->writeLine(''); } // @codeCoverageIgnoreEnd if ($do === true) { if (!$this->option('no-backup')) { $this->writeLine('Backup files:'); $now = $this->manager->getBackupDate(); foreach ($job as $file_lang_path => $file_content) { $backup_path = $this->manager->getBackupPath($file_lang_path, $now, $extension); if (!$this->option('dry-run')) { rename($file_lang_path, $backup_path); } $this->writeLine(" <info>" . $this->manager->getShortPath($file_lang_path) . "</info> -> <info>" . $this->manager->getShortPath($backup_path) . "</info>"); } $this->writeLine(''); } $this->writeLine('Save files:'); $open_files = ''; foreach ($job as $file_lang_path => $file_content) { if (!$this->option('dry-run')) { file_put_contents($file_lang_path, $file_content); } $this->writeLine(" <info>" . $this->manager->getShortPath($file_lang_path) . "</info>"); // Fix code style if (!empty($this->code_style_level) || !empty($this->code_style_fixers)) { try { $this->manager->fixCodeStyle($file_lang_path, $this->code_style_fixers, $this->code_style_level); } catch (Exception $e) { $this->writeError(" Cannot fix code style (" . $e->getMessage() . ")"); } // @codeCoverageIgnoreEnd } // @codeCoverageIgnoreStart if ($this->option('editor')) { $open_files .= ' ' . escapeshellarg($file_lang_path); } // @codeCoverageIgnoreEnd } $this->writeLine(''); $this->writeInfo('Process done!'); // @codeCoverageIgnoreStart if ($this->option('editor')) { exec($this->editor . $open_files); } // @codeCoverageIgnoreEnd // @codeCoverageIgnoreStart } else { $this->writeLine(''); $this->writeComment('Process aborted. No file has been changed.'); } } else { $this->writeLine(''); $this->writeInfo('Drink a Piña colada and/or smoke Super Skunk, you have nothing to do!'); } $this->writeLine(''); return self::SUCCESS; }
public function testValidDirectory() { $this->assertFalse(Tools::isValidDirectory(__DIR__, __FILE__)); }