Merge pull request #4818 from pratikshad/CRM-15770
[civicrm-core.git] / CRM / ACL / API.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
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. |
13 | |
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. |
18 | |
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 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2014
32 * $Id$
33 *
34 */
35 class CRM_ACL_API {
36
37 /**
38 * The various type of permissions
39 *
40 * @var int
41 */
42 const EDIT = 1;
43 const VIEW = 2;
44 const DELETE = 3;
45 const CREATE = 4;
46 const SEARCH = 5;
47 const ALL = 6;
48
49 /**
50 * Given a permission string, check for access requirements
51 *
52 * @param string $str the permission to check
53 * @param int $contactID the contactID for whom the check is made
54 *
55 * @return boolean true if yes, else false
56 * @static
57 */
58 public static function check($str, $contactID = NULL) {
59 if ($contactID == NULL) {
60 $session = CRM_Core_Session::singleton();
61 $contactID = $session->get('userID');
62 }
63
64 if (!$contactID) {
65 // anonymous user
66 $contactID = 0;
67 }
68
69 return CRM_ACL_BAO_ACL::check($str, $contactID);
70 }
71
72 /**
73 * Get the permissioned where clause for the user
74 *
75 * @param int $type the type of permission needed
76 * @param array $tables (reference ) add the tables that are needed for the select clause
77 * @param array $whereTables (reference ) add the tables that are needed for the where clause
78 * @param int $contactID the contactID for whom the check is made
79 * @param bool $onlyDeleted whether to include only deleted contacts
80 * @param bool $skipDeleteClause don't add delete clause if this is true,
81 * this means it is handled by generating query
82 *
83 * @return string the group where clause for this user
84 */
85 public static function whereClause($type,
86 &$tables,
87 &$whereTables,
88 $contactID = NULL,
89 $onlyDeleted = FALSE,
90 $skipDeleteClause = FALSE
91 ) {
92 // the default value which is valid for rhe final AND
93 $deleteClause = ' ( 1 ) ';
94 if (!$skipDeleteClause) {
95 if (CRM_Core_Permission::check('access deleted contacts') and $onlyDeleted) {
96 $deleteClause = '(contact_a.is_deleted)';
97 }
98 else {
99 // CRM-6181
100 $deleteClause = '(contact_a.is_deleted = 0)';
101 }
102 }
103
104 // first see if the contact has edit / view all contacts
105 if (CRM_Core_Permission::check('edit all contacts') ||
106 ($type == self::VIEW &&
107 CRM_Core_Permission::check('view all contacts')
108 )
109 ) {
110 return $skipDeleteClause ? ' ( 1 ) ' : $deleteClause;
111 }
112
113 if ($contactID == NULL) {
114 $session = CRM_Core_Session::singleton();
115 $contactID = $session->get('userID');
116 }
117
118 if (!$contactID) {
119 // anonymous user
120 $contactID = 0;
121 }
122
123 return implode(' AND ',
124 array(
125 CRM_ACL_BAO_ACL::whereClause($type,
126 $tables,
127 $whereTables,
128 $contactID
129 ),
130 $deleteClause,
131 )
132 );
133 }
134
135 /**
136 * Get all the groups the user has access to for the given operation
137 *
138 * @param int $type the type of permission needed
139 * @param int $contactID the contactID for whom the check is made
140 *
141 * @param string $tableName
142 * @param null $allGroups
143 * @param null $includedGroups
144 *
145 * @return array the ids of the groups for which the user has permissions
146 */
147 public static function group(
148 $type,
149 $contactID = NULL,
150 $tableName = 'civicrm_saved_search',
151 $allGroups = NULL,
152 $includedGroups = NULL
153 ) {
154 if ($contactID == NULL) {
155 $session = CRM_Core_Session::singleton();
156 $contactID = $session->get('userID');
157 }
158
159 if (!$contactID) {
160 // anonymous user
161 $contactID = 0;
162 }
163
164 return CRM_ACL_BAO_ACL::group($type, $contactID, $tableName, $allGroups, $includedGroups);
165 }
166
167 /**
168 * Check if the user has access to this group for operation $type
169 *
170 * @param int $type the type of permission needed
171 * @param int $groupID
172 * @param int $contactID the contactID for whom the check is made
173 *
174 * @param string $tableName
175 * @param null $allGroups
176 * @param null $includedGroups
177 * @param bool $flush
178 *
179 * @return array the ids of the groups for which the user has permissions
180 */
181 public static function groupPermission(
182 $type,
183 $groupID,
184 $contactID = NULL,
185 $tableName = 'civicrm_saved_search',
186 $allGroups = NULL,
187 $includedGroups = NULL,
188 $flush = FALSE
189 ) {
190
191 static $cache = array();
192 //@todo this is pretty hacky!!!
193 //adding a way for unit tests to flush the cache
194 if ($flush) {
195 $cache = array();
196 return;
197 }
198 if (!$contactID) {
199 $session = CRM_Core_Session::singleton();
200 $contactID = NULL;
201 if ($session->get('userID')) {
202 $contactID = $session->get('userID');
203 }
204 }
205
206 $key = "{$tableName}_{$type}_{$contactID}";
207 if (array_key_exists($key, $cache)) {
208 $groups = &$cache[$key];
209 }
210 else {
211 $groups = self::group($type, $contactID, $tableName, $allGroups, $includedGroups);
212 $cache[$key] = $groups;
213 }
214
215 return in_array($groupID, $groups) ? TRUE : FALSE;
216 }
217 }