by
KK » Sat Sep 18, 2021 3:07 am
Hi,
To be honest, Couch is supposed to be a 'single admin CMS' - this premise drives many of the decisions and keeps things simple. This, however, also means that having multiple users access the admin-panel (and work on the same resources) can lead to the 'lost updates' that you noticed.
One way of preventing this is from happening is by using 'pessimistic locking' - when a user opens a page for editing, everyone else is barred from doing the same till the user finally commits the save or closes the page. However, if the user happens to e.g. move way from her machine while the page is open, this will needlessly lock out the resource (some kind of timeout would be needed to free the page and make it available).
Another approach is to use 'optimistic locking' - basically, nothing is locked but at the point where a page is saved the system checks if the page has not already been modified by someone else (between the time the user opened it to edit and pressed the save button). If it has indeed been modified, the system will refuse to save the page (the user will need to re-open the page in edit mode).
Both the approaches will prevent users from overwriting each others work but the second one is simpler in getting the job done so let us use it.
Following is some code that you need to copy and paste in your 'addons/kfunctions.php' file (rename the sample file to this if not present).
- Code: Select all
// Custom field-type 'optimistic_lock'
class MyOptimistic_Lock extends KUserDefinedField{
// Load from database
function store_data_from_saved( $data ){
global $FUNCS, $DB;
$this->data = $this->page->modification_date;
}
function pre_render( &$def ){
$def['hide'] = 1;
}
function _render( $input_name, $input_id, $extra='', $dynamic_insertion=0 ){
$value = $this->data;
$html = '<input type="hidden" id="' . $input_id . '" name="'. $input_id .'" value="'. htmlspecialchars( $value, ENT_QUOTES, K_CHARSET ) .'" />';
return $html;
}
function validate(){
global $FUNCS;
if( $this->deleted || $this->k_inactive || $this->page->id==-1 ) return true;
if( $this->modified ){
$this->err_msg = 'This page has been modified by someone else. Please re-open it to see the modifications.';
return false;
}
return true;
}
// Save to database.
function get_data_to_save(){
return;
}
// Search value
function get_search_data(){
return;
}
function get_data( $for_ctx=0 ){
return;
}
}
$FUNCS->register_udf( 'optimistic_lock', 'MyOptimistic_Lock', 0/*not repeatable*/ );
The code above makes available a custom editable region of type 'optimistic_lock'.
To use it, please define one such region in the template(s) you need to protect e.g. this way -
- Code: Select all
<cms:editable type='optimistic_lock' name='post_lock' label='Post Lock' />
Of course, do not forget to visit the modified template as super-admin for the change to be picked-up by Couch.
OK, and that should be it; try opening a page of the protected template in two browsers (or tabs) and you'll see that if you save the page in one, trying to save it in the other will fail - you'll have to re-open the page to edit it (this will fetch fresh data so the user can see what has changed).
Hope this helps. Please test and let me know.