diff --git a/app/classes/Framadate/FramaDB.php b/app/classes/Framadate/FramaDB.php index fe6783359d87585b2d0fa7d4ae5cce24cd9dcfee..b93ea095a4750bcef961ae74fdf115db3bedb570 100644 --- a/app/classes/Framadate/FramaDB.php +++ b/app/classes/Framadate/FramaDB.php @@ -30,11 +30,23 @@ class FramaDB { $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); } - function areTablesCreated() { + /** + * @return \PDO Connection to database + */ + function getPDO() { + return $this->pdo; + } + + /** + * Find all tables in database. + * + * @return array The array of table names + */ + function allTables() { $result = $this->pdo->query('SHOW TABLES'); $schemas = $result->fetchAll(\PDO::FETCH_COLUMN); - return 0 != count(array_diff($schemas, ['comment', 'poll', 'slot', 'vote'])); + return $schemas; } function prepare($sql) { diff --git a/app/classes/Framadate/Migration/From_0_8_to_0_9_Migration.php b/app/classes/Framadate/Migration/From_0_8_to_0_9_Migration.php new file mode 100644 index 0000000000000000000000000000000000000000..5e0d452a06f6107243b746b282d3b498c31661cf --- /dev/null +++ b/app/classes/Framadate/Migration/From_0_8_to_0_9_Migration.php @@ -0,0 +1,144 @@ +<?php +namespace Framadate\Migration; + +/** + * This class executes the aciton in database to migrate data from version 0.8 to 0.9. + * + * @package Framadate\Migration + */ +class From_0_8_to_0_9_Migration implements Migration { + + function __construct() { + } + + function execute(\PDO $pdo) { + $this->createPollTable($pdo); + $this->migrateFromSondageToPoll($pdo); + + $this->createSlotTable($pdo); + $this->migrateFromSujetStudsToSlot($pdo); + + $this->createCommentTable($pdo); + $this->migrateFromCommentsToComment($pdo); + + $this->createVoteTable($pdo); + $this->migrateFromUserStudsToVote($pdo); + + return true; + } + + private function createPollTable(\PDO $pdo) { + $pdo->exec(' +CREATE TABLE IF NOT EXISTS `poll` ( + `id` CHAR(16) NOT NULL, + `admin_id` CHAR(24) NOT NULL, + `title` TEXT NOT NULL, + `description` TEXT, + `admin_name` VARCHAR(64) DEFAULT NULL, + `admin_mail` VARCHAR(128) DEFAULT NULL, + `creation_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `end_date` TIMESTAMP NOT NULL DEFAULT \'0000-00-00 00:00:00\', + `format` VARCHAR(1) DEFAULT NULL, + `editable` TINYINT(1) DEFAULT \'0\', + `receiveNewVotes` TINYINT(1) DEFAULT \'0\', + `active` TINYINT(1) DEFAULT \'1\', + PRIMARY KEY (`id`) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8'); + } + + private function migrateFromSondageToPoll(\PDO $pdo) { + $pdo->exec(' +INSERT INTO `poll` +(`id`, `admin_id`, `title`, `description`, `admin_name`, `admin_mail`, `creation_date`, `end_date`, `format`, `editable`, `receiveNewVotes`, `active`) + SELECT + `id_sondage`, + `id_sondage_admin`, + `titre`, + `commentaires`, + `nom_admin`, + `mail_admin`, + `date_creation`, + `date_fin`, + SUBSTR(`format`, 1, 1) AS `format`, + CASE SUBSTR(`format`, 2, 1) + WHEN \'+\' THEN 1 + ELSE 0 END AS `editable`, + `mailsonde`, + CASE SUBSTR(`format`, 2, 1) + WHEN \'-\' THEN 0 + ELSE 1 END AS `active` + FROM sondage'); + } + + private function createSlotTable(\PDO $pdo) { + $pdo->exec(' +CREATE TABLE IF NOT EXISTS `slot` ( + `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `poll_id` CHAR(16) NOT NULL, + `title` TEXT, + `moments` TEXT, + PRIMARY KEY (`id`), + KEY `poll_id` (`poll_id`) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8'); + } + + private function migrateFromSujetStudsToSlot(\PDO $pdo) { + // TODO Implements + } + + private function createCommentTable(\PDO $pdo) { + $pdo->exec(' +CREATE TABLE IF NOT EXISTS `comment` ( + `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `poll_id` CHAR(16) NOT NULL, + `name` TEXT, + `comment` TEXT NOT NULL, + PRIMARY KEY (`id`), + KEY `poll_id` (`poll_id`) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8'); + } + + private function migrateFromCommentsToComment(\PDO $pdo) { + $pdo->exec(' +INSERT INTO `comment` +(`poll_id`, `name`, `comment`) + SELECT + `id_sondage`, + `usercomment`, + `comment` + FROM `comments`'); + } + + private function createVoteTable(\PDO $pdo) { + $pdo->exec(' +CREATE TABLE IF NOT EXISTS `vote` ( + `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `poll_id` CHAR(16) NOT NULL, + `name` VARCHAR(64) NOT NULL, + `choices` TEXT NOT NULL, + PRIMARY KEY (`id`), + KEY `poll_id` (`poll_id`) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8'); + } + + private function migrateFromUserStudsToVote(\PDO $pdo) { + $pdo->exec(' +INSERT INTO `vote` +(`poll_id`, `name`, `choices`) + SELECT + `id_sondage`, + `nom`, + REPLACE(REPLACE(REPLACE(`reponses`, 1, \'X\'), 2, 1), \'X\', 2) + FROM `user_studs`'); + } + +} + \ No newline at end of file diff --git a/app/classes/Framadate/Migration/Migration.php b/app/classes/Framadate/Migration/Migration.php new file mode 100644 index 0000000000000000000000000000000000000000..e6d0eb9e5648f748dcef35f32b7114f30f83eb92 --- /dev/null +++ b/app/classes/Framadate/Migration/Migration.php @@ -0,0 +1,15 @@ +<?php +namespace Framadate\Migration; + +interface Migration { + + /** + * This methode is called only one time in the migration page. + * + * @param \PDO $pdo The connection to database + * @return bool true is the execution succeeded + */ + function execute(\PDO $pdo); + +} + \ No newline at end of file diff --git a/app/inc/constants.php.template b/app/inc/constants.php.template index d7b58bca6156fca6322de0b5c41401804c8bee6e..61781a6c40b177bbec0510244b1847cdbdada38e 100644 --- a/app/inc/constants.php.template +++ b/app/inc/constants.php.template @@ -41,6 +41,9 @@ const DB_PASSWORD = '<database password>'; // Database server name, leave empty to use a socket const DB_CONNECTION_STRING = 'mysql:host=<database host>;dbname=<database name>;port=<database port>'; +// Name of the table that store migration script already executed +const MIGRATION_TABLE = 'framadate_migration'; + // Default Language using POSIX variant of BC P47 standard (choose in $ALLOWED_LANGUAGES) const LANGUE = 'fr_FR'; diff --git a/bandeaux.php b/bandeaux.php index f93117796d12572709a51c608f1e4c1467746516..a5aea4fc3d26ebb69665e5b3b325c1438cd1ed40 100644 --- a/bandeaux.php +++ b/bandeaux.php @@ -45,7 +45,9 @@ function bandeau_titre($titre) <main role="main">'; global $connect; - if ($connect->areTablesCreated()) { + $tables = $connect->allTables(); + $diff = array_diff($tables, ['comment', 'poll', 'slot', 'vote']); + if (0 != count($diff)) { echo '<div class="alert alert-danger">'. _('Framadate is not properly installed, please check the "INSTALL" to setup the database before continuing.') .'</div>'; bandeau_pied(); die(); diff --git a/from_0-8_to_0-9.sql b/from_0-8_to_0-9.sql deleted file mode 100644 index 2b2ae23db08b0816f8ed19310ea09af4ac5b0e7a..0000000000000000000000000000000000000000 --- a/from_0-8_to_0-9.sql +++ /dev/null @@ -1,136 +0,0 @@ --- -------------------------------------------------------- - --- --- Table structure `poll` --- - -CREATE TABLE IF NOT EXISTS `poll` ( - `id` CHAR(16) NOT NULL, - `admin_id` CHAR(24) NOT NULL, - `title` TEXT NOT NULL, - `description` TEXT, - `admin_name` VARCHAR(64) DEFAULT NULL, - `admin_mail` VARCHAR(128) DEFAULT NULL, - `creation_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `end_date` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', - `format` VARCHAR(1) DEFAULT NULL, - `editable` TINYINT(1) DEFAULT '0', - `receiveNewVotes` TINYINT(1) DEFAULT '0', - `active` TINYINT(1) DEFAULT '1', - PRIMARY KEY (`id`) -) - ENGINE = InnoDB - DEFAULT CHARSET = utf8; - --- -------------------------------------------------------- - --- --- Table structure `slot` --- - -CREATE TABLE IF NOT EXISTS `slot` ( - `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `poll_id` CHAR(16) NOT NULL, - `title` TEXT, - `moments` TEXT, - PRIMARY KEY (`id`), - KEY `poll_id` (`poll_id`) -) - ENGINE = InnoDB - DEFAULT CHARSET = utf8; - --- -------------------------------------------------------- - --- --- Table structure `comment` --- - -CREATE TABLE IF NOT EXISTS `comment` ( - `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `poll_id` CHAR(16) NOT NULL, - `name` TEXT, - `comment` TEXT NOT NULL, - PRIMARY KEY (`id`), - KEY `poll_id` (`poll_id`) -) - ENGINE = InnoDB - DEFAULT CHARSET = utf8; - --- -------------------------------------------------------- - --- --- Table structure `vote` --- - -CREATE TABLE IF NOT EXISTS `vote` ( - `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `poll_id` CHAR(16) NOT NULL, - `name` VARCHAR(64) NOT NULL, - `choices` TEXT NOT NULL, - PRIMARY KEY (`id`), - KEY `poll_id` (`poll_id`) -) - ENGINE = InnoDB - DEFAULT CHARSET = utf8; - --- -------------------------------------------------------- - --- --- Migrate data from `sondage` to `poll` --- - -INSERT INTO `poll` -(`id`, `admin_id`, `title`, `description`, `admin_name`, `admin_mail`, `creation_date`, `end_date`, `format`, `editable`, `receiveNewVotes`, `active`) - SELECT - `id_sondage`, - `id_sondage_admin`, - `titre`, - `commentaires`, - `nom_admin`, - `mail_admin`, - `titre`, - `date_creation`, - `date_fin`, - SUBSTR(`format`, 1, 1) AS `format`, - CASE SUBSTR(`format`, 2, 1) - WHEN '+' THEN 1 - ELSE 0 END AS `editable`, - `mailsonde`, - CASE SUBSTR(`format`, 2, 1) - WHEN '-' THEN 0 - ELSE 1 END AS `active` - FROM sondage; - --- -------------------------------------------------------- - --- --- Migrate data from `sujet_studs` to `slot` --- - --- TODO Migrate this, is not so simple -/*INSERT INTO `slot` -(`poll_id`, `title`, `moments`) - SELECT `id_sondage`, - FROM `user_studs`;*/ - --- -------------------------------------------------------- - --- --- Migrate data from `comments` to `comment` --- - -INSERT INTO `comment` -(`poll_id`, `name`, `comment`) - SELECT `id_sondage`, `usercomment`, `comment` - FROM `comments`; - --- -------------------------------------------------------- - --- --- Migrate data from `user_studs` to `vote` --- - -INSERT INTO `vote` -(`poll_id`, `name`, `choices`) - SELECT `id_sondage`, `nom`, REPLACE(REPLACE(REPLACE(`reponses`, '1', 'X'), '2', '1'), 'X', 2) - FROM `user_studs`; diff --git a/migration.php b/migration.php new file mode 100644 index 0000000000000000000000000000000000000000..af64ef9311508f99fce93144068486fb03d4a707 --- /dev/null +++ b/migration.php @@ -0,0 +1,60 @@ +<?php +use Framadate\Migration\From_0_8_to_0_9_Migration; +use Framadate\Migration\Migration; +use Framadate\Utils; + +include_once __DIR__ . '/app/inc/init.php'; + +function output($msg) { + echo $msg . '<br/>'; +} + +// List a Migration sub classes to execute +$migrations = [ + new From_0_8_to_0_9_Migration(), + new From_0_8_to_0_9_Migration() +]; + +// Check if MIGRATION_TABLE already exists +$tables = $connect->allTables(); +$pdo = $connect->getPDO(); + +if (!in_array(MIGRATION_TABLE, $tables)) { + $pdo->exec(' +CREATE TABLE IF NOT EXISTS `' . MIGRATION_TABLE . '` ( + `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `name` TEXT NOT NULL, + `execute_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) + ENGINE = MyISAM + DEFAULT CHARSET = utf8;'); + + output('Table ' . MIGRATION_TABLE . ' created.'); +} + +$selectStmt = $pdo->prepare('SELECT id FROM ' . MIGRATION_TABLE . ' WHERE name=?'); +$insertStmt = $pdo->prepare('INSERT INTO ' . MIGRATION_TABLE . ' (name) VALUES (?)'); + +// Loop on every Migration sub classes +foreach ($migrations as $migration) { + $className = get_class($migration); + + // Check if $className is a Migration sub class + if (!$migration instanceof Migration) { + output('The class '. $className . ' is not a sub class of Framadate\\Migration\\Migration.'); + exit; + } + + // Check if the Migration is already executed + $selectStmt->execute([$className]); + $executed = $selectStmt->rowCount(); + $selectStmt->closeCursor(); + + if (!$executed) { + $migration->execute($pdo); + $insertStmt->execute([$className]); + output('Migration done: ' . $className); + } + +}