rel_letterbox_dir_path = $rel_letterbox_dir_path; //DB Connect $this->db = new dbquery(); $this->db->connect(); //Configure the PHPMailer if( isset($_SESSION['mailer']['type']) ) { if($_SESSION['mailer']['type'] == 'smtp') { parent::isSMTP(); } else if( $_SESSION['mailer']['type'] == 'sendmail' ) { parent::IsSendmail(); } else if( $_SESSION['mailer']['type'] == 'qmail' ) { parent::IsQmail(); } else { parent::IsMail(); } } if( isset($_SESSION['mailer']['smtp_host']) && !empty($_SESSION['mailer']['smtp_host']) ) { $this->Host = $_SESSION['mailer']['smtp_host']; } if( isset($_SESSION['mailer']['smtp_user']) && isset($_SESSION['mailer']['smtp_password']) && !empty($_SESSION['mailer']['smtp_user']) && !empty($_SESSION['mailer']['smtp_user']) ) { $this->Username = $_SESSION['mailer']['smtp_user']; $this->Password = $_SESSION['mailer']['smtp_password']; $this->SMTPAuth = true; } if( isset($_SESSION['mailer']['smtp_secure']) && !empty($_SESSION['mailer']['smtp_secure']) ) { $this->SMTPSecure = $_SESSION['mailer']['smtp_secure']; } if( isset($_SESSION['mailer']['charset']) && !empty($_SESSION['mailer']['charset'])) { $this->CharSet = $_SESSION['mailer']['charset']; } if( !isset($_SESSION['mailer']['x-mailer']) || empty($_SESSION['mailer']['x-mailer']) ) { $_SESSION['mailer']['x-mailer'] = "PHP/".phpversion(); } } private function load_rights() { //USER RIGHTS ? $this->db->query("SELECT USER_ID FROM mge_user_or_group muog, usergroup_content uc WHERE basket_or_other = '".$this->type_id."' AND ( ( TYPE = 'group' AND uc.group_id = user_id_or_group_id ) OR TYPE ='user' AND uc.user_id = user_id_or_group_id)"); $users = array(); while( $res = $this->db->fetch_object() ) $users[] = $res->USER_ID; $this->r_users_array = $users; //ENABLED ? $this->db->query("SELECT * FROM mailer_rights WHERE BASKET_OR_OTHER = '".$this->type_id."'"); if( $mr = $this->db->fetch_object() ) { //DISABLED CASE if( $mr->ENABLED == 1) $this->r_enabled = true; //ALREADY_MAIL CASE if( !empty($mr->ALREADY_MAILED_IN) && is_array(unserialize($mr->ALREADY_MAILED_IN)) ) { $this->r_renotif_array = unserialize($mr->ALREADY_MAILED_IN); } else { $this->r_renotif_array = array(); } //INVERSE SELECTION $all_selected = array(); //Retrieve the baskets list order by name $this->db->query("SELECT BASKET_ID FROM baskets WHERE ENABLED = 'Y'"); while( $res = $this->db->fetch_object() ) { $all_selected[] = $res->BASKET_ID; } //Retrieve the others notifs type from the {letterbox_dir_path + notif_path} $others_notifs = new DomDocument(); $others_notifs->load($this->rel_letterbox_dir_path."/".$this->notif_path); $xp_others_notifs = new domxpath($others_notifs); foreach($xp_others_notifs->query("/ROOT/NOTIFICATION/ID") as $nt) { if( is_numeric($nt->nodeValue) ) $all_selected[] = $nt->nodeValue; } $this->r_renotif_array = array_diff($all_selected,$this->r_renotif_array); return true; } else { return false; } } private function replace_metadata( $html, $sql_result, $convert_utf8 = false ) { if( count($sql_result) == 1 ) { $tab = array("0" => $html); } else { $cpt = preg_match_all("/".preg_quote($this->list_begin_open,"/")."(.*?)".preg_quote($this->list_begin_close,"/")."(.*?)".preg_quote($this->list_end,"/")."/is", $html, $matches, PREG_OFFSET_CAPTURE); //Create segments $offset[0] = 0; foreach( $matches[0] as $k_off => $d_off ) { $offset[$d_off[1]] = array( "offset" => $d_off[1], "strlen" => strlen($d_off[0]),"separator" => $matches[1][$k_off][0] ); $offset[strlen($d_off[0]) + $d_off[1]] = strlen($d_off[0]) + $d_off[1]; } $offset[strlen($html)] = strlen($html); $offset = array_values($offset); //Create array from segments $tab = array(); for( $i=0; $i < count($offset); $i++ ) { if( is_array($offset[$i]) ) { for( $j=0; $j < count($sql_result); $j++ ) { $tab[$i][$j] = substr($html,$offset[$i]["offset"],$offset[$i]["strlen"]); if( $j != (count($sql_result) -1) ) $tab[$i][$j] .= $offset[$i]["separator"]; } } else { if( $i+1 < count($offset) ) { if( is_array($offset[$i+1]) ) { $length = $offset[$i+1]["offset"] - $offset[$i]; } else { $length = $offset[$i+1] - $offset[$i]; } $tab[$i] = substr($html,$offset[$i],$length); } } } } //Replace metadata $key = array(); if( count($sql_result[0]) != 0 ) foreach( array_keys($sql_result[0]) as $k ) { if( $convert_utf8 ) $key[] = "[".htmlentities($k,ENT_COMPAT,"UTF-8")."]"; else $key[] = "[".$k."]"; } for( $i=0; $i < count($tab); $i++ ) { foreach( $sql_result as $k_sr => $d_sr ) { if( is_array($tab[$i]) ) { $tab[$i][$k_sr] = stripslashes( str_replace($key,array_values($d_sr),$tab[$i][$k_sr]) ); } else if( !is_array($tab[$i]) && $k_sr == 0 ) { $tab[$i] = stripslashes( str_replace($key,array_values($d_sr),$tab[$i]) ); } } } //Convert $tab to string $return = ""; for( $i=0; $i < count($tab); $i++ ) { if( is_array($tab[$i]) ) for( $j=0; $j < count($tab[$i]); $j++ ) $return .= $tab[$i][$j]; else $return .= $tab[$i]; } //Delete list_begin_open, list_begin_close, list_end $return = preg_replace("/".preg_quote($this->list_begin_open,"/").".*?".preg_quote($this->list_begin_close,"/")."(.*?)".preg_quote($this->list_end,"/")."/is","$1", $return); return $return; } private function mail_generate($subject_model,$html_body_model,$sql_query_result) { $return = array(); if( $this->group_mail === true ) { if( isset($sql_query_result) && count($sql_query_result) > 0 ) { $return[reset($this->table_id)]["body"] = $this->replace_metadata($html_body_model,$sql_query_result, true ); $return[reset($this->table_id)]["subject"] = $this->replace_metadata($subject_model, $sql_query_result ); } } else { //A TESTER foreach( $this->table_id as $id ) { if( isset($sql_query_result[0]) ) { $return[$id]["body"] = $this->replace_metadata($html_body_model,$sql_query_result, true ); $return[$id]["subject"] = $this->replace_metadata($subject_model,$sql_query_result ); } } } //OLD /* if( count($this->table_id) == 0 ) return $return; if( $this->group_mail === true ) { $sql_query = str_ireplace("@id"," IN (".implode(",",$this->table_id).") ",$sql_query); $this->db->query( $sql_query ); while( $tmp_res = $this->db->fetch_assoc() ) $db_res[] = $tmp_res; if( isset($db_res) && count($db_res) > 0 ) { $return[reset($this->table_id)]["body"] = $this->replace_metadata($html_body_model, $db_res, true ); $return[reset($this->table_id)]["subject"] = $this->replace_metadata($subject_model, $db_res ); } } else { foreach( $this->table_id as $id ) { $sql_query = str_ireplace("@id"," = ".$id,$sql_query); $this->db->query( $sql_query ); if( $db_res[0] = $this->db->fetch_assoc($sql_query) ) { $return[$id]["body"] = $this->replace_metadata($html_body_model,$db_res, true ); $return[$id]["subject"] = $this->replace_metadata($subject_model,$db_res); } } } echo "----------------------------------\n"; print_r($return); echo "----------------------------------\n"; */ return $return; } public function replace_embeddedImage($html_body) { $body = @DOMDocument::loadHTML("".$html_body.""); $img_html = $body->getElementsByTagName("img"); //TEST PHP VERSION $at_least_php53 = ( version_compare(PHP_VERSION, '5.3.0') >= 0 ); if( $at_least_php53 ) $finfo = new finfo(FILEINFO_MIME); //MIME-TYPE $md5_array = array(); for ($i = 0; $i < $img_html->length; $i++) { $src = $img_html->item($i)->getAttribute("src"); if( !empty($src) ) { $this_md5 = md5_file($this->rel_letterbox_dir_path."/".$src); //This file doesn't exist if( ! in_array( $this_md5, $md5_array) ) { $md5_array[] = $this_md5; if( $at_least_php53 ) $mime_type = $finfo->file( realpath($this->rel_letterbox_dir_path."/".$src) ); else $mime_type = mime_content_type( realpath($this->rel_letterbox_dir_path."/".$src) ); if( $mime_type ) { $mt = explode(";",$mime_type); parent::AddEmbeddedImage($this->rel_letterbox_dir_path."/".$src,$this_md5,basename($this->rel_letterbox_dir_path."/".$src),"base64",$mt[0]); } } $img_html->item($i)->setAttribute("src","cid:".$this_md5); } } return $body->saveHTML(); } private function create_virtual_table($sql_query,$file,$root_node,$keyword) { if( !@DOMDocument::load($this->rel_letterbox_dir_path."/".$file) ) { return 0; } $xml = DOMDocument::load($this->rel_letterbox_dir_path."/".$file); $xp_xml = new domxpath($xml); $nodes = $xp_xml->query($root_node); if( $nodes->length === 0 ) { return 1; } else { $replace = " ( "; foreach( $nodes as $l_one) { $replace .= " ( SELECT "; $level_two = $xp_xml->query("*",$l_one); if( $level_two->length === 0 ) { $level_two = $nodes; } foreach( $level_two as $l_two ) { if( is_numeric($l_two->nodeValue) ) $replace .= " ".$l_two->nodeValue." AS '".$l_two->nodeName."',"; else if( strcasecmp(mb_detect_encoding($l_two->nodeValue),"UTF-8") != 0 ) $replace .= " '".utf8_encode($l_two->nodeValue)."' AS '".utf8_encode($l_two->nodeName)."',"; else $replace .= " '".$l_two->nodeValue."' AS '".$l_two->nodeName."',"; } $replace = substr($replace,0,-1); $replace .= " ) UNION"; } $replace = substr($replace,0,-5); $replace .= " ) "; } return str_ireplace($keyword, $replace , $sql_query); } public function send_and_save($table_res,$table_id,$user_id,$type_id) { $this->table_res = $table_res; if( !is_array($table_id) ) $this->table_id = array($table_id); else $this->table_id = $table_id; $this->user_id = $user_id; $this->type_id = $type_id; if( count($this->table_id) == 0 ) return("No mail for this user and this basket"); //Load rights if(!$this->load_rights()) return("No rights defined for this basket"); if( empty($this->r_users_array) || !in_array($user_id,$this->r_users_array) ) return("The user is not in the notif rights list"); if( $this->r_enabled != true ) return("The notification is not enabled for the user"); //Load sql request $notif_conf = new DomDocument(); $notif_conf->load($this->rel_letterbox_dir_path."/".$this->notif_path); $xp_notif_conf = new domxpath($notif_conf); //Direct Case if( is_numeric($type_id) ) { $sql_query = "SELECT "; foreach( $xp_notif_conf->query("/ROOT/NOTIFICATION[ID='".$type_id."']/SELECT") as $select ) { if( trim($xp_notif_conf->query("FIELD",$select)->item(0)->nodeValue) != "" ) $sql_query .= $xp_notif_conf->query("FIELD",$select)->item(0)->nodeValue; if( trim($xp_notif_conf->query("ALIAS",$select)->item(0)->nodeValue) != "") $sql_query .= " AS ".trim($xp_notif_conf->query("ALIAS",$select)->item(0)->nodeValue); $sql_query .= ","; } $sql_query = substr($sql_query,0,-1); $sql_query .= " FROM ".$xp_notif_conf->query("/ROOT/NOTIFICATION[ID='".$type_id."']/FROM")->item(0)->nodeValue." WHERE ".$xp_notif_conf->query("/ROOT/NOTIFICATION[ID='".$type_id."']/WHERE")->item(0)->nodeValue; } //Basket Case else { $sql_query = "SELECT "; foreach( $xp_notif_conf->query("/ROOT/BASKETS/SELECT") as $select ) { if( trim($xp_notif_conf->query("FIELD",$select)->item(0)->nodeValue) != "" ) $sql_query .= trim($xp_notif_conf->query("FIELD",$select)->item(0)->nodeValue); if( trim($xp_notif_conf->query("ALIAS",$select)->item(0)->nodeValue) != "") $sql_query .= " AS ".trim($xp_notif_conf->query("ALIAS",$select)->item(0)->nodeValue); $sql_query .= ","; } $sql_query = substr($sql_query,0,-1); $sql_query .= " FROM ".$xp_notif_conf->query("/ROOT/BASKETS/FROM")->item(0)->nodeValue." WHERE ".$xp_notif_conf->query("/ROOT/BASKETS/WHERE")->item(0)->nodeValue; } //Virtual Table foreach( $xp_notif_conf->query("//VIRTUAL_TABLE") as $vt ) { $this_vt = $this->create_virtual_table( $sql_query, $xp_notif_conf->query("FILE",$vt)->item(0)->nodeValue, $xp_notif_conf->query("ROOT_NODE",$vt)->item(0)->nodeValue, $xp_notif_conf->query("KEYWORD",$vt)->item(0)->nodeValue ); if( !is_numeric($this_vt) ) $sql_query = $this_vt; else return("Error while loading virtual table (Code = ".$this_vt.")"); } //Load Subject $subject_model = $xp_notif_conf->query("/ROOT/NOTIFICATION[ID='".$type_id."']/SUBJECT")->item(0)->nodeValue; //Load Model $html_body_model = @file_get_contents($this->rel_letterbox_dir_path."/".$xp_notif_conf->query("/ROOT/MODEL_RELATIVE_DIR")->item(0)->nodeValue."/".$type_id.".html"); if( empty($html_body_model) ) return("The model for ".$type_id." doesn't exist"); //Add mail from parent::AddReplyTo($_SESSION['config']['adminmail']); $this->From = $_SESSION['config']['adminmail']; $this->FromName = $_SESSION['config']['adminname']; //Add mail to $this->db->query("SELECT MAIL, FIRSTNAME, LASTNAME FROM users WHERE USER_ID = '".$user_id."'"); if( $res = $this->db->fetch_object() ) parent::AddAddress($res->MAIL,$res->FIRSTNAME.",".$res->LASTNAME); else return("Invalid email for ".$user_id); //Returned array $return = array(); //Rights 2 $this->db->query("SELECT * FROM mailer_history WHERE TABLE_RES = '".$this->table_res."' AND TABLE_ID IN ('".implode('\',\'',$this->table_id)."') AND TO_USER_ID = '".$this->user_id."' AND RESULT = 'OK' AND TYPE_OR_BASKET NOT IN ('".implode('\',\'',$this->r_renotif_array)."') ORDER BY TABLE_RES, TABLE_ID, TO_USER_ID, SEQUENCE"); while( $res = $this->db->fetch_object() ) { $return[$res->TABLE_ID] = "Error : Notification already sent"; } //Remove error from the current ressource list $this->table_id = array_diff($this->table_id,array_keys($return)); if( count($this->table_id) == 0 ) return $return; //Execute query $sql_query = str_ireplace("@id"," IN (".implode(",",$this->table_id).") ",$sql_query); $this->db->query( $sql_query ); //$this->db->show(); exit(); while( $tmp_res = $this->db->fetch_assoc() ) { $sql_query_result[] = $tmp_res; } if( !isset($sql_query_result) || count($sql_query_result) == 0 ) return("The SQL query doesn't return anything\n SQL QUERY : ".$sql_query."\n"); //Generate emails from model $subject_and_body = $this->mail_generate($subject_model,$html_body_model,$sql_query_result); if( $this->group_mail && count($this->table_id) != count($subject_and_body) ) { foreach( array_diff($this->table_id,array_keys($subject_and_body)) as $id ) { $this->store_in_history($id,"OK"); $return[$id] = "Group with the last email sent"; } } foreach( $subject_and_body as $k_sab => $sab ) { if( !is_array($sab) ) return("Cannot generate email from the model"); //Add subject and body $this->Subject = $sab["subject"]; $this->Body = $sab["body"]; //Re-encode Body if( strcasecmp(mb_detect_encoding($this->Body),$this->CharSet) != 0 ) { $this->Body = utf8_decode($this->Body); } //Re-encode Subject if( strcasecmp(mb_detect_encoding($this->Subject),$this->CharSet) != 0 ) { $this->Subject = utf8_decode($this->Subject); } //Mail is HTML parent::isHTML(true); //Replace embeddedImage $this->Body = $this->replace_embeddedImage($this->Body); ini_set('implicit_flush',false); // (avoids output even with ob_start, in command line mode) ob_start(); if( !parent::Send() ) { $this->store_in_history($k_sab,"Error :".$this->ErrorInfo); ob_end_clean(); ini_set('implicit_flush',true); $return[$k_sab] = "Error :".$this->ErrorInfo; } else { $this->store_in_history($k_sab,"OK"); ob_end_clean(); ini_set('implicit_flush',true); $return[$k_sab] = "OK"; } } ksort($return); return $return; } //Reecriture header pour modifier le X-Mailer public function CreateHeader() { $result = parent::CreateHeader(); $result = preg_replace("/(X-Mailer:\s*).*(\n)/i","$1".$_SESSION['mailer']['x-mailer']."$2",$result); return $result; } public function send_simple($from,$from_name,$to=array(),$cc=array(),$cci=array(),$subject,$content,$html,$attachements=array() ) { $control_domain = array(); if( !empty($from) ) { $this->From = $from; $this->AddReplyTo($from); $control_domain[] = $from; } else { return "MAILFROM MISSING"; } if( !empty($from_name) ) { $this->FromName = $from_name; } foreach($to as $t) if ( !empty($t) ) { $this->AddAddress($t); $control_domain[] = $t; } foreach($cc as $c) if ( !empty($c) ) { $this->AddCC($c); $control_domain[] = $c; } foreach($cci as $ci) if ( !empty($ci) ) { $this->AddBCC($ci); $control_domain[] = $ci; } $this->Body = $content; $this->Subject = $subject; if( strcasecmp(mb_detect_encoding($content),$this->CharSet) != 0 ) { $this->Body = utf8_decode($this->Body); } if( strcasecmp(mb_detect_encoding($subject),$this->CharSet) != 0 ) { $this->Subject = utf8_decode($this->Subject); } foreach( $attachements as $attachement ) $this->AddAttachment($attachement["PATH"],$attachement["NAME"],"base64",$attachement["TYPEMIME"]); //Rewrite mailfrom if this mail is out of domains if( !empty($_SESSION['mailer']['domains']) ) { if( !$this->mail_rewriting_if($control_domain,explode(";",$_SESSION['mailer']['domains']),"OR") ) { $this->From = $_SESSION['config']['adminmail']; $this->FromName = $from_name; } } $this->Body = $this->replace_embeddedImage($this->Body); //Mail is HTML if( $html ) $this->isHTML(true); //Send the mail $this->exceptions = false; if( ! parent::Send() ) { return "Error :".$this->ErrorInfo; } else { return "OK"; } } private function mail_rewriting_if( $fields_to_check = array(),$domains_to_check = array(), $operand ='AND') { $match_result = array(); foreach( $fields_to_check as $check ) { foreach( $domains_to_check as $domain ) { if( stristr( trim(stristr($check,"@")),trim($domain) ) === FALSE ) { $match_result[$check] = 0; } else { $match_result[$check] = 1; break; } } } return eval("return (".implode(" ".$operand." ",$match_result).");"); } public function purge_history() { /* //Delete notes $this->db->query("DELETE FROM mailer_history WHERE TABLE_RES = 'notes' AND TABLE_ID IN ( SELECT ID FROM res_x r, notes n WHERE r.STATUS = 'END' AND r.IS_FOLDER = 'Y' AND n.RECORD_ID = r.RES_ID )"); //Remove deleted notes $this->db->query("DELETE FROM mailer_history WHERE TABLE_RES = 'notes' AND TABLE_ID NOT IN ( SELECT ID FROM notes)"); //Delete folder //Delete folder $this->db->query("SELECT r.RES_ID FROM res_x r WHERE STATUS = 'END' AND r.RES_ID NOT IN ( SELECT DISTINCT(r2.RES_ID) FROM listinstance l, res_x r2 WHERE l.RES_ID = r2.RES_ID AND RES_TABLE = 'res_x' AND l.VIEWED = 0 )"); SELECT r.RES_ID FROM res_x r WHERE STATUS = 'END' AND IS_FOLDER = 'Y' AND r.RES_ID NOT IN ( SELECT DISTINCT(r2.RES_ID) FROM listinstance l, res_x r2 WHERE l.RES_ID = r2.RES_ID AND RES_TABLE = 'res_x' AND l.VIEWED = 0 ) /* $this->db->query("DELETE FROM mailer_history WHERE TABLE_RES = 'res_x' AND TABLE_ID IN ( SELECT RES_ID FROM res_x r,listinstance l WHERE r.STATUS = 'END' AND r.IS_FOLDER = 'Y')"); */ } private function store_in_history($table_id,$result) { $this->db->query("INSERT INTO mailer_history (TABLE_RES,TABLE_ID,DATE,TO_USER_ID,SEQUENCE,TYPE_OR_BASKET,RESULT) SELECT '".$this->table_res."',".$table_id.",now(),'".$this->user_id."',MAX(SEQUENCE) + 1,'".$this->type_id."','".$result."' FROM mailer_history WHERE TABLE_RES = '".$this->table_res."' AND TABLE_ID = ".$table_id." AND TO_USER_ID = '".$this->user_id."' AND TYPE_OR_BASKET = '".$this->type_id."'"); } } ?>