#!/usr/bin/php -q
<?php
/**
 * Copyright (c) 2002-2006 Aurlien Maille
 * 
 * This file is part of Wanewsletter.
 * 
 * Wanewsletter 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 2 
 * of the License, or (at your option) any later version.
 * 
 * Wanewsletter 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 Wanewsletter; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * 
 * @package Wanewsletter
 * @author  Bobe <wascripts@phpcodeur.net>
 * @link    http://phpcodeur.net/wascripts/wanewsletter/
 * @license http://www.gnu.org/copyleft/gpl.html  GNU General Public License
 * @version $Id: wanewsletter 508 2010-11-05 20:21:21Z bobe $
 * 
 * @status experimental
 * 
 * Ce module est marqu comme exprimental car son intgration dans Wanewsletter
 * n'est pas considre comme tant satisfaisante, cependant, tous les tests
 * effectus ont t satisfaisant et la partie permettant les envois d'emails
 * notamment est considre comme tant utilisable en "production".
 */

define('IN_NEWSLETTER',  true);
define('IN_COMMANDLINE', true);
define('ANSI_TERMINAL',  true);
define('WA_ROOTDIR',     dirname(dirname(__FILE__)));

//
// PHP CLI ne change pas le rpertoire courant pour celui du script
//
if( php_sapi_name() != 'cli' )
{
	//
	// PHP en mode CGI ne rend pas disponible directement les variables
	// $argv et $argc si register_globals est sur Off
	//
	$argv = $_SERVER['argv'];
	$argc = $_SERVER['argc'];
}

if( preg_match('/\.UTF-?8/i', getenv('LANG')) ) // Au cas o le terminal utilise l'encodage utf-8
{
	function convert_output($data)
	{
		return wan_utf8_encode($data);
	}
	
	ob_start('convert_output', 1);
}

require WA_ROOTDIR . '/start.php';

load_settings();

$argv[0]  = basename($argv[0]);
$version  = WA_VERSION;
$emails   = array();
$format   = FORMAT_TEXTE;
$liste_id = null;
$message  = null;
$process_send = $process_subscribe = $import_mail = false;
$send_packet  = 400;
$send_delay   = 10;

if( $argc == 1 ) // Aucun argument fourni
{
	echo "Usage: $argv[0] [OPTION]...\n";
	echo "Pour en savoir davantage, faites:  $argv[0] --help .\n";
	exit(0);
}

//
// En mode un email par abonn, on envoit tous les emails par dfaut (avec une pause
//  intervalle rgulier (voir plus haut)).
//
if( $nl_config['engine_send'] == ENGINE_UNIQ )
{
	$nl_config['emails_sended'] = 0;
}

for( $i = 1; $i < $argc; $i++ )
{
	//
	// Version du script et de PHP et SAPI utilis
	//
	if( $argv[$i] == '--version' || $argv[$i] == '-v' )
	{
		echo "Wanewsletter $version with PHP " . phpversion() . " (" . php_sapi_name() . ")\n";
		exit(0);
	}
	
	//
	// Licence de Wanewsletter
	//
	else if( $argv[$i] == '--license' )
	{
		echo "Wanewsletter $version\n";
		echo "Copyright (c) 2002-2006 Aurlien Maille\n";
		echo "\n";
		
		if( preg_match('/^fr[_-]/', getenv('LANG')) )
		{
			echo <<<WANSHELL
Wanewsletter est un logiciel libre; vous pouvez le redistribuer ou le
modifier selon les termes de la License Publique Gnrale de GNU, publie
par la Free Software Foundation; soit la version 2 de la Licence ou,
soit (selon vos prfrences) toute version ultrieure.

Wanewsletter est distribu dans l'espoir qu'il soit utile,
mais AUCUNE garantie n'est donne tant pour des raisons COMMERCIALES que
pour RPONDRE  UN BESOIN PARTICULIER.  Consultez la Licence
Publique Gnrale de GNU pour plus de dtails.

Vous devriez avoir reu copie de la Licence Publique Gnrale de GNU
avec Wanewsletter; sinon, crivez  la Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


WANSHELL;
		}
		else
		{
			echo <<<WANSHELL
Wanewsletter 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 2
of the License, or (at your option) any later version.

Wanewsletter 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 Wanewsletter; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


WANSHELL;
		}
		
		exit(0);
	}
	
	//
	// Aide succinte d'utilisation en ligne de commande
	//
	else if( $argv[$i] == '--help' || $argv[$i] == '-h' )
	{
		echo <<<WANSHELL
Usage: $argv[0] [options]

Envois:
  -pNUM, --process-send=NUM  Lance un envoi avec NUM un id de liste
  -lNUM, --limit=NUM   Limite  NUM le nombre d'emails envoys
  -kNUM, --packet=NUM  Nombre d'envois maximum par flot (par dfaut, 400)
  -dNUM, --delay=NUM   Dure en secondes entre les flots d'envois
                       (par dfaut, 10).

Divers:
  --process-subscribe=NUM  Validation des inscriptions par email
  --import-mail=NUM        Importation d'emails avec NUM un id de liste
  --format=FORMAT          FORMAT peut prendre la valeur 'plain' ou 'html'
                           'text' et 'texte' sont accepts comme
                           alternative  'plain'.

Informations:
  -h, --help     Affiche la prsente aide
  -v, --version  Affiche les informations de version
      --license  Affiche les informations de licence

Exemple d'importation d'emails :
  $argv[0] --import-mail=1 -- address1@domain.tld address2@domain.tld
  
La liste d'adresses peut galement tre fournie en entre, les adresses
dans le fichier tant spares par des caractres blancs (espace, tabulation
ou saut de ligne) :
  $argv[0] --import-mail=1 < /path/to/address_list


WANSHELL;
		exit(0);
	}
	
	//
	// Lancement d'un flt d'envoi
	//
	else if( preg_match('/^-(?:-process-send=|p)(\d+)$/', $argv[$i], $match) )
	{
		$process_send = true;
		$liste_id = $match[1];
	}
	
	//
	// Validation des inscriptions par email
	//
	else if( preg_match('/^--process-subscribe=(\d+)$/', $argv[$i], $match) )
	{
		$process_subscribe = true;
		$liste_id = $match[1];
	}
	
	//
	// Limitation du nombre d'envois
	//
	else if( preg_match('/^-(?:-limit=|l)(\d+)$/', $argv[$i], $match) )
	{
		$nl_config['emails_sended'] = $match[1];
	}
	
	//
	// Nombre d'envois maximum  effectuer lors d'un flot d'envois
	//
	else if( preg_match('/^-(?:-packet=|k)(\d+)$/', $argv[$i], $match) )
	{
		$send_packet = $match[1];
	}
	
	//
	// Nombre d'envois maximum  effectuer lors d'un flot d'envois
	//
	else if( preg_match('/^-(?:-delay=|d)(\d+)$/', $argv[$i], $match) )
	{
		$send_delay = $match[1];
	}
	
	else if( preg_match('/^--import-mail=(\d+)$/', $argv[$i], $match) )
	{
		$import_mail = true;
		$liste_id = $match[1];
	}
	
	//
	// Format choisi pour les comptes des adresses emails importes
	//
	else if( preg_match('/^--format=/', $argv[$i], $match) )
	{
		$format = substr($argv[$i], 9);
		
		if( in_array($format, array('plain', 'text', 'texte')) )
		{
			$format = FORMAT_TEXTE;
		}
		else if( $format == 'html' )
		{
			$format = FORMAT_HTML;
		}
		else
		{
			trigger_error("Bad format. Possible values are 'plain', 'text', 'texte' or 'html'", CRITICAL_ERROR);
		}
	}
	
	//
	// Rcupration des adresses email passes dans la ligne de commande
	//
	else if( $argv[$i] == '--' )
	{
		if( isset($argv[++$i]) )
		{
			$emails = array_slice($argv, $i);
		}
	}
}

if( !is_null($liste_id) )
{
	$sql = 'SELECT liste_id, liste_format, sender_email, liste_alias, limitevalidate,
			liste_name, form_url, return_email, liste_sig, use_cron, confirm_subscribe,
			pop_host, pop_port, pop_user, pop_pass
		FROM ' . LISTE_TABLE . ' 
		WHERE liste_id = ' . $liste_id;
	if( !($result = $db->query($sql)) )
	{
		trigger_error('Impossible de rcuprer les informations sur cette liste', CRITICAL_ERROR);
	}
	
	if( !($listdata = $result->fetch()) )
	{
		trigger_error('Unknown_list', CRITICAL_ERROR);
	}
}

if( $process_send == true )
{
	define('SEND_PACKET', $send_packet);
	define('SEND_DELAY',  $send_delay);
	
	require WA_ROOTDIR . '/includes/engine_send.php';
	
	$sql = "SELECT log_id, log_subject, log_body_text, log_body_html, log_status
		FROM " . LOG_TABLE . "
		WHERE liste_id = $listdata[liste_id]
			AND log_status = " . STATUS_STANDBY . "
		LIMIT 1 OFFSET 0";
	if( !($result = $db->query($sql)) ) // on rcupre le dernier log en statut d'envoi
	{
		trigger_error('Impossible d\'obtenir les donnes sur ce log', CRITICAL_ERROR);
	}
	
	if( !($logdata = $result->fetch()) )
	{
		echo $lang['Message']['No_log_to_send'] . "\n";
		exit(0);
	}
	
	$sql = "SELECT jf.file_id, jf.file_real_name, jf.file_physical_name, jf.file_size, jf.file_mimetype
		FROM " . JOINED_FILES_TABLE . " AS jf
			INNER JOIN " . LOG_FILES_TABLE . " AS lf ON lf.file_id = jf.file_id
			INNER JOIN " . LOG_TABLE . " AS l ON l.log_id = lf.log_id
				AND l.liste_id = $listdata[liste_id]
				AND l.log_id   = $logdata[log_id]
		ORDER BY jf.file_real_name ASC";
	if( !($result = $db->query($sql)) )
	{
		trigger_error('Impossible d\'obtenir la liste des fichiers joints', CRITICAL_ERROR);
	}
	
	$logdata['joined_files'] = $result->fetchAll();
	
	//
	// On lance l'envoi
	//
	$message = launch_sending($listdata, $logdata);
	
	echo "\n";
}
else if( $process_subscribe )
{
	require WAMAILER_DIR . '/class.mailer.php';
	require WAMAILER_DIR . '/class.pop.php';
	require WA_ROOTDIR . '/includes/class.form.php';
	require WA_ROOTDIR . '/includes/functions.validate.php';
	include WA_ROOTDIR . '/includes/functions.stats.php';
	
	//
	// Initialisation de la classe mailer
	//
	$mailer = new Mailer(WA_ROOTDIR . '/language/email_' . $nl_config['language'] . '/');
	
	if( $nl_config['use_smtp'] )
	{
		$mailer->smtp_path = WAMAILER_DIR . '/';
		$mailer->use_smtp(
			$nl_config['smtp_host'],
			$nl_config['smtp_port'],
			$nl_config['smtp_user'],
			$nl_config['smtp_pass']
		);
	}
	
	$mailer->set_charset($lang['CHARSET']);
	$mailer->set_format(FORMAT_TEXTE);
	$mailer->set_from($listdata['sender_email'], unhtmlspecialchars($listdata['liste_name']));
	
	if( $listdata['return_email'] != '' )
	{
		$mailer->set_return_path($listdata['return_email']);
	}
	
	$wan = new Wanewsletter($listdata);
	$pop = new Pop();
	$pop->connect($listdata['pop_host'], $listdata['pop_port'], $listdata['pop_user'], $listdata['pop_pass']);
	
	$total    = $pop->stat_box();
	$mail_box = $pop->list_mail();
	
	foreach( $mail_box as $mail_id => $mail_size )
	{
		$headers = $pop->parse_headers($mail_id);
		
		if( !isset($headers['from']) || !preg_match('/^(?:"?([^"]*?)"?)?[ ]*(?:<)?([^> ]+)(?:>)?$/i', $headers['from'], $match) )
		{
			continue;
		}
		
		$pseudo = ( isset($match[1]) ) ? strip_tags(trim($match[1])) : '';
		$email  = trim($match[2]);
		
		if( !isset($headers['to']) || !stristr($headers['to'], $wan->liste_email) )
		{
			continue;
		}
		
		if( !isset($headers['subject']) )
		{
			continue;
		}
		
		$action = strtolower(trim($headers['subject']));
		
		switch( $action )
		{
			case 'desinscription':
			case 'dsinscription':
			case 'unsubscribe':
				$action = 'desinscription';
				break;
			
			case 'inscription':
			case 'subscribe':
				$action = 'inscription';
				break;
			
			case 'confirmation':
			case 'setformat':
				break;
			
			default:
				$pop->delete_mail($mail_id);
				continue 2;
				break;
		}
		
		$code = $pop->contents[$mail_id]['message'];
		if( strlen($code) == 32 ) // Compatibilit avec versions < 2.3
		{
			$code = substr($code, 0, 20);
		}
		
		if( $action == 'inscription' || $action == 'setformat' || ($action == 'desinscription' && empty($code)) )
		{
			$wan->do_action($action, $email);
		}
		else
		{
			if( empty($headers['date']) || intval($time = strtotime($headers['date'])) > 0 )
			{
				$time = time();
			}
			
			$wan->check_code($code, $time);
		}
		
		//
		// On supprime l'email maintenant devenu inutile
		//
		$pop->delete_mail($mail_id);
	}//end for
	
	$pop->quit();
	
	$message = $lang['Message']['Success_operation'];
}
else if( $import_mail == true )
{
	require WAMAILER_DIR . '/class.mailer.php';
	
	if( count($emails) == 0 )
	{
		$emails = '';
		while( !feof(STDIN) )
		{
			$emails .= fgets(STDIN);
		}
		
		$emails = preg_split('/\s+/', trim($emails));
	}
	
	if( count($emails) == 0 )
	{
		
	}
	
	$emails = array_unique($emails);
	$current_time = time();
	$emails_ok    = array();
	
	if( $listdata['liste_format'] != FORMAT_MULTIPLE )
	{
		$format = $listdata['liste_format'];
	}
	
	//
	// Vrification syntaxique des emails
	//
	$emails = array_filter($emails, create_function('$email',
		'global $lang;
		
		if( Mailer::validate_email($email) ) {
			return true;
		} else {
			printf("%s : %s\n", $email, $lang[\'Message\'][\'Invalid_email2\']);
			return false;
		}'
	));
	
	if( count($emails) > 0 )
	{
		$counter = 0;
		$sql_emails = array_map(create_function('$email',
			'return $GLOBALS["db"]->escape(strtolower($email));'), $emails);
		
		$sql = "SELECT a.abo_id, a.abo_email, a.abo_status, al.confirmed
			FROM " . ABONNES_TABLE . " AS a
				LEFT JOIN " . ABO_LISTE_TABLE . " AS al ON al.abo_id = a.abo_id
					AND al.liste_id = $listdata[liste_id]
			WHERE LOWER(a.abo_email) IN('" . implode("', '", $sql_emails) . "')";
		if( !($result = $db->query($sql)) )
		{
			trigger_error('Impossible de tester les tables d\'inscriptions', CRITICAL_ERROR);
		}
		
		//
		// Traitement des adresses email dj prsentes dans la base de donnes
		//
		while( $abodata = $result->fetch() )
		{
			if( !isset($abodata['confirmed']) ) // N'est pas inscrit  cette liste
			{
				$sql_data = array();
				$sql_data['abo_id']        = $abodata['abo_id'];
				$sql_data['liste_id']      = $listdata['liste_id'];
				$sql_data['format']        = $format;
				$sql_data['register_key']  = generate_key(20, false);
				$sql_data['register_date'] = $current_time;
				$sql_data['confirmed']     = ($abodata['abo_status'] == ABO_ACTIF) ? SUBSCRIBE_CONFIRMED : SUBSCRIBE_NOT_CONFIRMED;
				
				if( !$db->build(SQL_INSERT, ABO_LISTE_TABLE, $sql_data) )
				{
					trigger_error('Impossible d\'insrer une nouvelle entre dans la table abo_liste', CRITICAL_ERROR);
				}
				
				$counter++;
			}
			else
			{
				printf("%s : %s\n", $abodata['abo_email'], $lang['Message']['Allready_reg']);
			}
			
			array_push($emails_ok, $abodata['abo_email']);
		}
		
		//
		// Traitement des adresses email inconnues
		//
		@include 'PHP/Compat/Function/array_udiff.php';// partie du module PEAR PHP_Compat
		
		if( function_exists('array_udiff') )
		{
			$emails = array_udiff($emails, $emails_ok, 'strcasecmp');
		}
		else
		{
			$emails = array_diff($emails, $emails_ok);
		}
		
		foreach( $emails as $email )
		{
			$db->beginTransaction();
			
			$sql_data = array();
			$sql_data['abo_email']  = $email;
			$sql_data['abo_status'] = ABO_ACTIF;
			
			if( !$db->build(SQL_INSERT, ABONNES_TABLE, $sql_data) )
			{
				printf("%s : SQL error (#%d: %s)\n", $email, $db->errno, $db->error);
				$db->rollBack();
				continue;
			}
			
			$sql_data = array();
			$sql_data['abo_id']        = $db->lastInsertId();
			$sql_data['liste_id']      = $listdata['liste_id'];
			$sql_data['format']        = $format;
			$sql_data['register_key']  = generate_key(20, false);
			$sql_data['register_date'] = $current_time;
			$sql_data['confirmed']     = SUBSCRIBE_CONFIRMED;
			
			if( !$db->build(SQL_INSERT, ABO_LISTE_TABLE, $sql_data) )
			{
				trigger_error('Impossible d\'insrer une nouvelle entre dans la table abo_liste', CRITICAL_ERROR);
			}
			
			$counter++;
			$db->commit();
		}
		
		if( $counter > 1 )
		{
			$message = sprintf($lang['Message']['Success_import4_n'], $counter);
		}
		else if( $counter == 1 )
		{
			$message = sprintf($lang['Message']['Success_import4_1'], $counter);
		}
		else
		{
			$message = $lang['Message']['Success_import4_0'];
		}
	}
}

if( !is_null($message) )
{
	echo strip_tags($message), "\n";
}

exit(0);


