converted to unix-style eol
[www-register-wizard.git] / helpers / text_helper.php
1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2 /**
3  * CodeIgniter
4  *
5  * An open source application development framework for PHP 4.3.2 or newer
6  *
7  * @package             CodeIgniter
8  * @author              ExpressionEngine Dev Team
9  * @copyright   Copyright (c) 2008, EllisLab, Inc.
10  * @license             http://codeigniter.com/user_guide/license.html
11  * @link                http://codeigniter.com
12  * @since               Version 1.0
13  * @filesource
14  */
15
16 // ------------------------------------------------------------------------
17
18 /**
19  * CodeIgniter Text Helpers
20  *
21  * @package             CodeIgniter
22  * @subpackage  Helpers
23  * @category    Helpers
24  * @author              ExpressionEngine Dev Team
25  * @link                http://codeigniter.com/user_guide/helpers/text_helper.html
26  */
27
28 // ------------------------------------------------------------------------
29
30 /**
31  * Word Limiter
32  *
33  * Limits a string to X number of words.
34  *
35  * @access      public
36  * @param       string
37  * @param       integer
38  * @param       string  the end character. Usually an ellipsis
39  * @return      string
40  */     
41 if ( ! function_exists('word_limiter'))
42 {
43         function word_limiter($str, $limit = 100, $end_char = '&#8230;')
44         {
45                 if (trim($str) == '')
46                 {
47                         return $str;
48                 }
49         
50                 preg_match('/^\s*+(?:\S++\s*+){1,'.(int) $limit.'}/', $str, $matches);
51                         
52                 if (strlen($str) == strlen($matches[0]))
53                 {
54                         $end_char = '';
55                 }
56                 
57                 return rtrim($matches[0]).$end_char;
58         }
59 }
60         
61 // ------------------------------------------------------------------------
62
63 /**
64  * Character Limiter
65  *
66  * Limits the string based on the character count.  Preserves complete words
67  * so the character count may not be exactly as specified.
68  *
69  * @access      public
70  * @param       string
71  * @param       integer
72  * @param       string  the end character. Usually an ellipsis
73  * @return      string
74  */     
75 if ( ! function_exists('character_limiter'))
76 {
77         function character_limiter($str, $n = 500, $end_char = '&#8230;')
78         {
79                 if (strlen($str) < $n)
80                 {
81                         return $str;
82                 }
83                 
84                 $str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
85
86                 if (strlen($str) <= $n)
87                 {
88                         return $str;
89                 }
90                                                                         
91                 $out = "";
92                 foreach (explode(' ', trim($str)) as $val)
93                 {
94                         $out .= $val.' ';                       
95                         if (strlen($out) >= $n)
96                         {
97                                 return trim($out).$end_char;
98                         }               
99                 }
100         }
101 }
102         
103 // ------------------------------------------------------------------------
104
105 /**
106  * High ASCII to Entities
107  *
108  * Converts High ascii text and MS Word special characters to character entities
109  *
110  * @access      public
111  * @param       string
112  * @return      string
113  */     
114 if ( ! function_exists('ascii_to_entities'))
115 {
116         function ascii_to_entities($str)
117         {
118            $count       = 1;
119            $out = '';
120            $temp        = array();
121         
122            for ($i = 0, $s = strlen($str); $i < $s; $i++)
123            {
124                    $ordinal = ord($str[$i]);
125         
126                    if ($ordinal < 128)
127                    {
128                            $out .= $str[$i];
129                    }
130                    else
131                    {
132                            if (count($temp) == 0)
133                            {
134                                    $count = ($ordinal < 224) ? 2 : 3;
135                            }
136                 
137                            $temp[] = $ordinal;
138                 
139                            if (count($temp) == $count)
140                            {
141                                    $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
142
143                                    $out .= '&#'.$number.';';
144                                    $count = 1;
145                                    $temp = array();
146                            }
147                    }
148            }
149
150            return $out;
151         }
152 }
153         
154 // ------------------------------------------------------------------------
155
156 /**
157  * Entities to ASCII
158  *
159  * Converts character entities back to ASCII
160  *
161  * @access      public
162  * @param       string
163  * @param       bool
164  * @return      string
165  */     
166 if ( ! function_exists('entities_to_ascii'))
167 {
168         function entities_to_ascii($str, $all = TRUE)
169         {
170            if (preg_match_all('/\&#(\d+)\;/', $str, $matches))
171            {
172                    for ($i = 0, $s = count($matches['0']); $i < $s; $i++)
173                    {                            
174                            $digits = $matches['1'][$i];
175
176                            $out = '';
177
178                            if ($digits < 128)
179                            {
180                                    $out .= chr($digits);
181                 
182                            }
183                            elseif ($digits < 2048)
184                            {
185                                    $out .= chr(192 + (($digits - ($digits % 64)) / 64));
186                                    $out .= chr(128 + ($digits % 64));
187                            }
188                            else
189                            {
190                                    $out .= chr(224 + (($digits - ($digits % 4096)) / 4096));
191                                    $out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64));
192                                    $out .= chr(128 + ($digits % 64));
193                            }
194
195                            $str = str_replace($matches['0'][$i], $out, $str);                           
196                    }
197            }
198
199            if ($all)
200            {
201                    $str = str_replace(array("&amp;", "&lt;", "&gt;", "&quot;", "&apos;", "&#45;"),
202                                                           array("&","<",">","\"", "'", "-"),
203                                                           $str);
204            }
205
206            return $str;
207         }
208 }
209         
210 // ------------------------------------------------------------------------
211
212 /**
213  * Word Censoring Function
214  *
215  * Supply a string and an array of disallowed words and any
216  * matched words will be converted to #### or to the replacement
217  * word you've submitted.
218  *
219  * @access      public
220  * @param       string  the text string
221  * @param       string  the array of censoered words
222  * @param       string  the optional replacement value
223  * @return      string
224  */     
225 if ( ! function_exists('word_censor'))
226 {
227         function word_censor($str, $censored, $replacement = '')
228         {
229                 if ( ! is_array($censored))
230                 {
231                         return $str;
232                 }
233
234                 $str = ' '.$str.' ';
235                 foreach ($censored as $badword)
236                 {
237                         if ($replacement != '')
238                         {
239                                 $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")\b/i", $replacement, $str);
240                         }
241                         else
242                         {
243                                 $str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")\b/ie", "str_repeat('#', strlen('\\1'))", $str);
244                         }
245                 }
246         
247                 return trim($str);
248         }
249 }
250         
251 // ------------------------------------------------------------------------
252
253 /**
254  * Code Highlighter
255  *
256  * Colorizes code strings
257  *
258  * @access      public
259  * @param       string  the text string
260  * @return      string
261  */     
262 if ( ! function_exists('highlight_code'))
263 {
264         function highlight_code($str)
265         {               
266                 // The highlight string function encodes and highlights
267                 // brackets so we need them to start raw
268                 $str = str_replace(array('&lt;', '&gt;'), array('<', '>'), $str);
269         
270                 // Replace any existing PHP tags to temporary markers so they don't accidentally
271                 // break the string out of PHP, and thus, thwart the highlighting.
272         
273                 $str = str_replace(array('<?', '?>', '<%', '%>', '\\', '</script>'), 
274                                                         array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), $str);
275
276                 // The highlight_string function requires that the text be surrounded
277                 // by PHP tags, which we will remove later
278                 $str = '<?php '.$str.' ?>'; // <?
279
280                 // All the magic happens here, baby!    
281                 $str = highlight_string($str, TRUE);
282
283                 // Prior to PHP 5, the highligh function used icky <font> tags
284                 // so we'll replace them with <span> tags.
285
286                 if (abs(PHP_VERSION) < 5)
287                 {
288                         $str = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $str);
289                         $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);
290                 }
291                 
292                 // Remove our artificially added PHP, and the syntax highlighting that came with it
293                 $str = preg_replace('/<span style="color: #([A-Z0-9]+)">&lt;\?php(&nbsp;| )/i', '<span style="color: #$1">', $str);
294                 $str = preg_replace('/(<span style="color: #[A-Z0-9]+">.*?)\?&gt;<\/span>\n<\/span>\n<\/code>/is', "$1</span>\n</span>\n</code>", $str);
295                 $str = preg_replace('/<span style="color: #[A-Z0-9]+"\><\/span>/i', '', $str);
296                         
297                 // Replace our markers back to PHP tags.
298                 $str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
299                                                         array('&lt;?', '?&gt;', '&lt;%', '%&gt;', '\\', '&lt;/script&gt;'), $str);
300                                                                                 
301                 return $str;
302         }
303 }
304         
305 // ------------------------------------------------------------------------
306
307 /**
308  * Phrase Highlighter
309  *
310  * Highlights a phrase within a text string
311  *
312  * @access      public
313  * @param       string  the text string
314  * @param       string  the phrase you'd like to highlight
315  * @param       string  the openging tag to precede the phrase with
316  * @param       string  the closing tag to end the phrase with
317  * @return      string
318  */     
319 if ( ! function_exists('highlight_phrase'))
320 {
321         function highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>')
322         {
323                 if ($str == '')
324                 {
325                         return '';
326                 }
327         
328                 if ($phrase != '')
329                 {
330                         return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);
331                 }
332
333                 return $str;
334         }
335 }
336         
337 // ------------------------------------------------------------------------
338
339 /**
340  * Word Wrap
341  *
342  * Wraps text at the specified character.  Maintains the integrity of words.
343  * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor
344  * will URLs.
345  *
346  * @access      public
347  * @param       string  the text string
348  * @param       integer the number of characters to wrap at
349  * @return      string
350  */     
351 if ( ! function_exists('word_wrap'))
352 {
353         function word_wrap($str, $charlim = '76')
354         {
355                 // Se the character limit
356                 if ( ! is_numeric($charlim))
357                         $charlim = 76;
358         
359                 // Reduce multiple spaces
360                 $str = preg_replace("| +|", " ", $str);
361         
362                 // Standardize newlines
363                 if (strpos($str, "\r") !== FALSE)
364                 {
365                         $str = str_replace(array("\r\n", "\r"), "\n", $str);                    
366                 }
367         
368                 // If the current word is surrounded by {unwrap} tags we'll 
369                 // strip the entire chunk and replace it with a marker.
370                 $unwrap = array();
371                 if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
372                 {
373                         for ($i = 0; $i < count($matches['0']); $i++)
374                         {
375                                 $unwrap[] = $matches['1'][$i];                          
376                                 $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
377                         }
378                 }
379         
380                 // Use PHP's native function to do the initial wordwrap.  
381                 // We set the cut flag to FALSE so that any individual words that are 
382                 // too long get left alone.  In the next step we'll deal with them.
383                 $str = wordwrap($str, $charlim, "\n", FALSE);
384         
385                 // Split the string into individual lines of text and cycle through them
386                 $output = "";
387                 foreach (explode("\n", $str) as $line) 
388                 {
389                         // Is the line within the allowed character count?
390                         // If so we'll join it to the output and continue
391                         if (strlen($line) <= $charlim)
392                         {
393                                 $output .= $line."\n";                  
394                                 continue;
395                         }
396                         
397                         $temp = '';
398                         while((strlen($line)) > $charlim) 
399                         {
400                                 // If the over-length word is a URL we won't wrap it
401                                 if (preg_match("!\[url.+\]|://|wwww.!", $line))
402                                 {
403                                         break;
404                                 }
405
406                                 // Trim the word down
407                                 $temp .= substr($line, 0, $charlim-1);
408                                 $line = substr($line, $charlim-1);
409                         }
410                 
411                         // If $temp contains data it means we had to split up an over-length 
412                         // word into smaller chunks so we'll add it back to our current line
413                         if ($temp != '')
414                         {
415                                 $output .= $temp . "\n" . $line; 
416                         }
417                         else
418                         {
419                                 $output .= $line;
420                         }
421
422                         $output .= "\n";
423                 }
424
425                 // Put our markers back
426                 if (count($unwrap) > 0)
427                 {       
428                         foreach ($unwrap as $key => $val)
429                         {
430                                 $output = str_replace("{{unwrapped".$key."}}", $val, $output);
431                         }
432                 }
433
434                 // Remove the unwrap tags
435                 $output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output);
436
437                 return $output; 
438         }
439 }
440
441
442 /* End of file text_helper.php */
443 /* Location: ./system/helpers/text_helper.php */