Implemented the 'First Time Setup' page
authorAlexander Ebert <ebert@woltlab.com>
Fri, 11 Jan 2019 12:41:48 +0000 (13:41 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 11 Jan 2019 12:41:48 +0000 (13:41 +0100)
See #2797

wcfsetup/install/files/acp/templates/firstTimeSetup.tpl [new file with mode: 0644]
wcfsetup/install/files/lib/acp/action/InstallPackageAction.class.php
wcfsetup/install/files/lib/acp/form/FirstTimeSetupForm.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/option/OptionHandler.class.php
wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

diff --git a/wcfsetup/install/files/acp/templates/firstTimeSetup.tpl b/wcfsetup/install/files/acp/templates/firstTimeSetup.tpl
new file mode 100644 (file)
index 0000000..1281194
--- /dev/null
@@ -0,0 +1,47 @@
+{include file='header' pageTitle='wcf.acp.option.firstTimeSetup'}
+
+{event name='javascriptInclude'}
+
+<script data-relocate="true">
+       $(function() {
+               new WCF.Option.Handler();
+       });
+       
+       {event name='javascriptInit'}
+</script>
+
+<header class="contentHeader">
+       <div class="contentHeaderTitle">
+               <h1 class="contentTitle">{lang}wcf.acp.option.firstTimeSetup{/lang}</h1>
+               <p class="contentHeaderDescription">{lang}wcf.acp.option.firstTimeSetup.description{/lang}</p>
+       </div>
+       
+       {hascontent}
+               <nav class="contentHeaderNavigation">
+                       <ul>
+                               {content}
+                                       <li><a href="{link}{/link}" class="button"><span class="icon icon16 fa-home"></span> <span>{lang}wcf.global.acp{/lang}</span></a></li>
+                                       
+                                       {event name='contentHeaderNavigation'}
+                               {/content}
+                       </ul>
+               </nav>
+       {/hascontent}
+</header>
+
+{if $success|isset}
+       <p class="success">{lang}wcf.global.success.edit{/lang}</p>
+{/if}
+
+{include file='formError'}
+
+<form method="post" action="{link controller='FirstTimeSetup'}{/link}" enctype="multipart/form-data">
+       {include file='optionFieldList' langPrefix='wcf.acp.option.'}
+       
+       <div class="formSubmit">
+               <input type="submit" value="{lang}wcf.global.button.submit{/lang}" name="__submit" accesskey="s">
+               {@SECURITY_TOKEN_INPUT_TAG}
+       </div>
+</form>
+
+{include file='footer'}
index ea54f4033c2f5033ab14e5733a85fb8c3b99e948..30b887760798aab4abca06ae65d9e4e7fdebe549 100755 (executable)
@@ -132,8 +132,15 @@ class InstallPackageAction extends AbstractDialogAction {
                /** @var Application $application */
                $application = $statement->fetchObject(Application::class);
                
-               // do not use the LinkHandler here as it is sort of unreliable during WCFSetup
-               return $application->getPageURL() . 'acp/index.php?package-list/';
+               $controller = 'package-list';
+               if (WCF::getSession()->getVar('__wcfSetup_completed')) {
+                       $controller = 'first-time-setup';
+                       
+                       WCF::getSession()->unregister('__wcfSetup_completed');
+               }
+               
+               // Do not use the LinkHandler here as it is sort of unreliable during WCFSetup.
+               return $application->getPageURL() . "acp/index.php?{$controller}/";
        }
        
        /**
diff --git a/wcfsetup/install/files/lib/acp/form/FirstTimeSetupForm.class.php b/wcfsetup/install/files/lib/acp/form/FirstTimeSetupForm.class.php
new file mode 100644 (file)
index 0000000..f0a6e98
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+namespace wcf\acp\form;
+use wcf\data\option\OptionAction;
+use wcf\system\option\OptionHandler;
+use wcf\system\style\StyleHandler;
+use wcf\system\WCF;
+
+/**
+ * Shows the option edit form.
+ * 
+ * @author      Alexander Ebert
+ * @copyright   2001-2019 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core\Acp\Form
+ * 
+ * @property OptionHandler $optionHandler
+ */
+class FirstTimeSetupForm extends AbstractOptionListForm {
+       /**
+        * @inheritDoc
+        */
+       public $activeMenuItem = 'wcf.acp.menu.link.configuration';
+       
+       /**
+        * @inheritDoc
+        */
+       public $neededPermissions = ['admin.configuration.canEditOption'];
+       
+       /**
+        * list of options
+        * @var array
+        */
+       public $options = [];
+       
+       /**
+        * @var string[]
+        */
+       public $optionNames = [
+               'page_title',
+               'timezone',
+               'mail_from_name',
+               'mail_from_address',
+               'mail_admin_address',
+               'image_allow_external_source',
+               'module_contact_form',
+               'log_ip_address',
+               'package_server_auth_code',
+       ];
+       
+       /**
+        * @inheritDoc
+        */
+       protected function initOptionHandler() {
+               parent::initOptionHandler();
+               
+               $this->optionHandler->filterOptions($this->optionNames);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readData() {
+               parent::readData();
+               
+               foreach ($this->optionNames as $optionName) {
+                       $this->options[] = $this->optionHandler->getSingleOption($optionName);
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function save() {
+               parent::save();
+               
+               $saveOptions = $this->optionHandler->save('wcf.acp.option', 'wcf.acp.option.option');
+               $this->objectAction = new OptionAction([], 'updateAll', ['data' => $saveOptions]);
+               $this->objectAction->executeAction();
+               $this->saved();
+               
+               WCF::getTPL()->assign('success', true);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign([
+                       'options' => $this->options,
+                       'optionNames' => $this->optionNames,
+               ]);
+       }
+}
index 5319887824195e771636ed6f1e9bad3a07266779..dc951fb0b6dcc425608e6a26284d3e1acccdf000 100644 (file)
@@ -15,7 +15,7 @@ use wcf\util\StringUtil;
  * Handles options.
  * 
  * @author     Alexander Ebert
- * @copyright  2001-2018 WoltLab GmbH
+ * @copyright  2001-2019 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Option
  */
@@ -24,7 +24,7 @@ class OptionHandler implements IOptionHandler {
         * list of application abbreviations
         * @var string[]
         */
-       protected $abbreviations = null;
+       protected $abbreviations;
        
        /**
         * cache class name
@@ -36,25 +36,25 @@ class OptionHandler implements IOptionHandler {
         * list of all option categories
         * @var OptionCategory[]
         */
-       public $cachedCategories = null;
+       public $cachedCategories;
        
        /**
         * list of all options
         * @var Option[]
         */
-       public $cachedOptions = null;
+       public $cachedOptions;
        
        /**
         * category structure
         * @var array
         */
-       public $cachedCategoryStructure = null;
+       public $cachedCategoryStructure;
        
        /**
         * option structure
         * @var array
         */
-       public $cachedOptionToCategories = null;
+       public $cachedOptionToCategories;
        
        /**
         * name of the active option category
@@ -284,6 +284,17 @@ class OptionHandler implements IOptionHandler {
                ];
        }
        
+       /**
+        * Wrapper function to preserve backwards compatibility with the visibility of `getOption()`.
+        * 
+        * @param string $optionName
+        * @return array
+        * @since 3.2
+        */
+       public function getSingleOption($optionName) {
+               return $this->getOption($optionName);
+       }
+       
        /**
         * Validates an option.
         * 
@@ -415,6 +426,18 @@ class OptionHandler implements IOptionHandler {
                }
        }
        
+       /**
+        * Removes any option that is not listed in the provided list.
+        * 
+        * @param string[] $optionNames
+        * @since 5.2
+        */
+       public function filterOptions(array $optionNames) {
+               $this->options = array_filter($this->options, function (Option $option) use ($optionNames) {
+                       return in_array($option->optionName, $optionNames);
+               });
+       }
+       
        /**
         * Creates a list of all active options.
         * 
index e96d535711bd6818b19440973ff1793fc0f1d75d..c6603db27098a3e6a9f7d368576d25ec0b82c905 100644 (file)
@@ -297,6 +297,8 @@ class PackageInstallationDispatcher {
                                        
                                        // update options.inc.php
                                        OptionEditor::resetCache();
+                                       
+                                       WCF::getSession()->register('__wcfSetup_completed', true);
                                }
                                
                                // rebuild application paths
index 723139b71f165fb41140995de0d792693aeebc23..6c74ece735af499780e9caea091a794b86002698 100644 (file)
@@ -1665,6 +1665,8 @@ Als Benachrichtigungs-URL in der Konfiguration der sofortigen Zahlungsbestätigu
                <item name="wcf.acp.option.contact_form_enable_attachments"><![CDATA[Dateianhänge im Kontakt-Formular aktivieren]]></item>
                <item name="wcf.acp.option.contact_form_prune_attachments"><![CDATA[Dateianhänge automatisch entfernen]]></item>
                <item name="wcf.acp.option.contact_form_prune_attachments.description"><![CDATA[Alte Dateianhänge werden nach Ablauf der Frist automatisch gelöscht. [0, um die Löschung zu deaktivieren]]]></item>
+               <item name="wcf.acp.option.firstTimeSetup"><![CDATA[Erstmalige Einrichtung]]></item>
+               <item name="wcf.acp.option.firstTimeSetup.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Konfiguriere{else}Konfigurieren Sie{/if} die wichtigsten Einstellungen, diese können auch später über die Optionen verändert werden.]]></item>
        </category>
        <category name="wcf.acp.customOption">
                <item name="wcf.acp.customOption.list"><![CDATA[Eingabefelder]]></item>
index 0bfc3c11b8180a37f8f16cdf567d79ba1581dafe..031d653b9d4df4d4bb97b7f8d442741a7093f172 100644 (file)
@@ -1650,6 +1650,8 @@ When prompted for the notification URL for the instant payment notifications, pl
                <item name="wcf.acp.option.contact_form_enable_attachments"><![CDATA[Enable attachments for contact messages]]></item>
                <item name="wcf.acp.option.contact_form_prune_attachments"><![CDATA[Prune old attachments]]></item>
                <item name="wcf.acp.option.contact_form_prune_attachments.description"><![CDATA[Older attachments are automatically removed to recover disk space. Use 0 to disable.]]></item>
+               <item name="wcf.acp.option.firstTimeSetup"><![CDATA[First Time Setup]]></item>
+               <item name="wcf.acp.option.firstTimeSetup.description"><![CDATA[Configure the most important settings now, you can change them at any time later.]]></item>
        </category>
        <category name="wcf.acp.customOption">
                <item name="wcf.acp.customOption.list"><![CDATA[Option Fields]]></item>