<?php
/* $Id: userfunc.inc.php,v 1.96 2004/12/13 14:19:50 k-fish Exp $ */
/* User-Functions for Moregroupware */

if (!defined('ROOTPATH')) die("This is a library.");

// adding file revision into global array
if(function_exists("revisionInit")) revisionInit("\$Revision: 1.96 $", __FILE__);

// ===================
// define module types
// ===================
define('MODULE_TYPE_CORE', 1);
define('MODULE_TYPE_BASE', 2);
define('MODULE_TYPE_NORMAL', 3);

// helper for recursive deletion
function recDel($path){
    $dir = opendir($path);
    while(($file = readdir($dir)) !== false){
	if($file != '.' && $file != '..'){
	    if(is_dir("$path/$file")){
		recDel("$path/$file");
		@rmdir("$path/$file");
	    }
	    else
		@unlink("$path/$file");
	}
    }
} // end recDel()

function mgw_genID($seq_string,$limit=0) {
  global $conn;

  if ($limit > 0) {

    $id = $conn->genID($seq_string, $limit);
    if ($id < $limit) {
	  $id = $id + $limit;
	}
	return $id;
  } else {
    return $conn->genID($seq_string);
  }
}

// ====================================================
// See if is module installed
// ====================================================
function isModuleInstalled($module) {
    global $conn;

    $sql = "SELECT modulename FROM mgw_modules WHERE modulename=".$conn->QMagic($module);
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $row = $res->FetchRow();
    if($row["modulename"]==$module) return true;
    return false;
}

// ====================================================
// See if is module active
// ====================================================
function isModuleActive($module) {
    global $conn;

    $sql = "SELECT active FROM mgw_modules WHERE modulename=".$conn->QMagic($module);
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $row = $res->FetchRow();
    if($row["active"]==1) return true;
    return false;
}

// =================================================
// get installed modules, active and inactive
// =================================================
function getInstalledModules() {
    global $conn;
    
    /* clean $MGW->modules to fix sort problems */
    $ret = array();
    
    /* include non-active modules because $MGW->modules[modulename]["active"]
     * will be availible to programmers
     */
    $sql = "SELECT * FROM mgw_modules ORDER BY modulename!='general',modulename!='overview',modulename";
    if(!$res = $conn->Execute($sql)) exit(showSQLerror2($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    while ($row = $res->FetchRow()) {
        /* the name of a module (i.e. admin) wil be the array key because we don't
         * install a certain module more than once and this makes checking if a module
         * is installed much faster. maybe a function moduleIsInstalled(modulename)
         * would be handy (i.e. return (isset($MGW->modules[modulename]))
         */
        
	$data["active"] = $row["active"];
	$data["lu_user"] = $row["lu_user"];
	$data["lu_date"] = $row["lu_date"];

	$data["modulename"] = $row["modulename"];
	$data["folder"] = $row["modulename"];
	$data["name"] = $row["modulename"];
	$data["secure"] = isset($row["secure"])?$row["secure"]:0;
	$data["version"] = isset($row["version"])?$row["version"]:"0-68";
	$data["version_mtime"] = isset($row["version_mtime"])?$row["version_mtime"]:"";
	$data["base"] = isset($row["base"])?$row["base"]:"";
	$data["date"] = isset($row["date"])?$row["date"]:"";
	$data["author"] = isset($row["author"])?$row["author"]:"";
	$data["email"] = isset($row["email"])?$row["email"]:"";
	$data["description"] = $row["description"];
	$data["compatibility"] = isset($row["compatibility"])?$row["compatibility"]:"";
	$data["dependancies"] = isset($row["dependancies"])?$row["dependancies"]:"";
	$data["module_type"] = isset($row["module_type"])?$row["module_type"]:"";

	$ret[$row["modulename"]] = $data; 
    }
    
    return $ret;
}

// ====================================================
// See if user is still valid (auth against session)
// ====================================================
//
function checkLogin(){ 
    global $appconf;

    if (!isset($_SESSION["MGW"])){
        redirect(ROOTURL. "index.php?".SID);
	exit();
    }

    if(!isset($_SESSION["MGW"]->username)) {
	redirect(ROOTURL. "index.php?".SID);
	exit();
    }

    if($_SESSION["checkip"] && ($_SESSION["remoteip"] != get_remote_addr() || $_SESSION["http_user_agent"] != $_SERVER["HTTP_USER_AGENT"])){
	redirect(ROOTURL. "index.php?".SID);
	exit();
    }

    return true;
}

function queryRights2_bool($id_string) { 
  global $conn;

  $sql = "SELECT id_string,default_value,allow_users,deny_users,allow_groups,deny_groups FROM mgw_rights2 WHERE id_string=".$conn->quote($id_string);
  if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
  $row = $res->FetchRow();

  if (!isset($row["default_value"])) return false;
  if (!isset($_SESSION["MGW"]->userid)) return (bool)$row["default_value"];
  
  if ($row["default_value"]==0) {
    if (strpos("@".$row["allow_users"],",".$_SESSION["MGW"]->userid.",")>0) return true;
    foreach ($_SESSION["MGW"]->groups as $group) {
      if (strpos("@".$row["allow_groups"],",".$group.",")>0) return true;
	}
	return false;
  } else {
	if (strpos("@".$row["deny_users"],",".$_SESSION["MGW"]->userid.",")>0) return false;
    foreach ($_SESSION["MGW"]->groups as $group) {
      if (strpos("@".$row["deny_groups"],",".$group.",")>0) return false;
	}
	return true;
  }

  return $result;
}

function queryRights2($id_string) { 
  global $conn,$smarty,$appconf;

  if (!queryRights2_bool($id_string)) {
	$smarty->assign("errorheader",Lang::getLanguageString("permerror"));
	$smarty->assign("permerror",Lang::getLanguageString("permerrormsg"));
	$smarty->display($appconf["gentemplates"] ."/perm_errors.tpl");
	die();
  }
}

function query_access_module($module) {
  if ($module == "help") return true;
  if ($module == "general") return false;
  if ($_SESSION["MGW"]->username=="admin") return true;
  return queryRights2_bool("root_modules_".$module."_accessmodule");
}

function get_user_groups() {
  global $conn;

  $groups = array();
  if (isset($_SESSION["MGW"]->userid) && $_SESSION["MGW"]->userid and !count($_SESSION["MGW"]->groups)>0) {
    $sql = "SELECT * FROM mgw_groups_members WHERE userid=".$_SESSION["MGW"]->userid;
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    while($row = $res->FetchRow()) {
      $groups[] = $row["groupid"];
    }
  }
  return $groups;
}

function get_user_groups_names() {
  global $conn;

  $groups = array();
  if (isset($_SESSION["MGW"]->userid) && $_SESSION["MGW"]->userid and !count($_SESSION["MGW"]->groups_names)>0) {
    $sql = "SELECT * FROM mgw_groups_members,mgw_groups WHERE mgw_groups_members.userid=".$_SESSION["MGW"]->userid." and mgw_groups.id=mgw_groups_members.groupid";
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    while($row = $res->FetchRow()) {
      $groups[] = "@".strtolower($row["name"]);
    }
  }
  return $groups;
}


// ====================================================
// get actual Settings 
// ====================================================
//
function getUserSettings(){
    global $conn;

    // general settings (modulename *)  
    // this ensure that we also load the module independent settings !!

    $_SESSION["MGW"]->settings = array();
	
    // grab other module names from database
    $sql = "SELECT * FROM mgw_modules";
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));

    while($row = $res->FetchRow()) {
        $modulename[] = $row["modulename"];
    }

    if (!in_array("general",$modulename)) $modulename[] = "general";

    for($set_i=0;$set_i<count($modulename);$set_i++) {
	if (file_exists(ROOTPATH."/modules/".$modulename[$set_i]."/inc/settings.inc.php")) {
	    include ROOTPATH."/modules/".$modulename[$set_i]."/inc/settings.inc.php";
	}

        // little bit tricky:
        // shows all tags for actual module for "default" and "user"
        // the result is ordered by userid, this means that if a configtag
        // like "iconmode" is set to "0" in default(user) and "1" to actual
        // user, then "1" is taken (it overwrites the previous "0" in the array).
        // If the user has no mapping for iconmode then the default "0" is used.
        $sql = "SELECT * FROM mgw_configtags LEFT JOIN mgw_config ON mgw_configtags.configtagname=mgw_config.configtagname WHERE mgw_configtags.modulename=".$conn->QMagic($modulename[$set_i])." AND mgw_config.userid=".(int)$_SESSION["MGW"]->userid." OR mgw_configtags.modulename=".$conn->QMagic($modulename[$set_i])." AND mgw_config.userid=0 ORDER BY mgw_config.userid, mgw_config.serialnr";
    
        // echo $sql. "<p>";
        if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    
        while($row = $res->FetchRow()) {
            // if there are multiple dimensions for actual setting, save them in array instead
            // of a normal index in an array
            if($row["multipledimensions"]==1) {
                // when multiple dimension is on, delete defaults if at least one user dimension is there
                if($row["userid"]!=0 && $row["serialnr"]==1) $_SESSION["MGW"]->settings[$row["configtagname"]] = "";
    
                if($row["valuetype"]=="int") $_SESSION["MGW"]->settings[$row["configtagname"]][] = $row["value_int"];
                if($row["valuetype"]=="str") $_SESSION["MGW"]->settings[$row["configtagname"]][] = $row["value_str"];
                if($row["valuetype"]=="txt") $_SESSION["MGW"]->settings[$row["configtagname"]][] = $row["value_txt"];
            } else {
                if($row["valuetype"]=="int") $_SESSION["MGW"]->settings[$row["configtagname"]] = $row["value_int"];
                if($row["valuetype"]=="str") $_SESSION["MGW"]->settings[$row["configtagname"]] = $row["value_str"];
                if($row["valuetype"]=="txt") $_SESSION["MGW"]->settings[$row["configtagname"]] = $row["value_txt"];
            }
        }
		
	//load default value if not set:
	if (isset($settings[$modulename[$set_i]]) && is_array($settings[$modulename[$set_i]])) foreach ($settings[$modulename[$set_i]] as $my_module_settings) {
            if (is_array($my_module_settings)) foreach ($my_module_settings as $key=>$key2) {
		if (!isset($_SESSION["MGW"]->settings[$key]) and isset($key2["default"])) {
		    $_SESSION["MGW"]->settings[$key] = $key2["default"];
		}
            }
        }
    }// end for
    
    /* set date formats */
    $_SESSION["MGW"]->settings["datefmt"] = getDateFormate($_SESSION["MGW"]->settings["set_datefmt"],$_SESSION["MGW"]->settings["set_dmysep"]);
    $_SESSION["MGW"]->settings["timefmt"] = getDateFormate($_SESSION["MGW"]->settings["set_timefmt"],$_SESSION["MGW"]->settings["set_hourminsep"]);
}

function getDateFormate($fmt, $sep) {
	$ret = "";
    if ($fmt=="24h" or $fmt=="12h") {
        /* time */
        if ($fmt=="12h") {
            $ret = "h".$sep."ia";              
        } else {
            $ret = "H".$sep."i";
        }
    } else {
        /* date */
        for ($i=0;$i<strlen($fmt);$i++) {
            $ret .= $fmt[$i];
	    if ($i==0 || ($i!=0 && ($i != strlen($fmt)-1) && ($fmt[$i] != $fmt[$i-1]))) $ret .= $sep;
        }
    }
    return $ret;
}

// ====================================================
// Connect to Database (see config.inc.php) ADOdb
// ====================================================
//
function connect_database(){
    global $appconf;
    include ROOTPATH. '/include/adodb/adodb.inc.php'; // include adodb class
    $conn = ADONewConnection($appconf["dbvendor"]);    // create a connection
    $conn->PConnect($appconf["dbhost"], $appconf["dbuser"], $appconf["dbpassword"], $appconf["dbname"]);
    
    return $conn;
}

// ====================================================
// Show SQL Errors (ADOdb) 
// usage: showSQLerror(sql, ADODB error message, __LINE__, __FILE__)
// ====================================================
function showSQLerror($sql, $error = '', $where_line = '', $where_file = '') {
    global $appconf, $gwversion, $Revisions_array, $conn;
    // get the install files version (this is sometimes different
    // than the installed version (if people just copy the file over
    // a current installation)
    
    echo "<html>\n";
    echo "<head>\n";
    echo "<style type=\"text/css\">\n";
    echo "body {background-color:#555d66; color:#ffffff; font-family:Verdana,Helvetica,sans-serif;}\n";
    echo "a{color:#ffff33;}\n";
    echo "a:active{color:#ffff33;}\n";
    echo "a:visited{color:#ffff33;}\n";
    echo "hr {height:0px; border-width:1px; border-color:#dddddd; border-style:none none solid none;}\n";
    echo "</style>\n</head>";
    echo "<body>\n";
    echo "<img src=\"". ROOTURL. "modules/general/templates/default/media/mgwlogo.gif\" align=\"right\">\n";
    echo "<br /><h3>Problem in Moregroupware found!</h3>\n";
    echo showSystemInfo($where_line, $where_file);
    echo "<strong>Error (SQL)</strong>:<br />". $sql . "<br />\n";
    echo "<br /><strong>Error (MSG)</strong>:<br />". $error . "<br /><br />\n";
    echo "<strong>Dump</strong>:<br />POST: <pre>"; print_r($_POST); echo "</pre><br />GET: <pre>"; print_r($_GET);
    echo "</pre><br /><br /><hr />";
    echo "<br />Please report this error to our <a href=\"https://sourceforge.net/tracker/?func=add&group_id=32034&atid=404018\">Bugtracker</a> on sourceforge.net. Make sure to include the complete output on this screen into the bug report, along with a description of the steps that led to the error. Thanks for using moregroupware!\n";
    echo "</body>\n";
    echo "</html>\n";
}

function showSystemInfo($where_line = '', $where_file = ''){
    global $appconf, $conn, $Revisions_array;
    if(defined('INCLUDEPATH'))
	include(INCLUDEPATH . "version.inc.php");

    $str = '';
    $str .= "<table cellspacing=\"4\">\n";
    $str .= "<tr><th align=\"right\">Version (config.inc.php):</th><td>". $appconf["mgw_version"]. "</td></tr>\n";
    $str .= "<tr><th align=\"right\">Version (version.inc.php):</th><td>$gwversion</td></tr>\n";
    $str .= "<tr><th align=\"right\">PHP version:</th><td>".phpversion()."</td></tr>\n";
    $str .= "<tr><th align=\"right\">PHP OS:</th><td>".PHP_OS."</td></tr>\n";
    $str .= "<tr><th align=\"right\">register_globals:</th><td>".(int) ini_get("register_globals")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">magic_quotes_gpc:</th><td>".(int) ini_get("magic_quotes_gpc")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">safe_mode:</th><td>".(int) ini_get("safe_mode")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">sql.safe_mode:</th><td>".(int) ini_get("sql.safe_mode")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">Server software:</th><td>".$_SERVER["SERVER_SOFTWARE"]."</td></tr>\n";
    $str .= "<tr><th align=\"right\">User-Agent:</th><td>".$_SERVER["HTTP_USER_AGENT"]."</td></tr>\n";

    $str .= "<tr><th align=\"right\">session.use_trans_sid:</th><td>".(int) ini_get("session.use_trans_sid")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">session.auto_start:</th><td>".(int) ini_get("session.auto_start")."</td></tr>\n";

    $str .= "<tr><th align=\"right\">file_uploads:</th><td>".(int) ini_get("file_uploads")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">upload_max_filesize:</th><td>".ini_get("upload_max_filesize")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">upload_tmp_dir:</th><td>".ini_get("upload_tmp_dir")."</td></tr>\n";

    $str .= "<tr><th align=\"right\">memory_limit:</th><td>".ini_get("memory_limit")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">post_max_size:</th><td>".ini_get("post_max_size")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">max_execution_time:</th><td>".(int) ini_get("max_execution_time")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">max_input_time:</th><td>".(int) ini_get("max_input_time")."</td></tr>\n";
    $str .= "<tr><th align=\"right\">magic_quotes_runtime:</th><td>".(int) ini_get("magic_quotes_runtime")."</td></tr>\n";

    $dbinfo = $conn->ServerInfo();
    $str .= "<tr><th align=\"right\">Database:</th><td>".$appconf['dbvendor'].' / '.$dbinfo['description']." (".$dbinfo['version'].")</td></tr>\n";
    $str .= "<tr><th align=\"right\">Program:</th><td>".$_SERVER["PHP_SELF"]."</td></tr>\n";
    if($where_file!='') {
	$str .= "<tr><th align=\"right\">File:</th><td>$where_file</td></tr>\n";
	$rev_index = strtr(substr($where_file,-1*(strlen($where_file)-strrpos($where_file,"/")-1)),".","_");
	if(isset($Revisions_array[$rev_index])) $str .= "<tr><th align=\"right\">File revision:</th><td>".$Revisions_array[$rev_index]."</td></tr>\n";
    }
    if($where_line!='')
	$str .= "<tr><th align=\"right\">Line:</th><td>$where_line</td></tr>\n";
    $str .= "</table>\n<br />\n";

    return $str;
}

// ====================================================
// Redirect Wrapper
// ====================================================
//
function redirect($uri) {

    if(PHP_OS=="WINNT" || PHP_OS=="WIN32") {
	// we have problems with REFRESH with opera, so we use
	// location for opera and refresh for IE on WIN32
	if(strstr($_SERVER["HTTP_USER_AGENT"], "Opera")) {
	    header("Location: $uri");
	    exit();
	}
	else {
	    header("Refresh: 0; url=\"$uri\"");
	    exit();
	}
    }
    else {
	header("Location: $uri");
	exit();
    }
}

// ====================================================
// Create Submenu
// ====================================================
//
function createSubmenu($menuarray) {
    global $smarty, $myEnv;

    for($i=0;$i<count($menuarray);$i++) {
	  if (isset($menuarray[$i]["link"])) { $menuarray[$i]["link"] = addslashes($menuarray[$i]["link"]); }
    $smarty->append("sdata", $menuarray[$i]);
    }
    $smarty->assign("navimodule", $myEnv["module"]);
}


function get_user_info($user){
    global $conn, $appconf;

    // now we just look for the username and not for the password anymore.
    if(is_int($user))
	$sql = "SELECT * FROM mgw_users WHERE id=".(int)$user;
    else
	$sql = "SELECT * FROM mgw_users WHERE username=".$conn->QMagic($user);

    if(($row = $conn->GetRow($sql))===false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));

    $sql = ($row["lang"] == "login") ? "SELECT charset FROM mgw_languages WHERE langcode=".((isset($_POST["language"])) ? $conn->QMagic($_POST["language"]) : "'".$appconf['def_language']."'") : "SELECT charset FROM mgw_languages WHERE langcode=".$conn->QMagic($row["lang"]);
    if(($cs = $conn->GetOne($sql))===false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $row["charset"] = $cs;

    return $row;
}
 

function create_user_account_on_login($user){
    global $conn;
    
    //these vaules should not be harcoded, they should come from configuration.
    $id = mgw_genID('mgw__seq_users', 5);
    $pw = $conn->QMagic("auto_created_invalid_pwd");

    $sql = "INSERT INTO mgw_users (id, username, pw, skintheme, lang, lu_date, lastin, level) VALUES (".$id.", ".$conn->QMagic($user).",".$pw.",'backend.css', 'login', NOW(), NOW(), ".UACTIVE.")";
    if(!$conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));

    $sql="INSERT INTO mgw_groups_members (groupid, userid, lu_user, lu_date) VALUES (50001, ".$id.", 1, NOW())";
    if(!$conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
}

// =================================================
// alphabet_table user in contact and news module
// =================================================
function alphabet_table($args="action=alphab",$linkurl="index.php") {
    switch($_SESSION["MGW"]->spkz) {
    case "cs":
    $at = array ("A","Á","B","C","È","D","Ï","E","É","F","G","H","I","Í","J","K","L","M","N","Ò","O","Ó","P",
             "Q","R","Ø","S","©","T","«","U","Ú","V","W","X","Y","Ý","Z","®");
    break;
    case "nb":
    $at = array ("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R",
             "S","T","U","V","W","X","Y","Z","Æ","Ø","Å");
    break;
    case "de":
    $at = array ("A","Ä","B","C","D","E","F","G","H","I","J","K","L","M","N","O","Ö","P","Q","R",
             "S","T","U","Ü","V","W","X","Y","Z");
    break;
    case "ru":
     $at = array ("á","â","÷","ç","ä","å","³","ö","ú","é","ê","ë","ì","í","î","ï","ð","ò","ó","ô",
		  "õ","æ","è","ã","þ","û","ý","ù","ü","à","ñ");
    break;
    default:    
    $at = array ("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R",
             "S","T","U","V","W","X","Y","Z");
    break;
    }
    
    $out = "<table cellpadding=\"3\" cellspacing=\"2\">\n";
    $out .= "<tr>\n";
    $out .= "<td class=\"stand\"><a href=\"$linkurl?$args&amp;".SID."\">". Lang::getLanguageString("all") . "</a>\n";
    
    for($i=0;$i<count($at);$i++) {
        $out .= "<td class=\"stand\"><a href=\"$linkurl?$args&amp;list=".urlencode($at[$i])."&amp;".SID."\">" . $at[$i] . "</a></td>\n";
        if(count($at)>26 && $i==(ceil(count($at)/2))-1) $out .="</tr><tr><td>&nbsp;</td>";
    }
    if($i%2==1) $out.="<td>&nbsp;</td>";    
    
    $out .= "</tr>\n";
    $out .= "</table>\n";
    return $out;
}

// ======================================================================
// function to add revision of referer to global Revisions_array array
// ======================================================================
function revisionInit($revision, $file) {
    global $Revisions_array;
    $rev_index = strtr(substr($file,-1*(strlen($file)-strrpos($file,"/")-1)),".","_");
    $rev_value = substr(addslashes($revision),11,-2);
    $Revisions_array[$rev_index] = $rev_value;
}

// ======================================================================
// if user wants icons, assign icons if not -> not
// ======================================================================
function getIconStrings(){
    global $smarty,$appconf;
    $settings=$_SESSION["MGW"]->settings;

    if($settings["iconmode"]==1) {
	$icons["new"] = "<img src=\"". $appconf["imgpathgeneral"]. "/new_". $settings["iconid"]. ".gif\" border=\"0\" alt=\"".Lang::getLanguageString("new")."\" title=\"".Lang::getLanguageString("new")."\">";
	$icons["details"] = "<img src=\"". $appconf["imgpathgeneral"]. "/details_". $settings["iconid"]. ".gif\" border=\"0\" alt=\"".Lang::getLanguageString("details")."\" title=\"".Lang::getLanguageString("details")."\">";
	$icons["edit"] = "<img src=\"". $appconf["imgpathgeneral"]. "/edit_". $settings["iconid"]. ".gif\" border=\"0\" alt=\"".Lang::getLanguageString("edit")."\" title=\"".Lang::getLanguageString("edit")."\">";
	$icons["delete"] = "<img src=\"". $appconf["imgpathgeneral"]. "/delete_". $settings["iconid"]. ".gif\" border=\"0\" alt=\"".Lang::getLanguageString("delete")."\" title=\"".Lang::getLanguageString("delete")."\">";

	$icons["private"] = "<img src=\"". $appconf["imgpathgeneral"]. "/private_". $settings["iconid"]. ".gif\" border=\"0\">";

	$icons["prev"] = "<img src=\"". $appconf["imgpathgeneral"]. "/left_". $settings["iconid"]. ".gif\" border=\"0\">";
	$icons["next"] = "<img src=\"". $appconf["imgpathgeneral"]. "/right_". $settings["iconid"]. ".gif\" border=\"0\">";

	$icons["space"] = "&nbsp;&nbsp;";

	$smarty->assign("iconid", $settings["iconid"]);
	$smarty->assign("iconmode", true);
    } else {
	$icons["new"] = Lang::getLanguageString("new");
	$icons["details"] = Lang::getLanguageString("details");
	$icons["edit"] = Lang::getLanguageString("edit");
	$icons["delete"] = Lang::getLanguageString("delete");

	$icons["private"] = "P"; //should be replaced, but i don't know with what :)

	$icons["prev"] = "&lt;&lt;--|";
	$icons["next"] = "|--&gt;&gt;";

	$icons["space"] = "&nbsp;&nbsp;";

	$smarty->assign("iconmode", false);
    }
    return $icons;
}

// ====================================================
// Creates a country select box with favourite feature
// ====================================================
function createCountrySB ($sbname, $selected=""){
    global $conn;
    
    $favouritesel = false;

    // first get the favourite and the first line "please chose...."
    //
    $out = "<select name=\"$sbname\" size=\"1\">\n";
    $out .= "<option value=\"\">". Lang::getLanguageString("chosecountrytext") ."</option>\n";
    for($i=0;$i < count($_SESSION["MGW"]->settings["favourite_countries"]);$i++) {
    $sql = "SELECT name FROM mgw_countries WHERE code=".$conn->QMagic($_SESSION["MGW"]->settings["favourite_countries"][$i]);
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $row = $res->FetchRow();
    if($_SESSION["MGW"]->settings["favourite_countries"][$i]==$selected) {
        $seltext = " selected";
        $favouritesel = true;
    } else $seltext = "";
    $out .= "<option value=\"". $_SESSION["MGW"]->settings["favourite_countries"][$i] ."\"$seltext>". $row["name"]. "</option>\n";
    }
    $out .= "<option value=\"\">-----------------------------</option>\n";

    // now get the normal country list
    $sql = "SELECT * FROM mgw_countries";
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    while($row = $res->FetchRow()) {
	if($row["code"]==$selected and !$favouritesel) $seltext = " selected"; else $seltext = "";
	$out .= "<option value=\"". $row["code"]. "\"$seltext>". $row["name"]. "</option>\n";
    }
    $out .= "</select>\n";

    return $out;
}

/**
 * This is a email validating function seperate to the rest
 * of the class. It simply validates whether an email is of
 * the common internet form: <user>@<domain>. This can be
 * sufficient for most people. Optional stricter mode can
 * be utilised which restricts mailbox characters allowed
 * to alphanumeric, full stop, hyphen and underscore.
 *
 * @param  string  $data   Address to check
 * @param  boolean $strict Optional stricter mode
 * @return mixed           False if it fails, an indexed array
 *                         username/domain if it matches
 */
function isValidInetAddress($data, $strict = false){
    // if we see localhost in the address, don't check further.
    if(stristr($data,'localhost'))
	return explode('@', $data);

    $regex = $strict ? '/^([.0-9a-z_-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4})$/i' : '/^([*+!.&#$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4})$/i';
    if (preg_match($regex, trim($data), $matches)) {
	return array($matches[1], $matches[2]);
    } else {
	return false;
    }
}


function inList($in_list,$item)	{
    return strstr(",".$in_list.",", ",".$item.",");
}
	
function get_definition_data_from_xml($thefile) {
    $data = implode("",file($thefile));
    $data = substr($data,strpos($data,"<mgw>"));
    $parser = xml_parser_create();
    xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
    xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
    xml_parse_into_struct($parser,$data,$values,$tags);
    xml_parser_free($parser);

    $data = array();
    foreach ($values as $value) {
	if (isset($value["tag"]) and isset($value["value"])) $data[$value["tag"]][] = $value["value"];
    }

    if (!isset($data["name"][0])) die("<br>Could not find module name.<br><br><a href='../admin/modulemanager.php?".SID."'>Go back</a> to module manager.");
    if (!isset($data["version"][0])) die("<br>Could not find module version.<br><br><a href='../admin/modulemanager.php?".SID."'>Go back</a> to module manager.");
    if (!isset($data["module_type"][0])) $data["module_type"][0] = 3;

    return $data;
}

function get_definition_countries_from_xml($thefile) {
    $data = implode("",file($thefile));
    $data = substr($data,strpos($data,"<countries>"));
    $parser = xml_parser_create();
    xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
    xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
    xml_parse_into_struct($parser,$data,$values,$tags);
    xml_parser_free($parser);

    $data = array();
    foreach ($values as $value) {
	if (isset($value["attributes"]) and is_array($value["attributes"]) and count($value["attributes"])>0) $data[] = $value["attributes"];
    }

    return $data;
}

function execute_xml_schema($thefile,$module,$dbvendor) {
    global $conn, $buffer;

    $schema = new adoSchema($conn);
    $schema->setPrefix( "mgw" );

    $sqls = $schema->ParseSchema($thefile);
    
    // what is this part for? why those replacements?
    /*
    foreach ($sqls as $key=>$sql) {
 	if ($dbvendor=="mysql") {
 	    $sqls[$key] = str_replace("LONGTEXT","TEXT",$sqls[$key]);
 	    $sqls[$key] = str_replace("DATETIME","TIMESTAMP",$sqls[$key]);
 	}
    }
    */

    if (count($sqls)>0){
	$buffer .= "Executing schema ...\n";
	foreach ($sqls as $sql) {
	    if (is_array($sql) and count($sql)>0) {
		foreach ($sql as $sqlitem) {
		    if(!$res = $conn->Execute($sqlitem)) $buffer .= "\nSQL FAILED: ".$sqlitem."\n".$conn->ErrorMsg()."\n\n";
		}
	    } elseif (!is_array($sql)) {
		if(!$res = $conn->Execute($sql)) $buffer .= "\nSQL FAILED: ".$sql."\n".$conn->ErrorMsg()."\n\n";
	    }
	}
    }
    else
	$buffer .= "\nNo XML-SQL-Schema found.\n\n";

    $schema->Destroy();
}
	
function indentSubTagsRec($officeBody,$depth=1)	{
    if ($depth<1)	return $officeBody;		
    $officeBody = indentSubTags($officeBody);
    
    if ($depth>1)	{
	reset($officeBody);
	while(list($k,$v)=each($officeBody))	{
	    if (is_array($officeBody[$k]['subTags']))	{
		$officeBody[$k]['subTags'] = indentSubTagsRec($officeBody[$k]['subTags'],$depth-1);
	    }
	}
    }
    return $officeBody;
}

function indentSubTags($officeBody)	{
    $newStruct=array();
    $subStruct=array();
    $currentTag='';
    $currentLevel=0;
    reset($officeBody);
    while(list($k,$v)=each($officeBody))	{
	if ($currentTag)	{
	    if (!strcmp($v['tag'],$currentTag))	{	// match...
		if ($v['type']=='close')	$currentLevel--;
		if ($v['type']=='open')		$currentLevel++;
	    }
	    if ($currentLevel<=0)	{	// should never be LESS than 0, but for safety...
		$currentTag='';
		$subStruct['type']='complete';
		$newStruct[]=$subStruct;
	    } else {
		$subStruct['subTags'][]=$v;
	    }
	} else {	// On root level:
	    if (inList('complete,cdata',$v['type']))	{
		$newStruct[]=$v;
	    }
	    if ($v['type']=='open')	{
		$currentLevel=1;	
		$currentTag = $v['tag'];
		$subStruct=$v;
		$subStruct['subTags']=array();
	    }
	}
    }
    return $newStruct;
}

function show_print_r($var) {
  echo "<pre>";
  print_r($var);
  echo "</pre>";
}

function set_default_rights($parent,$tree,$module_admins=NULL) {
    global $conn;
    $mod_admins = '';
    if (is_array($module_admins)) {
        $module_name = str_replace('root_modules_', '', $parent);
        $module_name = substr($module_name, 0, -1);
        foreach ($module_admins as $module_admin) {
	    // check existance of module admin group
            $module_admin = $conn->QMagic($module_admin);
            $sql = "SELECT id FROM mgw_groups WHERE name=$module_admin";
            if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
            if ($res->RecordCount() == 0) {
                // create group if necessary
                $module_admin_id = (int)mgw_genID('mgw__seq_groups');
                $sql = "INSERT INTO mgw_groups (id, name, description, lu_user, lu_date) VALUES ($module_admin_id, $module_admin, ".$conn->QMagic("$module_name admin").", 1, ".$conn->DBTimeStamp(time()).")";
                if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
                $mod_admins .= "$module_admin_id,";
            } else {
	        // get group id
                $row = $res->FetchRow();
                $mod_admins .= $row["id"].",";
            }
        }
    }
    foreach ($tree as $item=>$temp_val) {
	$sql = "SELECT id FROM mgw_rights2 WHERE id_string=".$conn->QMagic($parent.$item);
	if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
	$row = $res->FetchRow();

	if (!isset($row["id"])) {
	    $default_value = is_array($temp_val) || $temp_val == 0 ? 0 : 1;
	    $sql = "INSERT INTO mgw_rights2 (id, id_string, allow_users, deny_users, allow_groups, deny_groups, cuser, cdate, default_value) VALUES (".(int)mgw_genID('mgw__seq_rights2').", ".$conn->QMagic($parent.$item).", ',,', ',,', ',50000,50001,$mod_admins', ',,', 1, ".time().", $default_value);";
	    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
	}
	if (is_array($temp_val) and count($temp_val)>0) set_default_rights($parent.$item."_",$temp_val,$module_admins);
    }
}

function set_default_rights_admin($parent,$tree) {
    global $conn;
    foreach ($tree as $item=>$temp_val) {
	$sql = "SELECT id FROM mgw_rights2 WHERE id_string=".$conn->QMagic($parent.$item);
	if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
	$row = $res->FetchRow();

	if (!isset($row["id"])) {
	    $sql = "INSERT INTO mgw_rights2 (id, id_string, allow_users, deny_users, allow_groups, deny_groups, cuser, cdate, default_value) VALUES (".(int)mgw_genID('mgw__seq_rights2').", ".$conn->QMagic($parent.$item).", ',1,', ',,', ',,', ',,', 1, ".time().", 0);";
	    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
	}
	if (is_array($temp_val) and count($temp_val)>0) set_default_rights_admin($parent.$item."_",$temp_val);
    }
}

function browser_detect() {
  $agent = "@".strtolower($_SERVER["HTTP_USER_AGENT"]);
  if (strpos($agent,"opera")) return "opera";
  if (strpos($agent,"konqueror")) return "konqueror";
  if (strpos($agent,"msie")) return "msie";
  if (strpos($agent,"mozilla/5")) return "mozilla";
  if (strpos($agent,"netscape6")) return "netscape6";
  if (strpos($agent,"mozilla")) return "netscape";
  if (strpos($agent,"lynx")) return "lynx";
  if (strpos($agent,"w3m")) return "w3m";
  return "";
}

function stripslashes_array($val) {
    if (is_array($val)) {
	$tmp = array();
	if (count($val)>0) {
	    foreach ($val as $value) {
		$tmp[] = stripslashes($value);
	    }
	}
    }
    else {
	$tmp = stripslashes($val);
    }
    return $tmp;
}

function get_remote_addr() {
  $ip="";
  if (isset($_SERVER["HTTP_CLIENT_IP"])) $ip = $_SERVER["HTTP_CLIENT_IP"];
    elseif (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
    elseif (isset($_SERVER["REMOTE_ADDR"])) $ip = $_SERVER["REMOTE_ADDR"];
    else $ip = "UNKNOWN";

  return $ip;
}

//============================================
// Functions replacements for compatibility
//============================================

// For PHP version < 4.2.0 missing the array_fill function
if (!function_exists('array_fill')) {

    function array_fill($iStart, $iLen, $vValue) {
       $aResult = array();
       for ($iCount = $iStart; $iCount < $iLen + $iStart; $iCount++) {
           $aResult[$iCount] = $vValue;
       }
       return $aResult;
    }
}

/* ============================================
   This function replaces Lang::getLanguageString 
   with L_.

   I started with just _ but that is part of the
   gnu gettext modules and clashed.

   Maybe we should investigate using gnu gettext?

   David Lloyd
   ============================================ */

function L_($v) {
	return Lang::getLanguageString($v);
}

?>
