Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
fee14197 | 4 | | CiviCRM version 5 | |
6a488035 | 5 | +--------------------------------------------------------------------+ |
6b83d5bd | 6 | | Copyright CiviCRM LLC (c) 2004-2019 | |
6a488035 TO |
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 | +--------------------------------------------------------------------+ | |
d25dd0ee | 26 | */ |
6a488035 TO |
27 | |
28 | /** | |
29 | * | |
30 | * @package CRM | |
6b83d5bd | 31 | * @copyright CiviCRM LLC (c) 2004-2019 |
6a488035 TO |
32 | */ |
33 | class CRM_Contact_BAO_GroupContact extends CRM_Contact_DAO_GroupContact { | |
34 | ||
35 | /** | |
fe482240 | 36 | * Class constructor. |
6a488035 | 37 | */ |
00be9182 | 38 | public function __construct() { |
6a488035 TO |
39 | parent::__construct(); |
40 | } | |
41 | ||
42 | /** | |
fe482240 | 43 | * Takes an associative array and creates a groupContact object. |
6a488035 TO |
44 | * |
45 | * the function extract all the params it needs to initialize the create a | |
46 | * group object. the params array could contain additional unused name/value | |
47 | * pairs | |
48 | * | |
77c5b619 TO |
49 | * @param array $params |
50 | * (reference ) an assoc array of name/value pairs. | |
6a488035 | 51 | * |
16b10e64 | 52 | * @return CRM_Contact_BAO_Group |
6a488035 | 53 | */ |
35cb4b48 CW |
54 | public static function add($params) { |
55 | $hook = empty($params['id']) ? 'create' : 'edit'; | |
56 | CRM_Utils_Hook::pre($hook, 'GroupContact', CRM_Utils_Array::value('id', $params), $params); | |
6a488035 | 57 | |
35cb4b48 | 58 | if (!self::dataExists($params)) { |
6a488035 TO |
59 | return NULL; |
60 | } | |
61 | ||
62 | $groupContact = new CRM_Contact_BAO_GroupContact(); | |
63 | $groupContact->copyValues($params); | |
6a488035 | 64 | $groupContact->save(); |
35cb4b48 CW |
65 | |
66 | // Lookup existing info for the sake of subscription history | |
67 | if (!empty($params['id'])) { | |
68 | $groupContact->find(TRUE); | |
69 | $params = $groupContact->toArray(); | |
70 | } | |
71 | CRM_Contact_BAO_SubscriptionHistory::create($params); | |
72 | ||
73 | CRM_Utils_Hook::post($hook, 'GroupContact', $groupContact->id, $groupContact); | |
74 | ||
6a488035 TO |
75 | return $groupContact; |
76 | } | |
77 | ||
78 | /** | |
fe482240 | 79 | * Check if there is data to create the object. |
6a488035 | 80 | * |
77c5b619 TO |
81 | * @param array $params |
82 | * (reference ) an assoc array of name/value pairs. | |
6a488035 | 83 | * |
608e6658 | 84 | * @return bool |
6a488035 | 85 | */ |
00be9182 | 86 | public static function dataExists(&$params) { |
35cb4b48 | 87 | return (!empty($params['id']) || (!empty($params['group_id']) && !empty($params['contact_id']))); |
6a488035 TO |
88 | } |
89 | ||
90 | /** | |
91 | * Given the list of params in the params array, fetch the object | |
92 | * and store the values in the values array | |
93 | * | |
77c5b619 TO |
94 | * @param array $params |
95 | * Input parameters to find object. | |
96 | * @param array $values | |
97 | * Output values of the object. | |
6c8f6e67 | 98 | * |
a6c01b45 CW |
99 | * @return array |
100 | * (reference) the values that could be potentially assigned to smarty | |
6a488035 | 101 | */ |
00be9182 | 102 | public static function getValues(&$params, &$values) { |
6a488035 TO |
103 | if (empty($params)) { |
104 | return NULL; | |
105 | } | |
b2be28e3 | 106 | $values['group']['data'] = CRM_Contact_BAO_GroupContact::getContactGroup($params['contact_id'], |
6a488035 TO |
107 | 'Added', |
108 | 3 | |
109 | ); | |
110 | ||
111 | // get the total count of groups | |
112 | $values['group']['totalCount'] = CRM_Contact_BAO_GroupContact::getContactGroup($params['contact_id'], | |
113 | 'Added', | |
114 | NULL, | |
115 | TRUE | |
116 | ); | |
117 | ||
118 | return NULL; | |
119 | } | |
120 | ||
121 | /** | |
122 | * Given an array of contact ids, add all the contacts to the group | |
123 | * | |
77c5b619 TO |
124 | * @param array $contactIds |
125 | * The array of contact ids to be added. | |
126 | * @param int $groupId | |
127 | * The id of the group. | |
c49a2977 CW |
128 | * @param string $method |
129 | * @param string $status | |
130 | * @param int $tracking | |
6a488035 | 131 | * |
a6c01b45 CW |
132 | * @return array |
133 | * (total, added, notAdded) count of contacts added to group | |
6a488035 | 134 | */ |
608e6658 | 135 | public static function addContactsToGroup( |
c49a2977 | 136 | $contactIds, |
6a488035 | 137 | $groupId, |
242bd179 TO |
138 | $method = 'Admin', |
139 | $status = 'Added', | |
6a488035 TO |
140 | $tracking = NULL |
141 | ) { | |
66fc0405 | 142 | if (empty($contactIds) || empty($groupId)) { |
be2fb01f | 143 | return []; |
66fc0405 | 144 | } |
6a488035 | 145 | |
6a488035 TO |
146 | CRM_Utils_Hook::pre('create', 'GroupContact', $groupId, $contactIds); |
147 | ||
006389de TO |
148 | list($numContactsAdded, $numContactsNotAdded) |
149 | = self::bulkAddContactsToGroup($contactIds, $groupId, $method, $status, $tracking); | |
6a488035 | 150 | |
0626851e | 151 | CRM_Contact_BAO_Contact_Utils::clearContactCaches(); |
6a488035 TO |
152 | |
153 | CRM_Utils_Hook::post('create', 'GroupContact', $groupId, $contactIds); | |
154 | ||
be2fb01f | 155 | return [count($contactIds), $numContactsAdded, $numContactsNotAdded]; |
6a488035 TO |
156 | } |
157 | ||
158 | /** | |
159 | * Given an array of contact ids, remove all the contacts from the group | |
160 | * | |
77c5b619 TO |
161 | * @param array $contactIds |
162 | * (reference ) the array of contact ids to be removed. | |
163 | * @param int $groupId | |
164 | * The id of the group. | |
fd31fa4c EM |
165 | * |
166 | * @param string $method | |
167 | * @param string $status | |
e97c66ff | 168 | * @param string $tracking |
6a488035 | 169 | * |
a6c01b45 CW |
170 | * @return array |
171 | * (total, removed, notRemoved) count of contacts removed to group | |
6a488035 | 172 | */ |
608e6658 | 173 | public static function removeContactsFromGroup( |
6a488035 TO |
174 | &$contactIds, |
175 | $groupId, | |
242bd179 TO |
176 | $method = 'Admin', |
177 | $status = 'Removed', | |
6a488035 TO |
178 | $tracking = NULL |
179 | ) { | |
180 | if (!is_array($contactIds)) { | |
be2fb01f | 181 | return [0, 0, 0]; |
6a488035 | 182 | } |
6a488035 TO |
183 | if ($status == 'Removed' || $status == 'Deleted') { |
184 | $op = 'delete'; | |
185 | } | |
186 | else { | |
187 | $op = 'edit'; | |
188 | } | |
189 | ||
190 | CRM_Utils_Hook::pre($op, 'GroupContact', $groupId, $contactIds); | |
191 | ||
192 | $date = date('YmdHis'); | |
193 | $numContactsRemoved = 0; | |
194 | $numContactsNotRemoved = 0; | |
195 | ||
196 | $group = new CRM_Contact_DAO_Group(); | |
197 | $group->id = $groupId; | |
198 | $group->find(TRUE); | |
199 | ||
200 | foreach ($contactIds as $contactId) { | |
201 | if ($status == 'Deleted') { | |
dadeae7d SL |
202 | $query = "DELETE FROM civicrm_group_contact WHERE contact_id = %1 AND group_id = %2"; |
203 | $dao = CRM_Core_DAO::executeQuery($query, [ | |
204 | 1 => [$contactId, 'Positive'], | |
205 | 2 => [$groupId, 'Positive'], | |
206 | ]); | |
be2fb01f | 207 | $historyParams = [ |
6a488035 TO |
208 | 'group_id' => $groupId, |
209 | 'contact_id' => $contactId, | |
210 | 'status' => $status, | |
211 | 'method' => $method, | |
212 | 'date' => $date, | |
213 | 'tracking' => $tracking, | |
be2fb01f | 214 | ]; |
6a488035 | 215 | CRM_Contact_BAO_SubscriptionHistory::create($historyParams); |
dadeae7d SL |
216 | // Removing a row from civicrm_group_contact for a smart group may mean a contact |
217 | // Is now back in a group based on criteria so we will invalidate the cache if it is there | |
218 | // So that accurate group cache is created next time it is needed. | |
219 | CRM_Contact_BAO_GroupContactCache::invalidateGroupContactCache($groupId); | |
6a488035 TO |
220 | } |
221 | else { | |
222 | $groupContact = new CRM_Contact_DAO_GroupContact(); | |
223 | $groupContact->group_id = $groupId; | |
224 | $groupContact->contact_id = $contactId; | |
225 | // check if the selected contact id already a member, or if this is | |
226 | // an opt-out of a smart group. | |
227 | // if not a member remove to groupContact else keep the count of contacts that are not removed | |
228 | if ($groupContact->find(TRUE) || $group->saved_search_id) { | |
229 | // remove the contact from the group | |
230 | $numContactsRemoved++; | |
231 | } | |
232 | else { | |
233 | $numContactsNotRemoved++; | |
234 | } | |
235 | ||
236 | //now we grant the negative membership to contact if not member. CRM-3711 | |
be2fb01f | 237 | $historyParams = [ |
6a488035 TO |
238 | 'group_id' => $groupId, |
239 | 'contact_id' => $contactId, | |
240 | 'status' => $status, | |
241 | 'method' => $method, | |
242 | 'date' => $date, | |
243 | 'tracking' => $tracking, | |
be2fb01f | 244 | ]; |
6a488035 TO |
245 | CRM_Contact_BAO_SubscriptionHistory::create($historyParams); |
246 | $groupContact->status = $status; | |
247 | $groupContact->save(); | |
c82bcfd1 | 248 | // Remove any rows from the group contact cache so it disappears straight away from smart groups. |
249 | CRM_Contact_BAO_GroupContactCache::removeContact($contactId, $groupId); | |
6a488035 TO |
250 | } |
251 | } | |
252 | ||
0626851e | 253 | CRM_Contact_BAO_Contact_Utils::clearContactCaches(); |
6a488035 TO |
254 | |
255 | CRM_Utils_Hook::post($op, 'GroupContact', $groupId, $contactIds); | |
256 | ||
be2fb01f | 257 | return [count($contactIds), $numContactsRemoved, $numContactsNotRemoved]; |
6a488035 TO |
258 | } |
259 | ||
260 | /** | |
fe482240 | 261 | * Get list of all the groups and groups for a contact. |
6a488035 | 262 | * |
77c5b619 TO |
263 | * @param int $contactId |
264 | * Contact id. | |
6a488035 | 265 | * |
da6b46f4 EM |
266 | * @param bool $visibility |
267 | * | |
6a488035 | 268 | * |
a6c01b45 CW |
269 | * @return array |
270 | * this array has key-> group id and value group title | |
6a488035 | 271 | */ |
00be9182 | 272 | public static function getGroupList($contactId = 0, $visibility = FALSE) { |
6a488035 TO |
273 | $group = new CRM_Contact_DAO_Group(); |
274 | ||
275 | $select = $from = $where = ''; | |
276 | ||
bad98dd5 | 277 | $select = 'SELECT civicrm_group.id, civicrm_group.title '; |
242bd179 TO |
278 | $from = ' FROM civicrm_group '; |
279 | $where = " WHERE civicrm_group.is_active = 1 "; | |
6a488035 TO |
280 | if ($contactId) { |
281 | $from .= ' , civicrm_group_contact '; | |
282 | $where .= " AND civicrm_group.id = civicrm_group_contact.group_id | |
283 | AND civicrm_group_contact.contact_id = " . CRM_Utils_Type::escape($contactId, 'Integer'); | |
284 | } | |
285 | ||
286 | if ($visibility) { | |
287 | $where .= " AND civicrm_group.visibility != 'User and User Admin Only'"; | |
288 | } | |
3636b520 | 289 | $groupBy = " GROUP BY civicrm_group.id"; |
6a488035 TO |
290 | |
291 | $orderby = " ORDER BY civicrm_group.name"; | |
bad98dd5 | 292 | $sql = $select . $from . $where . $groupBy . $orderby; |
6a488035 TO |
293 | |
294 | $group->query($sql); | |
295 | ||
be2fb01f | 296 | $values = []; |
6a488035 TO |
297 | while ($group->fetch()) { |
298 | $values[$group->id] = $group->title; | |
299 | } | |
300 | ||
301 | return $values; | |
302 | } | |
303 | ||
304 | /** | |
fe482240 | 305 | * Get the list of groups for contact based on status of group membership. |
6a488035 | 306 | * |
77c5b619 TO |
307 | * @param int $contactId |
308 | * Contact id. | |
309 | * @param string $status | |
310 | * State of membership. | |
311 | * @param int $numGroupContact | |
312 | * Number of groups for a contact that should be shown. | |
313 | * @param bool $count | |
314 | * True if we are interested only in the count. | |
315 | * @param bool $ignorePermission | |
316 | * True if we should ignore permissions for the current user. | |
6a488035 TO |
317 | * useful in profile where permissions are limited for the user. If left |
318 | * at false only groups viewable by the current user are returned | |
77c5b619 TO |
319 | * @param bool $onlyPublicGroups |
320 | * True if we want to hide system groups. | |
fd31fa4c EM |
321 | * |
322 | * @param bool $excludeHidden | |
6a488035 | 323 | * |
ea3ddccf | 324 | * @param int $groupId |
325 | * | |
f08cb0da | 326 | * @param bool $includeSmartGroups |
327 | * Include or Exclude Smart Group(s) | |
328 | * | |
69078420 | 329 | * @return array|int |
ea3ddccf | 330 | * the relevant data object values for the contact or the total count when $count is TRUE |
6a488035 | 331 | */ |
3875e6b6 | 332 | public static function getContactGroup( |
6a488035 | 333 | $contactId, |
242bd179 TO |
334 | $status = NULL, |
335 | $numGroupContact = NULL, | |
336 | $count = FALSE, | |
6a488035 TO |
337 | $ignorePermission = FALSE, |
338 | $onlyPublicGroups = FALSE, | |
242bd179 | 339 | $excludeHidden = TRUE, |
b120248c | 340 | $groupId = NULL, |
965403bf | 341 | $includeSmartGroups = FALSE |
6a488035 TO |
342 | ) { |
343 | if ($count) { | |
344 | $select = 'SELECT count(DISTINCT civicrm_group_contact.id)'; | |
345 | } | |
346 | else { | |
347 | $select = 'SELECT | |
348 | civicrm_group_contact.id as civicrm_group_contact_id, | |
349 | civicrm_group.title as group_title, | |
350 | civicrm_group.visibility as visibility, | |
351 | civicrm_group_contact.status as status, | |
352 | civicrm_group.id as group_id, | |
353 | civicrm_group.is_hidden as is_hidden, | |
354 | civicrm_subscription_history.date as date, | |
355 | civicrm_subscription_history.method as method'; | |
356 | } | |
357 | ||
b120248c | 358 | $where = " WHERE contact_a.id = %1 AND civicrm_group.is_active = 1"; |
965403bf AJ |
359 | if (!$includeSmartGroups) { |
360 | $where .= " AND saved_search_id IS NULL"; | |
361 | } | |
6a488035 TO |
362 | if ($excludeHidden) { |
363 | $where .= " AND civicrm_group.is_hidden = 0 "; | |
364 | } | |
be2fb01f | 365 | $params = [1 => [$contactId, 'Integer']]; |
6a488035 TO |
366 | if (!empty($status)) { |
367 | $where .= ' AND civicrm_group_contact.status = %2'; | |
be2fb01f | 368 | $params[2] = [$status, 'String']; |
6a488035 | 369 | } |
49fb4e06 RK |
370 | if (!empty($groupId)) { |
371 | $where .= " AND civicrm_group.id = %3 "; | |
be2fb01f | 372 | $params[3] = [$groupId, 'Integer']; |
49fb4e06 | 373 | } |
be2fb01f | 374 | $tables = [ |
6a488035 TO |
375 | 'civicrm_group_contact' => 1, |
376 | 'civicrm_group' => 1, | |
377 | 'civicrm_subscription_history' => 1, | |
be2fb01f CW |
378 | ]; |
379 | $whereTables = []; | |
6a488035 TO |
380 | if ($ignorePermission) { |
381 | $permission = ' ( 1 ) '; | |
382 | } | |
383 | else { | |
384 | $permission = CRM_Core_Permission::getPermissionedStaticGroupClause(CRM_Core_Permission::VIEW, $tables, $whereTables); | |
385 | } | |
386 | ||
387 | $from = CRM_Contact_BAO_Query::fromClause($tables); | |
388 | ||
389 | $where .= " AND $permission "; | |
390 | ||
391 | if ($onlyPublicGroups) { | |
392 | $where .= " AND civicrm_group.visibility != 'User and User Admin Only' "; | |
393 | } | |
394 | ||
395 | $order = $limit = ''; | |
396 | if (!$count) { | |
397 | $order = ' ORDER BY civicrm_group.title, civicrm_subscription_history.date ASC'; | |
398 | ||
399 | if ($numGroupContact) { | |
400 | $limit = " LIMIT 0, $numGroupContact"; | |
401 | } | |
402 | } | |
403 | ||
404 | $sql = $select . $from . $where . $order . $limit; | |
405 | ||
406 | if ($count) { | |
407 | $result = CRM_Core_DAO::singleValueQuery($sql, $params); | |
408 | return $result; | |
409 | } | |
410 | else { | |
411 | $dao = CRM_Core_DAO::executeQuery($sql, $params); | |
be2fb01f | 412 | $values = []; |
6a488035 TO |
413 | while ($dao->fetch()) { |
414 | $id = $dao->civicrm_group_contact_id; | |
415 | $values[$id]['id'] = $id; | |
416 | $values[$id]['group_id'] = $dao->group_id; | |
417 | $values[$id]['title'] = $dao->group_title; | |
418 | $values[$id]['visibility'] = $dao->visibility; | |
419 | $values[$id]['is_hidden'] = $dao->is_hidden; | |
420 | switch ($dao->status) { | |
421 | case 'Added': | |
422 | $prefix = 'in_'; | |
423 | break; | |
424 | ||
425 | case 'Removed': | |
426 | $prefix = 'out_'; | |
427 | break; | |
428 | ||
429 | default: | |
430 | $prefix = 'pending_'; | |
431 | } | |
432 | $values[$id][$prefix . 'date'] = $dao->date; | |
433 | $values[$id][$prefix . 'method'] = $dao->method; | |
434 | if ($status == 'Removed') { | |
435 | $query = "SELECT `date` as `date_added` FROM civicrm_subscription_history WHERE id = (SELECT max(id) FROM civicrm_subscription_history WHERE contact_id = %1 AND status = \"Added\" AND group_id = $dao->group_id )"; | |
436 | $dateDAO = CRM_Core_DAO::executeQuery($query, $params); | |
437 | if ($dateDAO->fetch()) { | |
438 | $values[$id]['date_added'] = $dateDAO->date_added; | |
439 | } | |
440 | } | |
441 | } | |
442 | return $values; | |
443 | } | |
444 | } | |
445 | ||
446 | /** | |
fe482240 | 447 | * Returns membership details of a contact for a group. |
6a488035 | 448 | * |
77c5b619 TO |
449 | * @param int $contactId |
450 | * Id of the contact. | |
451 | * @param int $groupID | |
3b992cb6 | 452 | * Id of a particular group. |
77c5b619 TO |
453 | * @param string $method |
454 | * If we want the subscription history details for a specific method. | |
6a488035 | 455 | * |
a6c01b45 CW |
456 | * @return object |
457 | * of group contact | |
6a488035 | 458 | */ |
00be9182 | 459 | public static function getMembershipDetail($contactId, $groupID, $method = 'Email') { |
e60f24eb | 460 | $leftJoin = $where = $orderBy = NULL; |
6a488035 TO |
461 | |
462 | if ($method) { | |
071c6f10 BS |
463 | //CRM-13341 add group_id clause |
464 | $leftJoin = " | |
465 | LEFT JOIN civicrm_subscription_history | |
466 | ON ( civicrm_group_contact.contact_id = civicrm_subscription_history.contact_id | |
467 | AND civicrm_subscription_history.group_id = {$groupID} )"; | |
6a488035 TO |
468 | $where = "AND civicrm_subscription_history.method ='Email'"; |
469 | $orderBy = "ORDER BY civicrm_subscription_history.id DESC"; | |
470 | } | |
471 | $query = " | |
472 | SELECT * | |
473 | FROM civicrm_group_contact | |
474 | $leftJoin | |
475 | WHERE civicrm_group_contact.contact_id = %1 | |
476 | AND civicrm_group_contact.group_id = %2 | |
477 | $where | |
478 | $orderBy | |
479 | "; | |
480 | ||
be2fb01f CW |
481 | $params = [ |
482 | 1 => [$contactId, 'Integer'], | |
483 | 2 => [$groupID, 'Integer'], | |
484 | ]; | |
6a488035 TO |
485 | $dao = CRM_Core_DAO::executeQuery($query, $params); |
486 | $dao->fetch(); | |
487 | return $dao; | |
488 | } | |
489 | ||
6a488035 | 490 | /** |
fe482240 | 491 | * Method to get Group Id. |
6a488035 | 492 | * |
77c5b619 | 493 | * @param int $groupContactID |
3b992cb6 | 494 | * Id of a particular group. |
6a488035 TO |
495 | * |
496 | * | |
497 | * @return groupID | |
6a488035 | 498 | */ |
00be9182 | 499 | public static function getGroupId($groupContactID) { |
6a488035 TO |
500 | $dao = new CRM_Contact_DAO_GroupContact(); |
501 | $dao->id = $groupContactID; | |
502 | $dao->find(TRUE); | |
503 | return $dao->group_id; | |
504 | } | |
505 | ||
506 | /** | |
100fef9d | 507 | * Takes an associative array and creates / removes |
6a488035 TO |
508 | * contacts from the groups |
509 | * | |
510 | * | |
77c5b619 TO |
511 | * @param array $params |
512 | * (reference ) an assoc array of name/value pairs. | |
513 | * @param array $contactId | |
514 | * Contact id. | |
2a6da8d7 EM |
515 | * |
516 | * @param bool $visibility | |
517 | * @param string $method | |
6a488035 | 518 | */ |
00be9182 | 519 | public static function create(&$params, $contactId, $visibility = FALSE, $method = 'Admin') { |
be2fb01f | 520 | $contactIds = []; |
6a488035 TO |
521 | $contactIds[] = $contactId; |
522 | ||
523 | //if $visibility is true we are coming in via profile mean $method = 'Web' | |
524 | $ignorePermission = FALSE; | |
525 | if ($visibility) { | |
526 | $ignorePermission = TRUE; | |
527 | } | |
528 | ||
529 | if ($contactId) { | |
f078bc70 | 530 | $contactGroupList = CRM_Contact_BAO_GroupContact::getContactGroup($contactId, 'Added', |
6a488035 TO |
531 | NULL, FALSE, $ignorePermission |
532 | ); | |
533 | if (is_array($contactGroupList)) { | |
534 | foreach ($contactGroupList as $key) { | |
535 | $groupId = $key['group_id']; | |
536 | $contactGroup[$groupId] = $groupId; | |
537 | } | |
538 | } | |
539 | } | |
540 | ||
541 | // get the list of all the groups | |
542 | $allGroup = CRM_Contact_BAO_GroupContact::getGroupList(0, $visibility); | |
543 | ||
544 | // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input | |
545 | if (!is_array($params)) { | |
be2fb01f | 546 | $params = []; |
6a488035 TO |
547 | } |
548 | ||
549 | // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input | |
550 | if (!isset($contactGroup) || !is_array($contactGroup)) { | |
be2fb01f | 551 | $contactGroup = []; |
6a488035 TO |
552 | } |
553 | ||
554 | // check which values has to be add/remove contact from group | |
555 | foreach ($allGroup as $key => $varValue) { | |
a7488080 | 556 | if (!empty($params[$key]) && !array_key_exists($key, $contactGroup)) { |
6a488035 TO |
557 | // add contact to group |
558 | CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIds, $key, $method); | |
559 | } | |
a7488080 | 560 | elseif (empty($params[$key]) && array_key_exists($key, $contactGroup)) { |
6a488035 TO |
561 | // remove contact from group |
562 | CRM_Contact_BAO_GroupContact::removeContactsFromGroup($contactIds, $key, $method); | |
563 | } | |
564 | } | |
565 | } | |
566 | ||
86538308 | 567 | /** |
100fef9d CW |
568 | * @param int $contactID |
569 | * @param int $groupID | |
86538308 EM |
570 | * |
571 | * @return bool | |
572 | */ | |
00be9182 | 573 | public static function isContactInGroup($contactID, $groupID) { |
6a488035 TO |
574 | if (!CRM_Utils_Rule::positiveInteger($contactID) || |
575 | !CRM_Utils_Rule::positiveInteger($groupID) | |
576 | ) { | |
577 | return FALSE; | |
578 | } | |
579 | ||
be2fb01f CW |
580 | $params = [ |
581 | ['group', 'IN', [$groupID], 0, 0], | |
582 | ['contact_id', '=', $contactID, 0, 0], | |
583 | ]; | |
584 | list($contacts, $_) = CRM_Contact_BAO_Query::apiQuery($params, ['contact_id']); | |
6a488035 TO |
585 | |
586 | if (!empty($contacts)) { | |
587 | return TRUE; | |
588 | } | |
589 | return FALSE; | |
590 | } | |
591 | ||
592 | /** | |
fe482240 | 593 | * Function merges the groups from otherContactID to mainContactID. |
6a488035 TO |
594 | * along with subscription history |
595 | * | |
77c5b619 TO |
596 | * @param int $mainContactId |
597 | * Contact id of main contact record. | |
598 | * @param int $otherContactId | |
599 | * Contact id of record which is going to merge. | |
6a488035 TO |
600 | * |
601 | * @see CRM_Dedupe_Merger::cpTables() | |
602 | * | |
603 | * TODO: use the 3rd $sqls param to append sql statements rather than executing them here | |
6a488035 | 604 | */ |
00be9182 | 605 | public static function mergeGroupContact($mainContactId, $otherContactId) { |
be2fb01f CW |
606 | $params = [ |
607 | 1 => [$mainContactId, 'Integer'], | |
608 | 2 => [$otherContactId, 'Integer'], | |
609 | ]; | |
6a488035 TO |
610 | |
611 | // find all groups that are in otherContactID but not in mainContactID, copy them over | |
612 | $sql = " | |
613 | SELECT cOther.group_id | |
614 | FROM civicrm_group_contact cOther | |
615 | LEFT JOIN civicrm_group_contact cMain ON cOther.group_id = cMain.group_id AND cMain.contact_id = %1 | |
616 | WHERE cOther.contact_id = %2 | |
617 | AND cMain.contact_id IS NULL | |
618 | "; | |
619 | $dao = CRM_Core_DAO::executeQuery($sql, $params); | |
620 | ||
be2fb01f | 621 | $otherGroupIDs = []; |
6a488035 TO |
622 | while ($dao->fetch()) { |
623 | $otherGroupIDs[] = $dao->group_id; | |
624 | } | |
625 | ||
626 | if (!empty($otherGroupIDs)) { | |
627 | $otherGroupIDString = implode(',', $otherGroupIDs); | |
628 | ||
629 | $sql = " | |
630 | UPDATE civicrm_group_contact | |
631 | SET contact_id = %1 | |
632 | WHERE contact_id = %2 | |
633 | AND group_id IN ( $otherGroupIDString ) | |
634 | "; | |
635 | CRM_Core_DAO::executeQuery($sql, $params); | |
636 | ||
637 | $sql = " | |
638 | UPDATE civicrm_subscription_history | |
639 | SET contact_id = %1 | |
640 | WHERE contact_id = %2 | |
641 | AND group_id IN ( $otherGroupIDString ) | |
642 | "; | |
643 | CRM_Core_DAO::executeQuery($sql, $params); | |
644 | } | |
645 | ||
646 | $sql = " | |
647 | SELECT cOther.group_id as group_id, | |
648 | cOther.status as group_status | |
649 | FROM civicrm_group_contact cMain | |
650 | INNER JOIN civicrm_group_contact cOther ON cMain.group_id = cOther.group_id | |
651 | WHERE cMain.contact_id = %1 | |
652 | AND cOther.contact_id = %2 | |
653 | "; | |
654 | $dao = CRM_Core_DAO::executeQuery($sql, $params); | |
655 | ||
be2fb01f | 656 | $groupIDs = []; |
6a488035 TO |
657 | while ($dao->fetch()) { |
658 | // only copy it over if it has added status and migrate the history | |
659 | if ($dao->group_status == 'Added') { | |
660 | $groupIDs[] = $dao->group_id; | |
661 | } | |
662 | } | |
663 | ||
664 | if (!empty($groupIDs)) { | |
665 | $groupIDString = implode(',', $groupIDs); | |
666 | ||
667 | $sql = " | |
668 | UPDATE civicrm_group_contact | |
669 | SET status = 'Added' | |
670 | WHERE contact_id = %1 | |
671 | AND group_id IN ( $groupIDString ) | |
672 | "; | |
673 | CRM_Core_DAO::executeQuery($sql, $params); | |
674 | ||
675 | $sql = " | |
676 | UPDATE civicrm_subscription_history | |
677 | SET contact_id = %1 | |
678 | WHERE contact_id = %2 | |
679 | AND group_id IN ( $groupIDString ) | |
680 | "; | |
681 | CRM_Core_DAO::executeQuery($sql, $params); | |
682 | } | |
683 | ||
684 | // delete all the other group contacts | |
685 | $sql = " | |
686 | DELETE | |
687 | FROM civicrm_group_contact | |
688 | WHERE contact_id = %2 | |
689 | "; | |
690 | CRM_Core_DAO::executeQuery($sql, $params); | |
691 | ||
692 | $sql = " | |
693 | DELETE | |
694 | FROM civicrm_subscription_history | |
695 | WHERE contact_id = %2 | |
696 | "; | |
697 | CRM_Core_DAO::executeQuery($sql, $params); | |
698 | } | |
699 | ||
700 | /** | |
701 | * Given an array of contact ids, add all the contacts to the group | |
702 | * | |
77c5b619 TO |
703 | * @param array $contactIDs |
704 | * The array of contact ids to be added. | |
705 | * @param int $groupID | |
706 | * The id of the group. | |
2a6da8d7 EM |
707 | * @param string $method |
708 | * @param string $status | |
e97c66ff | 709 | * @param string $tracking |
6a488035 | 710 | * |
a6c01b45 CW |
711 | * @return array |
712 | * (total, added, notAdded) count of contacts added to group | |
6a488035 | 713 | */ |
608e6658 | 714 | public static function bulkAddContactsToGroup( |
6a488035 TO |
715 | $contactIDs, |
716 | $groupID, | |
242bd179 TO |
717 | $method = 'Admin', |
718 | $status = 'Added', | |
6a488035 TO |
719 | $tracking = NULL |
720 | ) { | |
721 | ||
722 | $numContactsAdded = 0; | |
723 | $numContactsNotAdded = 0; | |
724 | ||
725 | $contactGroupSQL = " | |
726 | REPLACE INTO civicrm_group_contact ( group_id, contact_id, status ) | |
727 | VALUES | |
728 | "; | |
729 | $subscriptioHistorySQL = " | |
730 | INSERT INTO civicrm_subscription_history( group_id, contact_id, date, method, status, tracking ) | |
731 | VALUES | |
732 | "; | |
733 | ||
734 | $date = date('YmdHis'); | |
735 | ||
736 | // to avoid long strings, lets do BULK_INSERT_HIGH_COUNT values at a time | |
737 | while (!empty($contactIDs)) { | |
738 | $input = array_splice($contactIDs, 0, CRM_Core_DAO::BULK_INSERT_HIGH_COUNT); | |
739 | $contactStr = implode(',', $input); | |
740 | ||
741 | // lets check their current status | |
742 | $sql = " | |
743 | SELECT GROUP_CONCAT(contact_id) as contactStr | |
744 | FROM civicrm_group_contact | |
745 | WHERE group_id = %1 | |
746 | AND status = %2 | |
747 | AND contact_id IN ( $contactStr ) | |
748 | "; | |
be2fb01f CW |
749 | $params = [ |
750 | 1 => [$groupID, 'Integer'], | |
751 | 2 => [$status, 'String'], | |
752 | ]; | |
6a488035 | 753 | |
be2fb01f | 754 | $presentIDs = []; |
6a488035 TO |
755 | $dao = CRM_Core_DAO::executeQuery($sql, $params); |
756 | if ($dao->fetch()) { | |
757 | $presentIDs = explode(',', $dao->contactStr); | |
758 | $presentIDs = array_flip($presentIDs); | |
759 | } | |
760 | ||
be2fb01f | 761 | $gcValues = $shValues = []; |
6a488035 TO |
762 | foreach ($input as $cid) { |
763 | if (isset($presentIDs[$cid])) { | |
764 | $numContactsNotAdded++; | |
765 | continue; | |
766 | } | |
767 | ||
768 | $gcValues[] = "( $groupID, $cid, '$status' )"; | |
769 | $shValues[] = "( $groupID, $cid, '$date', '$method', '$status', '$tracking' )"; | |
770 | $numContactsAdded++; | |
771 | } | |
772 | ||
773 | if (!empty($gcValues)) { | |
774 | $cgSQL = $contactGroupSQL . implode(",\n", $gcValues); | |
775 | CRM_Core_DAO::executeQuery($cgSQL); | |
776 | ||
777 | $shSQL = $subscriptioHistorySQL . implode(",\n", $shValues); | |
778 | CRM_Core_DAO::executeQuery($shSQL); | |
779 | } | |
780 | } | |
781 | ||
be2fb01f | 782 | return [$numContactsAdded, $numContactsNotAdded]; |
6a488035 | 783 | } |
76773c5a CW |
784 | |
785 | /** | |
786 | * Get options for a given field. | |
787 | * @see CRM_Core_DAO::buildOptions | |
788 | * | |
77c5b619 TO |
789 | * @param string $fieldName |
790 | * @param string $context | |
608e6658 | 791 | * @see CRM_Core_DAO::buildOptionsContext |
77c5b619 | 792 | * @param array $props |
16b10e64 | 793 | * whatever is known about this dao object. |
76773c5a | 794 | * |
608e6658 | 795 | * @return array|bool |
76773c5a | 796 | */ |
be2fb01f | 797 | public static function buildOptions($fieldName, $context = NULL, $props = []) { |
76773c5a | 798 | |
887688b9 | 799 | $options = CRM_Core_PseudoConstant::get(__CLASS__, $fieldName, $props, $context); |
76773c5a | 800 | |
76352fbc | 801 | // Sort group list by hierarchy |
802 | // TODO: This will only work when api.entity is "group_contact". What about others? | |
803 | if (($fieldName == 'group' || $fieldName == 'group_id') && ($context == 'search' || $context == 'create')) { | |
804 | $options = CRM_Contact_BAO_Group::getGroupsHierarchy($options, NULL, '- ', TRUE); | |
76773c5a CW |
805 | } |
806 | ||
807 | return $options; | |
808 | } | |
96025800 | 809 | |
6a488035 | 810 | } |