[ Index ]

PHP Cross Reference of MyBB 1.8.40

title

Body

[close]

/inc/ -> class_mailhandler.php (source)

   1  <?php
   2  /**
   3   * MyBB 1.8
   4   * Copyright 2014 MyBB Group, All Rights Reserved
   5   *
   6   * Website: http://www.mybb.com
   7   * License: http://www.mybb.com/about/license
   8   *
   9   */
  10  
  11  /**
  12   * Base mail handler class.
  13   */
  14  class MailHandler
  15  {
  16      /**
  17       * Which email it should send to.
  18       *
  19       * @var string
  20       */
  21      public $to;
  22  
  23      /**
  24       * 1/0 value weather it should show errors or not.
  25       *
  26       * @var integer
  27       */
  28      public $show_errors = 1;
  29  
  30      /**
  31       * Who it is from.
  32       *
  33       * @var string
  34       */
  35      public $from;
  36  
  37      /**
  38       * Full from string including name in format "name" <email>
  39       *
  40       * @var string
  41       */
  42      public $from_named;
  43  
  44      /**
  45       * Who the email should return to.
  46       *
  47       * @var string
  48       */
  49      public $return_email;
  50  
  51      /**
  52       * The subject of mail.
  53       *
  54       * @var string
  55       */
  56      public $subject;
  57  
  58      /**
  59       * The unaltered subject of mail.
  60       *
  61       * @var string
  62       */
  63      public $orig_subject;
  64  
  65      /**
  66       * The message of the mail.
  67       *
  68       * @var string
  69       */
  70      public $message;
  71  
  72      /**
  73       * The headers of the mail.
  74       *
  75       * @var string
  76       */
  77      public $headers;
  78  
  79      /**
  80       * The charset of the mail.
  81       *
  82       * @var string
  83       * @default utf-8
  84       */
  85      public $charset = "utf-8";
  86  
  87      /**
  88       * The currently used delimiter new lines.
  89       *
  90       * @var string
  91       */
  92      public $delimiter = "\r\n";
  93  
  94      /**
  95       * How it should parse the email (HTML or plain text?)
  96       *
  97       * @var string
  98       */
  99      public $parse_format = 'text';
 100  
 101      /**
 102       * The last received response from the SMTP server.
 103       *
 104       * @var string
 105       */
 106      public $data = '';
 107  
 108      /**
 109       * The last received response code from the SMTP server.
 110       *
 111       * @var string
 112       */
 113      public $code = 0;
 114  
 115      /**
 116       * Returns the appropriate email address based on the type.
 117       *
 118       * @param string $type The type of email address to return. 
 119       * @return string The selected email address.
 120       */    
 121  	function get_email($type='from')
 122      {
 123          global $mybb;
 124      
 125          if($type === 'reply-to') 
 126          {
 127              if(isset($mybb->settings['returnemail']) && trim($mybb->settings['returnemail'])) 
 128              {
 129                  return $mybb->settings['returnemail'];
 130              }
 131          }
 132      
 133          // Fallback or 'from' case
 134          return $mybb->settings['adminemail'];
 135      }    
 136  
 137      /**
 138       * Builds the whole mail.
 139       * To be used by the different email classes later.
 140       *
 141       * @param string $to to email.
 142       * @param string $subject subject of email.
 143       * @param string $message message of email.
 144       * @param string $from from email.
 145       * @param string $charset charset of email.
 146       * @param string $headers headers of email.
 147       * @param string $format format of the email (HTML, plain text, or both?).
 148       * @param string $message_text plain text version of the email.
 149       * @param string $return_email the return email address.
 150       */
 151  	function build_message($to, $subject, $message, $from="", $charset="", $headers="", $format="text", $message_text="", $return_email="")
 152      {
 153          global $parser, $lang, $mybb;
 154  
 155          $this->message = '';
 156          $this->headers = $headers;
 157          
 158          if($from)
 159          {
 160              $this->from = $from;
 161              $this->from_named = $this->from;
 162          }
 163          else
 164          {
 165              $this->from = $this->get_email('from');
 166              $this->from_named = '"'.$this->utf8_encode($mybb->settings['bbname']).'"';
 167              $this->from_named .= " <".$this->from.">";
 168          }
 169  
 170          $this->from = $this->cleanup($this->from);
 171          $this->from_named = $this->cleanup($this->from_named);
 172  
 173          if($return_email)
 174          {
 175              $this->return_email = $return_email;
 176          }
 177          else
 178          {
 179              $this->return_email = $this->get_email('reply-to');
 180          }
 181  
 182          $this->return_email = $this->cleanup($this->return_email);
 183  
 184          $this->set_to($to);
 185          $this->set_subject($subject);
 186  
 187          if($charset)
 188          {
 189              $this->set_charset($charset);
 190          }
 191  
 192          $this->parse_format = $format;
 193          $this->set_common_headers();
 194          $this->set_message($message, $message_text);
 195      }
 196  
 197      /**
 198       * Sets the charset.
 199       *
 200       * @param string $charset charset
 201       */
 202  	function set_charset($charset)
 203      {
 204          global $lang;
 205  
 206          if(empty($charset))
 207          {
 208              $this->charset = $lang->settings['charset'];
 209          }
 210          else
 211          {
 212              $this->charset = $charset;
 213          }
 214      }
 215  
 216      /**
 217       * Sets and formats the email message.
 218       *
 219       * @param string $message message
 220       * @param string $message_text
 221       */
 222  	function set_message($message, $message_text="")
 223      {
 224          $message = $this->cleanup_crlf($message);
 225  
 226          if($message_text)
 227          {
 228              $message_text = $this->cleanup_crlf($message_text);
 229          }
 230  
 231          if($this->parse_format == "html" || $this->parse_format == "both")
 232          {
 233              $this->set_html_headers($message, $message_text);
 234          }
 235          else
 236          {
 237              $this->message = $message;
 238              $this->set_plain_headers();
 239          }
 240      }
 241  
 242      /**
 243       * Sets and formats the email subject.
 244       *
 245       * @param string $subject
 246       */
 247  	function set_subject($subject)
 248      {
 249          $this->orig_subject = $this->cleanup($subject);
 250          $this->subject = $this->utf8_encode($this->orig_subject);
 251      }
 252  
 253      /**
 254       * Sets and formats the recipient address.
 255       *
 256       * @param string $to
 257       */
 258  	function set_to($to)
 259      {
 260          $to = $this->cleanup($to);
 261  
 262          $this->to = $this->cleanup($to);
 263      }
 264  
 265      /**
 266       * Sets the plain headers, text/plain
 267       */
 268  	function set_plain_headers()
 269      {
 270          $this->headers .= "Content-Type: text/plain; charset={$this->charset}{$this->delimiter}";
 271      }
 272  
 273      /**
 274       * Sets the alternative headers, text/html and text/plain.
 275       *
 276       * @param string $message
 277       * @param string $message_text
 278       */
 279  	function set_html_headers($message, $message_text="")
 280      {
 281          if(!$message_text && $this->parse_format == 'both')
 282          {
 283              $message_text = strip_tags($message);
 284          }
 285  
 286          if($this->parse_format == 'both')
 287          {
 288              $mime_boundary = "=_NextPart".md5(TIME_NOW);
 289  
 290              $this->headers .= "Content-Type: multipart/alternative; boundary=\"{$mime_boundary}\"{$this->delimiter}";
 291              $this->message = "This is a multi-part message in MIME format.{$this->delimiter}{$this->delimiter}";
 292  
 293              $this->message .= "--{$mime_boundary}{$this->delimiter}";
 294              $this->message .= "Content-Type: text/plain; charset=\"{$this->charset}\"{$this->delimiter}";
 295              $this->message .= "Content-Transfer-Encoding: 8bit{$this->delimiter}{$this->delimiter}";
 296              $this->message .= $message_text."{$this->delimiter}{$this->delimiter}";
 297  
 298              $this->message .= "--{$mime_boundary}{$this->delimiter}";
 299  
 300              $this->message .= "Content-Type: text/html; charset=\"{$this->charset}\"{$this->delimiter}";
 301              $this->message .= "Content-Transfer-Encoding: 8bit{$this->delimiter}{$this->delimiter}";
 302              $this->message .= $message."{$this->delimiter}{$this->delimiter}";
 303  
 304              $this->message .= "--{$mime_boundary}--{$this->delimiter}{$this->delimiter}";
 305          }
 306          else
 307          {
 308              $this->headers .= "Content-Type: text/html; charset=\"{$this->charset}\"{$this->delimiter}";
 309              $this->headers .= "Content-Transfer-Encoding: 8bit{$this->delimiter}{$this->delimiter}";
 310              $this->message = $message."{$this->delimiter}{$this->delimiter}";
 311          }
 312      }
 313  
 314      /**
 315       * Sets the common headers.
 316       */
 317  	function set_common_headers()
 318      {
 319          global $mybb;
 320  
 321          // Build mail headers
 322          $this->headers .= "From: {$this->from_named}{$this->delimiter}";
 323  
 324          if($this->return_email)
 325          {
 326              $this->headers .= "Return-Path: {$this->return_email}{$this->delimiter}";
 327              $this->headers .= "Reply-To: {$this->return_email}{$this->delimiter}";
 328          }
 329  
 330          if(isset($_SERVER['SERVER_NAME']))
 331          {
 332              $http_host = $_SERVER['SERVER_NAME'];
 333          }
 334          else if(isset($_SERVER['HTTP_HOST']))
 335          {
 336              $http_host = $_SERVER['HTTP_HOST'];
 337          }
 338          else
 339          {
 340              $http_host = "unknown.local";
 341          }
 342  
 343          $msg_id = md5(uniqid(TIME_NOW, true)) . "@" . $this->cleanup($http_host);
 344  
 345          if($mybb->settings['mail_message_id'])
 346          {
 347              $this->headers .= "Message-ID: <{$msg_id}>{$this->delimiter}";
 348          }
 349          $this->headers .= "Content-Transfer-Encoding: 8bit{$this->delimiter}";
 350          $this->headers .= "X-Priority: 3{$this->delimiter}";
 351          $this->headers .= "X-Mailer: MyBB{$this->delimiter}";
 352          $this->headers .= "MIME-Version: 1.0{$this->delimiter}";
 353      }
 354  
 355      /**
 356       * Log a fatal error message to the database.
 357       *
 358       * @param string $error The error message
 359       */
 360  	function fatal_error($error)
 361      {
 362          global $db;
 363  
 364          $mail_error = array(
 365              "subject" => $db->escape_string($this->orig_subject),
 366              "message" => $db->escape_string($this->message),
 367              "toaddress" => $db->escape_string($this->to),
 368              "fromaddress" => $db->escape_string($this->from),
 369              "dateline" => TIME_NOW,
 370              "error" => $db->escape_string($error),
 371              "smtperror" => $db->escape_string($this->data),
 372              "smtpcode" => (int)$this->code
 373          );
 374          $db->insert_query("mailerrors", $mail_error);
 375  
 376          // Another neat feature would be the ability to notify the site administrator via email - but wait, with email down, how do we do that? How about private message and hope the admin checks their PMs?
 377      }
 378  
 379      /**
 380       * Rids pesky characters from subjects, recipients, from addresses etc (prevents mail injection too)
 381       *
 382       * @param string $string The string being checked
 383       * @return string The cleaned string
 384       */
 385  	function cleanup($string)
 386      {
 387          $string = str_replace(array("\r", "\n", "\r\n"), "", $string);
 388          $string = trim($string);
 389          return $string;
 390      }
 391  
 392      /**
 393       * Converts message text to suit the correct delimiter
 394       * See dev.mybb.com/issues/1735 (Jorge Oliveira)
 395       *
 396       * @param string $text The text being converted
 397       * @return string The converted string
 398       */
 399  	function cleanup_crlf($text)
 400      {
 401          $text = str_replace("\r\n", "\n", $text);
 402          $text = str_replace("\r", "\n", $text);
 403          $text = str_replace("\n", "\r\n", $text);
 404  
 405          return $text;
 406      }
 407  
 408      /**
 409       * Encode a string based on the character set enabled. Used to encode subjects
 410       * and recipients in email messages going out so that they show up correctly
 411       * in email clients.
 412       *
 413       * @param string $string The string to be encoded.
 414       * @return string The encoded string.
 415       */
 416  	function utf8_encode($string)
 417      {
 418          if(strtolower($this->charset) == 'utf-8' && preg_match('/[^\x20-\x7E]/', $string))
 419          {
 420              $chunk_size = 47; // Derived from floor((75 - strlen("=?UTF-8?B??=")) * 0.75);
 421              $len = strlen($string);
 422              $output = '';
 423              $pos = 0;
 424  
 425              while($pos < $len)
 426              {
 427                  $newpos = min($pos + $chunk_size, $len);
 428  
 429                  if($newpos != $len)
 430                  {
 431                      while(ord($string[$newpos]) >= 0x80 && ord($string[$newpos]) < 0xC0)
 432                      {
 433                          // Reduce len until it's safe to split UTF-8.
 434                          $newpos--;
 435                      }
 436                  }
 437  
 438                  $chunk = substr($string, $pos, $newpos - $pos);
 439                  $pos = $newpos;
 440  
 441                  $output .= " =?UTF-8?B?".base64_encode($chunk)."?=\n";
 442              }
 443              return trim($output);
 444          }
 445          return $string;
 446      }
 447  }


2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup Cross-referenced by PHPXref