Merge pull request #365 from eileenmcnaughton/4.3
[civicrm-core.git] / api / v3 / Relationship.php
CommitLineData
6a488035
TO
1<?php
2// $Id$
3
4/*
5 +--------------------------------------------------------------------+
6 | CiviCRM version 4.3 |
7 +--------------------------------------------------------------------+
8 | Copyright CiviCRM LLC (c) 2004-2013 |
9 +--------------------------------------------------------------------+
10 | This file is a part of CiviCRM. |
11 | |
12 | CiviCRM is free software; you can copy, modify, and distribute it |
13 | under the terms of the GNU Affero General Public License |
14 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
15 | |
16 | CiviCRM is distributed in the hope that it will be useful, but |
17 | WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
19 | See the GNU Affero General Public License for more details. |
20 | |
21 | You should have received a copy of the GNU Affero General Public |
22 | License and the CiviCRM Licensing Exception along |
23 | with this program; if not, contact CiviCRM LLC |
24 | at info[AT]civicrm[DOT]org. If you have questions about the |
25 | GNU Affero General Public License or the licensing of CiviCRM, |
26 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
27 +--------------------------------------------------------------------+
28*/
29
30/**
31 * File for the CiviCRM APIv3 relationship functions
32 *
33 * @package CiviCRM_APIv3
34 * @subpackage API_Relationship
35 *
36 * @copyright CiviCRM LLC (c) 2004-2013
37 * @version $Id: Relationship.php 30486 2010-11-02 16:12:09Z shot $
38 *
39 */
40
41/**
42 * Add or update a relationship
43 *
44 * @param array $params input parameters
45 *
46 * @example RelationshipCreate.php Std Create example
47 *
48 * @return array API Result Array
49 * {@getfields relationship_create}
50 * @static void
51 * @access public
52 *
53 */
54function civicrm_api3_relationship_create($params) {
55
56 $values = array();
57 _civicrm_api3_relationship_format_params($params, $values);
58 $ids = array();
59 $action = CRM_Core_Action::ADD;
60
61 if (CRM_Utils_Array::value('id', $params)) {
62 $ids['relationship'] = $params['id'];
63 $ids['contactTarget'] = $values['contact_id_b'];
64 $action = CRM_Core_Action::UPDATE;
65 }
66
67 $values['relationship_type_id'] = $values['relationship_type_id'] . '_a_b';
68 $values['contact_check'] = array($params['contact_id_b'] => $params['contact_id_b']);
69 $ids['contact'] = $values['contact_id_a'];
70 $relationshipBAO = CRM_Contact_BAO_Relationship::create($values, $ids);
71
72 if ($relationshipBAO[1]) {
73 return civicrm_api3_create_error('Relationship is not valid');
74 }
75 elseif ($relationshipBAO[2]) {
76 return civicrm_api3_create_error('Relationship already exists');
77 }
78 CRM_Contact_BAO_Relationship::relatedMemberships($params['contact_id_a'], $values, $ids, $action);
79 $relationID = $relationshipBAO[4][0];
80 return civicrm_api3_create_success(array(
81 $relationID => array('id' => $relationID,
82 'moreIDs' => implode(',', $relationshipBAO[4]),
83 )));
84}
11e09c59
TO
85
86/**
6a488035
TO
87 * Adjust Metadata for Create action
88 *
89 * @param array $params array or parameters determined by getfields
90 */
91function _civicrm_api3_relationship_create_spec(&$params) {
92 $params['contact_id_a']['api.required'] = 1;
93 $params['contact_id_b']['api.required'] = 1;
94 $params['relationship_type_id']['api.required'] = 1;
95 $params['is_active']['api.default'] = 1;
96}
97
98/**
99 * Delete a relationship
100 *
101 * @param array $params
102 *
103 * @return array API Result Array
104 * {@getfields relationship_delete}
105 * @example RelationshipDelete.php Delete Example
106 *
107 * @static void
108 * @access public
109 */
110function civicrm_api3_relationship_delete($params) {
111
112 require_once 'CRM/Utils/Rule.php';
113 if (!CRM_Utils_Rule::integer($params['id'])) {
114 return civicrm_api3_create_error('Invalid value for relationship ID');
115 }
116
117 $relationBAO = new CRM_Contact_BAO_Relationship();
118 $relationBAO->id = $params['id'];
119 if (!$relationBAO->find(TRUE)) {
120 return civicrm_api3_create_error('Relationship id is not valid');
121 }
122 else {
123 $relationBAO->del($params['id']);
124 return civicrm_api3_create_success('Deleted relationship successfully');
125 }
126}
127
128/**
129 * Function to get the relationship
130 *
131 * @param array $params input parameters.
132 * @todo Result is inconsistent depending on whether contact_id is passed in :
133 * - if you pass in contact_id - it just returns all relationships for 'contact_id'
134 * - if you don't pass in contact_id then it does a filter on the relationship table (DAO based search)
135 *
136 * @return Array API Result Array
137 * {@getfields relationship_get}
138 * @example RelationshipGet.php
139 * @access public
140 */
141function civicrm_api3_relationship_get($params) {
142
143 if (!CRM_Utils_Array::value('contact_id', $params)) {
144 $relationships = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE);
145 }
146 else {
147 $relationships = array();
148 $relationships = CRM_Contact_BAO_Relationship::getRelationship($params['contact_id'],
149 CRM_Utils_Array::value('status_id', $params),
150 0,
151 0,
152 CRM_Utils_Array::value('id', $params), NULL
153 );
154 }
155 foreach ($relationships as $relationshipId => $values) {
156 _civicrm_api3_custom_data_get($relationships[$relationshipId], 'Relationship', $relationshipId, NULL, CRM_Utils_Array::value('relationship_type_id',$values));
157 }
158
159
160 return civicrm_api3_create_success($relationships, $params);
161}
162
163/**
164 * take the input parameter list as specified in the data model and
165 * convert it into the same format that we use in QF and BAO object
166 *
167 * @param array $params Associative array of property name/value
168 * pairs to insert in new contact.
169 * @param array $values The reformatted properties that we can use internally
170 * '
171 *
172 * @return array|CRM_Error
173 * @access public
174 */
175function _civicrm_api3_relationship_format_params($params, &$values) {
176 // copy all the relationship fields as is
177
178 $fields = CRM_Contact_DAO_Relationship::fields();
179 _civicrm_api3_store_values($fields, $params, $values);
180
181 $relationTypes = CRM_Core_PseudoConstant::relationshipType('name');
182 if (CRM_Utils_Array::value('id', $params)) {
183 $relation = new CRM_Contact_BAO_Relationship();
184 $relation->id = $params['id'];
185 if (!$relation->find(TRUE)) {
186 throw new Exception('Relationship id is not valid');
187 }
188 else {
189 if ((isset($params['contact_id_a']) && $params['contact_id_a'] != $relation->contact_id_a) ||
190 (isset($params['contact_id_b']) && $params['contact_id_b'] != $relation->contact_id_b)
191 ) {
192 throw new Exception('Cannot change the contacts once relationship has been created');
193 }
194 else {
195 // since the BAO function is not std & won't accept just 'id' (aargh) let's
196 // at least return our BAO here
197 $values = array();
198 _civicrm_api3_object_to_array($relation, $values);
199 $values = array_merge($values, $params);
200 // and we need to reformat our date fields....
201 $dateFields = array('start_date', 'end_date');
202 foreach ($dateFields as $dateField){
203 $values[$dateField] = CRM_Utils_Date::processDate($values[$dateField]);
204 }
205 }
206 }
207 }
208
209 foreach ($params as $key => $value) {
210 // ignore empty values or empty arrays etc
211 require_once 'CRM/Utils/System.php';
212 if (CRM_Utils_System::isNull($value)) {
213 continue;
214 }
215
216 switch ($key) {
217 case 'contact_id_a':
218 case 'contact_id_b':
219 require_once 'CRM/Utils/Rule.php';
220 if (!CRM_Utils_Rule::integer($value)) {
221 throw new Exception("contact_id not valid: $value");
222 }
223 $dao = new CRM_Core_DAO();
224 $qParams = array();
225 $svq = $dao->singleValueQuery("SELECT id FROM civicrm_contact WHERE id = $value",
226 $qParams
227 );
228 if (!$svq) {
229 throw new Exception("Invalid Contact ID: There is no contact record with contact_id = $value.");
230 }
231 break;
232
233 case 'relationship_type':
234 foreach ($relationTypes as $relTypId => $relValue) {
235 if (CRM_Utils_Array::key(ucfirst($value), $relValue)) {
236 $relationshipTypeId = $relTypId;
237 break;
238 }
239 }
240
241 if ($relationshipTypeId) {
242 if (CRM_Utils_Array::value('relationship_type_id', $values) &&
243 $relationshipTypeId != $values['relationship_type_id']
244 ) {
245 throw new Exception('Mismatched Relationship Type and Relationship Type Id');
246 }
247 $values['relationship_type_id'] = $params['relationship_type_id'] = $relationshipTypeId;
248 }
249 else {
250 throw new Exception('Invalid Relationship Type');
251 }
252 case 'relationship_type_id':
253 if ($key == 'relationship_type_id' && !array_key_exists($value, $relationTypes)) {
254 throw new Exception("$key not a valid: $value");
255 }
256
257 // execute for both relationship_type and relationship_type_id
258 $relation = $relationTypes[$params['relationship_type_id']];
259 if (!empty($params['contact_id_a']) && $relation['contact_type_a'] &&
260 $relation['contact_type_a'] != CRM_Contact_BAO_Contact::getContactType($params['contact_id_a'])
261 ) {
262 throw new Exception("Contact ID :{$params['contact_id_a']} is not of contact type {$relation['contact_type_a']}");
263 }
264 if (!empty($params['contact_id_b']) && $relation['contact_type_b'] &&
265 $relation['contact_type_b'] != CRM_Contact_BAO_Contact::getContactType($params['contact_id_b'])
266 ) {
267 throw new Exception("Contact ID :{$params['contact_id_b']} is not of contact type {$relation['contact_type_b']}");
268 }
269 break;
270
271 default:
272 break;
273 }
274 }
275
276 if (array_key_exists('note', $params)) {
277 $values['note'] = $params['note'];
278 }
279 _civicrm_api3_custom_format_params($params, $values, 'Relationship');
280
281 return array();
282}