Improve the unattended installation process for developers
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / devtools / DevtoolsSetup.class.php
CommitLineData
f8d85495
AE
1<?php
2namespace wcf\system\devtools;
3use wcf\system\SingletonFactory;
4use wcf\util\FileUtil;
5use wcf\util\JSON;
6
7/**
8 * Enables the rapid deployment of new installations using a central configuration file
9 * in the document root. Requires the developer mode to work.
10 *
11 * @author Alexander Ebert
12 * @copyright 2001-2017 WoltLab GmbH
13 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
14 * @package WoltLabSuite\Core\System\Devtools\Package
15 * @since 3.1
16 */
17class DevtoolsSetup extends SingletonFactory {
18 /**
19 * configuration file in the server's document root
20 * @var string
21 */
22 const CONFIGURATION_FILE = 'wsc-dev-config-31.json';
23
24 /**
25 * configuration data
26 * @var array
27 */
28 protected $configuration = [];
29
30 /**
31 * @inheritDoc
32 */
33 protected function init() {
34 if (empty($_SERVER['DOCUMENT_ROOT'])) return;
35
36 $docRoot = FileUtil::addTrailingSlash(FileUtil::unifyDirSeparator($_SERVER['DOCUMENT_ROOT']));
37 if (!file_exists($docRoot . self::CONFIGURATION_FILE)) return;
38
39 $contents = file_get_contents($docRoot . self::CONFIGURATION_FILE);
40
41 // allow the exception to go rampage
42 $this->configuration = JSON::decode($contents);
43 }
44
45 /**
46 * Returns the database configuration.
47 *
48 * @return array|null
49 */
50 public function getDatabaseConfig() {
51 if (!isset($this->configuration['setup']) || !isset($this->configuration['setup']['database'])) return null;
52
53 // dirname return a single backslash on Windows if there are no parent directories
54 $dir = dirname($_SERVER['SCRIPT_NAME']);
55 $dir = ($dir === '\\') ? '/' : FileUtil::addTrailingSlash($dir);
56 if ($dir === '/') throw new \RuntimeException("Refusing to install in the document root.");
57
58 $dir = FileUtil::removeLeadingSlash(FileUtil::removeTrailingSlash($dir));
59 $dbName = implode('_', explode('/', $dir));
60
61 $dbConfig = $this->configuration['setup']['database'];
62 return [
63 'auto' => $dbConfig['auto'],
64 'host' => $dbConfig['host'],
65 'password' => $dbConfig['password'],
66 'username' => $dbConfig['username'],
67 'dbName' => $dbName,
68 'dbNumber' => $dbConfig['dbNumber']
69 ];
70 }
71
72 /**
73 * Returns true if the suggested default paths for the Core and, if exists,
74 * the bundled app should be used.
75 *
76 * @return boolean
77 */
78 public function useDefaultInstallPath() {
79 return (isset($this->configuration['setup']) && isset($this->configuration['setup']['useDefaultInstallPath']) && $this->configuration['setup']['useDefaultInstallPath'] === true);
80 }
81
82 /**
83 * List of option values that will be set after the setup has completed.
84 *
85 * @return string[]
86 */
87 public function getOptionOverrides() {
88 if (!isset($this->configuration['configuration']) || empty($this->configuration['configuration']['option'])) return [];
89
90 return $this->configuration['configuration']['option'];
91 }
92
93 /**
94 * Returns a list of users that should be automatically created during setup.
95 *
96 * @return array|\Generator
97 */
98 public function getUsers() {
99 if (empty($this->configuration['user'])) return [];
100
101 foreach ($this->configuration['user'] as $user) {
102 if ($user['username'] === 'root') throw new \LogicException("The 'root' user is automatically created.");
103
104 yield [
105 'username' => $user['username'],
106 'password' => $user['password'],
107 'email' => $user['email']
108 ];
109 }
110 }
111
112 /**
113 * Returns the raw configuration data.
114 *
115 * @return array
116 */
117 public function getRawConfiguration() {
118 return $this->configuration;
119 }
120}