Commit 4fea4f31 authored by Nic's avatar Nic Committed by Aegir user

events participants extension

parent 3302bfff
This diff is collapsed.
# View My Event Participants
## Overview
View My Event Participants (org.civicrm.vieweventparticipants) is a CiviCRM extension granting access for event creators to view or edit their events' participants.
## Why would you need this extension?
This extension is only needed if you have users who create events but who do not have permission to view or edit all the participant contacts of those events. I.e. the event creators do not have "view all contacts" or "edit all contacts" permission and do not have permission via ACLs (access control lists) to view or edit all the relevant contacts.
## What does this extension do?
It implements two new permissions: 'view my event participants' and 'edit my event participants'. These grant the user access to all the contacts who are participants of events that were created by the user.
**N.B.** If other ACLs are in place, e.g. through CiviCRM's "Manage ACLs" user interface, then this extension allows access to the user's events' participants _in addition to_ the contacts permitted by these other ACLs. Consider whether this is what you want: in some use cases, you might instead want to grant access to view/edit only the participants who are also permitted by the other ACLs.
E.g. suppose there's an existing ACL that gives a user access to all contacts with a UK address. With this extension, that user would have access to all UK contacts _plus_ all participants of events created by the user - even if those participants are outside the UK.
**Note:** access is granted by means of a hook. Consequently this will not show up in the CiviCRM user interface under Manage ACLs: it's done "under the hood".
## How do I use it?
1. Install the extension.
Currently this extension is not available for automated distribution through CiviCRM's Extension management screen and so must be manually downloaded onto the server, from https://github.com/circleinteractive/org.civicrm.vieweventparticipants and unpacked into your CiviCRM extensions directory. See https://docs.civicrm.org/sysadmin/en/latest/customize/extensions/ .
2. Enable the extension.
From the CiviCRM menu, go to Administer -> System settings -> Extensions. Click the **Enable** link for View Event Participants (org.civicrm.vieweventparticipants).
3. Grant permissions.
In your CMS's permissions management screen, grant the 'view my event participants' or 'edit my event participants' permissions to the users/roles who need to be able to view/edit their event participants.
<?xml version="1.0"?>
<extension key="org.civicrm.vieweventparticipants" type="module">
<file>vieweventparticipants</file>
<name>View My Event Participants</name>
<description>Grants access for event creators to view or edit their events' participants.</description>
<license>AGPL-3.0</license>
<maintainer>
<author>Dave Jenkins</author>
<email>davej@circle-interactive.co.uk</email>
</maintainer>
<urls>
<url desc="Main Extension Page">https://github.com/circleinteractive/org.civicrm.vieweventparticipants</url>
<url desc="Documentation">https://github.com/circleinteractive/org.civicrm.vieweventparticipants/blob/master/README.md</url>
<url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
</urls>
<releaseDate>2017-10-20</releaseDate>
<version>1.0.beta1</version>
<develStage>beta</develStage>
<compatibility>
<ver>4.7</ver>
</compatibility>
<comments>This is a new extension but has undergone extensive testing, including a suite of unit tests.</comments>
<civix>
<namespace>CRM/Vieweventparticipants</namespace>
</civix>
</extension>
<?xml version="1.0"?>
<phpunit backupGlobals="false" backupStaticAttributes="false" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" syntaxCheck="false" bootstrap="tests/phpunit/bootstrap.php">
<testsuites>
<testsuite name="My Test Suite">
<directory>./tests/phpunit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./</directory>
</whitelist>
</filter>
<listeners>
<listener class="Civi\Test\CiviTestListener">
<arguments/>
</listener>
</listeners>
</phpunit>
# Tests for org.civicrm.vieweventparticipants
**To run the tests:**
1. Set up a development build of CiviCRM, e.g. using [buildkit](https://docs.civicrm.org/dev/en/latest/tools/buildkit/).
2. Install the org.civicrm.vieweventparticipants extension in the default extensions directory, files/civicrm/ext/ .
3. In a terminal, go into the directory `files/civicrm/ext/org.civicrm.vieweventparticipants` .
4. Specify the location of your CiviCRM settings file, e.g.
```export CIVICRM_SETTINGS=/Users/myuser/buildkit/build/dmaster/sites/default/civicrm.settings.php```
using the actual location of your civicrm.settings.php file.
5. Run the tests with:
```phpunit4 ./tests/phpunit/CRM/Vieweventparticipants/ACLTest.php```
<?php
ini_set('memory_limit', '2G');
ini_set('safe_mode', 0);
eval(cv('php:boot --level=classloader', 'phpcode'));
// Allow autoloading of PHPUnit helper classes in this extension.
$loader = new \Composer\Autoload\ClassLoader();
$loader->add('CRM_', __DIR__);
$loader->add('Civi\\', __DIR__);
$loader->add('api_', __DIR__);
$loader->add('api\\', __DIR__);
$loader->register();
/**
* Call the "cv" command.
*
* @param string $cmd
* The rest of the command to send.
* @param string $decode
* Ex: 'json' or 'phpcode'.
* @return string
* Response output (if the command executed normally).
* @throws \RuntimeException
* If the command terminates abnormally.
*/
function cv($cmd, $decode = 'json') {
$cmd = 'cv ' . $cmd;
$descriptorSpec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => STDERR);
$oldOutput = getenv('CV_OUTPUT');
putenv("CV_OUTPUT=json");
$process = proc_open($cmd, $descriptorSpec, $pipes, __DIR__);
putenv("CV_OUTPUT=$oldOutput");
fclose($pipes[0]);
$result = stream_get_contents($pipes[1]);
fclose($pipes[1]);
if (proc_close($process) !== 0) {
throw new RuntimeException("Command failed ($cmd):\n$result");
}
switch ($decode) {
case 'raw':
return $result;
case 'phpcode':
// If the last output is /*PHPCODE*/, then we managed to complete execution.
if (substr(trim($result), 0, 12) !== "/*BEGINPHP*/" || substr(trim($result), -10) !== "/*ENDPHP*/") {
throw new \RuntimeException("Command failed ($cmd):\n$result");
}
return $result;
case 'json':
return json_decode($result, 1);
default:
throw new RuntimeException("Bad decoder format ($decode)");
}
}
<?php
require_once 'vieweventparticipants.civix.php';
/**
* Implements hook_civicrm_config().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_config
*/
function vieweventparticipants_civicrm_config(&$config) {
_vieweventparticipants_civix_civicrm_config($config);
}
/**
* Implements hook_civicrm_xmlMenu().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_xmlMenu
*/
function vieweventparticipants_civicrm_xmlMenu(&$files) {
_vieweventparticipants_civix_civicrm_xmlMenu($files);
}
/**
* Implements hook_civicrm_install().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_install
*/
function vieweventparticipants_civicrm_install() {
_vieweventparticipants_civix_civicrm_install();
}
/**
* Implements hook_civicrm_uninstall().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall
*/
function vieweventparticipants_civicrm_uninstall() {
_vieweventparticipants_civix_civicrm_uninstall();
}
/**
* Implements hook_civicrm_enable().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_enable
*/
function vieweventparticipants_civicrm_enable() {
CRM_Core_Session::setStatus(
ts(
"To use the extension: in your CMS's permissions management screen, grant the 'view my event participants' or 'edit my event participants' permissions to the users/roles who need to be able to view/edit their event participants.
See the <a href=\"%1\">documentation</a> for details.",
array(
'domain' => 'org.civicrm.vieweventparticipants',
1 => 'https://github.com/circleinteractive/org.civicrm.vieweventparticipants/blob/master/README.md',
)
),
ts(
'"View My Event Participants" extension enabled',
array('domain' => 'org.civicrm.vieweventparticipants')
),
'success'
);
_vieweventparticipants_civix_civicrm_enable();
}
/**
* Implements hook_civicrm_disable().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable
*/
function vieweventparticipants_civicrm_disable() {
_vieweventparticipants_civix_civicrm_disable();
}
/**
* Implements hook_civicrm_upgrade().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_upgrade
*/
function vieweventparticipants_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
return _vieweventparticipants_civix_civicrm_upgrade($op, $queue);
}
/**
* Implements hook_civicrm_managed().
*
* Generate a list of entities to create/deactivate/delete when this module
* is installed, disabled, uninstalled.
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed
*/
function vieweventparticipants_civicrm_managed(&$entities) {
_vieweventparticipants_civix_civicrm_managed($entities);
}
/**
* Implements hook_civicrm_caseTypes().
*
* Generate a list of case-types.
*
* Note: This hook only runs in CiviCRM 4.4+.
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes
*/
function vieweventparticipants_civicrm_caseTypes(&$caseTypes) {
_vieweventparticipants_civix_civicrm_caseTypes($caseTypes);
}
/**
* Implements hook_civicrm_angularModules().
*
* Generate a list of Angular modules.
*
* Note: This hook only runs in CiviCRM 4.5+. It may
* use features only available in v4.6+.
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes
*/
function vieweventparticipants_civicrm_angularModules(&$angularModules) {
_vieweventparticipants_civix_civicrm_angularModules($angularModules);
}
/**
* Implements hook_civicrm_alterSettingsFolders().
*
* @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterSettingsFolders
*/
function vieweventparticipants_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) {
_vieweventparticipants_civix_civicrm_alterSettingsFolders($metaDataFolders);
}
/**
* Implements hook_civicrm_permission().
*
* @link https://docs.civicrm.org/dev/en/master/hooks/hook_civicrm_permission/
*/
function vieweventparticipants_civicrm_permission(&$permissions) {
$permissions['view my event participants'] = array(
ts('CiviEvent: view my event participants', array('domain' => 'org.civicrm.vieweventparticipants')),
ts('Grants event creators permission to view their event\'s participants', array('domain' => 'org.civicrm.vieweventparticipants')),
);
$permissions['edit my event participants'] = array(
ts('CiviEvent: edit my event participants', array('domain' => 'org.civicrm.vieweventparticipants')),
ts('Grants event creators permission to edit their event\'s participants', array('domain' => 'org.civicrm.vieweventparticipants')),
);
}
/**
* Implements hook_civicrm_aclWhereClause().
*
* @link https://docs.civicrm.org/dev/en/master/hooks/hook_civicrm_aclWhereClause/
*/
function vieweventparticipants_civicrm_aclWhereClause($type, &$tables, &$whereTables, &$contactID, &$where) {
/*
* Grant access for event creators to view or edit their events' participants.
*/
if (!$contactID) {
return;
}
if ($type != CRM_Core_Permission::VIEW && $type != CRM_Core_Permission::EDIT) {
return;
}
/*
* Only allow access if user also has our permission.
*/
if ($type == CRM_Core_Permission::VIEW && !CRM_Core_Permission::check('view my event participants')) {
return;
}
if ($type == CRM_Core_Permission::EDIT && !CRM_Core_Permission::check('edit my event participants')) {
return;
}
if (!in_array('civicrm_participant', $whereTables)) {
$tables['civicrm_participant'] = $whereTables['civicrm_participant']
= "LEFT JOIN civicrm_participant ON contact_a.id = civicrm_participant.contact_id";
}
if (!in_array('civicrm_event', $whereTables)) {
$tables['civicrm_event'] = $whereTables['civicrm_event']
= "LEFT JOIN civicrm_event ON civicrm_participant.event_id = civicrm_event.id";
}
/*
* If other ACLs are in place, e.g. through ACL UI, then we allow access to
* the user's events' participants in addition to the contacts permitted by
* these other ACLs. Hence OR.
*/
if (!empty($where)) {
$where = "($where) OR ";
}
$where .= sprintf("(civicrm_event.created_id = %d)", $contactID);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment