.dev/install/install.php

Summary

Maintainability
F
3 days
Test Coverage
<?php

// TODO: form validation
// TODO: add language selector $_POST['install_project_lang']
// TODO: webserver selection (write htaccess or not?)
// TODO: storage path seletion and checking for writable
// TODO: check for required extensions and functions (pcre, mbstring, iconv, date, ctype, sockets, Phar, SimpleXML, tokenizer, curl, json, mysql|mysqli, gd, imagettftext, memcache)
// TODO: check for optional exts: (mcrypt, gmp, imagick, xcache, zip, memcached)

class yf_core_install
{
    /**
     * @param mixed $body
     */
    public function main_layout_html($body = '')
    {
        ob_start(); ?>
<!DOCTYPE html>
<html>
<head>
    <title>YF Installation</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="//netdna.bootstrapcdn.com/bootswatch/2.3.2/<?php echo installer()->bs_current_theme(); ?>/bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
.sidebar-nav { padding: 9px 0; }
.dropdown-menu .sub-menu { left: 100%; position: absolute; top: 0; visibility: hidden; margin-top: -1px; }
.dropdown-menu li:hover .sub-menu { visibility: visible; }
.dropdown:hover .dropdown-menu { display: block; }
.nav-tabs .dropdown-menu, .nav-pills .dropdown-menu, .navbar .dropdown-menu { margin-top: 0; }
.navbar .sub-menu:before { border-bottom: 7px solid transparent; border-left: none; border-right: 7px solid rgba(0, 0, 0, 0.2); border-top: 7px solid transparent; left: -7px; top: 10px; }
.navbar .sub-menu:after { border-top: 6px solid transparent; border-left: none; border-right: 6px solid #fff; border-bottom: 6px solid transparent; left: 10px; top: 11px; left: -6px; }
    </style>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
    <script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js" type="text/javascript"></script>
    <script type="text/javascript">
    $(function(){
        $(".theme-selector > li > a").click(function(){
            var theme = this.id.substr(9) // 9 == strlen('theme_id_')
            document.cookie='yf_theme=' + theme;
            window.location.reload();
            return false;
        })
    })
    </script>
</head>
<body>
    <div class="navbar">
        <div class="navbar-inner">
            <a class="brand" href="https://github.com/yfix/yf">YF Framework</a>
            <ul class="nav">
                <li class=""><a href="https://github.com/yfix/yf">Home</a></li>
                <li class="dropdown">
                    <a class="dropdown-toggle" data-toggle="dropdown">Select theme <b class="caret"></b></a>
                    <ul class="dropdown-menu theme-selector">
<?php
        foreach ((array) installer()->bs_get_avail_themes() as $theme) {
            echo '<li><a href="#" id="theme_id_' . $theme . '">' . $theme . '</a></li>' . PHP_EOL;
        } ?>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
<?php
        echo $body; ?>
</body>
</html>
<?php
        return ob_get_clean();
    }

    /**
     * @param mixed $page
     * @param mixed $vars
     * @param mixed $errors
     */
    public function show_html($page = 'form', $vars = [], $errors = [])
    {
        if (php_sapi_name() == 'cli' || ! $_SERVER['PHP_SELF']) {
            return print '__CONSOLE_INSTALL__' . PHP_EOL;
        }
        $cur_dir = realpath('./');
        $up1_dir = dirname($cur_dir) . '/';
        if ( ! is_writable($cur_dir)) {
            $error = 'Current dir: ' . $cur_dir . ' is not writable, please fix filesystem permissions.';
        } elseif ( ! is_writable($up1_dir)) {
            $error = 'Up 1 level dir: ' . $up1_dir . ' is not writable, please fix filesystem permissions.';
        }
        ob_start();
        if ($page == 'form') {
            ?>
    <header>
        <div class="container">
            <p class="lead">Welcome to YF Framework installation process. Submit form below to finish.</p>
        </div>
    </header>
    <div class="container">
        <form class="form-horizontal" method="post" action="{FORM_ACTION}">
<?php
        foreach ((array) installer()->get_form_keys() as $name => $desc) {
            if (false !== strpos($name, 'install_checkbox_')) {
                continue;
            }
            echo '
            <div class="control-group ' . (isset($errors[$name]) ? 'error' : '') . '">
                <label class="control-label" for="' . $name . '">' . $desc . '</label>
                <div class="controls"><input type="text" id="' . $name . '" name="' . $name . '" placeholder="' . $desc . '" value="' . htmlspecialchars($vars[$name], ENT_QUOTES) . '">'
                    . (isset($errors[$name]) ? '<span class="help-inline">' . $errors[$name] . '</span>' : '')
                . '</div>
            </div>
            ';
        } ?>
            <div class="control-group">
                <div class="controls">
<?php
        foreach ((array) installer()->get_form_keys() as $name => $desc) {
            if (false === strpos($name, 'install_checkbox_')) {
                continue;
            }
            echo '
                    <label class="checkbox"><input type="checkbox" name="' . $name . '" value="1" ' . $vars[$name] . '>' . htmlspecialchars($desc, ENT_QUOTES) . '</label>
            ';
        } ?>
                </div>
            </div>
            <div class="control-group">
                <div class="controls">
                    <button type="submit" class="btn">Install!</button>
                </div>
            </div>
        </form>
    </div>
<?php
        } elseif ($page == 'results') {
            ?>
    <header>
        <div class="container">
            <p class="lead">YF Framework installation complete.</p>
        </div>
    </header>
    <div class="container">
        <div class="control-group">
            <div class="controls">
                <a class="btn" target="_blank" href="{install_web_path}">User Side</a>
                <a class="btn" target="_blank" href="{install_web_path}admin/">Admin Side</a>
            </div>
        </div>
    </div>
    <div class="container">
{install_log}
    </div>
<?php
        }
        $html = ob_get_clean();
        $body = '';
        if ($error) {
            $body .= '<div class="alert alert-danger">' . $error . '</div>';
        }
        $body .= installer()->main_layout_html($html);
        $replace = [];
        foreach ((array) $vars as $k => $v) {
            $replace['{' . $k . '}'] = htmlspecialchars($v, ENT_QUOTES);
        }
        echo str_replace(array_keys($replace), array_values($replace), $body);
        return installer();
    }


    public function bs_get_avail_themes()
    {
        return ['amelia', 'cerulean', 'cosmo', 'cyborg', 'flatly', 'journal', 'readable', 'simplex', 'slate', 'spacelab', 'spruce', 'superhero', 'united'];
    }


    public function bs_current_theme()
    {
        $theme = 'slate'; // Default
        $avail_themes = installer()->bs_get_avail_themes();
        if ($_COOKIE['yf_theme'] && in_array($_COOKIE['yf_theme'], $avail_themes)) {
            $theme = $_COOKIE['yf_theme'];
        }
        return $theme;
    }


    public function get_form_keys()
    {
        return [
            'install_yf_path' => 'Filesystem path to YF',
            'install_db_host' => 'Database Host',
            'install_db_name' => 'Database Name',
            'install_db_user' => 'Database Username',
            'install_db_pswd' => 'Database Password',
            'install_db_prefix' => 'Database Prefix',
            'install_admin_login' => 'Administrator Login',
            'install_admin_pswd' => 'Administrator Password',
            'install_rw_base' => 'URL Rewrites Base',
            'install_web_path' => 'Web Path',
            'install_web_name' => 'Website Name',
            'install_checkbox_rw_enabled' => 'Enable URL Rewrites',
            'install_checkbox_db_create' => 'Create Database if not exists',
            'install_checkbox_db_drop_existing' => 'Drop Existing Tables',
            'install_checkbox_demo_data' => 'Load Demo Data',
            'install_checkbox_debug_info' => 'Show Debug Info',
        ];
    }


    public function get_form_defaults()
    {
        return [
            'install_yf_path' => $this->get_default_yf_path(),
            'install_db_host' => 'localhost',
            'install_db_name' => 'test_' . substr(md5(microtime()), 0, 6),
            'install_db_user' => 'root',
            'install_db_pswd' => '123456',
            'install_db_prefix' => 't_',
            'install_web_path' => installer()->get_default_web_path(),
            'install_admin_login' => 'admin',
            'install_admin_pswd' => '123456',
            'install_rw_base' => installer()->get_default_rewrite_base(),
            'install_web_name' => 'YF Website',
            'install_checkbox_rw_enabled' => '',
            'install_checkbox_db_create' => '1',
            'install_checkbox_db_drop_existing' => '1',
            'install_checkbox_demo_data' => '',
            'install_checkbox_debug_info' => '',
        ];
    }


    public function get_default_yf_path()
    {
        $result = null;
        switch (true) {
            case is_dir('./yf/'):
                $result = __DIR__ . '/yf/';
                break;
            case is_dir('../yf/'):
                $result = '../yf/';
                break;
            case is_dir('../../yf/'):
                $result = '../../yf/';
                break;
        }
        $result && $result = realpath($result) . '/';
        return  $result;
    }


    public function get_default_web_path()
    {
        $request_uri = $_SERVER['REQUEST_URI'];
        $cur_web_path = $request_uri[strlen($request_uri) - 1] == '/' ? substr($request_uri, 0, -1) : dirname($request_uri);
        return '//' . $_SERVER['HTTP_HOST'] . str_replace(['\\', '//'], '/', $cur_web_path . '/');
    }


    public function get_default_rewrite_base()
    {
        return dirname($_SERVER['REQUEST_URI']) != '/' ? dirname($_SERVER['REQUEST_URI']) . '/' : '/';
    }


    public function prepare_vars()
    {
        $vars = [
            'FORM_ACTION' => $_SERVER['PHP_SELF'],
        ];
        $defaults = installer()->get_form_defaults();
        foreach ((array) installer()->get_form_keys() as $k => $desc) {
            $val = isset($_POST[$k]) ? $_POST[$k] : $defaults[$k];
            if (false !== strpos($k, 'install_checkbox_') && $val) {
                $val = 'checked';
            }
            $vars[$k] = $val;
        }
        return $vars;
    }


    public function set_php_conf()
    {
        define('YF_IN_INSTALLER', true);
        define('PROJECT_PATH', $_POST['install_project_path'] ?: realpath('./') . '/');
        define('INCLUDE_PATH', PROJECT_PATH);
        define('APP_PATH', dirname(PROJECT_PATH) . '/');
        define('CONFIG_PATH', APP_PATH . '/config/');
        $GLOBALS['PROJECT_CONF']['main']['USE_CUSTOM_ERRORS'] = 1;
        $GLOBALS['PROJECT_CONF']['main']['SESSION_OFF'] = 1;
        $GLOBALS['PROJECT_CONF']['db']['RECONNECT_NUM_TRIES'] = 1;
        $GLOBALS['PROJECT_CONF']['db']['ALLOW_AUTO_CREATE_DB'] = 1;
        ini_set('display_errors', 'on');
        ini_set('memory_limit', '512M');
        error_reporting(E_ALL ^ E_NOTICE);
        return installer();
    }

    /**
     * @param mixed $vars
     */
    public function pre_init_yf_core($vars = [])
    {
        if (defined('YF_PATH')) {
            return false;
        }
        ! $vars && $vars = installer()->prepare_vars();
        define('YF_PATH', $vars['install_yf_path']);
        require YF_PATH . 'classes/yf_main.class.php';
        return new yf_main('user', $no_db_connect = true, $auto_init_all = false);
    }


    public function init_yf_core()
    {
        define('DB_TYPE', 'mysqli');
        define('DB_HOST', $_POST['install_db_host']);
        define('DB_NAME', $_POST['install_db_name']);
        define('DB_USER', $_POST['install_db_user']);
        define('DB_PSWD', $_POST['install_db_pswd']);
        define('DB_PREFIX', $_POST['install_db_prefix']);
        define('DB_CHARSET', 'utf8');

        define('DEBUG_MODE', (int) $_POST['install_checkbox_debug_info']);

        define('DB_PREFIX', $_POST['install_db_prefix']);
        if ( ! defined('YF_PATH')) {
            define('YF_PATH', $_POST['install_yf_path']);
            require YF_PATH . 'classes/yf_main.class.php';
            new yf_main('user', $no_db_connect = false, $auto_init_all = false);
        }

        define('INSTALLER_PATH', YF_PATH . '.dev/' . basename(__DIR__) . '/');
        return installer();
    }


    public function test_db_connection()
    {
        $test = db()->query('SHOW TABLES');
        if ( ! $test && ! db()->db_connect_id) {
            $error = db()->error();
            if ($error['code'] == 9999) { // YF special code when cannot connect
                installer()->cannot_connect_to_db = true;
            }
        }
        return ! installer()->cannot_connect_to_db;
    }


    public function write_db_setup()
    {
        $db_setup_file_content = '<?php
define(\'DB_TYPE\',    \'mysqli\');
define(\'DB_HOST\',    \'' . $_POST['install_db_host'] . '\');
define(\'DB_NAME\',    \'' . $_POST['install_db_name'] . '\');
define(\'DB_USER\',    \'' . $_POST['install_db_user'] . '\');
define(\'DB_PSWD\',    \'' . $_POST['install_db_pswd'] . '\');
define(\'DB_PREFIX\',    \'' . $_POST['install_db_prefix'] . '\');
define(\'DB_CHARSET\',\'utf8\');';
        $fpath = CONFIG_PATH . 'db_setup.php';
        $d = dirname($fpath);
        if ( ! file_exists($d)) {
            mkdir($d, 0777, true);
        }
        if ( ! file_exists($fpath)) {
            file_put_contents($fpath, $db_setup_file_content);
        }
        return installer();
    }

    /**
     * @param mixed $rewrite_enabled
     */
    public function write_user_index_php($rewrite_enabled = true)
    {
        $index_file_content = '<?php
$dev_settings = dirname(__DIR__).\'/.dev/override.php\';
if (file_exists($dev_settings)) {
    require_once $dev_settings;
}
$saved_settings = __DIR__.\'/saved_settings.php\';
if (file_exists($saved_settings)) {
    require_once $saved_settings;
}
define(\'DEBUG_MODE\', false);
define(\'YF_PATH\', \'' . YF_PATH . '\');
define(\'WEB_PATH\', \'' . rtrim($_POST['install_web_path'], '/') . '/\');
define(\'SITE_DEFAULT_PAGE\', \'./?object=home_page\');
define(\'SITE_ADVERT_NAME\', \'' . $_POST['install_web_name'] . '\');
require dirname(__DIR__).\'/config/project_conf.php\';' . PHP_EOL
. ($rewrite_enabled ? '$PROJECT_CONF[\'tpl\'][\'REWRITE_MODE\'] = true;' . PHP_EOL : '')
. 'require YF_PATH.\'classes/yf_main.class.php\';
new yf_main(\'user\', $no_db_connect = false, $auto_init_all = true);';
        $fpath = PROJECT_PATH . 'index.php';
        $d = dirname($fpath);
        if ( ! file_exists($d)) {
            mkdir($d, 0777, true);
        }
        if ( ! file_exists($fpath)) {
            file_put_contents($fpath, $index_file_content);
        }
        return installer();
    }

    /**
     * @param mixed $rewrite_enabled
     */
    public function write_admin_index_php($rewrite_enabled = true)
    {
        $admin_index_file_content = '<?php
$dev_settings = dirname(dirname(__DIR__)).\'/.dev/override.php\';
if (file_exists($dev_settings)) {
    require_once $dev_settings;
}
$saved_settings = dirname(__DIR__).\'/saved_settings.php\';
if (file_exists($saved_settings)) {
    require_once $saved_settings;
}
define(\'DEBUG_MODE\', false);
define(\'YF_PATH\', \'' . YF_PATH . '\');
define(\'WEB_PATH\', \'//\'.$_SERVER[\'HTTP_HOST\'].\'/\');
//define(\'WEB_PATH\', \'' . rtrim($_POST['install_web_path'], '/') . '/\');
define(\'ADMIN_WEB_PATH\', WEB_PATH. basename(__DIR__).\'/\');
//define(\'ADMIN_WEB_PATH\', \'//\'.$_SERVER[\'HTTP_HOST\'].\'/\'.basename(__DIR__).\'/\');
define(\'ADMIN_SITE_PATH\', __DIR__.\'/\');
define(\'SITE_DEFAULT_PAGE\', \'./?object=admin_home\');
define(\'ADMIN_FRAMESET_MODE\', 1);
require dirname(dirname(__DIR__)).\'/config/project_conf.php\';
require YF_PATH.\'classes/yf_main.class.php\';
new yf_main(\'admin\', $no_db_connect = false, $auto_init_all = true);';
        $fpath = PROJECT_PATH . 'admin/index.php';
        $d = dirname($fpath);
        if ( ! file_exists($d)) {
            mkdir($d, 0777, true);
        }
        if ( ! file_exists($fpath)) {
            file_put_contents($fpath, $admin_index_file_content);
        }
        return installer();
    }

    /**
     * @param mixed $table
     * @param mixed $dir
     */
    public function import_table_data($table, $dir = '')
    {
        if ( ! $dir) {
            $dir = INSTALLER_PATH . 'installer_data/db_tables/';
        }
        $file = $dir . $table . '.data.php';
        if ( ! file_exists($file)) {
            return false;
        }
        $data = include $file;
        if (empty($data)) {
            return false;
        }
        return db()->replace_safe(DB_PREFIX . $table, $data);
    }


    public function import_base_db_structure()
    {
        $import_tables = [
            'dashboards',
            'static_pages',
            'user',
        ];
        $suffix = '.sql.php';
        $suffix_len = strlen($suffix);
        $sql_paths = [
            'yf' => YF_PATH . 'share/db/sql/sys_*' . $suffix,
            'yf_plugins' => YF_PATH . 'plugins/*/share/db/sql/sys_*' . $suffix,
            'yf_install' => INSTALLER_PATH . 'installer_data/db_tables/*' . $suffix,
        ];
        foreach ((array) $sql_paths as $pattern) {
            foreach ((array) glob($pattern) as $f) {
                $import_tables[] = substr(basename($f), 0, -$suffix_len);
            }
        }
        $import_tables = array_combine($import_tables, $import_tables);

        // Typically missing database should be created automatically through this setting:
        // $GLOBALS['PROJECT_CONF']['db']['ALLOW_AUTO_CREATE_DB'] = 1;
        // But in case it was failed, we trying again with more high-level API of db utils
        $db_exists = db()->utils()->database_exists(DB_NAME);
        if ($_POST['install_checkbox_db_create'] && ! $db_exists) {
            db()->utils()->create_database(DB_NAME);
            $db_exists = db()->utils()->database_exists(DB_NAME);
        }
        if ( ! $db_exists) {
            exit('Target database not exists or script cannot create it');
        }

        // delete or ignore already existed tables
        $Q = db()->query('SHOW TABLES LIKE "' . DB_PREFIX . '%"');
        while ($A = db()->fetch_row($Q)) {
            $existing_db_tables[$A[0]] = $A[0];
        }
        if ( ! empty($existing_db_tables)) {
            if ($_POST['install_checkbox_db_drop_existing']) {
                foreach ((array) $existing_db_tables as $value) {
                    db()->query('DROP TABLE IF EXISTS `' . $value . '`');
                }
            } else {
                foreach ((array) $existing_db_tables as $value) {
                    $value = str_replace(DB_PREFIX, '', $value);
                    unset($import_tables[$value]);
                }
            }
        }
        foreach ((array) $import_tables as $table) {
            db()->utils()->create_table($table);
        }
        foreach ((array) $import_tables as $table) {
            $this->import_table_data($table);
        }
        return installer();
    }


    public function import_demo_data()
    {
        $lang = $_POST['install_project_lang'];

        $suffix = '.data.php';
        $suffix_len = strlen($suffix);
        $data_paths['en'] = INSTALLER_PATH . 'installer_data/db_tables_en/*' . $suffix;
        if ($lang && $lang != 'en') {
            $data_paths[$lang] = INSTALLER_PATH . 'installer_data/db_tables_' . $lang . '/*' . $suffix;
        }
        $tables = [];
        foreach ((array) $data_paths as $pattern) {
            foreach ((array) glob($pattern) as $f) {
                $tables[] = substr(basename($f), 0, -$suffix_len);
            }
        }
        $tables = array_combine($tables, $tables);
        // Important: this is needed to initialize YF database structure installer and create these tables, if not done before
        foreach ((array) $tables as $table) {
            db()->query('SELECT * FROM ' . db($table) . ' LIMIT 1');
        }
        $dir = INSTALLER_PATH . 'installer_data/db_tables_en/';
        foreach ((array) glob($dir . '*.data.php') as $f) {
            $_table = substr(basename($f), 0, -strlen('.data.php'));
            $this->import_table_data($_table, $dir);
        }
        if ($lang) {
            $dir = INSTALLER_PATH . 'installer_data/db_tables_' . $lang . '/';
            foreach ((array) glob($dir . '*.data.php') as $f) {
                $_table = substr(basename($f), 0, -strlen('.data.php'));
                $this->import_table_data($_table, $dir);
            }
        }
        db()->update_safe('sys_menu_items', ['active' => 1], '1=1');
        return installer();
    }

    /**
     * @param mixed $rewrite_enabled
     */
    public function write_htaccess($rewrite_enabled = true)
    {
        if ($rewrite_enabled) {
            $htaccess_file_content = file_get_contents(INSTALLER_PATH . 'installer_data/htaccess.txt');
            db()->update_safe('sys_settings', ['value' => 1], 'id=4');
        } else {
            $htaccess_file_content = file_get_contents(INSTALLER_PATH . 'installer_data/htaccess2.txt');
        }
        file_put_contents(PROJECT_PATH . '.htaccess', str_replace('%%%#path#%%%', $_POST['install_rw_base'], $htaccess_file_content));
        return installer();
    }


    public function set_admin_login_pswd()
    {
        //        db()->_connected &&
        //        db()->utils()->table_exists('sys_admin') &&
        db()->replace_safe('sys_admin', [
            'id' => 1,
            'login' => $_POST['install_admin_login'],
            'password' => md5($_POST['install_admin_pswd']),
            'first_name' => $_POST['install_admin_login'],
            'add_date' => time(),
            'group' => 1,
            'active' => 1,
        ]);
        return installer();
    }


    public function copy_project_skeleton()
    {
        _class('dir')->copy_dir(INSTALLER_PATH . 'skel_basic/', APP_PATH, '', '/\.(svn|git)/');
        return installer();
    }


    public function show_form()
    {
        $vars = installer()->prepare_vars();
        installer()->pre_init_yf_core($vars);
        $form_items = [];
        $validate_rules = [];
        foreach (installer()->get_form_keys() as $id => $desc) {
            $type = 'text';
            if (strpos($id, '_checkbox_') !== false) {
                $type = 'check_box';
            }
            $form_items[$id] = [$type, $id, $desc];
            $validate_rules[$id] = 'trim|required';
        }
        $defaults = installer()->get_form_defaults();
        $form = form($defaults)
            ->validate($validate_rules)
            ->array_to_form($form_items)
            ->save('', 'Install');
        //        print _class('html')->layout(array(
        //            'nav_bar'    => _class('html')->nav_bar(),
        //            'body'        => $form,
        //        ));
        echo $form;
    }
}


function installer()
{
    static $installer;
    if ( ! is_object($installer)) {
        $installer = new yf_core_install();
    }
    return $installer;
}
/////////////////////////////


$errors = [];
if (empty($_POST)) { // Initial page
    //    installer()->show_form();
    installer()->show_html('form', installer()->prepare_vars());
    exit();
}

installer()
    ->set_php_conf()
    ->init_yf_core()
    ->test_db_connection();
if ( ! installer()->test_db_connection()) {
    $msg = 'Cannot connect to db server';
    $errors['install_db_host'] = $msg;
    $errors['install_db_user'] = $msg;
    $errors['install_db_pswd'] = $msg;
}
if ($errors) {
    installer()->show_html('form', installer()->prepare_vars(), $errors);
    exit();
}
$url_rewrite = $_POST['install_checkbox_rw_enabled'];
installer()
    ->import_base_db_structure()
    ->write_db_setup()
    ->write_user_index_php($url_rewrite)
    ->write_admin_index_php($url_rewrite)
    ->write_htaccess($url_rewrite)
    ->set_admin_login_pswd()
    ->copy_project_skeleton();
if ($_POST['install_checkbox_demo_data']) {
    installer()->import_demo_data();
    _class('dir')->copy_dir(INSTALLER_PATH . 'skel_demo/', APP_PATH, '', '/\.(svn|git)/');
}
$debug_info = $_POST['install_checkbox_debug_info'] ? tpl()->parse('debug_console_js') . common()->show_debug_info() : '';
$vars = installer()->prepare_vars();

// TODO: create some log
$vars['install_log'] = '';

installer()->show_html('results', $vars);
echo $debug_info;