1<?php
2/* $Id: userfunc.inc.php,v 1.96 2004/12/13 14:19:50 k-fish Exp $ */
3/* User-Functions for Moregroupware */
4
5if (!defined('ROOTPATH')) die("This is a library.");
6
7// adding file revision into global array
8if(function_exists("revisionInit")) revisionInit("\$Revision: 1.96 $", __FILE__);
9
10// ===================
11// define module types
12// ===================
13define('MODULE_TYPE_CORE', 1);
14define('MODULE_TYPE_BASE', 2);
15define('MODULE_TYPE_NORMAL', 3);
16
17// helper for recursive deletion
18function recDel($path){
19    $dir = opendir($path);
20    while(($file = readdir($dir)) !== false){
21	if($file != '.' && $file != '..'){
22	    if(is_dir("$path/$file")){
23		recDel("$path/$file");
24		@rmdir("$path/$file");
25	    }
26	    else
27		@unlink("$path/$file");
28	}
29    }
30} // end recDel()
31
32function mgw_genID($seq_string,$limit=0) {
33  global $conn;
34
35  if ($limit > 0) {
36
37    $id = $conn->genID($seq_string, $limit);
38    if ($id < $limit) {
39	  $id = $id + $limit;
40	}
41	return $id;
42  } else {
43    return $conn->genID($seq_string);
44  }
45}
46
47// ====================================================
48// See if is module installed
49// ====================================================
50function isModuleInstalled($module) {
51    global $conn;
52
53    $sql = "SELECT modulename FROM mgw_modules WHERE modulename=".$conn->QMagic($module);
54    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
55    $row = $res->FetchRow();
56    if($row["modulename"]==$module) return true;
57    return false;
58}
59
60// ====================================================
61// See if is module active
62// ====================================================
63function isModuleActive($module) {
64    global $conn;
65
66    $sql = "SELECT active FROM mgw_modules WHERE modulename=".$conn->QMagic($module);
67    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
68    $row = $res->FetchRow();
69    if($row["active"]==1) return true;
70    return false;
71}
72
73// =================================================
74// get installed modules, active and inactive
75// =================================================
76function getInstalledModules() {
77    global $conn;
78
79    /* clean $MGW->modules to fix sort problems */
80    $ret = array();
81
82    /* include non-active modules because $MGW->modules[modulename]["active"]
83     * will be availible to programmers
84     */
85    $sql = "SELECT * FROM mgw_modules ORDER BY modulename!='general',modulename!='overview',modulename";
86    if(!$res = $conn->Execute($sql)) exit(showSQLerror2($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
87    while ($row = $res->FetchRow()) {
88        /* the name of a module (i.e. admin) wil be the array key because we don't
89         * install a certain module more than once and this makes checking if a module
90         * is installed much faster. maybe a function moduleIsInstalled(modulename)
91         * would be handy (i.e. return (isset($MGW->modules[modulename]))
92         */
93
94	$data["active"] = $row["active"];
95	$data["lu_user"] = $row["lu_user"];
96	$data["lu_date"] = $row["lu_date"];
97
98	$data["modulename"] = $row["modulename"];
99	$data["folder"] = $row["modulename"];
100	$data["name"] = $row["modulename"];
101	$data["secure"] = isset($row["secure"])?$row["secure"]:0;
102	$data["version"] = isset($row["version"])?$row["version"]:"0-68";
103	$data["version_mtime"] = isset($row["version_mtime"])?$row["version_mtime"]:"";
104	$data["base"] = isset($row["base"])?$row["base"]:"";
105	$data["date"] = isset($row["date"])?$row["date"]:"";
106	$data["author"] = isset($row["author"])?$row["author"]:"";
107	$data["email"] = isset($row["email"])?$row["email"]:"";
108	$data["description"] = $row["description"];
109	$data["compatibility"] = isset($row["compatibility"])?$row["compatibility"]:"";
110	$data["dependancies"] = isset($row["dependancies"])?$row["dependancies"]:"";
111	$data["module_type"] = isset($row["module_type"])?$row["module_type"]:"";
112
113	$ret[$row["modulename"]] = $data;
114    }
115
116    return $ret;
117}
118
119// ====================================================
120// See if user is still valid (auth against session)
121// ====================================================
122//
123function checkLogin(){
124    global $appconf;
125
126    if (!isset($_SESSION["MGW"])){
127        redirect(ROOTURL. "index.php?".SID);
128	exit();
129    }
130
131    if(!isset($_SESSION["MGW"]->username)) {
132	redirect(ROOTURL. "index.php?".SID);
133	exit();
134    }
135
136    if($_SESSION["checkip"] && ($_SESSION["remoteip"] != get_remote_addr() || $_SESSION["http_user_agent"] != $_SERVER["HTTP_USER_AGENT"])){
137	redirect(ROOTURL. "index.php?".SID);
138	exit();
139    }
140
141    return true;
142}
143
144function queryRights2_bool($id_string) {
145  global $conn;
146
147  $sql = "SELECT id_string,default_value,allow_users,deny_users,allow_groups,deny_groups FROM mgw_rights2 WHERE id_string=".$conn->quote($id_string);
148  if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
149  $row = $res->FetchRow();
150
151  if (!isset($row["default_value"])) return false;
152  if (!isset($_SESSION["MGW"]->userid)) return (bool)$row["default_value"];
153
154  if ($row["default_value"]==0) {
155    if (strpos("@".$row["allow_users"],",".$_SESSION["MGW"]->userid.",")>0) return true;
156    foreach ($_SESSION["MGW"]->groups as $group) {
157      if (strpos("@".$row["allow_groups"],",".$group.",")>0) return true;
158	}
159	return false;
160  } else {
161	if (strpos("@".$row["deny_users"],",".$_SESSION["MGW"]->userid.",")>0) return false;
162    foreach ($_SESSION["MGW"]->groups as $group) {
163      if (strpos("@".$row["deny_groups"],",".$group.",")>0) return false;
164	}
165	return true;
166  }
167
168  return $result;
169}
170
171function queryRights2($id_string) {
172  global $conn,$smarty,$appconf;
173
174  if (!queryRights2_bool($id_string)) {
175	$smarty->assign("errorheader",Lang::getLanguageString("permerror"));
176	$smarty->assign("permerror",Lang::getLanguageString("permerrormsg"));
177	$smarty->display($appconf["gentemplates"] ."/perm_errors.tpl");
178	die();
179  }
180}
181
182function query_access_module($module) {
183  if ($module == "help") return true;
184  if ($module == "general") return false;
185  if ($_SESSION["MGW"]->username=="admin") return true;
186  return queryRights2_bool("root_modules_".$module."_accessmodule");
187}
188
189function get_user_groups() {
190  global $conn;
191
192  $groups = array();
193  if (isset($_SESSION["MGW"]->userid) && $_SESSION["MGW"]->userid and !count($_SESSION["MGW"]->groups)>0) {
194    $sql = "SELECT * FROM mgw_groups_members WHERE userid=".$_SESSION["MGW"]->userid;
195    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
196    while($row = $res->FetchRow()) {
197      $groups[] = $row["groupid"];
198    }
199  }
200  return $groups;
201}
202
203function get_user_groups_names() {
204  global $conn;
205
206  $groups = array();
207  if (isset($_SESSION["MGW"]->userid) && $_SESSION["MGW"]->userid and !count($_SESSION["MGW"]->groups_names)>0) {
208    $sql = "SELECT * FROM mgw_groups_members,mgw_groups WHERE mgw_groups_members.userid=".$_SESSION["MGW"]->userid." and mgw_groups.id=mgw_groups_members.groupid";
209    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
210    while($row = $res->FetchRow()) {
211      $groups[] = "@".strtolower($row["name"]);
212    }
213  }
214  return $groups;
215}
216
217
218// ====================================================
219// get actual Settings
220// ====================================================
221//
222function getUserSettings(){
223    global $conn;
224
225    // general settings (modulename *)
226    // this ensure that we also load the module independent settings !!
227
228    $_SESSION["MGW"]->settings = array();
229
230    // grab other module names from database
231    $sql = "SELECT * FROM mgw_modules";
232    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
233
234    while($row = $res->FetchRow()) {
235        $modulename[] = $row["modulename"];
236    }
237
238    if (!in_array("general",$modulename)) $modulename[] = "general";
239
240    for($set_i=0;$set_i<count($modulename);$set_i++) {
241	if (file_exists(ROOTPATH."/modules/".$modulename[$set_i]."/inc/settings.inc.php")) {
242	    include ROOTPATH."/modules/".$modulename[$set_i]."/inc/settings.inc.php";
243	}
244
245        // little bit tricky:
246        // shows all tags for actual module for "default" and "user"
247        // the result is ordered by userid, this means that if a configtag
248        // like "iconmode" is set to "0" in default(user) and "1" to actual
249        // user, then "1" is taken (it overwrites the previous "0" in the array).
250        // If the user has no mapping for iconmode then the default "0" is used.
251        $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";
252
253        // echo $sql. "<p>";
254        if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
255
256        while($row = $res->FetchRow()) {
257            // if there are multiple dimensions for actual setting, save them in array instead
258            // of a normal index in an array
259            if($row["multipledimensions"]==1) {
260                // when multiple dimension is on, delete defaults if at least one user dimension is there
261                if($row["userid"]!=0 && $row["serialnr"]==1) $_SESSION["MGW"]->settings[$row["configtagname"]] = "";
262
263                if($row["valuetype"]=="int") $_SESSION["MGW"]->settings[$row["configtagname"]][] = $row["value_int"];
264                if($row["valuetype"]=="str") $_SESSION["MGW"]->settings[$row["configtagname"]][] = $row["value_str"];
265                if($row["valuetype"]=="txt") $_SESSION["MGW"]->settings[$row["configtagname"]][] = $row["value_txt"];
266            } else {
267                if($row["valuetype"]=="int") $_SESSION["MGW"]->settings[$row["configtagname"]] = $row["value_int"];
268                if($row["valuetype"]=="str") $_SESSION["MGW"]->settings[$row["configtagname"]] = $row["value_str"];
269                if($row["valuetype"]=="txt") $_SESSION["MGW"]->settings[$row["configtagname"]] = $row["value_txt"];
270            }
271        }
272
273	//load default value if not set:
274	if (isset($settings[$modulename[$set_i]]) && is_array($settings[$modulename[$set_i]])) foreach ($settings[$modulename[$set_i]] as $my_module_settings) {
275            if (is_array($my_module_settings)) foreach ($my_module_settings as $key=>$key2) {
276		if (!isset($_SESSION["MGW"]->settings[$key]) and isset($key2["default"])) {
277		    $_SESSION["MGW"]->settings[$key] = $key2["default"];
278		}
279            }
280        }
281    }// end for
282
283    /* set date formats */
284    $_SESSION["MGW"]->settings["datefmt"] = getDateFormate($_SESSION["MGW"]->settings["set_datefmt"],$_SESSION["MGW"]->settings["set_dmysep"]);
285    $_SESSION["MGW"]->settings["timefmt"] = getDateFormate($_SESSION["MGW"]->settings["set_timefmt"],$_SESSION["MGW"]->settings["set_hourminsep"]);
286}
287
288function getDateFormate($fmt, $sep) {
289	$ret = "";
290    if ($fmt=="24h" or $fmt=="12h") {
291        /* time */
292        if ($fmt=="12h") {
293            $ret = "h".$sep."ia";
294        } else {
295            $ret = "H".$sep."i";
296        }
297    } else {
298        /* date */
299        for ($i=0;$i<strlen($fmt);$i++) {
300            $ret .= $fmt[$i];
301	    if ($i==0 || ($i!=0 && ($i != strlen($fmt)-1) && ($fmt[$i] != $fmt[$i-1]))) $ret .= $sep;
302        }
303    }
304    return $ret;
305}
306
307// ====================================================
308// Connect to Database (see config.inc.php) ADOdb
309// ====================================================
310//
311function connect_database(){
312    global $appconf;
313    include ROOTPATH. '/include/adodb/adodb.inc.php'; // include adodb class
314    $conn = ADONewConnection($appconf["dbvendor"]);    // create a connection
315    $conn->PConnect($appconf["dbhost"], $appconf["dbuser"], $appconf["dbpassword"], $appconf["dbname"]);
316
317    return $conn;
318}
319
320// ====================================================
321// Show SQL Errors (ADOdb)
322// usage: showSQLerror(sql, ADODB error message, __LINE__, __FILE__)
323// ====================================================
324function showSQLerror($sql, $error = '', $where_line = '', $where_file = '') {
325    global $appconf, $gwversion, $Revisions_array, $conn;
326    // get the install files version (this is sometimes different
327    // than the installed version (if people just copy the file over
328    // a current installation)
329
330    echo "<html>\n";
331    echo "<head>\n";
332    echo "<style type=\"text/css\">\n";
333    echo "body {background-color:#555d66; color:#ffffff; font-family:Verdana,Helvetica,sans-serif;}\n";
334    echo "a{color:#ffff33;}\n";
335    echo "a:active{color:#ffff33;}\n";
336    echo "a:visited{color:#ffff33;}\n";
337    echo "hr {height:0px; border-width:1px; border-color:#dddddd; border-style:none none solid none;}\n";
338    echo "</style>\n</head>";
339    echo "<body>\n";
340    echo "<img src=\"". ROOTURL. "modules/general/templates/default/media/mgwlogo.gif\" align=\"right\">\n";
341    echo "<br /><h3>Problem in Moregroupware found!</h3>\n";
342    echo showSystemInfo($where_line, $where_file);
343    echo "<strong>Error (SQL)</strong>:<br />". $sql . "<br />\n";
344    echo "<br /><strong>Error (MSG)</strong>:<br />". $error . "<br /><br />\n";
345    echo "<strong>Dump</strong>:<br />POST: <pre>"; print_r($_POST); echo "</pre><br />GET: <pre>"; print_r($_GET);
346    echo "</pre><br /><br /><hr />";
347    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";
348    echo "</body>\n";
349    echo "</html>\n";
350}
351
352function showSystemInfo($where_line = '', $where_file = ''){
353    global $appconf, $conn, $Revisions_array;
354    if(defined('INCLUDEPATH'))
355	include(INCLUDEPATH . "version.inc.php");
356
357    $str = '';
358    $str .= "<table cellspacing=\"4\">\n";
359    $str .= "<tr><th align=\"right\">Version (config.inc.php):</th><td>". $appconf["mgw_version"]. "</td></tr>\n";
360    $str .= "<tr><th align=\"right\">Version (version.inc.php):</th><td>$gwversion</td></tr>\n";
361    $str .= "<tr><th align=\"right\">PHP version:</th><td>".phpversion()."</td></tr>\n";
362    $str .= "<tr><th align=\"right\">PHP OS:</th><td>".PHP_OS."</td></tr>\n";
363    $str .= "<tr><th align=\"right\">register_globals:</th><td>".(int) ini_get("register_globals")."</td></tr>\n";
364    $str .= "<tr><th align=\"right\">magic_quotes_gpc:</th><td>".(int) ini_get("magic_quotes_gpc")."</td></tr>\n";
365    $str .= "<tr><th align=\"right\">safe_mode:</th><td>".(int) ini_get("safe_mode")."</td></tr>\n";
366    $str .= "<tr><th align=\"right\">sql.safe_mode:</th><td>".(int) ini_get("sql.safe_mode")."</td></tr>\n";
367    $str .= "<tr><th align=\"right\">Server software:</th><td>".$_SERVER["SERVER_SOFTWARE"]."</td></tr>\n";
368    $str .= "<tr><th align=\"right\">User-Agent:</th><td>".$_SERVER["HTTP_USER_AGENT"]."</td></tr>\n";
369
370    $str .= "<tr><th align=\"right\">session.use_trans_sid:</th><td>".(int) ini_get("session.use_trans_sid")."</td></tr>\n";
371    $str .= "<tr><th align=\"right\">session.auto_start:</th><td>".(int) ini_get("session.auto_start")."</td></tr>\n";
372
373    $str .= "<tr><th align=\"right\">file_uploads:</th><td>".(int) ini_get("file_uploads")."</td></tr>\n";
374    $str .= "<tr><th align=\"right\">upload_max_filesize:</th><td>".ini_get("upload_max_filesize")."</td></tr>\n";
375    $str .= "<tr><th align=\"right\">upload_tmp_dir:</th><td>".ini_get("upload_tmp_dir")."</td></tr>\n";
376
377    $str .= "<tr><th align=\"right\">memory_limit:</th><td>".ini_get("memory_limit")."</td></tr>\n";
378    $str .= "<tr><th align=\"right\">post_max_size:</th><td>".ini_get("post_max_size")."</td></tr>\n";
379    $str .= "<tr><th align=\"right\">max_execution_time:</th><td>".(int) ini_get("max_execution_time")."</td></tr>\n";
380    $str .= "<tr><th align=\"right\">max_input_time:</th><td>".(int) ini_get("max_input_time")."</td></tr>\n";
381    $str .= "<tr><th align=\"right\">magic_quotes_runtime:</th><td>".(int) ini_get("magic_quotes_runtime")."</td></tr>\n";
382
383    $dbinfo = $conn->ServerInfo();
384    $str .= "<tr><th align=\"right\">Database:</th><td>".$appconf['dbvendor'].' / '.$dbinfo['description']." (".$dbinfo['version'].")</td></tr>\n";
385    $str .= "<tr><th align=\"right\">Program:</th><td>".$_SERVER["PHP_SELF"]."</td></tr>\n";
386    if($where_file!='') {
387	$str .= "<tr><th align=\"right\">File:</th><td>$where_file</td></tr>\n";
388	$rev_index = strtr(substr($where_file,-1*(strlen($where_file)-strrpos($where_file,"/")-1)),".","_");
389	if(isset($Revisions_array[$rev_index])) $str .= "<tr><th align=\"right\">File revision:</th><td>".$Revisions_array[$rev_index]."</td></tr>\n";
390    }
391    if($where_line!='')
392	$str .= "<tr><th align=\"right\">Line:</th><td>$where_line</td></tr>\n";
393    $str .= "</table>\n<br />\n";
394
395    return $str;
396}
397
398// ====================================================
399// Redirect Wrapper
400// ====================================================
401//
402function redirect($uri) {
403
404    if(PHP_OS=="WINNT" || PHP_OS=="WIN32") {
405	// we have problems with REFRESH with opera, so we use
406	// location for opera and refresh for IE on WIN32
407	if(strstr($_SERVER["HTTP_USER_AGENT"], "Opera")) {
408	    header("Location: $uri");
409	    exit();
410	}
411	else {
412	    header("Refresh: 0; url=\"$uri\"");
413	    exit();
414	}
415    }
416    else {
417	header("Location: $uri");
418	exit();
419    }
420}
421
422// ====================================================
423// Create Submenu
424// ====================================================
425//
426function createSubmenu($menuarray) {
427    global $smarty, $myEnv;
428
429    for($i=0;$i<count($menuarray);$i++) {
430	  if (isset($menuarray[$i]["link"])) { $menuarray[$i]["link"] = addslashes($menuarray[$i]["link"]); }
431    $smarty->append("sdata", $menuarray[$i]);
432    }
433    $smarty->assign("navimodule", $myEnv["module"]);
434}
435
436
437function get_user_info($user){
438    global $conn, $appconf;
439
440    // now we just look for the username and not for the password anymore.
441    if(is_int($user))
442	$sql = "SELECT * FROM mgw_users WHERE id=".(int)$user;
443    else
444	$sql = "SELECT * FROM mgw_users WHERE username=".$conn->QMagic($user);
445
446    if(($row = $conn->GetRow($sql))===false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
447
448    $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"]);
449    if(($cs = $conn->GetOne($sql))===false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
450    $row["charset"] = $cs;
451
452    return $row;
453}
454
455
456function create_user_account_on_login($user){
457    global $conn;
458
459    //these vaules should not be harcoded, they should come from configuration.
460    $id = mgw_genID('mgw__seq_users', 5);
461    $pw = $conn->QMagic("auto_created_invalid_pwd");
462
463    $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.")";
464    if(!$conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
465
466    $sql="INSERT INTO mgw_groups_members (groupid, userid, lu_user, lu_date) VALUES (50001, ".$id.", 1, NOW())";
467    if(!$conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
468}
469
470// =================================================
471// alphabet_table user in contact and news module
472// =================================================
473function alphabet_table($args="action=alphab",$linkurl="index.php") {
474    switch($_SESSION["MGW"]->spkz) {
475    case "cs":
476    $at = array ("A","�","B","C","�","D","�","E","�","F","G","H","I","�","J","K","L","M","N","�","O","�","P",
477             "Q","R","�","S","�","T","�","U","�","V","W","X","Y","�","Z","�");
478    break;
479    case "nb":
480    $at = array ("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R",
481             "S","T","U","V","W","X","Y","Z","�","�","�");
482    break;
483    case "de":
484    $at = array ("A","�","B","C","D","E","F","G","H","I","J","K","L","M","N","O","�","P","Q","R",
485             "S","T","U","�","V","W","X","Y","Z");
486    break;
487    case "ru":
488     $at = array ("�","�","�","�","�","�","�","�","�","�","�","�","�","�","�","�","�","�","�","�",
489		  "�","�","�","�","�","�","�","�","�","�","�");
490    break;
491    default:
492    $at = array ("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R",
493             "S","T","U","V","W","X","Y","Z");
494    break;
495    }
496
497    $out = "<table cellpadding=\"3\" cellspacing=\"2\">\n";
498    $out .= "<tr>\n";
499    $out .= "<td class=\"stand\"><a href=\"$linkurl?$args&amp;".SID."\">". Lang::getLanguageString("all") . "</a>\n";
500
501    for($i=0;$i<count($at);$i++) {
502        $out .= "<td class=\"stand\"><a href=\"$linkurl?$args&amp;list=".urlencode($at[$i])."&amp;".SID."\">" . $at[$i] . "</a></td>\n";
503        if(count($at)>26 && $i==(ceil(count($at)/2))-1) $out .="</tr><tr><td>&nbsp;</td>";
504    }
505    if($i%2==1) $out.="<td>&nbsp;</td>";
506
507    $out .= "</tr>\n";
508    $out .= "</table>\n";
509    return $out;
510}
511
512// ======================================================================
513// function to add revision of referer to global Revisions_array array
514// ======================================================================
515function revisionInit($revision, $file) {
516    global $Revisions_array;
517    $rev_index = strtr(substr($file,-1*(strlen($file)-strrpos($file,"/")-1)),".","_");
518    $rev_value = substr(addslashes($revision),11,-2);
519    $Revisions_array[$rev_index] = $rev_value;
520}
521
522// ======================================================================
523// if user wants icons, assign icons if not -> not
524// ======================================================================
525function getIconStrings(){
526    global $smarty,$appconf;
527    $settings=$_SESSION["MGW"]->settings;
528
529    if($settings["iconmode"]==1) {
530	$icons["new"] = "<img src=\"". $appconf["imgpathgeneral"]. "/new_". $settings["iconid"]. ".gif\" border=\"0\" alt=\"".Lang::getLanguageString("new")."\" title=\"".Lang::getLanguageString("new")."\">";
531	$icons["details"] = "<img src=\"". $appconf["imgpathgeneral"]. "/details_". $settings["iconid"]. ".gif\" border=\"0\" alt=\"".Lang::getLanguageString("details")."\" title=\"".Lang::getLanguageString("details")."\">";
532	$icons["edit"] = "<img src=\"". $appconf["imgpathgeneral"]. "/edit_". $settings["iconid"]. ".gif\" border=\"0\" alt=\"".Lang::getLanguageString("edit")."\" title=\"".Lang::getLanguageString("edit")."\">";
533	$icons["delete"] = "<img src=\"". $appconf["imgpathgeneral"]. "/delete_". $settings["iconid"]. ".gif\" border=\"0\" alt=\"".Lang::getLanguageString("delete")."\" title=\"".Lang::getLanguageString("delete")."\">";
534
535	$icons["private"] = "<img src=\"". $appconf["imgpathgeneral"]. "/private_". $settings["iconid"]. ".gif\" border=\"0\">";
536
537	$icons["prev"] = "<img src=\"". $appconf["imgpathgeneral"]. "/left_". $settings["iconid"]. ".gif\" border=\"0\">";
538	$icons["next"] = "<img src=\"". $appconf["imgpathgeneral"]. "/right_". $settings["iconid"]. ".gif\" border=\"0\">";
539
540	$icons["space"] = "&nbsp;&nbsp;";
541
542	$smarty->assign("iconid", $settings["iconid"]);
543	$smarty->assign("iconmode", true);
544    } else {
545	$icons["new"] = Lang::getLanguageString("new");
546	$icons["details"] = Lang::getLanguageString("details");
547	$icons["edit"] = Lang::getLanguageString("edit");
548	$icons["delete"] = Lang::getLanguageString("delete");
549
550	$icons["private"] = "P"; //should be replaced, but i don't know with what :)
551
552	$icons["prev"] = "&lt;&lt;--|";
553	$icons["next"] = "|--&gt;&gt;";
554
555	$icons["space"] = "&nbsp;&nbsp;";
556
557	$smarty->assign("iconmode", false);
558    }
559    return $icons;
560}
561
562// ====================================================
563// Creates a country select box with favourite feature
564// ====================================================
565function createCountrySB ($sbname, $selected=""){
566    global $conn;
567
568    $favouritesel = false;
569
570    // first get the favourite and the first line "please chose...."
571    //
572    $out = "<select name=\"$sbname\" size=\"1\">\n";
573    $out .= "<option value=\"\">". Lang::getLanguageString("chosecountrytext") ."</option>\n";
574    for($i=0;$i < count($_SESSION["MGW"]->settings["favourite_countries"]);$i++) {
575    $sql = "SELECT name FROM mgw_countries WHERE code=".$conn->QMagic($_SESSION["MGW"]->settings["favourite_countries"][$i]);
576    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
577    $row = $res->FetchRow();
578    if($_SESSION["MGW"]->settings["favourite_countries"][$i]==$selected) {
579        $seltext = " selected";
580        $favouritesel = true;
581    } else $seltext = "";
582    $out .= "<option value=\"". $_SESSION["MGW"]->settings["favourite_countries"][$i] ."\"$seltext>". $row["name"]. "</option>\n";
583    }
584    $out .= "<option value=\"\">-----------------------------</option>\n";
585
586    // now get the normal country list
587    $sql = "SELECT * FROM mgw_countries";
588    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
589    while($row = $res->FetchRow()) {
590	if($row["code"]==$selected and !$favouritesel) $seltext = " selected"; else $seltext = "";
591	$out .= "<option value=\"". $row["code"]. "\"$seltext>". $row["name"]. "</option>\n";
592    }
593    $out .= "</select>\n";
594
595    return $out;
596}
597
598/**
599 * This is a email validating function seperate to the rest
600 * of the class. It simply validates whether an email is of
601 * the common internet form: <user>@<domain>. This can be
602 * sufficient for most people. Optional stricter mode can
603 * be utilised which restricts mailbox characters allowed
604 * to alphanumeric, full stop, hyphen and underscore.
605 *
606 * @param  string  $data   Address to check
607 * @param  boolean $strict Optional stricter mode
608 * @return mixed           False if it fails, an indexed array
609 *                         username/domain if it matches
610 */
611function isValidInetAddress($data, $strict = false){
612    // if we see localhost in the address, don't check further.
613    if(stristr($data,'localhost'))
614	return explode('@', $data);
615
616    $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';
617    if (preg_match($regex, trim($data), $matches)) {
618	return array($matches[1], $matches[2]);
619    } else {
620	return false;
621    }
622}
623
624
625function inList($in_list,$item)	{
626    return strstr(",".$in_list.",", ",".$item.",");
627}
628
629function get_definition_data_from_xml($thefile) {
630    $data = implode("",file($thefile));
631    $data = substr($data,strpos($data,"<mgw>"));
632    $parser = xml_parser_create();
633    xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
634    xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
635    xml_parse_into_struct($parser,$data,$values,$tags);
636    xml_parser_free($parser);
637
638    $data = array();
639    foreach ($values as $value) {
640	if (isset($value["tag"]) and isset($value["value"])) $data[$value["tag"]][] = $value["value"];
641    }
642
643    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.");
644    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.");
645    if (!isset($data["module_type"][0])) $data["module_type"][0] = 3;
646
647    return $data;
648}
649
650function get_definition_countries_from_xml($thefile) {
651    $data = implode("",file($thefile));
652    $data = substr($data,strpos($data,"<countries>"));
653    $parser = xml_parser_create();
654    xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
655    xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
656    xml_parse_into_struct($parser,$data,$values,$tags);
657    xml_parser_free($parser);
658
659    $data = array();
660    foreach ($values as $value) {
661	if (isset($value["attributes"]) and is_array($value["attributes"]) and count($value["attributes"])>0) $data[] = $value["attributes"];
662    }
663
664    return $data;
665}
666
667function execute_xml_schema($thefile,$module,$dbvendor) {
668    global $conn, $buffer;
669
670    $schema = new adoSchema($conn);
671    $schema->setPrefix( "mgw" );
672
673    $sqls = $schema->ParseSchema($thefile);
674
675    // what is this part for? why those replacements?
676    /*
677    foreach ($sqls as $key=>$sql) {
678 	if ($dbvendor=="mysql") {
679 	    $sqls[$key] = str_replace("LONGTEXT","TEXT",$sqls[$key]);
680 	    $sqls[$key] = str_replace("DATETIME","TIMESTAMP",$sqls[$key]);
681 	}
682    }
683    */
684
685    if (count($sqls)>0){
686	$buffer .= "Executing schema ...\n";
687	foreach ($sqls as $sql) {
688	    if (is_array($sql) and count($sql)>0) {
689		foreach ($sql as $sqlitem) {
690		    if(!$res = $conn->Execute($sqlitem)) $buffer .= "\nSQL FAILED: ".$sqlitem."\n".$conn->ErrorMsg()."\n\n";
691		}
692	    } elseif (!is_array($sql)) {
693		if(!$res = $conn->Execute($sql)) $buffer .= "\nSQL FAILED: ".$sql."\n".$conn->ErrorMsg()."\n\n";
694	    }
695	}
696    }
697    else
698	$buffer .= "\nNo XML-SQL-Schema found.\n\n";
699
700    $schema->Destroy();
701}
702
703function indentSubTagsRec($officeBody,$depth=1)	{
704    if ($depth<1)	return $officeBody;
705    $officeBody = indentSubTags($officeBody);
706
707    if ($depth>1)	{
708	reset($officeBody);
709	while(list($k,$v)=each($officeBody))	{
710	    if (is_array($officeBody[$k]['subTags']))	{
711		$officeBody[$k]['subTags'] = indentSubTagsRec($officeBody[$k]['subTags'],$depth-1);
712	    }
713	}
714    }
715    return $officeBody;
716}
717
718function indentSubTags($officeBody)	{
719    $newStruct=array();
720    $subStruct=array();
721    $currentTag='';
722    $currentLevel=0;
723    reset($officeBody);
724    while(list($k,$v)=each($officeBody))	{
725	if ($currentTag)	{
726	    if (!strcmp($v['tag'],$currentTag))	{	// match...
727		if ($v['type']=='close')	$currentLevel--;
728		if ($v['type']=='open')		$currentLevel++;
729	    }
730	    if ($currentLevel<=0)	{	// should never be LESS than 0, but for safety...
731		$currentTag='';
732		$subStruct['type']='complete';
733		$newStruct[]=$subStruct;
734	    } else {
735		$subStruct['subTags'][]=$v;
736	    }
737	} else {	// On root level:
738	    if (inList('complete,cdata',$v['type']))	{
739		$newStruct[]=$v;
740	    }
741	    if ($v['type']=='open')	{
742		$currentLevel=1;
743		$currentTag = $v['tag'];
744		$subStruct=$v;
745		$subStruct['subTags']=array();
746	    }
747	}
748    }
749    return $newStruct;
750}
751
752function show_print_r($var) {
753  echo "<pre>";
754  print_r($var);
755  echo "</pre>";
756}
757
758function set_default_rights($parent,$tree,$module_admins=NULL) {
759    global $conn;
760    $mod_admins = '';
761    if (is_array($module_admins)) {
762        $module_name = str_replace('root_modules_', '', $parent);
763        $module_name = substr($module_name, 0, -1);
764        foreach ($module_admins as $module_admin) {
765	    // check existance of module admin group
766            $module_admin = $conn->QMagic($module_admin);
767            $sql = "SELECT id FROM mgw_groups WHERE name=$module_admin";
768            if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
769            if ($res->RecordCount() == 0) {
770                // create group if necessary
771                $module_admin_id = (int)mgw_genID('mgw__seq_groups');
772                $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()).")";
773                if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
774                $mod_admins .= "$module_admin_id,";
775            } else {
776	        // get group id
777                $row = $res->FetchRow();
778                $mod_admins .= $row["id"].",";
779            }
780        }
781    }
782    foreach ($tree as $item=>$temp_val) {
783	$sql = "SELECT id FROM mgw_rights2 WHERE id_string=".$conn->QMagic($parent.$item);
784	if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
785	$row = $res->FetchRow();
786
787	if (!isset($row["id"])) {
788	    $default_value = is_array($temp_val) || $temp_val == 0 ? 0 : 1;
789	    $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);";
790	    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
791	}
792	if (is_array($temp_val) and count($temp_val)>0) set_default_rights($parent.$item."_",$temp_val,$module_admins);
793    }
794}
795
796function set_default_rights_admin($parent,$tree) {
797    global $conn;
798    foreach ($tree as $item=>$temp_val) {
799	$sql = "SELECT id FROM mgw_rights2 WHERE id_string=".$conn->QMagic($parent.$item);
800	if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
801	$row = $res->FetchRow();
802
803	if (!isset($row["id"])) {
804	    $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);";
805	    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
806	}
807	if (is_array($temp_val) and count($temp_val)>0) set_default_rights_admin($parent.$item."_",$temp_val);
808    }
809}
810
811function browser_detect() {
812  $agent = "@".strtolower($_SERVER["HTTP_USER_AGENT"]);
813  if (strpos($agent,"opera")) return "opera";
814  if (strpos($agent,"konqueror")) return "konqueror";
815  if (strpos($agent,"msie")) return "msie";
816  if (strpos($agent,"mozilla/5")) return "mozilla";
817  if (strpos($agent,"netscape6")) return "netscape6";
818  if (strpos($agent,"mozilla")) return "netscape";
819  if (strpos($agent,"lynx")) return "lynx";
820  if (strpos($agent,"w3m")) return "w3m";
821  return "";
822}
823
824function stripslashes_array($val) {
825    if (is_array($val)) {
826	$tmp = array();
827	if (count($val)>0) {
828	    foreach ($val as $value) {
829		$tmp[] = stripslashes($value);
830	    }
831	}
832    }
833    else {
834	$tmp = stripslashes($val);
835    }
836    return $tmp;
837}
838
839function get_remote_addr() {
840  $ip="";
841  if (isset($_SERVER["HTTP_CLIENT_IP"])) $ip = $_SERVER["HTTP_CLIENT_IP"];
842    elseif (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
843    elseif (isset($_SERVER["REMOTE_ADDR"])) $ip = $_SERVER["REMOTE_ADDR"];
844    else $ip = "UNKNOWN";
845
846  return $ip;
847}
848
849//============================================
850// Functions replacements for compatibility
851//============================================
852
853// For PHP version < 4.2.0 missing the array_fill function
854if (!function_exists('array_fill')) {
855
856    function array_fill($iStart, $iLen, $vValue) {
857       $aResult = array();
858       for ($iCount = $iStart; $iCount < $iLen + $iStart; $iCount++) {
859           $aResult[$iCount] = $vValue;
860       }
861       return $aResult;
862    }
863}
864
865/* ============================================
866   This function replaces Lang::getLanguageString
867   with L_.
868
869   I started with just _ but that is part of the
870   gnu gettext modules and clashed.
871
872   Maybe we should investigate using gnu gettext?
873
874   David Lloyd
875   ============================================ */
876
877function L_($v) {
878	return Lang::getLanguageString($v);
879}
880
881?>
882