Merge pull request #1382 from swati-karande/CRM-13146
[civicrm-core.git] / api / v3 / Profile.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | CiviCRM version 4.3 |
6 +--------------------------------------------------------------------+
7 | Copyright CiviCRM LLC (c) 2004-2013 |
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
10 | |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public |
21 | License and the CiviCRM Licensing Exception along |
22 | with this program; if not, contact CiviCRM LLC |
23 | at info[AT]civicrm[DOT]org. If you have questions about the |
24 | GNU Affero General Public License or the licensing of CiviCRM, |
25 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
26 +--------------------------------------------------------------------+
27 */
28
29 /**
30 * File for the CiviCRM APIv3 activity profile functions
31 *
32 * @package CiviCRM_APIv3
33 * @subpackage API_ActivityProfile
34 * @copyright CiviCRM LLC (c) 2004-2013
35 * @version $Id: ActivityProfile.php 30486 2011-05-20 16:12:09Z rajan $
36 *
37 */
38
39 /**
40 * Include common API util functions
41 */
42 require_once 'api/v3/utils.php';
43
44 /**
45 * Retrieve Profile field values.
46 *
47 * @param array $params Associative array of property name/value
48 * pairs to get profile field values
49 *
50 * @return Profile field values|CRM_Error
51 *
52 * NOTE this api is not standard & since it is tested we need to honour that
53 * but the correct behaviour is for it to return an id indexed array as this supports
54 * multiple instances
55 */
56 function civicrm_api3_profile_get($params) {
57 $nonStandardLegacyBehaviour = is_numeric($params['profile_id']) ? TRUE : FALSE;
58
59 $profiles = (array) $params['profile_id'];
60 $values = array();
61 foreach ($profiles as $profileID) {
62 $values[$profileID] = array();
63 if (strtolower($profileID) == 'billing') {
64 $values[$profileID] = _civicrm_api3_profile_getbillingpseudoprofile($params);
65 continue;
66 }
67 if(!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'is_active')) {
68 throw new API_Exception('Invalid value for profile_id : ' . $profileID);
69 }
70
71 $isContactActivityProfile = CRM_Core_BAO_UFField::checkContactActivityProfileType($profileID);
72
73 if (CRM_Core_BAO_UFField::checkProfileType($profileID) && !$isContactActivityProfile) {
74 throw new API_Exception('Can not retrieve values for profiles include fields for more than one record type.');
75 }
76
77 $profileFields = CRM_Core_BAO_UFGroup::getFields($profileID,
78 FALSE,
79 NULL,
80 NULL,
81 NULL,
82 FALSE,
83 NULL,
84 TRUE,
85 NULL,
86 CRM_Core_Permission::EDIT
87 );
88
89
90 if ($isContactActivityProfile) {
91 civicrm_api3_verify_mandatory($params, NULL, array('activity_id'));
92
93 $errors = CRM_Profile_Form::validateContactActivityProfile($params['activity_id'],
94 $params['contact_id'],
95 $params['profile_id']
96 );
97 if (!empty($errors)) {
98 throw new API_Exception(array_pop($errors));
99 }
100
101 $contactFields = $activityFields = array();
102 foreach ($profileFields as $fieldName => $field) {
103 if (CRM_Utils_Array::value('field_type', $field) == 'Activity') {
104 $activityFields[$fieldName] = $field;
105 }
106 else {
107 $contactFields[$fieldName] = $field;
108 }
109 }
110
111 CRM_Core_BAO_UFGroup::setProfileDefaults($params['contact_id'], $contactFields, $values[$profileID], TRUE);
112
113 if ($params['activity_id']) {
114 CRM_Core_BAO_UFGroup::setComponentDefaults($activityFields, $params['activity_id'], 'Activity', $values[$profileID], TRUE);
115 }
116 }
117 else {
118 CRM_Core_BAO_UFGroup::setProfileDefaults($params['contact_id'], $profileFields, $values[$profileID], TRUE);
119 }
120 }
121 if($nonStandardLegacyBehaviour) {
122 $result = civicrm_api3_create_success();
123 $result['values'] = $values[$profileID];
124 return $result;
125 }
126 else {
127 return civicrm_api3_create_success($values, $params, 'Profile', 'Get');
128 }
129 }
130
131 function _civicrm_api3_profile_get_spec(&$params) {
132 $params['profile_id']['api.required'] = TRUE;
133 // does this mean we use a different call to get a 'blank' profile?
134 $params['contact_id']['api.required'] = TRUE;
135 }
136 /**
137 * Update Profile field values.
138 *
139 * @param array $params Associative array of property name/value
140 * pairs to update profile field values
141 *
142 * @return Updated Contact/ Activity object|CRM_Error
143 *
144 * @todo add example
145 * @todo add test cases
146 *
147 */
148 function civicrm_api3_profile_set($params) {
149
150 civicrm_api3_verify_mandatory($params, NULL, array('profile_id'));
151
152 if (!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $params['profile_id'], 'is_active')) {
153 throw new API_Exception('Invalid value for profile_id');
154 }
155
156 $isContactActivityProfile = CRM_Core_BAO_UFField::checkContactActivityProfileType($params['profile_id']);
157
158 if (CRM_Core_BAO_UFField::checkProfileType($params['profile_id']) && !$isContactActivityProfile) {
159 throw new API_Exception('Can not retrieve values for profiles include fields for more than one record type.');
160 }
161
162 $contactParams = $activityParams = $missingParams = array();
163
164 $profileFields = CRM_Core_BAO_UFGroup::getFields($params['profile_id'],
165 FALSE,
166 NULL,
167 NULL,
168 NULL,
169 FALSE,
170 NULL,
171 TRUE,
172 NULL,
173 CRM_Core_Permission::EDIT
174 );
175
176 if ($isContactActivityProfile) {
177 civicrm_api3_verify_mandatory($params, NULL, array('activity_id'));
178
179 $errors = CRM_Profile_Form::validateContactActivityProfile($params['activity_id'],
180 $params['contact_id'],
181 $params['profile_id']
182 );
183 if (!empty($errors)) {
184 return civicrm_api3_create_error(array_pop($errors));
185 }
186 }
187
188 foreach ($profileFields as $fieldName => $field) {
189 if (CRM_Utils_Array::value('is_required', $field)) {
190 if (!CRM_Utils_Array::value($fieldName, $params) || empty($params[$fieldName])) {
191 $missingParams[] = $fieldName;
192 }
193 }
194
195 if (!isset($params[$fieldName])) {
196 continue;
197 }
198
199 $value = $params[$fieldName];
200 if ($params[$fieldName] && isset($params[$fieldName . '_id'])) {
201 $value = $params[$fieldName . '_id'];
202 }
203
204 if ($isContactActivityProfile && CRM_Utils_Array::value('field_type', $field) == 'Activity') {
205 $activityParams[$fieldName] = $value;
206 }
207 else {
208 $contactParams[$fieldName] = $value;
209 }
210 }
211
212 if (!empty($missingParams)) {
213 throw new API_Exception("Missing required parameters for profile id {$params['profile_id']}: " . implode(', ', $missingParams));
214 }
215
216 $contactParams['version'] = 3;
217 $contactParams['contact_id'] = CRM_Utils_Array::value('contact_id', $params);
218 $contactParams['profile_id'] = $params['profile_id'];
219 $contactParams['skip_custom'] = 1;
220
221 $contactProfileParams = civicrm_api3_profile_apply($contactParams);
222 if (CRM_Utils_Array::value('is_error', $contactProfileParams)) {
223 return $contactProfileParams;
224 }
225
226 // Contact profile fields
227 $profileParams = $contactProfileParams['values'];
228
229 // If profile having activity fields
230 if ($isContactActivityProfile && !empty($activityParams)) {
231 $activityParams['id'] = $params['activity_id'];
232 $profileParams['api.activity.create'] = $activityParams;
233 }
234
235 $groups = $tags = array();
236 if (isset($profileParams['group'])) {
237 $groups = $profileParams['group'];
238 unset($profileParams['group']);
239 }
240
241 if (isset($profileParams['tag'])) {
242 $tags = $profileParams['tag'];
243 unset($profileParams['tag']);
244 }
245
246 return civicrm_api3('contact', 'create', $profileParams);
247
248 $ufGroupDetails = array();
249 $ufGroupParams = array('id' => $params['profile_id']);
250 CRM_Core_BAO_UFGroup::retrieve($ufGroupParams, $ufGroupDetails);
251
252 if (isset($profileFields['group'])) {
253 CRM_Contact_BAO_GroupContact::create($groups,
254 $params['contact_id'],
255 FALSE,
256 'Admin'
257 );
258 }
259
260 if (isset($profileFields['tag'])) {
261 CRM_Core_BAO_EntityTag::create($tags,
262 'civicrm_contact',
263 $params['contact_id']
264 );
265 }
266
267 if (CRM_Utils_Array::value('add_to_group_id', $ufGroupDetails)) {
268 $contactIds = array($params['contact_id']);
269 CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIds,
270 $ufGroupDetails['add_to_group_id']
271 );
272 }
273
274 return $result;
275 }
276
277 /**
278 * Provide formatted values for profile fields.
279 *
280 * @param array $params Associative array of property name/value
281 * pairs to profile field values
282 *
283 * @return formatted profile field values|CRM_Error
284 *
285 * @todo add example
286 * @todo add test cases
287 *
288 */
289 function civicrm_api3_profile_apply($params) {
290
291 civicrm_api3_verify_mandatory($params, NULL, array('profile_id'));
292
293 if (!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $params['profile_id'], 'is_active')) {
294 return civicrm_api3_create_error('Invalid value for profile_id');
295 }
296
297 $profileFields = CRM_Core_BAO_UFGroup::getFields($params['profile_id'],
298 FALSE,
299 NULL,
300 NULL,
301 NULL,
302 FALSE,
303 NULL,
304 TRUE,
305 NULL,
306 CRM_Core_Permission::EDIT
307 );
308
309 list($data, $contactDetails) = CRM_Contact_BAO_Contact::formatProfileContactParams($params,
310 $profileFields,
311 CRM_Utils_Array::value('contact_id', $params),
312 $params['profile_id'],
313 CRM_Utils_Array::value('contact_type', $params),
314 CRM_Utils_Array::value('skip_custom', $params, FALSE)
315 );
316
317 if (empty($data)) {
318 return civicrm_api3_create_error('Enable to format profile parameters.');
319 }
320
321 return civicrm_api3_create_success($data);
322 }
323
324 /**
325 * Return UFGroup fields
326 */
327 function civicrm_api3_profile_getfields($params) {
328 $dao = _civicrm_api3_get_DAO('UFGroup');
329 $d = new $dao();
330 $fields = $d->fields();
331 return civicrm_api3_create_success($fields);
332 }
333
334 /**
335 * This is a function to help us 'pretend' billing is a profile & treat it like it is one.
336 * It gets standard credit card address fields etc
337 * Note this is 'better' that the inbuilt version as it will pull in fallback values
338 * billing location -> is_billing -> primary
339 */
340 function _civicrm_api3_profile_getbillingpseudoprofile(&$params) {
341 $addressFields = array('street_address', 'city', 'state_province_id', 'country_id');
342 $result = civicrm_api3('contact', 'getsingle', array(
343 'id' => $params['contact_id'],
344 'api.address.getoptions' => array('field' => 'location_type_id',),
345 'api.address.get.1' => array('location_type_id' => 'Billing', 'return' => $addressFields),
346 // getting the is_billing required or not is an extra db call but probably cheap enough as this isn't an import api
347 'api.address.get.2' => array('is_billing' => True, 'return' => $addressFields),
348 'api.email.get.1' => array('location_type_id' => 'Billing',),
349 'api.email.get.2' => array('is_billing' => True,),
350 'return' => 'api.email.get, api.address.get, api.address.getoptions, email, first_name, last_name, middle_name,' . implode($addressFields, ','),
351 )
352 );
353 $locationTypeID = array_search('Billing', $result['api.address.getoptions']['values']);
354
355 $values = array(
356 'billing_first_name' => $result['first_name'],
357 'billing_middle_name' => $result['middle_name'],
358 'billing_last_name' => $result['last_name'],
359 );
360
361 if(!empty($result['api.address.get.1']['count'])) {
362 foreach ($addressFields as $fieldname) {
363 $values['billing_' . $fieldname . '-' . $locationTypeID] = isset($result['api.address.get.1']['values'][0][$fieldname]) ? $result['api.address.get.1']['values'][0][$fieldname] : '';
364 }
365 }
366 elseif(!empty($result['api.address.get.2']['count'])) {
367 foreach ($addressFields as $fieldname) {
368 $values['billing_' . $fieldname . '-' . $locationTypeID] = isset($result['api.address.get.2']['values'][0][$fieldname]) ? $result['api.address.get.2']['values'][0][$fieldname] : '';
369 }
370 }
371 else{
372 foreach ($addressFields as $fieldname) {
373 $values['billing_' . $fieldname . '-' . $locationTypeID] = isset($result[$fieldname]) ? $result[$fieldname] : '';
374 }
375 }
376
377 if(!empty($result['api.email.get.1']['count'])) {
378 $values['billing-email'. '-' . $locationTypeID] = $result['api.email.get.1']['values'][0]['email'];
379 }
380 elseif(!empty($result['api.email.get.2']['count'])) {
381 $values['billing-email'. '-' . $locationTypeID] = $result['api.email.get.2']['values'][0]['email'];
382 }
383 else{
384 $values['billing-email'. '-' . $locationTypeID] = $result['email'];
385 }
386 return $values;
387 }