Add view-only option on permissioned relationships:
authorAidan Saunders <aidan.saunders@squiffle.uk>
Thu, 29 Mar 2018 23:57:21 +0000 (00:57 +0100)
committerAidan Saunders <aidan.saunders@squiffle.uk>
Wed, 4 Jul 2018 11:34:10 +0000 (12:34 +0100)
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

CRM/Contact/BAO/Contact/Permission.php
CRM/Contact/BAO/Query.php
CRM/Contact/BAO/Relationship.php
CRM/Contact/DAO/Relationship.php
CRM/Contact/Form/Relationship.php
CRM/Contact/Form/Search/Criteria.php
CRM/Core/SelectValues.php
CRM/Report/Form/Contact/Relationship.php
templates/CRM/Contact/Form/Relationship.tpl
templates/CRM/Contact/Page/View/Relationship.tpl
xml/schema/Contact/Relationship.xml

index 09b8925ede78a3255e54b503a77629f68f06f8f1..883b39922f82456ea03d4dfb1f56aeca98973b5e 100644 (file)
@@ -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";
         }
       }
index eda7792aa7d315e4c17307b001562a4b3acf2dd9..2050ba977827b72745c658d553998e4eab9b5eba 100644 (file)
@@ -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
index 67c95393882e83f44754e9de1a7e7b6f3258b6c4..2b4db2f0a1c65e00b17f0060e8418448576ecf7b 100644 (file)
@@ -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'] .= '<span id="permission-a-b" class="crm-marker permission-relationship"> *</span>';
           }
 
-          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'] .= '<span id="permission-a-b" class="crm-marker permission-relationship"> +</span>';
+          }
+
+          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'] .= '<span id="permission-b-a" class="crm-marker permission-relationship"> *</span>';
           }
+
+          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'] .= '<span id="permission-b-a" class="crm-marker permission-relationship"> +</span>';
+          }
         }
 
         if (!empty($values['description'])) {
index f61c5c220fdbda0f18941bfcb951b42c3f87ae8e..62b70944f1127335fec80fa73a11916667dcbf20 100644 (file)
@@ -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',
index cdc2898fded815b46fb43f294c4cde1274301bf9..fc115dcf92524ceda91d4ebfcf2841f52c4b4b5a 100644 (file)
@@ -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')));
 
index 52d7a100168d5b6ce39baf69e9271424c622a7c9..845ab7c9a54138c071a4e3882b73e4cbc65054ab 100644 (file)
@@ -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) {
index 6f4ed3c8b41a7fa85f5fd79128d9a0ad6d09dbfd..3d429fa36e6ca6e89fe0daa3c3208a3a51c4c24f 100644 (file)
@@ -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'),
+    );
+  }
+
 }
index dd20fba0ea833491e8b6f716e4cff44bbba8f041..0e34078cdfb1f19f716de7d9cc01fef65e05ea8f 100644 (file)
@@ -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
    *
index d921c211a760473832101d47f5fef87b8dff007b..f2312bc11d1d5211c8fd872879d9e4de252ca19d 100644 (file)
                 {if $row.is_permission_a_b}
                   <div>
                   {if $row.rtype EQ 'a_b' AND $is_contact_id_a}
-                    {ts 1=$displayName 2=$row.display_name}<strong>%1</strong> can view and update information about %2.{/ts}
+                    {if $row.is_permission_a_b == 1}
+                      {ts 1=$displayName 2=$row.display_name}<strong>%1</strong> can view and update information about %2.{/ts}
+                    {else}
+                      {ts 1=$displayName 2=$row.display_name}<strong>%1</strong> can view information about %2.{/ts}
+                    {/if}
                   {else}
-                    {ts 1=$row.display_name 2=$displayName}<strong>%1</strong> can view and update information about %2.{/ts}
+                    {if $row.is_permission_a_b == 1}
+                      {ts 1=$row.display_name 2=$displayName}<strong>%1</strong> can view and update information about %2.{/ts}
+                    {else}
+                      {ts 1=$row.display_name 2=$displayName}<strong>%1</strong> can view information about %2.{/ts}
+                    {/if}
                   {/if}
                   </div>
                 {/if}
                 {if $row.is_permission_b_a}
                   <div>
                   {if $row.rtype EQ 'a_b' AND $is_contact_id_a}
-                    {ts 1=$row.display_name 2=$displayName}<strong>%1</strong> can view and update information about %2.{/ts}
+                    {if $row.is_permission_b_a == 1}
+                      {ts 1=$row.display_name 2=$displayName}<strong>%1</strong> can view and update information about %2.{/ts}
+                    {else}
+                      {ts 1=$row.display_name 2=$displayName}<strong>%1</strong> can view information about %2.{/ts}
+                    {/if}
                   {else}
-                    {ts 1=$displayName 2=$row.display_name}<strong>%1</strong> can view and update information about %2.{/ts}
+                    {if $row.is_permission_b_a == 1}
+                      {ts 1=$displayName 2=$row.display_name}<strong>%1</strong> can view and update information about %2.{/ts}
+                    {else}
+                      {ts 1=$displayName 2=$row.display_name}<strong>%1</strong> can view and update information about %2.{/ts}
+                    {/if}
                   {/if}
                   </div>
                 {/if}
           {capture assign="contact_b"}{if $action eq 1}{ts}selected contact(s){/ts}{else}{$display_name_b}{/if}{/capture}
           <td class="label"><label>{ts}Permissions{/ts}</label></td>
           <td>
+            {ts 1=$display_name_a 2=$contact_b}Permission for <strong>%1</strong> to access information about %2.{/ts}<br />
             {$form.is_permission_a_b.html}
-            {ts 1=$display_name_a 2=$contact_b}<strong>%1</strong> can view and update information about %2.{/ts}
           </td>
         </tr>
         <tr class="crm-relationship-form-block-is_permission_b_a">
           <td class="label"></td>
           <td>
+            {ts 1=$contact_b|ucfirst 2=$display_name_a}Permission for <strong>%1</strong> to access information about %2.{/ts}<br />
             {$form.is_permission_b_a.html}
-            {ts 1=$contact_b|ucfirst 2=$display_name_a}<strong>%1</strong> can view and update information about %2.{/ts}
           </td>
         </tr>
         <tr class="crm-relationship-form-block-is_active">
index fa315a6360942d358c812ff59d96cfa0a97dce3b..f8d99c5e27deb0655ebcb921dc420d4b6fed9b3a 100644 (file)
     <h3>{ts}Current Relationships{/ts}</h3>
     {include file="CRM/Contact/Page/View/RelationshipSelector.tpl" context="current"}
     <div id="permission-legend" class="crm-content-block">
-      <span class="crm-marker">* </span>
-      {ts}Indicates a permissioned relationship. This contact can be viewed and updated by the other.{/ts}
+      <span class="label">Permissioned Relationships: </span>&nbsp;
+      <span class="crm-marker"> +</span>
+      {ts}This contact can be viewed by the other.{/ts}&nbsp;
+      <span class="crm-marker"> *</span>
+      {ts}This contact can be viewed and updated by the other.{/ts}
     </div>
 
     <div class="spacer"></div>
index 92e7ec449033836352eefa4f49181ff6e8e9624b..03f2a6de2069152b7b528d87ed53e6c63fa2feab 100644 (file)
   </field>
   <field>
     <name>is_permission_a_b</name>
-    <type>boolean</type>
+    <type>int unsigned</type>
     <title>Contact A has Permission Over Contact B</title>
+    <required>true</required>
     <default>0</default>
-    <comment>is contact a has permission to view / edit contact and
-      related data for contact b ?
-    </comment>
+    <comment>Permission that Contact A has to view/update Contact B</comment>
     <add>2.1</add>
+    <pseudoconstant>
+      <callback>CRM_Core_SelectValues::getPermissionedRelationshipOptions</callback>
+    </pseudoconstant>
     <html>
-      <type>CheckBox</type>
+      <type>Radio</type>
     </html>
   </field>
   <field>
     <name>is_permission_b_a</name>
-    <type>boolean</type>
+    <type>int unsigned</type>
     <title>Contact B has Permission Over Contact A</title>
+    <required>true</required>
     <default>0</default>
-    <comment>is contact b has permission to view / edit contact and
-      related data for contact a ?
-    </comment>
+    <comment>Permission that Contact B has to view/update Contact A</comment>
     <add>2.1</add>
+    <pseudoconstant>
+      <callback>CRM_Core_SelectValues::getPermissionedRelationshipOptions</callback>
+    </pseudoconstant>
     <html>
-      <type>CheckBox</type>
+      <type>Radio</type>
     </html>
   </field>
   <field>