Source for file Rfc822Header.class.php

Documentation is available at Rfc822Header.class.php

  1. <?php
  2.  
  3. /**
  4.  * Rfc822Header.class.php
  5.  *
  6.  * This file contains functions needed to handle headers in mime messages.
  7.  *
  8.  * @copyright &copy; 2003-2006 The SquirrelMail Project Team
  9.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  10.  * @version $Id: Rfc822Header.class.php,v 1.17.2.26 2006/02/03 22:27:46 jervfors Exp $
  11.  * @package squirrelmail
  12.  * @subpackage mime
  13.  * @since 1.3.2
  14.  */
  15.  
  16. /**
  17.  * MIME header class
  18.  * input: header_string or array
  19.  * You must call parseHeader() function after creating object in order to fill object's
  20.  * parameters.
  21.  * @todo FIXME: there is no constructor function and class should ignore all input args.
  22.  * @package squirrelmail
  23.  * @subpackage mime
  24.  * @since 1.3.0
  25.  */
  26. class Rfc822Header {
  27.     /**
  28.      * Date header
  29.      * @var mixed 
  30.      */
  31.     var $date = -1;
  32.     /**
  33.      * Subject header
  34.      * @var string 
  35.      */
  36.     var $subject = '';
  37.     /**
  38.      * From header
  39.      * @var array 
  40.      */
  41.     var $from = array();
  42.     /**
  43.      * @var mixed 
  44.      */
  45.     var $sender = '';
  46.     /**
  47.      * Reply-To header
  48.      * @var array 
  49.      */
  50.     var $reply_to = array();
  51.     /**
  52.      * Mail-Followup-To header
  53.      * @var array 
  54.      */
  55.     var $mail_followup_to = array();
  56.     /**
  57.      * To header
  58.      * @var array 
  59.      */
  60.     var $to = array();
  61.     /**
  62.      * Cc header
  63.      * @var array 
  64.      */
  65.     var $cc = array();
  66.     /**
  67.      * Bcc header
  68.      * @var array 
  69.      */
  70.     var $bcc = array();
  71.     /**
  72.      * In-reply-to header
  73.      * @var string 
  74.      */
  75.     var $in_reply_to = '';
  76.     /**
  77.      * Message-ID header
  78.      * @var string 
  79.      */
  80.     var $message_id = '';
  81.     /**
  82.      * References header
  83.      * @var string 
  84.      */
  85.     var $references = '';
  86.     /**
  87.      * @var mixed 
  88.      */
  89.     var $mime = false;
  90.     /**
  91.      * @var mixed 
  92.      */
  93.     var $content_type = '';
  94.     /**
  95.      * @var mixed 
  96.      */
  97.     var $disposition = '';
  98.     /**
  99.      * X-Mailer header
  100.      * @var string 
  101.      */
  102.     var $xmailer = '';
  103.     /**
  104.      * Priority header
  105.      * @var integer 
  106.      */
  107.     var $priority = 3;
  108.     /**
  109.      * @var mixed 
  110.      */
  111.     var $dnt = '';
  112.     /**
  113.      * @var mixed 
  114.      */
  115.     var $encoding = '';
  116.     /**
  117.      * @var mixed 
  118.      */
  119.     var $mlist = array();
  120.     /**
  121.      * Extra header
  122.      * only needed for constructing headers in delivery class
  123.      * @var array 
  124.      */
  125.     var $more_headers = array();
  126.  
  127.     /**
  128.      * @param mixed $hdr string or array with message headers
  129.      */
  130.     function parseHeader($hdr{
  131.         if (is_array($hdr)) {
  132.             $hdr implode(''$hdr);
  133.         }
  134.         /* First we replace \r\n by \n and unfold the header */
  135.         /* FIXME: unfolding header with multiple spaces "\n( +)" */
  136.         $hdr trim(str_replace(array("\r\n""\n\t""\n "),array("\n"' '' ')$hdr));
  137.  
  138.         /* Now we can make a new header array with */
  139.         /* each element representing a headerline  */
  140.         $hdr explode("\n" $hdr);
  141.         foreach ($hdr as $line{
  142.             $pos strpos($line':');
  143.             if ($pos 0{
  144.                 $field substr($line0$pos);
  145.                 if (!strstr($field,' ')) /* valid field */
  146.                         $value trim(substr($line$pos+1));
  147.                         $this->parseField($field$value);
  148.                 }
  149.             }
  150.         }
  151.         if (!is_object($this->content_type)) {
  152.             $this->parseContentType('text/plain; charset=us-ascii');
  153.         }
  154.     }
  155.  
  156.     /**
  157.      * @param string $value 
  158.      * @return string 
  159.      */
  160.     function stripComments($value{
  161.         $result '';
  162.         $cnt strlen($value);
  163.         for ($i 0$i $cnt++$i{
  164.             switch ($value{$i}{
  165.                 case '"':
  166.                     $result .= '"';
  167.                     while ((++$i $cnt&& ($value{$i!= '"')) {
  168.                         if ($value{$i== '\\'{
  169.                             $result .= '\\';
  170.                             ++$i;
  171.                         }
  172.                         $result .= $value{$i};
  173.                     }
  174.                     $result .= $value{$i};
  175.                     break;
  176.                 case '(':
  177.                     $depth 1;
  178.                     while (($depth 0&& (++$i $cnt)) {
  179.                         switch($value{$i}{
  180.                             case '\\':
  181.                                 ++$i;
  182.                                 break;
  183.                             case '(':
  184.                                 ++$depth;
  185.                                 break;
  186.                             case ')':
  187.                                 --$depth;
  188.                                 break;
  189.                             default:
  190.                                 break;
  191.                         }
  192.                     }
  193.                     break;
  194.                 default:
  195.                     $result .= $value{$i};
  196.                     break;
  197.             }
  198.         }
  199.         return $result;
  200.     }
  201.  
  202.     /**
  203.      * Parse header field according to field type
  204.      * @param string $field field name
  205.      * @param string $value field value
  206.      */
  207.     function parseField($field$value{
  208.         $field strtolower($field);
  209.         switch($field{
  210.             case 'date':
  211.                 $value $this->stripComments($value);
  212.                 $d strtr($valuearray('  ' => ' '));
  213.                 $d explode(' '$d);
  214.                 $this->date = getTimeStamp($d);
  215.                 break;
  216.             case 'subject':
  217.                 $this->subject = $value;
  218.                 break;
  219.             case 'from':
  220.                 $this->from = $this->parseAddress($value,true);
  221.                 break;
  222.             case 'sender':
  223.                 $this->sender = $this->parseAddress($value);
  224.                 break;
  225.             case 'reply-to':
  226.                 $this->reply_to = $this->parseAddress($valuetrue);
  227.                 break;
  228.             case 'mail-followup-to':
  229.                 $this->mail_followup_to = $this->parseAddress($valuetrue);
  230.                 break;
  231.             case 'to':
  232.                 $this->to = $this->parseAddress($valuetrue);
  233.                 break;
  234.             case 'cc':
  235.                 $this->cc = $this->parseAddress($valuetrue);
  236.                 break;
  237.             case 'bcc':
  238.                 $this->bcc = $this->parseAddress($valuetrue);
  239.                 break;
  240.             case 'in-reply-to':
  241.                 $this->in_reply_to = $value;
  242.                 break;
  243.             case 'message-id':
  244.                 $value $this->stripComments($value);
  245.                 $this->message_id = $value;
  246.                 break;
  247.             case 'references':
  248.                 $value $this->stripComments($value);
  249.                 $this->references = $value;
  250.                 break;
  251.             case 'x-confirm-reading-to':
  252.             case 'return-receipt-to':
  253.             case 'disposition-notification-to':
  254.                 $value $this->stripComments($value);
  255.                 $this->dnt = $this->parseAddress($value);
  256.                 break;
  257.             case 'mime-version':
  258.                 $value $this->stripComments($value);
  259.                 $value str_replace(' '''$value);
  260.                 $this->mime = ($value == '1.0' true $this->mime);
  261.                 break;
  262.             case 'content-type':
  263.                 $value $this->stripComments($value);
  264.                 $this->parseContentType($value);
  265.                 break;
  266.             case 'content-disposition':
  267.                 $value $this->stripComments($value);
  268.                 $this->parseDisposition($value);
  269.                 break;
  270.             case 'user-agent':
  271.             case 'x-mailer':
  272.                 $this->xmailer = $value;
  273.                 break;
  274.             case 'x-priority':
  275.             case 'importance':
  276.             case 'priority':
  277.                 $this->priority = $this->parsePriority($value);
  278.                 break;
  279.             case 'list-post':
  280.                 $value $this->stripComments($value);
  281.                 $this->mlist('post'$value);
  282.                 break;
  283.             case 'list-reply':
  284.                 $value $this->stripComments($value);
  285.                 $this->mlist('reply'$value);
  286.                 break;
  287.             case 'list-subscribe':
  288.                 $value $this->stripComments($value);
  289.                 $this->mlist('subscribe'$value);
  290.                 break;
  291.             case 'list-unsubscribe':
  292.                 $value $this->stripComments($value);
  293.                 $this->mlist('unsubscribe'$value);
  294.                 break;
  295.             case 'list-archive':
  296.                 $value $this->stripComments($value);
  297.                 $this->mlist('archive'$value);
  298.                 break;
  299.             case 'list-owner':
  300.                 $value $this->stripComments($value);
  301.                 $this->mlist('owner'$value);
  302.                 break;
  303.             case 'list-help':
  304.                 $value $this->stripComments($value);
  305.                 $this->mlist('help'$value);
  306.                 break;
  307.             case 'list-id':
  308.                 $value $this->stripComments($value);
  309.                 $this->mlist('id'$value);
  310.                 break;
  311.             default:
  312.                 break;
  313.         }
  314.     }
  315.  
  316.     /**
  317.      * @param string $address 
  318.      * @return array 
  319.      */
  320.     function getAddressTokens($address{
  321.         $aTokens array();
  322.         $aAddress array();
  323.         $aSpecials array('(' ,'<' ,',' ,';' ,':');
  324.         $aReplace =  array(' (',' <',' ,',' ;',' :');
  325.         $address str_replace($aSpecials,$aReplace,$address);
  326.         $iCnt strlen($address);
  327.         $i 0;
  328.         while ($i $iCnt{
  329.             $cChar $address{$i};
  330.             switch($cChar)
  331.             {
  332.             case '<':
  333.                 $iEnd strpos($address,'>',$i+1);
  334.                 if (!$iEnd{
  335.                    $sToken substr($address,$i);
  336.                    $i $iCnt;
  337.                 else {
  338.                    $sToken substr($address,$i,$iEnd $i +1);
  339.                    $i $iEnd;
  340.                 }
  341.                 $sToken str_replace($aReplace$aSpecials,$sToken);
  342.                 if ($sToken$aTokens[$sToken;
  343.                 break;
  344.             case '"':
  345.                 $iEnd strpos($address,$cChar,$i+1);
  346.                 if ($iEnd{
  347.                    // skip escaped quotes
  348.                    $prev_char $address{$iEnd-1};
  349.                    while ($prev_char === '\\' && substr($address,$iEnd-2,2!== '\\\\'{
  350.                        $iEnd strpos($address,$cChar,$iEnd+1);
  351.                        if ($iEnd{
  352.                           $prev_char $address{$iEnd-1};
  353.                        else {
  354.                           $prev_char false;
  355.                        }
  356.                    }
  357.                 }
  358.                 if (!$iEnd{
  359.                     $sToken substr($address,$i);
  360.                     $i $iCnt;
  361.                 else {
  362.                     // also remove the surrounding quotes
  363.                     $sToken substr($address,$i+1,$iEnd $i -1);
  364.                     $i $iEnd;
  365.                 }
  366.                 $sToken str_replace($aReplace$aSpecials,$sToken);
  367.                 if ($sToken$aTokens[$sToken;
  368.                 break;
  369.             case '(':
  370.                 array_pop($aTokens)//remove inserted space
  371.                 $iEnd strpos($address,')',$i);
  372.                 if (!$iEnd{
  373.                     $sToken substr($address,$i);
  374.                     $i $iCnt;
  375.                 else {
  376.                     $iDepth 1;
  377.                     $iComment $i;
  378.                     while (($iDepth 0&& (++$iComment $iCnt)) {
  379.                         $cCharComment $address{$iComment};
  380.                         switch($cCharComment{
  381.                             case '\\':
  382.                                 ++$iComment;
  383.                                 break;
  384.                             case '(':
  385.                                 ++$iDepth;
  386.                                 break;
  387.                             case ')':
  388.                                 --$iDepth;
  389.                                 break;
  390.                             default:
  391.                                 break;
  392.                         }
  393.                     }
  394.                     if ($iDepth == 0{
  395.                         $sToken substr($address,$i,$iComment $i +1);
  396.                         $i $iComment;
  397.                     else {
  398.                         $sToken substr($address,$i,$iEnd $i 1);
  399.                         $i $iEnd;
  400.                     }
  401.                 }
  402.                 // check the next token in case comments appear in the middle of email addresses
  403.                 $prevToken end($aTokens);
  404.                 if (!in_array($prevToken,$aSpecials,true)) {
  405.                     if ($i+1<strlen($address&& !in_array($address{$i+1},$aSpecials,true)) {
  406.                         $iEnd strpos($address,' ',$i+1);
  407.                         if ($iEnd{
  408.                             $sNextToken trim(substr($address,$i+1,$iEnd $i -1));
  409.                             $i $iEnd-1;
  410.                         else {
  411.                             $sNextToken trim(substr($address,$i+1));
  412.                             $i $iCnt;
  413.                         }
  414.                         // remove the token
  415.                         array_pop($aTokens);
  416.                         // create token and add it again
  417.                         $sNewToken $prevToken $sNextToken;
  418.                         if($sNewToken$aTokens[$sNewToken;
  419.                     }
  420.                 }
  421.                 $sToken str_replace($aReplace$aSpecials,$sToken);
  422.                 if ($sToken$aTokens[$sToken;
  423.                 break;
  424.             case ',':
  425.             case ':':
  426.             case ';':
  427.             case ' ':
  428.                 $aTokens[$cChar;
  429.                 break;
  430.             default:
  431.                 $iEnd strpos($address,' ',$i+1);
  432.                 if ($iEnd{
  433.                     $sToken trim(substr($address,$i,$iEnd $i));
  434.                     $i $iEnd-1;
  435.                 else {
  436.                     $sToken trim(substr($address,$i));
  437.                     $i $iCnt;
  438.                 }
  439.                 if ($sToken$aTokens[$sToken;
  440.             }
  441.             ++$i;
  442.         }
  443.         return $aTokens;
  444.     }
  445.  
  446.     /**
  447.      * @param array $aStack 
  448.      * @param array $aComment 
  449.      * @param string $sEmail 
  450.      * @param string $sGroup 
  451.      * @return object AddressStructure object
  452.      */
  453.     function createAddressObject(&$aStack,&$aComment,&$sEmail,$sGroup=''{
  454.         //$aStack=explode(' ',implode('',$aStack));
  455.         if (!$sEmail{
  456.             while (count($aStack&& !$sEmail{
  457.                 $sEmail trim(array_pop($aStack));
  458.             }
  459.         }
  460.         if (count($aStack)) {
  461.             $sPersonal trim(implode('',$aStack));
  462.         else {
  463.             $sPersonal '';
  464.         }
  465.         if (!$sPersonal && count($aComment)) {
  466.             $sComment trim(implode(' ',$aComment));
  467.             $sPersonal .= $sComment;
  468.         }
  469.         $oAddr =new AddressStructure();
  470.         if ($sPersonal && substr($sPersonal,0,2== '=?'{
  471.             $oAddr->personal encodeHeader($sPersonal);
  472.         else {
  473.             $oAddr->personal $sPersonal;
  474.         }
  475.  //       $oAddr->group = $sGroup;
  476.         $iPosAt strpos($sEmail,'@');
  477.         if ($iPosAt{
  478.            $oAddr->mailbox substr($sEmail0$iPosAt);
  479.            $oAddr->host substr($sEmail$iPosAt+1);
  480.         else {
  481.            $oAddr->mailbox $sEmail;
  482.            $oAddr->host false;
  483.         }
  484.         $sEmail '';
  485.         $aStack $aComment array();
  486.         return $oAddr;
  487.     }
  488.  
  489.     /**
  490.      * recursive function for parsing address strings and storing them in an address stucture object.
  491.      *  personal name: encoded: =?charset?Q|B?string?=
  492.      *                 quoted:  "string"
  493.      *                 normal:  string
  494.      *  email        : <mailbox@host>
  495.      *               : mailbox@host
  496.      *  This function is also used for validating addresses returned from compose
  497.      *  That's also the reason that the function became a little bit huge
  498.      * @param string $address 
  499.      * @param boolean $ar return array instead of only the first element
  500.      * @param array $addr_ar (obsolete) array with parsed addresses
  501.      * @param string $group (obsolete)
  502.      * @param string $host default domainname in case of addresses without a domainname
  503.      * @param string $lookup (since) callback function for lookup of address strings which are probably nicks (without @)
  504.      * @return mixed array with AddressStructure objects or only one address_structure object.
  505.      */
  506.     function parseAddress($address,$ar=false,$aAddress=array(),$sGroup='',$sHost='',$lookup=false{
  507.         $aTokens $this->getAddressTokens($address);
  508.         $sPersonal $sEmail $sComment $sGroup '';
  509.         $aStack $aComment array();
  510.         foreach ($aTokens as $sToken{
  511.             $cChar $sToken{0};
  512.             switch ($cChar)
  513.             {
  514.             case '=':
  515.             case '"':
  516.             case ' ':
  517.                 $aStack[$sToken;
  518.                 break;
  519.             case '(':
  520.                 $aComment[substr($sToken,1,-1);
  521.                 break;
  522.             case ';':
  523.                 if ($sGroup{
  524.                     $aAddress[$this->createAddressObject($aStack,$aComment,$sEmail,$sGroup);
  525.                     $oAddr end($aAddress);
  526.                     if(!$oAddr || ((isset($oAddr)) && !$oAddr->mailbox && !$oAddr->personal)) {
  527.                         $sEmail $sGroup ':;';
  528.                     }
  529.                     $aAddress[$this->createAddressObject($aStack,$aComment,$sEmail,$sGroup);
  530.                     $sGroup '';
  531.                     $aStack $aComment array();
  532.                     break;
  533.                 }
  534.             case ',':
  535.                 $aAddress[$this->createAddressObject($aStack,$aComment,$sEmail,$sGroup);
  536.                 break;
  537.             case ':':
  538.                 $sGroup trim(implode(' ',$aStack));
  539.                 $sGroup preg_replace('/\s+/',' ',$sGroup);
  540.                 $aStack array();
  541.                 break;
  542.             case '<':
  543.                $sEmail trim(substr($sToken,1,-1));
  544.                break;
  545.             case '>':
  546.                /* skip */
  547.                break;
  548.             default$aStack[$sTokenbreak;
  549.             }
  550.         }
  551.         /* now do the action again for the last address */
  552.         $aAddress[$this->createAddressObject($aStack,$aComment,$sEmail);
  553.         /* try to lookup the addresses in case of invalid email addresses */
  554.         $aProcessedAddress array();
  555.         foreach ($aAddress as $oAddr{
  556.           $aAddrBookAddress array();
  557.           if (!$oAddr->host{
  558.             $grouplookup false;
  559.             if ($lookup{
  560.                  $aAddr call_user_func_array($lookup,array($oAddr->mailbox));
  561.                  if (isset($aAddr['email'])) {
  562.                      if (strpos($aAddr['email'],',')) {
  563.                          $grouplookup true;
  564.                          $aAddrBookAddress $this->parseAddress($aAddr['email'],true);
  565.                      else {
  566.                          $iPosAt strpos($aAddr['email']'@');
  567.                          $oAddr->mailbox substr($aAddr['email']0$iPosAt);
  568.                          $oAddr->host substr($aAddr['email']$iPosAt+1);
  569.                          if (isset($aAddr['name'])) {
  570.                              $oAddr->personal $aAddr['name'];
  571.                          else {
  572.                              $oAddr->personal encodeHeader($sPersonal);
  573.                          }
  574.                      }
  575.                  }
  576.             }
  577.             if (!$grouplookup && !$oAddr->mailbox{
  578.                 $oAddr->mailbox trim($sEmail);
  579.                 if ($sHost && $oAddr->mailbox{
  580.                     $oAddr->host $sHost;
  581.                 }
  582.             else if (!$grouplookup && !$oAddr->host{
  583.                 if ($sHost && $oAddr->mailbox{
  584.                     $oAddr->host $sHost;
  585.                 }
  586.             }
  587.           }
  588.           if (!$aAddrBookAddress && $oAddr->mailbox{
  589.               $aProcessedAddress[$oAddr;
  590.           else {
  591.               $aProcessedAddress array_merge($aProcessedAddress,$aAddrBookAddress);
  592.           }
  593.         }
  594.         if ($ar{
  595.             return $aProcessedAddress;
  596.         else {
  597.             return $aProcessedAddress[0];
  598.         }
  599.     }
  600.  
  601.     /**
  602.      * Normalise the different Priority headers into a uniform value,
  603.      * namely that of the X-Priority header (1, 3, 5). Supports:
  604.      * Priority, X-Priority, Importance.
  605.      * X-MS-Mail-Priority is not parsed because it always coincides
  606.      * with one of the other headers.
  607.      *
  608.      * NOTE: this is actually a duplicate from the function in
  609.      * functions/imap_messages. I'm not sure if it's ok here to call
  610.      * that function?
  611.      * @param string $sValue literal priority name
  612.      * @return integer 
  613.      */
  614.     function parsePriority($sValue{
  615.         // don't use function call inside array_shift.
  616.         $aValue split('/\w/',trim($sValue));
  617.         $value strtolower(array_shift($aValue));
  618.  
  619.         if is_numeric($value) ) {
  620.             return $value;
  621.         }
  622.         if $value == 'urgent' || $value == 'high' {
  623.             return 1;
  624.         elseif $value == 'non-urgent' || $value == 'low' {
  625.             return 5;
  626.         }
  627.         // default is normal priority
  628.         return 3;
  629.     }
  630.  
  631.     /**
  632.      * @param string $value content type header
  633.      */
  634.     function parseContentType($value{
  635.         $pos strpos($value';');
  636.         $props '';
  637.         if ($pos 0{
  638.            $type trim(substr($value0$pos));
  639.            $props trim(substr($value$pos+1));
  640.         else {
  641.            $type $value;
  642.         }
  643.         $content_type new ContentType($type);
  644.         if ($props{
  645.             $properties $this->parseProperties($props);
  646.             if (!isset($properties['charset'])) {
  647.                 $properties['charset''us-ascii';
  648.             }
  649.             $content_type->properties $this->parseProperties($props);
  650.         }
  651.         $this->content_type = $content_type;
  652.     }
  653.  
  654.     /**
  655.      * RFC2184
  656.      * @param array $aParameters 
  657.      * @return array 
  658.      */
  659.     function processParameters($aParameters{
  660.         $aResults array();
  661.         $aCharset array();
  662.         // handle multiline parameters
  663.         foreach($aParameters as $key => $value{
  664.             if ($iPos strpos($key,'*')) {
  665.                 $sKey substr($key,0,$iPos);
  666.                 if (!isset($aResults[$sKey])) {
  667.                     $aResults[$sKey$value;
  668.                     if (substr($key,-1== '*'// parameter contains language/charset info
  669.                         $aCharset[$sKey;
  670.                     }
  671.                 else {
  672.                     $aResults[$sKey.= $value;
  673.                 }
  674.             else {
  675.                 $aResults[$key$value;
  676.             }
  677.         }
  678.         foreach ($aCharset as $key{
  679.             $value $aResults[$key];
  680.             // extract the charset & language
  681.             $charset substr($value,0,strpos($value,"'"));
  682.             $value substr($value,strlen($charset)+1);
  683.             $language substr($value,0,strpos($value,"'"));
  684.             $value substr($value,strlen($charset)+1);
  685.             /* FIXME: What's the status of charset decode with language information ????
  686.              * Maybe language information contains only ascii text and charset_decode() 
  687.              * only runs htmlspecialchars() on it. If it contains 8bit information, you 
  688.              * get html encoded text in charset used by selected translation.
  689.              */
  690.             $value charset_decode($charset,$value);
  691.             $aResults[$key$value;
  692.         }
  693.         return $aResults;
  694.     }
  695.  
  696.     /**
  697.      * @param string $value 
  698.      * @return array 
  699.      */
  700.     function parseProperties($value{
  701.         $propArray explode(';'$value);
  702.         $propResultArray array();
  703.         foreach ($propArray as $prop{
  704.             $prop trim($prop);
  705.             $pos strpos($prop'=');
  706.             if ($pos 0)  {
  707.                 $key trim(substr($prop0$pos));
  708.                 $val trim(substr($prop$pos+1));
  709.                 if (strlen($val&& $val{0== '"'{
  710.                     $val substr($val1-1);
  711.                 }
  712.                 $propResultArray[$key$val;
  713.             }
  714.         }
  715.         return $this->processParameters($propResultArray);
  716.     }
  717.  
  718.     /**
  719.      * Fills disposition object in rfc822Header object
  720.      * @param string $value 
  721.      */
  722.     function parseDisposition($value{
  723.         $pos strpos($value';');
  724.         $props '';
  725.         if ($pos 0{
  726.             $name trim(substr($value0$pos));
  727.             $props trim(substr($value$pos+1));
  728.         else {
  729.             $name $value;
  730.         }
  731.         $props_a $this->parseProperties($props);
  732.         $disp new Disposition($name);
  733.         $disp->properties $props_a;
  734.         $this->disposition = $disp;
  735.     }
  736.  
  737.     /**
  738.      * Fills mlist array keys in rfc822Header object
  739.      * @param string $field 
  740.      * @param string $value 
  741.      */
  742.     function mlist($field$value{
  743.         $res_a array();
  744.         $value_a explode(','$value);
  745.         foreach ($value_a as $val{
  746.             $val trim($val);
  747.             if ($val{0== '<'{
  748.                 $val substr($val1-1);
  749.             }
  750.             if (substr($val07== 'mailto:'{
  751.                 $res_a['mailto'substr($val7);
  752.             else {
  753.                 $res_a['href'$val;
  754.             }
  755.         }
  756.         $this->mlist[$field$res_a;
  757.     }
  758.  
  759.     /**
  760.      * function to get the address strings out of the header.
  761.      * example1: header->getAddr_s('to').
  762.      * example2: header->getAddr_s(array('to', 'cc', 'bcc'))
  763.      * @param mixed $arr string or array of strings
  764.      * @param string $separator 
  765.      * @param boolean $encoded (since 1.4.0) return encoded or plain text addresses
  766.      * @return string 
  767.      */
  768.     function getAddr_s($arr$separator ',',$encoded=false{
  769.         $s '';
  770.  
  771.         if (is_array($arr)) {
  772.             foreach($arr as $arg{
  773.                 if ($this->getAddr_s($arg$separator$encoded)) {
  774.                     $s .= $separator;
  775.                 }
  776.             }
  777.             $s ($s substr($s2$s);
  778.         else {
  779.             $addr $this->{$arr};
  780.             if (is_array($addr)) {
  781.                 foreach ($addr as $addr_o{
  782.                     if (is_object($addr_o)) {
  783.                         if ($encoded{
  784.                             $s .= $addr_o->getEncodedAddress($separator;
  785.                         else {
  786.                             $s .= $addr_o->getAddress($separator;
  787.                         }
  788.                     }
  789.                 }
  790.                 $s substr($s0-strlen($separator));
  791.             else {
  792.                 if (is_object($addr)) {
  793.                     if ($encoded{
  794.                         $s .= $addr->getEncodedAddress();
  795.                     else {
  796.                         $s .= $addr->getAddress();
  797.                     }
  798.                 }
  799.             }
  800.         }
  801.         return $s;
  802.     }
  803.  
  804.     /**
  805.      * function to get the array of addresses out of the header.
  806.      * @param mixed $arg string or array of strings
  807.      * @param array $excl_arr array of excluded email addresses
  808.      * @param array $arr array of added email addresses
  809.      * @return array 
  810.      */
  811.     function getAddr_a($arg$excl_arr array()$arr array()) {
  812.         if (is_array($arg)) {
  813.             foreach($arg as $argument{
  814.                 $arr $this->getAddr_a($argument$excl_arr$arr);
  815.             }
  816.         else {
  817.             $addr $this->{$arg};
  818.             if (is_array($addr)) {
  819.                 foreach ($addr as $next_addr{
  820.                     if (is_object($next_addr)) {
  821.                         if (isset($next_addr->host&& ($next_addr->host != '')) {
  822.                             $email $next_addr->mailbox '@' $next_addr->host;
  823.                         else {
  824.                             $email $next_addr->mailbox;
  825.                         }
  826.                         $email strtolower($email);
  827.                         if ($email && !isset($arr[$email]&& !isset($excl_arr[$email])) {
  828.                             $arr[$email$next_addr->personal;
  829.                         }
  830.                     }
  831.                 }
  832.             else {
  833.                 if (is_object($addr)) {
  834.                     $email  $addr->mailbox;
  835.                     $email .= (isset($addr->host'@' $addr->host '');
  836.                     $email  strtolower($email);
  837.                     if ($email && !isset($arr[$email]&& !isset($excl_arr[$email])) {
  838.                         $arr[$email$addr->personal;
  839.                     }
  840.                 }
  841.             }
  842.         }
  843.         return $arr;
  844.     }
  845.  
  846.     /**
  847.      * @param mixed $address array or string
  848.      * @param boolean $recurs 
  849.      * @return mixed array, boolean
  850.      * @since 1.3.2
  851.      */
  852.     function findAddress($address$recurs false{
  853.         $result false;
  854.         if (is_array($address)) {
  855.             $i=0;
  856.             foreach($address as $argument{
  857.                 $match $this->findAddress($argumenttrue);
  858.                 $last end($match);
  859.                 if ($match[1]{
  860.                     return $i;
  861.                 else {
  862.                     if (count($match[0]&& !$result{
  863.                         $result $i;
  864.                     }
  865.                 }
  866.                 ++$i;
  867.             }
  868.         else {
  869.             if (!is_array($this->cc)) $this->cc array();
  870.             $srch_addr $this->parseAddress($address);
  871.             $results array();
  872.             foreach ($this->to as $to{
  873.                 if ($to->host == $srch_addr->host{
  874.                     if ($to->mailbox == $srch_addr->mailbox{
  875.                         $results[$srch_addr;
  876.                         if ($to->personal == $srch_addr->personal{
  877.                             if ($recurs{
  878.                                 return array($resultstrue);
  879.                             else {
  880.                                 return true;
  881.                             }
  882.                         }
  883.                     }
  884.                 }
  885.             }
  886.             foreach ($this->cc as $cc{
  887.                 if ($cc->host == $srch_addr->host{
  888.                     if ($cc->mailbox == $srch_addr->mailbox{
  889.                         $results[$srch_addr;
  890.                         if ($cc->personal == $srch_addr->personal{
  891.                             if ($recurs{
  892.                                 return array($resultstrue);
  893.                             else {
  894.                                 return true;
  895.                             }
  896.                         }
  897.                     }
  898.                 }
  899.             }
  900.             if ($recurs{
  901.                 return array($resultsfalse);
  902.             elseif (count($result)) {
  903.                 return true;
  904.             else {
  905.                 return false;
  906.             }
  907.         }
  908.         //exit;
  909.         return $result;
  910.     }
  911.  
  912.     /**
  913.      * @param string $type0 media type
  914.      * @param string $type1 media subtype
  915.      * @return array media properties
  916.      * @todo check use of media type arguments
  917.      */
  918.     function getContentType($type0$type1{
  919.         $type0 $this->content_type->type0;
  920.         $type1 $this->content_type->type1;
  921.         return $this->content_type->properties;
  922.     }
  923. }
  924.  
  925. ?>

Documentation generated on Sat, 07 Oct 2006 16:33:16 +0300 by phpDocumentor 1.3.0RC6