Commit | Line | Data |
---|---|---|
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 Activity records. |
6a488035 TO |
30 | * |
31 | * @package CiviCRM_APIv3 | |
6a488035 TO |
32 | */ |
33 | ||
34 | ||
35 | /** | |
61fe4988 | 36 | * Creates or updates an Activity. |
6a488035 | 37 | * |
cf470720 | 38 | * @param array $params |
c28e1768 | 39 | * Array per getfields documentation. |
6a488035 | 40 | * |
77b97be7 | 41 | * @throws API_Exception |
a6c01b45 | 42 | * @return array |
00f8641b | 43 | * API result array |
6a488035 TO |
44 | */ |
45 | function civicrm_api3_activity_create($params) { | |
46 | ||
a7488080 | 47 | if (empty($params['id'])) { |
6a488035 TO |
48 | // an update does not require any mandatory parameters |
49 | civicrm_api3_verify_one_mandatory($params, | |
50 | NULL, | |
51 | array( | |
7cdbcb16 TO |
52 | 'activity_name', |
53 | 'activity_type_id', | |
54 | 'activity_label', | |
6a488035 TO |
55 | ) |
56 | ); | |
57 | } | |
58 | ||
6a488035 TO |
59 | // check for various error and required conditions |
60 | // note that almost all the processing in there should be managed by the wrapper layer | |
61 | // & should be removed - needs testing | |
62 | $errors = _civicrm_api3_activity_check_params($params); | |
63 | ||
64 | // this should not be required as should throw exception rather than return errors - | |
65 | //needs testing | |
66 | if (!empty($errors)) { | |
67 | return $errors; | |
68 | } | |
69 | ||
6a488035 | 70 | // processing for custom data |
10114f2d | 71 | $values = $activityArray = array(); |
6a488035 TO |
72 | _civicrm_api3_custom_format_params($params, $values, 'Activity'); |
73 | ||
74 | if (!empty($values['custom'])) { | |
75 | $params['custom'] = $values['custom']; | |
76 | } | |
77 | ||
78 | // this should be set as a default rather than hard coded | |
79 | // needs testing | |
80 | $params['skipRecentView'] = TRUE; | |
81 | ||
82 | // If this is a case activity, see if there is an existing activity | |
83 | // and set it as an old revision. Also retrieve details we'll need. | |
84 | // this handling should all be moved to the BAO layer | |
7cdbcb16 TO |
85 | $case_id = ''; |
86 | $createRevision = FALSE; | |
6a488035 | 87 | $oldActivityValues = array(); |
e96d5fa3 CW |
88 | // Lookup case id if not supplied |
89 | if (!isset($params['case_id']) && !empty($params['id'])) { | |
90 | $params['case_id'] = CRM_Core_DAO::singleValueQuery("SELECT case_id FROM civicrm_case_activity WHERE activity_id = " . (int) $params['id']); | |
91 | } | |
a7488080 | 92 | if (!empty($params['case_id'])) { |
6a488035 | 93 | $case_id = $params['case_id']; |
a7488080 | 94 | if (!empty($params['id'])) { |
6a488035 TO |
95 | $oldActivityParams = array('id' => $params['id']); |
96 | if (!$oldActivityValues) { | |
97 | CRM_Activity_BAO_Activity::retrieve($oldActivityParams, $oldActivityValues); | |
98 | } | |
99 | if (empty($oldActivityValues)) { | |
10114f2d | 100 | throw new API_Exception(ts("Unable to locate existing activity.")); |
6a488035 TO |
101 | } |
102 | else { | |
103 | $activityDAO = new CRM_Activity_DAO_Activity(); | |
104 | $activityDAO->id = $params['id']; | |
105 | $activityDAO->is_current_revision = 0; | |
106 | if (!$activityDAO->save()) { | |
08007144 TO |
107 | if (is_object($activityDAO)) { |
108 | $activityDAO->free(); | |
109 | } | |
10114f2d | 110 | throw new API_Exception(ts("Unable to revision existing case activity.")); |
6a488035 TO |
111 | } |
112 | $createRevision = TRUE; | |
113 | } | |
114 | } | |
115 | } | |
116 | ||
117 | $deleteActivityAssignment = FALSE; | |
118 | if (isset($params['assignee_contact_id'])) { | |
119 | $deleteActivityAssignment = TRUE; | |
120 | } | |
121 | ||
122 | $deleteActivityTarget = FALSE; | |
123 | if (isset($params['target_contact_id'])) { | |
124 | $deleteActivityTarget = TRUE; | |
125 | } | |
126 | ||
127 | // this should all be handled at the BAO layer | |
128 | $params['deleteActivityAssignment'] = CRM_Utils_Array::value('deleteActivityAssignment', $params, $deleteActivityAssignment); | |
129 | $params['deleteActivityTarget'] = CRM_Utils_Array::value('deleteActivityTarget', $params, $deleteActivityTarget); | |
130 | ||
131 | if ($case_id && $createRevision) { | |
132 | // This is very similar to the copy-to-case action. | |
133 | if (!CRM_Utils_Array::crmIsEmptyArray($oldActivityValues['target_contact'])) { | |
134 | $oldActivityValues['targetContactIds'] = implode(',', array_unique($oldActivityValues['target_contact'])); | |
135 | } | |
136 | if (!CRM_Utils_Array::crmIsEmptyArray($oldActivityValues['assignee_contact'])) { | |
137 | $oldActivityValues['assigneeContactIds'] = implode(',', array_unique($oldActivityValues['assignee_contact'])); | |
138 | } | |
139 | $oldActivityValues['mode'] = 'copy'; | |
140 | $oldActivityValues['caseID'] = $case_id; | |
141 | $oldActivityValues['activityID'] = $oldActivityValues['id']; | |
142 | $oldActivityValues['contactID'] = $oldActivityValues['source_contact_id']; | |
143 | ||
144 | $copyToCase = CRM_Activity_Page_AJAX::_convertToCaseActivity($oldActivityValues); | |
145 | if (empty($copyToCase['error_msg'])) { | |
146 | // now fix some things that are different from copy-to-case | |
147 | // then fall through to the create below to update with the passed in params | |
148 | $params['id'] = $copyToCase['newId']; | |
149 | $params['is_auto'] = 0; | |
150 | $params['original_id'] = empty($oldActivityValues['original_id']) ? $oldActivityValues['id'] : $oldActivityValues['original_id']; | |
151 | } | |
152 | else { | |
10114f2d | 153 | throw new API_Exception(ts("Unable to create new revision of case activity.")); |
6a488035 TO |
154 | } |
155 | } | |
156 | ||
157 | // create activity | |
158 | $activityBAO = CRM_Activity_BAO_Activity::create($params); | |
159 | ||
160 | if (isset($activityBAO->id)) { | |
161 | if ($case_id && !$createRevision) { | |
162 | // If this is a brand new case activity we need to add this | |
163 | $caseActivityParams = array('activity_id' => $activityBAO->id, 'case_id' => $case_id); | |
164 | CRM_Case_BAO_Case::processCaseActivity($caseActivityParams); | |
165 | } | |
166 | ||
167 | _civicrm_api3_object_to_array($activityBAO, $activityArray[$activityBAO->id]); | |
244bbdd8 | 168 | return civicrm_api3_create_success($activityArray, $params, 'Activity', 'get', $activityBAO); |
6a488035 TO |
169 | } |
170 | } | |
11e09c59 TO |
171 | |
172 | /** | |
61fe4988 EM |
173 | * Specify Meta data for create. |
174 | * | |
175 | * Note that this data is retrievable via the getfields function and is used for pre-filling defaults and | |
176 | * ensuring mandatory requirements are met. | |
177 | * | |
cf470720 | 178 | * @param array $params |
c28e1768 | 179 | * Array of parameters determined by getfields. |
6a488035 TO |
180 | */ |
181 | function _civicrm_api3_activity_create_spec(&$params) { | |
182 | ||
61fe4988 | 183 | // Default for source_contact_id = currently logged in user. |
6a488035 TO |
184 | $params['source_contact_id']['api.default'] = 'user_contact_id'; |
185 | ||
67744c4e CW |
186 | $params['status_id']['api.aliases'] = array('activity_status'); |
187 | ||
6a488035 TO |
188 | $params['assignee_contact_id'] = array( |
189 | 'name' => 'assignee_id', | |
0a24dc9a CW |
190 | 'title' => 'Activity Assignee', |
191 | 'description' => 'Contact(s) assigned to this activity.', | |
6a488035 | 192 | 'type' => 1, |
7e61908b | 193 | 'FKClassName' => 'CRM_Contact_DAO_Contact', |
0a24dc9a | 194 | 'FKApiName' => 'Contact', |
6a488035 TO |
195 | ); |
196 | $params['target_contact_id'] = array( | |
197 | 'name' => 'target_id', | |
198 | 'title' => 'Activity Target', | |
0a24dc9a | 199 | 'description' => 'Contact(s) participating in this activity.', |
6a488035 | 200 | 'type' => 1, |
7e61908b | 201 | 'FKClassName' => 'CRM_Contact_DAO_Contact', |
0a24dc9a | 202 | 'FKApiName' => 'Contact', |
6a488035 | 203 | ); |
2f3d72cf | 204 | |
205 | $params['source_contact_id'] = array( | |
7cdbcb16 TO |
206 | 'name' => 'source_contact_id', |
207 | 'title' => 'Activity Source Contact', | |
0a24dc9a | 208 | 'description' => 'Person who created this activity. Defaults to current user.', |
7cdbcb16 | 209 | 'type' => 1, |
7e61908b | 210 | 'FKClassName' => 'CRM_Contact_DAO_Contact', |
7cdbcb16 | 211 | 'api.default' => 'user_contact_id', |
0a24dc9a CW |
212 | 'FKApiName' => 'Contact', |
213 | ); | |
214 | ||
215 | $params['case_id'] = array( | |
216 | 'name' => 'case_id', | |
217 | 'title' => 'Case ID', | |
218 | 'description' => 'For creating an activity as part of a case.', | |
219 | 'type' => 1, | |
220 | 'FKClassName' => 'CRM_Case_DAO_Case', | |
221 | 'FKApiName' => 'Case', | |
2f3d72cf | 222 | ); |
223 | ||
6a488035 TO |
224 | } |
225 | ||
1196e086 CW |
226 | /** |
227 | * Specify Metadata for get. | |
228 | * | |
229 | * @param array $params | |
230 | */ | |
231 | function _civicrm_api3_activity_get_spec(&$params) { | |
232 | $params['tag_id'] = array( | |
1196e086 CW |
233 | 'title' => 'Tags', |
234 | 'description' => 'Find activities with specified tags.', | |
235 | 'type' => 1, | |
236 | 'FKClassName' => 'CRM_Core_DAO_Tag', | |
237 | 'FKApiName' => 'Tag', | |
238 | ); | |
239 | $params['case_id'] = array( | |
1196e086 CW |
240 | 'title' => 'Cases', |
241 | 'description' => 'Find activities within specified cases.', | |
242 | 'type' => 1, | |
243 | 'FKClassName' => 'CRM_Case_DAO_Case', | |
244 | 'FKApiName' => 'Case', | |
245 | ); | |
526e0834 CW |
246 | $params['contact_id'] = array( |
247 | 'title' => 'Activity Contact ID', | |
248 | 'description' => 'Find activities involving this contact (as target, source, OR assignee).', | |
249 | 'type' => 1, | |
250 | 'FKClassName' => 'CRM_Contact_DAO_Contact', | |
251 | 'FKApiName' => 'Contact', | |
252 | ); | |
1196e086 | 253 | $params['target_contact_id'] = array( |
1196e086 CW |
254 | 'title' => 'Target Contact ID', |
255 | 'description' => 'Find activities with specified target contact.', | |
256 | 'type' => 1, | |
257 | 'FKClassName' => 'CRM_Contact_DAO_Contact', | |
258 | 'FKApiName' => 'Contact', | |
259 | ); | |
260 | $params['source_contact_id'] = array( | |
1196e086 CW |
261 | 'title' => 'Source Contact ID', |
262 | 'description' => 'Find activities with specified source contact.', | |
263 | 'type' => 1, | |
264 | 'FKClassName' => 'CRM_Contact_DAO_Contact', | |
265 | 'FKApiName' => 'Contact', | |
266 | ); | |
267 | $params['assignee_contact_id'] = array( | |
1196e086 CW |
268 | 'title' => 'Assignee Contact ID', |
269 | 'description' => 'Find activities with specified assignee contact.', | |
270 | 'type' => 1, | |
271 | 'FKClassName' => 'CRM_Contact_DAO_Contact', | |
272 | 'FKApiName' => 'Contact', | |
273 | ); | |
274 | } | |
275 | ||
6a488035 | 276 | /** |
61fe4988 | 277 | * Gets a CiviCRM activity according to parameters. |
6a488035 | 278 | * |
cf470720 | 279 | * @param array $params |
61fe4988 | 280 | * Array per getfields documentation. |
6a488035 | 281 | * |
bbd2743b | 282 | * @return array API result array |
00f8641b | 283 | * API result array |
bbd2743b | 284 | * |
285 | * @throws \API_Exception | |
286 | * @throws \CiviCRM_API3_Exception | |
287 | * @throws \Civi\API\Exception\UnauthorizedException | |
6a488035 TO |
288 | */ |
289 | function civicrm_api3_activity_get($params) { | |
bbd2743b | 290 | if (!empty($params['check_permissions']) && !CRM_Core_Permission::check('view all activities')) { |
291 | // In absence of view all activities permission it's possible to see a specific activity by ACL. | |
292 | // Note still allowing view all activities to override ACLs is based on the 'don't change too much | |
293 | // if you are not sure principle' and it could be argued that the ACLs should always be applied. | |
294 | if (empty($params['id']) || !empty($params['contact_id'])) { | |
295 | // We fall back to the original blunt permissions if we don't have an id to check or we are about | |
296 | // to go to the weird place that the legacy 'contact_id' parameter takes us to. | |
297 | throw new \Civi\API\Exception\UnauthorizedException( | |
298 | "Cannot access activities. Required permission: 'view all activities''" | |
299 | ); | |
300 | } | |
301 | ||
302 | if (!CRM_Activity_BAO_Activity::checkPermission($params['id'], CRM_Core_Action::VIEW)) { | |
303 | throw new \Civi\API\Exception\UnauthorizedException( | |
304 | 'You do not have permission to view this activity' | |
305 | ); | |
306 | } | |
307 | } | |
308 | ||
526e0834 CW |
309 | $sql = CRM_Utils_SQL_Select::fragment(); |
310 | // Support search by activity_contact | |
311 | $extraFieldSpecs = array(); | |
312 | _civicrm_api3_activity_create_spec($extraFieldSpecs); | |
313 | $options = civicrm_api3('ActivityContact', 'getoptions', array('field' => 'record_type_id')); | |
314 | $options = $options['values']; | |
315 | $activityContactOptions = array( | |
316 | 'contact_id' => NULL, | |
317 | 'target_contact_id' => array_search('Activity Targets', $options), | |
318 | 'source_contact_id' => array_search('Activity Source', $options), | |
319 | 'assignee_contact_id' => array_search('Activity Assignees', $options), | |
320 | ); | |
321 | foreach ($activityContactOptions as $activityContactName => $activityContactValue) { | |
322 | if (!empty($params[$activityContactName])) { | |
323 | _civicrm_api3_validate_integer($params, $activityContactName, $extraFieldSpecs[$activityContactName], 'Activity'); | |
324 | if (!is_array($params[$activityContactName])) { | |
325 | $params[$activityContactName] = array('=' => $params[$activityContactName]); | |
326 | } | |
327 | $clause = \CRM_Core_DAO::createSQLFilter('contact_id', $params[$activityContactName]); | |
328 | $typeClause = $activityContactValue ? 'record_type_id = #typeId AND ' : ''; | |
329 | $sql->where("a.id IN (SELECT activity_id FROM civicrm_activity_contact WHERE $typeClause !clause)", | |
330 | array('#typeId' => $activityContactValue, '!clause' => $clause) | |
331 | ); | |
6a488035 TO |
332 | } |
333 | } | |
526e0834 CW |
334 | if (!empty($params['tag_id'])) { |
335 | _civicrm_api3_validate_integer($params, 'tag_id', $extraFieldSpecs['tag_id'], 'Activity'); | |
336 | if (!is_array($params['tag_id'])) { | |
337 | $params['tag_id'] = array('=' => $params['tag_id']); | |
1196e086 | 338 | } |
526e0834 CW |
339 | $clause = \CRM_Core_DAO::createSQLFilter('tag_id', $params['tag_id']); |
340 | if ($clause) { | |
341 | $sql->where('a.id IN (SELECT entity_id FROM civicrm_entity_tag WHERE entity_table = "civicrm_activity" AND !clause)', array('!clause' => $clause)); | |
1196e086 | 342 | } |
526e0834 CW |
343 | } |
344 | if (!empty($params['case_id'])) { | |
345 | _civicrm_api3_validate_integer($params, 'case_id', $extraFieldSpecs['case_id'], 'Activity'); | |
346 | if (!is_array($params['case_id'])) { | |
347 | $params['case_id'] = array('=' => $params['case_id']); | |
348 | } | |
349 | $clause = \CRM_Core_DAO::createSQLFilter('case_id', $params['case_id']); | |
350 | if ($clause) { | |
351 | $sql->where('a.id IN (SELECT activity_id FROM civicrm_case_activity WHERE !clause)', array('!clause' => $clause)); | |
0298287b | 352 | } |
6a488035 | 353 | } |
526e0834 | 354 | $activities = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE, 'Activity', $sql); |
244bbdd8 | 355 | $options = _civicrm_api3_get_options_from_params($params, FALSE, 'Activity', 'get'); |
22e263ad | 356 | if ($options['is_count']) { |
244bbdd8 | 357 | return civicrm_api3_create_success($activities, $params, 'Activity', 'get'); |
e2e3c1ce | 358 | } |
6a488035 | 359 | |
ab5fa8f2 TO |
360 | $activities = _civicrm_api3_activity_get_formatResult($params, $activities); |
361 | //legacy custom data get - so previous formatted response is still returned too | |
244bbdd8 | 362 | return civicrm_api3_create_success($activities, $params, 'Activity', 'get'); |
ab5fa8f2 TO |
363 | } |
364 | ||
365 | /** | |
61fe4988 | 366 | * Given a list of activities, append any extra data requested about the activities. |
ab5fa8f2 | 367 | * |
b081365f | 368 | * @note Called by civicrm-core and CiviHR |
ab5fa8f2 | 369 | * |
cf470720 TO |
370 | * @param array $params |
371 | * API request parameters. | |
ab5fa8f2 | 372 | * @param array $activities |
61fe4988 | 373 | * |
a6c01b45 | 374 | * @return array |
72b3a70c | 375 | * new activities list |
ab5fa8f2 TO |
376 | */ |
377 | function _civicrm_api3_activity_get_formatResult($params, $activities) { | |
30db5cbf CW |
378 | if (!$activities) { |
379 | return $activities; | |
380 | } | |
381 | ||
6a488035 TO |
382 | $returns = CRM_Utils_Array::value('return', $params, array()); |
383 | if (!is_array($returns)) { | |
384 | $returns = str_replace(' ', '', $returns); | |
385 | $returns = explode(',', $returns); | |
386 | } | |
387 | $returns = array_fill_keys($returns, 1); | |
388 | ||
389 | foreach ($params as $n => $v) { | |
390 | if (substr($n, 0, 7) == 'return.') { | |
391 | $returnkey = substr($n, 7); | |
392 | $returns[$returnkey] = $v; | |
393 | } | |
394 | } | |
0298287b | 395 | |
2f3d72cf | 396 | $returns['source_contact_id'] = 1; |
db6e8cb4 CW |
397 | if (!empty($returns['target_contact_name'])) { |
398 | $returns['target_contact_id'] = 1; | |
399 | } | |
400 | if (!empty($returns['assignee_contact_name'])) { | |
401 | $returns['assignee_contact_id'] = 1; | |
402 | } | |
403 | ||
6a488035 TO |
404 | foreach ($returns as $n => $v) { |
405 | switch ($n) { | |
406 | case 'assignee_contact_id': | |
407 | foreach ($activities as $key => $activityArray) { | |
db6e8cb4 CW |
408 | $cids = $activities[$key]['assignee_contact_id'] = CRM_Activity_BAO_ActivityAssignment::retrieveAssigneeIdsByActivityId($activityArray['id']); |
409 | if ($cids && !empty($returns['assignee_contact_name'])) { | |
410 | foreach ($cids as $cid) { | |
411 | $activities[$key]['assignee_contact_name'][$cid] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name'); | |
412 | } | |
413 | } | |
6a488035 TO |
414 | } |
415 | break; | |
35671d00 | 416 | |
6a488035 TO |
417 | case 'target_contact_id': |
418 | foreach ($activities as $key => $activityArray) { | |
db6e8cb4 CW |
419 | $cids = $activities[$key]['target_contact_id'] = CRM_Activity_BAO_ActivityTarget::retrieveTargetIdsByActivityId($activityArray['id']); |
420 | if ($cids && !empty($returns['target_contact_name'])) { | |
421 | foreach ($cids as $cid) { | |
422 | $activities[$key]['target_contact_name'][$cid] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name'); | |
423 | } | |
424 | } | |
6a488035 TO |
425 | } |
426 | break; | |
35671d00 | 427 | |
42d30b83 DL |
428 | case 'source_contact_id': |
429 | foreach ($activities as $key => $activityArray) { | |
db6e8cb4 CW |
430 | $cid = $activities[$key]['source_contact_id'] = CRM_Activity_BAO_Activity::getSourceContactID($activityArray['id']); |
431 | if ($cid && !empty($returns['source_contact_name'])) { | |
432 | $activities[$key]['source_contact_name'] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'display_name'); | |
433 | } | |
42d30b83 DL |
434 | } |
435 | break; | |
35671d00 | 436 | |
30db5cbf CW |
437 | case 'tag_id': |
438 | $tags = civicrm_api3('EntityTag', 'get', array( | |
439 | 'entity_table' => 'civicrm_activity', | |
440 | 'entity_id' => array('IN' => array_keys($activities)), | |
441 | 'return' => array('tag_id', 'entity_id'), | |
442 | 'options' => array('limit' => 0), | |
443 | )); | |
444 | foreach ($tags['values'] as $tag) { | |
445 | $activities[$tag['entity_id']]['tag_id'][] = (int) $tag['tag_id']; | |
446 | } | |
447 | break; | |
448 | ||
6a488035 TO |
449 | default: |
450 | if (substr($n, 0, 6) == 'custom') { | |
451 | $returnProperties[$n] = $v; | |
452 | } | |
453 | } | |
454 | } | |
526e0834 CW |
455 | |
456 | // Legacy ouput | |
457 | if (!empty($params['contact_id'])) { | |
458 | $statusOptions = CRM_Activity_BAO_Activity::buildOptions('status_id', 'get'); | |
459 | $typeOptions = CRM_Activity_BAO_Activity::buildOptions('activity_type_id', 'validate'); | |
460 | foreach ($activities as $key => &$activityArray) { | |
461 | if (!empty($activityArray['status_id'])) { | |
462 | $activityArray['status'] = $statusOptions[$activityArray['status_id']]; | |
463 | } | |
464 | if (!empty($activityArray['activity_type_id'])) { | |
465 | $activityArray['activity_name'] = $typeOptions[$activityArray['activity_type_id']]; | |
466 | } | |
467 | } | |
468 | } | |
469 | ||
30db5cbf | 470 | if (!empty($returnProperties) || !empty($params['contact_id'])) { |
6a488035 | 471 | foreach ($activities as $activityId => $values) { |
10114f2d | 472 | //@todo - should possibly load activity type id if not loaded (update with id) |
e9ff5391 | 473 | _civicrm_api3_custom_data_get($activities[$activityId], CRM_Utils_Array::value('check_permissions', $params), 'Activity', $activityId, NULL, CRM_Utils_Array::value('activity_type_id', $values)); |
6a488035 TO |
474 | } |
475 | } | |
ab5fa8f2 | 476 | return $activities; |
6a488035 TO |
477 | } |
478 | ||
2f3d72cf | 479 | |
6a488035 TO |
480 | /** |
481 | * Delete a specified Activity. | |
482 | * | |
cf470720 TO |
483 | * @param array $params |
484 | * Array holding 'id' of activity to be deleted. | |
6a488035 | 485 | * |
10114f2d | 486 | * @throws API_Exception |
6a488035 | 487 | * |
61fe4988 | 488 | * @return array |
00f8641b | 489 | * API result array |
6a488035 TO |
490 | */ |
491 | function civicrm_api3_activity_delete($params) { | |
492 | ||
493 | if (CRM_Activity_BAO_Activity::deleteActivity($params)) { | |
244bbdd8 | 494 | return civicrm_api3_create_success(1, $params, 'Activity', 'delete'); |
6a488035 TO |
495 | } |
496 | else { | |
244bbdd8 | 497 | throw new API_Exception('Could not delete Activity'); |
6a488035 TO |
498 | } |
499 | } | |
500 | ||
501 | /** | |
61fe4988 | 502 | * Check for required params. |
6a488035 | 503 | * |
cf470720 TO |
504 | * @param array $params |
505 | * Associated array of fields. | |
10114f2d EM |
506 | * |
507 | * @throws API_Exception | |
508 | * @throws Exception | |
a6c01b45 | 509 | * @return array |
72b3a70c | 510 | * array with errors |
6a488035 TO |
511 | */ |
512 | function _civicrm_api3_activity_check_params(&$params) { | |
513 | ||
514 | $contactIDFields = array_intersect_key($params, | |
7cdbcb16 TO |
515 | array( |
516 | 'source_contact_id' => 1, | |
517 | 'assignee_contact_id' => 1, | |
518 | 'target_contact_id' => 1, | |
519 | ) | |
6a488035 | 520 | ); |
42d30b83 DL |
521 | |
522 | // this should be handled by wrapper layer & probably the api would already manage it | |
523 | //correctly by doing post validation - ie. a failure should result in a roll-back = an error | |
524 | // needs testing | |
6a488035 TO |
525 | if (!empty($contactIDFields)) { |
526 | $contactIds = array(); | |
527 | foreach ($contactIDFields as $fieldname => $contactfield) { | |
528 | if (empty($contactfield)) { | |
529 | continue; | |
530 | } | |
531 | if (is_array($contactfield)) { | |
532 | foreach ($contactfield as $contactkey => $contactvalue) { | |
533 | $contactIds[$contactvalue] = $contactvalue; | |
534 | } | |
535 | } | |
536 | else { | |
537 | $contactIds[$contactfield] = $contactfield; | |
538 | } | |
539 | } | |
540 | ||
6a488035 TO |
541 | $sql = ' |
542 | SELECT count(*) | |
543 | FROM civicrm_contact | |
544 | WHERE id IN (' . implode(', ', $contactIds) . ' )'; | |
545 | if (count($contactIds) != CRM_Core_DAO::singleValueQuery($sql)) { | |
61fe4988 | 546 | throw new API_Exception('Invalid Contact Id'); |
6a488035 TO |
547 | } |
548 | } | |
549 | ||
35671d00 | 550 | $activityIds = array( |
7cdbcb16 TO |
551 | 'activity' => CRM_Utils_Array::value('id', $params), |
552 | 'parent' => CRM_Utils_Array::value('parent_id', $params), | |
553 | 'original' => CRM_Utils_Array::value('original_id', $params), | |
6a488035 TO |
554 | ); |
555 | ||
556 | foreach ($activityIds as $id => $value) { | |
557 | if ($value && | |
558 | !CRM_Core_DAO::getFieldValue('CRM_Activity_DAO_Activity', $value, 'id') | |
559 | ) { | |
10114f2d | 560 | throw new API_Exception('Invalid ' . ucfirst($id) . ' Id'); |
6a488035 TO |
561 | } |
562 | } | |
563 | // this should be handled by wrapper layer & probably the api would already manage it | |
564 | //correctly by doing pseudoconstant validation | |
565 | // needs testing | |
a60ed840 | 566 | $activityTypes = CRM_Activity_BAO_Activity::buildOptions('activity_type_id', 'validate'); |
7cdbcb16 TO |
567 | $activityName = CRM_Utils_Array::value('activity_name', $params); |
568 | $activityName = ucfirst($activityName); | |
6a488035 TO |
569 | $activityLabel = CRM_Utils_Array::value('activity_label', $params); |
570 | if ($activityLabel) { | |
a60ed840 | 571 | $activityTypes = CRM_Activity_BAO_Activity::buildOptions('activity_type_id', 'create'); |
6a488035 TO |
572 | } |
573 | ||
574 | $activityTypeId = CRM_Utils_Array::value('activity_type_id', $params); | |
575 | ||
576 | if ($activityName || $activityLabel) { | |
577 | $activityTypeIdInList = array_search(($activityName ? $activityName : $activityLabel), $activityTypes); | |
578 | ||
579 | if (!$activityTypeIdInList) { | |
35671d00 | 580 | $errorString = $activityName ? "Invalid Activity Name : $activityName" : "Invalid Activity Type Label"; |
6a488035 TO |
581 | throw new Exception($errorString); |
582 | } | |
583 | elseif ($activityTypeId && ($activityTypeId != $activityTypeIdInList)) { | |
10114f2d | 584 | throw new API_Exception('Mismatch in Activity'); |
6a488035 TO |
585 | } |
586 | $params['activity_type_id'] = $activityTypeIdInList; | |
587 | } | |
588 | elseif ($activityTypeId && | |
589 | !array_key_exists($activityTypeId, $activityTypes) | |
590 | ) { | |
10114f2d | 591 | throw new API_Exception('Invalid Activity Type ID'); |
6a488035 TO |
592 | } |
593 | ||
6a488035 TO |
594 | // check for activity duration minutes |
595 | // this should be validated @ the wrapper layer not here | |
596 | // needs testing | |
597 | if (isset($params['duration_minutes']) && !is_numeric($params['duration_minutes'])) { | |
10114f2d | 598 | throw new API_Exception('Invalid Activity Duration (in minutes)'); |
6a488035 TO |
599 | } |
600 | ||
6a488035 TO |
601 | //if adding a new activity & date_time not set make it now |
602 | // this should be managed by the wrapper layer & setting ['api.default'] in speces | |
603 | // needs testing | |
8cc574cf | 604 | if (empty($params['id']) && empty($params['activity_date_time'])) { |
6a488035 TO |
605 | $params['activity_date_time'] = CRM_Utils_Date::processDate(date('Y-m-d H:i:s')); |
606 | } | |
607 | ||
608 | return NULL; | |
609 | } | |
610 | ||
dabf9814 | 611 | /** |
61fe4988 EM |
612 | * Get parameters for activity list. |
613 | * | |
7cdbcb16 | 614 | * @see _civicrm_api3_generic_getlist_params |
dabf9814 | 615 | * |
7cdbcb16 TO |
616 | * @param array $request |
617 | * API request. | |
dabf9814 CW |
618 | */ |
619 | function _civicrm_api3_activity_getlist_params(&$request) { | |
7cdbcb16 TO |
620 | $fieldsToReturn = array( |
621 | 'activity_date_time', | |
622 | 'activity_type_id', | |
623 | 'subject', | |
624 | 'source_contact_id', | |
625 | ); | |
dabf9814 CW |
626 | $request['params']['return'] = array_unique(array_merge($fieldsToReturn, $request['extra'])); |
627 | $request['params']['options']['sort'] = 'activity_date_time DESC'; | |
628 | $request['params'] += array( | |
629 | 'is_current_revision' => 1, | |
630 | 'is_deleted' => 0, | |
631 | ); | |
632 | } | |
633 | ||
634 | /** | |
61fe4988 EM |
635 | * Get output for activity list. |
636 | * | |
dabf9814 CW |
637 | * @see _civicrm_api3_generic_getlist_output |
638 | * | |
8c6b335b CW |
639 | * @param array $result |
640 | * @param array $request | |
dabf9814 CW |
641 | * |
642 | * @return array | |
643 | */ | |
644 | function _civicrm_api3_activity_getlist_output($result, $request) { | |
645 | $output = array(); | |
646 | if (!empty($result['values'])) { | |
647 | foreach ($result['values'] as $row) { | |
648 | $data = array( | |
649 | 'id' => $row[$request['id_field']], | |
650 | 'label' => $row[$request['label_field']] ? $row[$request['label_field']] : ts('(no subject)'), | |
7cdbcb16 TO |
651 | 'description' => array( |
652 | CRM_Core_Pseudoconstant::getLabel('CRM_Activity_BAO_Activity', 'activity_type_id', $row['activity_type_id']), | |
653 | ), | |
dabf9814 CW |
654 | ); |
655 | if (!empty($row['activity_date_time'])) { | |
656 | $data['description'][0] .= ': ' . CRM_Utils_Date::customFormat($row['activity_date_time']); | |
657 | } | |
658 | if (!empty($row['source_contact_id'])) { | |
7cdbcb16 TO |
659 | $data['description'][] = ts('By %1', array( |
660 | 1 => CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $row['source_contact_id'], 'display_name'), | |
661 | )); | |
dabf9814 | 662 | } |
8a938c69 CW |
663 | // Add repeating info |
664 | $repeat = CRM_Core_BAO_RecurringEntity::getPositionAndCount($row['id'], 'civicrm_activity'); | |
665 | $data['extra']['is_recur'] = FALSE; | |
666 | if ($repeat) { | |
667 | $data['suffix'] = ts('(%1 of %2)', array(1 => $repeat[0], 2 => $repeat[1])); | |
668 | $data['extra']['is_recur'] = TRUE; | |
669 | } | |
dabf9814 CW |
670 | $output[] = $data; |
671 | } | |
672 | } | |
673 | return $output; | |
674 | } |