Exemple #1
0
 /**
  * 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'];
 }
 /**
  * Create an article category channel. This function works basically like the blog library's version
  *
  * @param array 	$input						data array, should have standard channel data like title, parentid, 
  * @param int 		$channelid					parentid that the new channel should fall under. 
  * @param int		$channelConvTemplateid		"Conversation" level pagetemplate to use. Typically vB_Page::getArticleConversPageTemplate()
  * @param int 		$channelPgTemplateId		"Channel" level pagetemplate to use. Typically  vB_Page::getArticleChannelPageTemplate()
  * @param int 		$ownerSystemGroupId
  *
  * @return int The nodeid of the new blog channel
  */
 public function createChannel($input, $channelid, $channelConvTemplateid, $channelPgTemplateId, $ownerSystemGroupId)
 {
     if (!isset($input['parentid']) or intval($input['parentid']) < 1) {
         $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_Article'] = $channelConvTemplateid;
     $input['childroute'] = 'vB5_Route_Article';
     // add channel node
     $channelLib = vB_Library::instance('content_channel');
     $input['page_parentid'] = 0;
     $result = $channelLib->add($input, array('skipNotifications' => true, 'skipFloodCheck' => true, 'skipDupCheck' => true));
     //Make the current user the channel owner.
     $userApi = vB_Api::instanceInternal('user');
     $usergroup = vB::getDbAssertor()->getRow('usergroup', array('systemgroupid' => $ownerSystemGroupId));
     vB_Cache::allCacheEvent(array('nodeChg_' . $this->articleHomeChannel, "nodeChg_{$channelid}"));
     vB::getUserContext()->rebuildGroupAccess();
     vB_Channel::rebuildChannelTypes();
     // clear follow cache
     vB_Api::instanceInternal('follow')->clearFollowCache(array($input['userid']));
     return $result['nodeid'];
 }
Exemple #3
0
 /**
  * Clears follow in class cache
  */
 public function clearFollowCache($userIds)
 {
     foreach ($userIds as $user) {
         unset($this->followers[$user]);
         unset($this->userFollowers[$user]);
         unset($this->userFollowing[$user]);
         unset($this->subscriptions[$user]);
         vB_Cache::allCacheEvent("followChg_{$user}");
     }
     $this->userListCache = array();
 }
Exemple #4
0
 /**
  * Rebuild the style datastore.
  */
 public function buildStyleDatastore()
 {
     $this->setCssDate();
     $stylecache = $this->fetchStyles(true, false, array('themes' => true));
     foreach ($stylecache as $key => $style) {
         // VBV-4174: we don't want stylevars in the datastore
         if (isset($style['newstylevars'])) {
             unset($stylecache[$key]['newstylevars']);
         }
     }
     vB::getDatastore()->build('stylecache', serialize($stylecache), 1);
     vB_Cache::allCacheEvent('vbCachedFullPage');
     vB_Library::instance('template')->rebuildTextonlyDS();
     return $stylecache;
 }
 /**
  * Additional data to update after a save call (such as denormalized values in other tables).
  * In batch updates, is executed once after all records are updated.
  *
  * @param	boolean	Do the query?
  */
 function post_save_once($doquery = true)
 {
     parent::post_save_once($doquery);
     if (!empty($this->moderator['userid'])) {
         vB_Cache::allCacheEvent('userChg_' . $this->moderator['userid']);
     }
     vB::getUserContext()->rebuildGroupAccess();
 }
Exemple #6
0
 /**
  * Undelete a set of nodes
  * @param array $nodeids
  * @param boolean is rebuild needed
  * @throws vB_Exception_Api
  * @return array - the nodeids that have been deleted
  */
 public function undeleteNodes($nodeids, $needRebuild = false)
 {
     if (empty($nodeids)) {
         return false;
     }
     $errors = array();
     $events = array();
     $loginfo = array();
     $counts = $updates = array();
     $nodeids = array_unique($nodeids);
     $assertor = vB::getDbAssertor();
     $result = $assertor->assertQuery('vBForum:node', array('nodeid' => $nodeids, 'deleteuserid' => 0, 'deletereason' => '', 'unpublishdate' => 0, 'showpublished' => 1, vB_db_Query::TYPE_KEY => vB_db_Query::QUERY_UPDATE));
     if (!empty($result['errors'])) {
         $errors[] = $result['errors'];
     }
     $searchAPI = vB_Api::instanceInternal('Search');
     foreach ($nodeids as $nodeid) {
         $events[] = $nodeid;
         $result = $this->publishChildren($nodeid);
         if (!empty($result['errors'])) {
             $errors[] = $result['errors'];
         }
         // Clear cache for this node or user post count won't update
         vB_Cache::allCacheEvent('nodeChg_' . $nodeid);
         $node = $this->getNode($nodeid);
         // Update user post count (un(soft)delete)
         vB_Library_Content::getContentLib($node['contenttypeid'])->incrementUserPostCount($node);
         $loginfo[] = array('nodeid' => $node['nodeid'], 'nodetitle' => $node['title'], 'nodeusername' => $node['authorname'], 'nodeuserid' => $node['userid']);
         $parents = $this->fetchClosureParent($nodeid);
         foreach ($parents as $parent) {
             $nodeInfo = $this->getNodeBare($parent['parent']);
             if ($nodeInfo['contenttypeid'] == $this->channelTypeId) {
                 $result = $this->fixNodeLast($parent['parent']);
             } else {
                 $result = $assertor->assertQuery('vBForum:updateLastData', array('parentid' => $parent['parent'], 'timenow' => vB::getRequest()->getTimeNow()));
             }
             if (!empty($result['errors'])) {
                 $errors[] = $result['errors'];
             }
             switch ($parent['depth']) {
                 case 0:
                     // Actual node.
                     vB_Node::fixNodeCount($parent['parent']);
                     break;
                 case 1:
                     // Immediate parent.
                     $parentinfo = $this->getNodeBare($parent['parent']);
                     $counts = array('totalcount' => $parentinfo['totalcount'], 'totalunpubcount' => $parentinfo['totalunpubcount']);
                     vB_Node::fixNodeCount($parent['parent']);
                     $parentinfo = $this->getNodeBare($parent['parent']);
                     $counts = array('totalcount' => $parentinfo['totalcount'] - $counts['totalcount'], 'totalunpubcount' => $parentinfo['totalunpubcount'] - $counts['totalunpubcount']);
                     break;
                 default:
                     // Higher parents.
                     $updates['totalcount'][$parent['parent']] = $counts['totalcount'];
                     $updates['totalunpubcount'][$parent['parent']] = $counts['totalunpubcount'];
                     break;
             }
         }
         $assertor->assertQuery('vBForum:updateNodeTotals', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_METHOD, 'updates' => $updates));
         $searchAPI->attributeChanged($nodeid);
     }
     $searchAPI->purgeCacheForCurrentUser();
     if ($needRebuild) {
         vB::getUserContext()->rebuildGroupAccess();
         vB_Channel::rebuildChannelTypes();
     }
     $this->clearCacheEvents($nodeids);
     $this->clearChildCache($nodeids);
     if (!empty($errors)) {
         return array('errors' => $errors);
     }
     vB_Library_Admin::logModeratorAction($loginfo, 'node_restored_by_x');
     return $nodeids;
 }
Exemple #7
0
 /** This grants a user additional permissions in a specific channel, by adding to the groupintopic table
  *
  *	@param	int
  *	@param	mixed	integer or array of integers
  * 	@param	int
  *
  *	@return	bool
  ***/
 public static function setGroupInTopic($userid, $nodeids, $usergroupid)
 {
     //check the data.
     if (!is_numeric($userid) or !is_numeric($usergroupid)) {
         throw new vB_Exception_Api('invalid_data');
     }
     if (!is_array($nodeids)) {
         $nodeids = array($nodeids);
     } else {
         $nodeids = array_unique($nodeids);
     }
     //We don't do a permission check. It's essential that the api's do that before calling here.
     //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.
     $assertor = vB::getDbAssertor();
     $existing = $assertor->assertQuery('vBForum:groupintopic', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'userid' => $userid, 'groupid' => $usergroupid));
     foreach ($existing as $permission) {
         $index = array_search($permission['nodeid'], $nodeids);
         if ($index !== false) {
             unset($nodeids[$index]);
         }
     }
     //and do the inserts
     foreach ($nodeids as $nodeid) {
         $assertor->assertQuery('vBForum:groupintopic', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_INSERT, 'userid' => $userid, 'nodeid' => $nodeid, 'groupid' => $usergroupid));
     }
     vB_Cache::allCacheEvent(array("userPerms_{$userid}", "userChg_{$userid}", "followChg_{$userid}", "sgMemberChg_{$userid}"));
     vB_Api::instanceInternal('user')->clearChannelPerms($userid);
     vB::getUserContext($userid)->reloadGroupInTopic();
     vB::getUserContext()->clearChannelPermissions();
     //if we got here all is well.
     return true;
 }
 /**
  * Checks if the current node should be counted in the user post count for the author.
  *
  * @param	array	The node
  * @param	(unpublish|unapprove)	The action that was just carried out on the node
  *
  * @return	boolean	Whether or not the node should be counted in user post count.
  */
 protected function countInUserPostCount(array $node, $action = '')
 {
     // NOTICE: How we determine if a post counts in user post count here needs to
     // match the criteria used in admincp/misc.php?do=updateposts
     // If you update in one place, please update in the other
     // check if this content type counts as a "post"
     // We have to jump through a bunch of hoops to not count VMs, PMs,
     // reports, and other items in user post count
     // @todo - VMs and comments should probably be their own content types
     // extended from the Text content type.
     if (!$this->includeInUserPostCount or $this->isVisitorMessage($node['nodeid'])) {
         return false;
     }
     if (!isset($node['starter'])) {
         //force a reload
         vB_Cache::allCacheEvent('nodeChg_' . $node['nodeid']);
         $node = vB_Library::instance('node')->getNodeFullContent($node['nodeid'], $node['contenttypeid']);
     }
     return !$this->isComment($node['nodeid'], $node) and ($action == 'unapprove' or $node['approved']) and ($action == 'unpublish' or $node['showpublished'] and !$node['deleteuserid']);
 }
 protected static function updateContentRoute($oldRouteInfo, $newRouteInfo)
 {
     $db = vB::getDbAssertor();
     $events = array();
     // update redirect301 fields
     $updateIds = $db->assertQuery('get_update_route_301', array('oldrouteid' => $oldRouteInfo['routeid']));
     if (!empty($updateIds)) {
         $routeIds = array();
         foreach ($updateIds as $route) {
             $routeid = $route['routeid'];
             $events[] = "routeChg_{$routeid}";
             $routeIds[] = $routeid;
         }
         $db->update('routenew', array('redirect301' => $newRouteInfo['routeid'], 'name' => vB_dB_Query::VALUE_ISNULL), array('routeid' => $routeIds));
     }
     // don't modify the routeid for default pages, as it will still be used
     $updateIds = $db->assertQuery('page', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::COLUMNS_KEY => array('pageid'), vB_dB_Query::CONDITIONS_KEY => array('routeid' => $oldRouteInfo['routeid'], 'pagetype' => vB_Page::TYPE_CUSTOM)));
     if (!empty($updateIds)) {
         $pageIds = array();
         foreach ($updateIds as $page) {
             $pageid = $page['pageid'];
             $events[] = "pageChg_{$pageid}";
             $pageIds[] = $pageid;
         }
         $db->update('page', array('routeid' => $newRouteInfo['routeid']), array('pageid' => $pageIds));
     }
     vB_Cache::allCacheEvent($events);
 }
        $pfcs[] = $pfc['profilefieldcategoryid'];
    }
    if (!in_array($vbulletin->GPC['profilefield']['profilefieldcategoryid'], $pfcs)) {
        $vbulletin->GPC['profilefield']['profilefieldcategoryid'] = 0;
    }
    if (empty($vbulletin->GPC['profilefieldid'])) {
        // insert
        /*insert query*/
        $vbulletin->GPC['profilefieldid'] = vB::getDbAssertor()->insert('vBForum:profilefield', $vbulletin->GPC['profilefield']);
        $vbulletin->GPC['profilefieldid'] = is_array($vbulletin->GPC['profilefieldid']) ? array_pop($vbulletin->GPC['profilefieldid']) : $vbulletin->GPC['profilefieldid'];
        $vbulletin->db->query_write("ALTER TABLE " . TABLE_PREFIX . "userfield ADD field{$vbulletin->GPC['profilefieldid']} MEDIUMTEXT NOT NULL");
        $vbulletin->db->query_write("OPTIMIZE TABLE " . TABLE_PREFIX . "userfield");
    } else {
        vB::getDbAssertor()->update('vBForum:profilefield', $vbulletin->GPC['profilefield'], array('profilefieldid' => $vbulletin->GPC['profilefieldid']));
    }
    vB_Cache::allCacheEvent('vBProfileFieldsChg');
    $vbulletin->db->query_write("\n\t\tREPLACE INTO " . TABLE_PREFIX . "phrase\n\t\t\t(languageid, fieldname, varname, text, product, username, dateline, version)\n\t\tVALUES\n\t\t\t(\n\t\t\t\t0,\n\t\t\t\t'cprofilefield',\n\t\t\t\t'field" . $vbulletin->db->escape_string($vbulletin->GPC['profilefieldid']) . "_title',\n\t\t\t\t'" . $vbulletin->db->escape_string($vbulletin->GPC['title']) . "',\n\t\t\t\t'vbulletin',\n\t\t\t\t'" . $vbulletin->db->escape_string($vbulletin->userinfo['username']) . "',\n\t\t\t\t" . TIMENOW . ",\n\t\t\t\t'" . $vbulletin->db->escape_string($vbulletin->options['templateversion']) . "'\n\t\t\t),\n\t\t\t(\n\t\t\t\t0,\n\t\t\t\t'cprofilefield',\n\t\t\t\t'field" . $vbulletin->db->escape_string($vbulletin->GPC['profilefieldid']) . "_desc',\n\t\t\t\t'" . $vbulletin->db->escape_string($vbulletin->GPC['description']) . "',\n\t\t\t\t'vbulletin',\n\t\t\t\t'" . $vbulletin->db->escape_string($vbulletin->userinfo['username']) . "',\n\t\t\t\t" . TIMENOW . ",\n\t\t\t\t'" . $vbulletin->db->escape_string($vbulletin->options['templateversion']) . "'\n\t\t\t)\n\t");
    require_once DIR . '/includes/adminfunctions_language.php';
    build_language();
    build_profilefield_cache();
    if ($vbulletin->GPC['modifyfields']) {
        $args = array('do' => 'modifycheckbox', 'profilefieldid' => $vbulletin->GPC['profilefieldid']);
    } else {
        $args = array('do' => 'modify');
    }
    print_stop_message2(array('saved_x_successfully', htmlspecialchars_uni($vbulletin->GPC['title'])), 'profilefield', $args);
}
// ###################### Start add #######################
if ($_REQUEST['do'] == 'add' or $_REQUEST['do'] == 'edit') {
    $vbulletin->input->clean_array_gpc('r', array('type' => vB_Cleaner::TYPE_STR));
    if ($_REQUEST['do'] == 'add') {
 /**
  * Updates the user record with infractions, warnings, and ipoints
  *
  * @param	int	User id
  */
 protected function updateDenormalizedUserData($userid)
 {
     $userInfractions = $this->getUserInfractions($userid, 0, 1);
     $data = array('infractions' => $userInfractions ? intval($userInfractions['statistics']['total_infractions']) : 0, 'warnings' => $userInfractions ? intval($userInfractions['statistics']['total_warnings']) : 0, 'ipoints' => $userInfractions ? intval($userInfractions['statistics']['points']) : 0);
     $conditions = array('userid' => $userid);
     $changed = $this->assertor->update('user', $data, $conditions);
     vB_Cache::allCacheEvent('userChg_' . $userid);
     return $changed == 1;
 }
Exemple #12
0
 protected static function updateContentRoute($oldRouteInfo, $newRouteInfo)
 {
     $db = vB::getDbAssertor();
     $events = array();
     $events[] = "vB_ChannelStructure_chg";
     // invalidate vB_ChTree... record so that channels' routes are updated
     // update redirect301 fields
     $updateIds = $db->assertQuery('get_update_route_301', array('oldrouteid' => $oldRouteInfo['routeid']));
     if (!empty($updateIds)) {
         $routeIds = array();
         foreach ($updateIds as $route) {
             $routeid = $route['routeid'];
             $events[] = "routeChg_{$routeid}";
             $routeIds[] = $routeid;
         }
         $db->update('routenew', array('redirect301' => $newRouteInfo['routeid'], 'name' => vB_dB_Query::VALUE_ISNULL), array('routeid' => $routeIds));
     }
     // update routeid in nodes table
     $updateIds = $db->assertQuery('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::COLUMNS_KEY => array('nodeid'), vB_dB_Query::CONDITIONS_KEY => array('routeid' => $oldRouteInfo['routeid'])));
     if (!empty($updateIds)) {
         $nodeIds = array();
         foreach ($updateIds as $node) {
             $nodeid = $node['nodeid'];
             // this does not affect parents, so we don't need to clear they cache
             $events[] = "nodeChg_{$nodeid}";
             $nodeIds[] = $nodeid;
         }
         $db->update('vBForum:node', array('routeid' => $newRouteInfo['routeid']), array('nodeid' => $nodeIds));
     }
     // don't modify the routeid for default pages, as it will still be used
     $updateIds = $db->assertQuery('page', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::COLUMNS_KEY => array('pageid'), vB_dB_Query::CONDITIONS_KEY => array('routeid' => $oldRouteInfo['routeid'], 'pagetype' => vB_Page::TYPE_CUSTOM)));
     if (!empty($updateIds)) {
         $pageIds = array();
         foreach ($updateIds as $page) {
             $pageid = $page['pageid'];
             $events[] = "pageChg_{$pageid}";
             $pageIds[] = $pageid;
         }
         $db->update('page', array('routeid' => $newRouteInfo['routeid']), array('pageid' => $pageIds));
     }
     /* The code below implies that multiple conversation routes could exist under a single channel. However, I don't know
      *	when this might be the case. When moving channels/topics, the routes are untouched. Topic redirects are handled by
      *	the redirect & node tables.
      */
     // update conversation generic route
     $routes = $db->getRows('routenew', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::CONDITIONS_KEY => array(array('field' => 'class', 'value' => array('vB5_Route_Conversation', 'vB5_Route_Article')), array('field' => 'prefix', 'value' => $oldRouteInfo['prefix']), array('field' => 'contentid', 'value' => $oldRouteInfo['channelid']), array('field' => 'redirect301', 'operator' => vB_dB_Query::OPERATOR_ISNULL))));
     foreach ($routes as $route) {
         $events[] = "routeChg_{$route['routeid']}";
         //if the old route has a name, clear it.  Only one route should ever have a name and it belongs to the route
         //we are about to create.
         if ($route['name']) {
             $db->update('routenew', array('name' => vB_dB_Query::VALUE_ISNULL), array('routeid' => $route['routeid']));
         }
         // create new conversation route using most of the old route's data
         $newConversationRoute = $route;
         unset($newConversationRoute['routeid']);
         unset($newConversationRoute['redirect301']);
         $newConversationRoute['prefix'] = $newRouteInfo['prefix'];
         // special case, if prefix is empty (i.e. this is a new home page) then we must leave out the leading '/',
         // or selectBestRoute will not be able to match the path (which never has a leading '/') to regex.
         $newConversationRoute['regex'] = ($newRouteInfo['prefix'] === '' ? '' : preg_quote($newRouteInfo['prefix']) . '/') . vB5_Route_Conversation::REGEXP;
         // save the new route. If you need to call validInput(), be sure to unset prefix first, otherwise it'll think it's
         // a custom conversation url (as opposed to custom channel url, which this is)
         $newConversationRouteid = vB5_Route_Conversation::saveRoute($newConversationRoute);
         if (is_array($newConversationRouteid)) {
             $newConversationRouteid = (int) array_pop($newConversationRouteid);
         }
         // then update old convo route's redirect301
         $db->update('routenew', array('redirect301' => $newConversationRouteid), array('routeid' => $route['routeid']));
         // update routeids for conversation nodes
         // Copied from the channel node updates above.
         $updateIds = $db->assertQuery('vBForum:node', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::COLUMNS_KEY => array('nodeid'), vB_dB_Query::CONDITIONS_KEY => array('routeid' => $route['routeid'])));
         if (!empty($updateIds)) {
             $nodeIds = array();
             foreach ($updateIds as $node) {
                 $nodeid = $node['nodeid'];
                 // this does not affect parents, so we don't need to clear they cache
                 $events[] = "nodeChg_{$nodeid}";
                 $nodeIds[] = $nodeid;
             }
             // if there are ever cases of multiple conversation routes per channel, and they're sizable, it might be
             // worth creating a method query to handle all node updates at once instead of per conversation route.
             $db->update('vBForum:node', array('routeid' => $newConversationRouteid), array('nodeid' => $nodeIds));
         }
     }
     vB_Cache::allCacheEvent($events);
 }
Exemple #13
0
 /**
  * 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;
 }
 /**
  * Initializes the user context with the permissions for the selected user.
  *
  * This is used for the initial constructor and can be used to refresh permissions
  * if they have changed.
  *
  * @param boolean $forceReload -- Do not use cached permissions
  *
  */
 public function reloadUserPerms($forceReload = false)
 {
     if (!$forceReload) {
         $cached = vB_Cache::instance(vB_Cache::CACHE_LARGE)->read('vB_UserPerms' . $this->userid);
     }
     if (!empty($cached)) {
         $this->groupInTopic = $cached['groupintopic'];
         $this->usergroups = $cached['usergroups'];
         $this->moderatorPerms = $cached['moderatorperms'];
         $this->channelAccess = $cached['channelAccess'];
         $this->permissionContext = new vB_PermissionContext($this->datastore, $cached['primary'], $cached['secondary'], $cached['infraction']);
         $this->canModerate = $cached['canmoderate'];
         $this->superMod = $cached['superMod'];
     } else {
         //make sure we clear the stored session data.
         if ($forceReload) {
             vB_Cache::allCacheEvent('userPerms_' . $this->userid);
         }
         $this->superMod = array('moderatorpermissions' => 0, 'moderatorpermissions2' => 0);
         // fetch user groups
         $userLib = vB_Library::instance('user');
         if ($this->userid > 0) {
             try {
                 $result = $userLib->fetchUserGroups($this->userid);
             } catch (vB_Exception_Api $e) {
                 $errors = $e->get_errors();
                 if ($errors[0][0] == 'invalid_user_specified') {
                     //note that we can't get here on the second call because the userid is 0
                     //we need to make sure we don't infinitely recurse here
                     $this->userid = 0;
                     return $this->reloadUserPerms($forceReload);
                 }
                 throw $e;
             }
         } else {
             $result = false;
         }
         if ($result) {
             $primary_group_id = $result['groupid'];
             $secondary_group_ids = $result['secondary'];
             $infraction_group_ids = $result['infraction'];
         } else {
             $primary_group_id = self::USERGROUP_GUESTS;
             $secondary_group_ids = array();
             $infraction_group_ids = array();
         }
         //We can't call the user api function getGroupInTopic(), because that does a permission check. Which causes a recursion loop
         //We have to do a try-catch block here. During an upgrade we check permissions although the groupintopic table doesn't exist.
         try {
             if ($this->userid > 0) {
                 $this->reloadGroupInTopic();
             }
         } catch (exception $e) {
             //Nothing to do here. Just continue
         }
         // ignore secondary usergroups if allowmembergroups is set to "No"
         $bf_ugp_genericoptions = $this->datastore->get_value('bf_ugp_genericoptions');
         $usergroupCache = $this->datastore->get_value('usergroupcache');
         //vB::getDatastore()->getValue('usergroupcache');
         if (!($usergroupCache[$primary_group_id]['genericoptions'] & $bf_ugp_genericoptions['allowmembergroups'])) {
             $this->usergroups = array($primary_group_id);
         } else {
             $this->usergroups = array_merge(array($primary_group_id), $secondary_group_ids);
         }
         $this->permissionContext = new vB_PermissionContext($this->datastore, $primary_group_id, $secondary_group_ids, $infraction_group_ids);
         //Add any permissions from the moderator table.
         if ($this->userid) {
             // Since moderator perms are based on the moderator table, I'm leaving this independent of the usergroup option 'allowmembergroups'
             $this->moderatorPerms = $userLib->fetchModerator($this->userid);
             if ($this->hasPermission('adminpermissions', 'ismoderator') and !empty($this->moderatorPerms[0])) {
                 if (!isset($this->moderatorPerms[0]['permissions'])) {
                     $this->moderatorPerms[0]['permissions'] = 0;
                 }
                 if (!isset($this->moderatorPerms[0]['permissions2'])) {
                     $this->moderatorPerms[0]['permissions2'] = 0;
                 }
                 $this->superMod = array('moderatorpermissions' => $this->moderatorPerms[0]['permissions'], 'moderatorpermissions2' => $this->moderatorPerms[0]['permissions2']);
             }
         } else {
             $this->moderatorPerms = array();
         }
         vB_Cache::instance(vB_Cache::CACHE_LARGE)->write('vB_UserPerms' . $this->userid, array('groupintopic' => $this->groupInTopic, 'usergroups' => $this->usergroups, 'moderatorperms' => $this->moderatorPerms, 'primary' => $primary_group_id, 'secondary' => $secondary_group_ids, 'infraction' => $infraction_group_ids, 'channelAccess' => $this->getAllChannelAccess(), 'canmoderate' => $this->getCanModerate(), 'superMod' => $this->superMod), 1440, array('userPerms_' . $this->userid, 'userChg_' . $this->userid, 'perms_changed', 'vB_ChannelStructure_chg'));
     }
 }
Exemple #15
0
 /**
  * Extracts the thumbnail from og:image meta data
  *
  * @param  string url of video
  * @param  int    optional nodeid of video node
  *
  * @return mixed  url string or false
  */
 public function getVideoThumbnail($url, $nodeid = false)
 {
     //Note that this is called from the template, and often there will be no ndeid
     if (!empty($nodeid)) {
         $video = $this->getContent($nodeid);
         if (!empty($video)) {
             $video = array_pop($video);
         }
     }
     if (empty($video)) {
         //Try to get from cache first.
         $cacheKey = 'vB_Vid' . md5($url);
         $check = vB_Cache::instance(vB_Cache::CACHE_LARGE)->read($cacheKey);
         if (!empty($check)) {
             return $check;
         }
         $video = $this->assertor->getRow('vBForum:video', array('url' => $url));
     }
     //check if we have the thumbnail in the video
     if (!empty($video) and !empty($video['thumbnail']) and !empty($video['thumbnail_date']) and $video['thumbnail_date'] >= vB::getRequest()->getTimeNow() - self::THUMBNAIL_TTL) {
         return $video['thumbnail'];
     }
     $data = vB_Api::instance('content_link')->parsePage($url);
     if (!empty($data['images'])) {
         $thumbnail = $data['images'];
         // only return the first image. May want to change this later after product audit?
         if (is_array($thumbnail)) {
             $thumbnail = $thumbnail[0];
         }
         //save the thumbnail so we don't have to fetch it next time it's needed
         if (!empty($video)) {
             //there is a video record.  Put it there.
             $this->assertor->update('vBForum:video', array('thumbnail' => $thumbnail, 'thumbnail_date' => vB::getRequest()->getTimeNow()), array('nodeid' => $video['nodeid']));
             vB_Cache::allCacheEvent('nodeChg_' . $video['nodeid']);
         } else {
             //put into cache
             if (empty($cacheKey)) {
                 $cacheKey = 'vB_Vid' . md5($url);
             }
             vB_Cache::instance(vB_Cache::CACHE_LARGE)->write($cacheKey, $thumbnail, self::THUMBNAIL_TTL);
         }
         return $thumbnail;
     }
     // we should probably have a default placeholder
     // we can return in case no image is found..
     return false;
 }
Exemple #16
0
 /**
  * Updates data after user being deleted.
  *
  */
 protected function updateDeletedUserData()
 {
     $phrase = vB_Api::instanceInternal('phrase')->fetch('guest');
     $guestPhrase = $phrase['guest'];
     unset($phrase);
     // node data update
     $events = array();
     $nodes = $this->assertor->getRows('vBForum:node', array('userid' => $this->existing['userid']));
     foreach ($nodes as $node) {
         $events[$node['nodeid']] = 'nodeChg_' . $node['nodeid'];
     }
     $this->assertor->update('vBForum:node', array('userid' => 0, 'authorname' => $guestPhrase), array('userid' => $this->existing['userid']));
     // node last data update
     $nodes = $this->assertor->getRows('vBForum:node', array('lastauthorid' => $this->existing['userid']));
     foreach ($nodes as $node) {
         $events[$node['nodeid']] = 'nodeChg_' . $node['nodeid'];
     }
     $this->assertor->update('vBForum:node', array('lastauthorid' => 0, 'lastcontentauthor' => $guestPhrase), array('lastauthorid' => $this->existing['userid']));
     // vms
     $nodes = $this->assertor->getRows('vBForum:node', array('setfor' => $this->existing['userid']));
     foreach ($nodes as $node) {
         $events[$node['nodeid']] = 'nodeChg_' . $node['nodeid'];
     }
     $this->assertor->update('vBForum:node', array('setfor' => 0), array('setfor' => $this->existing['userid']));
     if (!empty($events)) {
         vB_Cache::allCacheEvent($events);
     }
 }
Exemple #17
0
 /**
  * Delete a user
  *
  * @param integer 	int 	 	The ID of user to be deleted
  * @param bool 		boolean 	Whether to transfer the Groups and Blogs owned by the user to current logged-in admininstrator
  */
 public function delete($userid, $transfer_groups = true)
 {
     $this->checkHasAdminPermission('canadminusers');
     require_once DIR . '/includes/adminfunctions.php';
     // check user is not set in the $undeletable users string
     if (is_unalterable_user($userid)) {
         throw new vB_Exception_Api('user_is_protected_from_alteration_by_undeletableusers_var');
     } else {
         $info = vB_User::fetchUserInfo($userid);
         if (!$info) {
             throw new vB_Exception_Api('invalid_user_specified');
         }
         $events = array();
         if ($transfer_groups) {
             $adminuserid = vB::getCurrentSession()->fetch_userinfo_value('userid');
             // Admin userid
             $this->library->transferOwnership($userid, $adminuserid);
         } else {
             $nodeidsforuser = array();
             $groups = vB_Api::instanceInternal('socialgroup')->getSGInfo(array('userid' => $userid, 'perpage' => 100));
             if (!empty($groups['results'])) {
                 foreach ($groups['results'] as $groupnodeid => $group) {
                     $nodeidsforuser[] = $groupnodeid;
                     $events[] = 'nodeChg_' . $groupnodeid;
                 }
             }
             $blogs = vB_Api::instanceInternal('blog')->getBlogInfo(1, 100, $userid);
             if (!empty($blogs['results'])) {
                 foreach ($blogs['results'] as $blognodeid => $blog) {
                     $nodeidsforuser[] = $blognodeid;
                     $events[] = 'nodeChg_' . $blognodeid;
                 }
             }
             foreach ($nodeidsforuser as $nodeid) {
                 vB_Api::instanceInternal('content_channel')->delete($nodeid);
             }
         }
         $userdm = new vB_Datamanager_User(vB_DataManager_Constants::ERRTYPE_ARRAY_UNPROCESSED);
         $userdm->set_existing($info);
         $userdm->delete();
         if ($userdm->has_errors(false)) {
             throw $userdm->get_exception();
         }
         $events[] = 'userChg_' . $userid;
         vB_Cache::allCacheEvent($events);
         return true;
     }
 }
Exemple #18
0
         $sql = "UPDATE " . TABLE_PREFIX . "node \nSET displayorder = CASE \n";
         $events = array();
         foreach ($nodes as $node) {
             $nodeid = $node['nodeid'];
             $displayorder = $node['displayorder'];
             if ($displayorders[$nodeid] === $displayorder) {
                 unset($displayorders[$nodeid]);
             } else {
                 $sql .= "\tWHEN nodeid = " . $nodeid . " THEN " . $displayorders[$nodeid] . "\n";
                 $events[] = 'nodeChg_' . $nodeid;
             }
         }
         $sql .= "ELSE displayorder \nEND  \nWHERE nodeid IN (" . implode(',', array_keys($displayorders)) . ")";
         if (!empty($displayorders)) {
             $vbulletin->db->query_write($sql);
             vB_Cache::allCacheEvent($events);
         }
     }
     print_cp_redirect2('cms', array('do' => $gobackto), 1);
 }
 // for everything else, there has to be selected nodes...
 if (!is_array($vbulletin->GPC['select_node']) or empty($vbulletin->GPC['select_node'])) {
     print_stop_message2('nothing_to_do');
 }
 // grab nodeids, make sure they're int
 $nodeids = array();
 foreach ($vbulletin->GPC['select_node'] as $nodeid => $nothing) {
     $nodeid = intval($nodeid);
     if ($nodeid > 0) {
         $nodeids[$nodeid] = $nodeid;
     }
Exemple #19
0
 public static function updateRoute($routeId, $data)
 {
     $assertor = vB::getDbAssertor();
     $oldRouteInfo = $assertor->getRow('routenew', array('routeid' => $routeId));
     if (!$oldRouteInfo) {
         return false;
     }
     if (isset($oldRouteInfo['arguments']) and !empty($oldRouteInfo['arguments'])) {
         $arguments = unserialize($oldRouteInfo['arguments']);
         foreach ($arguments as $key => $val) {
             $oldRouteInfo[$key] = $val;
         }
     }
     $class = $oldRouteInfo['class'];
     $new_data = array_merge($oldRouteInfo, $data);
     unset($new_data['routeid']);
     // When we're updating a conversation route for a topic that was previously under a channel with a custom URL,
     // the old route has a redirect301 that causes a redirect loop.
     unset($new_data['redirect301']);
     if (!call_user_func_array(array($class, 'validInput'), array(&$new_data))) {
         throw new Exception('Invalid route data');
     }
     if (isset($new_data['prefix']) and $new_data['prefix'] !== $oldRouteInfo['prefix']) {
         $conditions = array('prefix' => $new_data['prefix'], 'class' => $class);
         // used for cache invalidation below
         $deletedRoutes = $assertor->getRows('routenew', $conditions);
         // Overwrite any related record with the same regex.
         // If you need to validate the prefix before calling this method: use vB5_Route::isPrefixUsed (see vB_Api_Page::savePage).
         // VBV-11372, in order to delete the "home" route (which has an empty regex), we cannot rely on regex for deletion.
         $assertor->delete('routenew', $conditions);
         //if the old route has a name, clear it.  Only one route should ever have a name and it belongs to the route
         //we are about to create.
         if ($oldRouteInfo['name']) {
             $assertor->update('routenew', array('name' => vB_dB_Query::VALUE_ISNULL), array('routeid' => $oldRouteInfo['routeid']));
         }
         // url has changed: create a new route and update old ones and page record
         $newrouteid = self::saveRoute($new_data);
         if (is_array($newrouteid)) {
             $newrouteid = (int) array_pop($newrouteid);
         }
         $new_data['routeid'] = $newrouteid;
         call_user_func(array($class, 'updateContentRoute'), $oldRouteInfo, $new_data);
         $result = $newrouteid;
     } else {
         // url has not changed, so there is no need to create a new route
         unset($new_data['prefix']);
         unset($new_data['regex']);
         unset($new_data['arguments']);
         self::saveRoute($new_data, array('routeid' => $oldRouteInfo['routeid']));
         $result = $oldRouteInfo['routeid'];
     }
     // invalidate cache
     $events[$oldRouteInfo['routeid']] = "routeChg_" . $oldRouteInfo['routeid'];
     foreach ($deletedRoutes as $route) {
         $events[$route['routeid']] = "routeChg_" . $route['routeid'];
     }
     // check if a common route was modified.
     $common = self::fetchCommonRoutes();
     foreach ($common as $route) {
         if (array_key_exists($route['routeid'], $events)) {
             $events[] = 'vB_routesChgMultiple';
             break;
         }
     }
     vB_Cache::allCacheEvent($events);
     return $result;
 }
 protected static function updateContentRoute($oldRouteInfo, $newRouteInfo)
 {
     $db = vB::getDbAssertor();
     $events = array();
     $arguments = unserialize($newRouteInfo['arguments']);
     // update routeid in nodes table
     $db->update('vBForum:node', array('routeid' => $newRouteInfo['routeid']), array('nodeid' => $arguments['nodeid']));
     $events[] = "nodeChg_{$arguments['nodeid']}";
     // don't modify the routeid for default pages, as it will still be used
     $updateIds = $db->assertQuery('page', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, vB_dB_Query::COLUMNS_KEY => array('pageid'), vB_dB_Query::CONDITIONS_KEY => array('routeid' => $oldRouteInfo['routeid'], 'pagetype' => vB_Page::TYPE_CUSTOM)));
     if (!empty($updateIds)) {
         $pageIds = array();
         foreach ($updateIds as $page) {
             $pageid = $page['pageid'];
             $events[] = "pageChg_{$pageid}";
             $pageIds[] = $pageid;
         }
         $db->update('page', array('routeid' => $newRouteInfo['routeid']), array('pageid' => $pageIds));
     }
     vB_Cache::allCacheEvent($events);
 }