Commit 05b32a30 authored by Carsten  Rose's avatar Carsten Rose
Browse files

#3679, Automatic DB update - Schema & FormEditor

For updates of QFQ prior to 0.17.0, do:   ALTER TABLE  `Form` COMMENT =  'Version=<your old QFQ version>'
DatabaseUpdate.php, DatabaseUpdateData.php: new class.
QuickFormQuery.php: Add DB UpdateCheck
Database.php: moved to new subdirectory `database`. Add 'ALTER' as a new SQL command.
FormAction.php, TypeAhead.php, Report.php, Sendmail.php, FillStoreForm.php, Store.php, AbstractBuild.php, Delete.php, Evaluate.php: Update path to Database.php.
parent aa8d3089
......@@ -17,7 +17,7 @@ Documentation
-------------
See the documentation provided with the exentions inside Typo3
<your Typo3 installation>/typo3conf/ext/qfq/Documentation/_make/build/html/Index.html
<your Typo3 installation>/typo3conf/ext/qfq/Documentation/html/Index.html
Or the latest stable version under https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Index.html
......
......@@ -11,4 +11,5 @@ $EM_CONF[$_EXTKEY] = array(
'clearcacheonload' => true,
'state' => 'alpha',
'version' => '0.17.0'
);
\ No newline at end of file
);
......@@ -14,16 +14,16 @@ use qfq;
//use qfq\OnArray;
//use qfq\UserFormException;
require_once(__DIR__ . '/../qfq/store/Store.php');
require_once(__DIR__ . '/../qfq/Constants.php');
require_once(__DIR__ . '/../qfq/exceptions/DbException.php');
require_once(__DIR__ . '/../qfq/exceptions/UserFormException.php');
require_once(__DIR__ . '/../qfq/Database.php');
require_once(__DIR__ . '/../qfq/helper/HelperFormElement.php');
require_once(__DIR__ . '/../qfq/helper/Support.php');
require_once(__DIR__ . '/../qfq/helper/OnArray.php');
require_once(__DIR__ . '/../qfq/helper/Ldap.php');
require_once(__DIR__ . '/../qfq/report/Link.php');
require_once(__DIR__ . '/store/Store.php');
require_once(__DIR__ . '/Constants.php');
require_once(__DIR__ . '/exceptions/DbException.php');
require_once(__DIR__ . '/exceptions/UserFormException.php');
require_once(__DIR__ . '/database/Database.php');
require_once(__DIR__ . '/helper/HelperFormElement.php');
require_once(__DIR__ . '/helper/Support.php');
require_once(__DIR__ . '/helper/OnArray.php');
require_once(__DIR__ . '/helper/Ldap.php');
require_once(__DIR__ . '/report/Link.php');
/**
* Class AbstractBuildForm
......
......@@ -166,6 +166,9 @@ const ERROR_MISSING_INTL = 1075;
const ERROR_HTML_TOKEN_TOO_SHORT = 1076;
const ERROR_MISSING_PRINTF_ARGUMENTS = 1077;
const ERROR_MISSING_DEFINITON = 1078;
const ERROR_QFQ_VERSION = 1079;
const ERROR_PLAY_FORM_EDITOR_SQL = 1080;
// Subrecord
const ERROR_SUBRECORD_MISSING_COLUMN_ID = 1100;
......
......@@ -9,7 +9,7 @@
namespace qfq;
require_once(__DIR__ . '/Constants.php');
require_once(__DIR__ . '/Database.php');
require_once(__DIR__ . '/database/Database.php');
require_once(__DIR__ . '/store/Store.php');
......
......@@ -12,7 +12,7 @@ use qfq;
use qfq\Store;
require_once(__DIR__ . '/../qfq/store/Store.php');
require_once(__DIR__ . '/../qfq/Database.php');
require_once(__DIR__ . '/../qfq/database/Database.php');
require_once(__DIR__ . '/helper/Support.php');
/**
......
......@@ -34,7 +34,8 @@ require_once(__DIR__ . '/exceptions/UserFormException.php');
require_once(__DIR__ . '/exceptions/CodeException.php');
require_once(__DIR__ . '/exceptions/DbException.php');
require_once(__DIR__ . '/exceptions/ErrorHandler.php');
require_once(__DIR__ . '/Database.php');
require_once(__DIR__ . '/database/Database.php');
require_once(__DIR__ . '/database/DatabaseUpdate.php');
require_once(__DIR__ . '/Evaluate.php');
require_once(__DIR__ . '/BuildFormPlain.php');
require_once(__DIR__ . '/BuildFormTable.php');
......@@ -149,7 +150,14 @@ class QuickFormQuery {
$this->store = Store::getInstance($bodytext, $phpUnit);
$this->store->setVar(TYPO3_TT_CONTENT_UID, $t3data[T3DATA_UID], STORE_TYPO3);
$this->db = new Database();
$this->eval = new Evaluate($this->store, $this->db);
$config = $this->store->getStore(STORE_SYSTEM);
$updateDb = new DatabaseUpdate($this->db);
$updateDb->checkNupdate($config[SYSTEM_DB_SERVER], $config[SYSTEM_DB_USER], $config[SYSTEM_DB_PASSWORD], $config[SYSTEM_DB_NAME]);
}
/**
......
......@@ -15,15 +15,15 @@ use qfq\UserFormException;
use qfq\Support;
use qfq\Store;
require_once(__DIR__ . '/exceptions/UserFormException.php');
require_once(__DIR__ . '/exceptions/CodeException.php');
require_once(__DIR__ . '/exceptions/DbException.php');
require_once(__DIR__ . '/../exceptions/UserFormException.php');
require_once(__DIR__ . '/../exceptions/CodeException.php');
require_once(__DIR__ . '/../exceptions/DbException.php');
require_once(__DIR__ . '/store/Store.php');
require_once(__DIR__ . '/store/Config.php');
require_once(__DIR__ . '/helper/Support.php');
require_once(__DIR__ . '/helper/Logger.php');
require_once(__DIR__ . '/helper/BindParam.php');
require_once(__DIR__ . '/../store/Store.php');
require_once(__DIR__ . '/../store/Config.php');
require_once(__DIR__ . '/../helper/Support.php');
require_once(__DIR__ . '/../helper/Logger.php');
require_once(__DIR__ . '/../helper/BindParam.php');
/**
* Class Database
......@@ -86,12 +86,15 @@ class Database {
}
// DB Init
if ($dbInit !== false && $dbInit != '') {
$this->sql($dbInit);
}
}
/**
* Open mysqli database connection if not already done.
*
......@@ -313,6 +316,7 @@ class Database {
break;
case 'SET':
case 'ALTER':
$queryType = QUERY_TYPE_CONTROL;
$stat[DB_AFFECTED_ROWS] = 0;
$count = $stat[DB_AFFECTED_ROWS];
......
<?php
/**
* Created by PhpStorm.
* User: crose
* Date: 5/9/17
* Time: 8:56 AM
*/
namespace qfq;
require_once(__DIR__ . '/../exceptions/CodeException.php');
require_once(__DIR__ . '/Database.php');
/*
* Read the extension version number.
* Read the QFQ database version number: stored in the comment field of table 'Form'. Format: Version=x.y.z
* If versions different:
* * Import the update table 'DatabaseUpdateData.php'.
* * Play all changes after 'old' upto 'new'.
* * Save new QFQ database version in the comment field of table 'Form'
*
* In a new QFQ installation, the comment field of table 'Form' is empty. On the first call of QFQ, the version string will be set.
*
*/
class DatabaseUpdate {
/**
* @var Database instantiated class
*/
protected $db = null;
/**
* @param Database $db
*/
public function __construct(Database $db) {
$this->db = $db;
}
/**
* @return mixed
* @throws CodeException
*/
private function getExtensionVersion() {
$path = __DIR__ . '/../../../ext_emconf.php';
$_EXTKEY = EXT_KEY;
$EM_CONF = NULL;
if (@file_exists($path)) {
include $path;
if (isset($EM_CONF[$_EXTKEY]['version'])) {
return $EM_CONF[$_EXTKEY]['version'];
}
}
throw new CodeException('Failed to read extension version', ERROR_QFQ_VERSION);
}
/**
* @return bool
* @throws CodeException
* @throws DbException
*/
private function getDatabaseVersion() {
$row = $this->db->sql("SHOW TABLE STATUS WHERE Name='Form'", ROW_EXPECT_1);
$arr = explode('=', $row['Comment']);
if (count($arr) != 2 || $arr[0] != 'Version' || $arr[1] == '') {
return false;
}
return $arr[1];
}
/**
* @param $version
* @throws CodeException
* @throws DbException
*/
private function setDatabaseVersion($version) {
$this->db->sql("ALTER TABLE `Form` COMMENT = 'Version=$version'");
}
/**
* @throws CodeException
*/
public function checkNupdate($host, $user, $password, $database) {
$new = $this->getExtensionVersion();
$old = $this->getDatabaseVersion();
if ($new != $old) {
$this->dbUpdateStatements($old, $new);
$this->playFormEditorSql($host, $user, $password, $database);
$this->setDatabaseVersion($new);
}
}
/**
* @return null
* @throws CodeException
*/
private function readUpdateData() {
$path = __DIR__ . '/DatabaseUpdateData.php';
if (!@file_exists($path)) {
throw new CodeException("File '$path'' not found", ERROR_IO_OPEN);
}
$UPDATE_ARRAY = null;
include $path;
return $UPDATE_ARRAY;
}
/**
* @param $old
* @param $new
*/
private function dbUpdateStatements($old, $new) {
if ($new == '' || $old === false) {
return;
}
$updateArray = $this->readUpdateData();
$apply = false;
foreach ($updateArray as $key => $sqlStatements) {
if ($apply) {
// Play Statements
foreach ($sqlStatements as $sql) {
$this->db->sql($sql);
}
}
switch ($key) {
case $old:
$apply = true;
break;
case $new:
$apply = false;
break;
default:
break;
}
}
}
/**
* @param $host
* @param $user
* @param $password
* @param $database
* @throws CodeException
*/
private function playFormEditorSql($host, $user, $password, $database) {
$output = array();
$return_var = 0;
$host = escapeshellarg($host);
$user = escapeshellarg($user);
$password = escapeshellarg($password);
$database = escapeshellarg($database);
$cmd = "mysql -u $user --password=$password -h $host $database < " . __DIR__ . '/../../sql/formEditor.sql';
exec($cmd, $output, $return_var);
if ($return_var != 0) {
$msg = implode("\n", $output);
throw new CodeException("Error playing formEditor.sql: $msg", ERROR_PLAY_FORM_EDITOR_SQL);
}
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: crose
* Date: 5/9/17
* Time: 9:38 AM
*/
// Always put the latest updates to the end!!!
$UPDATE_ARRAY = array(
'0.12.0' => [
"ALTER TABLE `FormElement` ADD `rowLabelInputNote` SET('row','label','/label','input','/input','note','/note','/row') NOT NULL DEFAULT 'row,label,/label,input,/input,note,/note,/row' AFTER `bsNoteColumns` ",
"ALTER TABLE `FormElement` CHANGE `type` `type` ENUM( 'checkbox', 'date', 'datetime', 'dateJQW', 'datetimeJQW', 'extra', 'gridJQW', 'text', 'editor', 'time', 'note', 'password', 'radio', 'select', 'subrecord', 'upload', 'fieldset', 'pill', 'templateGroup', 'beforeLoad', 'beforeSave', 'beforeInsert', 'beforeUpdate', 'beforeDelete', 'afterLoad', 'afterSave', 'afterInsert', 'afterUpdate', 'afterDelete', 'sendMail' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'text' ",
],
'0.13.0' => [
" ALTER TABLE FormElement MODIFY COLUMN checkType ENUM('alnumx','digit','numerical','email','min|max','min|max date', 'pattern','allbut','all') NOT NULL DEFAULT 'alnumx' ",
],
'0.14.0' => [
" ALTER TABLE `FormElement` CHANGE `placeholder` `placeholder` VARCHAR(512) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' ",
],
'0.15.0' => [
"UPDATE FormElement SET parameter = REPLACE(parameter, 'typeAheadLdapKeyPrintf', 'typeAheadLdapIdPrintf')",
"ALTER TABLE `FormElement` CHANGE `placeholder` `placeholder` VARCHAR( 2048 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' ",
],
'0.16.0' => [
"ALTER TABLE `FormElement` ADD INDEX `feIdContainer` (`feIdContainer`)",
"ALTER TABLE `FormElement` ADD INDEX `ord` (`ord`)",
"ALTER TABLE `FormElement` ADD INDEX `feGroup` (`feGroup`)",
"ALTER TABLE `FormElement` ADD `adminNote` TEXT NOT NULL AFTER `note`",
],
'0.17.0' => [
"ALTER TABLE `FormElement` ADD `encode` ENUM( 'none', 'specialchar' ) NOT NULL DEFAULT 'specialchar' AFTER `subrecordOption`",
"UPDATE `FormElement` SET encode='none' WHERE class='native' AND type='editor'",
"ALTER TABLE `Form` ADD `escapeTypeDefault` ENUM( '', 's', 'd', 'l', 'L', 'm', '-' ) NOT NULL DEFAULT '' AFTER `permitEdit`",
"UPDATE `Form` SET `escapeTypeDefault`='-'",
],
);
......@@ -9,7 +9,7 @@
namespace qfq;
require_once(__DIR__ . '/../Constants.php');
require_once(__DIR__ . '/../Database.php');
require_once(__DIR__ . '/../database/Database.php');
require_once(__DIR__ . '/../store/Store.php');
require_once(__DIR__ . '/../Evaluate.php');
require_once(__DIR__ . '/../report/Sendmail.php');
......
......@@ -14,7 +14,7 @@ require_once(__DIR__ . '/../store/Sip.php');
require_once(__DIR__ . '/../store/Session.php');
require_once(__DIR__ . '/../Constants.php');
require_once(__DIR__ . '/../helper/Ldap.php');
require_once(__DIR__ . '/../Database.php');
require_once(__DIR__ . '/../database/Database.php');
class TypeAhead {
......
......@@ -14,7 +14,7 @@ namespace qfq;
require_once(__DIR__ . '/Define.php');
require_once(__DIR__ . '/Variables.php');
require_once(__DIR__ . '/Error.php');
require_once(__DIR__ . '/../Database.php');
require_once(__DIR__ . '/../database/Database.php');
require_once(__DIR__ . '/Link.php');
require_once(__DIR__ . '/Sendmail.php');
require_once(__DIR__ . '/../exceptions/UserReportExtension.php');
......
......@@ -5,7 +5,7 @@ namespace qfq;
//use qfq;
require_once(__DIR__ . '/../Constants.php');
require_once(__DIR__ . '/../Database.php');
require_once(__DIR__ . '/../database/Database.php');
class Sendmail {
......
......@@ -9,7 +9,7 @@
namespace qfq;
require_once(__DIR__ . '/Store.php');
require_once(__DIR__ . '/../Database.php');
require_once(__DIR__ . '/../database/Database.php');
require_once(__DIR__ . '/../Constants.php');
require_once(__DIR__ . '/../helper/HelperFormElement.php');
require_once(__DIR__ . '/../exceptions/UserFormException.php');
......
......@@ -18,7 +18,7 @@ require_once(__DIR__ . '/../../qfq/helper/Sanitize.php');
require_once(__DIR__ . '/../../qfq/Constants.php');
require_once(__DIR__ . '/../../qfq/store/Sip.php');
require_once(__DIR__ . '/../../qfq/store/T3Info.php');
require_once(__DIR__ . '/../../qfq/Database.php');
require_once(__DIR__ . '/../../qfq/database/Database.php');
require_once(__DIR__ . '/../../qfq/store/Config.php');
/*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment