Esempio n. 1
0
 /**
  * Adds breadcrumb entries for all the parents of the passed node id.
  * This is inclusive of the passed node id, but excludes "home".
  * Modifies $this->breadcrumbs
  *
  * @param	int	Node ID
  * @param	bool	If true, only add the top-most parent after home, and ignore the rest.
  */
 protected function addParentNodeBreadcrumbs($nodeId, $onlyAddTopParent = false)
 {
     try {
         // obtain crumbs
         $nodeLibrary = vB_Library::instance('node');
         $nodeParents = $nodeLibrary->getNodeParents($nodeId);
         $nodeParentsReversed = array_reverse($nodeParents);
         $parentsInfo = $nodeLibrary->getNodes($nodeParentsReversed);
         $routeIds = array();
         foreach ($nodeParentsReversed as $parentId) {
             if ($parentId != 1) {
                 $routeIds[] = $parentsInfo[$parentId]['routeid'];
                 if ($onlyAddTopParent) {
                     break;
                 }
             }
         }
         vB5_Route::preloadRoutes($routeIds);
         foreach ($nodeParentsReversed as $parentId) {
             if ($parentId != 1) {
                 $this->breadcrumbs[] = array('title' => $parentsInfo[$parentId]['title'], 'url' => vB5_Route::buildUrl($parentsInfo[$parentId]['routeid']));
                 if ($onlyAddTopParent) {
                     break;
                 }
             }
         }
     } catch (vB_Exception $e) {
         // if we don't have permissions to view the channel, then skip this
     }
 }
Esempio n. 2
0
 /** gets Get info on every SG Channel
  *
  *	@param	array	Array of options to filter the info (used to show all/my groups).
  *	@param	array	Array of route info of the social group parent channel to be used for building pagination URLs.
  * 	@return mixed 	Array containing the social group channel info we need.
  */
 public function getSGInfo($options = array(), $routeInfo = array())
 {
     $response = array();
     $nodeApi = vB_Api::instanceInternal('node');
     $sgParentChannel = $this->getSGChannel();
     if (!empty($options['sgparent']) and intval($options['sgparent']) and intval($options['sgparent'] != $sgParentChannel)) {
         $sgParent = intval($options['sgparent']);
         $depth = 1;
     } else {
         $sgParent = $sgParentChannel;
         $depth = 2;
     }
     // category check
     if (!$this->isSGNode($sgParent)) {
         throw new vB_Exception_Api('invalid_sg_parent');
     }
     //Get base data
     $channelContentType = vB_Types::instance()->getContentTypeId('vBForum_Channel');
     $params = array('starter_only' => 1, 'view' => 'activity', 'depth_exact' => 1, 'nolimit' => 1);
     $queryParams = array('sgParentChannel' => $sgParent, 'depth' => $depth);
     if (!empty($options['userid'])) {
         $queryParams['userid'] = $params['userid'] = intval($options['userid']);
     }
     $page = (!empty($options['page']) and intval($options['page'])) ? intval($options['page']) : 1;
     $perpage = (!empty($options['perpage']) and intval($options['perpage'])) ? intval($options['perpage']) : 20;
     $cacheParams = array_merge($params, array('page' => $page, 'perpage' => $perpage, 'sgparent' => $sgParent, 'depth' => $depth));
     $cacheKey = 'sgResults_' . (vB::getUserContext()->fetchUserId() ? vB::getUserContext()->fetchUserId() : 0) . crc32(serialize($cacheParams));
     if ($result = vB_Cache::instance(vB_Cache::CACHE_FAST)->read($cacheKey) or !vB::getUserContext()->hasPermission('socialgrouppermissions', 'canviewgroups')) {
         //we don't cache the pagination URLs as they may vary for the same content depending on the specified routeInfo (routeId, arguments, queryParameters)
         $pageInfo = $result['pageInfo'];
         $paginationURLs = $this->buildPaginationURLs($pageInfo['currentpage'], $pageInfo['totalpages'], $routeInfo);
         if ($paginationURLs) {
             $pageInfo = array_merge($pageInfo, $paginationURLs);
             $result['pageInfo'] = $pageInfo;
         }
         return $result;
     }
     $nodeContent = $nodeApi->listNodeContent($sgParent, $page, $perpage, $depth, $channelContentType, $params);
     $totalCount = vB::getDbAssertor()->getRow('vBForum:getSocialGroupsTotalCount', $queryParams);
     //We need the nodeids to collect some data
     $cacheEvents = array('nodeChg_' . $sgParent);
     $lastids = array();
     $lastNodes = array();
     $channelids = array();
     $categories = array();
     $contributorIds = array();
     $sgCategories = array_keys($this->getCategories());
     $sgParentChannel = $this->getSGChannel();
     foreach ($nodeContent as $key => $node) {
         if ($node['parentid'] == $sgParentChannel) {
             $categories[] = $node['nodeid'];
             unset($nodeContent[$node['nodeid']]);
         } else {
             if ($node['lastcontentid'] > 0) {
                 $lastids[] = $node['lastcontentid'];
             }
             if (in_array($node['parentid'], $sgCategories)) {
                 $categories[] = $node['parentid'];
             }
             $channelids[] = $node['nodeid'];
             $contributorIds[] = $node['userid'];
             $cacheEvents[] = 'nodeChg_' . $node['nodeid'];
         }
     }
     $categories = array_unique($categories);
     if (empty($channelids)) {
         //for display purposes, we set totalpages to 1 even if there are no records because we don't want the UI to display Page 1 of 0
         $result = array('results' => array(), 'totalcount' => 0, 'pageInfo' => array('currentpage' => $page, 'perpage' => $perpage, 'nexturl' => '', 'prevurl' => '', 'totalpages' => 1, 'totalrecords' => 0, 'sgparent' => $sgParent));
         vB_Cache::instance(vB_Cache::CACHE_FAST)->write($cacheKey, $result, 60, array_unique($cacheEvents));
         return $result;
     }
     $mergedNodes = vB_Library::instance('node')->getNodes($lastids + $categories);
     foreach ($lastids as $lastid) {
         if (empty($mergedNodes[$lastid])) {
             continue;
         }
         $lastNodes[$lastid] = $mergedNodes[$lastid];
     }
     foreach ($categories as $category) {
         if (empty($mergedNodes[$category])) {
             continue;
         }
         $categoriesInfo[$category] = $mergedNodes[$category];
     }
     // update category info
     foreach ($nodeContent as $key => $node) {
         // add category info
         if (isset($categoriesInfo[$node['parentid']])) {
             $nodeContent[$key]['content']['channeltitle'] = $categoriesInfo[$node['parentid']]['title'];
             $nodeContent[$key]['content']['channelroute'] = $categoriesInfo[$node['parentid']]['routeid'];
             $cacheEvents[] = 'nodeChg_' . $node['parentid'];
         }
     }
     $lastTitles = $lastInfo = array();
     $lastIds = array();
     foreach ($lastNodes as $lastnode) {
         $lastInfo[$lastnode['nodeid']]['starter'] = $lastnode['starter'];
         if ($lastnode['starter'] == $lastnode['nodeid']) {
             $lastInfo[$lastnode['nodeid']]['title'] = $lastnode['title'];
             $lastInfo[$lastnode['nodeid']]['routeid'] = $lastnode['routeid'];
             $contributorIds[] = $lastnode['userid'];
         } else {
             //We need another query
             $lastIds[$lastnode['starter']] = $lastnode['starter'];
         }
     }
     //Now get any lastcontent starter information we need
     if (!empty($lastIds)) {
         $nodes = vB_Library::instance('node')->getNodes($lastIds);
         foreach ($nodeContent as $index => $channel) {
             $nodeid = $lastInfo[$channel['lastcontentid']]['starter'];
             if (isset($nodes[$nodeid])) {
                 $node =& $nodes[$nodeid];
                 $lastInfo[$channel['lastcontentid']]['routeid'] = $node['routeid'];
                 $lastInfo[$channel['lastcontentid']]['title'] = $node['title'];
             }
         }
     }
     if (!empty($options['contributors'])) {
         //Get contributors
         $groups = vB::getDbAssertor()->getColumn('vBForum:usergroup', 'usergroupid', array('systemgroupid' => array(vB_Api_UserGroup::CHANNEL_MODERATOR_SYSGROUPID, vB_Api_UserGroup::CHANNEL_MEMBER_SYSGROUPID, vB_Api_UserGroup::CHANNEL_OWNER_SYSGROUPID)), false, 'systemgroupid');
         $membersQry = vB::getDbAssertor()->assertQuery('vBForum:groupintopic', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'nodeid' => $channelids, 'groupid' => $groups));
         $groupManagers = array();
         $contributors = array();
         foreach ($membersQry as $record) {
             if ($record['groupid'] == $groups[vB_Api_UserGroup::CHANNEL_MODERATOR_SYSGROUPID]) {
                 $groupManagers[] = $record;
             }
             $contributorIds[$record['userid']] = $record['userid'];
             $cacheEvents[] = 'sgMemberChg_' . $record['userid'];
         }
         $userApi = vB_Api::instanceInternal('user');
         $avatarInfo = vB_Api::instanceInternal('user')->fetchAvatars($contributorIds);
         foreach ($groupManagers as $index => $contributor) {
             if (!isset($contributors[$contributor['nodeid']])) {
                 $contributors[$contributor['nodeid']] = array();
             }
             $userInfo = $userApi->fetchUserinfo($contributor['userid']);
             $contributors[$contributor['nodeid']][$contributor['userid']] = $userInfo;
             $contributors[$contributor['nodeid']][$contributor['userid']]['avatar'] = $avatarInfo[$contributor['userid']];
         }
     }
     // Obtain keys for sg pages
     $pageKeyInfo = array();
     $routes = vB::getDbAssertor()->getRows('routenew', array('class' => 'vB5_Route_Channel', 'contentid' => $channelids), false, 'routeid');
     vB5_Route::preloadRoutes(array_keys($routes));
     foreach ($routes as $record) {
         $route = vB5_Route_Channel::getRoute($record['routeid'], @unserialize($record['arguments']));
         if ($route and $pageKey = $route->getPageKey()) {
             $pageKeyInfo[$pageKey] = $record['contentid'];
         }
     }
     $viewingQry = vB::getDbAssertor()->getRows('session', array(vB_dB_Query::TYPE_KEY => vB_dB_Query::QUERY_SELECT, 'pagekey' => array_keys($pageKeyInfo)));
     $viewing = array();
     foreach ($viewingQry as $viewingUser) {
         if (!isset($viewing[$viewingUser['nodeid']])) {
             $viewing[$viewingUser['nodeid']] = 0;
         }
         $viewing[$viewingUser['nodeid']]++;
     }
     // get the members count
     $countRecords = vB::getDbAssertor()->assertQuery('vBForum:getChannelMembersCount', array('nodeid' => $channelids, 'groupid' => $groups));
     $membersCount = array();
     foreach ($countRecords as $count) {
         $membersCount[$count['nodeid']] = $count;
     }
     foreach ($nodeContent as $index => $channel) {
         $nodeid = $channel['nodeid'];
         if (!empty($options['contributors'])) {
             $nodeContent[$index]['contributors'] = !empty($contributors[$nodeid]) ? $contributors[$nodeid] : 0;
             $nodeContent[$index]['contributorscount'] = !empty($contributors[$nodeid]) ? count($contributors[$nodeid]) : 0;
         }
         $nodeContent[$index]['members'] = !empty($membersCount[$nodeid]) ? $membersCount[$nodeid]['members'] : 0;
         $nodeContent[$index]['viewing'] = !empty($viewing[$nodeid]) ? $viewing[$nodeid] : 0;
         $nodeContent[$index]['lastposttitle'] = !empty($lastInfo[$channel['lastcontentid']]['title']) ? $lastInfo[$channel['lastcontentid']]['title'] : 0;
         $nodeContent[$index]['lastpostrouteid'] = !empty($lastInfo[$channel['lastcontentid']]['routeid']) ? $lastInfo[$channel['lastcontentid']]['routeid'] : 0;
         $nodeContent[$index]['owner_avatar'] = $avatarInfo[$nodeContent[$index]['userid']];
         $nodeContent[$index]['lastauthor_avatar'] = $avatarInfo[$nodeContent[$index]['lastauthorid']];
     }
     $total = $totalCount['totalcount'];
     if ($total > 0) {
         $pages = ceil($total / $perpage);
     } else {
         $pages = 1;
         //we don't want the UI to display Page 1 of 0
     }
     $pageInfo = array('currentpage' => $page, 'perpage' => $perpage, 'prevurl' => '', 'nexturl' => '', 'totalpages' => $pages, 'totalrecords' => $total, 'sgparent' => $sgParent);
     $result = array('results' => $nodeContent, 'totalcount' => count($nodeContent), 'pageInfo' => $pageInfo);
     vB_Cache::instance(vB_Cache::CACHE_FAST)->write($cacheKey, $result, 60, array_unique($cacheEvents));
     //we don't cache the pagination URLs as they may vary for the same content depending on the specified routeInfo (routeId, arguments, queryParameters)
     $paginationURLs = $this->buildPaginationURLs($page, $pages, $routeInfo);
     if ($paginationURLs) {
         $pageInfo = array_merge($pageInfo, $paginationURLs);
         $result['pageInfo'] = $pageInfo;
     }
     return $result;
 }
Esempio n. 3
0
 /**
  * 	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;
 }
Esempio n. 4
0
 /** Preloads a list of routes to reduce database traffic
  *
  * @param	mixed	array of route ids- can be integers or strings.
  **/
 public function preloadRoutes($routeIds)
 {
     return vB5_Route::preloadRoutes($routeIds);
 }