/** * Check and make safe embedded codes (removes mark-up HTML purify might have added) * @param array $matches */ protected function _postPurifyCodeBoxes($content) { /* Fetch paired opening and closing tags */ $data = $this->getTagPositions($content, 'CODE', array('[', ']')); if (is_array($data) && count($data)) { foreach ($data['open'] as $id => $val) { $o = $data['open'][$id]; $c = $data['close'][$id] - $o; $slice = substr($content, $o, $c); $_origLen = strlen($slice); $slice = IPSText::stripTags($slice, '<pre>,<br>'); $slice = str_replace("<br />", "\n", $slice); $slice = str_replace("\n", "<!-preserve.newline-->", $slice); $slice = preg_replace('#(https|http|ftp)://#', '\\1://', $slice); $content = substr_replace($content, $slice, $o, $c); $_newLen = strlen($slice); if ($_newLen != $_origLen) { /* Bump up next */ foreach ($data['open'] as $_id => $_val) { $_o = $data['open'][$_id]; /* Ascii face alert */ if ($_o > $o) { $data['open'][$_id] += $_newLen - $_origLen; $data['close'][$_id] += $_newLen - $_origLen; } } } } } return $content; }
/** * Check and make safe embedded codes * @param array $matches */ protected function _makeCodeTagContentSafeForSaving($content) { $parser = $this->_newParserObject(); /* Fetch paired opening and closing tags */ $data = $parser->getTagPositions($content, 'pre', array('<', '>')); if (is_array($data) && count($data)) { foreach ($data['open'] as $id => $val) { $o = $data['open'][$id]; $c = $data['close'][$id] - $o; $slice = substr($content, $o, $c); $_origLen = strlen($slice); $slice = str_replace('[', '[', $slice); $slice = preg_replace('/\\/(\\w+?)\\]/', '/\\1]', $slice); $slice = str_replace("{parse", "{parse", $slice); $slice = preg_replace('#(https|http|ftp)://#', '\\1-~~-//', $slice); /* Stop (r) (tm) and (c) from switching out */ $slice = preg_replace('#\\((tm|r|c)\\)#i', '($1)', $slice); $slice = IPSText::stripTags($slice, 'pre'); $_newLen = strlen($slice); if ($_newLen != $_origLen) { /* Bump up next */ foreach ($data['open'] as $_id => $_val) { $_o = $data['open'][$_id]; /* Ascii face alert */ if ($_o > $o) { $data['open'][$_id] += $_newLen - $_origLen; $data['close'][$_id] += $_newLen - $_origLen; } } } $content = substr_replace($content, $slice, $o, $c); } } return $content; }
/** * Check Multi Quote * Checks for quoted information * * @param string Any raw post * @return string Formatted post */ protected function _checkMultiQuote($postContent) { $raw_post = ''; if (!$this->request['qpid']) { $this->request['qpid'] = IPSCookie::get('mqtids'); if ($this->request['qpid'] == ",") { $this->request['qpid'] = ""; } } else { //----------------------------------------- // Came from reply button //----------------------------------------- $this->request['parent_id'] = $this->request['qpid']; } $this->request['qpid'] = preg_replace('/[^,\\d]/', "", trim($this->request['qpid'])); /* Load parser */ $classToLoad = IPSLib::loadLibrary(IPS_ROOT_PATH . 'sources/classes/text/parser.php', 'classes_text_parser'); $parser = new $classToLoad(); if ($this->request['qpid']) { $this->quoted_pids = preg_split('/,/', $this->request['qpid'], -1, PREG_SPLIT_NO_EMPTY); //----------------------------------------- // Get the posts from the DB and ensure we have // suitable read permissions to quote them //----------------------------------------- if (count($this->quoted_pids)) { $perm_id = $this->getAuthor('org_perm_id') ? $this->getAuthor('org_perm_id') : $this->getAuthor('g_perm_id'); $perm_array = explode(",", $perm_id); $this->DB->build(array('select' => 'p.*', 'from' => array('posts' => 'p'), 'where' => "p.pid IN(" . implode(',', $this->quoted_pids) . ")", 'add_join' => array(array('select' => 't.*', 'from' => array('topics' => 't'), 'where' => 't.tid=p.topic_id', 'type' => 'left'), array('select' => 'member_id, members_display_name', 'from' => array('members' => 'm'), 'where' => 'p.author_id=m.member_id', 'type' => 'left')))); $this->DB->execute(); while ($tp = $this->DB->fetch()) { $canSee = $this->registry->getClass('topics')->canView($tp); /* Direct quote/reply access */ if ($this->request['qpid'] && !$canSee) { $msg = str_replace('EX_', '', $this->registry->getClass('topics')->getErrorMessage()); $this->registry->output->showError($msg, 10340, null, null, 404); } if ($canSee === true && $this->registry->permissions->check('read', $this->registry->class_forums->forum_by_id[$tp['forum_id']], $perm_array) === true) { $tmp_post = $tp['post']; $tp['author_name'] = $tp['members_display_name'] ? $tp['members_display_name'] : $tp['author_name']; $tmp_post = $parser->stripSharedMedia($tmp_post); if ($this->settings['strip_quotes']) { $oldPost = $tmp_post; $tmp_post = $parser->stripQuotes($tmp_post); if (!preg_match('#\\S+?#', trim(IPSText::stripTags($tmp_post)))) { $tmp_post = $oldPost; } unset($oldPost); } if ($tmp_post) { $raw_post .= $parser->buildQuoteTag($tmp_post, $tp['author_name'], $tp['post_date'], 0, $tp['pid']); } } } $raw_post = trim($raw_post) . "<br />"; } } //----------------------------------------- // Make raw POST safe for the text area //----------------------------------------- $raw_post .= $postContent; return $raw_post; }
/** * Retrieve the member's location * * @author Brandon Farber * @param array Member information (including session info!) * @return array Member info with session info parsed * @since IPB 3.0 */ public static function getLocation($member) { $member['online_extra'] = ""; //----------------------------------------- // Grab 'where' info //----------------------------------------- if (!$member['in_error'] and $member['current_appcomponent'] and IPSLib::appIsInstalled($member['current_appcomponent'])) { $member['current_appcomponent'] = IPSText::alphanumericalClean($member['current_appcomponent']); $filename = IPSLib::getAppDir($member['current_appcomponent']) . '/extensions/coreExtensions.php'; if (is_file($filename)) { $toload = IPSLib::loadLibrary($filename, 'publicSessions__' . $member['current_appcomponent'], $member['current_appcomponent']); if (class_exists($toload)) { $loader = new $toload(); if (method_exists($loader, 'parseOnlineEntries')) { $tmp = $loader->parseOnlineEntries(array($member['id'] => $member)); // Yes, this is really id - it's session id, not member id if (isset($tmp[$member['id']]) && is_array($tmp[$member['id']]) && count($tmp[$member['id']])) { if (isset($tmp[$member['id']]['_whereLinkSeo'])) { $member['online_extra'] = "{$tmp[$member['id']]['where_line']} <a href='" . $tmp[$member['id']]['_whereLinkSeo'] . "' title='" . IPSText::stripTags($tmp[$member['id']]['where_line']) . ' ' . IPSText::stripTags($tmp[$member['id']]['where_line_more']) . "'>" . IPSText::truncate(IPSText::stripTags($tmp[$member['id']]['where_line_more']), 35) . "</a>"; } else { if (isset($tmp[$member['id']]['where_link']) and $tmp[$member['id']]['where_line_more']) { $member['online_extra'] = "{$tmp[$member['id']]['where_line']} <a href='" . ipsRegistry::$settings['base_url'] . "{$tmp[$member['id']]['where_link']}' title='" . IPSText::stripTags($tmp[$member['id']]['where_line']) . ' ' . IPSText::stripTags($tmp[$member['id']]['where_line_more']) . "'>" . IPSText::truncate(IPSText::stripTags($tmp[$member['id']]['where_line_more']), 35) . "</a>"; } else { if (isset($tmp[$member['id']]['where_link'])) { $member['online_extra'] = "<a href='" . ipsRegistry::$settings['base_url'] . "{$tmp[$member['id']]['where_link']}' title='" . IPSText::stripTags($tmp[$member['id']]['where_line']) . "'>" . IPSText::truncate(IPSText::stripTags($tmp[$member['id']]['where_line']), 35) . "</a>"; } else { $member['online_extra'] = $tmp[$member['id']]['where_line']; } } } } } } } } if (!$member['online_extra']) { $member['online_extra'] = $member['id'] ? ipsRegistry::getClass('class_localization')->words['board_index'] : ipsRegistry::getClass('class_localization')->words['not_online']; } return $member; }
/** * Fetches data to quote * * @return @e void */ protected function _quote() { /* Init */ $pid = intval($this->request['p']); $pids = explode(',', IPSText::cleanPermString($this->request['pids'])); $posts = array(); $_post = ''; /* Load editor stuff */ $classToLoad = IPSLib::loadLibrary(IPS_ROOT_PATH . 'sources/classes/editor/composite.php', 'classes_editor_composite'); $this->editor = new $classToLoad(); /* Set up topic */ if ($pid) { $posts[] = $this->registry->getClass('topics')->getPostById($pid); } else { foreach ($pids as $pid) { $posts[] = $this->registry->getClass('topics')->getPostById($pid); } } /* Permission ids */ $perm_id = $this->memberData['org_perm_id'] ? $this->memberData['org_perm_id'] : $this->memberData['g_perm_id']; $perm_array = explode(",", $perm_id); /* Load parser */ $classToLoad = IPSLib::loadLibrary(IPS_ROOT_PATH . 'sources/classes/text/parser.php', 'classes_text_parser'); $parser = new $classToLoad(); /* Naughty boy chex */ foreach ($posts as $post) { /* Set up data */ $this->registry->getClass('topics')->setTopicData($post); if ($this->registry->getClass('topics')->canView() !== true) { $this->returnJsonError('no_permission'); } if ($this->registry->permissions->check('read', $this->registry->class_forums->getForumById($post['forum_id']), $perm_array) !== TRUE) { $this->returnJsonError('no_permission'); } /* Post visible? */ if ($this->registry->getClass('class_forums')->fetchHiddenType($post) != 'visible') { $this->returnJsonError('no_permission'); } /* Phew that was a toughy wasn't it? */ if ($this->settings['strip_quotes']) { $oldPost = $post['post']; $post['post'] = $parser->stripQuotes($post['post']); if (!preg_match('#\\S+?#', trim(IPSText::stripTags($post['post'], '<img>')))) { $post['post'] = $oldPost; } unset($oldPost); } /* Strip shared media in quotes */ $post['post'] = $parser->stripSharedMedia($post['post']); /* We don't use makeQuoteSafe() here because the result is returned via AJAX and inserted as text into the editor. + shows as + as a result if we do */ $_quoted = rtrim($post['post']); $_name = $post['members_display_name'] ? $post['members_display_name'] : $post['author_name']; $_post .= $parser->buildQuoteTag($_quoted, $_name, $post['post_date'], 0, $post['pid']); } $this->editor->setContent($_post, 'topics'); $this->returnHtml($this->editor->getContent()); }
/** * Code to pre */ public function codeToPre($editor, $tagName) { $data = $this->getTagPositions($editor, $tagName, array('[', ']')); if (is_array($data['open'])) { foreach ($data['openWithTag'] as $id => $val) { $o = $data['openWithTag'][$id]; $c = $data['closeWithTag'][$id] - $o; if ($c < 1) { continue; } $slice = substr($editor, $o, $c); $openTag = substr($editor, $o, $data['open'][$id] - $o); $closeTag = substr($editor, $data['close'][$id], strlen($tagName) + 3); $_openTagLen = strlen($openTag); $_closeTagLen = strlen($closeTag); list($tag, $rawAttr) = explode('=', $openTag); list($lang, $lineNum) = explode(':', str_replace(array('[', ']'), '', $rawAttr)); // Fix lang if using XML tag if (!$lang && $tagName != 'code') { $lang = $tagName; } // Need to bump up lengths of opening and closing $_origLength = strlen($slice); $sliceContents = substr($editor, $data['open'][$id], $data['close'][$id] - $data['open'][$id]); /* Extra conversion for BBCODE>HTML mode */ $replacement = $sliceContents; $replacement = str_replace(array("\r\n", "\r"), "\n", $replacement); $replacement = preg_replace('#(https|http|ftp)://#', '\\1-~~-//', $replacement); $replacement = str_replace('[', '[', $replacement); $replacement = preg_replace("#<br([^>]+?)?>(\n)?#i", "\n", $replacement); $replacement = trim(str_replace("</p>\n", "\n", $replacement)); /* Stop (r) (tm) and (c) from switching out */ $replacement = preg_replace('#\\((tm|r|c)\\)#i', '($1)', $replacement); $replacement = IPSText::stripTags($replacement, 'pre'); $slice = str_replace($sliceContents, $replacement, $slice); /* add in class attributes */ $classExtra .= '_linenums:' . intval(trim($lineNum)); if ($lang) { $classExtra .= ' _lang-' . trim(htmlspecialchars($lang)); } /* Convert tags */ $_newOpenTag = "<pre class=\"_prettyXprint " . $classExtra . "\">"; $_newCloseTag = "</pre>"; $slice = str_replace($openTag, $_newOpenTag, $slice); $slice = str_replace($closeTag, $_newCloseTag, $slice); $editor = substr_replace($editor, $slice, $o, $c); break; } } /* Recursively parse quotes */ if (count($data['open']) > 1 and count($data['close']) > 1) { $editor = $this->codeToPre($editor, $tagName); } $editor = preg_replace('#<p([^>]+?)?' . '>(( |\\s)+?)?</p>(\\s+?)?<pre#i', '<pre', $editor); $editor = preg_replace('#</pre>(\\s+?)?<p([^>]+?)?' . '>(( |\\s)+?)?</p>#i', '</pre>', $editor); return $editor; }
/** * Cleans an email message * * @param string Email content * @param bool Skip converting < and > * @param bool Fix up plain text links * @return string Cleaned email content */ public function cleanMessage($message = "", $skipAngleBrackets = false, $fixPlainTextLinks = true) { if (!$this->html_email) { $message = preg_replace_callback('#\\[url=(.+?)\\](.+?)\\[/url\\]#', array($this, "_formatUrl"), $message); } //----------------------------------------- // Unconvert smilies 'cos at this point they are img tags //----------------------------------------- $message = IPSText::unconvertSmilies($message); //----------------------------------------- // We may want to adjust this later, but for // now just strip any other html //----------------------------------------- $message = preg_replace('#</p>(\\s+?)?<p([^>]+?)?>#is', '<br />', $message); /* We need to fix links in plaintext templates so people don't get "http://some..ing" instead of "http://something" */ if ($fixPlainTextLinks) { $message = $this->fixPlaintextLinks($message); } $message = IPSText::stripTags($message, '<br>,<blockquote>'); IPSText::getTextClass('bbcode')->parse_html = 0; IPSText::getTextClass('bbcode')->parse_nl2br = 1; IPSText::getTextClass('bbcode')->parse_bbcode = 0; /* Textual representations of certain bbcodes to attempt to keep context */ $plainText = '<br /><br />------------ QUOTE ----------<br />\\1<br />-----------------------------<br /><br />'; $message = preg_replace('#\\[quote(?:[^\\]]+?)?\\](.+?)\\[/quote\\]#s', $plainText, $message); $message = preg_replace('#<blockquote(?:[^>]+?)?>(.+?)</blockquote>#s', $plainText, $message); $plainTextCode = '*CODE* \\1 */CODE*'; $message = preg_replace('#\\[code(?:[^\\]]+?)?\\](.+?)\\[/code\\]#s', $plainTextCode, $message); $message = preg_replace('#\\[member=(.+?)\\]#s', "\\1", $message); $message = IPSText::getTextClass('bbcode')->stripAllTags($message, true); //----------------------------------------- // Bear with me... //----------------------------------------- $message = str_replace("\n", "\r\n", $message); $message = str_replace("\r", "", $message); $message = str_replace("<br>", "\r\n", $message); $message = str_replace("<br />", "\r\n", $message); $message = str_replace("\r\n\r\n", "\r\n", $message); $message = str_replace(""", '"', $message); $message = str_replace("\", "\\", $message); $message = str_replace("$", "\$", $message); $message = str_replace("!", "!", $message); $message = str_replace(""", '"', $message); $message = str_replace("'", "'", $message); $message = str_replace("(", "(", $message); $message = str_replace(")", ")", $message); $message = str_replace("<", "<", $message); $message = str_replace(">", ">", $message); $message = str_replace("|", '|', $message); $message = str_replace("&", "&", $message); $message = str_replace("&", '&', $message); $message = str_replace(":", ":", $message); $message = str_replace("[", "[", $message); $message = str_replace("]", "]", $message); $message = str_replace("@", '@', $message); $message = str_replace(" ", ' ', $message); if (!$skipAngleBrackets) { $message = str_replace("<", '<', $message); $message = str_replace(">", '>', $message); } return $message; }