Source for file url_parser.php

Documentation is available at url_parser.php

  1. <?php
  2.  
  3. /**
  4.  * url_parser.php
  5.  *
  6.  * This code provides various string manipulation functions that are
  7.  * used by the rest of the SquirrelMail code.
  8.  *
  9.  * @copyright &copy; 1999-2006 The SquirrelMail Project Team
  10.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  11.  * @version $Id: url_parser.php,v 1.44.2.9 2006/05/06 08:32:08 tokul Exp $
  12.  * @package squirrelmail
  13.  */
  14.  
  15. /**
  16.  * Undocumented - complain, then patch.
  17.  */
  18. function replaceBlock (&$in$replace$start$end{
  19.     $begin substr($in,0,$start);
  20.     $end   substr($in,$end,strlen($in)-$end);
  21.     $in    $begin.$replace.$end;
  22. }
  23.  
  24. /* Having this defined in just one spot could help when changes need
  25.  * to be made to the pattern
  26.  * Make sure that the expression is evaluated case insensitively
  27.  *
  28.  * Here's pretty sophisticated IP matching:
  29.  * $IPMatch = '(2[0-5][0-9]|1?[0-9]{1,2})';
  30.  * $IPMatch = '\[?' . $IPMatch . '(\.' . $IPMatch . '){3}\]?';
  31.  */
  32. /* Here's enough: */
  33. global $IP_RegExp_Match$Host_RegExp_Match$Email_RegExp_Match;
  34. $IP_RegExp_Match '\\[?[0-9]{1,3}(\\.[0-9]{1,3}){3}\\]?';
  35. $Host_RegExp_Match '(' $IP_RegExp_Match .
  36.     '|[0-9a-z]([-.]?[0-9a-z])*\\.[a-z][a-z]+)';
  37. $Email_RegExp_Match '[0-9a-z]([-_.+]?[0-9a-z])*(%' $Host_RegExp_Match .
  38.     ')?@' $Host_RegExp_Match;
  39.  
  40. function parseEmail (&$body{
  41.     global $color$Email_RegExp_Match$compose_new_win;
  42.     $sbody     $body;
  43.     $addresses array();
  44.  
  45.     /* Find all the email addresses in the body */
  46.     while(eregi($Email_RegExp_Match$sbody$regs)) {
  47.         $addresses[$regs[0]] $regs[0];
  48.         $start strpos($sbody$regs[0]strlen($regs[0]);
  49.         $sbody substr($sbody$start);
  50.     }
  51.     /* Replace each email address with a compose URL */
  52.     foreach ($addresses as $email{
  53.         $comp_uri makeComposeLink('src/compose.php?send_to='.urlencode($email)$email);
  54.         $body str_replace($email$comp_uri$body);
  55.     }
  56.     /* Return number of unique addresses found */
  57.     return count($addresses);
  58. }
  59.  
  60.  
  61. /* We don't want to re-initialize this stuff for every line.  Save work
  62.  * and just do it once here.
  63.  */
  64. global $url_parser_url_tokens;
  65. $url_parser_url_tokens array(
  66.     'http://',
  67.     'https://',
  68.     'ftp://',
  69.     'telnet:',  // Special case -- doesn't need the slashes
  70.         'gopher://',
  71.     'news://');
  72.  
  73. global $url_parser_poss_ends;
  74. $url_parser_poss_ends array(' '"\n""\r"'<''>'".\r"".\n",
  75.     '.&nbsp;''&nbsp;'')''(''&quot;''&lt;''&gt;''.<',
  76.     ']''[''{''}'"\240"', ''. '",\n"",\r");
  77.  
  78.  
  79. function parseUrl (&$body{
  80.     global $url_parser_poss_ends$url_parser_url_tokens;
  81.     $start      0;
  82.     $blength    strlen($body);
  83.  
  84.     while ($start != $blength{
  85.         $target_token '';
  86.         $target_pos $blength;
  87.  
  88.         /* Find the first token to replace */
  89.         foreach ($url_parser_url_tokens as $the_token{
  90.             $pos strpos(strtolower($body)$the_token$start);
  91.             if (is_int($pos&& $pos $target_pos{
  92.                 $target_pos   $pos;
  93.                 $target_token $the_token;
  94.             }
  95.         }
  96.  
  97.         /* Look for email addresses between $start and $target_pos */
  98.         $check_str substr($body$start$target_pos-$start);
  99.  
  100.         if (parseEmail($check_str)) {
  101.             replaceBlock($body$check_str$start$target_pos);
  102.             $blength    strlen($body);
  103.             $target_pos strlen($check_str$start;
  104.         }
  105.  
  106.         /* If there was a token to replace, replace it */
  107.         if ($target_token != ''{
  108.             /* Find the end of the URL */
  109.             $end $blength;
  110.             foreach ($url_parser_poss_ends as $val{
  111.                 $enda strpos($body$val$target_pos);
  112.                 if (is_int($enda&& $enda $end{
  113.                     $end $enda;
  114.                 }
  115.             }
  116.  
  117.             /* make sure that there are no 8bit chars between $target_pos and suspected end of URL */
  118.             if (!is_bool($first8bit=sq_strpos_8bit($body,$target_pos,$end))) {
  119.                 $end $first8bit;
  120.             }
  121.  
  122.             /* Extract URL */
  123.             $url substr($body$target_pos$end-$target_pos);
  124.  
  125.             /* Needed since lines are not passed with \n or \r */
  126.             while ereg("[,\.]$"$url) ) {
  127.                 $url substr$url0-);
  128.                 $end--;
  129.             }
  130.  
  131.             /* Replace URL with HyperLinked Url, requires 1 char in link */
  132.             if ($url != '' && $url != $target_token{
  133.                 $url_str "<a href=\"$url\" target=\"_blank\">$url</a>";
  134.                 replaceBlock($body,$url_str,$target_pos,$end);
  135.                 $target_pos += strlen($url_str);
  136.             }
  137.             else {
  138.                 // Not quite a valid link, skip ahead to next chance
  139.                 $target_pos += strlen($target_token);
  140.             }
  141.         }
  142.  
  143.         /* Move forward */
  144.         $start   $target_pos;
  145.         $blength strlen($body);
  146.     }
  147. }
  148.  
  149. /**
  150.  * Finds first occurrence of 8bit data in the string
  151.  *
  152.  * Function finds first 8bit symbol or html entity that represents 8bit character.
  153.  * Search start is defined by $offset argument. Search ends at $maxlength position.
  154.  * If $maxlength is not defined or bigger than provided string, search ends when
  155.  * string ends.
  156.  *
  157.  * Check returned data type in order to avoid confusion between bool(false)
  158.  * (not found) and int(0) (first char in the string).
  159.  * @param string $haystack 
  160.  * @param integer $offset 
  161.  * @param integer $maxlength 
  162.  * @return mixed integer with first 8bit character position or boolean false
  163.  * @since 1.5.2 and 1.4.7
  164.  */
  165. function sq_strpos_8bit($haystack,$offset=0,$maxlength=false{
  166.     $ret false;
  167.     
  168.     if ($maxlength===false || strlen($haystack$maxlength{
  169.         $maxlength=strlen($haystack);
  170.     }
  171.  
  172.     for($i=$offset;$i<$maxlength;$i++{
  173.         /* rh7-8 compatibility. don't use full 8bit range in regexp */
  174.         if (preg_match('/[\200-\237]|\240|[\241-\377]/',$haystack[$i])) {
  175.             /* we have 8bit char. stop here and return position */
  176.             $ret $i;
  177.             break;
  178.         elseif ($haystack[$i]=='&'{
  179.             $substring substr($haystack,$i);
  180.             /**
  181.              * 1. look for "&#(decimal number);" where decimal_number is bigger than 127
  182.              * 2. look for "&x(hexadecimal number);", where hex number is bigger than x7f
  183.              * 3. look for any html character entity that is not 7bit html special char. Use 
  184.              * own sq_get_html_translation_table() function with 'utf-8' character set in 
  185.              * order to get all html entities.
  186.              */
  187.             if ((preg_match('/^&#(\d+);/',$substring,$match&& $match[1]>127||
  188.                 (preg_match('/^&x([0-9a-f]+);/i',$substring,$match&& $match[1]>"\x7f"||
  189.                 (preg_match('/^&([a-z]+);/i',$substring,$match&& 
  190.                  !in_array($match[0],get_html_translation_table(HTML_SPECIALCHARS)) && 
  191.                  in_array($match[0],sq_get_html_translation_table(HTML_ENTITIES,ENT_COMPAT,'utf-8')))) {
  192.                 $ret $i;
  193.                 break;
  194.             }
  195.         }
  196.     }
  197.     return $ret;
  198. }
  199. ?>

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