2005-08-21 06:49:02 +00:00
< ? php
/* SVN FILE: $Id$ */
/**
* Text Helper
2005-12-23 21:57:26 +00:00
*
2005-09-07 01:52:45 +00:00
* Text manipulations : Highlight , excerpt , truncate , strip of links , convert email addresses to mailto : links ...
2005-08-21 06:49:02 +00:00
*
* PHP versions 4 and 5
*
2007-02-02 10:39:45 +00:00
* CakePHP ( tm ) : Rapid Development Framework < http :// www . cakephp . org />
2008-01-01 22:18:17 +00:00
* Copyright 2005 - 2008 , Cake Software Foundation , Inc .
2006-05-26 05:29:17 +00:00
* 1785 E . Sahara Avenue , Suite 490 - 204
* Las Vegas , Nevada 89104
2005-08-21 06:49:02 +00:00
*
2005-12-23 21:57:26 +00:00
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice .
2005-08-21 06:49:02 +00:00
*
2005-12-23 21:57:26 +00:00
* @ filesource
2008-01-01 22:18:17 +00:00
* @ copyright Copyright 2005 - 2008 , Cake Software Foundation , Inc .
2007-02-02 10:39:45 +00:00
* @ link http :// www . cakefoundation . org / projects / info / cakephp CakePHP ( tm ) Project
2006-05-26 05:29:17 +00:00
* @ package cake
* @ subpackage cake . cake . libs . view . helpers
2007-02-02 10:39:45 +00:00
* @ since CakePHP ( tm ) v 0.10 . 0.1076
2006-05-26 05:29:17 +00:00
* @ version $Revision $
* @ modifiedby $LastChangedBy $
* @ lastmodified $Date $
* @ license http :// www . opensource . org / licenses / mit - license . php The MIT License
2005-08-21 06:49:02 +00:00
*/
/**
2005-10-18 22:27:39 +00:00
* Included libraries .
2005-12-27 03:33:44 +00:00
*
2005-08-21 06:49:02 +00:00
*/
2006-05-26 05:29:17 +00:00
2006-08-06 17:55:01 +00:00
if ( ! class_exists ( 'HtmlHelper' )) {
2006-11-25 04:31:26 +00:00
uses ( 'view' . DS . 'helpers' . DS . 'html' );
2005-12-27 03:33:44 +00:00
}
2005-08-21 06:49:02 +00:00
/**
* Text helper library .
2005-12-23 21:57:26 +00:00
*
2005-09-07 01:52:45 +00:00
* Text manipulations : Highlight , excerpt , truncate , strip of links , convert email addresses to mailto : links ...
2005-08-21 06:49:02 +00:00
*
2006-05-26 05:29:17 +00:00
* @ package cake
* @ subpackage cake . cake . libs . view . helpers
2005-08-21 06:49:02 +00:00
*/
2006-10-27 21:40:34 +00:00
class TextHelper extends AppHelper {
2006-07-27 04:12:24 +00:00
2006-02-18 23:42:21 +00:00
/**
2007-09-06 05:28:36 +00:00
* Highlights a given phrase in a text . You can specify any expression in highlighter that
* may include the \1 expression to include the $phrase found .
2005-12-27 03:33:44 +00:00
*
* @ param string $text Text to search the phrase in
* @ param string $phrase The phrase that will be searched
* @ param string $highlighter The piece of html with that the phrase will be highlighted
* @ return string The highlighted text
2007-09-06 05:28:36 +00:00
* @ access public
2005-12-27 03:33:44 +00:00
*/
2006-07-27 04:12:24 +00:00
function highlight ( $text , $phrase , $highlighter = '<span class="highlight">\1</span>' ) {
if ( empty ( $phrase )) {
return $text ;
}
if ( is_array ( $phrase )) {
$replace = array ();
$with = array ();
2007-06-20 06:15:35 +00:00
foreach ( $phrase as $key => $value ) {
2007-04-13 14:27:59 +00:00
$key = $value ;
$value = $highlighter ;
2006-05-26 05:29:17 +00:00
2007-04-21 16:55:09 +00:00
$replace [] = '|(' . $key . ')|i' ;
2006-07-27 04:12:24 +00:00
$with [] = empty ( $value ) ? $highlighter : $value ;
}
2005-08-21 06:49:02 +00:00
2006-07-27 04:12:24 +00:00
return preg_replace ( $replace , $with , $text );
} else {
return preg_replace ( " |( { $phrase } )|i " , $highlighter , $text );
}
}
2006-02-18 23:42:21 +00:00
/**
2005-12-27 03:33:44 +00:00
* Strips given text of all links ( < a href =.... )
*
* @ param string $text Text
* @ return string The text without links
2007-09-06 05:28:36 +00:00
* @ access public
2005-12-27 03:33:44 +00:00
*/
2006-07-27 04:12:24 +00:00
function stripLinks ( $text ) {
2007-09-06 05:28:36 +00:00
return preg_replace ( '|<a\s+[^>]+>|im' , '' , preg_replace ( '|<\/a>|im' , '' , $text ));
2006-07-27 04:12:24 +00:00
}
2006-02-18 23:42:21 +00:00
/**
2005-12-27 03:33:44 +00:00
* Adds links ( < a href =.... ) to a given text , by finding text that begins with
* strings like http :// and ftp ://.
*
* @ param string $text Text to add links to
* @ param array $htmlOptions Array of HTML options .
* @ return string The text with links
2007-09-06 05:28:36 +00:00
* @ access public
2005-12-27 03:33:44 +00:00
*/
2006-07-27 04:12:24 +00:00
function autoLinkUrls ( $text , $htmlOptions = array ()) {
$options = 'array(' ;
2007-06-20 06:15:35 +00:00
foreach ( $htmlOptions as $option => $value ) {
2007-11-22 05:36:20 +00:00
$value = var_export ( $value , true );
$options .= " ' $option ' => $value , " ;
2006-07-27 04:12:24 +00:00
}
$options .= ')' ;
2005-08-21 06:49:02 +00:00
2007-10-21 22:21:28 +00:00
$text = preg_replace_callback ( '#(?<!href="|">)((?:http|https|ftp|nntp)://[^ <]+)#i' , create_function ( '$matches' ,
2006-10-08 15:30:58 +00:00
'$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->link($matches[0], $matches[0],' . $options . ');' ), $text );
2005-08-21 06:49:02 +00:00
2008-05-13 03:53:26 +00:00
return preg_replace_callback ( '#(?<!href="|">)(?<!http://|https://|ftp://|nntp://)(www\.[^\n\%\ <]+[^<\n\%\,\.\ <])(?<!\))#i' ,
2007-12-08 06:08:03 +00:00
create_function ( '$matches' , '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->link($matches[0], "http://" . strtolower($matches[0]),' . $options . ');' ), $text );
2006-07-27 04:12:24 +00:00
}
2006-02-18 23:42:21 +00:00
/**
2005-12-27 03:33:44 +00:00
* Adds email links ( < a href = " mailto:....) to a given text.
*
* @ param string $text Text
* @ param array $htmlOptions Array of HTML options .
* @ return string The text with links
2007-09-06 05:28:36 +00:00
* @ access public
2005-12-27 03:33:44 +00:00
*/
2006-07-27 04:12:24 +00:00
function autoLinkEmails ( $text , $htmlOptions = array ()) {
$options = 'array(' ;
2006-05-26 05:29:17 +00:00
2007-06-20 06:15:35 +00:00
foreach ( $htmlOptions as $option => $value ) {
2006-07-27 04:12:24 +00:00
$options .= " ' $option ' => ' $value ', " ;
}
$options .= ')' ;
2005-08-21 06:49:02 +00:00
2007-02-01 04:02:43 +00:00
return preg_replace_callback ( '#([_A-Za-z0-9+-]+(?:\.[_A-Za-z0-9+-]+)*@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*)#' ,
2007-01-06 21:10:33 +00:00
create_function ( '$matches' , '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->link($matches[0], "mailto:" . $matches[0],' . $options . ');' ), $text );
2006-07-27 04:12:24 +00:00
}
2006-02-18 23:42:21 +00:00
/**
2005-12-27 03:33:44 +00:00
* Convert all links and email adresses to HTML links .
*
* @ param string $text Text
* @ param array $htmlOptions Array of HTML options .
* @ return string The text with links
2007-09-06 05:28:36 +00:00
* @ access public
2005-12-27 03:33:44 +00:00
*/
2006-07-27 04:12:24 +00:00
function autoLink ( $text , $htmlOptions = array ()) {
return $this -> autoLinkEmails ( $this -> autoLinkUrls ( $text , $htmlOptions ), $htmlOptions );
}
2006-02-18 23:42:21 +00:00
/**
2005-12-27 03:33:44 +00:00
* Truncates text .
*
* Cuts a string to the length of $length and replaces the last characters
* with the ending if the text is longer than length .
*
2008-04-23 13:23:12 +00:00
* @ param string $text String to truncate .
2007-10-22 16:11:12 +00:00
* @ param integer $length Length of returned string , including ellipsis .
2008-04-23 13:23:12 +00:00
* @ param mixed $ending If string , will be used as Ending and appended to the trimmed string . Can also be an associative array that can contain the last three params of this method .
2007-10-22 16:54:36 +00:00
* @ param boolean $exact If false , $text will not be cut mid - word
2008-04-23 13:23:12 +00:00
* @ param boolean $considerHtml If true , HTML tags would be handled correctly
2005-12-27 03:33:44 +00:00
* @ return string Trimmed string .
*/
2008-04-23 13:23:12 +00:00
function truncate ( $text , $length = 100 , $ending = '...' , $exact = true , $considerHtml = false ) {
if ( is_array ( $ending )) {
extract ( $ending );
}
if ( $considerHtml ) {
if ( strlen ( preg_replace ( '/<.*?>/' , '' , $text )) <= $length ) {
return $text ;
}
2006-05-26 05:29:17 +00:00
2008-04-23 13:23:12 +00:00
preg_match_all ( '/(<.+?>)?([^<>]*)/s' , $text , $lines , PREG_SET_ORDER );
$total_length = strlen ( $ending );
$open_tags = array ();
$truncate = '' ;
2005-12-23 21:57:26 +00:00
2008-04-23 13:23:12 +00:00
foreach ( $lines as $line_matchings ) {
if ( ! empty ( $line_matchings [ 1 ])) {
if ( preg_match ( '/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is' , $line_matchings [ 1 ])) {
} elseif ( preg_match ( '/^<\s*\/([^\s]+?)\s*>$/s' , $line_matchings [ 1 ], $tag_matchings )) {
$pos = array_search ( $tag_matchings [ 1 ], $open_tags );
if ( $pos !== false ) {
unset ( $open_tags [ $pos ]);
}
} elseif ( preg_match ( '/^<\s*([^\s>!]+).*?>$/s' , $line_matchings [ 1 ], $tag_matchings )) {
array_unshift ( $open_tags , strtolower ( $tag_matchings [ 1 ]));
}
$truncate .= $line_matchings [ 1 ];
}
$content_length = strlen ( preg_replace ( '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i' , ' ' , $line_matchings [ 2 ]));
if ( $total_length + $content_length > $length ) {
$left = $length - $total_length ;
$entities_length = 0 ;
if ( preg_match_all ( '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i' , $line_matchings [ 2 ], $entities , PREG_OFFSET_CAPTURE )) {
foreach ( $entities [ 0 ] as $entity ) {
if ( $entity [ 1 ] + 1 - $entities_length <= $left ) {
$left -- ;
$entities_length += strlen ( $entity [ 0 ]);
} else {
break ;
}
}
}
$truncate .= substr ( $line_matchings [ 2 ], 0 , $left + $entities_length );
break ;
} else {
$truncate .= $line_matchings [ 2 ];
$total_length += $content_length ;
}
if ( $total_length >= $length ) {
break ;
2006-07-27 04:12:24 +00:00
}
}
2008-04-23 13:23:12 +00:00
} else {
if ( strlen ( $text ) <= $length ) {
return $text ;
} else {
$truncate = substr ( $text , 0 , $length - strlen ( $ending ));
}
2006-07-27 04:12:24 +00:00
}
2008-04-23 13:23:12 +00:00
if ( ! $exact ) {
$spacepos = strrpos ( $truncate , ' ' );
if ( isset ( $spacepos )) {
$truncate = substr ( $truncate , 0 , $spacepos );
}
}
$truncate .= $ending ;
if ( $considerHtml ) {
foreach ( $open_tags as $tag ) {
$truncate .= '</' . $tag . '>' ;
}
}
return $truncate ;
2006-07-27 04:12:24 +00:00
}
2006-02-18 23:42:21 +00:00
/**
2005-12-27 03:33:44 +00:00
* Alias for truncate () .
*
* @ see TextHelper :: truncate ()
2007-09-06 05:28:36 +00:00
* @ access public
2005-12-27 03:33:44 +00:00
*/
2006-07-27 04:12:24 +00:00
function trim () {
$args = func_get_args ();
return call_user_func_array ( array ( & $this , 'truncate' ), $args );
}
2006-02-18 23:42:21 +00:00
/**
2005-12-27 03:33:44 +00:00
* Extracts an excerpt from the text surrounding the phrase with a number of characters on each side determined by radius .
*
* @ param string $text String to search the phrase in
* @ param string $phrase Phrase that will be searched for
2007-10-22 16:11:12 +00:00
* @ param integer $radius The amount of characters that will be returned on each side of the founded phrase
2005-12-27 03:33:44 +00:00
* @ param string $ending Ending that will be appended
2007-09-06 05:28:36 +00:00
* @ return string Modified string
* @ access public
2005-12-27 03:33:44 +00:00
*/
2006-07-27 04:12:24 +00:00
function excerpt ( $text , $phrase , $radius = 100 , $ending = " ... " ) {
if ( empty ( $text ) or empty ( $phrase )) {
return $this -> truncate ( $text , $radius * 2 , $ending );
}
2006-07-27 04:20:30 +00:00
if ( $radius < strlen ( $phrase )) {
2006-07-27 04:12:24 +00:00
$radius = strlen ( $phrase );
}
2007-12-08 06:08:03 +00:00
$pos = strpos ( strtolower ( $text ), strtolower ( $phrase ));
2007-09-06 05:28:36 +00:00
$startPos = ife ( $pos <= $radius , 0 , $pos - $radius );
$endPos = ife ( $pos + strlen ( $phrase ) + $radius >= strlen ( $text ), strlen ( $text ), $pos + strlen ( $phrase ) + $radius );
2006-07-27 04:12:24 +00:00
$excerpt = substr ( $text , $startPos , $endPos - $startPos );
if ( $startPos != 0 ) {
$excerpt = substr_replace ( $excerpt , $ending , 0 , strlen ( $phrase ));
}
if ( $endPos != strlen ( $text )) {
$excerpt = substr_replace ( $excerpt , $ending , - strlen ( $phrase ));
}
return $excerpt ;
}
2006-07-27 04:20:30 +00:00
/**
* Creates a comma separated list where the last two items are joined with 'and' , forming natural English
*
* @ param array $list The list to be joined
* @ return string
2007-09-06 05:28:36 +00:00
* @ access public
2006-07-27 04:20:30 +00:00
*/
2007-05-24 22:55:05 +00:00
function toList ( $list , $and = 'and' ) {
2006-07-27 04:20:30 +00:00
$r = '' ;
$c = count ( $list ) - 1 ;
foreach ( $list as $i => $item ) {
$r .= $item ;
if ( $c > 0 && $i < $c )
{
2007-05-24 22:55:05 +00:00
$r .= ( $i < $c - 1 ? ', ' : " { $and } " );
2006-07-27 04:20:30 +00:00
}
}
return $r ;
}
2006-02-18 23:42:21 +00:00
/**
2005-12-27 03:33:44 +00:00
* Text - to - html parser , similar to Textile or RedCloth , only with a little different syntax .
*
* @ param string $text String to " flay "
2007-10-22 16:54:36 +00:00
* @ param boolean $allowHtml Set to true if if html is allowed
2005-12-27 03:33:44 +00:00
* @ return string " Flayed " text
2007-09-06 05:28:36 +00:00
* @ access public
2005-12-27 03:33:44 +00:00
* @ todo Change this . We need a real Textile parser .
2008-05-12 06:46:58 +00:00
* @ codeCoverageIgnoreStart
2005-12-27 03:33:44 +00:00
*/
2006-07-27 04:12:24 +00:00
function flay ( $text , $allowHtml = false ) {
2008-05-12 06:46:58 +00:00
trigger_error ( __ ( '(TextHelper::flay) Deprecated: the Flay library is no longer supported and will be removed in a future version.' , true ), E_USER_WARNING );
2006-07-27 04:12:24 +00:00
if ( ! class_exists ( 'Flay' )) {
uses ( 'flay' );
}
return Flay :: toHtml ( $text , false , $allowHtml );
}
2008-05-12 07:05:33 +00:00
/**
* @ codeCoverageIgnoreEnd
*/
2005-08-21 06:49:02 +00:00
}
?>