<?php

if (!defined('XOOPS_ROOT_PATH')) exit();

/*** THE EASIEST MULTILANGUAGE HACK  by GIJOE  ***/
if (!class_exists('Xoonips_MultiLanguage')) {
	// CONFIGURATIONS BEGIN

	// list the language tags separated with comma
	define('XOONIPS_EASIESTML_LANGS', 'en,ja'); // [en]english[/en]  [ja]japananese[/ja] common

	// list the language images separated with comma
	define('XOONIPS_EASIESTML_LANGIMAGES', 'images/english.gif,images/japanese.gif');

	// list the language names separated with comma (these will be alt of <img>)
	define('XOONIPS_EASIESTML_LANGNAMES', 'in english,in japanese');

	// list language - accept_chaset patterns (perl regex) separated with comma
	define('XOONIPS_EASIESTML_ACCEPT_CHARSET_REGEXES', ',/shift_jis/i');

	// list language - accept_language patterns (perl regex) separated with comma
	define('XOONIPS_EASIESTML_ACCEPT_LANGUAGE_REGEXES', '/^en/,/^ja/');

	// charset in Content-Type separated with comma (only for fastestcache)
	define('XOONIPS_EASIESTML_CHARSETS', 'ISO-8859-1,UTF-8');

	// tag name for language image  (default [mlimg]. don't include specialchars)
	define('XOONIPS_EASIESTML_IMAGETAG', 'mlimg');

	// make regular expression which disallows language tags to cross it
	define('XOONIPS_EASIESTML_NEVERCROSSREGEX', '/\<\/table\>/');

	// the life time of language selection stored in cookie
	define('XOONIPS_EASIESTML_COOKIELIFETIME', 365*86400);

	// default language
	define('XOONIPS_EASIESTML_DEFAULT_LANG', 0);

	// post merger  eg) <input name="subject[en]"> and <input name="subject[ja]">
	define('XOONIPS_EASIESTML_USEPOSTMERGER', 0);

	// CONFIGURATIONS END

    class Xoonips_MultiLanguage extends XCube_ActionFilter {

    	private $dirname;
    	// language tag
    	private $easiestml_lang;
    	// charset in Content-Type
    	private $easiestml_charset;
    	// variable name for language tag
		private $langname;

    	public function Xoonips_MultiLanguage($dirname) {

    		$this->dirname = $dirname;
    		$this->langname = $this->dirname . '_easiestml_lang';

    		// Target check
			if (preg_match('?' . preg_quote(XOOPS_ROOT_PATH, '?') . '(/modules/[^\/]+/common/|/modules/system/|/admin\.php)?', $_SERVER['SCRIPT_FILENAME']) ||
				preg_match('?(/modules/' . $dirname . '/admin/maintenance\.php\?page=itemtype&action=edit&op=export)?', $_SERVER['REQUEST_URI'])) {
				return;
			}

			// get cookie path
			$xoops_cookie_path = defined('XOOPS_COOKIE_PATH') ? XOOPS_COOKIE_PATH : preg_replace('?http://[^/]+(/.*)$?' , "$1" , XOOPS_URL);
			if ($xoops_cookie_path == XOOPS_URL) {
				$xoops_cookie_path = '/';
			}

			// for modrewrite
			if (empty($_GET[$this->langname]) && preg_match('#[/?&]' . $this->langname . '[=/]([0-9a-zA-Z%]{1,12})#' , $_SERVER['REQUEST_URI'] , $regs)) {
				$_GET[$this->langname] = urldecode($regs[1]);
			}

			// deciding the current language (the priority is important)
			$easiestml_langs = explode(',', XOONIPS_EASIESTML_LANGS);
			$easiestml_charsets = explode(',', XOONIPS_EASIESTML_CHARSETS);
			if (!empty($_GET[$this->langname]) && $_GET[$this->langname] == 'all') {
				// set by GET (all)
				$this->easiestml_lang = 'all';
			} elseif (!empty($_GET[$this->langname]) && ($offset = array_search($_GET[$this->langname], $easiestml_langs)) !== false) {
				// set by GET (other than all)
				$this->easiestml_lang = $_GET[$this->langname];
				$this->easiestml_charset = $easiestml_charsets[$offset];
				setcookie($this->langname, $this->easiestml_lang, time() + XOONIPS_EASIESTML_COOKIELIFETIME, $xoops_cookie_path, '' , 0);
			} elseif (!empty($_COOKIE[$this->langname]) && ($offset = array_search($_COOKIE[$this->langname], $easiestml_langs)) !== false) {
				// set by COOKIE (other than all)
				$this->easiestml_lang = $_COOKIE[$this->langname];
				$this->easiestml_charset = $easiestml_charsets[$offset];
			} elseif (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
				// set by HTTP_ACCEPT_LANGUAGE pattern
				$offset = 0;
				foreach (explode(',', XOONIPS_EASIESTML_ACCEPT_LANGUAGE_REGEXES) as $pattern) {
					if ($pattern && preg_match($pattern, $_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
						$this->easiestml_lang = $easiestml_langs[$offset];
						$this->easiestml_charset = $easiestml_charsets[$offset];
						break;
					}
					$offset++;
				}
			} elseif (!empty($_SERVER['HTTP_ACCEPT_CHARSET'])) {
				// set by HTTP_ACCEPT_CHARSET pattern
				$offset = 0 ;
				foreach (explode(',', XOONIPS_EASIESTML_ACCEPT_CHARSET_REGEXES) as $pattern) {
					if ($pattern && preg_match($pattern , $_SERVER['HTTP_ACCEPT_CHARSET'])) {
						$this->easiestml_lang = $easiestml_langs[$offset];
						$this->easiestml_charset = $easiestml_charsets[$offset];
						break;
					}
					$offset++;
				}
			}

			if (empty($this->easiestml_lang)) {
				$this->easiestml_lang = $easiestml_langs[XOONIPS_EASIESTML_DEFAULT_LANG];
				$this->easiestml_charset = $easiestml_charsets[XOONIPS_EASIESTML_DEFAULT_LANG];
			}

			// merge posts eg) subject[ja] and subject[en]
			if (@EASIESTML_USEPOSTMERGER && ! empty($_POST)) {
				$this->easiestmlPostMerge($_POST, $easiestml_langs);
			}

			// charset for Content-Type
			ob_start(array(&$this, 'easiestml'));
		}

		// post merger
		private function easiestmlPostMerge(&$data, $easiestml_langs) {
			$merged_string = '';
			$langs_counter = 0;
			foreach (array_keys($data) as $index) {
				if (is_array($data[$index])) {
					$this->easiestmlPostMerge($data[$index], $easiestml_langs);
				} elseif (in_array($index , $easiestml_langs)) {
					$merged_string .= '[' . $index . ']' . $data[$index ] . '[/' . $index . ']';
					$langs_counter++;
				}
			}

			if ($langs_counter == sizeof($easiestml_langs)) {
				$data = $merged_string;
			}
		}

		// ob filter
		public function easiestml($s , $lang = '') {
			global $xoopsUser ;

			// all mode for debug (allowed to system admin only)
			if (is_object($xoopsUser) && $xoopsUser->isAdmin(1) && !empty($_GET[$this->langname]) && $_GET[$this->langname] == 'all') {
				return $s;
			}

			$easiestml_langs = explode(',', XOONIPS_EASIESTML_LANGS);
			// protection against some injection
			if (!in_array($this->easiestml_lang, $easiestml_langs)) {
				$this->easiestml_lang = $easiestml_langs[0];
			}

			// manual language $lang parameter
			if ($lang && in_array($lang, $easiestml_langs)) {
				$this->easiestml_lang = $lang;
			}

			// escape brackets inside of <input type="text" value="...">
			//$s = preg_replace_callback('/(\<input)(?=.*type\=[\'\"]?text[\'\"]?)([^>]*)(\>)/isU', 'easiestml_escape_bracket', $s);
			$s = preg_replace_callback('/(\<input)([^>]*)(\>)/isU', array(&$this, 'easiestmlEscapeBracketTextbox'), $s);

			// escape brackets inside of <textarea></textarea>
			$s = preg_replace_callback('/(\<textarea[^>]*\>)(.*)(<\/textarea\>)/isU', array(&$this, 'easiestmlEscapeBracketTextarea'), $s);

			// multilanguage image tag
			$langimages = explode(',', XOONIPS_EASIESTML_LANGIMAGES);
			$langnames = explode(',', XOONIPS_EASIESTML_LANGNAMES);
			if (empty($_SERVER['QUERY_STRING'])) {
				$link_base = basename($_SERVER['SCRIPT_NAME']) . '?' . $this->langname . '=';
			} elseif (($pos = strpos($_SERVER['QUERY_STRING'], $this->langname . '=')) === false) {
				$link_base = basename($_SERVER['SCRIPT_NAME']) . '?' . htmlspecialchars($_SERVER['QUERY_STRING'], ENT_QUOTES) . '&amp;' . $this->langname . '=';
			} elseif ($pos < 2) {
				$link_base = basename($_SERVER['SCRIPT_NAME']) . '?' . $this->langname . '=';
			} else {
				$link_base = basename($_SERVER['SCRIPT_NAME']) . '?' . htmlspecialchars(substr($_SERVER['QUERY_STRING'], 0, $pos - 1), ENT_QUOTES) . '&amp;' . $this->langname . '=';
			}
			$langimage_html = '';
			foreach ($easiestml_langs as $l => $lang) {
				$langimage_html .= '<a href="' . $link_base . urlencode($lang) . '"><img src="' . XOOPS_URL . '/' . $langimages[$l] . '" alt="' . $langnames[$l] . '" /></a> ';
			}
			$s = preg_replace('/\[' . XOONIPS_EASIESTML_IMAGETAG . '\]/' , $langimage_html, $s);

			// eliminate description between the other language tags.
			foreach ($easiestml_langs as $lang) {
				if($this->easiestml_lang == $lang) continue;
				$s = preg_replace_callback('/\[' . preg_quote($lang) . '\].*\[\/' . preg_quote($lang) . '(?:\]\<br \/\>|\])/isU', array(&$this, 'easiestmlCheckNevercross'), $s);
			}

			// simple pattern to strip selected lang_tags (remove all tags)
			$s = preg_replace('/\[\/?' . preg_quote($this->easiestml_lang) . '\](\<br \/\>)?/i', '', $s);

			return $s ;
		}

		private function easiestmlEscapeBracketTextbox($matches) {
			if (preg_match('/type=["\']?text["\']?/i', $matches[2])) {
				return $matches[1] . str_replace('[', '&#91;', $matches[2]) . $matches[3];
			} else {
				return $matches[1] . $matches[2] . $matches[3];
			}
		}

		private function easiestmlEscapeBracketTextarea($matches) {
			return $matches[1] . str_replace('[', '&#91;', $matches[2]) . $matches[3];
		}

		private function easiestmlCheckNevercross($matches) {
			return preg_match(XOONIPS_EASIESTML_NEVERCROSSREGEX , $matches[0]) ? $matches[0] : '';
		}
	}
}

