Вход Регистрация
Файл: concrete5.7.5.6/concrete/vendor/mlocati/concrete5-translation-library/src/Parser/Php.php
Строк: 333
<?php

namespace C5TLParser;

/**
 * Extract translatable strings from PHP files (functions t(), tc() and t2()).
 */
class Php extends C5TLParser
{
    
/**
     * @see C5TLParser::getParserName()
     */
    
public function getParserName()
    {
        return 
function_exists('t') ? t('PHP Parser') : 'PHP Parser';
    }

    
/**
     * @see C5TLParser::canParseDirectory()
     */
    
public function canParseDirectory()
    {
        return 
true;
    }

    
/**
     * @see C5TLParser::parseDirectoryDo()
     */
    
protected function parseDirectoryDo(GettextTranslations $translations$rootDirectory$relativePath$subParsersFilter$exclude3rdParty)
    {
        
$phpFiles = array();
        foreach (
array_merge(array(''), $this->getDirectoryStructure($rootDirectory$exclude3rdParty)) as $child) {
            
$fullDirectoryPath = ($child === '') ? $rootDirectory "$rootDirectory/$child";
            
$contents = @scandir($fullDirectoryPath);
            if (
$contents === false) {
                throw new 
Exception("Unable to parse directory $fullDirectoryPath");
            }
            foreach (
$contents as $file) {
                if (
$file[0] !== '.') {
                    
$fullFilePath "$fullDirectoryPath/$file";
                    if (
preg_match('/^(.*).php$/i'$file) && is_file($fullFilePath)) {
                        
$phpFiles[] = ($child === '') ? $file "$child/$file";
                    }
                }
            }
        }
        if (
count($phpFiles) > 0) {
            if (
C5TLGettext::commandIsAvailable('xgettext')) {
                
$newTranslations = static::parseDirectoryDo_xgettext($rootDirectory$phpFiles);
            } else {
                
$newTranslations = static::parseDirectoryDo_php($rootDirectory$phpFiles);
            }
            if (
$newTranslations->count() > 0) {
                if (
$relativePath !== '') {
                    foreach (
$newTranslations as $newTranslation) {
                        static::
fixExtractedComments($newTranslation);
                        
$references $newTranslation->getReferences();
                        
$newTranslation->deleteReferences();
                        foreach (
$references as $reference) {
                            
$newTranslation->addReference($relativePath.'/'.$reference[0], $reference[1]);
                        }
                        
$translations[] = $newTranslation;
                    }
                } else {
                    foreach (
$newTranslations as $newTranslation) {
                        static::
fixExtractedComments($newTranslation);
                        
$translations[] = $newTranslation;
                    }
                }
            }
        }
    }

    protected static function 
fixExtractedComments(GettextTranslation $translation)
    {
        
$extractedComments $translation->getExtractedComments();
        
$n count($extractedComments);
        if (
$n 0) {
            
$m null;
            
$translation->deleteExtractedComments();
            foreach (
$extractedComments as $extractedComment) {
                if (
preg_match('/^s*i18n:?s*(.*)s*$/s'$extractedComment$m)) {
                    
$translation->addExtractedComment($m[1]);
                } else {
                    
$translation->addExtractedComment($extractedComment);
                }
            }
        }
    }

    
/**
     * Extracts translatable strings from PHP files with xgettext.
     *
     * @param string        $rootDirectory The base root directory
     * @param array[string] $phpFiles      The relative paths to the PHP files to be parsed
     *
     * @throws Exception Throws an Exception in case of problems
     *
     * @return GettextTranslations
     */
    
protected static function parseDirectoryDo_xgettext($rootDirectory$phpFiles)
    {
        
$initialDirectory = @getcwd();
        if (
$initialDirectory === false) {
            throw new 
Exception('Unable to determine the current working directory');
        }
        if (@
chdir($rootDirectory) === false) {
            throw new 
Exception('Unable to switch to directory '.$rootDirectory);
        }
        try {
            
$tempDirectory C5TLOptions::getTemporaryDirectory();
            
$tempFileList = @tempnam($tempDirectory'cil');
            if (
$tempFileList === false) {
                throw new 
Exception(t('Unable to create a temporary file'));
            }
            if (@
file_put_contents($tempFileListimplode("n"$phpFiles)) === false) {
                global 
$php_errormsg;
                if (isset(
$php_errormsg) && $php_errormsg) {
                    throw new 
Exception("Error writing a temporary file: $php_errormsg");
                } else {
                    throw new 
Exception('Error writing a temporary file');
                }
            }
            
$tempFilePot = @tempnam($tempDirectory'cil');
            if (
$tempFilePot === false) {
                throw new 
Exception(t('Unable to create a temporary file'));
            }
            
$line 'xgettext';
            
$line .= ' --default-domain=messages'// Domain
            
$line .= ' --output='.escapeshellarg(basename($tempFilePot)); // Output .pot file name
            
$line .= ' --output-dir='.escapeshellarg(dirname($tempFilePot)); // Output .pot folder name
            
$line .= ' --language=PHP'// Source files are in php
            
$line .= ' --from-code=UTF-8'// Source files are in utf-8
            
$line .= ' --add-comments=i18n'// Place comment blocks preceding keyword lines in output file if they start with '// i18n: '
            
$line .= ' --keyword'// Don't use default keywords
            
$line .= ' --keyword=t:1'// Look for the first argument of the "t" function for extracting translatable text in singular form
            
$line .= ' --keyword=t2:1,2'// Look for the first and second arguments of the "t2" function for extracting both the singular and plural forms
            
$line .= ' --keyword=tc:1c,2'// Look for the first argument of the "tc" function for extracting translation context, and the second argument is the translatable text in singular form.
            
$line .= ' --no-escape'// Do not use C escapes in output
            
$line .= ' --add-location'// Generate '#: filename:line' lines
            
$line .= ' --files-from='.escapeshellarg($tempFileList); // Get list of input files from file
            
$line .= ' 2>&1';
            
$output = array();
            
$rc null;
            @
exec($line$output$rc);
            @
unlink($tempFileList);
            unset(
$tempFileList);
            if (!
is_int($rc)) {
                
$rc = -1;
            }
            if (!
is_array($output)) {
                
$output = array();
            }
            if (
$rc !== 0) {
                throw new 
Exception('xgettext failed: '.implode("n"$output));
            }
            
$newTranslations GettextTranslations::fromPoFile($tempFilePot);
            @
unlink($tempFilePot);
            unset(
$tempFilePot);
        } catch (
Exception $x) {
            @
chdir($initialDirectory);
            if (isset(
$tempFilePot) && @is_file($tempFilePot)) {
                @
unlink($tempFilePot);
            }
            if (isset(
$tempFileList) && @is_file($tempFileList)) {
                @
unlink($tempFileList);
            }
            throw 
$x;
        }

        return 
$newTranslations;
    }

    
/**
     * Extracts translatable strings from PHP files with xgettext.
     *
     * @param string        $rootDirectory The base root directory
     * @param array[string] $phpFiles      The relative paths to the PHP files to be parsed
     *
     * @throws Exception Throws an Exception in case of problems
     *
     * @return GettextTranslations
     */
    
protected static function parseDirectoryDo_php($rootDirectory$phpFiles)
    {
        
$prefix $rootDirectory.'/';
        
$originalFunctions GettextExtractorsPhpCode::$functions;
        
GettextExtractorsPhpCode::$functions['t'] = '__';
        
GettextExtractorsPhpCode::$functions['t2'] = 'n__';
        
GettextExtractorsPhpCode::$functions['tc'] = 'p__';
        try {
            
$absFiles array_map(
                function (
$phpFile) use ($prefix) {
                    return 
$prefix.$phpFile;
                },
                
$phpFiles
            
);
            
$newTranslations GettextTranslations::fromPhpCodeFile($absFiles);
            
GettextExtractorsPhpCode::$functions $originalFunctions;
        } catch (
Exception $x) {
            
GettextExtractorsPhpCode::$functions $originalFunctions;
            throw 
$x;
        }

        
$startAt strlen($prefix);
        foreach (
$newTranslations as $newTranslation) {
            
$references $newTranslation->getReferences();
            
$newTranslation->deleteReferences();
            foreach (
$references as $reference) {
                
$newTranslation->addReference(substr($reference[0], $startAt), $reference[1]);
            }
        }

        return 
$newTranslations;
    }
}
Онлайн: 1
Реклама