PageRenderTime 75ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/source/function/function_editor.php

https://github.com/jinbo51/DiscuzX
PHP | 409 lines | 360 code | 43 blank | 6 comment | 58 complexity | 11e2f1bdcd7737e86a4b16dd2e6ceac4 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * [Discuz!] (C)2001-2099 Comsenz Inc.
  4. * This is NOT a freeware, use is subject to license terms
  5. *
  6. * $Id: function_editor.php 32078 2012-11-07 05:28:56Z monkey $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9. exit('Access Denied');
  10. }
  11. function absoluteurl($url) {
  12. global $_G;
  13. if($url{0} == '/') {
  14. return 'http://'.$_SERVER['HTTP_HOST'].$url;
  15. } else {
  16. return $_G['siteurl'].$url;
  17. }
  18. }
  19. function atag($aoptions, $text) {
  20. $href = getoptionvalue('href', $aoptions);
  21. if(substr($href, 0, 7) == 'mailto:') {
  22. $tag = 'email';
  23. $href = substr($href, 7);
  24. } else {
  25. $tag = 'url';
  26. if(!preg_match("/^[a-z0-9]+:/i", $href)) {
  27. $href = absoluteurl($href);
  28. }
  29. }
  30. return "[$tag=$href]".trim(recursion('a', $text, 'atag'))."[/$tag]";
  31. }
  32. function divtag($divoptions, $text) {
  33. $prepend = $append = '';
  34. parsestyle($divoptions, $prepend, $append);
  35. $align = getoptionvalue('align', $divoptions);
  36. switch($align) {
  37. case 'left':
  38. case 'center':
  39. case 'right':
  40. break;
  41. default:
  42. $align = '';
  43. }
  44. if($align) {
  45. $prepend .= "[align=$align]";
  46. $append .= "[/align]";
  47. }
  48. $append .= "\n";
  49. return $prepend.recursion('div', $text, 'divtag').$append;
  50. }
  51. function fetchoptionvalue($option, $text) {
  52. if(($position = strpos($text, $option)) !== false) {
  53. $delimiter = $position + strlen($option);
  54. if($text{$delimiter} == '"') {
  55. $delimchar = '"';
  56. } elseif($text{$delimiter} == '\'') {
  57. $delimchar = '\'';
  58. } else {
  59. $delimchar = ' ';
  60. }
  61. $delimloc = strpos($text, $delimchar, $delimiter + 1);
  62. if($delimloc === false) {
  63. $delimloc = strlen($text);
  64. } elseif($delimchar == '"' OR $delimchar == '\'') {
  65. $delimiter++;
  66. }
  67. return trim(substr($text, $delimiter, $delimloc - $delimiter));
  68. } else {
  69. return '';
  70. }
  71. }
  72. function fonttag($fontoptions, $text) {
  73. $tags = array('font' => 'face=', 'size' => 'size=', 'color' => 'color=');
  74. $prependtags = $appendtags = '';
  75. foreach($tags as $bbcode => $locate) {
  76. $optionvalue = fetchoptionvalue($locate, $fontoptions);
  77. if($optionvalue) {
  78. $prependtags .= "[$bbcode=$optionvalue]";
  79. $appendtags = "[/$bbcode]$appendtags";
  80. }
  81. }
  82. parsestyle($fontoptions, $prependtags, $appendtags);
  83. return $prependtags.recursion('font', $text, 'fonttag').$appendtags;
  84. }
  85. function getoptionvalue($option, $text) {
  86. preg_match("/$option(\s+?)?\=(\s+?)?[\"']?(.+?)([\"']|$|>)/is", $text, $matches);
  87. return isset($matches[3]) ? trim($matches[3]) : '';
  88. }
  89. function html2bbcode($text) {
  90. $text = strip_tags($text, '<table><tr><td><b><strong><i><em><u><a><div><span><p><strike><blockquote><ol><ul><li><font><img><br><br/><h1><h2><h3><h4><h5><h6><script>');
  91. if(ismozilla()) {
  92. $text = preg_replace("/(?<!<br>|<br \/>|\r)(\r\n|\n|\r)/", ' ', $text);
  93. }
  94. $pregfind = array(
  95. "/<script.*>.*<\/script>/siU",
  96. '/on(mousewheel|mouseover|click|load|onload|submit|focus|blur)="[^"]*"/i',
  97. "/(\r\n|\n|\r)/",
  98. "/<table([^>]*(width|background|background-color|bgcolor)[^>]*)>/siUe",
  99. "/<table.*>/siU",
  100. "/<tr.*>/siU",
  101. "/<td>/i",
  102. "/<td(.+)>/siUe",
  103. "/<\/td>/i",
  104. "/<\/tr>/i",
  105. "/<\/table>/i",
  106. '/<h([0-9]+)[^>]*>/siUe',
  107. '/<\/h([0-9]+)>/siU',
  108. "/<img[^>]+smilieid=\"(\d+)\".*>/esiU",
  109. "/<img([^>]*src[^>]*)>/eiU",
  110. "/<a\s+?name=.+?\".\">(.+?)<\/a>/is",
  111. "/<br.*>/siU",
  112. "/<span\s+?style=\"float:\s+(left|right);\">(.+?)<\/span>/is",
  113. );
  114. $pregreplace = array(
  115. '',
  116. '',
  117. '',
  118. "tabletag('\\1')",
  119. '[table]',
  120. '[tr]',
  121. '[td]',
  122. "tdtag('\\1')",
  123. '[/td]',
  124. '[/tr]',
  125. '[/table]',
  126. "\"[size=\".(7 - \\1).\"]\"",
  127. "[/size]\n\n",
  128. "smileycode('\\1')",
  129. "imgtag('\\1')",
  130. '\1',
  131. "\n",
  132. "[float=\\1]\\2[/float]",
  133. );
  134. $text = preg_replace($pregfind, $pregreplace, $text);
  135. $text = recursion('b', $text, 'simpletag', 'b');
  136. $text = recursion('strong', $text, 'simpletag', 'b');
  137. $text = recursion('i', $text, 'simpletag', 'i');
  138. $text = recursion('em', $text, 'simpletag', 'i');
  139. $text = recursion('u', $text, 'simpletag', 'u');
  140. $text = recursion('a', $text, 'atag');
  141. $text = recursion('font', $text, 'fonttag');
  142. $text = recursion('blockquote', $text, 'simpletag', 'indent');
  143. $text = recursion('ol', $text, 'listtag');
  144. $text = recursion('ul', $text, 'listtag');
  145. $text = recursion('div', $text, 'divtag');
  146. $text = recursion('span', $text, 'spantag');
  147. $text = recursion('p', $text, 'ptag');
  148. $pregfind = array("/(?<!\r|\n|^)\[(\/list|list|\*)\]/", "/<li>(.*)((?=<li>)|<\/li>)/iU", "/<p.*>/iU", "/<p><\/p>/i", "/(<a>|<\/a>|<\/li>)/is", "/<\/?(A|LI|FONT|DIV|SPAN)>/siU", "/\[url[^\]]*\]\[\/url\]/i", "/\[url=javascript:[^\]]*\](.+?)\[\/url\]/is");
  149. $pregreplace = array("\n[\\1]", "\\1\n", "\n", '', '', '', '', "\\1");
  150. $text = preg_replace($pregfind, $pregreplace, $text);
  151. $strfind = array('&nbsp;', '&lt;', '&gt;', '&amp;');
  152. $strreplace = array(' ', '<', '>', '&');
  153. $text = str_replace($strfind, $strreplace, $text);
  154. return dhtmlspecialchars(trim($text));
  155. }
  156. function imgtag($attributes) {
  157. $value = array('src' => '', 'width' => '', 'height' => '');
  158. preg_match_all("/(src|width|height)=([\"|\']?)([^\"']+)(\\2)/is", dstripslashes($attributes), $matches);
  159. if(is_array($matches[1])) {
  160. foreach($matches[1] as $key => $attribute) {
  161. $value[strtolower($attribute)] = $matches[3][$key];
  162. }
  163. }
  164. @extract($value);
  165. if(!preg_match("/^http:\/\//i", $src)) {
  166. $src = absoluteurl($src);
  167. }
  168. return $src ? ($width && $height ? '[img='.$width.','.$height.']'.$src.'[/img]' : '[img]'.$src.'[/img]') : '';
  169. }
  170. function ismozilla() {
  171. $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
  172. if(strpos($useragent, 'gecko') !== FALSE) {
  173. preg_match("/gecko\/(\d+)/", $useragent, $regs);
  174. return $regs[1];
  175. }
  176. return FALSE;
  177. }
  178. function litag($listoptions, $text) {
  179. return '[*]'.rtrim($text);
  180. }
  181. function listtag($listoptions, $text, $tagname) {
  182. require_once libfile('function/post');
  183. $text = preg_replace('/<li>((.(?!<\/li))*)(?=<\/?ol|<\/?ul|<li|\[list|\[\/list)/siU', '<li>\\1</li>', $text).(isopera() ? '</li>' : NULL);
  184. $text = recursion('li', $text, 'litag');
  185. if($tagname == 'ol') {
  186. $listtype = fetchoptionvalue('type=', $listoptions) ? fetchoptionvalue('type=', $listoptions) : 1;
  187. if(in_array($listtype, array('1', 'a', 'A'))) {
  188. $opentag = '[list='.$listtype.']';
  189. }
  190. } else {
  191. $opentag = '[list]';
  192. }
  193. return $text ? $opentag.recursion($tagname, $text, 'listtag').'[/list]' : FALSE;
  194. }
  195. function parsestyle($tagoptions, &$prependtags, &$appendtags) {
  196. $searchlist = array(
  197. array('tag' => 'align', 'option' => TRUE, 'regex' => 'text-align:\s*(left);?', 'match' => 1),
  198. array('tag' => 'align', 'option' => TRUE, 'regex' => 'text-align:\s*(center);?', 'match' => 1),
  199. array('tag' => 'align', 'option' => TRUE, 'regex' => 'text-align:\s*(right);?', 'match' => 1),
  200. array('tag' => 'color', 'option' => TRUE, 'regex' => '(?<![a-z0-9-])color:\s*([^;]+);?', 'match' => 1),
  201. array('tag' => 'font', 'option' => TRUE, 'regex' => 'font-family:\s*([^;]+);?', 'match' => 1),
  202. array('tag' => 'size', 'option' => TRUE, 'regex' => 'font-size:\s*(\d+(\.\d+)?(px|pt|in|cm|mm|pc|em|ex|%|));?', 'match' => 1),
  203. array('tag' => 'b', 'option' => FALSE, 'regex' => 'font-weight:\s*(bold);?'),
  204. array('tag' => 'i', 'option' => FALSE, 'regex' => 'font-style:\s*(italic);?'),
  205. array('tag' => 'u', 'option' => FALSE, 'regex' => 'text-decoration:\s*(underline);?')
  206. );
  207. $style = getoptionvalue('style', $tagoptions);
  208. $style = preg_replace(
  209. "/(?<![a-z0-9-])color:\s*rgb\((\d+),\s*(\d+),\s*(\d+)\)(;?)/ie",
  210. 'sprintf("color: #%02X%02X%02X$4", $1, $2, $3)',
  211. $style
  212. );
  213. foreach($searchlist as $searchtag) {
  214. if(preg_match('/'.$searchtag['regex'].'/i', $style, $match)) {
  215. $opnvalue = $match["$searchtag[match]"];
  216. $prependtags .= '['.$searchtag['tag'].($searchtag['option'] == TRUE ? '='.$opnvalue.']' : ']');
  217. $appendtags = '[/'.$searchtag['tag']."]$appendtags";
  218. }
  219. }
  220. }
  221. function ptag($poptions, $text) {
  222. $align = getoptionvalue('align', $poptions);
  223. switch($align) {
  224. case 'left':
  225. case 'center':
  226. case 'right':
  227. break;
  228. default:
  229. $align = '';
  230. }
  231. $prepend = $append = '';
  232. parsestyle($poptions, $prepend, $append);
  233. if($align) {
  234. $prepend .= "[align=$align]";
  235. $append .= "[/align]";
  236. }
  237. $append .= "\n";
  238. return $prepend.recursion('p', $text, 'ptag').$append;
  239. }
  240. function recursion($tagname, $text, $function, $extraargs = '') {
  241. $tagname = strtolower($tagname);
  242. $open_tag = "<$tagname";
  243. $open_tag_len = strlen($open_tag);
  244. $close_tag = "</$tagname>";
  245. $close_tag_len = strlen($close_tag);
  246. $beginsearchpos = 0;
  247. do {
  248. $textlower = strtolower($text);
  249. $tagbegin = @strpos($textlower, $open_tag, $beginsearchpos);
  250. if($tagbegin === FALSE) {
  251. break;
  252. }
  253. $strlen = strlen($text);
  254. $inquote = '';
  255. $found = FALSE;
  256. $tagnameend = FALSE;
  257. for($optionend = $tagbegin; $optionend <= $strlen; $optionend++) {
  258. $char = $text{$optionend};
  259. if(($char == '"' || $char == "'") && $inquote == '') {
  260. $inquote = $char;
  261. } elseif(($char == '"' || $char == "'") && $inquote == $char) {
  262. $inquote = '';
  263. } elseif($char == '>' && !$inquote) {
  264. $found = TRUE;
  265. break;
  266. } elseif(($char == '=' || $char == ' ') && !$tagnameend) {
  267. $tagnameend = $optionend;
  268. }
  269. }
  270. if(!$found) {
  271. break;
  272. }
  273. if(!$tagnameend) {
  274. $tagnameend = $optionend;
  275. }
  276. $offset = $optionend - ($tagbegin + $open_tag_len);
  277. $tagoptions = substr($text, $tagbegin + $open_tag_len, $offset);
  278. $acttagname = substr($textlower, $tagbegin + 1, $tagnameend - $tagbegin - 1);
  279. if($acttagname != $tagname) {
  280. $beginsearchpos = $optionend;
  281. continue;
  282. }
  283. $tagend = strpos($textlower, $close_tag, $optionend);
  284. if($tagend === FALSE) {
  285. break;
  286. }
  287. $nestedopenpos = strpos($textlower, $open_tag, $optionend);
  288. while($nestedopenpos !== FALSE && $tagend !== FALSE) {
  289. if($nestedopenpos > $tagend) {
  290. break;
  291. }
  292. $tagend = strpos($textlower, $close_tag, $tagend + $close_tag_len);
  293. $nestedopenpos = strpos($textlower, $open_tag, $nestedopenpos + $open_tag_len);
  294. }
  295. if($tagend === FALSE) {
  296. $beginsearchpos = $optionend;
  297. continue;
  298. }
  299. $localbegin = $optionend + 1;
  300. $localtext = $function($tagoptions, substr($text, $localbegin, $tagend - $localbegin), $tagname, $extraargs);
  301. $text = substr_replace($text, $localtext, $tagbegin, $tagend + $close_tag_len - $tagbegin);
  302. $beginsearchpos = $tagbegin + strlen($localtext);
  303. } while($tagbegin !== FALSE);
  304. return $text;
  305. }
  306. function simpletag($options, $text, $tagname, $parseto) {
  307. if(trim($text) == '') {
  308. return '';
  309. }
  310. $text = recursion($tagname, $text, 'simpletag', $parseto);
  311. return "[$parseto]{$text}[/$parseto]";
  312. }
  313. function smileycode($smileyid) {
  314. global $_G;
  315. if(!is_array($_G['cache']['smileycodes'])) {
  316. loadcache(array('bbcodes_display', 'bbcodes', 'smileycodes', 'smilies', 'smileytypes', 'domainwhitelist'));
  317. }
  318. foreach($_G['cache']['smileycodes'] as $id => $code) {
  319. if($smileyid == $id) {
  320. return $code;
  321. }
  322. }
  323. }
  324. function spantag($spanoptions, $text) {
  325. $prependtags = $appendtags = '';
  326. parsestyle($spanoptions, $prependtags, $appendtags);
  327. return $prependtags.recursion('span', $text, 'spantag').$appendtags;
  328. }
  329. function tabletag($attributes) {
  330. $attributes = dstripslashes($attributes);
  331. $width = '';
  332. if(preg_match("/width=([\"|\']?)(\d{1,4}%?)(\\1)/is", $attributes, $matches)) {
  333. $width = substr($matches[2], -1) == '%' ? (substr($matches[2], 0, -1) <= 98 ? $matches[2] : '98%') : ($matches[2] <= 560 ? $matches[2] : '560');
  334. } elseif(preg_match("/width\s?:\s?(\d{1,4})([px|%])/is", $attributes, $matches)) {
  335. $width = $matches[2] == '%' ? ($matches[1] <= 98 ? $matches[1].'%' : '98%') : ($matches[1] <= 560 ? $matches[1] : '560');
  336. }
  337. if(preg_match("/(?:background|background-color|bgcolor)[:=]\s*([\"']?)((rgb\(\d{1,3}%?,\s*\d{1,3}%?,\s*\d{1,3}%?\))|(#[0-9a-fA-F]{3,6})|([a-zA-Z]{1,20}))(\\1)/i", $attributes, $matches)) {
  338. $bgcolor = $matches[2];
  339. $width = $width ? $width : '98%';
  340. } else {
  341. $bgcolor = '';
  342. }
  343. return $bgcolor ? "[table=$width,$bgcolor]" :($width ? "[table=$width]" : '[table]');
  344. }
  345. function tdtag($attributes) {
  346. $value = array('colspan' => 1, 'rowspan' => 1, 'width' => '');
  347. preg_match_all("/(colspan|rowspan|width)=([\"|\']?)(\d{1,4}%?)(\\2)/is", dstripslashes($attributes), $matches);
  348. if(is_array($matches[1])) {
  349. foreach($matches[1] as $key => $attribute) {
  350. $value[strtolower($attribute)] = $matches[3][$key];
  351. }
  352. }
  353. @extract($value);
  354. return $width == '' ? ($colspan == 1 && $rowspan == 1 ? '[td]' : "[td=$colspan,$rowspan]") : "[td=$colspan,$rowspan,$width]";
  355. }
  356. ?>