Merge pull request #4726 from atif-shaikh/CRM-5039
[civicrm-core.git] / tools / extensions / org.civicrm.multisite / multisite.php
CommitLineData
6a488035
TO
1<?php
2
3require_once 'multisite.civix.php';
4
5/**
6 * Implementation of hook_civicrm_config
7 */
8function multisite_civicrm_config(&$config) {
9 _multisite_civix_civicrm_config($config);
10}
11
12/**
13 * Implementation of hook_civicrm_xmlMenu
14 *
15 * @param $files array(string)
16 */
17function multisite_civicrm_xmlMenu(&$files) {
18 _multisite_civix_civicrm_xmlMenu($files);
19}
20
21/**
22 * Implementation of hook_civicrm_install
23 */
24function multisite_civicrm_install() {
25 return _multisite_civix_civicrm_install();
26}
27
28/**
29 * Implementation of hook_civicrm_uninstall
30 */
31function multisite_civicrm_uninstall() {
32 return _multisite_civix_civicrm_uninstall();
33}
34
35/**
36 * Implementation of hook_civicrm_enable
37 */
38function multisite_civicrm_enable() {
39 return _multisite_civix_civicrm_enable();
40}
41
42/**
43 * Implementation of hook_civicrm_disable
44 */
45function multisite_civicrm_disable() {
46 return _multisite_civix_civicrm_disable();
47}
48
49/**
50 * Implementation of hook_civicrm_upgrade
51 *
52 * @param $op string, the type of operation being performed; 'check' or 'enqueue'
53 * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks
54 *
55 * @return mixed based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending)
56 * for 'enqueue', returns void
57 */
58function multisite_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
59 return _multisite_civix_civicrm_upgrade($op, $queue);
60}
61
62/**
63 * Implementation of hook_civicrm_managed
64 *
65 * Generate a list of entities to create/deactivate/delete when this module
66 * is installed, disabled, uninstalled.
67 */
68function multisite_civicrm_managed(&$entities) {
69 return _multisite_civix_civicrm_managed($entities);
70}
71
72/**
73 * * Implementation of hook_civicrm_post
74 *
75 * Current implemtation assumes shared user table for all sites -
76 * a more sophisticated version will be able to cope with a combination of shared user tables
77 * and separate user tables
78 *
79 * @param string $op
80 * @param string $objectName
81 * @param integer $objectId
82 * @param object $objectRef
83 */
84function multisite_civicrm_post($op, $objectName, $objectId, &$objectRef) {
85 if ($op == 'edit' && $objectName == 'UFMatch') {
86 static $updating = FALSE;
87 if ($updating) {
88 return; // prevent recursion
89 }
90 $updating = TRUE;
91 $ufs = civicrm_api('uf_match', 'get', array(
92 'version' => 3,
93 'contact_id' => $objectRef->contact_id,
94 'uf_id' => $objectRef->uf_id,
95 'id' => array(
96 '!=' => $objectRef->id
97 )
98 ));
99 foreach ($ufs['values'] as $ufMatch) {
100 civicrm_api('UFMatch', 'create', array(
101 'version' => 3,
102 'id' => $ufMatch['id'],
103 'uf_name' => $objectRef->uf_name
104 ));
105 }
106 }
107}
108/**
109 *
110 * @param unknown_type $type
111 * @param unknown_type $contactID
112 * @param unknown_type $tableName
113 * @param unknown_type $allGroups
114 * @param unknown_type $currentGroups
115 */
116function multisite_civicrm_aclGroup($type, $contactID, $tableName, &$allGroups, &$currentGroups) {
117 // only process saved search
118 if ($tableName != 'civicrm_saved_search') {
119 return;
120 }
121 $groupID = _multisite_get_domain_group();
122 if(!$groupID){
123 return;
124 }
125 $currentGroups = _multisite_get_all_child_groups($groupID, FALSE);
126}
127
128/**
129 *
130 * @param string $type
131 * @param array $tables tables to be included in query
132 * @param array $whereTables tables required for where portion of query
133 * @param integer $contactID contact for whom where clause is being composed
134 * @param string $where Where clause The completed clause will look like
135 * (multisiteGroupTable.group_id IN ("1,2,3,4,5") AND multisiteGroupTable.status IN ('Added') AND contact_a.is_deleted = 0)
136 * where the child groups are groups the contact is potentially a member of
137 *
138 */
139function multisite_civicrm_aclWhereClause($type, &$tables, &$whereTables, &$contactID, &$where) {
140 if (! $contactID) {
141 return;
142 }
143 if(!_multisite_add_permissions($type)){
144 return;
145 }
146 $groupID = _multisite_get_domain_group();
147 if(!$groupID){
148 return;
149 }
150 $childOrgs = _multisite_get_all_child_groups($groupID);
151
152 if (! empty($childOrgs)) {
153 $groupTable = 'civicrm_group_contact';
154 $tables[$groupTable] = $whereTables[$groupTable] = "LEFT JOIN {$groupTable} multisiteGroupTable ON contact_a.id = multisiteGroupTable.contact_id";
155
156 $where = "(multisiteGroupTable.group_id IN (" . implode(',', $childOrgs) . ") AND multisiteGroupTable.status IN ('Added') AND contact_a.is_deleted = 0)";
157 }
158}
159/**
160 *
161 * @param array $permissions
162 */
163function multisite_civicrm_permissions(&$permissions){
164 $prefix = ts('CiviCRM Multisite') . ': ';
165 $permissions = $permissions + array(
166 'view all contacts in domain' => $prefix . ts('view all contacts in domain'),
167 'edit all contacts in domain' => $prefix . ts('edit all contacts in domain'),
168 );
169}
170
171/**
172 * Implementation of hook_civicrm_config
173 */
174function multisite_civicrm_alterSettingsFolders(&$metaDataFolders = NULL){
175 _multisite_civix_civicrm_alterSettingsFolders($metaDataFolders);
176}
177
178/**
179 * Get all groups that are children of the parent group
180 * (iterate through all levels)
181 *
182 * @param integer $groupID
183 * @param boolean $includeParent
184 * @return array:child groups
185 */
186function _multisite_get_all_child_groups($groupID, $includeParent = TRUE) {
187 static $_cache = array();
188
189 if (! array_key_exists($groupID, $_cache)) {
190 $childGroups = &CRM_Core_BAO_Cache::getItem('descendant groups for an org', $groupID);
191
192 if (empty($childGroups)) {
193 $childGroups = array();
194
195 $query = "
196SELECT children
197FROM civicrm_group
198WHERE children IS NOT NULL
199AND id IN ";
200
201 if (! is_array($groupID)) {
202 $groupIDs = array(
203 $groupID
204 );
205 }
206
207 while (! empty($groupIDs)) {
208 $groupIDString = implode(',', $groupIDs);
209
210 $realQuery = $query . " ( $groupIDString )";
211 $dao = CRM_Core_DAO::executeQuery($realQuery);
212 $groupIDs = array();
213 while ($dao->fetch()) {
214 if ($dao->children) {
215 $childIDs = explode(',', $dao->children);
216 foreach ($childIDs as $childID) {
217 if (! array_key_exists($childID, $childGroups)) {
218 $childGroups[$childID] = 1;
219 $groupIDs[] = $childID;
220 }
221 }
222 }
223 }
224 }
225
226 CRM_Core_BAO_Cache::setItem($childGroups, 'descendant groups for an org', $groupID);
227 }
228 $_cache[$groupID] = $childGroups;
229 }
230
231 if ($includeParent || CRM_Core_Permission::check('administer Multiple Organizations')) {
232 return array_keys(array(
233 $groupID => 1
234 ) + $_cache[$groupID]);
235 }
236 else {
237 return array_keys($_cache[$groupID]);
238 }
239}
240
241/**
2a6da8d7
EM
242 *
243 * @param int $permission
6a488035
TO
244 *
245 * @return NULL|integer $groupID
246 */
247function _multisite_get_domain_group($permission = 1) {
248 $groupID = CRM_Core_BAO_Domain::getGroupId();
249 if(empty($groupID) || !is_numeric($groupID)){
250 /* domain group not defined - we could let people know but
251 * it is acceptable for some domains not to be in the multisite
252 * so should probably check enabled before we spring an error
253 */
254 return NULL;
255 }
256 // We will check for the possiblility of the acl_enabled setting being deliberately set to 0
257 if($permission){
258 $aclsEnabled = civicrm_api('setting', 'getvalue', array(
259 'version' => 3,
260 'name' => 'multisite_acl_enabled',
261 'group' => 'Multi Site Preferences')
262 );
263 if(is_numeric($aclsEnabled) && !$aclsEnabled){
264 return NULL;
265 }
266 }
267
268 return $groupID;
269 }
270
8deefe64
EM
271/**
272 * Should we be adding ACLs in this instance. If we don't add them the user
273 * will not be able to see anything. We check if the install has the permissions
274 * hook implemented correctly & if so only allow view & edit based on those.
275 *
276 * Otherwise all users get these permissions added (4.2 vs 4.3 / other CMS issues)
277 *
278 * @param integer $type type of operation
279 *
280 * @return bool
281 */
6a488035
TO
282 function _multisite_add_permissions($type){
283 $hookclass = 'CRM_Utils_Hook';
284 if(!method_exists($hookclass, 'permissions')){
285 // ie. unpatched 4.2 so we can't check for extra declared permissions
286 // & default to applying this to all
287 return TRUE;
288 }
289 // extra check to make sure that hook is properly implemented
290 // if not we won't check for it. NB view all contacts in domain is enough checking
291 $declaredPermissions = CRM_Core_Permission::getCorePermissions();
292 if(!array_key_exists('view all contacts in domain', $declaredPermissions)){
293 drupal_set_message('here');
294 return TRUE;
295 }
296
297 if(CRM_ACL_BAO_ACL::matchType($type, 'View') &&
298 CRM_Core_Permission::check('view all contacts in domain')) {
299 return TRUE;
300 }
301
302 if(CRM_ACL_BAO_ACL::matchType($type, 'Edit') &&
303 CRM_Core_Permission::check('edit all contacts in domain')) {
304 return TRUE;
305 }
306 return FALSE;
307 }
308