PageRenderTime 24ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Core/Text.php

https://github.com/Dundee/NORS
PHP | 341 lines | 268 code | 33 blank | 40 comment | 15 complexity | 64d0607d8e1f142bc564c03161b887d3 MD5 | raw file
  1. <?php
  2. /**
  3. * Letters that can't be used in URL.
  4. *
  5. * @global string NOT_ALLOWED_ENTITIES Not allowed letters
  6. */
  7. define('NOT_ALLOWED_ENTITIES', "ĚŠČŘŽÝÁÄÍÉŮÚÜÓÖŐŇŤĎĽľěščřžýáäíéůúüóöňťď. '`´;:=?!@#$%^&*+/|,<>{}()[]~\"¨§");
  8. define('ALLOWED_ENTITIES', "ESCRZYAAIEUUUOOONTDLlescrzyaaieuuuoontd----------------------------------");
  9. /**
  10. * Text manipulation class
  11. *
  12. * @author Daniel Milde <daniel@milde.cz>
  13. * @package Core
  14. */
  15. class Core_Text
  16. {
  17. protected $text;
  18. public function __construct($text = FALSE)
  19. {
  20. $this->text = $text;
  21. }
  22. /**
  23. * Gets perex from text
  24. * @param int $maxWords Maximum number of words in perex
  25. * @param string $text
  26. * @return string
  27. */
  28. public function getPerex($maxWords = 100, $text = FALSE)
  29. {
  30. $text = $text ? $text : $this->text;
  31. $per = $this->getParagraphs(1, $text);
  32. if (substr_count($per, " ") > $maxWords) {
  33. $per = $this->getWords($maxWords, $text) . '...';
  34. }
  35. return $per;
  36. }
  37. /**
  38. * Gets paragraphs from text
  39. * @param int $number Number of paragraphs
  40. * @param string $text
  41. * @return string
  42. */
  43. public function getParagraphs($number, $text = FALSE)
  44. {
  45. $text = $text ? $text : $this->text;
  46. $text = preg_replace("/\n\s+\n/", "\n\n", $text);
  47. return $this->getTokens($text, $number, "\n\n");
  48. }
  49. /**
  50. * Gets words from text
  51. * @param int $number Number of words
  52. * @param string $text
  53. * @return string
  54. */
  55. public function getWords($number, $text = FALSE)
  56. {
  57. $text = $text ? $text : $this->text;
  58. $text = str_replace(ENDL, " ", $text); //endlines split words as well
  59. $text = preg_replace("/\s{2,}/", " ", $text); //remove multiple spaces
  60. return $this->getTokens($text, $number, " ");
  61. }
  62. /**
  63. * Formats plain text into valid html.
  64. *
  65. * @param string $text
  66. * @return string forrmated html
  67. */
  68. public function format_comment($text = FALSE) {
  69. $text = $text ? $text : $this->text;
  70. /*$text = strip_tags($text);*/
  71. $text = htmlspecialchars($text);
  72. $text = str_replace("\r", '', $text);
  73. $text = $this->clearAmpersand($text);
  74. $text = preg_replace('/(.+?)(?:\n\n|\z)/s', '<p>$1</p>' . ENDL, $text); //paragraphs
  75. $text = preg_replace('%(?<!</p>)\s*\n%', '<br />' . ENDL, $text); //newline into break but not after </p>
  76. while (preg_match('%\[code\](.*)</?p>(.*)\[/code\]%s', $text)) {
  77. $text = preg_replace('%\[code\](.*)<p>(.*)\[/code\]%s', "[code]$1$2[/code]", $text);
  78. $text = preg_replace('%\[code\](.*)</p>(.*)\[/code\]%s', "[code]$1\n$2[/code]", $text);
  79. }
  80. while (preg_match('%\[code\].*<br />.*\[/code\]%s', $text)) {
  81. $text = preg_replace('%\[code\](.*)<br />(.*)\[/code\]%s', "[code]$1$2[/code]", $text);
  82. }
  83. //XSS in url and img
  84. if (preg_match('%\[url\].+\[/url\]%U', $text)) {
  85. if (!preg_match('%\[url\]https?://.+\[/url\]%U', $text)) {
  86. $text = preg_replace('%\[url\](.+)\[/url\]%U', '', $text);
  87. }
  88. }
  89. if (preg_match('%\[img\].+\[/img\]%U', $text)) {
  90. if (!preg_match('%\[img\]https?://.+\[/img\]%U', $text)) {
  91. $text = preg_replace('%\[img\](.+)\[/img\]%U', '', $text);
  92. }
  93. }
  94. //tags
  95. $text = preg_replace('%\[url\](.+)\[/url\]%U', '<a href="$1">$1</a>', $text); //ungreedy
  96. $text = preg_replace('%\[img\](.+)\[/img\]%U', '<a href="$1">' . __('image') . '</a>', $text);
  97. $text = preg_replace('%\[b\](.+)\[/b\]%U', '<strong>$1</strong>', $text);
  98. $text = preg_replace('%\[i\](.+)\[/i\]%U', '<em>$1</em>', $text);
  99. $text = preg_replace('%\[code\](.*)\[/code\]%Us', '<pre>$1</pre>', $text);
  100. return $text;
  101. }
  102. /**
  103. * Formats html into valid html.
  104. *
  105. * @param string $text
  106. * @return string forrmated html
  107. */
  108. public function format_html($text = FALSE) {
  109. $text = $text ? $text : $this->text;
  110. $text = str_replace("\r", '', $text);
  111. $text = $this->clearAmpersand($text);
  112. //tables
  113. $start = strpos($text, '||');
  114. while (!($start === false)) {
  115. $length = strpos( substr($text, $start + 1, strlen($text) - ($start+1)) , '||');
  116. $length += 3;
  117. $table = trim(substr($text, $start, $length));
  118. $output = '<table rules="all" border="1">';
  119. $rows = explode(ENDL, $table);
  120. for ($i = 1; $i < (count($rows) - 1); $i++) {
  121. if ($i == 1) $tag = 'th';
  122. else $tag = 'td';
  123. $rows[$i] = str_replace('|', '</' . $tag . '><' . $tag . '>', $rows[$i]);
  124. $output .= ENDL . '<tr><' . $tag . '>' . $rows[$i] . '</' . $tag . '></tr>';
  125. }
  126. $output .= ENDL . '</table>';
  127. $text = str_replace($table, $output, $text);
  128. $start = FALSE;
  129. $start = strpos($text, '||');
  130. }
  131. //code
  132. $code = array();
  133. $start = strpos($text, '<code>');
  134. $i = 0;
  135. while (!($start === false)) {
  136. $length = strpos( substr($text, $start + 1, strlen($text) - ($start+1)) , '</code>');
  137. $length += 3;
  138. $code[$i] = trim(substr($text, $start, $length));
  139. $text = str_replace($code, "#CODE$i#", $text);
  140. $start = FALSE;
  141. $start = strpos($text, '<code>');
  142. $i++;
  143. }
  144. //pictures - needed for NORS 3 posts
  145. $content = $text;
  146. $i=0;
  147. $start = strpos($content, "<img");
  148. while(!($start===false)){
  149. $length = strpos( substr($content, $start + 1, strlen($content) - ($start + 1)) , ">");
  150. $length += 2;
  151. $img = trim(substr($content, $start, $length));
  152. $path = preg_replace('/^<img +src="([^"]*)".*>$/',"\\1", $img);
  153. $alt = preg_replace('/^<img +src="[^"]+" +alt="([^"]+)".*>$/', "\\1", $img);
  154. if (preg_match('%^\./%', $path)) {
  155. $arr = explode("/", $path);
  156. $filename = $arr[count($arr)-1];
  157. $arr[count($arr) - 1] = 'thub';
  158. $arr[] = $filename;
  159. $thub_path = implode("/", $arr);
  160. $path = ltrim($path, './');
  161. $thub = '<div class="thumbnail-old">
  162. <a href="' . APP_URL . '/' . $path . '" class="lightbox2" data-lightbox="lightbox" title="' . $alt . '">
  163. <img src="' . APP_URL . '/' . $thub_path . '" alt="' . $alt . '" />
  164. </a>
  165. </div>';
  166. $text = str_replace($img, $thub, $text);
  167. }
  168. $start = strpos($content, "<img", $start + $length);
  169. }
  170. $text .= ENDL;
  171. //make space around some tags (due to paragraphs)
  172. $text = preg_replace('!(<(?:code|table|ul|ol|li|pre|form|blockquote|h[1-6])[^>]*>)!', ENDL . '$1', $text);
  173. $text = preg_replace('!(</(?:code|table|ul|ol|li|pre|form|blockquote|h[1-6])>)!', '$1' . ENDL . ENDL, $text);
  174. $text = preg_replace('/(.+?)(?:\n\n\s*|\z\s*)/s', '<p>$1</p>' . ENDL, $text); //paragraphs
  175. //$text = preg_replace('%(?<!</p>)\s*\n%', '<br />' . ENDL, $text); //newline into break but not after </p>
  176. //remove <p> around tags
  177. $text = preg_replace('!<p>\s*(</?(?:code|table|tr|td|th|div|ul|ol|li|pre|select|form|blockquote|p|h[1-6])[^>]*>)!', "$1", $text);
  178. $text = preg_replace('!(</?(?:code|table|tr|td|th|div|ul|ol|li|pre|select|form|blockquote|p|h[1-6])[^>]*>)\s*</p>|</div>"!', "$1", $text);
  179. if (iterable ($code)) {
  180. foreach ($code as $i=>$v) {
  181. $text = str_replace("#CODE$i#", $v, $text);
  182. }
  183. }
  184. //syntax highlighting
  185. $text = str_replace('<code>', '<pre>', $text);
  186. $text = str_replace('</code>', '</pre>', $text);
  187. return $text;
  188. }
  189. /**
  190. * Hides mail away from bots
  191. * @param string $text
  192. * @return string
  193. */
  194. public function hideMail($text = FALSE) {
  195. $text = $text ? $text : $this->text;
  196. $return = '';
  197. for($i=0; $i < strlen($text); $i++){
  198. $x = substr($text, $i, 1);
  199. $return .= "&#" . ord($x) . ";";
  200. }
  201. return $return;
  202. }
  203. /**
  204. * urlEncode
  205. *
  206. * Generates text prepared to be displayed as URL.
  207. *
  208. * @param string $text Non-formated text
  209. * @return string Text formated for URL
  210. */
  211. public function urlEncode($text = FALSE)
  212. {
  213. $text = $text ? $text : $this->text;
  214. $text = str_replace("–", "-", $text);
  215. $text = str_replace("—", "-", $text);
  216. $text = iconv("utf-8", "iso-8859-2", $text);
  217. $not_allowed = iconv("utf-8", "iso-8859-2", NOT_ALLOWED_ENTITIES);
  218. $allowed = iconv("utf-8", "iso-8859-2", ALLOWED_ENTITIES);
  219. $link = strtr($text, $not_allowed, $allowed);
  220. $link = iconv("iso-8859-2", "utf-8", $link);
  221. while (strpos($link, '--')) {
  222. $link = str_replace('--', '-', $link);
  223. }
  224. $link = strtolower($link);
  225. $link = clearOutput($link);
  226. $link = str_replace("&quot;", "", $link);
  227. $link = str_replace("'", "", $link);
  228. return $link;
  229. }
  230. /**
  231. * MD5 crypt with soil
  232. * @param string $text Text to be crypted
  233. * @param string $soil
  234. * @return string
  235. */
  236. public function crypt($text, $soil){
  237. $pass = $soil.'+dfgyuI9'.$text;
  238. return md5($pass);
  239. }
  240. /**
  241. * Creates a timestamp from date string in format "yyyy-mm-dd hh:ii:ss" or "yyyy-mm-dd"
  242. * @param String $ymd_his Date string
  243. * @return int Unix timestamp
  244. */
  245. public function dateToTimeStamp($ymd_his = FALSE){
  246. $ymd_his = $ymd_his ? $ymd_his : $this->text;
  247. if ( preg_match('/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $ymd_his)) {
  248. list($date,$time) = explode(" ",$ymd_his);
  249. list($y,$m,$d) = explode("-",$date);
  250. list($h,$i,$s) = explode(":",$time);
  251. } elseif ( preg_match('/[0-9]{4}-[0-9]{2}-[0-9]{2}/', $ymd_his) ){
  252. list($y,$m,$d) = explode("-",$ymd_his);
  253. $h = $i = $s = 0;
  254. } else {
  255. return time();
  256. }
  257. return mktime ($h, $i, $s, $m, $d, $y);
  258. }
  259. /**
  260. * Replaces & by &amp; but ommit entities
  261. * @param string $text
  262. * @return string
  263. */
  264. public function clearAmpersand($text)
  265. {
  266. return preg_replace('/&([^#])(?![a-z]{1,8};)/', '&amp;$1', $text);
  267. }
  268. /**
  269. * Gets tokens from text
  270. * @param string $text
  271. * @param int $number Number of paragraphs
  272. * @param string $delimiter
  273. * @return string
  274. */
  275. private function getTokens($text, $number, $delimiter = " ")
  276. {
  277. $length = mb_strlen($text);
  278. $begin = 0;
  279. if (strpos($text, $delimiter) === FALSE) return $text;
  280. for($i = $number; $i > 0; $i--) {
  281. $position = mb_strpos($text, $delimiter, ++$begin);
  282. $begin = $position;
  283. //echor($begin.'-'.$i);
  284. if(!$begin){
  285. $position = $length;
  286. break;
  287. }
  288. }
  289. return mb_substr($text, 0, $position);
  290. }
  291. }