b2evolution PHP Cross Reference Blogging Systems

Source: /inc/_ext/mime_parser/rfc822_addresses.php - 905 lines - 20232 bytes - Summary - Text - Print

   1  <?php
   2  /*
   3   * rfc822_addresses.php
   4   *
   5   * @(#) $Id: rfc822_addresses.php 1180 2012-04-05 00:48:28Z sam2kb $
   6   *
   7   */
   8  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
   9  
  10  /*
  11  {metadocument}<?xml version="1.0" encoding="ISO-8859-1" ?>
  12  <class>
  13  
  14      <package>net.manuellemos.mimeparser</package>
  15  
  16      <version>@(#) $Id: rfc822_addresses.php 1180 2012-04-05 00:48:28Z sam2kb $</version>
  17      <copyright>Copyright  (C) Manuel Lemos 2006 - 2008</copyright>
  18      <title>RFC 822 e-mail addresses parser</title>
  19      <author>Manuel Lemos</author>
  20      <authoraddress>mlemos-at-acm.org</authoraddress>
  21  
  22      <documentation>
  23          <idiom>en</idiom>
  24          <purpose>Parse e-mail addresses from headers of <link>
  25                  <url>http://www.ietf.org/rfc/rfc822.txt</url>
  26                  <data>RFC 822</data>
  27              </link> compliant e-mail messages.</purpose>
  28          <usage>Use the function <functionlink>ParseAddressList</functionlink>
  29              function to retrieve the list of e-mail addresses contained in
  30              e-mail message headers like <tt>From</tt>, <tt>To</tt>, <tt>Cc</tt>
  31              or <tt>Bcc</tt>.</usage>
  32      </documentation>
  33  
  34  {/metadocument}
  35  */
  36  
  37  class rfc822_addresses_class
  38  {
  39      /* Private variables */
  40  
  41      var $v = '';
  42  
  43      /* Public variables */
  44  
  45  /*
  46  {metadocument}
  47      <variable>
  48          <name>error</name>
  49          <type>STRING</type>
  50          <value></value>
  51          <documentation>
  52              <purpose>Store the message that is returned when an error
  53                  occurs.</purpose>
  54              <usage>Check this variable to understand what happened when a call to
  55                  any of the class functions has failed.<paragraphbreak />
  56                  This class uses cumulative error handling. This means that if one
  57                  class functions that may fail is called and this variable was
  58                  already set to an error message due to a failure in a previous call
  59                  to the same or other function, the function will also fail and does
  60                  not do anything.<paragraphbreak />
  61                  This allows programs using this class to safely call several
  62                  functions that may fail and only check the failure condition after
  63                  the last function call.<paragraphbreak />
  64                  Just set this variable to an empty string to clear the error
  65                  condition.</usage>
  66          </documentation>
  67      </variable>
  68  {/metadocument}
  69  */
  70      var $error = '';
  71  
  72  /*
  73  {metadocument}
  74      <variable>
  75          <name>error_position</name>
  76          <type>INTEGER</type>
  77          <value>-1</value>
  78          <documentation>
  79              <purpose>Point to the position of the message data or file that
  80                  refers to the last error that occurred.</purpose>
  81              <usage>Check this variable to determine the relevant position of the
  82                  message when a parsing error occurs.</usage>
  83          </documentation>
  84      </variable>
  85  {/metadocument}
  86  */
  87      var $error_position = -1;
  88  
  89  /*
  90  {metadocument}
  91      <variable>
  92          <name>ignore_syntax_errors</name>
  93          <type>BOOLEAN</type>
  94          <value>1</value>
  95          <documentation>
  96              <purpose>Specify whether the class should ignore syntax errors in
  97                  malformed addresses.</purpose>
  98              <usage>Set this variable to <booleanvalue>0</booleanvalue> if it is
  99                  necessary to verify whether message data may be corrupted due to
 100                  to eventual bugs in the program that generated the
 101                  message.<paragraphbreak />
 102                  Currently the class only ignores some types of syntax errors.
 103                  Other syntax errors may still cause the
 104                  <functionlink>ParseAddressList</functionlink> to fail.</usage>
 105          </documentation>
 106      </variable>
 107  {/metadocument}
 108  */
 109      var $ignore_syntax_errors=1;
 110  
 111  /*
 112  {metadocument}
 113      <variable>
 114          <name>warnings</name>
 115          <type>HASH</type>
 116          <value></value>
 117          <documentation>
 118              <purpose>Return a list of positions of the original message that
 119                  contain syntax errors.</purpose>
 120              <usage>Check this variable to retrieve eventual message syntax
 121                  errors that were ignored when the
 122                  <variablelink>ignore_syntax_errors</variablelink> is set to
 123                  <booleanvalue>1</booleanvalue>.<paragraphbreak />
 124                  The indexes of this array are the positions of the errors. The
 125                  array values are the corresponding syntax error messages.</usage>
 126          </documentation>
 127      </variable>
 128  {/metadocument}
 129  */
 130      var $warnings=array();
 131  
 132      /* Private functions */
 133  
 134      Function SetError($error)
 135      {
 136          $this->error = $error;
 137          return(0);
 138      }
 139  
 140      Function SetPositionedError($error, $position)
 141      {
 142          $this->error_position = $position;
 143          return($this->SetError($error));
 144      }
 145  
 146      Function SetWarning($warning, $position)
 147      {
 148          $this->warnings[$position]=$warning;
 149          return(1);
 150      }
 151  
 152      Function SetPositionedWarning($error, $position)
 153      {
 154          if(!$this->ignore_syntax_errors)
 155              return($this->SetPositionedError($error, $position));
 156          return($this->SetWarning($error, $position));
 157      }
 158  
 159      Function QDecode($p, &$value, &$encoding)
 160      {
 161          $encoding = $charset = null;
 162          $s = 0;
 163          $decoded = '';
 164          $l = strlen($value);
 165          while($s < $l)
 166          {
 167              if(GetType($q = strpos($value, '=?', $s)) != 'integer')
 168              {
 169                  if($s == 0)
 170                      return(1);
 171                  if($s < $l)
 172                      $decoded .= substr($value, $s);
 173                  break;
 174              }
 175              if($s < $q)
 176                  $decoded .= substr($value, $s, $q - $s);
 177              $q += 2;
 178              if(GetType($c = strpos($value, '?', $q)) != 'integer'
 179              || $q == $c)
 180                  return($this->SetPositionedWarning('invalid Q-encoding character set', $p + $q));
 181              if(IsSet($charset))
 182              {
 183                  $another_charset = strtolower(substr($value, $q, $c - $q));
 184                  if(strcmp($charset, $another_charset)
 185                  && strcmp($another_charset, 'ascii'))
 186                      return($this->SetWarning('it is not possible to decode an encoded value using mixed character sets into a single value', $p + $q));
 187              }
 188              else
 189              {
 190                  $charset = strtolower(substr($value, $q, $c - $q));
 191                  if(!strcmp($charset, 'ascii'))
 192                      $charset = null;
 193              }
 194              ++$c;
 195              if(GetType($t = strpos($value, '?', $c)) != 'integer'
 196              || $c==$t)
 197                  return($this->SetPositionedWarning('invalid Q-encoding type', $p + $c));
 198              $type = strtolower(substr($value, $c, $t - $c));
 199              ++$t;
 200              if(GetType($e = strpos($value, '?=', $t)) != 'integer')
 201                  return($this->SetPositionedWarning('invalid Q-encoding encoded data', $p + $e));
 202              switch($type)
 203              {
 204                  case 'q':
 205                      for($s = $t; $s<$e;)
 206                      {
 207                          switch($b = $value[$s])
 208                          {
 209                              case '=':
 210                                  $h = HexDec($hex = strtolower(substr($value, $s + 1, 2)));
 211                                  if($s + 3 > $e
 212                                  || strcmp(sprintf('%02x', $h), $hex))
 213                                      return($this->SetPositionedWarning('invalid Q-encoding q encoded data', $p + $s));
 214                                  $decoded .= chr($h);
 215                                  $s += 3;
 216                                  break;
 217  
 218                              case '_':
 219                                  $decoded .= ' ';
 220                                  ++$s;
 221                                  break;
 222  
 223                              default:
 224                                  $decoded .= $b;
 225                                  ++$s;
 226                          }
 227                      }
 228                      break;
 229  
 230                  case 'b':
 231                      if($e <= $t
 232                      || strlen($binary = base64_decode($data = substr($value, $t, $e - $t))) == 0
 233                      || GetType($binary) != 'string')
 234                          return($this->SetPositionedWarning('invalid Q-encoding b encoded data', $p + $t));
 235                      $decoded .= $binary;
 236                      $s = $e;
 237                      break;
 238  
 239                  default:
 240                      return($this->SetPositionedWarning('Q-encoding '.$type.' is not yet supported', $p + $c));
 241              }
 242              $s += 2;
 243              $s += strspn($value, " \t", $s);
 244          }
 245          $value = $decoded;
 246          $encoding = $charset;
 247          return(1);
 248      }
 249  
 250      Function ParseCText(&$p, &$c_text)
 251      {
 252          $c_text = null;
 253          $v = $this->v;
 254          if($p<strlen($v)
 255          && GetType(strchr("\t\r\n ()\\\0", $c = $v[$p])) != 'string'
 256          && Ord($c)<128)
 257          {
 258              $c_text = $c;
 259              ++$p;
 260          }
 261          return(1);
 262      }
 263  
 264      Function ParseQText(&$p, &$q_text)
 265      {
 266          $q_text = null;
 267          $v = $this->v;
 268          if($p>strlen($v)
 269          || GetType(strchr("\t\r\n \"\\\0", $c = $v[$p])) == 'string')
 270              return(1);
 271          if(Ord($c) >= 128)
 272          {
 273              if(!$this->ignore_syntax_errors)
 274                  return(1);
 275              $this->SetPositionedWarning('it was used an unencoded 8 bit character', $p);
 276          }
 277          $q_text = $c;
 278          ++$p;
 279          return(1);
 280      }
 281  
 282      Function ParseQuotedPair(&$p, &$quoted_pair)
 283      {
 284          $quoted_pair = null;
 285          $v = $this->v;
 286          $l = strlen($v);
 287          if($p+1 < $l
 288          && !strcmp($v[$p], '\\')
 289          && GetType(strchr("\r\n\0", $c = $v[$p + 1])) != 'string'
 290          && Ord($c)<128)
 291          {
 292              $quoted_pair = $c;
 293              $p += 2;
 294          }
 295          return(1);
 296      }
 297  
 298      Function ParseCContent(&$p, &$c_content)
 299      {
 300          $c_content = null;
 301          $c = $p;
 302          if(!$this->ParseQuotedPair($c, $content))
 303              return(0);
 304          if(!IsSet($content))
 305          {
 306              if(!$this->ParseCText($c, $content))
 307                  return(0);
 308              if(!IsSet($content))
 309              {
 310                  if(!$this->ParseComment($c, $content))
 311                      return(0);
 312                  if(!IsSet($content))
 313                      return(1);
 314              }
 315          }
 316          $c_content = $content;
 317          $p = $c;
 318          return(1);
 319      }
 320  
 321      Function SkipWhiteSpace(&$p)
 322      {
 323          $v = $this->v;
 324          $l = strlen($v);
 325          for(;$p<$l; ++$p)
 326          {
 327              switch($v[$p])
 328              {
 329                  case ' ':
 330                  case "\n":
 331                  case "\r":
 332                  case "\t":
 333                      break;
 334                  default:
 335                      return(1);
 336              }
 337          }
 338          return(1);
 339      }
 340  
 341      Function ParseComment(&$p, &$comment)
 342      {
 343          $comment = null;
 344          $v = $this->v;
 345          $l = strlen($v);
 346          $c = $p;
 347          if($c >= $l
 348          || strcmp($v[$c], '('))
 349              return(1);
 350          ++$c;
 351          for(; $c < $l;)
 352          {
 353              if(!$this->SkipWhiteSpace($c))
 354                  return(0);
 355              if(!$this->ParseCContent($c, $c_content))
 356                  return(0);
 357              if(!IsSet($c_content))
 358                  break;
 359          }
 360          if(!$this->SkipWhiteSpace($c))
 361              return(0);
 362          if($c >= $l
 363          || strcmp($v[$c], ')'))
 364              return(1);
 365          ++$c;
 366          $comment = substr($v, $p, $c - $p);
 367          $p = $c;
 368          return(1);
 369      }
 370  
 371      Function SkipCommentGetWhiteSpace(&$p, &$space)
 372      {
 373          $v = $this->v;
 374          $l = strlen($v);
 375          for($space = '';$p<$l;)
 376          {
 377              switch($w = $v[$p])
 378              {
 379                  case ' ':
 380                  case "\n":
 381                  case "\r":
 382                  case "\t":
 383                      ++$p;
 384                      $space .= $w;
 385                      break;
 386                  case '(':
 387                      if(!$this->ParseComment($p, $comment))
 388                          return(0);
 389                  default:
 390                      return(1);
 391              }
 392          }
 393          return(1);
 394      }
 395  
 396      Function SkipCommentWhiteSpace(&$p)
 397      {
 398          $v = $this->v;
 399          $l = strlen($v);
 400          for(;$p<$l;)
 401          {
 402              switch($w = $v[$p])
 403              {
 404                  case ' ':
 405                  case "\n":
 406                  case "\r":
 407                  case "\t":
 408                      ++$p;
 409                      break;
 410                  case '(':
 411                      if(!$this->ParseComment($p, $comment))
 412                          return(0);
 413                  default:
 414                      return(1);
 415              }
 416          }
 417          return(1);
 418      }
 419  
 420      Function ParseQContent(&$p, &$q_content)
 421      {
 422          $q_content = null;
 423          $q = $p;
 424          if(!$this->ParseQuotedPair($q, $content))
 425              return(0);
 426          if(!IsSet($content))
 427          {
 428              if(!$this->ParseQText($q, $content))
 429                  return(0);
 430              if(!IsSet($content))
 431                  return(1);
 432          }
 433          $q_content = $content;
 434          $p = $q;
 435          return(1);
 436      }
 437  
 438      Function ParseAtom(&$p, &$atom, $dot)
 439      {
 440          $atom = null;
 441          $v = $this->v;
 442          $l = strlen($v);
 443          $a = $p;
 444          if(!$this->SkipCommentGetWhiteSpace($a, $space))
 445              return(0);
 446          $match = '/^([-'.($dot ? '.' : '').'A-Za-z0-9!#$&\'*+\\/=?^_{|}~]+)/';
 447          for($s = $a;$a < $l;)
 448          {
 449              if(preg_match($match, substr($this->v, $a), $m))
 450                  $a += strlen($m[1]);
 451              elseif(Ord($v[$a]) < 128)
 452                  break;
 453              elseif(!$this->SetPositionedWarning('it was used an unencoded 8 bit character', $a))
 454                  return(0);
 455              else
 456                  ++$a;
 457          }
 458          if($s == $a)
 459              return(1);
 460          $atom = $space.substr($this->v, $s, $a - $s);
 461          if(!$this->SkipCommentGetWhiteSpace($a, $space))
 462              return(0);
 463          $atom .= $space;
 464          $p = $a;
 465          return(1);
 466      }
 467  
 468      Function ParseQuotedString(&$p, &$quoted_string)
 469      {
 470          $quoted_string = null;
 471          $v = $this->v;
 472          $l = strlen($v);
 473          $s = $p;
 474          if(!$this->SkipCommentWhiteSpace($s))
 475              return(0);
 476          if($s >= $l
 477          || strcmp($v[$s], '"'))
 478              return(1);
 479          ++$s;
 480          for($string = '';$s < $l;)
 481          {
 482              $w = $s;
 483              if(!$this->SkipWhiteSpace($s))
 484                  return(0);
 485              if($w != $s)
 486                  $string .= substr($v, $w, $s - $w);
 487              if(!$this->ParseQContent($s, $q_content))
 488                  return(0);
 489              if(!IsSet($q_content))
 490                  break;
 491              $string .= $q_content;
 492          }
 493              $w = $s;
 494          if(!$this->SkipWhiteSpace($s))
 495              return(0);
 496          if($w != $s)
 497              $string .= substr($v, $w, $s - $w);
 498          if($s >= $l
 499          || strcmp($v[$s], '"'))
 500              return(1);
 501          ++$s;
 502          if(!$this->SkipCommentWhiteSpace($s))
 503              return(0);
 504          $quoted_string = $string;
 505          $p = $s;
 506          return(1);
 507      }
 508  
 509      Function ParseWord(&$p, &$word)
 510      {
 511          $word = null;
 512          if(!$this->ParseQuotedString($p, $word))
 513              return(0);
 514          if(IsSet($word))
 515              return(1);
 516          if(!$this->ParseAtom($p, $word, 0))
 517              return(0);
 518          return(1);
 519      }
 520  
 521      Function ParseObsPhrase(&$p, &$obs_phrase)
 522      {
 523          $obs_phrase = null;
 524          $v = $this->v;
 525          $l = strlen($v);
 526          $ph = $p;
 527          if(!$this->ParseWord($ph, $word))
 528              return(0);
 529          $string = $word;
 530          for(;;)
 531          {
 532              if(!$this->ParseWord($ph, $word))
 533                  return(0);
 534              if(IsSet($word))
 535              {
 536                  $string .= $word;
 537                  continue;
 538              }
 539              $w = $ph;
 540              if(!$this->SkipCommentGetWhiteSpace($ph, $space))
 541                  return(0);
 542              if($w != $ph)
 543              {
 544                  $string .= $space;
 545                  continue;
 546              }
 547              if($ph >= $l
 548              || strcmp($v[$ph], '.'))
 549                  break;
 550              $string .= '.';
 551              ++$ph;
 552          }
 553          $obs_phrase = $string;
 554          $p = $ph;
 555          return(1);
 556      }
 557  
 558      Function ParsePhrase(&$p, &$phrase)
 559      {
 560          $phrase = null;
 561          if(!$this->ParseObsPhrase($p, $phrase))
 562              return(0);
 563          if(IsSet($phrase))
 564              return(1);
 565          $ph = $p;
 566          if(!$this->ParseWord($ph, $word))
 567              return(0);
 568          $string = $word;
 569          for(;;)
 570          {
 571              if(!$this->ParseWord($ph, $word))
 572                  return(0);
 573              if(!IsSet($word))
 574                  break;
 575              $string .= $word;
 576          }
 577          $phrase = $string;
 578          $p = $ph;
 579          return(1);
 580      }
 581  
 582      Function ParseAddrSpec(&$p, &$addr_spec)
 583      {
 584          $addr_spec = null;
 585          $v = $this->v;
 586          $l = strlen($v);
 587          $a = $p;
 588          if(!$this->ParseQuotedString($a, $local_part))
 589              return(0);
 590          if(!IsSet($local_part))
 591          {
 592              if(!$this->ParseAtom($a, $local_part, 1))
 593                  return(0);
 594              $local_part = trim($local_part);
 595          }
 596          if($a >= $l
 597          || strcmp($v[$a], '@'))
 598              return(1);
 599          ++$a;
 600          if(!$this->ParseAtom($a, $domain, 1))
 601              return(0);
 602          if(!IsSet($domain))
 603              return(1);
 604          $addr_spec = $local_part.'@'.trim($domain);
 605          $p = $a;
 606          return(1);
 607      }
 608  
 609      Function ParseAngleAddr(&$p, &$addr)
 610      {
 611          $addr = null;
 612          $v = $this->v;
 613          $l = strlen($v);
 614          $a = $p;
 615          if(!$this->SkipCommentWhiteSpace($a))
 616              return(0);
 617          if($a >= $l
 618          || strcmp($v[$a], '<'))
 619              return(1);
 620          ++$a;
 621          if(!$this->ParseAddrSpec($a, $addr_spec))
 622              return(0);
 623          if($a >= $l
 624          || strcmp($v[$a], '>'))
 625              return(1);
 626          ++$a;
 627          if(!$this->SkipCommentWhiteSpace($a))
 628              return(0);
 629          $addr = $addr_spec;
 630          $p = $a;
 631          return(1);
 632      }
 633  
 634      Function ParseName(&$p, &$address)
 635      {
 636          $address = null;
 637          $a = $p;
 638          if(!$this->ParsePhrase($a, $display_name))
 639              return(0);
 640          if(IsSet($display_name))
 641          {
 642              if(!$this->QDecode($p, $display_name, $encoding))
 643                  return(0);
 644              $address['name'] = trim($display_name);
 645              if(IsSet($encoding))
 646                  $address['encoding'] = $encoding;
 647          }
 648          $p = $a;
 649          return(1);
 650      }
 651  
 652      Function ParseNameAddr(&$p, &$address)
 653      {
 654          $address = null;
 655          $a = $p;
 656          if(!$this->ParsePhrase($a, $display_name))
 657              return(0);
 658          if(!$this->ParseAngleAddr($a, $addr))
 659              return(0);
 660          if(!IsSet($addr))
 661              return(1);
 662          $address = array('address'=>$addr);
 663          if(IsSet($display_name))
 664          {
 665              if(!$this->QDecode($p, $display_name, $encoding))
 666                  return(0);
 667              $address['name'] = trim($display_name);
 668              if(IsSet($encoding))
 669                  $address['encoding'] = $encoding;
 670          }
 671          $p = $a;
 672          return(1);
 673      }
 674  
 675      Function ParseAddrNameAddr(&$p, &$address)
 676      {
 677          $address = null;
 678          $a = $p;
 679          if(!$this->ParseAddrSpec($a, $display_name))
 680              return(0);
 681          if(!IsSet($display_name))
 682              return(1);
 683          if(!$this->ParseAngleAddr($a, $addr))
 684              return(0);
 685          if(!IsSet($addr))
 686              return(1);
 687          if(!$this->QDecode($p, $display_name, $encoding))
 688              return(0);
 689          $address = array(
 690              'address'=>$addr,
 691              'name' => trim($display_name)
 692          );
 693          if(IsSet($encoding))
 694              $address['encoding'] = $encoding;
 695          $p = $a;
 696          return(1);
 697      }
 698  
 699      Function ParseMailbox(&$p, &$address)
 700      {
 701          $address = null;
 702          if($this->ignore_syntax_errors)
 703          {
 704              $a = $p;
 705              if(!$this->ParseAddrNameAddr($p, $address))
 706                  return(0);
 707              if(IsSet($address))
 708                  return($this->SetPositionedWarning('it was specified an unquoted address as name', $a));
 709          }
 710          if(!$this->ParseNameAddr($p, $address))
 711              return(0);
 712          if(IsSet($address))
 713              return(1);
 714          if(!$this->ParseAddrSpec($p, $addr_spec))
 715              return(0);
 716          if(IsSet($addr_spec))
 717          {
 718              $address = array('address'=>$addr_spec);
 719              return(1);
 720          }
 721          $a = $p;
 722          if($this->ignore_syntax_errors
 723          && $this->ParseName($p, $address)
 724          && IsSet($address))
 725              return($this->SetPositionedWarning('it was specified a name without an address', $a));
 726          return(1);
 727      }
 728  
 729      Function ParseMailboxGroup(&$p, &$mailbox_group)
 730      {
 731          $v = $this->v;
 732          $l = strlen($v);
 733          $g = $p;
 734          if(!$this->ParseMailbox($g, $address))
 735              return(0);
 736          if(!IsSet($address))
 737              return(1);
 738          $addresses = array($address);
 739          for(;$g < $l;)
 740          {
 741              if(strcmp($v[$g], ','))
 742                  break;
 743              ++$g;
 744              if(!$this->ParseMailbox($g, $address))
 745                  return(0);
 746              if(!IsSet($address))
 747                  return(1);
 748              $addresses[] = $address;
 749          }
 750          $mailbox_group = $addresses;
 751          $p = $g;
 752          return(1);
 753      }
 754  
 755      Function ParseGroup(&$p, &$address)
 756      {
 757          $address = null;
 758          $v = $this->v;
 759          $l = strlen($v);
 760          $g = $p;
 761          if(!$this->ParsePhrase($g, $display_name))
 762              return(0);
 763          if(!IsSet($display_name)
 764          || $g >= $l
 765          || strcmp($v[$g], ':'))
 766              return(1);
 767          ++$g;
 768          if(!$this->ParseMailboxGroup($g, $mailbox_group))
 769              return(0);
 770          if(!IsSet($mailbox_group))
 771          {
 772              if(!$this->SkipCommentWhiteSpace($g))
 773                  return(0);
 774              $mailbox_group = array();
 775          }
 776          if($g >= $l
 777          || strcmp($v[$g], ';'))
 778              return(1);
 779          $c = ++$g;
 780          if($this->SkipCommentWhiteSpace($g)
 781          && $g > $c
 782          && !$this->SetPositionedWarning('it were used invalid comments after a group of addresses', $c))
 783              return(0);
 784          if(!$this->QDecode($p, $display_name, $encoding))
 785              return(0);
 786          $address = array(
 787              'name'=>$display_name,
 788              'group'=>$mailbox_group
 789          );
 790          if(IsSet($encoding))
 791              $address['encoding'] = $encoding;
 792          $p = $g;
 793          return(1);
 794      }
 795  
 796      Function ParseAddress(&$p, &$address)
 797      {
 798          $address = null;
 799          if(!$this->ParseGroup($p, $address))
 800              return(0);
 801          if(!IsSet($address))
 802          {
 803              if(!$this->ParseMailbox($p, $address))
 804                  return(0);
 805          }
 806          return(1);
 807      }
 808  
 809      /* Public functions */
 810  
 811  /*
 812  {metadocument}
 813      <function>
 814          <name>ParseAddressList</name>
 815          <type>BOOLEAN</type>
 816          <documentation>
 817              <purpose>Parse and extract e-mail addresses eventually from headers
 818                  of an e-mail message.</purpose>
 819              <usage>Pass a string value with a list of e-mail addresses to the
 820                  <argumentlink>
 821                      <function>ParseAddressList</function>
 822                      <argument>value</argument>
 823                  </argumentlink>. The <argumentlink>
 824                      <function>ParseAddressList</function>
 825                      <argument>addresses</argument>
 826                  </argumentlink> returns the list of e-mail addresses found.</usage>
 827              <returnvalue>This function returns <booleanvalue>1</booleanvalue> if
 828                  the specified value is parsed successfully. Otherwise,
 829                  check the variables <variablelink>error</variablelink> and
 830                  <variablelink>error_position</variablelink> to determine what
 831                  error occurred and the relevant value position.</returnvalue>
 832          </documentation>
 833          <argument>
 834              <name>value</name>
 835              <type>STRING</type>
 836              <documentation>
 837                  <purpose>String with a list of e-mail addresses to parse.</purpose>
 838              </documentation>
 839          </argument>
 840          <argument>
 841              <name>addresses</name>
 842              <type>ARRAY</type>
 843              <out />
 844              <documentation>
 845                  <purpose>Return the list of parsed e-mail addresses.
 846                      Each entry in the list is an associative array.<paragraphbreak />
 847                      For normal addresses, this associative array has the entry
 848                      <stringvalue>address</stringvalue> set to the e-mail address.
 849                      If the address has an associated name, it is stored in the
 850                      entry <stringvalue>name</stringvalue>.<paragraphbreak />
 851                      For address groups, there is the entry
 852                      <stringvalue>name</stringvalue>.
 853                      The group addresses list are stored in the entry
 854                      <stringvalue>group</stringvalue> as an array. The structure of
 855                      the group addresses list array is the same as this addresses
 856                      list array argument.</purpose>
 857              </documentation>
 858          </argument>
 859          <do>
 860  {/metadocument}
 861  */
 862      Function ParseAddressList($value, &$addresses)
 863      {
 864          $this->warnings = array();
 865          $addresses = array();
 866          $this->v = $v = $value;
 867          $l = strlen($v);
 868          $p = 0;
 869          if(!$this->ParseAddress($p, $address))
 870              return(0);
 871          if(!IsSet($address))
 872              return($this->SetPositionedError('it was not specified a valid address', $p));
 873          $addresses[] = $address;
 874          while($p < $l)
 875          {
 876              if(strcmp($v[$p], ',')
 877              && !$this->SetPositionedWarning('multiple addresses must be separated by commas: ', $p))
 878                  return(0);
 879              ++$p;
 880              if(!$this->ParseAddress($p, $address))
 881                  return(0);
 882              if(!IsSet($address))
 883                  return($this->SetPositionedError('it was not specified a valid address after comma', $p));
 884              $addresses[] = $address;
 885          }
 886          return(1);
 887      }
 888  /*
 889  {metadocument}
 890          </do>
 891      </function>
 892  {/metadocument}
 893  */
 894  
 895  };
 896  
 897  /*
 898  
 899  {metadocument}
 900  </class>
 901  {/metadocument}
 902  
 903  */
 904  
 905  ?>

title

Description

title

Description

title

Description

title

title

Body