Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- namespace WebBundle\Command;
- use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
- use Symfony\Component\Console\Input\InputInterface;
- use Symfony\Component\Console\Input\InputOption;
- use Symfony\Component\Console\Output\OutputInterface;
- use Symfony\Component\Yaml\Parser;
- use Symfony\Component\Yaml\Dumper;
- /**
- * Generic and extremely basic Symfony console command that merges translation files in src/<bundle>/Resources/translations/ directories
- * with translation files in the app/Resources/translations/ directory.
- *
- * Expected behaviour:
- * 1 - You have some translation files in src/<bundle>/Resources/translations/, but no translation files in app/Resources/translations/:
- * ---- This command will create a copy of translation files in src/<bundle>/Resources/translations/ in app/Resources/translations/.
- * Having translation files with identical filenames in multiple bundle folders will result in a merged copy, with duplicate key/value
- * pairs being overwritten by one another.
- *
- * 2 - You have some translation files in src/<bundle>/Resources/translations/ as well as translation files in app/Resources/translations/:
- * ---- This command will merge the translation files in app/Resources/translations/ with a copy of translation files in
- * src/<bundle>/Resources/translations/. Key/value pairs from the translation files in app/Resources/translations/ will have priority,
- * so no edited translations should be lost. The behaviour from (1) still applies.
- *
- * @author Kalman Olah <hello _AT_ kalmanolah _DOT_ net>
- */
- class TranslationMergeCommand extends ContainerAwareCommand
- {
- private $container;
- private $input;
- private $output;
- private $yaml_parser;
- private $yaml_dumper;
- private $source_only;
- private $base_dir;
- private $source_dir;
- private $vendor_dir;
- private $target_dir;
- private $translations_dir;
- private $cache;
- private $cache_merged;
- const LN_INFO = 'info';
- const LN_ERROR = 'error';
- const LN_COMMENT = 'comment';
- const LN_QUESTION = 'question';
- const DS = DIRECTORY_SEPARATOR;
- const YAML_INLINE = 10;
- protected function configure()
- {
- $this
- ->setName('translations:merge')
- ->setDescription('Merges translation files in the src/<bundle>/Resources/translations/ folder with translation files in the app/Resources/translations/ folder')
- ->addOption(
- 'source-only',
- null,
- InputOption::VALUE_OPTIONAL,
- 'Should this command only look for bundles in the src/ folder? [TRUE/false]',
- true
- );
- }
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- $this->container = $this->getContainer();
- $this->input = $input;
- $this->output = $output;
- $this->yaml_parser = new Parser();
- $this->yaml_dumper = new Dumper();
- $this->source_only = $this->getOption('source-only') == 'true';
- $this->base_dir = $this->container->get('kernel')->getRootDir().self::DS.'..'.self::DS;
- $this->source_dir = $this->base_dir.'src'.self::DS;
- $this->vendor_dir = $this->base_dir.'vendor'.self::DS;
- $this->target_dir = $this->base_dir.'app'.self::DS;
- $this->translations_dir = 'Resources'.self::DS.'translations'.self::DS;
- $this->cache = array();
- $this->cache_merged = array();
- $this->performCommand();
- }
- private function println($string = '', $style = null, $indent = false)
- {
- if ($indent) {
- if (is_bool($indent)) {
- $indent = 4;
- }
- $indenting = '';
- while ($indent > 0) {
- $indenting .= ' ';
- --$indent;
- }
- $string = $indenting.$string;
- }
- if ($style !== null) {
- $string = '<'.$style.'>'.$string.'</'.$style.'>';
- }
- $this->output->writeln($string);
- }
- private function getOption($name)
- {
- return $this->input->getOption($name);
- }
- private function performCommand()
- {
- $this->println();
- $this->println('Beginning the merging of translation files..', self::LN_INFO);
- $this->println();
- $this->println('Searching for bundles..', self::LN_COMMENT, 2);
- $bundles = $this->getBundles();
- $this->println('Found <comment>'.count($bundles).'</comment> bundle(s). Attempting to loop..', null, 2);
- $this->println();
- if (count($bundles) == 0) {
- $this->println('No bundles were found, not looping.', null, 4);
- $this->println();
- } else {
- foreach ($bundles as $bundle) {
- if ($this->source_only && !$bundle[1]) {
- $this->println('Skipping bundle <question>'.$bundle[0].'</question> since it\'s not part of the source folder.', null, 4);
- $this->println();
- } else {
- $this->println('Looking for translation files in bundle <comment>'.$bundle[0].'</comment>..', self::LN_INFO, 4);
- $bundle_trans_dir = $bundle[0].$this->translations_dir;
- $this->println('Searching in <comment>'.$bundle_trans_dir.'</comment>..', null, 4);
- $bundle_trans_path = $bundle[1] ? $this->source_dir : $this->vendor_dir;
- $bundle_trans_path .= $bundle_trans_dir;
- if (!is_dir($bundle_trans_path)) {
- $this->println('The directory does not exist. Skipping.', null, 4);
- $this->println();
- } else {
- $translations = $this->getTranslationFiles($bundle_trans_path);
- $this->println('Found <comment>'.count($translations).'</comment> translation file(s). Attempting to loop..', null, 4);
- $this->println();
- if (count($translations) === 0) {
- $this->println('No translation files were found, not looping.', null, 6);
- $this->println();
- } else {
- foreach ($translations as $translation) {
- $this->cacheTranslationFile($bundle[0], $bundle_trans_path, $translation);
- $this->println('Added parsed content of <info>'.$translation.'</info> to cache.', null, 6);
- }
- $this->println();
- }
- }
- }
- }
- $this->println('Attempting to merge cached translation file content..', self::LN_COMMENT, 2);
- $count = $this->getCachedTranslationFileCount();
- if ($count == 0) {
- $this->println('No cached translation files found. Skipping.', null, 2);
- $this->println();
- } else {
- $this->println('Merging <comment>'.$count.'</comment> translation file(s)..', null, 2);
- $this->println();
- foreach ($this->cache as $file => $variants) {
- $this->mergeAndCacheTranslationFiles($file, array_values($variants));
- $this->println('Successfully merged <info>'.count($variants).'</info> variant(s) of <info>'.$file.'</info>.', null, 4);
- }
- $this->println();
- }
- $this->println('Attempting to write merged translation files..', self::LN_COMMENT, 2);
- $count = count($this->cache_merged);
- if ($count == 0) {
- $this->println('No merged translation files found. Skipping.', null, 2);
- $this->println();
- } else {
- $this->println('Writing <comment>'.$count.'</comment> merged translation file(s)..', null, 2);
- $write_path = $this->target_dir.$this->translations_dir;
- $this->println('Writing to <comment>'.$write_path.'</comment>..', null, 2);
- if (!is_dir($write_path)) {
- $this->println('The directory does not exist. Attempting to create it.', null, 2);
- mkdir($write_path, 0777, true);
- }
- $this->println();
- foreach ($this->cache_merged as $file => $content) {
- $this->println('Trying to write <info>'.$file.'</info>..', null, 4);
- if (file_exists($write_path.$file)) {
- $this->println('The output file already exists. Merging contents..', null, 6);
- $original_content = $this->getParsedTranslationFileContent($write_path, $file);
- $this->mergeAndCacheTranslationFiles($file, array($content, $original_content));
- }
- $this->writeMergedTranslationFile($write_path, $file);
- $this->println('Done!', self::LN_INFO, 6);
- }
- $this->println();
- }
- }
- $this->println('Merging of translation files was completed successfully.', self::LN_INFO);
- $this->println();
- }
- private function getBundles()
- {
- $return = array();
- $bundles = $this->container->getParameter('kernel.bundles');
- foreach ($bundles as $bundle) {
- $bundle_split = explode('\\', $bundle);
- $bundle_file = array_values($bundle_split);
- $bundle_file = end($bundle_file).'.php';
- $bundle_path = implode(self::DS, array_slice($bundle_split, 0, -1)).self::DS;
- $bundle_in_source = file_exists($this->source_dir.$bundle_path.$bundle_file);
- array_push($return, array($bundle_path, $bundle_in_source));
- }
- return $return;
- }
- private function getTranslationFiles($path)
- {
- $return = array();
- if ($handle = opendir($path)) {
- while (($file = readdir($handle)) !== false) {
- // We're only going to read files ending in .yml
- if (preg_match('/.*\.yml$/', $file)) {
- array_push($return, $file);
- }
- }
- closedir($handle);
- }
- return $return;
- }
- private function getCachedTranslationFileCount()
- {
- $count = 0;
- foreach ($this->cache as $tmp) {
- foreach ($tmp as $tmp_tmp) {
- ++$count;
- }
- }
- return $count;
- }
- private function getParsedTranslationFileContent($path, $file)
- {
- $content = file_get_contents($path.$file);
- $content_parsed = $this->yaml_parser->parse($content);
- return $content_parsed;
- }
- private function cacheTranslationFile($bundle, $path, $file)
- {
- if (!array_key_exists($file, $this->cache)) {
- $this->cache[$file] = array();
- }
- $content_parsed = $this->getParsedTranslationFileContent($path, $file);
- $this->cache[$file][$bundle] = $content_parsed;
- }
- private function mergeAndCacheTranslationFiles($file, $variants)
- {
- $merged = array();
- for ($i = 0; $i < count($variants); ++$i) {
- $merged = $this->mergeDistinctlyAndRecursively($merged, $variants[$i]);
- }
- $this->cache_merged[$file] = $merged;
- }
- private function mergeDistinctlyAndRecursively(&$array1, &$array2)
- {
- $return = $array1;
- foreach ($array2 as $key => &$value) {
- if (is_array($value) && isset($return[$key]) && is_array($return[$key])) {
- $return[$key] = $this->mergeDistinctlyAndRecursively($return[$key], $value);
- } else {
- $return[$key] = $value;
- }
- }
- return $return;
- }
- private function writeMergedTranslationFile($path, $file)
- {
- $content = $this->cache_merged[$file];
- $content_dumped = $this->yaml_dumper->dump($content, self::YAML_INLINE);
- file_put_contents($path.$file, $content_dumped);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement