Skip to content
This repository has been archived by the owner on Nov 3, 2023. It is now read-only.

Feature: to lock a content element, module, article, page etc. when somebody else is editing it at the same time #8412

Closed
jankout opened this issue Jul 18, 2016 · 11 comments
Labels

Comments

@jankout
Copy link

jankout commented Jul 18, 2016

I would like to have a feature to lock a content element, module, article, page etc. when somebody else is editing it at the same time. Admin could set whether and what should be locked when the described situation comes.

For example in the Typo3 works like this: when admin wants to edit something what somebody else is editing at the same time, it appears a notice (pop up) that somebody is editing and if you want to go on, you take the risk to overwrite it.

Always when two or more persons are editing something in the backend there should be a lock symbol next to the editing content.

@leofeyer
Copy link
Member

As discussed at the developer's meeting in July 2016, access tracking should be bound to version numbers, which simplifies recognizing "dead lock". Also, if a new version is created while someone is editing an element, there should be a flash message telling them when saving it.

@jankout
Copy link
Author

jankout commented Jul 26, 2016

Great. Thank you very much.

@leofeyer
Copy link
Member

leofeyer commented Jan 20, 2017

Here's how I would implement it:

interface LockService
{
    /**
     * Adds a new lock entry.
     *
     * @param string   $table     The table name
     * @param int      $id        The record ID
     * @param int      $sessionId The ID of the user session
     * @param int|null $version   An optional version number if versioning is supported
     */
    public function lock($table, $id, $sessionId, $version = null);

    /**
     * Checks if an entry is locked.
     *
     *   - Is the element still at the locked version?
     *   - Is there still a session matching the session ID?
     *
     * @param string $table The table name
     * @param int    $id    The record ID
     *
     * @return bool
     */
    public function isLocked($table, $id);
    
    /**
     * Removes a lock entry.
     *
     * @param string $table     The table name
     * @param int    $id        The record ID
     * @param int    $sessionId The ID of the user session
     *
     * @return int|null The initial version number or null if versioning is not supported
     */
    public function unlock($table, $id, $sessionId);
}

Then we could use it like this:

$lockService = $container->get('contao.lock_service');

if ($lockService->isLocked('tl_content', 22)) {
    // Show a "the element is currently edited by user X" screen
    // Proceed or go back?
}

$lockService->lock('tl_content', 22, 2, 8);

// Show the edit screen

if ($canSave) {
    // save

    $initialVersion = $lockService->unlock('tl_content', 22, 2);

    if ($newVersion != $initialVersion + 1) {
        // Show a "user X has created another version while you were editing" screen
    }
}

It could work something like this:

  • User A starts editing content element 4.
  • The lock services adds a lock entry for tl_content.4 with user ID 2 and version 1.
  • User B starts editing content element 4.
  • He sees a "This element is currently edited by user A. Proceed?" screen.
  • If he clicks "cancel", he is taken back and nothing else happens.
  • Otherwise lock services adds a lock entry for tl_content.4 with user ID 3 and version 1.
  • If user B saves his changes, version 2 of the record is created.
  • If user A saves his changes, version 3 of the record is created.
  • The lock service recognizes the jump from version 1 to version 3 and shows a "User B has created another version while you were editing the record" screen.

@contao/developers Does this make sense?

@jankout
Copy link
Author

jankout commented Jan 20, 2017

Great. For me it sounds good. Maybe it would be useful to see in the backend at the start who else is login-in.

@aschempp
Copy link
Member

aschempp commented Jan 20, 2017 via email

@asaage
Copy link

asaage commented Jan 20, 2017

  • He sees a "This element is currently edited by user A. Proceed?" screen.
  • If he clicks "cancel", he is taken back and nothing else happens.

I think there is a lot to consider. It should not require aditional user interaction to proceed.
How would you handle multiple Browser-Tab's of a single user?
What if a record gets locked by two users? How would the service behave with the various submitOnChange fields or shortcut-Icon's like publish?

@leofeyer
Copy link
Member

Also, we need to implement expiration, maybe checking the user's session.

It is already part of the interface. Read the phpDoc of the isLocked() method. 😄

@leofeyer
Copy link
Member

It should not require aditional user interaction to proceed.

It definitely should! There must be an option to know about the lock status before the edit form is loaded. Otherwise there would be a lock entry and no way for us to prevent a deadlock if the user hits the "go back" button.

@asaage
Copy link

asaage commented Jan 20, 2017

So you would impose a lock when the edit form is loaded? But the user could still go back then without saving.
Wouldn't it be better to just check for an increased version of the record on save and then notify?

@leofeyer
Copy link
Member

That was not the original request.

@leofeyer
Copy link
Member

leofeyer commented May 5, 2017

See contao/core-bundle#809.

@leofeyer leofeyer closed this as completed May 5, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants