WordPress.org

Make WordPress Core

source: tags/2.1.3/wp-includes/formatting.php

Last change on this file was 5096, checked in by ryan, 14 years ago

Fix relative link mangling in clean_url. fixes #4017 for 2.1

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.2 KB
Line 
1<?php
2
3function wptexturize($text) {
4        global $wp_cockneyreplace;
5        $next = true;
6        $output = '';
7        $curl = '';
8        $textarr = preg_split('/(<.*>)/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
9        $stop = count($textarr);
10
11        // if a plugin has provided an autocorrect array, use it
12        if ( isset($wp_cockneyreplace) ) {
13                $cockney = array_keys($wp_cockneyreplace);
14                $cockney_replace = array_values($wp_cockneyreplace);
15        } else {
16                $cockney = array("'tain't","'twere","'twas","'tis","'twill","'til","'bout","'nuff","'round","'cause");
17                $cockneyreplace = array("&#8217;tain&#8217;t","&#8217;twere","&#8217;twas","&#8217;tis","&#8217;twill","&#8217;til","&#8217;bout","&#8217;nuff","&#8217;round","&#8217;cause");
18        }
19
20        $static_characters = array_merge(array('---', ' -- ', '--', 'xn&#8211;', '...', '``', '\'s', '\'\'', ' (tm)'), $cockney); 
21        $static_replacements = array_merge(array('&#8212;', ' &#8212; ', '&#8211;', 'xn--', '&#8230;', '&#8220;', '&#8217;s', '&#8221;', ' &#8482;'), $cockneyreplace);
22
23        $dynamic_characters = array('/\'(\d\d(?:&#8217;|\')?s)/', '/(\s|\A|")\'/', '/(\d+)"/', '/(\d+)\'/', '/(\S)\'([^\'\s])/', '/(\s|\A)"(?!\s)/', '/"(\s|\S|\Z)/', '/\'([\s.]|\Z)/', '/(\d+)x(\d+)/');
24        $dynamic_replacements = array('&#8217;$1','$1&#8216;', '$1&#8243;', '$1&#8242;', '$1&#8217;$2', '$1&#8220;$2', '&#8221;$1', '&#8217;$1', '$1&#215;$2'); 
25
26        for ( $i = 0; $i < $stop; $i++ ) {
27                $curl = $textarr[$i];
28
29                if (isset($curl{0}) && '<' != $curl{0} && $next) { // If it's not a tag
30                        // static strings
31                        $curl = str_replace($static_characters, $static_replacements, $curl);
32
33                        // regular expressions
34                        $curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);
35                } elseif ( strstr($curl, '<code') || strstr($curl, '<pre') || strstr($curl, '<kbd') || strstr($curl, '<style') || strstr($curl, '<script') ) { 
36                        $next = false;
37                } else {
38                        $next = true;
39                }
40
41                $curl = preg_replace('/&([^#])(?![a-zA-Z1-4]{1,8};)/', '&#038;$1', $curl);
42                $output .= $curl;
43        }
44
45        return $output;
46}
47
48function clean_pre($text) {
49        $text = str_replace('<br />', '', $text);
50        $text = str_replace('<p>', "\n", $text);
51        $text = str_replace('</p>', '', $text);
52        return $text;
53}
54
55function wpautop($pee, $br = 1) {
56        $pee = $pee . "\n"; // just to make things a little easier, pad the end
57        $pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
58        // Space things out a little
59        $allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|style|script|object|input|param|p|h[1-6])';
60        $pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
61        $pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
62        $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
63        $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
64        $pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end
65        $pee = preg_replace('|<p>\s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
66        $pee = preg_replace('!<p>([^<]+)\s*?(</(?:div|address|form)[^>]*>)!', "<p>$1</p>$2", $pee);
67        $pee = preg_replace( '|<p>|', "$1<p>", $pee );
68        $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
69        $pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
70        $pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
71        $pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
72        $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
73        $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
74        if ($br) {
75                $pee = preg_replace('/<(script|style).*?<\/\\1>/se', 'str_replace("\n", "<WPPreserveNewline />", "\\0")', $pee);
76                $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
77                $pee = str_replace('<WPPreserveNewline />', "\n", $pee);
78        }
79        $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
80        $pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
81        if ( strstr( $pee, '<pre' ) )
82                $pee = preg_replace('!(<pre.*?>)(.*?)</pre>!ise', " stripslashes('$1') .  stripslashes(clean_pre('$2'))  . '</pre>' ", $pee);
83        $pee = preg_replace( "|\n</p>$|", '</p>', $pee );
84
85        return $pee;
86}
87
88
89function seems_utf8($Str) { # by bmorel at ssi dot fr
90        for ($i=0; $i<strlen($Str); $i++) {
91                if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb
92                elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
93                elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
94                elseif ((ord($Str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb
95                elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb
96                elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b
97                else return false; # Does not match any model
98                for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
99                        if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80))
100                        return false;
101                }
102        }
103        return true;
104}
105
106function wp_specialchars( $text, $quotes = 0 ) {
107        // Like htmlspecialchars except don't double-encode HTML entities
108        $text = str_replace('&&', '&#038;&', $text);
109        $text = str_replace('&&', '&#038;&', $text);
110        $text = preg_replace('/&(?:$|([^#])(?![a-z1-4]{1,8};))/', '&#038;$1', $text);
111        $text = str_replace('<', '&lt;', $text);
112        $text = str_replace('>', '&gt;', $text);
113        if ( 'double' === $quotes ) {
114                $text = str_replace('"', '&quot;', $text);
115        } elseif ( 'single' === $quotes ) {
116                $text = str_replace("'", '&#039;', $text);
117        } elseif ( $quotes ) {
118                $text = str_replace('"', '&quot;', $text);
119                $text = str_replace("'", '&#039;', $text);
120        }
121        return $text;
122}
123
124function utf8_uri_encode( $utf8_string, $length = 0 ) {
125        $unicode = '';
126        $values = array();
127        $num_octets = 1;
128
129        for ($i = 0; $i < strlen( $utf8_string ); $i++ ) {
130
131                $value = ord( $utf8_string[ $i ] );
132
133                if ( $value < 128 ) {
134                        if ( $length && ( strlen($unicode) + 1 > $length ) )
135                                break; 
136                        $unicode .= chr($value);
137                } else {
138                        if ( count( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3;
139
140                        $values[] = $value;
141
142                        if ( $length && ( (strlen($unicode) + ($num_octets * 3)) > $length ) )
143                                break;
144                        if ( count( $values ) == $num_octets ) {
145                                if ($num_octets == 3) {
146                                        $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]);
147                                } else {
148                                        $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]);
149                                }
150
151                                $values = array();
152                                $num_octets = 1;
153                        }
154                }
155        }
156
157        return $unicode;
158}
159
160function remove_accents($string) {
161        if ( !preg_match('/[\x80-\xff]/', $string) )
162                return $string;
163
164        if (seems_utf8($string)) {
165                $chars = array(
166                // Decompositions for Latin-1 Supplement
167                chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
168                chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
169                chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
170                chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
171                chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
172                chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
173                chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
174                chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
175                chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
176                chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
177                chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
178                chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
179                chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
180                chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
181                chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
182                chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
183                chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
184                chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
185                chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
186                chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
187                chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
188                chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
189                chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
190                chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
191                chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
192                chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
193                chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
194                chr(195).chr(191) => 'y',
195                // Decompositions for Latin Extended-A
196                chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
197                chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
198                chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
199                chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
200                chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
201                chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
202                chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
203                chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
204                chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
205                chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
206                chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
207                chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
208                chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
209                chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
210                chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
211                chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
212                chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
213                chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
214                chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
215                chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
216                chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
217                chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
218                chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
219                chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
220                chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
221                chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
222                chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
223                chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
224                chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
225                chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
226                chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
227                chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
228                chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
229                chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
230                chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
231                chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
232                chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
233                chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
234                chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
235                chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
236                chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
237                chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
238                chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
239                chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
240                chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
241                chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
242                chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
243                chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
244                chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
245                chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
246                chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
247                chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
248                chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
249                chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
250                chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
251                chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
252                chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
253                chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
254                chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
255                chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
256                chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
257                chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
258                chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
259                chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
260                // Euro Sign
261                chr(226).chr(130).chr(172) => 'E',
262                // GBP (Pound) Sign
263                chr(194).chr(163) => '');
264
265                $string = strtr($string, $chars);
266        } else {
267                // Assume ISO-8859-1 if not UTF-8
268                $chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
269                        .chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
270                        .chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
271                        .chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
272                        .chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
273                        .chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
274                        .chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
275                        .chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
276                        .chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
277                        .chr(252).chr(253).chr(255);
278
279                $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
280
281                $string = strtr($string, $chars['in'], $chars['out']);
282                $double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
283                $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
284                $string = str_replace($double_chars['in'], $double_chars['out'], $string);
285        }
286
287        return $string;
288}
289
290function sanitize_file_name( $name ) { // Like sanitize_title, but with periods
291        $name = strtolower( $name );
292        $name = preg_replace('/&.+?;/', '', $name); // kill entities
293        $name = str_replace( '_', '-', $name );
294        $name = preg_replace('/[^a-z0-9\s-.]/', '', $name);
295        $name = preg_replace('/\s+/', '-', $name);
296        $name = preg_replace('|-+|', '-', $name);
297        $name = trim($name, '-');
298        return $name;
299}
300
301function sanitize_user( $username, $strict = false ) {
302        $raw_username = $username;
303        $username = strip_tags($username);
304        // Kill octets
305        $username = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '', $username);
306        $username = preg_replace('/&.+?;/', '', $username); // Kill entities
307
308        // If strict, reduce to ASCII for max portability.
309        if ( $strict )
310                $username = preg_replace('|[^a-z0-9 _.\-@]|i', '', $username);
311
312        return apply_filters('sanitize_user', $username, $raw_username, $strict);
313}
314
315function sanitize_title($title, $fallback_title = '') {
316        $title = strip_tags($title);
317        $title = apply_filters('sanitize_title', $title);
318
319        if (empty($title)) {
320                $title = $fallback_title;
321        }
322
323        return $title;
324}
325
326function sanitize_title_with_dashes($title) {
327        $title = strip_tags($title);
328        // Preserve escaped octets.
329        $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
330        // Remove percent signs that are not part of an octet.
331        $title = str_replace('%', '', $title);
332        // Restore octets.
333        $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);
334
335        $title = remove_accents($title);
336        if (seems_utf8($title)) {
337                if (function_exists('mb_strtolower')) {
338                        $title = mb_strtolower($title, 'UTF-8');
339                }
340                $title = utf8_uri_encode($title, 200);
341        }
342
343        $title = strtolower($title);
344        $title = preg_replace('/&.+?;/', '', $title); // kill entities
345        $title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
346        $title = preg_replace('/\s+/', '-', $title);
347        $title = preg_replace('|-+|', '-', $title);
348        $title = trim($title, '-');
349
350        return $title;
351}
352
353function convert_chars($content, $flag = 'obsolete') {
354        // Translation of invalid Unicode references range to valid range
355        $wp_htmltranswinuni = array(
356        '&#128;' => '&#8364;', // the Euro sign
357        '&#129;' => '',
358        '&#130;' => '&#8218;', // these are Windows CP1252 specific characters
359        '&#131;' => '&#402;',  // they would look weird on non-Windows browsers
360        '&#132;' => '&#8222;',
361        '&#133;' => '&#8230;',
362        '&#134;' => '&#8224;',
363        '&#135;' => '&#8225;',
364        '&#136;' => '&#710;',
365        '&#137;' => '&#8240;',
366        '&#138;' => '&#352;',
367        '&#139;' => '&#8249;',
368        '&#140;' => '&#338;',
369        '&#141;' => '',
370        '&#142;' => '&#382;',
371        '&#143;' => '',
372        '&#144;' => '',
373        '&#145;' => '&#8216;',
374        '&#146;' => '&#8217;',
375        '&#147;' => '&#8220;',
376        '&#148;' => '&#8221;',
377        '&#149;' => '&#8226;',
378        '&#150;' => '&#8211;',
379        '&#151;' => '&#8212;',
380        '&#152;' => '&#732;',
381        '&#153;' => '&#8482;',
382        '&#154;' => '&#353;',
383        '&#155;' => '&#8250;',
384        '&#156;' => '&#339;',
385        '&#157;' => '',
386        '&#158;' => '',
387        '&#159;' => '&#376;'
388        );
389
390        // Remove metadata tags
391        $content = preg_replace('/<title>(.+?)<\/title>/','',$content);
392        $content = preg_replace('/<category>(.+?)<\/category>/','',$content);
393
394        // Converts lone & characters into &#38; (a.k.a. &amp;)
395        $content = preg_replace('/&([^#])(?![a-z1-4]{1,8};)/i', '&#038;$1', $content);
396
397        // Fix Word pasting
398        $content = strtr($content, $wp_htmltranswinuni);
399
400        // Just a little XHTML help
401        $content = str_replace('<br>', '<br />', $content);
402        $content = str_replace('<hr>', '<hr />', $content);
403
404        return $content;
405}
406
407function funky_javascript_fix($text) {
408        // Fixes for browsers' javascript bugs
409        global $is_macIE, $is_winIE;
410
411        if ( $is_winIE || $is_macIE )
412                $text =  preg_replace("/\%u([0-9A-F]{4,4})/e",  "'&#'.base_convert('\\1',16,10).';'", $text);
413
414        return $text;
415}
416
417/*
418 balanceTags
419
420 Balances Tags of string using a modified stack.
421
422 @param text      Text to be balanced
423 @param force     Forces balancing, ignoring the value of the option
424 @return          Returns balanced text
425 @author          Leonard Lin (leonard@acm.org)
426 @version         v1.1
427 @date            November 4, 2001
428 @license         GPL v2.0
429 @notes
430 @changelog
431 ---  Modified by Scott Reilly (coffee2code) 02 Aug 2004
432        1.2  ***TODO*** Make better - change loop condition to $text
433        1.1  Fixed handling of append/stack pop order of end text
434             Added Cleaning Hooks
435        1.0  First Version
436*/
437function balanceTags($text, $force = false) {
438
439        if ( !$force && get_option('use_balanceTags') == 0 )
440                return $text;
441
442        $tagstack = array(); $stacksize = 0; $tagqueue = ''; $newtext = '';
443
444        # WP bug fix for comments - in case you REALLY meant to type '< !--'
445        $text = str_replace('< !--', '<    !--', $text);
446        # WP bug fix for LOVE <3 (and other situations with '<' before a number)
447        $text = preg_replace('#<([0-9]{1})#', '&lt;$1', $text);
448
449        while (preg_match("/<(\/?\w*)\s*([^>]*)>/",$text,$regex)) {
450                $newtext .= $tagqueue;
451
452                $i = strpos($text,$regex[0]);
453                $l = strlen($regex[0]);
454
455                // clear the shifter
456                $tagqueue = '';
457                // Pop or Push
458                if ($regex[1][0] == "/") { // End Tag
459                        $tag = strtolower(substr($regex[1],1));
460                        // if too many closing tags
461                        if($stacksize <= 0) {
462                                $tag = '';
463                                //or close to be safe $tag = '/' . $tag;
464                        }
465                        // if stacktop value = tag close value then pop
466                        else if ($tagstack[$stacksize - 1] == $tag) { // found closing tag
467                                $tag = '</' . $tag . '>'; // Close Tag
468                                // Pop
469                                array_pop ($tagstack);
470                                $stacksize--;
471                        } else { // closing tag not at top, search for it
472                                for ($j=$stacksize-1;$j>=0;$j--) {
473                                        if ($tagstack[$j] == $tag) {
474                                        // add tag to tagqueue
475                                                for ($k=$stacksize-1;$k>=$j;$k--){
476                                                        $tagqueue .= '</' . array_pop ($tagstack) . '>';
477                                                        $stacksize--;
478                                                }
479                                                break;
480                                        }
481                                }
482                                $tag = '';
483                        }
484                } else { // Begin Tag
485                        $tag = strtolower($regex[1]);
486
487                        // Tag Cleaning
488
489                        // If self-closing or '', don't do anything.
490                        if((substr($regex[2],-1) == '/') || ($tag == '')) {
491                        }
492                        // ElseIf it's a known single-entity tag but it doesn't close itself, do so
493                        elseif ($tag == 'br' || $tag == 'img' || $tag == 'hr' || $tag == 'input') {
494                                $regex[2] .= '/';
495                        } else {        // Push the tag onto the stack
496                                // If the top of the stack is the same as the tag we want to push, close previous tag
497                                if (($stacksize > 0) && ($tag != 'div') && ($tagstack[$stacksize - 1] == $tag)) {
498                                        $tagqueue = '</' . array_pop ($tagstack) . '>';
499                                        $stacksize--;
500                                }
501                                $stacksize = array_push ($tagstack, $tag);
502                        }
503
504                        // Attributes
505                        $attributes = $regex[2];
506                        if($attributes) {
507                                $attributes = ' '.$attributes;
508                        }
509                        $tag = '<'.$tag.$attributes.'>';
510                        //If already queuing a close tag, then put this tag on, too
511                        if ($tagqueue) {
512                                $tagqueue .= $tag;
513                                $tag = '';
514                        }
515                }
516                $newtext .= substr($text,0,$i) . $tag;
517                $text = substr($text,$i+$l);
518        }
519
520        // Clear Tag Queue
521        $newtext .= $tagqueue;
522
523        // Add Remaining text
524        $newtext .= $text;
525
526        // Empty Stack
527        while($x = array_pop($tagstack)) {
528                $newtext .= '</' . $x . '>'; // Add remaining tags to close
529        }
530
531        // WP fix for the bug with HTML comments
532        $newtext = str_replace("< !--","<!--",$newtext);
533        $newtext = str_replace("<    !--","< !--",$newtext);
534
535        return $newtext;
536}
537
538function force_balance_tags($text) {
539        return balanceTags($text, true);
540}
541
542function format_to_edit($content, $richedit = false) {
543        $content = apply_filters('format_to_edit', $content);
544        if (! $richedit )
545                $content = htmlspecialchars($content);
546        return $content;
547}
548
549function format_to_post($content) {
550        global $wpdb;
551        $content = apply_filters('format_to_post', $content);
552        return $content;
553}
554
555function zeroise($number,$threshold) { // function to add leading zeros when necessary
556        return sprintf('%0'.$threshold.'s', $number);
557}
558
559
560function backslashit($string) {
561        $string = preg_replace('/^([0-9])/', '\\\\\\\\\1', $string);
562        $string = preg_replace('/([a-z])/i', '\\\\\1', $string);
563        return $string;
564}
565
566function trailingslashit($string) {
567                if ( '/' != substr($string, -1)) {
568                                $string .= '/';
569                }
570                return $string;
571}
572
573function addslashes_gpc($gpc) {
574        global $wpdb;
575
576        if (get_magic_quotes_gpc()) {
577                $gpc = stripslashes($gpc);
578        }
579
580        return $wpdb->escape($gpc);
581}
582
583
584function stripslashes_deep($value)
585{
586         $value = is_array($value) ?
587                                                         array_map('stripslashes_deep', $value) :
588                                                         stripslashes($value);
589
590         return $value;
591}
592
593function antispambot($emailaddy, $mailto=0) {
594        $emailNOSPAMaddy = '';
595        srand ((float) microtime() * 1000000);
596        for ($i = 0; $i < strlen($emailaddy); $i = $i + 1) {
597                $j = floor(rand(0, 1+$mailto));
598                if ($j==0) {
599                        $emailNOSPAMaddy .= '&#'.ord(substr($emailaddy,$i,1)).';';
600                } elseif ($j==1) {
601                        $emailNOSPAMaddy .= substr($emailaddy,$i,1);
602                } elseif ($j==2) {
603                        $emailNOSPAMaddy .= '%'.zeroise(dechex(ord(substr($emailaddy, $i, 1))), 2);
604                }
605        }
606        $emailNOSPAMaddy = str_replace('@','&#64;',$emailNOSPAMaddy);
607        return $emailNOSPAMaddy;
608}
609
610function make_clickable($ret) {
611        $ret = ' ' . $ret;
612        // in testing, using arrays here was found to be faster
613        $ret = preg_replace(
614                array(
615                        '#([\s>])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)#is',
616                        '#([\s>])((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*)#is',
617                        '#([\s>])([a-z0-9\-_.]+)@([^,< \n\r]+)#i'),
618                array(
619                        '$1<a href="$2" rel="nofollow">$2</a>',
620                        '$1<a href="http://$2" rel="nofollow">$2</a>',
621                        '$1<a href="mailto:$2@$3">$2@$3</a>'),$ret);
622        // this one is not in an array because we need it to run last, for cleanup of accidental links within links
623        $ret = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $ret);
624        $ret = trim($ret);
625        return $ret;
626}
627
628function wp_rel_nofollow( $text ) {
629        global $wpdb;
630        // This is a pre save filter, so text is already escaped.
631        $text = stripslashes($text);
632        $text = preg_replace('|<a (.+?)>|ie', "'<a ' . str_replace(' rel=\"nofollow\"','',stripslashes('$1')) . ' rel=\"nofollow\">'", $text);
633        $text = $wpdb->escape($text);
634        return $text;
635}
636
637function convert_smilies($text) {
638        global $wp_smiliessearch, $wp_smiliesreplace;
639    $output = '';
640        if (get_option('use_smilies')) {
641                // HTML loop taken from texturize function, could possible be consolidated
642                $textarr = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE); // capture the tags as well as in between
643                $stop = count($textarr);// loop stuff
644                for ($i = 0; $i < $stop; $i++) { 
645                        $content = $textarr[$i]; 
646                        if ((strlen($content) > 0) && ('<' != $content{0})) { // If it's not a tag
647                                $content = preg_replace($wp_smiliessearch, $wp_smiliesreplace, $content); 
648                        } 
649                        $output .= $content; 
650                }
651        } else {
652                // return default text.
653                $output = $text;
654        }
655        return $output;
656}
657
658
659function is_email($user_email) {
660        $chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i";
661        if(strstr($user_email, '@') && strstr($user_email, '.')) {
662                if (preg_match($chars, $user_email)) {
663                        return true;
664                } else {
665                        return false;
666                }
667        } else {
668                return false;
669        }
670}
671
672// used by wp-mail to handle charsets in email subjects
673function wp_iso_descrambler($string) {
674  /* this may only work with iso-8859-1, I'm afraid */
675  if (!preg_match('#\=\?(.+)\?Q\?(.+)\?\=#i', $string, $matches)) {
676    return $string;
677  } else {
678    $subject = str_replace('_', ' ', $matches[2]);
679    $subject = preg_replace('#\=([0-9a-f]{2})#ei', "chr(hexdec(strtolower('$1')))", $subject);
680    return $subject;
681  }
682}
683
684
685// give it a date, it will give you the same date as GMT
686function get_gmt_from_date($string) {
687  // note: this only substracts $time_difference from the given date
688  preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches);
689  $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
690  $string_gmt = gmdate('Y-m-d H:i:s', $string_time - get_option('gmt_offset') * 3600);
691  return $string_gmt;
692}
693
694// give it a GMT date, it will give you the same date with $time_difference added
695function get_date_from_gmt($string) {
696  // note: this only adds $time_difference to the given date
697  preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches);
698  $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
699  $string_localtime = gmdate('Y-m-d H:i:s', $string_time + get_option('gmt_offset')*3600);
700  return $string_localtime;
701}
702
703// computes an offset in seconds from an iso8601 timezone
704function iso8601_timezone_to_offset($timezone) {
705  // $timezone is either 'Z' or '[+|-]hhmm'
706  if ($timezone == 'Z') {
707    $offset = 0;
708  } else {
709    $sign    = (substr($timezone, 0, 1) == '+') ? 1 : -1;
710    $hours   = intval(substr($timezone, 1, 2));
711    $minutes = intval(substr($timezone, 3, 4)) / 60;
712    $offset  = $sign * 3600 * ($hours + $minutes);
713  }
714  return $offset;
715}
716
717// converts an iso8601 date to MySQL DateTime format used by post_date[_gmt]
718function iso8601_to_datetime($date_string, $timezone = USER) {
719  if ($timezone == GMT) {
720    preg_match('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', $date_string, $date_bits);
721    if (!empty($date_bits[7])) { // we have a timezone, so let's compute an offset
722      $offset = iso8601_timezone_to_offset($date_bits[7]);
723    } else { // we don't have a timezone, so we assume user local timezone (not server's!)
724      $offset = 3600 * get_option('gmt_offset');
725    }
726    $timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]);
727    $timestamp -= $offset;
728    return gmdate('Y-m-d H:i:s', $timestamp);
729  } elseif ($timezone == USER) {
730    return preg_replace('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', '$1-$2-$3 $4:$5:$6', $date_string);
731  }
732}
733
734function popuplinks($text) {
735        // Comment text in popup windows should be filtered through this.
736        // Right now it's a moderately dumb function, ideally it would detect whether
737        // a target or rel attribute was already there and adjust its actions accordingly.
738        $text = preg_replace('/<a (.+?)>/i', "<a $1 target='_blank' rel='external'>", $text);
739        return $text;
740}
741
742function sanitize_email($email) {
743        return preg_replace('/[^a-z0-9+_.@-]/i', '', $email);
744}
745
746function human_time_diff( $from, $to = '' ) {
747        if ( empty($to) )
748                $to = time();
749        $diff = (int) abs($to - $from);
750        if ($diff <= 3600) {
751                $mins = round($diff / 60);
752                if ($mins <= 1) {
753                        $mins = 1;
754                }
755                $since = sprintf(__ngettext('%s min', '%s mins', $mins), $mins);
756        } else if (($diff <= 86400) && ($diff > 3600)) {
757                $hours = round($diff / 3600);
758                if ($hours <= 1) {
759                        $hour = 1;
760                }
761                $since = sprintf(__ngettext('%s hour', '%s hours', $hours), $hours);
762        } elseif ($diff >= 86400) {
763                $days = round($diff / 86400);
764                if ($days <= 1) {
765                        $days = 1;
766                }
767                $since = sprintf(__ngettext('%s day', '%s days', $days), $days);
768        }
769        return $since;
770}
771
772function wp_trim_excerpt($text) { // Fakes an excerpt if needed
773        global $post;
774        if ( '' == $text ) {
775                $text = get_the_content('');
776                $text = apply_filters('the_content', $text);
777                $text = str_replace(']]>', ']]&gt;', $text);
778                $text = strip_tags($text);
779                $excerpt_length = 55;
780                $words = explode(' ', $text, $excerpt_length + 1);
781                if (count($words) > $excerpt_length) {
782                        array_pop($words);
783                        array_push($words, '[...]');
784                        $text = implode(' ', $words);
785                }
786        }
787        return $text;
788}
789
790function ent2ncr($text) {
791        $to_ncr = array(
792                '&quot;' => '&#34;',
793                '&amp;' => '&#38;',
794                '&frasl;' => '&#47;',
795                '&lt;' => '&#60;',
796                '&gt;' => '&#62;',
797                '|' => '&#124;',
798                '&nbsp;' => '&#160;',
799                '&iexcl;' => '&#161;',
800                '&cent;' => '&#162;',
801                '&pound;' => '&#163;',
802                '&curren;' => '&#164;',
803                '&yen;' => '&#165;',
804                '&brvbar;' => '&#166;',
805                '&brkbar;' => '&#166;',
806                '&sect;' => '&#167;',
807                '&uml;' => '&#168;',
808                '&die;' => '&#168;',
809                '&copy;' => '&#169;',
810                '&ordf;' => '&#170;',
811                '&laquo;' => '&#171;',
812                '&not;' => '&#172;',
813                '&shy;' => '&#173;',
814                '&reg;' => '&#174;',
815                '&macr;' => '&#175;',
816                '&hibar;' => '&#175;',
817                '&deg;' => '&#176;',
818                '&plusmn;' => '&#177;',
819                '&sup2;' => '&#178;',
820                '&sup3;' => '&#179;',
821                '&acute;' => '&#180;',
822                '&micro;' => '&#181;',
823                '&para;' => '&#182;',
824                '&middot;' => '&#183;',
825                '&cedil;' => '&#184;',
826                '&sup1;' => '&#185;',
827                '&ordm;' => '&#186;',
828                '&raquo;' => '&#187;',
829                '&frac14;' => '&#188;',
830                '&frac12;' => '&#189;',
831                '&frac34;' => '&#190;',
832                '&iquest;' => '&#191;',
833                '&Agrave;' => '&#192;',
834                '&Aacute;' => '&#193;',
835                '&Acirc;' => '&#194;',
836                '&Atilde;' => '&#195;',
837                '&Auml;' => '&#196;',
838                '&Aring;' => '&#197;',
839                '&AElig;' => '&#198;',
840                '&Ccedil;' => '&#199;',
841                '&Egrave;' => '&#200;',
842                '&Eacute;' => '&#201;',
843                '&Ecirc;' => '&#202;',
844                '&Euml;' => '&#203;',
845                '&Igrave;' => '&#204;',
846                '&Iacute;' => '&#205;',
847                '&Icirc;' => '&#206;',
848                '&Iuml;' => '&#207;',
849                '&ETH;' => '&#208;',
850                '&Ntilde;' => '&#209;',
851                '&Ograve;' => '&#210;',
852                '&Oacute;' => '&#211;',
853                '&Ocirc;' => '&#212;',
854                '&Otilde;' => '&#213;',
855                '&Ouml;' => '&#214;',
856                '&times;' => '&#215;',
857                '&Oslash;' => '&#216;',
858                '&Ugrave;' => '&#217;',
859                '&Uacute;' => '&#218;',
860                '&Ucirc;' => '&#219;',
861                '&Uuml;' => '&#220;',
862                '&Yacute;' => '&#221;',
863                '&THORN;' => '&#222;',
864                '&szlig;' => '&#223;',
865                '&agrave;' => '&#224;',
866                '&aacute;' => '&#225;',
867                '&acirc;' => '&#226;',
868                '&atilde;' => '&#227;',
869                '&auml;' => '&#228;',
870                '&aring;' => '&#229;',
871                '&aelig;' => '&#230;',
872                '&ccedil;' => '&#231;',
873                '&egrave;' => '&#232;',
874                '&eacute;' => '&#233;',
875                '&ecirc;' => '&#234;',
876                '&euml;' => '&#235;',
877                '&igrave;' => '&#236;',
878                '&iacute;' => '&#237;',
879                '&icirc;' => '&#238;',
880                '&iuml;' => '&#239;',
881                '&eth;' => '&#240;',
882                '&ntilde;' => '&#241;',
883                '&ograve;' => '&#242;',
884                '&oacute;' => '&#243;',
885                '&ocirc;' => '&#244;',
886                '&otilde;' => '&#245;',
887                '&ouml;' => '&#246;',
888                '&divide;' => '&#247;',
889                '&oslash;' => '&#248;',
890                '&ugrave;' => '&#249;',
891                '&uacute;' => '&#250;',
892                '&ucirc;' => '&#251;',
893                '&uuml;' => '&#252;',
894                '&yacute;' => '&#253;',
895                '&thorn;' => '&#254;',
896                '&yuml;' => '&#255;',
897                '&OElig;' => '&#338;',
898                '&oelig;' => '&#339;',
899                '&Scaron;' => '&#352;',
900                '&scaron;' => '&#353;',
901                '&Yuml;' => '&#376;',
902                '&fnof;' => '&#402;',
903                '&circ;' => '&#710;',
904                '&tilde;' => '&#732;',
905                '&Alpha;' => '&#913;',
906                '&Beta;' => '&#914;',
907                '&Gamma;' => '&#915;',
908                '&Delta;' => '&#916;',
909                '&Epsilon;' => '&#917;',
910                '&Zeta;' => '&#918;',
911                '&Eta;' => '&#919;',
912                '&Theta;' => '&#920;',
913                '&Iota;' => '&#921;',
914                '&Kappa;' => '&#922;',
915                '&Lambda;' => '&#923;',
916                '&Mu;' => '&#924;',
917                '&Nu;' => '&#925;',
918                '&Xi;' => '&#926;',
919                '&Omicron;' => '&#927;',
920                '&Pi;' => '&#928;',
921                '&Rho;' => '&#929;',
922                '&Sigma;' => '&#931;',
923                '&Tau;' => '&#932;',
924                '&Upsilon;' => '&#933;',
925                '&Phi;' => '&#934;',
926                '&Chi;' => '&#935;',
927                '&Psi;' => '&#936;',
928                '&Omega;' => '&#937;',
929                '&alpha;' => '&#945;',
930                '&beta;' => '&#946;',
931                '&gamma;' => '&#947;',
932                '&delta;' => '&#948;',
933                '&epsilon;' => '&#949;',
934                '&zeta;' => '&#950;',
935                '&eta;' => '&#951;',
936                '&theta;' => '&#952;',
937                '&iota;' => '&#953;',
938                '&kappa;' => '&#954;',
939                '&lambda;' => '&#955;',
940                '&mu;' => '&#956;',
941                '&nu;' => '&#957;',
942                '&xi;' => '&#958;',
943                '&omicron;' => '&#959;',
944                '&pi;' => '&#960;',
945                '&rho;' => '&#961;',
946                '&sigmaf;' => '&#962;',
947                '&sigma;' => '&#963;',
948                '&tau;' => '&#964;',
949                '&upsilon;' => '&#965;',
950                '&phi;' => '&#966;',
951                '&chi;' => '&#967;',
952                '&psi;' => '&#968;',
953                '&omega;' => '&#969;',
954                '&thetasym;' => '&#977;',
955                '&upsih;' => '&#978;',
956                '&piv;' => '&#982;',
957                '&ensp;' => '&#8194;',
958                '&emsp;' => '&#8195;',
959                '&thinsp;' => '&#8201;',
960                '&zwnj;' => '&#8204;',
961                '&zwj;' => '&#8205;',
962                '&lrm;' => '&#8206;',
963                '&rlm;' => '&#8207;',
964                '&ndash;' => '&#8211;',
965                '&mdash;' => '&#8212;',
966                '&lsquo;' => '&#8216;',
967                '&rsquo;' => '&#8217;',
968                '&sbquo;' => '&#8218;',
969                '&ldquo;' => '&#8220;',
970                '&rdquo;' => '&#8221;',
971                '&bdquo;' => '&#8222;',
972                '&dagger;' => '&#8224;',
973                '&Dagger;' => '&#8225;',
974                '&bull;' => '&#8226;',
975                '&hellip;' => '&#8230;',
976                '&permil;' => '&#8240;',
977                '&prime;' => '&#8242;',
978                '&Prime;' => '&#8243;',
979                '&lsaquo;' => '&#8249;',
980                '&rsaquo;' => '&#8250;',
981                '&oline;' => '&#8254;',
982                '&frasl;' => '&#8260;',
983                '&euro;' => '&#8364;',
984                '&image;' => '&#8465;',
985                '&weierp;' => '&#8472;',
986                '&real;' => '&#8476;',
987                '&trade;' => '&#8482;',
988                '&alefsym;' => '&#8501;',
989                '&crarr;' => '&#8629;',
990                '&lArr;' => '&#8656;',
991                '&uArr;' => '&#8657;',
992                '&rArr;' => '&#8658;',
993                '&dArr;' => '&#8659;',
994                '&hArr;' => '&#8660;',
995                '&forall;' => '&#8704;',
996                '&part;' => '&#8706;',
997                '&exist;' => '&#8707;',
998                '&empty;' => '&#8709;',
999                '&nabla;' => '&#8711;',
1000                '&isin;' => '&#8712;',
1001                '&notin;' => '&#8713;',
1002                '&ni;' => '&#8715;',
1003                '&prod;' => '&#8719;',
1004                '&sum;' => '&#8721;',
1005                '&minus;' => '&#8722;',
1006                '&lowast;' => '&#8727;',
1007                '&radic;' => '&#8730;',
1008                '&prop;' => '&#8733;',
1009                '&infin;' => '&#8734;',
1010                '&ang;' => '&#8736;',
1011                '&and;' => '&#8743;',
1012                '&or;' => '&#8744;',
1013                '&cap;' => '&#8745;',
1014                '&cup;' => '&#8746;',
1015                '&int;' => '&#8747;',
1016                '&there4;' => '&#8756;',
1017                '&sim;' => '&#8764;',
1018                '&cong;' => '&#8773;',
1019                '&asymp;' => '&#8776;',
1020                '&ne;' => '&#8800;',
1021                '&equiv;' => '&#8801;',
1022                '&le;' => '&#8804;',
1023                '&ge;' => '&#8805;',
1024                '&sub;' => '&#8834;',
1025                '&sup;' => '&#8835;',
1026                '&nsub;' => '&#8836;',
1027                '&sube;' => '&#8838;',
1028                '&supe;' => '&#8839;',
1029                '&oplus;' => '&#8853;',
1030                '&otimes;' => '&#8855;',
1031                '&perp;' => '&#8869;',
1032                '&sdot;' => '&#8901;',
1033                '&lceil;' => '&#8968;',
1034                '&rceil;' => '&#8969;',
1035                '&lfloor;' => '&#8970;',
1036                '&rfloor;' => '&#8971;',
1037                '&lang;' => '&#9001;',
1038                '&rang;' => '&#9002;',
1039                '&larr;' => '&#8592;',
1040                '&uarr;' => '&#8593;',
1041                '&rarr;' => '&#8594;',
1042                '&darr;' => '&#8595;',
1043                '&harr;' => '&#8596;',
1044                '&loz;' => '&#9674;',
1045                '&spades;' => '&#9824;',
1046                '&clubs;' => '&#9827;',
1047                '&hearts;' => '&#9829;',
1048                '&diams;' => '&#9830;'
1049        );
1050
1051        return str_replace( array_keys($to_ncr), array_values($to_ncr), $text );
1052}
1053
1054function wp_richedit_pre($text) {
1055        // Filtering a blank results in an annoying <br />\n
1056        if ( empty($text) ) return apply_filters('richedit_pre', '');
1057
1058        $output = $text;
1059        $output = convert_chars($output);
1060        $output = wpautop($output);
1061
1062        // These must be double-escaped or planets will collide.
1063        $output = str_replace('&lt;', '&amp;lt;', $output);
1064        $output = str_replace('&gt;', '&amp;gt;', $output);
1065
1066        return apply_filters('richedit_pre', $output);
1067}
1068
1069function clean_url( $url, $protocols = null ) {
1070        if ('' == $url) return $url;
1071        $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%]|i', '', $url);
1072        $strip = array('%0d', '%0a');
1073        $url = str_replace($strip, '', $url);
1074        $url = str_replace(';//', '://', $url);
1075        // Append http unless a relative link starting with / or a php file.
1076        if ( strpos($url, '://') === false &&
1077                substr( $url, 0, 1 ) != '/' && !preg_match('/^[a-z0-9]+?\.php/i', $url) )
1078                $url = 'http://' . $url;
1079       
1080        $url = preg_replace('/&([^#])(?![a-z]{2,8};)/', '&#038;$1', $url);
1081        if ( !is_array($protocols) )
1082                $protocols = array('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet'); 
1083        if ( wp_kses_bad_protocol( $url, $protocols ) != $url )
1084                return '';
1085        return $url;
1086}
1087
1088// Borrowed from the PHP Manual user notes. Convert entities, while
1089// preserving already-encoded entities:
1090function htmlentities2($myHTML) {
1091        $translation_table=get_html_translation_table (HTML_ENTITIES,ENT_QUOTES);
1092        $translation_table[chr(38)] = '&';
1093        return preg_replace("/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/","&amp;" , strtr($myHTML, $translation_table));
1094}
1095
1096// Escape single quotes, specialchar double quotes, and fix line endings.
1097function js_escape($text) {
1098        $safe_text = wp_specialchars($text, 'double');
1099        $safe_text = str_replace('&#039;', "'", $safe_text);
1100        $safe_text = preg_replace("/\r?\n/", "\\n", addslashes($safe_text));
1101        return apply_filters('js_escape', $safe_text, $text);
1102}
1103
1104// Escaping for HTML attributes
1105function attribute_escape($text) {
1106        $safe_text = wp_specialchars($text, true);
1107        return apply_filters('attribute_escape', $safe_text, $text);
1108}
1109
1110function wp_make_link_relative( $link ) {
1111        return preg_replace('|https?://[^/]+(/.*)|i', '$1', $link );
1112}
1113
1114?>
Note: See TracBrowser for help on using the repository browser.