XBackBone/install/index.php

230 lines
8.8 KiB
PHP
Raw Normal View History

2018-11-15 15:08:11 +00:00
<?php
2019-11-20 17:49:31 +00:00
2019-05-09 10:51:33 +00:00
(PHP_MAJOR_VERSION >= 7 && PHP_MINOR_VERSION >= 1) ?: die('Sorry, PHP 7.1 or above is required to run XBackBone.');
2019-11-13 12:02:31 +00:00
require __DIR__.'/../vendor/autoload.php';
2018-11-15 15:08:11 +00:00
use App\Database\DB;
2019-11-13 12:02:31 +00:00
use App\Database\Migrator;
use App\Factories\ViewFactory;
2018-11-15 15:08:11 +00:00
use App\Web\Session;
2019-11-13 12:02:31 +00:00
use App\Web\View;
use DI\Bridge\Slim\Bridge;
use DI\ContainerBuilder;
2019-11-20 17:49:31 +00:00
use function DI\factory;
use function DI\get;
use function DI\value;
use League\Flysystem\FileExistsException;
use League\Flysystem\Filesystem;
2019-11-13 12:02:31 +00:00
use Psr\Container\ContainerInterface as Container;
use Psr\Http\Message\ResponseInterface as Response;
2019-11-18 10:42:42 +00:00
use Psr\Http\Message\ServerRequestInterface as Request;
2018-11-15 15:08:11 +00:00
2019-11-13 12:02:31 +00:00
define('PLATFORM_VERSION', json_decode(file_get_contents(__DIR__.'/../composer.json'))->version);
define('BASE_DIR', realpath(__DIR__.'/../').DIRECTORY_SEPARATOR);
2018-11-15 15:08:11 +00:00
2019-09-14 12:50:14 +00:00
// default config
2019-11-21 17:00:47 +00:00
$config = [
2019-11-18 10:42:42 +00:00
'base_url' => str_replace('/install/', '', (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http')."://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"),
2019-11-20 17:49:31 +00:00
'debug' => true,
2019-11-21 17:00:47 +00:00
'db' => [
2019-11-13 12:02:31 +00:00
'connection' => 'sqlite',
2019-11-21 17:00:47 +00:00
'dsn' => realpath(__DIR__.'/../').implode(DIRECTORY_SEPARATOR, ['resources', 'database', 'xbackbone.db']),
2019-11-20 17:49:31 +00:00
'username' => null,
'password' => null,
2019-11-21 17:00:47 +00:00
],
'storage' => [
2019-11-13 12:02:31 +00:00
'driver' => 'local',
2019-11-20 17:49:31 +00:00
'path' => realpath(__DIR__.'/../').DIRECTORY_SEPARATOR.'storage',
2019-11-21 17:00:47 +00:00
],
];
2018-11-15 15:08:11 +00:00
2019-11-13 12:02:31 +00:00
if (file_exists(__DIR__.'/../config.php')) {
$config = array_replace_recursive($config, require __DIR__.'/../config.php');
}
2019-11-13 12:02:31 +00:00
$builder = new ContainerBuilder();
2019-11-21 17:00:47 +00:00
$builder->addDefinitions([
2019-11-20 17:49:31 +00:00
'config' => value($config),
2019-11-19 11:32:58 +00:00
View::class => factory(function (Container $container) {
2019-11-13 12:02:31 +00:00
return ViewFactory::createInstallerInstance($container);
}),
2019-11-19 11:32:58 +00:00
'view' => get(View::class),
2019-11-21 17:00:47 +00:00
]);
2019-11-19 11:32:58 +00:00
$builder->addDefinitions(__DIR__.'/../bootstrap/container.php');
2019-11-13 12:02:31 +00:00
$app = Bridge::create($builder->build());
2019-11-18 10:42:42 +00:00
$app->setBasePath(parse_url($config['base_url'].'/install', PHP_URL_PATH));
2019-11-13 12:02:31 +00:00
$app->addRoutingMiddleware();
2019-11-18 10:42:42 +00:00
$app->get('/', function (Response $response, View $view, Session $session) use (&$config) {
2019-11-13 12:02:31 +00:00
if (!extension_loaded('gd')) {
$session->alert('The required "gd" extension is not loaded.', 'danger');
}
if (!extension_loaded('intl')) {
$session->alert('The required "intl" extension is not loaded.', 'danger');
}
if (!extension_loaded('json')) {
$session->alert('The required "json" extension is not loaded.', 'danger');
}
if (!extension_loaded('fileinfo')) {
$session->alert('The required "fileinfo" extension is not loaded.', 'danger');
}
if (!is_writable(__DIR__.'/../resources/cache')) {
$session->alert('The cache folder is not writable ('.__DIR__.'/../resources/cache'.')', 'danger');
}
if (!is_writable(__DIR__.'/../resources/database')) {
$session->alert('The database folder is not writable ('.__DIR__.'/../resources/database'.')', 'danger');
}
if (!is_writable(__DIR__.'/../resources/sessions')) {
$session->alert('The sessions folder is not writable ('.__DIR__.'/../resources/sessions'.')', 'danger');
}
$installed = file_exists(__DIR__.'/../config.php');
2019-11-21 17:00:47 +00:00
return $view->render($response, 'install.twig', [
2019-11-19 11:32:58 +00:00
'installed' => $installed,
2019-11-21 17:00:47 +00:00
]);
})->setName('install');
2018-11-15 15:08:11 +00:00
2019-11-18 10:42:42 +00:00
$app->post('/', function (Request $request, Response $response, Filesystem $storage, Session $session) use (&$config) {
2019-11-13 12:02:31 +00:00
// Check if there is a previous installation, if not, setup the config file
$installed = true;
2019-11-22 11:21:02 +00:00
// disable debug in production
unset($config['debug']);
2019-11-13 12:02:31 +00:00
if (!file_exists(__DIR__.'/../config.php')) {
$installed = false;
// config file setup
2019-11-18 10:42:42 +00:00
$config['base_url'] = param($request, 'base_url');
2019-11-13 12:02:31 +00:00
$config['storage']['driver'] = param($request, 'storage_driver');
$config['db']['connection'] = param($request, 'connection');
$config['db']['dsn'] = param($request, 'dsn');
$config['db']['username'] = param($request, 'db_user');
$config['db']['password'] = param($request, 'db_password');
// setup storage configuration
switch ($config['storage']['driver']) {
case 's3':
$config['storage']['key'] = param($request, 'storage_key');
$config['storage']['secret'] = param($request, 'storage_secret');
$config['storage']['region'] = param($request, 'storage_region');
$config['storage']['bucket'] = param($request, 'storage_bucket');
$config['storage']['path'] = param($request, 'storage_path');
break;
case 'dropbox':
$config['storage']['token'] = param($request, 'storage_token');
break;
case 'ftp':
if (!extension_loaded('ftp')) {
$session->alert('The "ftp" extension is not loaded.', 'danger');
2019-11-20 17:49:31 +00:00
2019-11-18 10:42:42 +00:00
return redirect($response, urlFor('/'));
}
2019-11-13 12:02:31 +00:00
$config['storage']['host'] = param($request, 'storage_host');
$config['storage']['username'] = param($request, 'storage_username');
$config['storage']['password'] = param($request, 'storage_password');
$config['storage']['port'] = param($request, 'storage_port');
$config['storage']['path'] = param($request, 'storage_path');
$config['storage']['passive'] = param($request, 'storage_passive') === '1';
$config['storage']['ssl'] = param($request, 'storage_ssl') === '1';
break;
case 'google-cloud':
$config['storage']['project_id'] = param($request, 'storage_project_id');
$config['storage']['key_path'] = param($request, 'storage_key_path');
$config['storage']['bucket'] = param($request, 'storage_bucket');
break;
case 'local':
default:
$config['storage']['path'] = param($request, 'storage_path');
break;
}
}
2019-11-13 12:02:31 +00:00
// check if the storage is valid
$storageTestFile = 'storage_test.xbackbone.txt';
2019-11-20 17:49:31 +00:00
try {
2019-11-13 12:02:31 +00:00
try {
$success = $storage->write($storageTestFile, 'XBACKBONE_TEST_FILE');
} catch (FileExistsException $fileExistsException) {
$success = $storage->update($storageTestFile, 'XBACKBONE_TEST_FILE');
2019-11-13 12:02:31 +00:00
}
if (!$success) {
throw new Exception('The storage is not writable.');
2019-11-13 12:02:31 +00:00
}
$storage->readAndDelete($storageTestFile);
} catch (Exception $e) {
$session->alert("Storage setup error: {$e->getMessage()} [{$e->getCode()}]", 'danger');
2019-11-20 17:49:31 +00:00
2019-11-18 10:42:42 +00:00
return redirect($response, urlFor('/install'));
2019-11-13 12:02:31 +00:00
}
// if from older installations with no support of other than local driver
// update the config
if ($installed && isset($config['storage_dir'])) {
$config['storage']['driver'] = 'local';
$config['storage']['path'] = $config['storage_dir'];
unset($config['storage_dir']);
}
// Build the dns string and run the migrations
try {
$firstMigrate = false;
if ($config['db']['connection'] === 'sqlite' && !file_exists(__DIR__.'/../'.$config['db']['dsn'])) {
touch(__DIR__.'/../'.$config['db']['dsn']);
$firstMigrate = true;
}
2019-11-18 10:42:42 +00:00
$db = new DB(dsnFromConfig($config), $config['db']['username'], $config['db']['password']);
2019-11-13 12:02:31 +00:00
$migrator = new Migrator($db, __DIR__.'/../resources/schemas', $firstMigrate);
$migrator->migrate();
} catch (PDOException $e) {
$session->alert("Cannot connect to the database: {$e->getMessage()} [{$e->getCode()}]", 'danger');
2019-11-20 17:49:31 +00:00
2019-11-18 10:42:42 +00:00
return redirect($response, urlFor('/install'));
2019-11-13 12:02:31 +00:00
}
// if not installed, create the default admin account
if (!$installed) {
2019-11-21 17:00:47 +00:00
$db->query("INSERT INTO `users` (`email`, `username`, `password`, `is_admin`, `user_code`) VALUES (?, 'admin', ?, 1, ?)", [param($request, 'email'), password_hash(param($request, 'password'), PASSWORD_DEFAULT), humanRandomString(5)]);
2019-11-13 12:02:31 +00:00
}
// post install cleanup
cleanDirectory(__DIR__.'/../resources/cache');
cleanDirectory(__DIR__.'/../resources/sessions');
2019-11-19 14:19:47 +00:00
removeDirectory(__DIR__.'/../install');
2019-11-13 12:02:31 +00:00
// if is upgrading and existing installation, put it out maintenance
if ($installed) {
unset($config['maintenance']);
2019-11-19 12:59:17 +00:00
unset($config['lang']);
}
2019-11-13 12:02:31 +00:00
// Finally write the config
$ret = file_put_contents(__DIR__.'/../config.php', '<?php'.PHP_EOL.'return '.var_export($config, true).';');
if ($ret === false) {
$session->alert('The config folder is not writable ('.__DIR__.'/../config.php'.')', 'danger');
2019-11-20 17:49:31 +00:00
return redirect($response, '/install');
2019-11-13 12:02:31 +00:00
}
// Installed successfully, destroy the installer session
2019-11-15 16:08:07 +00:00
$session->destroy();
2019-11-20 17:49:31 +00:00
2019-11-18 10:42:42 +00:00
return redirect($response, urlFor('/?afterInstall=true'));
2018-11-15 15:08:11 +00:00
});
2019-11-20 17:49:31 +00:00
$app->run();