/** * Gets an array of controllers for a collection. * * @param vBCms_Collection_Content $content - The content to fetch controllers for * @param bool $skip_errors - Whether to skip content that throws exceptions * @return array vBCms_Content - Array of content controllers. */ public static function getControllers(vBCms_Collection_Content $collection, $skip_errors = true) { $controllers = array(); if (!$collection->isValid()) { return $controllers; } foreach ($collection AS $id => $content) { try { $controller = self::create($content->getPackage(), $content->getClass(), $content); } catch (vB_Exception $e) { if (!$skip_errors OR $e->isCritical()) { throw ($e); } continue; } $controllers[$content->getId()] = $controller; } return $controllers; }
/** * Fetches the SQL for loading. * $required_query is used to identify which query to build for classes that * have multiple queries for fetching info. * * This can safely be based on $this->required_info as long as a consitent * flag is used for identifying the query. * * @param int $required_query - The required query * @param bool $force_rebuild - Whether to rebuild the string * * @return string */ protected function getLoadQuery($required_query = self::QUERY_BASIC, $force_rebuild = false) { // Hooks should check the required query before populating the hook vars $hook_query_fields = $hook_query_joins = $hook_query_where = ''; ($hook = vBulletinHook::fetch_hook($this->query_hook)) ? eval($hook) : false; if (self::QUERY_BASIC == $required_query) { if (! isset(vB::$vbulletin->userinfo['permissions']['cms'])) { vBCMS_Permissions::getUserPerms(); } $extrasql = '' ; $permissionstring = "( (" . vBCMS_Permissions::getPermissionString() . ($this->filter_includepreview ? ") OR (node.setpublish AND node.publishdate <" . TIMENOW . " AND node.publicpreview > 0" : '' ) . "))" ; if (!$this->sortby) { if ($this->orderby == 3) { $extrasql = " INNER JOIN (SELECT parentnode, MAX(lastupdated) AS lastupdated FROM " . TABLE_PREFIX . "cms_node AS node WHERE contenttypeid <> " . vb_Types::instance()->getContentTypeID("vBCms_Section") . " AND " . vBCMS_Permissions::getPermissionString() . " GROUP BY parentnode ) AS ordering ON ordering.parentnode = node.parentnode AND node.lastupdated = ordering.lastupdated WHERE 1=1"; $this->sortby = " ORDER BY node.setpublish DESC, node.publishdate DESC "; } else if ($this->orderby == 2) { $this->sortby = " ORDER BY node.publishdate DESC "; } else if ($this->orderby == 4) { $this->sortby = " ORDER BY info.title ASC "; } else if ($this->orderby == 5) { $this->sortby = " ORDER BY sectionorder.displayorder ASC "; } else { $this->sortby = " ORDER BY CASE WHEN sectionorder.displayorder > 0 THEN sectionorder.displayorder ELSE 9999999 END ASC, node.publishdate DESC"; } } //We need a nodeid for the displayorder below if ($this->filter_node_exact AND !$this->filter_node ) { $this->filter_node = $this->filter_node_exact; } //enforce the max_records limits if ($this->max_records) { $this->paginate = true; if (!$this->start) { $this->start = 0; } $this->quantity = $this->max_records; } $sql = "SELECT " . ($this->count_records ? 'SQL_CALC_FOUND_ROWS': '') . " node.nodeid AS itemid, (node.nodeleft = 1) AS isroot, node.nodeid, node.contenttypeid, node.contentid, node.url, node.parentnode, node.styleid, node.userid, node.layoutid, node.publishdate, node.setpublish, node.issection, parent.permissionsfrom as parentpermissions, node.permissionsfrom, node.publicpreview, node.showtitle, node.showuser, node.showpreviewonly, node.showall, node.showupdated, node.showviewcount, node.showpublishdate, node.settingsforboth, node.includechildren, node.editshowchildren, node.shownav, node.hidden, node.nosearch, node.nodeleft, info.description, info.title, info.html_title, info.viewcount, info.creationdate, info.workflowdate, info.workflowstatus, info.workflowcheckedout, info.workflowlevelid, info.associatedthreadid, user.username, sectionorder.displayorder, thread.replycount, parentinfo.title AS parenttitle $hook_query_fields FROM " . TABLE_PREFIX . "cms_node AS node INNER JOIN " . TABLE_PREFIX . "cms_nodeinfo AS info ON info.nodeid = node.nodeid $hook_query_join LEFT JOIN " . TABLE_PREFIX . "user AS user ON user.userid = node.userid LEFT JOIN " . TABLE_PREFIX . "thread AS thread ON thread.threadid = info.associatedthreadid LEFT JOIN " . TABLE_PREFIX . "cms_sectionorder AS sectionorder ON sectionorder.sectionid = " . intval($this->filter_node) ." AND sectionorder.nodeid = node.nodeid LEFT JOIN " . TABLE_PREFIX . "cms_node AS parent ON parent.nodeid = node.parentnode LEFT JOIN " . TABLE_PREFIX . "cms_nodeinfo AS parentinfo ON parentinfo.nodeid = parent.nodeid " . (intval($this->filter_node) ? " INNER JOIN " . TABLE_PREFIX . "cms_node AS rootnode ON rootnode.nodeid = " . intval($this->filter_node) . " AND (node.nodeleft >= rootnode.nodeleft AND node.nodeleft <= rootnode.noderight) AND node.nodeleft != rootnode.nodeleft " : '') . $extrasql . " AND node.contenttypeid <> " . vb_Types::instance()->getContentTypeID("vBCms_Section") . " AND node.new != 1 " . ($this->itemid ? "AND node.nodeid IN (" . implode(',', $this->itemid) . ") " : '') . ($this->filter_contenttype ? "AND node.contenttypeid = " . intval($this->filter_contenttype) . " " : '') . ($this->filter_contentid ? "AND node.contentid = " . intval($this->contentid) . " ": '') . ($this->filter_nosections ? "AND node.issection != '1' " : '') . ($this->filter_onlysections ? "AND node.issection = '1' " : '') . ($this->filter_ignorepermissions ? '' : " AND " . $permissionstring) . ($this->filter_userid ? "AND node.userid = " . intval($this->filter_userid) . " " : '') . ($this->visible_only ? "AND node.hidden = 0 " : '') . ($this->filter_published ? "AND node.setpublish = '1' AND node.publishdate <= " . intval(TIMENOW) . " " : '') . ($this->filter_unpublished ? "AND node.setpublish = '0' OR node.publishdate > " . intval(TIMENOW) . " " : '') . " " . $this->getFilterNotContentTypeSql() . (intval($this->filter_node_exact) ? "AND (node.parentnode = " . $this->filter_node_exact . " OR sectionorder.displayorder > 0 )": '') . (($this->orderby == 5) ? " AND sectionorder.displayorder > 0 " : '') . " $content_query_where $hook_query_where " . $this->sortby . ( ($this->paginate AND intval($this->quantity)) ? (" LIMIT " . intval($this->start) . ', ' . intval($this->quantity)) : '') ; return $sql; } else { return parent::getLoadQuery(); } }
public function actionList($page_url) { //This is an aggregator. We can pull in three different modes as of this writing, // and we plan to add more. We can have passed on the url the following: // author=id, category=id, section=id, and format=id. "Format" should normally // be passed as for author only, and it defines a sectionid to be used for the format. global $vbphrase; //Load cached values as appropriate $metacache_key = 'vbcms_list_data_' . implode('_', $this->segments); vB_Cache::instance()->restoreCacheInfo($metacache_key); // Create the page view $view = new vB_View_Page('vbcms_page'); $view->page_url = $page_url; $view->base_url = VB_URL_BASE_PATH; $view->html_title = $this->title; $this->content = vBCms_Content::create('vBCms', 'Section', $this->displaysectionid); $sectionnode = new vBCms_Item_Content($this->displaysectionid, vBCms_Item_Content::INFO_CONFIG) ; //There are configuration settings on the section for items per page and // section layout. If they are set let's use them. First items per page. $this->config = $sectionnode->getConfig(); if (isset($this->config['items_perhomepage']) AND intval($this->config['items_perhomepage'])) { $this->perpage = $this->config['items_perhomepage']; } // Get layout $this->layout = new vBCms_Item_Layout($this->layoutid); $this->layout->requireInfo(vBCms_Item_Layout::INFO_CONFIG | vBCms_Item_Layout::INFO_WIDGETS); // Create the layout view $layout = new vBCms_View_Layout($this->layout->getTemplate()); $layout->contentcolumn = $this->layout->getContentColumn(); $layout->contentindex = $this->layout->getContentIndex(); // Get content controller $collection = new vBCms_Collection_Content(); $collection->setContentQueryWhere($this->query_filter . " AND node.contenttypeid <> " . vB_Types::instance()->getContentTypeID("vBCms_Section") ); $collection->setContentQueryJoins($this->joins); vB::$vbulletin->input->clean_array_gpc('r', array('page' => TYPE_INT)); if ((vB::$vbulletin->GPC_exists['page'] AND intval(vB::$vbulletin->GPC['page']))) { $current_page = intval(vB::$vbulletin->GPC['page']); } elseif (intval($this->segments['page'])) { $current_page = intval($this->segments['page']); } else { $current_page = 1; } $collection->paginate(); $collection->paginateQuantity($this->perpage); $collection->paginatePage($current_page); $results = array(); // Get the content view //Our templates assume a counter beginning at one, not zero. $counter = 0; foreach($collection as $id => $content) { //make sure we've loaded all the information we need $content->requireInfo(vBCms_Item_Content::INFO_NODE | vBCms_Item_Content::INFO_CONTENT | vBCms_Item_Content::INFO_PARENTS); // 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 if ($result = $controller->getPreview()) { $counter++; $results[$counter] = $result; } } $recordcount = $collection->getCount(); $contentview->contenttypeid = vB_Types::instance()->getContentTypeID("vBCms_Section"); $contentview->contentid = $contentview->item_id = $contentview->nodeid = $this->displaysectionid; $contentview = new vB_View_Content('vbcms_content_list'); $contentview->package = 'vBCms'; $contentview->class = 'Section'; $contentview->result_type = $this->result_type; $contentview->rawtitle = $this->title; $contentview->title = $this->title; $contentview->current_page = $current_page; if (! $recordcount) { switch($this->segments['type']){ case 'author': $contentview->contents = array(1 => new vB_Phrase('vbcms', 'no_content_for_author_x', $this->title )); break; case 'section': $contentview->contents = array(1 => new vB_Phrase('vbcms', 'no_content_for_section_x', $this->title )); break; case 'category': $contentview->contents = array(1 => new vB_Phrase('vbcms', 'no_content_for_category_x', $this->title )); break; ; } // switch } else { if (isset($this->config['content_layout']) AND intval($this->config['content_layout']) AND (intval($this->config['content_layout']) < 7)) { $content_rendered = new vb_View('vbcms_content_section_type' . intval($this->config['content_layout'])); $content_rendered->contents = $results; $content_rendered->result_count = $counter; $contentview->content_rendered = $content_rendered; } else { $contentview->contents = $results; } if (intval($recordcount) > intval($this->perpage)) { $baseurl = vB_Route::create('vBCms_Route_List', $this->segments['type'] . '/' . intval($this->segments['value']) . ($this->urlstring == '' ? '' : '-' . $this->urlstring) . '/')->getCurrentURL(); $contentview->pagenav = construct_page_nav($current_page, $this->perpage, $recordcount, $baseurl); } else { $contentview->pagecount = 1; } } $layout->content = $contentview; // Get widget locations $layout->widgetlocations = $this->layout->getWidgetLocations(); if (count($layout->widgetlocations)) { $widgetids = $this->layout->getWidgetIds(); if (count($widgetids)) { // Get Widgets $widgets = vBCms_Widget::getWidgetCollection($widgetids, vBCms_Item_Widget::INFO_CONFIG, $this->displaysectionid); $widgets = vBCms_Widget::getWidgetControllers($widgets, true, $this->content); // Get the widget views $widget_views = array(); foreach($widgets AS $widgetid => $widget) { try { $widget_views[$widgetid] = $widget->getPageView(); } catch (vB_Exception $e) { if ($e->isCritical()) { throw ($e); } if (vB::$vbulletin->debug) { $widget_views[$widgetid] = 'Exception: ' . $e; } } } // Assign the widgets to the layout view $layout->widgets = $widget_views; } } // Assign the layout view to the page view $view->layout = $layout; // Add general page info $view->setPageTitle($this->content->getTitle()); $view->pagedescription = $this->content->getDescription(); $this->resolveWolPath(); vB_Cache::instance()->saveCacheInfo($metacache_key); // Render view and return return $view->render(); }
/** * 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; } }