webmum/installer/step3.php
Oliver Hartl a7c3a4f271 Implementation of the WebMUM installer (#52)
* Preparation for installer and discontinue support of old config style.

* Adding installer with step 0

* Fixing travis config, because example config isn't loaded anymore if normal config does not exist.

* Adding installer step 1: database connection

* Adding installer step 2: database schema

* Adding installer step 3: Your first admin user

* Minor fix on step 3

* Adding installer step 4: general settings

* Adding installer step 5: optional features

* Adding final installation step 7: writing config & finish

* Display the current installation progress

* Fixing installation finish

* Disable direct access to installer

* Change colors of "notifying" text

* Add check and cross marks to requirements page of the installer

* Change how config directory is checked, no more writable check but error if writing fails.

* Execute post-receice..
2016-06-06 18:49:21 +02:00

306 lines
9.3 KiB
PHP

<?php
if(strpos($_SERVER['REQUEST_URI'], 'installer/') !== false){
die('You cannot directly access the installer files.');
}
/*-----------------------------------------------------------------------------*/
$thisStep = 3;
if($_SESSION['installer']['lastStep'] > $thisStep){
$_SESSION['installer']['subStep'] = 1;
}
elseif($_SESSION['installer']['lastStep'] < $thisStep || !isset($_SESSION['installer']['subStep'])){
$_SESSION['installer']['subStep'] = 0;
}
$error = null;
/*-----------------------------------------------------------------------------*/
$exampleConfigValues = require_once 'config/config.php.example';
$tablesInDatabase = array();
try{
Database::init($_SESSION['installer']['config']['mysql']);
$db = Database::getInstance();
$tablesResult = $db->query(
"SELECT TABLE_NAME FROM information_schema.tables "
."WHERE TABLE_SCHEMA='".$db->escape($_SESSION['installer']['config']['mysql']['database'])."';"
);
foreach($tablesResult->fetch_all() as $row){
$tablesInDatabase[] = $row[0];
}
}
catch(Exception $e){
}
function getTableAttributes($table)
{
global $_SESSION;
$attributes = array();
if(Database::isInitialized()){
try{
$db = Database::getInstance();
$tablesResult = $db->query(
"SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_KEY, EXTRA FROM information_schema.columns "
."WHERE TABLE_SCHEMA = '".$db->escape($_SESSION['installer']['config']['mysql']['database'])."' "
."AND TABLE_NAME = '".$db->escape($table)."' "
."ORDER BY TABLE_NAME,ORDINAL_POSITION;"
);
foreach($tablesResult->fetch_all() as $row){
$s = $row[0];
if(!empty($row[1])){
$s .= ' : '.$row[1];
}
if($row[2] == 'NO'){
$s .= ', NOT NULL';
}
if(!is_null($row[3])){
$s .= ', DEFAULT \''.$row[3].'\'';
}
if(!empty($row[4])){
if(strpos($row[4], 'PR') !== false){
$s .= ', PRIMARY KEY';
}
if(strpos($row[4], 'UN') !== false){
$s .= ', UNIQUE KEY';
}
}
if(!empty($row[5]) && strpos($row[5], 'auto_inc') !== false){
$s .= ', AUTO_INCREMENT';
}
$attributes[$row[0]] = $s;
}
}
catch(Exception $e){
}
}
return $attributes;
}
$optionalAttributes = array(
'users' => array('mailbox_limit', 'max_user_redirects'),
'aliases' => array('multi_source', 'is_created_by_user'),
);
define('ATTR_SEP', '---');
function getAttr($name, $default = null)
{
global $_SESSION, $_POST;
if(isset($_POST[$name])){
return strip_tags($_POST[$name]);
}
elseif(strpos($name, ATTR_SEP) !== false){
list($table, $attribute) = explode(ATTR_SEP, $name);
if(isset($_SESSION['installer']['config']['schema']['attributes'][$table][$attribute])){
return $_SESSION['installer']['config']['schema']['attributes'][$table][$attribute];
}
}
elseif(isset($_SESSION['installer']['config']['schema']['tables'][$name])){
return $_SESSION['installer']['config']['schema']['tables'][$name];
}
return $default;
}
/*-----------------------------------------------------------------------------*/
if(isset($_GET['go'])){
if($_GET['go'] == 'next' && $_SERVER['REQUEST_METHOD'] == 'POST'){
try{
if($_SESSION['installer']['subStep'] === 0){
$tables = array();
foreach($exampleConfigValues['schema']['tables'] as $table => $mappedTable){
if(!isset($_POST[$table])
|| !in_array($_POST[$table], $tablesInDatabase)
){
throw new InvalidArgumentException('Missing mapping for table "'.$table.'".');
}
if(in_array($_POST[$table], array_values($tables))){
throw new Exception('You cannot map table "'.$_POST[$table].'" twice.');
}
$tables[$table] = $_POST[$table];
}
// saving information
$_SESSION['installer']['config']['schema'] = array();
$_SESSION['installer']['config']['schema']['tables'] = $tables;
installer_message('Database tables were successfully mapped.');
$_SESSION['installer']['subStep'] = 1;
installer_next($thisStep, 0);
}
elseif($_SESSION['installer']['subStep'] === 1){
$attributes = array();
foreach($_SESSION['installer']['config']['schema']['tables'] as $table => $mappedTable){
$attributes[$table] = array();
$attributesInDatabase = getTableAttributes($table);
foreach($exampleConfigValues['schema']['attributes'][$table] as $attribute => $mappedAttribute){
$key = $table.'---'.$attribute;
if(isset($optionalAttributes[$table])
&& in_array($attribute, $optionalAttributes[$table])
&& !isset($attributesInDatabase[$_POST[$key]])
){
$attributes[$table][$attribute] = '';
}
else{
if(!isset($_POST[$key]) || !isset($attributesInDatabase[$_POST[$key]])){
throw new InvalidArgumentException('Missing mapping for attribute "'.$attribute.'" on table "'.$table.'".');
}
if(in_array($_POST[$key], $attributes[$table])){
throw new Exception('You cannot map attribute "'.$_POST[$key].'" twice on table "'.$table.'".');
}
$attributes[$table][$attribute] = $_POST[$key];
}
}
}
// saving information
$_SESSION['installer']['config']['schema']['attributes'] = $attributes;
installer_message('Database attributes were successfully mapped.');
unset($_SESSION['installer']['subStep']);
installer_next($thisStep);
}
}
catch(Exception $e){
$error = $e->getMessage();
}
}
elseif($_GET['go'] == 'prev'){
// reset
if(isset($_SESSION['installer']['config']['schema']['tables'])){
if($_SESSION['installer']['subStep'] === 0){
unset($_SESSION['installer']['config']['schema']);
}
elseif($_SESSION['installer']['subStep'] === 1){
unset($_SESSION['installer']['config']['schema']['attributes']);
}
}
if($_SESSION['installer']['subStep'] === 0){
unset($_SESSION['installer']['subStep']);
installer_prev($thisStep, ($_SESSION['installer']['type'] === INSTALLER_TYPE_MAP) ? 2 : 1);
}
else{
$_SESSION['installer']['subStep'] = 0;
installer_prev($thisStep, 0);
}
}
}
?>
<?php echo installer_message(); ?>
<h2>
Step 2 of <?php echo INSTALLER_MAX_STEP; ?>:
<?php if($_SESSION['installer']['subStep'] === 0): ?>
Database - table mapping.
<?php elseif($_SESSION['installer']['subStep'] === 1): ?>
Database - attribute mapping.
<?php else: ?>
Wrong turn
<?php endif; ?>
</h2>
<?php if(!empty($error)): ?>
<div class="notification notification-fail"><?php echo $error; ?></div>
<?php endif; ?>
<?php if($_SESSION['installer']['subStep'] === 0): ?>
<form class="form" action="/?step=<?php echo $thisStep; ?>&go=next" method="post">
<?php foreach($exampleConfigValues['schema']['tables'] as $table => $mappedTable): ?>
<div class="input-group">
<label for="<?php echo $table; ?>">Table "<?php echo $table; ?>"</label>
<div class="input">
<select name="<?php echo $table; ?>">
<option value="">-- Not mapped --</option>
<?php foreach($tablesInDatabase as $t): ?>
<option value="<?php echo $t; ?>" <?php echo getAttr($table, $mappedTable) == $t ? 'selected' : ''; ?>><?php echo $t; ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<?php endforeach; ?>
<hr class="invisible">
<div class="buttons">
<a class="button" href="/?step=<?php echo $thisStep; ?>&go=prev">Back</a>
<button class="button button-primary" type="submit">Continue</button>
</div>
</form>
<?php elseif($_SESSION['installer']['subStep'] === 1): ?>
<form class="form" action="/?step=<?php echo $thisStep; ?>&go=next" method="post">
<?php
$lastTable = array_keys($_SESSION['installer']['config']['schema']['tables']);
$lastTable = $lastTable[count($lastTable) - 1];
foreach($_SESSION['installer']['config']['schema']['tables'] as $table => $mappedTable):
$attributesInDatabase = getTableAttributes($mappedTable);
?>
<h3>
Table "<?php echo $table; ?>"
<div class="sub-header">Has been mapped to table "<?php echo $mappedTable; ?>".</div>
</h3>
<div style="margin-left: 25px;">
<?php foreach($exampleConfigValues['schema']['attributes'][$table] as $attribute => $mappedAttribute): ?>
<div class="input-group">
<label for="<?php echo $table.ATTR_SEP.$attribute; ?>">Attribute "<?php echo $attribute; ?>"</label>
<?php if(isset($optionalAttributes[$table]) && in_array($attribute, $optionalAttributes[$table])): ?>
<div class="input-info">This attribute is optional (used by optional features) and doesn't need to be mapped.</div>
<?php endif; ?>
<div class="input">
<select name="<?php echo $table.ATTR_SEP.$attribute; ?>">
<option value="">-- Not mapped --</option>
<?php foreach($attributesInDatabase as $dbAttr => $dbAttrText): ?>
<option value="<?php echo $dbAttr; ?>" <?php echo getAttr($table.ATTR_SEP.$attribute, $mappedAttribute) == $dbAttr ? 'selected' : ''; ?>><?php echo $dbAttrText; ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<?php endforeach; ?>
</div>
<?php if($table != $lastTable): ?>
<hr>
<?php endif; ?>
<?php endforeach; ?>
<hr class="invisible">
<div class="buttons">
<a class="button" href="/?step=<?php echo $thisStep; ?>&go=prev">Back</a>
<button class="button button-primary" type="submit">Continue</button>
</div>
</form>
<?php else: ?>
<div class="notification notification-fail">You took the wrong turn, <a href="/">restart installation</a>.</div>
<?php endif; ?>