* Xmap by Guillermo Vargas * a sitemap component for Joomla! CMS (http://www.joomla.org) * Author Website: http://joomla.vargas.co.cr * Project License: GNU/GPL http://www.gnu.org/copyleft/gpl.html */ defined('_VALID_MOS') or die('Direct Access to this location is not allowed.'); // load Xmap language file global $mosConfig_absolute_path,$mosConfig_locale,$mosConfig_sef,$mosConfig_lang; $view = mosGetParam( $_REQUEST, 'view', 'html' ); if ($view == 'xslfile') { header('Content-Type: text/xml'); @readfile($mosConfig_absolute_path.'/components/com_xmap/gss.xsl'); exit; } $LangPath = $mosConfig_absolute_path . '/administrator/components/com_xmap/language/'; if( file_exists( $LangPath . $mosConfig_lang . '.php') ) { require_once( $LangPath . $mosConfig_lang. '.php' ); } else { require_once( $LangPath . 'english.php' ); } require_once( $mosConfig_absolute_path.'/administrator/components/com_xmap/classes/XmapConfig.php' ); require_once( $mosConfig_absolute_path.'/administrator/components/com_xmap/classes/XmapSitemap.php' ); require_once( $mosConfig_absolute_path.'/administrator/components/com_xmap/classes/XmapPlugins.php' ); require_once( $mosConfig_absolute_path.'/administrator/components/com_xmap/classes/XmapCache.php' ); global $xSitemap,$xConfig; $xConfig = new XmapConfig; $xConfig->load(); $Itemid = intval(mosGetParam( $_REQUEST, 'Itemid', '' )); $sitemapid = ''; // Firts lets try to get the sitemap's id from the menu's params if ( $Itemid ) { $menu = new mosMenu( $database ); $menu->load( $Itemid ); $params = new mosParameters( $menu->params ); $sitemapid=intval($params->get( 'sitemap','' )); } if (!$sitemapid) { //If the is no sitemap id specificated $sitemapid = intval(mosGetParam($_REQUEST,'sitemap','')); } if ( !$sitemapid && $xConfig->sitemap_default ) { $sitemapid = $xConfig->sitemap_default; } $xSitemap = new XmapSitemap(); $xSitemap->load($sitemapid); if (!$xSitemap->id) { echo _XMAP_MSG_NO_SITEMAP; return; } if ( $view=='xml' ) { Header("Content-type: text/xml; charset=UTF-8"); Header("Content-encoding: UTF-8"); } global $xmap; $xmapCache = XmapCache::getCache($xSitemap); if ($xSitemap->usecache) { $xmapCache->call('xmapCallShowSitemap',$view,$xSitemap->id,$mosConfig_locale,$mosConfig_sef); // call plugin's handler function } else { xmapCallShowSitemap($view,$xSitemap->id); } switch ($view) { case 'html': $xSitemap->views_html++; $xSitemap->lastvisit_html = time(); $xSitemap->save(); break; case 'xml': $xSitemap->views_xml++; $xSitemap->lastvisit_xml = time(); $xSitemap->save(); $scriptname = basename($_SERVER['SCRIPT_NAME']); $no_html = intval(mosGetParam($_REQUEST, 'no_html', '0')); if ($view=='xml' && $scriptname != 'index2.php' || $no_html != 1) { die(); } break; } /** * Function called to generate and generate the tree. Created specially to * use with the cache call method * The params locale and sef are only for cache purppses */ function xmapCallShowSitemap($view,$sitemapid,$locale='',$sef='') { global $xmapCache,$mosConfig_absolute_path,$mosConfig_live_site,$xSitemap,$xConfig; switch( $view ) { case 'xml': // XML Sitemaps output require_once( $mosConfig_absolute_path .'/components/com_xmap/xmap.xml.php' ); $xmap = new XmapXML( $xConfig, $xSitemap ); $xmap->generateSitemap($view,$xConfig,$xmapCache); $xSitemap->count_xml = $xmap->count; break; default: // Html output global $mainframe; require_once( $mainframe->getPath('front_html') ); if (!$xConfig->exclude_css) { $mainframe->addCustomHeadTag( '' ); } $xmap = new XmapHtml( $xConfig, $xSitemap ); $xmap->generateSitemap($view,$xConfig,$xmapCache); $xSitemap->count_html = $xmap->count; break; } } class Xmap { /** @var XmapConfig Configuration settings */ var $config; /** @var XmapSitemap Configuration settings */ var $sitemap; /** @var integer The current user's access level */ var $gid; /** @var boolean Is authentication disabled for this website? */ var $noauth; /** @var string Current time as a ready to use SQL timeval */ var $now; /** @var object Access restrictions for user */ var $access; /** @var string Type of sitemap to be generated */ var $view; /** @var string count of links on sitemap */ var $count=0; /** Default constructor, requires the config as parameter. */ function Xmap( &$config, &$sitemap ) { global $acl, $my, $mainframe,$mosConfig_offset; $access = new stdClass(); $access->canEdit = $acl->acl_check( 'action', 'edit', 'users', $my->usertype, 'content', 'all' ); $access->canEditOwn = $acl->acl_check( 'action', 'edit', 'users', $my->usertype, 'content', 'own' ); $access->canPublish = $acl->acl_check( 'action', 'publish', 'users', $my->usertype, 'content', 'all' ); $this->access = &$access; $this->noauth = $mainframe->getCfg( 'shownoauth' ); $this->gid = $my->gid; $this->now = (time() - ($mosConfig_offset * 60 * 60)); $this->config = &$config; $this->sitemap = &$sitemap; } /** Generate a full website tree */ function generateSitemap( $type,&$config, &$cache ) { $menus = $this->sitemap->getMenus(); $plugins = XmapPlugins::loadAvailablePlugins(); $root = array(); $this->startOutput($menus,$config); foreach ( $menus as $menutype => $menu ) { if ( ($type == 'html' && !$menu->show) || ($type == 'xml' && !$menu->showXML ) ) { continue; } $node = new stdclass(); $menu->id = 0; $menu->menutype = $menutype; $node->uid = $menu->uid = "menu".$menu->id; $node->menutype = $menutype; $node->ordering = $menu->ordering; $node->priority = $menu->priority; $node->changefreq = $menu->changefreq; $node->browserNav = 3; $node->type = 'separator'; $node->name = $this->getMenuTitle($menutype); // get the mod_mainmenu title from modules table $this->startMenu($node); $this->printMenuTree($menu,$cache,$plugins); $this->endMenu($node); } $this->endOutput($menus); return true; } /** Get a Menu's tree * Get the complete list of menu entries where the menu is in $menutype. * If the component, that is linked to the menuentry, has a registered handler, * this function will call the handler routine and add the complete tree. * A tree with subtrees for each menuentry is returned. */ function printMenuTree( &$menu, &$cache, $plugins) { global $database; if( strlen($menu->menutype) == 0 ) { $result = null; return $result; } $menuExluded = explode( ',', $this->sitemap->exclmenus ); // by mic: fill array with excluded menu IDs /* * noauth is true: - Will show links to registered content, even if the client is not logged in. - The user will need to login to see the item in full. * noauth is false: - Will show only links to content for which the logged in client has access. */ $sql = "SELECT m.id, m.name, m.parent, m.link, m.type, m.browserNav, m.menutype, m.ordering, m.params, m.componentid, c.name AS component" . "\n FROM #__menu AS m" . "\n LEFT JOIN #__components AS c ON m.type='components' AND c.id=m.componentid" . "\n WHERE m.published='1' AND m.parent=".$menu->id." AND m.menutype = '".$menu->menutype."'" . ( $this->noauth ? '' : "\n AND m.access <= '". $this->gid ."'" ) . "\n ORDER BY m.menutype,m.parent,m.ordering"; // Load all menuentries $database->setQuery( $sql ); $items = $database->loadObjectList(); if( count($items) <= 0) { //ignore empty menus $result = null; return $result; } $this->changeLevel(1); $isJ15 = defined ('_JEXEC') && defined('JPATH_COMPONENT'); foreach ( $items as $i => $item ) { // Add each menu entry to the root tree. $item->priority = $menu->priority; $item->changefreq = $menu->changefreq; if( in_array( $item->id, $menuExluded ) ) { // ignore exluded menu-items continue; } $node = new stdclass; $node->id = $item->id; $node->uid = "item".$item->id; $node->name = $item->name; // displayed name of node $node->parent = $item->parent; // id of parent node $node->browserNav = $item->browserNav; // how to open link $node->ordering = isset( $item->ordering ) ? $item->ordering : $i; // display-order of the menuentry $node->priority = $item->priority; $node->changefreq = $item->changefreq; $node->type = $item->type; // menuentry-type $node->menutype = $item->menutype; // menuentry-type if ( $isJ15 && substr($item->link,0,9) == 'index.php' ) { $node->link = 'index.php?Itemid=' . $node->id; // For Joomla 1.5 SEF compatibility } else { $node->link = isset( $item->link ) ? htmlspecialchars( $item->link ) : ''; // convert link to valid xml } $this->printNode($node); XmapPlugins::printTree( $this, $item, $cache, $plugins ); // Determine the menu entry's type and call it's handler $this->printMenuTree($node,$cache,$plugins); } $this->changeLevel(-1); } /** Look up the title for the module that links to $menutype */ function getMenuTitle($menutype) { global $database; $query = "SELECT * FROM #__modules WHERE published='1' AND module='mod_mainmenu' AND params LIKE '%menutype=". $menutype ."%'"; $database->setQuery( $query ); if( !$database->loadObject($row) ) return ''; return $row->title; } function getItemLink (&$node) { global $mosConfig_live_site; $link = $node->link; if ( isset($node->id) ) { switch( @$node->type ) { case 'separator': break; case 'url': if ( preg_match( "#^/?index\.php\?#", $link ) ) { if ( strpos( $link, 'Itemid=') === FALSE ) { if (strpos( $link, '?') === FALSE ) { $link .= '?Itemid='.$node->id; } else { $link .= '&Itemid='.$node->id; } } } break; default: if ( strpos( $link, 'Itemid=' ) === FALSE ) { $link .= '&Itemid='.$node->id; } break; } } if( strcasecmp( substr( $link, 0, 4), 'http' ) ){ if (strcasecmp( substr( $link, 0, 9), 'index.php' ) === 0 ){ $link = sefRelToAbs($link); // apply SEF transformation if( strcasecmp( substr($link,0,4), 'http' ) ) { // fix broken sefRelToAbs() $link = $mosConfig_live_site. (substr($link,0,1) == '/'? '' : '/').$link; } } else { // Case for internal links not starting with index.php $link = $mosConfig_live_site. '/' .$link; } } return $link; } /** Print tree details for debugging and testing */ function printDebugTree( &$tree ) { foreach( $tree as $menu) { echo $menu->name."
\n"; echo '
';
			print_r( $menu->tree );
			echo '
'; } } /** called with usort to sort menus */ function sort_ordering( &$a, &$b) { if( $a->ordering == $b->ordering ) return 0; return $a->ordering < $b->ordering ? -1 : 1; } }