Merge pull request #341 from Block8/dc/installer-fixes

Fixes to improve installation
This commit is contained in:
Dan Cryer 2014-04-16 09:29:27 +01:00
commit ba595f7e5f
9 changed files with 379 additions and 538 deletions

View file

@ -1,28 +1,34 @@
<?php
/**
* PHPCI - Continuous Integration for PHP
*
* @copyright Copyright 2013, Block 8 Limited.
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
* @link http://www.phptesting.org/
*/
* PHPCI - Continuous Integration for PHP
*
* @copyright Copyright 2013, Block 8 Limited.
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
* @link http://www.phptesting.org/
*/
namespace PHPCI\Command;
use Exception;
use PDO;
use b8\Database;
use b8\Store\Factory;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use b8\Store\Factory;
use PHPCI\Builder;
use Symfony\Component\Console\Helper\DialogHelper;
use PHPCI\Model\User;
/**
* Install console command - Installs PHPCI.
* @author Dan Cryer <dan@block8.co.uk>
* @package PHPCI
* @subpackage Console
*/
* Install console command - Installs PHPCI.
* @author Dan Cryer <dan@block8.co.uk>
* @package PHPCI
* @subpackage Console
*/
class InstallCommand extends Command
{
protected function configure()
@ -33,137 +39,235 @@ class InstallCommand extends Command
}
/**
* Installs PHPCI - Can be run more than once as long as you ^C instead of entering an email address.
*/
* Installs PHPCI - Can be run more than once as long as you ^C instead of entering an email address.
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// Gather initial data from the user:
$this->verifyNotInstalled($output);
$output->writeln('');
$output->writeln('<info>******************</info>');
$output->writeln('<info> Welcome to PHPCI</info>');
$output->writeln('<info>******************</info>');
$output->writeln('');
$this->checkRequirements($output);
$output->writeln('Please answer the following questions:');
$output->writeln('-------------------------------------');
$output->writeln('');
/**
* @var \Symfony\Component\Console\Helper\DialogHelper
*/
$dialog = $this->getHelperSet()->get('dialog');
// ----
// Get MySQL connection information and verify that it works:
// ----
$connectionVerified = false;
while (!$connectionVerified) {
$db = array();
$db['servers']['read'] = $dialog->ask($output, 'Please enter your MySQL host [localhost]: ', 'localhost');
$db['servers']['write'] = $db['servers']['read'];
$db['name'] = $dialog->ask($output, 'Please enter your database name [phpci]: ', 'phpci');
$db['username'] = $dialog->ask($output, 'Please enter your database username [phpci]: ', 'phpci');
$db['password'] = $dialog->askHiddenResponse($output, 'Please enter your database password: ');
$connectionVerified = $this->verifyDatabaseDetails($db, $output);
}
$output->writeln('');
// ----
// Get basic installation details (URL, etc)
// ----
$conf = array();
$conf['b8']['database']['servers']['read'] = $this->ask('Enter your MySQL host: ');
$conf['b8']['database']['servers']['write'] = $conf['b8']['database']['servers']['read'];
$conf['b8']['database']['name'] = $this->ask('Enter the database name PHPCI should use: ');
$conf['b8']['database']['username'] = $this->ask('Enter your MySQL username: ');
$conf['b8']['database']['password'] = $this->ask('Enter your MySQL password: ', true);
$ask = 'Your PHPCI URL (without trailing slash): ';
$conf['phpci']['url'] = $this->ask($ask, false, array(FILTER_VALIDATE_URL,"/[^\/]$/i"));
$conf['phpci']['github']['id'] = $this->ask('(Optional) Github Application ID: ', true);
$conf['phpci']['github']['secret'] = $this->ask('(Optional) Github Application Secret: ', true);
$conf['b8']['database'] = $db;
$conf['phpci']['url'] = $dialog->askAndValidate(
$output,
'Your PHPCI URL (without trailing slash): ',
function ($answer) {
if (!filter_var($answer, FILTER_VALIDATE_URL)) {
throw new Exception('Must be a valid URL');
}
$conf['phpci']['email_settings']['smtp_address'] = $this->ask('(Optional) Smtp server address: ', true);
$conf['phpci']['email_settings']['smtp_port'] = $this->ask('(Optional) Smtp port: ', true);
$conf['phpci']['email_settings']['smtp_encryption'] = $this->ask('(Optional) Smtp encryption: ', true);
$conf['phpci']['email_settings']['smtp_username'] = $this->ask('(Optional) Smtp Username: ', true);
$conf['phpci']['email_settings']['smtp_password'] = $this->ask('(Optional) Smtp Password: ', true);
$conf['phpci']['email_settings']['from_address'] = $this->ask('(Optional) Email address to send from: ', true);
return $answer;
},
false
);
$ask = '(Optional) Default address to email notifications to: ';
$conf['phpci']['email_settings']['default_mailto_address'] = $this->ask($ask, true);
$this->writeConfigFile($conf);
$this->setupDatabase($output);
$this->createAdminUser($output, $dialog);
}
$dbUser = $conf['b8']['database']['username'];
$dbPass = $conf['b8']['database']['password'];
$dbHost = $conf['b8']['database']['servers']['write'];
$dbName = $conf['b8']['database']['name'];
/**
* Check PHP version, required modules and for disabled functions.
* @param OutputInterface $output
*/
protected function checkRequirements(OutputInterface $output)
{
$output->write('Checking requirements...');
$errors = false;
// Create the database if it doesn't exist:
$cmd = 'mysql -u' . $dbUser . (!empty($dbPass) ? ' -p' . $dbPass : '') . ' -h' . $dbHost .
' -e "CREATE DATABASE IF NOT EXISTS ' . $dbName . '"';
// Check PHP version:
if (!(version_compare(PHP_VERSION, '5.3.3') >= 0)) {
$output->writeln('');
$output->writeln('<error>PHPCI requires at least PHP 5.3.3 to function.</error>');
$errors = true;
}
shell_exec($cmd);
// Check required extensions are present:
$requiredExtensions = array('PDO', 'pdo_mysql', 'mcrypt');
foreach ($requiredExtensions as $extension) {
if (!extension_loaded($extension)) {
$output->writeln('');
$output->writeln('<error>'.$extension.' extension must be installed.</error>');
$errors = true;
}
}
// Check required functions are callable:
$requiredFunctions = array('exec', 'shell_exec');
foreach ($requiredFunctions as $function) {
if (!function_exists($function)) {
$output->writeln('');
$output->writeln('<error>PHPCI needs to be able to call the '.$function.'() function. Is it disabled in php.ini?</error>');
$errors = true;
}
}
if (!function_exists('password_hash')) {
$output->writeln('');
$output->writeln('<error>PHPCI requires the password_hash() function available in PHP 5.4, or the password_compat library by ircmaxell.</error>');
$errors = true;
}
if ($errors) {
throw new Exception('PHPCI cannot be installed, as not all requirements are met. Please review the errors above before continuing.');
}
$output->writeln(' <info>OK</info>');
$output->writeln('');
}
/**
* Try and connect to MySQL using the details provided.
* @param array $db
* @param OutputInterface $output
* @return bool
*/
protected function verifyDatabaseDetails(array $db, OutputInterface $output)
{
try {
$pdo = new PDO(
'mysql:host='.$db['servers']['write'].';dbname='.$db['name'],
$db['username'],
$db['password'],
array(
\PDO::ATTR_PERSISTENT => false,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_TIMEOUT => 2,
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'',
)
);
return true;
} catch (Exception $ex) {
$output->writeln('<error>PHPCI could not connect to MySQL with the details provided. Please try again.</error>');
$output->writeln('<error>' . $ex->getMessage() . '</error>');
}
return false;
}
/**
* Write the PHPCI config.yml file.
* @param array $config
*/
protected function writeConfigFile(array $config)
{
$dumper = new \Symfony\Component\Yaml\Dumper();
$yaml = $dumper->dump($conf);
$yaml = $dumper->dump($config);
file_put_contents(PHPCI_DIR . 'PHPCI/config.yml', $yaml);
}
protected function setupDatabase(OutputInterface $output)
{
$output->write('Setting up your database... ');
// Load PHPCI's bootstrap file:
require(PHPCI_DIR . 'bootstrap.php');
// Update the database:
$gen = new \b8\Database\Generator(\b8\Database::getConnection(), 'PHPCI', './PHPCI/Model/Base/');
$gen->generate();
// Try to create a user account:
$adminEmail = $this->ask('Enter your email address (leave blank if updating): ', true, FILTER_VALIDATE_EMAIL);
if (empty($adminEmail)) {
return;
try {
// Set up the database, based on table data from the models:
$gen = new Database\Generator(Database::getConnection(), 'PHPCI', './PHPCI/Model/Base/');
$gen->generate();
} catch (Exception $ex) {
$output->writeln('');
$output->writeln('<error>PHPCI failed to set up the database.</error>');
$output->writeln('<error>' . $ex->getMessage() . '</error>');
die;
}
$adminPass = $this->ask('Enter your desired admin password: ');
$adminName = $this->ask('Enter your name: ');
$output->writeln('<info>OK</info>');
}
protected function createAdminUser(OutputInterface $output, DialogHelper $dialog)
{
// Try to create a user account:
$adminEmail = $dialog->askAndValidate(
$output,
'Your email address: ',
function ($answer) {
if (!filter_var($answer, FILTER_VALIDATE_EMAIL)) {
throw new Exception('Must be a valid email address.');
}
return $answer;
},
false
);
$adminPass = $dialog->askHiddenResponse($output, 'Enter your desired admin password: ');
$adminName = $dialog->ask($output, 'Enter your name: ');
try {
$user = new \PHPCI\Model\User();
$user = new User();
$user->setEmail($adminEmail);
$user->setName($adminName);
$user->setIsAdmin(1);
$user->setHash(password_hash($adminPass, PASSWORD_DEFAULT));
$store = \b8\Store\Factory::getStore('User');
$store = Factory::getStore('User');
$store->save($user);
print 'User account created!' . PHP_EOL;
$output->writeln('<info>User account created!</info>');
} catch (\Exception $ex) {
print 'There was a problem creating your account. :(' . PHP_EOL;
print $ex->getMessage();
$output->writeln('<error>PHPCI failed to create your admin account.</error>');
$output->writeln('<error>' . $ex->getMessage() . '</error>');
die;
}
}
protected function ask($question, $emptyOk = false, $validationFilter = null)
protected function verifyNotInstalled(OutputInterface $output)
{
print $question . ' ';
if (file_exists(PHPCI_DIR . 'PHPCI/config.yml')) {
$content = file_get_contents(PHPCI_DIR . 'PHPCI/config.yml');
$rtn = '';
$stdin = fopen('php://stdin', 'r');
$rtn = fgets($stdin);
fclose($stdin);
$rtn = trim($rtn);
if (!$emptyOk && empty($rtn)) {
$rtn = $this->ask($question, $emptyOk, $validationFilter);
} elseif ($validationFilter != null && ! empty($rtn)) {
if (! $this -> controlFormat($rtn, $validationFilter, $statusMessage)) {
print $statusMessage;
$rtn = $this->ask($question, $emptyOk, $validationFilter);
if (!empty($content)) {
$output->writeln('<error>PHPCI/config.yml exists and is not empty.</error>');
$output->writeln('<error>If you were trying to update PHPCI, please use phpci:update instead.</error>');
die;
}
}
return $rtn;
}
protected function controlFormat($valueToInspect, $filter, &$statusMessage)
{
$filters = !(is_array($filter))? array($filter) : $filter;
$statusMessage = '';
$status = true;
$options = array();
foreach ($filters as $filter) {
if (! is_int($filter)) {
$regexp = $filter;
$filter = FILTER_VALIDATE_REGEXP;
$options = array(
'options' => array(
'regexp' => $regexp,
)
);
}
if (! filter_var($valueToInspect, $filter, $options)) {
$status = false;
switch ($filter)
{
case FILTER_VALIDATE_URL:
$statusMessage = 'Incorrect url format.' . PHP_EOL;
break;
case FILTER_VALIDATE_EMAIL:
$statusMessage = 'Incorrect e-mail format.' . PHP_EOL;
break;
case FILTER_VALIDATE_REGEXP:
$statusMessage = 'Incorrect format.' . PHP_EOL;
break;
}
}
}
return $status;
}
}

View file

@ -48,8 +48,30 @@ class UpdateCommand extends Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->verifyInstalled($output);
$output->writeln('Updating PHPCI database.');
// Update the database:
$gen = new \b8\Database\Generator(\b8\Database::getConnection(), 'PHPCI', './PHPCI/Model/Base/');
$gen->generate();
$output->writeln('<info>Done!</info>');
}
protected function verifyInstalled(OutputInterface $output)
{
if (!file_exists(PHPCI_DIR . 'PHPCI/config.yml')) {
$output->writeln('<error>PHPCI does not appear to be installed.</error>');
$output->writeln('<error>Please install PHPCI via phpci:install instead.</error>');
die;
}
$content = file_get_contents(PHPCI_DIR . 'PHPCI/config.yml');
if (empty($content)) {
$output->writeln('<error>PHPCI does not appear to be installed.</error>');
$output->writeln('<error>Please install PHPCI via phpci:install instead.</error>');
die;
}
}
}

View file

@ -39,7 +39,15 @@ class SettingsController extends Controller
public function index()
{
$this->view->settings = $this->settings;
$emailSettings = array();
if (isset($this->settings['phpci']['email_settings'])) {
$emailSettings = $this->settings['phpci']['email_settings'];
}
$this->view->github = $this->getGithubForm();
$this->view->emailSettings = $this->getEmailForm($emailSettings);
if (!empty($this->settings['phpci']['github']['token'])) {
$this->view->githubUser = $this->getGithubUser($this->settings['phpci']['github']['token']);
@ -52,17 +60,28 @@ class SettingsController extends Controller
{
$this->settings['phpci']['github']['id'] = $this->getParam('githubid', '');
$this->settings['phpci']['github']['secret'] = $this->getParam('githubsecret', '');
$error = $this->storeSettings();
if($error)
{
if($error) {
header('Location: ' . PHPCI_URL . 'settings?saved=2');
}
else
{
} else {
header('Location: ' . PHPCI_URL . 'settings?saved=1');
}
die;
}
public function email()
{
$this->settings['phpci']['email_settings'] = $this->getParams();
$error = $this->storeSettings();
if ($error) {
header('Location: ' . PHPCI_URL . 'settings?saved=2');
} else {
header('Location: ' . PHPCI_URL . 'settings?saved=1');
}
die;
}
@ -120,18 +139,23 @@ class SettingsController extends Controller
$field->setLabel('Application ID');
$field->setClass('form-control');
$field->setContainerClass('form-group');
$field->setValue($this->settings['phpci']['github']['id']);
$form->addField($field);
if (isset($this->settings['phpci']['github']['id'])) {
$field->setValue($this->settings['phpci']['github']['id']);
}
$field = new Form\Element\Text('githubsecret');
$field->setRequired(true);
$field->setPattern('[a-zA-Z0-9]+');
$field->setLabel('Application Secret');
$field->setClass('form-control');
$field->setContainerClass('form-group');
$field->setValue($this->settings['phpci']['github']['secret']);
$form->addField($field);
if (isset($this->settings['phpci']['github']['secret'])) {
$field->setValue($this->settings['phpci']['github']['secret']);
}
$field = new Form\Element\Submit();
$field->setValue('Save &raquo;');
@ -141,6 +165,76 @@ class SettingsController extends Controller
return $form;
}
protected function getEmailForm($values = array())
{
$form = new Form();
$form->setMethod('POST');
$form->setAction(PHPCI_URL . 'settings/email');
$form->addField(new Form\Element\Csrf('csrf'));
$field = new Form\Element\Text('smtp_address');
$field->setRequired(false);
$field->setLabel('SMTP Server');
$field->setClass('form-control');
$field->setContainerClass('form-group');
$field->setValue('localhost');
$form->addField($field);
$field = new Form\Element\Text('smtp_port');
$field->setRequired(false);
$field->setPattern('[0-9]+');
$field->setLabel('SMTP Port');
$field->setClass('form-control');
$field->setContainerClass('form-group');
$field->setValue(25);
$form->addField($field);
$field = new Form\Element\Text('smtp_username');
$field->setRequired(false);
$field->setLabel('SMTP Username');
$field->setClass('form-control');
$field->setContainerClass('form-group');
$form->addField($field);
$field = new Form\Element\Text('smtp_password');
$field->setRequired(false);
$field->setLabel('SMTP Password');
$field->setClass('form-control');
$field->setContainerClass('form-group');
$form->addField($field);
$field = new Form\Element\Email('from_address');
$field->setRequired(false);
$field->setLabel('From Email Address');
$field->setClass('form-control');
$field->setContainerClass('form-group');
$form->addField($field);
$field = new Form\Element\Email('default_mailto_address');
$field->setRequired(false);
$field->setLabel('Default Notification Address');
$field->setClass('form-control');
$field->setContainerClass('form-group');
$form->addField($field);
$field = new Form\Element\Checkbox('smtp_encryption');
$field->setCheckedValue(1);
$field->setRequired(false);
$field->setLabel('Use SMTP encryption?');
$field->setContainerClass('form-group');
$field->setValue(1);
$form->addField($field);
$field = new Form\Element\Submit();
$field->setValue('Save &raquo;');
$field->setClass('btn btn-success pull-right');
$form->addField($field);
$form->setValues($values);
return $form;
}
protected function getGithubUser($token)
{
$http = new HttpClient('https://api.github.com');

View file

@ -28,7 +28,12 @@
<h3 class="title">Github Application</h3>
<?php
$id = $settings['phpci']['github']['id'];
$id = null;
if (isset($settings['phpci']['github']['id'])) {
$id = $settings['phpci']['github']['id'];
}
$returnTo = PHPCI_URL . 'settings/github-callback';
$githubUri = 'https://github.com/login/oauth/authorize?client_id='.$id.'&scope=repo&redirect_uri=' . $returnTo;
?>
@ -66,3 +71,27 @@
</div>
</div>
</div>
<div class="box">
<div class="row">
<div class="col-lg-12">
<h3 class="title">Email Settings</h3>
<?php if (!isset($settings['phpci']['email_settings'])): ?>
<p class="alert alert-warning clearfix">
Before PHPCI can send build status emails, you need to configure your SMTP settings below.
</p>
<?php endif; ?>
</div>
<div class="col-lg-8">
<?php print $emailSettings; ?>
</div>
<div class="col-lg-4">
<!-- nothing -->
</div>
</div>
</div>

View file

@ -64,14 +64,6 @@
</div>
<div id="content" class="container">
<?php if (file_exists(PHPCI_DIR . 'public/install.php')): ?>
<div class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<strong>Warning!</strong> install.php detected, for security purposes please delete it immediately.
</div>
<?php endif; ?>
<?php print $content; ?>
</div>

View file

@ -11,7 +11,10 @@
use PHPCI\Logging\Handler;
use PHPCI\Logging\LoggerConfig;
date_default_timezone_set(@date_default_timezone_get());
$timezone = ini_get('date.timezone');
if (empty($timezone)) {
date_default_timezone_set('UTC');
}
// Set up a basic autoloader for PHPCI:
$autoload = function ($class) {

View file

@ -23,6 +23,10 @@
},
"require": {
"php": ">=5.3.3",
"ext-mcrypt": "*",
"ext-pdo": "*",
"ext-pdo_mysql": "*",
"block8/b8framework" : "1.*",
"ircmaxell/password-compat": "1.*",
"swiftmailer/swiftmailer" : "5.0.*",

View file

@ -16,3 +16,4 @@ require_once('../bootstrap.php');
$fc = new PHPCI\Application($config, new b8\Http\Request());
print $fc->handleRequest();

View file

@ -1,408 +0,0 @@
<?php
require_once(dirname(__FILE__) . '/../bootstrap.php');
$installStage = 'start';
$formAction = '';
$config = array();
$ciUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on" ? 'https' : 'http') . '://';
$ciUrl .= $_SERVER['HTTP_HOST'];
$ciUrl .= str_replace('/install.php', '', $_SERVER['REQUEST_URI']);
/**
* Pre installation checks:
*/
$installOK = true;
$composerInstalled = true;
$isWriteable = true;
$phpOK = true;
$checkWriteable = function ($path) {
if ($path{strlen($path)-1}=='/') {
return is__writable($path.uniqid(mt_rand()).'.tmp');
} elseif (is_dir($path)) {
return is__writable($path.'/'.uniqid(mt_rand()).'.tmp');
}
// check tmp file for read/write capabilities
$remove = file_exists($path);
$file = @fopen($path, 'a');
if ($file === false) {
return false;
}
fclose($file);
if (!$remove) {
unlink($path);
}
return true;
};
if (!file_exists(PHPCI_DIR . 'vendor/autoload.php')) {
$composerInstalled = false;
$installOK = false;
}
if (!$checkWriteable(PHPCI_DIR . 'PHPCI/config.yml')) {
$isWriteable = false;
$installOK = false;
}
if (PHP_VERSION_ID < 50303) {
$phpOK = false;
$installOK = false;
}
/**
* Installation processing:
*/
if ($installOK && strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') {
$installStage = $_POST['stage'];
$config = json_decode(base64_decode($_POST['config']), true);
unset($_POST['stage']);
unset($_POST['config']);
if (!empty($config)) {
$config = array_merge_recursive($config, $_POST);
} else {
$config = $_POST;
}
if ($installStage == 'complete') {
/**
* Register autoloader:
*/
require_once(PHPCI_DIR . 'vendor/autoload.php');
/**
* Temporary save phpci URL for redirect after install ($config is replaced in bootstrap.php)
*/
$phpciUrl = $config['phpci']['url'];
/**
* Write config file:
*/
$config['b8']['database']['servers']['read'] = array($config['b8']['database']['servers']['read']);
$config['b8']['database']['servers']['write'] = $config['b8']['database']['servers']['read'];
$adminUser = $config['tmp']['user'];
$adminPass = $config['tmp']['pass'];
unset($config['tmp']);
$dumper = new \Symfony\Component\Yaml\Dumper();
$yaml = $dumper->dump($config, 5);
file_put_contents(PHPCI_DIR . 'PHPCI/config.yml', $yaml);
/**
* Create database:
*/
$dbhost = $config['b8']['database']['servers']['write'][0];
$dbname = $config['b8']['database']['name'] ?: 'phpci';
$dbuser = $config['b8']['database']['username'] ?: 'phpci';
$dbpass = $config['b8']['database']['password'];
$pdo = new PDO('mysql:host=' . $dbhost, $dbuser, $dbpass);
$pdo->query('CREATE DATABASE IF NOT EXISTS `' . $dbname . '`');
/**
* Bootstrap PHPCI and populate database:
*/
require(PHPCI_DIR . 'bootstrap.php');
ob_start();
$gen = new \b8\Database\Generator(\b8\Database::getConnection(), 'PHPCI', PHPCI_DIR . 'PHPCI/Model/Base/');
$gen->generate();
ob_end_clean();
/**
* Create our admin user:
*/
$store = \b8\Store\Factory::getStore('User');
try {
$user = $store->getByEmail($adminUser);
} catch (Exception $ex) {
}
if (empty($user)) {
$user = new \PHPCI\Model\User();
$user->setEmail($adminUser);
$user->setName($adminUser);
$user->setIsAdmin(1);
$user->setHash(password_hash($adminPass, PASSWORD_DEFAULT));
$store->save($user);
}
$formAction = rtrim( $phpciUrl, '/' ) . '/session/login';
}
}
switch ($installStage) {
case 'start':
$nextStage = 'database';
break;
case 'database':
$nextStage = 'github';
break;
case 'github':
$nextStage = 'email';
break;
case 'email':
$nextStage = 'complete';
break;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Install PHPCI</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="assets/css/bootstrap.min.css">
<style type="text/css">
html {
min-height: 100%;
}
body
{
background: #224466; /* Old browsers */
background: radial-gradient(ellipse at center, #224466 0%,#112233 100%);
min-height: 100%;
font-family: Roboto, Arial, Sans-Serif;
font-style: normal;
font-weight: 300;
padding-top: 0px;
}
#form-box
{
background: linear-gradient(to bottom, #fcfcfc 50%,#e0e0e0 100%);
border-radius: 5px;
box-shadow: 0 0 30px rgba(0,0,0, 0.3);
margin: 0 auto;
padding: 15px 30px;
text-align: left;
width: 550px;
}
#logo {
background: transparent url('http://www.block8.co.uk/badge-dark-muted.png') no-repeat top left;
display: inline-block;
height: 26px;
margin: 40px auto;
width: 90px;
}
#logo:hover {
background-image: url('http://www.block8.co.uk/badge-dark.png');
}
#phpci-logo img {
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="container">
<div class="row" style="margin-top: 30px; text-align: center">
<a id="phpci-logo" href="http://www.phptesting.org">
<img src="assets/img/logo-large.png">
</a>
<div class="" id="form-box">
<form autocomplete="off" action="<?php print $formAction; ?>" method="POST" class="form-horizontal">
<input type="hidden" name="prevstage" value="<?php print $installStage; ?>">
<input type="hidden" name="stage" value="<?php print $nextStage; ?>">
<input type="hidden" name="config" value="<?php print base64_encode(json_encode($config)); ?>">
<?php if ($installStage == 'start'): ?>
<h3>Welcome to PHPCI!</h3>
<?php if ($installOK): ?>
<p>Your server has passed all of PHPCI's pre-installation checks, please press continue below to
begin installation.</p>
<?php else: ?>
<p>Please correct the problems below, then refresh this page to continue.</p>
<?php endif; ?>
<?php if (!$composerInstalled): ?>
<p class="alert alert-danger">
<strong>Important!</strong>
You need to run composer to install dependencies before running the installer.
</p>
<?php endif; ?>
<?php if (!$isWriteable): ?>
<p class="alert alert-danger">
<strong>Important!</strong>
./PHPCI/config.yml needs to be writeable to continue.
</p>
<?php endif; ?>
<?php if (!$phpOK): ?>
<p class="alert alert-danger"><strong>Important!</strong> PHPCI requires PHP 5.3.3 or above.</p>
<?php endif; ?>
<?php elseif ($installStage == 'database'): ?>
<h3>Database Details</h3>
<div class="form-group">
<label for="dbhost" class="col-lg-3 control-label">Host</label>
<div class="col-lg-9">
<input name="b8[database][servers][read]" type="text" class="form-control" id="dbhost" placeholder="localhost" value="localhost" required>
</div>
</div>
<div class="form-group">
<label for="dbname" class="col-lg-3 control-label">Name</label>
<div class="col-lg-9">
<input name="b8[database][name]" type="text" class="form-control" id="dbname" placeholder="phpci" required>
</div>
</div>
<div class="form-group">
<label for="dbuser" class="col-lg-3 control-label">Username</label>
<div class="col-lg-9">
<input autocomplete="off" name="b8[database][username]" type="text" class="form-control" id="dbuser" placeholder="phpci" required>
</div>
</div>
<div class="form-group">
<label for="dbpass" class="col-lg-3 control-label">Password</label>
<div class="col-lg-9">
<input autocomplete="off" name="b8[database][password]" type="password" class="form-control" id="dbpass">
</div>
</div>
<h3>PHPCI Details</h3>
<div class="form-group">
<label for="phpciurl" class="col-lg-3 control-label">URL</label>
<div class="col-lg-9">
<input name="phpci[url]" type="url" class="form-control" id="phpciurl" value="<?php print $ciUrl; ?>" required>
</div>
</div>
<div class="form-group">
<label for="adminuser" class="col-lg-3 control-label">Admin Email</label>
<div class="col-lg-9">
<input autocomplete="off" name="tmp[user]" type="email" class="form-control" id="adminuser" placeholder="admin@phptesting.org" required>
</div>
</div>
<div class="form-group">
<label for="adminpass" class="col-lg-3 control-label">Password</label>
<div class="col-lg-9">
<input autocomplete="off" name="tmp[pass]" type="password" class="form-control" id="adminpass" required>
</div>
</div>
<?php elseif($installStage == 'github'): ?>
<h3>Github App Settings (Optional)</h3>
<div class="form-group">
<label for="appkey" class="col-lg-3 control-label">App ID</label>
<div class="col-lg-9">
<input autocomplete="off" name="phpci[github][id]" type="text" class="form-control" id="appkey">
</div>
</div>
<div class="form-group">
<label for="appsecret" class="col-lg-3 control-label">Secret</label>
<div class="col-lg-9">
<input autocomplete="off" name="phpci[github][secret]" type="text" class="form-control" id="appsecret">
</div>
</div>
<?php elseif($installStage == 'email'): ?>
<h3>SMTP Settings (Optional)</h3>
<div class="form-group">
<label for="emailadd" class="col-lg-3 control-label">Server</label>
<div class="col-lg-9">
<input name="phpci[email_settings][smtp_address]" type="text" class="form-control" id="emailadd" placeholder="e.g. smtp.gmail.com">
</div>
</div>
<div class="form-group">
<label for="emailport" class="col-lg-3 control-label">Port</label>
<div class="col-lg-9">
<input autocomplete="off" name="phpci[email_settings][smtp_port]" type="text" class="form-control" id="emailport" placeholder="992">
</div>
</div>
<div class="form-group">
<label for="emailenc" class="col-lg-3 control-label">Encryption</label>
<div class="col-lg-9">
<input autocomplete="off" name="phpci[email_settings][smtp_encryption]" type="checkbox" class="form-" id="emailenc" checked>
</div>
</div>
<div class="form-group">
<label for="emailuser" class="col-lg-3 control-label">Username</label>
<div class="col-lg-9">
<input autocomplete="off" name="phpci[email_settings][smtp_username]" type="text" class="form-control" id="emailuser">
</div>
</div>
<div class="form-group">
<label for="emailpass" class="col-lg-3 control-label">Password</label>
<div class="col-lg-9">
<input autocomplete="off" name="phpci[email_settings][smtp_password]" type="password" class="form-control" id="emailpass">
</div>
</div>
<div class="form-group">
<label for="emailfrom" class="col-lg-3 control-label">From Address</label>
<div class="col-lg-9">
<input autocomplete="off" name="phpci[email_settings][from_address]" type="email" class="form-control" id="emailfrom">
<p>The address system emails should come from.</p>
</div>
</div>
<div class="form-group">
<label for="defaultto" class="col-lg-3 control-label">Default To</label>
<div class="col-lg-9">
<input autocomplete="off" name="phpci[email_settings][default_mailto_address]" type="email" class="form-control" id="defaultto">
<p class="desc">The address to which notifications should go by default.</p>
</div>
</div>
<?php else: ?>
<p>Thank you for installing PHPCI. Click continue below to log in for the first time!</p>
<input type="hidden" name="email" value="<?php print $adminUser; ?>">
<input type="hidden" name="password" value="<?php print $adminPass; ?>">
<?php endif; ?>
<div class="form-group">
<div class="col-lg-12">
<button type="submit" class="pull-right btn btn-success"<?php print (!$installOK ? ' disabled' : ''); ?>>Continue &raquo;</button>
</div>
</div>
</form>
</div>
<a id="logo" href="http://www.block8.co.uk/"></a>
</div>
</div>
</body>
</html>