protected function initializeDatabase() { $database = Installer::createDatabase($this->getConfiguration()); Installer::createAdministratorProfile($this->getConfiguration(), $database, static::ADMINISTRATOR_EMAIL, static::ADMINISTRATOR_PASSWORD); unset($database); return parent::initializeDatabase(); }
/** * Main method. * * @return int */ function main() { $verbose = !(Console::isDirect(STDOUT) || !OS_WIN); while (false !== ($c = $this->getOption($v))) { switch ($c) { case '__ambiguous': $this->resolveOptionAmbiguity($v); break; case 'v': $verbose = $v; break; case 'h': case '?': default: return $this->usage(); } } if (true === Installer::isInstalled()) { echo 'The application is already installed.', "\n"; return 1; } $oldTitle = Window::getTitle(); Window::setTitle('Installation of sabre/katana'); $form = ['baseUrl' => '/', 'email' => null, 'password' => null, 'database' => ['driver' => 'sqlite', 'host' => '', 'port' => '', 'name' => '', 'username' => '', 'password' => '']]; $readline = new Console\Readline(); if (true === $verbose) { $windowWidth = Window::getSize()['x']; $labelMaxWidth = 35; $inputMaxWidth = $windowWidth - $labelMaxWidth; $numberOfSteps = 5; $input = function ($default = '') use($inputMaxWidth) { return Text::colorize($default . str_repeat(' ', $inputMaxWidth - mb_strlen($default)), 'foreground(black) background(#cccccc)'); }; $resetInput = function ($default = '') use($input, $labelMaxWidth) { Cursor::move('→', $labelMaxWidth); echo $input($default); Cursor::move('LEFT'); Cursor::move('→', $labelMaxWidth); Cursor::colorize('foreground(black) background(#cccccc)'); }; echo Text::colorize('Installation of sabre/' . "\n" . Welcome::LOGO, 'foreground(yellow)'), "\n\n", static::getBaseURLInfo(), "\n\n", 'Choose the base URL: ', $input('/'), "\n", 'Your administrator login: '******'Choose the administrator password: '******'Choose the administrator email: ', $input(), "\n", 'Choose the database driver: ', '🔘 SQLite ⚪️ MySQL', "\n"; Window::scroll('↑', 10); Cursor::move('↑', 10); Cursor::move('↑', $numberOfSteps); Cursor::move('→', $labelMaxWidth); // Disable arrow up and down. $no_echo = function ($readline) { return $readline::STATE_NO_ECHO; }; $readline->addMapping("[A", $no_echo); $readline->addMapping("[B", $no_echo); $step = function ($index, $label, callable $validator, $errorMessage, $default = '') use($numberOfSteps, &$readline, $resetInput, $labelMaxWidth) { Cursor::colorize('foreground(black) background(#cccccc)'); do { $out = $readline->readLine(); if (empty($out)) { $out = $default; } $valid = $validator($out); if (true !== $valid) { Cursor::move('↑'); $resetInput($default); Cursor::save(); Cursor::move('LEFT'); Cursor::move('↓', $numberOfSteps - $index + 1); list($title, $message) = explode("\n", $errorMessage); Cursor::colorize('foreground(white) background(red)'); echo $title, "\n"; Cursor::colorize('foreground(red) background(normal)'); echo $message; Cursor::restore(); } else { Cursor::save(); Cursor::move('LEFT'); Cursor::move('↓', $numberOfSteps - $index - 1); Cursor::colorize('normal'); Cursor::clear('↓'); Cursor::restore(); } } while (true !== $valid); if ($numberOfSteps !== $index + 1) { Cursor::move('→', $labelMaxWidth); } Cursor::colorize('normal'); return $out; }; $progress = function ($percent, $message) use($windowWidth) { static $margin = 4; $barWidth = $windowWidth - $margin * 2; Cursor::move('LEFT'); Cursor::move('↑', 1); Cursor::clear('↓'); if ($percent <= 0) { $color = '#c74844'; } elseif ($percent <= 25) { $color = '#cb9a3d'; } elseif ($percent <= 50) { $color = '#dcb11e'; } elseif ($percent <= 75) { $color = '#aed633'; } else { $color = '#54b455'; } echo str_repeat(' ', $margin); Cursor::colorize('foreground(' . $color . ') background(' . $color . ')'); echo str_repeat('|', $percent * $barWidth / 100); Cursor::move('LEFT ↓'); Cursor::colorize('background(normal)'); echo str_repeat(' ', $margin) . $message; Cursor::colorize('normal'); sleep(1); }; } else { echo 'Installation of sabre/' . "\n" . Welcome::LOGO, "\n\n", static::getBaseURLInfo(), "\n\n"; $step = function ($index, $label, callable $validator, $errorMessage, $default = '') use(&$readline) { do { echo $label; if (!empty($default)) { echo ' [default: ', $default, ']'; } $out = $readline->readLine(': '); if (empty($out)) { $out = $default; } $valid = $validator($out); if (true !== $valid) { echo $errorMessage, "\n"; } } while (true !== $valid); return $out; }; $progress = function ($percent, $message) { echo $message, "\n"; }; } $form['baseUrl'] = $step(0, 'Choose the base URL', function ($baseUrl) use($verbose) { $valid = Installer::checkBaseUrl($baseUrl); if (true === $valid && true === $verbose) { Cursor::move('↓'); } return $valid; }, 'Base URL must start and end by a slash' . "\n" . 'Check the Section “The base URL” on http://sabre.io/dav/gettingstarted/.', '/'); if (false === $verbose) { echo 'Your administrator login: '******'password'] = $step(1, 'Choose the administrator password', function ($administratorPassword) { return Installer::checkPassword($administratorPassword . $administratorPassword); }, 'Password must not be empty' . "\n" . 'An empty password is not a password anymore!'); $readline = $oldReadline; $form['email'] = $step(2, 'Choose the administrator email', function ($administratorEmail) { return Installer::checkEmail($administratorEmail . $administratorEmail); }, 'Email is invalid' . "\n" . 'The given email seems invalid.'); $databaseDriver =& $form['database']['driver']; if (true === $verbose) { $radioReadline = new Console\Readline\Password(); $radioReadline->addMapping('\\e[D', function () use($labelMaxWidth, &$databaseDriver) { $databaseDriver = 'sqlite'; Cursor::save(); Cursor::move('LEFT'); Cursor::move('→', $labelMaxWidth); Cursor::clear('→'); echo '🔘 SQLite ⚪️ MySQL'; Cursor::restore(); }); $radioReadline->addMapping('\\e[C', function () use($labelMaxWidth, &$databaseDriver) { $databaseDriver = 'mysql'; Cursor::save(); Cursor::move('LEFT'); Cursor::move('→', $labelMaxWidth); Cursor::clear('→'); echo '⚪️ SQLite 🔘 MySQL'; Cursor::restore(); }); Cursor::hide(); $radioReadline->readLine(); Cursor::show(); unset($databaseDriver); if ('mysql' === $form['database']['driver']) { echo 'Choose MySQL host: ', $input(), "\n", 'Choose MySQL port: ', $input('3306'), "\n", 'Choose MySQL username: '******'Choose MySQL password: '******'Choose MySQL database name: ', $input(), "\n"; Window::scroll('↑', 10); Cursor::move('↑', 10); $numberOfSteps = 5; Cursor::move('↑', $numberOfSteps); Cursor::move('→', $labelMaxWidth); Cursor::colorize('foreground(black) background(#cccccc)'); } } else { $form['database']['driver'] = $step(3, 'Choose the database driver (sqlite or mysql)', function ($databaseDriver) { return in_array($databaseDriver, ['sqlite', 'mysql']); }, 'Database driver is invalid' . "\n" . 'Database driver must be `sqlite` or `mysql`', 'sqlite'); } if ('mysql' === $form['database']['driver']) { $form['database']['host'] = $step(0, 'Choose MySQL host', function () { return true; }, ''); $form['database']['port'] = $step(1, 'Choose MySQL port', function ($port) { return false !== filter_var($port, FILTER_VALIDATE_INT); }, 'Port is invalid' . "\n" . 'Port must be an integer.', '3306'); $form['database']['username'] = $step(2, 'Choose MySQL username', function () { return true; }, ''); $oldReadline = $readline; $readline = new Console\Readline\Password(); $form['database']['password'] = $step(3, 'Choose MySQL password', function () { return true; }, ''); $readline = $oldReadline; $form['database']['name'] = $step(3, 'Choose MySQL database name', function () { return true; }, ''); } $readline->readLine("\n" . 'Ready to install? (Enter to continue, Ctrl-C to abort)'); echo "\n\n"; try { $progress(5, 'Create configuration file…'); $configuration = Installer::createConfigurationFile(Server::CONFIGURATION_FILE, ['baseUrl' => $form['baseUrl'], 'database' => $form['database']]); $progress(25, 'Configuration file created 👍!'); $progress(30, 'Create the database…'); $database = Installer::createDatabase($configuration); $progress(50, 'Database created 👍!'); $progress(55, 'Create administrator profile…'); Installer::createAdministratorProfile($configuration, $database, $form['email'], $form['password']); $progress(75, 'Administrator profile created 👍!'); $progress(100, 'sabre/katana is ready!'); } catch (\Exception $e) { $progress(-1, 'An error occured: ' . $e->getMessage()); if (null !== ($previous = $e->getPrevious())) { echo 'Underlying error: ' . $previous->getMessage(); } echo "\n", 'You are probably likely to run: ' . '`make uninstall` before trying again.', "\n"; return 2; } list($dirname) = Uri\split($form['baseUrl']); echo "\n\n", 'The administration interface will be found at this path: ', '<your website>', $dirname, '/admin.php.', "\n"; Window::setTitle($oldTitle); }
/** * @tags installation configuration database sqlite authentication administration */ function case_create_administrator_profile() { $this->given($configuration = new Configuration($this->helper->configuration('configuration.json', ['database' => ['dsn' => $this->helper->sqlite(), 'username' => '', 'password' => '']])), $database = CUT::createDatabase($configuration), $login = Server::ADMINISTRATOR_LOGIN, $email = '*****@*****.**', $password = '******')->when($result = CUT::createAdministratorProfile($configuration, $database, $email, $password))->then->boolean($result)->isTrue(); $this->when($result = $database->query('SELECT * FROM principals', $database::FETCH_CLASS, 'StdClass'))->then->array($collection = iterator_to_array($result))->hasSize(3)->let($tuple = $collection[0])->string($tuple->id)->isEqualTo('1')->string($tuple->uri)->isEqualTo('principals/' . $login)->string($tuple->email)->isEqualTo($email)->string($tuple->displayname)->isEqualTo('Administrator')->let($tuple = $collection[1])->string($tuple->id)->isEqualTo('2')->string($tuple->uri)->isEqualTo('principals/' . $login . '/calendar-proxy-read')->variable($tuple->email)->isNull()->variable($tuple->displayname)->isNull()->let($tuple = $collection[2])->string($tuple->id)->isEqualTo('3')->string($tuple->uri)->isEqualTo('principals/' . $login . '/calendar-proxy-write')->variable($tuple->email)->isNull()->variable($tuple->displayname)->isNull()->when($result = $database->query('SELECT * FROM users', $database::FETCH_CLASS, 'StdClass'))->then->array($collection = iterator_to_array($result))->hasSize(1)->let($tuple = $collection[0])->string($tuple->username)->isEqualTo($login)->string($tuple->digesta1)->boolean(User::checkPassword($password, $tuple->digesta1))->isTrue(); }
} $response->setBody(json_encode($out)); HTTP\Sapi::sendResponse($response); })->get('install', '/(?-i)install/(?<jsonpayload>.+)', function ($jsonpayload) { $payload = json_decode($jsonpayload); $source = new Eventsource\Server(); $send = function ($data) use($source) { $source->step->send(json_encode($data)); sleep(1); }; try { $send(['percent' => 5, 'message' => 'Create configuration file…']); $configuration = Installer::createConfigurationFile(SABRE_KATANA_CONFIG, ['baseUrl' => $payload->baseurl, 'database' => ['driver' => $payload->database->driver, 'host' => $payload->database->host, 'port' => $payload->database->port, 'name' => $payload->database->name, 'username' => $payload->database->username, 'password' => $payload->database->password]]); $send(['percent' => 25, 'message' => 'Configuration file created 👍!']); $send(['percent' => 30, 'message' => 'Create the database…']); $database = Installer::createDatabase($configuration); $send(['percent' => 50, 'message' => 'Database created 👍!']); $send(['percent' => 55, 'message' => 'Create administrator profile…']); Installer::createAdministratorProfile($configuration, $database, $payload->email, $payload->password); $send(['percent' => 75, 'message' => 'Administrator profile created 👍!']); $send(['percent' => 100, 'message' => 'sabre/katana is ready!']); } catch (\Exception $e) { $send(['percent' => -1, 'message' => 'An error occured: ' . $e->getMessage()]); // + log } }); $query = substr($url, $pos + 1); if (false !== ($posEnd = strpos($query, '&'))) { $query = substr($query, 0, $posEnd); } $router->route($query, '/');
protected function case_full_installation($payload) { $this->when($configuration = CUT::createConfigurationFile($this->helper->configuration('server.json'), ['baseUrl' => $payload->baseurl, 'database' => ['driver' => $payload->database->driver, 'host' => $payload->database->host, 'port' => $payload->database->port, 'name' => $payload->database->name, 'username' => $payload->database->username, 'password' => $payload->database->password]]), $configuration->database->dsn = $this->helper->sqlite())->then->object($configuration)->isInstanceOf('Sabre\\Katana\\Configuration')->when($database = CUT::createDatabase($configuration))->then->object($database)->isInstanceOf('PDO')->when($result = CUT::createAdministratorProfile($configuration, $database, $payload->email, $payload->password))->then->boolean($result)->isTrue(); }