I wanted to allow clients to easily toggle whether a document requires a webuser to be logged in. Also, by default, I wanted it to require a logged in webuser.
For my needs it was crucial to avoid using the access permissions tab. Why? It affects manager user access too which is an accident waiting to happen. Also it defaults to public access.
Using
the CakeModx class I was able to write a plugin for this. I have tested it and it works, use it at your own risk however.
To use it follow a couple of steps:
1. Setup a TV with the name "require-login" using input type "Radio options". Input option values should be like "No (make public)==no||Yes (Only for logged in members)==yes". Use default value "yes" and assign to your template.
2.
Download CakeModx, extract files and upload to "assets/cakemodx"
3. Create a new user group in manager tab security > web permissions > web user groups
4. Create a new resource group in manager tab security > web permissions > resource groups
5. Link step user groupd (step 3.) and resource group (step 4.) in manager tab security > web permissions > user/resource group links
6. Make a new plugin, call it "tvToggleDocGroup" and check system event "OnDocFormSave" in "System Events" tab. Then paste the following code in "General" tab > "Plugin Code"
/* Plugin tvToggleDocGroup by Johan "MrDutchy" van den Broek */
if ($id == '')
$id = $modx->documentIdentifier;
/* Settings */
// change this to your webgroup
$docgroup_priv = "wdgMembers";
// change this to your tv
$tv_toggle_priv = "require-login";
// change this to your template ids for which you wish to toggle
$runForTemplates = array(8,5,6);
$cakemodxPath = MODX_BASE_PATH . 'assets/cakemodx/';
include_once($cakemodxPath . 'CakeMODx.php');
/* Initialization */
$cake = new CakeModx;
$group_id = $cake->group_name2id($docgroup_priv);
$doc = $modx->getDocument($id, 'template');
$currTemplate = $doc['template'];
/* Processing*/
if (in_array($currTemplate, $runForTemplates))
{
//$modx->logEvent(5, 1, "plugin triggered for doc (id: {$id}, template id: {$currTemplate} and group id: {$group_id}) - taking action for this template", 'tvToggleDocGroup');
$login = $modx->getTemplateVar($tv_toggle_priv, '*', $id);
// determine if it is already part of this group
$table = $modx->getFullTableName("document_groups");
$res = $modx->db->select('id',$table, "`document_group` = {$group_id} AND `document` = {$id}");
$count = $modx->db->getRecordCount($res);
//$modx->logEvent(5, 1, "When checking group membership $count records were found", 'tvToggleDocGroup');
if (isset($login['value']) && $login['value'] === 'yes')
{
if ($count == 0)
$cake->joinDocgroup($docgroup_priv, $id);
}
else
{
if ($count > 0)
{
$affected = $modx->db->delete($table, "document_group = $group_id AND document = $id");
//$modx->logEvent(5, 3, "$affected rows affected when remove document (id: {$id}) from group (id: {$group_id})", 'tvToggleDocGroup');
}
}
}
else
{
// do nothing, this is not a template we've activated it for!
//$modx->logEvent(5, 1, "plugin triggered for doc (id: {$id}, template id: {$currTemplate} and group id: {$group_id}) - no action for this template", 'tvToggleDocGroup');
}
7. Do a minor edit of the plugin code to reflect the document group name you picked in step 4., i.e. change line
$docgroup_priv = "wdgMembers";
IMPORTANT: I experienced a caveat with including the CakeMODx class in a plugin. Turns out you cannot include CakeMODx.class.php or you will get a MODx parser error. Rename it to CakeMODx.php and update your include and it will go away.
EDITS:
IMPROVEMENT: Dynamically determine table name to account for modx table prefixes (new code in this post)
FIX: Fixed a bug of multiple adding to a group. Added select query to check whether document is already in the group. (new code in this post)