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

namespace Punic;

/**
 * Territory-related stuff.
 */
class Territory
{
    
/**
     * Retrieve the name of a territory (country, continent, ...).
     *
     * @param string $territoryCode The territory code
     * @param string $locale The locale to use. If empty we'll use the default locale set in PunicData
     *
     * @return string Returns the localized territory name (returns $territoryCode if not found)
     */
    
public static function getName($territoryCode$locale '')
    {
        
$result $territoryCode;
        if (
preg_match('/^[a-z0-9]{2,3}$/i'$territoryCode)) {
            
$territoryCode strtoupper($territoryCode);
            
$data Data::get('territories'$locale);
            if (isset(
$data[$territoryCode])) {
                
$result $data[$territoryCode];
            }
        }

        return 
$result;
    }

    
/**
     * Return the list of continents in the form of an array with key=ID, value=name.
     *
     * @param string $locale The locale to use. If empty we'll use the default locale set in PunicData
     *
     * @return array
     */
    
public static function getContinents($locale '')
    {
        return static::
getList('C'$locale);
    }

    
/**
     * Return the list of countries in the form of an array with key=ID, value=name.
     *
     * @param string $locale The locale to use. If empty we'll use the default locale set in PunicData
     *
     * @return array
     */
    
public static function getCountries($locale '')
    {
        return static::
getList('c'$locale);
    }

    
/**
     * Return a list of continents and relative countries. The resulting array is in the following form (JSON representation):
     * ```json
     * {
     *     "002": {
     *         "name": "Africa",
     *         "children": {
     *             "DZ": {"name": "Algeria"},
     *             "AO": {"name": "Angola"},
     *             ...
     *         }
     *     },
     *     "150": {
     *         "name": "Europe",
     *         "children": {
     *             "AL": {"name": "Albania"},
     *             "AD": {"name": "Andorra"},
     *             ...
     *         }
     *     }
     *     ...
     * }
     * ```
     * The arrays are sorted by territory name.
     *
     * @param string $locale The locale to use. If empty we'll use the default locale set in PunicData
     *
     * @return array
     */
    
public static function getContinentsAndCountries($locale '')
    {
        return static::
getList('Cc'$locale);
    }

    
/**
     * Return a list of some specified territory, structured or not.
     * $levels control which data you want to retrieve. It can be one or more of the following values:
     * <ul>
     *     <li>'W': world</li>
     *     <li>'C': continents</li>
     *     <li>'S': sub-continents</li>
     *     <li>'c': countries</li>
     * </ul>
     * If only one level is specified you'll get a flat list (like the one returned by {@link getContinents}).
     * If one or more levels are specified, you'll get a structured list (like the one returned by {@link getContinentsAndCountries}).
     *
     * @param string $levels A string with one or more of the characters: 'W' (for world), 'C' (for continents), 'S' (for sub-continents), 'c' (for countries)
     * @param string $locale The locale to use. If empty we'll use the default locale set in PunicData
     *
     * @return array
     *
     * @link http://www.unicode.org/cldr/charts/latest/supplemental/territory_containment_un_m_49.html
     *
     * @throws ExceptionBadArgumentType
     */
    
public static function getList($levels 'W'$locale '')
    {
        static 
$levelMap = array('W' => 0'C' => 1'S' => 2'c' => 3);
        
$decodedLevels = array();
        
$n is_string($levels) ? strlen($levels) : 0;
        if (
$n 0) {
            for (
$i 0$i $n; ++$i) {
                
$l substr($levels$i1);
                if (!isset(
$levelMap[$l])) {
                    
$decodedLevels = array();
                    break;
                }
                if (!
in_array($levelMap[$l], $decodedLevelstrue)) {
                    
$decodedLevels[] = $levelMap[$l];
                }
            }
        }
        if (
count($decodedLevels) === 0) {
            throw new 
PunicExceptionBadArgumentType($levels"list of territory kinds: it should be a list of one or more of the codes '".implode("', '"array_keys($levelMap))."'");
        }
        
$struct self::filterStructure(self::getStructure(), $decodedLevels0);
        
$flatList = (count($decodedLevels) > 1) ? false true;
        
$finalized self::finalizeWithNames(Data::get('territories'$locale), $struct$flatList);

        if (
$flatList) {
            
$sorter = new PunicComparer();
            
$sorter->sort($finalizedtrue);
        } else {
            
$finalized = static::sort($finalized);
        }

        return 
$finalized;
    }

    
/**
     * Return a list of territory identifiers for which we have some info (languages, population, literacy level, Gross Domestic Product).
     *
     * @return array The list of territory IDs for which we have some info
     */
    
public static function getTerritoriesWithInfo()
    {
        return 
array_keys(Data::getGeneric('territoryInfo'));
    }

    
/**
     * Return the list of languages spoken in a territory.
     *
     * @param string $territoryCode The territory code
     * @param string $filterStatuses Filter language status.
     * <ul>
     *     <li>If empty no filter will be applied</li>
     *     <li>'o' to include official languages</li>
     *     <li>'r' to include official regional languages</li>
     *     <li>'f' to include de facto official languages</li>
     *     <li>'m' to include official minority languages</li>
     *     <li>'u' to include unofficial or unknown languages</li>
     * </ul>
     * @param string $onlyCodes Set to true to retrieve only the language codes. If set to false (default) you'll receive a list of arrays with these keys:
     * <ul>
     *     <li>string id: the language identifier</li>
     *     <li>string status: 'o' for official; 'r' for official regional; 'f' for de facto official; 'm' for official minority; 'u' for unofficial or unknown</li>
     *     <li>number population: the amount of people speaking the language (%)</li>
     *     <li>number|null writing: the amount of people able to write (%). May be null if no data is available</li>
     * </ul>
     *
     * @return array|null Return the languages spoken in the specified territory, as described by the $onlyCodes parameter (or null if $territoryCode is not valid or no data is available)
     */
    
public static function getLanguages($territoryCode$filterStatuses ''$onlyCodes false)
    {
        
$result null;
        
$info self::getTerritoryInfo($territoryCode);
        if (
is_array($info)) {
            
$result = array();
            foreach (
$info['languages'] as $languageID => $languageInfo) {
                if (!isset(
$languageInfo['status'])) {
                    
$languageInfo['status'] = 'u';
                }
                if ((
strlen($filterStatuses) === 0) || (stripos($filterStatuses$languageInfo['status']) !== false)) {
                    if (!isset(
$languageInfo['writing'])) {
                        
$languageInfo['writing'] = null;
                    }
                    if (
$onlyCodes) {
                        
$result[] = $languageID;
                    } else {
                        
$result[] = array_merge(array('id' => $languageID), $languageInfo);
                    }
                }
            }
        }

        return 
$result;
    }

    
/**
     * Return the population of a specific territory.
     *
     * @param string $territoryCode The territory code
     *
     * @return number|null Return the size of the population of the specified territory (or null if $territoryCode is not valid or no data is available)
     */
    
public static function getPopulation($territoryCode)
    {
        
$result null;
        
$info self::getTerritoryInfo($territoryCode);
        if (
is_array($info)) {
            
$result $info['population'];
        }

        return 
$result;
    }

    
/**
     * Return the literacy level for a specific territory, in %.
     *
     * @param string $territoryCode The territory code
     *
     * @return number|null Return the % of literacy lever of the specified territory (or null if $territoryCode is not valid or no data is available)
     */
    
public static function getLiteracyLevel($territoryCode)
    {
        
$result null;
        
$info self::getTerritoryInfo($territoryCode);
        if (
is_array($info)) {
            
$result $info['literacy'];
        }

        return 
$result;
    }

    
/**
     * Return the GDP (Gross Domestic Product) for a specific territory, in US$.
     *
     * @param string $territoryCode The territory code
     *
     * @return number|null Return the GDP of the specified territory (or null if $territoryCode is not valid or no data is available)
     */
    
public static function getGrossDomesticProduct($territoryCode)
    {
        
$result null;
        
$info self::getTerritoryInfo($territoryCode);
        if (
is_array($info)) {
            
$result $info['gdp'];
        }

        return 
$result;
    }

    
/**
     * Return a list of territory IDs where a specific language is spoken, sorted by the total number of people speaking that language.
     *
     * @param string $languageID The language identifier
     *
     * @return array
     */
    
public static function getTerritoriesForLanguage($languageID)
    {
        
$langPeople = array();
        foreach (
Data::getGeneric('territoryInfo') as $territoryID => $territoryInfo) {
            foreach (
$territoryInfo['languages'] as $langID => $langInfo) {
                if ((
strcasecmp($languageID$langID) === 0) || (stripos($langID$languageID.'_') === 0)) {
                    
$langPeople[] = array('territoryID' => $territoryID'people' => $territoryInfo['population'] * $langInfo['population']);
                }
            }
        }
        
usort($langPeople, function ($a$b) {
               
$delta $a['people'] - $b['people'];
               if (
$delta != 0) {
                   
$result = ($delta 0) ? -1;
               } else {
                   
$result strcmp($a['territoryID'], $b['territoryID']);
               }

               return 
$result;
        });
        
$territoryIDs = array();
        foreach (
$langPeople as $lp) {
            
$territoryIDs[] = $lp['territoryID'];
        }

        return 
$territoryIDs;
    }

    
/**
     * Return the code of the territory that contains a territory.
     *
     * @param string $childTerritoryCode
     *
     * @return string Return the parent territory code, or an empty string if $childTerritoryCode is the World (001) or if it's invalid.
     */
    
public static function getParentTerritoryCode($childTerritoryCode)
    {
        
$result '';
        if (
is_string($childTerritoryCode) && preg_match('/^[a-z0-9]{2,3}$/i'$childTerritoryCode)) {
            
$childTerritoryCode strtoupper($childTerritoryCode);
            foreach (
Data::getGeneric('territoryContainment') as $parentTerritoryCode => $parentTerritoryInfo) {
                if (
in_array($childTerritoryCode$parentTerritoryInfo['contains'], true)) {
                    
$result is_int($parentTerritoryCode) ? substr('00'.$parentTerritoryCode, -3) : $parentTerritoryCode;
                    if ((
$result === '001') || (strlen(static::getParentTerritoryCode($result)) > 0)) {
                        break;
                    }
                }
            }
        }

        return 
$result;
    }

    
/**
     * Retrieve the child territories of a parent territory.
     *
     * @param string $parentTerritoryCode
     * @param bool $expandSubGroups Set to true to expand the sub-groups, false to retrieve them.
     *
     * @return array Return the list of territory codes that are children of $parentTerritoryCode (if $parentTerritoryCode is invalid you'll get an empty list)
     */
    
public static function getChildTerritoryCodes($parentTerritoryCode$expandSubGroups false)
    {
        
$result = array();
        if (
is_string($parentTerritoryCode) && preg_match('/^[a-z0-9]{2,3}$/i'$parentTerritoryCode)) {
            
$parentTerritoryCode strtoupper($parentTerritoryCode);
            
$data Data::getGeneric('territoryContainment');
            if (isset(
$data[$parentTerritoryCode])) {
                
$children $data[$parentTerritoryCode]['contains'];
                if (
$expandSubGroups) {
                    foreach (
$children as $child) {
                        
$grandChildren = static::getChildTerritoryCodes($childtrue);
                        if (empty(
$grandChildren)) {
                            
$result[] = $child;
                        } else {
                            
$result array_merge($result$grandChildren);
                        }
                    }
                } else {
                    
$result $children;
                }
            }
        }

        return 
$result;
    }

    protected static function 
getTerritoryInfo($territoryCode)
    {
        
$result null;
        if (
preg_match('/^[a-z0-9]{2,3}$/i'$territoryCode)) {
            
$territoryCode strtoupper($territoryCode);
            
$data Data::getGeneric('territoryInfo');
            if (isset(
$data[$territoryCode])) {
                
$result $data[$territoryCode];
            }
        }

        return 
$result;
    }

    protected static function 
getStructure()
    {
        static 
$cache null;
        if (
$cache === null) {
            
$data Data::getGeneric('territoryContainment');
            
$result = static::fillStructure($data'001'0);
            
$cache $result;
        } else {
            
$result $cache;
        }

        return 
$result;
    }

    protected static function 
fillStructure($data$id$level)
    {
        
$item = array('id' => $id'level' => $level'children' => array());
        if (isset(
$data[$id])) {
            foreach (
$data[$id]['contains'] as $childID) {
                
$item['children'][] = static::fillStructure($data$childID$level 1);
            }
        }

        return 
$item;
    }

    protected static function 
finalizeWithNames($data$list$flatList)
    {
        
$result = array();
        foreach (
$list as $item) {
            
$name $data[$item['id']];
            if (
$flatList) {
                
$result[$item['id']] = $name;
            } else {
                
$result[$item['id']] = array('name' => $name);
                if (
count($item['children']) > 0) {
                    
$result[$item['id']]['children'] = static::finalizeWithNames($data$item['children'], $flatList);
                }
            }
        }

        return 
$result;
    }

    protected static function 
filterStructure($parent$levels)
    {
        
$thisResult = array();
        if (
in_array($parent['level'], $levelstrue)) {
            
$thisResult[0] = $parent;
            
$thisResult[0]['children'] = array();
            
$addToSub true;
        } else {
            
$addToSub false;
        }

        
$subList = array();
        foreach (
$parent['children'] as $child) {
            
$subList array_merge($subList, static::filterStructure($child$levels));
        }
        if (
$addToSub) {
            
$thisResult[0]['children'] = $subList;
        } else {
            
$thisResult $subList;
        }

        return 
$thisResult;
    }

    protected static function 
sort($list)
    {
        foreach (
array_keys($list) as $i) {
            if (isset(
$list[$i]['children'])) {
                
$list[$i]['children'] = static::sort($list[$i]['children']);
            }
        }
        
$sorter = new PunicComparer();
        
uasort($list, function ($a$b) use ($sorter) {
            return 
$sorter->compare($a['name'], $b['name']);
        });

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