<?php

	/*
	*	Gekko - Open Source Web Development Framework
	*	------------------------------------------------------------------------
	*	Copyright (C) 2004-2006, J. Carlos Nieto <xiam@users.sourceforge.net>
	*	This program is Free Software.
	*
	*	@package	Gekko
	*	@subpackage	/lib
	*	@license	http://www.gnu.org/copyleft/gpl.html GNU/GPL License 2.0
	*	@author		J. Carlos Nieto <xiam@users.sourceforge.net>
	*	@link		http://www.gekkoware.org
	*/

	if (!defined("IN-GEKKO")) die("Get a life!");

	// magic quotes are evil
	set_magic_quotes_runtime(0);

	require_once(GEKKO_USER_DIR."dbconf.php");
	require_once(GEKKO_USER_DIR."cgdb.php");

	require_once(GEKKO_SOURCE_DIR."lib/database.lib.php");
	require_once(GEKKO_SOURCE_DIR."modules/conf/core.lib.php");
	require_once(GEKKO_SOURCE_DIR."lib/lang.lib.php");
	require_once(GEKKO_SOURCE_DIR."lib/cache.lib.php");
	require_once(GEKKO_SOURCE_DIR."lib/accesscontrol.lib.php");
	require_once(GEKKO_SOURCE_DIR."lib/plugins.lib.php");

	Class gekkoModule {
		var $buff;
		var $main;
		function srcPath($module) {
			return GEKKO_SOURCE_DIR."modules/$module/";
		}
		function exists($module) {
			if ($module) {
				$module = preg_replace("/[^a-z0-9\.\-\_]/i", '', $module);
				return ereg("\.\.", $module) ? false : file_exists(gekkoModule::srcPath($module));
			}
			return false;
		}
		function isInstalled($module) {
			$db =& $GLOBALS["db"];
			$q = $db->query("SELECT id FROM ".db_table("module")." WHERE module = '{$module}'",
			__FILE__, __LINE__, true);
			return $db->numRows($q);
		}
		function auth($module, $type = "exec") {
			$db =& $GLOBALS["db"];
			$q = $db->query("SELECT auth_{$type} FROM ".db_table("module")."
			WHERE module = '{$module}'", __FILE__, __LINE__, true);
			if ($db->numRows($q)) {
				$row = $db->fetchRow($q);
				return gauth($row["auth_{$type}"]);
			}
			return false;
		}
		function getCoreClass($module) {
			return "gekkoModule_".preg_replace("/[^a-z0-9]/i", '_', $module);
		}
		/*
			Types:
				U = Uninstall
				R = Reinstall
				I = Install
				P = Upgrade
		*/
		function install($module, $type = "I") {

			$db =& $GLOBALS["db"];

			require_once GEKKO_SOURCE_DIR."modules/packages/main.lib.php";
			require_once GEKKO_SOURCE_DIR."modules/{$module}/module.inc.php";

			// initializing module's core class (was included just above this line)
			$modclass = gekkoModule::getCoreClass($module);
			$modclass = new $modclass;

			// parsing module information
			$modxml = packages::parseModuleXML($module);

			if ($type == 'P') {
				// U[P]GRADE
				if (($inform = Packages::checkInstall($modxml)) == false) {
					// getting installed version
					$installed_version = conf::getKey($module, "_version");

					// upgrading
					$modclass->upgrade($installed_version);

					// new configuration variables, keeping user settings
					$modclass->configure();

					// updating version
					conf::setKey($module, "_version", $modxml["release"]["version"], "s");
				}
			}

			if ($type == 'U' || $type == 'R') {
				// [U]NINSTALL, [R]EINSTALL

				// dropping from modules table
				$db->query("DELETE FROM ".db_table("module")." WHERE module = '{$module}'",
				__FILE__, __LINE__, true);

				// dropping configuration variables
				conf::delKey($module, "*");

				// invoking an uninstall routine for module's core class
				$modclass->uninstall();

				// involing ext_uninstall routine for each module required by this one
				if (isset($modxml["requires"]["module"]))
					foreach ($modxml["requires"]["module"] as $required) {

						require_once GEKKO_SOURCE_DIR."modules/$required/module.inc.php";

						$reqclass = gekkoModule::getCoreClass($required);
						$reqclass = new $reqclass;

						$reqclass->ext_uninstall($module);

						unset($reqclass);
					}
			}

			if ($type == 'I' || $type == 'R') {
				// [I]NSTALL, [R]EINSTALL

				if (($inform = Packages::checkInstall($modxml)) == false) {

					// the module must register by itself and create its
					// own tables using the install routine invoked below.
					$modclass->install();

					// invoking self configuration
					$modclass->configure();

					// setting module version entry
					conf::setKey($module, "_version", $modxml["release"]["version"], "s");

				} else {
					// there is a missing dependency
					header("content-type: text/plain");
					echo $inform;
					abort();
				}

			}

			unset ($modclass);

			return false;
		}
		function save($data) {
			$this->buff .= $data;
		}
		function data() {
			return $this->buff;
		}
		function getList($packages = true) {

			$cache_key = "gekko_module_list";

			$modules = cacheVar($cache_key);

			if (!$modules) {

				$dir = opendir(GEKKO_SOURCE_DIR."modules/");
				$modules = Array();

				while (($file = readdir($dir)) !== false) {
					if ($file == "." || $file == ".." || !is_dir(GEKKO_SOURCE_DIR."modules/".$file))
						continue;
					$modules[] = $file;
				}

				closedir($dir);

				cacheVar($cache_key, $modules);
			}

			return $modules;
		}
		function register($id, $module, $access, $admin) {
			/*
				Assigned IDs for new modules are reserved from 1 up to 64
				for Gekko official modules. Custom modules for your
				own application must be registered with an ID major than
				64
				* read HACKING file
			*/
			$db =& $GLOBALS["db"];

			$module = strtolower($module);

			// checking if module or id is already registered
			$q = $db->query("SELECT id FROM ".db_table("module")."
			WHERE id = '{$id}' OR module = '{$module}'",
			__FILE__, __LINE__, true);

			if ($db->numRows($q)) {
				// refusing to duplicate a module name or id
				trigger_error("Couldn't register module '$module' with id '$id': Duplicated ID or NAME. Please read HACKING file.", E_USER_ERROR);
			}

			// registering module
			$q = $db->query("
			INSERT INTO ".db_table("module")."
				(id, module, auth_exec, auth_manage, modified)
			VALUES
				('$id', '".strtolower($module)."', '$access', '$admin', '".time()."')
			", __FILE__, __LINE__, true);

			// creating a group for this module (if doesn't exists)
			$q = $db->query(
				"SELECT id FROM ".db_table("group")." WHERE id = '$id'",
				__FILE__, __LINE__, true
			);
			if (!$db->numRows($q)) {
				$db->query("INSERT INTO ".db_table("group")." (id, groupname, description)
				VALUES ('$id', '$module', '".ucfirst($module)."')");
			}
		}
	}


	/*
	* LoadLib(libname1, libname2, ...);
	* @returns: error when a library wasn't found
	*
	*/
	function LoadLib() {
		$args = func_get_args();
		foreach ($args as $lib) {
			unset($f);
			if (file_exists($f = GEKKO_SOURCE_DIR."lib/$lib")) {
				require_once $f;
			} elseif (file_exists($f = GEKKO_SOURCE_DIR."modules/$lib/main.lib.php")) {
				require_once $f;
			} else {
				trigger_error("Could not load library '$lib'", E_USER_ERROR);
			}
		}
	}
	function setDefault($variable, $value) {
		if (!isset($GLOBALS[$variable]))
			$GLOBALS[$variable] = $value;
	}

	## BEGIN URL HANDLING ##

	/**
	* urlEvalPrototype(URL Prototype);
	* @returns: a ready-to-use version of the provided prototype
	*
	*/
	function urlEvalPrototype($href, $relative = true, $html = true) {

		// if the url begins with proto:// leave as is.
		if (strpos($href, '://') == false) {

			// url formatting
			$parts = URLSplitVars($href);

			// new href prototype
			$href = Array('path'=>Array(),'vars'=>Array());

			// checking parts
			foreach ($parts['path'] as $part) {
				if (($d = strpos($part, '=')) !== false) {
					if (GEKKO_USE_PRETTY_URLS) {
						// if allowed to use pretty URLs
						$href['path'][] = substr($part, $d+1);
					} else {
						// when we are not allowed
						$href['vars'][] = $part;
					}
				} else {
					// leaving part as is (it is not a variable)
					$href['path'][] = $part;
				}
			}

			// merging 'vars'
			$href['vars'] = array_merge($href['vars'], $parts['vars']);

			// joining 'path' and 'vars'
			$href['path'] = implode('/', $href['path']);
			$href['vars'] = implode('&', $href['vars']);

			// joining again into a single href with a relative path if needed
			$href = implode($href['vars'] ? '?' : '', $href);
			if ($html) $href = HTMLSpecialChars($href);

			if ((defined("GEKKO_USE_ABSOLUTE_URIS") && GEKKO_USE_ABSOLUTE_URIS) || (!$relative)) {
				return _l("C_SITE.URL").$href;
			} else {
				$href = (substr($href, 0, 1) == '/') ? dirname($_SERVER["SCRIPT_NAME"]).$href : _L('C_SITE.URL').$href;
			}
		}
		return $href;
	}

	/**
	* URLCheckVarType(Type, &Variable);
	* @returns: modified variable according it's type
	*
	*/
	function URLCheckVarType($type, &$value) {
		switch ($type) {
			case "int":
				$value = 0+intval(preg_replace("/[^\d\-]/", "", $value));
			break;
			case "alpha":
				$value = preg_replace("/[^\w\-\_]/", "", $value);
			break;
			case "date":
				$value = preg_replace("/[^0-9.\-]/", "", $value);
				$value = preg_replace("/[^0-9]/", "-", $value);
			break;
			case "page":
				if ($value != "last") {
					$value = preg_replace("/[^0-9]/", "", $value);
				}
				if (!$value)
					$value = 1;
			break;
			case "string":
				$value = preg_replace("/[^\w\s\.\-\_\/,]/", "", $value);
			break;
			case "data":
				// as is
			break;
			default:
				if (preg_match("/\[(.*?)\]/", $type, $match)) {
					$value = preg_replace("/[^$match[1]]/", "", $value);
				} else {
					trigger_error("Missing datatype for variable '$value'", E_USER_WARNING);
				}
			break;
		}
		return $value;
	}

	/**
	* URLSpliVars(URL Prototype);
	* @returns: an array containing both 'path' and 'vars' (normal variables)
	*
	*/
	function URLSplitVars($url) {

		$parts = Array('path' => array(), 'vars' => array());

		// splitting by path/info?var=val
		$buff = explode('?', $url);

		// simple variables
		if (isset($buff[1]))
			$parts['vars'] = explode('&', $buff[1]);

		// path variables
		if ($buff[0])
			$parts['path'] = explode('/', trim($buff[0], '/'));

		return $parts;
	}

	/**
	* URLGetVars(URL Prototype);
	* @returns: an array of checked URL variables according it's prototype
	* @example: URLGetVars('/module=alpha/title=string?var1=int');
	*
	*/
	function URLGetArgs($proto) {
		$return = Array();
		$varList = Array();

		$parts = URLSplitVars($proto);

		// initializing variables to null
		foreach ($parts as $part) {
			if (is_array($part))
				foreach ($part as $var)
					if (preg_match("/([^=]*)=.*/", $var, $buff))
						$GLOBALS[$buff[1]] = null;
		}

		// PATH_INFO
		if (isset($_SERVER['PATH_INFO'])) {
			$buff = explode('/', trim($_SERVER['PATH_INFO'], '/'));
			foreach ($buff as $i => $value) {
				if (isset($parts['path'][$i])) {
					// variable type & name (default type is string)
					$tmp = explode('=', trim($parts['path'][$i]));
					list($name, $type) = (count($tmp) > 1) ? $tmp : array($tmp[0], 'string');

					// PATH_INFO variables are overwritten by those setted in _GET
					if (isset($_GET[$name]))
						$value = $_GET[$name];
					// checking variable type
					if (($tmp = URLCheckVarType($type, $value)) != false)
						$return[$name] = $tmp;
				}
			}
		} elseif ($parts['path']) {
			// no path info
			$parts['vars'] = array_merge($parts['vars'], $parts['path']);
		}

		// _GET
		if ($parts['vars']) {
			foreach ($parts['vars'] as $part) {
				$tmp = explode('=', trim($part));
				list($name, $type) = (count($tmp) > 1) ? $tmp : array($tmp[0], 'string');
				if (isset($_GET[$name])) {
					$value = $_GET[$name];
					if (URLCheckVarType($type, $value))
						$return[$name] = $value;
				} else {
					$return[$name] = "";
				}
			}
		}
		return $return;
	}


	/**
	* urlSetArgs(URL Prototype, Base URL);
	* @returns: modified url arguments (and path info)
	* @example: urlSetArgs('v1=anakin&v2=skywalker', '/path/info?v1=foo&v2=var');
	*
	*/
	function URLSetArgs($proto, $base_url = null) {

		// getting current url arguments
		if ($base_url === null)
			$base_url = substr($_SERVER["REQUEST_URI"], strlen($_SERVER["SCRIPT_NAME"]));

		$varList = Array();

		// splitting variable list
		if (($path = strpos($proto, '/')) !== false) {
			// when url contains path_info
			$proto = explode('/', trim($proto, '/'));
		} else {
			$proto = explode('&', $proto);
		}

		// variable names
		foreach ($proto as $part) {
			$part = explode("=", $part);
			if (count($part) == 1)
				$part[1] = '';
			$varList[] = Array('name'=>$part[0],'value'=>$part[1]);
		}

		if (GEKKO_USE_PRETTY_URLS && $path) {

			// setting variable range
			if ($base_url && preg_match("/(.*)\?(.*)/", $base_url, $buff))
				list($tmp, $base_url, $base_args) = $buff;

			$return = ($base_url) ? explode('/', trim('/', $base_url)) : array();

			// overwriting or creating variables (checking range)
			for ($i = 0; $i < count($varList); $i++)
				$return[$i] = $varList[$i]['value'];

			return '/'.implode("/", $return).(isset($base_args) ? "?$base_args" : '');
		} else {
			foreach ($varList as $var) {
				// is this variable set in base_url?
				if (preg_match("/(\?|&){$var['name']}=.*(&|$)/", $base_url)) {
					$base_url = preg_replace("/(\?|&)({$var['name']}\=.*?)(&|$)/", "\\1{$var['name']}={$var['value']}\\3", $base_url);
				} else {
					// not found, appending it
					$base_url .= (preg_match("/\?.*\=.*/", $base_url) ? "&" : "?")."{$var['name']}={$var['value']}";
				}
			}
			return $base_url;
		}
	}
	## END URL HANDLING ##


	/*
		gauth(String auth, String levels);

		Returns true when $level is contained within $auth string.
		When $level is not set, this function takes users groups
		as $level and checks if one of the $levels (separated by
		commas) matchs with one of the auth levels (separated by
		commas too).

		For example:
			gauth("1,2,3", "4,5");
		Returns false, since both 4 and 5 are out of $auth
		variable
			gauth("4,2", "2");
		Returns true, "2" is contained into "4,2"

		Remember that both $auth and $levels must be strings
		containing comma-separated numeric values. But you can
		pass (at least for $auth) a module name, this will be
		automatically replaced by its corresponding id.
	*/

	function gauth($auth, $level = "") {

		// using user's groups when no level is specified
		if (!$level)
			$level = $GLOBALS["USER"]["groups"];

		// both $auth & $level are separated by commas
		$auth = explode(",", $auth);
		$level = explode(",", $level);

		// when $auth argument is not an integer it should
		// be a module name
		while (list($key) = each($auth)) {
			if ((strlen($auth[$key]) > 1) && (!is_integer($auth[$key]))) {
				$auth[$key] = isset($GLOBALS["cgdb"][$auth[$key]]) ? $GLOBALS["cgdb"][$auth[$key]] : $auth[$key];
			}
		}

		// checking level codes
		/*
			Level ranges
			code -  returns true for
			  1  -  super user (el mero mero)
			  *  -  any level
			  @  -  reserved gekko core modules (1 - 200)
			  #  -  reserved module levels (1 - 400)
			  $  -  user level (1 - 500)
			  ?  -  unprivileged level (501 or no groups)
		*/

		if (in_array("*", $auth)) return true;

		// special fix for visitors
		if (isset($auth[0]) && $auth[0] == '?')
			return !(defined("AUTH") && AUTH);

		foreach ($level as $check) {
			// note that I'm using (x > 0)
			if (($check = intval(trim($check))) > 0) {
				// access granted using level codes
				if ($check <= 200 && in_array("@", $auth)) return true;
				if ($check <= 400 && in_array("#", $auth)) return true;
				if ($check <= 500 && in_array("$", $auth)) return true;
				if ($check == 501 && in_array("?", $auth)) return true;
				// superadmin has total access to any level because we love him/her :)
				if ($check === $GLOBALS["cgdb"]["admin"]) return true;
				// access granted using specific levels
				if (in_array($check, $auth)) return true;
			} else {
				// no groups means no access
				if (in_array("?", $auth)) return true;
			}
		}
		return false;
	}
	// authentication hash
	function mkauth($hash, $key) {
		return $key.":".md5($hash.IP_ADDR);
	}
	// random string
	function genkey($len, $charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") {
		$charlen = strlen($charset);
		$return = '';
		for ($i = 0; $i < $len; $i++)
			$return .= $charset[rand(0, $charlen-1)];
		return $return;
	}

	// set cookie
	function set_userconf($name, $value = null, $life = null) {

		if (defined("IN-INSTALL")) {
			$prefix = "gekkocms_";
			if (!$life) $life = 3600*24;
		} else {
			$prefix = conf::getkey("core", "site.cookie.prefix");
			 if (!$life) $life = conf::getkey("core", "site.cookie.life");
		}

		$path = dirname($_SERVER["SCRIPT_NAME"]);

		if (preg_match("/(.*?)\/modules\/.*/", $_SERVER["SCRIPT_NAME"], $match)) {
			if (isset($match[1]))
				$path = rtrim($match[1],"/")."/";
		}

		setCookie (
			$prefix.$name,
			$value,
			time()+$life,
			$path ? $path : '/'
		);

	}

	// read cookie
	function get_userconf($name) {
		if (defined("IN-INSTALL"))
			return isset($_COOKIE["gekkocms_".$name]) ? $_COOKIE["gekkocms_".$name] : null;
		else
			return isset($_COOKIE[conf::getkey("core", "site.cookie.prefix").$name]) ? $_COOKIE[conf::getkey("core", "site.cookie.prefix").$name] : null;
	}

	/*
	*	slog(System message, file to save, importance level);
	*	Logs
	*/
	function slog($string, $file = "messages", $level = 1) {

		$logdir = GEKKO_TEMP_DIR."logs/";

		if (!file_exists($logdir)) {
			mkdir($logdir, 0775);
			chmod($logdir, 0775);
		}

		if (($h = @fopen($logdir.$file.".log", "a")) !== false) {
			if (!defined("SLOG_LOGGED_".strtoupper($file))) {
				$log = "\n[".date("d/m/Y H:i:s")."] ".((isset($GLOBALS["USER"]) ? "(uid={$GLOBALS["USER"]["id"]}) {$GLOBALS["USER"]["username"]}@": ""))."".getIP()." [{$_SERVER["HTTP_USER_AGENT"]}]\n{$_SERVER["REQUEST_URI"]}";
				$log = $string ? "$log\n-- $string\n" : "$log\n";
				define("SLOG_LOGGED_".strtoupper($file), true);
			}
			fwrite($h, isset($log) ? $log : "-- $string\n");
			fclose($h);
		}
	}

	/*
	*	abort();
	*	Aborts Gekko execution, closes SQL connections.
	*/
	function abort($msg = null, $output_buffer = true) {

		shutdown(false);

		$msg = Lang::Parse($msg);

		slog("core: Script aborted ".($msg ? $msg : "No error message")."");

		if ($msg)
			echo $msg;

		if ($output_buffer && function_exists("gzoutput"))
			gzoutput();

		exit();
	}

	/*
		Reads and entire file
	*/
	function fileRead($fname) {
		if (($h = @fopen($fname, "r")) !== false) {
			$c = fread($h, filesize($fname));
			fclose($h);
			return $c;
		} else {
			trigger_error("Couldn't read \"$fname\".", E_USER_ERROR);
		}
	}

	function listdir($dir, $recursive = false, $only_files = false) {

		if (substr($dir, -1) != "/") $dir .= "/";

		$dp = @opendir($dir);
		$dc = Array();
		while (($file = @readdir($dp)) !== false) {
			if ($file != "." && $file != "..") {
				if ($recursive && is_dir($dir.$file)) {
					$tmp = listdir($dir.$file, true);
					$dfs = Array();
					foreach ($tmp as $f) {
						$dfs[] = $file."/".$f;
					}
					$dc = array_merge($dc, $dfs);
					if ($only_files) continue;

				}
				$dc[] = $file;
			}
		}
		@closedir($dp);
		return $dc;
	}

	function redirect($where = null) {

		$where = trim(preg_replace("/[\r|\n](.*?)/", "", $where));

		if (substr($where, 0, 1) != '/') {

			if ($where)
				$where = urlEvalPrototype($where, true, false);

			if (preg_match("/^[a-z0-9A-Z]:\/\/.*$/", $where)) {
				$location = $where;
			} else {
				$location = $where ? $where : $_SERVER['HTTP_REFERER'];
			}

		} else {
			$location = $where;
		}

		if ((isset($_GET["ajax_flag"]) && $_GET["ajax_flag"] == 1) || (isset($_POST["ajax_flag"]) && $_POST["ajax_flag"] == 1))
			echo "Location: ".html_entity_decode($location);
		else
			header("Location: $location");
	}

	function sanitize(&$var, $force = false) {
		if (is_array($var)) {
			while (list($key) = each($var))
				sanitize($var[$key], $force);
		} else {
			if ($force)
				$var = stripslashes($var);
			if ($force || !get_magic_quotes_gpc())
				$var = addslashes($var);
		}
	}

	function checkAuthStr($auth) {
		return ($auth == _l("C_AUTH_STR"));
	}

	function accessDenied($print = false, $file = false, $line = false) {
		if (GEKKO_ENABLE_DEBUG && $file && $line) {
			echo "$file:$line\n";
		}
		if ($print) {
			echo _l("E_ACCESS_DENIED");
		} else {
			if (function_exists("mkmessagebox"))
				return mkMessageBox("error", _l("E_ACCESS_DENIED"));
			return _l("E_ACCESS_DENIED");
		}
	}

	function gdebug($text, $exit = 1) {
		header("content-type: text/plain");
		print_r($text);
		if ($exit) die;
	}

	### DATE HANDLING FUNCTIONS
	function mkdate($unixtime = null) {
		return date("d-m-Y H:i:s A", $unixtime ? $unixtime : time());
	}
	function time2date($unixtime = null) {
		return date("Y-m-d H:i:s", $unixtime ? $unixtime : time());
	}
	function date2time($sqldate) {

		$sqldate = preg_replace("/[^0-9]/", "", $sqldate);

		$y = substr($sqldate, 0, 4);
		$m = substr($sqldate, 4, 2);
		$d = substr($sqldate, 6, 2);
		$h = substr($sqldate, 8, 2);
		$i = substr($sqldate, 10, 2);
		$s = substr($sqldate, 12, 2);

		return mktime((int)$h, (int)$i, (int)$s, (int)$m, (int)$d, (int)$y);
	}

	function date2mysqltime($date) {
		return sprintf("%4d%2d%2d000000", $date["y"], $date["m"], $date["d"]);
	}

	function file_extension($file) {
		return strtolower(substr($file = basename($file), (strpos(strrev($file), ".")*-1)));
	}


	function local_referer() {
		if (isset($_SERVER["HTTP_REFERER"])) {
			preg_match("/http:\/\/.*?\/(.*)/", $_SERVER["HTTP_REFERER"], $m);
			return "/".$m[1];
		} else {
			return "";
		}
	}
	function db_languagelock() {
		return "(language_id = '".GEKKO_LANGUAGE_ID."')";
	}
	/*
		timeMark(yyyy.mm.dd)
		@returns: unix timestamp range
	*/
	function timeMark($date) {
		if ($date) {
			$date = explode("-", $date);
			if (isset($date[2])) {
				// year-month-day
				$lo = mktime(0, 0, 0, (int)$date[1], (int)$date[2], (int)$date[0]);
				$hi = mktime(23, 59, 59, (int)$date[1], (int)$date[2], (int)$date[0]);
			} else if (isset($date[1])) {
				// year-month
				$lo = mktime(0, 0, 0, (int)$date[1], 1, (int)$date[0]);
				$hi = mktime(23, 59, 59, (int)$date[1], date("t", $lo), (int)$date[0]);
			} else if (isset($date[0])) {
				// year
				$lo = mktime(0, 0, 0, 1, 1, (int)$date[0]);
				$hi = mktime(23, 59, 59, 12, 31, (int)$date[0]);
			} else {
				return false;
			}
			return array($lo, $hi);
		}
		return false;
	}
	function use_ssl() {
		if ((!defined("GEKKO_NO_SSL") || GEKKO_NO_SSL != true) && !isset($_GET["no_ssl"]) && !isset($_SERVER["HTTPS"])) {
			// trying to determine if this server supports ssl
			if (function_exists("apache_get_modules")) {
				$ap_mods = apache_get_modules();
				// if it does, redirecting user to SSL mode.
				if (in_array("mod_ssl", $ap_mods)) {
					if (!defined("IN-INSTALL"))
						$GLOBALS["AccessTable"]->dropEntry("core-exec-preban");
					redirect("https://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"]);
					abort(null, false);
				}
			}
		}
	}
	function ssl_normal_redirect(&$return) {
		// using ssl only for specifical tasks
		if (isset($_SERVER["HTTPS"])) {
			if ($return) {
				$return = "http://".$_SERVER["HTTP_HOST"].dirname($_SERVER["SCRIPT_URL"])."/".$return;
			} else {
				$return = "http".substr($_SERVER["HTTP_REFERER"], 5);
			}
		}
	}

	// converts text strings into a url-friendly form
	function urlTitleEncode($title) {
		$title = rawurlencode(str_replace("/", "-", $title));
		return $title;
	}
	/* makes a filename looking cute */
	function beauty_basename($file) {
		$title = basename($file);
		$title = substr($title, 0, strlen($title) - strpos(strrev($title), ".") - 1);
		$title = ucwords(preg_replace("(_|-)", " ", $title));
		return $title;
	}

	function is_user() {
		return gauth("$");
	}

	function shutdown($exit = true) {

		if (isset($GLOBALS["db"]))
			$GLOBALS["db"]->close();

		gekko_session_save();

		if ($exit)
			exit();
	}

	function gekko_session_start() {
		require_once GEKKO_SOURCE_DIR."lib/blowfish.lib.php";

		session_start();

		// getting the sess key
		if (isset($_COOKIE["sess"]) && isset($_SESSION["data"])) {
			// never trust the client side...
			$_COOKIE["sess"] = substr(preg_replace("/[^a-zA-Z0-9]/", '', $_COOKIE["sess"]),0, 48);

			$bf = new Crypt_Blowfish(substr($_COOKIE["sess"], 0, 48));
			$data = @unserialize(@gzuncompress($bf->decrypt($_SESSION["data"])));
			$_SESSION = $data ? $data : array();

		} else {
			$_SESSION = array();
		}
	}

	function gekko_session_save() {
		if (!defined("GEKKO_SESSION_SAVED")) {

			require_once GEKKO_SOURCE_DIR."lib/blowfish.lib.php";

			if (!isset($_COOKIE["sess"])) {
				// creating a new random key (length = 48)
				$_COOKIE["sess"] = genkey(48);
				@setcookie("sess", $_COOKIE["sess"], time()+84600, '/');
			}

			// never trust the client side...
			$_COOKIE["sess"] = substr(preg_replace("/[^a-zA-Z0-9]/", '', $_COOKIE["sess"]), 0, 48);

			$bf = new Crypt_Blowfish($_COOKIE["sess"]);

			$data = gzcompress(serialize($_SESSION));
			$_SESSION = array();
			$_SESSION["data"] = $bf->encrypt($data);

			session_write_close();

			define("GEKKO_SESSION_SAVED", true);
		}
	}

	function is_absolute_path($filename) {
		if (isset($_SERVER["WINDIR"])) {
			return preg_match("/^[A-Z]:\\.*?/i", $filename);
		} else {
			return ($filename[0] == '/');
		}
	}

	sanitize($_GET);
	sanitize($_POST);
	sanitize($_COOKIE);
	sanitize($_SERVER, true);

	if (!defined("IN-INSTALL"))
		cacheInit();
?>
