Вход Регистрация
Файл: concrete5.7.5.6/concrete/vendor/punic/punic/code/Data.php
Строк: 528
<?php

namespace Punic;

/**
 * Common data helper stuff.
 */
class Data
{
    
/**
     * Let's cache already loaded files (locale-specific).
     *
     * @var array
     */
    
protected static $cache = array();

    
/**
     * Let's cache already loaded files (not locale-specific).
     *
     * @var array
     */
    
protected static $cacheGeneric = array();

    
/**
     * The current default locale.
     *
     * @var string
     */
    
protected static $defaultLocale 'en_US';

    
/**
     * The fallback locale (used if default locale is not found).
     *
     * @var string
     */
    
protected static $fallbackLocale 'en_US';

    
/**
     * Return the current default locale.
     *
     * @return string
     */
    
public static function getDefaultLocale()
    {
        return static::
$defaultLocale;
    }

    
/**
     * Return the current default language.
     *
     * @return string
     */
    
public static function getDefaultLanguage()
    {
        
$info = static::explodeLocale(static::$defaultLocale);

        return 
$info['language'];
    }

    
/**
     * Set the current default locale and language.
     *
     * @param string $locale
     *
     * @throws PunicExceptionInvalidLocale Throws an exception if $locale is not a valid string
     */
    
public static function setDefaultLocale($locale)
    {
        if (static::
explodeLocale($locale) === null) {
            throw new 
ExceptionInvalidLocale($locale);
        }
        static::
$defaultLocale $locale;
    }

    
/**
     * Return the current fallback locale (used if default locale is not found).
     *
     * @return string
     */
    
public static function getFallbackLocale()
    {
        return static::
$fallbackLocale;
    }

    
/**
     * Return the current fallback language (used if default locale is not found).
     *
     * @return string
     */
    
public static function getFallbackLanguage()
    {
        
$info = static::explodeLocale(static::$fallbackLocale);

        return 
$info['language'];
    }

    
/**
     * Set the current fallback locale and language.
     *
     * @param string $locale
     *
     * @throws PunicExceptionInvalidLocale Throws an exception if $locale is not a valid string
     */
    
public static function setFallbackLocale($locale)
    {
        if (static::
explodeLocale($locale) === null) {
            throw new 
ExceptionInvalidLocale($locale);
        }
        if (static::
$fallbackLocale !== $locale) {
            static::
$fallbackLocale $locale;
            static::
$cache = array();
        }
    }

    
/**
     * Get the locale data.
     *
     * @param string $identifier The data identifier
     * @param string $locale The locale identifier (if empty we'll use the current default locale)
     *
     * @return array
     *
     * @throws PunicException Throws an exception in case of problems
     *
     * @internal
     */
    
public static function get($identifier$locale '')
    {
        if (!(
is_string($identifier) && isset($identifier[0]))) {
            throw new 
ExceptionInvalidDataFile($identifier);
        }
        if (empty(
$locale)) {
            
$locale = static::$defaultLocale;
        }
        if (!isset(static::
$cache[$locale])) {
            static::
$cache[$locale] = array();
        }
        if (!isset(static::
$cache[$locale][$identifier])) {
            if (!@
preg_match('/^[a-zA-Z0-9_\-]+$/'$identifier)) {
                throw new 
ExceptionInvalidDataFile($identifier);
            }
            
$dir = static::getLocaleFolder($locale);
            if (!isset(
$dir[0])) {
                throw new 
ExceptionDataFolderNotFound($locale, static::$fallbackLocale);
            }
            
$file $dir.DIRECTORY_SEPARATOR.$identifier.'.json';
            if (!
is_file(__DIR__.DIRECTORY_SEPARATOR.$file)) {
                throw new 
ExceptionDataFileNotFound($identifier$locale, static::$fallbackLocale);
            }
            
$json = @file_get_contents(__DIR__.DIRECTORY_SEPARATOR.$file);
            
//@codeCoverageIgnoreStart
            // In test enviro we can't replicate this problem
            
if ($json === false) {
                throw new 
ExceptionDataFileNotReadable($file);
            }
            
//@codeCoverageIgnoreEnd
            
$data = @json_decode($jsontrue);
            
//@codeCoverageIgnoreStart
            // In test enviro we can't replicate this problem
            
if (!is_array($data)) {
                throw new 
ExceptionBadDataFileContents($file$json);
            }
            
//@codeCoverageIgnoreEnd
            
static::$cache[$locale][$identifier] = $data;
        }

        return static::
$cache[$locale][$identifier];
    }

    
/**
     * Get the generic data.
     *
     * @param string $identifier The data identifier
     *
     * @return array
     *
     * @throws Exception Throws an exception in case of problems
     *
     * @internal
     */
    
public static function getGeneric($identifier)
    {
        if (!(
is_string($identifier) && isset($identifier[0]))) {
            throw new 
ExceptionInvalidDataFile($identifier);
        }
        if (isset(static::
$cacheGeneric[$identifier])) {
            return static::
$cacheGeneric[$identifier];
        }
        if (!
preg_match('/^[a-zA-Z0-9_\-]+$/'$identifier)) {
            throw new 
ExceptionInvalidDataFile($identifier);
        }
        
$file 'data'.DIRECTORY_SEPARATOR."$identifier.json";
        if (!
is_file(__DIR__.DIRECTORY_SEPARATOR.$file)) {
            throw new 
ExceptionDataFileNotFound($identifier);
        }
        
$json = @file_get_contents(__DIR__.DIRECTORY_SEPARATOR.$file);
        
//@codeCoverageIgnoreStart
        // In test enviro we can't replicate this problem
        
if ($json === false) {
            throw new 
ExceptionDataFileNotReadable($file);
        }
        
//@codeCoverageIgnoreEnd
        
$data = @json_decode($jsontrue);
        
//@codeCoverageIgnoreStart
        // In test enviro we can't replicate this problem
        
if (!is_array($data)) {
            throw new 
ExceptionBadDataFileContents($file$json);
        }
        
//@codeCoverageIgnoreEnd
        
static::$cacheGeneric[$identifier] = $data;

        return 
$data;
    }

    
/**
     * Return a list of available locale identifiers.
     *
     * @param bool $allowGroups Set to true if you want to retrieve locale groups (eg. 'en-001'), false otherwise
     *
     * @return array
     */
    
public static function getAvailableLocales($allowGroups false)
    {
        
$locales = array();
        
$dir __DIR__.DIRECTORY_SEPARATOR.'data';
        if (
is_dir($dir) && is_readable($dir)) {
            
$contents = @scandir($dir);
            if (
is_array($contents)) {
                foreach (
array_diff($contents, array('.''..')) as $item) {
                    if (
is_dir($dir.DIRECTORY_SEPARATOR.$item)) {
                        if (
$item === 'root') {
                            
$item 'en-US';
                        }
                        
$info = static::explodeLocale($item);
                        if (
is_array($info)) {
                            if ((!
$allowGroups) && preg_match('/^[0-9]{3}$/'$info['territory'])) {
                                foreach (
Territory::getChildTerritoryCodes($info['territory'], true) as $territory) {
                                    if (isset(
$info['script'][0])) {
                                        
$locales[] = "{$info['language']}-{$info['script']}-$territory";
                                    } else {
                                        
$locales[] = "{$info['language']}-$territory";
                                    }
                                }
                                
$locales[] = $item;
                            } else {
                                
$locales[] = $item;
                            }
                        }
                    }
                }
            }
        }

        return 
$locales;
    }

    
/**
     * Try to guess the full locale (with script and territory) ID associated to a language.
     *
     * @param string $language The language identifier (if empty we'll use the current default language)
     * @param string $script The script identifier (if $language is empty we'll use the current default script)
     *
     * @return string Returns an empty string if the territory was not found, the territory ID otherwise
     */
    
public static function guessFullLocale($language ''$script '')
    {
        
$result '';
        if (empty(
$language)) {
            
$defaultInfo = static::explodeLocale(static::$defaultLocale);
            
$language $defaultInfo['language'];
            
$script $defaultInfo['script'];
        }
        
$data = static::getGeneric('likelySubtags');
        
$keys = array();
        if (!empty(
$script)) {
            
$keys[] = "$language-$script";
        }
        
$keys[] = $language;
        foreach (
$keys as $key) {
            if (isset(
$data[$key])) {
                
$result $data[$key];
                if (isset(
$script[0]) && (stripos($result"$language-$script-") !== 0)) {
                    
$parts = static::explodeLocale($result);
                    if (
$parts !== null) {
                        
$result "{$parts['language']}-$script-{$parts['territory']}";
                    }
                }
                break;
            }
        }

        return 
$result;
    }

    
/**
     * Return the terrotory associated to the locale (guess it if it's not present in $locale).
     *
     * @param string $locale The locale identifier (if empty we'll use the current default locale)
     * @param bool $checkFallbackLocale Set to true to check the fallback locale if $locale (or the default locale) don't have an associated territory, false to don't fallback to fallback locale
     *
     * @return string
     */
    
public static function getTerritory($locale ''$checkFallbackLocale true)
    {
        
$result '';
        if (empty(
$locale)) {
            
$locale = static::$defaultLocale;
        }
        
$info = static::explodeLocale($locale);
        if (
is_array($info)) {
            if (!isset(
$info['territory'][0])) {
                
$fullLocale = static::guessFullLocale($info['language'], $info['script']);
                if (
strlen($fullLocale)) {
                    
$info = static::explodeLocale($fullLocale);
                }
            }
            if (isset(
$info['territory'][0])) {
                
$result $info['territory'];
            } elseif (
$checkFallbackLocale) {
                
$result = static::getTerritory(static::$fallbackLocalefalse);
            }
        }

        return 
$result;
    }

    
/**
     * @deprecated
     */
    
protected static function getParentTerritory($territory)
    {
        return 
Territory::getParentTerritoryCode($territory);
    }

    
/**
     * @deprecated
     */
    
protected static function expandTerritoryGroup($parentTerritory)
    {
        return 
Territory::getChildTerritoryCodes($parentTerritorytrue);
    }

    
/**
     * Return the node associated to the locale territory.
     *
     * @param array $data The parent array for which you want the territory node
     * @param string $locale The locale identifier (if empty we'll use the current default locale)
     *
     * @return mixed Returns null if the node was not found, the node data otherwise
     *
     * @internal
     */
    
public static function getTerritoryNode($data$locale '')
    {
        
$result null;
        
$territory = static::getTerritory($locale);
        while (isset(
$territory[0])) {
            if (isset(
$data[$territory])) {
                
$result $data[$territory];
                break;
            }
            
$territory Territory::getParentTerritoryCode($territory);
        }

        return 
$result;
    }

    
/**
     * Return the node associated to the language (not locale) territory.
     *
     * @param array $data The parent array for which you want the language node
     * @param string $locale The locale identifier (if empty we'll use the current default locale)
     *
     * @return mixed Returns null if the node was not found, the node data otherwise
     *
     * @internal
     */
    
public static function getLanguageNode($data$locale '')
    {
        
$result null;
        if (empty(
$locale)) {
            
$locale = static::$defaultLocale;
        }
        foreach (static::
getLocaleAlternatives($locale) as $l) {
            if (isset(
$data[$l])) {
                
$result $data[$l];
                break;
            }
        }

        return 
$result;
    }

    
/**
     * Returns the item of an array associated to a locale.
     *
     * @param array $data The data containing the locale info
     * @param string $locale The locale identifier (if empty we'll use the current default locale)
     *
     * @return mixed Returns null if $data is not an array or it does not contain locale info, the array item otherwise
     *
     * @internal
     */
    
public static function getLocaleItem($data$locale '')
    {
        
$result null;
        if (
is_array($data)) {
            if (empty(
$locale)) {
                
$locale = static::$defaultLocale;
            }
            foreach (static::
getLocaleAlternatives($locale) as $alternative) {
                if (isset(
$data[$alternative])) {
                    
$result $data[$alternative];
                    break;
                }
            }
        }

        return 
$result;
    }

    
/**
     * Parse a string representing a locale and extract its components.
     *
     * @param string $locale
     *
     * @return null|string[] Return null if $locale is not valid; if $locale is valid returns an array with keys 'language', 'script', 'territory', 'parentLocale'
     *
     * @internal
     */
    
public static function explodeLocale($locale)
    {
        
$result null;
        if (
is_string($locale)) {
            if (
$locale === 'root') {
                
$locale 'en-US';
            }
            
$chunks explode('-'str_replace('_''-'strtolower($locale)));
            if (
count($chunks) <= 3) {
                if (
preg_match('/^[a-z]{2,3}$/'$chunks[0])) {
                    
$language $chunks[0];
                    
$script '';
                    
$territory '';
                    
$parentLocale '';
                    
$ok true;
                    
$chunkCount count($chunks);
                    for (
$i 1$ok && ($i $chunkCount); ++$i) {
                        if (
preg_match('/^[a-z]{4}$/'$chunks[$i])) {
                            if (isset(
$script[0])) {
                                
$ok false;
                            } else {
                                
$script ucfirst($chunks[$i]);
                            }
                        } elseif (
preg_match('/^([a-z]{2})|([0-9]{3})$/'$chunks[$i])) {
                            if (isset(
$territory[0])) {
                                
$ok false;
                            } else {
                                
$territory strtoupper($chunks[$i]);
                            }
                        } else {
                            
$ok false;
                        }
                    }
                    if (
$ok) {
                        
$parentLocales = static::getGeneric('parentLocales');
                        if (isset(
$script[0]) && isset($territory[0]) && isset($parentLocales["$language-$script-$territory"])) {
                            
$parentLocale $parentLocales["$language-$script-$territory"];
                        } elseif (isset(
$script[0]) && isset($parentLocales["$language-$script"])) {
                            
$parentLocale $parentLocales["$language-$script"];
                        } elseif (isset(
$territory[0]) && isset($parentLocales["$language-$territory"])) {
                            
$parentLocale $parentLocales["$language-$territory"];
                        } elseif (isset(
$parentLocales[$language])) {
                            
$parentLocale $parentLocales[$language];
                        }
                        
$result = array(
                            
'language' => $language,
                            
'script' => $script,
                            
'territory' => $territory,
                            
'parentLocale' => $parentLocale,
                        );
                    }
                }
            }
        }

        return 
$result;
    }

    
/**
     * Returns the path of the locale-specific data, looking also for the fallback locale.
     *
     * @param string $locale The locale for which you want the data folder
     *
     * @return string Returns an empty string if the folder is not found, the absolute path to the folder otherwise
     */
    
protected static function getLocaleFolder($locale)
    {
        static 
$cache = array();
        
$result '';
        if (
is_string($locale)) {
            
$key $locale.'/'.static::$fallbackLocale;
            if (!isset(
$cache[$key])) {
                foreach (static::
getLocaleAlternatives($locale) as $alternative) {
                    
$dir 'data'.DIRECTORY_SEPARATOR.$alternative;
                    if (
is_dir(__DIR__.DIRECTORY_SEPARATOR.$dir)) {
                        
$result $dir;
                        break;
                    }
                }
                
$cache[$key] = $result;
            }
            
$result $cache[$key];
        }

        return 
$result;
    }

    
/**
     * Returns a list of locale identifiers associated to a locale.
     *
     * @param string $locale The locale for which you want the alternatives
     * @param string $addFallback Set to true to add the fallback locale to the result, false otherwise
     *
     * @return array
     */
    
protected static function getLocaleAlternatives($locale$addFallback true)
    {
        
$result = array();
        
$localeInfo = static::explodeLocale($locale);
        if (!
is_array($localeInfo)) {
            throw new 
ExceptionInvalidLocale($locale);
        }
        
$language $localeInfo['language'];
        
$script $localeInfo['script'];
        
$territory $localeInfo['territory'];
        
$parentLocale $localeInfo['parentLocale'];
        if (!isset(
$territory[0])) {
            
$fullLocale = static::guessFullLocale($language$script);
            if (isset(
$fullLocale[0])) {
                
$localeInfo = static::explodeLocale($fullLocale);
                
$language $localeInfo['language'];
                
$script $localeInfo['script'];
                
$territory $localeInfo['territory'];
                
$parentLocale $localeInfo['parentLocale'];
            }
        }
        
$territories = array();
        while (isset(
$territory[0])) {
            
$territories[] = $territory;
            
$territory Territory::getParentTerritoryCode($territory);
        }
        if (isset(
$script[0])) {
            foreach (
$territories as $territory) {
                
$result[] = "{$language}-{$script}-{$territory}";
            }
        }
        if (isset(
$script[0])) {
            
$result[] = "{$language}-{$script}";
        }
        foreach (
$territories as $territory) {
            
$result[] = "{$language}-{$territory}";
            if (
"{$language}-{$territory}=== 'en-US') {
                
$result[] = 'root';
            }
        }
        if (isset(
$parentLocale[0])) {
            
$result array_merge($result, static::getLocaleAlternatives($parentLocalefalse));
        }
        
$result[] = $language;
        if (
$addFallback && ($locale !== static::$fallbackLocale)) {
            
$result array_merge($result, static::getLocaleAlternatives(static::$fallbackLocalefalse));
        }
        for (
$i count($result) - 1$i 1; --$i) {
            for (
$j 0$j $i; ++$j) {
                if (
$result[$i] === $result[$j]) {
                    
array_splice($result$i1);
                    break;
                }
            }
        }
        
$i array_search('root'$resulttrue);
        if (
$i !== false) {
            
array_splice($result$i1);
            
$result[] = 'root';
        }

        return 
$result;
    }
}
Онлайн: 2
Реклама