Commit d231eb20 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Feature #3981 / Record Locking

Dirty.php: record delete is handled - if lock exist, delete is not allowed.
parent c9a42543
......@@ -271,7 +271,7 @@ class QuickFormQuery {
if ($formMode === FORM_DELETE || $formMode === FORM_SAVE) {
$dirty = new Dirty();
$timeOutDurationSeconds = $this->store->getVar(STORE_SYSTEM, SYSTEM_RECORD_LOCK_TIMEOUT_SECONDS);
$dirty->checkDirtyAndRelease($this->formSpec[F_DIRTY_MODE], $this->formSpec[F_TABLE_NAME], $recordId, $timeOutDurationSeconds);
$dirty->checkDirtyAndRelease($formMode, $this->formSpec[F_DIRTY_MODE], $this->formSpec[F_TABLE_NAME], $recordId, $timeOutDurationSeconds);
}
if ($formMode === FORM_DELETE) {
......
......@@ -187,14 +187,15 @@ class Dirty {
* Release a dirtyRecord. This is only possible if the current user owns the dirtyRecord.
* In case of not owner, throws an exception and the save should break.
*
* @param $dirtyMode
* @param $tableName
* @param $recordId
* @param $timeOutDurationSeconds
* @param string $formMode
* @param string $dirtyMode
* @param string $tableName
* @param int $recordId
* @param int $timeOutDurationSeconds
* @throws CodeException
* @throws UserFormException
*/
public function checkDirtyAndRelease($dirtyMode, $tableName, $recordId, $timeOutDurationSeconds) {
public function checkDirtyAndRelease($formMode, $dirtyMode, $tableName, $recordId, $timeOutDurationSeconds) {
if ($recordId == 0) {
return; // New records never have a recordDirty nor a conflict.
......@@ -207,11 +208,27 @@ class Dirty {
}
if (empty($recordDirty)) {
if ($formMode == FORM_DELETE) {
return;
}
throw new UserFormException("Missing record lock: please reload the form, edit and save again.");
}
$msgUser = (empty($recordDirty[DIRTY_FE_USER])) ? "another user" : "user '$recordDirty[DIRTY_FE_USER]'";
$msgAt = "at " . $recordDirty[COLUMN_CREATED] . " from " . $recordDirty[DIRTY_REMOTE_ADDRESS];
if ($formMode == FORM_DELETE) {
throw new UserFormException("The record has been locked by $msgUser $msgAt");
}
// Is the dirtyRecord mine?
if ($recordDirty[DIRTY_QFQ_USER_SESSION_COOKIE] == $this->client[CLIENT_COOKIE_QFQ]) {
//TODO Check ob der Record seit dem Lock veraendert wurde. Falls ja, eine Meldung und Frage was zu tun ist.
//TODO
// Clear the lock
$this->deleteDirtyRecord($recordDirty[COLUMN_ID]);
return;
......@@ -222,13 +239,9 @@ class Dirty {
// Check if overwrite is allowed
if ($dirtyMode == DIRTY_MODE_ADVISORY && $recordDirty[F_DIRTY_MODE] == DIRTY_MODE_ADVISORY) {
$this->deleteDirtyRecord($recordDirty[COLUMN_ID]);
return;
}
$at = "at " . $recordDirty[COLUMN_CREATED] . " from " . $recordDirty[DIRTY_REMOTE_ADDRESS];
$msgUser = (empty($recordDirty[DIRTY_FE_USER])) ? "another user" : "user '$recordDirty[DIRTY_FE_USER]'";
// Check if the record is timed out
if ($timeOutDurationSeconds != 0) {
$datetimeExpire = date_add(date_create($recordDirty[COLUMN_MODIFIED]), date_interval_create_from_date_string("$timeOutDurationSeconds second"));
......@@ -238,7 +251,7 @@ class Dirty {
}
}
throw new UserFormException("Save not possible - the record has been locked by $msgUser $at");
throw new UserFormException("Save not possible - the record has been locked by $msgUser $msgAt");
}
......
......@@ -129,18 +129,19 @@ CREATE TABLE IF NOT EXISTS `FormElement` (
#//
#DELIMITER ;
DROP TABLE IF EXISTS `Dirty`;
CREATE TABLE IF NOT EXISTS `Dirty` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`sip` VARCHAR(255) NOT NULL,
`tableName` VARCHAR(255) NOT NULL,
`recordId` INT(11) NOT NULL,
`recordModified` DATETIME NOT NULL,
`feUser` VARCHAR(255) NOT NULL,
`qfqUserSessionCookie` VARCHAR(255) NOT NULL,
`dirtyMode` ENUM('timeout', 'readonly', 'overwrite') NOT NULL,
`remoteAddress` VARCHAR(45) NOT NULL,
`modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created` DATETIME NOT NULL,
`id` INT(11) NOT NULL AUTO_INCREMENT,
`sip` VARCHAR(255) NOT NULL,
`tableName` VARCHAR(255) NOT NULL,
`recordId` INT(11) NOT NULL,
`recordModified` DATETIME NOT NULL,
`feUser` VARCHAR(255) NOT NULL,
`qfqUserSessionCookie` VARCHAR(255) NOT NULL,
`dirtyMode` ENUM('exclusive', 'advisory', 'none') NOT NULL DEFAULT 'exclusive',
`remoteAddress` VARCHAR(45) NOT NULL,
`modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created` DATETIME NOT NULL,
PRIMARY KEY (`id`),
KEY `sip` (`sip`),
KEY `tableName` (`tableName`),
......@@ -210,7 +211,8 @@ VALUES
(1, 'created', 'Created', 'readonly', 'text', 'all', 'native', 380, 0, 20, '', '', '', '', '', 3, '', '', '', 'specialchar', 'no', ''),
(1, 'multi', 'Multi', 'show', 'fieldset', 'all', 'native', 400, 0, 0, '', '', '', '', '', 4, '', '', '', 'specialchar', 'no', ''),
(1, 'multiMode', 'Multi Mode', 'show', 'radio', 'all', 'native', 410, 0, 0, '', '', '', '', '', 4, '', '', '', 'specialchar', 'no', ''),
(1, 'multiMode', 'Multi Mode', 'show', 'radio', 'all', 'native', 410, 0, 0, '', '', '', '', '', 4, '', '', '',
'specialchar', 'no', ''),
(1, 'multiSql', 'Multi SQL', 'show', 'text', 'all', 'native', 420, '40,3', 0, '', '', '', '', '', 4, '', '', '',
'none', 'no', ''),
(1, 'multiDetailForm', 'Multi Detail Form', 'show', 'text', 'all', 'native', 430, 0, 0, '', '', '', '', '', 4,
......
Supports Markdown
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