<?php 
 
/** 
 * @author Joseluis Laso <[email protected]> 
 */ 
 
namespace JLaso\TranslationsApiBundle\Command; 
 
use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\DBAL\Query\QueryBuilder; 
use Doctrine\ODM\MongoDB\DocumentManager; 
use Doctrine\ORM\EntityManager; 
use JLaso\TranslationsApiBundle\Service\ClientSocketService; 
use JLaso\TranslationsBundle\Document\Repository\TranslationRepository; 
use JLaso\TranslationsBundle\Document\Translation; 
use JLaso\TranslationsBundle\Entity\Project; 
use JLaso\TranslationsBundle\Entity\Repository\ProjectRepository; 
use JLaso\TranslationsBundle\Entity\User; 
use JLaso\TranslationsBundle\Service\MailerService; 
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; 
use Symfony\Component\Console\Command\Command; 
use Symfony\Component\Console\Helper\DialogHelper; 
use Symfony\Component\Console\Helper\HelperSet; 
use Symfony\Component\Console\Helper\TableHelper; 
use Symfony\Component\Console\Input\InputArgument; 
use Symfony\Component\Console\Input\InputInterface; 
use Symfony\Component\Console\Input\InputOption; 
use Symfony\Component\Console\Output\OutputInterface; 
use Symfony\Component\DependencyInjection\Container; 
 
class TranslationsUpdateFromExcelCommand extends ContainerAwareCommand 
{ 
 
    /** @var  string */ 
    protected $name; 
    /** @var  string */ 
    protected $description; 
    /** @var ClientSocketService */ 
    private $clientApiService; 
 
    protected function configure() 
    { 
        $this->name        = 'jlaso:translations:update-from-excel'; 
        $this->description = 'Update translations from an Excel document'; 
        $this 
            ->setName($this->name) 
            ->setDescription($this->description) 
            ->addArgument('excel', InputArgument::REQUIRED, 'excel doc') 
            ->addArgument('language', InputArgument::REQUIRED, 'language') 
            ->addOption('port', null, InputArgument::OPTIONAL, 'port') 
            ->addOption('address', null, InputArgument::OPTIONAL, 'address') 
            ->addOption('approved', null, InputArgument::OPTIONAL, 'approved') 
        ; 
    } 
 
    protected function init($server = null, $port = null) 
    { 
        /** @var ClientSocketService $clientApiService */ 
        $clientApiService = $this->getContainer()->get('jlaso_translations.client.socket'); 
        $this->clientApiService = $clientApiService; 
        $this->clientApiService->init($server, $port); 
    } 
 
    /** 
     * @param $keys 
     * @param $needle 
     * @param $reference 
     * 
     * @return mixed 
     */ 
    protected function substitute($keys, $needle, $reference) 
    { 
 
        foreach($keys as $srch=>$replc){ 
 
            //$srch = str_replace(array("(",")","[","]"), array('\(','\)','\[','\]')); 
            if(preg_match("/\((?<idx>\d+)\)/", $srch, $match)){ 
                $idx = $match['idx']; 
                $regr = "/\({$idx}\)(?<val>.*?)\({$idx}\)/"; 
                if(preg_match($regr, $reference, $match)){ 
                    $replc = "%".$match['val']."%"; 
                }else{ 
                    //$regr = "/\({$idx}\)(.*?)\({$idx}\)/"; 
                    $replc = "%$1%"; 
                }; 
                $regr = "/\(\s?{$idx}\s?\)(.*?)\(\s?{$idx}\s?\)/"; 
            }else{ 
                if(preg_match("/\[(?<idx>\d+)\]/", $srch, $match)){ 
                    $idx = $match['idx']; 
                    $regr = "/\[\s?{$idx}\s?\]/";  //print "\n\t$idx\t$regr\t$replc\n"; 
                }else{ 
                    die("error in substitute $srch=>$replc"); 
                } 
            } 
            $needle = preg_replace($regr, $replc, $needle); 
        } 
 
        return $needle; 
    } 
 
    protected function getCellValue(\PHPExcel_Worksheet $sheet, $coord) 
    { 
        $cell = $sheet->getCell($coord); 
        if($cell){ 
            return $cell->getValue(); 
        } 
    } 
 
    /** 
     * FORMAT for the excel document 
     * ============================= 
     * 
     * one worksheet named as the language you want to import 
     * one workseeht named "key" with the following format 
     *   rowX colA ColB 
     *     1   [1]  (1)   => (1) var substitution, [1] style substitution 
     * 
     * the reason for this "key system" is that normally translators haven't to translate the html labels and variables and this is a way to assure this 
     */ 
 
    public function execute(InputInterface $input, OutputInterface $output) 
    { 
        $container = $this->getContainer(); 
        $file      = $input->getArgument('excel'); 
        $language  = $input->getArgument('language'); 
        $approved  = (boolean)$input->getOption('approved'); 
 
        $this->init($input->getOption('address'), $input->getOption('port')); 
 
        $phpExcel  = $container->get('phpexcel'); 
 
        /** @var \PHPExcel $excel */ 
        $excel     = $phpExcel->createPHPExcelObject($file); 
 
        $keySheet = $excel->getSheetByName('key'); 
        $key = array(); //array_flip(json_decode($keySheet->getCell('A1'), true)); 
        foreach($keySheet->getRowIterator() as $row){ 
 
            $rowNum = $row->getRowIndex(); 
            $cellIterator = $row->getCellIterator(); 
            $cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set 
 
            foreach ($cellIterator as $cell) { 
                /** @var \PHPExcel_Cell $cell */ 
                $cellValue = $cell->getCalculatedValue(); 
                switch($cell->getColumn()){ 
                    case("A"): 
                        $index = "[$rowNum]"; 
                        break; 
                    case("B"): 
                        $index = "($rowNum)"; 
                        break; 
                }; 
                if (!is_null($cellValue)) { 
                    $key[$index] = $cellValue; 
                } 
            } 
        } 
 
        // get the worksheet that match its title with language 
        $worksheet = $excel->getSheetByName($language); 
 
        $output->writeln("\n<comment>Worksheet - " . $worksheet->getTitle() . "</comment>"); 
        $localData = array(); 
 
        foreach ($worksheet->getRowIterator() as $row) { 
            /** @var \PHPExcel_Worksheet_Row $row */ 
            $index       = $row->getRowIndex(); 
            $rowNum      = $row->getRowIndex(); 
            $keyName     = $this->getCellValue($worksheet, "A{$rowNum}"); 
            $reference   = $this->getCellValue($worksheet, "B{$rowNum}"); 
            $message     = $this->getCellValue($worksheet, "C{$rowNum}"); 
            $substituted = $this->substitute($key, $message, $reference); 
            //$output->writeln(sprintf("<comment>$index</comment>\t<info>%s</info> => %s => <comment>%s</comment>", $keyName, $reference, $substituted)); 
            $localData[$keyName] = $substituted; 
        } 
 
        // download translations from server 
        $result = $this->clientApiService->getCatalogIndex(); 
 
        if($result['result']){ 
            $catalogs = $result['catalogs']; 
        }else{ 
            die('error getting catalogs'); 
        } 
 
        $tempData = array(); 
 
        foreach($catalogs as $catalog){ 
 
            $output->writeln(PHP_EOL . sprintf('<info>Processing "%s" catalog ...</info>', $catalog)); 
 
            $result = $this->clientApiService->downloadKeys($catalog); 
            //var_dump($result); die; 
            file_put_contents('/tmp/' . $catalog . '.json', json_encode($result)); 
            $bundles = $result['bundles']; 
            //var_dump($result['data']['Bad credentials']); die; 
 
            foreach($result['data'] as $key=>$data){ 
 
                foreach($data as $locale=>$messageData){ 
 
                    if(($locale == $language) && isset($localData[$key])){ 
                        $tempData[$key][$catalog] = array_merge($messageData, array('new' => $localData[$key])); 
                        //$output->writeln(sprintf("\t|-- key %s:%s/%s ... ", $catalog, $key, $locale)); 
                        echo '.'; 
                        //$fileName = isset($messageData['fileName']) ? $messageData['fileName'] : ''; 
                    } 
 
                } 
            } 
        } 
 
        //print_r($tempData); 
 
        $output->writeln("\nAnalysing the result of the match process...\n"); 
        $count = 0; 
        // data to send to translations server 
        $data = array(); 
        // this date guarantees that the data sent to server forces to update key 
        $date = date('c'); 
 
        // get the key that are repeated 
        foreach($tempData as $key=>$restData){ 
            if(count($restData) > 1){ 
                $output->writeln("\tthe key $key is in more that one catalog"); 
            } 
            foreach($restData as $catalog=>$messageData){ 
 
                if(!empty($messageData['new']) && ($messageData['message'] != $messageData['new'])){ 
 
                    //var_dump($messageData); die; 
                    $data[$key][$language] = array( 
                        'approved'  => $approved, 
                        'message'   => $messageData['new'], 
                        'updatedAt' => $date, 
                        'fileName'  => isset($messageData['fileName']) ? $messageData['fileName'] : "", 
                        'bundle'    => isset($bundles[$key]) ? $bundles[$key] : "", 
                    ); 
                    $output->writeln("the key $key needs to be updated"); 
                    $count++; 
 
                } 
 
            } 
        } 
 
        $total = count($localData); 
        $output->writeln("\nfound $count keys that need to be updated from a total of $total keys that have the file to process\n"); 
 
        if($count){ 
            //ld($data); 
            $output->writeln('uploadKeys("' . $catalog . '", $data)'); 
            $result = $this->clientApiService->uploadKeys($catalog, $data); 
            //var_dump($result); 
        } 
 
        $output->writeln("\n done!"); 
    } 
 
 
 
}
 
 |