<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 -->
--- /dev/null
+{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'}
--- /dev/null
+{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'}
--- /dev/null
+<?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
+ ]);
+ }
+}
--- /dev/null
+<?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
+ ]);
+ }
+}
// 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();
<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>
<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>
<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>