Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
19 KiB

9 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. <?php
  2. require_once("include/oembed.php");
  3. require_once('include/event.php');
  4. function stripcode_br_cb($s) {
  5. return '[code]' . str_replace('<br />', '', $s[1]) . '[/code]';
  6. }
  7. function tryoembed($match){
  8. $url = ((count($match)==2)?$match[1]:$match[2]);
  9. // logger("tryoembed: $url");
  10. $o = oembed_fetch_url($url);
  11. //echo "<pre>"; var_dump($match, $url, $o); killme();
  12. if ($o->type=="error") return $match[0];
  13. $html = oembed_format_object($o);
  14. return $html; //oembed_iframe($html,$o->width,$o->height);
  15. }
  16. // [noparse][i]italic[/i][/noparse] turns into
  17. // [noparse][ i ]italic[ /i ][/noparse],
  18. // to hide them from parser.
  19. function bb_spacefy($st) {
  20. $whole_match = $st[0];
  21. $captured = $st[1];
  22. $spacefied = preg_replace("/\[(.*?)\]/", "[ $1 ]", $captured);
  23. $new_str = str_replace($captured, $spacefied, $whole_match);
  24. return $new_str;
  25. }
  26. // The previously spacefied [noparse][ i ]italic[ /i ][/noparse],
  27. // now turns back and the [noparse] tags are trimed
  28. // returning [i]italic[/i]
  29. function bb_unspacefy_and_trim($st) {
  30. $whole_match = $st[0];
  31. $captured = $st[1];
  32. $unspacefied = preg_replace("/\[ (.*?)\ ]/", "[$1]", $captured);
  33. return $unspacefied;
  34. }
  35. if(! function_exists('bb_extract_images')) {
  36. function bb_extract_images($body) {
  37. $saved_image = array();
  38. $orig_body = $body;
  39. $new_body = '';
  40. $cnt = 0;
  41. $img_start = strpos($orig_body, '[img');
  42. $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false);
  43. $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false);
  44. while(($img_st_close !== false) && ($img_end !== false)) {
  45. $img_st_close++; // make it point to AFTER the closing bracket
  46. $img_end += $img_start;
  47. if(! strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) {
  48. // This is an embedded image
  49. $saved_image[$cnt] = substr($orig_body, $img_start + $img_st_close, $img_end - ($img_start + $img_st_close));
  50. $new_body = $new_body . substr($orig_body, 0, $img_start) . '[$#saved_image' . $cnt . '#$]';
  51. $cnt++;
  52. }
  53. else
  54. $new_body = $new_body . substr($orig_body, 0, $img_end + strlen('[/img]'));
  55. $orig_body = substr($orig_body, $img_end + strlen('[/img]'));
  56. if($orig_body === false) // in case the body ends on a closing image tag
  57. $orig_body = '';
  58. $img_start = strpos($orig_body, '[img');
  59. $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false);
  60. $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false);
  61. }
  62. $new_body = $new_body . $orig_body;
  63. return array('body' => $new_body, 'images' => $saved_image);
  64. }}
  65. if(! function_exists('bb_replace_images')) {
  66. function bb_replace_images($body, $images) {
  67. $newbody = $body;
  68. $cnt = 0;
  69. foreach($images as $image) {
  70. // We're depending on the property of 'foreach' (specified on the PHP website) that
  71. // it loops over the array starting from the first element and going sequentially
  72. // to the last element
  73. $newbody = str_replace('[$#saved_image' . $cnt . '#$]', '<img src="' . $image .'" alt="' . t('Image/photo') . '" />', $newbody);
  74. $cnt++;
  75. }
  76. return $newbody;
  77. }}
  78. // BBcode 2 HTML was written by WAY2WEB.net
  79. // extended to work with Mistpark/Friendica - Mike Macgirvin
  80. function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
  81. $a = get_app();
  82. // Move all spaces out of the tags
  83. $Text = preg_replace("/\[(\w*)\](\s*)/ism", '$2[$1]', $Text);
  84. $Text = preg_replace("/(\s*)\[\/(\w*)\]/ism", '[/$2]$1', $Text);
  85. // Hide all [noparse] contained bbtags by spacefying them
  86. // POSSIBLE BUG --> Will the 'preg' functions crash if there's an embedded image?
  87. $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$Text);
  88. $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy',$Text);
  89. $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text);
  90. // Extract the private images which use data url's since preg has issues with
  91. // large data sizes. Stash them away while we do bbcode conversion, and then put them back
  92. // in after we've done all the regex matching. We cannot use any preg functions to do this.
  93. $extracted = bb_extract_images($Text);
  94. $Text = $extracted['body'];
  95. $saved_image = $extracted['images'];
  96. // If we find any event code, turn it into an event.
  97. // After we're finished processing the bbcode we'll
  98. // replace all of the event code with a reformatted version.
  99. $ev = bbtoevent($Text);
  100. // Replace any html brackets with HTML Entities to prevent executing HTML or script
  101. // Don't use strip_tags here because it breaks [url] search by replacing & with amp
  102. $Text = str_replace("<", "&lt;", $Text);
  103. $Text = str_replace(">", "&gt;", $Text);
  104. // Convert new line chars to html <br /> tags
  105. // nlbr seems to be hopelessly messed up
  106. // $Text = nl2br($Text);
  107. // We'll emulate it.
  108. $Text = str_replace("\r\n","\n", $Text);
  109. $Text = str_replace(array("\r","\n"), array('<br />','<br />'), $Text);
  110. if($preserve_nl)
  111. $Text = str_replace(array("\n","\r"), array('',''),$Text);
  112. // Set up the parameters for a URL search string
  113. $URLSearchString = "^\[\]";
  114. // Set up the parameters for a MAIL search string
  115. $MAILSearchString = $URLSearchString;
  116. // Perform URL Search
  117. $Text = preg_replace("/([^\]\=]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1<a href="$2" target="external-link">$2</a>', $Text);
  118. if ($tryoembed)
  119. $Text = preg_replace_callback("/\[bookmark\=([^\]]*)\].*?\[\/bookmark\]/ism",'tryoembed',$Text);
  120. $Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",'[url=$1]$2[/url]',$Text);
  121. if ($tryoembed)
  122. $Text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism",'tryoembed',$Text);
  123. $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="external-link">$1</a>', $Text);
  124. $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" target="external-link">$2</a>', $Text);
  125. //$Text = preg_replace("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_blank">$2</a>', $Text);
  126. // we may need to restrict this further if it picks up too many strays
  127. // link acct:user@host to a webfinger profile redirector
  128. $Text = preg_replace('/acct:(.*?)@(.*?)([ ,])/', '<a href="' . $a->get_baseurl() . '/acctlink?addr=' . "$1@$2"
  129. . '" target="extlink" >acct:' . "$1@$2$3" . '</a>',$Text);
  130. // Perform MAIL Search
  131. $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text);
  132. $Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1">$2</a>', $Text);
  133. // Check for bold text
  134. $Text = preg_replace("(\[b\](.*?)\[\/b\])ism",'<strong>$1</strong>',$Text);
  135. // Check for Italics text
  136. $Text = preg_replace("(\[i\](.*?)\[\/i\])ism",'<em>$1</em>',$Text);
  137. // Check for Underline text
  138. $Text = preg_replace("(\[u\](.*?)\[\/u\])ism",'<u>$1</u>',$Text);
  139. // Check for strike-through text
  140. $Text = preg_replace("(\[s\](.*?)\[\/s\])ism",'<strike>$1</strike>',$Text);
  141. // Check for over-line text
  142. $Text = preg_replace("(\[o\](.*?)\[\/o\])ism",'<span class="overline">$1</span>',$Text);
  143. // Check for colored text
  144. $Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism","<span style=\"color: $1;\">$2</span>",$Text);
  145. // Check for sized text
  146. // [size=50] --> font-size: 50px (with the unit).
  147. $Text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism","<span style=\"font-size: $1px;\">$2</span>",$Text);
  148. $Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism","<span style=\"font-size: $1;\">$2</span>",$Text);
  149. // Check for centered text
  150. $Text = preg_replace("(\[center\](.*?)\[\/center\])ism","<div style=\"text-align:center;\">$1</div>",$Text);
  151. // Check for list text
  152. $Text = str_replace("[*]", "<li>", $Text);
  153. // Check for style sheet commands
  154. $Text = preg_replace("(\[style=(.*?)\](.*?)\[\/style\])ism","<span style=\"$1;\">$2</span>",$Text);
  155. // Check for CSS classes
  156. $Text = preg_replace("(\[class=(.*?)\](.*?)\[\/class\])ism","<span class=\"$1\">$2</span>",$Text);
  157. // handle nested lists
  158. $endlessloop = 0;
  159. while ((((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false)) ||
  160. ((strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false)) ||
  161. ((strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false)) ||
  162. ((strpos($Text, "[/li]") !== false) && (strpos($Text, "[li]") !== false))) && (++$endlessloop < 20)) {
  163. $Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text);
  164. $Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>' ,$Text);
  165. $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text);
  166. $Text = preg_replace("/\[list=((?-i)i)\](.*?)\[\/list\]/ism",'<ul class="listlowerroman" style="list-style-type: lower-roman;">$2</ul>' ,$Text);
  167. $Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>' ,$Text);
  168. $Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>' ,$Text);
  169. $Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>' ,$Text);
  170. $Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text);
  171. $Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text);
  172. $Text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>' ,$Text);
  173. }
  174. $Text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>' ,$Text);
  175. $Text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>' ,$Text);
  176. $Text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>' ,$Text);
  177. $Text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '<table>$1</table>' ,$Text);
  178. $Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table border="1" >$1</table>' ,$Text);
  179. $Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table border="0" >$1</table>' ,$Text);
  180. $Text = str_replace('[hr]','<hr />', $Text);
  181. // This is actually executed in prepare_body()
  182. $Text = str_replace('[nosmile]','',$Text);
  183. // Check for font change text
  184. $Text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm","<span style=\"font-family: $1;\">$2</span>",$Text);
  185. // Declare the format for [code] layout
  186. // $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism",'stripcode_br_cb',$Text);
  187. $CodeLayout = '<code>$1</code>';
  188. // Check for [code] text
  189. $Text = preg_replace("/\[code\](.*?)\[\/code\]/ism","$CodeLayout", $Text);
  190. // Declare the format for [spoiler] layout
  191. $SpoilerLayout = '<blockquote class="spoiler">$1</blockquote>';
  192. // Check for [spoiler] text
  193. // handle nested quotes
  194. $endlessloop = 0;
  195. while ((strpos($Text, "[/spoiler]") !== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20))
  196. $Text = preg_replace("/\[spoiler\](.*?)\[\/spoiler\]/ism","$SpoilerLayout", $Text);
  197. // Check for [spoiler=Author] text
  198. $t_wrote = t('$1 wrote:');
  199. // handle nested quotes
  200. $endlessloop = 0;
  201. while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler=") !== false) and (++$endlessloop < 20))
  202. $Text = preg_replace("/\[spoiler=[\"\']*(.*?)[\"\']*\](.*?)\[\/spoiler\]/ism",
  203. "<br /><strong class=".'"spoiler"'.">" . $t_wrote . "</strong><blockquote class=".'"spoiler"'.">$2</blockquote>",
  204. $Text);
  205. // Declare the format for [quote] layout
  206. $QuoteLayout = '<blockquote>$1</blockquote>';
  207. // Check for [quote] text
  208. // handle nested quotes
  209. $endlessloop = 0;
  210. while ((strpos($Text, "[/quote]") !== false) and (strpos($Text, "[quote]") !== false) and (++$endlessloop < 20))
  211. $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism","$QuoteLayout", $Text);
  212. // Check for [quote=Author] text
  213. $t_wrote = t('$1 wrote:');
  214. // handle nested quotes
  215. $endlessloop = 0;
  216. while ((strpos($Text, "[/quote]")!== false) and (strpos($Text, "[quote=") !== false) and (++$endlessloop < 20))
  217. $Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism",
  218. "<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote>$2</blockquote>",
  219. $Text);
  220. // [img=widthxheight]image source[/img]
  221. //$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '<img src="$3" style="height: $2px; width: $1px;" >', $Text);
  222. $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '<img src="$3" style="width: $1px;" >', $Text);
  223. // Images
  224. // [img]pathtoimage[/img]
  225. $Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img src="$1" alt="' . t('Image/photo') . '" />', $Text);
  226. // Try to Oembed
  227. if ($tryoembed) {
  228. $Text = preg_replace("/\[video\](.*?\.(ogg|ogv|oga|ogm|webm|mp4))\[\/video\]/ism", '<video src="$1" controls="controls" width="' . $a->videowidth . '" height="' . $a->videoheight . '"><a href="$1">$1</a></video>', $Text);
  229. $Text = preg_replace("/\[audio\](.*?\.(ogg|ogv|oga|ogm|webm|mp4|mp3))\[\/audio\]/ism", '<audio src="$1" controls="controls"><a href="$1">$1</a></audio>', $Text);
  230. $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryoembed', $Text);
  231. $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryoembed', $Text);
  232. } else {
  233. $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '$1', $Text);
  234. $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '$1', $Text);
  235. }
  236. // html5 video and audio
  237. if ($tryoembed)
  238. $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<iframe src="$1" width="' . $a->videowidth . '" height="' . $a->videoheight . '"><a href="$1">$1</a></iframe>', $Text);
  239. else
  240. $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1">$1</a>', $Text);
  241. // Youtube extensions
  242. if ($tryoembed) {
  243. $Text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
  244. $Text = preg_replace_callback("/\[youtube\](www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
  245. $Text = preg_replace_callback("/\[youtube\](https?:\/\/youtu.be\/.*?)\[\/youtube\]/ism",'tryoembed',$Text);
  246. }
  247. $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text);
  248. $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text);
  249. $Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text);
  250. if ($tryoembed)
  251. $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="http://www.youtube.com/embed/$1" frameborder="0" ></iframe>', $Text);
  252. else
  253. $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", "http://www.youtube.com/watch?v=$1", $Text);
  254. if ($tryoembed) {
  255. $Text = preg_replace_callback("/\[vimeo\](https?:\/\/player.vimeo.com\/video\/[0-9]+).*?\[\/vimeo\]/ism",'tryoembed',$Text);
  256. $Text = preg_replace_callback("/\[vimeo\](https?:\/\/vimeo.com\/[0-9]+).*?\[\/vimeo\]/ism",'tryoembed',$Text);
  257. }
  258. $Text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism",'[vimeo]$1[/vimeo]',$Text);
  259. $Text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism",'[vimeo]$1[/vimeo]',$Text);
  260. if ($tryoembed)
  261. $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="http://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $Text);
  262. else
  263. $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", "http://vimeo.com/$1", $Text);
  264. // $Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '<object width="425" height="350" type="application/x-shockwave-flash" data="http://www.youtube.com/v/$1" ><param name="movie" value="http://www.youtube.com/v/$1"></param><!--[if IE]><embed src="http://www.youtube.com/v/$1" type="application/x-shockwave-flash" width="425" height="350" /><![endif]--></object>', $Text);
  265. // oembed tag
  266. $Text = oembed_bbcode2html($Text);
  267. // Avoid triple linefeeds through oembed
  268. $Text = str_replace("<br style='clear:left'></span><br /><br />", "<br style='clear:left'></span><br />", $Text);
  269. // If we found an event earlier, strip out all the event code and replace with a reformatted version.
  270. // Replace the event-start section with the entire formatted event. The other bbcode is stripped.
  271. // Summary (e.g. title) is required, earlier revisions only required description (in addition to
  272. // start which is always required). Allow desc with a missing summary for compatibility.
  273. if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
  274. $sub = format_event_html($ev);
  275. $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text);
  276. $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text);
  277. $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text);
  278. $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text);
  279. $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text);
  280. $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text);
  281. }
  282. // Unhide all [noparse] contained bbtags unspacefying them
  283. // and triming the [noparse] tag.
  284. $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim',$Text);
  285. $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim',$Text);
  286. $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim',$Text);
  287. $Text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/','&$1;',$Text);
  288. // fix any escaped ampersands that may have been converted into links
  289. $Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism",'<$1$2=$3&$4>',$Text);
  290. $Text = preg_replace("/\<(.*?)(src|href)=\"[^hfm](.*?)\>/ism",'<$1$2="">',$Text);
  291. if($saved_image)
  292. $Text = bb_replace_images($Text, $saved_image);
  293. // Clean up the HTML by loading and saving the HTML with the DOM
  294. // Only do it when it has to be done - for performance reasons
  295. if (!$tryoembed) {
  296. $doc = new DOMDocument();
  297. $doc->preserveWhiteSpace = false;
  298. $Text = mb_convert_encoding($Text, 'HTML-ENTITIES', "UTF-8");
  299. $doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">';
  300. @$doc->loadHTML($doctype."<html><body>".$Text."</body></html>");
  301. $Text = $doc->saveHTML();
  302. $Text = str_replace(array("<html><body>", "</body></html>", $doctype), array("", "", ""), $Text);
  303. $Text = str_replace('<br></li>','</li>', $Text);
  304. $Text = mb_convert_encoding($Text, "UTF-8", 'HTML-ENTITIES');
  305. }
  306. call_hooks('bbcode',$Text);
  307. return $Text;
  308. }