<?php

/**
** file: LanguageSelector.php
** Author: Jörg Reinholz, fastix WebDesign & Consult, Kassel (Germany), http://www.fastix.org
** Description: This function helps to Select a Language
** License: https://code.fastix.org/lizenz.php
**
** USAGE:
** include 'LanguageSelector.php'

** Create the Objekt:
** $LanguageSelector = new LanguageSelector( array('fr', 'en', 'es', 'pt', 'de') );
## use the object:
** define ( 'LANG', $LanguageSelector -> getLang() );

## furter you can use $LanguageSelector -> getLastSelection() to get the language faster.
##


** The method getLang:
** =================
** First this show what languages are given ($arLanguages)
** Example:
**    FIRST SELECTION: ("site owners preselection")
**      If you have called SelectOneOffAcceptedLanguages ( 'fr', 'en', 'es', 'pt', 'de'] )
**            then is 'de' the selected language at this time
**    SECOND SELECTION: ("user-agent preselection")
**      If the User-Agent send the Accept-Language-Header and this is one of the accepted languages
**            then this function overwrite the first selection with the most wanted language.
**    THIRD SELECTION:
**      If a cookie ($this -> storeName) stored (and resived) and this is one of the accepted languages
**          then this function overwrite the second selection with this language.
**    FOURTH SELECTION:
**      If a hostname (eg 'DE.www.fastix.org', 'DE.fastix.org')  given and this is one of the accepted languages
**          then this function overwrite the third selection with this.
**    FIVE SELECTION:
**      If a (virtual) directory ('fastix.org/DE/') given and this is one of the accepted languages
**          then this function overwrite the fourth selection with this.
**    LAST SELECTION:
**      If a information into the URI-parameters given and this is one of the accepted languages
**          then this function overwrite the fift selection with this.

**
**    Show ISO 639-1 and  RFC 1766 for more informations.
**    Read RFC2616, section 14, for the HTTP_ACCEPT_LANGUAGE-Header.
**/

class LanguageSelector {

    private $arHasLanguages;
    private $hashHasLanguages;
    private $LastSelection = false;
    public  $storeMethod = 'cookie';
    public  $storeName = 'USER_SELECTED_LANGUAGE'; # used for: SESSION, COOKIE, GET, POST, HTML-Input-Name
                                                   # must bee a string of numbers, letters and '_', first char a letter or '_'

    public function __construct ( $arHasLanguages ) {
        $arTmp = array();
        $arHash = array();
        foreach ( $arHasLanguages as $s ) {
            $s = trim( strtolower( $s ) );
            if ( $s ) {
                $ar[] = $s;
                $hash[$s] = true;
            }
        }
        $this -> arHasLanguages   = $ar;
        $this -> hashHasLanguages = $hash;
    }

    private function getLangFromString( $string ) {
        $string = trim( strtolower( $string ) );
        if ( isset( $this -> hashHasLanguages[$string] ) ) {
            return $string;
        } else {
            return false;
        }
    }

    public function getLang() {

        ### FIRST SELECTION ###
        $retLang = $this -> arHasLanguages[0];

        ### SECOND SELECTION ###
        if ( isset ( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
            $arTmp = explode( ',' , $_SERVER['HTTP_ACCEPT_LANGUAGE'] );
            foreach ( $arTmp as $item ) {
                $arLangQuote = array();
                $arLangQuote = explode( ';', $item );
                if ( ! isset($arLangQuote[1] ) ) {
                    $arLangQuote[1] = 1;
                }
                $arLangQuote[0] = trim( $arLangQuote[0] );
                if ( $arLangQuote[0] ) {
                    $arT['quote'] = floatval( trim( str_replace( 'q=', '', $arLangQuote[1] ) ) );
                    $arT['lang']  = trim( strtolower( $arLangQuote[0] ) );
                    $arAcceptedLanguages[] = $arT;
                }
            }
        }
        $SelectedLanguage = $this -> arHasLanguages[0];
        $quote = 0;
        foreach ( $this -> arHasLanguages as $lang ) {
            foreach ( $arAcceptedLanguages as $arTmp ) {
                if ( $lang == $arTmp['lang'] && $arTmp['quote'] > $quote ) {
                    $retLang = $arTmp['lang'];
                    $quote   = $arTmp['quote'];
                }
            }
        }

        ### THIRD SELECTION: ###
        if ( 'cookie' == $this -> storeMethod ) {
            if ( isset( $_COOKIE[$this -> storeName] ) ) {
                $tmp = $this -> getLangFromString ( $_COOKIE[$this -> storeName] );
                if ( $tmp ) {
                    $retLang = $tmp;
                }
            }
        } elseif ( 'session' == $this -> storeMethod ) {
            session_start();
            if ( isset( $_GET[$this -> storeName] ) && 'unset' == $_GET[$this -> storeName] ) {
                unset( $_SESSION[ $this -> storeName] );
                header( 'Location: '. $_SERVER['SCRIPT_NAME'] );
                exit;
            }
            $tmp = $this -> getLangFromString ( $_SESSION[$this -> storeName] );
            if ( $tmp ) {
                $retLang = $tmp;
            }
        } else {
            trigger_error( "Fatal: storeMethod must be 'cookie' or 'session' given is: '" . $this -> storeMethod . "'", E_USER_ERROR );
        }

        ### FOURTH PER-HOST-SELECTION: ###
        $parts = explode(  '.' , strtolower( $_SERVER['HTTP_HOST'] ) );
        $tmp = $this -> getLangFromString( $parts[0] );
        if ( $tmp ) {
            $retLang = $tmp;
        }

        ### FIFT METHOD: PER-DIR-SELECTION: ###
        $parts = explode( '/' , trim( strtolower( $_SERVER['REQUEST_URI'] ) , '/' ) );
        $tmp = $this -> getLangFromString ( $parts[0] );
        if ( $tmp ) {
            $retLang = $tmp;
        }
        $this ->  LastSelection = $retLang;

        ### LAST METHOD: GET/POST-SELECTION: ###
        if ( isset( $_REQUEST[$this -> storeName] ) ) {
            $tmp = $this -> getLangFromString ( $_REQUEST[$this -> storeName] );
            if ( $tmp ) {
                $retLang = $tmp;
                $this -> LastSelection = $retLang;
                $this -> storeSelection( $retLang );
                header( 'Location: ' . $_SERVER['SCRIPT_NAME'] );
                exit;
            }

        }

        return $retLang;
    }

    public function getLastSelection() {
        return $this -> LastSelection;
    }

    public function storeSelection( $lang ) {
        if ( 'cookie' == $this -> storeMethod ) {
            setcookie( $this -> storeName, $lang );
        } elseif ('session' == $this -> storeMethod ) {
            if ( ! session_status() == PHP_SESSION_ACTIVE ) {
                session_start();
            }
            $_SESSION[$this -> storeName] = $lang;
        } else {
            trigger_error( "Fatal: storeMethod must be 'cookie' or 'session'. given is: '" . $this -> storeMethod . "'", E_USER_ERROR );
        }
    }
}