Commit | Line | Data |
---|---|---|
5d5d3b35 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
a30c801b | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
5d5d3b35 | 5 | | | |
a30c801b TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
5d5d3b35 TO |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | ||
5d5d3b35 | 12 | /** |
39151786 TO |
13 | * The Cxn API allows a Civi site to initiate a connection to a |
14 | * remote application. There are three primary actions: | |
15 | * | |
16 | * - register: Establish a new connection. | |
17 | * - unregister: Destroy an existing connection. | |
18 | * - get: Get a list of existing connections. | |
19 | */ | |
20 | ||
21 | /** | |
22 | * Adjust metadata for "register" action. | |
23 | * | |
24 | * @param array $spec | |
25 | * List of fields. | |
26 | */ | |
27 | function _civicrm_api3_cxn_register_spec(&$spec) { | |
28 | $daoFields = CRM_Cxn_DAO_Cxn::fields(); | |
29 | $spec['app_guid'] = $daoFields['app_guid']; | |
cf8f0fff | 30 | $spec['app_meta_url'] = [ |
08c79574 TO |
31 | 'name' => 'app_meta_url', |
32 | 'type' => CRM_Utils_Type::T_STRING, | |
33 | 'title' => ts('Application Metadata URL'), | |
34 | 'description' => 'Application Metadata URL', | |
35 | 'maxlength' => 255, | |
36 | 'size' => CRM_Utils_Type::HUGE, | |
cf8f0fff | 37 | ]; |
39151786 TO |
38 | } |
39 | ||
40 | /** | |
41 | * Register with a remote application and create a new connection. | |
42 | * | |
43 | * One should generally identify an application using the app_guid. | |
44 | * However, if you need to test a new/experimental application, then | |
45 | * disable CIVICRM_CXN_CA and specify app_meta_url. | |
46 | * | |
5d5d3b35 TO |
47 | * @param array $params |
48 | * Array with keys: | |
39151786 TO |
49 | * - app_guid: The unique identifer of the target application. |
50 | * - app_meta_url: The URL for the application's metadata. | |
5d5d3b35 | 51 | * @return array |
39151786 | 52 | * @throws Exception |
5d5d3b35 TO |
53 | */ |
54 | function civicrm_api3_cxn_register($params) { | |
39151786 | 55 | if (!empty($params['app_meta_url'])) { |
08c79574 TO |
56 | list ($status, $json) = CRM_Utils_HttpClient::singleton()->get($params['app_meta_url']); |
57 | if (CRM_Utils_HttpClient::STATUS_OK != $status) { | |
58 | throw new API_Exception("Failed to download appMeta. (Bad HTTP response)"); | |
5d5d3b35 | 59 | } |
08c79574 TO |
60 | $appMeta = json_decode($json, TRUE); |
61 | if (empty($appMeta)) { | |
62 | throw new API_Exception("Failed to download appMeta. (Malformed)"); | |
5d5d3b35 TO |
63 | } |
64 | } | |
39151786 | 65 | elseif (!empty($params['app_guid'])) { |
cf8f0fff | 66 | $appMeta = civicrm_api3('CxnApp', 'getsingle', [ |
6fb60f90 | 67 | 'appId' => $params['app_guid'], |
cf8f0fff | 68 | ]); |
39151786 | 69 | } |
5d5d3b35 | 70 | |
39151786 TO |
71 | if (empty($appMeta) || !is_array($appMeta)) { |
72 | throw new API_Exception("Missing expected parameter: app_guid"); | |
5d5d3b35 | 73 | } |
39151786 | 74 | \Civi\Cxn\Rpc\AppMeta::validate($appMeta); |
5d5d3b35 | 75 | |
5d5d3b35 | 76 | try { |
7b4bbb34 | 77 | /** @var \Civi\Cxn\Rpc\RegistrationClient $client */ |
048222df | 78 | $client = \Civi::service('cxn_reg_client'); |
39151786 TO |
79 | list($cxnId, $result) = $client->register($appMeta); |
80 | CRM_Cxn_BAO_Cxn::updateAppMeta($appMeta); | |
5d5d3b35 TO |
81 | } |
82 | catch (Exception $e) { | |
39151786 | 83 | CRM_Cxn_BAO_Cxn::updateAppMeta($appMeta); |
5d5d3b35 TO |
84 | throw $e; |
85 | } | |
86 | ||
0efb07c0 TO |
87 | return $result; |
88 | } | |
89 | ||
70599df6 | 90 | /** |
91 | * Adjust metadata for cxn unregister. | |
92 | * | |
93 | * @param array $spec | |
94 | */ | |
39151786 TO |
95 | function _civicrm_api3_cxn_unregister_spec(&$spec) { |
96 | $daoFields = CRM_Cxn_DAO_Cxn::fields(); | |
97 | $spec['cxn_guid'] = $daoFields['cxn_guid']; | |
98 | $spec['app_guid'] = $daoFields['app_guid']; | |
cf8f0fff | 99 | $spec['force'] = [ |
39151786 TO |
100 | 'name' => 'force', |
101 | 'type' => CRM_Utils_Type::T_BOOLEAN, | |
102 | 'title' => ts('Force'), | |
103 | 'description' => 'Destroy connection even if the remote application is non-responsive.', | |
104 | 'default' => '0', | |
cf8f0fff | 105 | ]; |
39151786 TO |
106 | } |
107 | ||
0efb07c0 | 108 | /** |
39151786 TO |
109 | * Unregister with a remote application; destroy an existing connection. |
110 | * | |
111 | * Specify app_guid XOR cxn_guid. | |
112 | * | |
0efb07c0 TO |
113 | * @param array $params |
114 | * Array with keys: | |
39151786 TO |
115 | * - cxn_guid: string |
116 | * - app_guid: string | |
117 | * - force: bool | |
0efb07c0 TO |
118 | * @return array |
119 | */ | |
120 | function civicrm_api3_cxn_unregister($params) { | |
a8b2e33f TO |
121 | $cxnId = _civicrm_api3_cxn_parseCxnId($params); |
122 | $appMeta = CRM_Cxn_BAO_Cxn::getAppMeta($cxnId); | |
123 | ||
124 | /** @var \Civi\Cxn\Rpc\RegistrationClient $client */ | |
048222df | 125 | $client = \Civi::service('cxn_reg_client'); |
a8b2e33f TO |
126 | list($cxnId, $result) = $client->unregister($appMeta, CRM_Utils_Array::value('force', $params, FALSE)); |
127 | ||
128 | return $result; | |
129 | } | |
130 | ||
131 | /** | |
132 | * @param array $params | |
133 | * An array with cxn_guid and/or app_guid. | |
134 | * @return string | |
135 | * The CxnId. (If not available, then an exception is thrown.) | |
136 | * | |
137 | * @throws API_Exception | |
138 | */ | |
139 | function _civicrm_api3_cxn_parseCxnId($params) { | |
39151786 TO |
140 | $cxnId = NULL; |
141 | ||
142 | if (!empty($params['cxn_guid'])) { | |
143 | $cxnId = $params['cxn_guid']; | |
144 | } | |
145 | elseif (!empty($params['app_guid'])) { | |
cf8f0fff CW |
146 | $cxnId = CRM_Core_DAO::singleValueQuery('SELECT cxn_guid FROM civicrm_cxn WHERE app_guid = %1', [ |
147 | 1 => [$params['app_guid'], 'String'], | |
148 | ]); | |
39151786 TO |
149 | if (!$cxnId) { |
150 | throw new API_Exception("The app_guid does not correspond to an active connection."); | |
151 | } | |
152 | } | |
153 | if (!$cxnId) { | |
154 | throw new API_Exception('Missing required parameter: cxn_guid'); | |
5d5d3b35 | 155 | } |
a8b2e33f | 156 | return $cxnId; |
5d5d3b35 | 157 | } |
39151786 | 158 | |
70599df6 | 159 | /** |
160 | * Adjust metadata for cxn get action. | |
161 | * | |
162 | * @param array $spec | |
163 | */ | |
52079b6d TO |
164 | function _civicrm_api3_cxn_get_spec(&$spec) { |
165 | // Don't trust AJAX callers or other external code to modify, filter, or return the secret. | |
166 | unset($spec['secret']); | |
167 | } | |
168 | ||
39151786 TO |
169 | /** |
170 | * Returns an array of Cxn records. | |
171 | * | |
172 | * @param array $params | |
173 | * Array of one or more valid property_name=>value pairs. | |
174 | * | |
175 | * @return array | |
176 | * API result array. | |
177 | */ | |
178 | function civicrm_api3_cxn_get($params) { | |
52079b6d TO |
179 | // Don't trust AJAX callers or other external code to modify, filter, or return the secret. |
180 | unset($params['secret']); | |
181 | ||
098de400 TO |
182 | $result = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params); |
183 | if (is_array($result['values'])) { | |
184 | foreach (array_keys($result['values']) as $i) { | |
185 | if (!empty($result['values'][$i]['app_meta'])) { | |
186 | $result['values'][$i]['app_meta'] = json_decode($result['values'][$i]['app_meta'], TRUE); | |
187 | } | |
188 | if (!empty($result['values'][$i]['perm'])) { | |
189 | $result['values'][$i]['perm'] = json_decode($result['values'][$i]['perm'], TRUE); | |
190 | } | |
52079b6d TO |
191 | // Don't trust AJAX callers or other external code to modify, filter, or return the secret. |
192 | unset($result['values'][$i]['secret']); | |
098de400 TO |
193 | } |
194 | } | |
52079b6d | 195 | |
098de400 | 196 | return $result; |
39151786 | 197 | } |
a8b2e33f TO |
198 | |
199 | /** | |
200 | * Adjust metadata for "getlink" action. | |
201 | * | |
202 | * @param array $spec | |
203 | * List of fields. | |
204 | */ | |
205 | function _civicrm_api3_cxn_getlink_spec(&$spec) { | |
206 | $daoFields = CRM_Cxn_DAO_Cxn::fields(); | |
207 | $spec['app_guid'] = $daoFields['app_guid']; | |
208 | $spec['cxn_guid'] = $daoFields['cxn_guid']; | |
cf8f0fff | 209 | $spec['page_name'] = [ |
b5552396 | 210 | 'name' => 'page_name', |
a8b2e33f TO |
211 | 'type' => CRM_Utils_Type::T_STRING, |
212 | 'title' => ts('Page Type'), | |
213 | 'description' => 'The type of page (eg "settings")', | |
214 | 'maxlength' => 63, | |
215 | 'size' => CRM_Utils_Type::HUGE, | |
cf8f0fff CW |
216 | 'api.aliases' => ['page'], |
217 | ]; | |
a8b2e33f TO |
218 | } |
219 | ||
220 | /** | |
221 | * | |
222 | * @param array $params | |
223 | * Array with keys: | |
224 | * - cxn_guid OR app_guid: string. | |
225 | * - page: string. | |
226 | * @return array | |
227 | * @throws Exception | |
228 | */ | |
229 | function civicrm_api3_cxn_getlink($params) { | |
230 | $cxnId = _civicrm_api3_cxn_parseCxnId($params); | |
231 | $appMeta = CRM_Cxn_BAO_Cxn::getAppMeta($cxnId); | |
232 | ||
b5552396 | 233 | if (empty($params['page_name']) || !is_string($params['page_name'])) { |
a8b2e33f TO |
234 | throw new API_Exception("Invalid page"); |
235 | } | |
236 | ||
237 | /** @var \Civi\Cxn\Rpc\RegistrationClient $client */ | |
048222df | 238 | $client = \Civi::service('cxn_reg_client'); |
cf8f0fff | 239 | return $client->call($appMeta, 'Cxn', 'getlink', [ |
b5552396 | 240 | 'page' => $params['page_name'], |
cf8f0fff | 241 | ]); |
a8b2e33f | 242 | } |
0b5469cd C |
243 | |
244 | /** | |
245 | * | |
246 | * @param array $params | |
247 | * @return array | |
248 | * @throws Exception | |
249 | */ | |
250 | function civicrm_api3_cxn_getcfg($params) { | |
cf8f0fff | 251 | $result = [ |
0b5469cd C |
252 | 'CIVICRM_CXN_CA' => defined('CIVICRM_CXN_CA') ? CIVICRM_CXN_CA : NULL, |
253 | 'CIVICRM_CXN_VIA' => defined('CIVICRM_CXN_VIA') ? CIVICRM_CXN_VIA : NULL, | |
254 | 'CIVICRM_CXN_APPS_URL' => defined('CIVICRM_CXN_APPS_URL') ? CIVICRM_CXN_APPS_URL : NULL, | |
255 | 'siteCallbackUrl' => CRM_Cxn_BAO_Cxn::getSiteCallbackUrl(), | |
cf8f0fff | 256 | ]; |
0b5469cd | 257 | return civicrm_api3_create_success($result); |
0b5469cd | 258 | } |
e3c37dee C |
259 | |
260 | /** | |
261 | * Creates or modifies a Cxn row. | |
262 | * | |
263 | * @param array $params | |
264 | * Array with keys: | |
265 | * - id, cxn_guid OR app_guid: string. | |
266 | * - is_active: boolean. | |
267 | * - options: JSON | |
268 | * @return page | |
269 | * @throws Exception | |
270 | */ | |
271 | function civicrm_api3_cxn_create($params) { | |
272 | $result = ""; | |
273 | ||
274 | try { | |
275 | // get the ID | |
276 | if (!empty($params['id'])) { | |
277 | $cxnId = $params['id']; | |
278 | } | |
279 | else { | |
280 | $cxnId = _civicrm_api3_cxn_parseCxnId($params); | |
281 | } | |
282 | ||
283 | // see if it's sth to update | |
284 | if (isset($params['options']) || isset($params['is_active'])) { | |
285 | ||
286 | $dao = new CRM_Cxn_DAO_Cxn(); | |
287 | $dao->id = $cxnId; | |
288 | ||
289 | if ($dao->find()) { | |
290 | if (isset($params['is_active'])) { | |
291 | $dao->is_active = (int) $params['is_active']; | |
292 | } | |
293 | if (isset($params['options'])) { | |
294 | $dao->options = $params['options']; | |
295 | } | |
296 | ||
297 | $result = $dao->save(); | |
298 | } | |
299 | ||
300 | } | |
301 | return civicrm_api3_create_success($result, $params, 'Cxn', 'create'); | |
302 | ||
303 | } | |
7c31ae57 | 304 | catch (Exception $ex) { |
e3c37dee C |
305 | throw $ex; |
306 | } | |
307 | } |