From 27b14f9140a74ea933fb8e4f79b2abd39e547b44 Mon Sep 17 00:00:00 2001 From: Joris de Wit Date: Thu, 7 Aug 2014 08:59:13 -0700 Subject: [PATCH 1/3] specify id in findTranslationList query --- Storage/MongoDBStorage.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Storage/MongoDBStorage.php b/Storage/MongoDBStorage.php index 26c145a..0ef0d5d 100755 --- a/Storage/MongoDBStorage.php +++ b/Storage/MongoDBStorage.php @@ -2,6 +2,9 @@ namespace ServerGrove\Bundle\TranslationEditorBundle\Storage; +use ServerGrove\Bundle\TranslationEditorBundle\Document\Entry; +use ServerGrove\Bundle\TranslationEditorBundle\Document\Locale; + /** * Doctrine MongoDB Storage * @@ -68,13 +71,15 @@ public function findTranslationList(array $criteria = array()) { $builder = $this->manager->createQueryBuilder($this->getTranslationClassName()); - if(isset($criteria['locale']) && $criteria['locale'] instanceof \ServerGrove\Bundle\TranslationEditorBundle\Document\Locale) { - $criteria['locale'] = $criteria['locale']->getId(); + if (isset($criteria['locale']) && $criteria['locale'] instanceof Locale) { + $criteria['locale.id'] = $criteria['locale']->getId(); + unset($criteria['locale']); } - if(isset($criteria['entry']) && $criteria['entry'] instanceof \ServerGrove\Bundle\TranslationEditorBundle\Document\Entry) { - $criteria['entry'] = $criteria['entry']->getId(); + if (isset($criteria['entry']) && $criteria['entry'] instanceof Entry) { + $criteria['entry.id'] = $criteria['entry']->getId(); + unset($criteria['entry']); } - + $this->hydrateCriteria($builder, $criteria); return iterator_to_array($builder->getQuery()->execute()); @@ -89,7 +94,7 @@ public function findTranslationList(array $criteria = array()) protected function hydrateCriteria($builder, array $criteria = array()) { foreach ($criteria as $fieldName => $fieldValue) { - $builder->addOr($builder->expr()->field($fieldName)->equals($fieldValue)); + $builder->field($fieldName)->equals($fieldValue); } } } From 787c8ec62c5cc45c9b3962916191d19a9cc065bf Mon Sep 17 00:00:00 2001 From: Joris de Wit Date: Thu, 7 Aug 2014 09:15:45 -0700 Subject: [PATCH 2/3] Add translation generator Uses Microsoft Translator to automatically create translations for a new locale. Requires the AvroTranslatorBundle. --- Command/GenerateCommand.php | 79 +++++++++++++++++++ DependencyInjection/Configuration.php | 5 ++ .../ServerGroveTranslationEditorExtension.php | 4 + Generator/TranslationGenerator.php | 66 ++++++++++++++++ README.md | 16 ++++ Resources/config/translator.xml | 15 ++++ composer.json | 3 +- 7 files changed, 187 insertions(+), 1 deletion(-) create mode 100755 Command/GenerateCommand.php create mode 100644 Generator/TranslationGenerator.php create mode 100644 Resources/config/translator.xml diff --git a/Command/GenerateCommand.php b/Command/GenerateCommand.php new file mode 100755 index 0000000..28fb9ec --- /dev/null +++ b/Command/GenerateCommand.php @@ -0,0 +1,79 @@ + + */ +class GenerateCommand extends AbstractCommand +{ + /** + * {@inheritdoc} + */ + protected function configure() + { + parent::configure(); + + $this + ->setName('locale:editor:generate') + ->setDescription('Creates a translation file for a locale automatically') + ; + } + + /** + * {@inheritdoc} + */ + public function execute(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + $this->output = $output; + + $dialog = $this->getHelper('dialog'); + + $storage = $this->getContainer()->get('server_grove_translation_editor.storage'); + + $localesArray = array(); + $locales = $storage->findLocaleList(); + + foreach($locales as $locale) { + $localesArray[] = $locale->getLanguage(); + } + + $fromIndex = $dialog->select( + $output, + 'Please select the locale to translate from', + $localesArray, + 0 + ); + + $from = $localesArray[$fromIndex]; + + $to = $dialog->ask( + $output, + 'Please enter the locale of the language to translate to: ', + '' + ); + + if (strlen($to) != 2) { + throw new \Exception('Locale must be 2 digits'); + } + + $generator = $this->getContainer()->get('server_grove_translation_editor.translation.generator'); + + $this->output->writeln('Please wait while your translations are translated.'); + + $generator->run($from, $to, true); + + $this->output->writeln('Done.'); + } + +} diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 36b73b0..5cd41ef 100755 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -35,6 +35,11 @@ public function getConfigTreeBuilder() ->end() ->end() ->end() + ->booleanNode('use_translator') + ->defaultValue(false) + ->isRequired() + ->cannotBeEmpty() + ->end() ->end(); return $treeBuilder; diff --git a/DependencyInjection/ServerGroveTranslationEditorExtension.php b/DependencyInjection/ServerGroveTranslationEditorExtension.php index 2fca651..91927fb 100755 --- a/DependencyInjection/ServerGroveTranslationEditorExtension.php +++ b/DependencyInjection/ServerGroveTranslationEditorExtension.php @@ -23,5 +23,9 @@ public function load(array $configs, ContainerBuilder $container) $container->setParameter($this->getAlias() . '.storage.type', $config['storage']['type']); $container->setParameter($this->getAlias() . '.storage.manager', $config['storage']['manager']); + + if ($config['use_translator'] == true) { + $loader->load('translator.xml'); + } } } diff --git a/Generator/TranslationGenerator.php b/Generator/TranslationGenerator.php new file mode 100644 index 0000000..9e8ab8d --- /dev/null +++ b/Generator/TranslationGenerator.php @@ -0,0 +1,66 @@ +storageService = $storageService; + $this->translator = $translator; + } + + /** + * Converts translations from one language to another + * + * @param string $from The language to translate from + * @param string $to The language to translate to + */ + public function run($from, $to, $progress = false) + { + $localeList = $this->storageService->findLocaleList(array('language' => $from)); + + if (count($localeList) == 0) { + throw new \Exception(sprintf('Locale "%s" does not exist', $from)); + } + + $locale = reset($localeList); + + $toLocaleList = $this->storageService->findLocaleList(array('language' => $to)); + + $toLocale = reset($toLocaleList); + + if (!$toLocale instanceOf Locale) { + $toLocale = $this->storageService->createLocale($to); + + $this->storageService->flush(); + } + + $translations = $this->storageService->findTranslationList(array('locale' => $locale)); + + foreach ($translations as $translation) { + $newValue = $this->translator->translate($translation->getValue(), $from, $to); + + $this->storageService->createTranslation($toLocale, $translation->getEntry(), $newValue); + + $this->storageService->flush(); + + if ($progress) { + echo '.'; + } + } + } +} diff --git a/README.md b/README.md index 4fc9d81..5e61c0e 100755 --- a/README.md +++ b/README.md @@ -16,6 +16,12 @@ Import translation files into MongoDB. If no files is specified, the command wil Export translations to translation files from MongoDB. If no files is specified, the command will search for files in translations directories in src/ +* Generate new translation files + + ./app/console locale:editor:generate + +Automatically generate translation files for a new locale using Microsoft Translator. Requires AvroTranslatorBundle. + ## Screenshot @@ -75,6 +81,12 @@ Doctrine MongoDB configuration (in your config_dev.yml): type: server_grove_translation_editor.storage.mongodb manager: doctrine_mongodb.odm.document_manager +Enable the generator with the following configuration. + + server_grove_translation_editor: + use_translator: true + + Add the routing configuration to app/config/routing_dev.yml SGTranslationEditorBundle: @@ -95,6 +107,10 @@ Add the routing configuration to app/config/routing_dev.yml ./app/console locale:editor:export +3. Generate translations from an existing locale to a new locale + + ./app/console locale:editor:generate + ## WARNING **PLEASE** Backup your translation files before using the editor. **Use a source control system like git, even svn is ok**. We are not responsible for lost information. diff --git a/Resources/config/translator.xml b/Resources/config/translator.xml new file mode 100644 index 0000000..77e2be8 --- /dev/null +++ b/Resources/config/translator.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/composer.json b/composer.json index 6118fb6..139551a 100755 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ ], "require": { "php": ">=5.3.2", - "symfony/framework-bundle": "2.*" + "symfony/framework-bundle": "2.*", + "avro/translator-bundle": "*" }, "autoload": { "psr-0": { From 423ed6c266ebf743f335bf35f1d747dcd3eb1ef6 Mon Sep 17 00:00:00 2001 From: Joris de Wit Date: Fri, 8 Aug 2014 09:02:01 -0700 Subject: [PATCH 3/3] suggest avro/translator-bundle instead of require --- composer.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 139551a..9133a98 100755 --- a/composer.json +++ b/composer.json @@ -15,8 +15,10 @@ ], "require": { "php": ">=5.3.2", - "symfony/framework-bundle": "2.*", - "avro/translator-bundle": "*" + "symfony/framework-bundle": "2.*" + }, + "suggest": { + "avro/translator-bundle": "Needed when using the translation generator" }, "autoload": { "psr-0": {