Tentando evitar crons sempre que possível, mas com base na resposta de @Farahmand, coloquei uma variação desse código em um onUserLogout()
evento do plug-in do usuário :
Quando qualquer usuário efetua logout , o plug-in faz check-in de seu conteúdo, bem como quaisquer outros check-outs que possam ter sido abandonados. Queria que apenas determinados grupos de usuários fossem afetados e garantisse que qualquer conteúdo de usuário administrativo nunca fosse afetado (por nossos próprios motivos internos - talvez exagero em instalações típicas, mas, no nosso caso, temos grupos de usuários personalizados que podem estar em vários dos grupos de usuários padrão, portanto, foram responsáveis por essa sobreposição).
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;
}
Tenho certeza de que o SQL pode ser ajustado para fusos horários etc., mas aqui está a instrução SQL resultante:
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))
)