]> git.mxchange.org Git - friendica.git/blob - src/Console/AutomaticInstallation.php
Merge pull request #8142 from nupplaphil/task/di_config
[friendica.git] / src / Console / AutomaticInstallation.php
1 <?php
2
3 namespace Friendica\Console;
4
5 use Asika\SimpleConsole\Console;
6 use Friendica\App;
7 use Friendica\App\BaseURL;
8 use Friendica\Core\Config\IConfig;
9 use Friendica\Core\Config\Cache;
10 use Friendica\Core\Installer;
11 use Friendica\Core\Theme;
12 use Friendica\Database\Database;
13 use Friendica\Util\BasePath;
14 use Friendica\Util\ConfigFileLoader;
15 use RuntimeException;
16
17 class AutomaticInstallation extends Console
18 {
19         /** @var App\Mode */
20         private $appMode;
21         /** @var Cache */
22         private $configCache;
23         /** @var IConfig */
24         private $config;
25         /** @var Database */
26         private $dba;
27
28         protected function getHelp()
29         {
30                 return <<<HELP
31 Installation - Install Friendica automatically
32 Synopsis
33         bin/console autoinstall [-h|--help|-?] [-v] [-a] [-f]
34
35 Description
36     Installs Friendica with data based on the local.config.php file or environment variables
37
38 Notes
39     Not checking .htaccess/URL-Rewrite during CLI installation.
40
41 Options
42     -h|--help|-?            Show help information
43     -v                      Show more debug information.
44     -a                      All setup checks are required (except .htaccess)
45     -f|--file <config>      prepared config file (e.g. "config/local.config.php" itself) which will override every other config option - except the environment variables)
46     -s|--savedb               Save the DB credentials to the file (if environment variables is used)
47     -H|--dbhost <host>        The host of the mysql/mariadb database (env MYSQL_HOST)
48     -p|--dbport <port>        The port of the mysql/mariadb database (env MYSQL_PORT)
49     -d|--dbdata <database>    The name of the mysql/mariadb database (env MYSQL_DATABASE)
50     -U|--dbuser <username>    The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
51     -P|--dbpass <password>    The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
52     -U|--url <url>            The full base URL of Friendica - f.e. 'https://friendica.local/sub' (env FRIENDICA_URL) 
53     -B|--phppath <php_path>   The path of the PHP binary (env FRIENDICA_PHP_PATH)
54     -b|--basepath <base_path> The basepath of Friendica (env FRIENDICA_BASE_PATH)
55     -t|--tz <timezone>        The timezone of Friendica (env FRIENDICA_TZ)
56     -L|--lang <language>      The language of Friendica (env FRIENDICA_LANG)
57  
58 Environment variables
59    MYSQL_HOST                  The host of the mysql/mariadb database (mandatory if mysql and environment is used)
60    MYSQL_PORT                  The port of the mysql/mariadb database
61    MYSQL_USERNAME|MYSQL_USER   The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb)
62    MYSQL_PASSWORD              The password of the mysql/mariadb database login
63    MYSQL_DATABASE              The name of the mysql/mariadb database
64    FRIENDICA_URL               The full base URL of Friendica - f.e. 'https://friendica.local/sub'
65    FRIENDICA_PHP_PATH          The path of the PHP binary - leave empty for auto detection
66    FRIENDICA_BASE_PATH         The basepath of Friendica - leave empty for auto detection
67    FRIENDICA_ADMIN_MAIL        The admin email address of Friendica (this email will be used for admin access)
68    FRIENDICA_TZ                The timezone of Friendica
69    FRIENDICA_LANG              The langauge of Friendica
70    
71 Examples
72         bin/console autoinstall -f 'input.config.php
73                 Installs Friendica with the prepared 'input.config.php' file
74
75         bin/console autoinstall --savedb
76                 Installs Friendica with environment variables and saves them to the 'config/local.config.php' file
77
78         bin/console autoinstall -h localhost -p 3365 -U user -P passwort1234 -d friendica
79                 Installs Friendica with a local mysql database with credentials
80 HELP;
81         }
82
83         public function __construct(App\Mode $appMode, Cache $configCache, IConfig $config, Database $dba, array $argv = null)
84         {
85                 parent::__construct($argv);
86
87                 $this->appMode     = $appMode;
88                 $this->configCache = $configCache;
89                 $this->config      = $config;
90                 $this->dba         = $dba;
91         }
92
93         protected function doExecute()
94         {
95                 // Initialise the app
96                 $this->out("Initializing setup...\n");
97
98                 $installer = new Installer();
99
100                 $configCache  = $this->configCache;
101                 $basePathConf = $configCache->get('system', 'basepath');
102                 $basepath     = new BasePath($basePathConf);
103                 $installer->setUpCache($configCache, $basepath->getPath());
104
105                 $this->out(" Complete!\n\n");
106
107                 // Check Environment
108                 $this->out("Checking environment...\n");
109
110                 $installer->resetChecks();
111
112                 if (!$this->runBasicChecks($installer, $configCache)) {
113                         $errorMessage = $this->extractErrors($installer->getChecks());
114                         throw new RuntimeException($errorMessage);
115                 }
116
117                 $this->out(" Complete!\n\n");
118
119                 // if a config file is set,
120                 $config_file = $this->getOption(['f', 'file']);
121
122                 if (!empty($config_file)) {
123
124                         if (!file_exists($config_file)) {
125                                 throw new RuntimeException("ERROR: Config file does not exist.\n");
126                         }
127
128                         //reload the config cache
129                         $loader = new ConfigFileLoader($config_file);
130                         $loader->setupCache($configCache);
131
132                 } else {
133                         // Creating config file
134                         $this->out("Creating config file...\n");
135
136                         $save_db = $this->getOption(['s', 'savedb'], false);
137
138                         $db_host = $this->getOption(['H', 'dbhost'], ($save_db) ? (getenv('MYSQL_HOST')) : Installer::DEFAULT_HOST);
139                         $db_port = $this->getOption(['p', 'dbport'], ($save_db) ? getenv('MYSQL_PORT') : null);
140                         $configCache->set('database', 'hostname', $db_host . (!empty($db_port) ? ':' . $db_port : ''));
141                         $configCache->set('database', 'database',
142                                 $this->getOption(['d', 'dbdata'],
143                                         ($save_db) ? getenv('MYSQL_DATABASE') : ''));
144                         $configCache->set('database', 'username',
145                                 $this->getOption(['U', 'dbuser'],
146                                         ($save_db) ? getenv('MYSQL_USER') . getenv('MYSQL_USERNAME') : ''));
147                         $configCache->set('database', 'password',
148                                 $this->getOption(['P', 'dbpass'],
149                                         ($save_db) ? getenv('MYSQL_PASSWORD') : ''));
150
151                         $php_path = $this->getOption(['b', 'phppath'], !empty('FRIENDICA_PHP_PATH') ? getenv('FRIENDICA_PHP_PATH') : null);
152                         if (!empty($php_path)) {
153                                 $configCache->set('config', 'php_path', $php_path);
154                         } else {
155                                 $configCache->set('config', 'php_path', $installer->getPHPPath());
156                         }
157
158                         $configCache->set('config', 'admin_email',
159                                 $this->getOption(['A', 'admin'],
160                                         !empty(getenv('FRIENDICA_ADMIN_MAIL')) ? getenv('FRIENDICA_ADMIN_MAIL') : ''));
161                         $configCache->set('system', 'default_timezone',
162                                 $this->getOption(['T', 'tz'],
163                                         !empty(getenv('FRIENDICA_TZ')) ? getenv('FRIENDICA_TZ') : Installer::DEFAULT_TZ));
164                         $configCache->set('system', 'language',
165                                 $this->getOption(['L', 'lang'],
166                                         !empty(getenv('FRIENDICA_LANG')) ? getenv('FRIENDICA_LANG') : Installer::DEFAULT_LANG));
167
168                         $basepath = $this->getOption(['b', 'basepath'], !empty(getenv('FRIENDICA_BASE_PATH')) ? getenv('FRIENDICA_BASE_PATH') : null);
169                         if (!empty($basepath)) {
170                                 $configCache->set('system', 'basepath', $basepath);
171                         }
172
173                         $url = $this->getOption(['U', 'url'], !empty(getenv('FRIENDICA_URL')) ? getenv('FRIENDICA_URL') : null);
174
175                         if (empty($url)) {
176                                 $this->out('The Friendica URL has to be set during CLI installation.');
177                                 return 1;
178                         } else {
179                                 $baseUrl = new BaseURL($this->config, []);
180                                 $baseUrl->saveByURL($url);
181                         }
182
183                         $installer->createConfig($configCache);
184                 }
185
186                 $this->out("Complete!\n\n");
187
188                 // Check database connection
189                 $this->out("Checking database...\n");
190
191                 $installer->resetChecks();
192
193                 if (!$installer->checkDB($this->dba)) {
194                         $errorMessage = $this->extractErrors($installer->getChecks());
195                         throw new RuntimeException($errorMessage);
196                 }
197
198                 $this->out(" Complete!\n\n");
199
200                 // Install database
201                 $this->out("Inserting data into database...\n");
202
203                 $installer->resetChecks();
204
205                 if (!$installer->installDatabase($basePathConf)) {
206                         $errorMessage = $this->extractErrors($installer->getChecks());
207                         throw new RuntimeException($errorMessage);
208                 }
209
210                 if (!empty($config_file) && $config_file != 'config' . DIRECTORY_SEPARATOR . 'local.config.php') {
211                         // Copy config file
212                         $this->out("Copying config file...\n");
213                         if (!copy($basePathConf . DIRECTORY_SEPARATOR . $config_file, $basePathConf . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
214                                 throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '" . $basePathConf . "'" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.config.php' manually.\n");
215                         }
216                 }
217
218                 $this->out(" Complete!\n\n");
219
220                 // Install theme
221                 $this->out("Installing theme\n");
222                 if (!empty($this->config->get('system', 'theme'))) {
223                         Theme::install($this->config->get('system', 'theme'));
224                         $this->out(" Complete\n\n");
225                 } else {
226                         $this->out(" Theme setting is empty. Please check the file 'config/local.config.php'\n\n");
227                 }
228
229                 $this->out("\nInstallation is finished\n");
230
231                 return 0;
232         }
233
234         /**
235          * @param Installer $installer   The Installer instance
236          * @param Cache     $configCache The config cache
237          *
238          * @return bool true if checks were successfully, otherwise false
239          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
240          */
241         private function runBasicChecks(Installer $installer, Cache $configCache)
242         {
243                 $checked = true;
244
245                 $installer->resetChecks();
246                 if (!$installer->checkFunctions()) {
247                         $checked = false;
248                 }
249                 if (!$installer->checkImagick()) {
250                         $checked = false;
251                 }
252                 if (!$installer->checkLocalIni()) {
253                         $checked = false;
254                 }
255                 if (!$installer->checkSmarty3()) {
256                         $checked = false;
257                 }
258                 if (!$installer->checkKeys()) {
259                         $checked = false;
260                 }
261
262                 $php_path = $configCache->get('config', 'php_path');
263
264                 if (!$installer->checkPHP($php_path, true)) {
265                         $checked = false;
266                 }
267
268                 $this->out(" NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.\n");
269
270                 return $checked;
271         }
272
273         /**
274          * @param array $results
275          *
276          * @return string
277          */
278         private function extractErrors($results)
279         {
280                 $errorMessage      = '';
281                 $allChecksRequired = $this->getOption('a') !== null;
282
283                 foreach ($results as $result) {
284                         if (($allChecksRequired || $result['required'] === true) && $result['status'] === false) {
285                                 $errorMessage .= "--------\n";
286                                 $errorMessage .= $result['title'] . ': ' . $result['help'] . "\n";
287                         }
288                 }
289
290                 return $errorMessage;
291         }
292 }