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

Manual.rst: add doc for record locking.

Dirty.php: workaround for #4127
parent 7db36c32
......@@ -1486,18 +1486,54 @@ General
page. This is nice to configure few Typo 3 pages. The disadvantage is that the user might loose the navigation.
.. _record_locking:
Record locking
--------------
Forms and 'record delete'-function support basic record locking. If a user opens a form and start to change content, a
record lock will be acquired in the background. If the lock is denied (another user already owns a lock on the record) an
alert is shown.
By default the record lock mode is 'exclusive' and the default timeout is 15 minutes. Both can be configured per form. The
initial default timeout can also be configured in `config.qfq.ini`_ (will be copied to the form during creating the form).
If a timeout expires, the lock is deleted. During the next change in a form, the lock is acquired again.
A lock is assgined to a record of a table. Multiple forms, with the same primary table, uses the same lock for a given record.
If a `Form` acts on further records (e.g. via FE action), those records are not protected by this basic record locking.
If a user tries to delete a record and another user already owns a lock on that record, the delete action is denied.
If there are different locking modes in mulitiple forms, the most restricting mode applies for the current lock.
Exclusive
^^^^^^^^^
An existing lock on a record forbids any write action on that record.
Advisory
^^^^^^^^
An existing lock on a record informs the user that another user is currently working on that record. Nevertheless,
writing is allowed.
None
^^^^
No locking at all.
.. _comment-space-character:
Comment- and space-character
----------------------------
The following applies to the fields `Form.parameter` and `FormElement.parameter`:
* Lines will be trimmed - leading and trailing spaces will be removed.
* If a leading and/or trailing space is needed, escape it: '\ hello world \' > ' hello world '.
* Lines starting with a '#' are treated as a comment and will not be parsed. Suche lines are treated as 'empty lines'.
* The comment sign can be escaped with '\'.
* Lines starting with a '#' are treated as a comment and will not be parsed. Such lines are treated as 'empty lines'.
* The comment sign can be escaped with '\\'.
.. _form-main:
......
......@@ -272,10 +272,14 @@ class QuickFormQuery {
$dirty = new Dirty();
// $dirty->checkDirtyAndRelease($formMode, $this->formSpec[F_RECORD_LOCK_TIMEOUT_SECONDS],
// $this->formSpec[F_DIRTY_MODE], $this->formSpec[F_TABLE_NAME], $recordId);
$lockStatus = $dirty->getCheckDirty( $this->formSpec[F_TABLE_NAME], $recordId, $recordDirty, $msg);
switch($lockStatus) {
$lockStatus = $dirty->getCheckDirty($this->formSpec[F_TABLE_NAME], $recordId, $recordDirty, $msg);
switch ($lockStatus) {
case LOCK_NOT_FOUND:
throw new UserFormException("Missing record lock: please reload the form, edit and save again.", ERROR_DIRTY_MISSING_LOCK);
if ($this->formSpec[F_DIRTY_MODE] != DIRTY_MODE_NONE) {
throw new UserFormException("Missing record lock: please reload the form, edit and save again.", ERROR_DIRTY_MISSING_LOCK);
}
break;
case LOCK_FOUND_CONFLICT:
throw new UserFormException($msg, ERROR_DIRTY_ALREADY_LOCKED);
case LOCK_FOUND_OWNER:
......@@ -554,7 +558,7 @@ class QuickFormQuery {
case FORM_SAVE:
case FORM_UPDATE:
// $this->feSpecNative = $this->db->getNativeFormElements(SQL_FORM_ELEMENT_ALL_CONTAINER, ['no', $this->formSpec["id"], 'native'], $this->formSpec);
$this->feSpecNative = $this->getNativeFormElements(SQL_FORM_ELEMENT_NATIVE_TG_COUNT, [$this->formSpec["id"]], $this->formSpec);
$this->feSpecNative = $this->getNativeFormElements(SQL_FORM_ELEMENT_NATIVE_TG_COUNT, [$this->formSpec["id"]], $this->formSpec);
break;
case FORM_DELETE:
......@@ -1012,7 +1016,7 @@ class QuickFormQuery {
case SIP_SIP:
case SIP_URLPARAM:
case SIP_TABLE:
continue; // do not copy these params to the new SIP
continue; // do not copy these params to the new SIP
case SIP_RECORD_ID:
// set the new recordId
......
......@@ -325,9 +325,10 @@ class Dirty {
// Is the dirtyRecord mine?
if ($lockStatus == LOCK_FOUND_OWNER) {
if (false == $this->checkModified($tableName, $recordId, $recordDirty[DIRTY_RECORD_MODIFIED])) {
return [API_STATUS => API_ANSWER_STATUS_CONFLICT, API_MESSAGE => 'The record has been modified in the meantime. Please reload the form, edit and save again.'];
}
// Uncommentent as long as '#4127 /Record Locking: save() impliziert 'release'' is open
// if (false == $this->checkModified($tableName, $recordId, $recordDirty[DIRTY_RECORD_MODIFIED])) {
// return [API_STATUS => API_ANSWER_STATUS_CONFLICT, API_MESSAGE => 'The record has been modified in the meantime. Please reload the form, edit and save again.'];
// }
// Clear the lock
$this->deleteDirtyRecord($recordDirty[COLUMN_ID]);
......
......@@ -1011,8 +1011,6 @@ class DirtyTest extends \AbstractDatabaseTest {
$result = $dirty->process();
}
/**
* Clear Session to have a new clean environment
*
......
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