/** * Fetches views from aggregated content. * Uses a minimum set of collections to fetch the required info for the content * types specified. * * @param int $viewtype - The viewtype to aggregate * @return array vB_View */ protected function aggregateContent($viewtype = self::VIEW_PREVIEW, &$page_info = null) { if ((self::VIEW_AGGREGATE != $viewtype) AND (self::VIEW_PREVIEW != $viewtype) AND (self::VIEW_PAGE != $viewtype)) { throw (new vB_Exception_Content('Viewtype specified for section aggregation is not valid: \'' . htmlspecialchars($viewtype) . '\'')); } $this->config = $this->content->getConfig(); // Only filter to published if section is published and user can't edit $filter_published = ($this->content->isPublished() AND (!$this->content->canEdit() AND !$this->content->canCreate())); $aggregate = new vBCms_Collection_Content_Section(); $aggregate->requireInfo(vB_Model::QUERY_BASIC); $filter_node = $this->content->getIncludeChildren(); //If this is a hidden section we ignore the hidden flag. Otherwise we don't show //hidden articles. $aggregate->setFilterHidden = (!$this->content->getHidden()); if (!$this->config['pagination_links'] OR $this->config['simple_paging']) { $aggregate->setCount(false); } //This changes depending on whether we are displaying an edit or view page; if ($this->editing) { if (!$filter_node) { $aggregate->setFilterNodeExact($this->content->getNodeId()); } else { $aggregate->filterNode($this->content->getNodeId()); } } else //We're in view mode { //And what content to show. If the setting is 2, then that means show // subsection content. Otherwise only the section will show. if ($this->config['contentfrom'] != 2) { $aggregate->setFilterNodeExact($this->content->getNodeId()); } else { $aggregate->filterNode($this->content->getNodeId()); } $aggregate->setIncludepreview(true); } $aggregate->filterPublished($filter_published); $aggregate->requireInfo(vBCms_Item_Content::INFO_BASIC | vBCms_Item_Content::INFO_NODE); if ($this->canPublish()) { $aggregate->filterVisible(false); } if (!intval($this->config['section_priority']) OR (intval($this->config['section_priority'])> 20) ) { $this->config['section_priority'] = 1; } // Let's set the order. $aggregate->setOrderBy($this->config['section_priority']); if (!intval($this->config['items_perhomepage']) OR (intval($this->config['items_perhomepage'])> 20) ) { $this->config['items_perhomepage'] = 7; } $aggregate->paginate(); $aggregate->paginateQuantity(intval($this->config['items_perhomepage'])); if ($this->config['simple_paging']) { $aggregate->setMaxRecords(10 * $this->config['items_perhomepage']); } if ($this->editing) { $aggregate->paginatePage(1); $this->current_page = 1; } else { //what page are we rendering? vB::$vbulletin->input->clean_array_gpc('r', array('page' => TYPE_INT )); $this->current_page = (vB::$vbulletin->GPC_exists['page'] AND intval(vB::$vbulletin->GPC['page'])) ? vB::$vbulletin->GPC['page'] : 1; $aggregate->paginatePage($this->current_page); } $results = array(); // If we only need the aggregate view then we don't need to get specific collections if (self::VIEW_AGGREGATE == $viewtype) { // get info flags for generic aggregate view $aggregate->requireInfo($this->getViewInfoFlags(self::VIEW_AGGREGATE)); if (!$aggregate->getShown() AND $aggregate->getTotal()) { throw (new vB_Exception_404()); } $rawcount = $aggregate->getTotal(); foreach ($aggregate AS $id => $content) { // get the content controller $controller = vB_Types::instance()->getContentTypeController($content->getContentTypeId(), $content); // set preview length $controller->setPreviewLength(400); // get the aggregate view from the controller $results[$id] = $controller->getAggregateView(); if ($this->config['simple_paging'] AND count($results) >= intval($this->config['items_perhomepage']) ) { break; } } } else { // Aggregated collection info for individual contenttypes. $collection_infos = array(); // Individual content controllers $controllers = array(); // Check that there were results for the selected page if (!$aggregate->getShown() AND $aggregate->getTotal()) { throw (new vB_Exception_404()); } // Get the individual collections required for each contenttype foreach ($aggregate AS $id => $content) { if ($this->config['simple_paging'] AND count($results) >= intval($this->config['items_perhomepage']) ) { break; } // save an ordered space for the result $results[$id] = true; // get a controller for the specific type $controllers[$id] = vB_Types::instance()->getContentTypeController($content->getContentTypeId(), $content); // get required info flags for a preview $info_flags = $controllers[$id]->getViewInfoFlags(self::VIEW_PREVIEW); // get the appropriate collection class required for the preview $collection_class = $controllers[$id]->getCollectionClass($info_flags); // create the collection if (!isset($collection_infos[$collection_class])) { $collection_infos[$collection_class] = array(); } // don't use the same collection where the required info differs if (!isset($collection_infos[$collection_class][$info_flags])) { $collection_infos[$collection_class][$info_flags] = array('collection' => new $collection_class, 'items' => array()); } // add loaded content item to appropriate collection based on the class and required info $collection_infos[$collection_class][$info_flags]['items'][$id] = $content; } if (!sizeof($collection_infos)) { return false; } vBCMS_Permissions::loadPermissionsfrom(array_keys($results)); $nodeids = array(); foreach ($collection_infos AS $collection_info) { foreach ($collection_info AS $info_flags => $collection_objects) { // add the loaded items to the collection $collection_objects['collection']->setCollection($collection_objects['items'], $aggregate->getLoadedInfoFlags()); // require the rich preview info $collection_objects['collection']->requireInfo($info_flags); foreach ($collection_objects['collection'] AS $id => $item) { $nodeids[] = $id; if (count($results) > $this->config['items_perhomepage']) { break; } } } } // get the views from the unique collections foreach ($collection_infos AS $collection_info) { foreach ($collection_info AS $info_flags => $collection_objects) { // add the loaded items to the collection $collection_objects['collection']->setCollection($collection_objects['items'], $aggregate->getLoadedInfoFlags()); // require the rich preview info $collection_objects['collection']->requireInfo($info_flags); // get the final item views foreach ($collection_objects['collection'] AS $id => $item) { if (isset($results[$id])) { // set preview length $controllers[$id]->setPreviewLength(400); // theoretically the updated item should already be assigned to it's controller if (!($results[$id] = $controllers[$id]->getPreview($this->config['preview_length']))) { unset($results[$id]); } } } } } } return array('aggregate' => $aggregate, 'results' => $results) ; }
/** * Prepares the navbar view so that it can be fetched and rendered. * Note: Forcing the cache to be ignored is useful if the subnav has just been * updated. * * @param vBCms_Item_Content $node - The current node * @param bool $refresh - Forces the cache to be ignored and the view to be rebuilt. */ public static function prepareNavBar($node = false, $refresh = false) { // Normalize node $node = ($node ? $node : 1); if (!$node instanceof vBCms_Item_Content) { $node = new vBCms_Item_Content($node, vBCms_Item_Content::INFO_NAVIGATION); } $cache_key = self::getHash($node); if ($refresh OR !$navnodes = vB_Cache::instance()->read($cache_key, false, true)) { //The query to pull the navigation requires that the //parent information be available $node->requireInfo(vBCms_Item_Content::INFO_PARENTS); $node->isValid(); $node->requireInfo(vBCms_Item_Content::INFO_NAVIGATION); if ($navnodes = $node->getNavigationNodes()) { // get collection $collection = new vBCms_Collection_Content($navnodes, vBCms_Item_Content::INFO_NODE | vBCms_Item_Content::INFO_PARENTS); $collection->filterVisible(false); // check count if (!$collection->isValid()) { return false; } // set original ids as keys $navnodes = array_flip($navnodes); // remap order foreach ($collection AS $navnode) { $navnodes[$navnode->getNodeId()] = $navnode; } unset($collection); // remove unfound entries foreach ($navnodes AS $id => $navnode) { if (!$navnode instanceof vBCms_Item_Content) { unset($navnodes[$id]); } } // write cache vB_Cache::instance()->write( $cache_key, $navnodes, self::$cache_ttl, array( self::getCacheEventId($node->getNavigationNode()), self::GLOBAL_CACHE_EVENT, self::GLOBAL_SECTION_CACHE_EVENT ) ); } } if (is_array($navnodes) AND !empty($navnodes)) { $perms_load = array(); foreach($navnodes as $navnode) { $perms_load[] = $navnode->getNodeId(); } vBCMS_Permissions::loadPermissionsfrom(array_keys($perms_load)); } // create navlinks for published nodes $links = array(); $route = new vBCms_Route_Content(); foreach ((array)$navnodes AS $navnode) { if ($navnode->isPublished() AND $navnode->canView()) { $route->node = $navnode->getUrlSegment(); $links[] = array( 'title' => $navnode->getTitle(), 'url' => $route->getCurrentUrl() ); } } if (!self::$view OR $refresh) { self::$view = new vB_View('vbcms_navbar_link'); self::$view->links = $links; } }