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