[ Index ]
 

Code source de Mantis 1.1.0rc3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/core/ -> class.urlmatch.php (source)

   1  <?php
   2  // Class mantisLink
   3  //
   4  // 09-18-2004 Bastian Pfennigschmidt for Mantis Bugtracker
   5  class mantisLink extends urlmatch
   6  {
   7  	function mantisLink()
   8      {
   9          parent::urlmatch();
  10          $this->charLimit = 50;
  11          $this->breakTxt = '...';
  12          $this->addProperty("target=\"_blank\"");
  13      }
  14  
  15  	function match($string, $screenTxt="")
  16      {
  17          $urls = $this->_getUrls($string, $screenTxt);
  18  
  19          while (list($key, $value) = each($urls))
  20          {
  21              $string = str_replace(
  22                      $value["url"],
  23                      "<a href=\"".$value["url_prepend"].$value["url"]."\">".$this->_screenURL($value["url"])."</a> ".
  24                      $value["prepend"].$value["url_prepend"].$value["url"]."\">".$this->_screenURL($value["url"],$screenTxt)."</a>",
  25                      $string
  26                      );
  27          }
  28  
  29          return $string;
  30      }
  31  }
  32  
  33  /*
  34  class: urlmatch
  35  released: 08-19-2002
  36  revised: 11-21-2002
  37  revised: 09-18-2004 Bastian Pfennigschmidt
  38  author: kumar (kumar@chicagomodular.com)
  39  
  40  ****description:
  41  
  42  Looks for any URLs in a string of text and matches each one with a customizable <a> tag.  Convenient for parsing user input where users are not expected to write HTML.  The class finds URLs starting with 'http|https|ftp|www', ignores HTML tags, supports the addition of <a> properties (such as defining a CSS class), and supports a character limit for the displayed link text.  I have tested it with many possibilities but please don't hesitate to report any bugs to my above email address.  To-Do: matching email addresses, if the need arises.
  43  
  44  ****revision 09-18-2004:    Bastian Pfennigschmidt
  45  
  46  Better trim functions
  47  Move link output into additional methode to make overwrite possible
  48  Accept @ in URL
  49  
  50  ****revision 11-21-2002:
  51  
  52  Small fix to detect tabs and PC/MS-DOS line breaks.
  53  
  54  ****revision 10-14-2002:
  55  
  56  Fixed many bugs relating to detecting punctuation and characters within the URL or trailing the URL, matching multiple URLs (as in a list), URLs appearing within or around HTML tags or as HTML source... there are many more URL-in-text scenarios supported now.  You may notice from the code, however, there are many preg checks to ensure the flexibility of the class.  If speed is a concern of yours, you may want to comment out the code that looks for HTML source (href="") or code that detects and deletes multiple http/www URLs.  Also, PHP 4.1.0 is now required but if anyone needs this for lesser versions, please email me.
  57  
  58  
  59  ****requirements:
  60  
  61  PHP >= 4.1.0 (array_key_exists(), foreach())
  62  
  63  license: The GNU General Public License (GPL)
  64  http://www.opensource.org/licenses/gpl-license.html
  65  
  66  */
  67  
  68  class urlmatch
  69  {
  70      // @public: -- edit here or set values in your script or child class:
  71  
  72      var $charLimit = 50; // num of chars to limit for the screen-displayed URL
  73      var $breakTxt = "..."; // text to show at the end of a break, if the char limit is reached
  74      var $startFromLeft;    // this is for compatibilty only - please use $breakPosition instead
  75      var $breakPosition = "smart"; // in the event your screen URL is longer than the character limit :
  76                                 // left: add the break at the left, shows the directory side [right side] of the URL
  77                                 // right: add the break at the right, shows the domain side of the URL [left side]
  78                                 // smart: add the break at a smart position, shows beginning and end of the URL
  79      var $debug = FALSE; // set this to TRUE to display internal matching procedure
  80  
  81      // @private: -- do not edit:
  82  
  83      var $tags = array();
  84      var $matchUrl;
  85      var $matchHtmlSrc;
  86      var $matchOpeningPunctuation;
  87      var $matchClosingPunctuation;
  88  
  89  	function urlmatch()
  90      // constructor
  91      {
  92          $this->matchHtmlSrc = "/^href=\"?.*/i";
  93          $this->matchOpeningPunctuation = "/^('|\").*/";
  94          $this->matchClosingPunctuation = "/(\?|\(|\)|\"|'|\.|,|;|!)$/";
  95  
  96          $this->matchUrl = implode("",array(
  97          "/^'?\"?" // possible opening punctuation
  98          ,"(www|ftp:\/\/|http:\/\/|https:\/\/)" // match opening of a URL, possibly in parenthesis, quotes, etc.
  99          ,"(.*@){0,1}"
 100          ,"([\.[:alnum:]_-]){0,4}" // match 4 possible subdomains
 101          ,"([[:alnum:]_-]+\.)" // match the domain
 102          ,"([[:alnum:]_-]\.?)" // match possible top level sub domain
 103          ,"([[:alpha:]]){0,3}" // match final top level domain
 104          ,".*$" // match possible directories or query string, anything
 105          ,"/i")); // perl modifiers: case-insensitive
 106      }
 107  
 108  	function addProperty($strProperty)
 109      //
 110      // @public: call this to add any tag properties for the <a> tag
 111      //
 112      // @param: string $strProperty (i.e. "target=\"_blank\"")
 113      //
 114      {
 115          $this->tags[] = $strProperty;
 116      }
 117  
 118  	function match($string,$screenTxt="")
 119      //
 120      // @public: Creates the link for output
 121      //
 122      // @param: string $url (the matched URL passed from match() )
 123      // @param: string $prepend (prepend of url passed from match() )
 124      // @param: string $url_prepend (the url prepend of url passed from match() )
 125      //
 126      {
 127          $urls = $this->_getUrls($string, $screenTxt);
 128  
 129          while (list($key, $value) = each($urls))
 130          {
 131              $string = str_replace(
 132                      $value["url"],
 133                      $value["prepend"].$value["url_prepend"].$value["url"]."\">".$this->_screenURL($value["url"],$screenTxt)."</a>",
 134                      $string
 135                      );
 136          }
 137  
 138          return $string;
 139      }
 140  
 141  	function _getUrls($string,$screenTxt="")
 142      //
 143      // @private: call this to return the final string with all urls matched
 144      //
 145      // @param: string $string (entire string which may contain URLs)
 146      // @param: string $screenTxt (text, if any, which should be displayed for the matched URL)
 147      //
 148      {
 149          // init token:
 150          $token = " \t\r\n<>()"; // split by any characters we know will not be in a URL
 151          $piece = strtok($string,$token);
 152          $storedURLsToMatch = array();
 153          $htmlSrcUrlsToDelete = array();
 154          $urls = array();
 155          if($this->debug)
 156          {
 157              $i=1;
 158              echo "string: ",htmlspecialchars($string),"<br />\n";
 159          } // END if($this->debug)
 160  
 161          // look through the string one piece at a time, pices being separated by the token above:
 162          while(!($piece === FALSE))
 163          {
 164              // init:
 165              $url_prepend="";
 166              if($this->debug)
 167              {
 168                  echo "strtok $i: '",htmlspecialchars($piece),"'<br />\n";
 169                  $i++;
 170              } // END if($this->debug)
 171  
 172              if(preg_match($this->matchHtmlSrc,$piece))
 173              // if we have found a url already coded by means of href="http://etc...", delete that url from the match queue:
 174              {
 175                  $piece = substr($piece,6,strlen($piece)-7); // get rid of href=" and trailing "
 176                  if(preg_match($this->matchUrl,$piece))
 177                  {
 178                      $htmlSrcUrlsToDelete[] = $piece;
 179                      if($this->debug){
 180                          echo str_repeat("&nbsp;",4),"detected already coded url: '",htmlspecialchars($piece),"'<br />\n"; }
 181                  } // end if(preg_match($this->matchUrl,$piece))
 182              }  // end if(preg_match($this->matchHtmlSrc,$piece))
 183  
 184              if(preg_match($this->matchUrl,$piece,$theMatch))
 185              // if we have matched a URL:
 186              {
 187                  // init:
 188                  $new_url = $theMatch[0];
 189                  $sameURLwithoutProtocol = "";
 190  
 191                  // deal with www urls, and prepare for logging url, below:
 192                  if(strtolower($theMatch[1]) == "www")
 193                      $url_prepend .= "http://";
 194                  else
 195                      $sameURLwithoutProtocol = str_replace($theMatch[1],"",$theMatch[0]);
 196  
 197                  // find out if we matched some punctuation text which needs to be put back in place:
 198                  if(preg_match($this->matchOpeningPunctuation,$theMatch[0],$openingPuncuationMatch))
 199                  {
 200                      $new_url = substr($new_url,strlen($openingPuncuationMatch[1]));
 201                      if($this->debug)
 202                          echo str_repeat("&nbsp;",4),"cleaning up url: '",htmlspecialchars($new_url),"'<br />\n";
 203                      unset($openingPuncuationMatch);
 204                  } // END if(preg_match($this->matchOpeningPunctuation,$theMatch[0],$openingPuncuationMatch))
 205  
 206                  if(preg_match($this->matchClosingPunctuation,$new_url,$cleanup))
 207                  // if the URL ends in unnecessary punctuation, such as a "?" or ")":
 208                  {
 209                      $new_url = substr($new_url,0,-strlen($cleanup[1]));
 210                      if($this->debug){
 211                          echo str_repeat("&nbsp;",4),"cleaning up url: '",htmlspecialchars($new_url),"'<br />\n"; }
 212                  } // END if(preg_match($this->matchClosingPunctuation,$new_url,$cleanup))
 213  
 214                  // log URLs for replacement, if not already logged:
 215                  if(    !array_key_exists($new_url,$storedURLsToMatch) or
 216                          !array_key_exists($sameURLwithoutProtocol,$storedURLsToMatch) )
 217                  {
 218                      $storedURLsToMatch[$new_url] = $url_prepend;
 219                  } // END if(!array_key_exists($new_url,$storedURLsToMatch) or ...
 220              } // END if(preg_match($this->matchUrl,$piece,$theMatch))
 221              $piece = strtok($token);
 222          } // end while(!($piece === FALSE))
 223  
 224          // define the shared prefix for each matched URL:
 225          $prepend = "<a ";
 226          for($i=0, $max=count($this->tags); $i<$max; $i++)
 227          {
 228              $prepend .= $this->tags[$i]." ";
 229          } // END for($i=0, $max=count($this->tags); $i<$max; $i++)
 230          $prepend .= "href=\"";
 231  
 232          foreach($htmlSrcUrlsToDelete as $alreadyCodedUrl)
 233          // delete any urls from the toMatch array which already exist as html src:
 234          {
 235              if(array_key_exists($alreadyCodedUrl,$storedURLsToMatch))
 236              {
 237                  unset($storedURLsToMatch[$alreadyCodedUrl]);
 238                  if($this->debug)
 239                      echo str_repeat("&nbsp;",4),"deleting url: '$alreadyCodedUrl'<br />\n";
 240              } // END if(array_key_exists($alreadyCodedUrl,$storedURLsToMatch))
 241          } // END foreach($htmlSrcUrlsToDelete as $alreadyCodedUrl)
 242  
 243          foreach($storedURLsToMatch as $theMatchedURL => $url_prepend)
 244          // match each url found in the above search with an html tag:
 245          {
 246              $doTheReplace = TRUE;
 247              if(strtolower(substr($theMatchedURL,0,3)) == "www")
 248              // if no protocol, avoid replacing the same URL twice:
 249              {
 250                  if(
 251                      array_key_exists("http://".$theMatchedURL,$storedURLsToMatch) or
 252                      array_key_exists("https://".$theMatchedURL,$storedURLsToMatch) or
 253                      array_key_exists("ftp://".$theMatchedURL,$storedURLsToMatch))
 254  
 255                      $doTheReplace = FALSE;     // we can't process the www url in this text when
 256                                              // there are duplicates containing http:// .. sorry.
 257              } // END if(strtolower(substr($theMatchedURL,0,3)) == "www")
 258              if($doTheReplace)
 259              {
 260                  $urls[] = array("url" => $theMatchedURL, "prepend" => $prepend, "url_prepend" => $url_prepend);
 261  
 262                  if($this->debug)
 263                      echo str_repeat("&nbsp;",4),"matching url: '$theMatchedURL'<br />\n";
 264              } // END if($doTheReplace)
 265          } // END foreach($storedURLsToMatch as $theMatchedURL => $url_prepend)
 266  
 267          // finish:
 268          if($this->debug) echo "\n<br />";
 269          return $urls;
 270      } // END function getUrls()
 271  
 272  	function _screenURL($theScreenURL,$screenTxt="")
 273      //
 274      // @private: logic for the displayed link text.
 275      // checks length of display text and will truncate to the string limit if necessary.
 276      //
 277      // @param: string $theScreenURL (the matched URL passed from match() )
 278      // @param: string $screenTxt ($screenTxt if passed from match() )
 279      //
 280      {
 281          // For compatibility:
 282          if ($this->startFromLeft)
 283              $this->breakPosition = "right";
 284  
 285          $output = (!empty($screenTxt)) ? $screenTxt: $theScreenURL;
 286          if(strlen($output) > $this->charLimit)
 287          {
 288              switch($this->breakPosition)
 289              {
 290                  case "left":
 291                      $output = $this->breakTxt . substr($output,-$this->charLimit);
 292                  break;
 293  
 294                  case "right":
 295                      $output = substr($output,0,$this->charLimit) . $this->breakTxt;
 296                  break;
 297  
 298                  case "smart":
 299                  default:
 300                     $lengthToKeep = $this->charLimit - strlen($this->breakTxt);
 301                     $modulo = $lengthToKeep % 2;
 302                     $start = 0;
 303                     $end = 0;
 304                     if ($modulo == 0) {
 305                         $start = $lengthToKeep / 2;
 306                         $end   = $start;
 307                     } else {
 308                         $start = intval($lengthToKeep / 2);
 309                         $end   = $start + 1;
 310                     }
 311                     $output = substr($output, 0, $start) .$this->breakTxt. substr($output, -$end);
 312                  break;
 313              }
 314  
 315          } // END if(strlen($output) > $this->charLimit)
 316          return $output;
 317      } // END function screenURL($theScreenURL,$screenTxt="")
 318  
 319  } // END class urlmatch
 320  ?>


Généré le : Thu Nov 29 09:42:17 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics