/** * Returns possible matches for the string input * * @access private * @return void Outputs to screen */ private function _getMemberNames() { //----------------------------------------- // INIT //----------------------------------------- $name = $this->convertAndMakeSafe(ipsRegistry::$request['name'], 0); //----------------------------------------- // Check length //----------------------------------------- if (IPSText::mbstrlen($name) < 3) { $this->returnJsonError('requestTooShort'); } //----------------------------------------- // Try query... //----------------------------------------- $this->DB->build(array('select' => 'm.members_display_name, m.name, m.member_id, m.member_group_id', 'from' => array('members' => 'm'), 'where' => "LOWER(m.members_display_name) LIKE '" . $this->DB->addSlashes($name) . "%'", 'order' => $this->DB->buildLength('m.members_display_name') . ' ASC', 'limit' => array(0, 15), 'add_join' => array(array('select' => 'p.*', 'from' => array('profile_portal' => 'p'), 'where' => 'p.pp_member_id=m.member_id', 'type' => 'left')))); $this->DB->execute(); //----------------------------------------- // Got any results? //----------------------------------------- if (!$this->DB->getTotalRows()) { $this->returnJsonArray(array()); } $return = array(); while ($r = $this->DB->fetch()) { $photo = IPSMember::buildProfilePhoto($r); $group = IPSLib::makeNameFormatted('', $r['member_group_id']); $return[$r['member_id']] = array('name' => $r['members_display_name'], 'showas' => '<strong>' . $r['members_display_name'] . '</strong> (' . $group . ')', 'img' => $photo['pp_thumb_photo'], 'img_w' => $photo['pp_mini_width'], 'img_h' => $photo['pp_mini_height']); } $this->returnJsonArray($return); }
/** * Returns possible matches for the string input * * @return @e void Outputs to screen */ protected function _getMembers() { //----------------------------------------- // INIT //----------------------------------------- $name = IPSText::convertUnicode($this->convertAndMakeSafe($this->request['name'], 0), true); $name = IPSText::convertCharsets($name, 'utf-8', IPS_DOC_CHAR_SET); //----------------------------------------- // Check length //----------------------------------------- if (IPSText::mbstrlen($name) < 3) { $this->returnJsonError('requestTooShort'); } //----------------------------------------- // Try query... //----------------------------------------- $this->DB->build(array('select' => 'm.members_display_name, m.member_id, m.members_seo_name, m.member_group_id', 'from' => array('members' => 'm'), 'where' => "m.members_l_display_name LIKE '" . $this->DB->addSlashes(strtolower($name)) . "%'", 'order' => $this->DB->buildLength('m.members_display_name') . ' ASC', 'limit' => array(0, 15), 'add_join' => array(array('select' => 'p.*', 'from' => array('profile_portal' => 'p'), 'where' => 'p.pp_member_id=m.member_id', 'type' => 'left')))); $this->DB->execute(); //----------------------------------------- // Got any results? //----------------------------------------- if (!$this->DB->getTotalRows()) { $this->returnJsonArray(array()); } $return = array(); while ($r = $this->DB->fetch()) { $url = $this->registry->output->buildSEOUrl("app=core&module=modcp&do=editmember&mid={$r['member_id']}", 'public'); $photo = IPSMember::buildProfilePhoto($r); $group = IPSMember::makeNameFormatted('', $r['member_group_id']); $return[$r['member_id']] = array('name' => $r['members_display_name'], 'showas' => '<strong>' . $r['members_display_name'] . '</strong> (' . $group . ')', 'img' => $photo['pp_thumb_photo'], 'img_w' => $photo['pp_mini_width'], 'img_h' => $photo['pp_mini_height'], 'url' => $url); } $this->returnJsonArray($return); }
/** * Build the actual output to show * * @access protected * @param array $content Display text * @param string $option URL to link to * @return string Content to replace bbcode with */ protected function _buildOutput($content, $option) { // This is problematic if url contains a ' or " // $option = str_replace( array( '"', "'", ''', '"' ), '', $option ); //----------------------------------------- // Remove " and ' from beginning + end //----------------------------------------- if (substr($option, 0, 5) == ''') { $option = substr($option, 5); } else { if (substr($option, 0, 6) == '"') { $option = substr($option, 6); } else { if (substr($option, 0, 1) == "'") { $option = substr($option, 1); } else { if (substr($option, 0, 1) == '"') { $option = substr($option, 1); } } } } if (substr($option, -5) == ''') { $option = substr($option, 0, -5); } else { if (substr($option, -6) == '"') { $option = substr($option, 0, -6); } else { if (substr($option, -1) == "'") { $option = substr($option, 0, -1); } else { if (substr($option, -1) == '"') { $option = substr($option, 0, -1); } } } } //----------------------------------------- // Some security checking //----------------------------------------- if (IPSText::xssCheckUrl($option) !== TRUE) { return $content; } /* Check for mangled or embedded URLs */ if (stristr($option, '[attachment') or stristr($option, '[quote') or stristr($option, '[url') or stristr($option, '[/url') or stristr($content, '[url') or stristr($content, '[/url')) { return $content; } //----------------------------------------- // Fix quotes in urls //----------------------------------------- $option = str_replace(array(''', "'"), '%27', $option); $option = str_replace(array('"', '"'), '%22', $option); foreach ($this->cache->getCache('bbcode') as $bbcode) { $_tags = $this->_retrieveTags(); foreach ($_tags as $tag) { if (strpos($option, '[' . $tag) !== false) { return $content; } } } //----------------------------------------- // URL filtering? //----------------------------------------- if ($this->settings['ipb_use_url_filter']) { $list_type = $this->settings['ipb_url_filter_option'] == "black" ? "blacklist" : "whitelist"; if ($this->settings['ipb_url_' . $list_type]) { $list_values = array(); $list_values = explode("\n", str_replace("\r", "", $this->settings['ipb_url_' . $list_type])); if ($list_type == "whitelist") { $list_values[] = "http://{$_SERVER['HTTP_HOST']}/*"; } if (count($list_values)) { $good_url = 0; foreach ($list_values as $my_url) { if (!trim($my_url)) { continue; } $my_url = preg_quote($my_url, '/'); $my_url = str_replace('\\*', "(.*?)", $my_url); if ($list_type == "blacklist") { if (preg_match('/' . $my_url . '/i', $option)) { $this->warning = 'domain_not_allowed'; return $content; } } else { if (preg_match('/' . $my_url . '/i', $option)) { $good_url = 1; } } } if (!$good_url and $list_type == "whitelist") { $this->warning = 'domain_not_allowed'; return $content; } } } } //----------------------------------------- // Let's remove any nested links.. //----------------------------------------- $content = preg_replace('/<a href=\'(.+?)\'(.*?)>(.+?)<\\/a>/is', "\\3", $content); //----------------------------------------- // Need to "truncate" the "content" to ~35 // EDIT: but only if it's the same as content //----------------------------------------- /* Changes here @link http://community.invisionpower.com/tracker/issue-36082-long-links-on-mobile-extend-width/ */ if (empty($this->settings['__noTruncateUrl']) and IPSText::mbstrlen($content) > 38 and (substr($content, 0, 7) == 'http://' or substr($content, 0, 8) == 'https://')) { $content = htmlspecialchars(IPSText::mbsubstr(html_entity_decode(urldecode($content)), 0, 20)) . '...' . htmlspecialchars(IPSText::mbsubstr(html_entity_decode(urldecode($content)), -15)); } //----------------------------------------- // Adding rel='nofollow'? //----------------------------------------- $rels = array(); $rel = ''; $_title = ''; /* Fetch actual host for better matching */ $data = @parse_url($option); if ($this->settings['posts_add_nofollow']) { if (!stristr($data['host'], $_SERVER['HTTP_HOST'])) { $rels[] = "nofollow"; } } if ($this->settings['links_external']) { if (!stristr($data['host'], $_SERVER['HTTP_HOST'])) { /* Look a little closer */ $rels[] = "external"; $_title = $this->lang->words['bbc_external_link']; } } if (count($rels)) { $rel = " rel='" . implode(' ', $rels) . "'"; } return "<a href='{$option}' class='bbc_url' title='{$_title}'{$rel}>{$content}</a>"; }
/** * Post a status update to twitter based on native content * Which may be longer and such and so on and so forth, etc * * @access public * @param string Content * @param string URL to add * @param bool Always add the URL regardless of content length * @param bool Add a hashtag */ public function updateStatusWithUrl($content, $url, $alwaysAdd = TRUE, $hashtag = '') { if (is_string($hashtag) && !empty($hashtag)) { if (substr($hashtag, 0, 1) != '#') { $hashtag = '#' . $hashtag; } $hashtag = ' ' . $hashtag; } else { if (!is_string($hashtag)) { $hashtag = ''; } } /* Ensure content is correctly de-html-ized */ $content = IPSText::UNhtmlspecialchars($content); /* Is the text longer than 140 chars? */ if ($alwaysAdd === TRUE or IPSText::mbstrlen($content) > 140) { /* Leave 26 chars for URL shortener */ $less = 26 + strlen($hashtag); if (IPSText::mbstrlen($content) > 140 - $less) { $content = IPSText::mbsubstr($content, 0, 140 - ($less + 3)) . '...' . $hashtag; } if (IPSText::mbstrlen($url) > 26) { /* Generate short URL */ $classToLoad = IPSLib::loadLibrary(IPS_ROOT_PATH . 'sources/classes/url/shorten.php', 'urlShorten'); $shorten = new $classToLoad(); try { $data = $shorten->shorten($url, IPS_URL_SHORTEN_SERVICE); $url = $data['url']; } catch (Exception $ex) { /* Stop the exception bubbling back to parent classes */ } } return $this->updateStatus($content . ' ' . $url); } else { /* Just post it */ return $this->updateStatus($content); } }
/** * Cleans incoming tags * @param String or Array Comma delim string or array of tags * @param Bool If TRUE, will check minimum and maximum amounts of tags - not necessary for searching * @return Array Array of cleaned tags */ private function _cleanTags($tags, $checkForMinimumAndMaximum = TRUE) { /* Sort out tags */ if (!is_array($tags)) { if (strstr($tags, ',')) { $_tags = explode(',', IPSText::cleanPermString($tags)); $tags = array(); foreach ($_tags as $t) { if ($t) { $tags[] = $this->_stripHtml(trim($this->_forceLower() ? IPSText::mbstrtolower($t) : $t)); } } } else { if (!strlen($tags)) { return false; } $tags = array($this->_stripHtml($this->_forceLower() ? IPSText::mbstrtolower($tags) : $tags)); } } /* So.. got tags to parse? */ if (count($tags)) { /* Make sure they are all unique */ $tags = array_unique($tags); /* Check for min/max string length */ if ($checkForMinimumAndMaximum and ($this->_getMaxLen() or $this->_getMinLen())) { $_tags = $tags; $tags = array(); foreach ($_tags as $tag) { if ($this->_getMaxLen()) { if (IPSText::mbstrlen($tag) > $this->_getMaxLen()) { continue; } } if ($this->_getMinLen()) { if (IPSText::mbstrlen($tag) < $this->_getMinLen()) { continue; } } $tags[] = $tag; } } /* removes any bad words */ $badwords = $this->cache->getCache('badwords'); if ($this->_mustCleanWords() and is_array($badwords) && count($badwords)) { $_tags = $tags; $tags = array(); foreach ($_tags as $tag) { $_bad = false; foreach ($badwords as $badword) { if (strtolower($tag) == strtolower($badword['type'])) { $_bad = true; break; } } if (!$_bad) { $tags[] = $tag; } } } } /* Now, do we have a sufficient number of tags? */ if ($checkForMinimumAndMaximum && $this->_getMaxTags() && count($tags) > $this->_getMaxTags()) { $this->setErrorMsg('too_many_tags'); return false; } /* Perhaps not enough? */ if ($checkForMinimumAndMaximum && $this->_getMinTags() && count($tags) < $this->_getMinTags()) { $this->setErrorMsg('too_few_tags'); return false; } /* Generic catch all in case min/max tags aren't set up. */ if (!count($tags)) { $this->setErrorMsg('no_good_tags'); return false; } /* Phew. */ return $tags; }
/** * Sends the PM * * @access private * @return void, or HTML form */ private function _sendNewPersonalTopic() { //----------------------------------------- // INIT //----------------------------------------- if ($this->messengerFunctions->checkHasHitMax()) { $this->registry->getClass('output')->showError('maxperday_hit', 10272); } $msgTitle = IPSText::getTextClass('bbcode')->stripBadWords(trim(IPSText::parseCleanValue($_POST['msg_title']))); $authKey = $this->request['auth_key']; $sendToName = $this->request['entered_name']; $sendToID = intval($this->request['toMemberID']); $sendType = trim($this->request['sendType']); $_inviteUsers = trim($this->request['inviteUsers']); $msgContent = $_POST['Post']; $topicID = $this->request['topicID']; $inviteUsers = array(); $draft = $this->request['save'] ? TRUE : FALSE; //----------------------------------------- // Error checking //----------------------------------------- if (IPSText::mbstrlen(trim($msgTitle)) < 2) { return $this->_showNewTopicForm($this->lang->words['err_no_title']); } if (IPSText::mbstrlen(trim(IPSText::br2nl($_POST['Post']))) < 3) { return $this->_showNewTopicForm($this->lang->words['err_no_msg']); } if ($this->request['auth_key'] != $this->member->form_hash) { $this->registry->getClass('output')->_showNewTopicForm('messenger_bad_key', 2024); } if ($sendToID and $sendToName == "") { return $this->_showNewTopicForm($this->lang->words['err_no_chosen_member']); } //----------------------------------------- // Invite Users //----------------------------------------- if ($this->memberData['g_max_mass_pm'] and $_inviteUsers) { $_tmp = array(); foreach (explode(',', $_inviteUsers) as $name) { $name = trim($name); if ($name) { $inviteUsers[] = $name; } } } //----------------------------------------- // Grab member ID //----------------------------------------- $toMember = $sendToID ? IPSMember::load($sendToID, 'core') : IPSMember::load($sendToName, 'core', 'displayname'); if (!$toMember['member_id']) { return $this->_showNewTopicForm($this->lang->words['err_no_chosen_member']); } //----------------------------------------- // Send .. or.. save... //----------------------------------------- try { $this->messengerFunctions->sendNewPersonalTopic($toMember['member_id'], $this->memberData['member_id'], $inviteUsers, $msgTitle, $msgContent, array('isDraft' => $draft, 'topicID' => $topicID, 'sendMode' => $sendType, 'postKey' => $this->_postKey)); } catch (Exception $error) { $msg = $error->getMessage(); if (strstr($msg, 'BBCODE_')) { $msg = str_replace('BBCODE_', '', $msg); return $this->_showNewTopicForm($this->lang->words[$msg]); } else { if (isset($this->lang->words['err_' . $msg])) { $_msgString = $this->lang->words['err_' . $msg]; $_msgString = str_replace('#NAMES#', implode(",", $this->messengerFunctions->exceptionData), $_msgString); $_msgString = str_replace('#TONAME#', $toMember['members_display_name'], $_msgString); $_msgString = str_replace('#FROMNAME#', $this->memberData['members_display_name'], $_msgString); $_msgString = str_replace('#DATE#', $this->messengerFunctions->exceptionData[0], $_msgString); } else { $_msgString = $this->lang->words['err_UNKNOWN'] . ' ' . $msg; } } return $this->_showNewTopicForm($_msgString); } //----------------------------------------- // Swap and serve... //----------------------------------------- if ($draft !== TRUE) { $text = str_replace("<#FROM_MEMBER#>", $this->memberData['members_display_name'], $this->lang->words['sent_text']); $text = str_replace("<#MESSAGE_TITLE#>", $msgTitle, $text); } else { $text = "Your message has been saved as a draft"; } $this->registry->getClass('output')->redirectScreen($text, $this->settings['base_url'] . 'app=members&module=messaging&section=view&do=inbox'); }
/** * Write to the admin log in loggy ma log * * @param string Username * @param string ok/fail flag * @return @e void * @note This is private so that a hacker couldn't get into ACP, upload a new hook that lets them clear the log, and then clear the login log */ private function _writeToLog($username = '', $flag = 'fail') { //----------------------------------------- // INIT //----------------------------------------- $username = $username ? $username : $this->request['username']; $flag = $flag == 'ok' ? 1 : 0; $admin_post_details = array(); //----------------------------------------- // Generate POST / GET details //----------------------------------------- foreach ($_GET as $k => $v) { $admin_post_details['get'][$k] = $v; } foreach ($_POST as $k => $v) { if ($k == 'password' and IPSText::mbstrlen($v) > 1) { $v = $v ? (IPSText::mbstrlen($v) - 1 > 0 ? str_repeat('*', IPSText::mbstrlen($v) - 1) : '') . substr($v, -1, 1) : ''; } $admin_post_details['post'][$k] = $v; } //----------------------------------------- // Write to disk... //----------------------------------------- $this->DB->insert('admin_login_logs', array('admin_ip_address' => $this->member->ip_address, 'admin_username' => $username, 'admin_time' => time(), 'admin_success' => $flag, 'admin_post_details' => serialize($admin_post_details))); }
/** * Finish URLs for display * Truncates them, applies white/black lists, adds rel / targets * @param string In * @return string Out */ protected function _finishUrlsForDisplay($txt) { /* If HTML mode, don't clean links */ if (parent::$Perms['parseHtml']) { return $txt; } /* Reset counter */ $this->cache->updateCacheWithoutSaving('_tmp_bbcode_media', 0); /* Parse media URLs that are NOT linked */ $txt = preg_replace_callback('#(^|\\s|\\)|\\(|\\{|\\}|>|\\]|\\[|;|href=\\S)((http|https|news|ftp)://(?:[^<>\\)\\[\\"\\s]+|[a-zA-Z0-9/\\._\\-!&\\#;,%\\+\\?:=]+))(</a>)?#is', array($this, '_parseMediaUrls_CallBack'), $txt); /* LEGACY stuffs - a post from < 3.4 may not be HTMLised properly */ if ($this->_urlsEnabled === true && preg_match('#(http|https)://#', $txt) && !stristr($txt, '<a')) { $txt = $this->_autoLinkUrls($txt); } preg_match_all('#<a\\s+?(?:[^>]*?)href=["\']([^"\']+?)?["\']([^>]*?)?>(.+?)</a>#is', $txt, $urlMatches); /* Finish up URLs and such */ for ($i = 0; $i < count($urlMatches[0]); $i++) { $raw = $urlMatches[0][$i]; $url = $urlMatches[1][$i]; $attr = $urlMatches[2][$i]; $text = $urlMatches[3][$i]; $done = false; $pm = true; preg_match('#data-ipb=["\']([^"\']+?)?["\']#i', $raw, $matches); if ($matches[1] && stristr($matches[1], 'noparse')) { continue; } else { if ($matches[1] && stristr($matches[1], 'nomediaparse')) { $pm = false; } } preg_match('#rel=["\']([^"\']+?)?["\']#i', $raw, $matches); if ($matches[1] && stristr($matches[1], 'lightbox')) { continue; } /* Urls disabled? */ if ($this->_urlsEnabled !== true) { $txt = str_replace($raw, $url, $txt); continue; } /* Restored 1st March, Matt @link http://community.invisionpower.com/resources/bugs.html/_/ip-board/some-previously-embedded-content-youtube-etc-now-showing-as-links-after-upgrade-r41411 */ /* Is this a media URL? */ /* Updated 14 May, http://community.invisionpower.com/resources/bugs.html/_/ip-board/url-tags-get-changed-to-media-tags-automatically-r40467 - Editor now sets "noparsemedia" data-ipb attribute, which we can skip here for automatic parsing */ if ($pm and $this->settings['bbcode_automatic_media'] and isset($this->_bbcodes['media']) and ($this->_bbcodes['media']['bbcode_sections'] == 'all' or in_array(parent::$Perms['parseArea'], explode(',', $this->_bbcodes['media']['bbcode_sections'])))) { $media = $this->cache->getCache('mediatag'); if ($url == $text && is_array($media) and count($media)) { foreach ($media as $type => $r) { if (preg_match("#^" . $r['match'] . "\$#is", $url)) { $this->cache->updateCacheWithoutSaving('_tmp_autoparse_media', 1); $_result = $this->_parseBBCode('[media]' . $url . '[/media]', 'display', array('media')); $this->cache->updateCacheWithoutSaving('_tmp_autoparse_media', 0); $txt = str_replace($raw, $_result, $txt); $done = true; } } } } /* Format the URL */ if ($done !== true) { // ----------------------------------------- // URL filtering? // ----------------------------------------- if (!$this->isAllowedUrl($url)) { /* Unlink */ $txt = str_replace($raw, $url, $txt); } // ----------------------------------------- // Let's remove any nested links.. // ----------------------------------------- $text = preg_replace('/<a href=[\'"](.+?)[\'"](.*?)>(.+?)<\\/a>/is', "\\3", $text); // ----------------------------------------- // Need to "truncate" the "content" to ~35 // EDIT: but only if it's the same as content // ----------------------------------------- /* * Changes here @link * http://community.invisionpower.com/tracker/issue-36082-long-links-on-mobile-extend-width/ # V V Don't split if URL has entities V V # */ if (empty($this->settings['__noTruncateUrl']) and IPSText::mbstrlen($text) > 38 && !preg_match('#&\\#([0-9]{2,4})#i', $text) and (substr($text, 0, 7) == 'http://' or substr($text, 0, 8) == 'https://')) { $text = htmlspecialchars(IPSText::mbsubstr(html_entity_decode(urldecode($text)), 0, 20)) . '...' . htmlspecialchars(IPSText::mbsubstr(html_entity_decode(urldecode($text)), -15)); } // ----------------------------------------- // Adding rel='nofollow'? // ----------------------------------------- $rels = array(); $rel = ''; $_title = ''; /* Skipping VigLink? */ if ($this->settings['viglink_norewrite'] and IPSMember::isInGroup(parent::$Perms['memberData'], explode(',', $this->settings['viglink_norewrite']))) { $rels[] = 'norewrite'; } /* Fetch actual host for better matching */ $data = @parse_url($url); if ($this->settings['posts_add_nofollow']) { if (!stristr($data['host'], $_SERVER['HTTP_HOST'])) { $rels[] = "nofollow"; } } if ($this->settings['links_external']) { if (!stristr($data['host'], $_SERVER['HTTP_HOST'])) { /* Look a little closer */ $rels[] = "external"; $_title = $this->lang->words['bbc_external_link']; } } if (count($rels)) { $rel = " rel='" . implode(' ', $rels) . "'"; } $replace = "<a href='{$url}' class='bbc_url' title='{$_title}'{$rel}>{$text}</a>"; $txt = str_replace($raw, $replace, $txt); } } return $txt; }
/** * Formats search term for SQL * * @access private * @param string Raw IPB santized form input * @return array array( 'search_term' => Safe string to use in SQL, 'removed' => array of removed search terms ) */ public function formatSearchTerm($search_term) { $isBoolean = $this->isBoolean(); $andor = isset($this->request['andor_type']) ? $this->request['andor_type'] : $this->settings['s_andor_type']; $removedTerms = array(); /* Fix up some sanitized HTML */ $search_term = str_replace("&", '&', IPSText::parseCleanValue(rawurldecode($search_term))); $search_term = str_replace(""", '"', $search_term); $search_term = IPSText::mbstrtolower($search_term); /* Check for disallowed search terms */ while (preg_match_all('/(?:^|\\s+)(img|quote|code|html|javascript|a href|color|span|div|border|style)(?:\\s+|$)/', $search_term, $removed_search_terms)) { $removedTerms[] = $removed_search_terms[0][0]; $search_term = preg_replace('/(^|\\s+)(?:img|quote|code|html|javascript|a href|color|span|div|border|style)(\\s+|$)/', str_replace(" ", " ", "\$1\$2"), $search_term); } /* remove < min char words */ if (substr_count($search_term, '"') != 2) { $_words = explode(' ', $search_term); $search_term = ''; foreach ($_words as $_w) { if (IPSText::mbstrlen($_w) >= $this->settings['min_search_word']) { $search_term .= $_w . ' '; } else { if ($_w) { $removedTerms[] = $_w; } } } } /* Remove some formatting */ //$search_term = str_replace( array( '|', '\\', '/' ), '', $search_term ); // | is an OR operator for sphinx - don't want to block globally if ($search_term) { $search_term = str_replace(array('\\', '/'), '', trim($search_term)); /* Sphinx chars are not allowed */ $search_term = str_replace(array('.', ')', '(', '!', '@', '[', ']', '~', '^'), '', $search_term); $search_term = preg_replace('#(?!\\s)-#', '\\1‐', $search_term); if ($andor == 'and' and !(substr_count($search_term, '"') == 2)) { $search_term = '+' . preg_replace('/\\s+(?!-|~)/', " +", $search_term); } } return array('search_term' => $search_term, 'removed' => $removedTerms); }
/** * Edit a post * * Usage: * $post->setForumID(1); * $post->setTopicID(5); * $post->setPostID(100); * $post->setAuthor( $member ); * * $post->setPostContent( "Hello [b]there![/b]" ); * # Optional: No bbcode, etc parsing will take place * # $post->setPostContentPreFormatted( "Hello <b>there!</b>" ); * $post->editPost(); * * Exception Error Codes: * NO_POSTING_PPD : No post ID set * NO_CONTENT : No post content set * CONTENT_TOO_LONG : Post is too long * * @return mixed */ public function editPost() { //----------------------------------------- // Global checks and functions //----------------------------------------- try { $this->globalSetUp(); } catch (Exception $error) { $e = $error->getMessage(); if ($e != 'NO_POSTING_PPD') { $this->_postErrors = $error->getMessage(); } } if ($this->_bypassPermChecks !== TRUE && IPSMember::isOnModQueue($this->getAuthor()) === NULL) { $this->_postErrors = 'warnings_restrict_post_perm'; } if (!$this->getPostContent() and !$this->getPostContentPreFormatted()) { $this->_postErrors = 'NO_CONTENT'; } //----------------------------------------- // Get topic //----------------------------------------- try { $topic = $this->editSetUp(); } catch (Exception $error) { $this->_postErrors = $error->getMessage(); } //----------------------------------------- // Parse the post, and check for any errors. //----------------------------------------- $post = $this->compilePostData(); //----------------------------------------- // Do we have a valid post? //----------------------------------------- if (strlen(trim(IPSText::removeControlCharacters(IPSText::br2nl($post['post'])))) < 1) { $this->_postErrors = 'NO_CONTENT'; } if (IPSText::mbstrlen($post['post']) > $this->settings['max_post_length'] * 1024) { $this->_postErrors = 'CONTENT_TOO_LONG'; } if ($this->_postErrors != "") { //----------------------------------------- // Show the form again //----------------------------------------- return FALSE; } //----------------------------------------- // Ajax specifics //----------------------------------------- if ($this->getIsAjax() === TRUE) { # Prevent polls from being edited $this->can_add_poll = 0; # Prevent titles from being edited $this->edit_title = 0; # Prevent open time from being edited $this->can_set_open_time = 0; # Prevent close time from being edited $this->can_set_close_time = 0; # Set Settings $this->setSettings(array('enableSignature' => $this->_originalPost['use_sig'] ? 1 : 0, 'enableEmoticons' => $this->_originalPost['use_emo'] ? 1 : 0, 'post_htmlstatus' => $this->getSettings('post_htmlstatus'))); if (!$this->getAuthor('g_append_edit')) { $this->request['add_edit'] = ($this->_originalPost['append_edit'] or !$this->getAuthor('g_append_edit') ? 1 : 0); } } //----------------------------------------- // Compile the poll //----------------------------------------- if ($this->can_add_poll) { //----------------------------------------- // Load the poll from the DB //----------------------------------------- $this->poll_data = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'polls', 'where' => "tid=" . intval($topic['tid']))); $this->poll_answers = !empty($this->poll_data['choices']) && IPSLib::isSerialized($this->poll_data['choices']) ? IPSLib::safeUnserialize(stripslashes($this->poll_data['choices'])) : array(); } //----------------------------------------- // Compile the poll //----------------------------------------- $this->poll_questions = $this->compilePollData(); if ($this->_postErrors != "" or $this->getIsPreview() === TRUE) { //----------------------------------------- // Show the form again //----------------------------------------- return FALSE; } /* Got a topics table to update? */ $updateTopicTable = array(); //----------------------------------------- // Reset some data //----------------------------------------- $post['ip_address'] = $this->_originalPost['ip_address']; $post['topic_id'] = $this->_originalPost['topic_id']; $post['author_id'] = $this->_originalPost['author_id']; $post['post_date'] = $this->_originalPost['post_date']; $post['author_name'] = $this->_originalPost['author_name']; $post['queued'] = $this->_originalPost['queued']; $post['edit_time'] = $this->getDate() ? $this->getDate() : IPS_UNIX_TIME_NOW; $post['edit_name'] = $this->getAuthor('members_display_name'); if ($this->_originalPost['new_topic'] == 1) { /* Tagging */ if (isset($_POST['ipsTags'])) { $this->registry->tags->replace($_POST['ipsTags'], array('meta_id' => $topic['tid'], 'meta_parent_id' => $topic['forum_id'], 'member_id' => $this->memberData['member_id'], 'meta_visible' => $topic['approved'])); } /* Like if not ajax edit */ if (!IPS_IS_AJAX) { $this->addTopicToTracker($topic['tid']); } //----------------------------------------- // Update open and close times //----------------------------------------- if ($this->can_set_open_time and $this->times['open']) { $updateTopicTable['topic_open_time'] = intval($this->times['open']); if ($topic['topic_open_time'] and $this->times['open']) { $updateTopicTable['state'] = 'closed'; if (IPS_UNIX_TIME_NOW > $topic['topic_open_time']) { if (IPS_UNIX_TIME_NOW < $topic['topic_close_time']) { $updateTopicTable['state'] = 'open'; } } } if (!$this->times['open'] and $topic['topic_open_time']) { if ($topic['state'] == 'closed') { $updateTopicTable['state'] = 'open'; } } } else { if ($this->can_set_open_time and $topic['topic_open_time']) { $updateTopicTable['topic_open_time'] = 0; } } if ($this->can_set_close_time and $this->times['close']) { $updateTopicTable['topic_close_time'] = intval($this->times['close']); //----------------------------------------- // Was a close time, but not now? //----------------------------------------- if (!$this->times['close'] and $topic['topic_close_time']) { if ($topic['state'] == 'closed') { $updateTopicTable['state'] = 'open'; } } } else { if ($this->can_set_close_time and $topic['topic_close_time']) { $updateTopicTable['topic_close_time'] = 0; } } if ($this->edit_title) { if ($this->getForumID() != $topic['forum_id']) { $updateTopicTable['forum_id'] = $this->getForumID(); } } } //----------------------------------------- // Update poll //----------------------------------------- if ($this->can_add_poll) { if (is_array($this->poll_questions) and count($this->poll_questions)) { $poll_only = 0; if ($this->settings['ipb_poll_only'] and $this->request['poll_only'] == 1) { $poll_only = 1; } $poll_view_voters = !$this->poll_data['votes'] ? $this->request['poll_view_voters'] : $this->poll_data['poll_view_voters']; if ($topic['poll_state']) { $_pollData = array('votes' => intval($this->poll_total_votes), 'choices' => addslashes(serialize($this->poll_questions)), 'poll_question' => IPSText::stripAttachTag($this->request['poll_question']), 'poll_only' => $poll_only, 'poll_view_voters' => intval($poll_view_voters)); /* Data Hook Location */ IPSLib::doDataHooks($_pollData, 'editPostUpdatePoll'); $this->DB->update('polls', $_pollData, 'tid=' . $topic['tid']); if ($this->poll_data['choices'] != serialize($this->poll_questions) or $this->poll_data['votes'] != intval($this->poll_total_votes)) { $this->DB->insert('moderator_logs', array('forum_id' => $this->getForumData('id'), 'topic_id' => $topic['tid'], 'post_id' => $this->_originalPost['pid'], 'member_id' => $this->getAuthor('member_id'), 'member_name' => $this->getAuthor('members_display_name'), 'ip_address' => $this->ip_address, 'http_referer' => htmlspecialchars(my_getenv('HTTP_REFERER')), 'ctime' => IPS_UNIX_TIME_NOW, 'topic_title' => $topic['title'], 'action' => $this->lang->words['edited_poll'], 'query_string' => htmlspecialchars(my_getenv('QUERY_STRING')))); } } else { $_pollData = array('tid' => $topic['tid'], 'forum_id' => $this->getForumData('id'), 'start_date' => IPS_UNIX_TIME_NOW, 'choices' => addslashes(serialize($this->poll_questions)), 'starter_id' => $this->getAuthor('member_id'), 'votes' => 0, 'poll_question' => IPSText::stripAttachTag($this->request['poll_question']), 'poll_only' => $poll_only, 'poll_view_voters' => intval($poll_view_voters)); /* Data Hook Location */ IPSLib::doDataHooks($_pollData, 'editPostAddPoll'); $this->DB->insert('polls', $_pollData); $this->DB->insert('moderator_logs', array('forum_id' => $this->getForumData('id'), 'topic_id' => $topic['tid'], 'post_id' => $this->_originalPost['pid'], 'member_id' => $this->getAuthor('member_id'), 'member_name' => $this->getAuthor('members_display_name'), 'ip_address' => $this->ip_address, 'http_referer' => htmlspecialchars(my_getenv('HTTP_REFERER')), 'ctime' => IPS_UNIX_TIME_NOW, 'topic_title' => $topic['title'], 'action' => sprintf($this->lang->words['added_poll'], $this->request['poll_question']), 'query_string' => htmlspecialchars(my_getenv('QUERY_STRING')))); /* Update topics table later */ $updateTopicTable['poll_state'] = 1; $updateTopicTable['last_vote'] = 0; } } else { /* Remove the poll */ $this->DB->delete('polls', 'tid=' . $topic['tid']); $this->DB->delete('voters', 'tid=' . $topic['tid']); /* Update topics table later */ $updateTopicTable['poll_state'] = 0; $updateTopicTable['last_vote'] = 0; } } //----------------------------------------- // Update topic title? //----------------------------------------- if ($this->edit_title == 1) { //----------------------------------------- // Update topic title //----------------------------------------- if ($this->_topicTitle != "") { if ($this->_topicTitle != $topic['title'] or !$topic['title_seo']) { $updateTopicTable['title'] = $this->_topicTitle; $updateTopicTable['title_seo'] = IPSText::makeSeoTitle($this->_topicTitle); $_forumUpdate = array(); if ($topic['tid'] == $this->getForumData('last_id')) { $_forumUpdate['last_title'] = $updateTopicTable['title']; $_forumUpdate['seo_last_title'] = $updateTopicTable['title_seo']; } if ($topic['tid'] == $this->getForumData('newest_id')) { $_forumUpdate['newest_title'] = $updateTopicTable['title']; } if (count($_forumUpdate)) { $this->DB->update('forums', $_forumUpdate, 'id=' . $this->getForumData('id')); } if ($this->moderator['edit_topic'] == 1 or $this->getAuthor('g_is_supmod') == 1) { $this->DB->insert('moderator_logs', array('forum_id' => $this->getForumData('id'), 'topic_id' => $topic['tid'], 'post_id' => $this->_originalPost['pid'], 'member_id' => $this->getAuthor('member_id'), 'member_name' => $this->getAuthor('members_display_name'), 'ip_address' => $this->ip_address, 'http_referer' => htmlspecialchars(my_getenv('HTTP_REFERER')), 'ctime' => IPS_UNIX_TIME_NOW, 'topic_title' => $topic['title'], 'action' => sprintf($this->lang->words['edited_topic_title'], $topic['title'], $this->_topicTitle), 'query_string' => htmlspecialchars(my_getenv('QUERY_STRING')))); } } } } //----------------------------------------- // Reason for edit? //----------------------------------------- if ($this->_bypassPermChecks or isset($this->moderator['edit_post']) && $this->moderator['edit_post'] or $this->getAuthor('g_is_supmod')) { $post['post_edit_reason'] = trim($this->request['post_edit_reason']); } //----------------------------------------- // Update the database (ib_forum_post) //----------------------------------------- $post['append_edit'] = 1; if ($this->_bypassPermChecks or $this->getAuthor('g_append_edit')) { if ($this->request['add_edit'] != 1) { $post['append_edit'] = 0; } } /* HTML Status */ $post['post_htmlstate'] = $this->getSettings('post_htmlstatus'); /* Typecast */ $this->DB->setDataType('post_edit_reason', 'string'); /* Data Hook Location */ IPSLib::doDataHooks($post, 'editPostData'); $this->DB->update('posts', $post, 'pid=' . $this->_originalPost['pid']); /* Got a topic to update? */ $updateTopicTable['post_data'] = $post; $updateTopicTable['forum_data'] = $this->getForumData(); IPSLib::doDataHooks($updateTopicTable, 'editPostTopicData'); unset($updateTopicTable['post_data'], $updateTopicTable['forum_data']); // Remove added data if (count($updateTopicTable)) { $this->DB->update('topics', $updateTopicTable, 'tid=' . $topic['tid']); } /* remove saved content */ if ($this->memberData['member_id']) { $this->editor->removeAutoSavedContent(array('member_id' => $this->memberData['member_id'], 'autoSaveKey' => 'edit-' . intval($this->_originalPost['pid']))); } /* Add to cache */ IPSContentCache::update($this->_originalPost['pid'], 'post', $this->formatPostForCache($post['post'])); /* Upload Attachments */ $this->uploadAttachments($this->post_key, $this->_originalPost['pid']); //----------------------------------------- // Make attachments "permanent" //----------------------------------------- $this->makeAttachmentsPermanent($this->post_key, $this->_originalPost['pid'], 'post', array('topic_id' => $topic['tid'])); //----------------------------------------- // Make sure paperclip symbol is OK //----------------------------------------- $this->recountTopicAttachments($topic['tid']); //----------------------------------------- // Leave data for other apps //----------------------------------------- $this->setTopicData($topic); $this->setPostData(array_merge($this->_originalPost, $post)); return TRUE; }
/** * Save the group [add/edit] * * @param string 'add' or 'edit' * @return @e void [Outputs to screen] */ protected function _saveGroup($type = 'edit') { //----------------------------------------- // INIT //----------------------------------------- $group_id = intval($this->request['id']); $oldGroup = $this->caches['group_cache'][$group_id]; //----------------------------------------- // Auth check... //----------------------------------------- ipsRegistry::getClass('adminFunctions')->checkSecurityKey($this->request['secure_key']); //----------------------------------------- // Check... //----------------------------------------- if (!$this->request['g_title']) { $this->registry->output->showError($this->lang->words['g_title_error'], 1127); } if (intval($this->request['g_max_mass_pm']) > 500) { $this->registry->output->showError($this->lang->words['g_mass_pm_too_large'], 1127); } #MSSQL needs a check on this if (IPSText::mbstrlen($this->request['g_title']) > 32) { $this->registry->output->showError($this->lang->words['g_title_error'], 1127); } if ($type == 'edit') { if (!$group_id) { $this->registry->output->showError($this->lang->words['g_whichgroup'], 1128); } //----------------------------------------- // Check restrictions. //----------------------------------------- if ($this->caches['group_cache'][$group_id]['g_access_cp']) { $this->registry->getClass('class_permissions')->checkPermissionAutoMsg('groups_edit_admin'); } } //----------------------------------------- // Check restrictions. //----------------------------------------- if (($type == 'add' or !$this->caches['group_cache'][$group_id]['g_access_cp']) and $this->request['g_access_cp']) { $this->registry->getClass('class_permissions')->checkPermissionAutoMsg('groups_add_admin'); } //----------------------------------------- // Sort out the perm mask id things //----------------------------------------- $new_perm_set_id = 0; if ($this->request['g_new_perm_set']) { $this->DB->insert('forum_perms', array('perm_name' => $this->request['g_new_perm_set'])); $new_perm_set_id = $this->DB->getInsertId(); } else { if (!is_array($this->request['permid'])) { $this->registry->output->showError($this->lang->words['g_oneperm'], 1129); } } $this->lang->loadLanguageFile(array('admin_permissions'), 'members'); //----------------------------------------- // Some other generic fields //----------------------------------------- $promotion_a = '-1'; // id $promotion_b = '-1'; // posts if ($this->request['g_promotion_id'] and $this->request['g_promotion_id'] > 0) { $promotion_a = $this->request['g_promotion_id']; $promotion_b = $this->request['g_promotion_posts']; } if ($this->request['g_attach_per_post'] and $this->request['g_attach_max'] > 0) { if ($this->request['g_attach_per_post'] > $this->request['g_attach_max']) { $this->registry->output->global_message = $this->lang->words['g_pergreater']; $this->_groupForm('edit'); return; } } $this->request['p_max'] = str_replace(":", "", $this->request['p_max']); $this->request['p_width'] = str_replace(":", "", $this->request['p_width']); $this->request['p_height'] = str_replace(":", "", $this->request['p_height']); $this->request['g_attach_max'] = intval($this->request['g_attach_max']); $this->request['g_attach_per_post'] = intval($this->request['g_attach_per_post']); $this->request['p_max'] = intval($this->request['p_max']); $sig_limits = array($this->request['use_signatures'], $this->request['max_images'], $this->request['max_dims_x'], $this->request['max_dims_y'], $this->request['max_urls'], $this->request['max_lines']); //----------------------------------------- // Set the db array //----------------------------------------- $db_string = array('g_view_board' => intval($this->request['g_view_board']), 'g_mem_info' => intval($this->request['g_mem_info']), 'g_can_add_friends' => intval($this->request['g_can_add_friends']), 'g_use_search' => intval($this->request['g_use_search']), 'g_edit_profile' => intval($this->request['g_edit_profile']), 'g_use_pm' => intval($this->request['g_use_pm']), 'g_pm_perday' => intval($this->request['g_pm_perday']), 'g_is_supmod' => intval($this->request['g_is_supmod']), 'g_access_cp' => intval($this->request['g_access_cp']), 'g_title' => trim($this->request['g_title']), 'g_access_offline' => intval($this->request['g_access_offline']), 'g_dname_changes' => intval($this->request['g_dname_changes']), 'g_dname_date' => intval($this->request['g_dname_date']), 'prefix' => trim(IPSText::safeslashes($_POST['prefix'])), 'suffix' => trim(IPSText::safeslashes($_POST['suffix'])), 'g_hide_from_list' => intval($this->request['g_hide_from_list']), 'g_perm_id' => $new_perm_set_id ? $new_perm_set_id : implode(",", $this->request['permid']), 'g_icon' => trim(IPSText::safeslashes($_POST['g_icon'])), 'g_attach_max' => $this->request['g_attach_max'] == '' ? 0 : intval($this->request['g_attach_max']), 'g_max_messages' => intval($this->request['g_max_messages']), 'g_max_mass_pm' => intval($this->request['g_max_mass_pm']), 'g_pm_flood_mins' => intval($this->request['g_pm_flood_mins']), 'g_search_flood' => intval($this->request['g_search_flood']), 'g_promotion' => $promotion_a . '&' . $promotion_b, 'g_photo_max_vars' => $this->request['p_max'] . ':' . $this->request['p_width'] . ':' . $this->request['p_height'], 'g_dohtml' => intval($this->request['g_dohtml']), 'g_bypass_badwords' => intval($this->request['g_bypass_badwords']), 'g_can_msg_attach' => intval($this->request['g_can_msg_attach']), 'g_attach_per_post' => intval($this->request['g_attach_per_post']), 'g_rep_max_positive' => intval($this->request['g_rep_max_positive']), 'g_rep_max_negative' => intval($this->request['g_rep_max_negative']), 'g_signature_limits' => implode(':', $sig_limits), 'g_hide_online_list' => intval($this->request['g_hide_online_list']), 'g_displayname_unit' => intval($this->request['g_displayname_unit']), 'g_sig_unit' => intval($this->request['g_sig_unit']), 'g_max_notifications' => intval($this->request['g_max_notifications']), 'g_max_bgimg_upload' => intval($this->request['g_max_bgimg_upload']), 'g_bitoptions' => IPSBWOPtions::freeze($this->request, 'groups', 'global')); $this->DB->setDataType('g_title', 'string'); //----------------------------------------- // Ok? Load interface and child classes //----------------------------------------- IPSLib::loadInterface('admin/group_form.php'); $_groupPlugins = array(); foreach (IPSLib::getEnabledApplications() as $app_dir => $app_data) { if (is_file(IPSLib::getAppDir($app_dir) . '/extensions/admin/group_form.php')) { $_class = IPSLib::loadLibrary(IPSLib::getAppDir($app_dir) . '/extensions/admin/group_form.php', 'admin_group_form__' . $app_dir, $app_dir); $_groupPlugins[$_class] = new $_class($this->registry); $remote = $_groupPlugins[$_class]->getForSave(); $db_string = array_merge($db_string, $remote); } } //----------------------------------------- // Editing...do an update //----------------------------------------- if ($type == 'edit') { $this->DB->update('groups', $db_string, 'g_id=' . $group_id); //----------------------------------------- // Update moderator table too //----------------------------------------- $this->DB->update('moderators', array('group_name' => $db_string['g_title']), 'group_id=' . $group_id); $this->cache->rebuildCache('moderators', 'forums'); ipsRegistry::getClass('adminFunctions')->saveAdminLog(sprintf($this->lang->words['g_editedlog'], $db_string['g_title'])); $this->registry->output->global_message = $this->lang->words['g_edited']; } else { $this->DB->insert('groups', $db_string); $group_id = $this->DB->getInsertId(); ipsRegistry::getClass('adminFunctions')->saveAdminLog(sprintf($this->lang->words['g_addedlog'], $db_string['g_title'])); $this->registry->output->global_message = $this->lang->words['g_added']; } $this->rebuildGroupCache(); //----------------------------------------- // Post save callbacks //----------------------------------------- if (count($_groupPlugins)) { foreach ($_groupPlugins as $_className => $_object) { if (method_exists($_object, 'postSave')) { $_object->postSave($group_id); } } } if ($new_perm_set_id) { $from = ''; if ($type == 'edit' and $db_string['g_access_cp'] and !$oldGroup['g_access_cp'] or $type == 'add' and $db_string['g_access_cp']) { //----------------------------------------- // Do they already have restrictions? //----------------------------------------- $test = $this->DB->buildAndFetch(array('select' => 'row_id', 'from' => 'admin_permission_rows', 'where' => "row_id_type='group' AND row_id=" . $group_id)); if (!$test['row_id']) { $from = '&_from=group-' . $group_id; } } $this->registry->output->global_message = $this->lang->words['per_saved']; $this->registry->output->silentRedirectWithMessage($this->settings['base_url'] . 'module=groups&section=permissions&do=edit_set_form' . $from . '&id=' . $new_perm_set_id); } else { if ($type == 'edit' and $db_string['g_access_cp'] and !$oldGroup['g_access_cp'] or $type == 'add' and $db_string['g_access_cp']) { //----------------------------------------- // Do they already have restrictions? //----------------------------------------- $test = $this->DB->buildAndFetch(array('select' => 'row_id', 'from' => 'admin_permission_rows', 'where' => "row_id_type='group' AND row_id=" . $group_id)); if (!$test['row_id']) { $this->registry->output->html .= $this->html->groupAdminConfirm($group_id); } } $this->_mainScreen(); } }
/** * Save member * * @param int Member key: Either Array, ID or email address. If it's an array, it must be in the format: * array( 'core' => array( 'field' => 'member_id', 'value' => 1 ) ) - useful for passing custom fields through * @param array Fields to save in the following format: array( 'members' => array( 'email' => '*****@*****.**', * 'joined' => time() ), * 'extendedProfile' => array( 'signature' => 'My signature' ) ); * Tables: members, pfields_content, profile_portal. * You can also use the aliases: 'core [members]', 'extendedProfile [profile_portal]', and 'customFields [pfields_content]' * @return boolean True if the save was successful * * Exception Error Codes: * NO_DATA : No data to save * NO_VALID_KEY : No valid key to save * NO_AUTO_LOAD : Could not autoload the member as she does not exist * INCORRECT_TABLE : Table one is attempting to save to does not exist * NO_MEMBER_GROUP_ID: Member group ID is in the array but blank */ public static function save($member_key, $save = array()) { $member_id = 0; $member_email = ''; $member_field = ''; $_updated = 0; $bitWiseFields = ipsRegistry::fetchBitWiseOptions('global'); $member_k_array = array('members' => array(), 'pfields_content' => array(), 'profile_portal' => array()); $_tables = array_keys($save); $_MEMBERKEY = 'member_id'; $_MEMBERVALUE = $member_key; //----------------------------------------- // Test... //----------------------------------------- if (!is_array($save) or !count($save)) { throw new Exception('NO_DATA'); } //----------------------------------------- // ID or email? //----------------------------------------- if (!is_array($member_key)) { if (strstr($member_key, '@')) { $_MEMBERKEY = 'email'; if (IPSText::mbstrlen($member_key) > 150) { throw new Exception('NO_VALID_KEY'); } $member_k_array['members'] = array('field' => 'email', 'value' => "'" . ipsRegistry::instance()->DB()->addSlashes(strtolower($member_key)) . "'"); //----------------------------------------- // Check to see if we've got more than the core // table to save on. //----------------------------------------- $_got_more_than_core = FALSE; foreach ($_tables as $table) { if (isset(self::$remap[$table])) { $table = self::$remap[$table]; } if ($table != 'members') { $_got_more_than_core = TRUE; break; } } if ($_got_more_than_core === TRUE) { /* Get the ID */ $_memberTmp = self::load($member_key, 'core'); if ($_memberTmp['member_id']) { $member_k_array['pfields_content'] = array('field' => 'member_id', 'value' => $_memberTmp['member_id']); $member_k_array['profile_portal'] = array('field' => 'pp_member_id', 'value' => $_memberTmp['member_id']); } else { throw new Exception("NO_AUTO_LOAD"); } } } else { $member_k_array['members'] = array('field' => 'member_id', 'value' => intval($member_key)); $member_k_array['pfields_content'] = array('field' => 'member_id', 'value' => intval($member_key)); $member_k_array['profile_portal'] = array('field' => 'pp_member_id', 'value' => intval($member_key)); self::_updateCache($member_key, $save); } } else { $_member_k_array = $member_k_array; foreach ($member_key as $table => $data) { if (isset(self::$remap[$table])) { $table = self::$remap[$table]; } if (!in_array($table, array_keys($_member_k_array))) { throw new Exception('INCORRECT_TABLE'); } $member_k_array[$table] = $data; } } //----------------------------------------- // Test... //----------------------------------------- if (!is_array($member_k_array) or !count($member_k_array)) { throw new Exception('NO_DATA'); } //----------------------------------------- // Now save... //----------------------------------------- foreach ($save as $table => $data) { if (isset(self::$remap[$table])) { $table = self::$remap[$table]; } if ($table == 'profile_portal') { $data[$member_k_array[$table]['field']] = $member_k_array[$table]['value']; //----------------------------------------- // Does row exist? //----------------------------------------- $check = ipsRegistry::DB()->buildAndFetch(array('select' => 'pp_member_id', 'from' => 'profile_portal', 'where' => 'pp_member_id=' . $data['pp_member_id'])); if (!$check['pp_member_id']) { ipsRegistry::DB()->insert($table, $data); } else { ipsRegistry::DB()->update($table, $data, 'pp_member_id=' . $data['pp_member_id']); } } else { if ($table == 'pfields_content') { $data[$member_k_array[$table]['field']] = $member_k_array[$table]['value']; //----------------------------------------- // Does row exist? //----------------------------------------- $check = ipsRegistry::DB()->buildAndFetch(array('select' => 'member_id', 'from' => 'pfields_content', 'where' => 'member_id=' . $data['member_id'])); ipsRegistry::DB()->setDataType(array_keys($data), 'string'); if (!$check['member_id']) { ipsRegistry::DB()->insert($table, $data); } else { ipsRegistry::DB()->update($table, $data, 'member_id=' . $data['member_id']); } } else { if ($table == 'members') { /* Make sure we have a value for member_group_id if passed */ if (isset($data['member_group_id']) and !$data['member_group_id']) { throw new Exception("NO_MEMBER_GROUP_ID"); } /* Some stuff that can end up here */ unset($data['_canBeIgnored']); /* Bitwise options */ if (is_array($bitWiseFields['members'])) { $_freeze = array(); foreach ($bitWiseFields['members'] as $field) { if (isset($data[$field])) { /* Add to freezeable array */ $_freeze[$field] = $data[$field]; /* Remove it from the fields to save to DB */ unset($data[$field]); } } if (count($_freeze)) { $data['members_bitoptions'] = IPSBWOptions::freeze($_freeze, 'members', 'global'); } } if (isset($data['members_display_name']) and $data['members_display_name']) { if (IPSText::mbstrlen($data['members_display_name']) > 255) { throw new Exception('NO_VALID_KEY'); } $data['members_l_display_name'] = strtolower($data['members_display_name']); $data['members_seo_name'] = IPSText::makeSeoTitle($data['members_display_name']); } if (isset($data['name']) and $data['name']) { if (IPSText::mbstrlen($data['name']) > 255) { throw new Exception('NO_VALID_KEY'); } $data['members_l_username'] = strtolower($data['name']); } ipsRegistry::DB()->setDataType(array('name', 'title', 'members_l_username', 'members_display_name', 'members_l_display_name', 'members_seo_name'), 'string'); ipsRegistry::DB()->setDataType(array('msg_count_total', 'msg_count_new', 'members_bitoptions'), 'int'); } ipsRegistry::DB()->update($table, $data, $member_k_array[$table]['field'] . '=' . $member_k_array[$table]['value']); } } $_updated += ipsRegistry::instance()->DB()->getAffectedRows(); } //----------------------------------------- // If member login key is updated during // session creation, this causes fatal error //----------------------------------------- if (is_object(ipsRegistry::member())) { $save[$_MEMBERKEY] = $_MEMBERVALUE; IPSLib::runMemberSync('onProfileUpdate', $save); } return $_updated > 0 ? TRUE : FALSE; }
/** * Run a mysql query and display results * * @param string $sql The query to run * @return @e void */ public function sqlViewResults($sql) { /* INIT */ $limit = 50; $pages = ""; $the_queries = array(); $tableName = ''; $truncated = array(); /* Title Map */ $map = array('processes' => $this->lang->words['my_processes'], 'runtime' => $this->lang->words['my_runtime'], 'system' => $this->lang->words['my_sysvar']); /* Figure out the title */ if (!empty($map[$this->request['do']])) { $tbl_title = $map[$this->request['do']]; $man_query = 0; } else { $tbl_title = $this->lang->words['my_manual']; $man_query = 1; } /* Turn off error die */ $this->DB->return_die = 1; /* Split up multiple queries */ $the_queries = array(); if (strstr($sql, ";")) { $queries = preg_split("/;[\r\n|\n]+/", $sql, -1, PREG_SPLIT_NO_EMPTY); foreach ($queries as $query) { if (substr($query, -1, 1) == ";") { $query = substr($query, 0, -1); } $the_queries[]['sql'] = $query; } } else { if ($sql) { $the_queries[]['sql'] = $sql; } } $columns = array(); $rows = array(); $queryCntForArray = 0; if (!count($the_queries)) { $the_queries[$queryCntForArray] = ''; $columns[$queryCntForArray][] = $this->lang->words['manual_error']; $rows[$queryCntForArray][] = array('error' => $this->lang->words['manual_noquery']); } else { /* Loop through the queries and run them */ foreach ($the_queries as $key => $sql) { /* INIT */ $links = ""; $sql['sql'] = trim($sql['sql']); if (preg_match("#^SELECT(?:.*)\\s+?FROM\\s+?(\\S+?)(;?)(?:\\s|\$)#i", $sql['sql'], $match)) { $the_queries[$key]['tableName'] = $match[1]; } /* Check the sql */ $test_sql = str_replace("\\'", "", $sql['sql']); $apos_count = substr_count($test_sql, "'"); if ($apos_count % 2 != 0) { $columns[$queryCntForArray][] = $this->lang->words['manual_error']; $rows[$queryCntForArray][] = array('error' => $this->lang->words['manual_invalid'] . htmlspecialchars($sql['sql'])); unset($apos_count, $test_sql); continue; } unset($apos_count, $test_sql); /* Check for drop and flush */ if (preg_match("/^(DROP|FLUSH)/i", $sql['sql'])) { $columns[$queryCntForArray][] = $this->lang->words['manual_error']; $rows[$queryCntForArray][] = array('error' => $this->lang->words['manual_notallowed']); continue; } else { if (preg_match("/^(?!SELECT)/i", preg_replace("#\\s{1,}#s", "", $sql['sql'])) and preg_match("/admin_login_logs/i", preg_replace("#\\s{1,}#s", "", $sql['sql'])) || preg_match("/admin_permission_rows/i", preg_replace("#\\s{1,}#s", "", $sql['sql']))) { $columns[$queryCntForArray][] = $this->lang->words['manual_error']; $rows[$queryCntForArray][] = array('error' => $this->lang->words['manual_loginlogs']); continue; } } /* Setup for query */ $this->DB->error = ""; $this->DB->allow_sub_select = 1; /* Run the query */ $this->DB->query($sql['sql'], 1); /* Check for errors... */ if ($this->DB->error != "") { $columns[$queryCntForArray][] = $this->lang->words['manual_error']; $rows[$queryCntForArray][] = array('error' => htmlspecialchars($this->DB->error)); continue; } /* Build display rows */ $rows[$queryCntForArray] = array(); $columns[$queryCntForArray] = array(); if (preg_match("/^SELECT/i", $sql['sql']) or preg_match("/^SHOW/i", $sql['sql']) or preg_match("/^EXPLAIN/i", $sql['sql'])) { /* Sort out the pages and stuff, auto limit if need be */ if (!preg_match("/^EXPLAIN/i", $sql['sql']) && !preg_match("/^SHOW/i", $sql['sql']) and !preg_match("/LIMIT[ 0-9,]+\$/i", $sql['sql'])) { /* Start value */ $start = $this->request['st'] ? intval($this->request['st']) : 0; /* Count the number of rows we got back */ $rows_returned = $this->DB->getTotalRows(); /* Paginate the results */ if ($rows_returned > $limit) { $links = $this->registry->output->generatePagination(array('totalItems' => $rows_returned, 'itemsPerPage' => $limit, 'currentStartValue' => $start, 'baseUrl' => "{$this->settings['base_url']}{$this->form_code}&do=runsql&query=" . urlencode($sql['sql']))); /* Reformat the query with a LIMIT */ if (substr($sql['sql'], -1, 1) == ";") { $sql['sql'] = substr($sql['sql'], 0, -1); } $sql['sql'] .= " LIMIT {$start}, {$limit}"; /* Re-run with limit */ $this->DB->query($sql['sql'], 1); } } /* Create the columns array */ $fields = $this->DB->getResultFields(); $cnt = count($fields); for ($i = 0; $i < $cnt; $i++) { $columns[$queryCntForArray][] = $fields[$i]->name; } /* Populate the rows array */ while ($r = $this->DB->fetch()) { /* Loop through the results and add to row */ $row = array(); for ($i = 0; $i < $cnt; $i++) { if ($man_query == 1) { if (IPSText::mbstrlen($r[$fields[$i]->name]) > 200 and !preg_match("/^SHOW/i", $sql['sql'])) { if (!$this->request['notruncate']) { $r[$fields[$i]->name] = IPSText::truncate($r[$fields[$i]->name], 200) . '...'; } $truncated[] = $fields[$i]->name; } } if (!$this->request['notruncate'] or strlen($r[$fields[$i]->name]) < 201) { $row[] = nl2br(htmlspecialchars(wordwrap($r[$fields[$i]->name], 50, "\n", 1))); } else { $row[] = htmlspecialchars($r[$fields[$i]->name]); } } /* Add to output array */ $rows[$queryCntForArray][] = $row; } } else { $columns[$queryCntForArray][] = ''; $rows[$queryCntForArray][] = array($this->lang->words['query_executed_successfully']); } $this->DB->freeResult(); $queryCntForArray++; } } if (count($the_queries) == 1 && $the_queries[0]['tableName']) { $this->registry->output->extra_nav[] = array("{$this->settings['base_url']}{$this->form_code}&do=runsql&query=" . urlencode("SELECT * FROM {$the_queries[0]['tableName']}"), $the_queries[0]['tableName']); } /* Output */ $this->registry->output->html .= $this->html->sqlViewResults($the_queries, $columns, $rows, $links, $truncated); }
/** * Post a reply * Very simply posts a reply. Simple. * * Usage: * $post->setFopicID(1); * $post->setTopicID(5); * $post->setPostID(100); * $post->setAuthor( $member ); * * $post->setPostContent( "Hello [b]there![/b]" ); * # Optional: No bbcode, etc parsing will take place * # $post->setPostContentPreFormatted( "Hello <b>there!</b>" ); * $post->editPost(); * * Exception Error Codes: * NO_TOPIC_ID : No topic ID set * NO_FORUM_ID : No forum ID set * NO_AUTHOR_SET : No Author set * NO_CONTENT : No post content set * CONTENT_TOO_LONG : Post is too long * NO_SUCH_TOPIC : No such topic * NO_SUCH_FORUM : No such forum * NO_REPLY_PERM : Author cannot reply to this topic * TOPIC_LOCKED : The topic is locked * NO_REPLY_POLL : Cannot reply to this poll only topic * TOPIC_LOCKED : The topic is locked * NO_REPLY_POLL : This is a poll only topic * NO_POST_FORUM : Unable to post in that forum * FORUM_LOCKED : Forum read only * * @access public * @return mixed */ public function editPost() { //----------------------------------------- // Set up //----------------------------------------- $topic_id = intval($this->getTopicID()); $forum_id = intval($this->getForumID()); //----------------------------------------- // Global checks and functions //----------------------------------------- try { $this->globalSetUp(); } catch (Exception $error) { $this->_postErrors = $error->getMessage(); } if (!$this->getPostContent() and !$this->getPostContentPreFormatted()) { $this->_postErrors = 'NO_CONTENT'; } //----------------------------------------- // Get topic //----------------------------------------- try { $topic = $this->editSetUp(); } catch (Exception $error) { $this->_postErrors = $error->getMessage(); } //----------------------------------------- // Parse the post, and check for any errors. //----------------------------------------- $post = $this->compilePostData(); //----------------------------------------- // Do we have a valid post? //----------------------------------------- if (strlen(trim(IPSText::removeControlCharacters(IPSText::br2nl($post['post'])))) < 1) { $this->_postErrors = 'NO_CONTENT'; } if (IPSText::mbstrlen($postContent) > $this->settings['max_post_length'] * 1024) { $this->_postErrors = 'CONTENT_TOO_LONG'; } //----------------------------------------- // Ajax specifics //----------------------------------------- if ($this->getIsAjax() === TRUE) { # Prevent polls from being edited $this->can_add_poll = 0; # Prevent titles from being edited $this->edit_title = 0; # Set Settings $this->setSettings(array('enableSignature' => $this->_originalPost['use_sig'] ? 1 : 0, 'enableEmoticons' => $this->_originalPost['use_emo'] ? 1 : 0, 'post_htmlstatus' => intval($this->_originalPost['post_htmlstate']))); $this->request['iconid'] = $this->_originalPost['icon_id']; if (!$this->getAuthor('g_append_edit')) { $this->request['add_edit'] = ($this->_originalPost['append_edit'] or !$this->getAuthor('g_append_edit') ? 1 : 0); } } //----------------------------------------- // Compile the poll //----------------------------------------- if ($this->can_add_poll) { //----------------------------------------- // Load the poll from the DB //----------------------------------------- $this->poll_data = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'polls', 'where' => "tid=" . $topic['tid'])); $this->DB->execute(); $this->poll_answers = $this->poll_data['choices'] ? unserialize(stripslashes($this->poll_data['choices'])) : array(); } //----------------------------------------- // Compile the poll //----------------------------------------- $this->poll_questions = $this->compilePollData(); if ($this->_postErrors != "" or $this->getIsPreview() === TRUE) { //----------------------------------------- // Show the form again //----------------------------------------- return FALSE; } //----------------------------------------- // Grab the edit time //----------------------------------------- $time = ipsRegistry::getClass('class_localization')->getDate(time(), 'LONG'); //----------------------------------------- // Reset some data //----------------------------------------- $post['ip_address'] = $this->_originalPost['ip_address']; $post['topic_id'] = $this->_originalPost['topic_id']; $post['author_id'] = $this->_originalPost['author_id']; $post['post_date'] = $this->_originalPost['post_date']; $post['author_name'] = $this->_originalPost['author_name']; $post['queued'] = $this->_originalPost['queued']; $post['edit_time'] = time(); $post['edit_name'] = $this->getAuthor('members_display_name'); //----------------------------------------- // If the post icon has changed, update the topic post icon //----------------------------------------- if ($this->_originalPost['new_topic'] == 1) { if ($post['icon_id'] != $this->_originalPost['icon_id']) { $this->DB->update('topics', array('icon_id' => $post['icon_id']), 'tid=' . $topic['tid']); } } //----------------------------------------- // Update open and close times //----------------------------------------- if ($this->_originalPost['new_topic'] == 1) { $times = array(); if ($this->can_set_open_time and $this->times['open']) { $times['topic_open_time'] = intval($this->times['open']); if ($topic['topic_open_time'] and $this->times['open']) { $times['state'] = "closed"; if (time() > $topic['topic_open_time']) { if (time() < $topic['topic_close_time']) { $times['state'] = "open"; } } } if (!$this->times['open'] and $topic['topic_open_time']) { if ($topic['state'] == 'closed') { $times['state'] = 'open'; } } } if ($this->can_set_close_time and $this->times['close']) { $times['topic_close_time'] = intval($this->times['close']); //----------------------------------------- // Was a close time, but not now? //----------------------------------------- if (!$this->times['close'] and $topic['topic_close_time']) { if ($topic['state'] == 'closed') { $times['state'] = 'open'; } } } if (count($times)) { $this->DB->update('topics', $times, "tid=" . $topic['tid']); } } //----------------------------------------- // Update poll //----------------------------------------- if ($this->can_add_poll) { if (is_array($this->poll_questions) and count($this->poll_questions)) { $poll_only = 0; if ($this->settings['ipb_poll_only'] and $this->request['poll_only'] == 1) { $poll_only = 1; } $poll_view_voters = !$this->poll_data['votes'] ? $this->request['poll_view_voters'] : $this->poll_data['poll_view_voters']; if ($topic['poll_state']) { $this->DB->update('polls', array('votes' => intval($this->poll_total_votes), 'choices' => addslashes(serialize($this->poll_questions)), 'poll_question' => IPSText::stripAttachTag($this->request['poll_question']), 'poll_only' => $poll_only, 'poll_view_voters' => intval($poll_view_voters)), 'tid=' . $topic['tid']); if ($this->poll_data['choices'] != serialize($this->poll_questions) or $this->poll_data['votes'] != intval($this->poll_total_votes)) { $this->DB->insert('moderator_logs', array('forum_id' => $this->getForumData('id'), 'topic_id' => $topic['tid'], 'post_id' => $this->_originalPost['pid'], 'member_id' => $this->getAuthor('member_id'), 'member_name' => $this->getAuthor('members_display_name'), 'ip_address' => $this->ip_address, 'http_referer' => my_getenv('HTTP_REFERER'), 'ctime' => time(), 'topic_title' => $topic['title'], 'action' => "Edited poll", 'query_string' => my_getenv('QUERY_STRING'))); } } else { $this->DB->insert('polls', array('tid' => $topic['tid'], 'forum_id' => $this->getForumData('id'), 'start_date' => time(), 'choices' => addslashes(serialize($this->poll_questions)), 'starter_id' => $this->getAuthor('member_id'), 'votes' => 0, 'poll_question' => IPSText::stripAttachTag($this->request['poll_question']), 'poll_only' => $poll_only, 'poll_view_voters' => intval($poll_view_voters))); $this->DB->insert('moderator_logs', array('forum_id' => $this->getForumData('id'), 'topic_id' => $topic['tid'], 'post_id' => $this->_originalPost['pid'], 'member_id' => $this->getAuthor('member_id'), 'member_name' => $this->getAuthor('members_display_name'), 'ip_address' => $this->ip_address, 'http_referer' => my_getenv('HTTP_REFERER'), 'ctime' => time(), 'topic_title' => $topic['title'], 'action' => "Added a poll to the topic titled '" . $this->request['poll_question'] . "'", 'query_string' => my_getenv('QUERY_STRING'))); $this->DB->update('topics', array('poll_state' => 1, 'last_vote' => 0, 'total_votes' => 0), 'tid=' . $topic['tid']); } } else { //----------------------------------------- // Remove the poll //----------------------------------------- $this->DB->buildAndFetch(array('delete' => 'polls', 'where' => "tid=" . $topic['tid'])); $this->DB->buildAndFetch(array('delete' => 'voters', 'where' => "tid=" . $topic['tid'])); $this->DB->update('topics', array('poll_state' => 0, 'last_vote' => 0, 'total_votes' => 0), 'tid=' . $topic['tid']); } } //----------------------------------------- // Update topic title? //----------------------------------------- if ($this->edit_title == 1) { //----------------------------------------- // Update topic title //----------------------------------------- if ($this->_topicTitle != "") { if ($this->_topicTitle != $topic['title'] or $this->_topicDescription != $topic['description'] or !$topic['title_seo']) { $this->DB->update('topics', array('title' => $this->_topicTitle, 'title_seo' => IPSText::makeSeoTitle($this->_topicTitle), 'description' => $this->_topicDescription), "tid=" . $topic['tid']); if ($topic['tid'] == $this->getForumData('last_id')) { $this->DB->update('forums', array('last_title' => $this->_topicTitle), 'id=' . $this->getForumData('id')); //ipsRegistry::getClass('class_forums')->updateForumCache(); } if ($this->moderator['edit_topic'] == 1 or $this->getAuthor('g_is_supmod') == 1) { $this->DB->insert('moderator_logs', array('forum_id' => $this->getForumData('id'), 'topic_id' => $topic['tid'], 'post_id' => $this->_originalPost['pid'], 'member_id' => $this->getAuthor('member_id'), 'member_name' => $this->getAuthor('members_display_name'), 'ip_address' => $this->ip_address, 'http_referer' => my_getenv('HTTP_REFERER'), 'ctime' => time(), 'topic_title' => $topic['title'], 'action' => "Edited topic title or description '{$topic['title']}' to '" . $this->_topicTitle . "' via post form", 'query_string' => my_getenv('QUERY_STRING'))); } } } } //----------------------------------------- // Reason for edit? //----------------------------------------- if ($this->moderator['edit_post'] or $this->getAuthor('g_is_supmod')) { $post['post_edit_reason'] = trim($this->request['post_edit_reason']); } //----------------------------------------- // Update the database (ib_forum_post) //----------------------------------------- $post['append_edit'] = 1; if ($this->getAuthor('g_append_edit')) { if ($this->request['add_edit'] != 1) { $post['append_edit'] = 0; } } $this->DB->force_data_type = array('post_edit_reason' => 'string'); $this->DB->update('posts', $post, 'pid=' . $this->_originalPost['pid']); if ($this->_originalPost['topic_firstpost']) { $pid = 0; $title = $r['title']; } else { $pid = serialize(array('pid' => $r['pid'], 'title' => $r['title'])); $title = ''; } /* Remove from the search index */ $this->registry->class_forums->removePostFromSearchIndex($post['topic_id'], $this->_originalPost['pid'], $topic['posts'] ? 0 : 1); /* Update the search index */ $topic_title = $this->_topicTitle ? $this->_topicTitle : $topic['title']; /* Add to cache */ IPSContentCache::update($this->_originalPost['pid'], 'post', $this->formatPostForCache($post['post'])); /* Upload Attachments */ $this->uploadAttachments($this->post_key, $this->_originalPost['pid']); //----------------------------------------- // Make attachments "permanent" //----------------------------------------- $this->makeAttachmentsPermanent($this->post_key, $this->_originalPost['pid'], 'post', array('topic_id' => $topic['tid'])); //----------------------------------------- // Make sure paperclip symbol is OK //----------------------------------------- $this->recountTopicAttachments($topic['tid']); //----------------------------------------- // Leave data for other apps //----------------------------------------- $this->setTopicData($topic); $this->setPostData(array_merge($this->_originalPost, $post)); return TRUE; }
/** * Saves the add/edit calendar event form * * @access public * @param string $type Either add or edit * @return void */ public function calendarEventSave($type = 'add') { /* INIT */ $read_perms = '*'; $end_day = ""; $end_month = ""; $end_year = ""; $end_date = ""; $event_ranged = 0; $event_repeat = 0; $can_edit = 0; $form_type = $this->request['formtype']; $event_id = intval($this->request['event_id']); $calendar_id = intval($this->request['calendar_id']); $allow_emoticons = $this->request['enableemo'] == 'yes' ? 1 : 0; $private_event = $this->request['e_type'] == 'private' ? 1 : 0; $event_title = trim($this->request['event_title']); $day = intval($this->request['e_day']); $month = intval($this->request['e_month']); $year = intval($this->request['e_year']); $end_day = intval($this->request['end_day']); $end_month = intval($this->request['end_month']); $end_year = intval($this->request['end_year']); $recur_unit = intval($this->request['recur_unit']); $event_tz = intval($this->request['event_tz']); $offset = 0; $event_all_day = 0; $event_calendar_id = intval($this->request['event_calendar_id']); $set_time = intval($this->request['set_times']); $hour_min = array(); if ($set_time) { $hour_min = strstr($this->request['event_timestart'], ":") ? explode(":", $this->request['event_timestart']) : 0; if (intval($hour_min[0]) < 0 || intval($hour_min[0]) > 23) { $hour_min[0] = 0; } if (intval($hour_min[1]) < 0 || intval($hour_min[1]) > 59) { $hour_min[1] = 0; } if ($hour_min[0] || $hour_min[1]) { $offset = $event_tz * 3600; } else { $hour_min = array(); $offset = 0; } } else { $event_all_day = 1; } $this->settings['max_post_length'] = $this->settings['max_post_length'] ? $this->settings['max_post_length'] : 2140000; /* Check Permissions */ if (!$this->memberData['member_id']) { $this->registry->output->showError('calendar_no_guests', 10412); } $this->calendarBuildPermissions($event_calendar_id); if (!$this->can_post) { $this->registry->output->showError('calendar_no_post_perm', 10413); } /* WHATDOWEDO? */ if ($type == 'add') { } else { /* Check ID */ if (!$event_id) { $this->registry->output->showError('calendar_event_not_found', 10414); } /* Get the event */ $this->DB->build(array('select' => '*', 'from' => 'cal_events', 'where' => "event_id={$event_id}")); $this->DB->execute(); if (!($event = $this->DB->fetch())) { $this->registry->output->showError('calendar_event_not_found', 10415); } /* Do we have permission to edit this event */ if ($this->memberData['member_id'] == $event['event_member_id']) { $can_edit = 1; } else { if ($this->memberData['g_is_supmod'] == 1) { $can_edit = 1; } } if ($can_edit != 1) { $this->registry->output->showError('calendar_no_edit_perm', 10416); } } /* Do we have a valid post? */ if (strlen(trim(IPSText::removeControlCharacters(IPSText::br2nl($_POST['Post'])))) < 1) { $this->registry->output->showError('calendar_post_too_short', 10417); } /* Check the post length */ if (IPSText::mbstrlen($_POST['Post']) > $this->settings['max_post_length'] * 1024) { $this->registry->output->showError('calendar_post_too_long', 10418); } /* Fix up the event title */ if (IPSText::mbstrlen($event_title) < 2 or !$event_title) { $this->registry->output->showError('calendar_no_title', 10419); } if (IPSText::mbstrlen($event_title) > 64) { $this->registry->output->showError('calendar_title_too_long', 10420); } /* Are we an admin, and have we set w/groups can see */ if ($this->memberData['g_access_cp']) { if (is_array($_POST['e_groups'])) { foreach ($this->cache->getCache('group_cache') as $gid => $groupCache) { if ($groupCache['g_access_cp']) { $_POST['e_groups'][] = $gid; } } $read_perms = implode(",", $_POST['e_groups']); } if ($read_perms == "") { $read_perms = '*'; } } /* Check dates: Range */ if ($form_type == 'range') { if ($end_year < $year) { $this->registry->output->showError('calendar_range_wrong', 10421); } if ($end_year == $year) { if ($end_month < $month) { $this->registry->output->showError('calendar_range_wrong', 10422); } if ($end_month == $month and $end_day <= $day) { $this->registry->output->showError('calendar_range_wrong', 10423); } } $_final_unix_from = gmmktime(0, 0, 0, $month, $day, $year) + $offset; // # Midday $_final_unix_to = gmmktime(23, 59, 59, $end_month, $end_day, $end_year) + $offset; // # End of the day $event_ranged = 1; $set_time = 0; $hour_min = array(); } elseif ($form_type == 'recur') { if ($this->request['recur_unit']) { $event_repeat = 1; } if ($end_year < $year) { $this->registry->output->showError('calendar_range_wrong', 10424); } if ($end_year == $year) { if ($end_month < $month) { $this->registry->output->showError('calendar_range_wrong', 10425); } if ($end_month == $month and $end_day <= $day) { $this->registry->output->showError('calendar_range_wrong', 10426); } } $hour = 0; $min = 0; if ($set_time) { if (is_array($hour_min)) { $hour = $hour_min[0]; $min = $hour_min[1]; } } $_final_unix_from = gmmktime($hour, $min, 0, $month, $day, $year) + $offset; $_final_unix_to = gmmktime($hour, $min, 0, $end_month, $end_day, $end_year) + $offset; # End of the day $event_recur = 1; } else { $hour = 0; $min = 0; if ($set_time) { if (is_array($hour_min)) { $hour = $hour_min[0]; $min = $hour_min[1]; } } $_final_unix_from = gmmktime($hour, $min, 0, $month, $day, $year) - $offset; $_final_unix_to = 0; } /* Do we have a sensible date? */ if (!checkdate($month, $day, $year)) { $this->registry->output->showError('calendar_invalid_date', 10427); } /* Post process the editor, now we have safe HTML and bbcode */ IPSText::getTextClass('bbcode')->parse_html = 0; IPSText::getTextClass('bbcode')->parse_smilies = intval($allow_emoticons); IPSText::getTextClass('bbcode')->parse_bbcode = 1; IPSText::getTextClass('bbcode')->parsing_section = 'calendar'; $this->request['Post'] = IPSText::getTextClass('editor')->processRawPost('Post'); $this->request['Post'] = IPSText::getTextClass('bbcode')->preDbParse($this->request['Post']); /* Event approved? */ $event_approved = $this->can_avoid_queue ? 1 : ($this->calendar_cache[$event_calendar_id]['cal_moderate'] ? 0 : 1); if ($private_event == 1) { $event_approved = 1; } /* Create new event */ if ($type == 'add') { /* Add it to the DB */ $this->DB->insert('cal_events', array('event_calendar_id' => $event_calendar_id, 'event_member_id' => $this->memberData['member_id'], 'event_content' => $this->request['Post'], 'event_title' => $event_title, 'event_smilies' => $allow_emoticons, 'event_perms' => $read_perms, 'event_private' => $private_event, 'event_approved' => $event_approved, 'event_unixstamp' => time(), 'event_recurring' => $recur_unit, 'event_tz' => $event_tz, 'event_timeset' => count($hour_min) > 0 ? intval($hour_min[0]) . ":" . intval($hour_min[1]) : 0, 'event_unix_from' => $_final_unix_from, 'event_unix_to' => $_final_unix_to, 'event_all_day' => $event_all_day)); /* Recache */ $this->calendarCallRecache(); /* Bounce */ if ($event_approved) { $this->registry->output->redirectScreen($this->lang->words['new_event_redirect'], $this->settings['base_url'] . "app=calendar&module=calendar&cal_id={$event_calendar_id}"); } else { $this->registry->output->redirectScreen($this->lang->words['new_event_mod'], $this->settings['base_url'] . "app=calendar&module=calendar&cal_id{$event_calendar_id}"); } } else { /* Update the database recored */ $this->DB->update('cal_events', array('event_calendar_id' => $event_calendar_id, 'event_content' => $this->request['Post'], 'event_title' => $event_title, 'event_smilies' => $allow_emoticons, 'event_perms' => $read_perms, 'event_private' => $private_event, 'event_approved' => $event_approved, 'event_unixstamp' => time(), 'event_recurring' => $recur_unit, 'event_tz' => $event_tz, 'event_timeset' => count($hour_min) > 0 ? intval($hour_min[0]) . ":" . intval($hour_min[1]) : 0, 'event_unix_from' => $_final_unix_from, 'event_unix_to' => $_final_unix_to, 'event_all_day' => $event_all_day), 'event_id=' . $event_id); /* Recache */ $this->calendarCallRecache(); /* Bounce */ if ($event_approved) { $this->registry->output->redirectScreen($this->lang->words['edit_event_redirect'], $this->settings['base_url'] . "app=calendar&module=calendar&cal_id={$event_calendar_id}&do=showevent&event_id={$event_id}"); } else { $this->registry->output->redirectScreen($this->lang->words['new_event_mod'], $this->settings['base_url'] . "app=calendar&module=calendar&cal_id={$event_calendar_id}"); } } }
/** * Authenticate the request * * @access public * @param string Username * @param string Email Address * @param string Password * @return boolean Authentication successful */ public function authenticate($username, $email_address, $password) { //----------------------------------------- // Set basic data //----------------------------------------- $send = array('act' => 'login', 'key' => $this->connectConfig['master_key'], 'password' => md5($password)); //----------------------------------------- // Load to check if we have master ID already //----------------------------------------- if ($username) { $_member = IPSMember::load($username, 'all', 'username'); } else { $_member = IPSMember::load($email_address, 'all', 'email'); } if ($_member['ipsconnect_id']) { $send['idType'] = 'id'; $send['id'] = $_member['ipsconnect_id']; } else { if ($username) { $send['idType'] = 'username'; $send['id'] = $username; } else { $send['idType'] = 'email'; $send['id'] = $email_address; } } //----------------------------------------- // Send API Call //----------------------------------------- $send['key'] = md5($send['key'] . $send['id']); $url = $this->connectConfig['master_url'] . '?' . http_build_query($send); $return = $this->cfm->getFileContents($url); $data = @json_decode($return, TRUE); if (!isset($data['connect_status']) or !$data['connect_status']) { $this->return_code = 'WRONG_AUTH'; return false; } //----------------------------------------- // If unsuccessful, return //----------------------------------------- if ($data['connect_status'] != 'SUCCESS') { $this->return_code = $data['connect_status']; if ($this->return_code == 'ACCOUNT_LOCKED') { $this->account_unlock = $data['connect_unlock']; /* @link http://community.invisionpower.com/resources/bugs.html/_/ip-board/ipsconnect-account-unlock-time-r40812 */ if ($data['connect_unlock_period']) { $this->settings['ipb_bruteforce_period'] = $data['connect_unlock_period']; } } if ($this->return_code == 'VALIDATING') { $this->revalidate_url = $data['connect_revalidate_url']; } return false; } //----------------------------------------- // Create or update member accordingly //----------------------------------------- $update = array(); $this->member_data = IPSMember::load($data['connect_id'], 'all', 'ipsconnect'); if (!isset($this->member_data['member_id']) and isset($_member['member_id'])) { $this->member_data = $_member; $update['ipsconnect_id'] = $data['connect_id']; } if (!isset($this->member_data['member_id'])) { if (IPSText::mbstrlen($data['connect_username']) > ipsRegistry::$settings['max_user_name_length']) { $data['connect_username'] = IPSText::mbsubstr($data['connect_username'], 0, ipsRegistry::$settings['max_user_name_length']); } $this->member_data = $this->createLocalMember(array('members' => array('name' => $data['connect_username'], 'members_display_name' => $data['connect_displayname'], 'email' => $email_address, 'password' => $password, 'ipsconnect_id' => $data['connect_id']))); } else { if ($this->member_data['name'] != $data['connect_username'] and !defined('CONNECT_NOSYNC_NAMES')) { $update['name'] = $data['connect_username']; } if ($this->member_data['members_display_name'] != $data['connect_displayname'] and !defined('CONNECT_NOSYNC_NAMES')) { $update['members_display_name'] = $data['connect_displayname']; } if ($this->member_data['email'] != $data['connect_email']) { $update['email'] = $data['connect_email']; } IPSMember::updatePassword($this->member_data['member_id'], md5($password)); } //----------------------------------------- // Privacy //----------------------------------------- $privacy = $this->member_data['g_hide_online_list'] || empty($this->settings['disable_anonymous']) && !empty($this->request['anonymous']) ? 1 : 0; $update['login_anonymous'] = intval($privacy) . '&1'; //----------------------------------------- // Update //----------------------------------------- if (!empty($update)) { IPSMember::save($this->member_data['member_id'], array('members' => $update)); } //----------------------------------------- // If this is ACP or cross domain, just log in without SSO // http://community.invisionpower.com/resources/bugs.html/_/ip-board/cross-domain-connect-logins-r41932 //----------------------------------------- $local = strtolower(@parse_url($this->settings['board_url'], PHP_URL_HOST)); $connect = strtolower(@parse_url($this->connectConfig['master_url'], PHP_URL_HOST)); if (strstr($local, '.') && !IPSLib::validateIPv4($local)) { $_domain = array(); foreach (array_reverse(explode('.', $local)) as $bit) { $_domain[] = $bit; if (!in_array($bit, array('aero', 'asia', 'biz', 'cat', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'jobs', 'mil', 'mobi', 'museum', 'name', 'net', 'org', 'pro', 'tel', 'travel', 'ac', 'ad', 'ae', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'as', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'bj', 'bl', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cc', 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'cr', 'cu', 'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'ee', 'eg', 'eh', 'er', 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh', 'gi', 'gl', 'gm', 'gn', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'io', 'iq', 'ir', 'is', 'it', 'je', 'jm', 'jo', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', 'lv', 'ly', 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mk', 'ml', 'mm', 'mn', 'mo', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'nc', 'ne', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'pa', 'pe', 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'ps', 'pt', 'pw', 'py', 'qa', 're', 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr', 'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tf', 'tg', 'th', 'tj', 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'tt', 'tv', 'tw', 'tz', 'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu', 'za', 'zm', 'zw'))) { break; } } $local = '.' . implode('.', array_reverse($_domain)); } if (strstr($connect, '.') && !IPSLib::validateIPv4($connect)) { $_domain = array(); foreach (array_reverse(explode('.', $connect)) as $bit) { $_domain[] = $bit; if (!in_array($bit, array('aero', 'asia', 'biz', 'cat', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'jobs', 'mil', 'mobi', 'museum', 'name', 'net', 'org', 'pro', 'tel', 'travel', 'ac', 'ad', 'ae', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'as', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'bj', 'bl', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cc', 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'cr', 'cu', 'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'ee', 'eg', 'eh', 'er', 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh', 'gi', 'gl', 'gm', 'gn', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'io', 'iq', 'ir', 'is', 'it', 'je', 'jm', 'jo', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', 'lv', 'ly', 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mk', 'ml', 'mm', 'mn', 'mo', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'nc', 'ne', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'pa', 'pe', 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'ps', 'pt', 'pw', 'py', 'qa', 're', 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr', 'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tf', 'tg', 'th', 'tj', 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'tt', 'tv', 'tw', 'tz', 'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu', 'za', 'zm', 'zw'))) { break; } } $connect = '.' . implode('.', array_reverse($_domain)); } if ($this->is_admin_auth or $this->is_password_check or $local != $connect) { $this->return_code = 'SUCCESS'; return; } //----------------------------------------- // And redirect to log us in centrally //----------------------------------------- $redirect = $this->request['referer'] ? $this->request['referer'] : $this->settings['board_url']; if (strpos($redirect, '?') === FALSE) { $redirect .= '?'; } $this->registry->output->silentRedirect($url . '&noparams=1&redirect=' . base64_encode($redirect) . '&redirectHash=' . md5($this->connectConfig['master_key'] . base64_encode($redirect))); }
/** * Set member based on IPS Connect * * @param array Data returned from IPS Connect * @return void */ protected function _handleIpsConnect($data) { if ($data['connect_status'] != 'SUCCESS') { return false; } $update = array(); $member = IPSMember::load($data['connect_id'], 'all,members_partial', 'ipsconnect'); if (!isset($member['member_id'])) { if (IPSText::mbstrlen($data['connect_username']) > ipsRegistry::$settings['max_user_name_length']) { $data['connect_username'] = IPSText::mbsubstr($data['connect_username'], 0, ipsRegistry::$settings['max_user_name_length']); } $member = IPSMember::create(array('members' => array('name' => $data['connect_username'], 'members_display_name' => $data['connect_displayname'], 'email' => $data['connect_email'], 'ipsconnect_id' => $data['connect_id'])), FALSE, TRUE, FALSE); } if (!$member['ipsconnect_id']) { $update['ipsconnect_id'] = $data['connect_id']; } if ($member['name'] != $data['connect_username'] and !defined('CONNECT_NOSYNC_NAMES')) { $update['name'] = $data['connect_username']; } if ($member['members_display_name'] != $data['connect_displayname'] and !defined('CONNECT_NOSYNC_NAMES')) { $update['members_display_name'] = $data['connect_displayname']; } if ($member['email'] != $data['connect_email']) { $update['email'] = $data['connect_email']; } if (!empty($update)) { IPSMember::save($member['member_id'], array('members' => $update)); } self::setMember($member['member_id']); if ($member['partial_member_id']) { $this->DB->delete('members_partial', "partial_member_id={$member['partial_member_id']}"); } }
/** * Builds an array of output for used in threaded view * * @access public * @param array $post * @param integer $depth * @return array **/ public function _threadedRenderListRow($post, $depth) { $post['depthguide'] = ""; $this->settings['post_showtext_notitle'] = 1; for ($i = 1; $i < $depth; $i++) { $post['depthguide'] .= $this->depth_guide[$i]; } // Last child? if ($depth > 0) { $last_id = count($this->structured_pids[$post['post_parent']]) - 1; if ($this->structured_pids[$post['post_parent']][$last_id] == $post['pid']) { $this->depth_guide[$depth] = '<img src="' . $this->settings['img_url'] . '/spacer.gif" alt="" width="20" height="16">'; $post['depthguide'] .= "<img src='" . $this->settings['img_url'] . "/to_post_no_children.gif' alt='-' />"; } else { $this->depth_guide[$depth] = '<img src="' . $this->settings['img_url'] . '/to_down_pipe.gif" alt="|" />'; $post['depthguide'] .= "<img src='" . $this->settings['img_url'] . "/to_post_with_children.gif' alt='-' />"; } } if (!$post['post_title']) { if ($this->settings['post_showtext_notitle']) { $post_text = IPSText::getTextClass('bbcode')->stripAllTags(strip_tags(IPSText::br2nl($post['post']))); if (IPSText::mbstrlen($post_text) > 50) { $post['post_title'] = IPSText::truncate($post_text, 50) . '...'; } else { $post['post_title'] = $post_text; } if (!trim($post['post_title'])) { $post['post_title'] = $this->lang->words['post_title_re'] . $this->topics->topic['title']; } } else { $post['post_title'] = $this->lang->words['post_title_re'] . $this->topics->topic['title']; } } $post['linked_name'] = IPSLib::makeProfileLink($post['author_name'], $post['author_id']); $post['formatted_date'] = $this->registry->class_localization->getDate($post['post_date'], 'LONG'); $post['new_post'] = 't_threaded_read'; if ($post['post_date'] > $this->topics->last_read_tid) { $post['new_post'] = 't_threaded_read'; } if (strstr($this->used_post_ids, ',' . $post['pid'] . ',')) { $post['_show_highlight'] = 1; } return $post; }
/** * Check for guest's name being in use * * @return @e void */ protected function _fixGuestName() { if (!$this->memberData['member_id']) { $this->request['UserName'] = trim($this->request['UserName']); $this->request['UserName'] = str_replace('<br />', '', $this->request['UserName']); $this->request['UserName'] = $this->request['UserName'] ? $this->request['UserName'] : $this->lang->words['global_guestname']; $this->request['UserName'] = IPSText::mbstrlen($this->request['UserName']) > $this->settings['max_user_name_length'] ? $this->lang->words['global_guestname'] : $this->request['UserName']; } }
/** * Parse search results * * @param array $r Search result * @return array $html Blocks of HTML */ public function parseAndFetchHtmlBlocks($rows) { /* Forum stuff */ $sub = false; $isVnc = false; $search_term = IPSSearchRegistry::get('in.clean_search_term'); $noPostPreview = IPSSearchRegistry::get('opt.noPostPreview'); $results = array(); $attachPids = array(); /* loop and process */ foreach ($rows as $id => $data) { /* Reset */ $pages = 0; /* Set up forum */ $forum = $this->registry->getClass('class_forums')->forum_by_id[$data['forum_id']]; $this->last_topic = $data['tid']; /* Various data */ $data['_last_post'] = $data['last_post']; $data['_longTitle'] = $data['content_title']; $data['_shortTitle'] = IPSText::mbstrlen(strip_tags($data['content_title'])) > 60 ? IPSText::truncate($data['content_title'], 60) : $data['content_title']; $data['last_poster'] = $data['last_poster_id'] ? IPSMember::buildDisplayData($data['last_poster_id']) : IPSMember::buildDisplayData(IPSMember::setUpGuest($this->settings['guest_name_pre'] . $data['last_poster_name'] . $this->settings['guest_name_suf'])); $data['starter'] = $data['starter_id'] ? IPSMember::makeProfileLink($data['starter_name'], $data['starter_id'], $data['seo_first_name']) : $this->settings['guest_name_pre'] . $data['starter_name'] . $this->settings['guest_name_suf']; //$data['last_post'] = $this->registry->getClass( 'class_localization')->getDate( $data['last_post'], 'SHORT' ); if (isset($data['post_date'])) { $data['_post_date'] = $data['post_date']; //$data['post_date'] = $this->registry->getClass( 'class_localization')->getDate( $data['post_date'], 'SHORT' ); } if ($this->registry->getClass('class_forums')->canQueuePosts($forum['id'])) { $data['posts'] += intval($data['topic_queuedposts']); } if ($this->registry->getClass('class_forums')->canSeeSoftDeletedPosts($forum['id'])) { $data['posts'] += intval($data['topic_deleted_posts']); } if ($data['posts']) { if (($data['posts'] + 1) % $this->settings['display_max_posts'] == 0) { $pages = ($data['posts'] + 1) / $this->settings['display_max_posts']; } else { $number = ($data['posts'] + 1) / $this->settings['display_max_posts']; $pages = ceil($number); } } if ($pages > 1) { for ($i = 0; $i < $pages; ++$i) { $real_no = $i * $this->settings['display_max_posts']; $page_no = $i + 1; if ($page_no == 4 and $pages > 4) { $data['pages'][] = array('last' => 1, 'st' => ($pages - 1) * $this->settings['display_max_posts'], 'page' => $pages, 'total' => $pages); break; } else { $data['pages'][] = array('last' => 0, 'st' => $real_no, 'page' => $page_no, 'total' => $pages); } } } /* For-matt some stuffs */ if (IPSSearchRegistry::get('opt.noPostPreview') != true) { if (!$data['cache_content']) { IPSText::getTextClass('bbcode')->parse_smilies = $data['use_emo']; IPSText::getTextClass('bbcode')->parse_html = ($forum['use_html'] and $this->caches['group_cache'][$data['member_group_id']]['g_dohtml'] and $data['post_htmlstate']) ? 1 : 0; IPSText::getTextClass('bbcode')->parse_nl2br = $data['post_htmlstate'] == 2 ? 1 : 0; IPSText::getTextClass('bbcode')->parse_bbcode = $forum['use_ibc']; IPSText::getTextClass('bbcode')->parsing_section = 'topics'; IPSText::getTextClass('bbcode')->parsing_mgroup = $data['member_group_id']; IPSText::getTextClass('bbcode')->parsing_mgroup_others = $data['mgroup_others']; $data['post'] = IPSText::getTextClass('bbcode')->preDisplayParse($data['post']); } else { $data['post'] = '<!--cached-' . gmdate('r', $data['cache_updated']) . '-->' . $data['cache_content']; } $data['post'] = IPSText::searchHighlight($data['post'], $search_term); } /* Has attachments */ if ($data['topic_hasattach']) { $attachPids[$data['pid']] = $data['post']; } $rows[$id] = $data; } /* Attachments */ if (count($attachPids) and IPSSearchRegistry::get('set.returnType') != 'tids') { /* Load attachments class */ if (!is_object($this->class_attach)) { $classToLoad = IPSLib::loadLibrary(IPSLib::getAppDir('core') . '/sources/classes/attach/class_attach.php', 'class_attach'); $this->class_attach = new $classToLoad($this->registry); $this->class_attach->type = 'post'; $this->class_attach->init(); } $attachHTML = $this->class_attach->renderAttachments($attachPids, array_keys($attachPids)); /* Now parse back in the rendered posts */ if (is_array($attachHTML) and count($attachHTML)) { foreach ($attachHTML as $id => $_data) { /* Get rid of any lingering attachment tags */ if (stristr($_data['html'], "[attachment=")) { $_data['html'] = IPSText::stripAttachTag($_data['html']); } $rows[$id]['post'] = $_data['html']; $rows[$id]['attachmentHtml'] = $_data['attachmentHtml']; } } } /* Go through and build HTML */ foreach ($rows as $id => $data) { /* Format content */ list($html, $sub) = $this->formatContent($data); $results[$id] = array('html' => $html, 'app' => $data['app'], 'type' => $data['type'], 'sub' => $sub, '_followData' => !empty($data['_followData']) ? $data['_followData'] : array()); } return $results; }
/** * Processes the registration form * * @return @e void */ public function registerProcessForm() { $this->_resetMember(); $form_errors = array(); $coppa = $this->request['coppa_user'] == 1 ? 1 : 0; $in_password = trim($this->request['PassWord']); $in_email = strtolower(trim($this->request['EmailAddress'])); /* Did we agree to the t&c? */ if (!$this->request['agree_tos']) { $form_errors['tos'] = array($this->lang->words['must_agree_to_terms']); } /* Custom profile field stuff */ $classToLoad = IPSLib::loadLibrary(IPS_ROOT_PATH . 'sources/classes/customfields/profileFields.php', 'customProfileFields'); $custom_fields = new $classToLoad(); $custom_fields->initData('edit'); $custom_fields->parseToSave($_POST, 'register'); /* Check */ if ($custom_fields->error_messages) { $form_errors['general'] = $custom_fields->error_messages; } /* Check the email address */ if (!$in_email or strlen($in_email) < 6 or !IPSText::checkEmailAddress($in_email)) { $form_errors['email'][$this->lang->words['err_invalid_email']] = $this->lang->words['err_invalid_email']; } if (trim($this->request['PassWord_Check']) != $in_password or !$in_password) { $form_errors['password'][$this->lang->words['passwords_not_match']] = $this->lang->words['passwords_not_match']; } /* There's no reason for this - http://community.invisionpower.com/resources/bugs.html/_/ip-board/registrations-limit-passwords-to-32-characters-for-no-apparent-reason-r37770 elseif ( strlen( $in_password ) < 3 ) { $form_errors['password'][$this->lang->words['pass_too_short']] = $this->lang->words['pass_too_short']; } elseif ( strlen( $in_password ) > 32 ) { $form_errors['password'][$this->lang->words['pass_too_long']] = $this->lang->words['pass_too_long']; } */ /* Check the username */ $user_check = IPSMember::getFunction()->cleanAndCheckName($this->request['members_display_name'], array(), 'name'); $disp_check = IPSMember::getFunction()->cleanAndCheckName($this->request['members_display_name'], array(), 'members_display_name'); if (is_array($user_check['errors']) && count($user_check['errors'])) { foreach ($user_check['errors'] as $key => $error) { $form_errors['dname'][$error] = isset($this->lang->words[$error]) ? $this->lang->words[$error] : $error; } } /* this duplicates username error above */ /*if( is_array( $disp_check['errors'] ) && count( $disp_check['errors'] ) ) { foreach( $disp_check['errors'] as $key => $error ) { $form_errors['dname'][ $error ] = isset($this->lang->words[ $error ]) ? $this->lang->words[ $error ] : $error; } }*/ /* Is this email addy taken? */ if (IPSMember::checkByEmail($in_email) == TRUE) { $form_errors['email'][$this->lang->words['reg_error_email_taken']] = $this->lang->words['reg_error_email_taken']; } /* Load handler... */ $classToLoad = IPSLib::loadLibrary(IPS_ROOT_PATH . 'sources/handlers/han_login.php', 'han_login'); $this->han_login = new $classToLoad($this->registry); $this->han_login->init(); $this->han_login->emailExistsCheck($in_email); if ($this->han_login->return_code and $this->han_login->return_code != 'METHOD_NOT_DEFINED' and $this->han_login->return_code != 'EMAIL_NOT_IN_USE') { $form_errors['email'][$this->lang->words['reg_error_email_taken']] = $this->lang->words['reg_error_email_taken']; } /* Are they banned [EMAIL]? */ if (IPSMember::isBanned('email', $in_email) === TRUE) { $form_errors['email'][$this->lang->words['reg_error_email_ban']] = $this->lang->words['reg_error_email_ban']; } /* Check the CAPTCHA */ if ($this->settings['bot_antispam_type'] != 'none') { if ($this->registry->getClass('class_captcha')->validate() !== TRUE) { $form_errors['general'][$this->lang->words['err_reg_code']] = $this->lang->words['err_reg_code']; } } /* Check the Q and A */ $qanda = intval($this->request['qanda_id']); $pass = true; if ($qanda) { $pass = false; $data = $this->DB->buildAndFetch(array('select' => '*', 'from' => 'question_and_answer', 'where' => 'qa_id=' . $qanda)); if ($data['qa_id']) { $answers = explode("\n", str_replace("\r", "", $data['qa_answers'])); if (count($answers)) { foreach ($answers as $answer) { $answer = trim($answer); if (IPSText::mbstrlen($answer) and mb_strtolower($answer) == mb_strtolower($this->request['qa_answer'])) { $pass = true; break; } } } } } else { //----------------------------------------- // Do we have any questions? //----------------------------------------- $data = $this->DB->buildAndFetch(array('select' => 'COUNT(*) as questions', 'from' => 'question_and_answer')); if ($data['questions']) { $pass = false; } } if (!$pass) { $form_errors['general'][$this->lang->words['err_q_and_a']] = $this->lang->words['err_q_and_a']; } /* CHECK 2: Any errors ? */ if (count($form_errors)) { $this->registerForm($form_errors); return; } /* Build up the hashes */ $mem_group = $this->settings['member_group']; /* Are we asking the member or admin to preview? */ if ($this->settings['reg_auth_type']) { $mem_group = $this->settings['auth_group']; } else { if ($coppa == 1) { $mem_group = $this->settings['auth_group']; } } /* Create member */ $member = array('name' => $this->request['members_display_name'], 'password' => $in_password, 'members_display_name' => $this->request['members_display_name'], 'email' => $in_email, 'member_group_id' => $mem_group, 'joined' => time(), 'ip_address' => $this->member->ip_address, 'time_offset' => $this->request['time_offset'], 'coppa_user' => $coppa, 'members_auto_dst' => intval($this->settings['time_dst_auto_correction']), 'allow_admin_mails' => intval($this->request['allow_admin_mail']), 'language' => $this->member->language_id); /* Spam Service */ $spamCode = 0; $_spamFlag = 0; if ($this->settings['spam_service_enabled']) { /* Query the service */ $spamCode = IPSMember::querySpamService($in_email); /* Action to perform */ $action = $this->settings['spam_service_action_' . $spamCode]; /* Perform Action */ switch ($action) { /* Proceed with registration */ case 1: break; /* Flag for admin approval */ /* Flag for admin approval */ case 2: $member['member_group_id'] = $this->settings['auth_group']; $this->settings['reg_auth_type'] = 'admin'; $_spamFlag = 1; break; /* Approve the account, but ban it */ /* Approve the account, but ban it */ case 3: $member['member_banned'] = 1; $member['bw_is_spammer'] = 1; $this->settings['reg_auth_type'] = ''; break; /* Deny registration */ /* Deny registration */ case 4: $this->registry->output->showError('spam_denied_account', '100x001', FALSE, '', 200); break; } } //----------------------------------------- // Create the account //----------------------------------------- $member = IPSMember::create(array('members' => $member, 'pfields_content' => $custom_fields->out_fields), FALSE, FALSE, FALSE); //----------------------------------------- // Login handler create account callback //----------------------------------------- $this->han_login->createAccount(array('member_id' => $member['member_id'], 'email' => $member['email'], 'joined' => $member['joined'], 'password' => $in_password, 'ip_address' => $this->member->ip_address, 'username' => $member['members_display_name'], 'name' => $member['name'], 'members_display_name' => $member['members_display_name'])); //----------------------------------------- // We'll just ignore if this fails - it shouldn't hold up IPB anyways //----------------------------------------- /*if ( $han_login->return_code AND ( $han_login->return_code != 'METHOD_NOT_DEFINED' AND $han_login->return_code != 'SUCCESS' ) ) { $this->registry->output->showError( 'han_login_create_failed', 2017, true ); }*/ //----------------------------------------- // Validation //----------------------------------------- $validate_key = md5(IPSMember::makePassword() . time()); $time = time(); if ($coppa != 1) { if ($this->settings['reg_auth_type'] == 'user' or $this->settings['reg_auth_type'] == 'admin' or $this->settings['reg_auth_type'] == 'admin_user') { //----------------------------------------- // We want to validate all reg's via email, // after email verificiation has taken place, // we restore their previous group and remove the validate_key //----------------------------------------- $this->DB->insert('validating', array('vid' => $validate_key, 'member_id' => $member['member_id'], 'real_group' => $this->settings['member_group'], 'temp_group' => $this->settings['auth_group'], 'entry_date' => $time, 'coppa_user' => $coppa, 'new_reg' => 1, 'ip_address' => $member['ip_address'], 'spam_flag' => $_spamFlag)); if ($this->settings['reg_auth_type'] == 'user' or $this->settings['reg_auth_type'] == 'admin_user') { /* Send out the email. */ $message = array('THE_LINK' => $this->registry->getClass('output')->buildSEOUrl("app=core&module=global§ion=register&do=auto_validate&uid=" . urlencode($member['member_id']) . "&aid=" . urlencode($validate_key), 'publicNoSession', 'false'), 'NAME' => $member['members_display_name'], 'MAN_LINK' => $this->registry->getClass('output')->buildSEOUrl("app=core&module=global§ion=register&do=05", 'publicNoSession', 'false'), 'EMAIL' => $member['email'], 'ID' => $member['member_id'], 'CODE' => $validate_key); IPSText::getTextClass('email')->setPlainTextTemplate(IPSText::getTextClass('email')->getTemplate("reg_validate", $this->member->language_id)); IPSText::getTextClass('email')->buildPlainTextContent($message); IPSText::getTextClass('email')->buildHtmlContent($message); IPSText::getTextClass('email')->subject = sprintf($this->lang->words['new_registration_email'], $this->settings['board_name']); IPSText::getTextClass('email')->to = $member['email']; IPSText::getTextClass('email')->sendMail(); $this->output = $this->registry->output->getTemplate('register')->showAuthorize($member); } else { if ($this->settings['reg_auth_type'] == 'admin') { $this->output = $this->registry->output->getTemplate('register')->showPreview($member); } } /* Only send new registration email if the member wasn't banned */ if ($this->settings['new_reg_notify'] and !$member['member_banned']) { $date = $this->registry->class_localization->getDate(time(), 'LONG', 1); IPSText::getTextClass('email')->getTemplate('admin_newuser'); IPSText::getTextClass('email')->buildMessage(array('DATE' => $date, 'LOG_IN_NAME' => $member['name'], 'EMAIL' => $member['email'], 'IP' => $member['ip_address'], 'DISPLAY_NAME' => $member['members_display_name'])); IPSText::getTextClass('email')->subject = sprintf($this->lang->words['new_registration_email1'], $this->settings['board_name']); IPSText::getTextClass('email')->to = $this->settings['email_in']; IPSText::getTextClass('email')->sendMail(); } $this->registry->output->setTitle($this->lang->words['reg_success'] . ' - ' . ipsRegistry::$settings['board_name']); $this->registry->output->addNavigation($this->lang->words['nav_reg'], ''); } else { /* We don't want to preview, or get them to validate via email. */ $stat_cache = $this->cache->getCache('stats'); if ($member['members_display_name'] and $member['member_id'] and !$this->caches['group_cache'][$member['member_group_id']]['g_hide_online_list']) { $stat_cache['last_mem_name'] = $member['members_display_name']; $stat_cache['last_mem_name_seo'] = IPSText::makeSeoTitle($member['members_display_name']); $stat_cache['last_mem_id'] = $member['member_id']; } $stat_cache['mem_count'] += 1; $this->cache->setCache('stats', $stat_cache, array('array' => 1)); /* Only send new registration email if the member wasn't banned */ if ($this->settings['new_reg_notify'] and !$member['member_banned']) { $date = $this->registry->class_localization->getDate(time(), 'LONG', 1); IPSText::getTextClass('email')->getTemplate('admin_newuser'); IPSText::getTextClass('email')->buildMessage(array('DATE' => $date, 'LOG_IN_NAME' => $member['name'], 'EMAIL' => $member['email'], 'IP' => $member['ip_address'], 'DISPLAY_NAME' => $member['members_display_name'])); IPSText::getTextClass('email')->subject = sprintf($this->lang->words['new_registration_email1'], $this->settings['board_name']); IPSText::getTextClass('email')->to = $this->settings['email_in']; IPSText::getTextClass('email')->sendMail(); } IPSCookie::set('pass_hash', $member['member_login_key'], 1); IPSCookie::set('member_id', $member['member_id'], 1); //----------------------------------------- // Fix up session //----------------------------------------- $privacy = $member['g_hide_online_list'] || empty($this->settings['disable_anonymous']) && !empty($this->request['Privacy']) ? 1 : 0; # Update value for onCompleteAccount call $member['login_anonymous'] = $privacy . '&1'; $this->member->sessionClass()->convertGuestToMember(array('member_name' => $member['members_display_name'], 'member_id' => $member['member_id'], 'member_group' => $member['member_group_id'], 'login_type' => $privacy)); IPSLib::runMemberSync('onCompleteAccount', $member); $this->registry->output->silentRedirect($this->settings['base_url'] . '&app=core&module=global§ion=login&do=autologin&fromreg=1'); } } else { /* This is a COPPA user, so lets tell them they registered OK and redirect to the form. */ $this->DB->insert('validating', array('vid' => $validate_key, 'member_id' => $member['member_id'], 'real_group' => $this->settings['member_group'], 'temp_group' => $this->settings['auth_group'], 'entry_date' => $time, 'coppa_user' => $coppa, 'new_reg' => 1, 'ip_address' => $member['ip_address'])); $this->registry->output->redirectScreen($this->lang->words['cp_success'], $this->settings['base_url'] . 'app=core&module=global&section=register&do=12'); } }
/** * Custom sort operation * * @param string A * @param string B * @return integer */ protected function _thisUsort($a, $b) { if (IPSText::mbstrlen($a['type']) == IPSText::mbstrlen($b['type'])) { return 0; } return IPSText::mbstrlen($a['type']) > IPSText::mbstrlen($b['type']) ? -1 : 1; }
/** * Clean a username or display name * * @access protected * @param string Name * @param string Field (name or members_display_name) * @return array array( 'name' => $cleaned_name, 'errors' => array() ) */ protected function _cleanName($name, $field = 'members_display_name') { $original = $name; $name = trim($name); if ($field == 'name') { // Commented out for bug report #15354 //$name = str_replace( '|', '|' , $name ); /* Remove multiple spaces */ $name = preg_replace("/\\s{2,}/", " ", $name); } //----------------------------------------- // Remove line breaks //----------------------------------------- if (ipsRegistry::$settings['usernames_nobr']) { $name = IPSText::br2nl($name); $name = str_replace("\n", "", $name); $name = str_replace("\r", "", $name); } //----------------------------------------- // Remove sneaky spaces //----------------------------------------- if (ipsRegistry::$settings['strip_space_chr']) { /* use hexdec to convert between '0xAD' and chr */ $name = IPSText::removeControlCharacters($name); } //----------------------------------------- // Trim after above ops //----------------------------------------- $name = trim($name); //----------------------------------------- // Test unicode name //----------------------------------------- $unicode_name = $this->_getUnicodeName($name); //----------------------------------------- // Do we have a name? //----------------------------------------- if ($field == 'name' or $field == 'members_display_name' and ipsRegistry::$settings['auth_allow_dnames']) { if (!$name or IPSText::mbstrlen($name) < 3 or IPSText::mbstrlen($name) > ipsRegistry::$settings['max_user_name_length']) { ipsRegistry::getClass('class_localization')->loadLanguageFile(array('public_register'), 'core'); $key = $field == 'members_display_name' ? 'reg_error_no_name' : 'reg_error_username_none'; $text = sprintf(ipsRegistry::getClass('class_localization')->words[$key], ipsRegistry::$settings['max_user_name_length']); //----------------------------------------- // Only show note about special chars when relevant //----------------------------------------- if (strpos($name, '&') !== false) { $text .= ipsRegistry::getClass('class_localization')->words['reg_error_no_name_spec']; } return array('name' => $original, 'errors' => array($text)); } } //----------------------------------------- // Blocking certain chars in username? //----------------------------------------- if (ipsRegistry::$settings['username_characters']) { $check_against = preg_quote(ipsRegistry::$settings['username_characters'], "/"); if (!preg_match("/^[" . $check_against . "]+\$/i", $name)) { return array('name' => $original, 'errors' => array(str_replace('{chars}', ipsRegistry::$settings['username_characters'], ipsRegistry::$settings['username_errormsg']))); } } //----------------------------------------- // Manually check against bad chars //----------------------------------------- if (strpos($unicode_name, '\') !== false or strpos($unicode_name, '&#quot;') !== false or strpos($unicode_name, '$') !== false or strpos($unicode_name, '&#lt;') !== false or strpos($unicode_name, '$') !== false or strpos($unicode_name, ']') !== false or strpos($unicode_name, '[') !== false or strpos($unicode_name, ',') !== false or strpos($unicode_name, '|') !== false or strpos($unicode_name, '&#gt;') !== false) { ipsRegistry::getClass('class_localization')->loadLanguageFile(array('public_register'), 'core'); return array('name' => $original, 'errors' => array(ipsRegistry::getClass('class_localization')->words['reg_error_chars'])); } return array('name' => $name, 'errors' => array()); }
/** * Check for guest's name being in use * * @access private * @return void **/ private function _check_guest_name() { /* is this even used anymore? I disabled it 'cos it was adding the prefix and suffix twice when using a 'found' name -- Matt */ if (!$this->memberData['member_id']) { $this->request['UserName'] = trim($this->request['UserName']); $this->request['UserName'] = str_replace('<br />', '', $this->request['UserName']); $this->request['UserName'] = $this->request['UserName'] ? $this->request['UserName'] : $this->lang->words['global_guestname']; $this->request['UserName'] = IPSText::mbstrlen($this->request['UserName']) > $this->settings['max_user_name_length'] ? $this->lang->words['global_guestname'] : $this->request['UserName']; } return; /*if( ! $this->memberData['member_id'] ) { $this->request['UserName'] = trim( $this->request['UserName'] ); $this->request['UserName'] = str_replace( '<br />', '', $this->request['UserName'] ); $this->request['UserName'] = $this->request['UserName'] ? $this->request['UserName'] : $this->lang->words['global_guestname'] ; $this->request['UserName'] = IPSText::mbstrlen( $this->request['UserName'] ) > $this->settings['max_user_name_length'] ? $this->lang->words['global_guestname'] : $this->request['UserName']; if ($this->request['UserName'] != $this->lang->words['global_guestname']) { $this->DB->build( array( 'select' => 'member_id, name, members_display_name, members_created_remote, email, member_group_id, member_login_key, ip_address, login_anonymous', 'from' => 'members', 'where' => 'members_l_username=\'' . trim( strtolower( $this->request['UserName'] ) ) . '\'' ) ); $this->DB->execute(); if ( $this->DB->getTotalRows() ) { $this->request['UserName'] = $this->settings['guest_name_pre'] . $this->request['UserName'] . $this->settings['guest_name_suf'] ; } } }*/ }
/** * Loop over the bbcode and make replacements as necessary * * @access public * @param string Current text * @param string [db|display] Current method to parse * @param mixed [optional] Only parse the selected code(s) * @return string Converted text */ public function parseBbcode($txt, $cur_method = 'db', $_code = null) { //----------------------------------------- // Pull out the non-replacable codes //----------------------------------------- if (!is_string($_code)) { $txt = $this->_storeNonParsed($txt, $cur_method); } //----------------------------------------- // We want preDbParse method called for shared // media for permission checking, so force it for now.. //----------------------------------------- if ($cur_method == 'db') { $this->_bbcodes[$cur_method]['sharedmedia'] = $this->_bbcodes['display']['sharedmedia']; $txt = preg_replace_callback('#(\\[code.*\\[/code\\])#is', array($this, '_checkForEmbeddedCode'), $txt); } //----------------------------------------- // Regular replacing //----------------------------------------- if (isset($this->_bbcodes[$cur_method]) and is_array($this->_bbcodes[$cur_method]) and count($this->_bbcodes[$cur_method])) { foreach ($this->_bbcodes[$cur_method] as $_bbcode) { //----------------------------------------- // Can this group use this bbcode? //----------------------------------------- if ($_bbcode['bbcode_groups'] != 'all' and $this->parsing_mgroup) { $pass = false; $groups = array_diff(explode(',', $_bbcode['bbcode_groups']), array('')); $mygroups = array($this->parsing_mgroup); if ($this->parsing_mgroup_others) { $mygroups = array_diff(array_merge($mygroups, explode(',', IPSText::cleanPermString($this->parsing_mgroup_others))), array('')); } foreach ($groups as $g_id) { if (in_array($g_id, $mygroups)) { $pass = true; break; } } if (!$pass) { continue; } } //----------------------------------------- // Reset our current position //----------------------------------------- $this->cur_pos = 0; //----------------------------------------- // Store teh tags //----------------------------------------- $_tags = array($_bbcode['bbcode_tag']); //----------------------------------------- // We'll also need to check for any aliases //----------------------------------------- if ($_bbcode['bbcode_aliases']) { $aliases = explode(',', trim($_bbcode['bbcode_aliases'])); if (is_array($aliases) and count($aliases)) { foreach ($aliases as $alias) { $_tags[] = trim($alias); } } } //----------------------------------------- // If we have a plugin, just pass off //----------------------------------------- if ($_bbcode['bbcode_php_plugin']) { /* Legacy issues */ if ($_bbcode['bbcode_php_plugin'] == 'defaults.php') { $file = IPS_ROOT_PATH . 'sources/classes/text/parser/bbcode/' . $_bbcode['bbcode_php_plugin']; $class = 'bbcode_plugin_' . IPSText::alphanumericalClean($_bbcode['bbcode_tag']); $method = "run"; } else { $file = IPS_ROOT_PATH . 'sources/classes/bbcode/custom/' . $_bbcode['bbcode_php_plugin']; $class = 'bbcode_' . IPSText::alphanumericalClean($_bbcode['bbcode_tag']); $method = "pre" . ucwords($cur_method) . "Parse"; } //----------------------------------------- // Are we only parsing one code? //----------------------------------------- if (is_array($_code)) { $good = false; foreach ($_tags as $_tag) { if (in_array($_tag, $_code)) { $good = true; break; // Got one, stop here } } if (!$good) { continue; } } else { if (is_string($_code)) { if (!in_array($_code, $_tags)) { continue; } } } $_key = md5($_bbcode['bbcode_tag']); //----------------------------------------- // Do we already have this plugin in our registry? //----------------------------------------- if (isset($this->plugins[$_key])) { //----------------------------------------- // Run the method if it exists //----------------------------------------- if (method_exists($this->plugins[$_key], $method)) { $_original = $txt; $txt = $this->plugins[$_key]->{$method}($txt, $method == 'run' ? $cur_method == 'db' ? 'html' : 'display' : 'bbcode'); if (!$txt) { $txt = $_original; } else { if ($this->plugins[$_key]->error) { $this->error = $this->plugins[$_key]->error; return $txt; } else { if ($this->plugins[$_key]->warning) { $this->warning = $this->plugins[$_key]->warning; } } } } } elseif (is_file($file)) { $_classname = IPSLib::loadLibrary($file, $class); //----------------------------------------- // Class we need exists //----------------------------------------- if (class_exists($_classname)) { //----------------------------------------- // New instance of class, store in plugin registry for use next time //----------------------------------------- $plugin = new $_classname($this->registry, $this); //$method = "pre" . ucwords($cur_method) . "Parse"; $this->plugins[md5($_bbcode['bbcode_tag'])] = $plugin; //----------------------------------------- // Method we need exists //----------------------------------------- if (method_exists($plugin, $method)) { $_original = $txt; $txt = $plugin->{$method}($txt, $method == 'run' ? $cur_method == 'db' ? 'html' : 'display' : 'bbcode'); if (!$txt) { $txt = $_original; } else { if ($plugin->error) { $this->error = $plugin->error; return $txt; } else { if ($plugin->warning) { $this->warning = $plugin->warning; } } } } } } //----------------------------------------- // When we run a plugin, we don't do any other processing "automatically". // Plugin is capable of doing what it wants that way. //----------------------------------------- continue; } //----------------------------------------- // Loop over this bbcode's tags //----------------------------------------- foreach ($_tags as $_tag) { //----------------------------------------- // Are we only parsing one code? //----------------------------------------- if (is_array($_code) and !in_array($_tag, $_code)) { continue; } else { if (is_string($_code) and $_tag != $_code) { continue; } } //----------------------------------------- // Infinite loop catcher //----------------------------------------- $_iteration = 0; //----------------------------------------- // Start building open tag //----------------------------------------- $open_tag = '[' . $_tag; //----------------------------------------- // Doz I can haz opin tag? Loopy loo //----------------------------------------- while (($this->cur_pos = stripos($txt, $open_tag, $this->cur_pos)) !== false) { //----------------------------------------- // Stop infinite loops //----------------------------------------- if ($_iteration > $this->settings['max_bbcodes_per_post']) { break; } $open_length = strlen($open_tag); //----------------------------------------- // Grab the new position to jump to //----------------------------------------- $new_pos = strpos($txt, ']', $this->cur_pos) ? strpos($txt, ']', $this->cur_pos) : $this->cur_pos + 1; //----------------------------------------- // Extract the option (like surgery) //----------------------------------------- $_option = ''; if ($_bbcode['bbcode_useoption']) { //----------------------------------------- // Is option optional? //----------------------------------------- if ($_bbcode['bbcode_optional_option']) { //----------------------------------------- // Does we haz it? //----------------------------------------- if (substr($txt, $this->cur_pos + strlen($open_tag), 1) == '=') { $open_length += 1; $_option = substr($txt, $this->cur_pos + $open_length, strpos($txt, ']', $this->cur_pos) - ($this->cur_pos + $open_length)); } else { if (strpos($txt, ']', $this->cur_pos) - ($this->cur_pos + $open_length) !== 0) { if (strpos($txt, ']', $this->cur_pos)) { $this->cur_pos = $new_pos; continue; } else { break; } } } } else { $open_length += 1; $_option = substr($txt, $this->cur_pos + $open_length, strpos($txt, ']', $this->cur_pos) - ($this->cur_pos + $open_length)); } } else { if (strpos($txt, ']', $this->cur_pos) - ($this->cur_pos + $open_length) !== 0) { if (strpos($txt, ']', $this->cur_pos)) { $this->cur_pos = $new_pos; continue; } } } $_iteration++; //----------------------------------------- // Protect against XSS //----------------------------------------- $_optionStrLen = IPSText::mbstrlen($_option); $_optionSlenstr = strlen($_option); $_option = $this->checkXss($_option, false, $_tag); if ($_option !== FALSE) { /* Not parsing URls? - Needs to be AFTER the FALSE check just above */ if (!empty($_bbcode['bbcode_no_auto_url_parse'])) { $_option = preg_replace("#(http|https|news|ftp)://#i", "\\1://", $_option); } //----------------------------------------- // If this is a single tag, that's it //----------------------------------------- if ($_bbcode['bbcode_single_tag']) { $txt = substr_replace($txt, $this->_bbcodeToHtml($_bbcode, $_option, ''), $this->cur_pos, $open_length + $_optionSlenstr + 1); } else { $close_tag = '[/' . $_tag . ']'; if (stripos($txt, $close_tag, $new_pos) !== false) { $_content = substr($txt, $this->cur_pos + $open_length + $_optionSlenstr + 1, stripos($txt, $close_tag, $this->cur_pos) - ($this->cur_pos + $open_length + $_optionSlenstr + 1)); if ($_bbcode['bbcode_useoption'] and $_bbcode['bbcode_optional_option'] and !$_option and !stristr($_bbcode['bbcode_replace'], '{option}')) { $_option = $_content; $_option = $this->checkXss($_option, false, $_tag); } /* Not parsing URls? */ if (!empty($_bbcode['bbcode_no_auto_url_parse'])) { $_content = preg_replace("#(http|https|news|ftp)://#i", "\\1://", $_content); } $txt = substr_replace($txt, $this->_bbcodeToHtml($_bbcode, $_option, $_content), $this->cur_pos, stripos($txt, $close_tag, $this->cur_pos) + strlen($close_tag) - $this->cur_pos); } else { //----------------------------------------- // If there's no close tag, no need to continue //----------------------------------------- break; } } } //----------------------------------------- // And reset current position to end of open tag // Bug 14744 - if we jump to $new_pos it can skip the opening of the next bbcode tag // when the replacement HTML is shorter than the full bbcode representation... //----------------------------------------- $this->cur_pos = stripos($txt, $open_tag) ? stripos($txt, $open_tag) : $this->cur_pos + 1; //$new_pos; if ($this->cur_pos > strlen($txt)) { break; } } } } } //----------------------------------------- // (c) (r) and (tm) //----------------------------------------- if ($cur_method == 'display' and $_code !== 'code' and $_code !== 'php' and $_code !== 'sql' and $_code !== 'xml') { $txt = str_ireplace("(c)", "©", $txt); $txt = str_ireplace("(tm)", "™", $txt); $txt = str_ireplace("(r)", "®", $txt); } //----------------------------------------- // And finally replace those bbcodes //----------------------------------------- if (!$_code) { $txt = $this->_parseNonParsed($txt, $cur_method); } //----------------------------------------- // Auto parse URLs (only if this is full sweep) //----------------------------------------- if (!$_code and $cur_method == 'display') { /* If we parse <a href='http://site.com'>http://site[color=red].com[/color]</a>, it breaks * @link http://community.invisionpower.com/tracker/issue-24318-colors-in-urls-as-names-breaks-them/ * Here we will extract <a></a> pairs, put in */ $_storedLinks = array(); $_counter = 0; while (preg_match('/<a href=\'(.+?)\'(.*?)>(.+?)<\\/a>/is', $txt, $matches)) { /* Is this a linked media URL? */ if ($this->settings['bbcode_automatic_media'] and isset($this->_bbcodes['display']['media']) and ($this->_bbcodes['display']['media']['bbcode_sections'] == 'all' or in_array($this->parsing_section, explode(',', $this->_bbcodes['display']['media']['bbcode_sections'])))) { $media = $this->cache->getCache('mediatag'); #href must match text (or has been shortened) and not a <a href="vid.com/4/">check this out!</a> style link if ($matches[1] == $matches[3] or strstr($matches[3], '...')) { if (is_array($media) and count($media)) { foreach ($media as $type => $r) { if (preg_match("#^" . $r['match'] . "\$#is", $matches[1])) { $this->cache->updateCacheWithoutSaving('_tmp_autoparse_media', 1); $_result = $this->parseBbcode('[media]' . $matches[1] . '[/media]', 'display', 'media'); $this->cache->updateCacheWithoutSaving('_tmp_autoparse_media', 0); $txt = str_replace($matches[0], $_result, $txt); $this->_mediaUrlConverted[] = $matches[1]; continue; } } } } } $_counter++; $_storedLinks[$_counter] = $matches[0]; $txt = str_replace($matches[0], '<!--LINKS_TEMP--' . $_counter . '-->', $txt); } /* Capture 'href="' and '</a>' as [URL] is now parsed first, we discard these in _autoParseUrls */ /** * @link http://community.invisionpower.com/tracker/issue-23726-parser-wrong-url-with-unicode-chars/ * I had to add the /u modifier to correct this. Previously, the first byte sequence of the word was matching \s. * @link http://community.invisionpower.com/tracker/issue-24684-posts-are-blankmissing/ * Reverting this fix as it's breaking in some environments - not really sure what we can do about this at this point */ //$opts = ( IPS_DOC_CHAR_SET == 'UTF-8' ) ? 'isu' : 'is'; if (!$this->parse_html) { $opts = "is"; $txt = preg_replace_callback('#(^|\\s|\\)|\\(|\\{|\\}|>|\\]|\\[|;|href=\\S)((http|https|news|ftp)://(?:[^<>\\)\\[\\"\\s]+|[a-zA-Z0-9/\\._\\-!&\\#;,%\\+\\?:=]+))(</a>)?#' . $opts, array($this, '_autoParseUrls'), $txt); } /* Now put back stored links */ foreach ($_storedLinks as $_inc => $_storedLink) { $txt = str_replace('<!--LINKS_TEMP--' . $_inc . '-->', $_storedLink, $txt); } } return $txt; }
/** * Recursively build up the tracked forums * * @access private * @param array Tracked forums * @param integer Forum id to start at * @param array Forum data thus far * @param integer Depth level * @return array Forums */ private function _showForumSubsRecurse($forums, $root, $forumArray = array(), $depth = 0) { if (is_array($this->registry->getClass('class_forums')->forum_cache[$root]) and count($this->registry->getClass('class_forums')->forum_cache[$root])) { foreach ($this->registry->getClass('class_forums')->forum_cache[$root] as $id => $forum) { if (in_array($id, array_keys($forums))) { //----------------------------------------- // Got perms to see this forum? //----------------------------------------- if (!$this->registry->getClass('class_forums')->forum_by_id[$forum['id']]) { continue; } $forum['_depth'] = $depth; $forum['_newTopics'] = $forums[$forum['id']]['_newTopics']; $forum['_type'] = $forums[$forum['id']]['_type']; $forum['folder_icon'] = $this->registry->getClass('class_forums')->forumsNewPosts($forum); $forum['last_title'] = str_replace("!", "!", $forum['last_title']); $forum['last_title'] = str_replace(""", '"', $forum['last_title']); if (IPSText::mbstrlen($forum['last_title']) > 30) { $forum['last_title'] = IPSText::truncate($forum['last_title'], 30); } $forumArray[$forum['id']] = $forum; } $forumArray = $this->_showForumSubsRecurse($forums, $forum['id'], $forumArray, $depth + 1); } } return $forumArray; }
/** * Post a status update to Facebook based on native content * Which may be longer and such and so on and so forth, etc * * @access public * @param string Content * @param string URL to add * @param bool Always add the URL regardless of content length */ public function updateStatusWithUrl($content, $url, $alwaysAdd = false) { $memberData = $this->memberData; /* Got a member? */ if (!$memberData['member_id']) { throw new Exception('NO_MEMBER'); } /* Linked account? */ if (!$memberData['fb_uid']) { throw new Exception('NOT_LINKED'); } /* Ensure content is correctly de-html-ized */ $content = IPSText::UNhtmlspecialchars($content); /* Ensure it's converted cleanly into utf-8 */ $content = html_entity_decode($content, ENT_QUOTES, 'UTF-8'); /* Is the text longer than 140 chars? */ if ($alwaysAdd === TRUE or IPSText::mbstrlen($content) > 500) { /* Leave 26 chars for URL shortener */ $content = IPSText::mbsubstr($content, 0, 474) . '...'; if (IPSText::mbstrlen($url) > 26) { /* Generate short URL */ $classToLoad = IPSLib::loadLibrary(IPS_ROOT_PATH . 'sources/classes/url/shorten.php', 'urlShorten'); $shorten = new $classToLoad(); try { $data = $shorten->shorten($url, IPS_URL_SHORTEN_SERVICE); $url = $data['url']; } catch (Exception $ex) { /* Stop the exception bubbling back to parent classes */ } } $content .= ' ' . $url; } /* POST the data */ try { $this->_api->api(array('method' => 'users.setStatus', 'access_token' => $this->_userToken, 'uid' => $this->_userId, 'status' => $content, 'status_includes_verb' => true)); } catch (Exception $e) { $this->registry->output->logErrorMessage($e->getMessage(), 'FB-EXCEPTION'); } }
/** * Local authentication * * @access public * @param string Username * @param string Email Address * @param string Password * @return boolean Authentication successful */ public function authLocal($username, $email_address, $password) { $password = md5($password); //----------------------------------------- // Type of login //----------------------------------------- $type = 'username'; if (is_array($this->method_config) and $this->method_config['login_folder_name'] == 'internal') { $type = $this->method_config['login_user_id']; } if ($this->_forceEmailCheck === TRUE or $email_address and !$username) { $type = 'email'; } switch ($type) { case 'username': if (IPSText::mbstrlen($username) > 32) { $this->return_code = 'NO_USER'; return false; } $this->member_data = IPSMember::load($username, 'groups', 'username'); break; case 'email': $this->member_data = IPSMember::load($email_address, 'groups', 'email'); break; } //----------------------------------------- // Got an account //----------------------------------------- if (!$this->member_data['member_id']) { $this->return_code = 'NO_USER'; return false; } //----------------------------------------- // Verify it is not blocked //----------------------------------------- if (!$this->_checkFailedLogins()) { return false; } //----------------------------------------- // Check password... //----------------------------------------- if (IPSMember::authenticateMember($this->member_data['member_id'], $password) != true) { if (!$this->_appendFailedLogin()) { return false; } $this->return_code = 'WRONG_AUTH'; return false; } else { $this->return_code = 'SUCCESS'; return false; } }
/** * Parses a submitted form for custom fields, returning an array with keys 'save_array' and 'errors' * * @param array Array of field data * @return @e array */ public function getFieldsToSave($input_array) { /* INI */ $save_data = array(); $errors = array(); /* Loop through all the fields */ foreach ($this->field_list as $field) { /* Submitted Value */ $submit_value = $this->formatTextToSave($input_array['field_' . $field['id']]); if (!is_array($submit_value)) { $submit_value = trim($submit_value); } /* Check for restrictions */ if (isset($field['restrictions']) && is_array($field['restrictions'])) { if ($field['type'] == 'input' or $field['type'] == 'textarea') { /* Size Restriction */ if ($field['restrictions']['max_size'] && IPSText::mbstrlen($submit_value) > $field['restrictions']['max_size']) { $errors['field_' . $field['id']][] = 'too_big'; } /* Size Restriction */ if ($field['restrictions']['min_size'] && IPSText::mbstrlen($submit_value) < $field['restrictions']['min_size']) { $errors['field_' . $field['id']][] = 'too_small'; } } /* Null restriction */ if ($field['restrictions']['not_null'] && ((string) $submit_value !== '0' and !$submit_value)) { $errors['field_' . $field['id']][] = 'empty'; } /* Format Restriction */ if ($field['restrictions']['format'] && $submit_value) { $regex = str_replace('n', '\\d', preg_quote($field['restrictions']['format'], "#")); $regex = str_replace('a', '\\w', $regex); if (!preg_match("#^" . $regex . "\$#iu", $submit_value)) { $errors['field_' . $field['id']][] = 'invalid'; } } /* Check box? */ if ($field['type'] == 'cbox') { if (is_array($input_array['field_' . $field['id']]) and count($input_array['field_' . $field['id']])) { $submit_value = '|' . implode('|', array_keys($input_array['field_' . $field['id']])) . '|'; } } } /* Add to save */ $this->field_list[$field['id']]['value'] = $submit_value; $save_data['field_' . $field['id']] = $submit_value; } return array('save_array' => $save_data, 'errors' => $errors); }
/** * Regular member loop for member list * * @param array Member data * @param bool Show checkbox * @return string HTML */ public function memberListRow($member, $extraColumn = false) { $IPBHTML = ""; $member['group_title'] = IPSMember::makeNameFormatted($member['group_title'], $member['member_group_id']); if (trim($member['members_display_name']) == '') { $member['members_display_name'] = "<em class='desctext'>{$this->lang->words['sm_nodisplayname']}</em>"; } if (IPSText::mbstrlen($member['email']) > 50) { $_email = htmlspecialchars(substr(html_entity_decode($member['email']), 0, 20)) . '...' . htmlspecialchars(substr(html_entity_decode($member['email']), -25)); $member['email'] = '<span style="border-bottom:1px dotted gray; cursor:pointer" title="' . $member['email'] . "\">" . $_email . '</span>'; } $_extraStyle = $member['member_banned'] ? '_red' : ($member['bw_is_spammer'] ? '_amber' : ''); $_extraText = $member['member_banned'] ? '(' . $this->lang->words['m_f_showbanned'] . ')' : ($member['bw_is_spammer'] ? '(' . $this->lang->words['m_f_showspam'] . ')' : ''); $_serviceImg = ""; if ($member['fb_uid']) { $_serviceImg = "<a href='http://www.facebook.com/profile.php?id={$member['fb_uid']}' target='_blank'><img src='{$this->settings['skin_acp_url']}/images/members/facebook.png' /></a> "; } if ($member['twitter_id']) { $_serviceImg .= "<img src='{$this->settings['skin_acp_url']}/images/members/twitter.png' />"; } $IPBHTML .= <<<HTML \t<tr id='member-{$member['member_id']}' data-mid="{$member['member_id']}" class='member_row {$_extraStyle}'> \t\t<td><a href='{$this->settings['base_url']}&module=members&section=members&do=viewmember&member_id={$member['member_id']}'><img src='{$member['pp_thumb_photo']}' style='width: 30px; height: 30px; border: 1px solid #d8d8d8' /></a></td> \t\t<td class='member_name'><a href='{$this->settings['base_url']}&module=members&section=members&do=viewmember&member_id={$member['member_id']}' class='larger_text'>{$member['members_display_name']}</a></td> \t\t<td>{$_serviceImg} {$member['email']}</td> \t\t<td> \t\t\t{$member['_joined']} \t\t</td> \t\t<td>{$member['group_title']} <span style='color:gray;font-size:0.8em'>{$_extraText}</span></td> \t\t<td><a href='{$this->settings['base_url']}&app=members&module=members&section=tools&do=learn_ip&ip={$member['ip_address']}'>{$member['ip_address']}</a></td> \t\t<td> \t\t\t<p class='member_controls'> \t\t\t\t<a href='#' class='ipsBadge badge_red member_action' data-action='delete' title='{$this->lang->words['form_deletemember']}'>{$this->lang->words['m_but_delete']}</a> HTML; if ($extraColumn) { $IPBHTML .= <<<HTML \t\t<input type='checkbox' /> HTML; } $IPBHTML .= <<<HTML \t\t\t</p> \t\t</td> \t</tr> HTML; //--endhtml--// return $IPBHTML; }