11

Most of our users don't understand that they should Save or Cancel when they edit their content, thus we constantly have scores of articles and categories that are locked. I realize that this can be done manually by the administrator, but editing goes on 24/7, and it's rather tedious to constantly go through all the items determining if the edit has been abandoned or not.

Is there a way to have the locks timeout somehow?

2 Answers 2

5

You can define an hourly cron job or use phpMyAdmin and execute this SQL:

UPDATE `jos_content` c    SET c.checked_out = 0, c.checked_out_time = 0 WHERE HOUR(TIMEDIFF(CONVERT_TZ(NOW(), @@session.time_zone, '+00:00'), c.checked_out_time)) >= 2;
UPDATE `jos_categories` c SET c.checked_out = 0, c.checked_out_time = 0 WHERE HOUR(TIMEDIFF(CONVERT_TZ(NOW(), @@session.time_zone, '+00:00'), c.checked_out_time)) >= 1;

Note: Replace jos with your table prefix.

The above SQL check in articles and categories that checked out more than two hours or an hour ago respectively. I assume that an article and a category should be saved within two hours and an hour respectively. You may increase those numbers.

2
  • Figured it would be a job for SQL, but hoped for some kind of hidden feature in the newer versions.
    – GDP
    Commented Dec 8, 2014 at 23:43
  • 1
    AFAIK there is no built-in feature but you can use Autocheckin plugin.
    – Farahmand
    Commented Dec 9, 2014 at 6:52
5

Trying to avoid crons whenever possible, but based on the answer from @Farahmand, I put a variation of this code in a User Plugin onUserLogout() event:

When any user logs out, the plugin checks-in any of their content, as well as any other check-outs that may have been abandoned. I wanted only certain user groups to be affected, and to insure that any admin users content was never affected (for our own internal reasons - perhaps overkill for typical installations, but in our case we have custom user groups that can be in several of the standard user groups, so have accounted for that overlap).

function onUserLogout() {
    $groups_include = '2,4,10';    // Affect Registered, Publishers, and Custom Group
    $groups_exclude = '7,8';       // Don't affect Administrators or Super Users

    $db = JFactory::getDbo();
    $query = $db->getQuery(true);
    $query->update($db->quoteName('#__content'))
    ->set('checked_out = 0, checked_out_time = 0')
    ->where('( checked_out = '.JFactory::getUser()->id.' ) OR (
        checked_out_time < NOW() - INTERVAL 12 HOUR
        AND checked_out IN (SELECT GROUP_CONCAT(user_id) FROM scm_user_usergroup_map WHERE group_id IN ('.$groups_include.'))
        AND checked_out NOT IN (SELECT GROUP_CONCAT(user_id) FROM scm_user_usergroup_map WHERE group_id IN ('.$groups_exclude.'))
        )'
    );
    $db->setQuery($query);
    $db->execute();
    return true;
}

I'm sure the SQL can be adjusted for Timezones, etc., but here's the resulting SQL statement:

UPDATE `gdp_content`
SET checked_out = 0, checked_out_time = 0
WHERE ( checked_out = 30 ) OR (
        checked_out_time < NOW() - INTERVAL 12 HOUR
        AND checked_out IN (SELECT GROUP_CONCAT(user_id) FROM scm_user_usergroup_map WHERE group_id IN (2,10,11))
        AND checked_out NOT IN (SELECT GROUP_CONCAT(user_id) FROM scm_user_usergroup_map WHERE group_id IN (7,8))
        )
2
  • 2
    cool idea this one after user logout
    – FFrewin
    Commented Dec 9, 2014 at 16:37
  • 2
    Nice answer. To avoid adjusting Timezones, you can replace checked_out_time < NOW() - INTERVAL 12 HOUR with checked_out_time < JFactory::getDate('now +12 hours') - Not tested.
    – Farahmand
    Commented Dec 9, 2014 at 20:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.