From 79dc9f0b0e959b9600986bdf0e6dfd68f90ddf90 Mon Sep 17 00:00:00 2001 From: Yves Christian Kpakpo <yveschristian.kpakpo@maarch.org> Date: Tue, 19 Mar 2013 01:00:32 +0000 Subject: [PATCH] Update: sendmail module --- sendmail/trunk/batch/LoggerLog4php.php | 314 ++++++++++++++++++ sendmail/trunk/batch/batch_tools.php | 157 +++++++++ .../trunk/batch/config/config.xml.default | 62 ++++ sendmail/trunk/batch/load_process_emails.php | 264 +++++++++++++++ sendmail/trunk/batch/process_emails.php | 184 ++++++++++ sendmail/trunk/batch/scripts/sendmail.bat | 1 + sendmail/trunk/batch/scripts/sendmail.sh | 5 + sendmail/trunk/class/class_modules_tools.php | 141 +++++--- sendmail/trunk/js/functions.js | 5 +- sendmail/trunk/mail_form.php | 2 +- sendmail/trunk/sendmail_ajax_content.php | 8 +- 11 files changed, 1097 insertions(+), 46 deletions(-) create mode 100644 sendmail/trunk/batch/LoggerLog4php.php create mode 100644 sendmail/trunk/batch/batch_tools.php create mode 100644 sendmail/trunk/batch/config/config.xml.default create mode 100644 sendmail/trunk/batch/load_process_emails.php create mode 100644 sendmail/trunk/batch/process_emails.php create mode 100644 sendmail/trunk/batch/scripts/sendmail.bat create mode 100644 sendmail/trunk/batch/scripts/sendmail.sh diff --git a/sendmail/trunk/batch/LoggerLog4php.php b/sendmail/trunk/batch/LoggerLog4php.php new file mode 100644 index 00000000000..900b13489c9 --- /dev/null +++ b/sendmail/trunk/batch/LoggerLog4php.php @@ -0,0 +1,314 @@ +<?php + +/** Logger class + * + * @author Laurent Giovannoni <dev@maarch.org> + **/ + +class Logger4Php +{ + + /** + * Array of errors levels + * + * @protected + **/ + protected $error_levels = array('DEBUG' => 0, 'INFO' => 1, 'NOTICE' => 2, 'WARNING' => 3, 'ERROR' => 4); + + /** + * Maps each handler with its log threshold. + * + * @protected + **/ + protected $mapping; + + /** + * Minimum log level + * + * @protected + **/ + protected $threshold_level; + + /** + * Path to log4Php library + * + * @protected + **/ + protected $log4PhpLibrary; + + /** + * Name of the logger + * + * @protected + **/ + protected $log4PhpLogger; + + /** + * Name of the business code + * + * @protected + **/ + protected $log4PhpBusinessCode; + + /** + * Path of the param of log4php + * + * @protected + **/ + protected $log4PhpConfigPath; + + /** + * Name of the batch + * + * @protected + **/ + protected $log4PhpBatchName; + + /** Class constructor + * + * Inits the threshold level + * + * @param $threshold_level (string) Threshold level (set to 'INFO' by default) + **/ + function __construct($threshold_level = 'WARNING') + { + $this->threshold_level = $threshold_level; + $this->mapping = array_fill(0, count($this->error_levels), array()); + } + + /** Writes error message in current handlers + * + * writes only if the error level is greater or equal the threshold level + * + * @param $msg (string) Error message + * @param $error_level (string) Error level (set to 'INFO' by default) + * @param $error_code (integer) Error code (set to 0 by default) + **/ + public function write($msg, $error_level = 'INFO', $error_code = 0, $other_params = array()) + { + if (!array_key_exists($error_level, $this->error_levels)) { + $error_level = 'INFO'; + } + $foundLogger = false; + if ($this->error_levels[$error_level] >= $this->error_levels[$this->threshold_level]) { + for ($i=$this->error_levels[$error_level];$i>=0;$i--) { + foreach ($this->mapping[$i] as $handler) { + $handler->write($msg, $error_level, $error_code, $other_params); + if ( + get_class($handler) == 'FileHandler' + && (isset($this->log4PhpLibrary) + && !empty($this->log4PhpLibrary)) + ) { + if ($error_code == 0) { + $result = 'OK'; + } else { + $result = 'KO'; + $msg = '%error_code:' . $error_code . '% ' . $msg; + } + require_once($this->log4PhpLibrary); + $remote_ip = '127.0.0.1'; + Logger::configure($this->log4PhpConfigPath); + $logger = Logger::getLogger($this->log4PhpLogger); + $searchPatterns = array('%ACCESS_METHOD%', + '%RESULT%', + '%BUSINESS_CODE%', + '%HOW%', + '%WHAT%', + '%REMOTE_IP%', + '%BATCH_NAME%' + ); + $replacePatterns = array('Script', + $result, + $this->log4PhpBusinessCode, + 'UP', + $msg, + $remote_ip, + $this->log4PhpBatchName + ); + $logLine = str_replace($searchPatterns, + $replacePatterns, + '[%ACCESS_METHOD%][%RESULT%]' + . '[%BUSINESS_CODE%][%HOW%][%WHAT%][%BATCH_NAME%]' + ); + $this->writeLog4php($logger, $logLine, $error_level); + } + } + } + } + } + + /** + * + * write a log entry with a specific log level + * @param object $logger Log4php logger + * @param string $logLine Line we want to trace + * @param enum $level Log level + */ + function writeLog4php($logger, $logLine, $level) { + switch ($level) { + case 'DEBUG': + $logger->debug($logLine); + break; + case 'INFO': + $logger->info($logLine); + break; + case 'WARNING': + $logger->warn($logLine); + break; + case 'ERROR': + $logger->error($logLine); + break; + case 'FATAL': + $logger->fatal($logLine); + break; + } + } + + /** Adds a new handler in the current handlers array + * + * @param $handler (object) Handler object + **/ + public function add_handler(&$handler, $error_level = NULL) + { + if(!isset($handler)) + return false; + + if(!isset($error_level) || !array_key_exists($error_level, $this->error_levels)) + { + $error_level = $this->threshold_level; + } + + $this->mapping[$this->error_levels[$error_level]][] = $handler; + return true; + } + + /** Adds a new handler in the current handlers array + * + * @param $handler (object) Handler object + **/ + public function change_handler_log_level(&$handler, $log_level ) + { + if (!isset($handler) || !isset($log_level)) + return false; + + if (!array_key_exists($log_level, $this->error_levels)) { + return false; + } + + for ($i=0; $i<count($this->mapping);$i++) { + for($j=0;$j<count($this->mapping[$i]);$j++) { + if($handler == $this->mapping[$i][$j]) { + unset($this->mapping[$i][$j]); + } + } + } + $this->mapping = array_values($this->mapping); + $this->mapping[$this->error_levels[$log_level]][] = $handler; + return true; + } + + /** Sets treshold level + * + * @param $treshold (string) treshold level + **/ + public function set_threshold_level($treshold) + { + if (isset($treshold) && array_key_exists($treshold, $this->error_levels)) { + $this->threshold_level = $treshold; + return true; + } + $this->threshold_level = 'WARNING'; + return false; + } + + /** Sets log4Php library path + * + * @param $log4PhpLibrary (string) path + **/ + public function set_log4PhpLibrary($log4PhpLibrary) + { + if (isset($log4PhpLibrary) && !empty($log4PhpLibrary)) { + if (file_exists($log4PhpLibrary)) { + $this->log4PhpLibrary = $log4PhpLibrary; + return true; + } else { + return false; + } + } + return false; + } + + /** Sets log4php logger name + * + * @param $log4PhpLogger (string) logger name + **/ + public function set_log4PhpLogger($log4PhpLogger) + { + if (isset($log4PhpLogger) && !empty($log4PhpLogger)) { + $this->log4PhpLogger = $log4PhpLogger; + return true; + } + $this->log4PhpLogger = 'loggerTechnique'; + return false; + } + + /** Sets log4php path to log4php xml config + * + * @param $log4PhpPath (string) path to log4php xml config + **/ + public function set_log4PhpConfigPath($log4PhpConfigPath) + { + if (isset($log4PhpConfigPath) && !empty($log4PhpConfigPath)) { + if (file_exists($log4PhpConfigPath)) { + $this->log4PhpConfigPath = $log4PhpConfigPath; + return true; + } else { + return false; + } + } + return false; + } + + /** Sets log4php business code + * + * @param $log4PhpBusinessCode (string) business code + **/ + public function set_log4PhpBusinessCode($log4PhpBusinessCode) + { + if (isset($log4PhpBusinessCode) && !empty($log4PhpBusinessCode)) { + $this->log4PhpBusinessCode = $log4PhpBusinessCode; + return true; + } + $this->log4PhpBusinessCode = 'Maarch'; + return false; + } + + /** Sets log4php batch name + * + * @param $log4PhpBatchName (string) BatchName + **/ + public function set_log4PhpBatchName($log4PhpBatchName) + { + if (isset($log4PhpBatchName) && !empty($log4PhpBatchName)) { + $this->log4PhpBatchName = $log4PhpBatchName; + return true; + } + $this->log4PhpBatchName = 'MaarchBatch'; + return false; + } + + /** Class destructor + * + * Calls handlers destructors + **/ + function __destruct() + { + for($i=0; $i<count($this->mapping);$i++) + { + foreach($this->mapping[$i] as $handler) + { + unset($handler); + } + } + } +} diff --git a/sendmail/trunk/batch/batch_tools.php b/sendmail/trunk/batch/batch_tools.php new file mode 100644 index 00000000000..f32ded8bd60 --- /dev/null +++ b/sendmail/trunk/batch/batch_tools.php @@ -0,0 +1,157 @@ +<?php + +/* + * Copyright 2008-2011 Maarch + * + * This file is part of Maarch Framework. + * + * Maarch Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Maarch Framework 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 + * along with Maarch Framework. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * @brief API to manage batchs + * + * @file + * @author Laurent Giovannoni <dev@maarch.org> + * @date $date$ + * @version $Revision$ + * @ingroup sendmail + */ + +/** + * Execute a sql query + * + * @param object $dbConn connection object to the database + * @param string $queryTxt path of the file to include + * @param boolean $transaction for rollback if error + * @return true if ok, exit if ko and rollback if necessary + */ +function Bt_doQuery($dbConn, $queryTxt, $transaction=false) +{ + $res = $dbConn->query($queryTxt, true); + if (!$res) { + if ($transaction) { + $GLOBALS['logger']->write('ROLLBACK', 'INFO'); + $dbConn->query('ROLLBACK', true); + } + Bt_exitBatch( + 104, 'SQL Query error:' . $queryTxt + ); + } + $GLOBALS['logger']->write('SQL query:' . $queryTxt, 'DEBUG'); + return true; +} + +/** + * Exit the batch with a return code, message in the log and + * in the database if necessary + * + * @param int $returnCode code to exit (if > O error) + * @param string $message message to the log and the DB + * @return nothing, exit the program + */ +function Bt_exitBatch($returnCode, $message='') +{ + if (file_exists($GLOBALS['lckFile'])) { + unlink($GLOBALS['lckFile']); + } + if ($returnCode > 0) { + $GLOBALS['totalProcessedResources']--; + if ($GLOBALS['totalProcessedResources'] == -1) { + $GLOBALS['totalProcessedResources'] = 0; + } + if($returnCode < 100) { + if (file_exists($GLOBALS['errorLckFile'])) { + unlink($GLOBALS['errorLckFile']); + } + $semaphore = fopen($GLOBALS['errorLckFile'], "a"); + fwrite($semaphore, '1'); + fclose($semaphore); + } + $GLOBALS['logger']->write($message, 'ERROR', $returnCode); + Bt_logInDataBase($GLOBALS['totalProcessedResources'], 1, 'return code:' + . $returnCode . ', ' . $message); + } elseif ($message <> '') { + $GLOBALS['logger']->write($message, 'INFO', $returnCode); + Bt_logInDataBase($GLOBALS['totalProcessedResources'], 0, 'return code:' + . $returnCode . ', ' . $message); + } + exit($returnCode); +} + +/** +* Insert in the database the report of the batch +* @param long $totalProcessed total of resources processed in the batch +* @param long $totalErrors total of errors in the batch +* @param string $info message in db +*/ +function Bt_logInDataBase($totalProcessed=0, $totalErrors=0, $info='') +{ + $query = "insert into history_batch (module_name, batch_id, event_date, " + . "total_processed, total_errors, info) values('" + . $GLOBALS['batchName'] . "', " . $GLOBALS['wb'] . ", " + . $GLOBALS['db']->current_datetime() . ", " . $totalProcessed . ", " . $totalErrors . ", '" + . $GLOBALS['func']->protect_string_db(substr(str_replace('\\', '\\\\', str_replace("'", "`", $info)), 0, 999)) . "')"; + //. $GLOBALS['func']->protect_string_db(substr($info, 0, 999)) . "')"; + Bt_doQuery($GLOBALS['db'], $query); +} + +/** + * Get the batch if of the batch + * + * @return nothing + */ +function Bt_getWorkBatch() +{ + $req = "select param_value_int from parameters where id = " + . "'". $GLOBALS['batchName'] . "_id'"; + $GLOBALS['db']->query($req); + while ($reqResult = $GLOBALS['db']->fetch_array()) { + $GLOBALS['wb'] = $reqResult[0] + 1; + } + if ($GLOBALS['wb'] == '') { + $req = "insert into parameters(id, param_value_int) values " + . "('" . $GLOBALS['batchName'] . "_id', 1)"; + $GLOBALS['db']->query($req); + $GLOBALS['wb'] = 1; + } +} + +/** + * Update the database with the new batch id of the batch + * + * @return nothing + */ +function Bt_updateWorkBatch() +{ + $req = "update parameters set param_value_int = " . $GLOBALS['wb'] . " " + . "where id = '" . $GLOBALS['batchName'] . "_id'"; + $GLOBALS['db']->query($req); +} + +/** + * Include the file requested if exists + * + * @param string $file path of the file to include + * @return nothing + */ +function Bt_myInclude($file) +{ + if (file_exists($file)) { + include_once ($file); + } else { + throw new IncludeFileError($file); + } +} + diff --git a/sendmail/trunk/batch/config/config.xml.default b/sendmail/trunk/batch/config/config.xml.default new file mode 100644 index 00000000000..c2f21e89dd1 --- /dev/null +++ b/sendmail/trunk/batch/config/config.xml.default @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<ROOT> + <CONFIG> + <Lang>fr</Lang> <!-- fr, en--> + <MaarchDirectory>C:\xampp\htdocs\maarch_entreprise\</MaarchDirectory> + <MaarchUrl>http://localhost/maarch_entreprise/</MaarchUrl> + <MaarchApps>maarch_entreprise</MaarchApps> + <TmpDirectory>C:\xampp\htdocs\maarch_entreprise\modules\sendmail\batch\tmp\</TmpDirectory> + <debugmode> + <dontflag_mail>true</dontflag_mail> + <verbose_mode>false</verbose_mode> + <simulate_sendmail>false</simulate_sendmail> + </debugmode> + <maxsize>5</maxsize> <!--In Mo: Taille maximum pour envoyer le courrier en pièce jointe afin d’éviter les erreurs du serveur mail--> + <maxitem>90</maxitem> <!-- Nombre de pièce jointe maximum à envoyer si transfert en pièce jointe--> + </CONFIG> + <COLLECTION> + <Id>letterbox_coll</Id> + <Table>res_letterbox</Table> + <VersionTable>res_version_letterbox</VersionTable> + <View>res_view_letterbox</View> + <Adr>adr_x</Adr> + <Extension>mlb_coll_ext</Extension> + </COLLECTION> + <COLLECTION> + <Id>business_coll</Id> + <Table>res_business</Table> + <VersionTable>res_version_business</VersionTable> + <View>res_view_business</View> + <Adr>adr_business</Adr> + <Extension>business_coll_ext</Extension> + </COLLECTION> + <CONFIG_BASE> + <databaseserver>127.0.0.1</databaseserver> + <databaseserverport>5432</databaseserverport> + <databasetype>POSTGRESQL</databasetype> + <databasename>maarch_entreprise</databasename> + <databaseuser>postgres</databaseuser> + <databasepassword>maarch</databasepassword> + </CONFIG_BASE> + <MAILER> + <path_to_mailer>\apps\maarch_entreprise\tools\mails\htmlMimeMail.php</path_to_mailer> + <path_to_phpmailer>PHPMailer_v5.1</path_to_phpmailer> + <type>smtp</type><!-- mail (default), smtp, sendmail, qmail --> + <smtp_host>smtp.yourdomain.com</smtp_host><!-- smtp1.example.com:25;smtp2.example.com --> + <smtp_port>25</smtp_port><!-- smtp1.example.com:25;smtp2.example.com --> + <smtp_user>notif@yourdomain.com</smtp_user> + <smtp_password></smtp_password> + <smtp_auth>true</smtp_auth> + <smtp_secure>tls</smtp_secure><!-- tls ou ssl --> + <charset>utf-8</charset><!-- Default : iso-8859-1 --> + <domains></domains><!-- Rewrite Recipient with config->adminmail if mailfrom and mailto is out of the domains --> + <x-mailer></x-mailer><!-- Rewrite X-Mailer header, default : PHP/[phpversion] --> + <mailfrom>notifications@maarch.fr</mailfrom> + </MAILER> + <LOG4PHP> + <enabled>false</enabled> + <Log4PhpLogger>loggerTechnique</Log4PhpLogger> + <Log4PhpBusinessCode>MaarchEntrepriseDemo</Log4PhpBusinessCode> + <Log4PhpConfigPath>/var/www/maarch_entreprise/apps/maarch_entreprise/xml/log4php.xml</Log4PhpConfigPath> + </LOG4PHP> +</ROOT> \ No newline at end of file diff --git a/sendmail/trunk/batch/load_process_emails.php b/sendmail/trunk/batch/load_process_emails.php new file mode 100644 index 00000000000..d68f7a4b4b1 --- /dev/null +++ b/sendmail/trunk/batch/load_process_emails.php @@ -0,0 +1,264 @@ +<?php + +/* + * Copyright 2008-2013 Maarch + * + * This file is part of Maarch Framework. + * + * Maarch Framework is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Maarch Framework 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 + * along with Maarch Framework. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * @brief process the sendmail table + * + * @file + * @author Cyril Vazquez <dev@maarch.org> + * @author Yves Christian Kpakpo <dev@maarch.org> + * @date $date$ + * @version $Revision$ + * @ingroup sendmail + */ + +/** +* @brief Class to include the file error +* +*/ +class IncludeFileError extends Exception +{ + public function __construct($file) + { + $this->file = $file; + parent :: __construct('Include File \'$file\' is missing!', 1); + } +} + +try { + include('Maarch_CLITools/ArgsParser.php'); + include('LoggerLog4php.php'); + include('Maarch_CLITools/FileHandler.php'); + include('Maarch_CLITools/ConsoleHandler.php'); +} catch (IncludeFileError $e) { + echo 'Maarch_CLITools required ! \n (pear.maarch.org)\n'; + exit(106); +} + +// Globals variables definition +$GLOBALS['batchName'] = 'sendmail'; +$GLOBALS['wb'] = ''; +$totalProcessedResources = 0; +$batchDirectory = ''; +$log4PhpEnabled = false; + +// Open Logger +$GLOBALS['logger'] = new Logger4Php(); +$GLOBALS['logger']->set_threshold_level('DEBUG'); + +$logFile = 'logs' . DIRECTORY_SEPARATOR . date('Y-m-d_H-i-s') . '.log'; + +$file = new FileHandler($logFile); +$GLOBALS['logger']->add_handler($file); + +// Load tools +include('batch_tools.php'); + +// Defines scripts arguments +$argsparser = new ArgsParser(); +// The config file +$argsparser->add_arg( + 'config', + array( + 'short' => 'c', + 'long' => 'config', + 'mandatory' => true, + 'help' => 'Config file path is mandatory.', + ) +); + +// Parsing script options +try { + $options = $argsparser->parse_args($GLOBALS['argv']); + // If option = help then options = false and the script continues ... + if ($options == false) { + exit(0); + } +} catch (MissingArgumentError $e) { + if ($e->arg_name == 'config') { + $GLOBALS['logger']->write('Configuration file missing', 'ERROR', 101); + exit(101); + } +} + +$txt = ''; +foreach (array_keys($options) as $key) { + if (isset($options[$key]) && $options[$key] == false) { + $txt .= $key . '=false,'; + } else { + $txt .= $key . '=' . $options[$key] . ','; + } +} +$GLOBALS['logger']->write($txt, 'DEBUG'); +$GLOBALS['configFile'] = $options['config']; +// Loading config file +$GLOBALS['logger']->write( + 'Load xml config file:' . $GLOBALS['configFile'], + 'INFO' +); +// Tests existence of config file +if (!file_exists($GLOBALS['configFile'])) { + $GLOBALS['logger']->write( + 'Configuration file ' . $GLOBALS['configFile'] + . ' does not exist', 'ERROR', 102 + ); + exit(102); +} + +$xmlconfig = simplexml_load_file($GLOBALS['configFile']); + +if ($xmlconfig == FALSE) { + $GLOBALS['logger']->write( + 'Error on loading config file:' + . $GLOBALS['configFile'], 'ERROR', 103 + ); + exit(103); +} + + +// Load config +$config = $xmlconfig->CONFIG; +$lang = (string)$config->Lang; +$GLOBALS['maarchDirectory'] = $_SESSION['config'] + ['corepath'] = (string)$config->MaarchDirectory; +$_SESSION['config']['app_id'] = (string) $config->MaarchApps; +$GLOBALS['TmpDirectory'] = $_SESSION['config'] + ['tmppath'] = (string)$config->TmpDirectory; +$GLOBALS['batchDirectory'] = $GLOBALS['maarchDirectory'] . 'modules' + . DIRECTORY_SEPARATOR . 'sendmail' + . DIRECTORY_SEPARATOR . 'batch'; + +set_include_path(get_include_path() . PATH_SEPARATOR . $GLOBALS['maarchDirectory']); + +//log4php params +$log4phpParams = $xmlconfig->LOG4PHP; +if ((string) $log4phpParams->enabled == 'true') { + $GLOBALS['logger']->set_log4PhpLibrary( + $GLOBALS['maarchDirectory'] . 'apps/maarch_entreprise/tools/log4php/Logger.php' + ); + $GLOBALS['logger']->set_log4PhpLogger((string) $log4phpParams->Log4PhpLogger); + $GLOBALS['logger']->set_log4PhpBusinessCode((string) $log4phpParams->Log4PhpBusinessCode); + $GLOBALS['logger']->set_log4PhpConfigPath((string) $log4phpParams->Log4PhpConfigPath); + $GLOBALS['logger']->set_log4PhpBatchName($GLOBALS['batchName']); +} + +// Mailer +$mailerParams = $xmlconfig->MAILER; +$path_to_mailer = (string)$mailerParams->path_to_mailer; + +//Charset +$GLOBALS['charset'] = (string)$mailerParams->charset; + +try { + Bt_myInclude( + $GLOBALS['maarchDirectory'] . 'core' . DIRECTORY_SEPARATOR . 'class' + . DIRECTORY_SEPARATOR . 'class_functions.php' + ); + Bt_myInclude( + $GLOBALS['maarchDirectory'] . 'core' . DIRECTORY_SEPARATOR . 'class' + . DIRECTORY_SEPARATOR . 'class_db.php' + ); + Bt_myInclude( + $GLOBALS['maarchDirectory'] . 'core' . DIRECTORY_SEPARATOR . 'class' + . DIRECTORY_SEPARATOR . 'class_core_tools.php' + ); + Bt_myInclude( + $GLOBALS['maarchDirectory'] . 'apps' . DIRECTORY_SEPARATOR . 'maarch_entreprise' + . DIRECTORY_SEPARATOR . 'class' . DIRECTORY_SEPARATOR . 'class_users.php' + ); + Bt_myInclude( + $GLOBALS['maarchDirectory'] . "modules" . DIRECTORY_SEPARATOR . "sendmail" + . DIRECTORY_SEPARATOR . "sendmail_tables.php" + ); + Bt_myInclude( + $GLOBALS['maarchDirectory'] . "modules" . DIRECTORY_SEPARATOR . "sendmail" + . DIRECTORY_SEPARATOR . "class". DIRECTORY_SEPARATOR . "class_modules_tools.php" + ); + Bt_myInclude( + $GLOBALS['maarchDirectory'] . $path_to_mailer + ); + +} catch (IncludeFileError $e) { + $GLOBALS['logger']->write( + 'Problem with the php include path:' .$e .' '. get_include_path(), + 'ERROR' + ); + exit(); +} + +// Controlers and objects +$dbConfig = $xmlconfig->CONFIG_BASE; +$_SESSION['config']['databaseserver'] = (string)$dbConfig->databaseserver; +$_SESSION['config']['databaseserverport'] = (string)$dbConfig->databaseserverport; +$_SESSION['config']['databaseuser'] = (string)$dbConfig->databaseuser; +$_SESSION['config']['databasepassword'] = (string)$dbConfig->databasepassword; +$_SESSION['config']['databasename'] = (string)$dbConfig->databasename; +$_SESSION['config']['databasetype'] = (string)$dbConfig->databasetype; + + $i = 0; +foreach ($xmlconfig->COLLECTION as $col) { + + $GLOBALS['collections'][$i] = array( + 'id' => (string) $col->Id, + 'table' => (string) $col->Table, + 'version_table' => (string) $col->VersionTable, + 'view' => (string) $col->View, + 'adr' => (string) $col->Adr, + 'extensions' => (string) $col->Extension + ); + $i++; +} + +$coreTools = new core_tools(); +$coreTools->load_lang($lang, $GLOBALS['maarchDirectory'], $_SESSION['config']['app_id']); + +$sendmail_tools = new sendmail(); +$users = new class_users(); +$GLOBALS['func'] = new functions(); + +$GLOBALS['db'] = new dbquery($GLOBALS['configFile']); +$GLOBALS['db']->connect(); + +$GLOBALS['errorLckFile'] = $GLOBALS['batchDirectory'] . DIRECTORY_SEPARATOR + . $GLOBALS['batchName'] .'_error.lck'; +$GLOBALS['lckFile'] = $GLOBALS['batchDirectory'] . DIRECTORY_SEPARATOR + . $GLOBALS['batchName'] . '.lck'; + +if (file_exists($GLOBALS['errorLckFile'])) { + $GLOBALS['logger']->write( + 'Error persists, please solve this before launching a new batch', + 'ERROR', 13 + ); + exit(13); +} + +/*if (file_exists($GLOBALS['lckFile'])) { + $GLOBALS['logger']->write( + 'An instance of the batch is already in progress', + 'ERROR', 109 + ); + exit(109); +} +$semaphore = fopen($GLOBALS['lckFile'], 'a'); +fwrite($semaphore, '1'); +fclose($semaphore);*/ + +Bt_getWorkBatch(); diff --git a/sendmail/trunk/batch/process_emails.php b/sendmail/trunk/batch/process_emails.php new file mode 100644 index 00000000000..f46260e43cb --- /dev/null +++ b/sendmail/trunk/batch/process_emails.php @@ -0,0 +1,184 @@ +<?php + +/******************************************************************************/ + +// load the config and prepare to process +include('load_process_emails.php'); + +/* begin */ +$state = 'LOAD_EMAILS'; +while ($state <> 'END') { + if (isset($GLOBALS['logger'])) { + $GLOBALS['logger']->write('STATE:' . $state, 'INFO'); + } + switch ($state) { + + /**********************************************************************/ + /* LOAD_EMAILS */ + /* List the records to proceed */ + /**********************************************************************/ + case 'LOAD_EMAILS' : + $query = "SELECT * FROM " . EMAILS_TABLE + . " WHERE email_status = 'W' and send_date is NULL"; + Bt_doQuery($GLOBALS['db'], $query); + $totalEmailsToProcess = $GLOBALS['db']->nb_result(); + $currentEmail = 0; + if ($totalEmailsToProcess === 0) { + Bt_exitBatch(0, 'No e-mails to process'); + } + $GLOBALS['logger']->write($totalEmailsToProcess . ' e-mails to proceed.', 'INFO'); + $GLOBALS['emails'] = array(); + while ($emailRecordset = $GLOBALS['db']->fetch_object()) { + $GLOBALS['emails'][] = $emailRecordset; + } + $state = 'SEND_AN_EMAIL'; + break; + + /**********************************************************************/ + /* SEND_AN_EMAIL */ + /* Load parameters and send an e-mail */ + /**********************************************************************/ + case 'SEND_AN_EMAIL' : + if($currentEmail < $totalEmailsToProcess) { + $email = $GLOBALS['emails'][$currentEmail]; + $GLOBALS['mailer'] = new htmlMimeMail(); + if($mailerParams->smtp_auth === "true") $smtp_auth = true; + $GLOBALS['mailer']->setSMTPParams( + $host = (string)$mailerParams->smtp_host, + $port = (string)$mailerParams->smtp_port, + $helo = (string)$mailerParams->domains, + $auth = $smtp_auth, + $user = (string)$mailerParams->smtp_user, + $pass = (string)$mailerParams->smtp_password + ); + //Composing email + //--> Set from + $userInfo = $users->get_user($email->user_id); + $GLOBALS['logger']->write("Sending e-mail from : " + . '"' . $userInfo['firstname'].' ' .$userInfo['lastname'] + . '" <'.$userInfo['mail'].'>', 'INFO'); + + $GLOBALS['mailer']->setFrom('"'.$userInfo['firstname'].' ' + . $userInfo['lastname'].' ('.$userInfo['mail'].')" <'.$user.'> '); + + // + $GLOBALS['logger']->write("Sending e-mail to : " . $email->to_list, 'INFO'); + if (!empty($email->cc_list))$GLOBALS['logger']->write("Copy e-mail to : " . $email->cc_list, 'INFO'); + if (!empty($email->cci_list))$GLOBALS['logger']->write("Copy invisible e-mail to : " . $email->cci_list, 'INFO'); + + //--> Set the return path + $GLOBALS['mailer']->setReturnPath($userInfo['mail']); + //--> To + $to = array(); + $to = explode(',', $email->to_list); + //--> Cc + if (!empty($email->cc_list)) { + $GLOBALS['mailer']->setCc($email->cc_list); + } + //--> Cci + if (!empty($email->cci_list)) { + $GLOBALS['mailer']->setBcc($email->cci_list); + } + //--> Set subject + $GLOBALS['logger']->write("Subject : " . $email->email_object, 'INFO'); + $GLOBALS['mailer']->setSubject($email->email_object); + //--> Set body: Is Html/raw text ? + if ($email->is_html == 'Y') { + $GLOBALS['mailer']->setHtml($email->email_body); + } else { + $GLOBALS['mailer']->setText($email->email_body); + } + //--> Set charset + $GLOBALS['mailer']->setTextCharset($GLOBALS['charset']); + $GLOBALS['mailer']->setHtmlCharset($GLOBALS['charset']); + $GLOBALS['mailer']->setHeadCharset($GLOBALS['charset']); + + //--> Set attachments + //Res master + if ($email->is_res_master_attached == 'Y') { + $GLOBALS['logger']->write("Set attachment on res master : " . $email->res_id, 'INFO'); + + //Get file from docserver + $resFile = $sendmail_tools->getResource($GLOBALS['collections'], $email->coll_id, $email->res_id); + //Get file content + if(is_file($resFile['file_path'])) { + //Filename + $resFilename = $sendmail_tools->createFilename($resFile['label'], $resFile['ext']); + $GLOBALS['logger']->write("Set attachment filename : " . $resFilename, 'INFO'); + + //File content + $file_content = $GLOBALS['mailer']->getFile($resFile['file_path']); + //Add file + $GLOBALS['mailer']->addAttachment($file_content, $resFilename, $resFile['mime_type']); + } + } + + //Res attachment + if (!empty($email->res_attachment_id_list)) { + $attachments = explode(',', $email->res_attachment_id_list); + foreach($attachments as $attachment_id) { + $GLOBALS['logger']->write("Set attachment on res attachment : " . $attachment_id, 'INFO'); + $attachmentFile = $sendmail_tools->getAttachment( + $email->coll_id, + $email->res_id, + $attachment_id + ); + if(is_file($attachmentFile['file_path'])) { + //Filename + $attachmentFilename = $sendmail_tools->createFilename($attachmentFile['label'], $attachmentFile['ext']); + $GLOBALS['logger']->write("Set attachment filename : " . $attachmentFilename, 'INFO'); + + //File content + $file_content = $GLOBALS['mailer']->getFile($attachmentFile['file_path']); + //Add file + $GLOBALS['mailer']->addAttachment($file_content, $attachmentFilename, $attachmentFile['mime_type']); + } + } + } + + //Notes + if (!empty($email->note_id_list)) { + $notes = explode(',', $email->note_id_list); + $noteFile = $sendmail_tools->createNotesFile($email->coll_id, $email->res_id, $notes); + if(is_file($noteFile['file_path'])) { + //File content + $file_content = $GLOBALS['mailer']->getFile($noteFile['file_path']); + //Add file + $GLOBALS['mailer']->addAttachment($file_content, $noteFile['filename'], $noteFile['mime_type']); + } + } + + //Now send the mail + $return = $GLOBALS['mailer']->send($to, (string)$mailerParams->type); + + if($return || $return == 0) { + $exec_result = 'S'; + } else { + $GLOBALS['logger']->write("Errors when sending message through SMTP :" + . implode(', ', $GLOBALS['mailer']->errors), 'ERROR'); + $exec_result = 'E'; + } + //Update emails table + $query = "UPDATE " . EMAILS_TABLE + . " SET send_date = " . $GLOBALS['db']->current_datetime() + . ", email_status = '".$exec_result."' " + . " WHERE email_id = ".$email->email_id; + $GLOBALS['db']->connect(); + Bt_doQuery($GLOBALS['db'], $query); + $currentEmail++; + $state = 'SEND_AN_EMAIL'; + } else { + $state = 'END'; + } + break; + } +} + +$GLOBALS['logger']->write('End of process', 'INFO'); +Bt_logInDataBase( + $totalEmailsToProcess, 0, 'process without error' +); +$GLOBALS['db']->disconnect(); +//unlink($GLOBALS['lckFile']); +exit($GLOBALS['exitCode']); +?> diff --git a/sendmail/trunk/batch/scripts/sendmail.bat b/sendmail/trunk/batch/scripts/sendmail.bat new file mode 100644 index 00000000000..521ac5fc3b2 --- /dev/null +++ b/sendmail/trunk/batch/scripts/sendmail.bat @@ -0,0 +1 @@ +"C:\xampp\php\php.exe" "C:\xampp\htdocs\maarch_entreprise\modules\sendmail\batch\process_emails.php" -c "C:\xampp\htdocs\maarch_entreprise\modules\sendmail\batch\config\config.xml" \ No newline at end of file diff --git a/sendmail/trunk/batch/scripts/sendmail.sh b/sendmail/trunk/batch/scripts/sendmail.sh new file mode 100644 index 00000000000..f6491ff5ddc --- /dev/null +++ b/sendmail/trunk/batch/scripts/sendmail.sh @@ -0,0 +1,5 @@ +#!/bin/sh +cd /var/www/maarch_entreprise/modules/sendmail/batch/ +emailsPath='/var/www/maarch_entreprise/modules/sendmail/batch/process_emails.php' +php $emailsPath -c /var/www/maarch_entreprise/modules/sendmail/batch/config/config.xml + diff --git a/sendmail/trunk/class/class_modules_tools.php b/sendmail/trunk/class/class_modules_tools.php index 31e7af0b07b..23c2edc19c9 100644 --- a/sendmail/trunk/class/class_modules_tools.php +++ b/sendmail/trunk/class/class_modules_tools.php @@ -188,10 +188,10 @@ class sendmail extends dbquery public function rawToHtml($text) { //... - $text = str_replace("\r\n", "\n", $text); - $text = str_replace("\r", "\n", $text); + // $text = str_replace("\r\n", "\n", $text); + // $text = str_replace("\r", "\n", $text); // - $text = str_replace("\n", "<br />", $text); + // $text = str_replace("\n", "<br />", $text); // return $text; } @@ -201,10 +201,28 @@ class sendmail extends dbquery $text = str_replace("<br>", "\n", $text); $text = str_replace("<br/>", "\n", $text); $text = str_replace("<br />", "\n", $text); + $text = strip_tags($text); // return $text; } + public function cleanHtml($htmlContent){ + + $htmlContent = str_replace(';', '###', $htmlContent); + $htmlContent = str_replace('--', '___', $htmlContent); + + $allowedTags = '<html><head><body><title>'; //Structure + $allowedTags .= '<h1><h2><h3><h4><h5><h6><b><i><tt><u><strike><blockquote><pre><blink><font><big><small><sup><sub><strong><em>'; // Text formatting + $allowedTags .='<p><br><hr><center><div><span>'; // Text position + $allowedTags .= '<li><ol><ul><dl><dt><dd>'; // Lists + $allowedTags .= '<img><a>'; // Multimedia + $allowedTags .= '<table><tr><td><th><tbody><thead><tfooter><caption>'; // Tables + $allowedTags .= '<form><input><textarea><select>'; // Forms + $htmlContent = strip_tags($htmlContent, $allowedTags); + + return $htmlContent; + } + public function getEmail($id, $owner=true) { $email = array(); if (!empty($id)) { @@ -247,7 +265,9 @@ class sendmail extends dbquery $email['notes'] = explode(',', $res->note_id_list); } $email['object'] = $this->show_string($res->email_object); - $email['body'] = $this->show_string($res->email_body); + $body = str_replace('###', ';', $res->email_body); + $body = str_replace('___', '--', $body); + $email['body'] = $this->show_string($body); $email['resMasterAttached'] = $res->is_res_master_attached; $email['isHtml'] = $res->is_html; $email['status'] = $res->email_status; @@ -344,7 +364,7 @@ class sendmail extends dbquery //$viewResourceArr['status'] /ko /ok //$viewResourceArr['error'] - $this->show_array($viewResourceArr); + // $this->show_array($viewResourceArr); } return $viewResourceArr; @@ -438,7 +458,7 @@ class sendmail extends dbquery ); } - $this->show_array($viewAttachmentArr); + // $this->show_array($viewAttachmentArr); return $viewAttachmentArr; } @@ -460,49 +480,90 @@ class sendmail extends dbquery $db->connect(); if (count($notesArray) > 0) { - /* - for($i=0; $i < count($notesArray); $i++) { - $note_id = $notesArray[$i]; - $db->query(""select n.date_note, n.note_text, u.lastname, " - . "u.firstname from " . NOTES_TABLE . " n inner join ". USERS_TABLE - . " u on n.user_id = u.user_id where n.id = " . $note_id ." and identifier = " . $id - . " and coll_id ='" . $coll_id . "' order by date_note desc"); - - if($db->nb_result() > 0) { - - $line = $db->fetch_object(); + //Format + $format = 'html'; + //Mime type + $mimeType = 'text/html'; + //Filename + $fileName = "notes_".date(dmY_Hi).".".$format; + //File path + $fileNameOnTmp = 'tmp_file_' . rand() + . '.' . strtolower($format); + $filePathOnTmp = $_SESSION['config'] + ['tmppath'] . DIRECTORY_SEPARATOR + . $fileNameOnTmp; + + //Create file + if (file_exists($filePathOnTmp)) { + unlink($filePathOnTmp); + } + + //File content + $content = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ' + . '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >'; + $content .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">'; + $content .= "<head><title>Maarch Notes</title><meta http-equiv='Content-Type' " + . "content='text/html; charset=UTF-8' /><meta content='fr' " + . "http-equiv='Content-Language'/><meta http-equiv='cache-control' " + . "content='no-cache'/><meta http-equiv='pragma' content='no-cache'>" + . "<meta http-equiv='Expires' content='0'></head>"; + $content .= "<body onload='javascript:window.print();' style='font-size:8pt'>"; + $content .= "<h2>"._NOTES."</h2>"; + $content .= "<table cellpadding='4' cellspacing='0' border='1' width='100%'>"; + + for($i=0; $i < count($notesArray); $i++) { + $db->query("select n.date_note, n.note_text, u.lastname, " + . "u.firstname from " . NOTES_TABLE . " n inner join ". USERS_TABLE + . " u on n.user_id = u.user_id where n.id = " . $notesArray[$i] ." and identifier = " . $id + . " and coll_id ='" . $coll_id . "' order by date_note desc"); - $user = $db->show_string($line->lastname . " " . $line->firstname); - $notes = $db->show_string($line->note_text); - $date = $line->date_note; - - //create file - } + if($db->nb_result() > 0) { + + $line = $db->fetch_object(); + + $user = $db->show_string($line->firstname . " " . $line->lastname); + $notes = $db->show_string($line->note_text); + $date = $db->dateformat($line->date_note); + $content .= "<tr height='130px'>"; + $content .= "<td width='15%'>"; + $content .= "<h3>"._USER.": ". $user."</h3>"; + $content .= "<h3>"._DATE.": ". $date."</h3>"; + $content .= "</td>"; + $content .= "<td width='85%'>"; + $content .= $notes; + $content .= "</td>"; + $content .= "</tr>"; } - */ - $format = 'html'; - $name = "notes_".$id."_".date(dmY).".".$format; + } + + $content .= "</table>"; + $content .= "</body></html>"; + //Write file + $inF = fopen($filePathOnTmp,"w"); + fwrite($inF, $content); + fclose($inF); $viewAttachmentArr = array( - 'status' => 'ok', - 'label' => '', - 'mime_type' => $mimeType, - 'ext' => $format, - 'file_content' => '', - 'tmp_path' => $_SESSION['config'] - ['tmppath'], - 'file_path' => $filePathOnTmp, - 'filename' => $name, - 'called_by_ws' => '', - 'error' => '' - ); - + 'status' => 'ok', + 'label' => '', + 'mime_type' => $mimeType, + 'ext' => $format, + 'file_content' => '', + 'tmp_path' => $_SESSION['config'] + ['tmppath'], + 'file_path' => $filePathOnTmp, + 'filename' => $fileName, + 'called_by_ws' => '', + 'error' => '' + ); + + // $this->show_array($viewAttachmentArr); + return $viewAttachmentArr; } else { return false; } - } } diff --git a/sendmail/trunk/js/functions.js b/sendmail/trunk/js/functions.js index 7ddee26814f..226afefaa58 100644 --- a/sendmail/trunk/js/functions.js +++ b/sendmail/trunk/js/functions.js @@ -78,11 +78,14 @@ function updateAdress(path, action, adress, target, array_index, email_format_te function validEmailForm (path, form_id) { // var bodyContent = getBodyConten(); - + // var content = tinyMCE.get('body_from_html').getContent(); // + // alert(content); + tinyMCE.triggerSave(); new Ajax.Request(path, { asynchronous:false, method:'post', + // parameters: Form.serialize(form_id)+ '&body_from_html=' + content, parameters: Form.serialize(form_id), encoding: 'UTF-8', onSuccess: function(answer){ diff --git a/sendmail/trunk/mail_form.php b/sendmail/trunk/mail_form.php index 0ea1827bbba..6d7c109c8c4 100644 --- a/sendmail/trunk/mail_form.php +++ b/sendmail/trunk/mail_form.php @@ -279,7 +279,7 @@ if ($mode == 'add') { //raw text arera $content .='<div id="raw_mode" style="display:'.$displayRaw.'">'; $content .= '<textarea name="body_from_raw" id="body_from_raw" class="emailInput" cols="60" rows="15">' - ._DEFAULT_BODY.$all_joined_files.'</textarea>'; + ._DEFAULT_BODY.$sendmail_tools->htmlToRaw($all_joined_files).'</textarea>'; $content .='</div>'; //Buttons diff --git a/sendmail/trunk/sendmail_ajax_content.php b/sendmail/trunk/sendmail_ajax_content.php index 63e401e9687..fc146852feb 100644 --- a/sendmail/trunk/sendmail_ajax_content.php +++ b/sendmail/trunk/sendmail_ajax_content.php @@ -169,7 +169,7 @@ switch ($mode) { } else { if (isset($_SESSION['adresses']['to']) && count($_SESSION['adresses']['to']) > 0 ) { if (!empty($_REQUEST['object'])) { - // print_r($_REQUEST); + // print_r($_REQUEST);exit; //Check adress for to $to = join(',', $_SESSION['adresses']['to']); @@ -211,7 +211,7 @@ switch ($mode) { (!empty($_REQUEST['is_html']) && $_REQUEST['is_html'] == 'Y')? $isHtml = 'Y' : $isHtml = 'N'; //Body content if ($isHtml == 'Y') { - $body = $request->protect_string_db($_REQUEST['body_from_html']); + $body = $request->protect_string_db($sendmail_tools->cleanHtml($_REQUEST['body_from_html'])); } else { $body = $request->protect_string_db($_REQUEST['body_from_raw']); } @@ -293,7 +293,7 @@ switch ($mode) { } else { if (isset($_SESSION['adresses']['to']) && count($_SESSION['adresses']['to']) > 0 ) { if (!empty($_REQUEST['object'])) { - // print_r($_REQUEST); + // print_r($_REQUEST);exit; //Check adress for to $to = join(',', $_SESSION['adresses']['to']); @@ -335,7 +335,7 @@ switch ($mode) { (!empty($_REQUEST['is_html']) && $_REQUEST['is_html'] == 'Y')? $isHtml = 'Y' : $isHtml = 'N'; //Body content if ($isHtml == 'Y') { - $body = $request->protect_string_db($_REQUEST['body_from_html']); + $body = $request->protect_string_db($sendmail_tools->cleanHtml($_REQUEST['body_from_html'])); } else { $body = $request->protect_string_db($_REQUEST['body_from_raw']); } -- GitLab