Improved sitemap implementation
authorAlexander Ebert <ebert@woltlab.com>
Mon, 25 Jun 2012 15:22:15 +0000 (17:22 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 25 Jun 2012 15:22:15 +0000 (17:22 +0200)
com.woltlab.wcf/template/headInclude.tpl
com.woltlab.wcf/template/header.tpl
com.woltlab.wcf/template/sitemap.tpl [new file with mode: 0644]
wcfsetup/install/files/js/WCF.js
wcfsetup/install/files/lib/data/DatabaseObject.class.php
wcfsetup/install/files/lib/data/DatabaseObjectList.class.php
wcfsetup/install/files/lib/data/sitemap/SitemapAction.class.php
wcfsetup/install/files/lib/system/cache/builder/SitemapCacheBuilder.class.php
wcfsetup/install/files/lib/system/sitemap/SitemapHandler.class.php

index aceab103b394be24971250f36f8b1ccf4ea2f791..cdc52025a110af16490cdf359d884203e052f2c7 100644 (file)
@@ -84,6 +84,7 @@
                new WCF.Date.Time();
                new WCF.Effect.SmoothScroll();
                new WCF.Effect.BalloonTooltip();
+               new WCF.Sitemap();
                WCF.Dropdown.init();
                
                {event name='javascriptInit'}
index 34743942a1becdc48ece25ac162f57eb530e4102..4aec40b794e13693ffc0c35bcd914f0512f4827d 100644 (file)
@@ -40,6 +40,7 @@
                        
                        <ul class="navigationIcons">
                                <li id="toBottomLink"><a href="{$__wcf->getAnchor('bottom')}" title="{lang}wcf.global.scrollDown{/lang}" class="jsTooltip"><img src="{icon size='S'}circleArrowDownColored{/icon}" alt="" class="icon16" /> <span class="invisible">{lang}wcf.global.scrollDown{/lang}</span></a></li>
+                               <li id="sitemap"><a title="{lang}wcf.sitemap.title{/lang}" class="jsTooltip"><img src="{icon size='S'}switchColored{/icon}" alt="" class="icon16" /> <span class="invisible">{lang}wcf.sitemap.title{/lang}</span></a></li>
                                {if $headerNavigation|isset}{@$headerNavigation}{/if}
                                {event name='headerNavigation'}
                        </ul>
diff --git a/com.woltlab.wcf/template/sitemap.tpl b/com.woltlab.wcf/template/sitemap.tpl
new file mode 100644 (file)
index 0000000..44e20e6
--- /dev/null
@@ -0,0 +1,31 @@
+<div class="sitemap">
+       {hascontent}
+               <div class="tabMenuContainer" data-active="sitemap-{@$defaultSitemapName}">
+                       <nav class="tabMenu">
+                               <ul>
+                                       {content}
+                                               {foreach from=$tree item=sitemapName}
+                                                       <li><a href="#sitemap-{$sitemapName}" class="sitemapNavigation" data-sitemap-name="{$sitemapName}">{lang}wcf.sitemap.{$sitemapName}{/lang}</a></li>
+                                               {/foreach}
+                                       {/content}
+                               </ul>
+                       </nav>
+                       
+                       {foreach from=$tree item=sitemapName}
+                               <div id="sitemap-{$sitemapName}" class="container containerPadding tabMenuContent hidden">
+                                       {if $sitemapName == $defaultSitemapName}{@$sitemap}{/if}
+                               </div>
+                       {/foreach}
+               </div>
+               
+               <script type="text/javascript">
+                       //<![CDATA[
+                       $(function() {
+                               WCF.TabMenu.init();
+                       });
+                       //]]>
+               </script>
+       {hascontentelse}
+               {@$sitemap}
+       {/hascontent}
+</div>
\ No newline at end of file
index 4704270b0f46c7a3cd1eb892e0d1a5f18b684553..2eb8f75ae5a2f70b5dbf2df1aa9e89f1ee06f2de 100644 (file)
@@ -5836,6 +5836,126 @@ $.widget('ui.wcfSidebar', {
        }
 });
 
+/**
+ * Provides a generic sitemap.
+ */
+WCF.Sitemap = Class.extend({
+       /**
+        * sitemap name cache
+        */
+       _cache: [ ],
+       
+       /**
+        * dialog overlay
+        * @var jQuery
+        */
+       _dialog: null,
+       
+       /**
+        * initialization state
+        * @var boolean
+        */
+       _didInit: false,
+       
+       /**
+        * action proxy
+        * @var WCF.Action.Proxy
+        */
+       _proxy: null,
+       
+       /**
+        * Initializes the generic sitemap.
+        */
+       init: function() {
+               $('#sitemap').click($.proxy(this._click, this));
+               
+               this._cache = [ ];
+               this._dialog = null;
+               this._didInit = false;
+               this._proxy = new WCF.Action.Proxy({
+                       success: $.proxy(this._success, this)
+               });
+       },
+       
+       /**
+        * Handles clicks on the sitemap icon.
+        */
+       _click: function() {
+               if (this._dialog === null) {
+                       this._dialog = $('<div id="sitemapDialog" />').appendTo(document.body);
+                       
+                       this._proxy.setOption('data', {
+                               actionName: 'getSitemap',
+                               className: 'wcf\\data\\sitemap\\SitemapAction'
+                       });
+                       this._proxy.sendRequest();
+               }
+               else {
+                       this._dialog.wcfDialog('open');
+               }
+       },
+       
+       /**
+        * Handles successful AJAX responses.
+        * 
+        * @param       object          data
+        * @param       string          textStatus
+        * @param       jQuery          jqXHR
+        */
+       _success: function(data, textStatus, jqXHR) {
+               if (this._didInit) {
+                       this._cache.push(data.returnValues.sitemapName);
+                       
+                       this._dialog.find('#sitemap-' + data.returnValues.sitemapName).html(data.returnValues.template);
+                       
+                       // redraw dialog
+                       this._dialog.wcfDialog('render');
+               }
+               else {
+                       // mark sitemap name as loaded
+                       this._cache.push(data.returnValues.sitemapName);
+                       
+                       // insert sitemap template
+                       this._dialog.html(data.returnValues.template);
+                       
+                       // bind event listener
+                       this._dialog.find('.sitemapNavigation').click($.proxy(this._navigate, this));
+                       
+                       // show dialog
+                       this._dialog.wcfDialog({
+                               title: WCF.Language.get('wcf.sitemap.title')
+                       });
+                       
+                       this._didInit = true;
+               }
+       },
+       
+       /**
+        * Navigates between different sitemaps.
+        * 
+        * @param       object          event
+        */
+       _navigate: function(event) {
+               var $sitemapName = $(event.currentTarget).data('sitemapName');
+               if (WCF.inArray($sitemapName, this._cache)) {
+                       this._dialog.find('.tabMenuContainer').wcfTabs('select', 'sitemap-' + $sitemapName);
+                       
+                       // redraw dialog
+                       this._dialog.wcfDialog('render');
+               }
+               else {
+                       this._proxy.setOption('data', {
+                               actionName: 'getSitemap',
+                               className: 'wcf\\data\\sitemap\\SitemapAction',
+                               parameters: {
+                                       sitemapName: $sitemapName
+                               }
+                       });
+                       this._proxy.sendRequest();
+               }
+       }
+});
+
 /**
  * Provides a toggleable sidebar with persistent visibility.
  */
index 16ade9df48e5f6163b1e92daee8135d07b2ff5cd..1adc322b2660731ab3e7406b53d3d9bff2c78e37 100644 (file)
@@ -133,6 +133,20 @@ abstract class DatabaseObject implements IStorableObject {
         * @see wcf\data\IStorableObject::getDatabaseTableAlias()
         */
        public static function getDatabaseTableAlias() {
+               if (empty(static::$databaseTableName)) {
+                       $className = get_called_class();
+                       $className = substr($className, (strrpos($className, '\\') + 1));
+                               
+                       preg_match_all('~((?:^|[A-Z])[a-z]+)~', $className, $matches);
+                       foreach ($matches[1] as $part) {
+                               if (!empty(static::$databaseTableName)) {
+                                       static::$databaseTableName .= '_';
+                               }
+               
+                               static::$databaseTableName .= strtolower($part);
+                       }
+               }
+               
                return static::$databaseTableName;
        }
        
index ca0e83a0214f541edd63f3dd518fb0a3faddceee..ea22f1a863ad8d31e1bf7b3079def704e4cae906 100644 (file)
@@ -157,7 +157,6 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
                        if (!count($this->objectIDs)) {
                                return;
                        }
-                       
                        $sql = "SELECT  ".(!empty($this->sqlSelects) ? $this->sqlSelects.($this->useQualifiedShorthand ? ',' : '') : '')."
                                        ".($this->useQualifiedShorthand ? $this->getDatabaseTableAlias().'.*' : '')."
                                FROM    ".$this->getDatabaseTableName()." ".$this->getDatabaseTableAlias()."
@@ -169,6 +168,7 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
                        $this->objects = $statement->fetchObjects(($this->objectClassName ?: $this->className));
                }
                else {
+                       //if (!empty($this->sqlSelects)) die("x".$this->sqlSelects);
                        $sql = "SELECT  ".(!empty($this->sqlSelects) ? $this->sqlSelects.($this->useQualifiedShorthand ? ',' : '') : '')."
                                        ".($this->useQualifiedShorthand ? $this->getDatabaseTableAlias().'.*' : '')."
                                FROM    ".$this->getDatabaseTableName()." ".$this->getDatabaseTableAlias()."
index aceebf64618ac24b65e748d801fdf73deb993980..929675faea4a188b1af5dadc277701c68508d7d4 100644 (file)
@@ -38,16 +38,21 @@ class SitemapAction extends AbstractDatabaseObjectAction {
        public function getSitemap() {
                if (isset($this->parameters['sitemapName'])) {
                        return array(
+                               'sitemapName' => $this->parameters['sitemapName'],
                                'template' => SitemapHandler::getInstance()->getSitemap($this->parameters['sitemapName'])
                        );
                }
                else {
+                       $sitemapName = SitemapHandler::getInstance()->getDefaultSitemapName();
+                       
                        WCF::getTPL()->assign(array(
-                               'tree' => SitemapHandler::getInstance()->getTree(),
-                               'sitemap' => SitemapHandler::getInstance()->getSitemap()
+                               'defaultSitemapName' => $sitemapName,
+                               'sitemap' => SitemapHandler::getInstance()->getSitemap($sitemapName),
+                               'tree' => SitemapHandler::getInstance()->getTree()
                        ));
                        
                        return array(
+                               'sitemapName' => $sitemapName,
                                'template' => WCF::getTPL()->fetch('sitemap')
                        );
                }
index 1c04f3df596d57c133e7e47c9a517f9abf54a4b3..8350344b6d9d85f21782336a415e4a1e4779e1da 100644 (file)
@@ -19,7 +19,7 @@ class SitemapCacheBuilder implements ICacheBuilder {
         */
        public function getData(array $cacheResource) {
                $sitemapList = new SitemapList();
-               $sitemapList->getConditionBuilder()->add("sitemap.packageID IN (?)", array(PackageDependencyHandler::getInstance()->getPackageIDs()));
+               $sitemapList->getConditionBuilder()->add("sitemap.packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
                $sitemapList->sqlLimit = 0;
                $sitemapList->readObjects();
                
index 5802fe4c03b4fb1fff93945044892ef92e20d832..4b4f9bca667ef0d735669ea05a5f13fc6dd13463 100644 (file)
@@ -55,25 +55,32 @@ class SitemapHandler extends SingletonFactory {
        }
        
        /**
-        * Returns sitemap for given sitemap name or falls back to active package id.
+        * Returns default sitemap name.
         * 
-        * @param       string          $sitemapName
-        * @return      wcf\data\sitemap\Sitemap
+        * @return      string
         */
-       public function getSitemap($sitemapName = '') {
-               if (empty($sitemapName)) {
-                       foreach ($this->cache as $sitemap) {
-                               if ($sitemap->packageID == PACKAGE_ID) {
-                                       $sitemapName = $sitemap->sitemapName;
-                               }
-                       }
-                       
-                       if (empty($sitemapName)) {
-                               $sitemap = reset($this->cache);
+       public function getDefaultSitemapName() {
+               foreach ($this->cache as $sitemap) {
+                       if ($sitemap->packageID == PACKAGE_ID) {
                                $sitemapName = $sitemap->sitemapName;
                        }
                }
                
+               if (empty($sitemapName)) {
+                       $sitemap = reset($this->cache);
+                       $sitemapName = $sitemap->sitemapName;
+               }
+               
+               return $sitemapName;
+       }
+       
+       /**
+        * Returns sitemap for given sitemap name.
+        * 
+        * @param       string          $sitemapName
+        * @return      wcf\data\sitemap\Sitemap
+        */
+       public function getSitemap($sitemapName) {
                foreach ($this->cache as $sitemap) {
                        if ($sitemap->sitemapName == $sitemapName) {
                                return $sitemap->getTemplate();