3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2018 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2018
37 class CRM_ACL_BAO_ACL
extends CRM_ACL_DAO_ACL
{
41 static $_entityTable = NULL;
42 static $_objectTable = NULL;
43 static $_operation = NULL;
45 static $_fieldKeys = NULL;
48 * Get ACL entity table.
52 public static function entityTable() {
53 if (!self
::$_entityTable) {
54 self
::$_entityTable = array(
55 'civicrm_contact' => ts('Contact'),
56 'civicrm_acl_role' => ts('ACL Role'),
59 return self
::$_entityTable;
65 public static function objectTable() {
66 if (!self
::$_objectTable) {
67 self
::$_objectTable = array(
68 'civicrm_contact' => ts('Contact'),
69 'civicrm_group' => ts('Group'),
70 'civicrm_saved_search' => ts('Contact Group'),
71 'civicrm_admin' => ts('Import'),
74 return self
::$_objectTable;
80 public static function operation() {
81 if (!self
::$_operation) {
82 self
::$_operation = array(
85 'Create' => ts('Create'),
86 'Delete' => ts('Delete'),
87 'Search' => ts('Search'),
91 return self
::$_operation;
95 * Construct a WHERE clause to handle permissions to $object_*
97 * @param array $tables
98 * Any tables that may be needed in the FROM.
99 * @param string $operation
100 * The operation being attempted.
101 * @param string $object_table
102 * The table of the object in question.
103 * @param int $object_id
104 * The ID of the object in question.
106 * If it's a grant/revoke operation, the ACL ID.
107 * @param bool $acl_role
108 * For grant operations, this flag determines if we're granting a single acl (false) or an entire group.
111 * The WHERE clause, or 0 on failure
113 public static function permissionClause(
114 &$tables, $operation,
115 $object_table = NULL, $object_id = NULL,
116 $acl_id = NULL, $acl_role = FALSE
118 $dao = new CRM_ACL_DAO_ACL();
121 'ACL' => self
::getTableName(),
122 'ACLRole' => 'civicrm_acl_role',
123 'ACLEntityRole' => CRM_ACL_DAO_EntityRole
::getTableName(),
124 'Contact' => CRM_Contact_DAO_Contact
::getTableName(),
125 'Group' => CRM_Contact_DAO_Group
::getTableName(),
126 'GroupContact' => CRM_Contact_DAO_GroupContact
::getTableName(),
129 $contact_id = CRM_Core_Session
::getLoggedInContactID();
131 $where = " {$t['ACL']}.operation = '" . CRM_Utils_Type
::escape($operation, 'String') . "'";
133 /* Include clause if we're looking for a specific table/id permission */
135 if (!empty($object_table)) {
136 $where .= " AND ( {$t['ACL']}.object_table IS null
137 OR ({$t['ACL']}.object_table = '" . CRM_Utils_Type
::escape($object_table, 'String') . "'";
138 if (!empty($object_id)) {
139 $where .= " AND ({$t['ACL']}.object_id IS null
140 OR {$t['ACL']}.object_id = " . CRM_Utils_Type
::escape($object_id, 'Integer') . ')';
145 /* Include clause if we're granting an ACL or ACL Role */
147 if (!empty($acl_id)) {
148 $where .= " AND ({$t['ACL']}.acl_id IS null
149 OR {$t['ACL']}.acl_id = " . CRM_Utils_Type
::escape($acl_id, 'Integer') . ')';
151 $where .= " AND {$t['ACL']}.acl_table = '{$t['ACLRole']}'";
154 $where .= " AND {$t['ACL']}.acl_table = '{$t['ACL']}'";
160 /* Query for permissions granted to all contacts in the domain */
162 $query[] = "SELECT {$t['ACL']}.*, 0 as override
165 WHERE {$t['ACL']}.entity_table = '{$t['Domain']}'
168 /* Query for permissions granted to all contacts through an ACL group */
170 $query[] = "SELECT {$t['ACL']}.*, 0 as override
173 INNER JOIN {$t['ACLEntityRole']}
174 ON ({$t['ACL']}.entity_table = '{$t['ACLRole']}'
175 AND {$t['ACL']}.entity_id =
176 {$t['ACLEntityRole']}.acl_role_id)
178 INNER JOIN {$t['ACLRole']}
179 ON {$t['ACL']}.entity_id =
182 WHERE {$t['ACLEntityRole']}.entity_table =
184 AND {$t['ACLRole']}.is_active = 1
187 /* Query for permissions granted directly to the contact */
189 $query[] = "SELECT {$t['ACL']}.*, 1 as override
192 INNER JOIN {$t['Contact']}
193 ON ({$t['ACL']}.entity_table = '{$t['Contact']}'
194 AND {$t['ACL']}.entity_id = {$t['Contact']}.id)
196 WHERE {$t['Contact']}.id = $contact_id
199 /* Query for permissions granted to the contact through an ACL group */
201 $query[] = "SELECT {$t['ACL']}.*, 1 as override
204 INNER JOIN {$t['ACLEntityRole']}
205 ON ({$t['ACL']}.entity_table = '{$t['ACLRole']}'
206 AND {$t['ACL']}.entity_id =
207 {$t['ACLEntityRole']}.acl_role_id)
209 INNER JOIN {$t['ACLRole']}
210 ON {$t['ACL']}.entity_id = {$t['ACLRole']}.id
212 WHERE {$t['ACLEntityRole']}.entity_table =
214 AND {$t['ACLRole']}.is_active = 1
215 AND {$t['ACLEntityRole']}.entity_id = $contact_id
218 /* Query for permissions granted to the contact through a group */
220 $query[] = "SELECT {$t['ACL']}.*, 0 as override
223 INNER JOIN {$t['GroupContact']}
224 ON ({$t['ACL']}.entity_table = '{$t['Group']}'
225 AND {$t['ACL']}.entity_id =
226 {$t['GroupContact']}.group_id)
229 AND {$t['GroupContact']}.contact_id = $contact_id
230 AND {$t['GroupContact']}.status = 'Added')";
232 /* Query for permissions granted through an ACL group to a Contact
235 $query[] = "SELECT {$t['ACL']}.*, 0 as override
238 INNER JOIN {$t['ACLEntityRole']}
239 ON ({$t['ACL']}.entity_table = '{$t['ACLRole']}'
240 AND {$t['ACL']}.entity_id =
241 {$t['ACLEntityRole']}.acl_role_id)
243 INNER JOIN {$t['ACLRole']}
244 ON {$t['ACL']}.entity_id = {$t['ACLRole']}.id
246 INNER JOIN {$t['GroupContact']}
247 ON ({$t['ACLEntityRole']}.entity_table =
249 AND {$t['ACLEntityRole']}.entity_id =
250 {$t['GroupContact']}.group_id)
253 AND {$t['ACLRole']}.is_active = 1
254 AND {$t['GroupContact']}.contact_id = $contact_id
255 AND {$t['GroupContact']}.status = 'Added'";
257 $union = '(' . implode(') UNION DISTINCT (', $query) . ')';
265 while ($dao->fetch()) {
266 /* Instant bypass for the following cases:
267 * 1) the rule governs all tables
268 * 2) the rule governs all objects in the table in question
269 * 3) the rule governs the specific object we want
272 if (empty($dao->object_table
) ||
273 ($dao->object_table
== $object_table
274 && (empty($dao->object_id
)
275 ||
$dao->object_id
== $object_id
282 /* Otherwise try to generate a clause for this rule */
284 $clause = self
::getClause(
285 $dao->object_table
, $dao->object_id
, $tables
288 /* If the clause returned is null, then the rule is a blanket
289 * (id is null) on a table other than the one we're interested
292 if (empty($clause)) {
297 /* Now we figure out if this is an allow or deny rule, and possibly
298 * a contact-level override */
306 if ($dao->override
) {
307 $override[] = $clause;
312 $allows = '(' . implode(' OR ', $allow) . ')';
313 $denies = '(' . implode(' OR ', $deny) . ')';
314 if (!empty($override)) {
315 $denies = '(NOT (' . implode(' OR ', $override) . ") AND $denies)";
318 return "($allows AND NOT $denies)";
322 * Given a table and id pair, return the filter clause
324 * @param string $table
325 * The table owning the object.
327 * The ID of the object.
328 * @param array $tables
329 * Tables that will be needed in the FROM.
331 * @return string|null
332 * WHERE-style clause to filter results,
333 * or null if $table or $id is null
335 public static function getClause($table, $id, &$tables) {
336 $table = CRM_Utils_Type
::escape($table, 'String');
337 $id = CRM_Utils_Type
::escape($id, 'Integer');
338 $whereTables = array();
340 $ssTable = CRM_Contact_BAO_SavedSearch
::getTableName();
345 elseif ($table == $ssTable) {
346 return CRM_Contact_BAO_SavedSearch
::whereClause($id, $tables, $whereTables);
348 elseif (!empty($id)) {
349 $tables[$table] = TRUE;
350 return "$table.id = $id";
356 * Construct an associative array of an ACL rule's properties
358 * @param string $format
359 * Sprintf format for array.
360 * @param bool $hideEmpty
361 * Only return elements that have a value set.
364 * Assoc. array of the ACL rule's properties
366 public function toArray($format = '%s', $hideEmpty = FALSE) {
369 if (!self
::$_fieldKeys) {
370 $fields = CRM_ACL_DAO_ACL
::fields();
371 self
::$_fieldKeys = array_keys($fields);
374 foreach (self
::$_fieldKeys as $field) {
375 $result[$field] = $this->$field;
381 * Retrieve ACLs for a contact or group. Note that including a contact id
382 * without a group id will return those ACL rules which are granted
383 * directly to the contact, but not those granted to the contact through
384 * any/all of his group memberships.
386 * @param int $contact_id
387 * ID of a contact to search for.
388 * @param int $group_id
389 * ID of a group to search for.
390 * @param bool $aclRoles
391 * Should we include ACL Roles.
394 * Array of assoc. arrays of ACL rules
396 public static function &getACLs($contact_id = NULL, $group_id = NULL, $aclRoles = FALSE) {
399 if (empty($contact_id)) {
403 $contact_id = CRM_Utils_Type
::escape($contact_id, 'Integer');
405 $group_id = CRM_Utils_Type
::escape($group_id, 'Integer');
408 $rule = new CRM_ACL_BAO_ACL();
410 $acl = self
::getTableName();
411 $contact = CRM_Contact_BAO_Contact
::getTableName();
412 $c2g = CRM_Contact_BAO_GroupContact
::getTableName();
413 $group = CRM_Contact_BAO_Group
::getTableName();
415 $query = " SELECT $acl.*
418 if (!empty($group_id)) {
419 $query .= " INNER JOIN $c2g
420 ON $acl.entity_id = $c2g.group_id
421 WHERE $acl.entity_table = '$group'
422 AND $acl.is_active = 1
423 AND $c2g.group_id = $group_id";
425 if (!empty($contact_id)) {
426 $query .= " AND $c2g.contact_id = $contact_id
427 AND $c2g.status = 'Added'";
431 if (!empty($contact_id)) {
432 $query .= " WHERE $acl.entity_table = '$contact'
433 AND $acl.entity_id = $contact_id";
437 $rule->query($query);
439 while ($rule->fetch()) {
440 $results[$rule->id
] = $rule->toArray();
444 $results +
= self
::getACLRoles($contact_id, $group_id);
451 * Get all of the ACLs through ACL groups.
453 * @param int $contact_id
454 * ID of a contact to search for.
455 * @param int $group_id
456 * ID of a group to search for.
459 * Array of assoc. arrays of ACL rules
461 public static function &getACLRoles($contact_id = NULL, $group_id = NULL) {
462 $contact_id = CRM_Utils_Type
::escape($contact_id, 'Integer');
464 $group_id = CRM_Utils_Type
::escape($group_id, 'Integer');
467 $rule = new CRM_ACL_BAO_ACL();
469 $acl = self
::getTableName();
470 $aclRole = 'civicrm_acl_role';
471 $aclRoleJoin = CRM_ACL_DAO_EntityRole
::getTableName();
472 $contact = CRM_Contact_BAO_Contact
::getTableName();
473 $c2g = CRM_Contact_BAO_GroupContact
::getTableName();
474 $group = CRM_Contact_BAO_Group
::getTableName();
476 $query = " SELECT $acl.*
478 INNER JOIN civicrm_option_group og
479 ON og.name = 'acl_role'
480 INNER JOIN civicrm_option_value ov
481 ON $acl.entity_table = '$aclRole'
482 AND ov.option_group_id = og.id
483 AND $acl.entity_id = ov.value";
485 if (!empty($group_id)) {
486 $query .= " INNER JOIN $c2g
487 ON $acl.entity_id = $c2g.group_id
488 WHERE $acl.entity_table = '$group'
489 AND $acl.is_active = 1
490 AND $c2g.group_id = $group_id";
492 if (!empty($contact_id)) {
493 $query .= " AND $c2g.contact_id = $contact_id
494 AND $c2g.status = 'Added'";
498 if (!empty($contact_id)) {
499 $query .= " WHERE $acl.entity_table = '$contact'
500 AND $acl.is_active = 1
501 AND $acl.entity_id = $contact_id";
507 $rule->query($query);
509 while ($rule->fetch()) {
510 $results[$rule->id
] = $rule->toArray();
517 * Get all ACLs granted to a contact through all group memberships.
519 * @param int $contact_id
521 * @param bool $aclRoles
522 * Include ACL Roles?.
525 * Assoc array of ACL rules
527 public static function &getGroupACLs($contact_id, $aclRoles = FALSE) {
528 $contact_id = CRM_Utils_Type
::escape($contact_id, 'Integer');
530 $rule = new CRM_ACL_BAO_ACL();
532 $acl = self
::getTableName();
533 $c2g = CRM_Contact_BAO_GroupContact
::getTableName();
534 $group = CRM_Contact_BAO_Group
::getTableName();
542 ON $acl.entity_id = $c2g.group_id
543 WHERE $acl.entity_table = '$group'
544 AND $c2g.contact_id = $contact_id
545 AND $c2g.status = 'Added'";
547 $rule->query($query);
549 while ($rule->fetch()) {
550 $results[$rule->id
] = $rule->toArray();
555 $results +
= self
::getGroupACLRoles($contact_id);
562 * Get all of the ACLs for a contact through ACL groups owned by Contact.
565 * @param int $contact_id
566 * ID of a contact to search for.
569 * Array of assoc. arrays of ACL rules
571 public static function &getGroupACLRoles($contact_id) {
572 $contact_id = CRM_Utils_Type
::escape($contact_id, 'Integer');
574 $rule = new CRM_ACL_BAO_ACL();
576 $acl = self
::getTableName();
577 $aclRole = 'civicrm_acl_role';
579 $aclER = CRM_ACL_DAO_EntityRole
::getTableName();
580 $c2g = CRM_Contact_BAO_GroupContact
::getTableName();
581 $group = CRM_Contact_BAO_Group
::getTableName();
583 $query = " SELECT $acl.*
585 INNER JOIN civicrm_option_group og
586 ON og.name = 'acl_role'
587 INNER JOIN civicrm_option_value ov
588 ON $acl.entity_table = '$aclRole'
589 AND ov.option_group_id = og.id
590 AND $acl.entity_id = ov.value
593 ON $aclER.acl_role_id = $acl.entity_id
594 AND $aclER.is_active = 1
596 ON $aclER.entity_id = $c2g.group_id
597 AND $aclER.entity_table = 'civicrm_group'
598 WHERE $acl.entity_table = '$aclRole'
599 AND $acl.is_active = 1
600 AND $c2g.contact_id = $contact_id
601 AND $c2g.status = 'Added'";
605 $rule->query($query);
607 while ($rule->fetch()) {
608 $results[$rule->id
] = $rule->toArray();
611 // also get all acls for "Any Role" case
612 // and authenticated User Role if present
614 $session = CRM_Core_Session
::singleton();
615 if ($session->get('ufID') > 0) {
622 WHERE $acl.entity_id IN ( $roles )
623 AND $acl.entity_table = 'civicrm_acl_role'
626 $rule->query($query);
627 while ($rule->fetch()) {
628 $results[$rule->id
] = $rule->toArray();
635 * Get all ACLs owned by a given contact, including domain and group-level.
637 * @param int $contact_id
641 * Assoc array of ACL rules
643 public static function &getAllByContact($contact_id) {
646 /* First, the contact-specific ACLs, including ACL Roles */
647 $result +
= self
::getACLs($contact_id, NULL, TRUE);
649 /* Then, all ACLs granted through group membership */
650 $result +
= self
::getGroupACLs($contact_id, TRUE);
656 * @param array $params
658 * @return CRM_ACL_DAO_ACL
660 public static function create(&$params) {
661 $dao = new CRM_ACL_DAO_ACL();
662 $dao->copyValues($params);
668 * @param array $params
671 public static function retrieve(&$params, &$defaults) {
672 CRM_Core_DAO
::commonRetrieve('CRM_ACL_DAO_ACL', $params, $defaults);
676 * Update the is_active flag in the db.
679 * Id of the database record.
680 * @param bool $is_active
681 * Value we want to set the is_active field.
684 * DAO object on success, null otherwise
686 public static function setIsActive($id, $is_active) {
687 // note this also resets any ACL cache
688 CRM_Core_BAO_Cache
::deleteGroup('contact fields');
690 return CRM_Core_DAO
::setFieldValue('CRM_ACL_DAO_ACL', $id, 'is_active', $is_active);
695 * @param int $contactID
699 public static function check($str, $contactID) {
701 $acls = CRM_ACL_BAO_Cache
::build($contactID);
703 $aclKeys = array_keys($acls);
704 $aclKeys = implode(',', $aclKeys);
706 if (empty($aclKeys)) {
712 FROM civicrm_acl_cache c, civicrm_acl a
713 WHERE c.acl_id = a.id
715 AND a.object_table = %1
716 AND a.id IN ( $aclKeys )
718 $params = array(1 => array($str, 'String'));
720 $count = CRM_Core_DAO
::singleValueQuery($query, $params);
721 return ($count) ?
TRUE : FALSE;
727 * @param $whereTables
728 * @param int $contactID
730 * @return null|string
732 public static function whereClause($type, &$tables, &$whereTables, $contactID = NULL) {
733 $acls = CRM_ACL_BAO_Cache
::build($contactID);
739 $aclKeys = array_keys($acls);
740 $aclKeys = implode(',', $aclKeys);
743 SELECT a.operation, a.object_id
744 FROM civicrm_acl_cache c, civicrm_acl a
745 WHERE c.acl_id = a.id
747 AND a.object_table = 'civicrm_saved_search'
748 AND a.id IN ( $aclKeys )
752 $dao = CRM_Core_DAO
::executeQuery($query);
754 // do an or of all the where clauses u see
756 while ($dao->fetch()) {
757 // make sure operation matches the type TODO
758 if (self
::matchType($type, $dao->operation
)) {
759 if (!$dao->object_id
) {
761 $whereClause = ' ( 1 ) ';
764 $ids[] = $dao->object_id
;
769 $ids = implode(',', $ids);
773 WHERE g.id IN ( $ids )
776 $dao = CRM_Core_DAO
::executeQuery($query);
777 $staticGroupIDs = array();
778 $cachedGroupIDs = array();
779 while ($dao->fetch()) {
780 // currently operation is restrcited to VIEW/EDIT
781 if ($dao->where_clause
) {
782 if ($dao->select_tables
) {
783 $tmpTables = array();
784 foreach (unserialize($dao->select_tables
) as $tmpName => $tmpInfo) {
785 if ($tmpName == '`civicrm_group_contact-' . $dao->id
. '`') {
786 $tmpName = '`civicrm_group_contact-ACL`';
787 $tmpInfo = str_replace('civicrm_group_contact-' . $dao->id
, 'civicrm_group_contact-ACL', $tmpInfo);
789 elseif ($tmpName == '`civicrm_group_contact_cache_' . $dao->id
. '`') {
790 $tmpName = '`civicrm_group_contact_cache-ACL`';
791 $tmpInfo = str_replace('civicrm_group_contact_cache_' . $dao->id
, 'civicrm_group_contact_cache-ACL', $tmpInfo);
793 $tmpTables[$tmpName] = $tmpInfo;
795 $tables = array_merge($tables,
799 if ($dao->where_tables
) {
800 $tmpTables = array();
801 foreach (unserialize($dao->where_tables
) as $tmpName => $tmpInfo) {
802 if ($tmpName == '`civicrm_group_contact-' . $dao->id
. '`') {
803 $tmpName = '`civicrm_group_contact-ACL`';
804 $tmpInfo = str_replace('civicrm_group_contact-' . $dao->id
, 'civicrm_group_contact-ACL', $tmpInfo);
805 $staticGroupIDs[] = $dao->id
;
807 elseif ($tmpName == '`civicrm_group_contact_cache_' . $dao->id
. '`') {
808 $tmpName = '`civicrm_group_contact_cache-ACL`';
809 $tmpInfo = str_replace('civicrm_group_contact_cache_' . $dao->id
, 'civicrm_group_contact_cache-ACL', $tmpInfo);
810 $cachedGroupIDs[] = $dao->id
;
812 $tmpTables[$tmpName] = $tmpInfo;
814 $whereTables = array_merge($whereTables, $tmpTables);
818 if (($dao->saved_search_id ||
$dao->children ||
$dao->parents
) &&
819 $dao->cache_date
== NULL
821 CRM_Contact_BAO_GroupContactCache
::load($dao);
825 if ($staticGroupIDs) {
826 $clauses[] = '( `civicrm_group_contact-ACL`.group_id IN (' . implode(', ', $staticGroupIDs) . ') AND `civicrm_group_contact-ACL`.status IN ("Added") )';
829 if ($cachedGroupIDs) {
830 $clauses[] = '`civicrm_group_contact_cache-ACL`.group_id IN (' . implode(', ', $cachedGroupIDs) . ')';
835 if (!empty($clauses)) {
836 $whereClause = ' ( ' . implode(' OR ', $clauses) . ' ) ';
839 // call the hook to get additional whereClauses
840 CRM_Utils_Hook
::aclWhereClause($type, $tables, $whereTables, $contactID, $whereClause);
842 if (empty($whereClause)) {
843 $whereClause = ' ( 0 ) ';
851 * @param int $contactID
852 * @param string $tableName
853 * @param null $allGroups
854 * @param null $includedGroups
858 public static function group(
861 $tableName = 'civicrm_saved_search',
863 $includedGroups = NULL
865 $userCacheKey = "{$contactID}_{$type}_{$tableName}_" . CRM_Core_Config
::domainID() . '_' . md5(implode(',', array_merge((array) $allGroups, (array) $includedGroups)));
866 if (empty(Civi
::$statics[__CLASS__
]['permissioned_groups'])) {
867 Civi
::$statics[__CLASS__
]['permissioned_groups'] = array();
869 if (!empty(Civi
::$statics[__CLASS__
]['permissioned_groups'][$userCacheKey])) {
870 return Civi
::$statics[__CLASS__
]['permissioned_groups'][$userCacheKey];
873 $acls = CRM_ACL_BAO_Cache
::build($contactID);
877 $aclKeys = array_keys($acls);
878 $aclKeys = implode(',', $aclKeys);
880 $cacheKey = CRM_Core_BAO_Cache
::cleanKey("$tableName-$aclKeys");
881 $cache = CRM_Utils_Cache
::singleton();
882 $ids = $cache->get($cacheKey);
886 SELECT a.operation, a.object_id
887 FROM civicrm_acl_cache c, civicrm_acl a
888 WHERE c.acl_id = a.id
890 AND a.object_table = %1
891 AND a.id IN ( $aclKeys )
892 GROUP BY a.operation,a.object_id
895 $params = array(1 => array($tableName, 'String'));
896 $dao = CRM_Core_DAO
::executeQuery($query, $params);
897 while ($dao->fetch()) {
898 if ($dao->object_id
) {
899 if (self
::matchType($type, $dao->operation
)) {
900 $ids[] = $dao->object_id
;
904 // this user has got the permission for all objects of this type
905 // check if the type matches
906 if (self
::matchType($type, $dao->operation
)) {
907 foreach ($allGroups as $id => $dontCare) {
914 $cache->set($cacheKey, $ids);
918 if (empty($ids) && !empty($includedGroups) &&
919 is_array($includedGroups)
921 $ids = $includedGroups;
925 if (!empty($allGroups)) {
926 $groupWhere = " AND id IN (" . implode(',', array_keys($allGroups)) . ")";
928 // Contacts create hidden groups from search results. They should be able to retrieve their own.
929 $ownHiddenGroupsList = CRM_Core_DAO
::singleValueQuery("
930 SELECT GROUP_CONCAT(id) FROM civicrm_group WHERE is_hidden =1 AND created_id = $contactID
933 if ($ownHiddenGroupsList) {
934 $ownHiddenGroups = explode(',', $ownHiddenGroupsList);
935 $ids = array_merge((array) $ids, $ownHiddenGroups);
940 CRM_Utils_Hook
::aclGroup($type, $contactID, $tableName, $allGroups, $ids);
941 Civi
::$statics[__CLASS__
]['permissioned_groups'][$userCacheKey] = $ids;
951 public static function matchType($type, $operation) {
953 switch ($operation) {
959 if ($type == CRM_ACL_API
::VIEW
) {
965 if ($type == CRM_ACL_API
::VIEW ||
$type == CRM_ACL_API
::EDIT
) {
971 if ($type == CRM_ACL_API
::CREATE
) {
977 if ($type == CRM_ACL_API
::DELETE
) {
983 if ($type == CRM_ACL_API
::SEARCH
) {
992 * Delete ACL records.
995 * ID of the ACL record to be deleted.
998 public static function del($aclId) {
999 // delete all entries from the acl cache
1000 CRM_ACL_BAO_Cache
::resetCache();
1002 $acl = new CRM_ACL_DAO_ACL();