/** * Create a blog channel. * * @param array $input * @param int $channelid * @param int $channelConvTemplateid * @param int $channelPgTemplateId * @param int $ownerSystemGroupId * * @return int The nodeid of the new blog channel */ public function createChannel($input, $channelid, $channelConvTemplateid, $channelPgTemplateId, $ownerSystemGroupId) { $input['parentid'] = $channelid; $input['inlist'] = 1; // we don't want it to be shown in channel list, but we want to move them $input['protected'] = 0; if (empty($input['userid'])) { $input['userid'] = vB::getCurrentSession()->get('userid'); } if (!isset($input['publishdate'])) { $input['publishdate'] = vB::getRequest()->getTimeNow(); } $input['templates']['vB5_Route_Channel'] = $channelPgTemplateId; $input['templates']['vB5_Route_Conversation'] = $channelConvTemplateid; // add channel node $channelLib = vB_Library::instance('content_channel'); $input['page_parentid'] = 0; $result = $channelLib->add($input, array('skipFloodCheck' => true, 'skipDupCheck' => true)); //Make the current user the channel owner. $userApi = vB_Api::instanceInternal('user'); $usergroup = vB::getDbAssertor()->getRow('usergroup', array('systemgroupid' => $ownerSystemGroupId)); if (empty($usergroup) or !empty($usergroup['errors'])) { //This should never happen. It would mean an invalid parameter was passed throw new vB_Exception_Api('invalid_request'); } vB_User::setGroupInTopic($input['userid'], $result['nodeid'], $usergroup['usergroupid']); vB_Cache::allCacheEvent(array('nodeChg_' . $this->blogChannel, "nodeChg_{$channelid}")); vB::getUserContext()->rebuildGroupAccess(); vB_Channel::rebuildChannelTypes(); // clear follow cache vB_Api::instanceInternal('follow')->clearFollowCache(array($input['userid'])); return $result['nodeid']; }
function do_get_new_updates() { include_once MCWD . '/include/login.php'; do_login(); $out = array('pm_notices' => get_pm_unread(), 'sub_notices' => get_sub_thread_updates()); vB_User::processLogout(); return $out; }
function vB_XML_Builder($content_type = null, $charset = null) { if ($content_type) { $this->content_type = $content_type; } if ($charset == null) { $userinfo = vB_User::fetchUserinfo(); $charset = !empty($userinfo['lang_charset']) ? $userinfo['lang_charset'] : vB_Template_Runtime::fetchStyleVar('charset'); if (empty($charset)) { $charset = 'utf-8'; } } $this->charset = strtolower($charset) == 'iso-8859-1' ? 'windows-1252' : $charset; }
public function __construct(&$dBAssertor, &$datastore, &$config, $userid) { $restoreSessionInfo = array('userid' => $userid); parent::__construct($dBAssertor, $datastore, $config, '', $restoreSessionInfo); $this->set('userid', $userid); //If we are in unit test we need to force a load of userinfo. if (defined('VB_AREA') and VB_AREA == 'Unit Test' and $userid > 0) { $useroptions = array(); if (defined('IN_CONTROL_PANEL')) { $useroptions[] = vB_Api_User::USERINFO_ADMIN; } $this->userinfo = vB_User::fetchUserInfo($this->vars['userid'], $useroptions, $this->vars['languageid'], true); } //needed for error message handling. $_SERVER['HTTP_HOST'] = 'commandline'; }
public function __construct($routeInfo, $matches, $queryString = '', $anchor = '') { if (empty($matches['tab'])) { $matches['tab'] = 'profile'; } parent::__construct($routeInfo, $matches, $queryString, $anchor); if (empty($this->arguments['userid'])) { $userInfo = vB::getCurrentSession()->fetch_userinfo(); $this->arguments['userid'] = $userInfo['userid']; $this->arguments['username'] = $userInfo['username']; } else { if (empty($this->arguments['username'])) { $userInfo = vB_User::fetchUserinfo($this->arguments['userid']); $this->arguments['username'] = $userInfo['username']; } } $this->breadcrumbs = array(0 => array('title' => $this->arguments['username'], 'url' => vB5_Route::buildUrl('profile', array('userid' => $this->arguments['userid'], 'username' => vB_String::getUrlIdent($this->arguments['username'])))), 1 => array('phrase' => 'user_settings', 'url' => '')); }
protected function getNewRouteInfo() { $param =& $this->queryParameters; $search = array(); // pull the parameter that still compatible with vb5 and discard others if (isset($param['userid'])) { $user = vB_User::fetchUserinfo($param['userid']); if ($user !== false) { $search['author'] = $user['username']; } } if (isset($param['starteronly'])) { $search['starter_only'] = $param['starteronly']; } if (isset($param['forumchoice'])) { $oldcontenttypeid = vB_Types::instance()->getContentTypeID(array('package' => 'vBForum', 'class' => 'Forum')); foreach ($param['forumchoice'] as $oldid) { $node = vB::getDbAssertor()->getRow('vBForum:node', array('oldid' => $oldid, 'oldcontenttypeid' => $oldcontenttypeid)); $search['channel'][] = $node['nodeid']; } } if (isset($param['do'])) { switch ($param['do']) { case 'finduser': if (!empty($search)) { $searchJSON = json_encode($search); } break; case 'getdaily': case 'getnew': $searchJSON = '{"date":"lastVisit","view":"topic","unread_only":1,"sort":{"lastcontent":"desc"},"exclude_type":["vBForum_PrivateMessage"]}'; break; default: } } $param = array(); if (!empty($searchJSON)) { $param['searchJSON'] = $searchJSON; } return 'search'; }
protected function initRoute($routeInfo, $matches, $queryString = '', $anchor = '') { parent::initRoute($routeInfo, $matches, $queryString, $anchor); // if we don't have a numeric userid at this point, make it 0 $this->arguments['userid'] = isset($this->arguments['userid']) ? intval($this->arguments['userid']) : 0; //there are lots of places we can get the username from if we don't have it, check them. if (!empty($this->arguments['userid']) and empty($this->arguments['username'])) { //node records provide both the username and the userid but under a different value. We generate profile links for node //display frequently and we'd like to avoid an extra database trip if (!empty($matches['authorname'])) { $this->arguments['username'] = $matches['authorname']; } else { //a lot of our profile links are for the current user -- who's information we have cached. $currentuser = vB::getCurrentSession()->fetch_userinfo(); if ($this->arguments['userid'] == $currentuser['userid']) { $this->arguments['username'] = $currentuser['username']; } else { $user = vB_User::fetchUserinfo($this->arguments['userid']); $this->arguments['username'] = $user['username']; } } } }
/** * This creates a request for access to a channel * * @param int $channelid the nodeid of the channel to which access is requested. * @param string $requestType the type of request. See vB_Api_Node::REQUEST_<> constants * @param int $recipient the userid of the member who will get the request * @param string $recipientname (Optional) the username of the member who will get the request * @param boolean $skipFloodCheck (Optional) whether request private message should skip flood check or not * * @return mixed If it is 1 or true, then it means that the follow request was successful. * If it is integer and greater than 1, then the request is pending. */ public function requestChannel($channelid, $requestType, $recipient = 0, $recipientname = null, $skipFloodCheck = false) { $userInfo = vB::getCurrentSession()->fetch_userinfo(); $userid = $userInfo['userid']; if (!($userid > 0)) { throw new vB_Exception_API('not_logged_no_permission'); } //make sure the parameters are valid if (!intval($channelid) or !intval($channelid) or !in_array($requestType, array(vB_Api_Node::REQUEST_TAKE_OWNER, vB_Api_Node::REQUEST_TAKE_MODERATOR, vB_Api_Node::REQUEST_TAKE_MEMBER, vB_Api_Node::REQUEST_GRANT_OWNER, vB_Api_Node::REQUEST_GRANT_MODERATOR, vB_Api_Node::REQUEST_GRANT_MEMBER, vB_Api_Node::REQUEST_SG_TAKE_OWNER, vB_Api_Node::REQUEST_SG_TAKE_MODERATOR, vB_Api_Node::REQUEST_SG_TAKE_MEMBER, vB_Api_Node::REQUEST_SG_GRANT_OWNER, vB_Api_Node::REQUEST_SG_GRANT_MODERATOR, vB_Api_Node::REQUEST_SG_GRANT_MEMBER, vB_Api_Node::REQUEST_TAKE_SUBSCRIBER, vB_Api_Node::REQUEST_GRANT_SUBSCRIBER, vB_Api_Node::REQUEST_SG_TAKE_SUBSCRIBER, vB_Api_Node::REQUEST_SG_GRANT_SUBSCRIBER))) { throw new vB_Exception_API('invalid_data'); } if ($recipient <= 0) { if (!empty($recipientname)) { // fetch by username $recipient = vB::getDbAssertor()->getField('user', array('username' => $recipientname)); if (!$recipient) { throw new vB_Exception_API('invalid_data'); } } else { throw new vB_Exception_API('invalid_data'); } } $node = $this->getNode($channelid); if ($node['contenttypeid'] != vB_Types::instance()->getContentTypeId('vBForum_Channel')) { throw new vB_Exception_API('invalid_request'); } //Let's make sure the user can grant this request. if (in_array($requestType, array(vB_Api_Node::REQUEST_TAKE_OWNER, vB_Api_Node::REQUEST_TAKE_MODERATOR, vB_Api_Node::REQUEST_TAKE_MEMBER, vB_Api_Node::REQUEST_SG_TAKE_OWNER, vB_Api_Node::REQUEST_SG_TAKE_MODERATOR, vB_Api_Node::REQUEST_SG_TAKE_MEMBER))) { //Can we grant the transfer? $userContext = vB::getUserContext(); if (!$userContext->getChannelPermission('moderatorpermissions', 'canaddowners', $channelid)) { throw new vB_Exception_API('no_permission'); } } else { // join is not valid when invite only... if (in_array($requestType, array(vB_Api_Node::REQUEST_GRANT_MEMBER, vB_Api_Node::REQUEST_SG_GRANT_MEMBER)) and ($node['nodeoptions'] & vB_Api_Node::OPTION_NODE_INVITEONLY) > 0) { throw new vB_Exception_Api('invalid_invite_only_request'); } //if this is set to auto-approve we don't need to send a request. if (in_array($requestType, array(vB_Api_Node::REQUEST_GRANT_MEMBER, vB_Api_Node::REQUEST_SG_GRANT_MEMBER)) and ($node['nodeoptions'] & vB_Api_Node::OPTION_AUTOAPPROVE_MEMBERSHIP) > 0) { $isBlog = vB_Api::instanceInternal('blog')->isBlogNode($channelid); $group = vB::getDbAssertor()->getRow('usergroup', array('systemgroupid' => vB_Api_UserGroup::CHANNEL_MEMBER_SYSGROUPID)); if ($isBlog) { // clear follow cache vB_Api::instanceInternal('follow')->clearFollowCache(array($userid)); } // return boolean true if successful $result = vB_User::setGroupInTopic($userid, $channelid, $group['usergroupid']); // for join requests, check for auto-subscribe & add subscription for user if ($result === true and $node['nodeoptions'] & vB_Api_Node::OPTION_AUTOSUBSCRIBE_ON_JOIN) { vB_Api::instanceInternal('follow')->add($channelid, vB_Api_Follow::FOLLOWTYPE_CHANNELS, $userid, true); } return $result; } if (in_array($requestType, array(vB_Api_Node::REQUEST_GRANT_SUBSCRIBER, vB_Api_Node::REQUEST_SG_GRANT_SUBSCRIBER))) { // subscribe means join in blog's context try { // @TODO check if using only the canview perms is fair enough... there might be cases where sg owner set canview perms for everyone that includes no joined members, even not logged users... if (!vB::getUserContext()->getChannelPermission('forumpermissions', 'canview', $channelid)) { throw new vB_Exception_Api('invalid_special_channel_subscribe_request'); } // check the auto accept first if (($node['nodeoptions'] & vB_Api_Node::OPTION_AUTOAPPROVE_SUBSCRIPTION) > 0) { // return int 1 - Following for auto-approved subscriptions return $response = vB_Api::instanceInternal('follow')->add($channelid, vB_Api_Follow::FOLLOWTYPE_CONTENT); } //see if this is set to invite only if (($node['nodeoptions'] & vB_Api_Node::OPTION_NODE_INVITEONLY) > 0) { throw new vB_Exception_Api('invalid_special_channel_subscribe_request'); } $owner = vB_Api::instanceInternal('blog')->fetchOwner($channelid); if (!$owner) { $recipient = $node['userid']; } else { $recipient = $owner; } } catch (vB_Exception_Api $ex) { throw $ex; } } //Can the recipient grant the transfer? $userContext = vB::getUserContext($recipient); if (!$userContext->getChannelPermission('moderatorpermissions', 'canaddowners', $channelid)) { throw new vB_Exception_API('no_permission'); } } $messageLib = vB_Library::instance('content_privatemessage'); $userInfo = vB::getCurrentSession()->fetch_userinfo(); $data = array('msgtype' => 'request', 'about' => $requestType, 'sentto' => $recipient, 'aboutid' => $channelid, 'sender' => $userInfo['userid']); // return int nodeid of created pending request if ($skipFloodCheck) { $result = $messageLib->addMessageNoFlood($data); return $result; } else { $result = $messageLib->add($data); return $result['nodeid']; } }
protected function checkCSRF() { if (!empty($_SERVER['REQUEST_METHOD']) and strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') { $userinfo = vB_User::fetchUserinfo(); if ($userinfo['userid'] > 0 and (!defined('CSRF_PROTECTION') or defined('CSRF_PROTECTION') and CSRF_PROTECTION === true)) { if (!$this->location['login']) { if (!isset($_POST['securitytoken'])) { $_POST['securitytoken'] = ''; } if (!vB_User::verifySecurityToken($_POST['securitytoken'], $userinfo['securitytoken_raw'])) { switch ($_POST['securitytoken']) { case '': return array('error' => 'security_token_missing'); case 'guest': return array('error' => 'security_token_guest'); case 'timeout': return array('error' => 'security_token_timeout'); default: return array('error' => 'security_token_invalid'); } } } } } return false; }
define('VB_ERROR_PERMISSION', true); $show['useurl'] = true; $show['specificerror'] = true; $url = $vbulletin->url; if ($vbulletin->options['usestrikesystem']) { admin_login_error('badlogin_strikes_passthru', array('strikes' => $strikes + 1)); eval(standard_error(fetch_error('badlogin_strikes_passthru', vB5_Route::buildUrl('lostpw|fullurl'), $strikes + 1))); } else { admin_login_error('badlogin_passthru', array('strikes' => $strikes + 1)); eval(standard_error(fetch_error('badlogin_passthru', vB5_Route::buildUrl('lostpw|fullurl'), $strikes + 1))); } } } vB_User::execUnstrikeUser($vbulletin->GPC['vb_login_username']); // create new session $res = vB_User::processNewLogin($auth, $vbulletin->GPC['logintype'], $vbulletin->GPC['cssprefs']); // set cookies (temp hack for admincp) if (isset($res['cpsession'])) { vbsetcookie('cpsession', $res['cpsession'], false, true, true); } vbsetcookie('userid', $res['userid'], false, true, true); vbsetcookie('password', $res['password'], false, true, true); vbsetcookie('sessionhash', $res['sessionhash'], false, false, true); // do redirect do_login_redirect(); } else { if ($_GET['do'] == 'login') { // add consistency with previous behavior exec_header_redirect(vB5_Route::buildUrl('home|fullurl')); } }
/** * Handles removing a channel moderator * * @param int $channelid The channel id of that $userId is leaving * @param int $userId Userid of the user leaving the channel. * * @param bool Flag indicating the moderator was removed successfully */ public function removeChannelModerator($channelId, $userId) { if (!intval($channelId)) { throw new vB_Exception_Api('invalid_node_id'); } if (!(intval($userId) > 0)) { throw new vB_Exception_Api('invalid_user_specified'); } // only the channel owner can add or remove moderators $currentUser = vB::getUserContext()->fetchUserId(); if ($currentUser != $this->fetchOwner($channelId)) { throw new vB_Exception_Api('invalid_permissions'); } // check for member/moderator records. $memberGroupId = vB_Api::instanceInternal('usergroup')->getMemberGroupId(); $moderatorGroupId = vB_Api::instanceInternal('usergroup')->getModeratorGroupId(); $gitQry = vB::getDbAssertor()->assertQuery('vBForum:groupintopic', array('userid' => $userId, 'nodeid' => $channelId, 'groupid' => array($memberGroupId, $moderatorGroupId))); // If the soon to be ex-moderator does not have a membership, we add one, but only // if they were actually a moderator (as opposed to pending) $needsMembership = false; if ($gitQry->valid()) { foreach ($gitQry as $gitRow) { if ($gitRow['groupid'] == $moderatorGroupId) { $needsMembership = true; } else { if ($gitRow['groupid'] == $memberGroupId) { $needsMembership = false; break; } } } } // unset group in topic, which also removes pending requests to that user $result = vB_Api::instanceInternal('user')->unsetGroupInTopic($userId, $channelId, $moderatorGroupId); // add membership & subscription as needed if ($needsMembership) { $isMember = vB_User::setGroupInTopic($userId, $channelId, $memberGroupId); // if autosubscribe, add subscription $node = vB_Api::instanceInternal('node')->getNode($channelId); if (($node['nodeoptions'] & vB_Api_Node::OPTION_AUTOSUBSCRIBE_ON_JOIN) > 0 and $isMember) { vB_Api::instanceInternal('follow')->add($channelId, vB_Api_Follow::FOLLOWTYPE_CHANNELS, $userId, true); } } return $result; }
/** * (Re)Generates an Activation ID for a user * * @param integer User's ID * @param integer The group to move the user to when they are activated * @param integer 0 for Normal Activation, 1 for Forgotten Password * @param boolean Whether this is an email change or not * * @return string The Activation ID * */ function build_user_activation_id($userid, $usergroupid, $type, $emailchange = 0) { global $vbulletin; if ($usergroupid == 3 or $usergroupid == 0) { // stop them getting stuck in email confirmation group forever :) $usergroupid = 2; } vB::getDbAssertor()->assertQuery('useractivation', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_DELETE, 'userid' => $userid, 'type' => $type)); $activateid = fetch_random_string(40); /*insert query*/ vB::getDbAssertor()->assertQuery('user_replaceuseractivation', array('userid' => $userid, 'timenow' => vB::getRequest()->getTimeNow(), 'activateid' => $activateid, 'type' => $type, 'usergroupid' => $usergroupid, 'emailchange' => intval($emailchange))); if ($userinfo = vB_User::fetchUserinfo($userid)) { $userdata = new vB_Datamanager_User($vbulletin, vB_DataManager_Constants::ERRTYPE_SILENT); $userdata->set_existing($userinfo); $userdata->set_bitfield('options', 'noactivationmails', 0); $userdata->save(); } return $activateid; }
/** * Ban users * * @param array $userids Userids to ban * @param int $banusergroupid Which banned usergroup to move the users to * @param string $period Ban period * @param string $reason Ban reason */ public function banUsers($userids, $banusergroupid, $period, $reason = '') { $loginuser =& vB::getCurrentSession()->fetch_userinfo(); $usercontext =& vB::getUserContext($loginuser['userid']); if (!$usercontext->hasAdminPermission('cancontrolpanel') and !$usercontext->hasPermission('moderatorpermissions', 'canbanusers')) { $forumHome = vB_Library::instance('content_channel')->getForumHomeChannel(); throw new vB_Exception_Api('nopermission_loggedin', array($loginuser['username'], vB_Template_Runtime::fetchStyleVar('right'), vB::getCurrentSession()->get('sessionurl'), $loginuser['securitytoken'], vB5_Route::buildUrl($forumHome['routeid'] . '|fullurl'))); } foreach ($userids as &$userid) { $userid = intval($userid); } $bannedusergroups = vB_Api::instanceInternal('usergroup')->fetchBannedUsergroups(); if (!in_array($banusergroupid, array_keys($bannedusergroups))) { throw new vB_Exception_Api('invalid_usergroup_specified'); } // check that the number of days is valid if ($period != 'PERMANENT' and !preg_match('#^(D|M|Y)_[1-9][0-9]?$#', $period)) { throw new vB_Exception_Api('invalid_ban_period_specified'); } if ($period == 'PERMANENT') { // make this ban permanent $liftdate = 0; } else { // get the unixtime for when this ban will be lifted require_once DIR . '/includes/functions_banning.php'; $liftdate = convert_date_to_timestamp($period); } $user_dms = array(); $current_bans = vB::getDbAssertor()->getRows('user_fetchcurrentbans', array('userids' => $userids)); foreach ($current_bans as $current_ban) { $userinfo = vB_User::fetchUserinfo($current_ban['userid']); $userid = $userinfo['userid']; if ($current_ban['bandate']) { // they already have a ban, check if the current one is being made permanent, continue if its not if ($liftdate and $liftdate < $current_ban['liftdate']) { continue; } // there is already a record - just update this record vB::getDbAssertor()->update('userban', array('bandate' => vB::getRequest()->getTimeNow(), 'liftdate' => $liftdate, 'adminid' => $loginuser['userid'], 'reason' => $reason), array('userid' => $userinfo['userid'])); } else { // insert a record into the userban table /*insert query*/ vB::getDbAssertor()->insert('userban', array('userid' => $userinfo['userid'], 'usergroupid' => $userinfo['usergroupid'], 'displaygroupid' => $userinfo['displaygroupid'], 'customtitle' => $userinfo['customtitle'], 'usertitle' => $userinfo['usertitle'], 'adminid' => $loginuser['userid'], 'bandate' => vB::getRequest()->getTimeNow(), 'liftdate' => $liftdate, 'reason' => $reason)); } // update the user record $user_dms[$userid] = new vB_Datamanager_User(vB_DataManager_Constants::ERRTYPE_SILENT); $user_dms[$userid]->set_existing($userinfo); $user_dms[$userid]->set('usergroupid', $banusergroupid); $user_dms[$userid]->set('displaygroupid', 0); // update the user's title if they've specified a special user title for the banned group if ($bannedusergroups[$banusergroupid]['usertitle'] != '') { $user_dms[$userid]->set('usertitle', $bannedusergroups[$banusergroupid]['usertitle']); $user_dms[$userid]->set('customtitle', 0); } $user_dms[$userid]->pre_save(); } foreach ($user_dms as $userdm) { $userdm->save(); } // and clear perms foreach ($userids as $uid) { vB::getUserContext($uid)->clearChannelPermissions(); } return true; }
/** * Send contact us mail * * @param array $maildata contact us mail data. Including name, email, subject, other_subject, message * @param array $hvinput Human Verify input data. @see vB_Api_Hv::verifyToken() * @throws vB_Exception_Api */ public function sendMail($maildata, $hvinput = array()) { $vboptions = vB::getDatastore()->getValue('options'); if (empty($maildata['name']) || empty($maildata['email']) || empty($maildata['message'])) { throw new vB_Exception_Api('please_complete_required_fields'); } if ($vboptions['contactusoptions'] and $maildata['subject'] == 'other' and ($maildata['other_subject'] == '' or !$vboptions['contactusother'])) { throw new vB_Exception_Api('nosubject'); } if (!is_valid_email($maildata['email'])) { throw new vB_Exception_Api('bademail'); } vB_Api::instanceInternal('hv')->verifyToken($hvinput, 'contactus'); // No Errors. Send mail. $languageid = -1; if ($vboptions['contactusoptions']) { if ($maildata['subject'] == 'other') { $maildata['subject'] = $maildata['other_subject']; } else { $options = explode("\n", trim($vboptions['contactusoptions'])); foreach ($options as $index => $title) { if ($index == $maildata['subject']) { if (preg_match('#^{(.*)} (.*)$#siU', $title, $matches)) { $title =& $matches[2]; if (is_numeric($matches[1]) and intval($matches[1]) !== 0) { $userinfo = vB_User::fetchUserinfo($matches[1]); $alt_email =& $userinfo['email']; $languageid =& $userinfo['languageid']; } else { $alt_email = $matches[1]; } } $maildata['subject'] = $title; break; } } } } if (!empty($alt_email)) { if ($alt_email == $vboptions['webmasteremail'] or $alt_email == $vboptions['contactusemail']) { $ip = vB::getRequest()->getIpAddress(); } else { $ip =& $vbphrase['n_a']; } $destemail =& $alt_email; } else { $ip = vB::getRequest()->getIpAddress(); if ($vboptions['contactusemail']) { $destemail =& $vboptions['contactusemail']; } else { $destemail =& $vboptions['webmasteremail']; } } $currentuser = vB::getCurrentSession()->fetch_userinfo(); $mailcontent = vB_Api::instanceInternal('phrase')->fetchEmailPhrases('contactus', array($vboptions['bbtitle'], $maildata['name'], $maildata['email'], $maildata['message'], $ip, $currentuser['username'], $currentuser['userid']), array($vboptions['bbtitle'], $maildata['subject']), $languageid); $flood = vB_Mail::vbmail($destemail, $mailcontent['subject'], $mailcontent['message'], true, $maildata['email']); if (is_array($flood)) { throw new vB_Exception_Api($flood[0], $flood[1]); } return true; }
/** * Validates that the current can create a node with these values * * @param array $data Array of field => value pairs which define the record. * @param int $action The action const, used to be checked for permission * @param int $nodeid * @param array|int nodeid or array of nodeids. If not passed $data must contain a nodeid * @param array $nodes -- $node records corresponding to the $nodeid variable. If not passed will be fetched from the DB * * @return bool */ public function validate(&$data, $action = self::ACTION_ADD, $nodeid = false, $nodes = false) { // Each descendant should override this function and add their own // check of individual required fields. if (defined('VB_AREA') and VB_AREA == 'Upgrade') { return true; } if (vB::getUserContext()->isSuperAdmin()) { //The only reason we would return false is if comments are globally disabled AND the content type is neither attachment nor photo, this // would be a comment, and the reply would be a comment. if ($action != self::ACTION_ADD or vB::getDatastore()->getOption('postcommentthreads') or $data['contenttypeid'] == vB_Types::instance()->getContentTypeID('vBForum_Photo') or $data['contenttypeid'] == vB_Types::instance()->getContentTypeID('vBForum_Attach')) { return true; } if (empty($data['parentid']) or !intval($data['parentid'])) { throw new vB_Exception_Api('invalid_data'); } $parent = vB_Library::instance('node')->getNodeBare($data['parentid']); //If the parent is not a starter. this would be a comment. if ($parent['starter'] > 0 and $parent['nodeid'] != $parent['starter']) { return false; } return true; } //we need a nodeid (or parentid if we are adding) or we cannot answer the question. if ($action == vB_Api_Content::ACTION_ADD) { if (empty($data['parentid']) or !intval($data['parentid'])) { throw new vB_Exception_Api('invalid_data'); } $parentid = $data['parentid']; } else { if (!$nodeid) { if (empty($data['nodeid'])) { throw new Exception('invalid_data'); } $nodeid = $data['nodeid']; } if (!is_array($nodeid)) { $nodeid = array($nodeid); } if (!$nodes) { // We need to go through the library. If current user doesn't have permission to view the node, // the API wouldn't return that node, and if the caller didn't pass in the specific array of nodes, // this function would incorrectly return "true". $nodes = vB_Library::instance('node')->getNodes($nodeid); } } $userContext = vB::getUserContext(); $userid = vB::getCurrentSession()->get('userid'); switch ($action) { case vB_Api_Content::ACTION_ADD: //Check the node-specific permissions first. $parent = vB_Library::instance('node')->getNode($parentid); if (in_array($this->contenttype, array('vBForum_Text', 'vBForum_Poll', 'vBForum_PrivateMessage')) and $parent['parentid'] != $parent['starter']) { // Only validate HV for specific content types. // To skip HV, please call library methods instead. vB_Api::instanceInternal('hv')->verifyToken($data['hvinput'], 'post'); } //confirm that the user can create this content type if (!$userContext->getChannelPermission('createpermissions', $this->contenttype, $parent['nodeid'])) { return FALSE; } //check the showPublished. if ($parent['showpublished'] == 0) { if (!$userContext->getChannelPermission('moderatorpermissions', 'canmoderateposts', $parentid)) { return false; } } if ($parent['open'] == 0 and !$userContext->getChannelPermission('moderatorpermissions', 'canmoderateposts', $parentid)) { return false; } //Data consistency for a VM. if ($parentid == vB_Api::instanceInternal('node')->fetchVMChannel()) { if (!isset($data['setfor']) or isset($data['setfor']) and (!is_numeric($data['setfor']) or $data['setfor'] <= 0)) { throw new vB_Exception_Api('invalid_data'); } $vm_user = vB_User::fetchUserinfo($data['setfor']); if ($vm_user == false or !$vm_user['vm_enable']) { throw new vB_Exception_Api('invalid_data'); } if ($data['setfor'] == $userid) { // Do we have add permission to write on our own wall? if (!vB::getUserContext()->hasPermission('visitormessagepermissions', 'canmessageownprofile')) { return false; } } else { if (!vB::getUserContext()->hasPermission('visitormessagepermissions', 'canmessageothersprofile')) { // Do we have permission to write on others' walls? return false; } } } return true; break; case vB_Api_Content::ACTION_UPDATE: //There are a couple of ways this user could be allowed to edit this record. // As a moderator $channelType = vB_Types::instance()->getContentTypeID('vBForum_Channel'); foreach ($nodes as $node) { // Can configure channel goes first, otherwise it is ignored due to the moderator perms if ($node['contenttypeid'] == $channelType) { $canEditChannels = ($userContext->getChannelPermission('forumpermissions2', 'canconfigchannel', $node['nodeid'], false, $node['parentid']) or $userContext->hasAdminPermission('canadminforums')); if (!$canEditChannels) { return false; } continue; } if ($userContext->getChannelPermission('moderatorpermissions', 'caneditposts', $node['nodeid'], false, $node['parentid'])) { continue; } $vmChannel = vB_Api::instanceInternal('node')->fetchVMChannel(); if ($node['parentid'] == $vmChannel) { $vm_user = vB_User::fetchUserinfo($node['setfor']); if (!$vm_user['vm_enable'] or $node['userid'] != $userid or !vB::getUserContext()->hasPermission('visitormessagepermissions', 'caneditownmessages') or !vB::getUserContext($vm_user['userid'])->hasPermission('genericpermissions', 'canviewmembers') and $userid == $vm_user['userid']) { return false; } } // It's a VM for the user from himself if (!empty($node['setfor']) and $node['setfor'] == $userid and $node['setfor'] == $node['userid'] and $userContext->hasPermission('visitormessagepermissions', 'caneditownmessages')) { continue; } //Now check the user permissions if ($node['userid'] == vB::getCurrentSession()->get('userid')) { //Check the editing time limit $limits = $userContext->getChannelLimits($node['nodeid']); if ($limits and !empty($limits['edit_time'])) { if ($node['publishdate'] + $limits['edit_time'] * 3600 < vB::getRequest()->getTimeNow()) { return false; } } if ($userContext->getChannelPermission('forumpermissions', 'caneditpost', $node['nodeid'], false, $node['parentid'])) { continue; } } else { if ($userContext->getChannelPermission('forumpermissions2', 'caneditothers', $node['nodeid'], false, $node['parentid'])) { continue; } } //if we got here the user isn't authorized to update this record. return false; } return true; break; case vB_Api_Content::ACTION_VIEW: $channelType = vB_Types::instance()->getContentTypeID('vBForum_Channel'); foreach ($nodes as $key => $node) { if (empty($node['nodeid']) or !is_numeric($node['nodeid'])) { $check = current($node); if (!empty($check['nodeid']) and is_numeric($check['nodeid'])) { $node = $check; } } $canViewChannel = $userContext->getChannelPermission('forumpermissions', 'canview', $node['nodeid'], false, $node['parentid']); if (!$canViewChannel) { return false; } if ($node['contenttypeid'] != $channelType) { // grab the starter's userid for the canviewothers check if (isset($node['starteruserid'])) { // 'starteruserid' is not always set, for ex when the $node // provided originated from node lib's getNodeBare() $starterUserid = $node['starteruserid']; } else { if ($node['nodeid'] == $node['starter']) { $starterUserid = $node['userid']; } else { $starter = vB_Api::instanceInternal('node')->getNode($node['starter']); $starterUserid = $starter['userid']; } } // They can't view this non-channel node if they just cannot view *any* threads, or if the thread is not theirs and they don't have canviewothers if (!$userContext->getChannelPermission('forumpermissions', 'canviewthreads', $node['nodeid'], false, $node['parentid']) or $starterUserid != $userid and !$userContext->getChannelPermission('forumpermissions', 'canviewothers', $node['nodeid'], false, $node['parentid'])) { return false; } } //If the node is published, we just need to check viewperms. if ($userid > 0 and $node['viewperms'] > 0 and $node['showpublished'] > 0 and $node['showapproved'] > 0) { continue; } //if the user has canalwaysview here, then ... they can view. if ($userContext->getChannelPermission('forumpermissions2', 'canalwaysview', $node['nodeid'], false, $node['parentid'])) { continue; } if ($node['viewperms'] > 1 and $node['showpublished'] > 0 and $node['showapproved'] > 0) { continue; } if (!$node['showapproved'] and !$userContext->getChannelPermission('moderatorpermissions', 'canmoderateposts', $node['nodeid'], false, $node['parentid'])) { return false; } // those with candeleteposts or canremoveposts moderator permissions should be able to view soft-deleted posts if (!$node['showpublished'] and !($userContext->getChannelPermission('moderatorpermissions', 'candeleteposts', $node['nodeid'], false, $node['parentid']) or $userContext->getChannelPermission('moderatorpermissions', 'canremoveposts', $node['nodeid'], false, $node['parentid']))) { return false; } if ($userContext->getChannelPermission('moderatorpermissions', 'caneditposts', $node['nodeid'], false, $node['parentid'])) { continue; } if ($node['viewperms'] == 0) { //Only blog members can view. We need to find the channel if ($node['contenttypeid'] == vB_Types::instance()->getContentTypeId('vBForum_Channel')) { $checkNodeId = $node['nodeid']; } else { if ($node['starter'] == $node['nodeid']) { //Check for the the parent's parent $checkNodeId = $node['parentid']; } else { // The channel is of course the starter's parent. $starter = vB_Api::instanceInternal('node')->getNode($node['starter']); $checkNodeId = $starter['parentid']; } } $groupInTopic = vB_Api::instanceInternal('user')->getGroupInTopic($userid, $checkNodeId); if (!$groupInTopic or empty($groupInTopic) or !empty($groupInTopic['errors'])) { //someone with moderator permission can view if ($userContext->getChannelPermission('moderatorpermissions', 'caneditposts', $node['nodeid'], false, $node['parentid'])) { continue; } if ($userContext->getChannelPermission('forumpermissions2', 'canalwaysview', $node['nodeid'], false, $node['parentid'])) { continue; } //Not O.K. return false; } $validGroups = vB_Api::instanceInternal('usergroup')->fetchPrivateGroups(); $found = false; foreach ($groupInTopic as $pair) { if (in_array($pair['groupid'], $validGroups)) { $found = true; break; } } if (!$found) { return false; } } else { if ($node['viewperms'] == 1 and $userid < 1) { return false; } } if (!$userContext->getChannelPermission('forumpermissions', 'canview', $node['nodeid'], false, $node['parentid'])) { return false; } } return true; break; case vB_Api_Content::ACTION_DELETE: foreach ($nodes as $node) { if ($node['contenttypeid'] !== vB_Types::instance()->getContentTypeID($this->contenttype)) { throw new vB_Exception_Api('invalid_request'); } // Check for Blog Channel - only allow owner to delete the blog // This part should just check for any channel, not a blog but see VBV-7931 if ($node['contenttypeid'] === vB_Types::instance()->getContentTypeId('vBForum_Channel')) { if ($userContext->getChannelPermission('forumpermissions2', 'candeletechannel', $node['nodeid']) or $userContext->hasAdminPermission('canadminforums')) { continue; } else { if (vB_Api::instanceInternal('socialgroup')->isSGNode($node['nodeid']) and $node['userid'] === vB::getCurrentSession()->get('userid')) { if (!$userContext->hasPermission('socialgrouppermissions', 'candeleteowngroups')) { return false; } continue; } else { return false; } } } if (!$userContext->getChannelPermission('moderatorpermissions', 'canremoveposts', $node['nodeid'])) { return false; } } return true; break; case vB_Api_Content::ACTION_APPROVE: foreach ($nodes as $node) { return $userContext->getChannelPermission('moderatorpermissions', 'canmoderateposts', $node['nodeid']); } break; case vB_Api_Content::ACTION_PUBLISH: foreach ($nodes as $node) { return $userContext->getChannelPermission('forumpermissions2', 'canpublish', $node['nodeid']); } break; default: } // switch }
/** * Applies the automatic ban to the user * * @param array User Info for the user to ban * @param array Data for the automatic ban to apply (returned from getAutomaticBanToApply) * @param array Data for the infraction that's being given */ protected function applyAutomaticBan(array $userInfo, array $banToApply, array $data) { $currentBan = $this->assertor->getRow('userban', array('userid' => $userInfo['userid'])); $user = vB::getCurrentSession()->fetch_userinfo(); // Drop the ban hammer if ($currentBan) { if (($banToApply['liftdate'] == 0 or $currentBan['liftdate'] < $banToApply['liftdate']) and $currentBan['liftdate'] != 0) { // there is already a record - just update this record $this->assertor->update('userban', array('bandate' => vB::getRequest()->getTimeNow(), 'liftdate' => $banToApply['liftdate'], 'adminid' => $user['userid'], 'reason' => $data['banreason']), array('userid' => $userInfo['userid'])); } } else { // insert a record into the userban table /*insert query*/ $this->assertor->insert('userban', array('userid' => $userInfo['userid'], 'usergroupid' => $userInfo['usergroupid'], 'displaygroupid' => $userInfo['displaygroupid'], 'customtitle' => $userInfo['customtitle'], 'usertitle' => $userInfo['usertitle'], 'bandate' => vB::getRequest()->getTimeNow(), 'liftdate' => $banToApply['liftdate'], 'adminid' => $user['userid'], 'reason' => $data['banreason'])); } //$existingUserInfo = $this->assertor->getRow('user', array('userid' => $userInfo['userid'])); $existingUserInfo = vB_User::fetchUserinfo($userInfo['userid']); // update the user record $userdata = new vB_Datamanager_User(vB::get_registry(), vB_DataManager_Constants::ERRTYPE_SILENT); $userdata->set_existing($existingUserInfo); $userdata->set('usergroupid', $banToApply['banusergroupid']); $userdata->set('displaygroupid', 0); // update the user's title if they've specified a special user title for the banned group $bannedUserGroups = vB_Api::instanceInternal('usergroup')->fetchBannedUsergroups(); if ($bannedUserGroups[$banToApply['banusergroupid']]['usertitle'] != '') { $userdata->set('usertitle', $bannedUserGroups[$banToApply['banusergroupid']]['usertitle']); $userdata->set('customtitle', 0); } $userdata->save(); unset($userdata); }
/** * Clear user cached info for given userids. * There's currently cached info in several places (vB_Session, vB_User and vB_Cache implementations) * this makes sure they all properly cleared. * * @param array List of users to clear cache. * * @param bool Cache was cleared or not. **/ public function clearUserInfo($userids) { if (empty($userids) or !is_array($userids)) { return false; } $events = array(); $userids = array_unique($userids); $session = vB::getCurrentSession(); $currentuser = $session->get('userid'); $updatecurrent = false; foreach ($userids as $userid) { // update current user? if ($currentuser == $userid) { $updatecurrent = true; } vB_User::clearUsersCache($userid); $events[] = 'userChg_' . $userid; } vB_Cache::allCacheEvent($events); if ($updatecurrent) { $session->clearUserInfo(); } return true; }
/** * Checks if userid's notification options for notification type * * @return boolean true if user should receive the notificationType */ public function userReceivesNotification($userid, $notificationType) { // grab bitfield masks for notification options $bf_masks = vB::getDatastore()->getValue('bf_misc_usernotificationoptions'); // each notification type should have an option linked to it. // note that NOTIFICATION_TYPE_MODERATE should not exist anymore. Mod messages go to // the pending posts folder $notificationOptionBitfields = array(self::NOTIFICATION_TYPE_VOTE => $bf_masks['general_voteconvs'], self::NOTIFICATION_TYPE_VOTEREPLY => $bf_masks['general_votereplies'], self::NOTIFICATION_TYPE_RATE => $bf_masks['general_likespost'], self::NOTIFICATION_TYPE_REPLY => $bf_masks['discussions_on'], self::NOTIFICATION_TYPE_COMMENT => $bf_masks['discussion_comment'], self::NOTIFICATION_TYPE_THREADCOMMENT => $bf_masks['discussions_on'], self::NOTIFICATION_TYPE_FOLLOW => $bf_masks['general_followrequest'], self::NOTIFICATION_TYPE_FOLLOWING => $bf_masks['general_followsyou'], self::NOTIFICATION_TYPE_VM => $bf_masks['general_vm'], self::NOTIFICATION_TYPE_USERMENTION => $bf_masks['general_usermention']); // grab user info $userInfo = vB_User::fetchUserinfo($userid); // if it has an option, check it. Notifications without an option are sent by default if (array_key_exists($notificationType, $notificationOptionBitfields)) { // check options return ($userInfo['notification_options'] & $notificationOptionBitfields[$notificationType]) == true; } else { // no option for this notification type, send notification return true; } }
/** * Replace securitytoken * */ public function actionReplaceSecurityToken() { $userinfo = vB_User::fetchUserinfo(); return array('newtoken' => $userinfo['securitytoken']); }
vB_Api::instanceInternal('user')->updateAccess($vbulletin->GPC['userid'], $vbulletin->GPC['accessupdate']); } catch (vB_Exception_Api $e) { $errors = $e->get_errors(); if (!empty($errors)) { $error = array_shift($errors); print_stop_message2($error[0]); } print_stop_message2('error'); } print_stop_message2('saved_access_masks_successfully', 'user', array('do' => 'edit', 'u' => $vbulletin->GPC['userid'])); } // ###################### Start modify ####################### if ($_REQUEST['do'] == 'modify') { $vbulletin->input->clean_array_gpc('r', array('userid' => vB_Cleaner::TYPE_INT, 'insertedadmin' => vB_Cleaner::TYPE_INT)); if ($vbulletin->GPC['userid']) { $userinfo = vB_User::fetchUserinfo($vbulletin->GPC['userid']); //$userinfo = fetch_userinfo($vbulletin->GPC['userid']); if (!$userinfo) { print_stop_message2('invalid_user_specified'); } print_form_header('user', 'edit', 0, 1, 'reviewform'); print_table_header($userinfo['username'], 2, 0, '', 'center', 0); construct_hidden_code('userid', $vbulletin->GPC['userid']); print_description_row(construct_link_code($vbphrase['view_profile'], "user.php?" . vB::getCurrentSession()->get('sessionurl') . "do=edit&u=" . $vbulletin->GPC['userid']) . iif($vbulletin->GPC['insertedadmin'], '<br />' . construct_link_code('<span style="color:red;"><strong>' . $vbphrase['update_or_add_administration_permissions'] . '</strong></span>', "adminpermissions.php?" . vB::getCurrentSession()->get('sessionurl') . "do=edit&u=" . $vbulletin->GPC['userid']))); print_table_footer(); } print_form_header('', ''); print_table_header($vbphrase['quick_search']); print_description_row("\n\t\t<ul>\n\t\t\t<li><a href=\"user.php?" . vB::getCurrentSession()->get('sessionurl') . "do=find\">" . $vbphrase['show_all_users'] . "</a></li>\n\t\t\t<li><a href=\"user.php?" . vB::getCurrentSession()->get('sessionurl') . "do=find&orderby=posts&direction=DESC&limitnumber=30\">" . $vbphrase['list_top_posters'] . "</a></li>\n\t\t\t<li><a href=\"user.php?" . vB::getCurrentSession()->get('sessionurl') . "do=find&user[lastactivityafter]=" . (TIMENOW - 86400) . "&orderby=lastactivity&direction=DESC\">" . $vbphrase['list_visitors_in_the_last_24_hours'] . "</a></li>\n\t\t\t<li><a href=\"user.php?" . vB::getCurrentSession()->get('sessionurl') . "do=find&orderby=joindate&direction=DESC&limitnumber=30\">" . $vbphrase['list_new_registrations'] . "</a></li>\n\t\t\t<li><a href=\"user.php?" . vB::getCurrentSession()->get('sessionurl') . "do=moderate\">" . $vbphrase['list_users_awaiting_moderation'] . "</a></li>\n\t\t\t<li><a href=\"user.php?" . vB::getCurrentSession()->get('sessionurl') . "do=find&user[coppauser]=1\">" . $vbphrase['show_all_coppa_users'] . "</a></li>\n\t\t</ul>\n\t"); print_table_footer(); print_form_header('user', 'find');
public function getUrl() { if (empty($this->arguments['title'])) { $node = vB_Library::instance('node')->getNodeBare($this->arguments['nodeid']); if (empty($node) or !empty($node['errors'])) { return FALSE; } if ($node['urlident']) { $this->arguments['title'] = $node['urlident']; } else { $this->arguments['title'] = vB_String::getUrlIdent($node['title']); } } if (empty($this->arguments['userid'])) { if (!isset($node['nodeid'])) { $node = vB_Library::instance('node')->getNodeBare($this->arguments['nodeid']); } if ($node['setfor']) { $user = vB_User::fetchUserinfo($node['setfor']); $this->arguments['userid'] = $user['userid']; $this->arguments['username'] = $user['username']; } } $url = '/member/' . $this->arguments['userid'] . '-' . vB_String::getUrlIdent($this->arguments['username']) . '/visitormessage/' . $this->arguments['nodeid'] . '-' . vB_String::vBStrToLower(vB_String::htmlSpecialCharsUni(str_replace(' ', '-', $this->arguments['title']))); if (strtolower(vB_String::getCharset()) != 'utf-8') { $url = vB_String::encodeUtf8Url($url); } return $url; }
/** * Fetch whovoted a node * @param $nodeid * @param $private_message false => return only who voted on that node, * true => return node voters plus the current loged user link to the voters (subscribed/notsubscribed) * * @return array Array of users. An user is also an array contains userid, username, isadmin, ismoderator */ public function fetchWhovoted($nodeid, $private_message = false) { $node = vB_Api::instanceInternal('node')->getNodeFullContent($nodeid); $node = $node[$nodeid]; $this->checkCanUseRep($node); if (!vB::getUserContext()->hasPermission('genericpermissions', 'canseewholiked')) { throw new vB_Exception_Api('no_permission'); } if ($private_message) { $currentUser = vB::getCurrentSession()->get('userid'); $users = $this->assertor->getRows('vBForum:reputation_privatemsg_fetchwhovoted', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'nodeid' => $node['nodeid'], 'currentuser' => $currentUser)); } else { $users = $this->assertor->getRows('vBForum:reputation_fetchwhovoted', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'nodeid' => $node['nodeid'])); } foreach ($users as &$user) { $user['ismoderator'] = false; $user['isadmin'] = false; $userinfo = vB_User::fetchUserinfo($user['userid']); $user['usertitle'] = $userinfo['usertitle']; $usercontext =& vB::getUserContext($user['userid']); if ($usercontext->hasPermission('adminpermissions', 'ismoderator')) { $user['ismoderator'] = true; } if ($usercontext->hasAdminPermission('cancontrolpanel')) { $user['isadmin'] = true; } $user['avatarurl'] = vB_Api::instanceInternal('user')->fetchAvatar($user['userid']); $user['avatarurl'] = $user['avatarurl']['avatarpath']; $user['profileurl'] = vB5_Route::buildUrl('profile', array('userid' => $user['userid'])); $user['musername'] = vB_Api::instanceInternal("user")->fetchMusername($user); } return $users; }
function do_logout() { $vbulletin = vB::get_registry(); $userinfo = vB_Api::instance('user')->fetchUserInfo(); $cleaned = vB::getCleaner()->cleanArray($_REQUEST, array('fr_username' => vB_Cleaner::TYPE_STR)); if ($userinfo['userid'] < 1) { return json_error(ERR_NO_PERMISSION); } $tableinfo = $vbulletin->db->query_first("\n\t\tSHOW TABLES LIKE '" . TABLE_PREFIX . "forumrunner_push_users'\n\t\t"); if ($tableinfo) { $vbulletin->db->query_write("\n\t\t\tDELETE FROM " . TABLE_PREFIX . "forumrunner_push_users\n\t\t\tWHERE fr_username = '******'fr_username']) . "' AND vb_userid = {$userinfo['userid']}\n\t\t\t"); } vB_User::processLogout(); // // Properly set cookies on logout // $login = array(); $session = vB::getCurrentSession(); $login['sessionhash'] = $session->get('sessionhash'); $login['password'] = $session->get('password'); $login['cpsession'] = $session->get('cpsession'); $login['userid'] = $session->get('userid'); vB5_Cookie::set('cpsession', $login['cpsession'], 30); vB5_Cookie::set('sessionhash', $login['sessionhash'], 30); vB5_Cookie::set('password', $login['password'], 30); vB5_Cookie::set('userid', $login['userid'], 30); return array('success' => true, 'requires_authentication' => requires_authentication()); }
/** Approves a channel request. * * @param int id of a request private message. * **/ public function approveChannelRequest($messageId) { $userInfo = vB::getCurrentSession()->fetch_userinfo(); $userid = $userInfo['userid']; $assertor = vB::getDbAssertor(); if (!intval($userid)) { throw new vB_Exception_Api('not_logged_no_permission'); } $sentto = $assertor->getRow('vBForum:sentto', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'nodeid' => $messageId, 'userid' => $userid)); if (!$sentto or !empty($sentto['errors'])) { throw new vB_Exception_Api('invalid_data'); } $messageApi = vB_Api::instanceInternal('content_privatemessage'); $message = $messageApi->getContent($messageId); $message = $message[$messageId]; if ($message['msgtype'] != 'request' or empty($message['aboutid'])) { throw new vB_Exception_Api('invalid_data'); } // if a user joins a channel as owner/moderator/member, check if they should automatically be subscribed $autoSubscribeMember = false; $node = $this->getNode($message['aboutid']); if (($node['nodeoptions'] & vB_Api_Node::OPTION_AUTOSUBSCRIBE_ON_JOIN) > 0) { $autoSubscribeMember = true; } switch ($message['about']) { case self::REQUEST_TAKE_MODERATOR: case self::REQUEST_SG_TAKE_MODERATOR: //Can we grant the transfer? $userContext = vB::getUserContext($message['userid']); if (!$userContext->getChannelPermission('moderatorpermissions', 'canaddowners', $message['aboutid'])) { throw new vB_Exception_API('no_permission'); } $usergroupInfo = vB_Api::instanceInternal('usergroup')->fetchUsergroupBySystemID(vB_Api_UserGroup::CHANNEL_MODERATOR_SYSGROUPID); $usergroupid = $usergroupInfo['usergroupid']; $permUserid = $userid; break; case self::REQUEST_TAKE_MEMBER: case self::REQUEST_SG_TAKE_MEMBER: $userContext = vB::getUserContext($message['userid']); if (!$userContext->getChannelPermission('moderatorpermissions', 'canaddowners', $message['aboutid'])) { throw new vB_Exception_API('no_permission'); } $usergroupInfo = vB_Api::instanceInternal('usergroup')->fetchUsergroupBySystemID(vB_Api_UserGroup::CHANNEL_MEMBER_SYSGROUPID); $usergroupid = $usergroupInfo['usergroupid']; $permUserid = $userid; break; case self::REQUEST_TAKE_OWNER: case self::REQUEST_SG_TAKE_OWNER: //Can we grant the transfer? $userContext = vB::getUserContext($message['userid']); if (!$userContext->getChannelPermission('moderatorpermissions', 'canaddowners', $message['aboutid'])) { throw new vB_Exception_API('no_permission'); } //We can't use the user api, because that checks the permissions. //let's get the current channels in which the user already is set for that group. //Then remove any for which they already are set. $usergroupInfo = vB_Api::instanceInternal('usergroup')->fetchUsergroupBySystemID(vB_Api_UserGroup::CHANNEL_OWNER_SYSGROUPID); $groupInTopic = vB_Api::instanceInternal('user')->getGroupInTopic($userid, $message['aboutid']); if ($groupInTopic and in_array($usergroupInfo, $groupInTopic)) { //This user already has this right $result = true; break; } //There is only one owner at a time, so we delete the current user; $result = $assertor->assertQuery('vBForum:groupintopic', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_DELETE, 'nodeid' => $message['aboutid'], 'groupid' => $usergroupInfo['usergroupid'])); //and do the inserts $result = $assertor->assertQuery('vBForum:groupintopic', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'userid' => $userid, 'nodeid' => $message['aboutid'], 'groupid' => $usergroupInfo['usergroupid'])); // add subscription for new owner if autosubcribe is enabled if ($autoSubscribeMember) { vB_Api::instanceInternal('follow')->add($message['aboutid'], vB_Api_Follow::FOLLOWTYPE_CHANNELS, $userid, true); } // Add membership for the old owner. Note the lack of auto-subscription check because an old owner // should already have a subscription if channel is auto-subscribe. $oldOwner = $node['userid']; $usergroupInfo = vB_Api::instanceInternal('usergroup')->fetchUsergroupBySystemID(vB_Api_UserGroup::CHANNEL_MEMBER_SYSGROUPID); vB_User::setGroupInTopic($oldOwner, $message['aboutid'], $usergroupInfo['usergroupid']); //replace the old owner in the node table as well $assertor->update('vBForum:node', array('userid' => $userid), array('nodeid' => $message['aboutid'])); $myUserContext = vB::getUserContext(); vB_Cache::instance()->allCacheEvent("userPerms_{$userid}"); // TODO: add node change event & check cache for blogs tab. Currently blogs tab doesn't update w/ the new owner. $myUserContext->clearChannelPermissions(); $myUserContext->reloadGroupInTopic(); $senderUserContext = vB::getUserContext($message['userid']); $senderUserContext->clearChannelPermissions(); $senderUserContext->reloadGroupInTopic(); return true; break; case self::REQUEST_GRANT_OWNER: case self::REQUEST_SG_GRANT_OWNER: // these requests don't exist yet. throw new vB_Exception_API('invalid_action'); // when these requests are implemented, be careful about what $permUserid below should be. // I think this request goes to the owner, so $permUserid has to be the sender of the message, // meaning we have to grab the node where nodeid = $message['nodeid'], & grab its author $usergroupInfo = vB_Api::instanceInternal('usergroup')->fetchUsergroupBySystemID(vB_Api_UserGroup::CHANNEL_OWNER_SYSGROUPID); $usergroupid = $usergroupInfo['usergroupid']; $permUserid = $message['userid']; break; case self::REQUEST_GRANT_MODERATOR: case self::REQUEST_SG_GRANT_MODERATOR: // these requests don't exist yet. throw new vB_Exception_API('invalid_action'); // when these requests are implemented, be careful about what $permUserid below should be. // I think this request goes to the owner, so $permUserid has to be the author of the message, // meaning we have to grab the node where nodeid = $message['nodeid'], & grab its author $usergroupInfo = vB_Api::instanceInternal('usergroup')->fetchUsergroupBySystemID(vB_Api_UserGroup::CHANNEL_MODERATOR_SYSGROUPID); $usergroupid = $usergroupInfo['usergroupid']; $permUserid = $message['userid']; break; case self::REQUEST_GRANT_MEMBER: case self::REQUEST_SG_GRANT_MEMBER: $usergroupInfo = vB_Api::instanceInternal('usergroup')->fetchUsergroupBySystemID(vB_Api_UserGroup::CHANNEL_MEMBER_SYSGROUPID); $usergroupid = $usergroupInfo['usergroupid']; $permUserid = $message['userid']; break; default: throw new vB_Exception_API('invalid_data'); } // switch $result = vB_User::setGroupInTopic($permUserid, $message['aboutid'], $usergroupid); // If automatic subscription is enabled for the channel (e.g. blogs by default) and if groupintopic is set // make the user follow the channel. if ($result === true and $autoSubscribeMember) { // The 4th param, $auto_subscribe = true, is required since an auto-subscribe probably doesn't come // with an existing subscriber request, only a join request. vB_Api::instanceInternal('follow')->add($message['aboutid'], vB_Api_Follow::FOLLOWTYPE_CHANNELS, $permUserid, true); } // I'm fairly certain that the below is incorrect. The (old) OWNER would receive the request, so $userid = $message['userid'].. // It should probably compaer $userid with $permUserid, given that $permUserid is corrected (see above case statement) //last item- if we just granted owner to a new member we should remove anyone else & add the old owner as a regular member if ($message['userid'] != $userid and in_array($message['about'], array(self::REQUEST_GRANT_OWNER, self::REQUEST_SG_GRANT_OWNER))) { $result = $assertor->assertQuery('vBForum:groupintopic', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_DELETE, vB_dB_Query::CONDITIONS_KEY => array(array('field' => 'nodeid', 'value' => $message['aboutid'], 'operator' => vB_dB_Query::OPERATOR_EQ), array('field' => 'groupid', 'value' => $usergroupid, 'operator' => vB_dB_Query::OPERATOR_EQ), array('field' => 'userid', 'value' => $message['userid'], 'operator' => vB_dB_Query::OPERATOR_NE)))); // TODO: if this is ever corrected/implemented, be sure to add the old owner as a member of the channel //reset the recipient's permissions. $myUserContext = vB::getUserContext(); vB_Cache::instance()->allCacheEvent("userPerms_{$userid}"); $myUserContext->clearChannelPermissions(); $myUserContext->reloadGroupInTopic(); } vB_Api::instanceInternal('user')->clearChannelPerms($userid); return true; }
protected function addFollow($userId) { $valid = $this->validate($userId); if ($valid['canproceed'] == true) { $userInfo = vB_User::fetchUserinfo($userId); $bitfields = vB::getDatastore()->get_value('bf_misc'); if ($valid['hasRelation']) { $params = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_UPDATE, vB_dB_Query::CONDITIONS_KEY => array('userid' => vB::getUserContext()->fetchUserId(), 'relationid' => $userId), 'type' => 'follow'); } else { $params = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'type' => 'follow', 'userid' => vB::getUserContext()->fetchUserId(), 'relationid' => $userId); } if ($userInfo['options'] & $bitfields['useroptions']['moderatefollowers']) { $userInfo = vB::getCurrentSession()->fetch_userinfo(); $request = vB_Library::instance('content_privatemessage')->addMessageNoFlood(array('msgtype' => 'request', 'sentto' => $userId, 'aboutid' => vB::getCurrentSession()->get('userid'), 'about' => 'follow', 'sender' => $userInfo['userid'])); $params['friend'] = 'pending'; } else { $params['friend'] = 'yes'; // send following notification $recipients = array($userId); $contextData = array('sender' => vB::getUserContext()->fetchUserId()); vB_Library::instance('notification')->triggerNotificationEvent('user-added-follow-user', $contextData, $recipients); vB_Library::instance('notification')->insertNotificationsToDB(); } $this->assertor->assertQuery('userlist', $params); /** Needed for followers subscriptions */ $currentUser = vB::getUserContext()->fetchUserId(); $followingRec = $this->assertor->getRow('userlist', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::CONDITIONS_KEY => array('userid' => $userId, 'relationid' => $currentUser, 'type' => 'follow'))); if ($followingRec and !empty($followingRec) and $followingRec['friend'] == 'no') { $this->assertor->update('userlist', array('friend' => 'yes'), array('userid' => $userId, 'relationid' => $currentUser, 'type' => 'follow')); } } else { foreach ($valid['errors'] as $error) { throw new vB_Exception_Api($error); } } }
$noticeid = $assertor->insert('vBForum:notice', array('title' => $vbulletin->GPC['title'], 'displayorder' => $vbulletin->GPC['displayorder'], 'persistent' => $vbulletin->GPC['persistent'], 'active' => $vbulletin->GPC['active'], 'dismissible' => $vbulletin->GPC['dismissible'])); } // Check to see if there is criteria to insert if ($have_criteria) { // assemble criteria insertion query $criteria_sql = array(); foreach ($vbulletin->GPC['criteria'] as $criteriaid => $criteria) { if ($criteria['active']) { $criteria_sql[] = array('noticeid' => $noticeid, 'criteriaid' => $criteriaid, 'condition1' => trim($criteria['condition1']), 'condition2' => trim($criteria['condition2']), 'condition3' => trim($criteria['condition3'])); } } // insert criteria $assertor->insertMultiple('vBForum:noticecriteria', array('noticeid', 'criteriaid', 'condition1', 'condition2', 'condition3'), $criteria_sql); } // insert / update phrase $userInfo = vB_User::fetchUserInfo(); $options = vB::getDatastore()->getValue('options'); $assertor->assertQuery('replaceIntoPhrases', array('languageid' => 0, 'varname' => 'notice_' . $noticeid . '_html', 'text' => $vbulletin->GPC['html'], 'product' => 'vbulletin', 'fieldname' => 'global', 'enteredBy' => $userInfo['username'], 'dateline' => vB::getRequest()->getTimeNow(), 'version' => $options['templateversion'])); // update the datastore notice cache build_notice_datastore(); // rebuild languages require_once DIR . '/includes/adminfunctions_language.php'; build_language(-1); print_stop_message2(array('saved_notice_x_successfully', $vbulletin->GPC['title']), 'notice', array('do' => 'modify')); } // ############################################################################# // edit a notice if ($_REQUEST['do'] == 'edit' or $_REQUEST['do'] == 'add') { $vbulletin->input->clean_array_gpc('r', array('noticeid' => vB_Cleaner::TYPE_UINT)); // initialize some data storage $notice_cache = array();
#$upload->allowanimation = ($userinfo['permissions']['genericpermissions'] & $vbulletin->bf_ugp_genericpermissions['cananimateprofilepic']) ? true : false; } } if (!$upload->process_upload($vbulletin->GPC['profilepicurl'])) { print_stop_message2(array('there_were_errors_encountered_with_your_upload_x', $upload->fetch_error())); } } else { $userpic = new vB_Datamanager_Userpic_Profilepic($vbulletin, vB_DataManager_Constants::ERRTYPE_CP, 'userpic'); $userpic->condition = array(array('field' => 'userid', 'value' => $userinfo['userid'], 'operator' => vB_dB_Query::OPERATOR_EQ)); $userpic->delete(); } print_stop_message2('saved_profile_picture_successfully', 'user', array('do' => 'edit', 'u' => $userinfo['userid'])); } // ###################### Start modify Signature Pic ########### if ($_REQUEST['do'] == 'sigpic') { $userinfo = vB_User::fetchUserinfo($vbulletin->GPC['userid'], array(vB_Api_User::USERINFO_SIGNPIC)); if (!$userinfo) { print_stop_message2('invalid_user_specified'); } if ($userinfo['sigpicwidth'] and $userinfo['sigpicheight']) { $size = " width=\"{$userinfo['sigpicwidth']}\" height=\"{$userinfo['sigpicheight']}\" "; } print_form_header('usertools', 'updatesigpic', 1); construct_hidden_code('userid', $userinfo['userid']); print_table_header($vbphrase['change_signature_picture'] . ": <span class=\"normal\">{$userinfo['username']}</span>"); if ($userinfo['sigpic']) { $userinfo['sigpicurl'] = vB::getDatastore()->getOption('frontendurl') . '/filedata/fetch?filedataid=' . $userinfo['sigpicfiledataid'] . '&sigpic=1'; print_description_row("<div align=\"center\"><img src=\"{$userinfo['sigpicurl']}\" {$size} alt=\"\" title=\"" . construct_phrase($vbphrase['xs_picture'], $userinfo['username']) . "\" /></div>"); print_yes_no_row($vbphrase['use_signature_picture'], 'usesigpic', 1); } else { construct_hidden_code('usesigpic', 1);
/** * Add a new phrase or update an existing phrase * @param string $fieldname New Phrase Type for adding, old Phrase Type for editing * @param string $varname New Varname for adding, old Varname for editing * @param array $data Phrase data to be added or updated * 'text' => Phrase text array. * 'oldvarname' => Old varname for editing only * 'oldfieldname' => Old fieldname for editing only * 't' => * 'ismaster' => * 'product' => Product ID of the phrase * @return void */ public function save($fieldname, $varname, $data) { $fieldname = trim($fieldname); $varname = trim($varname); $vb5_config =& vB::getConfig(); $install = false; if (defined('VBINSTALL') and VBINSTALL) { $install = true; } $session = vB::getCurrentSession(); if (!empty($session)) { $userinfo = $session->fetch_userinfo(); } else { $userinfo = vB_User::fetchUserinfo(1); } require_once DIR . '/includes/adminfunctions.php'; $full_product_info = fetch_product_list(true); if (empty($varname)) { throw new vB_Exception_Api('please_complete_required_fields'); } if (!preg_match('#^[' . self::VALID_CLASS . ']+$#', $varname)) { throw new vB_Exception_Api('invalid_phrase_varname'); } require_once DIR . '/includes/functions_misc.php'; foreach ($data['text'] as $text) { if (!validate_string_for_interpolation($text)) { throw new vB_Exception_Api('phrase_text_not_safe', array($varname)); } } // it's an update if (!empty($data['oldvarname']) and !empty($data['oldfieldname'])) { if (vB::getDbAssertor()->getField('phrase_fetchid', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_STORED, 'varname' => $varname))) { // Don't check if we are moving a phrase to another group but keeping the same name. See VBV-4192. if ($varname != $data['oldvarname'] and $fieldname != $data['oldfieldname']) { throw new vB_Exception_Api('there_is_already_phrase_named_x', array($varname)); } if ($varname != $data['oldvarname']) { throw new vB_Exception_Api('variable_name_exists', array($data['oldvarname'], $varname)); } } if (!is_array($data['oldfieldname'])) { $data['oldfieldname'] = array($data['oldfieldname']); } if (!in_array($fieldname, $data['oldfieldname'])) { $data['oldfieldname'][] = $fieldname; } // delete old phrases vB::getDbAssertor()->assertQuery('deleteOldPhrases', array('varname' => $data['oldvarname'], 'fieldname' => $data['oldfieldname'], 't' => $data['t'], 'debug' => empty($data['skipdebug']) && ($vb5_config['Misc']['debug'] or $install))); $update = 1; $this->setPhraseDate(); } if (empty($update)) { if (empty($data['text'][0]) and $data['text'][0] != '0' and !$data['t'] or empty($varname)) { throw new vB_Exception_Api('please_complete_required_fields'); } if (vB::getDbAssertor()->getField('phrase_fetchid', array('varname' => $varname, 'fieldname' => $fieldname))) { throw new vB_Exception_Api('there_is_already_phrase_named_x', array($varname)); } } if ($data['ismaster']) { if (($vb5_config['Misc']['debug'] or $install) and !$data['t']) { /*insert query*/ vB::getDbAssertor()->assertQuery('phrase', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_REPLACE, 'languageid' => -1, 'varname' => $varname, 'text' => $data['text'][0], 'fieldname' => $fieldname, 'product' => $data['product'], 'username' => $userinfo['username'], 'dateline' => vB::getRequest()->getTimeNow(), 'version' => $full_product_info[$data['product']]['version'])); } unset($data['text'][0]); } foreach ($data['text'] as $_languageid => $txt) { $_languageid = intval($_languageid); if (!empty($txt) or $txt == '0') { /*insert query*/ vB::getDbAssertor()->assertQuery('phrase', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_REPLACE, 'languageid' => $_languageid, 'varname' => $varname, 'text' => $txt, 'fieldname' => $fieldname, 'product' => $data['product'], 'username' => $userinfo['username'], 'dateline' => vB::getRequest()->getTimeNow(), 'version' => $full_product_info[$data['product']]['version'])); } } require_once DIR . '/includes/adminfunctions.php'; require_once DIR . '/includes/adminfunctions_language.php'; build_language(-1); }
protected function addContentInfo($results) { //the key of for each node is the nodeid, fortunately $userids = array(); $userContext = vB::getUserContext(); //If pagetext and previewtext aren't populated let's do that now. foreach ($results as $key => $record) { if (isset($record['pagetextimages'])) { unset($results[$key]['pagetextimages']); } //make sure the current user can see the content if (!$userContext->getChannelPermission('forumpermissions', 'canviewthreads', $record['nodeid'], false, $record['parentid'])) { continue; } if (!empty($record['userid']) and !in_array($record['userid'], $userids)) { $userids[] = $record['userid']; } if (empty($record['starter'])) { //The starter should never be empty or zero. Let's fix this. $starter = $this->getStarter($record['nodeid']); $data = array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_UPDATE, 'nodeid' => $record['nodeid'], 'starter' => $starter); $this->assertor->assertQuery('vBForum:node', $data); $results[$key]['starter'] = $starter; } $results[$key]['attach'] = array(); } if (!empty($userids)) { vB_Library::instance('user')->preloadUserInfo($userids); $canseehiddencustomfields = vB::getUserContext()->hasPermission('genericpermissions', 'canseehiddencustomfields'); $fields = array(); if (!$canseehiddencustomfields) { // Get profile fields information $fieldsInfo = vB_Cache::instance(vB_Cache::CACHE_STD)->read('vBProfileFields'); if (empty($fieldsInfo)) { $fieldsInfo = $this->assertor->getRows('vBForum:profilefield'); vB_Cache::instance(vB_Cache::CACHE_STD)->write('vBProfileFields', $fieldsInfo, 1440, array('vBProfileFieldsChg')); } foreach ($fieldsInfo as $field) { $fields['field' . $field['profilefieldid']] = $field['hidden']; } } foreach ($results as $key => $record) { $userInfo = vB_User::fetchUserInfo($record['userid']); if (!empty($record['userid']) and !empty($userInfo)) { $results[$key]['userinfo'] = array('userid' => $userInfo['userid'], 'username' => $userInfo['username'], 'rank' => $userInfo['rank'], 'usertitle' => $userInfo['usertitle'], 'joindate' => $userInfo['joindate'], 'posts' => $userInfo['posts'], 'customtitle' => $userInfo['customtitle'], 'userfield' => array()); // Add userfields data foreach ($fields as $fieldname => $hidden) { if (isset($userInfo[$fieldname]) and ($canseehiddencustomfields or !$hidden)) { $results[$key]['userinfo']['userfield'][$fieldname] = $userInfo[$fieldname]; } } } } } //let's get the attachment info. $attachments = vB_Api::instanceInternal('node')->getNodeAttachments(array_keys($results)); foreach ($attachments as $attachment) { if (array_key_exists($attachment['parentid'], $results)) { if (!is_array($results[$attachment['parentid']]['attach'])) { $results[$attachment['parentid']]['attach'] = array(); } $results[$attachment['parentid']]['attach'][] = $attachment; } } foreach ($results as $key => $result) { if (empty($result)) { continue; } if (!empty($result['attach']) and is_array($result['attach'])) { $results[$key]['photocount'] = count($result['attach']); } else { $results[$key]['photocount'] = 0; } } return $results; }
private function json2criteria(&$json) { if (is_string($json)) { $search_structure = json_decode($json, true); } else { $search_structure = $json; } if (empty($search_structure) or !is_array($search_structure)) { throw new vB_Exception_Api('invalid_search_syntax', array($json)); } $criteria = new vB_Search_Criteria(); $def_sort_field = 'created'; $def_sort_dir = 'DESC'; $currentUserId = vB::getCurrentSession()->get('userid'); $criteria->setUser($currentUserId); $normalized_criteria = array(); if (!empty($search_structure['keywords'])) { $words = $criteria->add_keyword_filter($search_structure['keywords'], !empty($search_structure['title_only'])); $def_sort_field = 'lastcontent'; if (!empty($words)) { $normalized_criteria['keywords'] = ''; $separator = ''; foreach ($words as $word) { if (!empty($word['joiner'])) { $normalized_criteria['keywords'] .= $separator . strtoupper($word['joiner']); $separator = ' '; } $normalized_criteria['keywords'] .= $separator . $word['word']; $separator = ' '; } if (!empty($search_structure['title_only'])) { $normalized_criteria['title_only'] = 1; } } else { $normalized_criteria['error'] = 'ignored_search_keywords'; } $ignored_words = $criteria->get_ignored_keywords(); if (!empty($ignored_words)) { $normalized_criteria['ignored_words'] = $ignored_words; $normalized_criteria['original_keywords'] = $search_structure['keywords']; } } if (!empty($search_structure['contenttypeid'])) { $search_structure['type'] = vB_Types::instance()->getContentTypeClasses($search_structure['contenttypeid']); if (count($search_structure['type']) == 1) { $search_structure['type'] = array_pop($search_structure['type']); } unset($search_structure['contenttypeid']); } if (!empty($search_structure['type'])) { $contentypeids = $criteria->add_contenttype_filter($search_structure['type']); $normalized_criteria['type'] = $search_structure['type']; $pmcontentypeid = vB_Types::instance()->getContentTypeID('vBForum_PrivateMessage'); if (in_array($pmcontentypeid, $contentypeids)) { if (count($contentypeids) == 1) { $search_structure['private_messages_only'] = 1; } else { $search_structure['include_private_messages'] = 1; } } $vmcontentypeid = vB_Types::instance()->getContentTypeID('vBForum_VisitorMessage'); if (in_array($vmcontentypeid, $contentypeids)) { if (count($contentypeids) == 1) { $search_structure['visitor_messages_only'] = 1; } else { $search_structure['include_visitor_messages'] = 1; } } $photocontentypeid = vB_Api::instanceInternal('contenttype')->fetchContentTypeIdFromClass('Photo'); if (in_array($photocontentypeid, $contentypeids)) { $search_structure['include_attach'] = 1; } } elseif (empty($search_structure['exclude_type']) or is_string($search_structure['exclude_type']) and $search_structure['exclude_type'] != 'vBForum_PrivateMessage' or is_array($search_structure['exclude_type']) and !in_array('vBForum_PrivateMessage', $search_structure['exclude_type'])) { $search_structure['include_private_messages'] = 1; } elseif (!empty($search_structure['exclude_type']) and (is_string($search_structure['exclude_type']) and $search_structure['exclude_type'] == 'vBForum_VisitorMessage' or is_array($search_structure['exclude_type']) and in_array('vBForum_VisitorMessage', $search_structure['exclude_type']))) { $search_structure['exclude_visitor_messages'] = 1; } if (empty($search_structure['type']) and empty($search_structure['exclude_visitor_messages']) and (empty($search_structure['exclude_type']) or is_string($search_structure['exclude_type']) and $search_structure['exclude_type'] != 'vBForum_VisitorMessage' or is_array($search_structure['exclude_type']) and !in_array('vBForum_VisitorMessage', $search_structure['exclude_type']))) { $search_structure['include_visitor_messages'] = 1; } // author by username if (!empty($search_structure['author'])) { //reducing users from array to single if (is_array($search_structure['author']) and count($search_structure['author']) == 1) { $search_structure['author'] = array_pop($search_structure['author']); $search_structure['exactname'] = 1; } // only one username if (is_string($search_structure['author'])) { // it's an exact username - no partial match if (!empty($search_structure['exactname'])) { $search_structure['author'] = trim($search_structure['author']); switch ($search_structure['author']) { case 'myFriends': $userid = array(); if (!empty($currentUserId)) { $userid = vB::getDbAssertor()->getColumn('userlist', 'relationid', array('userid' => $currentUserId, 'friend' => 'yes'), false, 'relationid'); } $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $userid, true); break; case 'iFollow': if (empty($search_structure[self::FILTER_FOLLOW])) { $search_structure[self::FILTER_FOLLOW] = self::FILTER_FOLLOWING_USERS; } elseif ($search_structure[self::FILTER_FOLLOW] == self::FILTER_FOLLOWING_CHANNEL) { $search_structure[self::FILTER_FOLLOW] = self::FILTER_FOLLOWING_BOTH; } break; default: $criteria->add_user_filter($search_structure['author'], !empty($search_structure['exactname'])); break; } $normalized_criteria['author'] = strtolower($search_structure['author']); $normalized_criteria['exactname'] = 1; } elseif (vb_String::vbStrlen($search_structure['author']) >= 3) { $criteria->add_user_filter($search_structure['author'], !empty($search_structure['exactname'])); $normalized_criteria['author'] = strtolower($search_structure['author']); } } elseif (is_array($search_structure['author'])) { $user_names = array(); foreach ($search_structure['author'] as $author) { $author = vB_String::htmlSpecialCharsUni($author); $user = vB_Api::instanceInternal("User")->fetchByUsername($author); $userid = false; if (!empty($user['userid'])) { $user_ids[] = $user['userid']; $user_names[] = $user['username']; } } if (!empty($user_ids)) { $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $user_ids, true); } else { $criteria->add_null_filter('no record matches usernames'); } sort($user_names); $normalized_criteria['author'] = $user_names; } } // author by userid if (!empty($search_structure['authorid'])) { //reducing users from array to single if (is_array($search_structure['authorid']) and count($search_structure['authorid']) == 1) { $search_structure['authorid'] = array_pop($search_structure['authorid']); } if (is_numeric($search_structure['authorid'])) { if (!empty($search_structure['visitor_messages_only'])) { $criteria->add_filter('visitor_messages_only', vB_Search_Core::OP_EQ, $search_structure['authorid']); $normalized_criteria['visitor_messages_only'] = 1; } elseif (!empty($search_structure['include_visitor_messages'])) { $criteria->add_filter('include_visitor_messages', vB_Search_Core::OP_EQ, $search_structure['authorid']); $normalized_criteria['include_visitor_messages'] = 1; } else { $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $search_structure['authorid'], true); } if (!empty($search_structure['exclude_visitor_messages'])) { $criteria->add_filter('exclude_visitor_messages', vB_Search_Core::OP_EQ, $search_structure['authorid']); $normalized_criteria['exclude_visitor_messages'] = 1; } $normalized_criteria['authorid'] = $search_structure['authorid']; } elseif (is_array($search_structure['authorid'])) { $user_ids = array(); foreach ($search_structure['authorid'] as $author) { if (is_numeric($author)) { $user_ids[] = intval($author); } } $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $user_ids, true); $normalized_criteria['authorid'] = sort($user_ids); } } else { if (!empty($search_structure['exclude_visitor_messages'])) { $criteria->add_filter('exclude_visitor_messages', vB_Search_Core::OP_EQ, 0); $normalized_criteria['exclude_visitor_messages'] = 1; } } // channel owner filter if (!empty($search_structure['my_channels'])) { $temp = array(); // restrict 'type' to string 'blog' or 'group', else default to 'blog' if (isset($search_structure['my_channels']['type']) and ($search_structure['my_channels']['type'] == 'blog' or $search_structure['my_channels']['type'] == 'group')) { $temp['type'] = $search_structure['my_channels']['type']; } else { $temp['type'] = 'blog'; } $normalized_criteria['my_channels'] = $temp; $criteria->add_filter('my_channels', vB_Search_Core::OP_EQ, $temp); unset($temp); } if (!empty($search_structure['private_messages_only'])) { $criteria->add_filter('private_messages_only', vB_Search_Core::OP_EQ, $currentUserId); $normalized_criteria['private_messages_only'] = 1; } // visitor message recipient if (!empty($search_structure['sentto'])) { //reducing users from array to single if (is_array($search_structure['sentto']) and count($search_structure['sentto']) == 1) { $search_structure['sentto'] = array_pop($search_structure['sentto']); } if (is_numeric($search_structure['sentto'])) { $criteria->add_filter('sentto', vB_Search_Core::OP_EQ, intval($search_structure['sentto'])); $normalized_criteria['visitor_messages_only'] = 1; $normalized_criteria['sentto'] = intval($search_structure['sentto']); } elseif (is_array($search_structure['sentto'])) { $user_ids = array_map('intval', $search_structure['sentto']); sort($user_ids); $criteria->add_filter('sentto', vB_Search_Core::OP_EQ, $user_ids); $normalized_criteria['visitor_messages_only'] = 1; $normalized_criteria['sentto'] = $user_ids; } } if (!empty($search_structure['tag'])) { if (is_array($search_structure['tag'])) { foreach ($search_structure['tag'] as $index => $tag) { $search_structure['tag'][$index] = vB_String::htmlSpecialCharsUni(trim($tag)); } } else { $search_structure['tag'] = vB_String::htmlSpecialCharsUni(trim($search_structure['tag'])); } $existing_tags = $criteria->add_tag_filter($search_structure['tag']); $normalized_criteria['tag'] = array_keys($existing_tags); vB_Api::instanceInternal('Tags')->logSearchTags($existing_tags); } if (!empty($search_structure['date'])) { if ($search_structure['date'] == self::FILTER_LASTVISIT) { $current_user = new vB_Legacy_CurrentUser(); $dateline = $current_user->get_field('lastvisit'); if (empty($dateline)) { $dateline = vB::getRequest()->getTimeNow() - 86400 * 14; } $criteria->add_date_filter(vB_Search_Core::OP_GT, $dateline); $normalized_criteria['date'] = self::FILTER_LASTVISIT; } if ($search_structure['date'] == self::FILTER_TOPICAGE) { $age = vB::getDatastore()->getOption('max_age_topic'); if (intval($age) == 0) { $age = 60; } $criteria->add_date_filter(vB_Search_Core::OP_GT, vB::getRequest()->getTimeNow() - 86400 * $age); $normalized_criteria['date'] = self::FILTER_TOPICAGE; } if ($search_structure['date'] == self::FILTER_CHANNELAGE) { $age = vB::getDatastore()->getOption('max_age_channel'); if (intval($age) == 0) { $age = 60; } $criteria->add_date_filter(vB_Search_Core::OP_GT, vB::getRequest()->getTimeNow() - 86400 * $age); $normalized_criteria['date'] = self::FILTER_CHANNELAGE; } // forcing to get the whole date spectrum; activity stream view enforces a date range so this is the workaround if (!empty($search_structure['date']) and is_string($search_structure['date']) and $search_structure['date'] == self::FILTER_DATEALL) { $criteria->add_date_filter(vB_Search_Core::OP_EQ, self::FILTER_DATEALL); $normalized_criteria['date'] = self::FILTER_DATEALL; } if (is_array($search_structure['date']) and !empty($search_structure['date']['from'])) { $dateline = $this->computeDateLine($search_structure['date']['from']); if (!empty($dateline)) { $criteria->add_date_filter(vB_Search_Core::OP_GT, $dateline); $normalized_criteria['date']['from'] = $search_structure['date']['from']; } } if (is_array($search_structure['date']) and !empty($search_structure['date']['to'])) { $dateline = $this->computeDateLine($search_structure['date']['to'], true); if (!empty($dateline)) { $criteria->add_date_filter(vB_Search_Core::OP_LT, $dateline); $normalized_criteria['date']['to'] = $search_structure['date']['to']; } } } if (!empty($search_structure['last'])) { if (is_array($search_structure['last']) and !empty($search_structure['last']['from'])) { $dateline = $this->computeDateLine($search_structure['last']['from']); if (!empty($dateline)) { $criteria->add_last_filter(vB_Search_Core::OP_GT, $dateline); $normalized_criteria['last']['from'] = $search_structure['last']['from']; } } if (is_array($search_structure['last']) and !empty($search_structure['last']['to'])) { $dateline = $this->computeDateLine($search_structure['last']['to'], true); if (!empty($dateline)) { $criteria->add_last_filter(vB_Search_Core::OP_LT, $dateline); $normalized_criteria['last']['to'] = $search_structure['last']['to']; } } } if (!empty($search_structure['exclude'])) { $criteria->add_exclude_filter($search_structure['exclude']); $normalized_criteria['exclude'] = $search_structure['exclude']; } if (empty($search_structure['sort'])) { $search_structure['sort'] = array($def_sort_field => $def_sort_dir); } if (!is_array($search_structure['sort'])) { $sort_dir = $def_sort_dir; if (strtolower($search_structure['sort']) == 'title') { $sort_dir = 'ASC'; } $search_structure['sort'] = array($search_structure['sort'] => $sort_dir); } foreach ($search_structure['sort'] as $sort_field => $sort_dir) { $criteria->set_sort($sort_field, strtoupper($sort_dir)); } if ($sort_field != $def_sort_field or $sort_dir != $def_sort_dir) { $normalized_criteria['sort'] = array($sort_field => strtoupper($sort_dir)); } if (!empty($search_structure['view'])) { if ($search_structure['view'] == vB_Api_Search::FILTER_VIEW_CONVERSATION_STREAM and !empty($search_structure['channel'])) { $search_structure['depth'] = 2; $search_structure['include_starter'] = true; } elseif ($search_structure['view'] == vB_Api_Search::FILTER_VIEW_CONVERSATION_THREAD and !empty($search_structure['channel'])) { $search_structure['depth'] = 1; $search_structure['include_starter'] = true; } else { $criteria->add_view_filter($search_structure['view']); $normalized_criteria['view'] = $search_structure['view']; } } if (!empty($search_structure['starter_only'])) { $criteria->add_filter('starter_only', vB_Search_Core::OP_EQ, true); $search_structure['include_starter'] = true; $normalized_criteria['starter_only'] = 1; } if (!empty($search_structure['reply_only'])) { $criteria->add_filter('reply_only', vB_Search_Core::OP_EQ, true); $search_structure['include_starter'] = false; $normalized_criteria['reply_only'] = 1; } if (!empty($search_structure['comment_only'])) { $criteria->add_filter('comment_only', vB_Search_Core::OP_EQ, true); $search_structure['include_starter'] = false; $normalized_criteria['comment_only'] = 1; } if (!empty($search_structure['channel'])) { $criteria->add_channel_filter($search_structure['channel'], empty($search_structure['depth']) ? false : $search_structure['depth'], empty($search_structure['include_starter']) ? false : true, empty($search_structure['depth_exact']) ? false : true); $normalized_criteria['channel'] = $search_structure['channel']; if (!empty($search_structure['depth'])) { $normalized_criteria['depth'] = $search_structure['depth']; } if (!empty($search_structure['depth_exact'])) { $normalized_criteria['depth_exact'] = true; } if (!empty($search_structure['include_starter'])) { $normalized_criteria['include_starter'] = 1; } } if (!empty($search_structure['featured'])) { $criteria->add_filter('featured', vB_Search_Core::OP_EQ, $search_structure['featured']); $normalized_criteria['featured'] = 1; } if (!empty($search_structure[self::FILTER_FOLLOW])) { if (is_string($search_structure[self::FILTER_FOLLOW]) and !empty($currentUserId)) { $criteria->add_follow_filter($search_structure[self::FILTER_FOLLOW], $currentUserId); $normalized_criteria[self::FILTER_FOLLOW] = $search_structure[self::FILTER_FOLLOW]; } elseif (is_array($search_structure[self::FILTER_FOLLOW])) { list($type, $userid) = each($search_structure[self::FILTER_FOLLOW]); //if ($userid == $currentUserId) //{ $criteria->add_follow_filter($type, $userid); $normalized_criteria[self::FILTER_FOLLOW] = $search_structure[self::FILTER_FOLLOW]; //} } } if (!empty($search_structure['my_following']) and !empty($currentUserId)) { $criteria->add_follow_filter(self::FILTER_FOLLOWING_CHANNEL, $currentUserId); $normalized_criteria['my_following'] = $search_structure['my_following']; } if (!empty($search_structure['exclude_type'])) { $criteria->add_contenttype_filter($search_structure['exclude_type'], vB_Search_Core::OP_NEQ); $normalized_criteria['exclude_type'] = $search_structure['exclude_type']; } if (!empty($search_structure['sticky_only'])) { $criteria->add_filter('sticky', vB_Search_Core::OP_EQ, '1'); $normalized_criteria['sticky_only'] = 1; } if (!empty($search_structure['exclude_sticky'])) { $criteria->add_filter('sticky', vB_Search_Core::OP_NEQ, '1'); $normalized_criteria['exclude_sticky'] = 1; } if (!empty($search_structure['include_sticky'])) { $criteria->set_include_sticky(); $normalized_criteria['include_sticky'] = 1; } if (empty($search_structure['include_blocked']) or empty($currentUserId) or !vB::getUserContext()->hasPermission('moderatorpermissions', 'canbanusers')) { //block people on the global ignore list. $globalignore = trim(vB::getDatastore()->getOption('globalignore')); if (!empty($globalignore)) { $blocked = preg_split('#\\s+#s', $globalignore, -1, PREG_SPLIT_NO_EMPTY); //the user can always see their own posts, so if they are in the blocked list we remove them if (!empty($currentUserId)) { $bbuserkey = array_search($currentUserId, $blocked); if ($bbuserkey !== FALSE and $bbuserkey !== NULL) { unset($blocked["{$bbuserkey}"]); } } //Make sure we didn't just empty the list if (!empty($blocked)) { $criteria->add_filter('userid', vB_Search_Core::OP_NEQ, $blocked, false, true); } } } elseif (!empty($currentUserId) and vB::getUserContext()->hasPermission('moderatorpermissions', 'canbanusers')) { $normalized_criteria['include_blocked'] = 1; } if (empty($search_structure['include_blocked']) and !empty($currentUserId)) { $currentUserInfo = vB_User::fetchUserinfo($currentUserId); if (!empty($currentUserInfo['ignorelist'])) { $criteria->add_filter('userid', vB_Search_Core::OP_NEQ, explode(' ', $currentUserInfo['ignorelist']), false, true); } } if (!empty($search_structure['ignore_protected'])) { $criteria->add_filter('protected', vB_Search_Core::OP_NEQ, '1'); $normalized_criteria['ignore_protected'] = 1; } if (!empty($search_structure['deleted_only']) and !empty($currentUserId) and vB::getUserContext()->hasPermission('moderatorpermissions', 'canremoveposts')) { $criteria->add_filter('showpublished', vB_Search_Core::OP_EQ, '0'); $criteria->add_filter('deleteuserid', vB_Search_Core::OP_NEQ, '0'); $normalized_criteria['deleted_only'] = 1; } if (!empty($search_structure['exclude_deleted'])) { $criteria->add_filter('showpublished', vB_Search_Core::OP_EQ, '1'); $normalized_criteria['exclude_deleted'] = 1; } if (empty($search_structure['include_attach'])) { $criteria->add_filter('inlist', vB_Search_Core::OP_EQ, 1); } else { $normalized_criteria['include_attach'] = 1; } if (!empty($search_structure['unapproved_only']) and !empty($currentUserId) and vB::getUserContext()->hasPermission('moderatorpermissions', 'canmanagethreads')) { $criteria->add_filter('approved', vB_Search_Core::OP_NEQ, '1'); $normalized_criteria['unapproved_only'] = 1; } if (!empty($search_structure['unread_only']) and !empty($currentUserId) and vB::getDatastore()->getOption('threadmarking') > 0) { $criteria->add_filter('marked', vB_Search_Core::OP_EQ, self::FILTER_MARKED_UNREAD); $normalized_criteria['unread_only'] = 1; } if (!empty($search_structure['specific'])) { $criteria->add_filter('nodeid', vB_Search_Core::OP_EQ, $search_structure['specific']); $normalized_criteria['specific'] = $search_structure['specific']; } if (!empty($search_structure['prefix'])) { $normalized_criteria['prefix'] = $search_structure['prefix']; $criteria->add_filter('prefixid', vB_Search_Core::OP_EQ, $search_structure['prefix']); } if (!empty($search_structure['has_prefix'])) { $normalized_criteria['has_prefix'] = 1; $criteria->add_filter('prefixid', vB_Search_Core::OP_NEQ, ''); } if (!empty($search_structure['no_prefix'])) { $normalized_criteria['no_prefix'] = 0; $criteria->add_filter('prefixid', vB_Search_Core::OP_EQ, ''); } // private messages are included by default. Use the exclude_type filter to exlude them // they are not included if a specific channel is requested OR looking for visitor messages if (!empty($search_structure['include_private_messages']) and empty($normalized_criteria['private_messages_only']) and empty($normalized_criteria['sentto']) and (empty($normalized_criteria['channel']) or is_numeric($normalized_criteria['channel']) and !in_array($normalized_criteria['channel'], array(vB_Channel::MAIN_CHANNEL, vB_Channel::DEFAULT_CHANNEL_PARENT, vB_Channel::PRIVATEMESSAGE_CHANNEL)) or is_array($normalized_criteria['channel']) and count(array_intersect($normalized_criteria['channel'], array(vB_Channel::MAIN_CHANNEL, vB_Channel::DEFAULT_CHANNEL_PARENT, vB_Channel::PRIVATEMESSAGE_CHANNEL))) == 0) and empty($normalized_criteria['my_channels'])) { $criteria->add_filter('include_private_messages', vB_Search_Core::OP_EQ, $currentUserId); } if (!empty($search_structure['nolimit']) and !empty($normalized_criteria['channel']) and (empty($normalized_criteria['view']) or $normalized_criteria['view'] != self::FILTER_VIEW_ACTIVITY) and empty($search_structure['author']) and empty($search_structure['authorid']) and empty($search_structure['keywords']) and empty($search_structure['sentto']) and empty($search_structure['private_messages_only']) and empty($search_structure['tag']) and empty($search_structure['featured']) and empty($search_structure['my_following']) and empty($search_structure['unapproved_only']) and empty($search_structure['unread_only'])) { $normalized_criteria['nolimit'] = 1; $criteria->setNoLimit(); } // Two pass caching can be disabled by either ignore_cache which // also disabled the searchlog table or by specifying 'disable_two_pass' // Two pass caching can be forced on when 'ignore_cache' has been called // by specifying 'force_two_pass' (for unit testing the two pass cache functionality itself) if (!empty($search_structure['ignore_cache']) or self::IGNORE_CACHE) { $normalized_criteria['disable_two_pass'] = 1; $criteria->setIgnoreCache(true); } if (!empty($search_structure['disable_two_pass'])) { $normalized_criteria['disable_two_pass'] = 1; } if (!empty($search_structure['force_two_pass']) and !empty($normalized_criteria['disable_two_pass'])) { unset($normalized_criteria['disable_two_pass']); } //checking for a restrictive filter if (empty($normalized_criteria['keywords']) and empty($normalized_criteria['authorid']) and empty($normalized_criteria['author']) and empty($normalized_criteria['private_messages_only']) and empty($normalized_criteria['visitor_messages_only']) and empty($normalized_criteria['sentto']) and empty($normalized_criteria['tag']) and (empty($normalized_criteria['date']) or is_string($normalized_criteria['date']) and $normalized_criteria['date'] == self::FILTER_DATEALL) and (empty($normalized_criteria['last']) or is_string($normalized_criteria['last']) and $normalized_criteria['last'] == self::FILTER_DATEALL) and empty($normalized_criteria['channel']) and empty($normalized_criteria['featured']) and empty($normalized_criteria[self::FILTER_FOLLOW]) and empty($normalized_criteria['my_following']) and empty($normalized_criteria['sticky_only']) and empty($normalized_criteria['deleted_only']) and empty($normalized_criteria['unapproved_only']) and empty($normalized_criteria['unread_only']) and empty($normalized_criteria['specific']) and empty($normalized_criteria['prefix']) and empty($normalized_criteria['has_prefix']) and empty($normalized_criteria['no_prefix']) and empty($normalized_criteria['my_channels'])) { //temporary solution for VBV-10061 if ($normalized_criteria['view'] == self::FILTER_VIEW_ACTIVITY) { $dateline = $this->computeDateLine(self::FILTER_LASTMONTH); if (!empty($dateline)) { $criteria->add_date_filter(vB_Search_Core::OP_GT, $dateline); } } else { throw new vB_Exception_Api('criteria_not_restrictive', array($normalized_criteria)); } } $criteria->setJSON($normalized_criteria); $json = $normalized_criteria; // allow the clients to send custom fields that will be preserved if (!empty($search_structure['custom'])) { $json['custom'] = $search_structure['custom']; } return $criteria; }