I am not exactly sure why the checkout_checkout is called during prepare op of nodeapi - i think i saw something posted somewhere suggesting why but can't find it now. The problem is that when a node is submitted the prepare hook is run and the checkout_checkout routine is run when it shouldn't be.

With the current function this doesn't actually hurt (other than minor performance hit of doing sql that isnt needed) but i modded your code to add a msg stating that node has now been locked when i go to edit page (which seems like a good idea to have). So with this addition it now becomes obvious that the redundant checkout is happening since i see the checked out msg appearing when i do the submit (followed by the "node has been updated" msg).

Because the update op does the checkout_release right after the prepare.. no harm is done as far as the table being correct. It just breaks having this msg there.

Also, why is it that you want to allow the user that has a node locked to come in and edit from another window/browser/machine/etc? It seems like this is a bad idea. Especially with the added feature you have now of providing link to checkin when you go to edit an already checkout node it seems to make even less sense. I have patched this function as well and changed the "go ahead and checkin" msg to be a bit more WARNING like to state that edits in other windows will be lost.

I'll post both these patches here once i modify the nodepai so that code doesnt checkout on submit (should be later tonight).

Peter Lindstrom
LiquidCMS - Content Management Solution Experts

Comments

liquidcms’s picture

StatusFileSize
new24.99 KB

Ok here is the patch i suggested although i actually found a couple bugs in the code as well - which i have fixed.

fixes/additions to checkout-5.x-1.0.module:
- bug with _exit if destination query is present
- bug with leading slash on "check back in link" in _message
- add even current user can't edit
- fix no checkout on submit
- add checkout msg

liquidcms’s picture

BTW - there is at least still 1 outstanding issue with this module which i likely will fix later this weekend. The use case is as follows:

- user edits node in window 1

- user tries to edit node in window 2
    - window 2 goes back to referring page and gives warning that edits in other windows will be lost if node is checked back in but gives link to allow checkin
    - selecting this link causes checkin and then checkout and goes to edit page in (window 2)

- window 1 is still open and if user navigates away from it the node will be checked in (even though user is now editing in window 2 but node is not checked out)

Simplest solution is to not allow user to checkin – but some way to release lock is required.

liquidcms’s picture

Status: Active » Needs review
smk-ka’s picture

Version: master » 5.x-1.x-dev
StatusFileSize
new8.87 KB

Outstanding post, thanks for pointing out these issues!

Since there were some interesting questions in your comments, and because some issues turned out to have even more bugs, I've taken some time to largely fix these and refactor several parts of the code. The changes in detail:

  • The biggest change was moving the node locking and releasing from hook_nodeapi() and hook_exit(), respectively, to a new central location (checkout_process()), which will be invoked during hook_menu() processing. This will allow users to specify additional paths that should keep a node locked, while the former approach only worked with the regular node edit form (despite the presence of some detection mechanism). For example, the default paths have already been enhanced by revisions and revisions/* pages, so a node will now be locked when administering revisions. Note there still is no admin page that lets you modify these paths.
  • As you already pointed out, the use of request_uri() and referer_uri() functions were the cause for several bugs. request_uri() has almost everywhere been replaced by $_GET['q'], whereas the usage of referer_uri() needed a lot more processing to work properly with clean urls enabled/disabled and (especially) url aliases.
  • Display the error message even for the same user and also the initial message when a document has been locked for the first time were both reasonable changes.
  • All issues about nodes being checked out multiple times *should* have been solved.
  • Additionally, checkout_checkout()'s obscure return value has been replaced by some cleaner logic. Several functions now have more descriptive names (hopefully).

Re comment #2: The key point is that the user already has been warned before the administrative check-in in big red letters, that when forcing a check-in any other editing session will be nuked. (That's also the reason why this is backed by an access permission, because only admins should have the power to forcefully release locks, not regular editing users). IMO there isn't anything left to do here.

liquidcms’s picture

very cool that you have taken the time to go through my patch and implement; but a couple questions/comments:

Since i have tested my solution a reasonable amount and i know that it fits with what my client was looking for i am a little hesitant to use your patch. That being said, i believe there is a lot to be said for using the "real" version and keeping up to date with any new developments/additions

Do you think that your patch includes at least everything that mine did (because i know i need all these things for my clients needs)?

- It sounds a bit like your 1st point you are suggesting you need to hand code additional paths as you need them for knowing when to remove the lock - possibly as opposed to stripping the query off as i did - but not sure; i'll need to check out the code.

- by your point 4 are you suggesting that your original solution should have prevented same user from checking out a checked out node and therefore my solution was not implemented - i could retest; but pretty sure this is not the case.

Also, re: my comment #2 - this is tricky. After a bit of thinking i think the only way to solve this issue (if my client wants me to; not sure yet) is to completely redo this module to be AJAX based. By this i am referring to the concept of a node lockout keep-alive. Not sure if you are familiar with the concept but this basically has the original edit page continually (perhaps 1 / min) send a "refresh" to the checkout table entry. This opens up the ability to do a lot of things much cleaner - but of course at the expense of requiring constant communication with the server.

With this approach the cron task is no longer needed. Any need window attempting to edit the node (such as from the same user) may basically now communicate (via the db) with the original window. If user chose to edit in new window a msg could be sent back to open window with a msg stating it is no longer able to edit. Likely not too tricky to code all this but again; i'll need to see what my client thinks abut the "final" issue.

cheers,
peter...

liquidcms’s picture

StatusFileSize
new2.28 KB

just to continue with this i ahve added another "feature"

currently when a user comes across a locked node they may only clear that lock if they have "admin checkout" rights.

it seemed to make sense that they should also be able to clear that lock if they are the user that owns the lock - so this patch adds that.

sorry, but havent had time to test smk-ka's patch and he hasnt had time to respond to my post regarding how different it is than mine - so i am still using my patched version - so this patch is on that.

wmostrey’s picture

Status: Needs review » Reviewed & tested by the community

I think both patches should get their own issue. smk-ka's patch from comment #4 patched perfectly against 5.x-1.0 and actually made the module work. It wasn't working for me at all in even the most simple of cases and now all works as advertised. It's RTBC.

ptalindstrom, perhaps you could re-roll your patch against that version?

jgraham’s picture

Thanks for the patch smk-ka it applied cleanly and installed fine.

However, when I edit a node (as admin) save it and then edit it as a user without "check out documents" permission I get a string of errors when attempting to edit;

user warning: Table 'cache_views' was not locked with LOCK TABLES query: SELECT data, created, headers, expire FROM cache_views WHERE cid = 'views_urls' in /var/www/drupal/includes/database.mysql.inc on line 172.
user warning: Table 'view_view' was not locked with LOCK TABLES query: SELECT name, url FROM view_view WHERE page = 1 AND LENGTH(url) > 0 in /var/www/drupal/includes/database.mysql.inc on line 172.
user warning: Table 'cache_views' was not locked with LOCK TABLES query: SELECT data, created, headers, expire FROM cache_views WHERE cid = 'views_default_views:en' in /var/www/drupal/includes/database.mysql.inc on line 172.
user warning: Table 'cache_views' was not locked with LOCK TABLES query: SELECT data, created, headers, expire FROM cache_views WHERE cid = 'views_tables:en' in /var/www/drupal/includes/database.mysql.inc on line 172.
user warning: Table 'v' was not locked with LOCK TABLES query: SELECT v.*, n.type FROM vocabulary v LEFT JOIN vocabulary_node_types n ON v.vid = n.vid ORDER BY v.weight, v.name in /var/www/drupal/includes/database.mysql.inc on line 172.
user warning: Table 'role' was not locked with LOCK TABLES query: SELECT * FROM role ORDER BY name in /var/www/drupal/includes/database.mysql.inc on line 172.

However, if the scenario is reproduced but the second user attempting to edit has the "check out documents" permission everything works as expected, and no errors/warnings are generated.

Should all users that can or may potentially edit any document be assigned the 'check out documents' privilege? If so, isn't that an unnecessary setting since all necessary information can be gleaned strictly by whether or not the user can edit a node? Or am I missing something here?

smk-ka’s picture

@jgraham
Could you please try the 2.x branch (available on the releases page)? This should have this bug (and others) fixed.

I'm still not sure how we should proceed with the 1.x branch (ie, this issue) and if it's worth fixing it. The reason why I've started a new branch was because my patch (#4) introduced several API changes, which I took as a starting point to completely overhaul the module. Backporting from there seems like a non-trivial task to me.

socialnicheguru’s picture

I am using pageroute. When I hit the back button in my browser, I get the error

"This content has been modified by another user, changes cannot be saved" and I cannot do anything.

I am on the same machine and browser.

Do I need to install the checkout module in order to get around this?

Chris

smk-ka’s picture

@activelyOUT
No, this seems to be a problem with pageroute itself, which this module can't resolve.

smk-ka’s picture

Status: Reviewed & tested by the community » Fixed

D5-2.0 has finally been released, closing this issue.

Anonymous’s picture

Status: Fixed » Closed (fixed)

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