PageRenderTime 36ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/src/libraries/default/base/template/helper/text.php

https://github.com/bhar1red/anahita
PHP | 272 lines | 153 code | 26 blank | 93 comment | 32 complexity | 180193acfb3d26cf79bb0ca8e63faca8 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * LICENSE: ##LICENSE##
  4. *
  5. * @category Anahita
  6. * @package Lib_Base
  7. * @subpackage Template_Helper
  8. * @author Arash Sanieyan <ash@anahitapolis.com>
  9. * @author Rastin Mehr <rastin@anahitapolis.com>
  10. * @copyright 2008 - 2010 rmdStudio Inc./Peerglobe Technology Inc
  11. * @license GNU GPLv3 <http://www.gnu.org/licenses/gpl-3.0.html>
  12. * @version SVN: $Id$
  13. * @link http://www.anahitapolis.com
  14. */
  15. /**
  16. * Template text helper
  17. *
  18. * @category Anahita
  19. * @package Lib_Base
  20. * @subpackage Template_Helper
  21. * @author Arash Sanieyan <ash@anahitapolis.com>
  22. * @author Rastin Mehr <rastin@anahitapolis.com>
  23. * @license GNU GPLv3 <http://www.gnu.org/licenses/gpl-3.0.html>
  24. * @link http://www.anahitapolis.com
  25. */
  26. class LibBaseTemplateHelperText extends KTemplateHelperAbstract implements KServiceInstantiatable
  27. {
  28. /**
  29. * Force creation of a singleton
  30. *
  31. * @param KConfigInterface $config An optional KConfig object with configuration options
  32. * @param KServiceInterface $container A KServiceInterface object
  33. *
  34. * @return KServiceInstantiatable
  35. */
  36. public static function getInstance(KConfigInterface $config, KServiceInterface $container)
  37. {
  38. if (!$container->has($config->service_identifier))
  39. {
  40. $classname = $config->service_identifier->classname;
  41. $instance = new $classname($config);
  42. $container->set($config->service_identifier, $instance);
  43. }
  44. return $container->get($config->service_identifier);
  45. }
  46. /**
  47. * Truncates a text
  48. *
  49. * @param string $text The text to truncate
  50. * @param array $options Truncation options. Can be 'length'=>integer, 'read_more'=>boolean,
  51. * 'ending'=>string, 'exact'=>boolean, 'consider_html'=>false
  52. *
  53. * @return string
  54. */
  55. public function truncate($text, $options = array())
  56. {
  57. $default = array('length'=>300, 'read_more'=>false, 'ending'=>'...', 'exact'=>true, 'consider_html'=>false);
  58. $options = array_merge($default, $options);
  59. extract($options, EXTR_SKIP);
  60. if ($consider_html)
  61. {
  62. // if the plain text is shorter than the maximum length, return the whole text
  63. if (strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
  64. return $text;
  65. }
  66. // splits all html-tags to scanable lines
  67. preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
  68. $total_length = strlen($ending);
  69. $open_tags = array();
  70. $truncate = '';
  71. foreach ($lines as $line_matchings) {
  72. // if there is any html-tag in this line, handle it and add it (uncounted) to the output
  73. if (!empty($line_matchings[1])) {
  74. // if it's an "empty element" with or without xhtml-conform closing slash (f.e. <br/>)
  75. if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
  76. // do nothing
  77. // if tag is a closing tag (f.e. </b>)
  78. } else if (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
  79. // delete tag from $open_tags list
  80. $pos = array_search($tag_matchings[1], $open_tags);
  81. if ($pos !== false) {
  82. unset($open_tags[$pos]);
  83. }
  84. // if tag is an opening tag (f.e. <b>)
  85. } else if (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
  86. // add tag to the beginning of $open_tags list
  87. array_unshift($open_tags, strtolower($tag_matchings[1]));
  88. }
  89. // add html-tag to $truncate'd text
  90. $truncate .= $line_matchings[1];
  91. }
  92. // calculate the length of the plain text part of the line; handle entities as one character
  93. $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
  94. if ($total_length+$content_length> $length) {
  95. // the number of characters which are left
  96. $left = $length - $total_length;
  97. $entities_length = 0;
  98. // search for html entities
  99. 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)) {
  100. // calculate the real length of all entities in the legal range
  101. foreach ($entities[0] as $entity) {
  102. if ($entity[1]+1-$entities_length <= $left) {
  103. $left--;
  104. $entities_length += strlen($entity[0]);
  105. } else {
  106. // no more characters left
  107. break;
  108. }
  109. }
  110. }
  111. $truncate .= KHelperString::substr($line_matchings[2], 0, $left+$entities_length);
  112. // maximum lenght is reached, so get off the loop
  113. break;
  114. } else {
  115. $truncate .= $line_matchings[2];
  116. $total_length += $content_length;
  117. }
  118. // if the maximum length is reached, get off the loop
  119. if($total_length>= $length) {
  120. break;
  121. }
  122. }
  123. } else {
  124. if (strlen($text) <= $length) {
  125. return $text;
  126. } else {
  127. $truncate = KHelperString::substr($text, 0, $length - strlen($ending));
  128. }
  129. }
  130. // if the words shouldn't be cut in the middle...
  131. if (!$exact) {
  132. // ...search the last occurance of a space...
  133. $spacepos = strrpos($truncate, ' ');
  134. if (isset($spacepos)) {
  135. // ...and cut the text in this position
  136. $truncate = KHelperString::substr($truncate, 0, $spacepos);
  137. }
  138. }
  139. // add the defined ending to the text
  140. $truncate .= $ending;
  141. if($consider_html) {
  142. // close all unclosed html-tags
  143. foreach ($open_tags as $tag) {
  144. $truncate .= '</' . $tag . '>';
  145. }
  146. }
  147. if ( $read_more )
  148. {
  149. $short_id = uniqid();
  150. $full_id = uniqid();
  151. $read_more = '<a class="an-read-more" onclick="$(\''.$short_id.'\').hide();$(\''.$full_id.'\').show();return false;" href="#">'.JText::_('LIB-AN-READMORE').'</a>';
  152. $read_less = '<a class="an-read-less" onclick="$(\''.$short_id.'\').show();$(\''.$full_id.'\').hide();return false;" href="#">'.JText::_('LIB-AN-READLESS').'</a>';
  153. $truncate = '<div id="'.$short_id.'">'.$truncate.$read_more.'</div>';
  154. $truncate .= '<div id="'.$full_id.'" style="display:none">'.$text.$read_less.'</div>';
  155. }
  156. return $truncate;
  157. }
  158. /**
  159. * returns substring of characters around a searchword
  160. *
  161. * @param string The source string
  162. * @param int Number of chars to return
  163. * @param string The searchword to select around
  164. * @return string
  165. */
  166. public function substring($text, $searchword, $length = 200)
  167. {
  168. $textlen = KHelperString::strlen($text);
  169. $lsearchword = KHelperString::strtolower($searchword);
  170. $wordfound = false;
  171. $pos = 0;
  172. while ($wordfound === false && $pos < $textlen)
  173. {
  174. if (($wordpos = @KHelperString::strpos($text, ' ', $pos + $length)) !== false)
  175. $chunk_size = $wordpos - $pos;
  176. else
  177. $chunk_size = $length;
  178. $chunk = KHelperString::substr($text, $pos, $chunk_size);
  179. $wordfound = KHelperString::strpos(KHelperString::strtolower($chunk), $lsearchword);
  180. if ($wordfound === false)
  181. $pos += $chunk_size + 1;
  182. }//while
  183. if ($wordfound !== false)
  184. return (($pos > 0) ? '...&nbsp;' : '') . $chunk . '&nbsp;...';
  185. else
  186. {
  187. if (($wordpos = @KHelperString::strpos($text, ' ', $length)) !== false)
  188. return KHelperString::substr($text, 0, $wordpos) . '&nbsp;...';
  189. else
  190. return KHelperString::substr($text, 0, $length);
  191. }
  192. }
  193. /**
  194. * wraps the provided keywords in a text with span tags containing the highlight css tag
  195. *
  196. * @param string $text
  197. * @param array $words
  198. * @return string of processed text
  199. */
  200. public function highlight($text, $words)
  201. {
  202. $words = KConfig::unbox($words);
  203. settype($words, 'array');
  204. foreach($words as $word)
  205. $text = KHelperString::str_ireplace($word, '<span class="an-text-highlight">'.$word.'</span>', $text);
  206. return $text;
  207. }
  208. /**
  209. * Return a size in a human friendly way
  210. *
  211. * @param int $size Return a size in a human friendly way
  212. *
  213. * @return string
  214. */
  215. public function size($size)
  216. {
  217. $kb=1024;$mb=1048576;$gb=1073741824;$tb=1099511627776;
  218. if(!$size)
  219. return '0 B';
  220. elseif($size<$kb)
  221. return $size.' B';
  222. elseif($size<$mb)
  223. return round($size/$kb, 2).' KB';
  224. elseif($size<$gb)
  225. return round($size/$mb, 2).' MB';
  226. elseif($size<$tb)
  227. return round($size/$gb, 2).' GB';
  228. else
  229. return round($size/$tb, 2).' TB';
  230. }
  231. /**
  232. * Return a sanitized version of a text which can be assigned to a javascript variable.
  233. *
  234. * @param string $text The text to sanitize
  235. *
  236. * @return string
  237. */
  238. public function script($text)
  239. {
  240. return htmlspecialchars(
  241. $this->getService('koowa:filter.string')
  242. ->sanitize(KHelperString::str_ireplace(array("\r\n", "\n"), '', $text))
  243. , ENT_QUOTES);
  244. }
  245. //end class
  246. }