<?php
/**
 * Mail module
 * 
 * Newsletter script. Be carefull, that file is not called directly.
 * The current file prepare Email transport using Swift library and send emails.
 * Newsletters to send and recipients are gotten from /newsletter/send.php file
 * (which file is called using cronjob)
 * 
 * @package linea21\core\mail
 * @author $Author$ - linea21 <info@linea21.com>
 * @version $Id$ 
 * @access public
 * @license http://opensource.org/licenses/gpl-3.0.html
 * @see /newsletter/send.php Direct file called by the application
 */

if(defined('MAIL_LIBRARY') && MAIL_LIBRARY == 'swiftMailer') $mailerLibrary = 'swiftMailer';
else $mailerLibrary = 'mailer'; // alternative 'swiftMailer'

use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Address;

/**
 * absolute_url
 * http://www.howtoforge.com/forums/showthread.php?t=4
 * @param string $txt
 * @param string $base_url
 * @return string $txt
 */
function absolute_url($txt, $base_url) {
  $needles = array('href="', 'src="', 'background="');
  $new_txt = '';
  if(substr($base_url,-1) != '/') $base_url .= '/';
  $new_base_url = $base_url;
  $base_url_parts = parse_url($base_url);

  foreach($needles as $needle){
    while($pos = strpos($txt, $needle)){
      $pos += strlen($needle);
      if(substr($txt,$pos,7) != 'http://' && substr($txt,$pos,8) != 'https://' && substr($txt,$pos,6) != 'ftp://' && substr($txt,$pos,7) != 'mailto:'){
        if(substr($txt,$pos,1) == '/') $new_base_url = $base_url_parts['scheme'].'://'.$base_url_parts['host'];
        $new_txt .= substr($txt,0,$pos).$new_base_url;
      } else {
        $new_txt .= substr($txt,0,$pos);
      }
            $txt = substr($txt, $pos);
        }
        $txt = $new_txt . $txt;
        $new_txt = '';
    }
    return $txt;
}

// https://symfony.com/doc/current/mailer.html
$mailer_dsn = 'native://default'; // default configuration

// We create the Transport
if (defined('MAIL_MAILER')) {

    // sendmail
    if (MAIL_MAILER == 'sendmail') {
        $mailer_dsn = 'sendmail://default';
        $transport = new Swift_SendmailTransport(MAIL_SENDMAIL); // alternative 'swiftMailer'
    }
    // smtp
    if (MAIL_MAILER == 'smtp') {
        if (defined('MAIL_SMTP_AUTH') && MAIL_SMTP_AUTH == 1) {
            if (defined('MAIL_SMTP_ENCRYPTION')) {
                $mailer_dsn = 'smtp://' . MAIL_SMTP_USER . ':' . MAIL_SMTP_PASS . '@' . MAIL_HOST . ':' . MAIL_PORT;
                $transport = (new Swift_SmtpTransport(MAIL_HOST, MAIL_PORT, MAIL_SMTP_ENCRYPTION))->setUsername(MAIL_SMTP_USER)->setPassword(MAIL_SMTP_PASS); // alternative 'swiftMailer'
            } else {
                $mailer_dsn = 'smtp://' . MAIL_SMTP_USER . ':' . MAIL_SMTP_PASS . '@' . MAIL_HOST . '?verify_peer=0:' . MAIL_PORT;
                $transport = (new Swift_SmtpTransport(MAIL_HOST, MAIL_PORT))->setUsername(MAIL_SMTP_USER)->setPassword(MAIL_SMTP_PASS); // alternative 'swiftMailer'
            }
        } else {
            $mailer_dsn = 'smtp://' . MAIL_HOST . ':' . MAIL_PORT;
            $transport = (new Swift_SmtpTransport(MAIL_HOST, MAIL_PORT)); // alternative 'swiftMailer'
        }
    }
}

// we define mailer transport settings
$transportMailer = Transport::fromDsn($mailer_dsn);
$mailer = new Mailer($transportMailer);

// Create the Swift_Mailer using the Transport if set as mailer library
if( $mailerLibrary == 'swiftMailer') $mailer = new Swift_Mailer($transport);

/**
 * Ability to set options through plugins
 * examples taken from :
 * http://swiftmailer.org/docs/plugins.html
 * Duplicate original file and locate it into public themes
 * Finally uncomment instructions and set them correcty
 */

// // Use AntiFlood to re-connect after 100 emails
// $mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100));

// // And specify a time in seconds to pause for (30 secs)
// $mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100, 30));

// // Rate limit to 100 emails per-minute
// $mailer->registerPlugin(new Swift_Plugins_ThrottlerPlugin(
// 		100, Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE
// ));

// // Rate limit to 10MB per-minute
// $mailer->registerPlugin(new Swift_Plugins_ThrottlerPlugin(
// 		1024 * 1024 * 10, Swift_Plugins_ThrottlerPlugin::BYTES_PER_MINUTE
// ));



/**
 echo "destinataire : ".$email_recipient."<br />";
 echo "sujet : ".$email_subject."<br />";
 echo "body : ".$email_html_body."<br />";
 echo "methode : ".$email_method."<br />";
 echo "host : ".$mail->Host."<br />";
 echo "port : ".$mail->Port."<br />";
 */

for($i = 0;$i < count($newsletters); $i++) {
  $newsletter_id = $newsletters[$i]['newsletter_id'];
  $email_subject = formatText($newsletters[$i]['newsletter_title'], '2HTML');


  $newsletter_body_html = formatText($newsletters[$i]['newsletter_body'], '2HTML');
  
  // get content with SIMPLEHTMLDOM
  $dom = str_get_html($template_html);
  
  // we do replace the content from template with content stored id db inside <div id="main">
  if($dom->find('div[id=main]', 0)) {
      $dom->find('div[id=main]', 0)->innertext= $newsletter_body_html;
      $template_html = $dom->save(); // we finally save changes to apply them
  }
 
  
  preg_replace("/(<\s*(a|img)\s+[^>]*(href|src)\s*=\s*[\"'])(?!http)([^\"'>]+)[\"'>]/", "$1".CURRENT_APP_URL."$4", $newsletter_body_html);
  $email_html_body=str_replace('##TITLE##', $email_subject, $template_html);
  $email_html_body=str_replace('##CHARSET##', CHARSET, $email_html_body);
  $email_html_body=str_replace('##CONTENTS##', '', $email_html_body); // @todo not used anymore since 2.6 - remove later
  $email_html_body=str_replace('##SITENAME##', SITE_NAME, $email_html_body);
  
  if(file_exists('../'.THEME_DIRECTORY.'/public/'.THEME_PUBLIC.'/images/logo-newsletter.png')) {
    $email_html_body=str_replace('##LOGOIMG##', '<p id="header-logo"><img src="'.SITE_ROOT_URL. THEME_DIRECTORY.'/public/'.THEME_PUBLIC.'/images/logo-newsletter.png" alt="logo" infer /></p>', $email_html_body);
  } else {
      $email_html_body=str_replace('##LOGOIMG##', '', $email_html_body);
      
  }
  // since v2.6 ##CSSPATH## not necessary
  $email_html_body=str_replace('##CSSPATH##', SITE_ROOT_URL. THEME_DIRECTORY.'/public/'.THEME_PUBLIC.'/css/', $email_html_body);
  $email_html_body=str_replace('##SITEURL##', SITE_ROOT_URL, $email_html_body);
  $email_html_body=str_replace('##SITEMAIL##', SITE_MAIL, $email_html_body);
  $email_html_body=absolute_url($email_html_body, SITE_ROOT_URL);

  $newsletter_body_txt = formatText($newsletters[$i]['newsletter_body']);
  $email_text_body=str_replace('##TITLE##', strip_tags(formatText($email_subject)) . "\n" . strip_tags(formatText($newsletter_body_txt)), $template_txt);
  $email_text_body=str_replace('##CONTENTS##', '', $email_text_body); // @todo not used anymore since 2.6 - remove later
  $email_text_body=str_replace('##SITENAME##', SITE_NAME, $email_text_body);
  $email_text_body=str_replace('##SITEURL##', SITE_ROOT_URL, $email_text_body);
  $email_text_body=str_replace('##SITEMAIL##', SITE_MAIL, $email_text_body);
  $email_text_body=absolute_url($email_text_body, SITE_ROOT_URL);


  isset($email_from) ? $from = $email_from : $from = MAIL_FROM;
  isset($email_fromname) ? $fromname = $email_fromname : $fromname = MAIL_FROMNAME;
  $altbody = str_replace('&amp;', '&', $email_text_body);


	// Create a message
	if( $mailerLibrary == 'swiftMailer') {
		// Create a message instance
		$message = new Swift_Message($email_subject);
		$message->setFrom(array($from => $fromname))
		->setReplyTo(array(MAIL_REPLY => MAIL_REPLYNAME));
	} else {
		// default case using symfony/mailer
		$message = (new Email())
				->from(new Address($from, $fromname))
				//->to('you@example.com')
				//->cc('cc@example.com')
				//->bcc('bcc@example.com')
				->replyTo(new Address(MAIL_REPLY, MAIL_REPLYNAME))
				//->priority(Email::PRIORITY_HIGH)
				->subject($email_subject);
	}

  for($k = 0; $k < count($emails_batch); $k++) {
      
    $email_id = $emails_batch[$k]['emailcol_id'];
    $email_recipient = $emails_batch[$k]['emailcol_email'];

    // we create the link to unsubscribe newsletter and add it to the message
    $unsubscribe_url= SITE_ROOT_URL.'public/index.php?rub='.$GLOBALS['links'][U_L]['subscribe-newsletter']['linkvalue'].'&del_action=on&newsletteremail='.$email_recipient;
    $unsubscribe_link_html = sprintf(_t('newsletter', 'unsubscribe_html'), $unsubscribe_url);
    $unsubscribe_link_txt = _t('newsletter', 'unsubscribe_txt'). ' '. $unsubscribe_url;

    $email_html_body=str_replace('##UNSUBSCRIBE_LINK##', $unsubscribe_link_html, $email_html_body);
    $email_text_body=str_replace('##UNSUBSCRIBE_LINK##', $unsubscribe_link_txt, $email_text_body);

    // finish message settings
    if( $mailerLibrary == 'swiftMailer') {
		$message->setBody($email_html_body, 'text/html')->addPart($altbody, 'text/plain')->setTo($email_recipient);
		$r = $mailer->Send($message);
		// hope it fixes bug https://dev.linea21.com/issues/1438 - see https://stackoverflow.com/questions/43871739/swiftmailer-broken-pipe-error
	    $mailer->getTransport()->stop(); // < this line closes socket and at next iteration its reopened
	} else {
		$message->html((string) $email_html_body)->text($altbody)->to($email_recipient);  // cast to string to prevent error on mime detection using symfony/mailer
		
		try {
			$mailer->send($message);
			$r = 1;
		} catch (TransportExceptionInterface $e) {
			// some error prevented the email sending; display an
			// error message or try to resend the message
			$r = 0;
		}
	}
	
	if(!$r) {
		$logmsg = 'not sent';
	} else {
		$logmsg = 'sent';
	}

	logfile(LOG_MAILING, array($email_subject, $newsletter_id, $email_recipient, $logmsg, $mailerLibrary));

  }

  if(!isset($doNotPublish)) $newsletter_object->SetNewsletterPublished($newsletter_id, $sql_object);
}

?>