Вход Регистрация
Файл: concrete5.7.5.6/concrete/src/Console/Command/TranslatePackageCommand.php
Строк: 374
<?php
namespace ConcreteCoreConsoleCommand;

use 
SymfonyComponentConsoleCommandCommand;
use 
SymfonyComponentConsoleInputInputOption;
use 
SymfonyComponentConsoleInputInputArgument;
use 
SymfonyComponentConsoleInputInputInterface;
use 
SymfonyComponentConsoleOutputOutputInterface;
use 
Core;
use 
Exception;
use 
Package;
use 
Localization;
use 
GettextTranslations;

class 
TranslatePackageCommand extends Command
{
    protected function 
configure()
    {
        
$this
            
->setName('c5:package-translate')
            ->
addArgument('package'InputArgument::REQUIRED'The handle of the package to be translated (or the path to a directory containing a concrete5 package)')
            ->
addOption('locale''l'InputOption::VALUE_REQUIRED InputOption::VALUE_IS_ARRAY'List of locale codes to handle')
            ->
addOption('contact''c'InputOption::VALUE_REQUIRED'Contact information to be put in the language files to report bugs to (eg the "Report-Msgid-Bugs-To" gettext header)''')
            ->
addOption('translator''t'InputOption::VALUE_REQUIRED'Translator to be put in the language files (eg the "Last-Translator" gettext header)''')
            ->
addOption('exclude-3rdparty''x'InputOption::VALUE_NONE'Specify this option to avoid parsing 3rd party folders')
            ->
setDescription('Creates or updates translations of a concrete5 package')
            ->
setHelp(<<<EOT
If the locale option(s) is not specified, we'll generate/update translations for the currently defined locales for the package.
If currently no locale is defined, we'll generate/update translations for all the currently installed locales of the core of concrete5.
In order to don't generate the locale files but only the master translations file (.pot), specify "--locale=-" (or "-l-")
Examples:
    concrete5 c5:package-translate package_handle
    concrete5 c5:package-translate package_handle --locale=it_IT --locale=de_DE
    concrete5 c5:package-translate package_handle -l it_IT -l de_DE
    concrete5 c5:package-translate package_handle --locale=-
    concrete5 c5:package-translate path/to/a/package/directory -l-

Please remark that this command can also parse legacy (pre-5.7) packages.

Returns codes:
  0 operation completed successfully
  1 errors occurred
EOT
            )
        ;
    }

    protected function 
execute(InputInterface $inputOutputInterface $output)
    {
        
$rc 0;
        try {
            
$vsh Core::make('helper/validation/strings');
            
/* @var ConcreteCoreUtilityServiceValidationStrings $vsh */
            
$fh Core::make('helper/file');
            
/* @var ConcreteCoreFileServiceFile $fh */

            // Let's determine the package handle, directory and version
            
$packageHandle null;
            
$packageDirectory null;
            
$packageVersion null;
            
$p $input->getArgument('package');
            if (
is_dir($p) || !$vsh->handle($p)) {
                
$packageDirectory = @realpath($p);
                if (
$packageDirectory === false) {
                    throw new 
Exception("Unable to find the directory '$p'");
                }
                
$controllerFile $packageDirectory.'/'.FILENAME_CONTROLLER;
                if (!
is_file($controllerFile)) {
                    throw new 
Exception("The directory '$packageDirectory' does not seems to contain a valid concrete5 package");
                }
                
$controllerContents $fh->getContents($controllerFile);
                if (
$controllerContents) {
                    
$allTokens = @token_get_all($controllerContents);
                    if (
$allTokens) {
                        
$tokens array_values(
                            
array_filter(
                                
$allTokens,
                                function (
$token) {
                                    
$keep true;
                                    if (
is_array($token)) {
                                        switch (
$token[0]) {
                                        case 
T_DOC_COMMENT:
                                        case 
T_WHITESPACE:
                                        case 
T_COMMENT;
                                            
$keep false;
                                            break;
                                        }
                                    }

                                    return 
$keep;
                                }
                            )
                        );
                        
// Look for package version
                        
for ($i 0$i count($tokens) - 2; ++$i) {
                            if (
                                
$packageHandle === null
                                
&& is_array($tokens[$i 0]) && $tokens[$i 0][0] === T_VARIABLE && $tokens[$i 0][1] === '$pkgHandle'
                                
&& is_string($tokens[$i 1]) && $tokens[$i 1] === '='
                                
&& is_array($tokens[$i 2]) && $tokens[$i 2][0] === T_CONSTANT_ENCAPSED_STRING
                            
) {
                                
$packageHandle = @eval('return '.$tokens[$i 2][1].';');
                            }
                            if (
                                
$packageVersion === null
                                
&& is_array($tokens[$i 0]) && $tokens[$i 0][0] === T_VARIABLE && $tokens[$i 0][1] === '$pkgVersion'
                                
&& is_string($tokens[$i 1]) && $tokens[$i 1] === '='
                                
&& is_array($tokens[$i 2]) && $tokens[$i 2][0] === T_CONSTANT_ENCAPSED_STRING
                            
) {
                                
$packageVersion = @eval('return '.$tokens[$i 2][1].';');
                            }
                        }
                    }
                }
                if (
$packageHandle === null) {
                    
$packageHandle basename($packageDirectory);
                }
            } else {
                foreach (
Package::getAvailablePackages(false) as $pkg) {
                    if (
strcasecmp($p$pkg->getPackageHandle()) === 0) {
                        
$packageHandle $pkg->getPackageHandle();
                        
$packageDirectory $pkg->getPackagePath();
                        
$packageVersion $pkg->getPackageVersion();
                        break;
                    }
                }
                if (
$packageHandle === null) {
                    throw new 
Exception("Unable to find a package with handle '$p'");
                }
            }
            
$packageLanguagesDirectory $packageDirectory.'/'.DIRNAME_LANGUAGES;

            
// Determine the locales to translate
            
$locales = array();
            
$localeOption $input->getOption('locale');
            if (
in_array('-'$localeOptiontrue)) {
                
// We don't want any locale
            
} elseif (empty($localeOption)) {
                
// List the currently package locales
                
foreach ($fh->getDirectoryContents($packageLanguagesDirectory) as $item) {
                    if (
is_file("$packageLanguagesDirectory/$item/LC_MESSAGES/messages.mo") || is_file("$packageLanguagesDirectory/$item/LC_MESSAGES/messages.po")) {
                        
$locales[] = $item;
                    }
                }
                if (empty(
$locales)) {
                    
// Let's use the core locales
                    
$locales Localization::getAvailableInterfaceLanguages();
                }
            } else {
                
// Normalize the locales (eg from it-it to it_IT)
                
foreach ($localeOption as $lo) {
                    
$chunks = array();
                    foreach (
explode('_'str_replace('-''_'$lo)) as $index => $chunk) {
                        if (
$index === 0) {
                            
// Language (eg zh)
                            
$chunks[] = strtolower($chunk);
                        } elseif (
strlen($chunk) === 4) {
                            
// Script (eg Hans)
                            
$chunks[] = ucfirst(strtolower($chunk));
                        } else {
                            
// Territory (eg CN)
                            
$chunks[] = strtoupper($chunk);
                        }
                    }
                    
$locales[] = implode('_'$chunks);
                }
            }

            
// Initialize the master translations file (.pot)
            
$pot = new Translations();
            
$pot->setHeader('Project-Id-Version'"$packageHandle $packageVersion");
            
$pot->setLanguage('en_US');
            
$pot->setHeader('Report-Msgid-Bugs-To'$input->getOption('contact'));
            
$pot->setHeader('Last-Translator'$input->getOption('translator'));

            
// Parse the package directory
            
$output->writeln('Parsing package contents');
            foreach (
C5TLParser::getAllParsers() as $parser) {
                if (
$parser->canParseDirectory()) {
                    
$output->write('- running parser "' $parser->getParserName() . '"... ');
                    
$parser->parseDirectory(
                        
$packageDirectory,
                        
"packages/$packageHandle",
                        
$pot,
                        
false,
                        
$input->getOption('exclude-3rdparty')
                    );
                    
$output->writeln('<info>done.</info>');
                }
            }

            
// Save the pot file
            
$output->write('Saving .pot file... ');
            if (!
is_dir($packageLanguagesDirectory)) {
                @
mkdir($packageLanguagesDirectory0775true);
                if (!
is_dir($packageLanguagesDirectory)) {
                    throw new 
Exception("Unable to create the directory $packageLanguagesDirectory");
                }
            }
            
$potFilename "$packageLanguagesDirectory/messages.pot";
            if (
$pot->toPoFile($potFilename) === false) {
                throw new 
Exception("Unable to save the .pot file to $potFilename");
            }
            
$output->writeln('<info>done.</info>');

            
// Creating/updating the locale files
            
foreach ($locales as $locale) {
                
$output->writeln("Working on locale $locale");
                
$poDirectory "$packageLanguagesDirectory/$locale/LC_MESSAGES";
                
$po = clone $pot;
                
$po->setLanguage($locale);
                
$poFile "$poDirectory/messages.po";
                
$moFile "$poDirectory/messages.mo";
                if (
is_file($poFile)) {
                    
$output->write("- reading current .po file... ");
                    
$oldPo Translations::fromPoFile($poFile);
                    
$output->writeln('<info>done.</info>');
                } elseif (
is_file($moFile)) {
                    
$output->write("- decompiling current .mo file... ");
                    
$oldPo Translations::fromMoFile($poFile);
                    
$output->writeln('<info>done.</info>');
                } else {
                    
$oldPo null;
                }
                if (
$oldPo !== null) {
                    
$output->write("- merging translations... ");
                    
$po->mergeWith($oldPo0);
                    
$output->writeln('<info>done.</info>');
                }
                
$output->write("- saving .po file... ");
                if (!
is_dir($poDirectory)) {
                    @
mkdir($poDirectory0775true);
                    if (!
is_dir($poDirectory)) {
                        throw new 
Exception("Unable to create the directory $poDirectory");
                    }
                }
                
$po->toPoFile($poFile);
                
$output->writeln('<info>done.</info>');
                
$output->write("- saving .mo file... ");
                
$po->toMoFile($moFile);
                
$output->writeln('<info>done.</info>');
            }
        } catch (
Exception $x) {
            
$output->writeln('<error>'.$x->getMessage().'</error>');
            
$rc 1;
        }

        return 
$rc;
    }
}
Онлайн: 4
Реклама