Merge pull request #10152 from agh1/crm-20419
[civicrm-core.git] / api / v3 / GroupContact.php
CommitLineData
6a488035 1<?php
6a488035
TO
2/*
3 +--------------------------------------------------------------------+
81621fee 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
1f4ea726 6 | Copyright CiviCRM LLC (c) 2004-2017 |
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 +--------------------------------------------------------------------+
26 */
27
28/**
244bbdd8 29 * This api exposes CiviCRM GroupContact records.
6a488035 30 *
b081365f
CW
31 * This api is for adding/removing contacts from a group,
32 * or fetching a list of groups for a contact.
33 *
34 * Important note: This api does not fetch smart groups for a contact.
244bbdd8 35 * To fetch all contacts in a smart group, use the Contact api
b081365f
CW
36 * passing a contact_id and group_id.
37 *
38 * To create/delete groups, use the group api instead.
6a488035 39 *
b081365f 40 * @package CiviCRM_APIv3
6a488035
TO
41 */
42
6a488035 43/**
244bbdd8 44 * Fetch a list of groups for a contact, or contacts for a group.
22242c87 45 *
244bbdd8
CW
46 * @Note: this only applies to static groups, not smart groups.
47 * To fetch all contacts in a smart group, use the Contact api
48 * passing a contact_id and group_id.
22242c87 49 *
6a488035
TO
50 * If no status mentioned in params, by default 'added' will be used
51 * to fetch the records
52 *
cf470720
TO
53 * @param array $params
54 * Name value pair of contact information.
6a488035 55 *
a6c01b45 56 * @return array
72b3a70c 57 * list of groups, given contact subsribed to
6a488035
TO
58 */
59function civicrm_api3_group_contact_get($params) {
60
61 if (empty($params['contact_id'])) {
62 if (empty($params['status'])) {
63 //default to 'Added'
64 $params['status'] = 'Added';
65 }
66 //ie. id passed in so we have to return something
3d700d00 67 return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
6a488035
TO
68 }
69 $status = CRM_Utils_Array::value('status', $params, 'Added');
70
49fb4e06 71 $groupId = CRM_Utils_Array::value('group_id', $params);
bd1fbcb7 72 $values = CRM_Contact_BAO_GroupContact::getContactGroup($params['contact_id'], $status, NULL, FALSE, TRUE, FALSE, TRUE, $groupId);
244bbdd8 73 return civicrm_api3_create_success($values, $params, 'GroupContact');
6a488035
TO
74}
75
8d47034f
J
76/**
77 * Adjust metadata for Create action.
78 *
79 * @param array $params
80 */
81function _civicrm_api3_group_contact_create_spec(&$params) {
82 $params['contact_id']['api.required'] = 1;
83 $params['group_id']['api.required'] = 1;
84}
85
6a488035 86/**
22242c87
EM
87 * Add contact(s) to group(s).
88 *
b081365f
CW
89 * This api has a legacy/nonstandard signature.
90 * On success, the return array will be structured as follows:
91 * @code
92 * array(
6a488035
TO
93 * "is_error" => 0,
94 * "version" => 3,
95 * "count" => 3,
96 * "values" => array(
97 * "not_added" => integer,
98 * "added" => integer,
99 * "total_count" => integer
100 * )
b081365f
CW
101 * )
102 * @endcode
6a488035 103 *
b081365f
CW
104 * On failure, the return array will be structured as follows:
105 * @code
106 * array(
6a488035
TO
107 * 'is_error' => 1,
108 * 'error_message' = string,
109 * 'error_data' = mixed or undefined
b081365f
CW
110 * )
111 * @endcode
112 *
113 * @param array $params
8d47034f
J
114 * Input parameters:
115 * - "contact_id" (required): First contact to add, or array of Contact IDs
116 * - "group_id" (required): First group to add contact(s) to, or array of Group IDs
117 * - "status" (optional): "Added" (default), "Pending" or "Removed"
118 * Legacy input parameters (will be deprecated):
119 * - "contact_id.1" etc. (optional): Additional contact_id to add to group(s)
120 * - "group_id.1" etc. (optional): Additional groups to add contact(s) to
b081365f
CW
121 *
122 * @return array
123 * Information about operation results
6a488035
TO
124 */
125function civicrm_api3_group_contact_create($params) {
3d700d00
CW
126 // Nonstandard bao - doesn't accept ID as a param, so convert id to group_id + contact_id
127 if (!empty($params['id'])) {
128 $getParams = array('id' => $params['id']);
129 $info = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $getParams);
130 if (!empty($info['values'][$params['id']])) {
131 $params['group_id'] = $info['values'][$params['id']]['group_id'];
132 $params['contact_id'] = $info['values'][$params['id']]['contact_id'];
133 }
134 }
6a488035
TO
135 $action = CRM_Utils_Array::value('status', $params, 'Added');
136 return _civicrm_api3_group_contact_common($params, $action);
137}
11e09c59 138
6a488035 139/**
22242c87 140 * Delete group contact record.
6a488035 141 *
72b3a70c 142 * @param array $params
a6c01b45 143 * @return array
8089541a
SL
144 * @throws API_Exception
145 * @throws CiviCRM_API3_Exception
e0b82b44 146 * @deprecated
6a488035
TO
147 */
148function civicrm_api3_group_contact_delete($params) {
3c64f1f6
SL
149 $checkParams = $params;
150 if (!empty($checkParams['status']) && in_array($checkParams['status'], array('Removed', 'Deleted'))) {
4e5d12a1 151 $checkParams['status'] = array('IN' => array('Added', 'Pending'));
3c64f1f6
SL
152 }
153 elseif (!empty($checkParams['status']) && $checkParams['status'] == 'Added') {
4e5d12a1 154 $checkParams['status'] = array('IN' => array('Pending', 'Removed'));
3c64f1f6
SL
155 }
156 elseif (!empty($checkParams['status'])) {
157 unset($checkParams['status']);
158 }
159 $groupContact = civicrm_api3('GroupContact', 'get', $checkParams);
160 if ($groupContact['count'] == 0 && !empty($params['skip_undelete'])) {
bd9042db 161 $checkParams['status'] = array('IN' => array('Removed', 'Pending'));
3c64f1f6
SL
162 }
163 $groupContact2 = civicrm_api3('GroupContact', 'get', $checkParams);
4e5d12a1 164 if ($groupContact['count'] == 0 && $groupContact2['count'] == 0) {
a60c0bc8
SL
165 throw new API_Exception('Cannot Delete GroupContact');
166 }
3d700d00
CW
167 $params['status'] = CRM_Utils_Array::value('status', $params, empty($params['skip_undelete']) ? 'Removed' : 'Deleted');
168 // "Deleted" isn't a real option so skip the api wrapper to avoid pseudoconstant validation
169 return civicrm_api3_group_contact_create($params);
6a488035 170}
11e09c59
TO
171
172/**
dc64d047
EM
173 * Adjust metadata.
174 *
d0997921 175 * @param array $params
6a488035
TO
176 */
177function _civicrm_api3_group_contact_delete_spec(&$params) {
178 // set as not required no either/or std yet
179 $params['id']['api.required'] = 0;
180}
181
182/**
d1b0d05e 183 * Get pending group contacts.
6a488035 184 *
72b3a70c 185 * @param array $params
6a488035 186 *
72b3a70c 187 * @return array|int
e0b82b44 188 * @deprecated
6a488035
TO
189 */
190function civicrm_api3_group_contact_pending($params) {
191 $params['status'] = 'Pending';
192 return civicrm_api('GroupContact', 'Create', $params);
193}
194
195/**
dc64d047 196 * Group contact helper function.
6a488035 197 *
b081365f
CW
198 * @todo behaviour is highly non-standard - need to figure out how to make this 'behave'
199 * & at the very least return IDs & details of the groups created / changed
200 *
6a488035
TO
201 * @param array $params
202 * @param string $op
203 *
5396af74 204 * @return array
6a488035
TO
205 */
206function _civicrm_api3_group_contact_common($params, $op = 'Added') {
207
208 $contactIDs = array();
209 $groupIDs = array();
8d47034f 210
cc7968d8 211 // CRM-16959: Handle multiple Contact IDs and Group IDs in legacy format
8d47034f 212 // (contact_id.1, contact_id.2) or as an array
6a488035
TO
213 foreach ($params as $n => $v) {
214 if (substr($n, 0, 10) == 'contact_id') {
8d47034f
J
215 if (is_array($v)) {
216 foreach ($v as $arr_v) {
217 $contactIDs[] = $arr_v;
218 }
219 }
220 else {
221 $contactIDs[] = $v;
222 }
6a488035
TO
223 }
224 elseif (substr($n, 0, 8) == 'group_id') {
8d47034f
J
225 if (is_array($v)) {
226 foreach ($v as $arr_v) {
227 $groupIDs[] = $arr_v;
228 }
229 }
230 else {
231 $groupIDs[] = $v;
232 }
6a488035
TO
233 }
234 }
235
6a488035
TO
236 $method = CRM_Utils_Array::value('method', $params, 'API');
237 $status = CRM_Utils_Array::value('status', $params, $op);
238 $tracking = CRM_Utils_Array::value('tracking', $params);
6a488035
TO
239
240 if ($op == 'Added' || $op == 'Pending') {
2241036a 241 $extraReturnValues = array(
6a488035
TO
242 'total_count' => 0,
243 'added' => 0,
21dfd5f5 244 'not_added' => 0,
6a488035
TO
245 );
246 foreach ($groupIDs as $groupID) {
247 list($tc, $a, $na) = CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIDs,
248 $groupID,
249 $method,
250 $status,
251 $tracking
252 );
253 $extraReturnValues['total_count'] += $tc;
254 $extraReturnValues['added'] += $a;
255 $extraReturnValues['not_added'] += $na;
256 }
257 }
258 else {
2241036a 259 $extraReturnValues = array(
6a488035
TO
260 'total_count' => 0,
261 'removed' => 0,
21dfd5f5 262 'not_removed' => 0,
6a488035
TO
263 );
264 foreach ($groupIDs as $groupID) {
265 list($tc, $r, $nr) = CRM_Contact_BAO_GroupContact::removeContactsFromGroup($contactIDs, $groupID, $method, $status, $tracking);
266 $extraReturnValues['total_count'] += $tc;
267 $extraReturnValues['removed'] += $r;
268 $extraReturnValues['not_removed'] += $nr;
269 }
270 }
244bbdd8
CW
271 // can't pass this by reference
272 $dao = NULL;
273 return civicrm_api3_create_success(1, $params, 'GroupContact', 'create', $dao, $extraReturnValues);
6a488035 274}
11e09c59
TO
275
276/**
dc64d047
EM
277 * Update group contact status.
278 *
6a488035 279 * @deprecated - this should be part of create but need to know we aren't missing something
dc64d047 280 *
d0997921 281 * @param array $params
dc64d047 282 *
645ee340
EM
283 * @return bool
284 * @throws \API_Exception
6a488035
TO
285 */
286function civicrm_api3_group_contact_update_status($params) {
287
288 civicrm_api3_verify_mandatory($params, NULL, array('contact_id', 'group_id'));
289
c49a2977
CW
290 CRM_Contact_BAO_GroupContact::addContactsToGroup(
291 array($params['contact_id']),
292 $params['group_id'],
293 CRM_Utils_Array::value('method', $params, 'API'),
294 'Added',
295 CRM_Utils_Array::value('tracking', $params)
296 );
6a488035
TO
297
298 return TRUE;
299}
300
a14e9d08 301/**
dc64d047
EM
302 * Deprecated function notices.
303 *
a14e9d08 304 * @deprecated api notice
a6c01b45 305 * @return array
16b10e64 306 * Array of deprecated actions
a14e9d08
CW
307 */
308function _civicrm_api3_group_contact_deprecation() {
309 return array(
310 'delete' => 'GroupContact "delete" action is deprecated in favor of "create".',
311 'pending' => 'GroupContact "pending" action is deprecated in favor of "create".',
312 'update_status' => 'GroupContact "update_status" action is deprecated in favor of "create".',
313 );
314}