alecpl
2010-10-27 d21a05b48117ce7dbef4ad7997ed15c26bccf481
commit | author | age
aa055c 1 <?php
T 2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/include/rcube_string_replacer.php                             |
6  |                                                                       |
e019f2 7  | This file is part of the Roundcube Webmail client                     |
A 8  | Copyright (C) 2009, Roundcube Dev. - Switzerland                      |
aa055c 9  | Licensed under the GNU GPL                                            |
T 10  |                                                                       |
11  | PURPOSE:                                                              |
12  |   Handle string replacements based on preg_replace_callback           |
13  |                                                                       |
14  +-----------------------------------------------------------------------+
15  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16  +-----------------------------------------------------------------------+
17
1d786c 18  $Id$
aa055c 19
T 20 */
21
22
23 /**
24  * Helper class for string replacements based on preg_replace_callback
25  *
26  * @package Core
27  */
28 class rcube_string_replacer
29 {
30   public static $pattern = '/##str_replacement\[([0-9]+)\]##/';
88ed23 31   public $mailto_pattern;
A 32   public $link_pattern;
aa055c 33   private $values = array();
T 34
88ed23 35
A 36   function __construct()
37   {
9cc93a 38     // Simplified domain expression for UTF8 characters handling
937e26 39     $utf_domain = '[^?&@"\'\\/()\s\r\t\n]+\\.[a-z]{2,5}';
d21a05 40     $url = '[a-z0-9%=#@+?.:;&\\/_~-]+';
88ed23 41
937e26 42     $this->link_pattern = "/([\w]+:\/\/|\Wwww\.)($utf_domain($url)?)/i";
b6244d 43     $this->mailto_pattern = "/("
A 44         ."[-\w!\#\$%&\'*+~\/^`|{}=]+(?:\.[-\w!\#\$%&\'*+~\/^`|{}=]+)*"  // local-part
9cc93a 45         ."@$utf_domain"                                                 // domain-part
d21a05 46         ."(\?$url)?"                                                    // e.g. ?subject=test...
b6244d 47         .")/i";
88ed23 48   }
aa055c 49
T 50   /**
51    * Add a string to the internal list
52    *
53    * @param string String value 
54    * @return int Index of value for retrieval
55    */
56   public function add($str)
57   {
58     $i = count($this->values);
59     $this->values[$i] = $str;
60     return $i;
61   }
62
63   /**
64    * Build replacement string
65    */
66   public function get_replacement($i)
67   {
68     return '##str_replacement['.$i.']##';
69   }
70
71   /**
72    * Callback function used to build HTML links around URL strings
73    *
74    * @param array Matches result from preg_replace_callback
75    * @return int Index of saved string value
76    */
77   public function link_callback($matches)
78   {
79     $i = -1;
80     $scheme = strtolower($matches[1]);
81
a17696 82     if (preg_match('!^(http|ftp|file)s?://!', $scheme)) {
88ed23 83       $url = $matches[1] . $matches[2];
A 84       $i = $this->add(html::a(array('href' => $url, 'target' => '_blank'), Q($url)));
aa055c 85     }
88ed23 86     else if (preg_match('/^(\W)www\.$/', $matches[1], $m)) {
A 87       $url = 'www.' . $matches[2];
88       $i = $this->add($m[1] . html::a(array('href' => 'http://' . $url, 'target' => '_blank'), Q($url)));
aa055c 89     }
T 90
3d4ba6 91     // Return valid link for recognized schemes, otherwise, return the unmodified string for unrecognized schemes.
T 92     return $i >= 0 ? $this->get_replacement($i) : $matches[0];
aa055c 93   }
T 94
95   /**
96    * Callback function used to build mailto: links around e-mail strings
97    *
98    * @param array Matches result from preg_replace_callback
99    * @return int Index of saved string value
100    */
101   public function mailto_callback($matches)
102   {
103     $i = $this->add(html::a(array(
104         'href' => 'mailto:' . $matches[1],
105         'onclick' => "return ".JS_OBJECT_NAME.".command('compose','".JQ($matches[1])."',this)",
106       ),
107       Q($matches[1])));
108
109     return $i >= 0 ? $this->get_replacement($i) : '';
110   }
111
112   /**
113    * Look up the index from the preg_replace matches array
114    * and return the substitution value.
115    *
116    * @param array Matches result from preg_replace_callback
117    * @return string Value at index $matches[1]
118    */
119   public function replace_callback($matches)
120   {
121     return $this->values[$matches[1]];
122   }
123
124   /**
125    * Replace substituted strings with original values
126    */
127   public function resolve($str)
128   {
129     return preg_replace_callback(self::$pattern, array($this, 'replace_callback'), $str);
130   }
131
132 }