public function call($forumid, $perpage = 20, $pagenumber = 1) { $contenttype = vB_Api::instance('contenttype')->fetchContentTypeIdFromClass('Channel'); $forum = vB_Api::instance('node')->getNodeFullContent($forumid); if (empty($forum) or isset($forum['errors'])) { return array("response" => array("errormessage" => array("invalidid"))); } $forum = $forum[$forumid]; $modPerms = vB::getUserContext()->getModeratorPerms($forum); $foruminfo = array('forumid' => $forum['nodeid'], 'title' => vB_String::unHtmlSpecialChars($forum['title']), 'description' => $forum['description'], 'title_clean' => $forum['htmltitle'], 'description_clean' => strip_tags($forum['description']), 'prefixrequired' => 0); $nodes = vB_Api::instance('node')->fetchChannelNodeTree($forumid, 3); $channels = array(); if (!empty($nodes) and empty($nodes['errors']) and isset($nodes['channels']) and !empty($nodes['channels'])) { foreach ($nodes['channels'] as $node) { $channels[] = vB_Library::instance('vb4_functions')->parseForum($node); } } $forumbits = $channels; $topics = array(); $topics_sticky = array(); $page_nav = vB_Library::instance('vb4_functions')->pageNav(1, $perpage, 1); $search = array("channel" => $forumid); $search['view'] = vB_Api_Search::FILTER_VIEW_TOPIC; $search['depth'] = 1; $search['include_sticky'] = true; $search['sort']['lastcontent'] = 'desc'; $search['nolimit'] = 1; $topic_search = vB_Api::instanceInternal('search')->getInitialResults($search, $perpage, $pagenumber, true); if (!isset($topic_search['errors']) and !empty($topic_search['results'])) { $topic_search['results'] = vB_Api::instance('node')->mergeNodeviewsForTopics($topic_search['results']); foreach ($topic_search['results'] as $key => $node) { if ($node['content']['contenttypeclass'] == 'Channel' or $node['content']['starter'] != $node['content']['nodeid']) { unset($topic_search['results'][$key]); } else { $topic = vB_Library::instance('vb4_functions')->parseThread($node); if ($topic['thread']['sticky']) { $topics_sticky[] = $topic; } else { $topics[] = $topic; } } } $page_nav = vB_Library::instance('vb4_functions')->pageNav($topic_search['pagenumber'], $perpage, $topic_search['totalRecords']); } $inlinemod = $forum['canmoderate'] ? 1 : 0; $subscribed = vB_Api::instance('follow')->isFollowingContent($forum['nodeid']); $subscribed = $subscribed ? 1 : 0; $forumsearch = vB::getUserContext()->hasPermission('forumpermissions', 'cansearch'); $response = array(); $response['response']['forumbits'] = $forumbits; $response['response']['foruminfo'] = $foruminfo; $response['response']['threadbits'] = $topics; $response['response']['threadbits_sticky'] = $topics_sticky; $response['response']['pagenav'] = $page_nav; $response['response']['pagenumber'] = intval($pagenumber); $response['show'] = array('subscribed_to_forum' => $subscribed, 'inlinemod' => $inlinemod, 'spamctrls' => $modPerms['candeleteposts'] > 0 ? 1 : 0, 'openthread' => $modPerms['canopenclose'] > 0 ? 1 : 0, 'approvethread' => $modPerms['canmoderateposts'] > 0 ? 1 : 0, 'movethread' => $modPerms['canmassmove'] > 0 ? 1 : 0, 'forumsearch' => $forumsearch, 'stickies' => count($topics_sticky) > 0 ? 1 : 0); return $response; }
function appendAttachments($nodeid, $posthash) { if (!empty($posthash) and !empty($nodeid)) { $filedataids = vB_Library::instance('vb4_posthash')->getFiledataids($posthash); foreach ($filedataids as $filedataid) { $result = vB_Api::instance('node')->addAttachment($nodeid, array('filedataid' => $filedataid['filedataid'])); if (empty($result) || !empty($result['errors'])) { // Ignore attachment errors } } } }
protected function getNewRouteInfo() { // go to home page if path is exactly like prefix if (count($this->matches) == 1 and empty($this->queryParameters)) { $blogHomeChannelId = vB_Api::instance('blog')->getBlogChannel(); $blogHomeChannel = vB_Library::instance('content_channel')->getBareContent($blogHomeChannelId); $blogHomeChannel = $blogHomeChannel[$blogHomeChannelId]; return $blogHomeChannel['routeid']; } $this->oldcontenttypeid = vB_Api_ContentType::OLDTYPE_BLOGCHANNEL; return parent::getNewRouteInfo(); }
public function buddylist() { $followers = vB_Api::instance('follow')->getFollowers($userid, array('page' => $pagenumber, 'perpage' => $perpage)); if ($followers === null || isset($followers['errors'])) { return vB_Library::instance('vb4_functions')->getErrorResponse($followers); } $friends = array(); foreach ($followers['results'] as $friend) { $friends[] = array('buddy' => array('userid' => $friend['userid'], 'username' => $friend['username'])); } return array('response' => array('offlineusers' => $friends)); }
function do_upload_avatar() { $cleaned = vB::getCleaner()->cleanArray($_REQUEST, array('upload' => vB_Cleaner::TYPE_FILE)); if (empty($cleaned['upload'])) { return json_error(ERR_NO_PERMISSION); } $upload_result = vB_Api::instance('profile')->upload($cleaned['upload']); if (!empty($upload_result['errors'])) { return json_error(ERR_NO_PERMISSION); } return true; }
public function editpost($postid) { $cleaner = vB::getCleaner(); $postid = $cleaner->clean($postid, vB_Cleaner::TYPE_UINT); $post = vB_Api::instance('node')->getFullContentforNodes(array($postid)); if (empty($post)) { return array("response" => array("errormessage" => array("invalidid"))); } $post = $post[0]; $prefixes = vB_Library::instance('vb4_functions')->getPrefixes($postid); $options = vB::getDatastore()->getValue('options'); $out = array('show' => array('tag_option' => 1), 'vboptions' => array('postminchars' => $options['postminchars'], 'titlemaxchars' => $options['titlemaxchars']), 'response' => array('prefix_options' => $prefixes, 'poststarttime' => 0, 'posthash' => vB_Library::instance('vb4_posthash')->getNewPosthash())); return $out; }
/** * Login with fabecook logged user * * @param [string] $signed_request [fb info] * @return [array] [response -> errormessage and session params] */ public function facebook($signed_request) { $cleaner = vB::getCleaner(); $signed_request = $cleaner->clean($signed_request, vB_Cleaner::TYPE_STR); $user_api = vB_Api::instance('user'); $loginInfo = $user_api->loginExternal('facebook', array('signedrequest' => $signed_request)); if (empty($loginInfo) || isset($loginInfo['errors'])) { //the api doesn't allow us to be that specific about our errors here. //and the app gets very cranky if the login returns an unexpected error code return array('response' => array('errormessage' => array('badlogin_facebook'))); } $result = array('session' => array('dbsessionhash' => $loginInfo['login']['sessionhash'], 'userid' => $loginInfo['login']['userid']), 'response' => array('errormessage' => array('redirect_login'))); return $result; }
public function docopythread($threadid, $destforumid) { $cleaner = vB::getCleaner(); $threadid = $cleaner->clean($threadid, vB_Cleaner::TYPE_UINT); $destforumid = $cleaner->clean($destforumid, vB_Cleaner::TYPE_UINT); if (empty($threadid) || empty($destforumid)) { return array('response' => array('errormessage' => 'invalidid')); } $result = vB_Api::instance('node')->cloneNodes(array($threadid), $destforumid); if ($result === null || isset($result['errors'])) { return vB_Library::instance('vb4_functions')->getErrorResponse($result); } else { return array('response' => array('errormessage' => array('redirect_movethread'))); } }
function do_subscribe_thread() { $userinfo = vB_Api::instance('user')->fetchUserInfo(); if ($userinfo['userid'] < 1) { return json_error(ERR_NO_PERMISSION); } $cleaned = vB::getCleaner()->cleanArray($_REQUEST, array('threadid' => vB_Cleaner::TYPE_UINT)); if (empty($cleaned['threadid'])) { return json_error(ERR_INVALID_SUB); } $result = vB_Api::instance('follow')->add($cleaned['threadid'], vB_Api_Follow::FOLLOWTYPE_CONTENT); if (empty($result) || !empty($result['errors'])) { return json_error(ERR_INVALID_SUB); } return true; }
function do_get_announcement() { $cleaned = vB::getCleaner()->cleanArray($_REQUEST, array('forumid' => vB_Cleaner::TYPE_UINT)); if (!isset($cleaned['forumid']) || $cleaned['forumid'] < 1) { return json_error(ERR_NO_PERMISSION); } $result = vB_Api::instance('announcement')->fetch($cleaned['forumid']); if ($result === null || isset($result['errors'])) { return json_error(ERR_NO_PERMISSION); } $posts = array(); foreach ($result as $ann) { $posts[] = fr_parse_post($ann); } return array('posts' => $posts, 'total_posts' => count($posts)); }
public function newthread($forumid) { $cleaner = vB::getCleaner(); $forumid = $cleaner->clean($forumid, vB_Cleaner::TYPE_UINT); $forum = vB_Api::instance('node')->getFullContentforNodes(array($forumid)); if (empty($forum)) { return array("response" => array("errormessage" => array("invalidid"))); } $forum = $forum[0]; $foruminfo = vB_Library::instance('vb4_functions')->parseForumInfo($forum); $prefixes = vB_Library::instance('vb4_functions')->getPrefixes($forumid); $options = vB::getDatastore()->getValue('options'); $postattachment = $forum['content']['createpermissions']['vbforum_attach']; $postattachment = empty($postattachment) ? 0 : intval($postattachment); $usercontext = vB::getUserContext($this->currentUserId); $maxtags = $usercontext->getChannelLimits($forumid, 'maxstartertags'); $out = array('show' => array('tag_option' => 1), 'vboptions' => array('postminchars' => $options['postminchars'], 'titlemaxchars' => $options['titlemaxchars'], 'maxtags' => $maxtags), 'response' => array('forumrules' => array('can' => array('postattachment' => $postattachment)), 'prefix_options' => $prefixes, 'foruminfo' => $foruminfo, 'poststarttime' => vB::getRequest()->getTimeNow(), 'posthash' => vB_Library::instance('vb4_posthash')->getNewPosthash())); return $out; }
public function isViglinkEnabled($prev, $feature = self::VIGLINK_FEATURE_ALL) { $utils = new Viglink_Utils(); $is_enabled = (bool) vB::getDatastore()->getOption('viglink_enabled'); $has_key = (bool) vB_Api::instance('site')->getViglinkKey(); $args = func_get_args(); $enabled = $is_enabled && $has_key; switch ($feature) { case self::VIGLINK_FEATURE_ALL: return $enabled; case self::VIGLINK_FEATURE_LII: // disabled for one of this user's groups? $disabled_group_ids = json_decode($utils->getOption('lii_excluded_usergroups', '[]')); $user_disabled_group_ids = array_intersect($disabled_group_ids, vB::getUserContext()->fetchUserGroups()); $lii_enabled_for_groups = empty($user_disabled_group_ids); $lii_enabled = $lii_enabled_for_groups; return $enabled && $lii_enabled; } }
public function sendemail($postid, $reason) { $cleaner = vB::getCleaner(); $postid = $cleaner->clean($postid, vB_Cleaner::TYPE_UINT); $reason = $cleaner->clean($reason, vB_Cleaner::TYPE_STR); if (empty($postid)) { return array('response' => array('errormessage' => array('invalidid'))); } if (empty($reason)) { return array('response' => array('errormessage' => array('invalidid'))); } $userinfo = vB_Api::instance('user')->fetchUserinfo(); $data = array('reportnodeid' => $postid, 'rawtext' => $reason, 'created' => vB::getRequest()->getTimeNow(), 'userid' => $userinfo['userid'], 'authorname' => $userinfo['username']); $result = vB_Api::instance('content_report')->add($data, array('wysiwyg' => false)); if ($result === null || isset($result['errors'])) { return vB_Library::instance('vb4_functions')->getErrorResponse($result); } return array('response' => array('errormessage' => array('redirect_reportthanks'))); }
public function newreply($threadid, $disablesmilies = false) { $cleaner = vB::getCleaner(); $threadid = $cleaner->clean($threadid, vB_Cleaner::TYPE_UINT); $thread = vB_Api::instance('node')->getFullContentforNodes(array($threadid)); if (empty($thread)) { return array("response" => array("errormessage" => array("invalidid"))); } $thread = $thread[0]; $prefixes = vB_Library::instance('vb4_functions')->getPrefixes($threadid); $options = vB::getDatastore()->getValue('options'); $postattachment = $thread['content']['createpermissions']['vbforum_attach']; $postattachment = empty($postattachment) ? 0 : intval($postattachment); /* additional options' checked checkboxes array... */ $checked = array('parseurl' => 1, 'signature' => "", "subscribe" => $thread['content']['subscribed']); // SIGNATURE $userContext = vB::getUserContext(); $currentUserId = $userContext->fetchUserId(); $signature = vB_Api::instanceInternal('user')->fetchSignature($currentUserId); if (!empty($signature)) { $checked['signature'] = 1; } // DISABLESMILIES // getDataForParse converts channel.options into bbcodeoptions, and this is used by the // frontend nodetext / bbcode parsers $textDataArray = vB_Api::instanceInternal('content_text')->getDataForParse(array($threadid)); $channelAllowsSmilies = $textDataArray[$threadid]['bbcodeoptions']['allowsmilies']; if ($channelAllowsSmilies) { if (!empty($disablesmilies)) { $checked['disablesmilies'] = 1; } else { $checked['disablesmilies'] = ""; } $show['smiliebox'] = 1; } else { $show['smiliebox'] = 0; } $out = array('show' => array('tag_option' => 1, 'smiliebox' => $show['smiliebox']), 'vboptions' => array('postminchars' => $options['postminchars'], 'titlemaxchars' => $options['titlemaxchars']), 'response' => array('title' => '', 'forumrules' => array('can' => array('postattachment' => $postattachment)), 'prefix_options' => $prefixes, 'poststarttime' => 0, 'posthash' => vB_Library::instance('vb4_posthash')->getNewPosthash()), 'checked' => $checked); return $out; }
protected function getNewRouteInfo() { $oldtype = array('cat' => 9988, 'groupid' => vB_Types::instance()->getContentTypeID('vBForum_SocialGroup'), 'discussionid' => vB_Types::instance()->getContentTypeID('vBForum_SocialGroupDiscussion')); $argument =& $this->arguments; $param =& $this->queryParameters; foreach ($oldtype as $key => $oldcontenttypeid) { if (!empty($param[$key]) and $oldid = intval($param[$key])) { $node = vB::getDbAssertor()->getRow('vBForum:node', array('oldid' => $oldid, 'oldcontenttypeid' => $oldcontenttypeid)); if (empty($node)) { throw new vB_Exception_404('invalid_page'); } $argument['nodeid'] = $node['nodeid']; return $node['routeid']; } } $sgChannelId = vB_Api::instance('socialgroup')->getSGChannel(); $sgChannel = vB::getDbAssertor()->getRow('vBForum:node', array('nodeid' => $sgChannelId)); $argument['nodeid'] = $sgChannel['nodeid']; return $sgChannel['routeid']; }
function do_delete_attachment() { $userinfo = vB_Api::instance('user')->fetchUserInfo(); if ($userinfo['userid'] < 1) { return json_error(ERR_NO_PERMISSION); } $cleaned = vB::getCleaner()->cleanArray($_REQUEST, array('attachmentid' => vB_Cleaner::TYPE_UINT)); if (empty($cleaned['attachmentid'])) { return json_error(ERR_NO_PERMISSION); } $fr_attach = vB_dB_Assertor::instance()->assertQuery('ForumRunner:getAttachmentMarkerById', array('id' => $cleaned['attachmentid'])); if (empty($fr_attach)) { return json_error(ERR_NO_PERMISSION); } $result = vB_Api::instance('content_attach')->deleteAttachment($fr_attach['attachmentid']); if (empty($result) || !empty($result['errors'])) { return json_error(ERR_NO_PERMISSION); } vB_dB_Assertor::instance()->assertQuery('ForumRunner:deleteAttachmentMarker', array('id' => $cleaned['attachmentid'])); return true; }
function do_online() { $userinfo = vB_Api::instance('user')->fetchUserInfo(); $result = vB_Api::instance('wol')->fetchAll(); $options = vB::get_datastore()->get_value('options'); if (is_null($result) || isset($result['errors'])) { return json_error(ERR_NO_PERMISSION); } $user_counts = vB_Api::instance('wol')->fetchCounts(); if (is_null($user_counts) || isset($user_counts['errors'])) { return json_error(ERR_NO_PERMISSION); } $users = array(); foreach ($result as $user) { $user_final = array('username' => $user['username'], 'userid' => $user['userid'], 'avatarurl' => $options['bburl'] . '/' . $user['avatarpath']); if (!empty($userinfo) && $user['userid'] === $userinfo['userid']) { $user_final['me'] = true; } $users[] = $user_final; } return array('users' => $users, 'num_guests' => $user_counts['guests']); }
public function manageattach($posthash, $attachment) { $cleaner = vB::getCleaner(); $posthash = $cleaner->clean($posthash, vB_Cleaner::TYPE_STR); $attach = $cleaner->clean($attachment, vB_Cleaner::TYPE_FILE); // vB5 doesn't understand multiple file uploads. // Manually split them. $attachments = array(); foreach ($attach as $key => $value) { for ($i = 0; $i < count($value); $i++) { $attachments[$i][$key] = $value[$i]; } } unset($attach); foreach ($attachments as $attachment) { $result = vB_Api::instance('content_attach')->upload($attachment); if (empty($result) || !empty($result['errors'])) { return vB_Library::instance('vb4_functions')->getErrorResponse($result); } vB_Library::instance('vb4_posthash')->addFiledataid($posthash, $result['filedataid']); } return array('response' => array()); }
function do_register() { $cleaned = vB::getCleaner()->cleanArray($_REQUEST, array('username' => vB_Cleaner::TYPE_STR, 'email' => vB_Cleaner::TYPE_STR, 'password' => vB_Cleaner::TYPE_STR, 'birthday' => vB_Cleaner::TYPE_STR, 'timezone_name' => vB_Cleaner::TYPE_STR)); if (empty($cleaned['username'])) { return fr_register_info(); } if (empty($cleaned['email']) || empty($cleaned['password'])) { return json_error(ERR_NO_PERMISSION); } $data = array('username' => $cleaned['username'], 'email' => $cleaned['email']); if (!empty($cleaned['birthday'])) { $data['birthday'] = $cleaned['birthday']; } $result = vB_Api::instance('user')->save(0, $cleaned['password'], $data, array(), array(), array()); if (empty($result) || !empty($result['errors'])) { if (is_array($result['errors'])) { $errorstr = ''; foreach ($result['errors'] as $error) { $phraseAux = vB_Api::instanceInternal('phrase')->fetch(array($error[0])); if (isset($phraseAux[$error[0]])) { $message = $phraseAux[$error[0]]; } else { $message = $error[0]; } if (sizeof($error) > 1) { $error[0] = $message; $message = call_user_func_array('construct_phrase', $error); } $errorstr .= strip_tags($message) . " "; } return json_error($errorstr); } return json_error(ERR_NO_PERMISSION); } return true; }
function do_ban_user() { $userinfo = vB_Api::instance('user')->fetchUserInfo(); if ($userinfo['userid'] < 1) { return json_error(ERR_NO_PERMISSION); } $cleaned = vB::getCleaner()->cleanArray($_REQUEST, array('userid' => vB_Cleaner::TYPE_UINT, 'usergroupid' => vB_Cleaner::TYPE_UINT, 'period' => vB_Cleaner::TYPE_STR, 'reason' => vB_Cleaner::TYPE_STR)); if (!isset($cleaned['userid']) || !isset($cleaned['period'])) { return json_error(ERR_NO_PERMISSION); } !isset($cleaned['usergroupid']) || $cleaned['usergroupid'] < 1 ? $banusergroupid = 8 : ($banusergroupid = $cleaned['usergroupid']); $user = vB_Api::instance('user')->banUsers(array($cleaned['userid']), $banusergroupid, $cleaned['period'], $cleaned['reason']); if ($user === null || isset($user['errors'])) { return false; } return true; }
protected function saveNavbarPhrase(&$element, &$phrases) { if (!isset($element['phrase']) or empty($element['phrase']) or strpos($element['phrase'], 'navbar_') !== 0 or isset($phrases[$element['phrase']]) and $phrases[$element['phrase']] != $element['title']) { $words = explode(' ', $element['title']); array_walk($words, 'trim'); $phrase = strtolower(implode('_', $words)); //translating some special characters to their latin form $phrase = vB_String::latinise($phrase); // remove any invalid chars $phrase = preg_replace('#[^' . vB_Library_Phrase::VALID_CLASS . ']+#', '', $phrase); $phrase = 'navbar_' . $phrase; $suffix = 0; $tmpPhrase = $phrase; while (isset($phrases[$tmpPhrase]) and $phrases[$tmpPhrase] != $element['title']) { $tmpPhrase = $phrase . ++$suffix; } $element['phrase'] = $tmpPhrase; } // Store the phrase-value so that we can check $phrases[$element['phrase']] = $element['title']; $existingPhrases = vB::getDbAssertor()->getRows('phrase', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'varname' => $element['phrase'])); // don't destroy translations $text = array(); foreach ($existingPhrases as $existingPhrase) { $text[$existingPhrase['languageid']] = $existingPhrase['text']; } // the edited phrase $text[0] = $element['title']; vB_Api::instance('phrase')->save('navbarlinks', $element['phrase'], array('text' => $text, 'oldvarname' => $element['phrase'], 'oldfieldname' => 'navbarlinks', 't' => 0, 'ismaster' => 0, 'product' => 'vbulletin')); // store phrase name instead of title $element['title'] = $element['phrase']; unset($element['phrase']); // do the same for subnavigation if (isset($element['subnav']) and !empty($element['subnav'])) { foreach ($element['subnav'] as &$subnav) { $this->saveNavbarPhrase($subnav, $phrases); } } }
// ###################### Start Remove User's Subscriptions ####################### if ($_REQUEST['do'] == 'removesubs') { print_delete_confirmation('user', $vbulletin->GPC['userid'], 'usertools', 'killsubs', 'subscriptions'); } // ###################### Start Remove User's Subscriptions ####################### if ($_POST['do'] == 'killsubs') { vB::getDbAssertor()->delete('vBForum:subscribediscussion', array('userid' => $vbulletin->GPC['userid'])); print_stop_message2('deleted_subscriptions_successfully', 'user', array('do' => 'edit', 'u' => $vbulletin->GPC['userid'])); } // ###################### Start Remove User's PMs ####################### if ($_REQUEST['do'] == 'removepms') { print_delete_confirmation('user', $vbulletin->GPC['userid'], 'usertools', 'killpms', 'private_messages_belonging_to_the_user'); } // ###################### Start Remove User's PMs ####################### if ($_POST['do'] == 'killpms') { $pmapi = vB_Api::instance('content_privatemessage'); $result = $pmapi->deleteMessagesForUser($vbulletin->GPC['userid']); if (isset($result['errors'][0])) { print_stop_message2($result['errors'][0]); } print_stop_message2(array('deleted_x_pms', $result['deleted']), 'user', array('do' => 'edit', 'u' => $vbulletin->GPC['userid'])); } // ###################### Start Remove PMs Sent by User ####################### if ($_REQUEST['do'] == 'removesentpms') { print_delete_confirmation('user', $vbulletin->GPC['userid'], 'usertools', 'killsentpms', 'private_messages_sent_by_the_user'); } // ###################### Start Remove User's PMs ####################### if ($_POST['do'] == 'killsentpms') { try { $user = vB_Api::instanceInternal('user')->fetchUserInfo(); } catch (vB_Exception_Api $ex) {
/** * updates a record * * @param int $nodeid * @param array $data -- The data for the node to be updated * @param boolean $convertWysiwygTextToBbcode * * @return boolean */ public function update($nodeid, $data, $convertWysiwygTextToBbcode = true) { // TODO: Permission check // $loginuser = &vB::getCurrentSession()->fetch_userinfo(); // $usercontext = &vB::getUserContext($loginuser['userid']); // if (!$usercontext->hasPermission('forumpermissions', 'canpostvideo')) // { // throw new Exception('no_permission'); // } $currentNode = vB_Library::instance('Node')->getNodeBare($nodeid); if ($currentNode['contenttypeid'] != vB_Types::instance()->getContentTypeID($this->contenttype)) { parent::changeContentType($nodeid, $currentNode['contenttypeid'], $this->contenttype); $data['contenttypeid'] = vB_Types::instance()->getContentTypeID($this->contenttype); } if (isset($data['videoitems'])) { $newvideoitems = $this->checkVideoData($data); unset($data['videoitems']); } $result = parent::update($nodeid, $data, $convertWysiwygTextToBbcode); // do not process videoitems if they are not provided if (!isset($data['videoitems'])) { return $result; } // Get a list of current video items $videoitems = $this->fetchVideoItems($nodeid); $oldvideoitemids = array(); $newvideoitemids = array(); foreach ($videoitems as $item) { $oldvideoitemids[$item['videoitemid']] = $item['videoitemid']; } foreach ($newvideoitems as $item) { $newvideoitemids[$item['videoitemid']] = $item['videoitemid']; $newvideoitemdata[$item['videoitemid']] = $item; } $itemstoremove = array_diff($oldvideoitemids, $newvideoitemids); $itemstoupdate = array_intersect($oldvideoitemids, $newvideoitemids); $itemstoinsert = array_diff($newvideoitemids, $oldvideoitemids); // Save video items foreach ($itemstoinsert as $itemid) { $this->assertor->assertQuery("videoitem", array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'nodeid' => $nodeid, 'provider' => $newvideoitemdata[$itemid]['provider'], 'code' => $newvideoitemdata[$itemid]['code'], 'url' => $newvideoitemdata[$itemid]['url'])); } foreach ($itemstoupdate as $itemid) { $this->assertor->assertQuery("videoitem", array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_UPDATE, 'nodeid' => $nodeid, 'provider' => $newvideoitemdata[$itemid]['provider'], 'code' => $newvideoitemdata[$itemid]['code'], 'url' => $newvideoitemdata[$itemid]['url'], vB_dB_Query::CONDITIONS_KEY => array('videoitemid' => $itemid))); } foreach ($itemstoremove as $itemid) { $this->assertor->assertQuery("videoitem", array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_DELETE, 'videoitemid' => $itemid)); } // do the indexing after the options are added vB_Api::instance('Search')->index($nodeid); vB_Cache::instance(vB_Cache::CACHE_FAST)->event("nodeChg_{$nodeid}"); vB_Cache::instance()->event("nodeChg_{$nodeid}"); return $result; }
/** * Determines if the given node is under the Articles Home Channel * * @param int $nodeid * @return bool */ public function isArticleNode($nodeId, $node = false) { $nodeId = intval($nodeId); $articlesRootChannelId = vB_Api::instance('content_channel')->fetchChannelIdByGUID(vB_Channel::DEFAULT_ARTICLE_PARENT); if ($nodeId < 0) { return false; } if (empty($node)) { $node = vB_Library::instance('node')->getNode($nodeId, true, false); } if (empty($node['parents'])) { $parents = vB_Library::instance('node')->getParents($nodeId); foreach ($parents as $parent) { if ($parent['nodeid'] == $articlesRootChannelId) { return true; } } return false; } return in_array($articlesRootChannelId, $node['parents']); }
function fr_search_results($searchid, $page, $perpage, $previewtype = 1, $showposts = false) { $result = vB_Api::instance('search')->getMoreNodes($searchid, $perpage, $page); if (empty($result) || !empty($result['error'])) { return json_error(ERR_NO_PERMISSION); } $complete_starters = array(); $threads = array(); foreach ($result['nodeIds'] as $nodeid) { $node = vB_Api::instance('node')->getFullContentforNodes(array($nodeid)); if (empty($node) || !empty($node['errors'])) { continue; } $node = $node[0]; if (!$showposts) { if ($node['nodeid'] != $node['starter'] && !in_array($node['starter'], $complete_starters)) { $node = vB_Api::instance('node')->getFullContentforNodes(array($node['starter'])); $node = $node[0]; $complete_starters[] = $node['starter']; } } $threads[] = fr_parse_thread($node, $previewtype); } $out = array('threads' => $threads, 'total_threads' => $result['totalRecords'], 'searchid' => $searchid); return $out; }
/** * Moves nodes to a new parent * * @param array Node ids * @param int New parent node id * @param bool Make topic * @param bool New title * @param bool Mod log * @param array Information to leave a thread redirect. If empty, no redirect is created. * If not empty, should contain these items: * redirect (string) - perm|expires Permanent or expiring redirect * frame (string) - h|d|w|m|y Hours, days, weeks, months, years (valid only for expiring redirects) * period (int) - 1-10 How many hours, days, weeks etc, for the expiring redirect * * @return */ public function moveNodes($nodeids, $to_parent, $makeTopic = false, $newtitle = false, $modlog = true, array $leaveRedirectData = array()) { $movedNodes = array(); $oldnodeInfo = array(); $to_parent = $this->assertNodeidStr($to_parent); $userContext = vB::getUserContext(); $currentUserid = vB::getCurrentSession()->get('userid'); $channelAPI = vB_Api::instanceInternal('content_channel'); $newparent = $this->getNode($to_parent); // If all the nodes to be moved are content nodes and are currently in the same // channel, then we are only merging posts/topics and need to check different permissions. // To detemine this, we iterate through all the nodes to be moved and get all the "starter" // nodeids. We then iterate through all the starters and check if they all have the same // parentid, which is the channel they are in. $isTopicMerge = false; $checkNodes = $this->getNodes(array_merge((array) $nodeids, (array) $to_parent)); $skipCheck = false; $checkStarterIds = array(); foreach ($checkNodes as $checkNode) { if (empty($checkNode['starter'])) { // we can skip this check because one of the nodes is a channel $skipCheck = true; break; } else { $checkStarterIds[] = $checkNode['starter']; } } if (!$skipCheck) { $checkStarters = $this->getNodes($checkStarterIds); $starterParents = array(); foreach ($checkStarters as $checkStarter) { $starterParents[$checkStarter['parentid']] = $checkStarter['parentid']; } if (count($starterParents) === 1) { // the parent node of all the starters is the same, so we are // only moving topics / posts around inside the same channel, // this is likely a topic merge request and we can check a separate // permission below $isTopicMerge = true; } unset($checkStarters, $checkStarter, $starterParents); } unset($checkNode, $checkStarterIds, $skipCheck); //If the current user has can moderator canmove on the current nodes, or if the user can create in //the new channel and is the owner of the moved nodes and has forum canmove, then they can move if (!$userContext->getChannelPermission('forumpermissions', 'canmove', $to_parent) and !$userContext->getChannelPermission('moderatorpermissions', 'canmassmove', $to_parent) and (!$isTopicMerge or !$userContext->getChannelPermission('moderatorpermissions', 'canmanagethreads', $to_parent))) { throw new vB_Exception_Api('no_permission'); } $nodes = vB::getDbAssertor()->getRows('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'nodeid' => $nodeids), array('field' => array('publishdate'), 'direction' => array(vB_dB_Query::SORT_ASC)), 'nodeid'); $needRebuild = false; $firstTitle = false; $loginfo = array(); $parent = $this->getNodeFullContent($to_parent); $parent = $parent[$to_parent]; $cacheEvents = array($to_parent); $oldparents = array(); $channelTypeid = vB_Types::instance()->getContentTypeId('vBForum_Channel'); $infractionTypeid = vB_Types::instance()->getContentTypeId('vBForum_Infraction'); foreach ($nodes as $node) { if ($node['contenttypeid'] == $infractionTypeid) { throw new vB_Exception_Api('cannot_move_infraction_nodes'); } if ($node['contenttypeid'] == $channelTypeid) { // If any of the moved nodes are channels, the target must be a channel. if ($newparent['contenttypeid'] != $channelTypeid) { throw new vB_Exception_Api('invalid_request'); } // We should not allow the moving of channels from one root channel to another. if ($channelAPI->getTopLevelChannel($newparent['nodeid']) != $channelAPI->getTopLevelChannel($node['nodeid'])) { throw new vB_Exception_Api('cant_change_top_level'); } } //Only channels can be moved to categories, UI shouldn't allow this if ($parent['contenttypeid'] == $channelTypeid) { $newrouteid = vB_Api::instanceInternal('route')->getChannelConversationRoute($to_parent); if ($node['contenttypeid'] != $channelTypeid and (empty($newrouteid) or !empty($parent['category']))) { // The node we want to move is not a channel and the parent cannot have conversations // (e.g. categories, the root blog channel, the root forum channel) throw new vB_Exception_Api('invalid_request'); } } if ($node['contenttypeid'] == vB_Types::instance()->getContentTypeID('vBForum_Channel')) { $needRebuild = true; } if ($userContext->getChannelPermission('moderatorpermissions', 'canmassmove', $node['nodeid']) or $currentUserid == $node['userid'] and $userContext->getChannelPermission('forumpermissions', 'canmove', $node['nodeid'], false, $node['parentid']) or $isTopicMerge and $userContext->getChannelPermission('moderatorpermissions', 'canmanagethreads', $to_parent)) { if (empty($movedNodes)) { if (empty($node['title']) and !empty($node['starter'])) { $starter = vB_Library::instance('node')->getNodeBare($node['starter']); $firstTitle = $starter['title']; } else { $firstTitle = $node['title']; } } $movedNodes[] = $node['nodeid']; $oldnodeInfo[$node['nodeid']] = $node; $oldparents[$node['nodeid']] = $node['parentid']; $this->contentLibs[$node['nodeid']] = vB_Library::instance('Content_' . vB_Types::instance()->getContentTypeClass($node['contenttypeid'])); if ($modlog) { $oldparent = $this->getNode($node['parentid']); $extra = array('fromnodeid' => $oldparent['nodeid'], 'fromtitle' => $oldparent['title'], 'tonodeid' => $newparent['nodeid'], 'totitle' => $newparent['title']); $loginfo[] = array('nodeid' => $node['nodeid'], 'nodetitle' => $node['title'], 'nodeusername' => $node['authorname'], 'nodeuserid' => $node['userid'], 'action' => $extra); } if (!in_array($node['parentid'], $cacheEvents)) { $cacheEvents[] = $node['parentid']; } if (!in_array($node['starter'], $cacheEvents) and intval($node['starter'])) { $cacheEvents[] = $node['starter']; } } else { throw new vB_Exception_Api('no_permission'); } } if (empty($movedNodes)) { return false; } //can't move a node to its decendant, we like proper trees. $db = vB::getDbAssertor(); $row = $db->getRow('vBForum:closure', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'parent' => $movedNodes, 'child' => $to_parent, vB_Db_Query::PARAM_LIMIT => 1)); if (!empty($row)) { throw new vB_Exception_Api('move_node_to_child'); } //back out counts for the nodes about to be moved. //keep track of the parentids to so we can update the last content after //we've moved things around. $lastContentParents = array(); foreach ($movedNodes as $nodeid) { $node = $this->getNode($nodeid); $movedNodeParents = $this->getParents($nodeid); $parentids = array(); foreach ($movedNodeParents as $movedNodeParent) { if ($movedNodeParent['nodeid'] != $nodeid) { $parentids[] = $movedNodeParent['nodeid']; $lastContentParents[] = $movedNodeParent['nodeid']; } } $this->updateAddRemovedNodeParentCounts($node, $node, $node['showpublished'], false, $parentids); } if ($parent['contenttypeid'] == $channelTypeid and $makeTopic) { if (empty($newtitle)) { if (!empty($firstTitle)) { $newtitle = $firstTitle; } else { throw new vB_Exception_Api('notitle'); } } $newchildid = $movedNodes[0]; $this->moveNodesInternal(array($newchildid), $newparent); // We need to promote give the new node the correct title vB::getDbAssertor()->assertQuery('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_UPDATE, 'routeid' => vB_Api::instanceInternal('route')->getChannelConversationRoute($to_parent), 'title' => $newtitle, 'htmltitle' => vB_String::htmlSpecialCharsUni(vB_String::stripTags($newtitle), false), 'urlident' => vB_String::getUrlIdent($newtitle), 'description' => $newtitle, vB_dB_Query::CONDITIONS_KEY => array('nodeid' => $movedNodes[0]))); if (count($movedNodes) > 1) { $grandchildren = array_slice($movedNodes, 1); $this->moveNodesInternal($grandchildren, $checkNodes[$newchildid]); } //moving the grandchildren under the first node may have changed it's last child info $db->assertQuery('vBForum:updateLastData', array('parentid' => $newchildid, 'timenow' => vB::getRequest()->getTimeNow())); $node = $this->getNode($newchildid); $this->updateSubTreePublishStatus($node, $newparent['showpublished']); } else { $this->moveNodesInternal($movedNodes, $newparent); foreach ($movedNodes as $nodeid) { $node = $this->getNode($nodeid); $this->updateSubTreePublishStatus($node, $newparent['showpublished']); } } //dedup the array (so we don't update a node more than once) but we need to //do so in a particular way. We always want to keep the *last* occurance //of any id in the array. This ensures that a node is not updated before //any of its decendants (which could cause bad results). $seen = array(); foreach ($lastContentParents as $key => $parentid) { if (isset($seen[$parentid])) { unset($lastContentParents[$seen[$parentid]]); } $seen[$parentid] = $key; } //we can't do this before we move the nodes because the parent/child relationships haven't //changed yet. foreach ($lastContentParents as $parentid) { $this->fixNodeLast($parentid); } $userid = vB::getCurrentSession()->get('userid'); // afterMove requires some ancestors info which we just changed above, let's clear cache before updating $searchAPI = vB_Api::instanceInternal('search'); foreach ($movedNodes as $nodeid) { vB_Cache::instance()->allCacheEvent('nodeChg_' . $nodeid); //some search information may have changed, let's check $searchAPI->attributeChanged($nodeid); } // Leave a thread redirect if required // Note: UI only allows leaving a redirect when moving a thread which is one node if (!empty($leaveRedirectData) and count($movedNodes) == 1 and count($nodes) == 1) { $node = reset($nodes); $redirectData = array('title' => $node['title'], 'urlident' => $node['urlident'], 'parentid' => $node['parentid'], 'tonodeid' => $node['nodeid'], 'userid' => $node['userid'], 'publishdate' => $node['publishdate'], 'created' => $node['created']); // handle expiring redirects if (isset($leaveRedirectData['redirect']) and $leaveRedirectData['redirect'] == 'expires') { $period = (int) isset($leaveRedirectData['period']) ? $leaveRedirectData['period'] : 1; $frame = (string) isset($leaveRedirectData['frame']) ? $leaveRedirectData['frame'] : 'm'; $period = max(min($period, 10), 1); $frame = in_array($frame, array('h', 'd', 'w', 'm', 'y'), true) ? $frame : 'm'; $frames = array('h' => 3600, 'd' => 86400, 'w' => 86400 * 7, 'm' => 86400 * 30, 'y' => 86400 * 365); $redirectData['unpublishdate'] = vB::getRequest()->getTimeNow() + $period * $frames[$frame]; } // skip any text spam checks, because a redirect has no text to check. vB_Library::instance('content_redirect')->add($redirectData, array('skipSpamCheck' => true)); } vB_Api::instance('Search')->purgeCacheForCurrentUser(); vB_Library_Admin::logModeratorAction($loginfo, 'node_moved_by_x'); $cacheEvents = array_unique(array_merge($movedNodes, $cacheEvents, array($to_parent))); $this->clearChildCache($cacheEvents); $this->clearCacheEvents($cacheEvents); if ($needRebuild) { vB::getUserContext()->rebuildGroupAccess(); vB_Channel::rebuildChannelTypes(); } return $movedNodes; }
} // ############################################################################# // insert queries and cache rebuilt for template insertion if ($_POST['do'] == 'inserttemplate') { if (!vB::getUserContext()->hasAdminPermission('canadmintemplates')) { print_cp_no_permission(); } $vbulletin->input->clean_array_gpc('p', array('title' => vB_Cleaner::TYPE_STR, 'product' => vB_Cleaner::TYPE_STR, 'template' => vB_Cleaner::TYPE_NOTRIM, 'searchstring' => vB_Cleaner::TYPE_STR, 'expandset' => vB_Cleaner::TYPE_NOHTML, 'searchset' => vB_Cleaner::TYPE_NOHTML, 'savehistory' => vB_Cleaner::TYPE_BOOL, 'histcomment' => vB_Cleaner::TYPE_STR, 'return' => vB_Cleaner::TYPE_STR, 'group' => vB_Cleaner::TYPE_STR, 'confirmremoval' => vB_Cleaner::TYPE_BOOL, 'confirmerrors' => vB_Cleaner::TYPE_BOOL, 'textonly' => vB_Cleaner::TYPE_BOOL)); // remove escaped CDATA (just in case user is pasting template direct from an XML editor // where the CDATA tags will have been escaped by our escaper... //$template = xml_unescape_cdata($template); if (!$vbulletin->GPC['title']) { print_stop_message2('please_complete_required_fields'); } handle_vbulletin_copyright_removal($vbulletin->GPC, 'inserttemplate'); $templateid = vB_Api::instance('template')->insert($vbulletin->GPC['dostyleid'], $vbulletin->GPC['title'], $vbulletin->GPC['template'], $vbulletin->GPC['product'], $vbulletin->GPC['savehistory'], $vbulletin->GPC['histcomment'], $vbulletin->GPC['confirmerrors'], array('textonly' => $vbulletin->GPC['textonly'])); //we can't easily display multiple errors in the admincp code, so display the first one. if (is_array($templateid) and isset($templateid['errors'][0])) { $error = $templateid['errors'][0]; if ($error[0] == 'template_eval_error' or $error[0] == 'template_compile_error') { print_template_confirm_error_page($vbulletin->GPC, construct_phrase($vbphrase['template_eval_error'], fetch_error_array($error[1]))); } elseif ($error[0] == 'template_x_exists_error') { $vbulletin->GPC['templateid'] = $error[2]; print_template_confirm_error_page($vbulletin->GPC, construct_phrase($vbphrase['template_x_exists_error'], fetch_error_array($error[1]))); } else { print_stop_message2($templateid['errors'][0]); } } //if no error, then redirect the page $args = array(); parse_str(vB::getCurrentSession()->get('sessionurl'), $args);
$is_windows = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'; $loadavg = array(); if (!$is_windows and function_exists('exec') and $stats = @exec('uptime 2>&1') and trim($stats) != '' and preg_match('#: ([\\d.,]+),?\\s+([\\d.,]+),?\\s+([\\d.,]+)$#', $stats, $regs)) { $loadavg[0] = vb_number_format($regs[1], 2); $loadavg[1] = vb_number_format($regs[2], 2); $loadavg[2] = vb_number_format($regs[3], 2); } else { if (!$is_windows and @file_exists('/proc/loadavg') and $stats = @file_get_contents('/proc/loadavg') and trim($stats) != '') { $loadavg = explode(' ', $stats); $loadavg[0] = vb_number_format($loadavg[0], 2); $loadavg[1] = vb_number_format($loadavg[1], 2); $loadavg[2] = vb_number_format($loadavg[2], 2); } } //will set the max logged in values as a side effect. $wolcounts = vB_Api::instance('wol')->fetchCounts(); if (isset($wolcounts['errors'])) { $woltext = fetch_error($wolcounts['errors'][0]); } else { if (!empty($loadavg)) { $wolphrase = 'users_online_x_members_y_guests'; } else { $wolphrase = 'x_y_members_z_guests'; } $woltext = construct_phrase($vbphrase[$wolphrase], vb_number_format($wolcounts['total']), vb_number_format($wolcounts['members']), vb_number_format($wolcounts['guests'])); } if (!empty($loadavg)) { print_label_row($vbphrase['server_load_averages'], "{$loadavg['0']} {$loadavg['1']} {$loadavg['2']} | " . $woltext, '', 'top', NULL, false); } else { print_label_row($vbphrase['users_online'], $woltext, '', 'top', NULL, false); }
function parseForum($node) { $subforums = array(); if (isset($node['subchannels']) and !empty($node['subchannels'])) { foreach ($node['subchannels'] as $subforum) { $subforums[] = $this->parseForum($subforum); } } $top = vB_Api::instance('content_channel')->fetchTopLevelChannelIds(); $top = $top['forum']; return array('parentid' => $node['parentid'] == $top ? -1 : $node['parentid'], 'forumid' => $node['nodeid'], 'title' => $node['title'], 'description' => $node['description'] !== null ? $node['description'] : '', 'title_clean' => strip_tags($node['title']), 'description_clean' => strip_tags($node['description']), 'threadcount' => $node['textcount'], 'replycount' => $node['totalcount'], 'lastpostinfo' => array('lastthreadid' => $node['lastcontent']['nodeid'], 'lastthreadtitle' => $node['lastcontent']['title'], 'lastposter' => $node['lastcontent']['authorname'], 'lastposterid' => $node['lastcontent']['userid'], 'lastposttime' => $node['lastcontent']['created']), 'is_category' => $node['category'], 'is_link' => 0, 'subforums' => $subforums); }
function fr_parse_conversation($message, $bbcode = false) { $message_tree = vB_Api::instance('content_privatemessage')->getMessage($message['nodeid']); $new_posts = false; $message_ids = array(); foreach ($message_tree['messages'] as $message) { if (!$message['msgread']) { $message_ids[] = $message['nodeid']; $new_posts = true; } } if ($new_posts) { vB_Api::instance('content_privatemessage')->setRead($message_ids, 0); } $message = $message_tree['message']; $out = array('conversation_id' => $message['nodeid'], 'title' => $message['title'] ? $message['title'] : remove_bbcode($message['pagetext']), 'new_posts' => $new_posts, 'total_messages' => count($message_tree['messages'])); if ($message['lastcontentid'] > 0) { $lastcontent = $message_tree['messages'][$message['lastcontentid']]; $out['userid'] = $message['lastauthorid']; $out['username'] = $message['lastauthorid'] > 0 ? $message['lastcontentauthor'] : (string) new vB_Phrase('global', 'guest'); $out['preview'] = make_preview($lastcontent['rawtext']); $out['lastmessagetime'] = fr_date($message['lastcontent']); } else { $out['userid'] = $message['userid']; $out['username'] = $message['authorname']; $out['preview'] = make_preview($message['rawtext']); $out['lastmessagetime'] = fr_date($message['publishdate']); } return $out; }