/** * Merges "posted" info into the topics array, used by the display_Topics template. * This adds the "content.posted" element to the node record. The value is the number of * times the current user has posted in the topic (replies and comments); zero if none. * * @param array Nodes * * @return array Same array of nodes, with the "posted" element added to the "content" sub-array */ public function mergePostedStatusForTopics($nodes) { $user = vB::getCurrentSession()->fetch_userinfo(); $userid = $user['userid']; return $this->library->mergePostedStatusForTopics($nodes, $userid); }
/** * Takes an array of node information and adds contentInfo * @param integer The node id of the parent where we are listing * @param integer page number to return * @param integer items per page * @param integer depth- 0 means no stopping, otherwise 1= direct child, 2= grandchild, etc * @param mixed if desired, will only return specific content types. * @param mixed 'sort', or 'exclude' recognized. * * @return mixed array of id's ***/ public function addFullContentInfo($nodeList, $options = array()) { //Now separate by content type $contenttypes = array(); if (empty($nodeList)) { return array(); } $nodeIds = array(); $needVote = array(); $cacheVote = array(); $needRead = array(); $parentids = array(); $attachCounts = array(); $photoCounts = array(); $channels = array(); $grabAttachCounts = array(); $cache = vB_Cache::instance(vB_Cache::CACHE_FAST); $userids = array(); foreach ($nodeList as $key => $node) { if (empty($node['nodeid'])) { continue; } if (!isset($contenttypes[$node['contenttypeid']])) { $contenttypes[$node['contenttypeid']] = array(); } $contenttypes[$node['contenttypeid']][$key] = $node['nodeid']; $nodeIds[] = $node['nodeid']; if ($this->channelTypeId != $node['contenttypeid']) { // only fetch attachments for non channels. $grabAttachCounts[] = $node['nodeid']; } if (!isset($node['nodeVoted'])) { $needVote[] = $node['nodeid']; } else { $cacheVote[$node['nodeid']] = $node['nodeVoted']; } if (!isset($node['readtime'])) { $needRead[$node['nodeid']] = $node['nodeid']; $nodeList[$key]['readtime'] = 0; } $parentids[$node['parentid']] = $node['parentid']; $needRead = array_merge($parentids, $needRead); if (!isset($userids[$node['userid']])) { $userids[$node['userid']] = $node['userid']; } } vB_Library::instance('user')->preloadUserInfo($userids); // pre-cache parents $parents = $this->getNodes($parentids); $parentrouteids = array(); foreach ($parents as $parent) { $parentrouteids[] = $parent['routeid']; } //pre-load parent routes vB5_Route::preloadRoutes($parentrouteids); // get votes $nodeVotes = empty($needVote) ? array() : $this->getNodeVotes($needVote); if (!empty($cacheVote)) { $this->cacheNodeVotes($cacheVote); } if (!empty($nodeIds)) { $attachments = $this->fetchNodeAttachments($nodeIds); $nodeAttachments = array(); foreach ($attachments as $key => $attach) { $nodeAttachments[$attach['parentid']][$attach['filedataid']] =& $attachments[$key]; } } // Fetch read marking data $threadmarking = vB::getDatastore()->getOption('threadmarking'); $userid = vB::getCurrentSession()->get('userid'); if ($threadmarking and $userid and !empty($nodeIds) and !empty($needRead)) { $reads = vB::getDbAssertor()->getRows('noderead', array('userid' => $userid, 'nodeid' => $needRead)); $parentsreads = array(); foreach ($reads as $read) { if (!empty($nodeList[$read['nodeid']])) { $nodeList[$read['nodeid']]['readtime'] = $read['readtime']; } else { $parentsreads[$read['nodeid']] = $read['readtime']; } } foreach ($nodeList as $nodeid => $node) { if (empty($parentsreads[$node['parentid']])) { $parentsreads[$node['parentid']] = 0; } $nodeList[$nodeid]['parentreadtime'] = $parentsreads[$node['parentid']]; } } //For each type, get the content detail. if (!empty($grabAttachCounts)) { $attachCountQry = vB::getDbAssertor()->getRows('vBForum:getDescendantAttachCount', array('nodeid' => $grabAttachCounts)); foreach ($attachCountQry as $count) { $attachCounts[$count['nodeid']] = $count['count']; } $photoCountQry = vB::getDbAssertor()->getRows('vBForum:getDescendantPhotoCount', array('nodeid' => $grabAttachCounts, 'photoTypeid' => vB_Types::instance()->getContentTypeID('vBForum_Photo'))); foreach ($photoCountQry as $count) { $photoCounts[$count['nodeid']] = $count['count']; } } // precache closure $this->fetchClosureParent($nodeIds); $optionMask = vB_Api::instanceInternal('node')->getOptions(); foreach ($contenttypes as $contenttypeid => $nodes) { if (!empty($nodes)) { $contentLib = vB_Library_Content::getContentLib($contenttypeid); $contentList = $contentLib->getFullContent($nodes); foreach ($nodes as $key => $nodeid) { if (isset($contentList[$nodeid])) { if (!empty($contentList[$nodeid]['node_no_permission'])) { unset($nodeList[$nodeid]); continue; } if (isset($nodeList[$key]['nodeVoted'])) { // node came into the function with nodeVoted already set $contentList[$nodeid]['nodeVoted'] = $nodeList[$key]['nodeVoted']; } else { // node came into this function w/o nodeVoted set so getNodeVotes retrieved it up there^ $contentList[$nodeid]['nodeVoted'] = in_array($nodeid, $nodeVotes) ? 1 : 0; } $nodeList[$key]['content'] = $contentList[$nodeid]; if (!empty($contentList[$nodeid]['contenttypeclass'])) { $nodeList[$key]['contenttypeclass'] = $contentList[$nodeid]['contenttypeclass']; } if ($contentList[$nodeid]['contenttypeid'] == $this->channelTypeId) { $channels[$contentList[$nodeid]['nodeid']] = $contentList[$nodeid]['nodeid']; } else { if (!empty($contentList[$nodeid]['channelid']) and !isset($channels[$contentList[$nodeid]['channelid']])) { $channels[$contentList[$nodeid]['channelid']] = $contentList[$nodeid]['channelid']; } } } foreach ($optionMask as $bitname => $bitmask) { $nodeList[$key][$bitname] = $bitmask & $node['nodeoptions'] ? 1 : 0; } if (isset($nodeAttachments[$nodeid])) { $nodeList[$key]['content']['attachments'] =& $nodeAttachments[$nodeid]; } else { $nodeList[$key]['content']['attachments'] = array(); } if (empty($attachCounts[$nodeid])) { $nodeList[$key]['attachcount'] = 0; } else { $nodeList[$key]['attachcount'] = $attachCounts[$nodeid]; } if (!empty($photoCounts[$nodeid])) { $nodeList[$key]['attachcount'] += $photoCounts[$nodeid]; } } } } // censor textual node items vB_Library_Node::censorNodes($nodeList); $this->addOptionalContentInfo($nodeList, $options); //Note- it is essential that the parentids be passed along with the nodeList. This allows all the permissions to // be pulled in one function call, and saves a lot of processing in the usercontext object. $this->markSubscribed($nodeList); $this->markJoined($nodeList); return $nodeList; }
/** * Assembles the response for detailed content * * @param Array $content getRawContent() response array. Each element is a nodeid-keyed array. Each * subarray must have the following data at minimum: nodeid, channelid, * contenttypeid, starter, showopen, userid, setfor (if VM), nodeoptions * * @return Array Nodeid-keyed array of the $content data, plus additional data such as contenttypeclass, * createpermissions, moderatorperms, channeltype, permissions, etc, @TODO: complete this list * Also the expanded nodeoptions of: * allow_post, moderate_comments, approve_membership, invite_only, autoparselinks, * disablesmilies, disable_bbcode, hide_title, hide_author, hide_publishdate, * display_fullincategory, display_pageviews, hide_comment_count */ public function assembleContent(&$content) { // get the class name for this content type to add to results $contentTypeClass = vB_Types::instance()->getContentTypeClass($this->contenttypeid); $userContext = vB::getUserContext(); $languageid = vB::getCurrentSession()->get('languageid'); //We can save some time by saving, for a page load, the list of // channels we already know the current user can't post. static $noComment = array(); $results = array(); $needUserRep = array(); $cache = vB_Cache::instance(vB_Cache::CACHE_STD); $fastCache = vB_Cache::instance(vB_Cache::CACHE_FAST); $thisUserid = vB::getCurrentSession()->get('userid'); //pre-cache channels $channelids = $nodeids = array(); $canUseRep = $userContext->hasPermission('genericpermissions', 'canuserep'); foreach ($content as $key => $record) { if (!$this->checkComplete($record)) { unset($content[$key]); } if (!empty($record['channelid'])) { $channelids[$record['channelid']] = $record['channelid']; } else { if ($record['contenttypeid'] == $this->channelTypeId) { $content[$key]['channelid'] = $record['nodeid']; $channelids[$record['nodeid']] = $record['nodeid']; } else { $starter = vB_Library::instance('node')->getNodeBare($record['starter']); $content[$key]['channelid'] = $starter['parentid']; $channelids[$starter['parentid']] = $starter['parentid']; } } $nodeids[] = $record['nodeid']; } // preload closure vB_Library::instance('node')->fetchClosureParent($nodeids); $channels = vB_Library::instance('node')->getNodes($channelids); //and preload channel permission data $channelPerms = vB::getUserContext()->fetchPermsForChannels($channelids); $needOnlineStatus = array(); $needReputation = array(); $contentUserids = array(); $channelTypes = vB::getDatastore()->getValue('vBChannelTypes'); //we can comment if there is at least one content type we can create, and the channel (in case this is a blog or //social group) doesn't have comments disabled, and either it's your and you have canreply $userid = vB::getCurrentSession()->get('userid'); $commentsEnabled = vB::getDatastore()->getOption('postcommentthreads'); $canmanageownprofile = $channelPerms['global']['canmanageownprofile']; foreach ($content as $key => $record) { $record['contenttypeclass'] = $contentTypeClass; $channelid = $record['channelid']; $thisChannelPerms = $channelPerms[$channelid]; //$record['createpermissions'] = $thisChannelPerms['cancreate']; /* * I'm making the assumption that the 'createpermissions' here is only used in the templates to check * whether a REPLY to this specific node can be created or not. For an example, refer to their use in * the contententry template. Note that if what we need is NOT supposed to be permissions to reply to * this node, we need to fetch the correct permissions at that time. For an example, refer to the * createcontent controller's loadEditor(), where it calls getCreatepermissionsForEdit(). * Since the permissions for replying to this node might be different from replying to the channel, * we don't want to rely on the channel perm's 'cancreate'. * PS. Never use these for "real" permission checking ("real" permission checking is in content api's validate()) */ $record['createpermissions'] = vB::getUserContext()->getCanCreate($record['nodeid']); $record['moderatorperms'] = $thisChannelPerms['moderate']; //channeltype if (isset($channelTypes[$channelid])) { $record['channeltype'] = $channelTypes[$channelid]; } else { $record['channeltype'] = ''; } $thisChannelPerms['global'] = $channelPerms['global']; if ($this->getCanEdit($record, $userContext, $thisChannelPerms)) { $record['canedit'] = 1; } else { $record['canedit'] = 0; } $record['canview'] = $thisChannelPerms['canview']; //There are four moderator-like permissions. Let's start setting them to zero. If the user has that // permissions we'll enable it soon. foreach (array('canmove', 'candeleteposts', 'candeletethread', 'canopenclose') as $permName) { $record[$permName] = 0; } if ($record['contenttypeid'] == $this->channelTypeId) { $record['canundeleteposts'] = $record['canremove'] = false; // TODO: GET RID OF $record['canremove'] } else { $record['canremove'] = $thisChannelPerms['canremoveposts']; // TODO: GET RID OF $record['canremove'] // Only the soft-delete mod permission grants undelete permission. // A user could get soft-delete permissions *without* undelete, which is why we leave // candeleteposts to be set by getCanDelete() below $record['canundeleteposts'] = $thisChannelPerms['moderate']['candeleteposts']; // TODO, update above with the new, real moderator permission when we work on VBV-12234 } // showUnpublishedNotice is used by display_Topics_item template to show the X Unpublished notice // in channel view. Because we muck around with the "moderator-like" permissions, including // candeleteposts, we can't rely on just that in the templates, so we have to do this. // For reference, VBV-12177 $record['showUnpublishedNotice'] = $thisChannelPerms['moderate']['candeleteposts']; // Hard delete & soft delete permissions can be independent. // For ex. canremoveposts doesn't give you soft-delete permissions, but does allow you to physically delete // The following values may be determined here in addition to 'candeletethread' & 'candeleteposts': $record['canharddeleteposts'] = 0; $record['moderatorperms']['canremoveposts'] = 0; // hard delete if ($this->getCanDelete($record, $userContext, $thisChannelPerms, true)) { // can hard delete $record['canharddeleteposts'] = 1; $record['moderatorperms']['canremoveposts'] = 1; // is this node a starter? That means they can delete the thread. if ($record['starter'] == $record['nodeid']) { $record['candeletethread'] = 1; } } // soft delete if ($this->getCanDelete($record, $userContext, $thisChannelPerms, false)) { // can soft delete $record['candeleteposts'] = 1; // 'cansoftdeleteposts' is used just to ensure $record['canmoderate'] will be set to 1 below // so that topics will have a checkbox in channel view, VBV-12183. It's not used for anything else. // we can't just set $record['moderatorperms']['canremoveposts'], because that value is used for // physical-delete specific things in the templates. $record['moderatorperms']['cansoftdeleteposts'] = 1; // is this node a starter? That means they can delete the thread. if ($record['starter'] == $record['nodeid']) { $record['candeletethread'] = 1; } } $record['moderate']['candeleteposts'] = $thisChannelPerms['moderate']['canundeleteposts'] = 0; // TODO: figure out what this does and remove if it does nothing $thisChannelPerms['canmoderateposts'] = $this->getCanModerate($record, $userContext, $thisChannelPerms); if ($thisChannelPerms['canmoderateposts']) { $record['canmoderate'] = $record['canmoderateposts'] = 1; $record['moderate']['canmoderateposts'] = $thisChannelPerms['moderate']['canmoderateposts'] = 1; // TODO: figure out what this does and remove if it does nothing } else { $record['canmoderate'] = 0; } //check the four 'my own' moderator-like permissions if ($record['showopen'] and $record['userid'] == $thisUserid) { //and the four moderator-like permissions for node owners. //move is for the topic, not replies & comments if ($record['nodeid'] == $record['starter'] and $thisChannelPerms['canmove']) { $record['moderatorperms']['canmove'] = 1; $record['moderatorperms']['canmovethread'] = 1; } if ($record['nodeid'] == $record['starter'] and $thisChannelPerms['canopenclose']) { $record['moderatorperms']['canopenclose'] = 1; } // TODO: figure out a way to combine this & the following if blocks into the // getCanDelete() checks we do above. // Note, this is probably redundant due to 'cansoftdeleteposts' above. if ($record['nodeid'] == $record['starter'] and $thisChannelPerms['candeleteownthread']) { // I don't think user_candeleteownpost is actually used in any templates. It seems to be used // just so that $record['canmoderate'] will be set to 1 below, so that inline mod will be enabled. // I'm leaving this alone for now, but there's probably a better way to do this. $record['moderatorperms']['user_candeleteownpost'] = 1; } if ($record['nodeid'] != $record['starter'] and $thisChannelPerms['candeleteownpost']) { $record['moderatorperms']['candeleteposts'] = 1; } if ($thisChannelPerms['caneditown']) { $record['moderatorperms']['caneditpost'] = 1; } } // allow the receiver to manage their VMs if they have permission if (!empty($record['setfor']) and $record['setfor'] == $userid and $canmanageownprofile) { $record['canmoderateposts'] = 1; $record['candeleteposts'] = 1; $thisChannelPerms['moderate']['canmoderateposts'] = 1; // TODO: figure out what this does and remove if it does nothing } if ($this->textCountChange > 0 and $this->isPublished($record)) { $record['textcount_1'] = $record['textcount'] + 1; $record['totalcount_1'] = $record['totalcount'] + 1; if ($record['canmoderate']) { $record['textcount_1'] += $record['textunpubcount']; $record['totalcount_1'] += $record['totalunpubcount']; } } else { $record['textcount_1'] = $record['textcount']; $record['totalcount_1'] = $record['totalcount']; } // Add userinfo for reputation - is there a cached version? if ($record['userid'] > 0 and $record['contenttypeid'] != $this->channelTypeId) { $needReputation['vBUserRep_' . $record['userid']] = 'vBUserRep_' . $record['userid']; } $record['allow_post'] = $record['nodeoptions'] & vB_Api_Node::OPTION_ALLOW_POST ? 1 : 0; $record['moderate_comments'] = $record['nodeoptions'] & vB_Api_Node::OPTION_MODERATE_COMMENTS ? 1 : 0; $record['approve_membership'] = $record['nodeoptions'] & vB_Api_Node::OPTION_AUTOAPPROVE_MEMBERSHIP ? 1 : 0; $record['invite_only'] = $record['nodeoptions'] & vB_Api_Node::OPTION_NODE_INVITEONLY ? 1 : 0; $record['autoparselinks'] = $record['nodeoptions'] & vB_Api_Node::OPTION_NODE_PARSELINKS ? 1 : 0; $record['disablesmilies'] = $record['nodeoptions'] & vB_Api_Node::OPTION_NODE_DISABLE_SMILIES ? 1 : 0; $record['disable_bbcode'] = $record['nodeoptions'] & vB_Api_Node::OPTION_NODE_DISABLE_BBCODE ? 1 : 0; $record['hide_title'] = $record['nodeoptions'] & vB_Api_Node::OPTION_NODE_HIDE_TITLE ? 1 : 0; $record['hide_author'] = $record['nodeoptions'] & vB_Api_Node::OPTION_NODE_HIDE_AUTHOR ? 1 : 0; $record['hide_publishdate'] = $record['nodeoptions'] & vB_Api_Node::OPTION_NODE_HIDE_PUBLISHDATE ? 1 : 0; $record['display_fullincategory'] = $record['nodeoptions'] & vB_Api_Node::OPTION_NODE_DISPLAY_FULL_IN_CATEGORY ? 1 : 0; $record['display_pageviews'] = $record['nodeoptions'] & vB_Api_Node::OPTION_NODE_DISPLAY_PAGEVIEWS ? 1 : 0; $record['hide_comment_count'] = $record['nodeoptions'] & vB_Api_Node::OPTION_NODE_HIDE_COMMENT_COUNT ? 1 : 0; $record['can_flag'] = intval($userid) ? 1 : 0; //If this is not a channel, we need the user information to check reputation. if ($record['contenttypeid'] != $this->channelTypeId) { $contentUserids[] = $record['userid']; // these cache keys are set by vB_Library_User::preloadUserInfo $needOnlineStatus[$record['userid']] = "vb_UserInfo_{$record['userid']}_{$languageid}"; //Now the moderator-type permissions if (!empty($record['moderatorperms'])) { foreach ($record['moderatorperms'] as $key => $perm) { if ($perm > 0 and $key != 'caneditpost') { $record['canmoderate'] = 1; break; } } } } $infractionLibrary = vB_Library::instance('content_infraction'); $record['caninfract'] = $infractionLibrary->canInfractNode($record['nodeid'], $record) ? 1 : 0; $record['canviewnodeinfraction'] = $infractionLibrary->canViewNodeInfraction($record['nodeid'], $record) ? 1 : 0; $record['canseewholiked'] = $userContext->hasPermission('genericpermissions', 'canseewholiked') ? 1 : 0; // Let's make sure that these two are always set, so we don't run into undefine indices downstream somewhere. // Note that 'createpermissions' is instantiated above, near the beginning of this foreach body $record['can_comment'] = 0; $record['canreply'] = 0; //the channel permissions don't seem to use vB_Api_Node::OPTION_ALLOW_POST and it appears to have //some special meaning for channels regarding comments so we'll handle channels seperately //If this is a channel we need to check canpostnew is the proper permission for channels if ($record['contenttypeid'] == $this->channelTypeId) { if (!$thisChannelPerms['canpostnew']) { $record['createpermissions'] = false; } if (($record['nodeoptions'] & vB_Api_Node::OPTION_ALLOW_POST) > 0) { $record['can_comment'] = (int) ($thisChannelPerms['cancomment'] and $commentsEnabled); $record['canreply'] = $thisChannelPerms['canreply']; } } else { if ($record['starter'] == $record['nodeid']) { $record['canreply'] = 0; if (!$thisChannelPerms['canreply']) { $record['createpermissions'] = false; } else { $record['canreply'] = ($record['nodeoptions'] & vB_Api_Node::OPTION_ALLOW_POST) > 0 ? 1 : 0; } } else { // per VBV-4523, commenting requires BOTH cancomment AND canreply if (!($thisChannelPerms['cancomment'] and $thisChannelPerms['canreply'])) { $record['createpermissions'] = false; } //if comments are disabled, then ... don't allow comments. if (($record['nodeoptions'] & vB_Api_Node::OPTION_ALLOW_POST) > 0 and $commentsEnabled) { $record['can_comment'] = ($thisChannelPerms['cancomment'] and $thisChannelPerms['canreply']) ? 1 : 0; if ($thisChannelPerms['cancomment'] and !empty($record['starter'])) { //If we were called with fullcontent then we already have the channel. if (empty($record['channelid'])) { $thisParent = $this->nodeApi->getNode($record['starter']); $record['channelid'] = $thisParent['parentid']; } if (empty($channels[$record['channelid']])) { $channels[$record['channelid']] = $this->nodeApi->getNode($record['channelid']); } //special interpretation of vB_Api_Node::OPTION_ALLOW_POST) for channels if that's not //set then replies in this channel shouldn't allow comments. //We need to check the nodeoptions field. if (($channels[$record['channelid']]['nodeoptions'] & vB_Api_Node::OPTION_ALLOW_POST) == 0) { $record['can_comment'] = 0; } } } } } /* * Note 2014-02-19: We should remove 'canremove'. It doesn't really do anything outside of unit tests * currently. Not to confuse this with the 'canremove' checked in editor_contenttype_Text_comment template. * That's set in the createcontent controller. * I haven't removed it yet because it would cause a bunch of unit test failures, since they still check for * this even though it's not used anymore. */ $record['permissions'] = array('canedit' => $record['canedit'], 'canmoderate' => $record['canmoderate'], 'canvote' => $thisChannelPerms['canvote'] ? 1 : 0, 'canuserep' => $canUseRep ? 1 : 0, 'canremove' => $record['canremove'], 'can_flag' => $record['can_flag'], 'canviewthreads' => $thisChannelPerms['canviewthreads'], 'canviewothers' => $thisChannelPerms['canviewothers'], 'caninfract' => $record['caninfract'], 'canviewnodeinfraction' => $record['canviewnodeinfraction'], 'canseewholiked' => $record['canseewholiked'], 'can_comment' => $record['can_comment']); // can't like an infraction if ($record['permissions']['canuserep'] and $this->contenttype == 'vBForum_Infraction') { $record['permissions']['canuserep'] = 0; } $record['moderatorperms']['canharddeleteposts'] = (int) $record['canharddeleteposts']; $record['moderatorperms']['candeleteposts'] = (int) $record['candeleteposts']; $record['moderatorperms']['canundeleteposts'] = (int) $record['canundeleteposts']; $record['moderatorperms']['candeletethread'] = empty($record['candeletethread']) ? 0 : 1; $record['moderatorperms']['canmoderateposts'] = empty($record['canmoderateposts']) ? 0 : 1; $results[$record['nodeid']] = $record; } if (!empty($contentUserids)) { vB_Library::instance('user')->preloadUserInfo($contentUserids); // Add online status require_once DIR . '/includes/functions_bigthree.php'; // we just preloaded this info, so there must be a cache hit $cached = $fastCache->read($needOnlineStatus); $loadedSigPerm = array(); foreach ($results as $key => $record) { if ($record['userid'] == 0) { continue; } $cache_key = "vb_UserInfo_{$record['userid']}_{$languageid}"; $authorInfo = $cached[$cache_key]; $results[$key]['signature'] = $authorInfo['signature']; if (!empty($authorInfo['signature'])) { if (empty($loadedSigPerm[$record['userid']])) { $loadedSigPerm[$record['userid']] = vB::getUserContext($record['userid'])->hasPermission('genericpermissions', 'canusesignature'); } $results[$key]['canSign'] = $loadedSigPerm[$record['userid']] ? 1 : 0; } $results[$key]['musername'] = vB_Api::instanceInternal("user")->fetchMusername($authorInfo); if (!isset($authorInfo['online'])) { fetch_online_status($authorInfo); } $results[$key]['online'] = $authorInfo['online']; $options = vB::getDatastore()->getValue('options'); if (!empty($options['postelements']) and $options['postelements'] == 4 and ($authorInfo['ipoints'] or $authorInfo['warnings'] or $authorInfo['infractions']) and ($userContext->hasPermission('genericpermissions', 'canreverseinfraction') or $userContext->hasPermission('genericpermissions', 'canseeinfraction') or $userContext->hasPermission('genericpermissions', 'cangiveinfraction') or vB::getCurrentSession()->get('userid') == $authorInfo['userid'])) { $results[$key]['postelements'] = $options['postelements']; $results[$key]['ipoints'] = $authorInfo['ipoints']; $results[$key]['warnings'] = $authorInfo['warnings']; $results[$key]['infractions'] = $authorInfo['infractions']; } } } if (!empty($needReputation)) { $cached = $cache->read($needReputation); foreach ($content as $record) { // Add userinfo for reputation - is there a cached version? if ($record['userid'] > 0 and $record['contenttypeid'] != $this->channelTypeId) { if ($cached['vBUserRep_' . $record['userid']] !== false) { $cacheitem = $cached['vBUserRep_' . $record['userid']]; $results[$record['nodeid']]['reputation'] = $cacheitem['reputation']; $results[$record['nodeid']]['showreputation'] = $cacheitem['showreputation']; $results[$record['nodeid']]['reputationlevelid'] = $cacheitem['reputationlevelid']; $results[$record['nodeid']]['reputationpower'] = $cacheitem['reputationpower']; $results[$record['nodeid']]['reputationimg'] = $cacheitem['reputationimg']; } else { $needUserRep[$record['nodeid']] = $record['userid']; } } } } //Now add reputation for any users for which we didn't have a cached value. if (!empty($needUserRep)) { $reputationLib = vB_Library::instance('reputation'); $userInfo = $this->assertor->assertQuery('user', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'userid' => $needUserRep)); $bf_misc_useroptions = vB::getDatastore()->getValue('bf_misc_useroptions'); $userReps = array(); //build the reputation information foreach ($userInfo as $authorInfo) { $userid = $authorInfo['userid']; $userReps[$userid] = array(); $userReps[$userid]['reputation'] = $authorInfo['reputation']; $userReps[$userid]['showreputation'] = $authorInfo['options'] & $bf_misc_useroptions['showreputation']; $userReps[$userid]['reputationlevelid'] = $authorInfo['reputationlevelid']; $userReps[$userid]['reputationpower'] = $reputationLib->fetchReppower($authorInfo); $userReps[$userid]['reputationimg'] = $reputationLib->fetchReputationImageInfo($authorInfo); //cache this for a day $cache->write('vBUserRep_' . $userid, $userReps[$userid], 1440, array("fUserContentChg_{$userid}", "userChg_{$userid}")); } foreach ($needUserRep as $nodeid => $userid) { if (!empty($userReps[$userid])) { foreach ($userReps[$userid] as $field => $val) { $results[$nodeid][$field] = $val; } } } } // censor textual node items vB_Library_Node::censorNodes($results); return $results; }