<?php
	/**************************************************************************\
	* Simple Groupware 0.700                                                   *
	* http://www.simple-groupware.de                                           *
	* Copyright (C) 2002-2011 by Thomas Bley                                   *
	* ------------------------------------------------------------------------ *
	*  This program is free software; you can redistribute it and/or           *
	*  modify it under the terms of the GNU General Public License Version 2   *
	*  as published by the Free Software Foundation; only version 2            *
	*  of the License, no later version.                                       *
	*                                                                          *
	*  This program is distributed in the hope that it will be useful,         *
	*  but WITHOUT ANY WARRANTY; without even the implied warranty of          *
	*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
	*  GNU General Public License for more details.                            *
	*                                                                          *
	*  You should have received a copy of the GNU General Public License       *
	*  Version 2 along with this program; if not, write to the Free Software   *
	*  Foundation, Inc., 59 Temple Place - Suite 330, Boston,                  *
	*  MA  02111-1307, USA.                                                    *
	\**************************************************************************/

class trigger {

static function login() {
  db_update("simple_sys_users",array("status"=>"online"),array("username=@username@","coalesce(status,'')!='ooo'"),array("username"=>$_SESSION["username"]));
  return "";
}

static function logout() {
  db_update("simple_sys_users",array("status"=>"offline"),array("username=@username@","coalesce(status,'')!='ooo'"),array("username"=>$_SESSION["username"]));
  return "";
}

// syntax: trigger_new="exec:cmd"
// e.g. trigger_new="exec:echo @fieldname@ >/tmp/example.txt"
static function exec($id, $data, $params) {
  $cmd = implode(":",$params);
  if (preg_match_all("|@(.*?)@|i",$cmd,$matches,PREG_SET_ORDER)) {
	foreach ($matches as $match) {
	  if (count($match)==2) {
		$req_key = $match[1];
		if (isset($data[$req_key])) {
		  $cmd = str_replace("@".$req_key."@",escapeshellarg($data[$req_key]),$cmd);
  } } } }
  if ($cmd=="") return "";
  sys_add_notification(sprintf("{t}System command executed: %s{/t}",$cmd));
  return sys_exec($cmd);
}

static function createeditexpenses($id, $data) {
  self::_createedit_payroll("simple_expenses", $id, $data);
  return "";
}

static function createedittimesheets($id, $data) {
  if ($data["ending"]!=0 and $data["begin"]!=0) {
    $duration = $data["ending"] - $data["begin"] - ($data["pause"]*3600);
    db_update("simple_timesheets",array("duration"=>$duration),array("id=@id@"),array("id"=>$id));
  }
  self::_createedit_payroll("simple_timesheets", $id, $data);
  return "";
}

static function createedituser($id, $data) {
  if (!empty($data["birthday"])) $birthday = sys_date("m-d",$data["birthday"]); else $birthday = "";
  if (!empty($data["anniversary"])) $anniversary = sys_date("m-d",$data["anniversary"]); else $anniversary = "";
  db_update("simple_sys_users",array("birthday_str"=>$birthday,"anniversary_str"=>$anniversary),array("id=@id@"),array("id"=>$id));
  if ($_SESSION["username"]==$data["username"]) login::process_login($data["username"]);
  return "";
}

static function createuser($id, $data) {
  if (!is_dir(SIMPLE_STORE."/home/".$data["username"])) sys_mkdir(SIMPLE_STORE."/home/".$data["username"]);
  self::createedituser($id,$data);
  return "";
}

static function deleteuser($id, $data) {
  $count = db_select_value("simple_sys_users","count(*) as count","username=@username@",array("username"=>$data["username"]));
  $row_id = self::_get_folder_by_anchor("home_".$data["username"]);
  if (!empty($count) and !empty($row_id)) {
	folders::delete($row_id);
	db_update("simple_sys_groups",array("members"=>"replace(members,'|".sql_quote($data["username"])."|','|')"),array("members like @username@"),array("username"=>"%|".$data["username"]."|%"),array("quote"=>false));
	sys_add_notification(sprintf("{t}Folder structure moved to trash.{/t} (%s)",$data["username"]));
  }
  db_update("simple_sys_users",array("activated"=>"0"),array("id=@id@"),array("id"=>$id));
  return "";
}

static function deletegroup($id) {
  db_update("simple_sys_groups",array("activated"=>"0"),array("id=@id@"),array("id"=>$id));
  return "";
}

static function deletegroup_by_name($name) {
  db_update("simple_sys_groups",array("activated"=>"0"),array("groupname=@name@"),array("name"=>$name));
  return "";
}

static function createeditcms($id, $data) {
  db_update("simple_cms",array("lastmodified"=>"lastmodified+1"),array("data like @pagename@"),array("pagename"=>"%(:include ".$data["pagename"]."%"),array("quote"=>false,"no_defaults"=>1));

  $rows = db_select("simple_cms","pagename",array("data like @content@","staticcache='1'"),"","",array("content"=>"%(:include ".$data["pagename"]."%"));
  if (is_array($rows)) {
    $rows[] = array("pagename"=>$data["pagename"]);
    foreach ($rows as $row) {
      $dir = SIMPLE_CACHE."/cms/".urlencode(strtolower($row["pagename"]));
	  if (is_dir($dir)) {
	    if (DEBUG) echo "delete ".$dir;
	    dirs_delete_all($dir,0,false);
	  }
} } }

static function deletecms($id, $data) {
  db_update("simple_cms",array("activated"=>"0"),array("id=@id@"),array("id"=>$id));
  $dir = SIMPLE_CACHE."/cms/".urlencode($data["pagename"]);
  if (is_dir($dir)) dirs_delete_all($dir,0,true);
  return "";
}

static function createeditforum($id, $data) {
  if ($data["threadid"]=="0") {
	db_update("simple_forum",array("threadid"=>$id),array("id=@id@"),array("id"=>$id));
  }
}

static function deletecontact($id, $data) {
  return self::_sync_delete($id,$data,"contacts");
}

static function deletetask($id, $data) {
  return self::_sync_delete($id,$data,"tasks");
}

static function deleteappointment($id, $data) {
  return self::_sync_delete($id,$data,"calendar");
}

static function deletenote($id, $data) {
  return self::_sync_delete($id,$data,"notes");
}

static function createedittask($id, $data, $unused=array(), $export=true) {
  if ($data["ending"]!=0 and $data["begin"]!=0 and $id!="") {
    $duration = $data["ending"] - $data["begin"];
    db_update("simple_tasks",array("duration"=>$duration),array("id=@id@"),array("id"=>$id));
  }
  if ($export) return self::_sync_createedit($id,$data,"tasks"); else return "";
}

static function createeditcontact($id, $data, $unused=array(), $export=true) {
  if (!empty($data["birthday"])) {
    $birthday = sys_date("m-d",$data["birthday"]);
    db_update("simple_contacts",array("birthday_str"=>$birthday),array("id=@id@"),array("id"=>$id));
  } else $birthday = "";
  if ($export) {
    return self::_sync_createedit($id,$data,"contacts");
  } else return "";
}

static function createeditnote($id, $data) {
  return self::_sync_createedit($id,$data,"notes");
}

static function increase_pwdexpire($id) {
  $expire = db_select_value("simple_sys_users","pwdexpires","id=@id@",array("id"=>$id));
  if (!empty($expire) and $expire < NOW) {
    $expires = NOW + 7776000; // 90 days
	db_update("simple_sys_users",array("pwdexpires"=>$expires),array("id=@id@"),array("id"=>$id));
  }
  return "";
}

// e.g. addgroupmember(0, array("username"=>$username), array($group))
static function addgroupmember($id, $data, $params) {
  if (empty($params[0]) or empty($data["username"])) return "";
  $groupname = $params[0];
  $members = db_select_value("simple_sys_groups","members","groupname=@name@",array("name"=>$groupname));
  if (!empty($members)) $members = explode("|",trim($members,"|")); else $members = array();
  $members[] = $data["username"];
  $members = implode("|",array_unique($members));
  db_update("simple_sys_groups",array("members"=>"|".$members."|"),array("groupname=@name@"),array("name"=>$groupname));
  return "";
}

static function setgroupmembers($group, $members) {
  if ($members!="") $members = "|".trim($members,"|")."|";
  db_update("simple_sys_groups",array("members"=>$members),array("groupname=@group@"),array("group"=>$group));
}

static function creategroup($name) {
  $row_id = db_select_value("simple_sys_groups","id","groupname=@name@",array("name"=>$name));
  $folder = self::_get_folder_by_type("sys_groups");
  
  if (empty($row_id) and !empty($folder)) {
	$id = sql_genID("simple_sys_groups")*100+$_SESSION["serverid"];
    $data = array("id"=>$id, "groupname"=>$name, "activated"=>1, "folder"=>$folder);
    $error_sql = db_insert("simple_sys_groups",$data);
	if ($error_sql=="") {
	  db_update_treesize("simple_sys_groups",$folder);
	  db_search_update("simple_sys_groups",$id,array(),array("groupname"=>"text"));
	  sys_log_stat("new_records",1);
	} else return $error_sql;
  }
  return "";
}

static function editgroup($id, $data) {
  if ($data["members"]!="") $data["members"] = "|".trim($data["members"],"|")."|";
  if (sys_strbegins($data["groupname"],"project_")) {
    $project = substr($data["groupname"],8);
    db_update("simple_projects",array("participants"=>$data["members"]),array("projectname=@project@"),array("project"=>$project));
  }
  if (sys_strbegins($data["groupname"],"department_")) {
    $department = substr($data["groupname"],11);
    db_update("simple_departments",array("members"=>$data["members"]),array("departmentname=@department@"),array("department"=>$department));
  }
  return "";
}

static function createeditproject($id, $data) {
  if ($data["finishsched"]!=0 and $data["startsched"]!=0) {
	db_update("simple_projects",array("duration"=>$data["finishsched"]-$data["startsched"]),array("id=@id@"),array("id"=>$id));
  }
  self::creategroup("project_".$data["projectname"]);
  self::setgroupmembers("project_".$data["projectname"], $data["participants"]);
  return "";
}

static function createeditdepartment($id, $data) {
  self::creategroup("department_".$data["departmentname"]);
  self::setgroupmembers("department_".$data["departmentname"], $data["members"]);
  return "";
}

static function deleteproject($id, $data) {
  $count = db_select_value("simple_projects","count(*) as count","projectname=@projectname@",array("projectname"=>$data["projectname"]));
  $row_id = self::_get_folder_by_anchor("projects_".$data["projectname"]);
  if (!empty($count) and !empty($row_id)) {
	folders::delete($row_id);
	sys_add_notification(sprintf("{t}Folder structure moved to trash.{/t} (%s)",$data["projectname"]));
  }
  self::deletegroup_by_name("project_".$data["projectname"]);
  return "";
}

static function deletedepartment($id, $data) {
  $count = db_select_value("simple_departments","count(*) as count","departmentname=@departmentname@",array("departmentname"=>$data["departmentname"]));
  $row_id = self::_get_folder_by_anchor("departments_".$data["departmentname"]);
  if (!empty($count) and !empty($row_id)) {
	folders::delete($row_id);
	sys_add_notification(sprintf("{t}Folder structure moved to trash.{/t} (%s)",$data["departmentname"]));
  }
  self::deletegroup_by_name("department_".$data["departmentname"]);
  return "";
}

static function deletechat($id, $data) {
  $count = db_select_value("simple_chat","count(*) as count","roomname=@roomname@",array("roomname"=>$data["roomname"]));
  if ($count==1) db_delete("simple_sys_chat2",array("room=@room@"),array("room"=>$data["roomname"]));
  return "";
}

static function sendmail_pop3($id, $data) {
  return self::sendmail($id,$data,array(),true);
}

static function sendmail($id, $data, $unused=array(), $to_self=false) {
  if (isset($data["sendnow"]) and $data["sendnow"]==0) return "";
  $row = self::sendmail_getconn($_SESSION["username"],$data["efrom"]);
  if (USE_MAIL_FUNCTION or !empty($row["smtp"])) {
    if (!empty($row["smtp"])) sys_credentials($data["folder"], "smtp:".$row["smtp"]."/");
    if (!empty($row["email"])) $data["efrom"] = $row["email"];
    if (!empty($row["name"])) $data["name"] = $row["name"];
	$error = lib_smtp::insert("",$data,$data["folder"],$to_self,USE_MAIL_FUNCTION);
	if ($error=="" and sys_strbegins($data["subject"],SMTP_NOTIFICATION)) {
	  sys_add_notification(sprintf("{t}Notificaiton sent to: %s{/t}",$data["eto"]));
    }
  } else {
    $error = sprintf("{t}SMTP not configured for %s{/t}",$_SESSION["username"]);
  }
  return $error;
}

static function createemail($id, $data) {
  if (empty($data["message_html"]) and !empty($data["message"])) {
	$message_html = nl2br(modify::htmlquote(trim($data["message"])));
	db_update("simple_emails",array("message_html"=>$message_html),array("id=@id@"),array("id"=>$id));
  }
  if (empty($data["message"]) and !empty($data["message_html"])) {
	$message = modify::htmlmessage($data["message_html"]);
	db_update("simple_emails",array("message"=>$message),array("id=@id@"),array("id"=>$id));
  }
  return "";
}

static function calcactivity($id, $data) {
  if (empty($data["ending"]) or empty($data["begin"])) return "";
  $duration = $data["ending"] - $data["begin"];
  db_update("simple_contactactivities",array("duration"=>$duration),array("id=@id@"),array("id"=>$id));
  return "";
}

static function createedithelpdesk($id, $data) {
  if (empty($data["ending"]) or empty($data["begin"])) return "";
  $duration = $data["ending"] - $data["begin"];
  db_update("simple_helpdesk",array("duration"=>$duration),array("id=@id@"),array("id"=>$id));
  return "";
}

static function calcappointment($id, $data, $unused=array(), $export=true) {
  if ($data["begin"] > $data["ending"]) {
    $tmp = $data["begin"];
	$data["begin"] = $data["ending"];
	$data["ending"] = $tmp;
  }
  if (isset($data["allday"]) and $data["allday"]=="1") {
    $begin_arr = sys_getdate($data["begin"]);
    $data["begin"] = mktime(0,0,0,$begin_arr["mon"],$begin_arr["mday"],$begin_arr["year"]);
    $end_arr = sys_getdate($data["ending"]);
    $data["ending"] = mktime(23,59,0,$end_arr["mon"],$end_arr["mday"],$end_arr["year"]);
  }
  if (!empty($data["recurrence"]) and $data["repeatcount"]*$data["repeatinterval"]>0) {
    $excludes = explode("|",trim($data["repeatexcludes"],"|"));
	if (empty($excludes[0])) unset($excludes[0]);
    $data["repeatcount"] += count($excludes);
    $until = strtotime("+".(int)($data["repeatcount"]*$data["repeatinterval"])." ".$data["recurrence"],$data["begin"]);
  } else $until = 0;
  
  $duration = $data["ending"] - $data["begin"];
  if (isset($data["repeatuntil"]) and $until>$data["repeatuntil"] and $data["repeatuntil"]!=0) $until = $data["repeatuntil"];
  $repeatbegin = 0;
  $repeatend = 0;
  if (!empty($data["recurrence"])) {
    switch ($data["recurrence"]) {
	case "weeks":
      $repeatbegin = sys_date("w",$data["begin"]);
      $repeatend = sys_date("w",$data["ending"]);
	  break;
	case "months":
      $repeatbegin = sys_date("j",$data["begin"]);
      $repeatend = sys_date("j",$data["ending"]);
	  break;
	case "years":
      $repeatbegin = sys_date("z",$data["begin"]);
      $repeatend = sys_date("z",$data["ending"]);
	  if ($repeatbegin > 58) $repeatbegin--; // leap year
	  if ($repeatend > 58) $repeatend++;
	  break;
    }
  }
  if (!empty($data["reminder"])) {
    $reminder_begin = $data["begin"]-$data["reminder"];
  } else $reminder_begin = 0;
  
  if ($id!="") {
    db_update("simple_calendar",array("begin"=>$data["begin"],"ending"=>$data["ending"],"duration"=>$duration,"until"=>$until,"repeatbegin"=>$repeatbegin,"repeatend"=>$repeatend,"reminder_begin"=>$reminder_begin),array("id=@id@"),array("id"=>$id));
  } else return array("until"=>$until,"repeatbegin"=>$repeatbegin,"repeatend"=>$repeatend);
  
  if ($export) return self::_sync_createedit($id,$data,"calendar"); else return "";
}

static function runxml($id, $data, $params) {
  list($file, $parent_anchor) = $params;
  $home = self::_get_folder_by_anchor($parent_anchor);
  if (!empty($home) and file_exists(sys_custom($file))) {
    folders::create_default_folders($file,$home,false,$data);
	sys_add_notification("{t}Folder structure created.{/t}");
  }
  return "";
}

static function create_ldap_user($ds, $base_dn, $username, $uid) {
  if ($base_dn=="") {
    $result_id = @ldap_read($ds,"","(objectclass=*)",array("namingContexts"));
    $attrs = ldap_get_attributes($ds, ldap_first_entry($ds,$result_id));
	$base_dn = $attrs["namingContexts"][0];
  }
  $res = ldap_search($ds,$base_dn,$uid."=".$username);
  if (ldap_count_entries($ds,$res)==1) {
	$data = ldap_get_attributes($ds, ldap_first_entry($ds,$res));
	if (is_array($data) and count($data)!=0) self::_create_ldap_user($username,$data);
  }
}

static function http_post($host, $port, $path, $data) {
  $errorNumber = 0;
  $errorString = "";
  if (($fp = @fsockopen($host, $port, $errorNumber, $errorString))) {
	$req = array();
	$req[] = "POST ".$path." HTTP/1.0";
    $req[] = "Host: ".$host;
    $req[] = "Content-Type: application/x-www-form-urlencoded";
    $req[] = "Content-Length: ".strlen($data);
	$req[] = "";
    $req[] = $data;
    fwrite($fp, implode("\r\n", $req));
	$resp = "";
	while (!feof($fp)) $resp .= fread($fp,8192);
	fclose($fp);
	return $resp;
  } else {
	return "ERROR: ".$errorString." ".$errorNumber;
  }
}

static function sendmail_getconn($username, $efrom) {
  $concat = sql_concat("concat(firstname;' ';lastname)");
  if ($efrom!="") {
    $row = db_select_first("simple_sys_identities",array("smtp","email","name"),array("email=@email@","users like @username_sql@"),"",array("username_sql"=>"%|".$username."|%","email"=>$efrom));
    if (empty($row["smtp"]) and !USE_MAIL_FUNCTION) {
	  $row["smtp"] = db_select_value("simple_sys_users","smtp","username=@username@",array("username"=>$username));
    }
  } else {
    $row = db_select_first("simple_sys_users",array("smtp","email","$concat as name"),"username=@username@","",array("username"=>$username));
    if (empty($row["smtp"]) and !USE_MAIL_FUNCTION) {
      $row = db_select_first("simple_sys_identities",array("smtp","email","name"),"users like @username_sql@","",array("username_sql"=>"%|".$username."|%"));
    }
  }
  return $row;
}

private static function _createlocation($name) {
  $row_id = db_select_value("simple_locations","id","locationname=@name@",array("name"=>$name));
  $folder = self::_get_folder_by_anchor("locations");
  if (empty($row_id) and !empty($folder)) {
	$id = sql_genID("simple_locations")*100+$_SESSION["serverid"];
    $data = array("id"=>$id, "locationname"=>$name, "folder"=>$folder);
    $error_sql = db_insert("simple_locations",$data);
	if ($error_sql=="") {
	  db_update_treesize("simple_locations",$folder);
	  db_search_update("simple_locations",$id,array(),array("locationname"=>"text"));
	  sys_log_stat("new_records",1);
	} else return $error_sql;
  }
  return "";
}

private static function _createedit_payroll($table, $id, $data) {
  $cdata = array();
  $payroll = false;
  if (in_array("admin_payroll",$_SESSION["groups"]) or sys_is_super_admin($_SESSION["username"])) {
    $payroll = true;
  }
  if (!$payroll) {
    $cdata["booking_number"] = "";
    if (in_array($data["status"],array("{t}confirmed{/t}","{t}booked{/t}"))) {
	  $cdata["status"] = "{t}unconfirmed{/t}";
	  sys_add_notification(sprintf("{t}Status reset to: %s{/t}","{t}unconfirmed{/t}"));
    }
  }
  if ($data["completed"]==1) {
    if ($data["rwrite_users"]!="") $cdata["rwrite_users"] = "";
    if ($data["rwrite_groups"]!="") $cdata["rwrite_groups"] = "";
	sys_add_notification("{t}Asset marked as read-only.{/t}");
  }
  if (count($cdata)>0) db_update($table,$cdata,array("id=@id@"),array("id"=>$id));
  if ($data["completed"]==1 and self::_add_asset_permission_group($table,$id,array_merge($data,$cdata),"admin_payroll")) {
    sys_add_notification(sprintf("{t}Permissions added for: %s{/t}","admin_payroll"));
  }
  return "";
}

private static function _create_ldap_user($username, $data) {
  $cdata = array();

  $mapping = array(
	"c"=>"country", "department"=>"department", "description"=>"jobdesc",
	"facsimiletelephonenumber"=>"fax", "fax"=>"fax", "givenname"=>"firstname", "ipphone"=>"skype",
	"l"=>"city", "mail"=>"email", "mobile"=>"mobile", "pager"=>"pager", "postalcode"=>"zipcode",
    "sn"=>"lastname", "st"=>"state", "street"=>"street", "streetaddress"=>"street",
    "telephonenumber"=>"phone", "wwwhomepage"=>"homepage", SETUP_AUTH_LDAP_ROOM=>"location"
  );
  foreach ($data as $key=>$val) {
    $key = strtolower($key);
    if (isset($mapping[$key]) and !empty($val[0])) $cdata[$mapping[$key]] = $val[0];
  }
  
  $username = strtolower($username);
  login::create_user($username,$cdata);
  if (!empty($cdata["location"])) self::_createlocation($cdata["location"]);

  if (isset($data[SETUP_AUTH_LDAP_MEMBEROF])) $groups = $data[SETUP_AUTH_LDAP_MEMBEROF]; else $groups = array();
  
  if (SETUP_AUTH_LDAP_GROUPS and is_array($groups) and count($groups)>1) {
	array_shift($groups);
	self::_create_ldap_groups($groups, $username);
  }
}

private static function _create_ldap_groups($groups, $username) {
  db_update("simple_sys_groups",array("members"=>"replace(members,'|".sql_quote($username)."|','|')"),array("members like @username@","createdby='auth_ldap'"),array("username"=>"%|".$username."|%"),array("quote"=>false));
  foreach ($groups as $group) {
	$group = ldap_dn2ufn($group);
	$group = substr($group,0,strpos($group,","));
	if (empty($group)) continue;
	
	// decode 2-byte unicode characters
	$group = preg_replace("/\\\\([A-F0-9]{2})/e",'chr(hexdec("\1"))',$group);
	self::creategroup($group);
	self::addgroupmember(0, array("username"=>$username), array($group));
  }
}

private static function _sync_delete($id, $data, $module) {
  if (!defined("SYNC4J") or !SYNC4J) return "";
  $anchor = db_select_value("simple_sys_tree","anchor","id=@id@",array("id"=>$data["folder"]));
  if (empty($data["id"]) or empty($anchor) or !sys_strbegins($anchor,$module."_")) return "";

  $error = "";
  switch ($module) {
	case "calendar":
	case "tasks":
	  if (empty($data["syncid"])) return "";
	  $error = db_update("fnbl_pim_calendar",array("status"=>"D","last_update"=>NOW*1000),array("id=@id@"),array("id"=>$data["syncid"]),array("no_defaults"=>1));
	  break;
	case "contacts":
	  if (empty($data["syncid"])) return "";
	  $error = db_update("fnbl_pim_contact",array("status"=>"D","last_update"=>NOW*1000),array("id=@id@"),array("id"=>$data["syncid"]),array("no_defaults"=>1));
	  break;
	case "notes":
	  if (empty($data["syncid"])) return "";
	  $error = db_update("fnbl_pim_note",array("status"=>"D","last_update"=>NOW*1000),array("id=@id@"),array("id"=>$data["syncid"]),array("no_defaults"=>1));
	  break;
  }
  return $error;
}

private static function _sync_createedit($id, $data, $module) {
  if (!defined("SYNC4J") or !SYNC4J) return "";

  $anchor = db_select_value("simple_sys_tree","anchor","id=@id@",array("id"=>$data["folder"]));
  if (empty($id) or empty($anchor) or !sys_strbegins($anchor,$module."_")) return "";
  $username = substr($anchor,strlen($module)+1);

  $error = "";
  switch ($module) {
	case "notes":
	  $row = db_select_first("fnbl_simple_notes_exp","*","id=@id@","",array("id"=>$id));
	  if (!empty($row["id"])) {
	    $row["userid"] = $username;
	    self::_sync_create_item("fnbl_pim_note",$row,"simple_notes",$id);
	  }
	  break;
	case "tasks":
	  $row = db_select_first("fnbl_simple_tasks_exp","*","id=@id@","",array("id"=>$id));
	  if (!empty($row["id"])) {
	    $row["userid"] = $username;
	    self::_sync_create_item("fnbl_pim_calendar",$row,"simple_tasks",$id);
	  }
	  break;
	case "calendar":
	  $row = db_select_first("fnbl_simple_calendar_exp","*","id=@id@","",array("id"=>$id));
	  if (!empty($row["id"])) {
	    $row["userid"] = $username;
		db_delete("fnbl_pim_calendar_exception",array("calendar=@id@"),array("id"=>$row["id"]));
	    self::_sync_create_item("fnbl_pim_calendar",$row,"simple_calendar",$id);

		if ($row["rec_exceptions"]!="0") {
		  $exceptions = explode("|",trim($row["rec_exceptions"],"|"));
		  if (count($exceptions)>0) {
		    foreach ($exceptions as $exception) {
			  $data = array("calendar"=>$row["id"],"occurrence_date"=>date("Y-m-d H:i:s",$exception));
			  db_insert("fnbl_pim_calendar_exception",$data,array("no_defaults"=>1));
	  } } } }
	  break;
	case "contacts":
	  $row = db_select_first("fnbl_simple_contacts_exp","*","id=@id@","",array("id"=>$id));
	  if (!empty($row["id"])) {
	    $row["userid"] = $username;
		db_delete("fnbl_pim_address",array("contact=@syncid@"),array("syncid"=>$row["syncid"]));
		db_delete("fnbl_pim_contact_item",array("contact=@syncid@"),array("syncid"=>$row["syncid"]));
	    self::_sync_create_item("fnbl_pim_contact",$row,"simple_contacts",$id);
		if (!empty($row["street"])) {
		  $data = array("contact"=>$row["syncid"], "type"=>1, "street"=>$row["street"], "city"=>$row["city"],
				  "state"=>$row["state"], "postal_code"=>$row["zipcode"], "country"=>$row["country"]);
		  db_insert("fnbl_pim_address",$data,array("no_defaults"=>1));
		}
		$items = array(
		  1 => $row["phoneprivate"],
		  2 => $row["fax"],
		  3 => $row["mobile"],
		  4 => $row["email"],
		  8 => $row["skype"],
		  10 => $row["phone"],
		  14 => $row["pager"],
		  16 => $row["emailprivate"]
		);
		foreach ($items as $key=>$item) {
		  if (empty($item)) continue;
		  db_insert("fnbl_pim_contact_item",array("contact"=>$row["syncid"],"type"=>$key,"value"=>$item),array("no_defaults"=>1));
		}
	  }
	  break;
  }  
  return $error;
}

private static function _sync_create_item($table,$row,$source_table,$id) {
  $row["id"] = $row["syncid"];
  $unset = array("syncid","rec_exceptions","country","state","street","city","zipcode","fax","mobile","phone","phoneprivate","email","emailprivate","pager","skype");
  foreach ($unset as $var) if (isset($row[$var])) unset($row[$var]);
  if (DEBUG) print_r($row);
  foreach ($row as $key=>$val) if ($val=='') $row[$key] = null;
  if ($row["status"]=="U") {
	return db_update($table,$row,array("id=@syncid@","status!='D'"),array("syncid"=>$row["id"]),array("no_defaults"=>1));
  } else {
	$error = db_insert($table,$row,array("no_defaults"=>1));
	if ($error=="") {
	  $error .= db_update($source_table,array("syncid"=>$row["id"]),array("id=@id@"),array("id"=>$id));
	}
	return $error;
  }
}

// TODO remove, deprecated
private static function _create_portal_items($anchor, $bookmarks) {
  $parent = self::_get_folder_by_anchor($anchor);
  if (!empty($parent)) {
	$i = 1;
	foreach ($bookmarks as $bookmark) {
      $folder_id = db_select_first("simple_sys_tree","id",array("ftype=@ftype@","parent=@parent@"),"lft asc",array("ftype"=>$bookmark[1],"parent"=>$parent));
	  if (empty($folder_id)) continue;
      $id = sql_genID("simple_portal")*100+$_SESSION["serverid"];
	  $url = "index.php?folder=".$folder_id["id"].str_replace("@folder@",$folder_id["id"],$bookmark[2]);
      $data = array(
        "id"=>$id,
        "bookmarkname"=>($i++).") ".$bookmark[0],
        "url"=>$url,
        "folder"=>$parent,
		"fullwidth"=>$bookmark[3],
		"height"=>$bookmark[4],
		"refresh"=>"300"
      );
      $error_sql = db_insert("simple_portal",$data);
	  if ($error_sql=="") {
	    db_update_treesize("simple_portal",$parent);
	    db_search_update("simple_portal",$id,array(),array("bookmarkname"=>"text","url"=>"text"));
	    sys_log_stat("new_records",1);
} } } }

private static function _add_asset_permission_group($table, $id, $data, $group) {
  $cdata = array();
  if (!in_array($group,explode("|",$data["rread_groups"]))) {
	$cdata["rread_groups"] = $data["rread_groups"]."|".$group;
  }
  if (!in_array($group,explode("|",$data["rwrite_groups"]))) {
	$cdata["rwrite_groups"] = $data["rwrite_groups"]."|".$group;
  }
  if (count($cdata)==0) return false;
  foreach ($cdata as $key=>$val) $cdata[$key] = "|".trim($val,"|")."|";
  db_update($table,$cdata,array("id=@id@"),array("id"=>$id));
  return true;
}

private static function _to_url($arr) {
  $url = "";
  foreach ($arr as $key=>$val) $url .= "&".$key."=".utf8_encode($val);
  return $url;
}

private static function _get_folder_by_anchor($anchor) {
  return db_select_value("simple_sys_tree","id","anchor=@anchor@",array("anchor"=>$anchor));
}

private static function _get_folder_by_type($type) {
  return db_select_value("simple_sys_tree","id","ftype=@ftype@",array("ftype"=>$type));
}

}