root

Changeset 468

Show
Ignore:
Timestamp:
01/08/09 09:02:57 (2 years ago)
Author:
wbond
Message:

Fixed ticket #120, fHTML::makeLinks() was double-linking some links in the form http://www.example.com

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • fHTML.php

    r448 r468 Hide Line Numbers
    66 * http://flourishlib.com/docs/UTF-8 for more information. 
    77 *  
    8  * @copyright  Copyright (c) 2007-2008 Will Bond 
     8 * @copyright  Copyright (c) 2007-2009 Will Bond 
    99 * @author     Will Bond [wb] <will@flourishlib.com> 
    1010 * @license    http://flourishlib.com/license 
     
    1313 * @link       http://flourishlib.com/fHTML 
    1414 *  
    15  * @version    1.0.0b2 
     15 * @version    1.0.0b3 
     16 * @changes    1.0.0b3  Fixed a bug where ::makeLinks() would double-link some URLs [wb, 2009-01-08] 
    1617 * @changes    1.0.0b2  Fixed a bug where ::makeLinks() would create links out of URLs in HTML tags [wb, 2008-12-05] 
    1718 * @changes    1.0.0b   The initial implementation [wb, 2007-09-25] 
     
    8990    static public function makeLinks($content, $link_text_length=0) 
    9091    { 
    91         // Determine what replacement to perform 
    92         if ($link_text_length) { 
    93             // We don't need UTF-8 strlen here becuase email addresses and URLs can't contain UTF-8 characters 
    94             $replacement = '((strlen("\1") > ' . $link_text_length . ') ? substr("\1", 0, ' . $link_text_length . ') . "..." : "\1")'; 
    95         } else { 
    96             $replacement = '"\1"'; 
    97         } 
    98          
    9992        // Find all a tags with contents, individual HTML tags and HTML comments 
    10093        $reg_exp = "/<\s*a(?:\s+[\w:]+(?:\s*=\s*(?:\"[^\"]*?\"|'[^']*?'|[^'\">\s]+))?)*\s*>.*?<\s*\/\s*a\s*>|<\s*\/?\s*[\w:]+(?:\s+[\w:]+(?:\s*=\s*(?:\"[^\"]*?\"|'[^']*?'|[^'\">\s]+))?)*\s*\/?\s*>|<\!--.*?-->/"; 
     
    10699        // For each chunk of text and create the links 
    107100        foreach($text_matches as $key => $text) { 
    108             $text_matches[$key] = str_replace( 
    109                 "\\'", 
    110                 "'", 
    111                 preg_replace( 
    112                     array( 
    113                         '#\b([a-z]{3,}://[a-z0-9%\$\-_.+!*;/?:@=&\'\#,]+[a-z0-9\$\-_+!*;/?:@=&\'\#,])\b#ie', # Fully URLs 
    114                         '#\b(www\.([a-z0-9\-]+\.)+[a-z]{2,}(?:/[a-z0-9%\$\-_.+!*;/?:@=&\'\#,]+[a-z0-9\$\-_+!*;/?:@=&\'\#,])?)\b#ie',  # www. domains 
    115                         '#\b([a-z0-9\\.+\'_\\-]+@(?:[a-z0-9\\-]+\.)+[a-z]{2,})\b#ie' # email addresses 
    116                     ), 
    117                     array( 
    118                         '"<a href=\"\1\">" . ' . $replacement . ' . "</a>"', 
    119                         '"<a href=\"http://\1\">" . ' . $replacement . ' . "</a>"', 
    120                         '"<a href=\"mailto:\1\">" . ' . $replacement . ' . "</a>"' 
    121                     ), 
    122                     $text 
    123                 ) 
     101            preg_match_all( 
     102                '~ 
     103                  \b([a-z]{3,}://[a-z0-9%\$\-_.+!*;/?:@=&\'\#,]+[a-z0-9\$\-_+!*;/?:@=&\'\#,])\b                           | # Fully URLs 
     104                  \b(www\.(?:[a-z0-9\-]+\.)+[a-z]{2,}(?:/[a-z0-9%\$\-_.+!*;/?:@=&\'\#,]+[a-z0-9\$\-_+!*;/?:@=&\'\#,])?)\b | # www. domains 
     105                  \b([a-z0-9\\.+\'_\\-]+@(?:[a-z0-9\\-]+\.)+[a-z]{2,})\b                                                    # email addresses 
     106                 ~ix', 
     107                $text, 
     108                $matches, 
     109                PREG_SET_ORDER 
    124110            ); 
     111             
     112            // For each match we find the first occurence, replace it and then 
     113            // start from the end of that finding the next occurence. This 
     114            // prevents double linking of matches for http://www.example.com and 
     115            // www.example.com 
     116            $last_pos = 0; 
     117            foreach ($matches as $match) { 
     118                $match_pos = strpos($text, $match[0], $last_pos); 
     119                $length    = strlen($match[0]); 
     120                $prefix    = ''; 
     121                 
     122                if (!empty($match[3])) { 
     123                    $prefix = 'mailto:'; 
     124                } elseif (!empty($match[2])) { 
     125                    $prefix = 'http://'; 
     126                } 
     127                 
     128                $replacement  = '<a href="' . $prefix . $match[0] . '">'; 
     129                $replacement .= ($link_text_length && strlen($match[0]) > $link_text_length) ? substr($match[0], 0, $link_text_length) . "…" : $match[0]; 
     130                $replacement .= '</a>'; 
     131                 
     132                $text = substr_replace( 
     133                    $text, 
     134                    $replacement, 
     135                    $match_pos, 
     136                    $length 
     137                ); 
     138                 
     139                $last_pos = $match_pos + strlen($replacement);   
     140            } 
     141             
     142            $text_matches[$key] = $text; 
    125143        } 
    126144         
     
    209227 
    210228/** 
    211  * Copyright (c) 2007-2008 Will Bond <will@flourishlib.com> 
     229 * Copyright (c) 2007-2009 Will Bond <will@flourishlib.com> 
    212230 *  
    213231 * Permission is hereby granted, free of charge, to any person obtaining a copy