[KLUG Members] Mail from PHP

Adam Tauno Williams members@kalamazoolinux.org
Sun, 18 Apr 2004 16:31:26 -0400


--=-C/Qu2FJm6U8GbCVlf6Yx
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

> I'm using the php mail() function to send stuff to someone at charter.net, 
> like this...
> mail(someone@charter.net,"Response from the website",$yada_yada,
>       "From: thewebsite@thewebsotedomain.com");
> charter.net rejects it because it's from "apache@localhost.localdomain"
> How can that be changed?

I've attached my mail_mesg class, this might help.

--=-C/Qu2FJm6U8GbCVlf6Yx
Content-Disposition: attachment; filename=baseclass.class
Content-Type: application/x-java-byte-code; name=baseclass.class
Content-Transfer-Encoding: 7bit

<?PHP
 
  class baseclass {
     var $error_number;
     var $error_text;
     var $debug_flag;
     var $object_id;
     var $object_property_bag;
     
     function baseclass() {
       if ($GLOBALS["DEBUG"] > 0)
         $this->set_debug_on();
       $this->object_id = $this->create_id();
       $this->object_property_bag = array();
      }
      
     function create_id() {
       return sprintf("object.%d.%s.%d.%d", 
                time(), 
                getenv("REMOTE_USER"),
                rand(1000000,9999999),
                posix_getpid());
      }
      
     function get_object_id() {
       return $this->object_id;
      }
      
     function get_property_count() {
       return count($this->object_property_bag);
      }
     
     function is_a_property($name) {
       if (isset($this->object_property_bag[$name]))
         return 1;
        else
          return 0;
      }
      
     function get_property_value($name) {
       return $this->object_property_bag[$name];
      }
      
     function set_property_value($name, $value) {
       $this->object_property_bag[$name] = $value;
      }

     function set_error($error_number, $error_text) {
       $this->error_number = $error_number;
       $this->error_text   = $error_text;
       if ($this->debug_flag)
         $this->write_debug_log($error_text);
      }

     function set_error_ok() {
       $this->error_number = 0;
       $this->error_text   = "OK";
      }
      
     function set_debug_on() {
       $this->debug_flag = 1;
      }
      
     function set_debug_off() {
       $this->debug_flag = 0;
      }
      
     function get_debug_status() {
       return $this->debug_flag;
      }

     function write_debug_log($debug_text) {
       if ($this->debug_flag)
        printf("DEBUG TEXT: %s<br>", $debug_text);
      }
   }

--=-C/Qu2FJm6U8GbCVlf6Yx
Content-Disposition: attachment; filename=container.class
Content-Type: application/x-php; name=container.class
Content-Transfer-Encoding: 7bit

<?php

require_once("baseclass.class");

  class container extends baseclass {
    var $obj_array;
    var $obj_count;
    var $obj_pos;
    var $obj_sort_key;
    var $obj_sort_member;
    var $obj_sort_prefs;

    function container() {
      baseclass::baseclass();
      $this->obj_array = array();
      $this->obj_sort_prefs["trim"] = 0;
      $this->obj_sort_prefs["upcase"] = 0;
      $this->obj_sort_prefs["order"] = 0;
      // Type: 0 = Ordinal, 1 = Natural
      $this->obj_sort_prefs["type"] = 0;
      $this->obj_count = 0;
      $this->obj_pos   = 0;
     }

    function purge() {
      $this->obj_array = array();
      $this->obj_count = 0;
      $this->obj_pos   = 0;
     }

    function get_count() {
      return $this->obj_count;
     }

    function set_position($pos) {
      if (($pos > 0) and ($pos < ($this->obj_count + 1))) 
       {
        $this->obj_pos = $pos;
        return 1;
       }
      return 0;
     }
      
    function get_position() {
      return $this->obj_pos;
     }  
    
    function next() {
      if ($this->obj_pos < $this->obj_count) 
       {
        $this->obj_pos++;
        return 1;
       }
      return 0;
     }

    function prev() {
      if (($this->obj_pos > 1) and ($this->obj_count > 0))
       {
        $this->obj_pos--;
        return 1;
       }
      return 0;
     }

    function rewind() {
      if ($this->obj_count > 0) {
        $this->obj_pos = 1;
        return 1;
       }
     }

  function put($object) {
    $this->obj_count++;
    $this->obj_array[$this->obj_count] = $object;
   }
   
  function remove_object($position) {
    if ($position > $this->obj_count) return;
    if ($this->obj_count == 1) {
      $this->purge();
     } else {
         if ($position == $this->obj_count) {
           unset($this->obj_array[$position]);
           $this->obj_count--;
          } else {
          	unset($this->obj_array[$position]);
              $this->obj_array[$position] = $this->obj_array[$this->obj_count];
              unset($this->obj_array[$obj_count]);
              $this->obj_count--;
             }
       }
   }
   
  function remove_value($value, $trimflag = 1, $debugflag = 0, $stringcompare = 0) {
  	if ($this->obj_count == 0) return;
  	$id = $this->search($value, $trimflag, $debugflag, $stringcompare);
  	if ($id) $this->remove_object($id);
  }

  function get() {
    return $this->obj_array[$this->obj_pos];
   }

  function search_by_key($searchkey, $searchvalue, $trimflag = 1, $debugflag = 0) {
    if ($this->obj_count == 0) return 0;
    if ($trimflag == 1)
     {
      $searchkey = trim($searchkey);
      $searchvalue = trim($searchvalue);
     }
    if (strlen($searchkey) == 0) return 0;
    if (strlen($searchvalue) == 0) return 0;
    $counter = 0;
    $valuefound = 0;
    while (($counter < $this->obj_count) and (!$valuefound))
     {
      $counter++;
      if ($debugflag)
        printf("[%d][%s](%s) =?= %s<br>", 
           $counter, $searchkey, $this->obj_array[$counter][$searchkey], $searchvalue);
      if ($this->obj_array[$counter][$searchkey] == $searchvalue) 
        $valuefound = $counter; 
     }
    if ($valuefound > 0) return $valuefound;
    return 0;
   }

  function search_by_member($searchmember, $searchvalue, $trimflag = 1, $debugflag = 0) {
    if ($this->obj_count == 0) return 0;
    if ($trimflag == 1)
     {
      $searchvalue = trim($searchvalue);
     }
    if (strlen($searchmember) == 0) return 0;
    if (strlen($searchvalue) == 0) return 0;
    $counter = 0;
    $valuefound = 0;
    while (($counter < $this->obj_count) and (!$valuefound))
     {
      $counter++;
      if ($debugflag)
        printf("[%d][%s](%s) =?= %s<br>", 
           $counter, $searchkey, $this->obj_array[$counter][$searchkey], $searchvalue);
      if ($this->obj_array[$counter]->$searchmember() == $searchvalue) 
        $valuefound = $counter; 
     }
    if ($valuefound > 0) return $valuefound;
    return 0;
   }

  function search($searchvalue, $trimflag = 1, $debugflag = 0, $stringcompare = 0) {
    if ($this->obj_count == 0) return 0;
    if ($trimflag == 1)
     {
      $searchvalue = trim($searchvalue);
     }
    if (strlen($searchvalue) == 0) return 0;
    $counter = 0;
    $valuefound = 0;
    while (($counter < $this->obj_count) and (!$valuefound))
     {
      $counter++;
      if ($debugflag)
        printf("[%d](%s) =?= %s<br>", 
           $counter, $this->obj_array[$counter], $searchvalue);
      if ($stringcompare) {
        if (strcmp ($searchvalue, $this->obj_array[$counter]) == 0)
          $valuefound = $counter;
       } else if ($this->obj_array[$counter] == $searchvalue)
                $valuefound = $counter; 
     }
    if ($valuefound > 0) return $valuefound;
    return 0;
   }
   
  function sorter($trimflag = 0, $upcaseflag = 0, $orderflag =0, $ordertype = 0, $debugflag =0) {
    $this->obj_sort_prefs["trim"] = $trimflag;
    $this->obj_sort_prefs["upcase"] = $upcaseflag;
    // Order: 0 = Ascending. 1 = Descending
    $this->obj_sort_prefs["order"] = $orderflag;
    // Type: 0 = Ordinal, 1 = Natural
    $this->obj_sort_prefs["type"] = $ordertype;    
    if ($debugflag)
     $this->set_debug_on();
    if ($this->debug_flag) 
      $this->write_debug_log(sprintf("container->sorter [ Elements: %d prior ]", count($this->obj_array)));
    if (isset($this->obj_array[0]))
      $this->write_debug_log(sprintf("container->sorter [ Array now has a ZERO index going in ]"));     
    usort($this->obj_array, array($this, "sort_procedure"));
    if ($this->debug_flag) {
      $this->write_debug_log(sprintf("container->sorter [ Elements: %d end ]", count($this->obj_array)));    
     }
    if (isset($this->obj_array[0])) {
      if ($this->debug_flag)   	
       $this->write_debug_log(sprintf("container->sorter [ Array now has a ZERO index, must shift up.... ]"));
     $i = count($this->obj_array);
     while ($i > 0) {
       $this->obj_array[$i] = $this->obj_array[($i - 1)];
       $i--;
      }
     unset($this->obj_array[0]);
    }
   }
   
  function sort_procedure($a, $b) {
    if ($this->debug_flag)
      $this->write_debug_log(sprintf("container->sort_procedure: (%s) =?= (%s)", $a, $b));  	
    if (isset($this->obj_sort_key)) {
      if ($this->debug_flag)
        $this->write_debug_log(sprintf("container->sort_procedure: Value extraction by key."));    	
      // get value at key array for sorting
      $a = $a[$this->obj_sort_key];
      $b = $b[$this->obj_sort_key];
     } else if (isset($this->obj_sort_member)) {
      if ($this->debug_flag)
        if ($this->debug_flag)
          $this->write_debug_log(sprintf("container->sort_procedure: Value extraction by member."));       	
        // get return value of member functions for sorting
        $sortmember = $this->obj_sort_member;
        if (is_object($a)) {
          $a = $a->$sortmember();
         } else $a = "";
        if (is_object($b)) {
          $b = $b->$sortmember();
         } else $b = "";                    
       } else {
        	// a is a and b is b
          }        
    return $this->sort_compare($a, $b, 
                    $this->obj_sort_prefs["trim"],
                    $this->obj_sort_prefs["upcase"],
                    $this->obj_sort_prefs["order"],
                    $this->obj_sort_prefs["type"],
                    0);
   }
  
  function sort_compare($a, $b, $trimflag = 0, $upcaseflag = 0, $orderflag =0, $ordertype = 0, $debugflag = 0) {
	if ($trimflag) {
	  $a = trim($a);
	  $b = trim($b);
	 }
	if ($upcaseflag) {
	  $a = strtoupper($a);
	  $b = strtoupper($b);
	 }
    if ($this->debug_flag)
      $this->write_debug_log(sprintf("container->sort_compare->(%s) =?= (%s)<br>", $a, $b));
	if ($orderflag) {
  	if ($ordertype) {
        return (strnatcmp($a, $b) * -1);
	   } else {
	       return (strcmp($a, $b) * -1);
	      }     
	 } else {
     	if ($ordertype) {
	       return strnatcmp($a, $b);
	      } else {
	          return strcmp($a, $b);
	         }
	    }
   }
   
  function sort_by_value($trimflag = 0, $upcaseflag = 0, $orderflag =0, $ordertype = 0, $debugflag = 0) {
    unset($this->obj_sort_key);
    unset($this->obj_sort_member);      	
    if ($this->debug_flag)
      $this->write_debug_log(sprintf("container->sort_by_value"));    
    $this->sorter($trimflag = 0, $upcaseflag = 0, $orderflag =0, $ordertype = 0, $debugflag = 0);
   }
   
  function sort_by_key($sortkey, $trimflag = 0, $upcaseflag = 0, $orderflag = 0, $ordertype = 0, $debugflag = 0) {
    $this->obj_sort_key = $sortkey;
    unset($this->obj_sort_member);
    if ($this->debug_flag)
      $this->write_debug_log(sprintf("container->sort_by_key"));    
    $this->sorter($trimflag = 0, $upcaseflag = 0, $orderflag =0, $ordertype = 0, $debugflag = 0);
   }
   
  function sort_by_member($sortmember, $trimflag = 0, $upcaseflag = 0, $orderflag = 0, $ordertype = 0, $debugflag = 0) {
    $this->obj_sort_member = $sortmember;
    unset($this->obj_sort_key);
    if ($this->debug_flag)
      $this->write_debug_log(sprintf("container->sort_by_member"));    
    $this->sorter($trimflag = 0, $upcaseflag = 0, $orderflag =0, $ordertype = 0, $debugflag = 0);    
   }
   
 }
?>

--=-C/Qu2FJm6U8GbCVlf6Yx
Content-Disposition: attachment; filename=mail_mesg.class
Content-Type: application/x-java-byte-code; name=mail_mesg.class
Content-Transfer-Encoding: 7bit

<?PHP

require_once("MIME.def");
require_once("output_sink.class");

class mail_mesg extends output_sink {
  var $destination;
  var $subject;
  var $reply_to;
  var $from;
  var $base64_func = '';	
  var $qp_func = ''; 
  var $mimeparts;
  
  function mail_mesg($destination = "", $subject = "", $from = "", $reply_to = "") {
    output_sink::output_sink();
    $this->write_debug_log("mail_mesg::mail_mesg()");
    if (strlen($destination) > 0) $this->destination = $destination;
    if (strlen($subject) > 0) $this->subject = $subject;  
    if (strlen($reply_to) > 0) $this->reply_to = $reply_to;
    if (strlen($from) > 0) $this->from = $from;
    $this->mimeparts = array();
   }
   
  function set_destination($destination) {
    $this->destination = $destination;
   }
   
  function set_subject($subject) {
    $this->subject = $subject;
   }
   
  function get_subject() {
    return $this->subject;
   }
   
  function set_from($from) {
    $this->from = $from;
   }
   
  function set_reply_to($reply_to) {
    $this->reply_to = $reply_to;
   } 
  
  function send_mesg() {
    $this->write_debug_log("mail_mesg::send_mesg()");
    $boundary = 'PM'.chr(rand(65, 91)).'------'.md5(uniqid(rand()));
    if (strlen($this->destination) == 0) {
      $this->set_error(0, "Mail Message has no destination");
      return 0;
     }
    if (strlen($this->from) == 0) $this->from = $this->destination;
    if (strlen($this->reply_to) == 0) $this->reply_to = $this->from;
    $this->write_debug_log(sprintf("mail_mesg::send_mesg() - Message has %d lines",
                             $this->get_count()));
    while ($counter < $this->get_count()) {
      $counter++;
      $this->set_position($counter);
      $body .= sprintf("%s\n", $this->get());
     }
    $email = "";
    $email  = "To: $this->destination".MIMECRLF;
    $email .= "From: $this->from".MIMECRLF;
    $email .= "Subject: " . $this->get_subject() . MIMECRLF;
    $email .= "X-Priority: 3".MIMECRLF;
    $email .= "X-Mailer: PHP/Apache/Linux".MIMECRLF;
    $email .= "Reply-To: $this->reply_to".MIMECRLF;
    $counter = 0;
    $body = "";
    while ($counter < $this->get_count()) {
      $counter++;
      $this->set_position($counter);
      $body .= sprintf("%s\n", $this->get());
     }
     
    if (sizeof($this->mimeparts) > 0) {
      $this->write_debug_log("mail_mesg::send_mesg() - This is a MIME message");
      $email .= "MIME-Version: 1.0" . MIMECRLF;
      $email .= "Content-Type: multipart/mixed;" . MIMECRLF;
      $email .= "\tboundary=\"" . $boundary . "\"" . MIMECRLF;
      $email .= "Content-Transfer-Encoding: ".MIMEBIT7.MIMECRLF;
      $email .= MIMECRLF.MIMEWARNING.MIMECRLF.MIMECRLF ;
      if (!empty($body)) {
		$this->attach($body, MIMEBODY, MIMETEXT, MIMEBIT7, "inline");
   	}
      for ($i=0 ; $i < sizeof($this->mimeparts); $i++) {
        if ($this->debug_flag)
          $this->write_debug_log(sprintf("mail_mesg:send_mesg() - Sending attachment %d", $i));        	
  	  if (!empty($this->mimeparts[$i])) 
	      $email .= MIMECRLF.'--'.$boundary.MIMECRLF.$this->mimeparts[$i].MIMECRLF;
       }
      $email .= '--'.$boundary.'--'.MIMECRLF;
     } else {
        $this->write_debug_log("mail_mesg::send_mesg() - This is a non-MIME message");
        $email .= MIMECRLF;
        $email .= "$body";
       }  
    $this->write_debug_log("mail_mesg::send_mesg() - Summoning MDA");
    $fp = popen("/usr/sbin/sendmail -t", "w");
    if ($fp == 0) {
       $this->write_debug_log("mail_mesg::send_mesg() - Summon Failed");
       $this->set_error(0, "popen to send mail failed");
       $this->write_debug_log("popen to send mail failed");
       return 0;
      }
    $this->write_debug_log($email);
    fwrite($fp, $email);
    pclose($fp);
    return 1;
   }
   
  function send() {
    $this->write_debug_log("mail_mesg::send_()");
    $this->send_mesg();
   }
   
  function attach_file($path, $description = "", $contenttype = MIMEOCTET, 
                       $encoding = MIMEBASE64, $disp = "attachment") {
    if ($this->debug_flag)
      $this->write_debug_log("mail_mesg:attach_file");
	if (!file_exists($path)) {
		$this->write_debug_log("File does not exist");
		return 0;
	}
	// Read in file
	$fp = fopen($path, "rb");	# (b)inary for Win compatability
	if (!$fp) {
		$this->write_debug_log("fopen() failed");
		return 0;	//failed
	}
	$contenttype .= ";\r\n\tname=".basename($path);
	$data = fread($fp, filesize($path));
	return $this->attach($data, 
			$description, 
			$contenttype,
			$encoding,
			$disp);	
  } 
  
 function attach($data, $description = "", $contenttype = MIMEOCTET, 
                 $encoding = MIMEBASE64, $disp = "attachment") {
    if ($this->debug_flag)
      $this->write_debug_log("mail_mesg:attach_file");                 	
	if (empty($data)) {
		$this->write_debug_log("No data to be attached");
		return 0;
	}
	if (trim($contenttype) == '') $contenttype  = MIMEOCTET ;
	if (trim($encoding) == '') $encoding = MIMEBASE64;
	if ($encoding == MIMEBIT7) $emsg = $data;
	elseif ($encoding == MIMEQP) 
		$emsg = $$this->qp_func($data);
	elseif ($encoding == MIMEBASE64) {
		if (!$this->base64_func) 	# Check if there is user-defined function
			$emsg = base64_encode($data);
		else 
			$emsg = $$this->base64_func($data);
	}
	$emsg = chunk_split($emsg);
	//Check if content-type is text/plain and if charset is not specified append default CHARSET
	if (preg_match("!^".MIMETEXT."!i", $contenttype) && !preg_match("!;charset=!i", $contenttype)) 
		$contenttype .= ";\r\n\tcharset=".MIMECHARSET ;
	$msg = sprintf("Content-Type: %sContent-Transfer-Encoding: %s%s%s%s",
	         $contenttype.MIMECRLF, 
	         $encoding.MIMECRLF,
	         ((($description) && (MIMEBODY != $description))?
	           "Content-Description: $description".MIMECRLF:""),
	         ($disp?"Content-Disposition: $disp".MIMECRLF:""), MIMECRLF.$emsg.MIMECRLF);
	if (MIMEBODY==$description) {
      if ($this->debug_flag)
        $this->write_debug_log("mail_mesg:attach_file:attaching body");  		
	  $this->mimeparts[0] = $msg;
	 } else {
         if ($this->debug_flag)
           $this->write_debug_log("mail_mesg:attach_file:attaching attachment");  	 
	     $this->mimeparts[sizeof($this->mimeparts) + 1] = $msg ;
         if ($this->debug_flag)
           $this->write_debug_log(
              sprintf("mail_mesg:attach_file:size of mimeparts %d", 
                sizeof($this->mimeparts)));  	 	     
	   }
	return sizeof($this->mimeparts);
  }    
 }

?>

--=-C/Qu2FJm6U8GbCVlf6Yx
Content-Disposition: attachment; filename=output_sink.class
Content-Type: application/x-java-byte-code; name=output_sink.class
Content-Transfer-Encoding: 7bit

<?PHP

require_once("container.class");

class output_sink extends container {

  function output_sink() {
    container::container();
   }

  function sink() {
   }
 }
--=-C/Qu2FJm6U8GbCVlf6Yx--