[ Index ] |
|
Code source de Mantis 1.1.0rc3 |
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(" ",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(" ",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(" ",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(" ",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(" ",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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Nov 29 09:42:17 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |