From: Aidan Saunders Date: Thu, 29 Mar 2018 23:57:21 +0000 (+0100) Subject: Add view-only option on permissioned relationships: X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=f871c3a9dab4b28d2ad522c7b7952049aebffbd8;p=civicrm-core.git Add view-only option on permissioned relationships: Change is_permission_a_b and is_permission_b_a to 3 values instead of 2. Update schema, DAO, BAO, view/edit/add, search, report --- diff --git a/CRM/Contact/BAO/Contact/Permission.php b/CRM/Contact/BAO/Contact/Permission.php index 09b8925ede..883b39922f 100644 --- a/CRM/Contact/BAO/Contact/Permission.php +++ b/CRM/Contact/BAO/Contact/Permission.php @@ -116,7 +116,7 @@ WHERE contact_id IN ({$contact_id_list}) if (count($result_set) < count($contact_ids)) { $rejected_contacts = array_diff_key($contact_ids, $result_set); // @todo consider storing these to the acl cache for next time, since we have fetched. - $allowed_by_relationship = self::relationshipList($rejected_contacts); + $allowed_by_relationship = self::relationshipList($rejected_contacts, $type); foreach ($allowed_by_relationship as $contact_id) { $result_set[(int) $contact_id] = TRUE; } @@ -161,7 +161,7 @@ WHERE contact_id IN ({$contact_id_list}) } // check permission based on relationship, CRM-2963 - if (self::relationshipList(array($id))) { + if (self::relationshipList(array($id), $type)) { return TRUE; } @@ -330,10 +330,13 @@ AND ac.user_id IS NULL * @param array $contact_ids * List of contact IDs to be filtered * + * @param int $type + * access type CRM_Core_Permission::VIEW or CRM_Core_Permission::EDIT + * * @return array * List of contact IDs that the user has permissions for */ - public static function relationshipList($contact_ids) { + public static function relationshipList($contact_ids, $type) { $result_set = array(); // no processing empty lists (avoid SQL errors as well) @@ -354,6 +357,11 @@ AND ac.user_id IS NULL // add a select statement for each direection $directions = array(array('from' => 'a', 'to' => 'b'), array('from' => 'b', 'to' => 'a')); + // CRM_Core_Permission::VIEW is satisfied by either CRM_Contact_BAO_Relationship::VIEW or CRM_Contact_BAO_Relationship::EDIT + $is_perm_condition = $type == CRM_Core_Permission::VIEW ? + ' != ' . CRM_Contact_BAO_Relationship::NONE : + ' = ' . CRM_Contact_BAO_Relationship::EDIT; + // NORMAL/SINGLE DEGREE RELATIONSHIPS foreach ($directions as $direction) { $user_id_column = "contact_id_{$direction['from']}"; @@ -373,7 +381,7 @@ SELECT civicrm_relationship.{$contact_id_column} AS contact_id WHERE civicrm_relationship.{$user_id_column} = {$contactID} AND civicrm_relationship.{$contact_id_column} IN ({$contact_id_list}) AND civicrm_relationship.is_active = 1 - AND civicrm_relationship.is_permission_{$direction['from']}_{$direction['to']} = 1 + AND civicrm_relationship.is_permission_{$direction['from']}_{$direction['to']} {$is_perm_condition} $AND_CAN_ACCESS_DELETED"; } @@ -399,9 +407,9 @@ SELECT second_degree_relationship.contact_id_{$second_direction['to']} AS contac WHERE first_degree_relationship.contact_id_{$first_direction['from']} = {$contactID} AND second_degree_relationship.contact_id_{$second_direction['to']} IN ({$contact_id_list}) AND first_degree_relationship.is_active = 1 - AND first_degree_relationship.is_permission_{$first_direction['from']}_{$first_direction['to']} = 1 + AND first_degree_relationship.is_permission_{$first_direction['from']}_{$first_direction['to']} {$is_perm_condition} AND second_degree_relationship.is_active = 1 - AND second_degree_relationship.is_permission_{$second_direction['from']}_{$second_direction['to']} = 1 + AND second_degree_relationship.is_permission_{$second_direction['from']}_{$second_direction['to']} {$is_perm_condition} $AND_CAN_ACCESS_DELETED"; } } diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index eda7792aa7..2050ba9778 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -4042,7 +4042,6 @@ WHERE $smartGroupClause $relationType = $this->getWhereValues('relation_type_id', $grouping); $targetName = $this->getWhereValues('relation_target_name', $grouping); $relStatus = $this->getWhereValues('relation_status', $grouping); - $relPermission = $this->getWhereValues('relation_permission', $grouping); $targetGroup = $this->getWhereValues('relation_target_group', $grouping); $nameClause = $name = NULL; @@ -4188,21 +4187,7 @@ civicrm_relationship.start_date > {$today} } $where[$grouping][] = "(contact_b.is_deleted = {$onlyDeleted})"; - //check for permissioned, non-permissioned and all permissioned relations - if ($relPermission[2] == 1) { - $where[$grouping][] = "( -civicrm_relationship.is_permission_a_b = 1 -)"; - $this->_qill[$grouping][] = ts('Relationship - Permissioned'); - } - elseif ($relPermission[2] == 2) { - //non-allowed permission relationship. - $where[$grouping][] = "( -civicrm_relationship.is_permission_a_b = 0 -)"; - $this->_qill[$grouping][] = ts('Relationship - Non-permissioned'); - } - + $this->addRelationshipPermissionClauses($grouping, $where); $this->addRelationshipDateClauses($grouping, $where); $this->addRelationshipActivePeriodClauses($grouping, $where); if (!empty($relTypes)) { @@ -4235,6 +4220,23 @@ civicrm_relationship.is_permission_a_b = 0 } } + public function addRelationshipPermissionClauses($grouping, &$where) { + $relPermission = $this->getWhereValues('relation_permission', $grouping); + if ($relPermission) { + $where[$grouping][] = "(civicrm_relationship.is_permission_a_b IN (" . implode(",", $relPermission[2]) . "))"; + + $allRelationshipPermissions = CRM_Contact_BAO_Relationship::buildOptions('is_permission_a_b'); + $relQill = ''; + foreach ($relPermission[2] as $rel) { + if (!empty($relQill)) { + $relQill .= ' OR '; + } + $relQill .= ts($allRelationshipPermissions[$rel]); + } + $this->_qill[$grouping][] = ts('Permissioned Relationships') . ' - ' . $relQill; + } + } + /** * Add start & end date criteria in * @param string $grouping diff --git a/CRM/Contact/BAO/Relationship.php b/CRM/Contact/BAO/Relationship.php index 67c9539388..2b4db2f0a1 100644 --- a/CRM/Contact/BAO/Relationship.php +++ b/CRM/Contact/BAO/Relationship.php @@ -37,6 +37,12 @@ class CRM_Contact_BAO_Relationship extends CRM_Contact_DAO_Relationship { */ const ALL = 0, PAST = 1, DISABLED = 2, CURRENT = 4, INACTIVE = 8; + /** + * Constants for is_permission fields. + * Note: the slightly non-obvious ordering is due to history... + */ + const NONE = 0, EDIT = 1, VIEW = 2; + /** * Create function - use the API instead. * @@ -470,8 +476,8 @@ class CRM_Contact_BAO_Relationship extends CRM_Contact_DAO_Relationship { public static function getdefaults() { return array( 'is_active' => 0, - 'is_permission_a_b' => 0, - 'is_permission_b_a' => 0, + 'is_permission_a_b' => self::NONE, + 'is_permission_b_a' => self::NONE, 'description' => '', 'start_date' => 'NULL', 'case_id' => NULL, @@ -2118,17 +2124,29 @@ AND cc.sort_name LIKE '%$name%'"; "action=view&reset=1&cid={$values['cid']}&id={$values['id']}&rtype={$values['rtype']}"); if ($params['context'] == 'current') { - if (($params['contact_id'] == $values['contact_id_a'] AND $values['is_permission_a_b'] == 1) OR - ($params['contact_id'] == $values['contact_id_b'] AND $values['is_permission_b_a'] == 1) + if (($params['contact_id'] == $values['contact_id_a'] AND $values['is_permission_a_b'] == CRM_Contact_BAO_Relationship::EDIT) OR + ($params['contact_id'] == $values['contact_id_b'] AND $values['is_permission_b_a'] == CRM_Contact_BAO_Relationship::EDIT) ) { $relationship['sort_name'] .= ' *'; } - if (($values['cid'] == $values['contact_id_a'] AND $values['is_permission_a_b'] == 1) OR - ($values['cid'] == $values['contact_id_b'] AND $values['is_permission_b_a'] == 1) + if (($params['contact_id'] == $values['contact_id_a'] AND $values['is_permission_a_b'] == CRM_Contact_BAO_Relationship::VIEW) OR + ($params['contact_id'] == $values['contact_id_b'] AND $values['is_permission_b_a'] == CRM_Contact_BAO_Relationship::VIEW) + ) { + $relationship['sort_name'] .= ' +'; + } + + if (($values['cid'] == $values['contact_id_a'] AND $values['is_permission_a_b'] == CRM_Contact_BAO_Relationship::EDIT) OR + ($values['cid'] == $values['contact_id_b'] AND $values['is_permission_b_a'] == CRM_Contact_BAO_Relationship::EDIT) ) { $relationship['relation'] .= ' *'; } + + if (($values['cid'] == $values['contact_id_a'] AND $values['is_permission_a_b'] == CRM_Contact_BAO_Relationship::VIEW) OR + ($values['cid'] == $values['contact_id_b'] AND $values['is_permission_b_a'] == CRM_Contact_BAO_Relationship::VIEW) + ) { + $relationship['relation'] .= ' +'; + } } if (!empty($values['description'])) { diff --git a/CRM/Contact/DAO/Relationship.php b/CRM/Contact/DAO/Relationship.php index f61c5c220f..62b70944f1 100644 --- a/CRM/Contact/DAO/Relationship.php +++ b/CRM/Contact/DAO/Relationship.php @@ -6,7 +6,7 @@ * * Generated from xml/schema/CRM/Contact/Relationship.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:a5a833da9d5016f0aeb06ba7c1058b3c) + * (GenCodeChecksum:49381da59affbf165a4c9ce87c9a68ec) */ /** @@ -85,18 +85,16 @@ class CRM_Contact_DAO_Relationship extends CRM_Core_DAO { public $description; /** - * is contact a has permission to view / edit contact and - related data for contact b ? + * Permission that Contact A has to view/update Contact B * - * @var boolean + * @var int unsigned */ public $is_permission_a_b; /** - * is contact b has permission to view / edit contact and - related data for contact a ? + * Permission that Contact B has to view/update Contact A * - * @var boolean + * @var int unsigned */ public $is_permission_b_a; @@ -251,33 +249,37 @@ class CRM_Contact_DAO_Relationship extends CRM_Core_DAO { ], 'is_permission_a_b' => [ 'name' => 'is_permission_a_b', - 'type' => CRM_Utils_Type::T_BOOLEAN, + 'type' => CRM_Utils_Type::T_INT, 'title' => ts('Contact A has Permission Over Contact B'), - 'description' => 'is contact a has permission to view / edit contact and - related data for contact b ? - ', + 'description' => 'Permission that Contact A has to view/update Contact B', + 'required' => TRUE, 'table_name' => 'civicrm_relationship', 'entity' => 'Relationship', 'bao' => 'CRM_Contact_BAO_Relationship', 'localizable' => 0, 'html' => [ - 'type' => 'CheckBox', + 'type' => 'Radio', ], + 'pseudoconstant' => [ + 'callback' => 'CRM_Core_SelectValues::getPermissionedRelationshipOptions', + ] ], 'is_permission_b_a' => [ 'name' => 'is_permission_b_a', - 'type' => CRM_Utils_Type::T_BOOLEAN, + 'type' => CRM_Utils_Type::T_INT, 'title' => ts('Contact B has Permission Over Contact A'), - 'description' => 'is contact b has permission to view / edit contact and - related data for contact a ? - ', + 'description' => 'Permission that Contact B has to view/update Contact A', + 'required' => TRUE, 'table_name' => 'civicrm_relationship', 'entity' => 'Relationship', 'bao' => 'CRM_Contact_BAO_Relationship', 'localizable' => 0, 'html' => [ - 'type' => 'CheckBox', + 'type' => 'Radio', ], + 'pseudoconstant' => [ + 'callback' => 'CRM_Core_SelectValues::getPermissionedRelationshipOptions', + ] ], 'case_id' => [ 'name' => 'case_id', diff --git a/CRM/Contact/Form/Relationship.php b/CRM/Contact/Form/Relationship.php index cdc2898fde..fc115dcf92 100644 --- a/CRM/Contact/Form/Relationship.php +++ b/CRM/Contact/Form/Relationship.php @@ -260,6 +260,7 @@ class CRM_Contact_Form_Relationship extends CRM_Core_Form { else { $defaults['is_active'] = $defaults['is_current_employer'] = 1; $defaults['relationship_type_id'] = $this->_rtypeId; + $defaults['is_permission_a_b'] = $defaults['is_permission_b_a'] = CRM_Contact_BAO_Relationship::NONE; } $this->_enabled = $defaults['is_active']; @@ -339,8 +340,8 @@ class CRM_Contact_Form_Relationship extends CRM_Core_Form { $this->addField('is_active', array('label' => ts('Enabled?'), 'type' => 'advcheckbox')); - $this->addField('is_permission_a_b'); - $this->addField('is_permission_b_a'); + $this->addField('is_permission_a_b', array(), TRUE); + $this->addField('is_permission_b_a', array(), TRUE); $this->addField('description', array('label' => ts('Description'))); diff --git a/CRM/Contact/Form/Search/Criteria.php b/CRM/Contact/Form/Search/Criteria.php index 52d7a10016..845ab7c9a5 100644 --- a/CRM/Contact/Form/Search/Criteria.php +++ b/CRM/Contact/Form/Search/Criteria.php @@ -467,9 +467,9 @@ class CRM_Contact_Form_Search_Criteria { $form->addRadio('relation_status', ts('Relationship Status'), $relStatusOption); $form->setDefaults(array('relation_status' => 0)); // relation permission - $relPermissionOption = array(ts('Any'), ts('Yes'), ts('No')); - $form->addRadio('relation_permission', ts('Permissioned Relationship?'), $relPermissionOption); - $form->setDefaults(array('relation_permission' => 0)); + $allRelationshipPermissions = CRM_Contact_BAO_Relationship::buildOptions('is_permission_a_b'); + $form->add('select', 'relation_permission', ts('Permissioned Relationship'), + array('' => ts('- select -')) + $allRelationshipPermissions, FALSE, array('multiple' => TRUE, 'class' => 'crm-select2')); //add the target group if ($form->_group) { diff --git a/CRM/Core/SelectValues.php b/CRM/Core/SelectValues.php index 6f4ed3c8b4..3d429fa36e 100644 --- a/CRM/Core/SelectValues.php +++ b/CRM/Core/SelectValues.php @@ -1096,4 +1096,17 @@ class CRM_Core_SelectValues { ); } + /** + * Relationship permissions + * + * @return array + */ + public static function getPermissionedRelationshipOptions() { + return array( + CRM_Contact_BAO_Relationship::NONE => ts('None'), + CRM_Contact_BAO_Relationship::VIEW => ts('View only'), + CRM_Contact_BAO_Relationship::EDIT => ts('View and update'), + ); + } + } diff --git a/CRM/Report/Form/Contact/Relationship.php b/CRM/Report/Form/Contact/Relationship.php index dd20fba0ea..0e34078cdf 100644 --- a/CRM/Report/Form/Contact/Relationship.php +++ b/CRM/Report/Form/Contact/Relationship.php @@ -256,10 +256,10 @@ class CRM_Report_Form_Contact_Relationship extends CRM_Report_Form { 'title' => ts('Relationship End Date'), ), 'is_permission_a_b' => array( - 'title' => ts('Is permission A over B?'), + 'title' => ts('Permission A has to access B'), ), 'is_permission_b_a' => array( - 'title' => ts('Is permission B over A?'), + 'title' => ts('Permission B has to access A'), ), 'description' => array( 'title' => ts('Description'), @@ -310,22 +310,14 @@ class CRM_Report_Form_Contact_Relationship extends CRM_Report_Form { ), 'is_permission_a_b' => array( 'title' => ts('Does contact A have permission over contact B?'), - 'operatorType' => CRM_Report_Form::OP_SELECT, - 'options' => array( - '' => ts('- Any -'), - 1 => ts('Yes'), - 0 => ts('No'), - ), + 'operatorType' => CRM_Report_Form::OP_MULTISELECT, + 'options' => CRM_Contact_BAO_Relationship::buildOptions('is_permission_a_b'), 'type' => CRM_Utils_Type::T_INT, ), 'is_permission_b_a' => array( 'title' => ts('Does contact B have permission over contact A?'), - 'operatorType' => CRM_Report_Form::OP_SELECT, - 'options' => array( - '' => ts('- Any -'), - 1 => ts('Yes'), - 0 => ts('No'), - ), + 'operatorType' => CRM_Report_Form::OP_MULTISELECT, + 'options' => CRM_Contact_BAO_Relationship::buildOptions('is_permission_b_a'), 'type' => CRM_Utils_Type::T_INT, ), ), @@ -792,6 +784,19 @@ class CRM_Report_Form_Contact_Relationship extends CRM_Report_Form { $entryFound = TRUE; } + // Handle permissioned relationships + if (array_key_exists('civicrm_relationship_is_permission_a_b', $row)) { + $rows[$rowNum]['civicrm_relationship_is_permission_a_b'] + = ts(self::permissionedRelationship($row['civicrm_relationship_is_permission_a_b'])); + $entryFound = TRUE; + } + + if (array_key_exists('civicrm_relationship_is_permission_b_a', $row)) { + $rows[$rowNum]['civicrm_relationship_is_permission_b_a'] + = ts(self::permissionedRelationship($row['civicrm_relationship_is_permission_b_a'])); + $entryFound = TRUE; + } + // skip looking further in rows, if first row itself doesn't // have the column we need if (!$entryFound) { @@ -800,6 +805,19 @@ class CRM_Report_Form_Contact_Relationship extends CRM_Report_Form { } } + /** + * Convert values to permissioned relationship descriptions + * @param [int] $key + * @return [string] + */ + public static function permissionedRelationship($key) { + static $lookup; + if (!$lookup) { + $lookup = CRM_Contact_BAO_Relationship::buildOptions("is_permission_a_b"); + }; + return CRM_Utils_Array::value($key, $lookup); + } + /** * @param $valid bool - set to 1 if we are looking for a valid relationship, 0 if not * diff --git a/templates/CRM/Contact/Form/Relationship.tpl b/templates/CRM/Contact/Form/Relationship.tpl index d921c211a7..f2312bc11d 100644 --- a/templates/CRM/Contact/Form/Relationship.tpl +++ b/templates/CRM/Contact/Form/Relationship.tpl @@ -57,18 +57,34 @@ {if $row.is_permission_a_b}
{if $row.rtype EQ 'a_b' AND $is_contact_id_a} - {ts 1=$displayName 2=$row.display_name}%1 can view and update information about %2.{/ts} + {if $row.is_permission_a_b == 1} + {ts 1=$displayName 2=$row.display_name}%1 can view and update information about %2.{/ts} + {else} + {ts 1=$displayName 2=$row.display_name}%1 can view information about %2.{/ts} + {/if} {else} - {ts 1=$row.display_name 2=$displayName}%1 can view and update information about %2.{/ts} + {if $row.is_permission_a_b == 1} + {ts 1=$row.display_name 2=$displayName}%1 can view and update information about %2.{/ts} + {else} + {ts 1=$row.display_name 2=$displayName}%1 can view information about %2.{/ts} + {/if} {/if}
{/if} {if $row.is_permission_b_a}
{if $row.rtype EQ 'a_b' AND $is_contact_id_a} - {ts 1=$row.display_name 2=$displayName}%1 can view and update information about %2.{/ts} + {if $row.is_permission_b_a == 1} + {ts 1=$row.display_name 2=$displayName}%1 can view and update information about %2.{/ts} + {else} + {ts 1=$row.display_name 2=$displayName}%1 can view information about %2.{/ts} + {/if} {else} - {ts 1=$displayName 2=$row.display_name}%1 can view and update information about %2.{/ts} + {if $row.is_permission_b_a == 1} + {ts 1=$displayName 2=$row.display_name}%1 can view and update information about %2.{/ts} + {else} + {ts 1=$displayName 2=$row.display_name}%1 can view and update information about %2.{/ts} + {/if} {/if}
{/if} @@ -116,15 +132,15 @@ {capture assign="contact_b"}{if $action eq 1}{ts}selected contact(s){/ts}{else}{$display_name_b}{/if}{/capture} + {ts 1=$display_name_a 2=$contact_b}Permission for %1 to access information about %2.{/ts}
{$form.is_permission_a_b.html} - {ts 1=$display_name_a 2=$contact_b}%1 can view and update information about %2.{/ts} + {ts 1=$contact_b|ucfirst 2=$display_name_a}Permission for %1 to access information about %2.{/ts}
{$form.is_permission_b_a.html} - {ts 1=$contact_b|ucfirst 2=$display_name_a}%1 can view and update information about %2.{/ts} diff --git a/templates/CRM/Contact/Page/View/Relationship.tpl b/templates/CRM/Contact/Page/View/Relationship.tpl index fa315a6360..f8d99c5e27 100644 --- a/templates/CRM/Contact/Page/View/Relationship.tpl +++ b/templates/CRM/Contact/Page/View/Relationship.tpl @@ -38,8 +38,11 @@

{ts}Current Relationships{/ts}

{include file="CRM/Contact/Page/View/RelationshipSelector.tpl" context="current"}
- * - {ts}Indicates a permissioned relationship. This contact can be viewed and updated by the other.{/ts} + Permissioned Relationships:   + + + {ts}This contact can be viewed by the other.{/ts}  + * + {ts}This contact can be viewed and updated by the other.{/ts}
diff --git a/xml/schema/Contact/Relationship.xml b/xml/schema/Contact/Relationship.xml index 92e7ec4490..03f2a6de20 100644 --- a/xml/schema/Contact/Relationship.xml +++ b/xml/schema/Contact/Relationship.xml @@ -114,28 +114,32 @@ is_permission_a_b - boolean + int unsigned Contact A has Permission Over Contact B + true 0 - is contact a has permission to view / edit contact and - related data for contact b ? - + Permission that Contact A has to view/update Contact B 2.1 + + CRM_Core_SelectValues::getPermissionedRelationshipOptions + - CheckBox + Radio is_permission_b_a - boolean + int unsigned Contact B has Permission Over Contact A + true 0 - is contact b has permission to view / edit contact and - related data for contact a ? - + Permission that Contact B has to view/update Contact A 2.1 + + CRM_Core_SelectValues::getPermissionedRelationshipOptions + - CheckBox + Radio