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.
 
 
 
 
 
 

1318 lines
46 KiB

  1. <?php
  2. require_once("include/oembed.php");
  3. require_once('include/event.php');
  4. function bb_attachment($Text, $plaintext = false, $tryoembed = true) {
  5. $Text = preg_replace_callback("/\[attachment(.*?)\](.*?)\[\/attachment\]/ism",
  6. function ($match) use ($plaintext){
  7. $attributes = $match[1];
  8. $type = "";
  9. preg_match("/type='(.*?)'/ism", $attributes, $matches);
  10. if ($matches[1] != "")
  11. $type = $matches[1];
  12. preg_match('/type="(.*?)"/ism', $attributes, $matches);
  13. if ($matches[1] != "")
  14. $type = $matches[1];
  15. if ($type == "")
  16. return($match[0]);
  17. if (!in_array($type, array("link", "audio", "video")))
  18. return($match[0]);
  19. $url = "";
  20. preg_match("/url='(.*?)'/ism", $attributes, $matches);
  21. if ($matches[1] != "")
  22. $url = $matches[1];
  23. preg_match('/url="(.*?)"/ism', $attributes, $matches);
  24. if ($matches[1] != "")
  25. $url = $matches[1];
  26. $title = "";
  27. preg_match("/title='(.*?)'/ism", $attributes, $matches);
  28. if ($matches[1] != "")
  29. $title = $matches[1];
  30. preg_match('/title="(.*?)"/ism', $attributes, $matches);
  31. if ($matches[1] != "")
  32. $title = $matches[1];
  33. $image = "";
  34. preg_match("/image='(.*?)'/ism", $attributes, $matches);
  35. if ($matches[1] != "")
  36. $image = $matches[1];
  37. preg_match('/image="(.*?)"/ism', $attributes, $matches);
  38. if ($matches[1] != "")
  39. $image = $matches[1];
  40. $preview = "";
  41. preg_match("/preview='(.*?)'/ism", $attributes, $matches);
  42. if ($matches[1] != "")
  43. $preview = $matches[1];
  44. preg_match('/preview="(.*?)"/ism', $attributes, $matches);
  45. if ($matches[1] != "")
  46. $preview = $matches[1];
  47. if ($plaintext)
  48. $text = sprintf('<a href="%s" target="_blank">%s</a>', $url, $title);
  49. else {
  50. $text = sprintf('<span class="type-%s">', $type);
  51. $bookmark = array(sprintf('[bookmark=%s]%s[/bookmark]', $url, $title), $title, $url);
  52. if ($tryoembed)
  53. $oembed = tryoembed($bookmark);
  54. else
  55. $oembed = $bookmark[0];
  56. if (($image != "") AND !strstr(strtolower($oembed), "<img "))
  57. $text .= sprintf('<img src="%s" alt="%s" class="attachment-image" />', $image, $title); // To-Do: Anführungszeichen in "alt"
  58. elseif (($preview != "") AND !strstr(strtolower($oembed), "<img "))
  59. $text .= sprintf('<img src="%s" alt="%s" class="attachment-preview" />', $preview, $title); // To-Do: Anführungszeichen in "alt"
  60. $text .= $oembed;
  61. $text .= sprintf('<blockquote>%s</blockquote></span>', trim($match[2]));
  62. }
  63. return($text);
  64. },$Text);
  65. return($Text);
  66. }
  67. function bb_rearrange_link($shared) {
  68. if ($shared[1] != "type-link")
  69. return($shared[0]);
  70. $newshare = trim($shared[2]);
  71. $newshare = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $newshare);
  72. if (!strpos($shared[0], "[bookmark"))
  73. $newshare = preg_replace("/\[url\=(.*?)\](.*?)\[\/url\]/ism", '[bookmark=$1]$2[/bookmark]', $newshare, 1);
  74. preg_match("/\[img\](.*?)\[\/img\]/ism", $newshare, $matches);
  75. if ($matches) {
  76. $newshare = str_replace($matches[0], '', $newshare);
  77. $newshare = "[img]".$matches[1]."[/img]\n".$newshare;
  78. }
  79. $search = array("\n\n", "\n ", " \n");
  80. $replace = array("\n", "\n", "\n");
  81. do {
  82. $oldtext = $newshare;
  83. $newshare = str_replace($search, $replace, $newshare);
  84. } while ($oldtext != $newshare);
  85. $newshare = "[class=type-link]".$newshare."[/class]";
  86. return($newshare);
  87. }
  88. function bb_remove_share_information($Text, $plaintext = false, $nolink = false) {
  89. $Text = preg_replace_callback("((.*?)\[class=(.*?)\](.*?)\[\/class\])ism",
  90. function ($match) use ($plaintext, $nolink){
  91. return(bb_cleanup_share($match, $plaintext, $nolink));
  92. },$Text);
  93. return($Text);
  94. }
  95. function bb_cleanup_share($shared, $plaintext, $nolink) {
  96. if (!in_array($shared[2], array("type-link", "type-video")))
  97. return($shared[0]);
  98. if ($plaintext)
  99. $shared[3] = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism","[bookmark=$1]$1[/bookmark]", $shared[3]);
  100. if (!preg_match_all("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",$shared[3], $bookmark))
  101. return($shared[0]);
  102. if ($nolink)
  103. return(trim($shared[1]));
  104. $title = "";
  105. $link = "";
  106. if (isset($bookmark[2][0]))
  107. $title = $bookmark[2][0];
  108. if (isset($bookmark[1][0]))
  109. $link = $bookmark[1][0];
  110. if (strpos($shared[1],$title) !== false)
  111. $title = "";
  112. // if (strpos($shared[1],$link) !== false)
  113. // $link = "";
  114. $text = trim($shared[1]);
  115. if (($text == "") AND ($title != "") AND ($link == ""))
  116. $text .= "\n\n".trim($title);
  117. if (($link != "") AND ($title != ""))
  118. $text .= "\n[url=".trim($link)."]".trim($title)."[/url]";
  119. elseif (($link != ""))
  120. $text .= "\n".trim($link);
  121. return(trim($text));
  122. }
  123. function bb_cleanstyle($st) {
  124. return "<span style=\"".cleancss($st[1]).";\">".$st[2]."</span>";
  125. }
  126. function bb_cleanclass($st) {
  127. return "<span class=\"".cleancss($st[1])."\">".$st[2]."</span>";
  128. }
  129. function cleancss($input) {
  130. $cleaned = "";
  131. $input = strtolower($input);
  132. for ($i = 0; $i < strlen($input); $i++) {
  133. $char = substr($input, $i, 1);
  134. if (($char >= "a") and ($char <= "z"))
  135. $cleaned .= $char;
  136. if (!(strpos(" #;:0123456789-_", $char) === false))
  137. $cleaned .= $char;
  138. }
  139. return($cleaned);
  140. }
  141. function stripcode_br_cb($s) {
  142. return '[code]' . str_replace('<br />', '', $s[1]) . '[/code]';
  143. }
  144. function tryoembed($match){
  145. $url = ((count($match)==2)?$match[1]:$match[2]);
  146. // Always embed the SSL version
  147. $url = str_replace(array("http://www.youtube.com/", "http://player.vimeo.com/"),
  148. array("https://www.youtube.com/", "https://player.vimeo.com/"), $url);
  149. //logger("tryoembed: $url");
  150. $o = oembed_fetch_url($url);
  151. //echo "<pre>"; var_dump($match, $url, $o); killme();
  152. if ($o->type=="error") return $match[0];
  153. $html = oembed_format_object($o);
  154. return $html; //oembed_iframe($html,$o->width,$o->height);
  155. }
  156. // [noparse][i]italic[/i][/noparse] turns into
  157. // [noparse][ i ]italic[ /i ][/noparse],
  158. // to hide them from parser.
  159. function bb_spacefy($st) {
  160. $whole_match = $st[0];
  161. $captured = $st[1];
  162. $spacefied = preg_replace("/\[(.*?)\]/", "[ $1 ]", $captured);
  163. $new_str = str_replace($captured, $spacefied, $whole_match);
  164. return $new_str;
  165. }
  166. // The previously spacefied [noparse][ i ]italic[ /i ][/noparse],
  167. // now turns back and the [noparse] tags are trimed
  168. // returning [i]italic[/i]
  169. function bb_unspacefy_and_trim($st) {
  170. $whole_match = $st[0];
  171. $captured = $st[1];
  172. $unspacefied = preg_replace("/\[ (.*?)\ ]/", "[$1]", $captured);
  173. return $unspacefied;
  174. }
  175. function bb_find_open_close($s, $open, $close, $occurance = 1) {
  176. if($occurance < 1)
  177. $occurance = 1;
  178. $start_pos = -1;
  179. for($i = 1; $i <= $occurance; $i++) {
  180. if( $start_pos !== false)
  181. $start_pos = strpos($s, $open, $start_pos + 1);
  182. }
  183. if( $start_pos === false)
  184. return false;
  185. $end_pos = strpos($s, $close, $start_pos);
  186. if( $end_pos === false)
  187. return false;
  188. $res = array( 'start' => $start_pos, 'end' => $end_pos );
  189. return $res;
  190. }
  191. function get_bb_tag_pos($s, $name, $occurance = 1) {
  192. if($occurance < 1)
  193. $occurance = 1;
  194. $start_open = -1;
  195. for($i = 1; $i <= $occurance; $i++) {
  196. if( $start_open !== false)
  197. $start_open = strpos($s, '[' . $name, $start_open + 1); // allow [name= type tags
  198. }
  199. if( $start_open === false)
  200. return false;
  201. $start_equal = strpos($s, '=', $start_open);
  202. $start_close = strpos($s, ']', $start_open);
  203. if( $start_close === false)
  204. return false;
  205. $start_close++;
  206. $end_open = strpos($s, '[/' . $name . ']', $start_close);
  207. if( $end_open === false)
  208. return false;
  209. $res = array( 'start' => array('open' => $start_open, 'close' => $start_close),
  210. 'end' => array('open' => $end_open, 'close' => $end_open + strlen('[/' . $name . ']')) );
  211. if( $start_equal !== false)
  212. $res['start']['equal'] = $start_equal + 1;
  213. return $res;
  214. }
  215. function bb_tag_preg_replace($pattern, $replace, $name, $s) {
  216. $string = $s;
  217. $occurance = 1;
  218. $pos = get_bb_tag_pos($string, $name, $occurance);
  219. while($pos !== false && $occurance < 1000) {
  220. $start = substr($string, 0, $pos['start']['open']);
  221. $subject = substr($string, $pos['start']['open'], $pos['end']['close'] - $pos['start']['open']);
  222. $end = substr($string, $pos['end']['close']);
  223. if($end === false)
  224. $end = '';
  225. $subject = preg_replace($pattern, $replace, $subject);
  226. $string = $start . $subject . $end;
  227. $occurance++;
  228. $pos = get_bb_tag_pos($string, $name, $occurance);
  229. }
  230. return $string;
  231. }
  232. if(! function_exists('bb_extract_images')) {
  233. function bb_extract_images($body) {
  234. $saved_image = array();
  235. $orig_body = $body;
  236. $new_body = '';
  237. $cnt = 0;
  238. $img_start = strpos($orig_body, '[img');
  239. $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false);
  240. $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false);
  241. while(($img_st_close !== false) && ($img_end !== false)) {
  242. $img_st_close++; // make it point to AFTER the closing bracket
  243. $img_end += $img_start;
  244. if(! strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) {
  245. // This is an embedded image
  246. $saved_image[$cnt] = substr($orig_body, $img_start + $img_st_close, $img_end - ($img_start + $img_st_close));
  247. $new_body = $new_body . substr($orig_body, 0, $img_start) . '[$#saved_image' . $cnt . '#$]';
  248. $cnt++;
  249. }
  250. else
  251. $new_body = $new_body . substr($orig_body, 0, $img_end + strlen('[/img]'));
  252. $orig_body = substr($orig_body, $img_end + strlen('[/img]'));
  253. if($orig_body === false) // in case the body ends on a closing image tag
  254. $orig_body = '';
  255. $img_start = strpos($orig_body, '[img');
  256. $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false);
  257. $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false);
  258. }
  259. $new_body = $new_body . $orig_body;
  260. return array('body' => $new_body, 'images' => $saved_image);
  261. }}
  262. if(! function_exists('bb_replace_images')) {
  263. function bb_replace_images($body, $images) {
  264. $newbody = $body;
  265. $cnt = 0;
  266. foreach($images as $image) {
  267. // We're depending on the property of 'foreach' (specified on the PHP website) that
  268. // it loops over the array starting from the first element and going sequentially
  269. // to the last element
  270. $newbody = str_replace('[$#saved_image' . $cnt . '#$]', '<img src="' . $image .'" alt="' . t('Image/photo') . '" />', $newbody);
  271. $cnt++;
  272. }
  273. return $newbody;
  274. }}
  275. /*
  276. function bb_ShareAttributes($match) {
  277. $attributes = $match[1];
  278. $author = "";
  279. preg_match("/author='(.*?)'/ism", $attributes, $matches);
  280. if ($matches[1] != "")
  281. $author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
  282. preg_match('/author="(.*?)"/ism', $attributes, $matches);
  283. if ($matches[1] != "")
  284. $author = $matches[1];
  285. $link = "";
  286. preg_match("/link='(.*?)'/ism", $attributes, $matches);
  287. if ($matches[1] != "")
  288. $link = $matches[1];
  289. preg_match('/link="(.*?)"/ism', $attributes, $matches);
  290. if ($matches[1] != "")
  291. $link = $matches[1];
  292. $avatar = "";
  293. preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
  294. if ($matches[1] != "")
  295. $avatar = $matches[1];
  296. preg_match('/avatar="(.*?)"/ism', $attributes, $matches);
  297. if ($matches[1] != "")
  298. $avatar = $matches[1];
  299. $profile = "";
  300. preg_match("/profile='(.*?)'/ism", $attributes, $matches);
  301. if ($matches[1] != "")
  302. $profile = $matches[1];
  303. preg_match('/profile="(.*?)"/ism', $attributes, $matches);
  304. if ($matches[1] != "")
  305. $profile = $matches[1];
  306. $posted = "";
  307. $itemcache = get_itemcachepath();
  308. // relative dates only make sense when they aren't cached
  309. if ($itemcache == "") {
  310. preg_match("/posted='(.*?)'/ism", $attributes, $matches);
  311. if ($matches[1] != "")
  312. $posted = $matches[1];
  313. preg_match('/posted="(.*?)"/ism', $attributes, $matches);
  314. if ($matches[1] != "")
  315. $posted = $matches[1];
  316. $reldate = (($posted) ? " " . relative_date($posted) : '');
  317. }
  318. $headline = '<div class="shared_header">';
  319. //$headline = '<br /><div class="shared_header">';
  320. if ($avatar != "")
  321. $headline .= '<img src="'.$avatar.'" height="32" width="32" >';
  322. $headline .= sprintf(t('<span><a href="%s" target="_blank">%s</a> wrote the following <a href="%s" target="_blank">post</a>'.$reldate.':</span>'), $profile, $author, $link);
  323. $headline .= "</div>";
  324. $text = $headline.'<blockquote class="shared_content">'.trim($match[2])."</blockquote>";
  325. return($text);
  326. }
  327. // Escpecially for Diaspora (there mustn't be links in the share information)
  328. function bb_ShareAttributesDiaspora($match) {
  329. $attributes = $match[2];
  330. $author = "";
  331. preg_match("/author='(.*?)'/ism", $attributes, $matches);
  332. if ($matches[1] != "")
  333. $author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
  334. preg_match('/author="(.*?)"/ism', $attributes, $matches);
  335. if ($matches[1] != "")
  336. $author = $matches[1];
  337. $profile = "";
  338. preg_match("/profile='(.*?)'/ism", $attributes, $matches);
  339. if ($matches[1] != "")
  340. $profile = $matches[1];
  341. preg_match('/profile="(.*?)"/ism', $attributes, $matches);
  342. if ($matches[1] != "")
  343. $profile = $matches[1];
  344. $link = "";
  345. preg_match("/link='(.*?)'/ism", $attributes, $matches);
  346. if ($matches[1] != "")
  347. $link = $matches[1];
  348. preg_match('/link="(.*?)"/ism', $attributes, $matches);
  349. if ($matches[1] != "")
  350. $link = $matches[1];
  351. $userid = GetProfileUsername($profile,$author);
  352. $headline = '<div class="shared_header">';
  353. $headline .= '<span><b>'.html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').$userid.':</b></span>';
  354. $headline .= "</div>";
  355. $text = trim($match[1]);
  356. if ($text != "")
  357. $text .= "<hr />";
  358. $text .= $headline.'<blockquote class="shared_content">'.trim($match[3])."</blockquote><br />";
  359. if ($link != "")
  360. $text .= '<br /><a href="'.$link.'">[l]</a>';
  361. // $text .= '<br /><a href="'.$link.'">'.t("Link").' [l]</a>';
  362. return($text);
  363. }
  364. // Optimized for Libertree, Wordpress, Tumblr, ...
  365. function bb_ShareAttributesForExport($match) {
  366. $attributes = $match[2];
  367. $author = "";
  368. preg_match("/author='(.*?)'/ism", $attributes, $matches);
  369. if ($matches[1] != "")
  370. $author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
  371. preg_match('/author="(.*?)"/ism', $attributes, $matches);
  372. if ($matches[1] != "")
  373. $author = $matches[1];
  374. $profile = "";
  375. preg_match("/profile='(.*?)'/ism", $attributes, $matches);
  376. if ($matches[1] != "")
  377. $profile = $matches[1];
  378. preg_match('/profile="(.*?)"/ism', $attributes, $matches);
  379. if ($matches[1] != "")
  380. $profile = $matches[1];
  381. $link = "";
  382. preg_match("/link='(.*?)'/ism", $attributes, $matches);
  383. if ($matches[1] != "")
  384. $link = $matches[1];
  385. preg_match('/link="(.*?)"/ism', $attributes, $matches);
  386. if ($matches[1] != "")
  387. $link = $matches[1];
  388. if ($link == "")
  389. $link = $profile;
  390. $userid = GetProfileUsername($profile,$author);
  391. $headline = '<div class="shared_header">';
  392. $headline .= '<span><b>'.html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8');
  393. $headline .= sprintf(t('<a href="%1$s" target="_blank">%2$s</a> %3$s'), $link, $userid, $posted);
  394. $headline .= ":</b></span></div>";
  395. $text = trim($match[1]);
  396. if ($text != "")
  397. $text .= "<hr />";
  398. $text .= $headline.'<blockquote class="shared_content">'.trim($match[3])."</blockquote><br />";
  399. return($text);
  400. }
  401. // Still in use?
  402. function bb_ShareAttributesSimple($match) {
  403. $attributes = $match[1];
  404. $author = "";
  405. preg_match("/author='(.*?)'/ism", $attributes, $matches);
  406. if ($matches[1] != "")
  407. $author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
  408. preg_match('/author="(.*?)"/ism', $attributes, $matches);
  409. if ($matches[1] != "")
  410. $author = $matches[1];
  411. $profile = "";
  412. preg_match("/profile='(.*?)'/ism", $attributes, $matches);
  413. if ($matches[1] != "")
  414. $profile = $matches[1];
  415. preg_match('/profile="(.*?)"/ism', $attributes, $matches);
  416. if ($matches[1] != "")
  417. $profile = $matches[1];
  418. $userid = GetProfileUsername($profile,$author);
  419. $text = "<br />".html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').' <a href="'.$profile.'">'.$userid."</a>: <br />»".$match[2]."«";
  420. return($text);
  421. }
  422. // Used for text exports (Twitter, Facebook, Google+)
  423. function bb_ShareAttributesSimple2($match) {
  424. $attributes = $match[1];
  425. $author = "";
  426. preg_match("/author='(.*?)'/ism", $attributes, $matches);
  427. if ($matches[1] != "")
  428. $author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
  429. preg_match('/author="(.*?)"/ism', $attributes, $matches);
  430. if ($matches[1] != "")
  431. $author = $matches[1];
  432. $profile = "";
  433. preg_match("/profile='(.*?)'/ism", $attributes, $matches);
  434. if ($matches[1] != "")
  435. $profile = $matches[1];
  436. preg_match('/profile="(.*?)"/ism', $attributes, $matches);
  437. if ($matches[1] != "")
  438. $profile = $matches[1];
  439. $userid = GetProfileUsername($profile,$author);
  440. //$text = "<br />".html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').' <a href="'.$profile.'">'.$userid."</a>: <br />".$match[2];
  441. $text = "<br />".html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').' '.$userid.": <br />".$match[2];
  442. return($text);
  443. }
  444. */
  445. function bb_ShareAttributes($share, $simplehtml) {
  446. $attributes = $share[2];
  447. $author = "";
  448. preg_match("/author='(.*?)'/ism", $attributes, $matches);
  449. if ($matches[1] != "")
  450. $author = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
  451. preg_match('/author="(.*?)"/ism', $attributes, $matches);
  452. if ($matches[1] != "")
  453. $author = $matches[1];
  454. $profile = "";
  455. preg_match("/profile='(.*?)'/ism", $attributes, $matches);
  456. if ($matches[1] != "")
  457. $profile = $matches[1];
  458. preg_match('/profile="(.*?)"/ism', $attributes, $matches);
  459. if ($matches[1] != "")
  460. $profile = $matches[1];
  461. $avatar = "";
  462. preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
  463. if ($matches[1] != "")
  464. $avatar = $matches[1];
  465. preg_match('/avatar="(.*?)"/ism', $attributes, $matches);
  466. if ($matches[1] != "")
  467. $avatar = $matches[1];
  468. $link = "";
  469. preg_match("/link='(.*?)'/ism", $attributes, $matches);
  470. if ($matches[1] != "")
  471. $link = $matches[1];
  472. preg_match('/link="(.*?)"/ism', $attributes, $matches);
  473. if ($matches[1] != "")
  474. $link = $matches[1];
  475. $posted = "";
  476. $itemcache = get_itemcachepath();
  477. // relative dates only make sense when they aren't cached
  478. if ($itemcache == "") {
  479. preg_match("/posted='(.*?)'/ism", $attributes, $matches);
  480. if ($matches[1] != "")
  481. $posted = $matches[1];
  482. preg_match('/posted="(.*?)"/ism', $attributes, $matches);
  483. if ($matches[1] != "")
  484. $posted = $matches[1];
  485. $reldate = (($posted) ? " " . relative_date($posted) : '');
  486. }
  487. $userid = GetProfileUsername($profile,$author);
  488. $preshare = trim($share[1]);
  489. if ($preshare != "")
  490. $preshare .= "<br /><br />";
  491. switch ($simplehtml) {
  492. case 1:
  493. $text = $preshare.html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').' <a href="'.$profile.'">'.$userid."</a>: <br />»".$share[3]."«";
  494. break;
  495. case 2:
  496. $text = $preshare.html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').' '.$userid.": <br />".$share[3];
  497. break;
  498. case 3:
  499. $headline = '<div class="shared_header">';
  500. $headline .= '<span><b>'.html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').$userid.':</b></span>';
  501. $headline .= "</div>";
  502. $text = trim($share[1]);
  503. if ($text != "")
  504. $text .= "<hr />";
  505. $text .= $headline.'<blockquote class="shared_content">'.trim($share[3])."</blockquote><br />";
  506. if ($link != "")
  507. $text .= '<br /><a href="'.$link.'">[l]</a>';
  508. break;
  509. case 4:
  510. $headline = '<div class="shared_header">';
  511. $headline .= '<span><b>'.html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8');
  512. $headline .= sprintf(t('<a href="%1$s" target="_blank">%2$s</a> %3$s'), $link, $userid, $posted);
  513. $headline .= ":</b></span></div>";
  514. $text = trim($share[1]);
  515. if ($text != "")
  516. $text .= "<hr />";
  517. $text .= $headline.'<blockquote class="shared_content">'.trim($share[3])."</blockquote><br />";
  518. break;
  519. case 5:
  520. $text = $preshare.html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8').' '.$userid.": <br />".$share[3];
  521. break;
  522. case 6:
  523. $text = $preshare."&gt;&gt; ".$userid.": <br />".$share[3];
  524. break;
  525. default:
  526. $headline = trim($share[1]).'<div class="shared_header">';
  527. if ($avatar != "")
  528. $headline .= '<img src="'.$avatar.'" height="32" width="32" >';
  529. $headline .= sprintf(t('<span><a href="%s" target="_blank">%s</a> wrote the following <a href="%s" target="_blank">post</a>'.$reldate.':</span>'), $profile, $author, $link);
  530. $headline .= "</div>";
  531. $text = $headline.'<blockquote class="shared_content">'.trim($share[3])."</blockquote>";
  532. break;
  533. }
  534. return($text);
  535. }
  536. function GetProfileUsername($profile, $username) {
  537. $twitter = preg_replace("=https?://twitter.com/(.*)=ism", "$1@twitter.com", $profile);
  538. if ($twitter != $profile)
  539. return($username." (".$twitter.")");
  540. $appnet = preg_replace("=https?://alpha.app.net/(.*)=ism", "$1@alpha.app.net", $profile);
  541. if ($appnet != $profile)
  542. return($username." (".$appnet.")");
  543. $gplus = preg_replace("=https?://plus.google.com/(.*)=ism", "$1@plus.google.com", $profile);
  544. if ($gplus != $profile)
  545. return($username." (".$gplus.")");
  546. $friendica = preg_replace("=https?://(.*)/profile/(.*)=ism", "$2@$1", $profile);
  547. if ($friendica != $profile)
  548. return($username." (".$friendica.")");
  549. $diaspora = preg_replace("=https?://(.*)/u/(.*)=ism", "$2@$1", $profile);
  550. if ($diaspora != $profile)
  551. return($username." (".$diaspora.")");
  552. $StatusnetHost = preg_replace("=https?://(.*)/user/(.*)=ism", "$1", $profile);
  553. if ($StatusnetHost != $profile) {
  554. $StatusnetUser = preg_replace("=https?://(.*)/user/(.*)=ism", "$2", $profile);
  555. if ($StatusnetUser != $profile) {
  556. $UserData = fetch_url("http://".$StatusnetHost."/api/users/show.json?user_id=".$StatusnetUser);
  557. $user = json_decode($UserData);
  558. if ($user)
  559. return($username." (".$user->screen_name."@".$StatusnetHost.")");
  560. }
  561. }
  562. // pumpio (http://host.name/user)
  563. $rest = preg_replace("=https?://([\.\w]+)/([\.\w]+)(.*)=ism", "$3", $profile);
  564. if ($rest == "") {
  565. $pumpio = preg_replace("=https?://([\.\w]+)/([\.\w]+)(.*)=ism", "$2@$1", $profile);
  566. if ($pumpio != $profile)
  567. return($username." (".$pumpio.")");
  568. }
  569. return($username);
  570. }
  571. function bb_RemovePictureLinks($match) {
  572. $text = Cache::get($match[1]);
  573. if(is_null($text)){
  574. $ch = @curl_init($match[1]);
  575. @curl_setopt($ch, CURLOPT_NOBODY, true);
  576. @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  577. @curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; Friendica)");
  578. @curl_exec($ch);
  579. $curl_info = @curl_getinfo($ch);
  580. if (substr($curl_info["content_type"], 0, 6) == "image/")
  581. $text = "[url=".$match[1]."]".$match[1]."[/url]";
  582. else {
  583. $text = "[url=".$match[2]."]".$match[2]."[/url]";
  584. // if its not a picture then look if its a page that contains a picture link
  585. require_once("include/network.php");
  586. $body = fetch_url($match[1]);
  587. $doc = new DOMDocument();
  588. @$doc->loadHTML($body);
  589. $xpath = new DomXPath($doc);
  590. $list = $xpath->query("//meta[@name]");
  591. foreach ($list as $node) {
  592. $attr = array();
  593. if ($node->attributes->length)
  594. foreach ($node->attributes as $attribute)
  595. $attr[$attribute->name] = $attribute->value;
  596. if (strtolower($attr["name"]) == "twitter:image")
  597. $text = "[url=".$attr["content"]."]".$attr["content"]."[/url]";
  598. }
  599. }
  600. Cache::set($match[1],$text);
  601. }
  602. return($text);
  603. }
  604. function bb_expand_links($match) {
  605. if (stristr($match[2], $match[3]) OR ($match[2] == $match[3]))
  606. return ($match[1]."[url]".$match[2]."[/url]");
  607. else
  608. return ($match[1].$match[3]." [url]".$match[2]."[/url]");
  609. }
  610. function bb_CleanPictureLinksSub($match) {
  611. $text = Cache::get($match[1]);
  612. if(is_null($text)){
  613. $ch = @curl_init($match[1]);
  614. @curl_setopt($ch, CURLOPT_NOBODY, true);
  615. @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  616. @curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; Friendica)");
  617. @curl_exec($ch);
  618. $curl_info = @curl_getinfo($ch);
  619. // if its a link to a picture then embed this picture
  620. if (substr($curl_info["content_type"], 0, 6) == "image/")
  621. $text = "[img]".$match[1]."[/img]";
  622. else {
  623. $text = "[img]".$match[2]."[/img]";
  624. // if its not a picture then look if its a page that contains a picture link
  625. require_once("include/network.php");
  626. $body = fetch_url($match[1]);
  627. $doc = new DOMDocument();
  628. @$doc->loadHTML($body);
  629. $xpath = new DomXPath($doc);
  630. $list = $xpath->query("//meta[@name]");
  631. foreach ($list as $node) {
  632. $attr = array();
  633. if ($node->attributes->length)
  634. foreach ($node->attributes as $attribute)
  635. $attr[$attribute->name] = $attribute->value;
  636. if (strtolower($attr["name"]) == "twitter:image")
  637. $text = "[img]".$attr["content"]."[/img]";
  638. }
  639. }
  640. Cache::set($match[1],$text);
  641. }
  642. return($text);
  643. }
  644. function bb_CleanPictureLinks($text) {
  645. $text = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'bb_CleanPictureLinksSub', $text);
  646. return ($text);
  647. }
  648. // BBcode 2 HTML was written by WAY2WEB.net
  649. // extended to work with Mistpark/Friendica - Mike Macgirvin
  650. function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = false, $forplaintext = false) {
  651. $stamp1 = microtime(true);
  652. $a = get_app();
  653. // Hide all [noparse] contained bbtags by spacefying them
  654. // POSSIBLE BUG --> Will the 'preg' functions crash if there's an embedded image?
  655. $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$Text);
  656. $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy',$Text);
  657. $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text);
  658. // Move all spaces out of the tags
  659. $Text = preg_replace("/\[(\w*)\](\s*)/ism", '$2[$1]', $Text);
  660. $Text = preg_replace("/(\s*)\[\/(\w*)\]/ism", '[/$2]$1', $Text);
  661. // Extract the private images which use data urls since preg has issues with
  662. // large data sizes. Stash them away while we do bbcode conversion, and then put them back
  663. // in after we've done all the regex matching. We cannot use any preg functions to do this.
  664. $extracted = bb_extract_images($Text);
  665. $Text = $extracted['body'];
  666. $saved_image = $extracted['images'];
  667. // If we find any event code, turn it into an event.
  668. // After we're finished processing the bbcode we'll
  669. // replace all of the event code with a reformatted version.
  670. $ev = bbtoevent($Text);
  671. // Replace any html brackets with HTML Entities to prevent executing HTML or script
  672. // Don't use strip_tags here because it breaks [url] search by replacing & with amp
  673. $Text = str_replace("<", "&lt;", $Text);
  674. $Text = str_replace(">", "&gt;", $Text);
  675. // remove some newlines before the general conversion
  676. $Text = preg_replace("/\s?\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","[share$1]$2[/share]",$Text);
  677. $Text = preg_replace("/\s?\[quote(.*?)\]\s?(.*?)\s?\[\/quote\]\s?/ism","[quote$1]$2[/quote]",$Text);
  678. $Text = preg_replace("/\n\[code\]/ism", "[code]", $Text);
  679. $Text = preg_replace("/\[\/code\]\n/ism", "[/code]", $Text);
  680. // Handle attached links or videos
  681. $Text = bb_attachment($Text, ($simplehtml != 4) AND ($simplehtml != 0), $tryoembed);
  682. // Rearrange shared links
  683. if (get_config("system", "rearrange_shared_links") AND (!$simplehtml OR $tryoembed))
  684. $Text = preg_replace_callback("(\[class=(.*?)\](.*?)\[\/class\])ism","bb_rearrange_link",$Text);
  685. // when the content is meant exporting to other systems then remove the avatar picture since this doesn't really look good on these systems
  686. if (!$tryoembed)
  687. $Text = preg_replace("/\[share(.*?)avatar\s?=\s?'.*?'\s?(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","\n[share$1$2]$3[/share]",$Text);
  688. // Convert new line chars to html <br /> tags
  689. // nlbr seems to be hopelessly messed up
  690. // $Text = nl2br($Text);
  691. // We'll emulate it.
  692. $Text = trim($Text);
  693. $Text = str_replace("\r\n","\n", $Text);
  694. // removing multiplicated newlines
  695. if (get_config("system", "remove_multiplicated_lines")) {
  696. $search = array("\n\n\n", "\n ", " \n", "[/quote]\n\n", "\n[/quote]", "[/li]\n", "\n[li]", "\n[ul]", "[/ul]\n", "\n\n[share ");
  697. $replace = array("\n\n", "\n", "\n", "[/quote]\n", "[/quote]", "[/li]", "[li]", "[ul]", "[/ul]", "\n[share ");
  698. do {
  699. $oldtext = $Text;
  700. $Text = str_replace($search, $replace, $Text);
  701. } while ($oldtext != $Text);
  702. }
  703. $Text = str_replace(array("\r","\n"), array('<br />','<br />'), $Text);
  704. if($preserve_nl)
  705. $Text = str_replace(array("\n","\r"), array('',''),$Text);
  706. // Set up the parameters for a URL search string
  707. $URLSearchString = "^\[\]";
  708. // Set up the parameters for a MAIL search string
  709. $MAILSearchString = $URLSearchString;
  710. // Remove all hashtag addresses
  711. if (!$tryoembed OR $simplehtml)
  712. $Text = preg_replace("/([#@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$1$3', $Text);
  713. // Bookmarks in red - will be converted to bookmarks in friendica
  714. $Text = preg_replace("/#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '[bookmark=$1]$1[/bookmark]', $Text);
  715. $Text = preg_replace("/#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '[bookmark=$1]$2[/bookmark]', $Text);
  716. $Text = preg_replace("/#\[url\=[$URLSearchString]*\]\^\[\/url\]\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/i",
  717. "[bookmark=$1]$2[/bookmark]", $Text);
  718. if (in_array($simplehtml, array(2, 6))) {
  719. $Text = preg_replace_callback("/([^#@])\[url\=([^\]]*)\](.*?)\[\/url\]/ism","bb_expand_links",$Text);
  720. //$Text = preg_replace("/[^#@]\[url\=([^\]]*)\](.*?)\[\/url\]/ism",' $2 [url]$1[/url]',$Text);
  721. $Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",' $2 [url]$1[/url]',$Text);
  722. }
  723. if ($simplehtml == 5)
  724. $Text = preg_replace("/[^#@]\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '[url]$1[/url]', $Text);
  725. // Perform URL Search
  726. if ($tryoembed)
  727. $Text = preg_replace_callback("/\[bookmark\=([^\]]*)\].*?\[\/bookmark\]/ism",'tryoembed',$Text);
  728. if ($simplehtml == 5)
  729. $Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",'[url]$1[/url]',$Text);
  730. else
  731. $Text = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/ism",'[url=$1]$2[/url]',$Text);
  732. // if the HTML is used to generate plain text, then don't do this search, but replace all URL of that kind to text
  733. if (!$forplaintext)
  734. $Text = preg_replace("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1<a href="$2" target="_blank">$2</a>', $Text);
  735. else {
  736. $Text = preg_replace("(\[url\]([$URLSearchString]*)\[\/url\])ism"," $1 ",$Text);
  737. $Text = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'bb_RemovePictureLinks', $Text);
  738. }
  739. if ($tryoembed)
  740. $Text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism",'tryoembed',$Text);
  741. $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_blank">$1</a>', $Text);
  742. $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" target="_blank">$2</a>', $Text);
  743. //$Text = preg_replace("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_blank">$2</a>', $Text);
  744. // Red compatibility, though the link can't be authenticated on Friendica
  745. $Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a href="$1" target="_blank">$2</a>', $Text);
  746. // we may need to restrict this further if it picks up too many strays
  747. // link acct:user@host to a webfinger profile redirector
  748. $Text = preg_replace('/acct:(.*?)@(.*?)([ ,])/', '<a href="' . $a->get_baseurl() . '/acctlink?addr=' . "$1@$2"
  749. . '" target="extlink" >acct:' . "$1@$2$3" . '</a>',$Text);
  750. // Perform MAIL Search
  751. $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text);
  752. $Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1">$2</a>', $Text);
  753. // Check for bold text
  754. $Text = preg_replace("(\[b\](.*?)\[\/b\])ism",'<strong>$1</strong>',$Text);
  755. // Check for Italics text
  756. $Text = preg_replace("(\[i\](.*?)\[\/i\])ism",'<em>$1</em>',$Text);
  757. // Check for Underline text
  758. $Text = preg_replace("(\[u\](.*?)\[\/u\])ism",'<u>$1</u>',$Text);
  759. // Check for strike-through text
  760. $Text = preg_replace("(\[s\](.*?)\[\/s\])ism",'<strike>$1</strike>',$Text);
  761. // Check for over-line text
  762. $Text = preg_replace("(\[o\](.*?)\[\/o\])ism",'<span class="overline">$1</span>',$Text);
  763. // Check for colored text
  764. $Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism","<span style=\"color: $1;\">$2</span>",$Text);
  765. // Check for sized text
  766. // [size=50] --> font-size: 50px (with the unit).
  767. $Text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism","<span style=\"font-size: $1px; line-height: initial;\">$2</span>",$Text);
  768. $Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism","<span style=\"font-size: $1; line-height: initial;\">$2</span>",$Text);
  769. // Check for centered text
  770. $Text = preg_replace("(\[center\](.*?)\[\/center\])ism","<div style=\"text-align:center;\">$1</div>",$Text);
  771. // Check for list text
  772. $Text = str_replace("[*]", "<li>", $Text);
  773. // Check for style sheet commands
  774. $Text = preg_replace_callback("(\[style=(.*?)\](.*?)\[\/style\])ism","bb_cleanstyle",$Text);
  775. // Check for CSS classes
  776. $Text = preg_replace_callback("(\[class=(.*?)\](.*?)\[\/class\])ism","bb_cleanclass",$Text);
  777. // handle nested lists
  778. $endlessloop = 0;
  779. while ((((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false)) ||
  780. ((strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false)) ||
  781. ((strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false)) ||
  782. ((strpos($Text, "[/li]") !== false) && (strpos($Text, "[li]") !== false))) && (++$endlessloop < 20)) {
  783. $Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text);
  784. $Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>' ,$Text);
  785. $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text);
  786. $Text = preg_replace("/\[list=((?-i)i)\](.*?)\[\/list\]/ism",'<ul class="listlowerroman" style="list-style-type: lower-roman;">$2</ul>' ,$Text);
  787. $Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>' ,$Text);
  788. $Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>' ,$Text);
  789. $Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>' ,$Text);
  790. $Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text);
  791. $Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text);
  792. $Text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>' ,$Text);
  793. }
  794. $Text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>' ,$Text);
  795. $Text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>' ,$Text);
  796. $Text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>' ,$Text);
  797. $Text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '<table>$1</table>' ,$Text);
  798. $Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table border="1" >$1</table>' ,$Text);
  799. $Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table border="0" >$1</table>' ,$Text);
  800. $Text = str_replace('[hr]','<hr />', $Text);
  801. // This is actually executed in prepare_body()
  802. $Text = str_replace('[nosmile]','',$Text);
  803. // Check for font change text
  804. $Text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm","<span style=\"font-family: $1;\">$2</span>",$Text);
  805. // Declare the format for [code] layout
  806. // $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism",'stripcode_br_cb',$Text);
  807. $CodeLayout = '<code>$1</code>';
  808. // Check for [code] text
  809. $Text = preg_replace("/\[code\](.*?)\[\/code\]/ism","$CodeLayout", $Text);
  810. // Declare the format for [spoiler] layout
  811. $SpoilerLayout = '<blockquote class="spoiler">$1</blockquote>';
  812. // Check for [spoiler] text
  813. // handle nested quotes
  814. $endlessloop = 0;
  815. while ((strpos($Text, "[/spoiler]") !== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20))
  816. $Text = preg_replace("/\[spoiler\](.*?)\[\/spoiler\]/ism","$SpoilerLayout", $Text);
  817. // Check for [spoiler=Author] text
  818. $t_wrote = t('$1 wrote:');
  819. // handle nested quotes
  820. $endlessloop = 0;
  821. while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler=") !== false) and (++$endlessloop < 20))
  822. $Text = preg_replace("/\[spoiler=[\"\']*(.*?)[\"\']*\](.*?)\[\/spoiler\]/ism",
  823. "<br /><strong class=".'"spoiler"'.">" . $t_wrote . "</strong><blockquote class=".'"spoiler"'.">$2</blockquote>",
  824. $Text);
  825. // Declare the format for [quote] layout
  826. $QuoteLayout = '<blockquote>$1</blockquote>';
  827. // Check for [quote] text
  828. // handle nested quotes
  829. $endlessloop = 0;
  830. while ((strpos($Text, "[/quote]") !== false) and (strpos($Text, "[quote]") !== false) and (++$endlessloop < 20))
  831. $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism","$QuoteLayout", $Text);
  832. // Check for [quote=Author] text
  833. $t_wrote = t('$1 wrote:');
  834. // handle nested quotes
  835. $endlessloop = 0;
  836. while ((strpos($Text, "[/quote]")!== false) and (strpos($Text, "[quote=") !== false) and (++$endlessloop < 20))
  837. $Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism",
  838. "<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote>$2</blockquote>",
  839. $Text);
  840. // [img=widthxheight]image source[/img]
  841. //$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '<img src="$3" style="height: $2px; width: $1px;" >', $Text);
  842. $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '<img src="$3" style="width: $1px;" >', $Text);
  843. $Text = preg_replace("/\[zmg\=([0-9]*)x([0-9]*)\](.*?)\[\/zmg\]/ism", '<img class="zrl" src="$3" style="width: $1px;" >', $Text);
  844. // Images
  845. // [img]pathtoimage[/img]
  846. $Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img src="$1" alt="' . t('Image/photo') . '" />', $Text);
  847. $Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '<img src="$1" alt="' . t('Image/photo') . '" />', $Text);
  848. // Shared content
  849. $Text = preg_replace_callback("/(.*?)\[share(.*?)\](.*?)\[\/share\]/ism",
  850. function ($match) use ($simplehtml){
  851. return(bb_ShareAttributes($match, $simplehtml));
  852. },$Text);
  853. /*
  854. if (!$simplehtml)
  855. $Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism","bb_ShareAttributes",$Text);
  856. elseif ($simplehtml == 1)
  857. $Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism","bb_ShareAttributesSimple",$Text);
  858. elseif (($simplehtml == 2) OR ($simplehtml == 5))
  859. $Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism","bb_ShareAttributesSimple2",$Text);
  860. elseif ($simplehtml == 3)
  861. $Text = preg_replace_callback("/(.*?)\[share(.*?)\](.*?)\[\/share\]/ism","bb_ShareAttributesDiaspora",$Text);
  862. elseif ($simplehtml == 4)
  863. $Text = preg_replace_callback("/(.*?)\[share(.*?)\](.*?)\[\/share\]/ism","bb_ShareAttributesForExport",$Text);
  864. */
  865. $Text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br/><img src="' .$a->get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br />', $Text);
  866. $Text = preg_replace("/\[crypt(.*?)\](.*?)\[\/crypt\]/ism",'<br/><img src="' .$a->get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . '$1' . ' ' . t('Encrypted content') . '" /><br />', $Text);
  867. //$Text = preg_replace("/\[crypt=(.*?)\](.*?)\[\/crypt\]/ism",'<br/><img src="' .$a->get_baseurl() . '/images/lock_icon.gif" alt="' . t('Encrypted content') . '" title="' . '$1' . ' ' . t('Encrypted content') . '" /><br />', $Text);
  868. // Try to Oembed
  869. if ($tryoembed) {
  870. $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);
  871. $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);
  872. $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryoembed', $Text);
  873. $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryoembed', $Text);
  874. } else {
  875. $Text = preg_replace("/\[video\](.*?)\[\/video\]/",
  876. '<a href="$1" target="_blank">$1</a>', $Text);
  877. $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/",
  878. '<a href="$1" target="_blank">$1</a>', $Text);
  879. }
  880. // html5 video and audio
  881. if ($tryoembed)
  882. $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<iframe src="$1" width="' . $a->videowidth . '" height="' . $a->videoheight . '"><a href="$1">$1</a></iframe>', $Text);
  883. else
  884. $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1">$1</a>', $Text);
  885. // Youtube extensions
  886. if ($tryoembed) {
  887. $Text = preg_replace_callback("/\[youtube\](https?:\/\/www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
  888. $Text = preg_replace_callback("/\[youtube\](www.youtube.com\/watch\?v\=.*?)\[\/youtube\]/ism", 'tryoembed', $Text);
  889. $Text = preg_replace_callback("/\[youtube\](https?:\/\/youtu.be\/.*?)\[\/youtube\]/ism",'tryoembed',$Text);
  890. }
  891. $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text);
  892. $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text);
  893. $Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text);
  894. if ($tryoembed)
  895. $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="https://www.youtube.com/embed/$1" frameborder="0" ></iframe>', $Text);
  896. else
  897. $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism",
  898. '<a href="https://www.youtube.com/watch?v=$1" target="_blank">https://www.youtube.com/watch?v=$1</a>', $Text);
  899. if ($tryoembed) {
  900. $Text = preg_replace_callback("/\[vimeo\](https?:\/\/player.vimeo.com\/video\/[0-9]+).*?\[\/vimeo\]/ism",'tryoembed',$Text);
  901. $Text = preg_replace_callback("/\[vimeo\](https?:\/\/vimeo.com\/[0-9]+).*?\[\/vimeo\]/ism",'tryoembed',$Text);
  902. }
  903. $Text = preg_replace("/\[vimeo\]https?:\/\/player.vimeo.com\/video\/([0-9]+)(.*?)\[\/vimeo\]/ism",'[vimeo]$1[/vimeo]',$Text);
  904. $Text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism",'[vimeo]$1[/vimeo]',$Text);
  905. if ($tryoembed)
  906. $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="https://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $Text);
  907. else
  908. $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism",
  909. '<a href="https://vimeo.com/$1" target="_blank">https://vimeo.com/$1</a>', $Text);
  910. // $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);
  911. // oembed tag
  912. $Text = oembed_bbcode2html($Text);
  913. // Avoid triple linefeeds through oembed
  914. $Text = str_replace("<br style='clear:left'></span><br /><br />", "<br style='clear:left'></span><br />", $Text);
  915. // If we found an event earlier, strip out all the event code and replace with a reformatted version.
  916. // Replace the event-start section with the entire formatted event. The other bbcode is stripped.
  917. // Summary (e.g. title) is required, earlier revisions only required description (in addition to
  918. // start which is always required). Allow desc with a missing summary for compatibility.
  919. if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
  920. $sub = format_event_html($ev);
  921. $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text);
  922. $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text);
  923. $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text);
  924. $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text);
  925. $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text);
  926. $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text);
  927. }
  928. // Unhide all [noparse] contained bbtags unspacefying them
  929. // and triming the [noparse] tag.
  930. $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim',$Text);
  931. $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim',$Text);
  932. $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim',$Text);
  933. $Text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/','&$1;',$Text);
  934. $Text = preg_replace('/\&\#039\;/','\'',$Text);
  935. $Text = preg_replace('/\&quot\;/','"',$Text);
  936. // fix any escaped ampersands that may have been converted into links
  937. $Text = preg_replace("/\<([^>]*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism",'<$1$2=$3&$4>',$Text);
  938. $Text = preg_replace("/\<([^>]*?)(src|href)=\"(?!http|ftp|mailto|cid)(.*?)\>/ism",'<$1$2="">',$Text);
  939. if($saved_image)
  940. $Text = bb_replace_images($Text, $saved_image);
  941. // Clean up the HTML by loading and saving the HTML with the DOM
  942. // Only do it when it has to be done - for performance reasons
  943. // Update: Now it is done every time - since bad structured html can break a whole page
  944. //if (!$tryoembed) {
  945. // $doc = new DOMDocument();
  946. // $doc->preserveWhiteSpace = false;
  947. // $Text = mb_convert_encoding($Text, 'HTML-ENTITIES', "UTF-8");
  948. // $doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">';
  949. // @$doc->loadHTML($doctype."<html><body>".$Text."</body></html>");
  950. // $Text = $doc->saveHTML();
  951. // $Text = str_replace(array("<html><body>", "</body></html>", $doctype), array("", "", ""), $Text);
  952. // $Text = str_replace('<br></li>','</li>', $Text);
  953. // $Text = mb_convert_encoding($Text, "UTF-8", 'HTML-ENTITIES');
  954. //}
  955. // Clean up some useless linebreaks in lists
  956. //$Text = str_replace('<br /><ul','<ul ', $Text);
  957. //$Text = str_replace('</ul><br />','</ul>', $Text);
  958. //$Text = str_replace('</li><br />','</li>', $Text);
  959. //$Text = str_replace('<br /><li>','<li>', $Text);
  960. // $Text = str_replace('<br /><ul','<ul ', $Text);
  961. // Remove all hashtag addresses
  962. /* if (!$tryoembed AND get_config("system", "remove_hashtags_on_export")) {
  963. $pattern = '/#<a.*?href="(.*?)".*?>(.*?)<\/a>/is';
  964. $Text = preg_replace($pattern, '#$2', $Text);
  965. }
  966. */
  967. call_hooks('bbcode',$Text);
  968. $a->save_timestamp($stamp1, "parser");
  969. return $Text;
  970. }
  971. ?>