Skip to content

Commit

Permalink
CRM-19557 Fix ACL caching function to not use inefficient query for v…
Browse files Browse the repository at this point in the history
…iew my contact

Conflicts:
	CRM/Contact/BAO/Contact/Permission.php
  • Loading branch information
eileenmcnaughton committed Oct 24, 2016
1 parent 5f652ac commit 9aea8e1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
13 changes: 9 additions & 4 deletions CRM/ACL/API.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ public static function check($str, $contactID = NULL) {
* @param bool $skipDeleteClause
* Don't add delete clause if this is true,.
* this means it is handled by generating query
* @param bool $skipOwnContactClause
* Do not add 'OR contact_id = $userID' to the where clause.
* This is a hideously inefficient query and should be avoided
* wherever possible.
*
* @return string
* the group where clause for this user
Expand All @@ -94,7 +98,8 @@ public static function whereClause(
&$whereTables,
$contactID = NULL,
$onlyDeleted = FALSE,
$skipDeleteClause = FALSE
$skipDeleteClause = FALSE,
$skipOwnContactClause = FALSE
) {
// the default value which is valid for the final AND
$deleteClause = ' ( 1 ) ';
Expand Down Expand Up @@ -131,9 +136,9 @@ public static function whereClause(
)
);

// Add permission on self
if ($contactID && (CRM_Core_Permission::check('edit my contact') ||
$type == self::VIEW && CRM_Core_Permission::check('view my contact'))
// Add permission on self if we really hate our server or have hardly any contacts.
if (!$skipOwnContactClause && $contactID && (CRM_Core_Permission::check('edit my contact') ||
$type == self::VIEW && CRM_Core_Permission::check('view my contact'))
) {
$where = "(contact_a.id = $contactID OR ($where))";
}
Expand Down
20 changes: 15 additions & 5 deletions CRM/Contact/BAO/Contact/Permission.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public static function allowList($contact_ids, $type = CRM_Core_Permission::VIEW
SELECT contact_id
FROM civicrm_acl_contact_cache
{$LEFT_JOIN_DELETED}
WHERE contact_id IN ({$contact_id_list})
WHERE contact_id IN ({$contact_id_list})
AND user_id = {$contactID}
AND operation = '{$operation}'
{$AND_CAN_ACCESS_DELETED}";
Expand Down Expand Up @@ -211,6 +211,7 @@ public static function cache($userID, $type = CRM_Core_Permission::VIEW, $force
$operationClause = " operation = 'Edit' ";
$operation = 'Edit';
}
$queryParams = array(1 => array($userID, 'Integer'));

if (!$force) {
// skip if already calculated
Expand All @@ -225,8 +226,7 @@ public static function cache($userID, $type = CRM_Core_Permission::VIEW, $force
WHERE user_id = %1
AND $operationClause
";
$params = array(1 => array($userID, 'Integer'));
$count = CRM_Core_DAO::singleValueQuery($sql, $params);
$count = CRM_Core_DAO::singleValueQuery($sql, $queryParams);
if ($count > 0) {
$_processed[$type][$userID] = 1;
return;
Expand All @@ -236,7 +236,7 @@ public static function cache($userID, $type = CRM_Core_Permission::VIEW, $force
$tables = array();
$whereTables = array();

$permission = CRM_ACL_API::whereClause($type, $tables, $whereTables, $userID);
$permission = CRM_ACL_API::whereClause($type, $tables, $whereTables, $userID, FALSE, FALSE, TRUE);

$from = CRM_Contact_BAO_Query::fromClause($whereTables);
CRM_Core_DAO::executeQuery("
Expand All @@ -247,6 +247,16 @@ public static function cache($userID, $type = CRM_Core_Permission::VIEW, $force
WHERE $permission
AND ac.user_id IS NULL
");

// Add in a row for the logged in contact. Do not try to combine with the above query or an ugly OR will appear in
// the permission clause.
if (CRM_Core_Permission::check('edit my contact') ||
($type == CRM_Core_Permission::VIEW && CRM_Core_Permission::check('view my contact'))) {
if (!CRM_Core_DAO::executeQuery("
SELECT count(*) FROM civicrm_acl_contact_cache WHERE user_id = %1 AND contact_id = %1 AND operation = '{$operation}'", $queryParams)) {
CRM_Core_DAO::executeQuery("INSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation ) VALUES(%1, %1, '{$operation}')");
}
}
$_processed[$type][$userID] = 1;
}

Expand Down Expand Up @@ -353,7 +363,7 @@ public static function relationshipList($contact_ids) {

$queries[] = "
SELECT civicrm_relationship.{$contact_id_column} AS contact_id
FROM civicrm_relationship
FROM civicrm_relationship
{$LEFT_JOIN_DELETED}
WHERE civicrm_relationship.{$user_id_column} = {$contactID}
AND civicrm_relationship.{$contact_id_column} IN ({$contact_id_list})
Expand Down

0 comments on commit 9aea8e1

Please sign in to comment.