add sitemap GUI
authorJoshua Rüsweg <josh@bastelstu.be>
Thu, 8 Jun 2017 21:18:39 +0000 (23:18 +0200)
committerJoshua Rüsweg <josh@bastelstu.be>
Thu, 8 Jun 2017 21:18:39 +0000 (23:18 +0200)
see #2286

com.woltlab.wcf/acpMenu.xml
wcfsetup/install/files/acp/templates/sitemapEdit.tpl [new file with mode: 0755]
wcfsetup/install/files/acp/templates/sitemapList.tpl [new file with mode: 0755]
wcfsetup/install/files/lib/acp/form/SitemapEditForm.class.php [new file with mode: 0755]
wcfsetup/install/files/lib/acp/page/SitemapListPage.class.php [new file with mode: 0755]
wcfsetup/install/files/lib/system/worker/SitemapRebuildWorker.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index a640cf8fc78e834e61ff50936a6af80d2cd8608d..088191930df88a4ffe4ec956086eed896cca53e7 100644 (file)
                                <parent>wcf.acp.menu.link.maintenance</parent>
                                <permissions>admin.management.canImportData</permissions>
                        </acpmenuitem>
+                       
+                       <acpmenuitem name="wcf.acp.menu.link.maintenance.sitemap">
+                               <controller>wcf\acp\page\SitemapListPage</controller>
+                               <parent>wcf.acp.menu.link.maintenance</parent>
+                               <permissions>admin.management.canRebuildData</permissions>
+                       </acpmenuitem>
                        <!-- /maintenance -->
                
                        <!-- stat -->
diff --git a/wcfsetup/install/files/acp/templates/sitemapEdit.tpl b/wcfsetup/install/files/acp/templates/sitemapEdit.tpl
new file mode 100755 (executable)
index 0000000..79b4f72
--- /dev/null
@@ -0,0 +1,81 @@
+{include file='header' pageTitle='wcf.acp.sitemap.edit'}
+
+<header class="contentHeader">
+       <div class="contentHeaderTitle">
+               <h1 class="contentTitle">{lang}wcf.acp.sitemap.edit{/lang}</h1>
+       </div>
+       
+       <nav class="contentHeaderNavigation">
+               <ul>
+                       <li><a href="{link controller='SitemapList'}{/link}" class="button"><span class="icon icon16 fa-list"></span> <span>{lang}wcf.acp.menu.link.maintenance.sitemap{/lang}</span></a></li>
+                       
+                       {event name='contentHeaderNavigation'}
+               </ul>
+       </nav>
+</header>
+
+{include file='formError'}
+
+{if $success|isset}
+       <p class="success">{lang}wcf.global.success.edit{/lang}</p>
+{/if}
+
+<form method="post" action="{link controller='SitemapEdit'}objectType={$objectType->objectType}{/link}">
+       <div class="section">
+               <dl{if $errorField == 'priority'} class="formError"{/if}>
+                       <dt><label for="priority">{lang}wcf.acp.sitemap.priority{/lang}</label></dt>
+                       <dd>
+                               <input type="number" id="priority" name="priority" step="0.1" min="0" max="1" value="{$priority}" class="medium"/>
+                               {if $errorField == 'priority'}
+                                       <small class="innerError">
+                                               {lang}wcf.acp.sitemap.priority.error.{$errorType}{/lang}
+                                       </small>
+                               {/if}
+                               <small>{lang}wcf.acp.sitemap.priority.description{/lang}</small>
+                       </dd>
+               </dl>
+               
+               <dl{if $errorField == 'changeFreq'} class="formError"{/if}>
+                       <dt><label for="changeFreq">{lang}wcf.acp.sitemap.changeFreq{/lang}</label></dt>
+                       <dd>
+                               <select id="changeFreq" name="changeFreq">
+                                       {foreach from=$validChangeFreq item="value"}
+                                               <option value="{$value}"{if $value == $changeFreq} selected="selected"{/if}>{lang}wcf.acp.sitemap.changeFreq.{$value}{/lang}</option>
+                                       {/foreach}
+                               </select>
+                               {if $errorField == 'changeFreq'}
+                                       <small class="innerError">
+                                               {if $errorType == 'empty'}{lang}wcf.global.form.error.empty{/lang}{/if}
+                                       </small>
+                               {/if}
+                       </dd>
+               </dl>
+               
+               <dl{if $errorField == 'rebuildTime'} class="formError"{/if}>
+                       <dt><label for="rebuildTime">{lang}wcf.acp.sitemap.rebuildTime{/lang}</label></dt>
+                       <dd>
+                               <div class="inputAddon">
+                                       <input type="number" id="rebuildTime" name="rebuildTime" min="0" value="{$rebuildTime}" class="short">
+                                       <span class="inputSuffix">{lang}wcf.acp.option.suffix.seconds{/lang}</span>
+                               </div>
+                               <small>{lang}wcf.acp.sitemap.rebuildTime.description{/lang}</small>
+                       </dd>
+               </dl>
+               
+               <dl>
+                       <dt></dt>
+                       <dd>
+                               <label><input type="checkbox" id="isDisabled" name="isDisabled" value="1"{if $isDisabled} checked="checked"{/if} /> {lang}wcf.acp.sitemap.isDisabled{/lang}</label>
+                       </dd>
+               </dl>
+       </div>
+       
+       {event name='sections'}
+       
+       <div class="formSubmit">
+               <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
+               {@SECURITY_TOKEN_INPUT_TAG}
+       </div>
+</form>
+
+{include file='footer'}
diff --git a/wcfsetup/install/files/acp/templates/sitemapList.tpl b/wcfsetup/install/files/acp/templates/sitemapList.tpl
new file mode 100755 (executable)
index 0000000..98d6471
--- /dev/null
@@ -0,0 +1,75 @@
+{include file='header' pageTitle='wcf.acp.menu.link.maintenance.sitemap'}
+
+<header class="contentHeader">
+       <div class="contentHeaderTitle">
+               <h1 class="contentTitle">{lang}wcf.acp.menu.link.maintenance.sitemap{/lang}</h1>
+       </div>
+
+       <nav class="contentHeaderNavigation">
+               <ul>
+                       <li><button id="sitemapRebuildButton"><span class="icon icon16 fa-refresh"></span> <span>{lang}wcf.acp.rebuildData.com.woltlab.wcf.sitemap{/lang}</span></button></li>
+
+                       {event name='contentHeaderNavigation'}
+               </ul>
+       </nav>
+</header>
+
+{if $sitemapObjectTypes|count}
+       <div class="section sortableListContainer">
+               <table class="table">
+                       <thead>
+                               <tr>
+                                       <th class="columnTitle columnSitemap" colspan="2">{lang}wcf.acp.sitemap{/lang}</th>
+                                       <th class="columnInteger columnPriority">{lang}wcf.acp.sitemap.priority{/lang}</th>
+                                       <th class="columnText columnChangeFreq">{lang}wcf.acp.sitemap.changeFreq{/lang}</th>
+                                       <th class="columnInteger columnRebuildTime">{lang}wcf.acp.sitemap.rebuildTime{/lang}</th>
+       
+                                       {event name='headColumns'}
+                               </tr>
+                       </thead>
+
+                       <tbody>
+                               {foreach from=$sitemapObjectTypes item=object}
+                                       <tr class="sitemapObjectRow">
+                                               <td class="columnIcon">
+                                                       <a href="{link controller="SitemapEdit"}objectType={$object->objectType}{/link}" title="{lang}wcf.acp.sitemap.{if $object->isDisabled}isDisabled{else}enabled{/if}{/lang}" class="jsTooltip"><span class="icon icon16 fa{if !$object->isDisabled}-check{/if}-square-o"></span></a>
+                                                       <a href="{link controller="SitemapEdit"}objectType={$object->objectType}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip"><span class="icon icon16 fa-pencil"></span></a>
+                                               </td>
+                                               <td class="columnTitle columnSitemap"><a href="{link controller="SitemapEdit"}objectType={$object->objectType}{/link}">{lang}wcf.acp.sitemap.objectType.{$object->objectType}{/lang}</a></td>
+                                               <td class="columnInteger columnPriority">{$object->priority}</td>
+                                               <td class="columnText columnChangeFreq">{lang}wcf.acp.sitemap.changeFreq.{$object->changeFreq}{/lang}</td>
+                                               <td class="columnInteger columnRebuildTime">{@TIME_NOW + $object->rebuildTime|dateDiff:TIME_NOW:true:"format_plain"}</td>
+       
+                                               {event name='columns'}
+                                       </tr>
+                               {/foreach}
+                       </tbody>
+               </table>
+       </div>
+       
+       <footer class="contentFooter">
+               {hascontent}
+                       <nav class="contentFooterNavigation">
+                               <ul>
+                                       {content}{event name='contentFooterNavigation'}{/content}
+                               </ul>
+                       </nav>
+               {/hascontent}
+       </footer>
+{else}
+       <p class="info">{lang}wcf.global.noItems{/lang}</p>
+{/if}
+
+<script data-relocate="true">
+       require(['Language'], function(Language) {
+               Language.add('wcf.acp.worker.abort.confirmMessage', '{lang}wcf.acp.worker.abort.confirmMessage{/lang}');
+               
+               elById("sitemapRebuildButton").addEventListener(WCF_CLICK_EVENT, function () {
+                       new WCF.ACP.Worker('sitemapRebuild', 'wcf\\system\\worker\\SitemapRebuildWorker', '{lang}wcf.acp.rebuildData.com.woltlab.wcf.sitemap{/lang}', {
+                               forceRebuild: true
+                       });
+               });
+       });
+</script>
+
+{include file='footer'}
diff --git a/wcfsetup/install/files/lib/acp/form/SitemapEditForm.class.php b/wcfsetup/install/files/lib/acp/form/SitemapEditForm.class.php
new file mode 100755 (executable)
index 0000000..a2d48ce
--- /dev/null
@@ -0,0 +1,183 @@
+<?php
+namespace wcf\acp\form;
+use wcf\data\object\type\ObjectType;
+use wcf\data\object\type\ObjectTypeAction;
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\form\AbstractForm;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\UserInputException;
+use wcf\system\WCF;
+
+/**
+ * Shows the sitemap edit form.
+ * 
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Acp\Form
+ * @since      3.1
+ */
+class SitemapEditForm extends AbstractForm {
+       /**
+        * @inheritDoc
+        */
+       public $templateName = 'sitemapEdit';
+       
+       /**
+        * @inheritDoc
+        */
+       public $activeMenuItem = 'wcf.acp.menu.link.maintenance';
+       
+       /**
+        * @inheritDoc
+        */
+       public $neededPermissions = ['admin.management.canRebuildData'];
+
+       /**
+        * The sitemap object type name.
+        * @var string
+        */
+       public $objectTypeName = null;
+
+       /**
+        * The sitemap object type.
+        * @var ObjectType
+        */
+       public $objectType = null;
+       
+       /**
+        * The priority for this sitemap object.
+        * @var float
+        */
+       public $priority = 0.5;
+       
+       /**
+        * The changeFreq for this sitemap object.
+        * @var string
+        */
+       public $changeFreq = 'monthly';
+       
+       /**
+        * An array with valid changeFreq values.
+        *
+        * @var array<string>
+        */
+       public $validChangeFreq = [
+               'always',
+               'hourly',
+               'daily',
+               'weekly',
+               'monthly',
+               'yearly',
+               'never'
+       ];
+       
+       /**
+        * `1` iff the sitemap is disabled. Otherwise `0`.
+        * @var integer
+        */
+       public $isDisabled = 0;
+
+       /**
+        * The time in seconds how long the sitemap should be cached. 
+        * @var integer
+        */
+       public $rebuildTime = 172800; // two days
+       
+       /**
+        * @inheritDoc
+        */
+       public function readParameters() {
+               parent::readParameters();
+               
+               if (isset($_GET['objectType'])) $this->objectTypeName = $_GET['objectType'];
+               $this->objectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.sitemap.object', $this->objectTypeName);
+               
+               if ($this->objectType === null) {
+                       throw new IllegalLinkException();
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readData() {
+               parent::readData();
+               
+               if (empty($_POST)) {
+                       if ($this->objectType->priority !== null) $this->priority = $this->objectType->priority; 
+                       if ($this->objectType->changeFreq !== null) $this->changeFreq = $this->objectType->changeFreq; 
+                       if ($this->objectType->rebuildTime !== null) $this->rebuildTime = $this->objectType->rebuildTime; 
+                       if ($this->objectType->isDisabled !== null) $this->isDisabled = $this->objectType->isDisabled;
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readFormParameters() {
+               parent::readFormParameters();
+               
+               if (isset($_POST['priority'])) $this->priority = floatval($_POST['priority']);
+               if (isset($_POST['changeFreq'])) $this->changeFreq = $_POST['changeFreq'];
+               if (isset($_POST['rebuildTime'])) $this->rebuildTime = intval($_POST['rebuildTime']);
+               $this->isDisabled = (isset($_POST['isDisabled'])) ? 1 : 0;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function validate() {
+               parent::validate();
+               
+               if ($this->priority > 1 || $this->priority < 0) {
+                       throw new UserInputException('priority', 'invalid');
+               }
+               
+               if (!in_array($this->changeFreq, $this->validChangeFreq)) {
+                       throw new UserInputException('changeFreq');
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function save() {
+               parent::save();
+               
+               $data = array_merge($this->objectType->additionalData, [
+                       'priority' => $this->priority,
+                       'changeFreq' => $this->changeFreq,
+                       'rebuildTime' => $this->rebuildTime,
+                       'isDisabled' => $this->isDisabled
+               ]);
+               
+               (new ObjectTypeAction([$this->objectType], 'update', [
+                       'data' => [
+                               'additionalData' => serialize($data)
+                       ]
+               ]))->executeAction();
+               
+               $this->saved();
+               
+               WCF::getTPL()->assign([
+                       'success' => true
+               ]);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign([
+                       'objectType' => $this->objectType,
+                       'priority' => $this->priority,
+                       'changeFreq' => $this->changeFreq,
+                       'rebuildTime' => $this->rebuildTime,
+                       'validChangeFreq' => $this->validChangeFreq,
+                       'isDisabled' => $this->isDisabled
+               ]);
+       }
+}
diff --git a/wcfsetup/install/files/lib/acp/page/SitemapListPage.class.php b/wcfsetup/install/files/lib/acp/page/SitemapListPage.class.php
new file mode 100755 (executable)
index 0000000..d2e1cbb
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+namespace wcf\acp\page;
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\page\AbstractPage;
+use wcf\system\WCF;
+
+/**
+ * Shows a list of sitemap object types. 
+ * 
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Acp\page
+ * @since      3.1
+ */
+class SitemapListPage extends AbstractPage {
+       /**
+        * @inheritDoc
+        */
+       public $activeMenuItem = 'wcf.acp.menu.link.maintenance.sitemap';
+       
+       /**
+        * @inheritDoc
+        */
+       public $neededPermissions = ['admin.management.canRebuildData'];
+       
+       /**
+        * @var array<ObjectType>
+        */
+       public $sitemapObjectTypes = [];
+       
+       /**
+        * @inheritDoc
+        */
+       public function readData() {
+               parent::readData();
+               
+               $this->sitemapObjectTypes = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.sitemap.object');
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+
+               WCF::getTPL()->assign([
+                       'sitemapObjectTypes' => $this->sitemapObjectTypes
+               ]);
+       }
+}
index 73bd0320e44cbaf6127fce7df8820a97e16af290..9baa3400516363c6f057886caba288bcbb0b91dd 100755 (executable)
@@ -59,7 +59,7 @@ class SitemapRebuildWorker extends AbstractWorker {
                        // read sitemaps
                        $sitemapObjects = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.sitemap.object');
                        foreach ($sitemapObjects as $sitemapObject) {
-                               if ($sitemapObject->enabled === null || $sitemapObject->enabled) {
+                               if ($sitemapObject->isDisabled === null || !$sitemapObject->isDisabled) {
                                        $this->sitemapObjects[] = $sitemapObject;
                                        
                                        $processor = $sitemapObject->getProcessor();
index bf1af4eac854372e3cc284ae27f169b01cc307d5..2e9503537497a792ef519f10952cd13ca79ead36 100644 (file)
                <item name="wcf.acp.menu.link.article.add"><![CDATA[Artikel hinzufügen]]></item>
                <item name="wcf.acp.menu.link.article.category.list"><![CDATA[Kategorien]]></item>
                <item name="wcf.acp.menu.link.article.category.add"><![CDATA[Kategorie hinzufügen]]></item>
+               <item name="wcf.acp.menu.link.maintenance.sitemap"><![CDATA[Sitemaps]]></item>
                <item name="wcf.acp.menu.add"><![CDATA[Menü hinzufügen]]></item>
                <item name="wcf.acp.menu.delete.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} das Menü <span class="confirmationObject">{lang}{$menu->title}{/lang}</span> wirklich löschen?]]></item>
                <item name="wcf.acp.menu.edit"><![CDATA[Menü bearbeiten]]></item>
@@ -1577,6 +1578,26 @@ GmbH=Gesellschaft mit beschränkter Haftung]]></item>
                <item name="wcf.acp.search.result.subtitle"><![CDATA[{implode from=$pieces item=piece glue=' » '}{$piece|language}{/implode}]]></item>
        </category>
        
+       <category name="wcf.acp.sitemap">
+               <item name="wcf.acp.sitemap"><![CDATA[Sitemap]]></item>
+               <item name="wcf.acp.sitemap.priority"><![CDATA[Priorität]]></item>
+               <item name="wcf.acp.sitemap.priority.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Gebe{else}Geben Sie{/if} hier die Priorität der Einträge in dieser Sitemap an. Gültige Werte liegen zwischen 0,0 und 1,0.]]></item>
+               <item name="wcf.acp.sitemap.priority.error.invalid"><![CDATA[Der Wert muss zwischen 0,0 und 1,0 liegen.]]></item>
+               <item name="wcf.acp.sitemap.changeFreq"><![CDATA[Änderungsfrequenz]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.always"><![CDATA[Immer]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.hourly"><![CDATA[Stündlich]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.daily"><![CDATA[Täglich]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.weekly"><![CDATA[Wöchentlich]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.monthly"><![CDATA[Monatlich]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.yearly"><![CDATA[Jährlich]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.never"><![CDATA[Nie]]></item>
+               <item name="wcf.acp.sitemap.rebuildTime"><![CDATA[Erneuerungszeit]]></item>
+               <item name="wcf.acp.sitemap.rebuildTime.description"><![CDATA[Die Zeit nachdem die Sitemap erneuert werden soll.]]></item>
+               <item name="wcf.acp.sitemap.isDisabled"><![CDATA[Sitemap deaktiviert]]></item>
+               <item name="wcf.acp.sitemap.enabled"><![CDATA[Sitemap aktiviert]]></item>
+               <item name="wcf.acp.sitemap.edit"><![CDATA[Sitemap bearbeiten]]></item>
+       </category>
+       
        <category name="wcf.acp.stat">
                <item name="wcf.acp.stat"><![CDATA[Statistiken]]></item>
                <item name="wcf.acp.stat.settings"><![CDATA[Einstellungen]]></item>
index 7ebcf86592110ed9b5e6121e6e4652ce4fe0b85f..420459a321f0deb449c5eb2d996eff4bae5cccff 100644 (file)
                <item name="wcf.acp.menu.link.article.add"><![CDATA[Add Article]]></item>
                <item name="wcf.acp.menu.link.article.category.list"><![CDATA[Categories]]></item>
                <item name="wcf.acp.menu.link.article.category.add"><![CDATA[Add Category]]></item>
+               <item name="wcf.acp.menu.link.maintenance.sitemap"><![CDATA[Sitemaps]]></item>
                <item name="wcf.acp.menu.add"><![CDATA[Add Menu]]></item>
                <item name="wcf.acp.menu.delete.confirmMessage"><![CDATA[Do you really want to delete the menu <span class="confirmationObject">{lang}{$menu->title}{/lang}</span>?]]></item>
                <item name="wcf.acp.menu.edit"><![CDATA[Edit Menu]]></item>
                <item name="wcf.acp.search.result.subtitle"><![CDATA[{implode from=$pieces item=piece glue=' » '}{$piece|language}{/implode}]]></item>
        </category>
        
+       <category name="wcf.acp.sitemap">
+               <item name="wcf.acp.sitemap"><![CDATA[Sitemap]]></item>
+               <item name="wcf.acp.sitemap.priority"><![CDATA[Priority]]></item>
+               <item name="wcf.acp.sitemap.priority.description"><![CDATA[The priority of the sitemap items. The value must be between 0.0 and 1.0.]]></item>
+               <item name="wcf.acp.sitemap.priority.error.invalid"><![CDATA[The value must be between 0.0 and 1.0.]]></item>
+               <item name="wcf.acp.sitemap.changeFreq"><![CDATA[Change Frequency]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.always"><![CDATA[Always]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.hourly"><![CDATA[Hourly]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.daily"><![CDATA[Daily]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.weekly"><![CDATA[Weekly]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.monthly"><![CDATA[Monthly]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.yearly"><![CDATA[Yearly]]></item>
+               <item name="wcf.acp.sitemap.changeFreq.never"><![CDATA[Never]]></item>
+               <item name="wcf.acp.sitemap.rebuildTime"><![CDATA[Rebuild Time]]></item>
+               <item name="wcf.acp.sitemap.rebuildTime.description"><![CDATA[The time after the sitemap have to be rebuilded.]]></item>
+               <item name="wcf.acp.sitemap.isDisabled"><![CDATA[Disable Sitemap]]></item>
+               <item name="wcf.acp.sitemap.enabled"><![CDATA[Sitemap enabled]]></item>
+               <item name="wcf.acp.sitemap.edit"><![CDATA[Edit Sitemap]]></item>
+       </category>
+       
        <category name="wcf.acp.stat">
                <item name="wcf.acp.stat"><![CDATA[Statistics]]></item>
                <item name="wcf.acp.stat.settings"><![CDATA[Settings]]></item>