# Summary

# Project URL

https://www.drupal.org/project/content_lock

# Where is the code?

The code is in these issue patches, which currently is generated from this GitHub pull request: https://github.com/juanolalla/content_lock/pull/1/files

# Estimated completion date

# Dependencies

# Who's doing the port?

# What help do they need?

# D8 roadmap

# Background and reference information

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mgifford created an issue. See original summary.

mgifford’s picture

brenk28’s picture

Here is a patch that make the D8 module functional until this gets updated. It against the 1.x-dev version from March 1 of 2016. It's not really an update of the existing module, though it does use it's schema (well, not the ajax column).

Here's how it works:

  • adds a content_lock table that has fields for nid, uid and timestamp
  • using form_hook_alter for the node edit form, if form has node id, check the content_lock table and if there is an entry for this node, display a message and disable the form
  • if there isn't an entry, save uid and timestamp to content_lock table, now this content is "locked"
  • in the form submit, remove the locked row from content_lock table (the node has been updated as is free to edit)
  • in a hook_entity_predelete checks the content_lock table for the nid to see if it is locked and if so, reroute to content admin page to prevent deletion

Considerations:

  • a person can click away from the page and no update is made to the lock table; but there is permission for breaking a lock to get around a bunch of locked content
  • Assumes that users will login with individual user accounts. I.e., multiple people will not be logging in under the same user name.
  • In a batch deletion of content, when a locked node is found, execution simply halts
brenk28’s picture

There were a couple typos in the last one causing the permission not to work. Here is a new one.

dawehner’s picture

I'm currently working on a port of the 7.x-2.x branch, which support multiple entity types, for example.

dawehner’s picture

flocondetoile’s picture

I worked on a D8 port of content lock module for a project, starting from #2606856: Drupal 8 Release? patch #3. My needs was to support node, block_content and taxonomy term entity. And the deadline was short.

The patch attached is used on a production site, and permit to lock these entities from simultaneous editing. I worked only the main feature on content lock module, so without the ajax feature, lock by format or the path protected feature, or others features may be.

I wanted to share this work that could be a first step to a D8 port, but the @dawehner work (I just saw writing these lines) seems more interesting (ajax feature for unlock a content entity if the user quit the page without submitting the form, seems that it will support any content entity, using a content entity type instead of a custom table, lock by format).

Content lock timeout module is also included. And some basic integration with views for node entity type is supported too (this was already in the patch #2606856: Drupal 8 Release?).

Some functional tests cover the main feature, but there is not yet tests about preventing an entity deletion if currently edited, and the timeout feature.

@dawehner may be you could use some parts of this patch, even if your approach is different.

flocondetoile’s picture

If the maintainer (@Joseph Zhao) can enable the automated tests on the 8.x branch, we could see the results.

mtift’s picture

The patch from #7 works for us, too. However, to help protect against orphaned locks, the attached patch adds a sentence to the message so that it reads:

This content is now locked by you against simultaneous editing. This content will remain locked if you navigate away from this page without saving it.

mtift’s picture

FileSize
75.73 KB

Ooops, missed a spot.

mtift’s picture

FileSize
795 bytes
75.96 KB

Well, it seems a bit weird to be patching my patch, but since we can't really open up issues against a patch, I'm going to offer a slightly different solution.

We are having problems with editors accidentally saving locked nodes, which can also bring them back to the seemingly unlocked node where they can make changes to the locked node. Consequently, the attached patch removes not just delete, but also publish and unpublish functionality when content is locked.

flocondetoile’s picture

Would be nice if we could have a first 8.x-1.x version committed, and why not a first alpha ?

m4olivei’s picture

+++ b/content_lock.module
@@ -19,3 +25,245 @@ function content_lock_help($route_name, RouteMatchInterface $route_match) {
+      $redirect = new LocalRedirectResponse($url);

This hook implementation needs to be re-thought. hook_entity_predelete will run any time a delete is triggered, including via code. I'm currently running into a situation where my Behat test suite is failing b/c the code in content_lock_entity_predelete recognizes a lock violation and sends a redirect response.

This logic should be limited to the UI somehow. Maybe form altering and adding a validation callback.

flocondetoile’s picture

It would be easier to work on a dev version, instead of working on a big patch.

juanolalla’s picture

Status: Active » Needs review
FileSize
76.76 KB
10 KB

After using the site with content lock for a few days, it's become clear that a cancel button is needed. Consider this scenario:

  • User visits a node (locking it from other editors)
  • User decides they aren't ready to work on it.
  • User clicks the back button or the 'View' tab.

In this case, the content is locked. The only way for the content to unlock is to save the node, which isn't always the desired action. You may wish to leave the node without changing it, and end the lock.

For this reason it appears we need a cancel button on nodes where the user has a lock, so they can clear the lock without saving.

I've implemented this button link over the patch #11, since it is working very well but we don't have anything of this committed to the D8 version of the project yet.

I've had to change the previous default redirection to the entity edit form, otherwise the user would be trapped in redirection, locking the content from the edit form, and coming back to the edit form which would be again locked by him or her. I've added destination query parameter as an option for redirection (as when coming from admin/content), otherwise it would be redirected to the canonical route of the entity (view).

I've made some adjustments for consistency, and fixed a couple of minor things, as a unused "use" statement and a misplaced var type annotation.

dawehner’s picture

  1. +++ b/content_lock.install
    @@ -0,0 +1,60 @@
    +function content_lock_schema() {
    +  $schema['content_lock'] = array(
    +    'description' => 'content lock module table.',
    +    'fields' => array(
    +      'entity_id' => array(
    +        'description' => 'The primary identifier for an entity.',
    +        'type' => 'int',
    +        'size' => 'normal',
    +        'unsigned' => TRUE,
    +        'not null' => TRUE,
    +        'default' => 0,
    +      ),
    +      'entity_type' => array(
    +        'description' => 'The type of an entity.',
    +        'type' => 'varchar',
    +        'length' => 255,
    +        'not null' => TRUE,
    +        'default' => 'node',
    +      ),
    +      'uid' => array(
    +        'description' => 'User that holds the lock.',
    +        'type' => 'int',
    +        'size' => 'normal',
    +        'unsigned' => TRUE,
    +        'not null' => TRUE,
    +        'default' => 0,
    +      ),
    +      'timestamp' => array(
    +        'description' => 'Time the lock occurred.',
    +        'size' => 'normal',
    +        'type' => 'int',
    +        'unsigned' => TRUE,
    +        'not null' => TRUE,
    +        'default' => 0,
    +      ),
    +    ),
    +    'indexes' => array(
    +      'user' => array('uid'),
    +    ),
    +    'foreign keys' => array(
    +      'uid' => array(
    +        'table' => 'users_field_data',
    +        'columns' => array('uid' => 'uid'),
    +      ),
    +    ),
    +  );
    +
    +  return $schema;
    +}
    

    Conceptually this really reminds me of the locking feature in views. We are using the tempstore functionality in the user module for that (service: ```user.shared_tempstore```), which should make all the DB storage here redundant.

  2. +++ b/content_lock.module
    @@ -19,3 +24,249 @@ function content_lock_help($route_name, RouteMatchInterface $route_match) {
    +  $base_form_id_supported = [
    +    'node_form',
    +    'block_content_form',
    +    'taxonomy_term_form',
    +  ];
    

    Is there a reason you don't support any entity type? Oh I see, this is bound to the particular form structure, too bad. As a follow up we could move this logic into a new handler type on entity types, so you can implement your own logic if needed. inline_entity_form does something similar.

  3. +++ b/content_lock.module
    @@ -19,3 +24,249 @@ function content_lock_help($route_name, RouteMatchInterface $route_match) {
    +  if (!is_null($entity->id())) {
    

    Nitpick: You can use $entity->isNew() for that

juanolalla’s picture

Thanks @dawehner!

I've cloned the content_lock 8.x-1.x branch in GitHub and the patch in the 2606858 branch, so we can work on issues through that branch / pull request, and the patch can be generated from it.

I've actually opened three issues, one with some pending work on the unlock button, other with the improvements suggested by @dawehner, and a third with other proposed changes required for testing by the D8 Strict Schema

https://github.com/juanolalla/content_lock/issues

juanolalla’s picture

Issue summary: View changes
FileSize
77.98 KB

Attaching a new patch with my last work, which corresponds with this GitHub pull request: https://github.com/juanolalla/content_lock/pull/1/files

The differences are:

1. https://github.com/juanolalla/content_lock/pull/6/files
I've solved the problem described in https://github.com/juanolalla/content_lock/issues/2#issuecomment-266821561, implementing a custom access for the break lock forms that doesn't require the general permision for breaking any content lock, allowing also the access to user that currently has the content locked.

2. https://github.com/juanolalla/content_lock/pull/7/files
I've addressed the config changes needed for the new Strict Schema testing that is enabled by default for Drupal 8 tests (GitHub issue https://github.com/juanolalla/content_lock/issues/4).

jazzdrive3’s picture

Status: Needs review » Reviewed & tested by the community

I've reviewed the patch and it works great. Marking this as ready.

chr.fritsch’s picture

Looks quite good. One thing i noticed, that the module should not have a hard dependency on the block_content module

mkolar’s picture

Hello guys, thanks for your work :)... As I wrote this already as comment to pull request on GitHub: route content_lock_timeout.settings_form should require "administer content lock" permission or something like this instead of "access administration pages". What do you think? For example with this permission my editors (they have access to admin pages) will be able to setup timeout for locks.

juanolalla’s picture

I think you're right @chr.fritsch, as @dawehner already mentioned too. I've created an specific issue for that in GitHub: https://github.com/juanolalla/content_lock/issues/9

The same with your comment @mkolar, created issue https://github.com/juanolalla/content_lock/issues/8

If this patch were commited sooner we would recreate those issues in Drupal.org content_lock project, but while this is still a big patch in this issue queue it makes more sense to me to be able to work separately on GitHub issues and merging one by one into the main pull request, corresponding to this patch.

Thanks both!

chr.fritsch’s picture

Status: Reviewed & tested by the community » Fixed

I recently got push access to this module.

So i just pushed #18 to the D8 branch.

Thank you @juanolalla for the awesome work. Would be nice if you could create issues in the d.o. issue queue for all outstanding tasks.

juanolalla’s picture

Thank you, and also thanks for creating the issues in d.o. I've deleted those in GitHub since we no longer need that repo.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.