Added sitemap API
authorAlexander Ebert <ebert@woltlab.com>
Fri, 22 Jun 2012 16:13:47 +0000 (18:13 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 22 Jun 2012 16:13:47 +0000 (18:13 +0200)
wcfsetup/install/files/lib/data/sitemap/Sitemap.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/sitemap/SitemapAction.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/sitemap/SitemapEditor.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/sitemap/SitemapList.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/cache/builder/SitemapCacheBuilder.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/package/plugin/SitemapPackageInstallationPlugin.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/sitemap/ISitemapProvider.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/sitemap/SitemapHandler.class.php [new file with mode: 0644]
wcfsetup/setup/db/install.sql

diff --git a/wcfsetup/install/files/lib/data/sitemap/Sitemap.class.php b/wcfsetup/install/files/lib/data/sitemap/Sitemap.class.php
new file mode 100644 (file)
index 0000000..bd0a675
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+namespace wcf\data\sitemap;
+use wcf\data\DatabaseObject;
+use wcf\system\exception\SystemException;
+use wcf\util\ClassUtil;
+
+/**
+ * Represents a sitemap entry.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2012 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage data.sitemap
+ * @category   Community Framework
+ */
+class Sitemap extends DatabaseObject {
+       /**
+        * ISitemapProvider object
+        * @var wcf\system\sitemap\ISitemapProvider
+        */
+       protected $sitemapObj = null;
+       
+       /**
+        * @see wcf\data\DatabaseObject::$databaseTableIndexName
+        */
+       protected static $databaseTableIndexName = 'sitemapID';
+       
+       /**
+        * Returns parsed template for current sitemap.
+        * 
+        * @return      string
+        */
+       public function getTemplate() {
+               if ($this->sitemapObj === null) {
+                       if (empty($this->className) || !class_exists($this->className)) {
+                               throw new SystemException("Unable to find class '".$this->className."' for sitemap '".$this->sitemapName."'");
+                       }
+                       
+                       if (!ClassUtil::isInstanceOf($this->className, 'wcf\system\sitemap\ISitemapProvider')) {
+                               throw new SystemException("Class '".$this->className."' does not implement the interface 'wcf\system\sitemap\ISitemapProvider'");
+                       }
+                       
+                       $this->sitemapObj = new $this->className();
+               }
+               
+               return $this->sitemapObj->getTemplate();
+       }
+}
diff --git a/wcfsetup/install/files/lib/data/sitemap/SitemapAction.class.php b/wcfsetup/install/files/lib/data/sitemap/SitemapAction.class.php
new file mode 100644 (file)
index 0000000..aceebf6
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+namespace wcf\data\sitemap;
+use wcf\data\AbstractDatabaseObjectAction;
+use wcf\system\exception\SystemException;
+use wcf\system\sitemap\SitemapHandler;
+use wcf\system\WCF;
+
+/**
+ * Executes sitemap-related actions.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2012 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage data.sitemap
+ * @category   Community Framework
+ */
+class SitemapAction extends AbstractDatabaseObjectAction {
+       /**
+        * @see wcf\data\AbstractDatabaseObjectAction::$allowGuestAccess
+        */
+       protected $allowGuestAccess = array('getSitemap');
+       
+       /**
+        * Does nothing.
+        */
+       public function validateGetSitemap() {
+               if (isset($this->parameters['sitemapName'])) {
+                       SitemapHandler::getInstance()->validateSitemapName($this->parameters['sitemapName']);
+               }
+       }
+       
+       /**
+        * Returns sitemap for active application group.
+        * 
+        * @return      array
+        */
+       public function getSitemap() {
+               if (isset($this->parameters['sitemapName'])) {
+                       return array(
+                               'template' => SitemapHandler::getInstance()->getSitemap($this->parameters['sitemapName'])
+                       );
+               }
+               else {
+                       WCF::getTPL()->assign(array(
+                               'tree' => SitemapHandler::getInstance()->getTree(),
+                               'sitemap' => SitemapHandler::getInstance()->getSitemap()
+                       ));
+                       
+                       return array(
+                               'template' => WCF::getTPL()->fetch('sitemap')
+                       );
+               }
+       }
+}
diff --git a/wcfsetup/install/files/lib/data/sitemap/SitemapEditor.class.php b/wcfsetup/install/files/lib/data/sitemap/SitemapEditor.class.php
new file mode 100644 (file)
index 0000000..2e0f185
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+namespace wcf\data\sitemap;
+use wcf\data\DatabaseObjectEditor;
+
+/**
+ * Provides functions to edit sitemap entries.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2012 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage data.sitemap
+ * @category   Community Framework
+ */
+class SitemapEditor extends DatabaseObjectEditor {
+       /**
+        * @see wcf\data\DatabaseObjectDecorator::$baseClass
+        */
+       protected static $baseClass = 'wcf\data\sitemap\Sitemap';
+}
diff --git a/wcfsetup/install/files/lib/data/sitemap/SitemapList.class.php b/wcfsetup/install/files/lib/data/sitemap/SitemapList.class.php
new file mode 100644 (file)
index 0000000..4a80631
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+namespace wcf\data\sitemap;
+use wcf\data\DatabaseObjectList;
+
+/**
+ * Represents a list of sitemap entries.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2012 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage data.sitemap
+ * @category   Community Framework
+ */
+class SitemapList extends DatabaseObjectList { }
diff --git a/wcfsetup/install/files/lib/system/cache/builder/SitemapCacheBuilder.class.php b/wcfsetup/install/files/lib/system/cache/builder/SitemapCacheBuilder.class.php
new file mode 100644 (file)
index 0000000..1c04f3d
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+namespace wcf\system\cache\builder;
+use wcf\data\sitemap\SitemapList;
+use wcf\system\package\PackageDependencyHandler;
+
+/**
+ * Caches sitemap structure.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2012 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage system.cache.builder
+ * @category   Community Framework
+ */
+class SitemapCacheBuilder implements ICacheBuilder {
+       /**
+        * @see wcf\system\cache\ICacheBuilder::getData()
+        */
+       public function getData(array $cacheResource) {
+               $sitemapList = new SitemapList();
+               $sitemapList->getConditionBuilder()->add("sitemap.packageID IN (?)", array(PackageDependencyHandler::getInstance()->getPackageIDs()));
+               $sitemapList->sqlLimit = 0;
+               $sitemapList->readObjects();
+               
+               return $sitemapList->getObjects();
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/package/plugin/SitemapPackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/SitemapPackageInstallationPlugin.class.php
new file mode 100644 (file)
index 0000000..518dd66
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+namespace wcf\system\package\plugin;
+use wcf\system\cache\CacheHandler;
+use wcf\system\WCF;
+
+/**
+ * This PIP installs, updates or deletes sitemaps.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2012 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage system.package.plugin
+ * @category   Community Framework
+ */
+class SitemapPackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin {
+       /**
+        * @see wcf\system\package\plugin\AbstractXMLPackageInstallationPlugin::$className
+        */
+       public $className = 'wcf\data\sitemap\SitemapEditor';
+       
+       /**
+        * @see wcf\system\package\plugin\AbstractPackageInstallationPlugin::$tableName
+        */
+       public $tableName = 'sitemap';
+       
+       /**
+        * @see wcf\system\package\plugin\AbstractXMLPackageInstallationPlugin::$tagName
+        */     
+       public $tagName = 'sitemap';
+       
+       /**
+        * @see wcf\system\package\plugin\AbstractXMLPackageInstallationPlugin::handleDelete()
+        */
+       protected function handleDelete(array $items) {
+               $sql = "DELETE FROM     wcf".WCF_N."_".$this->tableName."
+                       WHERE           sitemapName = ?
+                                       AND packageID = ?";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               foreach ($items as $item) {
+                       $statement->execute(array(
+                               $item['attributes']['name'],
+                               $this->installation->getPackageID()
+                       ));
+               }
+       }
+       
+       /**
+        * @see wcf\system\package\plugin\AbstractXMLPackageInstallationPlugin::prepareImport()
+        */
+       protected function prepareImport(array $data) {
+               return array(
+                       'sitemapName' => $data['attributes']['name'],
+                       'className' => $data['elements']['classname']
+               );
+       }
+       
+       /**
+        * @see wcf\system\package\plugin\AbstractXMLPackageInstallationPlugin::findExistingItem()
+        */
+       protected function findExistingItem(array $data) {
+               $sql = "SELECT  *
+                       FROM    wcf".WCF_N."_".$this->tableName."
+                       WHERE   sitemapName = ?
+                               AND packageID = ?";
+               $parameters = array(
+                       $data['sitemapName'],
+                       $this->installation->getPackageID()
+               );
+               
+               return array(
+                       'sql' => $sql,
+                       'parameters' => $parameters
+               );
+       }
+       
+       /**
+        * @see wcf\system\package\plugin\AbstractXMLPackageInstallationPlugin::cleanup()
+        */     
+       protected function cleanup() {
+               CacheHandler::getInstance()->clear(WCF_DIR.'cache', 'cache.sitemap-*.php');
+       }
+       
+       /**
+        * @see wcf\system\package\plugin\IPackageInstallationPlugin::uninstall()
+        */
+       public function uninstall() {
+               parent::uninstall();
+               
+               // clear cache immediately
+               CacheHandler::getInstance()->clear(WCF_DIR.'cache', 'cache.sitemap-*.php');
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/sitemap/ISitemapProvider.class.php b/wcfsetup/install/files/lib/system/sitemap/ISitemapProvider.class.php
new file mode 100644 (file)
index 0000000..27d0a5d
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+namespace wcf\system\sitemap;
+
+/**
+ * Provides a general interface for all sitemap entries.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2012 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage system.sitemap
+ * @category   Community Framework
+ */
+interface ISitemapProvider {
+       /**
+        * Returns the parsed sitemap template.
+        * 
+        * @return      string
+        */
+       public function getTemplate();
+}
\ No newline at end of file
diff --git a/wcfsetup/install/files/lib/system/sitemap/SitemapHandler.class.php b/wcfsetup/install/files/lib/system/sitemap/SitemapHandler.class.php
new file mode 100644 (file)
index 0000000..5802fe4
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+namespace wcf\system\sitemap;
+use wcf\system\application\ApplicationHandler;
+use wcf\system\cache\CacheHandler;
+use wcf\system\exception\SystemException;
+use wcf\system\SingletonFactory;
+
+/**
+ * Handles sitemap interactions.
+ *
+ * @author     Alexander Ebert
+ * @copyright  2001-2012 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage sitemap.sitemap
+ * @category   Community Framework
+ */
+class SitemapHandler extends SingletonFactory {
+       /**
+        * sitemap cache
+        * @var array<wcf\data\sitemap\Sitemap>
+        */
+       protected $cache = null;
+       
+       /**
+        * @see \wcf\system\SingletonFactory::init()
+        */
+       protected function init() {
+               $application = ApplicationHandler::getInstance()->getPrimaryApplication();
+               $cacheName = 'sitemap-'.$application->packageID;
+               
+               CacheHandler::getInstance()->addResource(
+                       $cacheName,
+                       WCF_DIR.'cache/cache.'.$cacheName.'.php',
+                       'wcf\system\cache\builder\SitemapCacheBuilder'
+               );
+               $this->cache = CacheHandler::getInstance()->get($cacheName);
+       }
+       
+       /**
+        * Returns array of tree items or an empty array if only one sitemap is registered.
+        *  
+        * @return      array<wcf\data\sitemap\Sitemap>
+        */
+       public function getTree() {
+               $tree = array();
+               
+               if (count($this->cache) > 0) {
+                       foreach ($this->cache as $sitemap) {
+                               $tree[] = $sitemap->sitemapName;
+                       }
+               }
+               
+               return $tree;
+       }
+       
+       /**
+        * Returns sitemap for given sitemap name or falls back to active package id.
+        * 
+        * @param       string          $sitemapName
+        * @return      wcf\data\sitemap\Sitemap
+        */
+       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);
+                               $sitemapName = $sitemap->sitemapName;
+                       }
+               }
+               
+               foreach ($this->cache as $sitemap) {
+                       if ($sitemap->sitemapName == $sitemapName) {
+                               return $sitemap->getTemplate();
+                       }
+               }
+               
+               return null;
+       }
+       
+       /**
+        * Validates sitemap name.
+        * 
+        * @param       string          $sitemapName
+        */
+       public function validateSitemapName($sitemapName) {
+               if (empty($sitemapName)) {
+                       throw new SystemException("Empty sitemap name provided");
+               }
+               
+               $isValid = false;
+               foreach ($this->cache as $sitemap) {
+                       if ($sitemap->sitemapName == $sitemapName) {
+                               $isValid = true;
+                       }
+               }
+               
+               if (!$isValid) {
+                       throw new SystemException("Sitemap name '".$sitemapName."' is unknown");
+               }
+       }
+}
\ No newline at end of file
index ee57c7d48a877859cf1e8fc632b26602c2e559f1..06864c05c9be7ec33af51de143884e055a7b3b4f 100644 (file)
@@ -532,6 +532,15 @@ CREATE TABLE wcf1_session (
        KEY packageID (packageID, lastActivityTime, spiderID)
 );
 
+DROP TABLE IF EXISTS wcf1_sitemap;
+CREATE TABLE wcf1_sitemap (
+       sitemapID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+       packageID INT(10) NOT NULL,
+       sitemapName VARCHAR(80) NOT NULL DEFAULT '',
+       className VARCHAR(255) NOT NULL DEFAULT '',
+       UNIQUE KEY sitemapName (packageID, sitemapName)
+);
+
 DROP TABLE IF EXISTS wcf1_spider;
 CREATE TABLE wcf1_spider (
        spiderID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
@@ -852,6 +861,8 @@ ALTER TABLE wcf1_search ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) O
 ALTER TABLE wcf1_session ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
 ALTER TABLE wcf1_session ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE CASCADE;
 
+ALTER TABLE wcf1_sitemap ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
+
 ALTER TABLE wcf1_user_storage ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE CASCADE;
 ALTER TABLE wcf1_user_storage ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;