}
}
+ /**
+ * @param string $entityName
+ * @param string $action
+ * @param array $record
+ * @param int $userID
+ * @return bool
+ * @see CRM_Core_DAO::checkAccess
+ */
+ public static function _checkAccess(string $entityName, string $action, array $record, int $userID): bool {
+ // Delegate relationship permissions to contacts a & b
+ foreach (['a', 'b'] as $ab) {
+ if (empty($record["contact_id_$ab"]) && !empty($record['id'])) {
+ $record["contact_id_$ab"] = CRM_Core_DAO::getFieldValue(__CLASS__, $record['id'], "contact_id_$ab");
+ }
+ if (!\Civi\Api4\Utils\CoreUtil::checkAccessDelegated('Contact', 'update', ['id' => $record["contact_id_$ab"]], $userID)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+
}
$where = ' contact_a.id > ' . $this->allowedContactId;
}
+ /**
+ * Only specified contact returned.
+ *
+ * @implements CRM_Utils_Hook::aclWhereClause
+ *
+ * @param $type
+ * @param $tables
+ * @param $whereTables
+ * @param $contactID
+ * @param $where
+ */
+ public function aclWhereMultipleContacts($type, &$tables, &$whereTables, &$contactID, &$where) {
+ $where = " contact_a.id IN (" . implode(', ', $this->allowedContacts) . ")";
+ }
+
/**
* Set up a core ACL.
*
$this->_ids['membership_type'] = $membershipTypeID;
}
- /**
- * Only specified contact returned.
- *
- * @implements CRM_Utils_Hook::aclWhereClause
- *
- * @param $type
- * @param $tables
- * @param $whereTables
- * @param $contactID
- * @param $where
- */
- public function aclWhereMultipleContacts($type, &$tables, &$whereTables, &$contactID, &$where) {
- $where = " contact_a.id IN (" . implode(', ', $this->allowedContacts) . ")";
- }
-
/**
* @implements CRM_Utils_Hook::selectWhereClause
*
namespace api\v4\Entity;
+use Civi\API\Exception\UnauthorizedException;
use Civi\Api4\Contact;
use api\v4\Api4TestBase;
use Civi\Api4\Relationship;
*/
class RelationshipTest extends Api4TestBase implements TransactionalInterface {
+ use \Civi\Test\ACLPermissionTrait;
+
/**
* Test relationship cache tracks created relationships.
*
$this->assertEquals($future->format('Y-m-d'), $cacheRecord['end_date']);
}
+ public function testRelationshipCheckAccess(): void {
+ $cid = $this->saveTestRecords('Contact', ['records' => 4])->column('id');
+ $this->allowedContacts = array_slice($cid, 1);
+ \CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM'];
+ \CRM_Utils_Hook::singleton()->setHook('civicrm_aclWhereClause', [$this, 'aclWhereMultipleContacts']);
+ $check = Relationship::checkAccess()
+ ->setAction('create')
+ ->setValues([
+ 'contact_id_a' => $cid[0],
+ 'contact_id_b' => $cid[1],
+ 'relationship_type_id' => 1,
+ ])
+ ->execute()->first();
+ $this->assertFalse($check['access']);
+
+ try {
+ Relationship::create()->setValues([
+ 'contact_id_a' => $cid[1],
+ 'contact_id_b' => $cid[0],
+ 'relationship_type_id' => 1,
+ ])->execute();
+ $this->fail();
+ }
+ catch (UnauthorizedException $e) {
+ Relationship::create(FALSE)->setValues([
+ 'contact_id_a' => $cid[1],
+ 'contact_id_b' => $cid[0],
+ 'relationship_type_id' => 1,
+ ])->execute();
+ }
+ Relationship::create()->setValues([
+ 'contact_id_a' => $cid[1],
+ 'contact_id_b' => $cid[2],
+ 'relationship_type_id' => 1,
+ ])->execute();
+
+ $this->assertCount(2, Relationship::get(FALSE)->addWhere('contact_id_a', '=', $cid[1])->execute());
+ $this->assertCount(1, Relationship::get()->addWhere('contact_id_a', '=', $cid[1])->execute());
+
+ Relationship::delete()
+ ->addWhere('contact_id_a', '=', $cid[1])
+ ->execute()->single();
+
+ }
+
}