<?php
/**
 * YANA library
 *
 * @package yana
 * @licence http://creativecommons.org/licenses/by-nc-sa/2.5/
 */

/**
 * create and send mails based on templates
 *
 * @access      public
 * @package     yana
 * @subpackage  mail
 */
class Mailer extends SmartTemplate
{

    /**#@+
     * @access  public
     * @var     string
     */

    var $subject = "";
    var $sender  = "";
    
    /**#@-*/

    /**
     * send
     *
     * send an e.mail
     *
     * @uses $mailer->send('recipient@somewhere.tld');
     *
     * @param string $recipient
     * @return boolean
     * @access public
     * @since Version 2.8
     */
    function send($recipient)
    {
        assert('is_string($this->subject);');
        assert('is_string($this->sender);');
        assert('is_string($recipient);');

        /* Why do we replace the default modifiers?
         *
         * Well - the original list may include html-specific filters
         * that produce html entities, that are no good for an e-mail
         * in text/plain format.
         */
        $this->smarty->default_modifiers = array('replaceToken');
        
        /* prepare header */
        if (!empty($this->sender)){ 
            $header = array();
            $header['from']        = $this->sender;
            $header['return-path'] = $this->sender;
        } else {
            $header = array();
        }
        $content = preg_replace("/<br ?\/?>/", "\n", $this->get());
        
        return Mailer::mail($recipient,"[MAILFORM] ".$this->subject,$content,$header);
    }

    /**
     * send an e.mail
     *
     * @uses  Mailer::mail('recipient@somewhere.tld', 'My Subject', 'My Text', array('from' => 'myMail@domain.tld'));
     *
     * @param string $recipient
     * @param string $subject
     * @param string $text
     * @param array $header (optional)
     * @return boolean
     * @access public
     * @static
     * @since Version 2.8
     */
    function mail($recipient, $subject, $text, $header = array())
    {
        assert('is_string($recipient);');
        assert('is_string($subject);');
        assert('is_string($text);');
        assert('is_array($header);');
        global $YANA;
    
        $recipient = untaintInput($recipient, 'mail');
        $subject   = strip_tags(untaintInput($subject, "string", 128, YANA_ESCAPE_LINEBREAK));
        $subject   = preg_replace("/[^\w \(\)äÄüÜöÖß\]\[]/",    "", $subject);
        $text      = untaintInput($text, "text");
        assert('is_string($text);');
        settype($header, "array");
        $header    = changeCaseArray($header, CASE_LOWER);
    
        $default_header = array();
        $default_header['x-mailer']      = "PHP/". phpversion();
        $default_header['x-sender-ip']   = $_SERVER['REMOTE_ADDR'];
        $default_header['x-server-time'] = date("d.m.Y H:i:s", time());
        $default_header['content-type']  = 'text/plain; charset="8859-1"';
        $default_header['mime-version']  = '1.0';
        $default_header['x-yana-php-header-protection'] = '0 (no suspicious header found)';
        $default_header['x-yana-php-spam-protection']   = '0 (no recipients were dropped)';
    
        /* untaint default sender */
        if (isset($YANA)) {
            $default_header['from'] = $YANA->getVar("PROFILE.GUESTBOOK.NOREPLY");
            $default_header['from'] = untaintInput($default_header['from'], "mail");
        } else {
            $default_header['from'] = "";
        }
    
        $untainted_header = array();

        if (is_array($header)) {
            foreach ($header as $key => $value)
            {
                if (preg_match('/^[a-z\d-]+$/', $key) && !preg_match('/[\r\n]/', $value)) {
                    $value = untaintInput($value, "string", 128, YANA_ESCAPE_LINEBREAK);
                    if (!empty($value)) {
                        switch ($key) {
                            case 'cc':
                                if (is_array($value)) {
                                    foreach ($value as $a_key => $a_value)
                                    {
                                        $a_value = untaintInput($a_value,"mail");
                                        if (!empty($a_value)) {
                                            if (empty($untainted_header['cc'])) {
                                                $untainted_header['cc']  = "$a_value";
                                            } else {
                                                $untainted_header['cc'] .= "; $a_value";
                                            }
                                        }
                                    } /* end foreach */
                                } else {
                                    $value = untaintInput($value,"mail");
                                    if (!empty($value)) $untainted_header['cc'] = "$value";
                                }
                            break;
                            case 'bcc':
                                /* bcc is not allowed! */
                                $untainted_header['x-yana-php-spam-protection'] = '1 (bcc is not allowed in form mail - recipients were dropped)';
                            break;
                            case 'return-path':
                                $value = untaintInput($value,"mail");
                                if (!empty($value)) $untainted_header['return-path'] = "$value";
                            break;
                            case 'from':
                                $value = untaintInput($value,"mail");
                                if (!empty($value)) $untainted_header['from'] = "$value";
                            break;
                            case 'content-type':
                                if (preg_match('/^(\w+\/\w+);( ?| +)charset="?[\w\d-]+"?$/i',$value)) {
                                    $untainted_header['content-type'] = "$value";
                                }
                            break;
                            case 'mime-version':
                                if (preg_match('/^\d\.\d$/',$value)) {
                                    $untainted_header['mime-version'] = "$value";
                                }
                            break;
                            case 'content-transfer-encoding':
                                if (preg_match('/^\d{,2}bit$/i',$value)) {
                                    $untainted_header['content-transfer-encoding'] = "$value";
                                }
                            break;
                            default:
                                if (preg_match('/^x-[a-z\d-]+$/', $key)) {
                                    if ($key != 'x-yana-php-header-protection' && $key != 'x-yana-php-spam-protection') {
                                        $untainted_header[$key] = "$value";
                                    } else {
                                        return false;
                                    }
                                } else {
                                    $untainted_header['x-yana-php-header-protection'] = '1 (Suspicious header attribute dropped due to security reasons. Mail might contain errors)';
                                }
                            break;
                        }
                    }
                } else {
                    $untainted_header['x-yana-php-header-protection'] = '1 (Suspicious header attribute dropped due to security reasons. Mail might contain errors)';
                }
            } /* end for */
        } /* end if */
    
        foreach ($default_header as $key => $value)
        {
            if (empty($untainted_header[$key]) && !empty($value)) {
                $untainted_header[$key] = $value;
            }
        }
    
        $text = preg_replace('/@/', '[at]', $text);
        
        if (preg_match('/^text\/plain/i', $untainted_header['content-type'])) {
            $text = wordwrap($text, 70);
        } else if (preg_match('/^text\/html/i', $untainted_header['content-type'])) {
            while (preg_match('/<\/?(\?|\!|link|meta|script|style|img|embed|object|param|).*>/Usi', $text))
            {
                $text = preg_replace('/<\/?(\?|\!|link|meta|script|style|img|embed|object|param|).*>/Usi', '', $text);
            }
        }
    
        $result_header = "";
        foreach ($untainted_header as $key => $value)
        {
            $result_header .= "$key: $value\n";
        }
    
        if (empty($recipient) || empty($subject) || empty($text)) {
            return false;
        }
                   
        @mail($recipient, $subject, $text, $result_header);
        return true;
    }

}

?>