PHP Classes

File: Command/TranslationsDumpCommand.php

Recommend this page to a friend!
  Classes of Joseluis Laso   Tradukoj.com Translations API Bundle   Command/TranslationsDumpCommand.php   Download  
File: Command/TranslationsDumpCommand.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,005 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\Tools\ArrayTools; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Helper\DialogHelper; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\SplFileInfo; use Symfony\Component\HttpKernel\Bundle\BundleInterface; use Symfony\Component\Translation\MessageCatalogueInterface; use Symfony\Component\Yaml\Inline; use Symfony\Component\Yaml\Yaml; use Symfony\Component\HttpKernel\Kernel; /** * Sync translations files - translations server. * * @author Joseluis Laso <jlaso@joseluislaso.es> */ class TranslationsDumpCommand extends ContainerAwareCommand { const COMMENTS = 'comments'; /** @var InputInterface */ private $input; /** @var OutputInterface */ private $output; /** @var EntityManager */ private $em; private $srcDir; /** @var TranslationRepository */ private $translationRepository; const THROWS_EXCEPTION = true; /** fake key to process app/Resources/translations */ const APP_BUNDLE_KEY = '*app'; /** * {@inheritdoc} */ protected function configure() { $this->setName('jlaso:translations:dump'); $this->setDescription('Dump yml translations files to pdo.'); $this->addOption('cache-clear', 'c', InputOption::VALUE_NONE, 'Remove translations cache files for managed locales.', null); $this->addOption('backup-files', 'b', InputOption::VALUE_NONE, 'Makes a backup of yaml files updated.', null); $this->addOption('force', null, InputOption::VALUE_OPTIONAL, 'Force replace local database content.', null); } /** * Estrategia: * - recuperar la lista de bundles * - confeccionar una lista completa de bundles con los locales y remotos * - recorrer la lista de bundles * - recuperar la lista de claves del bundle * - confeccionar una lista completa de claves con los locales y remotos del bundle * - enviar un if-newest de cada clave/idioma * */ protected function init() { /** @var EntityManager $em */ $this->em = $this->getContainer()->get('doctrine.orm.default_entity_manager'); $this->srcDir = realpath($this->getApplication()->getKernel()->getRootDir() . '/../src/') . '/'; $this->translationRepository = $this->em->getRepository('TranslationsApiBundle:Translation'); } /** * @param $bundleName * * @return BundleInterface */ protected function getBundleByName($bundleName) { /** @var Kernel $kernel */ $kernel = $this->getApplication()->getKernel(); $bundles = $kernel->getBundle($bundleName, false); return $bundles[count($bundles) - 1]; } /* * Scans folders to find translations files and extract catalog by filename */ protected function getLocalCatalogs() { $result = array(); $folders = array( $this->srcDir, dirname($this->srcDir) . '/app', ); foreach($folders as $folder){ $finder = new Finder(); $finder->files()->in($folder)->name('/\w+\.\w+\.yml$/i'); foreach($finder as $file){ //$yml = $file->getRealpath(); //$relativePath = $file->getRelativePath(); $fileName = $file->getRelativePathname(); if(preg_match("/translations\/(\w+)\.(\w+)\.yml/i", $fileName, $matches)){ $catalog = $matches[1]; $result[$catalog] = null; } } } return array_keys($result); } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $this->input = $input; $this->output = $output; $this->init(); if($input->getOption('force')!='yes'){ /** @var DialogHelper $dialog */ $dialog = $this->getHelper('dialog'); if (!$dialog->askConfirmation( $output, '<question>The local DB will be erased, it is ok ?</question>', false )) { die('Please, repeat the command with --force==yes in order to update remote DB with local changes'); } } // truncate local translations table $this->translationRepository->truncateTranslations(); $config = $this->getContainer()->getParameter('translations_api'); $managedLocales = $config['managed_locales']; if(!count($managedLocales)){ die('not found managed locales' . PHP_EOL); } $managedLocales[] = self::COMMENTS; //$apiConfig = $this->getContainer()->getParameter('jlaso_translations_api_access'); $this->output->writeln('<info>*** Syncing bundles translation files ***</info>'); $allLocalBundles = $this->getApplication()->getKernel()->getBundles(); /** @var BundleInterface[] $allLocalBundles */ foreach($allLocalBundles as $bundle){ // just added bundles that are within / src as the other are not responsible for their translations if(strpos($bundle->getPath(), $this->srcDir) === 0 ){ $name = $bundle->getName(); if(!isset($allBundles[$name])){ $allBundles[$name] = $name; } } }; // adding a fake bundle to process translations from /app/Resources/translations $allBundles[self::APP_BUNDLE_KEY] = self::APP_BUNDLE_KEY; $catalogs = $this->getLocalCatalogs(); // proccess local keys foreach ($allBundles as $bundleName) { $this->output->writeln(PHP_EOL . sprintf("<error>%s</error>", $this->center($bundleName))); foreach($managedLocales as $locale){ $this->output->writeln(sprintf('· %s/%s', $bundleName, $locale)); foreach($catalogs as $catalog){ if(self::APP_BUNDLE_KEY == $bundleName){ $bundle = null; $filePattern = $this->srcDir . '../app/Resources/translations/%s.%s.yml'; }else{ $bundle = $this->getBundleByName($bundleName); $filePattern = $bundle->getPath() . '/Resources/translations/%s.%s.yml'; } $fileName = sprintf($filePattern, $catalog, $locale); if(!file_exists($fileName)){ //$this->output->writeln(sprintf("· · <comment>File '%s' not found</comment>", $fileName)); }else{ // $maxDate = new \DateTime(date('c',filemtime($fileName))); $hasChanged = false; $localKeys = $this->getYamlAsArray($fileName); $this->output->writeln(sprintf("· · <info>Processing</info> '%s', found <info>%d</info> translations", $this->fileTrim($fileName), count($localKeys))); //$this->output->writeln(sprintf("\t|-- <info>getKeys</info> informs that there are %d keys ", count($remoteKeys))); foreach($localKeys as $localKey=>$message){ $this->output->writeln(sprintf("\t|-- key %s:%s/%s ... ", $bundleName, $localKey, $locale)); $this->updateOrInsertEntry($bundleName, $fileName, $localKey, $locale, $message, $catalog); } } //unlink($fileName); //$this->output->writeln(''); } } } $this->output->writeln(PHP_EOL . '<info>Flushing to DB ...</info>'); $this->em->flush(); if ($this->input->getOption('cache-clear')) { $this->output->writeln(PHP_EOL . '<info>Removing translations cache files ...</info>'); $this->getContainer()->get('translator')->removeLocalesCacheFiles($managedLocales); } $this->output->writeln(''); } /** * pretty center a message on the screen * * @param string $text * @param int $width * * @return string */ protected function center($text, $width = 120) { $len = strlen($text); if($len<$width){ $w = (intval($width - $len)/2); $left = str_repeat('·', $w); $right = str_repeat('·', $width - $len - $w); return $left . $text . $right; }else{ return $text; } } /** * removes the system path to project in order to archive only the relative path * * @param string $fileName * * @return string */ protected function fileTrim($fileName) { return str_replace(dirname($this->srcDir), '', $fileName); } /** * Reads a Yaml file and process the keys and returns as a associative indexed array * * @param string $file * * @return array */ protected function getYamlAsArray($file) { if(file_exists($file)){ return ArrayTools::YamlToKeyedArray(file_get_contents($file)); } return array(); } /** * @param string $bundleName * @param string $file * @param string $key * @param string $locale * @param string $content * @param string $catalog * @param \DateTime $updatedAt */ protected function updateOrInsertEntry($bundleName, $file, $key, $locale, $content, $catalog, \DateTime $updatedAt = null) { $shortFile = str_replace($this->srcDir, '', $file); $shortFile = str_replace('\/', '/', $shortFile); $mod = $updatedAt ?: new \DateTime(date('c',filemtime($file))); /** @var Translation $entry */ $entry = $this->translationRepository->findOneBy(array( 'domain' => $bundleName, 'key' => $key, 'locale' => $locale, ) ); if(!$entry){ $entry = new Translation(); } $entry->setDomain($catalog); $entry->setBundle($bundleName); $entry->setFile($shortFile); $entry->setKey($key); $entry->setMessage($content); $entry->setUpdatedAt($mod); $entry->setLocale($locale); $this->em->persist($entry); } }