XOOPS RMCommon Utilities  2.1.8.91RC
 All Classes Namespaces Files Functions Variables
textcleaner.php
Go to the documentation of this file.
1 <?php
2 // $Id: textcleaner.php 891 2011-12-30 08:41:31Z i.bitcero $
3 // --------------------------------------------------------------
4 // Red México Common Utilities
5 // A framework for Red México Modules
6 // Author: Eduardo Cortés <i.bitcero@gmail.com>
7 // Email: i.bitcero@gmail.com
8 // License: GPL 2.0
9 // --------------------------------------------------------------
10 
11 $aprotocols = array();
12 
17 {
18  private $protocols = array();
22  private $emots = array();
26  private $disable_tags = array(
27  '@<iframe[^>]*?>.*?</iframe>@si',
28  '@<script[^>]*?>.*?</script>@si',
29  '@<style[^>]*?>.*?</style>@si',
30  '@<html[^>]*?>.*?</html>@si',
31  '@<body[^>]*?>.*?</body>@si',
32  '@<meta[^>]*?>.*?</meta>@si'
33  );
37  static function getInstance(){
38  static $instance;
39  if (!isset($instance)) {
40  $instance = new TextCleaner();
41  }
42  return $instance;
43  }
44 
49  public function get_emotions(){
50 
51  $rmc_config = RMFunctions::get()->configs();
52 
53  if (!$rmc_config['dosmileys'])
54  return false;
55 
56  if (!empty($this->emots))
57  return $this->emots;
58 
59  // Only a few icons due to these can be extended by plugins or modules
60  $url = RMCURL.'/images/emots';
61  $this->emots[] = array('code'=>array(':)',':-)'),'icon'=>$url.'/smile.png');
62  $this->emots[] = array('code'=>array(':-S','O.o'),'icon'=>$url.'/confused.png');
63  $this->emots[] = array('code'=>array(":'("),'icon'=>$url.'/cry.png');
64  $this->emots[] = array('code'=>array(':->',':>'),'icon'=>$url.'/grin.png');
65  $this->emots[] = array('code'=>array(':D',':-D'),'icon'=>$url.'/happy.png');
66  $this->emots[] = array('code'=>array(':-O',':-o',':O',':o'),'icon'=>$url.'/surprised.png');
67  $this->emots[] = array('code'=>array(':p',':-p',':-P',':P'),'icon'=>$url.'/tongue.png');
68  $this->emots[] = array('code'=>array(':-(',':('),'icon'=>$url.'/unhappy.png');
69  $this->emots[] = array('code'=>array(';)',';-)'),'icon'=>$url.'/wink.png');
70  $this->emots[] = array('code'=>array(':-|'),'icon'=>$url.'/neutral.png');
71  $this->emots[] = array('code'=>array('8)','8-)','B)','B-)'),'icon'=>$url.'/cool.png');
72  $this->emots[] = array('code'=>array('>:(','>:-('),'icon'=>$url.'/mad.png');
73  $this->emots[] = array('code'=>array(':oops:'),'icon'=>$url.'/red.png');
74  $this->emots[] = array('code'=>array(':roll:'),'icon'=>$url.'/roll.png');
75  $this->emots[] = array('code'=>array('X-D','x-D'),'icon'=>$url.'/yell.png');
76 
77  // Get another emoticons from plugins or modules
78  $this->emots = RMEvents::get()->run_event('rmcommon.get_emotions', $this->emots);
79 
80  return $this->emots;
81 
82  }
88  function smiley($message)
89  {
90  $emots = $this->get_emotions();
91  $codes = array();
92  $icons = array();
93  foreach ($emots as $v){
94  foreach ($v['code'] as $code){
95  $codes[] = $code;
96  $icons[] = '<img src="'.$v['icon'].'" alt="" />';
97  }
98  }
99  $message = str_replace($codes,$icons,$message);
100  return $message;
101  }
102 
109  public function make_clickable($string){
110  $string = ' ' . $string;
111  // in testing, using arrays here was found to be faster
112  $string = preg_replace_callback('#(?<=[\s>])(\()?([\w]+?://(?:[\w\\x80-\\xff\#$%&~/\-=?@\[\](+]|[.,;:](?![\s<])|(?(1)\)(?![\s<])|\)))+)#is', "url_clickable", $string);
113  $string = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', 'ftp_clickable', $string);
114  $string = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', 'mail_clickable', $string);
115  // this one is not in an array because we need it to run last, for cleanup of accidental links within links
116  $string = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $string);
117  $string = trim($string);
118  return $string;
119  }
120 
121  function nofollow( $text ) {
122  global $wpdb;
123  // This is a pre save filter, so text is already escaped.
124  $text = stripslashes($text);
125  $text = preg_replace_callback('|<a (.+?)>|i', 'rel_nofollow', $text);
126  return $text;
127  }
128 
129  function popuplinks($text) {
130  $text = preg_replace('/<a (.+?)>/i', "<a $1 target='_blank' rel='external'>", $text);
131  return $text;
132  }
133 
140  public function url_clickable($matches){
141  $url = $matches[2];
142  $url = self::clean_url($url);
143  if ( empty($url) )
144  return $matches[0];
145 
146  return $matches[1] . "<a href=\"$url\" rel=\"nofollow\">$url</a>";
147  }
148 
149  public function ftp_clickable($matches){
150  $ret = '';
151  $dest = $matches[2];
152  $dest = 'http://' . $dest;
153  $dest = self::clean_url($dest);
154  if ( empty($dest) )
155  return $matches[0];
156  // removed trailing [,;:] from URL
157  if ( in_array(substr($dest, -1), array('.', ',', ';', ':')) === true ) {
158  $ret = substr($dest, -1);
159  $dest = substr($dest, 0, strlen($dest)-1);
160  }
161  return $matches[1] . "<a href=\"$dest\" rel=\"nofollow\">$dest</a>" . $ret;
162  }
163  public function mail_clickable($matches){
164  $email = $matches[2] . '@' . $matches[3];
165  return $matches[1] . "<a href=\"mailto:$email\">$email</a>";
166  }
167 
179  public function clean_url( $url, $protocols = null, $context = 'display' ) {
180  global $aprotocols;
181 
182  $original_url = $url;
183 
184  if ('' == $url) return $url;
185  $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);
186  $strip = array('%0d', '%0a', '%0D', '%0A');
187  $url = TextCleaner::replace($strip, $url);
188  $url = str_replace(';//', '://', $url);
189  /* If the URL doesn't appear to contain a scheme, we
190  * presume it needs http:// appended (unless a relative
191  * link starting with / or a php file).
192  */
193  if ( strpos($url, ':') === false &&
194  substr( $url, 0, 1 ) != '/' && substr( $url, 0, 1 ) != '#' && !preg_match('/^[a-z0-9-]+?\.php/i', $url) )
195  $url = 'http://' . $url;
196 
197  // Replace ampersands and single quotes only when displaying.
198  if ( 'display' == $context ) {
199  $url = preg_replace('/&([^#])(?![a-z]{2,8};)/', '&#038;$1', $url);
200  $url = str_replace( "'", '&#039;', $url );
201  }
202 
203  if ( !is_array($protocols) )
204  $protocols = array('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet');
205 
206  $aprotocols = $protocols;
207 
209  return '';
210 
211  return RMEvents::get()->run_event('rmcommon.clean_url', $url, $original_url, $context);
212  }
213 
214  private function bad_protocol($string, $allowed_protocols) {
215  $string = TextCleaner::no_null($string);
216  $string2 = $string.'a';
217 
218  while ($string != $string2) {
219  $string2 = $string;
220  $string = TextCleaner::bad_protocol_once($string, $allowed_protocols);
221  } # while
222 
223  return $string;
224  }
225 
226  private function bad_protocol_once($string, $allowed_protocols) {
227 
228  $string2 = preg_split('/:|&#58;|&#x3a;/i', $string, 2);
229  if ( isset($string2[1]) && !preg_match('%/\?%', $string2[0]) )
230  $string = TextCleaner::bad_protocol_once2($string2[0]) . trim($string2[1]);
231  else
232  $string = preg_replace_callback('/^((&[^;]*;|[\sA-Za-z0-9])*)'.'(:|&#58;|&#[Xx]3[Aa];)\s*/', 'bad_protocol_once2', $string);
233 
234  return $string;
235  }
236 
237  function bad_protocol_once2($matches) {
238  global $aprotocols;
239  $allowed_protocols = $aprotocols;
240 
241  if ( is_array($matches) ) {
242  if ( ! isset($matches[1]) || empty($matches[1]) )
243  return '';
244 
245  $string = $matches[1];
246  } else {
247  $string = $matches;
248  }
249 
250  $string2 = TextCleaner::decode_entities($string);
251  $string2 = preg_replace('/\s/', '', $string2);
252  $string2 = TextCleaner::no_null($string2);
253  $string2 = strtolower($string2);
254 
255  $allowed = false;
256  foreach ( (array) $allowed_protocols as $one_protocol)
257  if (strtolower($one_protocol) == $string2) {
258  $allowed = true;
259  break;
260  }
261 
262  if ($allowed)
263  return "$string2:";
264  else
265  return '';
266  }
267 
268  function decode_entities($string) {
269  $string = preg_replace_callback('/&#([0-9]+);/', 'decode_entities_chr', $string);
270  $string = preg_replace_callback('/&#[Xx]([0-9A-Fa-f]+);/', 'decode_entities_chr_hexdec', $string);
271 
272  return $string;
273  }
274 
275  public function decode_entities_chr( $match ) {
276  return chr( $match[1] );
277  }
278 
279  public function decode_entities_chr_hexdec( $match ) {
280  return chr( hexdec( $match[1] ) );
281  }
282 
283  public function no_null($string) {
284  $string = preg_replace('/\0+/', '', $string);
285  $string = preg_replace('/(\\\\0)+/', '', $string);
286 
287  return $string;
288  }
289 
290  public function replace($search, $subject){
291  $found = true;
292  while($found) {
293  $found = false;
294  foreach( (array) $search as $val ) {
295  while(strpos($subject, $val) !== false) {
296  $found = true;
297  $subject = str_replace($val, '', $subject);
298  }
299  }
300  }
301 
302  return $subject;
303  }
304 
311  public function truncate($text, $len){
312  $text = preg_replace("[\n|\r|\n\r]", ' ', $text);
313  $ret = substr(strip_tags($text), 0, $len);
314 
315  if (strlen($text)>$len) $ret .= '...';
316  return $ret;
317  }
318 
327  public function codeDecode($text, $allowimage = 1)
328  {
329  $patterns = array();
330  $replacements = array();
331  //$patterns[] = "/\[code](.*)\[\/code\]/esU";
332  //$replacements[] = "'<div class=\"exmCode\"><code><pre>'.wordwrap(MyTextSanitizer::htmlSpecialChars('\\1'), 100).'</pre></code></div>'";
333  // RMV: added new markup for intrasite url (allows easier site moves)
334  // TODO: automatically convert other URLs to this format if XOOPS_ROOT_PATH matches??
335  $patterns['patterns'][] = "/\[siteurl=(['\"]?)([^\"'<>]*)\\1](.*)\[\/siteurl\]/sU";
336  $patterns['replacements'][] = '<a href="'.XOOPS_ROOT_PATH.'/\\2">\\3</a>';
337  $patterns['patterns'][] = "/\[url=(['\"]?)(http[s]?:\/\/[^\"'<>]*)\\1](.*)\[\/url\]/sU";
338  $patterns['replacements'][] = '<a href="\\2" target="_blank">\\3</a>';
339  $patterns['patterns'][] = "/\[url=(['\"]?)(ftp?:\/\/[^\"'<>]*)\\1](.*)\[\/url\]/sU";
340  $patterns['replacements'][] = '<a href="\\2" target="_blank">\\3</a>';
341  $patterns['patterns'][] = "/\[url=(['\"]?)([^\"'<>]*)\\1](.*)\[\/url\]/sU";
342  $patterns['replacements'][] = '<a href="http://\\2" target="_blank">\\3</a>';
343  $patterns['patterns'][] = "/\[color=(['\"]?)([a-zA-Z0-9]*)\\1](.*)\[\/color\]/sU";
344  $patterns['replacements'][] = '<span style="color: #\\2;">\\3</span>';
345  $patterns['patterns'][] = "/\[size=(['\"]?)([a-z0-9-]*)\\1](.*)\[\/size\]/sU";
346  $patterns['replacements'][] = '<span style="font-size: \\2;">\\3</span>';
347  $patterns['patterns'][] = "/\[font=(['\"]?)([^;<>\*\(\)\"']*)\\1](.*)\[\/font\]/sU";
348  $patterns['replacements'][] = '<span style="font-family: \\2;">\\3</span>';
349  $patterns['patterns'][] = "/\[email]([^;<>\*\(\)\"']*)\[\/email\]/sU";
350  $patterns['replacements'][] = '<a href="mailto:\\1">\\1</a>';
351 
352  $patterns['patterns'][] = "/\[b](.*)\[\/b\]/sU";
353  $patterns['replacements'][] = '<b>\\1</b>';
354  $patterns['patterns'][] = "/\[i](.*)\[\/i\]/sU";
355  $patterns['replacements'][] = '<i>\\1</i>';
356  $patterns['patterns'][] = "/\[u](.*)\[\/u\]/sU";
357  $patterns['replacements'][] = '<u>\\1</u>';
358  $patterns['patterns'][] = "/\[d](.*)\[\/d\]/sU";
359  $patterns['replacements'][] = '<del>\\1</del>';
360 
361  $patterns['patterns'][] = "/\[quote(=(.*)){0,1}\](.*)\[\/quote\]/";
362  $patterns['replacements'][] = '<blockquote>$3<p class="citeby">$2</p></blockquote>';
363 
364  $patterns['patterns'][] = "/\[img align=(['\"]?)(left|center|right)\\1]([^\"\(\)'<>]*)\[\/img\]/sU";
365  $patterns['patterns'][] = "/\[img]([^\"\(\)'<>]*)\[\/img\]/sU";
366  $patterns['patterns'][] = "/\[img align=(['\"]?)(left|center|right)\\1 id=(['\"]?)([0-9]*)\\3]([^\"\(\)\?\&'<>]*)\[\/img\]/sU";
367  $patterns['patterns'][] = "/\[img id=(['\"]?)([0-9]*)\\1]([^\"\(\)\?\&'<>]*)\[\/img\]/sU";
368 
369  if ($allowimage != 1) {
370  $patterns['replacements'][] = '<a href="\\3" target="_blank">\\3</a>';
371  $patterns['replacements'][] = '<a href="\\1" target="_blank">\\1</a>';
372  $patterns['replacements'][] = '<a href="'.XOOPS_ROOT_PATH.'/image.php?id=\\4" target="_blank">\\4</a>';
373  $patterns['replacements'][] = '<a href="'.XOOPS_ROOT_PATH.'/image.php?id=\\2" target="_blank">\\3</a>';
374  } else {
375  $patterns['replacements'][] = '<img src="\\3" align="\\2" alt="" />';
376  $patterns['replacements'][] = '<img src="\\1" alt="" />';
377  $patterns['replacements'][] = '<img src="'.XOOPS_ROOT_PATH.'/image.php?id=\\4" align="\\2" alt="\\4" />';
378  $patterns['replacements'][] = '<img src="'.XOOPS_ROOT_PATH.'/image.php?id=\\2" alt="\\3" />';
379  }
380 
381  $text = str_replace( "\x00", "", $text );
382  $c = "[\x01-\x1f]*";
383  $patterns['patterns'][] = "/j{$c}a{$c}v{$c}a{$c}s{$c}c{$c}r{$c}i{$c}p{$c}t{$c}:/si";
384  $patterns['replacements'][] = "(script removed)";
385  $patterns['patterns'][] = "/a{$c}b{$c}o{$c}u{$c}t{$c}:/si";
386  $patterns['replacements'][] = "about :";
387 
388  // More patterns with plugins
389  $patterns = RMEvents::get()->run_event('rmcommon.get.replace.patterns', $patterns, $this);
390 
391  $text = preg_replace($patterns['patterns'], $patterns['replacements'], $text);
392 
393  $text = RMEvents::get()->run_event('rmcommon.code.decode',$text);
394 
395  return $text;
396  }
397 
405  function nl2Br($text)
406  {
407  return preg_replace("/(\015\012)|(\015)|(\012)/","<br />",$text);
408  }
409 
416  function addslashes($text)
417  {
418  if (get_magic_quotes_gpc()) {
419  $text = stripslashes($text);
420  }
421  return addslashes($text);
422  }
423  /*
424  * if magic_quotes_gpc is on, stirip back slashes
425  *
426  * @param string $text
427  *
428  * @return string
429  */
430  function stripslashes($text)
431  {
432  if (get_magic_quotes_gpc()) {
433  $text = stripslashes($text);
434  }
435  return $text;
436  }
437 
438  /*
439  * for displaying data in html textbox forms
440  *
441  * @param string $text
442  *
443  * @return string
444  */
445  function specialchars($string, $quote_style = ENT_NOQUOTES, $charset = 'UTF-8')
446  {
447  if ( 0 === strlen( $string ) ) {
448  return '';
449  }
450 
451  if ( !preg_match( '/[&<>"\']/', $string ) ) {
452  return $string;
453  }
454 
455  if ( empty( $quote_style ) ) {
456  $quote_style = ENT_NOQUOTES;
457  } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) {
458  $quote_style = ENT_QUOTES;
459  }
460 
461  if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) ) {
462  $charset = 'UTF-8';
463  }
464 
465  if ( $quote_style === 'double' ) {
466  $quote_style = ENT_COMPAT;
467  $_quote_style = ENT_COMPAT;
468  } elseif ( $quote_style === 'single' ) {
469  $quote_style = ENT_NOQUOTES;
470  }
471 
472  $string = @htmlspecialchars( $string, $quote_style, $charset );
473 
474  //return preg_replace("/&amp;/i", '&', htmlspecialchars($text, ENT_QUOTES));
475  return preg_replace(array("/&amp;/i", "/&nbsp;/i"), array('&', '&amp;nbsp;'), htmlspecialchars($string, ENT_QUOTES));
476  }
477 
484  function specialchars_decode( $string, $quote_style = ENT_NOQUOTES )
485  {
486  if ( 0 === strlen( $string ) ) {
487  return '';
488  }
489 
490  // Don't bother if there are no entities - saves a lot of processing
491  if ( strpos( $string, '&' ) === false ) {
492  return $string;
493  }
494 
495  if ( empty( $quote_style ) ) {
496  $quote_style = ENT_NOQUOTES;
497  } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) {
498  $quote_style = ENT_QUOTES;
499  }
500 
501  // More complete than get_html_translation_table( HTML_SPECIALCHARS )
502  $single = array( '&#039;' => '\'', '&#x27;' => '\'' );
503  $single_preg = array( '/&#0*39;/' => '&#039;', '/&#x0*27;/i' => '&#x27;' );
504  $double = array( '&quot;' => '"', '&#034;' => '"', '&#x22;' => '"' );
505  $double_preg = array( '/&#0*34;/' => '&#034;', '/&#x0*22;/i' => '&#x22;' );
506  $others = array( '&lt;' => '<', '&#060;' => '<', '&gt;' => '>', '&#062;' => '>', '&amp;' => '&', '&#038;' => '&', '&#x26;' => '&' );
507  $others_preg = array( '/&#0*60;/' => '&#060;', '/&#0*62;/' => '&#062;', '/&#0*38;/' => '&#038;', '/&#x0*26;/i' => '&#x26;' );
508 
509  if ( $quote_style === ENT_QUOTES ) {
510  $translation = array_merge( $single, $double, $others );
511  $translation_preg = array_merge( $single_preg, $double_preg, $others_preg );
512  } elseif ( $quote_style === ENT_COMPAT || $quote_style === 'double' ) {
513  $translation = array_merge( $double, $others );
514  $translation_preg = array_merge( $double_preg, $others_preg );
515  } elseif ( $quote_style === 'single' ) {
516  $translation = array_merge( $single, $others );
517  $translation_preg = array_merge( $single_preg, $others_preg );
518  } elseif ( $quote_style === ENT_NOQUOTES ) {
519  $translation = $others;
520  $translation_preg = $others_preg;
521  }
522 
523  $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string );
524 
525  return strtr( $string, $translation );
526  }
527 
543  function double_br($string, $br = 1) {
544  if ( trim($string) === '' )
545  return '';
546  $string = $string . "\n"; // just to make things a little easier, pad the end
547  $string = preg_replace('|<br />\s*<br />|', "\n\n", $string);
548  // Space things out a little
549  $allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)';
550  $string = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $string);
551  $string = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $string);
552  $string = str_replace(array("\r\n", "\r"), "\n", $string); // cross-platform newlines
553  if ( strpos($string, '<object') !== false ) {
554  $string = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $string); // no pee inside object/embed
555  $string = preg_replace('|\s*</embed>\s*|', '</embed>', $string);
556  }
557  $string = preg_replace("/\n\n+/", "\n\n", $string); // take care of duplicates
558  // make paragraphs, including one at the end
559  $strings = preg_split('/\n\s*\n/', $string, -1, PREG_SPLIT_NO_EMPTY);
560  $string = '';
561  foreach ( $strings as $tinkle )
562  $string .= '<p>' . trim($tinkle, "\n") . "</p>\n";
563  $string = preg_replace('|<p>\s*</p>|', '', $string); // under certain strange conditions it could create a P of entirely whitespace
564  $string = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $string);
565  $string = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $string); // don't pee all over a tag
566  $string = preg_replace("|<p>(<li.+?)</p>|", "$1", $string); // problem with nested lists
567  $string = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $string);
568  $string = str_replace('</blockquote></p>', '</p></blockquote>', $string);
569  $string = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $string);
570  $string = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $string);
571  if ($br) {
572  $string = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "<EXMPreserveNewline />", $matches[0]);'), $string);
573  $string = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $string); // optionally make line breaks
574  $string = str_replace('<EXMPreserveNewline />', "\n", $string);
575  }
576  $string = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $string);
577  $string = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $string);
578  if (strpos($string, '<pre') !== false)
579  $string = preg_replace_callback('!(<pre[^>]*>)(.*?)</pre>!is', 'TextCleaner::clean_pre', $string );
580  //$string = preg_replace( "|\n</p>$|", '</p>', $string );
581  //$string = preg_replace('/<p>\s*?(' . get_shortcode_regex() . ')\s*<\/p>/s', '$1', $string); // don't auto-p wrap shortcodes that stand alone
582 
583  return $string;
584  }
585 
596  function to_display($text, $dbr = true, $clean_tags = true, $paragraph = true){
597 
598  $rmc_config = empty($params) ? RMFunctions::get()->configs() : $params;
599 
600  $original_text = $text;
601  if ($rmc_config['dohtml'] != 1){
602  $text = $this->specialchars($text);
603  }
604 
605  // Convert [code] tag
606  $text = $this->codePreConv($text, $rmc_config['doxcode']);
607 
608  if ($rmc_config['dosmileys'])
609  $text = $this->smiley($text);
610 
611  // Decode exmcode
612  if ($rmc_config['doxcode'])
613  $text = $this->codeDecode($text, $rmc_config['doimage']);
614 
615  // Replace breaklines
616  if ($rmc_config['dobr'])
617  $text = $this->nl2Br($text);
618 
619  if($clean_tags) $text = $this->clean_disabled_tags($text);
620  $text = $this->make_clickable($text);
621  $text = $this->codeConv($text, $rmc_config['doxcode']); // Ryuji_edit(2003-11-18)
622  if($paragraph) $text = $this->double_br($text);
623 
624  // Custom Codes
625  global $rmCodes;
626  $text = $rmCodes->doCode($text);
627 
628  // Before to send the formatted string we send it to interceptor methods
629  return RMEvents::get()->run_event('rmcommon.text.todisplay', $text, $original_text);
630  }
631 
632  function clean_disabled_tags($text){
633 
634  $this->disable_tags = RMEvents::get()->run_event('rmcommon.more.disabled.tags', $this->disable_tags);
635 
636  $text = preg_replace_callback($this->disable_tags,"preg_striptags",$text);
637  return $text;
638 
639  }
640 
645  function codePreConv($text) {
646  $patterns = "/\[code([^\]]*?)\](.*)\[\/code\]/esU";
647  $replacements = "'[code$1]'.base64_encode('$2').'[/code]'";
648  $text = preg_replace($patterns, $replacements, $text);
649  return $text;
650  }
651 
652  function codeConv($text, $exmcode = 1){
653 
654  if ($exmcode==0)
655  return $text;
656 
657  $patterns = "/\[code([^\]]*?)\](.*)\[\/code\]/esU";
658  $replacements = "'<div class=\"xoopsCode\"><code>'.\$this->call_code_modifiers(\$this->specialchars(str_replace('\\\"', '\"', base64_decode('$2'))), '$1').'</code></div>'";
659  $text = preg_replace($patterns, $replacements, $text);
660  return $text;
661  }
662 
670  public function call_code_modifiers($code, $lang){
671  // Event to call methods thatr can handle code to display (eg. highlighters)
672  return RMEvents::get()->run_event('rmcommon.format.code', $code, $lang);
673  }
674 
686  function clean_pre($matches) {
687  if ( is_array($matches) )
688  $text = $matches[1] . $matches[2] . "</pre>";
689  else
690  $text = $matches;
691 
692  $text = str_replace('<br />', '', $text);
693  $text = str_replace('<p>', "\n", $text);
694  $text = str_replace('</p>', '', $text);
695 
696  return $text;
697  }
698 
706  public function encrypt($string, $encode64 = true){
707 
708  $rmc_config = RMFunctions::get()->configs();
709  $crypt = new Crypt(Crypt::MODE_HEX, $rmc_config['secretkey']);
710  $string = $crypt->encrypt($string);
711  //if ($encode64) $string = base64_encode($string);
712  return $string;
713 
714  }
715 
722  public function decrypt($string, $encode64 = true){
723 
725 
726  $crypt = new Crypt(Crypt::MODE_HEX, $rmc_config['secretkey']);
727  $string = $crypt->decrypt($string);
728 
729  return $string;
730 
731  }
732 
737  public function sweetstring($value, $lower = true) {
738  // Tranformamos todo a minusculas
739  $rtn = $lower ? strtolower(utf8_decode($value)) : $value;
740 
741  //Rememplazamos caracteres especiales latinos
742  $find = array('á', 'é', 'í', 'ó', 'ú', 'ñ');
743  $repl = array('a', 'e', 'i', 'o', 'u', 'n');
744  $rtn = str_replace ($find, $repl, utf8_encode($rtn));
745 
746  // Añadimos los guiones
747  $find = array(' ', '&', '\r\n', '\n', '+');
748  $rtn = str_replace ($find, '-', $rtn);
749 
750  // Eliminamos y Reemplazamos demás caracteres especiales
751  $find = array('/[^a-zA-Z0-9\-<>_]/', '/[\-]+/', '/<[^>]*>/');
752  $repl = array('', '-', '');
753  $url = preg_replace ($find, $repl, $rtn);
754  return $url;
755 
756  }
757 
758 }
759 
760 // For compatibility
761 function url_clickable($matches){
762  return TextCleaner::url_clickable($matches);
763 }
764 
765 function ftp_clickable($matches){
766  return TextCleaner::ftp_clickable($matches);
767 }
768 
769 function mail_clickable($matches){
770  return TextCleaner::mail_clickable($matches);
771 }
772 function bad_protocol_once2($matches){
773  return TextCleaner::bad_protocol_once2($matches);
774 }
775 function decode_entities_chr($matches){
776  return TextCleaner::decode_entities_chr($matches);
777 }
778 function decode_entities_chr_hexdec($matches){
780 }
781 function rel_nofollow( $matches ) {
782  $text = $matches[1];
783  $text = str_replace(array(' rel="nofollow"', " rel='nofollow'"), '', $text);
784  return "<a $text rel=\"nofollow\">";
785 }
786 function preg_striptags($match){
787  //return TextCleaner::getInstance()->specialchars($match);
788  $ret = '';
789  if(is_array($match)){
790  foreach($match as $i => $t){
791  $ret .= TextCleaner::getInstance()->specialchars($t);
792  }
793  } else {
794  $match = TextCleaner::getInstance()->specialchars($match);
795  }
796  return $ret;
797 }