Merge pull request #14162 from civicrm/5.13
[civicrm-core.git] / CRM / Contact / Page / AJAX.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
6b83d5bd 31 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
32 *
33 */
34
35/**
36 * This class contains all contact related functions that are called using AJAX (jQuery)
37 */
38class CRM_Contact_Page_AJAX {
272081ca
TO
39 /**
40 * When a user chooses a username, CHECK_USERNAME_TTL
41 * is the time window in which they can check usernames
42 * (without reloading the overall form).
43 */
69078420
SL
44 // 3hr; 3*60*60
45 const CHECK_USERNAME_TTL = 10800;
272081ca 46
69078420
SL
47 // 6hr; 6*60*60
48 const AUTOCOMPLETE_TTL = 21600;
b1dba111 49
06508628 50 /**
06508628
CW
51 * Ajax callback for custom fields of type ContactReference
52 *
53 * Todo: Migrate contact reference fields to use EntityRef
54 */
00be9182 55 public static function contactReference() {
06508628 56 $name = CRM_Utils_Array::value('term', $_GET);
6a488035
TO
57 $name = CRM_Utils_Type::escape($name, 'String');
58 $cfID = CRM_Utils_Type::escape($_GET['id'], 'Positive');
59
60 // check that this is a valid, active custom field of Contact Reference type
be2fb01f
CW
61 $params = ['id' => $cfID];
62 $returnProperties = ['filter', 'data_type', 'is_active'];
63 $cf = [];
6a488035 64 CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_CustomField', $params, $cf, $returnProperties);
a4cce21a 65 if (!$cf['id'] || !$cf['is_active'] || $cf['data_type'] != 'ContactReference') {
d8cdb7e5 66 CRM_Utils_System::civiExit(1);
6a488035
TO
67 }
68
9624538c 69 if (!empty($cf['filter'])) {
be2fb01f 70 $filterParams = [];
6a488035
TO
71 parse_str($cf['filter'], $filterParams);
72
73 $action = CRM_Utils_Array::value('action', $filterParams);
be2fb01f 74 if (!empty($action) && !in_array($action, ['get', 'lookup'])) {
d8cdb7e5 75 CRM_Utils_System::civiExit(1);
6a488035 76 }
da0136df 77
78 if (!empty($filterParams['group'])) {
79 $filterParams['group'] = explode(',', $filterParams['group']);
80 }
6a488035
TO
81 }
82
83 $list = array_keys(CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
353ffa53
TO
84 'contact_reference_options'
85 ), '1');
6a488035 86
be2fb01f 87 $return = array_unique(array_merge(['sort_name'], $list));
6a488035 88
89595c92 89 $limit = Civi::settings()->get('search_autocomplete_count');
6a488035 90
be2fb01f 91 $params = ['offset' => 0, 'rowCount' => $limit, 'version' => 3];
6a488035
TO
92 foreach ($return as $fld) {
93 $params["return.{$fld}"] = 1;
94 }
95
96 if (!empty($action)) {
be2fb01f 97 $excludeGet = [
353ffa53
TO
98 'reset',
99 'key',
100 'className',
101 'fnName',
102 'json',
103 'reset',
104 'context',
105 'timestamp',
106 'limit',
107 'id',
108 's',
109 'q',
408b79bf 110 'action',
be2fb01f 111 ];
6a488035
TO
112 foreach ($_GET as $param => $val) {
113 if (empty($val) ||
114 in_array($param, $excludeGet) ||
115 strpos($param, 'return.') !== FALSE ||
116 strpos($param, 'api.') !== FALSE
117 ) {
118 continue;
119 }
120 $params[$param] = $val;
121 }
122 }
123
124 if ($name) {
125 $params['sort_name'] = $name;
126 }
127
128 $params['sort'] = 'sort_name';
129
130 // tell api to skip permission chk. dgg
131 $params['check_permissions'] = 0;
132
133 // add filter variable to params
134 if (!empty($filterParams)) {
135 $params = array_merge($params, $filterParams);
136 }
137
138 $contact = civicrm_api('Contact', 'Get', $params);
139
a7488080 140 if (!empty($contact['is_error'])) {
d8cdb7e5 141 CRM_Utils_System::civiExit(1);
6a488035
TO
142 }
143
be2fb01f 144 $contactList = [];
6a488035 145 foreach ($contact['values'] as $value) {
be2fb01f 146 $view = [];
6a488035 147 foreach ($return as $fld) {
a7488080 148 if (!empty($value[$fld])) {
6a488035
TO
149 $view[] = $value[$fld];
150 }
151 }
be2fb01f 152 $contactList[] = ['id' => $value['id'], 'text' => implode(' :: ', $view)];
6a488035
TO
153 }
154
da0136df 155 if (!empty($_GET['is_unit_test'])) {
156 return $contactList;
157 }
8be1a839 158 CRM_Utils_JSON::output($contactList);
6a488035
TO
159 }
160
161 /**
100fef9d 162 * Fetch PCP ID by PCP Supporter sort_name, also displays PCP title and associated Contribution Page title
6a488035 163 */
00be9182 164 public static function getPCPList() {
7d86179d 165 $name = CRM_Utils_Array::value('term', $_GET);
353ffa53 166 $name = CRM_Utils_Type::escape($name, 'String');
89595c92 167 $limit = $max = Civi::settings()->get('search_autocomplete_count');
6a488035
TO
168
169 $where = ' AND pcp.page_id = cp.id AND pcp.contact_id = cc.id';
170
171 $config = CRM_Core_Config::singleton();
172 if ($config->includeWildCardInName) {
173 $strSearch = "%$name%";
174 }
175 else {
176 $strSearch = "$name%";
177 }
178 $includeEmailFrom = $includeNickName = '';
179 if ($config->includeNickNameInName) {
180 $includeNickName = " OR nick_name LIKE '$strSearch'";
181 }
182 if ($config->includeEmailInName) {
183 $includeEmailFrom = "LEFT JOIN civicrm_email eml ON ( cc.id = eml.contact_id AND eml.is_primary = 1 )";
184 $whereClause = " WHERE ( email LIKE '$strSearch' OR sort_name LIKE '$strSearch' $includeNickName ) {$where} ";
185 }
186 else {
187 $whereClause = " WHERE ( sort_name LIKE '$strSearch' $includeNickName ) {$where} ";
188 }
189
8da35492 190 $offset = $count = 0;
4feb1cad
CW
191 if (!empty($_GET['page_num'])) {
192 $page = (int) $_GET['page_num'];
8da35492
CW
193 $offset = $limit * ($page - 1);
194 $limit++;
6a488035
TO
195 }
196
197 $select = 'cc.sort_name, pcp.title, cp.title';
198 $query = "
199 SELECT id, data
200 FROM (
201 SELECT pcp.id as id, CONCAT_WS( ' :: ', {$select} ) as data, sort_name
202 FROM civicrm_pcp pcp, civicrm_contribution_page cp, civicrm_contact cc
203 {$includeEmailFrom}
900e6829 204 {$whereClause} AND pcp.page_type = 'contribute'
205 UNION ALL
206 SELECT pcp.id as id, CONCAT_WS( ' :: ', {$select} ) as data, sort_name
207 FROM civicrm_pcp pcp, civicrm_event cp, civicrm_contact cc
208 {$includeEmailFrom}
209 {$whereClause} AND pcp.page_type = 'event'
6a488035
TO
210 ) t
211 ORDER BY sort_name
8da35492 212 LIMIT $offset, $limit
6a488035
TO
213 ";
214
215 $dao = CRM_Core_DAO::executeQuery($query);
be2fb01f 216 $output = ['results' => [], 'more' => FALSE];
6a488035 217 while ($dao->fetch()) {
8da35492
CW
218 if (++$count > $max) {
219 $output['more'] = TRUE;
220 }
221 else {
be2fb01f 222 $output['results'][] = ['id' => $dao->id, 'text' => $dao->data];
8da35492 223 }
6a488035 224 }
8da35492 225 CRM_Utils_JSON::output($output);
6a488035
TO
226 }
227
00be9182 228 public static function relationship() {
3b1c37fe 229 $relType = CRM_Utils_Request::retrieve('rel_type', 'String', CRM_Core_DAO::$_nullObject, TRUE);
c91df8b4 230 $relContactID = CRM_Utils_Request::retrieve('rel_contact', 'Positive', CRM_Core_DAO::$_nullObject, TRUE);
a3d827a7
CW
231 $originalCid = CRM_Utils_Request::retrieve('cid', 'Positive');
232 $relationshipID = CRM_Utils_Request::retrieve('rel_id', 'Positive');
c91df8b4 233 $caseID = CRM_Utils_Request::retrieve('case_id', 'Positive', CRM_Core_DAO::$_nullObject, TRUE);
6a488035 234
3b1c37fe
CW
235 if (!CRM_Case_BAO_Case::accessCase($caseID)) {
236 CRM_Utils_System::permissionDenied();
237 }
6a488035 238
be2fb01f 239 $ret = ['is_error' => 0];
c91df8b4 240
3b1c37fe 241 list($relTypeId, $b, $a) = explode('_', $relType);
14a679f1 242
3b1c37fe
CW
243 if ($relationshipID && $originalCid) {
244 CRM_Case_BAO_Case::endCaseRole($caseID, $a, $originalCid, $relTypeId);
245 }
14a679f1 246
3b1c37fe 247 $clientList = CRM_Case_BAO_Case::getCaseClients($caseID);
14a679f1 248
3b1c37fe
CW
249 // Loop through multiple case clients
250 foreach ($clientList as $i => $sourceContactID) {
bb76ee5a 251 try {
a0fdfb65 252 $params = [
bb76ee5a
FG
253 'case_id' => $caseID,
254 'relationship_type_id' => $relTypeId,
255 "contact_id_$a" => $relContactID,
256 "contact_id_$b" => $sourceContactID,
a0fdfb65
MD
257 'sequential' => TRUE,
258 ];
259 // first check if there is any existing relationship present with same parameters.
260 // If yes then update the relationship by setting active and start date to current time
261 $relationship = civicrm_api3('Relationship', 'get', $params)['values'];
262 $params = array_merge(CRM_Utils_Array::value(0, $relationship, $params), [
bb76ee5a 263 'start_date' => 'now',
a0fdfb65
MD
264 'is_active' => TRUE,
265 'end_date' => '',
266 ]);
267 $result = civicrm_api3('relationship', 'create', $params);
bb76ee5a
FG
268 }
269 catch (CiviCRM_API3_Exception $e) {
270 $ret['is_error'] = 1;
271 $ret['error_message'] = $e->getMessage();
272 }
3b1c37fe
CW
273 // Save activity only for the primary (first) client
274 if ($i == 0 && empty($result['is_error'])) {
3e4eb9aa 275 CRM_Case_BAO_Case::createCaseRoleActivity($caseID, $result['id'], $relContactID, $sourceContactID);
c91df8b4 276 }
6a488035 277 }
3e4eb9aa
JP
278 if (!empty($_REQUEST['is_unit_test'])) {
279 return $ret;
280 }
6a488035 281
ecdef330 282 CRM_Utils_JSON::output($ret);
6a488035
TO
283 }
284
285 /**
fe482240 286 * Fetch the custom field help.
6a488035 287 */
00be9182 288 public static function customField() {
353ffa53 289 $fieldId = CRM_Utils_Type::escape($_REQUEST['id'], 'Integer');
be2fb01f
CW
290 $params = ['id' => $fieldId];
291 $returnProperties = ['help_pre', 'help_post'];
292 $values = [];
6a488035
TO
293
294 CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_CustomField', $params, $values, $returnProperties);
ecdef330 295 CRM_Utils_JSON::output($values);
6a488035
TO
296 }
297
00be9182 298 public static function groupTree() {
d42a224c 299 CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
6a488035
TO
300 $gids = CRM_Utils_Type::escape($_GET['gids'], 'String');
301 echo CRM_Contact_BAO_GroupNestingCache::json($gids);
302 CRM_Utils_System::civiExit();
303 }
304
6a488035 305 /**
fe482240 306 * Delete custom value.
6a488035 307 */
00be9182 308 public static function deleteCustomValue() {
d42a224c 309 CRM_Utils_System::setHttpHeader('Content-Type', 'text/plain');
6a488035
TO
310 $customValueID = CRM_Utils_Type::escape($_REQUEST['valueID'], 'Positive');
311 $customGroupID = CRM_Utils_Type::escape($_REQUEST['groupID'], 'Positive');
a3d827a7 312 $contactId = CRM_Utils_Request::retrieve('contactId', 'Positive');
6a488035 313 CRM_Core_BAO_CustomValue::deleteCustomValue($customValueID, $customGroupID);
a4cce21a 314 if ($contactId) {
7fa9167d 315 echo CRM_Contact_BAO_Contact::getCountComponent('custom_' . $customGroupID, $contactId);
6a488035
TO
316 }
317
2b68a50c 318 CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush();
6a488035
TO
319 CRM_Utils_System::civiExit();
320 }
321
6a488035 322 /**
fe482240 323 * check the CMS username.
ce80b209 324 */
69078420 325 public static function checkUserName() {
be2fb01f 326 $signer = new CRM_Utils_Signer(CRM_Core_Key::privateKey(), ['for', 'ts']);
a3d827a7
CW
327 $sig = CRM_Utils_Request::retrieve('sig', 'String');
328 $for = CRM_Utils_Request::retrieve('for', 'String');
272081ca
TO
329 if (
330 CRM_Utils_Time::getTimeRaw() > $_REQUEST['ts'] + self::CHECK_USERNAME_TTL
7fa9167d 331 || $for != 'civicrm/ajax/cmsuser'
332 || !$signer->validate($sig, $_REQUEST)
272081ca 333 ) {
be2fb01f 334 $user = ['name' => 'error'];
8be1a839 335 CRM_Utils_JSON::output($user);
272081ca
TO
336 }
337
6a488035 338 $config = CRM_Core_Config::singleton();
4c68cf7b 339 $username = trim(CRM_Utils_Array::value('cms_name', $_REQUEST));
6a488035 340
be2fb01f 341 $params = ['name' => $username];
6a488035 342
be2fb01f 343 $errors = [];
6a488035
TO
344 $config->userSystem->checkUserNameEmailExists($params, $errors);
345
346 if (isset($errors['cms_name']) || isset($errors['name'])) {
b44e3f84 347 //user name is not available
be2fb01f 348 $user = ['name' => 'no'];
8be1a839 349 CRM_Utils_JSON::output($user);
6a488035
TO
350 }
351 else {
352 //user name is available
be2fb01f 353 $user = ['name' => 'yes'];
8be1a839 354 CRM_Utils_JSON::output($user);
6a488035 355 }
8be1a839
TO
356
357 // Not reachable: JSON::output() above exits.
6a488035
TO
358 CRM_Utils_System::civiExit();
359 }
360
361 /**
fe482240 362 * Function to get email address of a contact.
6a488035 363 */
00be9182 364 public static function getContactEmail() {
a7488080 365 if (!empty($_REQUEST['contact_id'])) {
6a488035 366 $contactID = CRM_Utils_Type::escape($_REQUEST['contact_id'], 'Positive');
8c0ea1d7
TO
367 if (!CRM_Contact_BAO_Contact_Permission::allow($contactID, CRM_Core_Permission::EDIT)) {
368 return;
369 }
6a488035
TO
370 list($displayName,
371 $userEmail
353ffa53 372 ) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contactID);
effdc2d9 373
d42a224c 374 CRM_Utils_System::setHttpHeader('Content-Type', 'text/plain');
6a488035
TO
375 if ($userEmail) {
376 echo $userEmail;
377 }
378 }
379 else {
380 $noemail = CRM_Utils_Array::value('noemail', $_GET);
381 $queryString = NULL;
a4cce21a
JM
382 $name = CRM_Utils_Array::value('name', $_GET);
383 if ($name) {
6a488035
TO
384 $name = CRM_Utils_Type::escape($name, 'String');
385 if ($noemail) {
386 $queryString = " cc.sort_name LIKE '%$name%'";
387 }
388 else {
389 $queryString = " ( cc.sort_name LIKE '%$name%' OR ce.email LIKE '%$name%' ) ";
390 }
391 }
a4cce21a 392 else {
d75f2f47
EM
393 $cid = CRM_Utils_Array::value('cid', $_GET);
394 if ($cid) {
b44e3f84 395 //check cid for integer
a4cce21a
JM
396 $contIDS = explode(',', $cid);
397 foreach ($contIDS as $contID) {
398 CRM_Utils_Type::escape($contID, 'Integer');
399 }
400 $queryString = " cc.id IN ( $cid )";
d75f2f47 401 }
6a488035
TO
402 }
403
404 if ($queryString) {
be2fb01f 405 $result = [];
6a488035 406 $offset = CRM_Utils_Array::value('offset', $_GET, 0);
89595c92 407 $rowCount = Civi::settings()->get('search_autocomplete_count');
6a488035 408
bf00d1b6 409 $offset = CRM_Utils_Type::escape($offset, 'Int');
bf00d1b6 410
6a488035
TO
411 // add acl clause here
412 list($aclFrom, $aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause('cc');
413 if ($aclWhere) {
414 $aclWhere = " AND $aclWhere";
415 }
416 if ($noemail) {
417 $query = "
418SELECT sort_name name, cc.id
419FROM civicrm_contact cc
420 {$aclFrom}
421WHERE cc.is_deceased = 0 AND {$queryString}
422 {$aclWhere}
423LIMIT {$offset}, {$rowCount}
424";
425
426 // send query to hook to be modified if needed
427 CRM_Utils_Hook::contactListQuery($query,
428 $name,
edc80cda 429 CRM_Utils_Request::retrieve('context', 'Alphanumeric'),
a3d827a7 430 CRM_Utils_Request::retrieve('cid', 'Positive')
6a488035
TO
431 );
432
433 $dao = CRM_Core_DAO::executeQuery($query);
434 while ($dao->fetch()) {
be2fb01f 435 $result[] = [
6a488035 436 'id' => $dao->id,
cac1236c 437 'text' => $dao->name,
be2fb01f 438 ];
6a488035
TO
439 }
440 }
441 else {
442 $query = "
443SELECT sort_name name, ce.email, cc.id
444FROM civicrm_email ce INNER JOIN civicrm_contact cc ON cc.id = ce.contact_id
445 {$aclFrom}
446WHERE ce.on_hold = 0 AND cc.is_deceased = 0 AND cc.do_not_email = 0 AND {$queryString}
447 {$aclWhere}
448LIMIT {$offset}, {$rowCount}
449";
450
451 // send query to hook to be modified if needed
452 CRM_Utils_Hook::contactListQuery($query,
453 $name,
edc80cda 454 CRM_Utils_Request::retrieve('context', 'Alphanumeric'),
a3d827a7 455 CRM_Utils_Request::retrieve('cid', 'Positive')
6a488035
TO
456 );
457
6a488035
TO
458 $dao = CRM_Core_DAO::executeQuery($query);
459
460 while ($dao->fetch()) {
ce80b209 461 //working here
be2fb01f 462 $result[] = [
cac1236c 463 'text' => '"' . $dao->name . '" <' . $dao->email . '>',
6a488035 464 'id' => (CRM_Utils_Array::value('id', $_GET)) ? "{$dao->id}::{$dao->email}" : '"' . $dao->name . '" <' . $dao->email . '>',
be2fb01f 465 ];
6a488035
TO
466 }
467 }
aa8ff347 468 CRM_Utils_JSON::output($result);
6a488035
TO
469 }
470 }
471 CRM_Utils_System::civiExit();
472 }
473
00be9182 474 public static function getContactPhone() {
6a488035
TO
475
476 $queryString = NULL;
3ae9c7d6 477 $sqlParmas = [];
6a488035
TO
478 //check for mobile type
479 $phoneTypes = CRM_Core_OptionGroup::values('phone_type', TRUE, FALSE, FALSE, NULL, 'name');
480 $mobileType = CRM_Utils_Array::value('Mobile', $phoneTypes);
481
3ae9c7d6 482 $name = CRM_Utils_Request::retrieveValue('name', 'String', NULL, FALSE, 'GET');
a4cce21a 483 if ($name) {
3ae9c7d6
SL
484 $key = (int) count(array_keys($sqlParmas)) + 1;
485 $queryString = " ( cc.sort_name LIKE %{$key} OR cp.phone LIKE %{$key} ) ";
486 $sqlParams[$key] = ['%' . $name . '%', 'String'];
6a488035 487 }
a4cce21a 488 else {
3ae9c7d6 489 $cid = CRM_Utils_Request::retrieveValue('cid', 'CommaSeparatedIntegers', NULL, FALSE, 'GET');
d75f2f47 490 if ($cid) {
a4cce21a 491 $queryString = " cc.id IN ( $cid )";
6a488035 492 }
6a488035
TO
493 }
494
495 if ($queryString) {
be2fb01f 496 $result = [];
3ae9c7d6
SL
497 $offset = (int) CRM_Utils_Request::retrieveValue('offset', 'Integer', 0, FALSE, 'GET');
498 $rowCount = (int) CRM_Utils_Request::retrieveValue('rowcount', 'Integer', 20, FALSE, 'GET');
bf00d1b6 499
6a488035
TO
500 // add acl clause here
501 list($aclFrom, $aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause('cc');
502 if ($aclWhere) {
503 $aclWhere = " AND $aclWhere";
504 }
505
506 $query = "
507SELECT sort_name name, cp.phone, cc.id
508FROM civicrm_phone cp INNER JOIN civicrm_contact cc ON cc.id = cp.contact_id
509 {$aclFrom}
510WHERE cc.is_deceased = 0 AND cc.do_not_sms = 0 AND cp.phone_type_id = {$mobileType} AND {$queryString}
511 {$aclWhere}
512LIMIT {$offset}, {$rowCount}
513";
514
515 // send query to hook to be modified if needed
516 CRM_Utils_Hook::contactListQuery($query,
517 $name,
edc80cda 518 CRM_Utils_Request::retrieve('context', 'Alphanumeric'),
a3d827a7 519 CRM_Utils_Request::retrieve('cid', 'Positive')
6a488035
TO
520 );
521
3ae9c7d6 522 $dao = CRM_Core_DAO::executeQuery($query, $sqlParams);
6a488035
TO
523
524 while ($dao->fetch()) {
be2fb01f 525 $result[] = [
b792e485 526 'text' => '"' . $dao->name . '" (' . $dao->phone . ')',
6a488035 527 'id' => (CRM_Utils_Array::value('id', $_GET)) ? "{$dao->id}::{$dao->phone}" : '"' . $dao->name . '" <' . $dao->phone . '>',
be2fb01f 528 ];
6a488035 529 }
8be1a839 530 CRM_Utils_JSON::output($result);
6a488035
TO
531 }
532 CRM_Utils_System::civiExit();
533 }
534
00be9182 535 public static function buildSubTypes() {
a3d827a7 536 $parent = CRM_Utils_Request::retrieve('parentId', 'Positive');
6a488035
TO
537
538 switch ($parent) {
539 case 1:
540 $contactType = 'Individual';
541 break;
542
543 case 2:
544 $contactType = 'Household';
545 break;
546
547 case 4:
548 $contactType = 'Organization';
549 break;
550 }
551
552 $subTypes = CRM_Contact_BAO_ContactType::subTypePairs($contactType, FALSE, NULL);
553 asort($subTypes);
ecdef330 554 CRM_Utils_JSON::output($subTypes);
6a488035
TO
555 }
556
00be9182 557 public static function buildDedupeRules() {
a3d827a7 558 $parent = CRM_Utils_Request::retrieve('parentId', 'Positive');
6a488035
TO
559
560 switch ($parent) {
561 case 1:
562 $contactType = 'Individual';
563 break;
564
565 case 2:
566 $contactType = 'Household';
567 break;
568
569 case 4:
570 $contactType = 'Organization';
571 break;
572 }
573
574 $dedupeRules = CRM_Dedupe_BAO_RuleGroup::getByType($contactType);
575
ecdef330 576 CRM_Utils_JSON::output($dedupeRules);
6a488035
TO
577 }
578
579 /**
fe482240 580 * Function used for CiviCRM dashboard operations.
6a488035 581 */
00be9182 582 public static function dashboard() {
ce2cc43e 583 switch ($_REQUEST['op']) {
6a488035
TO
584 case 'save_columns':
585 CRM_Core_BAO_Dashboard::saveDashletChanges($_REQUEST['columns']);
ce2cc43e
CW
586 break;
587
6a488035
TO
588 case 'delete_dashlet':
589 $dashletID = CRM_Utils_Type::escape($_REQUEST['dashlet_id'], 'Positive');
590 CRM_Core_BAO_Dashboard::deleteDashlet($dashletID);
6a488035
TO
591 }
592
ce2cc43e 593 CRM_Utils_System::civiExit();
6a488035
TO
594 }
595
596 /**
fe482240 597 * Retrieve signature based on email id.
6a488035 598 */
00be9182 599 public static function getSignature() {
6a488035 600 $emailID = CRM_Utils_Type::escape($_REQUEST['emailID'], 'Positive');
353ffa53
TO
601 $query = "SELECT signature_text, signature_html FROM civicrm_email WHERE id = {$emailID}";
602 $dao = CRM_Core_DAO::executeQuery($query);
6a488035 603
be2fb01f 604 $signatures = [];
6a488035 605 while ($dao->fetch()) {
be2fb01f 606 $signatures = [
6a488035
TO
607 'signature_text' => $dao->signature_text,
608 'signature_html' => $dao->signature_html,
be2fb01f 609 ];
6a488035
TO
610 }
611
ecdef330 612 CRM_Utils_JSON::output($signatures);
6a488035
TO
613 }
614
615 /**
100fef9d 616 * Process dupes.
6a488035 617 */
00be9182 618 public static function processDupes() {
6a488035 619 $oper = CRM_Utils_Type::escape($_REQUEST['op'], 'String');
353ffa53
TO
620 $cid = CRM_Utils_Type::escape($_REQUEST['cid'], 'Positive');
621 $oid = CRM_Utils_Type::escape($_REQUEST['oid'], 'Positive');
6a488035
TO
622
623 if (!$oper || !$cid || !$oid) {
624 return;
625 }
626
627 $exception = new CRM_Dedupe_DAO_Exception();
628 $exception->contact_id1 = $cid;
629 $exception->contact_id2 = $oid;
630 //make sure contact2 > contact1.
631 if ($cid > $oid) {
632 $exception->contact_id1 = $oid;
633 $exception->contact_id2 = $cid;
634 }
635 $exception->find(TRUE);
636 $status = NULL;
637 if ($oper == 'dupe-nondupe') {
638 $status = $exception->save();
639 }
640 if ($oper == 'nondupe-dupe') {
641 $status = $exception->delete();
642 }
643
be2fb01f 644 CRM_Utils_JSON::output(['status' => ($status) ? $oper : $status]);
6a488035
TO
645 }
646
183ec330 647 /**
648 * Retrieve list of duplicate pairs from cache table.
649 */
00be9182 650 public static function getDedupes() {
63ef778e 651 $offset = isset($_REQUEST['start']) ? CRM_Utils_Type::escape($_REQUEST['start'], 'Integer') : 0;
652 $rowCount = isset($_REQUEST['length']) ? CRM_Utils_Type::escape($_REQUEST['length'], 'Integer') : 25;
6a488035 653
dc6285d5 654 $gid = CRM_Utils_Request::retrieve('gid', 'Positive');
655 $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive');
9f54f049 656 $null = NULL;
657 $criteria = CRM_Utils_Request::retrieve('criteria', 'Json', $null, FALSE, '{}');
bb22928b 658 $selected = CRM_Utils_Request::retrieveValue('selected', 'Boolean');
63ef778e 659 if ($rowCount < 0) {
660 $rowCount = 0;
661 }
6a488035 662
1f51ef4e 663 $whereClause = $orderByClause = '';
9f54f049 664 $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid, json_decode($criteria, TRUE));
665
69078420 666 $searchRows = [];
6a488035 667
ed92673b 668 $searchParams = self::getSearchOptionsFromRequest();
be2fb01f 669 $queryParams = [];
ed92673b 670
63ef778e 671 $join = '';
be2fb01f 672 $where = [];
579ea9bc 673
ed92673b 674 $isOrQuery = self::isOrQuery();
675
676 $nextParamKey = 3;
be2fb01f 677 $mappings = [
e67dcaf8 678 'dst' => 'cc1.display_name',
679 'src' => 'cc2.display_name',
680 'dst_email' => 'ce1.email',
681 'src_email' => 'ce2.email',
682 'dst_postcode' => 'ca1.postal_code',
683 'src_postcode' => 'ca2.postal_code',
684 'dst_street' => 'ca1.street',
685 'src_street' => 'ca2.street',
be2fb01f 686 ];
ed92673b 687
688 foreach ($mappings as $key => $dbName) {
689 if (!empty($searchParams[$key])) {
12af7add 690 // CRM-18694.
691 $wildcard = strstr($key, 'postcode') ? '' : '%';
be2fb01f 692 $queryParams[$nextParamKey] = [$wildcard . $searchParams[$key] . '%', 'String'];
ed92673b 693 $where[] = $dbName . " LIKE %{$nextParamKey} ";
694 $nextParamKey++;
695 }
63ef778e 696 }
ed92673b 697
698 if ($isOrQuery) {
69078420 699 $whereClause = ' ( ' . implode(' OR ', $where) . ' ) ';
63ef778e 700 }
701 else {
702 if (!empty($where)) {
69078420 703 $whereClause = implode(' AND ', $where);
63ef778e 704 }
f931b74c 705 }
63ef778e 706 $whereClause .= $whereClause ? ' AND de.id IS NULL' : ' de.id IS NULL';
6a488035 707
63ef778e 708 if ($selected) {
709 $whereClause .= ' AND pn.is_selected = 1';
710 }
2988f5c7 711 $join .= CRM_Dedupe_Merger::getJoinOnDedupeTable();
63ef778e 712
be2fb01f 713 $select = [
e67dcaf8 714 'cc1.contact_type' => 'dst_contact_type',
715 'cc1.display_name' => 'dst_display_name',
716 'cc1.contact_sub_type' => 'dst_contact_sub_type',
717 'cc2.contact_type' => 'src_contact_type',
718 'cc2.display_name' => 'src_display_name',
719 'cc2.contact_sub_type' => 'src_contact_sub_type',
720 'ce1.email' => 'dst_email',
721 'ce2.email' => 'src_email',
722 'ca1.postal_code' => 'dst_postcode',
723 'ca2.postal_code' => 'src_postcode',
724 'ca1.street_address' => 'dst_street',
725 'ca2.street_address' => 'src_street',
be2fb01f 726 ];
63ef778e 727
f931b74c 728 if ($select) {
63ef778e 729 $join .= " INNER JOIN civicrm_contact cc1 ON cc1.id = pn.entity_id1";
730 $join .= " INNER JOIN civicrm_contact cc2 ON cc2.id = pn.entity_id2";
731 $join .= " LEFT JOIN civicrm_email ce1 ON (ce1.contact_id = pn.entity_id1 AND ce1.is_primary = 1 )";
732 $join .= " LEFT JOIN civicrm_email ce2 ON (ce2.contact_id = pn.entity_id2 AND ce2.is_primary = 1 )";
733 $join .= " LEFT JOIN civicrm_address ca1 ON (ca1.contact_id = pn.entity_id1 AND ca1.is_primary = 1 )";
734 $join .= " LEFT JOIN civicrm_address ca2 ON (ca2.contact_id = pn.entity_id2 AND ca2.is_primary = 1 )";
735 }
ed92673b 736 $iTotal = CRM_Core_BAO_PrevNextCache::getCount($cacheKeyString, $join, $whereClause, '=', $queryParams);
1f51ef4e 737 if (!empty($_REQUEST['order'])) {
738 foreach ($_REQUEST['order'] as $orderInfo) {
739 if (!empty($orderInfo['column'])) {
740 $orderColumnNumber = $orderInfo['column'];
741 $dir = $orderInfo['dir'];
742 }
63ef778e 743 }
1f51ef4e 744 $columnDetails = CRM_Utils_Array::value($orderColumnNumber, $_REQUEST['columns']);
63ef778e 745 }
f931b74c 746 if (!empty($columnDetails)) {
63ef778e 747 switch ($columnDetails['data']) {
f931b74c 748 case 'src':
e67dcaf8 749 $orderByClause = " ORDER BY cc2.display_name {$dir}";
f931b74c 750 break;
751
752 case 'src_email':
e67dcaf8 753 $orderByClause = " ORDER BY ce2.email {$dir}";
f931b74c 754 break;
755
756 case 'src_street':
e67dcaf8 757 $orderByClause = " ORDER BY ca2.street_address {$dir}";
f931b74c 758 break;
759
760 case 'src_postcode':
e67dcaf8 761 $orderByClause = " ORDER BY ca2.postal_code {$dir}";
f931b74c 762 break;
763
764 case 'dst':
e67dcaf8 765 $orderByClause = " ORDER BY cc1.display_name {$dir}";
f931b74c 766 break;
767
768 case 'dst_email':
e67dcaf8 769 $orderByClause = " ORDER BY ce1.email {$dir}";
f931b74c 770 break;
771
772 case 'dst_street':
e67dcaf8 773 $orderByClause = " ORDER BY ca1.street_address {$dir}";
f931b74c 774 break;
775
776 case 'dst_postcode':
e67dcaf8 777 $orderByClause = " ORDER BY ca1.postal_code {$dir}";
f931b74c 778 break;
779
780 default:
063ffcb7 781 $orderByClause = " ORDER BY cc1.display_name ASC";
f931b74c 782 break;
63ef778e 783 }
784 }
6a488035 785
ed92673b 786 $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $whereClause, $offset, $rowCount, $select, $orderByClause, TRUE, $queryParams);
63ef778e 787 $iFilteredTotal = CRM_Core_DAO::singleValueQuery("SELECT FOUND_ROWS()");
6a488035 788
63ef778e 789 $count = 0;
790 foreach ($dupePairs as $key => $pairInfo) {
e67dcaf8 791 $pair = $pairInfo['data'];
63ef778e 792 $srcContactSubType = CRM_Utils_Array::value('src_contact_sub_type', $pairInfo);
793 $dstContactSubType = CRM_Utils_Array::value('dst_contact_sub_type', $pairInfo);
794 $srcTypeImage = CRM_Contact_BAO_Contact_Utils::getImage($srcContactSubType ?
795 $srcContactSubType : $pairInfo['src_contact_type'],
796 FALSE,
e67dcaf8 797 $pairInfo['entity_id2']
63ef778e 798 );
799 $dstTypeImage = CRM_Contact_BAO_Contact_Utils::getImage($dstContactSubType ?
800 $dstContactSubType : $pairInfo['dst_contact_type'],
801 FALSE,
e67dcaf8 802 $pairInfo['entity_id1']
63ef778e 803 );
6a488035 804
63ef778e 805 $searchRows[$count]['is_selected'] = $pairInfo['is_selected'];
806 $searchRows[$count]['is_selected_input'] = "<input type='checkbox' class='crm-dedupe-select' name='pnid_{$pairInfo['prevnext_id']}' value='{$pairInfo['is_selected']}' onclick='toggleDedupeSelect(this)'>";
807 $searchRows[$count]['src_image'] = $srcTypeImage;
e67dcaf8 808 $searchRows[$count]['src'] = CRM_Utils_System::href($pair['srcName'], 'civicrm/contact/view', "reset=1&cid={$pairInfo['entity_id2']}");
63ef778e 809 $searchRows[$count]['src_email'] = CRM_Utils_Array::value('src_email', $pairInfo);
810 $searchRows[$count]['src_street'] = CRM_Utils_Array::value('src_street', $pairInfo);
811 $searchRows[$count]['src_postcode'] = CRM_Utils_Array::value('src_postcode', $pairInfo);
812 $searchRows[$count]['dst_image'] = $dstTypeImage;
e67dcaf8 813 $searchRows[$count]['dst'] = CRM_Utils_System::href($pair['dstName'], 'civicrm/contact/view', "reset=1&cid={$pairInfo['entity_id1']}");
63ef778e 814 $searchRows[$count]['dst_email'] = CRM_Utils_Array::value('dst_email', $pairInfo);
815 $searchRows[$count]['dst_street'] = CRM_Utils_Array::value('dst_street', $pairInfo);
816 $searchRows[$count]['dst_postcode'] = CRM_Utils_Array::value('dst_postcode', $pairInfo);
da3afd4a 817 $searchRows[$count]['conflicts'] = str_replace("',", "',<br/>", CRM_Utils_Array::value('conflicts', $pair));
63ef778e 818 $searchRows[$count]['weight'] = CRM_Utils_Array::value('weight', $pair);
819
fd630ef9 820 if (!empty($pairInfo['data']['canMerge'])) {
c0cc2ad4 821 $mergeParams = [
822 'reset' => 1,
69078420
SL
823 'cid' => $pairInfo['entity_id1'],
824 'oid' => $pairInfo['entity_id2'],
825 'action' => 'update',
826 'rgid' => $rgid,
827 'criteria' => $criteria,
828 'limit' => CRM_Utils_Request::retrieve('limit', 'Integer'),
829 ];
6a488035 830 if ($gid) {
c0cc2ad4 831 $mergeParams['gid'] = $gid;
6a488035
TO
832 }
833
fd630ef9 834 $searchRows[$count]['actions'] = "<a class='crm-dedupe-flip' href='#' data-pnid={$pairInfo['prevnext_id']}>" . ts('flip') . "</a>&nbsp;|&nbsp;";
da3afd4a 835 $searchRows[$count]['actions'] .= CRM_Utils_System::href(ts('merge'), 'civicrm/contact/merge', $mergeParams);
fd630ef9 836 $searchRows[$count]['actions'] .= "&nbsp;|&nbsp;<a id='notDuplicate' href='#' onClick=\"processDupes( {$pairInfo['entity_id1']}, {$pairInfo['entity_id2']}, 'dupe-nondupe', 'dupe-listing'); return false;\">" . ts('not a duplicate') . "</a>";
6a488035
TO
837 }
838 else {
63ef778e 839 $searchRows[$count]['actions'] = '<em>' . ts('Insufficient access rights - cannot merge') . '</em>';
6a488035 840 }
63ef778e 841 $count++;
6a488035
TO
842 }
843
be2fb01f 844 $dupePairs = [
22b232f3 845 'data' => $searchRows,
846 'recordsTotal' => $iTotal,
847 'recordsFiltered' => $iFilteredTotal,
be2fb01f 848 ];
1f51ef4e 849 if (!empty($_REQUEST['is_unit_test'])) {
850 return $dupePairs;
851 }
22b232f3 852 CRM_Utils_JSON::output($dupePairs);
6a488035
TO
853 }
854
ed92673b 855 /**
856 * Get the searchable options from the request.
857 *
858 * @return array
859 */
860 public static function getSearchOptionsFromRequest() {
be2fb01f 861 $searchParams = [];
ed92673b 862 $searchData = CRM_Utils_Array::value('search', $_REQUEST);
863 $searchData['value'] = CRM_Utils_Type::escape($searchData['value'], 'String');
be2fb01f 864 $selectorElements = [
ed92673b 865 'is_selected',
866 'is_selected_input',
867 'src_image',
868 'src',
869 'src_email',
870 'src_street',
871 'src_postcode',
872 'dst_image',
873 'dst',
874 'dst_email',
875 'dst_street',
876 'dst_postcode',
877 'conflicts',
878 'weight',
879 'actions',
be2fb01f 880 ];
ed92673b 881 $columns = $_REQUEST['columns'];
882
883 foreach ($columns as $column) {
884 if (!empty($column['search']['value']) && in_array($column['data'], $selectorElements)) {
885 $searchParams[$column['data']] = CRM_Utils_Type::escape($column['search']['value'], 'String');
886 }
887 elseif (!empty($searchData['value'])) {
888 $searchParams[$column['data']] = $searchData['value'];
889 }
890 }
891 return $searchParams;
892 }
893
894 /**
895 * Is the query an OR query.
896 *
897 * If a generic search value is passed in - ie. $_REQUEST['search']['value'] = 'abc'
898 * then all fields are searched for this.
899 *
900 * It is unclear if there is any code that still passes this in or whether is is just legacy. It
901 * could cause a server-killing query on a large site so it probably is NOT in use if we haven't
902 * had complaints.
903 *
904 * @return bool
905 */
906 public static function isOrQuery() {
907 $searchData = CRM_Utils_Array::value('search', $_REQUEST);
908 return !empty($searchData['value']);
909 }
910
6a488035 911 /**
fe482240 912 * Retrieve a PDF Page Format for the PDF Letter form.
6a488035 913 */
00be9182 914 public function pdfFormat() {
6a488035
TO
915 $formatId = CRM_Utils_Type::escape($_REQUEST['formatId'], 'Integer');
916
917 $pdfFormat = CRM_Core_BAO_PdfFormat::getById($formatId);
918
ecdef330 919 CRM_Utils_JSON::output($pdfFormat);
6a488035
TO
920 }
921
922 /**
fe482240 923 * Retrieve Paper Size dimensions.
6a488035 924 */
00be9182 925 public static function paperSize() {
6a488035
TO
926 $paperSizeName = CRM_Utils_Type::escape($_REQUEST['paperSizeName'], 'String');
927
928 $paperSize = CRM_Core_BAO_PaperSize::getByName($paperSizeName);
929
ecdef330 930 CRM_Utils_JSON::output($paperSize);
6a488035
TO
931 }
932
183ec330 933 /**
934 * Swap contacts in a dupe pair i.e main with duplicate contact.
ea3ddccf 935 *
936 * @param int $prevNextId
183ec330 937 */
f931b74c 938 public static function flipDupePairs($prevNextId = NULL) {
fd630ef9 939 if (!$prevNextId) {
808c05a9 940 // @todo figure out if this is always POST & specify that rather than inexact GET
941 $prevNextId = CRM_Utils_Request::retrieve('pnid', 'Integer');
fd630ef9 942 }
808c05a9 943
944 $onlySelected = FALSE;
fd630ef9 945 if (is_array($prevNextId) && !CRM_Utils_Array::crmIsEmptyArray($prevNextId)) {
808c05a9 946 $onlySelected = TRUE;
fd630ef9 947 }
808c05a9 948 $prevNextId = CRM_Utils_Type::escapeAll((array) $prevNextId, 'Positive');
949 CRM_Core_BAO_PrevNextCache::flipPair($prevNextId, $onlySelected);
558cd7c7 950 CRM_Utils_System::civiExit();
fd630ef9 951 }
952
aeb97cc1
CW
953 /**
954 * Used to store selected contacts across multiple pages in advanced search.
955 */
00be9182 956 public static function selectUnselectContacts() {
353ffa53
TO
957 $name = CRM_Utils_Array::value('name', $_REQUEST);
958 $cacheKey = CRM_Utils_Array::value('qfKey', $_REQUEST);
959 $state = CRM_Utils_Array::value('state', $_REQUEST, 'checked');
6a488035
TO
960 $variableType = CRM_Utils_Array::value('variableType', $_REQUEST, 'single');
961
962 $actionToPerform = CRM_Utils_Array::value('action', $_REQUEST, 'select');
963
964 if ($variableType == 'multiple') {
965 // action post value only works with multiple type variable
966 if ($name) {
967 //multiple names like mark_x_1-mark_x_2 where 1,2 are cids
968 $elements = explode('-', $name);
969 foreach ($elements as $key => $element) {
970 $elements[$key] = self::_convertToId($element);
971 }
91209206 972 CRM_Utils_Type::escapeAll($elements, 'Integer');
0b8038a6 973 Civi::service('prevnext')->markSelection($cacheKey, $actionToPerform, $elements);
6a488035
TO
974 }
975 else {
0b8038a6 976 Civi::service('prevnext')->markSelection($cacheKey, $actionToPerform);
6a488035
TO
977 }
978 }
979 elseif ($variableType == 'single') {
980 $cId = self::_convertToId($name);
91209206 981 CRM_Utils_Type::escape($cId, 'Integer');
6a488035 982 $action = ($state == 'checked') ? 'select' : 'unselect';
0b8038a6 983 Civi::service('prevnext')->markSelection($cacheKey, $action, $cId);
6a488035 984 }
b7994703 985 $contactIds = Civi::service('prevnext')->getSelection($cacheKey);
6a488035
TO
986 $countSelectionCids = count($contactIds[$cacheKey]);
987
be2fb01f 988 $arrRet = ['getCount' => $countSelectionCids];
ecdef330 989 CRM_Utils_JSON::output($arrRet);
6a488035
TO
990 }
991
4319322b 992 /**
100fef9d 993 * @param string $name
4319322b
EM
994 *
995 * @return string
996 */
00be9182 997 public static function _convertToId($name) {
6a488035
TO
998 if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) {
999 $cId = substr($name, CRM_Core_Form::CB_PREFIX_LEN);
1000 }
1001 return $cId;
1002 }
1003
00be9182 1004 public static function getAddressDisplay() {
a3d827a7 1005 $contactId = CRM_Utils_Request::retrieve('contact_id', 'Positive');
6a488035
TO
1006 if (!$contactId) {
1007 $addressVal["error_message"] = "no contact id found";
1008 }
1009 else {
be2fb01f 1010 $entityBlock = [
408b79bf 1011 'contact_id' => $contactId,
1012 'entity_id' => $contactId,
be2fb01f 1013 ];
6a488035
TO
1014 $addressVal = CRM_Core_BAO_Address::getValues($entityBlock);
1015 }
1016
ecdef330 1017 CRM_Utils_JSON::output($addressVal);
6a488035 1018 }
40458f6c 1019
183ec330 1020 /**
1021 * Mark dupe pairs as selected from un-selected state or vice-versa, in dupe cache table.
1022 */
f931b74c 1023 public static function toggleDedupeSelect() {
63ef778e 1024 $pnid = $_REQUEST['pnid'];
1025 $isSelected = CRM_Utils_Type::escape($_REQUEST['is_selected'], 'Boolean');
9d2f6d53 1026 $cacheKeyString = CRM_Utils_Request::retrieve('cacheKey', 'Alphanumeric', $null, FALSE);
63ef778e 1027
be2fb01f
CW
1028 $params = [
1029 1 => [$isSelected, 'Boolean'],
69078420
SL
1030 // using % to address rows with conflicts as well
1031 3 => ["$cacheKeyString%", 'String'],
be2fb01f 1032 ];
63ef778e 1033
1034 //check pnid is_array or integer
1035 $whereClause = NULL;
1036 if (is_array($pnid) && !CRM_Utils_Array::crmIsEmptyArray($pnid)) {
13c42e60 1037 CRM_Utils_Type::escapeAll($pnid, 'Positive');
63ef778e 1038 $pnid = implode(', ', $pnid);
63ef778e 1039 $whereClause = " id IN ( {$pnid} ) ";
1040 }
1041 else {
1042 $pnid = CRM_Utils_Type::escape($pnid, 'Integer');
1043 $whereClause = " id = %2";
be2fb01f 1044 $params[2] = [$pnid, 'Integer'];
63ef778e 1045 }
1046
1047 $sql = "UPDATE civicrm_prevnext_cache SET is_selected = %1 WHERE {$whereClause} AND cacheKey LIKE %3";
1048 CRM_Core_DAO::executeQuery($sql, $params);
1049
1050 CRM_Utils_System::civiExit();
1051 }
1052
40458f6c 1053 /**
fe482240 1054 * Retrieve contact relationships.
40458f6c 1055 */
1056 public static function getContactRelationships() {
1057 $contactID = CRM_Utils_Type::escape($_GET['cid'], 'Integer');
edc80cda 1058 $context = CRM_Utils_Request::retrieve('context', 'Alphanumeric');
7d12de7f 1059 $relationship_type_id = CRM_Utils_Type::escape(CRM_Utils_Array::value('relationship_type_id', $_GET), 'Integer', FALSE);
40458f6c 1060
b0266403
CW
1061 if (!CRM_Contact_BAO_Contact_Permission::allow($contactID)) {
1062 return CRM_Utils_System::permissionDenied();
1063 }
1064
00f11506 1065 $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams();
40458f6c 1066
1067 $params['contact_id'] = $contactID;
1068 $params['context'] = $context;
4c5f31d0 1069 if ($relationship_type_id) {
cdee9432
TM
1070 $params['relationship_type_id'] = $relationship_type_id;
1071 }
40458f6c 1072
1073 // get the contact relationships
1074 $relationships = CRM_Contact_BAO_Relationship::getContactRelationshipSelector($params);
1075
7d12de7f 1076 CRM_Utils_JSON::output($relationships);
40458f6c 1077 }
96025800 1078
6a488035 1079}