/** * Display the XML sitemap * @access public * @return void */ function display($tpl = null) { $document = $this->document; $document->setMimeEncoding('application/xml'); $session = JFactory::getSession(); // Call by cache handler get no params, so recover from model state if (!$tpl) { $tpl = $this->getModel()->getState('documentformat'); } $this->data = $this->get('SitemapData'); $this->cparams = $this->getModel()->getState('cparams'); // Transport wrapper $this->HTTPClient = new JMapHttp(null, $this->cparams); $this->outputtedLinksBuffer = array(); // Reload $this->outputtedVideosBuffer from previous session if process_status === run, AKA an ongoing JS AJAX precaching is running $this->outputtedVideosBuffer = $this->app->input->get('process_status', null) === 'run' ? $session->get('com_jmap.videos_buffer') : array(); $this->application = JFactory::getApplication(); $this->xslt = $this->getModel()->getState('xslt'); $this->videoApisEndpoints = array('youtube' => 'https://gdata.youtube.com/feeds/api/videos/%s?v=2&alt=json', 'vimeo' => 'http://vimeo.com/api/v2/video/%s.json', 'dailymotion' => 'https://api.dailymotion.com/video/%s?fields=title,duration,description,thumbnail_360_url'); $uriInstance = JURI::getInstance(); $customHttpPort = trim($this->cparams->get('custom_http_port', '')); $getPort = $customHttpPort ? ':' . $customHttpPort : ''; $customDomain = trim($this->cparams->get('custom_sitemap_domain', '')); $getDomain = $customDomain ? rtrim($customDomain, '/') : rtrim($uriInstance->getScheme() . '://' . $uriInstance->getHost(), '/'); if ($this->cparams->get('append_livesite', true)) { $this->liveSite = rtrim($getDomain . $getPort, '/'); } else { $this->liveSite = null; } // Crawler live site management if ($this->cparams->get('sh404sef_multilanguage', 0) && JMapLanguageMultilang::isEnabled()) { $lang = '/' . $this->app->input->get('lang'); // Check if sh404sef insert language code param is off, otherwise the result would be doubled language chunk in liveSiteCrawler $sh404SefParams = JComponentHelper::getParams('com_sh404sef'); if ($sh404SefParams->get('shInsertLanguageCode', 0) || !$sh404SefParams->get('Enabled', 1)) { $lang = null; } $this->liveSiteCrawler = rtrim($getDomain . $getPort . $lang, '/'); } else { $this->liveSiteCrawler = rtrim($getDomain . $getPort, '/'); } // Add include path $this->addTemplatePath(JPATH_COMPONENT . '/views/sitemap/tmpl/videos'); $this->setLayout('default'); parent::display($tpl); // Assign $this->outputtedVideosBuffer for next session if process_status == start/run if (in_array($this->app->input->get('process_status', null), array('start', 'run'))) { $session->set('com_jmap.videos_buffer', $this->outputtedVideosBuffer); } // Delete $this->outputtedVideosBuffer session if process_status == end if ($this->app->input->get('process_status', null) === 'end') { $session->clear('com_jmap.videos_buffer'); } }
/** * Display the XML sitemap * @access public * @return void */ function display($tpl = null) { $document = $this->document; $document->setMimeEncoding('application/xml'); // Call by cache handler get no params, so recover from model state if (!$tpl) { $tpl = $this->getModel()->getState('documentformat'); } $this->data = $this->get('SitemapData'); $this->cparams = $this->getModel()->getState('cparams'); // Transport wrapper $this->HTTPClient = new JMapHttp(null, $this->cparams); $this->outputtedLinksBuffer = array(); $this->application = JFactory::getApplication(); $this->xslt = $this->getModel()->getState('xslt'); // Set regex for the images crawler $this->mainImagesRegex = $this->cparams->get('regex_images_crawler', 'advanced') == 'standard' ? '/(<img)([^>])*(src=["\']([^"\']+)["\'])([^>])*/i' : '/(<img)([^>])*(src=["\']?([^"\']+\\.(jpg|jpeg|gif|png))["\']?)([^>])*/i'; $uriInstance = JURI::getInstance(); $customHttpPort = trim($this->cparams->get('custom_http_port', '')); $getPort = $customHttpPort ? ':' . $customHttpPort : ''; $customDomain = trim($this->cparams->get('custom_sitemap_domain', '')); $getDomain = $customDomain ? rtrim($customDomain, '/') : rtrim($uriInstance->getScheme() . '://' . $uriInstance->getHost(), '/'); if ($this->cparams->get('append_livesite', true)) { $this->liveSite = rtrim($getDomain . $getPort, '/'); } else { $this->liveSite = null; } // Crawler live site management if ($this->cparams->get('sh404sef_multilanguage', 0) && JMapLanguageMultilang::isEnabled()) { $lang = '/' . $this->app->input->get('lang'); // Check if sh404sef insert language code param is off, otherwise the result would be doubled language chunk in liveSiteCrawler $sh404SefParams = JComponentHelper::getParams('com_sh404sef'); if ($sh404SefParams->get('shInsertLanguageCode', 0) || !$sh404SefParams->get('Enabled', 1)) { $lang = null; } $this->liveSiteCrawler = rtrim($getDomain . $getPort . $lang, '/'); } else { $this->liveSiteCrawler = rtrim($getDomain . $getPort, '/'); } $this->setLayout('default'); parent::display($tpl); }
} $additionalQueryStringParams = trim($additionalQueryStringParams, ','); if ($additionalQueryStringParams) { $additionalQueryStringParams = '&' . preg_replace('/,\\s*/i', '&', $additionalQueryStringParams); $additionalQueryStringParams = preg_replace('/\\s+/i', '', $additionalQueryStringParams); } $targetOption = $this->source->chunks->option; $targetViewName = $this->sourceparams->get('view', null); $targetView = $targetViewName ? '&view=' . $targetViewName : null; // Supported adapters for Router Helper $supportedRouterHelperAdapters = array('com_k2' => false, 'com_easyblog' => false, 'com_contact' => false, 'com_weblinks' => false, 'com_newsfeeds' => false, 'com_hwdmediashare' => false, 'com_eventbooking' => false, 'com_edocman' => false, 'com_phocadownload' => false, 'com_ezrealty' => false, 'com_iproperty' => false, 'com_djcatalog2' => false, 'com_jomestate' => false, 'com_eshop' => false, 'com_jomdirectory' => false); $supportedRouterHelperAdaptersPaths = array('com_eventbooking' => 'helper', 'com_edocman' => 'helper'); $supportedRouterHelperAdaptersFiles = array('com_easyblog' => 'router'); // Adapter for com_eshop if ($targetOption == 'com_eshop') { if (version_compare(JVERSION, '3.0', 'ge') && JMapLanguageMultilang::isEnabled()) { $supportedRouterHelperAdaptersFiles['com_eshop'] = 'routev3'; } } if (array_key_exists($targetOption, $supportedRouterHelperAdapters)) { $folderPath = array_key_exists($targetOption, $supportedRouterHelperAdaptersPaths) ? $supportedRouterHelperAdaptersPaths[$targetOption] : 'helpers'; $filePath = array_key_exists($targetOption, $supportedRouterHelperAdaptersFiles) ? $supportedRouterHelperAdaptersFiles[$targetOption] : 'route'; if (file_exists(JPATH_SITE . '/components/' . $targetOption . '/' . $folderPath . '/' . $filePath . '.php')) { include_once JPATH_SITE . '/components/' . $targetOption . '/' . $folderPath . '/' . $filePath . '.php'; $supportedRouterHelperAdapters[$targetOption] = true; $liveSite = $this->liveSite; } } // Fallback identifiers $titleIdentifier = !empty($this->source->chunks->titlefield_as) ? $this->source->chunks->titlefield_as : $this->source->chunks->titlefield; $idIdentifier = !empty($this->source->chunks->idfield_as) ? $this->source->chunks->idfield_as : $this->source->chunks->id;
/** * Route save single article to the corresponding SEF link * * @access private * @return string */ private function routeArticleToSefMenu($articleID, $catID, $language, $article) { // Try to route the article to a single article menu item view $helperRouteClass = $this->context['class']; $classMethod = $this->context['method']; // Route helper native by component, com_content, com_k2 if (!isset($this->context['routing'])) { $articleHelperRoute = $helperRouteClass::$classMethod($articleID, $catID, $language); } else { // Route helper universal JSitemap, com_zoo $articleHelperRoute = $helperRouteClass::$classMethod($article->option, $article->view, $article->id, $article->catid, null); if ($articleHelperRoute) { $articleHelperRoute = '?Itemid=' . $articleHelperRoute; } } // Extract Itemid from the helper routed URL $extractedItemid = preg_match('/Itemid=\\d+/i', $articleHelperRoute, $result); if (isset($result[0])) { // Get uri instance avoidng subdomains already included in the routing chunks $uriInstance = JUri::getInstance(); $resourceLiveSite = rtrim($uriInstance->getScheme() . '://' . $uriInstance->getHost(), '/'); $extractedItemid = $result[0]; $siteRouter = JRouterSite::getInstance('site', array('mode' => JROUTER_MODE_SEF)); $articleMenuRouted = $siteRouter->build('?' . $extractedItemid)->toString(); // Check if multilanguage is enabled if (JMapLanguageMultilang::isEnabled()) { if ($language != '*') { // New language manager instance $languageManager = JMapLanguageMultilang::getInstance($language); } else { // Get the default language tag // New language manager instance $languageManager = JMapLanguageMultilang::getInstance(); } // Extract the language tag $localeTag = $languageManager->getLocale(); $sefTag = $localeTag[4]; $articleMenuRouted = str_replace('/administrator', '/' . $sefTag, $articleMenuRouted); } else { $articleMenuRouted = str_replace('/administrator', '', $articleMenuRouted); } $articleMenuRouted = preg_match('/http/i', $articleMenuRouted) ? $articleMenuRouted : $resourceLiveSite . '/' . ltrim($articleMenuRouted, '/'); return $articleMenuRouted; } else { // Check if routing is valid otherwise throw exception throw new RuntimeException(JText::_('COM_JMAP_AUTOPING_ERROR_NOSEFROUTE_FOUND')); } }
/** * Get the Data for a view * * @access private * @param object $source * @param array $accessLevels * * @return Object */ private function getSourceData($source, $accessLevels) { // Create di un nuovo result source object popolato delle properties necessarie alla view e degli items recuperati da DB $resultSourceObject = new stdClass(); $resultSourceObject->id = $source->id; $resultSourceObject->name = $source->name; $resultSourceObject->type = $source->type; if ($source->sqlquery_managed) { $resultSourceObject->chunks = json_decode($source->sqlquery_managed); } // If sitemap format is gnews, allow only content data source and 3PD user data source that are supported as compatible, avoid calculate unuseful data and return immediately if ($this->documentFormat === 'gnews') { if ($source->type === 'menu') { return false; } if ($source->type === 'user') { if (isset($resultSourceObject->chunks)) { if (!in_array($resultSourceObject->chunks->table_maintable, $this->supportedGNewsTablesOptions)) { return false; } } } } // If sitemap format is rss, allow only content data source and 3PD user data source that are supported as compatible, avoid calculate unuseful data and return immediately if ($this->documentFormat === 'rss') { if ($source->type === 'menu') { return false; } // Load always manifest, both content and third party data sources $this->rssExtensionsManifest = $this->loadManifest('rss'); // If third party data sources check if it's supported, otherwise return false if ($source->type === 'user' && isset($resultSourceObject->chunks)) { // Add dynamic Virtuemart $vmProperty = '#__virtuemart_products_' . $this->siteLanguageRFC; $this->rssExtensionsManifest->{$vmProperty} = 'product_desc'; // Skip extensions not supported for RSS feed generation if (!property_exists($this->rssExtensionsManifest, $resultSourceObject->chunks->table_maintable)) { return false; } } } // Already a JRegistry object! Please note object cloning to avoid reference overwriting! // Component -> menu view specific level params override $resultSourceObject->params = clone $this->cparams; // Item specific level params override $resultSourceObject->params->merge(new JRegistry($source->params)); // Ensure the current datasource is enabled for the current sitemap format otherwise skip processing if (!$resultSourceObject->params->get('htmlinclude', 1) && $this->documentFormat == 'html') { return false; } if (!$resultSourceObject->params->get('xmlinclude', 1) && $this->documentFormat == 'xml') { return false; } if (!$resultSourceObject->params->get('xmlimagesinclude', 1) && $this->documentFormat == 'images') { return false; } if (!$resultSourceObject->params->get('xmlmobileinclude', 1) && $this->documentFormat == 'mobile') { return false; } if (!$resultSourceObject->params->get('gnewsinclude', 1) && $this->documentFormat == 'gnews') { return false; } if (!$resultSourceObject->params->get('rssinclude', 1) && $this->documentFormat == 'rss') { return false; } // ACL filtering $disableAcl = $resultSourceObject->params->get('disable_acl'); $sourceItems = array(); switch ($source->type) { case 'user': $query = $source->sqlquery; $debugMode = $resultSourceObject->params->get('debug_mode', 0); // Do runtime preprocessing if any for selected data source extension $query = $this->runtimePreProcessing($query, $resultSourceObject); // Se la raw query è stata impostata if ($query) { $query = str_replace('{aid}', '(' . implode(',', $accessLevels) . ')', $query); $query = str_replace('{langtag}', $this->_db->quote($this->langTag), $query); $query = str_replace('{languagetag}', $this->_db->quote($this->langTag), $query); // Manage for latest months placeholder if found one if (preg_match("/'?{(\\d+)months}'?/i", $query, $matches)) { $minValidCreatedDate = gmdate("Y-m-d H:i:s", strtotime("-" . $matches[1] . " months", time())); // All items need to be created after the minimum valid created date $query = preg_replace("/'?{(\\d+)months}'?/i", $this->_db->quote($minValidCreatedDate), $query); } // Runtime preprocessing for RSS description field if ($this->documentFormat === 'rss') { $query = $this->runtimeRssPreProcessing($resultSourceObject->chunks->table_maintable, $query); } // Check if a limit for query rows has been set, this means we are in precaching process by JS App client if (!$this->limitRows) { $this->_db->setQuery($query); } else { $this->_db->setQuery($query, $this->limitStart, $this->limitRows); } try { // Security safe check: only SELECT allowed if (preg_match('/(delete|update|insert|password)/i', $query)) { throw new JMapException(sprintf(JText::_('COM_JMAP_QUERY_NOT_ALLOWED_FROM_USER_DATASOURCE'), $source->name), 'warning'); } $sourceItems = $this->_db->loadObjectList(); if ($this->_db->getErrorNum() && !$sourceItems) { $queryExplained = null; if ($debugMode) { $queryExplained = '<br /><br />' . $this->_db->getErrorMsg() . '<br /><br />' . JText::_('COM_JMAP_SQLQUERY_EXPLAINED') . '<br /><br />' . $this->_db->getQuery() . '<br /><br />' . JText::_('COM_JMAP_SQLQUERY_EXPLAINED_END'); } throw new JMapException(sprintf(JText::_('COM_JMAP_ERROR_RETRIEVING_DATA_FROM_USER_DATASOURCE'), $source->name) . $queryExplained, 'warning'); } // Detected a precaching call, so store in the model state the number of affected rows for JS app if ($this->limitRows) { $this->setState('affected_rows', $this->_db->getAffectedRows()); } // Start subQueriesPostProcessor if needed for nested multilevel categories if ($resultSourceObject->params->get('multilevel_categories', 0) && $this->hasCategorization($resultSourceObject)) { // Pre assignment $resultSourceObject->data = $sourceItems; // Start post processor $this->subQueriesPostProcessor($resultSourceObject); } } catch (JMapException $e) { if ($e->getErrorLevel() == 'notice' && $debugMode) { $this->app->enqueueMessage($e->getMessage(), $e->getErrorLevel()); } elseif ($e->getErrorLevel() != 'notice') { $this->app->enqueueMessage($e->getMessage(), $e->getErrorLevel()); } $resultSourceObject->data = array(); return $resultSourceObject; } catch (Exception $e) { $jmapException = new JMapException($e->getMessage(), 'warning'); $this->app->enqueueMessage(sprintf(JText::_('COM_JMAP_ERROR_RETRIEVING_DATA_FROM_USER_DATASOURCE'), $source->name), 'warning'); if ($debugMode) { $this->app->enqueueMessage($jmapException->getMessage(), $jmapException->getErrorLevel()); } $resultSourceObject->data = array(); return $resultSourceObject; } } break; case 'menu': $menuAccess = null; $originalSourceItems = array(); // Unpublished items $doUnpublishedItems = $resultSourceObject->params->get('dounpublished', 0); // Exclusion menu $subQueryExclusion = null; $exclusionMenuItems = $resultSourceObject->params->get('exclusion', array()); if ($exclusionMenuItems && !is_array($exclusionMenuItems)) { $exclusionMenuItems = array($exclusionMenuItems); } if (count($exclusionMenuItems)) { $subQueryExclusion = "\n AND menuitems.id NOT IN (" . implode(',', $exclusionMenuItems) . ")"; } $queryChunk = null; if (!$doUnpublishedItems) { $queryChunk = "\n AND menuitems.published = 1"; } // Filter by access if ACL option enabled if ($disableAcl !== 'disabled') { $menuAccess = "\n AND menuitems.access IN ( " . implode(',', $accessLevels) . " )"; } // Filter by language only if multilanguage is correctly enabled by Joomla! plugin $menuLanguageFilter = null; if (JMapLanguageMultilang::isEnabled()) { $menuLanguageFilter = "\n AND ( menuitems.language = " . $this->_db->quote('*') . " OR menuitems.language = " . $this->_db->quote($this->langTag) . " ) "; } $menuQueryItems = "SELECT menuitems.*, menuitems.parent_id AS parent, menuitems.level AS sublevel, menuitems.title AS name, menupriorities.priority" . "\n FROM #__menu as menuitems" . "\n INNER JOIN #__menu_types AS menutypes" . "\n ON menuitems.menutype = menutypes.menutype" . "\n LEFT JOIN #__jmap_menu_priorities AS menupriorities" . "\n ON menupriorities.id = menuitems.id" . "\n WHERE\tmenuitems.published >= 0" . $queryChunk . $menuAccess . "\n AND menutypes.title = " . $this->_db->quote($source->name) . $menuLanguageFilter . $subQueryExclusion . "\n ORDER BY menuitems.menutype, menuitems.parent_id, menuitems.level, menuitems.lft"; // Check if a limit for query rows has been set, this means we are in precaching process by JS App client if (!$this->limitRows) { $this->_db->setQuery($menuQueryItems); } else { $this->_db->setQuery($menuQueryItems, $this->limitStart, $this->limitRows); } try { $originalSourceItems = $this->_db->loadObjectList(); if ($this->_db->getErrorNum()) { throw new JMapException(sprintf(JText::_('COM_JMAP_ERROR_RETRIEVING_DATA'), $source->name), 'notice'); } // Detected a precaching call, so store in the model state the number of affected rows for JS app if ($this->limitRows) { $this->setState('affected_rows', $this->_db->getAffectedRows()); } // Recursive ordering for menu rows ONLY if HTML format, otherwise make no sense so save resources and time if ($this->documentFormat == 'html') { $sourceItems = $this->sortMenu($originalSourceItems, $resultSourceObject->params); } else { $sourceItems = $originalSourceItems; } } catch (JMapException $e) { $this->app->enqueueMessage($e->getMessage(), $e->getErrorLevel()); $resultSourceObject->data = array(); return $resultSourceObject; } catch (Exception $e) { $jmapException = new JMapException($e->getMessage(), 'error'); $this->app->enqueueMessage($jmapException->getMessage(), $jmapException->getErrorLevel()); $resultSourceObject->data = array(); return $resultSourceObject; } break; case 'content': $access = null; $catAccess = null; $limitRecent = null; $dynamicSelectFields = null; $dynamicOrdering = null; $now = gmdate('Y-m-d H:i:s', time()); // Exclusion access for Google News Sitemap and if ACL is disabled $format = $this->getState('format'); // Set select fields only if html sitemap format is detected, save memory if XML and not needed if ($format == 'html') { $dynamicSelectFields = 'c.title AS title, cat.title AS category, cat.level,'; } // Set select fields only if RSS sitemap format is detected, save memory if not needed if ($format == 'rss' || $format == 'gnews') { $dynamicSelectFields = 'c.title AS title, cat.title AS category,'; } // Manage content articles order if ($format == 'rss' || $format != 'html' && $resultSourceObject->params->get('orderbydate', 0)) { $dynamicOrdering = "created DESC,"; } if ($format != 'gnews' && $disableAcl !== 'disabled') { $access = "\n AND c.access IN ( " . implode(',', $accessLevels) . " )"; $catAccess = "\n AND cat.access IN ( " . implode(',', $accessLevels) . " )"; } // Choose to limit valid articles for Google News Sitemap to last n most recent days if ($format == 'gnews' && $this->cparams->get('gnews_limit_recent', false)) { $validDays = $this->cparams->get('gnews_limit_valid_days', 2); $limitRecent = "\n AND UNIX_TIMESTAMP(c.publish_up) > " . (time() - 24 * 60 * 60 * $validDays); } // Exclusion categories $subQueryCatExclusion = null; $subQueryCategoryExclusion = null; $exclusionCategories = $resultSourceObject->params->get('catexclusion', array()); // Normalize select options if ($exclusionCategories && !is_array($exclusionCategories)) { $exclusionCategories = array($exclusionCategories); } // Exclusion children categories da table orm nested set model if (count($exclusionCategories)) { JTable::addIncludePath(JPATH_LIBRARIES . '/joomla/database/table'); $categoriesTableNested = JTable::getInstance('Category'); $children = array(); foreach ($exclusionCategories as $topCatID) { // Load Children categories se presenti $categoriesTableNested->load($topCatID); $tempChildren = $categoriesTableNested->getTree(); if (is_array($tempChildren) && count($tempChildren)) { foreach ($tempChildren as $child) { if (!in_array($child->id, $children) && !in_array($child->id, $exclusionCategories)) { $exclusionCategories[] = $child->id; } } } } $subQueryCatExclusion = "\n AND c.catid NOT IN (" . implode(',', $exclusionCategories) . ")"; $subQueryCategoryExclusion = "\n AND cat.id NOT IN (" . implode(',', $exclusionCategories) . ")"; } // Exclusion articles $subQueryArticleExclusion = null; $exclusionArticles = $resultSourceObject->params->get('articleexclusion', array()); // Normalize select options if ($exclusionArticles && !is_array($exclusionArticles)) { $exclusionArticles = array($exclusionArticles); } if (count($exclusionArticles)) { $subQueryArticleExclusion = "\n AND c.id NOT IN (" . implode(',', $exclusionArticles) . ")"; } // Evaluate content levels to include $includeArchived = $this->cparams->get('include_archived', 0); $contentLevel = $includeArchived ? ' > 0' : ' = 1'; // Filter by language only if multilanguage is correctly enabled by Joomla! plugin $contentLanguageFilter = null; $categoryLanguageFilter = null; if (JMapLanguageMultilang::isEnabled()) { $contentLanguageFilter = "\n AND ( c.language = " . $this->_db->quote('*') . " OR c.language = " . $this->_db->quote($this->langTag) . " ) "; $categoryLanguageFilter = "\n AND ( cat.language = " . $this->_db->quote('*') . " OR cat.language = " . $this->_db->quote($this->langTag) . " ) "; } // Check if pagebreaks analysis is required $pageBreaksFullText = null; if ($pageBreaksLinks = $this->cparams->get('show_pagebreaks', 0)) { $pageBreaksFullText = "\n ,CONCAT(c.introtext, c.fulltext) AS completetext"; } // Check if limit by recent months is set for content data source // Manage for latest months placeholder if found one $limitLatestItems = null; if ($monthsLimit = $resultSourceObject->params->get('created_date', null)) { $minValidCreatedDate = gmdate("Y-m-d H:i:s", strtotime("-" . $monthsLimit . " months", time())); $limitLatestItems = "\n AND c.created > " . $this->_db->quote($minValidCreatedDate); } $contentQueryItems = "SELECT c.id, c.language, c.publish_up, c.access, c.metakey, catspriorities.priority," . $dynamicSelectFields . "\n cat.id AS catid," . "\n UNIX_TIMESTAMP(c.modified) AS modified," . "\n CONCAT('index.php?option=com_content&view=article&id=', c.id) AS link , c.catid AS catslug," . "\n CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(':', c.id, c.alias) ELSE c.id END AS slug" . $pageBreaksFullText . "\n FROM " . $this->_db->quoteName('#__content') . " AS c" . "\n LEFT JOIN #__jmap_cats_priorities AS catspriorities ON catspriorities.id = c.catid" . "\n RIGHT JOIN #__categories AS cat ON cat.id = c.catid" . "\n AND c.state {$contentLevel}" . "\n AND ( c.publish_up = '0000-00-00 00:00:00' OR c.publish_up <= '{$now}' )" . "\n AND ( c.publish_down = '0000-00-00 00:00:00' OR c.publish_down >= '{$now}' )" . $limitRecent . $limitLatestItems . $access . $contentLanguageFilter . $subQueryCatExclusion . $subQueryArticleExclusion . "\n WHERE cat.published = '1'" . $catAccess . "\n AND cat.extension = " . $this->_db->quote('com_content') . $categoryLanguageFilter . $subQueryCategoryExclusion . "\n ORDER BY {$dynamicOrdering} cat.lft, c.ordering"; // Runtime preprocessing for RSS description field if ($this->documentFormat === 'rss') { $contentQueryItems = $this->runtimeRssPreProcessing('c', $contentQueryItems); } // Check if a limit for query rows has been set, this means we are in precaching process by JS App client if (!$this->limitRows) { $this->_db->setQuery($contentQueryItems); } else { $this->_db->setQuery($contentQueryItems, $this->limitStart, $this->limitRows); } try { $sourceItems = $this->_db->loadObjectList(); if ($this->_db->getErrorNum()) { throw new JMapException(sprintf(JText::_('COM_JMAP_ERROR_RETRIEVING_DATA'), $source->name), 'notice'); } // Detected a precaching call, so store in the model state the number of affected rows for JS app if ($this->limitRows) { $this->setState('affected_rows', $this->_db->getAffectedRows()); } // Sub article pagebreaks processing if ($pageBreaksLinks) { foreach ($sourceItems as $article) { $this->addPagebreaks($article); } } } catch (JMapException $e) { $this->app->enqueueMessage($e->getMessage(), $e->getErrorLevel()); $resultSourceObject->data = array(); return $resultSourceObject; } catch (Exception $e) { $jmapException = new JMapException($e->getMessage(), 'error'); $this->app->enqueueMessage($jmapException->getMessage(), $jmapException->getErrorLevel()); $resultSourceObject->data = array(); return $resultSourceObject; } break; case 'plugin': // Call the plugin interface and retrieve data $pluginName = strtolower($source->name); $className = 'JMapFilePlugin' . ucfirst($source->name); try { // Check if the plugin interface implementation exists if (!file_exists(JPATH_COMPONENT_ADMINISTRATOR . '/plugins/' . $pluginName . '/' . $pluginName . '.php')) { throw new JMapException(sprintf(JText::_('COM_JMAP_ERROR_PLUGIN_DATASOURCE_NOT_EXISTS'), $pluginName . '.php'), 'warning'); } // Include for multiple instances of this data source include_once JPATH_COMPONENT_ADMINISTRATOR . '/plugins/' . $pluginName . '/' . $pluginName . '.php'; // Check if the concrete class exists now if (!class_exists($className)) { throw new JMapException(sprintf(JText::_('COM_JMAP_ERROR_PLUGIN_CLASS_NOT_EXISTS'), $className), 'warning'); } // Load the language file for the plugin, manage partial language translations $jLang = JFactory::getLanguage(); $jLang->load($pluginName, JPATH_COMPONENT_ADMINISTRATOR . '/plugins/' . $pluginName, 'en-GB', true, true); if ($jLang->getTag() != 'en-GB') { $jLang->load($pluginName, JPATH_COMPONENT_ADMINISTRATOR . '/plugins/' . $pluginName, null, true, false); } // Instantiate the plugin class, inject $this class and manage limitRows for precaching in third party plugins $pluginInstance = new $className(); $retrievedData = $pluginInstance->getSourceData($resultSourceObject->params, $this->_db, $this); // 1) first structure required: plain list of items -> PLAIN LIST OF ELEMENTS if (!array_key_exists('items', $retrievedData)) { throw new JMapException(sprintf(JText::_('COM_JMAP_ERROR_PLUGIN_NODATA_RETURNED'), $pluginName), 'warning'); } $sourceItems = $retrievedData['items']; // Check if additional structures for nested categories tree are returned // 2) second structure optional: plain list of items grouped by cats -> LIST OF ELEMENTS GROUPED BY PLAIN CATS STRUCTURE if (array_key_exists('items_tree', $retrievedData)) { $resultSourceObject->itemsTree = $retrievedData['items_tree']; } // 3) third structure optional: nested tree of cats by parents -> LIST OF ELEMENTS GROUPED BY NESTED CATS STRUCTURE if (array_key_exists('categories_tree', $retrievedData)) { $resultSourceObject->categoriesTree = $retrievedData['categories_tree']; } } catch (JMapException $e) { if ($e->getErrorLevel() == 'notice' && $debugMode) { $this->app->enqueueMessage($e->getMessage(), $e->getErrorLevel()); } elseif ($e->getErrorLevel() != 'notice') { $this->app->enqueueMessage($e->getMessage(), $e->getErrorLevel()); } $resultSourceObject->data = array(); return $resultSourceObject; } catch (Exception $e) { $debugMode = $this->cparams->get('enable_debug', 0); $jmapException = new JMapException($e->getMessage(), 'warning'); $this->app->enqueueMessage(sprintf(JText::_('COM_JMAP_ERROR_RETRIEVING_DATA_FROM_USER_DATASOURCE'), $source->name), 'warning'); if ($debugMode) { $this->app->enqueueMessage($jmapException->getMessage(), $jmapException->getErrorLevel()); } $resultSourceObject->data = array(); return $resultSourceObject; } break; } // Final assignment $resultSourceObject->data = $sourceItems; return $resultSourceObject; }