Вход Регистрация
Файл: symfony-2.7/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
Строк: 274
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace SymfonyComponentTranslationLoader;

use 
SymfonyComponentConfigUtilXmlUtils;
use 
SymfonyComponentTranslationMessageCatalogue;
use 
SymfonyComponentTranslationExceptionInvalidResourceException;
use 
SymfonyComponentTranslationExceptionNotFoundResourceException;
use 
SymfonyComponentConfigResourceFileResource;

/**
 * XliffFileLoader loads translations from XLIFF files.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
class XliffFileLoader implements LoaderInterface
{
    
/**
     * {@inheritdoc}
     *
     * @api
     */
    
public function load($resource$locale$domain 'messages')
    {
        if (!
stream_is_local($resource)) {
            throw new 
InvalidResourceException(sprintf('This is not a local file "%s".'$resource));
        }

        if (!
file_exists($resource)) {
            throw new 
NotFoundResourceException(sprintf('File "%s" not found.'$resource));
        }

        list(
$xml$encoding) = $this->parseFile($resource);
        
$xml->registerXPathNamespace('xliff''urn:oasis:names:tc:xliff:document:1.2');

        
$catalogue = new MessageCatalogue($locale);
        foreach (
$xml->xpath('//xliff:trans-unit') as $translation) {
            
$attributes $translation->attributes();

            if (!(isset(
$attributes['resname']) || isset($translation->source)) || !isset($translation->target)) {
                continue;
            }

            
$source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
            
// If the xlf file has another encoding specified, try to convert it because
            // simple_xml will always return utf-8 encoded values
            
$target $this->utf8ToCharset((string) $translation->target$encoding);

            
$catalogue->set((string) $source$target$domain);

            if (isset(
$translation->note)) {
                
$notes = array();
                foreach (
$translation->note as $xmlNote) {
                    
$noteAttributes $xmlNote->attributes();
                    
$note = array('content' => $this->utf8ToCharset((string) $xmlNote$encoding));
                    if (isset(
$noteAttributes['priority'])) {
                        
$note['priority'] = (int) $noteAttributes['priority'];
                    }

                    if (isset(
$noteAttributes['from'])) {
                        
$note['from'] = (string) $noteAttributes['from'];
                    }

                    
$notes[] = $note;
                }

                
$catalogue->setMetadata((string) $source, array('notes' => $notes), $domain);
            }
        }
        
$catalogue->addResource(new FileResource($resource));

        return 
$catalogue;
    }

    
/**
     * Convert a UTF8 string to the specified encoding.
     *
     * @param string $content  String to decode
     * @param string $encoding Target encoding
     *
     * @return string
     */
    
private function utf8ToCharset($content$encoding null)
    {
        if (
'UTF-8' !== $encoding && !empty($encoding)) {
            if (
function_exists('mb_convert_encoding')) {
                return 
mb_convert_encoding($content$encoding'UTF-8');
            }

            if (
function_exists('iconv')) {
                return 
iconv('UTF-8'$encoding$content);
            }

            throw new 
RuntimeException('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
        }

        return 
$content;
    }

    
/**
     * Validates and parses the given file into a SimpleXMLElement.
     *
     * @param string $file
     *
     * @throws RuntimeException
     *
     * @return SimpleXMLElement
     *
     * @throws InvalidResourceException
     */
    
private function parseFile($file)
    {
        try {
            
$dom XmlUtils::loadFile($file);
        } catch (
InvalidArgumentException $e) {
            throw new 
InvalidResourceException(sprintf('Unable to load "%s": %s'$file$e->getMessage()), $e->getCode(), $e);
        }

        
$internalErrors libxml_use_internal_errors(true);

        
$location str_replace('\', '/', __DIR__).'/schema/dic/xliff-core/xml.xsd';
        $parts = explode('
/', $location);
        if (0 === stripos($location, '
phar://')) {
            
$tmpfile tempnam(sys_get_temp_dir(), 'sf2');
            if (
$tmpfile) {
                
copy($location$tmpfile);
                
$parts explode('/'str_replace('\', '/', $tmpfile));
            }
        }
        $drive = '
\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
        $location = '
file:///'.$drive.implode('/', array_map('rawurlencode', $parts));

        
$source file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-1.2-strict.xsd');
        
$source str_replace('http://www.w3.org/2001/xml.xsd'$location$source);

        if (!@
$dom->schemaValidateSource($source)) {
            throw new 
InvalidResourceException(implode("n"$this->getXmlErrors($internalErrors)));
        }

        
$dom->normalizeDocument();

        
libxml_clear_errors();
        
libxml_use_internal_errors($internalErrors);

        return array(
simplexml_import_dom($dom), strtoupper($dom->encoding));
    }

    
/**
     * Returns the XML errors of the internal XML parser.
     *
     * @param bool $internalErrors
     *
     * @return array An array of errors
     */
    
private function getXmlErrors($internalErrors)
    {
        
$errors = array();
        foreach (
libxml_get_errors() as $error) {
            
$errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
                
LIBXML_ERR_WARNING == $error->level 'WARNING' 'ERROR',
                
$error->code,
                
trim($error->message),
                
$error->file $error->file 'n/a',
                
$error->line,
                
$error->column
            
);
        }

        
libxml_clear_errors();
        
libxml_use_internal_errors($internalErrors);

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