Location: PHPKode > projects > Blandware AtLeap Lite - CMS on PHP > atleaplite/include/util/language.php
<?php
/*
 *  Copyright 2008 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * Language tools.
 *
 * @package     AtleapLite
 * @author      Roman Puchkovskiy
 * @license     http://www.apache.org/licenses/LICENSE-2.0  Apache License, Version 2.0
 */

/**
 * Class which represents a language.
 *
 * @package     AtleapLite
 */
class Language {
    var $code;
}

/**
 * Returns the current language.
 *
 * @return string code of the current language
 */
function getCurrentLanguage() {
    return $_SESSION['currentLanguage'];
}

/**
 * Sets the current language.
 *
 * @param string $lang  language code
 */
function setCurrentLanguage($lang) {
    $_SESSION['currentLanguage'] = $lang;
}

/**
 * Returns all known languages.
 *
 * @global array languages
 * @return all known languages
 */
function getLanguages() {
    global $languages;

    return $languages;
}

/**
 * Returns a language by its code.
 *
 * @param string $code  language code
 * @return object language
 */
function getLanguage($code) {
    $langs = getLanguages();
    return $langs[$code];
}

/**
 * Returns the default language code.
 *
 * @return string default language code
 */
function getDefaultLanguage() {
    global $defaultLanguage;

    return $defaultLanguage;
}

/**
 * If current language is not in session, determines it and puts there. When
 * determining, first Accept-Language header is used. If any of our languages
 * matches this header, 'the most matching' language is treated as the result.
 * If there's no such header or no languages match it, the default language is
 * used as the current language.
 */
function ensureCurrentLanguageIsInitialized() {
    $lang = getCurrentLanguage();
    if (!$lang) {
        $lang = detectCurrentLanguage();
        if (!$lang) {
            $lang = getDefaultLanguage();
        }
    }
    setCurrentLanguage($lang);
}

/**
 * Detects the current language using the Accept-Language header. If exists and
 * some known languages match it, the code of 'the most matching' language is
 * returned. If there's no such header or no known languages match it, null is
 * returned.
 *
 * @return string|null language code or null if could not detect
 */
function detectCurrentLanguage() {
    $acceptLanguage = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
    if (!$acceptLanguage) {
        return null;
    }

    $rangesAndQualities = explode(',', $acceptLanguage);
    foreach ($rangesAndQualities as $key => $value) {
        $rangesAndQualities[$key] = trim($value);
    }

    // convert strings to weighted langs retaining only those that match our
    // languages
    $langs = array();
    foreach ($rangesAndQualities as $rq) {
        $pos = strpos($rq, ';');
        if ($pos === false) {
            $range = $rq;
            $weight = 1.0;
        } else {
            list($range, $weight) = explode(';', $rq, 2);
        }
        $range = trim($range);
        $weight = floatval(trim($weight));

        if ($range == '*' || (float) $weight <= 0) {
            continue;
        }
        
        $lang = findExactLangMatch($range);
        if (!$lang) {
            // TODO: here only one match is taken while several are possible...
            // rework?
            $lang = findPrefixLangMatch($range);
        }
        if (!$lang) {
            // the range does not match
            continue;
        }
        if (isset($langs[$lang]) && (float) $weight <= (float) $langs[$lang]) {
            // avoiding loosing more valuable weight
            continue;
        }

        $langs[$lang] = $weight;
    }

    if (count($langs) == 0) {
        // no languages matched
        return null;
    }

    // now returning the most valuable language
    $maxWeight = 0.0;
    foreach ($langs as $l => $weight) {
        if ((float) $weight > (float) $maxWeight) {
            $maxWeight = $weight;
            $lang = $l;
        }
    }
    return $lang;
}

/**
 * Finds exact range match to one of known languages.
 *
 * @param string range to match
 * @return string|null language code or null if not found
 */
function findExactLangMatch($range) {
    $code = rangeToLanguageCode($range);
    if (getLanguage($code) != null) {
        return $code;
    } else {
        return null;
    }
}

/**
 * Finds prefix range match to one of known languages.
 *
 * @param string range to match
 * @return string|null language code or null if not found
 */
function findPrefixLangMatch($range) {
    $code = rangeToLanguageCode($range);
    foreach (getLanguages() as $lang) { 
        if (startsWith($lang->code, $code . '_')) {
            return $lang->code;
        }
    }
}

/**
 * Converts a range to language code. When converting, fragment separators which
 * are dashes ('-') are replaced with underscores ('_'). First fragment is
 * converted to the lowercase, while the second fragment is converted to the
 * uppercase.
 *
 * @param string $range the range to convert
 * @return string converted range
 */
function rangeToLanguageCode($range) {
    $fragments = explode('-', $range);
    $count = count($fragments);
    if ($count > 0) {
        $fragments[0] = strtolower($fragments[0]);
    }
    if ($count > 1) {
        $fragments[1] = strtoupper($fragments[1]);
    }
    return implode('_', $fragments);
}

/**
 * If a language is set using the GET parameter and the specified language is
 * supported, sets the current language to this value.
 */
function setLanguageFromParameter() {
    if (isset($_GET['language']) && getLanguage($_GET['language']) != null) {
        setCurrentLanguage($_GET['language']);
    }
}

/**
 * Returns an assoc array from language codes to their titles in the current
 * language plus element for 'all', if requested.
 *
 * @param bool $addNotSelected  if true, 'all' element will be added
 * @return array assoc array
 */
function getLanguagesForSelect($addNotSelected = false) {
    $languages =& getLanguages();
    $currentLang = getCurrentLanguage();
    $result = array();
    if ($addNotSelected) {
        $result[-1] = getMessage('common.all');
    }
    foreach ($languages as $language) {
        $result[$language->code] = getMessage('language.' . $language->code);
    }
    return $result;
}

?>
Return current item: Blandware AtLeap Lite - CMS on PHP