diff --git a/cli/database-upgrade.php b/cli/database-upgrade.php new file mode 100755 index 0000000..186eb5c --- /dev/null +++ b/cli/database-upgrade.php @@ -0,0 +1,141 @@ +#!/usr/bin/php +. + +/** + * This is the script to upgrade the database + * + * It will execute the available database patches until the database + * is to its latest version. + * + * To be honest, it also create the database schema if missing. + */ + +require __DIR__ . '/../load.php'; + +echo <<getPrefix(); + +// try to check if the database exists +$database_exists = true; +try { + ( new UserAPI() ) + ->limit( 1 ) + ->queryRow(); + +} catch( Exception $e ) { + $database_exists = false; +} + +if( !$database_exists ) { + // database schema installation + echo "important tables are missing! assuming no database.\n"; + echo "importing the schema for the first time\n"; + execute_queries_from_file( "$documentation_path/schema.sql" ); + + // if we have not imported any database version, just set the latest one + $version_exists = get_option( 'database_version', 0 ); + if( !$version_exists ) { + set_option( 'database_version', DATABASE_VERSION ); + } +} + +// get the current database version +$current_database_version = get_option( 'database_version', 1 ); + +// notify about the current status +printf( "current database version: %d\n", $current_database_version ); +printf( "last database version: %d\n", DATABASE_VERSION ); + +// update to next database versions once at time +while( $current_database_version < DATABASE_VERSION ) { + + $current_database_version++; + + $patch_name = sprintf( + 'patch-%04d.sql', + $current_database_version + ); + + // path to the expected patch + $patch_path = "$patch_directory/$patch_name"; + + echo "looking for patch $patch_path\n"; + + // check if there is a database patch to be applied + if( file_exists( $patch_path ) ) { + execute_queries_from_file( $patch_path ); + } else { + echo "\t skipped unexisting patch\n"; + } + + echo "\t increment database version to $current_database_version\n"; + + // update the database version + set_option( 'database_version', $current_database_version ); +} + +echo "database upgrade end. good for you!\n"; + + + + + + +/** + * Execute some queries from a file + * + * @param string $file + */ +function execute_queries_from_file( $file ) { + echo "\t executing queries from $file\n"; + + // get the patch content + $queries = file_get_contents( $file ); + + // replace the database prefix with the current one + $database_prefix = DB::instance()->getPrefix(); + $queries = str_replace( '{$prefix}', $database_prefix, $queries ); + + // execute the patch queries (it will die in case of error) + multiquery( $queries ); +} diff --git a/documentation/database/patches/README.md b/documentation/database/patches/README.md new file mode 100644 index 0000000..02acebc --- /dev/null +++ b/documentation/database/patches/README.md @@ -0,0 +1,12 @@ +== Database patches == + +This directory contains database patches. + +You can add here some database patches. + +When you are ready to execute them, just remember to: + +* update the `DATABASE_VERSION` in `load-post.php` +* run `cli/database-upgrade.php` + +That's all. diff --git a/load-post.php b/load-post.php index ab06775..18d7f48 100644 --- a/load-post.php +++ b/load-post.php @@ -1,112 +1,129 @@ . +/** + * This is your versioned configuration file + * + * It does not contains secrets. + * + * This file is required after loading your + * unversioned configuration file: + * + * load.php + */ + +// database version +// +// you can increase your database version if you added some patches in: +// documentation/database/patches +define( 'DATABASE_VERSION', 0 ); + // include path define_default( 'INCLUDE_PATH', ABSPATH . __ . 'include' ); // template path define_default( 'TEMPLATE_PATH', ABSPATH . __ . 'template' ); // autoload classes from the /include directory spl_autoload_register( function( $name ) { // TODO: autoload classes and create DomainTrait and use in Mailbox $path = INCLUDE_PATH . __ . "class-$name.php"; if( is_file( $path ) ) { require $path; } } ); // override default user class define( 'SESSIONUSER_CLASS', 'User' ); // load common functions require INCLUDE_PATH . __ . 'functions.php'; // jquery URL // provided by the libjs-jquery package as default define_default( 'JQUERY_URL', '/javascript/jquery/jquery.min.js' ); // Bootstrap CSS/JavaScript files without trailing slash // provided by the libjs-bootstrap package as default define_default( 'BOOTSTRAP_DIR_URL', '/javascript/bootstrap' ); // path to the Net SMTP class // provided by the php-net-smtp package as default define_default( 'NET_SMTP', '/usr/share/php/Net/SMTP.php' ); // base directory for your virtualhosts // e.g. you may have /var/www/example.com/index.html // do NOT end with a slash // TODO: support multiple hosts define_default( 'VIRTUALHOSTS_DIR', '/var/www' ); // default currency simbol define_default( 'DEFAULT_CURRENCY_SYMBOL', '€' ); // register JavaScript/CSS files register_js( 'jquery', JQUERY_URL ); register_js( 'bootstrap', BOOTSTRAP_DIR_URL . '/js/bootstrap.min.js' ); register_css( 'bootstrap', BOOTSTRAP_DIR_URL . '/css/bootstrap.min.css' ); register_css( 'custom-css', ROOT . '/content/style.css' ); // GNU Gettext i18n define( 'GETTEXT_DOMAIN', 'reyboz-hosting-panel' ); define( 'GETTEXT_DIRECTORY', 'l10n' ); define( 'GETTEXT_DEFAULT_ENCODE', CHARSET ); // UTF-8 // common strings define_default( 'SITE_NAME', "KISS Libre Hosting Panel" ); define_default( 'CONTACT_EMAIL', 'support@' . DOMAIN ); define_default( 'REPO_URL', 'https://gitpull.it/project/profile/15/' ); // limit session duration to 5 minutes (60s * 100m) define_default( 'SESSION_DURATION', 6000 ); /** * Mailbox base path * * Used by CLI scripts to calculate the current quotas. * * The mailboxes should have paths like: * MAILBOX_BASE_PATH/domain_name/user_name/ */ define_default( 'MAILBOX_BASE_PATH', '/home/vmail' ); // register web pages add_menu_entries( [ new MenuEntry( 'index', '/', __( "Dashboard" ), null, 'backend' ), new MenuEntry( 'login', 'login.php', __( "Login" ) ), new MenuEntry( 'profile', 'profile.php', __( "Profile" ) ), new MenuEntry( 'logout', 'logout.php', __( "Logout" ), null, 'read' ), new MenuEntry( 'user-list', 'user-list.php', __( "Users" ), null, 'edit-user-all' ), new MenuEntry( 'password-reset', 'password-reset.php', __( "Password reset" ) ), ] ); // permissions of a normal user register_permissions( 'user', [ 'read', 'backend', ] ); // permissions of an admin inherit_permissions( 'admin', 'user', [ 'edit-user-all', 'edit-email-all', 'edit-domain-all', 'edit-plan-all', 'edit-ftp-all', ] );