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