PHP Classes

File: Command/TranslationsDiscoverAndPushCommand.php

Recommend this page to a friend!
  Classes of Joseluis Laso   Tradukoj.com Translations API Bundle   Command/TranslationsDiscoverAndPushCommand.php   Download  
File: Command/TranslationsDiscoverAndPushCommand.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Tradukoj.com Translations API Bundle
Get remote translations for Symfony projects
Author: By
Last change:
Date: 9 years ago
Size: 11,047 bytes
 

Contents

Class file image Download
<?php namespace JLaso\TranslationsApiBundle\Command; use Doctrine\ORM\EntityManager; use JLaso\TranslationsApiBundle\Entity\Repository\TranslationRepository; use JLaso\TranslationsApiBundle\Entity\Translation; use JLaso\TranslationsApiBundle\Service\ClientSocketService; use Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\SplFileInfo; use JLaso\TranslationsApiBundle\Model\CandidateKey; /** * @author Joseluis Laso <jlaso@joseluislaso.es> * * Discover new keys used on twigs, php and js and push to server */ class TranslationsDiscoverAndPushCommand extends ContainerAwareCommand { /** @var InputInterface */ private $input; /** @var OutputInterface */ private $output; private $srcDir; /** @var TranslationRepository */ private $translationRepository; /** @var EntityManager */ private $em; /** @var ClientSocketService */ private $clientApiService; const THROWS_EXCEPTION = true; const ESCAPE_CHARS = '"'; /** @var array */ protected $inputFiles = array(); /** @var array */ protected $data = array(); /** @var array */ protected $filterStore = array(); /** * {@inheritdoc} */ protected function configure() { $this->setName('jlaso:translations:discover-and-push'); $this->setDescription('Discover new keys used on twigs, php and js and push to server.'); $this->addOption('bundle', null, InputArgument::OPTIONAL, '--bundle=bundleName to only extract keys for this bundle'); $this->addOption('min-words', null, InputArgument::OPTIONAL, '--min-words=number of words to consider a key'); } protected function init() { $this->srcDir = realpath($this->getApplication()->getKernel()->getRootDir() . '/../'); /** @var EntityManager $em */ $this->em = $this->getContainer()->get('doctrine.orm.default_entity_manager'); $this->translationRepository = $this->em->getRepository('TranslationsApiBundle:Translation'); /** @var ClientSocketService $clientApiService */ $clientApiService = $this->getContainer()->get('jlaso_translations.client.socket'); $this->clientApiService = $clientApiService; } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $this->input = $input; $this->output = $output; $this->init(); $verbose = (boolean)$input->getOption('verbose'); $bundleToExtract = $input->getOption('bundle'); $minWords = intval($input->getOption('min-words') ?: 0); $this->output->writeln('<info>*** Discovering new keys in php, twig and js files ***</info>'); $fileNames = array(); $keys = array(); $idx = 0; $numKeys = 0; $patterns = array( '*.twig' => '/(["\'])(?<trans>(?:\\\1|(?!\1).)+?)\1\s*\|\s*trans/i', '*.html.twig' => '/\.trans\s*\(\s*(["\'])(?<trans>(?:\\\1|(?!\1).)+?)\1/i', '*.php' => '/trans\s*\(\s*(["\'])(?<trans>(?:\\\1|(?!\1).)+?)\1\s*\)/i', '*Type.php' => '/([\'"])label\1\s*=>\s*([\'"])(?<trans>(?:\\\2|(?!\2).)+?)\2/', '*.js' => '/trans.getTranslation\s*\(\s*(["\'])(?<trans>(?:\\\1|(?!\1).)+?)\1\s*\)/i', ); $folders = array( $this->srcDir . '/app', $this->srcDir . '/src' ); $keyInfo = array(); foreach($patterns as $filePattern=>$exrPattern){ foreach($folders as $folder){ if($verbose){ $output->writeln($folder); } $finder = new Finder(); $files = $finder->in($folder)->name($filePattern)->files(); /** @var SplFileInfo[] $files */ foreach($files as $file){ $fileName = $folder . '/' . $file->getRelativePathname(); if(strpos($fileName, $folder . "/cache") === 0){ //$output->writeln(sprintf("ignored <comment>%s</comment>", $file)); continue; } if(preg_match("/\/(?P<bundle>.*Bundle)\//U", $file->getRelativePathname(), $match)){ $bundleName = $match['bundle']; }else{ $bundleName = "*app"; } if(!$bundleToExtract || ($bundleToExtract == $bundleName)){ $fileContents = file_get_contents($fileName); if(preg_match_all($exrPattern, $fileContents, $matches)){ if($verbose){ $output->writeln(sprintf("<info>%s</info>", $file)); } $fileNames[$bundleName] = $file->getRelativePathname(); if(!isset($keys[$bundleName])){ if($verbose){ $output->writeln($bundleName); } $keys[$bundleName] = array(); } $keys[$bundleName] = array_merge_recursive($keys[$bundleName], $matches["trans"]); foreach($matches['trans'] as $currentKey){ $keyInfo[$bundleName][$currentKey] = $file->getRelativePathname(); } $numKeys += count($matches['trans']); } $idx++; } } } } $output->writeln(sprintf("Total %d files examined, and found key translations in %d files", $idx, count($fileNames))); $output->writeln(sprintf("Total %d keys extracted (%d)", $numKeys, count($keys, COUNT_RECURSIVE))); // get all the translations from the local DB $sortedKeys = array(); /** @var Translation[] $localKeys */ $localKeys = $this->translationRepository->findAll(); foreach($localKeys as $localKey){ $bundle = $localKey->getBundle(); $keyName = $localKey->getKey(); $sortedKeys[$keyName][$bundle] = true; } unset($localKeys); $localSortedKeys = array(); /** @var CandidateKey[] $candidates */ $candidates = array(); // find keys thar are in files but not in db foreach($keys as $bundle=>$keyArray){ foreach($keyArray as $key){ if(!isset($sortedKeys[$key]/*[$bundle]*/)){ if(!$minWords || (($minWords-1) <= substr_count($key, "."))){ $file = $keyInfo[$bundle][$key]; $candidates[] = new CandidateKey($bundle, $file, $key); //$output->writeln(sprintf("file local key <info>%s</info>[<comment>%s</comment>] not found in DB, file %s", $bundle, $key, $file)); } } $localSortedKeys[$bundle][$key] = true; } } // // find keys that are in db but not used in files // foreach($sortedKeys as $bundle=>$keyArray){ // // //var_dump($keyArray); // foreach($keyArray as $key=>$void){ // // if(!isset($localSortedKeys[$bundle][$key])){ // // $output->writeln(sprintf("db key <info>%s</info>[<comment>%s</comment>] not used in local files", $bundle, $key)); // //var_dump($localSortedKeys[$bundle]); // //die; // } // // } // // } if(!count($candidates)){ $output->writeln("Congratulations!, you have all the keys synchronized"); exit; } $output->writeln("Check the possible candidate keys to upload to server"); foreach($candidates as $candidate){ $output->writeln( sprintf("key <info>%s</info>[<comment>%s</comment>] not found in local DB, file %s", $candidate->getKey(), $candidate->getBundle(), $candidate->getFile()) ); } $output->writeln(PHP_EOL . '<info>Have you been synchronized your translations with the sync command?</info>' . PHP_EOL); /** @var DialogHelper $dialog */ $dialog = $this->getHelper('dialog'); if ($dialog->askConfirmation( $output, '<question>Confirm that you want to upload the previous keys to server ?</question>', false )) { $catalog = $dialog->ask($output, 'Name of catalog in which to integrate new keys [messages]:', 'messages'); $data = array(); $date = new \DateTime(); $config = $this->getContainer()->getParameter('translations_api'); $managedLocales = $config['managed_locales']; foreach($candidates as $candidate){ $key = $candidate->getKey(); $bundle = $candidate->getBundle(); $fileName = $candidate->getFile(); preg_match('|^(?<prefix>\w+)/'.$bundle.'/|', $fileName, $matches); if($matches['prefix']){ $prefix = $matches['prefix']; foreach($managedLocales as $locale){ $data[$key][$locale] = array( 'message' => '', 'updatedAt' => $date->format('c'), 'fileName' => $prefix . '/' . $this->genFileFromBundleAndLocale($bundle, $catalog, $locale), 'bundle' => $bundle, ); } } } //$this->output->writeln('uploadKeys("' . $catalog . '", $data)'); //var_dump($data); //die; $this->clientApiService->init(/*'localhost', 10000*/); $result = $this->clientApiService->uploadKeys($catalog, $data); } $output->writeln('You must now to synchronize your translations with the sync command!'); } protected function genFileFromBundleAndLocale($bundleName, $catalog, $locale) { return sprintf("%s/Resources/translations/%s.%s.yml", $bundleName, $catalog, $locale); } /** * @param string $message * @throws \Exception */ protected function throwException($message) { $message = $message ?: 'Unexpected exception'; //print $message; throw new \Exception($message); } }