private function translatePost($post, $threadsPage = false) { $apiPost = array(); $fields = $threadsPage ? $this->threadsPageFields : $this->postFields; $this->translateFields($fields, $post, $apiPost); if ($threadsPage) { return $apiPost; } // Handle country field if (isset($post->body_nomarkup) && $this->config['country_flags']) { $modifiers = extract_modifiers($post->body_nomarkup); if (isset($modifiers['flag']) && isset($modifiers['flag alt']) && preg_match('/^[a-z]{2}$/', $modifiers['flag'])) { $country = strtoupper($modifiers['flag']); if ($country) { $apiPost['country'] = $country; $apiPost['country_name'] = $modifiers['flag alt']; } } } // Handle files // Note: 4chan only supports one file, so only the first file is taken into account for 4chan-compatible API. if (isset($post->files) && $post->files && !$threadsPage) { $file = $post->files[0]; $this->translateFields($this->fileFields, $file, $apiPost); $dotPos = strrpos($file->file, '.'); $apiPost['filename'] = substr($file->file, 0, $dotPos); $apiPost['ext'] = substr($file->file, $dotPos); $dotPos = strrpos($file->file, '.'); $apiPost['tim'] = substr($file->file, 0, $dotPos); } return $apiPost; }
private function translatePost($post) { $apiPost = array(); foreach ($this->postFields as $local => $translated) { if (!isset($post->{$local})) { continue; } $toInt = isset(self::$ints[$translated]); $val = $post->{$local}; if ($val !== null && $val !== '') { $apiPost[$translated] = $toInt ? (int) $val : $val; } } if (isset($post->filename)) { $dotPos = strrpos($post->filename, '.'); $apiPost['filename'] = substr($post->filename, 0, $dotPos); $apiPost['ext'] = substr($post->filename, $dotPos); } // Handle country field if (isset($post->body_nomarkup) && $this->config['country_flags']) { $modifiers = extract_modifiers($post->body_nomarkup); if (isset($modifiers['flag']) && isset($modifiers['flag alt']) && preg_match('/^[a-z]{2}$/', $modifiers['flag'])) { $country = strtoupper($modifiers['flag']); if ($country) { $apiPost['country'] = $country; $apiPost['country_name'] = $modifiers['flag alt']; } } } return $apiPost; }
private function translatePost($post, $threadsPage = false) { global $config, $board; $apiPost = array(); $fields = $threadsPage ? $this->threadsPageFields : $this->postFields; $this->translateFields($fields, $post, $apiPost); if (isset($config['poster_ids']) && $config['poster_ids']) { $apiPost['id'] = poster_id($post->ip, $post->thread, $board['uri']); } if ($threadsPage) { return $apiPost; } // Handle country field if (isset($post->body_nomarkup) && $this->config['country_flags']) { $modifiers = extract_modifiers($post->body_nomarkup); if (isset($modifiers['flag']) && isset($modifiers['flag alt']) && preg_match('/^[a-z]{2}$/', $modifiers['flag'])) { $country = strtoupper($modifiers['flag']); if ($country) { $apiPost['country'] = $country; $apiPost['country_name'] = $modifiers['flag alt']; } } } if ($config['slugify'] && !$post->thread) { $apiPost['semantic_url'] = $post->slug; } // Handle files // Note: 4chan only supports one file, so only the first file is taken into account for 4chan-compatible API. if (isset($post->files) && $post->files && !$threadsPage) { $file = $post->files[0]; $this->translateFile($file, $post, $apiPost); if (sizeof($post->files) > 1) { $extra_files = array(); foreach ($post->files as $i => $f) { if ($i == 0) { continue; } $extra_file = array(); $this->translateFile($f, $post, $extra_file); $extra_files[] = $extra_file; } $apiPost['extra_files'] = $extra_files; } } return $apiPost; }
private function translatePost($post, $threadsPage = false) { global $config, $board; $apiPost = array(); $fields = $threadsPage ? $this->threadsPageFields : $this->postFields; $this->translateFields($fields, $post, $apiPost); if ($this->config['poster_ids']) { if ($post->thread) { $apiPost['id'] = poster_id($post->ip, $post->thread, $board['uri']); } else { $apiPost['id'] = poster_id($post->ip, $post->id, $board['uri']); } } if ($threadsPage) { return $apiPost; } // Handle country field if (isset($post->body_nomarkup) && $this->config['country_flags']) { $modifiers = extract_modifiers($post->body_nomarkup); if (isset($modifiers['flag']) && isset($modifiers['flag alt']) && preg_match('/^[a-z]{2}$/', $modifiers['flag'])) { $country = strtoupper($modifiers['flag']); if ($country) { $apiPost['country'] = $country; $apiPost['country_name'] = $modifiers['flag alt']; } } } // Handle files if (isset($post->files) && $post->files && !$threadsPage) { $file = $post->files[0]; $this->translateFile($file, $apiPost); if (sizeof($post->files) > 1) { $extra_files = array(); foreach ($post->files as $i => $f) { if ($i == 0) { continue; } $extra_file = array(); $this->translateFile($f, $extra_file); $extra_files[] = $extra_file; } $apiPost['extra_files'] = $extra_files; } } return $apiPost; }
function markup(&$body, $track_cites = false, $op = false) { global $board, $config, $markup_urls; $modifiers = extract_modifiers($body); $body = preg_replace('@<tinyboard (?!escape )([\\w\\s]+)>(.+?)</tinyboard>@us', '', $body); $body = preg_replace('@<(tinyboard) escape ([\\w\\s]+)>@i', '<$1 $2>', $body); if (isset($modifiers['raw html']) && $modifiers['raw html'] == '1') { return array(); } $body = str_replace("\r", '', $body); $body = utf8tohtml($body); if (mysql_version() < 50503) { $body = mb_encode_numericentity($body, array(0x10000, 0xffffff, 0, 0xffffff), 'UTF-8'); } foreach ($config['markup'] as $markup) { if (is_string($markup[1])) { $body = preg_replace($markup[0], $markup[1], $body); } elseif (is_callable($markup[1])) { $body = preg_replace_callback($markup[0], $markup[1], $body); } } if ($config['markup_urls']) { $markup_urls = array(); $body = preg_replace_callback('/((?:https?:\\/\\/|ftp:\\/\\/|irc:\\/\\/)[^\\s<>()"]+?(?:\\([^\\s<>()"]*?\\)[^\\s<>()"]*?)*)((?:\\s|<|>|"|\\.||\\]|!|\\?|,|,|")*(?:[\\s<>()"]|$))/', 'markup_url', $body, -1, $num_links); if ($num_links > $config['max_links']) { error($config['error']['toomanylinks']); } if ($num_links < $config['min_links'] && $op) { error(sprintf($config['error']['notenoughlinks'], $config['min_links'])); } } if ($config['markup_repair_tidy']) { $body = str_replace(' ', ' ', $body); } if ($config['auto_unicode']) { $body = unicodify($body); if ($config['markup_urls']) { foreach ($markup_urls as &$url) { $body = str_replace(unicodify($url), $url, $body); } } } $tracked_cites = array(); // Cites if (isset($board) && preg_match_all('/(^|\\s)>>(\\d+?)([\\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycites']); } $skip_chars = 0; $body_tmp = $body; $search_cites = array(); foreach ($cites as $matches) { $search_cites[] = '`id` = ' . $matches[2][0]; } $search_cites = array_unique($search_cites); $query = query(sprintf('SELECT `thread`, `id` FROM ``posts_%s`` WHERE ' . implode(' OR ', $search_cites), $board['uri'])) or error(db_error()); $cited_posts = array(); while ($cited = $query->fetch(PDO::FETCH_ASSOC)) { $cited_posts[$cited['id']] = $cited['thread'] ? $cited['thread'] : false; } foreach ($cites as $matches) { $cite = $matches[2][0]; // preg_match_all is not multibyte-safe foreach ($matches as &$match) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } if (isset($cited_posts[$cite])) { $replacement = '<a onclick="highlightReply(\'' . $cite . '\', event);" href="' . $config['root'] . $board['dir'] . $config['dir']['res'] . ($cited_posts[$cite] ? $cited_posts[$cite] : $cite) . '.html#' . $cite . '">' . '>>' . $cite . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[3][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[3][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($board['uri'], $cite); } } } } // Cross-board linking if (preg_match_all('/(^|\\s)>>>\\/(' . $config['board_regex'] . 'f?)\\/(\\d+)?([\\s,.)?]|$)/um', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycross']); } $skip_chars = 0; $body_tmp = $body; if (isset($cited_posts)) { // Carry found posts from local board >>X links foreach ($cited_posts as $cite => $thread) { $cited_posts[$cite] = $config['root'] . $board['dir'] . $config['dir']['res'] . ($thread ? $thread : $cite) . '.html#' . $cite; } $cited_posts = array($board['uri'] => $cited_posts); } else { $cited_posts = array(); } $crossboard_indexes = array(); $search_cites_boards = array(); foreach ($cites as $matches) { $_board = $matches[2][0]; $cite = @$matches[3][0]; if (!isset($search_cites_boards[$_board])) { $search_cites_boards[$_board] = array(); } $search_cites_boards[$_board][] = $cite; } $tmp_board = $board['uri']; foreach ($search_cites_boards as $_board => $search_cites) { $clauses = array(); foreach ($search_cites as $cite) { if (!$cite || isset($cited_posts[$_board][$cite])) { continue; } $clauses[] = '`id` = ' . $cite; } $clauses = array_unique($clauses); if ($board['uri'] != $_board) { if (!openBoard($_board)) { continue; } // Unknown board } if (!empty($clauses)) { $cited_posts[$_board] = array(); $query = query(sprintf('SELECT `thread`, `id` FROM ``posts_%s`` WHERE ' . implode(' OR ', $clauses), $board['uri'])) or error(db_error()); while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { $cited_posts[$_board][$cite['id']] = $config['root'] . $board['dir'] . $config['dir']['res'] . ($cite['thread'] ? $cite['thread'] : $cite['id']) . '.html#' . $cite['id']; } } $crossboard_indexes[$_board] = $config['root'] . $board['dir'] . $config['file_index']; } // Restore old board if (!$tmp_board) { unset($GLOBALS['board']); } elseif ($board['uri'] != $tmp_board) { openBoard($tmp_board); } foreach ($cites as $matches) { $_board = $matches[2][0]; $cite = @$matches[3][0]; // preg_match_all is not multibyte-safe foreach ($matches as &$match) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } if ($cite) { if (isset($cited_posts[$_board][$cite])) { $link = $cited_posts[$_board][$cite]; $replacement = '<a ' . ($_board == $board['uri'] ? 'onclick="highlightReply(\'' . $cite . '\', event);" ' : '') . 'href="' . $link . '">' . '>>>/' . $_board . '/' . $cite . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($_board, $cite); } } } elseif (isset($crossboard_indexes[$_board])) { $replacement = '<a href="' . $crossboard_indexes[$_board] . '">' . '>>>/' . $_board . '/' . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); } } } $tracked_cites = array_unique($tracked_cites, SORT_REGULAR); if ($config['strip_superfluous_returns']) { $body = preg_replace('/\\s+$/', '', $body); } if ($config['markup_paragraphs']) { $paragraphs = explode("\n", $body); $bodyNew = ""; $tagsOpen = false; // Matches <a>, <a href="" title="">, but not <img/> and returns a $matchOpen = "#<([A-Z][A-Z0-9]*)+(?:(?:\\s+\\w+(?:\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)>#i"; // Matches </a> returns a $matchClose = "#</([A-Z][A-Z0-9]*/?)>#i"; $tagsOpened = array(); $tagsClosed = array(); foreach ($paragraphs as $paragraph) { // Determine if RTL based on content of line. if (strlen(trim($paragraph)) > 0) { $paragraphDirection = is_rtl($paragraph) ? "rtl" : "ltr"; } else { $paragraphDirection = "empty"; } // Add in a quote class for >quotes. if (strpos($paragraph, ">") === 0) { $quoteClass = "quote"; } else { $quoteClass = ""; } // If tags are closed, start a new line. if ($tagsOpen === false) { $bodyNew .= "<p class=\"body-line {$paragraphDirection} {$quoteClass}\">"; } // If tags are open, add the paragraph to our temporary holder instead. if ($tagsOpen !== false) { $tagsOpen .= $paragraph; // Recheck tags to see if we've formed a complete tag with this latest line. if (preg_match_all($matchOpen, $tagsOpen, $tagsOpened) === preg_match_all($matchClose, $tagsOpen, $tagsClosed)) { sort($tagsOpened[1]); sort($tagsClosed[1]); // Double-check to make sure these are the same tags. if (count(array_diff_assoc($tagsOpened[1], $tagsClosed[1])) === 0) { // Tags are closed! \o/ $bodyNew .= $tagsOpen; $tagsOpen = false; } } } else { if (preg_match_all($matchOpen, $paragraph, $tagsOpened) === preg_match_all($matchClose, $paragraph, $tagsClosed)) { sort($tagsOpened[1]); sort($tagsClosed[1]); // Double-check to make sure these are the same tags. if (count(array_diff_assoc($tagsOpened[1], $tagsClosed[1])) === 0) { $bodyNew .= $paragraph; } } else { // Tags are open! $tagsOpen = $paragraph; } } // If tags are open, do not close it. if (!$tagsOpen) { $bodyNew .= "</p>"; } else { if ($tagsOpen !== false) { $tagsOpen .= "<br />"; } } } if ($tagsOpen !== false) { $bodyNew .= $tagsOpen; } $body = $bodyNew; } else { $body = preg_replace("/^\\s*>.*\$/m", '<span class="quote">$0</span>', $body); $body = preg_replace("/\n/", '<br/>', $body); } if ($config['markup_repair_tidy']) { $tidy = new tidy(); $body = str_replace("\t", '	', $body); $body = $tidy->repairString($body, array('doctype' => 'omit', 'bare' => true, 'literal-attributes' => true, 'indent' => false, 'show-body-only' => true, 'wrap' => 0, 'output-bom' => false, 'output-html' => true, 'newline' => 'LF', 'quiet' => true), 'utf8'); $body = str_replace("\n", '', $body); } // replace tabs with 8 spaces $body = str_replace("\t", '	', $body); return $tracked_cites; }
function markup(&$body, $track_cites = false) { global $board, $config, $markup_urls; $modifiers = extract_modifiers($body); $body = preg_replace('@<tinyboard (?!escape )([\\w\\s]+)>(.+?)</tinyboard>@us', '', $body); $body = preg_replace('@<(tinyboard) escape ([\\w\\s]+)>@i', '<$1 $2>', $body); if (isset($modifiers['raw html']) && $modifiers['raw html'] == '1') { return array(); } $body = str_replace("\r", '', $body); $body = utf8tohtml($body); if (mysql_version() < 50503) { $body = mb_encode_numericentity($body, array(0x10000, 0xffffff, 0, 0xffffff), 'UTF-8'); } if ($config['markup_code']) { $code_markup = array(); $body = preg_replace_callback($config['markup_code'], function ($matches) use(&$code_markup) { $d = count($code_markup); $code_markup[] = $matches; return "<code {$d}>"; }, $body); } foreach ($config['markup'] as $markup) { if (is_string($markup[1])) { $body = preg_replace($markup[0], $markup[1], $body); } elseif (is_callable($markup[1])) { $body = preg_replace_callback($markup[0], $markup[1], $body); } } if ($config['markup_urls']) { $markup_urls = array(); $body = preg_replace_callback('/((?:https?:\\/\\/|ftp:\\/\\/|irc:\\/\\/)[^\\s<>()"]+?(?:\\([^\\s<>()"]*?\\)[^\\s<>()"]*?)*)((?:\\s|<|>|"|\\.||\\]|!|\\?|,|,|")*(?:[\\s<>()"]|$))/', 'markup_url', $body, -1, $num_links); if ($num_links > $config['max_links']) { error($config['error']['toomanylinks']); } } if ($config['markup_repair_tidy']) { $body = str_replace(' ', ' ', $body); } if ($config['auto_unicode']) { $body = unicodify($body); if ($config['markup_urls']) { foreach ($markup_urls as &$url) { $body = str_replace(unicodify($url), $url, $body); } } } $tracked_cites = array(); // Cites if (isset($board) && preg_match_all('/(^|\\s)>>(\\d+?)([\\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycites']); } $skip_chars = 0; $body_tmp = $body; $search_cites = array(); foreach ($cites as $matches) { $search_cites[] = '`id` = ' . $matches[2][0]; } $search_cites = array_unique($search_cites); $query = query(sprintf('SELECT `thread`, `id` FROM ``posts_%s`` WHERE ' . implode(' OR ', $search_cites), $board['uri'])) or error(db_error()); $cited_posts = array(); while ($cited = $query->fetch(PDO::FETCH_ASSOC)) { $cited_posts[$cited['id']] = $cited['thread'] ? $cited['thread'] : false; } foreach ($cites as $matches) { $cite = $matches[2][0]; // preg_match_all is not multibyte-safe foreach ($matches as &$match) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } if (isset($cited_posts[$cite])) { $replacement = '<a onclick="highlightReply(\'' . $cite . '\');" href="' . $config['root'] . $board['dir'] . $config['dir']['res'] . link_for(array('id' => $cite, 'thread' => $cited_posts[$cite])) . '#' . $cite . '">' . '>>' . $cite . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[3][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[3][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($board['uri'], $cite); } } } } // Cross-board linking if (preg_match_all('/(^|\\s)>>>\\/(' . $config['board_regex'] . 'f?)\\/(\\d+)?([\\s,.)?]|$)/um', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycross']); } $skip_chars = 0; $body_tmp = $body; if (isset($cited_posts)) { // Carry found posts from local board >>X links foreach ($cited_posts as $cite => $thread) { $cited_posts[$cite] = $config['root'] . $board['dir'] . $config['dir']['res'] . ($thread ? $thread : $cite) . '.html#' . $cite; } $cited_posts = array($board['uri'] => $cited_posts); } else { $cited_posts = array(); } $crossboard_indexes = array(); $search_cites_boards = array(); foreach ($cites as $matches) { $_board = $matches[2][0]; $cite = @$matches[3][0]; if (!isset($search_cites_boards[$_board])) { $search_cites_boards[$_board] = array(); } $search_cites_boards[$_board][] = $cite; } $tmp_board = $board['uri']; foreach ($search_cites_boards as $_board => $search_cites) { $clauses = array(); foreach ($search_cites as $cite) { if (!$cite || isset($cited_posts[$_board][$cite])) { continue; } $clauses[] = '`id` = ' . $cite; } $clauses = array_unique($clauses); if ($board['uri'] != $_board) { if (!openBoard($_board)) { continue; } // Unknown board } if (!empty($clauses)) { $cited_posts[$_board] = array(); $query = query(sprintf('SELECT `thread`, `id`, `slug` FROM ``posts_%s`` WHERE ' . implode(' OR ', $clauses), $board['uri'])) or error(db_error()); while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { $cited_posts[$_board][$cite['id']] = $config['root'] . $board['dir'] . $config['dir']['res'] . link_for($cite) . '#' . $cite['id']; } } $crossboard_indexes[$_board] = $config['root'] . $board['dir'] . $config['file_index']; } // Restore old board if ($board['uri'] != $tmp_board) { openBoard($tmp_board); } foreach ($cites as $matches) { $_board = $matches[2][0]; $cite = @$matches[3][0]; // preg_match_all is not multibyte-safe foreach ($matches as &$match) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } if ($cite) { if (isset($cited_posts[$_board][$cite])) { $link = $cited_posts[$_board][$cite]; $replacement = '<a ' . ($_board == $board['uri'] ? 'onclick="highlightReply(\'' . $cite . '\');" ' : '') . 'href="' . $link . '">' . '>>>/' . $_board . '/' . $cite . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($_board, $cite); } } } elseif (isset($crossboard_indexes[$_board])) { $replacement = '<a href="' . $crossboard_indexes[$_board] . '">' . '>>>/' . $_board . '/' . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); } } } $tracked_cites = array_unique($tracked_cites, SORT_REGULAR); $body = preg_replace("/^\\s*>.*\$/m", '<span class="quote">$0</span>', $body); if ($config['strip_superfluous_returns']) { $body = preg_replace('/\\s+$/', '', $body); } $body = preg_replace("/\n/", '<br/>', $body); // Fix code markup if ($config['markup_code']) { foreach ($code_markup as $id => $val) { $code = isset($val[2]) ? $val[2] : $val[1]; $code_lang = isset($val[2]) ? $val[1] : ""; $code = "<pre class='code lang-{$code_lang}'>" . str_replace(array("\n", "\t"), array(" ", "	"), htmlspecialchars($code)) . "</pre>"; $body = str_replace("<code {$id}>", $code, $body); } } if ($config['markup_repair_tidy']) { $tidy = new tidy(); $body = str_replace("\t", '	', $body); $body = $tidy->repairString($body, array('doctype' => 'omit', 'bare' => true, 'literal-attributes' => true, 'indent' => false, 'show-body-only' => true, 'wrap' => 0, 'output-bom' => false, 'output-html' => true, 'newline' => 'LF', 'quiet' => true), 'utf8'); $body = str_replace("\n", '', $body); } // replace tabs with 8 spaces $body = str_replace("\t", ' ', $body); return $tracked_cites; }
public function __construct($post, $root = null, $mod = false, $hr = true) { global $config; if (!isset($root)) { $root =& $config['root']; } foreach ($post as $key => $value) { $this->{$key} = $value; } $this->subject = utf8tohtml($this->subject); $this->name = utf8tohtml($this->name); $this->mod = $mod; $this->root = $root; $this->hr = $hr; $this->posts = array(); $this->omitted = 0; $this->omitted_images = 0; if ($this->embed) { $this->embed = embed_html($this->embed); } $this->modifiers = extract_modifiers($this->body_nomarkup); if ($config['always_regenerate_markup']) { $this->body = $this->body_nomarkup; markup($this->body); } if ($this->mod) { // Fix internal links // Very complicated regex $this->body = preg_replace('/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\\s)*)href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), $config['board_regex']) . ')/u', '<a $1href="?/$4', $this->body); } }
function mod_edit_post($board, $edit_raw_html, $postID) { global $config, $mod; if (!openBoard($board)) { error($config['error']['noboard']); } if (!hasPermission($config['mod']['editpost'], $board)) { error($config['error']['noaccess']); } if ($edit_raw_html && !hasPermission($config['mod']['rawhtml'], $board)) { error($config['error']['noaccess']); } $security_token = make_secure_link_token($board . '/edit' . ($edit_raw_html ? '_raw' : '') . '/' . $postID); $query = prepare(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = :id', $board)); $query->bindValue(':id', $postID); $query->execute() or error(db_error($query)); if (!($post = $query->fetch(PDO::FETCH_ASSOC))) { error($config['error']['404']); } if (isset($_POST['name'], $_POST['email'], $_POST['subject'], $_POST['body'])) { $trip = isset($_POST['remove_trip']) ? ' `trip` = NULL,' : ''; // Remove any modifiers they may have put in $_POST['body'] = remove_modifiers($_POST['body']); // Add back modifiers in the original post $modifiers = extract_modifiers($post['body_nomarkup']); foreach ($modifiers as $key => $value) { $_POST['body'] .= "<tinyboard {$key}>{$value}</tinyboard>"; } // Handle embed edits... foreach ($config['embedding'] as &$embed) { if (preg_match($embed[0], $_POST['embed'])) { $embed_link = $_POST['embed']; } } if ($edit_raw_html) { $query = prepare(sprintf('UPDATE ``posts_%s`` SET `name` = :name,' . $trip . ' `email` = :email, `subject` = :subject, `body` = :body, `body_nomarkup` = :body_nomarkup, `embed` = :embed `edited_at` = UNIX_TIMESTAMP(NOW()) WHERE `id` = :id', $board)); } else { $query = prepare(sprintf('UPDATE ``posts_%s`` SET `name` = :name,' . $trip . ' `email` = :email, `subject` = :subject, `body_nomarkup` = :body, `embed` = :embed, `edited_at` = UNIX_TIMESTAMP(NOW()) WHERE `id` = :id', $board)); } $query->bindValue(':id', $postID); $query->bindValue(':name', $_POST['name'] ? $_POST['name'] : $config['anonymous']); $query->bindValue(':email', $_POST['email']); $query->bindValue(':subject', $_POST['subject']); $query->bindValue(':body', $_POST['body']); if ($edit_raw_html) { $body_nomarkup = $_POST['body'] . "\n<tinyboard raw html>1</tinyboard>"; $query->bindValue(':body_nomarkup', $body_nomarkup); } if (isset($embed_link)) { $query->bindValue(':embed', $embed_link); } else { $query->bindValue(':embed', NULL, PDO::PARAM_NULL); } $query->execute() or error(db_error($query)); if ($config['clean']['edits_remove_local'] || $config['clean']['edits_remove_global']) { $query_global = "`clean_global` = :clean"; $query_global_mod = "`clean_global_mod_id` = :mod"; $query_local = "`clean_local` = :clean"; $query_local_mod = "`clean_local_mod_id` = :mod"; if ($config['clean']['edits_remove_local'] && $config['clean']['edits_remove_global']) { $query = prepare("UPDATE `post_clean` SET {$query_global}, {$query_global_mod}, {$query_local}, {$query_local_mod} WHERE `board_id` = :board AND `post_id` = :post"); } else { if ($config['clean']['edits_remove_global']) { $query = prepare("UPDATE `post_clean` SET {$query_global}, {$query_global_mod} WHERE `board_id` = :board AND `post_id` = :post"); } else { $query = prepare("UPDATE `post_clean` SET {$query_local}, {$query_local_mod} WHERE `board_id` = :board AND `post_id` = :post"); } } $query->bindValue(':clean', false); $query->bindValue(':mod', NULL); $query->bindValue(':board', $board); $query->bindValue(':post', $postID); $query->execute() or error(db_error($query)); // Finally, run a query to tidy up our records. $cleanup = prepare("DELETE FROM `post_clean` WHERE `clean_local` = FALSE AND `clean_global` = FALSE"); $query->execute() or error(db_error($query)); } if ($edit_raw_html) { modLog("Edited raw HTML of post #{$postID}"); } else { modLog("Edited post #{$postID}"); rebuildPost($postID); } buildIndex(); rebuildThemes('post', $board); header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $postID) . '#' . $postID, true, $config['redirect_http']); } else { // Remove modifiers $post['body_nomarkup'] = remove_modifiers($post['body_nomarkup']); $post['body_nomarkup'] = utf8tohtml($post['body_nomarkup']); $post['body'] = utf8tohtml($post['body']); if ($config['minify_html']) { $post['body_nomarkup'] = str_replace("\n", '
', $post['body_nomarkup']); $post['body'] = str_replace("\n", '
', $post['body']); $post['body_nomarkup'] = str_replace("\r", '', $post['body_nomarkup']); $post['body'] = str_replace("\r", '', $post['body']); $post['body_nomarkup'] = str_replace("\t", '	', $post['body_nomarkup']); $post['body'] = str_replace("\t", '	', $post['body']); } $preview = new Post($post); $html = $preview->build(true); mod_page(_('Edit post'), 'mod/edit_post_form.html', array('token' => $security_token, 'board' => $board, 'raw' => $edit_raw_html, 'post' => $post, 'preview' => $html)); } }