]> git.mxchange.org Git - friendica.git/blob - src/Module/Install.php
39d6a062afd438cb47437da531660251e4117f14
[friendica.git] / src / Module / Install.php
1 <?php
2
3 namespace Friendica\Module;
4
5 use Friendica\App;
6 use Friendica\BaseModule;
7 use Friendica\Core;
8 use Friendica\Core\Config\Cache\ConfigCache;
9 use Friendica\Core\L10n;
10 use Friendica\Core\Renderer;
11 use Friendica\Network\HTTPException;
12 use Friendica\Util\BasePath;
13 use Friendica\Util\Strings;
14 use Friendica\Util\Temporal;
15
16 class Install extends BaseModule
17 {
18         /**
19          * Step one - System check
20          */
21         const SYSTEM_CHECK = 1;
22         /**
23          * Step two - Base information
24          */
25         const BASE_CONFIG = 2;
26         /**
27          * Step three - Database configuration
28          */
29         const DATABASE_CONFIG = 3;
30         /**
31          * Step four - Adapt site settings
32          */
33         const SITE_SETTINGS = 4;
34         /**
35          * Step five - All steps finished
36          */
37         const FINISHED = 5;
38
39         /**
40          * @var int The current step of the wizard
41          */
42         private static $currentWizardStep;
43
44         /**
45          * @var Core\Installer The installer
46          */
47         private static $installer;
48
49         public static function init()
50         {
51                 $a = self::getApp();
52
53                 if (!$a->getMode()->isInstall()) {
54                         throw new HTTPException\ForbiddenException();
55                 }
56
57                 // route: install/testrwrite
58                 // $baseurl/install/testrwrite to test if rewrite in .htaccess is working
59                 // @TODO: Replace with parameter from router
60                 if ($a->getArgumentValue(1, '') == 'testrewrite') {
61                         // Status Code 204 means that it worked without content
62                         throw new HTTPException\NoContentException();
63                 }
64
65                 self::$installer = new Core\Installer();
66
67                 // get basic installation information and save them to the config cache
68                 $configCache = $a->getConfigCache();
69                 $basePath = new BasePath($a->getBasePath());
70                 self::$installer->setUpCache($configCache, $basePath->getPath());
71
72                 // We overwrite current theme css, because during install we may not have a working mod_rewrite
73                 // so we may not have a css at all. Here we set a static css file for the install procedure pages
74                 Renderer::$theme['stylesheet'] = $a->getBaseURL() . '/view/install/style.css';
75
76                 self::$currentWizardStep = ($_POST['pass'] ?? '') ?: self::SYSTEM_CHECK;
77         }
78
79         public static function post()
80         {
81                 $a           = self::getApp();
82                 $configCache = $a->getConfigCache();
83
84                 switch (self::$currentWizardStep) {
85                         case self::SYSTEM_CHECK:
86                         case self::BASE_CONFIG:
87                                 self::checkSetting($configCache, $_POST, 'config', 'php_path');
88                                 break;
89
90                         case self::DATABASE_CONFIG:
91                                 self::checkSetting($configCache, $_POST, 'config', 'php_path');
92
93                                 self::checkSetting($configCache, $_POST, 'config', 'hostname');
94                                 self::checkSetting($configCache, $_POST, 'system', 'ssl_policy');
95                                 self::checkSetting($configCache, $_POST, 'system', 'basepath');
96                                 self::checkSetting($configCache, $_POST, 'system', 'urlpath');
97                                 break;
98
99                         case self::SITE_SETTINGS:
100                                 self::checkSetting($configCache, $_POST, 'config', 'php_path');
101
102                                 self::checkSetting($configCache, $_POST, 'config', 'hostname');
103                                 self::checkSetting($configCache, $_POST, 'system', 'ssl_policy');
104                                 self::checkSetting($configCache, $_POST, 'system', 'basepath');
105                                 self::checkSetting($configCache, $_POST, 'system', 'urlpath');
106
107                                 self::checkSetting($configCache, $_POST, 'database', 'hostname', Core\Installer::DEFAULT_HOST);
108                                 self::checkSetting($configCache, $_POST, 'database', 'username', '');
109                                 self::checkSetting($configCache, $_POST, 'database', 'password', '');
110                                 self::checkSetting($configCache, $_POST, 'database', 'database', '');
111
112                                 // If we cannot connect to the database, return to the previous step
113                                 if (!self::$installer->checkDB($a->getDBA())) {
114                                         self::$currentWizardStep = self::DATABASE_CONFIG;
115                                 }
116
117                                 break;
118
119                         case self::FINISHED:
120                                 self::checkSetting($configCache, $_POST, 'config', 'php_path');
121
122                                 self::checkSetting($configCache, $_POST, 'config', 'hostname');
123                                 self::checkSetting($configCache, $_POST, 'system', 'ssl_policy');
124                                 self::checkSetting($configCache, $_POST, 'system', 'basepath');
125                                 self::checkSetting($configCache, $_POST, 'system', 'urlpath');
126
127                                 self::checkSetting($configCache, $_POST, 'database', 'hostname', Core\Installer::DEFAULT_HOST);
128                                 self::checkSetting($configCache, $_POST, 'database', 'username', '');
129                                 self::checkSetting($configCache, $_POST, 'database', 'password', '');
130                                 self::checkSetting($configCache, $_POST, 'database', 'database', '');
131
132                                 self::checkSetting($configCache, $_POST, 'system', 'default_timezone', Core\Installer::DEFAULT_TZ);
133                                 self::checkSetting($configCache, $_POST, 'system', 'language', Core\Installer::DEFAULT_LANG);
134                                 self::checkSetting($configCache, $_POST, 'config', 'admin_email', '');
135
136                                 // If we cannot connect to the database, return to the Database config wizard
137                                 if (!self::$installer->checkDB($a->getDBA())) {
138                                         self::$currentWizardStep = self::DATABASE_CONFIG;
139                                         return;
140                                 }
141
142                                 if (!self::$installer->createConfig($configCache)) {
143                                         return;
144                                 }
145
146                                 self::$installer->installDatabase($configCache->get('system', 'basepath'));
147
148                                 break;
149                 }
150         }
151
152         public static function content()
153         {
154                 $a           = self::getApp();
155                 $configCache = $a->getConfigCache();
156
157                 $output = '';
158
159                 $install_title = L10n::t('Friendica Communications Server - Setup');
160
161                 switch (self::$currentWizardStep) {
162                         case self::SYSTEM_CHECK:
163                                 $php_path = $configCache->get('config', 'php_path');
164
165                                 $status = self::$installer->checkEnvironment($a->getBaseURL(), $php_path);
166
167                                 $tpl    = Renderer::getMarkupTemplate('install_checks.tpl');
168                                 $output .= Renderer::replaceMacros($tpl, [
169                                         '$title'       => $install_title,
170                                         '$pass'        => L10n::t('System check'),
171                                         '$checks'      => self::$installer->getChecks(),
172                                         '$passed'      => $status,
173                                         '$see_install' => L10n::t('Please see the file "INSTALL.txt".'),
174                                         '$next'        => L10n::t('Next'),
175                                         '$reload'      => L10n::t('Check again'),
176                                         '$php_path'    => $php_path,
177                                 ]);
178                                 break;
179
180                         case self::BASE_CONFIG:
181                                 $ssl_choices = [
182                                         App\BaseURL::SSL_POLICY_NONE     => L10n::t("No SSL policy, links will track page SSL state"),
183                                         App\BaseURL::SSL_POLICY_FULL     => L10n::t("Force all links to use SSL"),
184                                         App\BaseURL::SSL_POLICY_SELFSIGN => L10n::t("Self-signed certificate, use SSL for local links only \x28discouraged\x29")
185                                 ];
186
187                                 $tpl    = Renderer::getMarkupTemplate('install_base.tpl');
188                                 $output .= Renderer::replaceMacros($tpl, [
189                                         '$title'      => $install_title,
190                                         '$pass'       => L10n::t('Base settings'),
191                                         '$ssl_policy' => ['system-ssl_policy',
192                                                 L10n::t("SSL link policy"),
193                                                 $configCache->get('system', 'ssl_policy'),
194                                                 L10n::t("Determines whether generated links should be forced to use SSL"),
195                                                 $ssl_choices],
196                                         '$hostname'   => ['config-hostname',
197                                                 L10n::t('Host name'),
198                                                 $configCache->get('config', 'hostname'),
199                                                 L10n::t('Overwrite this field in case the determinated hostname isn\'t right, otherweise leave it as is.'),
200                                                 'required'],
201                                         '$basepath'   => ['system-basepath',
202                                                 L10n::t("Base path to installation"),
203                                                 $configCache->get('system', 'basepath'),
204                                                 L10n::t("If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot."),
205                                                 'required'],
206                                         '$urlpath'    => ['system-urlpath',
207                                                 L10n::t('Sub path of the URL'),
208                                                 $configCache->get('system', 'urlpath'),
209                                                 L10n::t('Overwrite this field in case the sub path determination isn\'t right, otherwise leave it as is. Leaving this field blank means the installation is at the base URL without sub path.'),
210                                                 ''],
211                                         '$php_path'   => $configCache->get('config', 'php_path'),
212                                         '$submit'     => L10n::t('Submit'),
213                                 ]);
214                                 break;
215
216                         case self::DATABASE_CONFIG:
217                                 $tpl    = Renderer::getMarkupTemplate('install_db.tpl');
218                                 $output .= Renderer::replaceMacros($tpl, [
219                                         '$title'      => $install_title,
220                                         '$pass'       => L10n::t('Database connection'),
221                                         '$info_01'    => L10n::t('In order to install Friendica we need to know how to connect to your database.'),
222                                         '$info_02'    => L10n::t('Please contact your hosting provider or site administrator if you have questions about these settings.'),
223                                         '$info_03'    => L10n::t('The database you specify below should already exist. If it does not, please create it before continuing.'),
224                                         'checks'      => self::$installer->getChecks(),
225                                         '$hostname'   => $configCache->get('config', 'hostname'),
226                                         '$ssl_policy' => $configCache->get('system', 'ssl_policy'),
227                                         '$basepath'   => $configCache->get('system', 'basepath'),
228                                         '$urlpath'    => $configCache->get('system', 'urlpath'),
229                                         '$dbhost'     => ['database-hostname',
230                                                 L10n::t('Database Server Name'),
231                                                 $configCache->get('database', 'hostname'),
232                                                 '',
233                                                 'required'],
234                                         '$dbuser'     => ['database-username',
235                                                 L10n::t('Database Login Name'),
236                                                 $configCache->get('database', 'username'),
237                                                 '',
238                                                 'required',
239                                                 'autofocus'],
240                                         '$dbpass'     => ['database-password',
241                                                 L10n::t('Database Login Password'),
242                                                 $configCache->get('database', 'password'),
243                                                 L10n::t("For security reasons the password must not be empty"),
244                                                 'required'],
245                                         '$dbdata'     => ['database-database',
246                                                 L10n::t('Database Name'),
247                                                 $configCache->get('database', 'database'),
248                                                 '',
249                                                 'required'],
250                                         '$lbl_10'     => L10n::t('Please select a default timezone for your website'),
251                                         '$php_path'   => $configCache->get('config', 'php_path'),
252                                         '$submit'     => L10n::t('Submit')
253                                 ]);
254                                 break;
255
256                         case self::SITE_SETTINGS:
257                                 /* Installed langs */
258                                 $lang_choices = L10n::getAvailableLanguages();
259
260                                 $tpl    = Renderer::getMarkupTemplate('install_settings.tpl');
261                                 $output .= Renderer::replaceMacros($tpl, [
262                                         '$title'      => $install_title,
263                                         '$checks'     => self::$installer->getChecks(),
264                                         '$pass'       => L10n::t('Site settings'),
265                                         '$hostname'   => $configCache->get('config', 'hostname'),
266                                         '$ssl_policy' => $configCache->get('system', 'ssl_policy'),
267                                         '$basepath'   => $configCache->get('system', 'basepath'),
268                                         '$urlpath'    => $configCache->get('system', 'urlpath'),
269                                         '$dbhost'     => $configCache->get('database', 'hostname'),
270                                         '$dbuser'     => $configCache->get('database', 'username'),
271                                         '$dbpass'     => $configCache->get('database', 'password'),
272                                         '$dbdata'     => $configCache->get('database', 'database'),
273                                         '$adminmail'  => ['config-admin_email',
274                                                 L10n::t('Site administrator email address'),
275                                                 $configCache->get('config', 'admin_email'),
276                                                 L10n::t('Your account email address must match this in order to use the web admin panel.'),
277                                                 'required', 'autofocus', 'email'],
278                                         '$timezone'   => Temporal::getTimezoneField('system-default_timezone',
279                                                 L10n::t('Please select a default timezone for your website'),
280                                                 $configCache->get('system', 'default_timezone'),
281                                                 ''),
282                                         '$language'   => ['system-language',
283                                                 L10n::t('System Language:'),
284                                                 $configCache->get('system', 'language'),
285                                                 L10n::t('Set the default language for your Friendica installation interface and to send emails.'),
286                                                 $lang_choices],
287                                         '$php_path'   => $configCache->get('config', 'php_path'),
288                                         '$submit'     => L10n::t('Submit')
289                                 ]);
290                                 break;
291
292                         case self::FINISHED:
293                                 $db_return_text = "";
294
295                                 if (count(self::$installer->getChecks()) == 0) {
296                                         $txt            = '<p style="font-size: 130%;">';
297                                         $txt            .= L10n::t('Your Friendica site database has been installed.') . EOL;
298                                         $db_return_text .= $txt;
299                                 }
300
301                                 $tpl    = Renderer::getMarkupTemplate('install_finished.tpl');
302                                 $output .= Renderer::replaceMacros($tpl, [
303                                         '$title'  => $install_title,
304                                         '$checks' => self::$installer->getChecks(),
305                                         '$pass'   => L10n::t('Installation finished'),
306                                         '$text'   => $db_return_text . self::whatNext($a),
307                                 ]);
308
309                                 break;
310                 }
311
312                 return $output;
313         }
314
315         /**
316          * Creates the text for the next steps
317          *
318          * @param App $a The global App
319          *
320          * @return string The text for the next steps
321          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
322          */
323         private static function whatNext($a)
324         {
325                 $baseurl = $a->getBaseUrl();
326                 return
327                         L10n::t('<h1>What next</h1>')
328                         . "<p>" . L10n::t('IMPORTANT: You will need to [manually] setup a scheduled task for the worker.')
329                         . L10n::t('Please see the file "INSTALL.txt".')
330                         . "</p><p>"
331                         . L10n::t('Go to your new Friendica node <a href="%s/register">registration page</a> and register as new user. Remember to use the same email you have entered as administrator email. This will allow you to enter the site admin panel.', $baseurl)
332                         . "</p>";
333         }
334
335         /**
336          * Checks the $_POST settings and updates the config Cache for it
337          *
338          * @param ConfigCache $configCache The current config cache
339          * @param array       $post        The $_POST data
340          * @param string      $cat         The category of the setting
341          * @param string      $key         The key of the setting
342          * @param null|string $default     The default value
343          */
344         private static function checkSetting(ConfigCache $configCache, array $post, $cat, $key, $default = null)
345         {
346                 $configCache->set($cat, $key,
347                         Strings::escapeTags(
348                                 trim(($post[sprintf('%s-%s', $cat, $key)] ?? '') ?:
349                                                 ($default ?? $configCache->get($cat, $key))
350                                 )
351                         )
352                 );
353         }
354 }