Exemple #1
0
/**
 * Recursively generates subdivision definitions.
 */
function generate_subdivisions($countryCode, array $parents, $subdivisionPaths, $languages)
{
    $group = build_group($parents);
    $subdivisions = [];
    foreach ($subdivisionPaths as $subdivisionPath) {
        $definition = file_get_contents('raw/' . $subdivisionPath . '.json');
        $definition = json_decode($definition, true);
        // The lname is usable as a latin code when the key is non-latin.
        $code = $definition['key'];
        if (isset($definition['lname'])) {
            $code = $definition['lname'];
        }
        if (!isset($subdivisions[$group])) {
            $subdivisions[$group] = ['country_code' => $countryCode, 'parents' => $parents, 'locale' => ''];
            if (isset($definition['lang']) && isset($definition['lname'])) {
                // Only add the locale if there's a local name.
                $subdivisions[$group]['locale'] = process_locale($definition['lang']);
            }
            if (count($subdivisions[$group]['parents']) < 2) {
                // A single parent is the same as the country code.
                unset($subdivisions[$group]['parents']);
            }
        }
        // (Ab)use the local_name field to hold latin translations. This allows
        // us to support only a single translation, but since our only example
        // here is Canada (with French), it will do.
        $translationLanguage = reset($languages);
        if ($translationLanguage) {
            $translation = file_get_contents('raw/' . $subdivisionPath . '--' . $translationLanguage . '.json');
            $translation = json_decode($translation, true);
            $subdivisions[$group]['locale'] = LocaleHelper::canonicalize($translationLanguage);
            $definition['lname'] = $definition['name'];
            $definition['name'] = $translation['name'];
        }
        // Remove the locale key if it wasn't filled.
        if (empty($subdivisions[$group]['locale'])) {
            unset($subdivisions[$group]['locale']);
        }
        // Generate the subdivision.
        $subdivisions[$group]['subdivisions'][$code] = create_subdivision_definition($countryCode, $definition);
        if (isset($definition['sub_keys'])) {
            $subdivisions[$group]['subdivisions'][$code]['has_children'] = true;
            $subdivisionChildrenPaths = [];
            $subdivisionChildrenKeys = explode('~', $definition['sub_keys']);
            foreach ($subdivisionChildrenKeys as $subdivisionChildrenKey) {
                $subdivisionChildrenPaths[] = $subdivisionPath . '_' . $subdivisionChildrenKey;
            }
            $childParents = array_merge($parents, [$code]);
            $subdivisions += generate_subdivisions($countryCode, $childParents, $subdivisionChildrenPaths, $languages);
        }
    }
    // Apply any found customizations.
    $customizations = get_subdivision_customizations($group);
    $subdivisions[$group] = apply_subdivision_customizations($subdivisions[$group], $customizations);
    // All subdivisions have been removed. Remove the rest of the data.
    if (empty($subdivisions[$group]['subdivisions'])) {
        unset($subdivisions[$group]);
    }
    return $subdivisions;
}
/**
 * Recursively generates subdivision definitions.
 */
function generate_subdivisions($countryCode, $parentId, $subdivisionPaths, $languages)
{
    $subdivisions = [];
    // Start by retrieving all json definitions.
    $definitions = [];
    $definitionKeys = [];
    foreach ($subdivisionPaths as $subdivisionPath) {
        $definition = file_get_contents('raw/' . $subdivisionPath . '.json');
        $definition = json_decode($definition, true);
        $definitions[$subdivisionPath] = $definition;
        $definitionKeys[] = $definition['key'];
    }
    // Determine whether the definition keys are safe to be used as subdivision
    // ids (by having the same length, and being ASCII).
    $keySuitableAsId = true;
    foreach ($definitionKeys as $index => $key) {
        if (strlen($key) != strlen($definitionKeys[0]) || !ctype_print($key)) {
            $keySuitableAsId = false;
            break;
        }
    }
    foreach ($definitions as $subdivisionPath => $definition) {
        // Construct a safe id for this subdivision. Google doesn't have one.
        if (isset($definition['isoid'])) {
            // Administrative areas often have a numeric isoid.
            $subdivisionId = $parentId . '-' . $definition['isoid'];
        } elseif (count($definitionKeys) > 1 && $keySuitableAsId) {
            // Many administrative areas have no isoid, but use a safe
            // two/three letter identifier as the key.
            $subdivisionId = $parentId . '-' . $definition['key'];
        } elseif (in_array($countryCode, ['AU'])) {
            // Special case countries which have different key lengths,
            // but which are known to be safe (for example, Australia).
            $subdivisionId = $parentId . '-' . $definition['key'];
        } else {
            // Localities and dependent localities have keys that are
            // not guaranteed to be in the local script, so we hash them.
            $subdivisionId = $parentId . '-' . substr(sha1($parentId . $definition['key']), 0, 6);
        }
        if (!isset($subdivisions[$parentId])) {
            $subdivisions[$parentId] = ['country_code' => $countryCode, 'parent_id' => $countryCode == $parentId ? null : $parentId, 'locale' => determine_locale($definition)];
        }
        $subdivisions[$parentId]['subdivisions'][$subdivisionId] = create_subdivision_definition($definition);
        // If the subdivision has translations, retrieve them.
        // Note: At the moment, only Canada and Switzerland have translations,
        // and those translations are for administrative areas only.
        // It is unknown whether the current way of assembling the url would
        // work with several levels of translated subdivisions.
        foreach ($languages as $language) {
            $translation = file_get_contents('raw/' . $subdivisionPath . '--' . $language . '.json');
            $translation = json_decode($translation, true);
            $subdivisions[$parentId]['subdivisions'][$subdivisionId]['translations'][$language]['name'] = $translation['name'];
        }
        if (isset($definition['sub_keys'])) {
            $subdivisions[$parentId]['subdivisions'][$subdivisionId]['has_children'] = true;
            $subdivisionChildrenPaths = [];
            $subdivisionChildrenKeys = explode('~', $definition['sub_keys']);
            foreach ($subdivisionChildrenKeys as $subdivisionChildrenKey) {
                $subdivisionChildrenPaths[] = $subdivisionPath . '_' . $subdivisionChildrenKey;
            }
            $subdivisions += generate_subdivisions($countryCode, $subdivisionId, $subdivisionChildrenPaths, $languages);
        }
    }
    return $subdivisions;
}