Changes: - Require at least one slash after the protocol. Horde's other filters don't expect us to match mailto: as part of these filters, so don't. - Limit the URL protocol to 20 characters to avoid PCRE problems. - Allow "+" characters in URL protocols (like svn+ssh://). Parameters: - callback: (string) A callback function that the URL is passed through before being set as the href attribute. Must be a string with the function name, the function must take the original URL as the first and only parameter. DEFAULT: No callback - class: (string) The CSS class of the generated links. DEFAULT: none - encode: (boolean) Whether to escape special HTML characters in the URLs and finally "encode" the complete tag so that it can be decoded later with the decode() method. This is useful if you want to run htmlspecialchars() or similar *after* using this filter. DEFAULT: false - nofollow: (boolean) Whether to set the 'rel="nofollow"' attribute on links. DEFAULT: false - target: (string) The link target. DEFAULT: '_blank' Copyright 2003-2016 Horde LLC (http://www.horde.org/) See the enclosed file COPYING for license information (LGPL). If you did not receive this file, see http://www.horde.org/licenses/lgpl21.
Author: Tyler Colbert (tyler@colberts.us)
Author: Jan Schneider (jan@horde.org)
Author: Chuck Hagenbuch (chuck@horde.org)
Inheritance: extends Horde_Text_Filter_Base
Ejemplo n.º 1
0
    /**
     * Initialize the regex for this instance.
     */
    public static function initializeRegex()
    {
        self::$regex = <<<END_OF_REGEX
(?xi)
(?:\\b|^)
(  # Capture 1: entire matched URL
  (
   (?:[a-z][\\w-+]{0,19})?:/{1,3}  # URL protocol and colon followed by 1-3
                                  # slashes, or just colon and slashes (://)
    |                             #  - or -
    (?<!\\.)www\\d{0,3}\\.           # "www.", "www1.", "www2." … "www999."
                                  # without a leading period
    |                             #  - or -
    [a-z0-9.\\-]+\\.[a-z]{2,4}/    # looks like domain name followed by a slash
  )
  (?:                           # One or more:
    [^\\s()<>\\[\\]]+                         # Run of non-space, non-()<>
    (?<![\\s`!()\\[\\]{};:\\'".,<>?«»“”‘’]{2}) # that is not followed by two or more
                                           # punct chars that indicate end-of-url
    |                                      #  - or -
    \\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)     # balanced parens, up to 2 levels
  )+
  (?:                           # End with:
    \\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)  # balanced parens, up to 2 levels
    |                                   #  - or -
    [^\\s`!()\\[\\]{};:\\'".,<>?«»“”‘’]     # not a space or one of these punct
                                        # chars
  )
)
END_OF_REGEX;
    }
Ejemplo n.º 2
0
 /**
  * Parse the information in mailing list headers.
  *
  * @param string $id    The header ID.
  * @param string $data  The header text to process.
  *
  * @return string  The HTML-escaped header value.
  */
 protected function _parseListHeaders($id, $data)
 {
     global $injector;
     $parser = $injector->getInstance('Horde_ListHeaders');
     $text_filter = $injector->getInstance('Horde_Core_Factory_TextFilter');
     $parsed = $parser->parse($id, $data);
     if ($parsed instanceof Horde_ListHeaders_Id) {
         $out = $parsed->id;
         if ($parsed->label) {
             $out .= ' -- <em>' . $parsed->label . '</em>';
         }
         return $out;
     }
     foreach ($parsed as $val) {
         /* RFC 2369 [2] states that we should only show the *FIRST* URL
          * that appears in a header that we can adequately handle. */
         if (stripos($val->url, 'mailto:') === 0) {
             $url = substr($val->url, 7);
             $clink = new IMP_Compose_Link($url);
             $out = Horde::link($clink->link()) . $url . '</a>';
             foreach ($val->comments as $val2) {
                 $out .= htmlspecialchars('(' . $val2 . ')');
             }
             return $out;
         } elseif ($url = $text_filter->filter($val->url, 'Linkurls')) {
             $out = $url;
             foreach ($val->comments as $val2) {
                 $out .= htmlspecialchars('(' . $val2 . ')');
             }
             return $out;
         }
     }
     /* Pass through Linkurls filter anyway, since it is possible the
      * sender did not correctly put URL between brackets. */
     return Horde_Text_Filter_Linkurls::decode(htmlspecialchars($text_filter->filter($data, 'Linkurls', array('encode' => true))));
 }
Ejemplo n.º 3
0
 /**
  * Executes any code necessary before applying the filter patterns.
  *
  * @param mixed $text  The text before the filtering. Either a string or
  *                     a Horde_Text_Flowed object (since 1.1.0).
  *
  * @return string  The modified text.
  */
 public function preProcess($text)
 {
     if ($text instanceof Horde_Text_Flowed) {
         $text->setMaxLength(0);
         $lines = $text->toFixedArray();
         $level = 0;
         $out = $txt = '';
         foreach ($lines as $key => $val) {
             $line = ltrim($val['text'], '>');
             if (!isset($lines[$key + 1])) {
                 $out .= $this->preProcess(ltrim($txt) . $line);
                 while (--$level > 0) {
                     $out .= '</blockquote>';
                 }
             } elseif ($val['level'] > $level) {
                 $out .= $this->preProcess(ltrim($txt));
                 do {
                     $out .= $this->_params['flowed'];
                 } while (++$level != $val['level']);
                 $txt = $line;
             } elseif ($val['level'] < $level) {
                 $out .= $this->preProcess(ltrim($txt));
                 do {
                     $out .= '</blockquote>';
                 } while (--$level != $val['level']);
                 $txt = $line;
             } else {
                 $txt .= "\n" . $line;
             }
         }
         return $out;
     }
     if (!strlen($text)) {
         return '';
     }
     /* Abort out on simple cases. */
     if ($this->_params['parselevel'] == self::PASSTHRU) {
         return $text;
     }
     if ($this->_params['parselevel'] == self::NOHTML_NOBREAK) {
         return @htmlspecialchars($text, ENT_COMPAT, $this->_params['charset']);
     }
     if ($this->_params['parselevel'] < self::NOHTML) {
         $filters = array();
         if ($this->_params['linkurls']) {
             reset($this->_params['linkurls']);
             $this->_params['linkurls'][key($this->_params['linkurls'])]['encode'] = true;
             $filters = $this->_params['linkurls'];
         } else {
             $filters['linkurls'] = array('encode' => true);
         }
         if ($this->_params['parselevel'] < self::MICRO_LINKURL) {
             if ($this->_params['emails']) {
                 reset($this->_params['emails']);
                 $this->_params['emails'][key($this->_params['emails'])]['encode'] = true;
                 $filters += $this->_params['emails'];
             } else {
                 $filters['emails'] = array('encode' => true);
             }
         }
         $text = Horde_Text_Filter::filter($text, array_keys($filters), array_values($filters));
     }
     /* For level MICRO or NOHTML, start with htmlspecialchars(). */
     $text2 = @htmlspecialchars($text, ENT_COMPAT, $this->_params['charset']);
     /* Bad charset input in may result in an empty string. Or the charset
      * may not be supported. Convert to UTF-8 for htmlspecialchars() and
      * then convert back. If we STILL don't have any output, the input
      * charset is probably incorrect. Try the popular Western charsets as
      * a last resort. */
     if (!strlen($text2)) {
         $text2 = Horde_String::convertCharset(@htmlspecialchars(Horde_String::convertCharset($text, $this->_params['charset'], 'UTF-8'), ENT_COMPAT, 'UTF-8'), 'UTF-8', $this->_params['charset']);
         if (!strlen($text2)) {
             foreach (array('windows-1252', 'utf-8') as $val) {
                 $text2 = Horde_String::convertCharset(@htmlspecialchars($text, ENT_COMPAT, $val), $val, $this->_params['charset']);
                 if (strlen($text2)) {
                     break;
                 }
             }
         }
     }
     $text = $text2;
     /* Do in-lining of http://xxx.xxx to link, xxx@xxx.xxx to email. */
     if ($this->_params['parselevel'] < self::NOHTML) {
         $text = Horde_Text_Filter_Linkurls::decode($text);
         if ($this->_params['parselevel'] < self::MICRO_LINKURL) {
             $text = Horde_Text_Filter_Emails::decode($text);
         }
         if ($this->_params['space2html']) {
             $params = reset($this->_params['space2html']);
             $driver = key($this->_params['space2html']);
         } else {
             $driver = 'space2html';
             $params = array();
         }
         $text = Horde_Text_Filter::filter($text, $driver, $params);
     }
     /* Do the newline ---> <br /> substitution. Everybody gets this; if
      * you don't want even that, just use htmlspecialchars(). */
     return nl2br($text);
 }