From 46bd110b0eb704c42f7d6596911bc9551077473a Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Fri, 22 Jun 2012 18:13:47 +0200 Subject: [PATCH] Added sitemap API --- .../files/lib/data/sitemap/Sitemap.class.php | 49 ++++++++ .../lib/data/sitemap/SitemapAction.class.php | 55 +++++++++ .../lib/data/sitemap/SitemapEditor.class.php | 20 ++++ .../lib/data/sitemap/SitemapList.class.php | 15 +++ .../builder/SitemapCacheBuilder.class.php | 28 +++++ ...SitemapPackageInstallationPlugin.class.php | 93 +++++++++++++++ .../system/sitemap/ISitemapProvider.class.php | 21 ++++ .../system/sitemap/SitemapHandler.class.php | 107 ++++++++++++++++++ wcfsetup/setup/db/install.sql | 11 ++ 9 files changed, 399 insertions(+) create mode 100644 wcfsetup/install/files/lib/data/sitemap/Sitemap.class.php create mode 100644 wcfsetup/install/files/lib/data/sitemap/SitemapAction.class.php create mode 100644 wcfsetup/install/files/lib/data/sitemap/SitemapEditor.class.php create mode 100644 wcfsetup/install/files/lib/data/sitemap/SitemapList.class.php create mode 100644 wcfsetup/install/files/lib/system/cache/builder/SitemapCacheBuilder.class.php create mode 100644 wcfsetup/install/files/lib/system/package/plugin/SitemapPackageInstallationPlugin.class.php create mode 100644 wcfsetup/install/files/lib/system/sitemap/ISitemapProvider.class.php create mode 100644 wcfsetup/install/files/lib/system/sitemap/SitemapHandler.class.php 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 index 0000000000..bd0a675bb1 --- /dev/null +++ b/wcfsetup/install/files/lib/data/sitemap/Sitemap.class.php @@ -0,0 +1,49 @@ + + * @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 index 0000000000..aceebf6461 --- /dev/null +++ b/wcfsetup/install/files/lib/data/sitemap/SitemapAction.class.php @@ -0,0 +1,55 @@ + + * @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 index 0000000000..2e0f18598a --- /dev/null +++ b/wcfsetup/install/files/lib/data/sitemap/SitemapEditor.class.php @@ -0,0 +1,20 @@ + + * @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 index 0000000000..4a80631d97 --- /dev/null +++ b/wcfsetup/install/files/lib/data/sitemap/SitemapList.class.php @@ -0,0 +1,15 @@ + + * @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 index 0000000000..1c04f3df59 --- /dev/null +++ b/wcfsetup/install/files/lib/system/cache/builder/SitemapCacheBuilder.class.php @@ -0,0 +1,28 @@ + + * @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 index 0000000000..518dd66851 --- /dev/null +++ b/wcfsetup/install/files/lib/system/package/plugin/SitemapPackageInstallationPlugin.class.php @@ -0,0 +1,93 @@ + + * @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 index 0000000000..27d0a5d70e --- /dev/null +++ b/wcfsetup/install/files/lib/system/sitemap/ISitemapProvider.class.php @@ -0,0 +1,21 @@ + + * @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 index 0000000000..5802fe4c03 --- /dev/null +++ b/wcfsetup/install/files/lib/system/sitemap/SitemapHandler.class.php @@ -0,0 +1,107 @@ + + * @package com.woltlab.wcf + * @subpackage sitemap.sitemap + * @category Community Framework + */ +class SitemapHandler extends SingletonFactory { + /** + * sitemap cache + * @var array + */ + 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 + */ + 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 diff --git a/wcfsetup/setup/db/install.sql b/wcfsetup/setup/db/install.sql index ee57c7d48a..06864c05c9 100644 --- a/wcfsetup/setup/db/install.sql +++ b/wcfsetup/setup/db/install.sql @@ -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; -- 2.20.1