PHPCS fixes.
[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
2d1fefa0 627 $status = self::markNonDuplicates($cid, $oid, $oper);
6a488035 628
be2fb01f 629 CRM_Utils_JSON::output(['status' => ($status) ? $oper : $status]);
6a488035
TO
630 }
631
183ec330 632 /**
633 * Retrieve list of duplicate pairs from cache table.
634 */
00be9182 635 public static function getDedupes() {
63ef778e 636 $offset = isset($_REQUEST['start']) ? CRM_Utils_Type::escape($_REQUEST['start'], 'Integer') : 0;
637 $rowCount = isset($_REQUEST['length']) ? CRM_Utils_Type::escape($_REQUEST['length'], 'Integer') : 25;
6a488035 638
dc6285d5 639 $gid = CRM_Utils_Request::retrieve('gid', 'Positive');
640 $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive');
9f54f049 641 $null = NULL;
642 $criteria = CRM_Utils_Request::retrieve('criteria', 'Json', $null, FALSE, '{}');
bb22928b 643 $selected = CRM_Utils_Request::retrieveValue('selected', 'Boolean');
63ef778e 644 if ($rowCount < 0) {
645 $rowCount = 0;
646 }
6a488035 647
1f51ef4e 648 $whereClause = $orderByClause = '';
9f54f049 649 $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid, json_decode($criteria, TRUE));
650
69078420 651 $searchRows = [];
6a488035 652
ed92673b 653 $searchParams = self::getSearchOptionsFromRequest();
be2fb01f 654 $queryParams = [];
ed92673b 655
63ef778e 656 $join = '';
be2fb01f 657 $where = [];
579ea9bc 658
ed92673b 659 $isOrQuery = self::isOrQuery();
660
661 $nextParamKey = 3;
be2fb01f 662 $mappings = [
e67dcaf8 663 'dst' => 'cc1.display_name',
664 'src' => 'cc2.display_name',
665 'dst_email' => 'ce1.email',
666 'src_email' => 'ce2.email',
667 'dst_postcode' => 'ca1.postal_code',
668 'src_postcode' => 'ca2.postal_code',
669 'dst_street' => 'ca1.street',
670 'src_street' => 'ca2.street',
be2fb01f 671 ];
ed92673b 672
673 foreach ($mappings as $key => $dbName) {
674 if (!empty($searchParams[$key])) {
12af7add 675 // CRM-18694.
676 $wildcard = strstr($key, 'postcode') ? '' : '%';
be2fb01f 677 $queryParams[$nextParamKey] = [$wildcard . $searchParams[$key] . '%', 'String'];
ed92673b 678 $where[] = $dbName . " LIKE %{$nextParamKey} ";
679 $nextParamKey++;
680 }
63ef778e 681 }
ed92673b 682
683 if ($isOrQuery) {
69078420 684 $whereClause = ' ( ' . implode(' OR ', $where) . ' ) ';
63ef778e 685 }
686 else {
687 if (!empty($where)) {
69078420 688 $whereClause = implode(' AND ', $where);
63ef778e 689 }
f931b74c 690 }
63ef778e 691 $whereClause .= $whereClause ? ' AND de.id IS NULL' : ' de.id IS NULL';
6a488035 692
63ef778e 693 if ($selected) {
694 $whereClause .= ' AND pn.is_selected = 1';
695 }
2988f5c7 696 $join .= CRM_Dedupe_Merger::getJoinOnDedupeTable();
63ef778e 697
be2fb01f 698 $select = [
e67dcaf8 699 'cc1.contact_type' => 'dst_contact_type',
700 'cc1.display_name' => 'dst_display_name',
701 'cc1.contact_sub_type' => 'dst_contact_sub_type',
702 'cc2.contact_type' => 'src_contact_type',
703 'cc2.display_name' => 'src_display_name',
704 'cc2.contact_sub_type' => 'src_contact_sub_type',
705 'ce1.email' => 'dst_email',
706 'ce2.email' => 'src_email',
707 'ca1.postal_code' => 'dst_postcode',
708 'ca2.postal_code' => 'src_postcode',
709 'ca1.street_address' => 'dst_street',
710 'ca2.street_address' => 'src_street',
be2fb01f 711 ];
63ef778e 712
f931b74c 713 if ($select) {
63ef778e 714 $join .= " INNER JOIN civicrm_contact cc1 ON cc1.id = pn.entity_id1";
715 $join .= " INNER JOIN civicrm_contact cc2 ON cc2.id = pn.entity_id2";
716 $join .= " LEFT JOIN civicrm_email ce1 ON (ce1.contact_id = pn.entity_id1 AND ce1.is_primary = 1 )";
717 $join .= " LEFT JOIN civicrm_email ce2 ON (ce2.contact_id = pn.entity_id2 AND ce2.is_primary = 1 )";
718 $join .= " LEFT JOIN civicrm_address ca1 ON (ca1.contact_id = pn.entity_id1 AND ca1.is_primary = 1 )";
719 $join .= " LEFT JOIN civicrm_address ca2 ON (ca2.contact_id = pn.entity_id2 AND ca2.is_primary = 1 )";
720 }
ed92673b 721 $iTotal = CRM_Core_BAO_PrevNextCache::getCount($cacheKeyString, $join, $whereClause, '=', $queryParams);
1f51ef4e 722 if (!empty($_REQUEST['order'])) {
723 foreach ($_REQUEST['order'] as $orderInfo) {
724 if (!empty($orderInfo['column'])) {
725 $orderColumnNumber = $orderInfo['column'];
726 $dir = $orderInfo['dir'];
727 }
63ef778e 728 }
1f51ef4e 729 $columnDetails = CRM_Utils_Array::value($orderColumnNumber, $_REQUEST['columns']);
63ef778e 730 }
f931b74c 731 if (!empty($columnDetails)) {
63ef778e 732 switch ($columnDetails['data']) {
f931b74c 733 case 'src':
e67dcaf8 734 $orderByClause = " ORDER BY cc2.display_name {$dir}";
f931b74c 735 break;
736
737 case 'src_email':
e67dcaf8 738 $orderByClause = " ORDER BY ce2.email {$dir}";
f931b74c 739 break;
740
741 case 'src_street':
e67dcaf8 742 $orderByClause = " ORDER BY ca2.street_address {$dir}";
f931b74c 743 break;
744
745 case 'src_postcode':
e67dcaf8 746 $orderByClause = " ORDER BY ca2.postal_code {$dir}";
f931b74c 747 break;
748
749 case 'dst':
e67dcaf8 750 $orderByClause = " ORDER BY cc1.display_name {$dir}";
f931b74c 751 break;
752
753 case 'dst_email':
e67dcaf8 754 $orderByClause = " ORDER BY ce1.email {$dir}";
f931b74c 755 break;
756
757 case 'dst_street':
e67dcaf8 758 $orderByClause = " ORDER BY ca1.street_address {$dir}";
f931b74c 759 break;
760
761 case 'dst_postcode':
e67dcaf8 762 $orderByClause = " ORDER BY ca1.postal_code {$dir}";
f931b74c 763 break;
764
765 default:
063ffcb7 766 $orderByClause = " ORDER BY cc1.display_name ASC";
f931b74c 767 break;
63ef778e 768 }
769 }
6a488035 770
ed92673b 771 $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $whereClause, $offset, $rowCount, $select, $orderByClause, TRUE, $queryParams);
63ef778e 772 $iFilteredTotal = CRM_Core_DAO::singleValueQuery("SELECT FOUND_ROWS()");
6a488035 773
63ef778e 774 $count = 0;
775 foreach ($dupePairs as $key => $pairInfo) {
e67dcaf8 776 $pair = $pairInfo['data'];
63ef778e 777 $srcContactSubType = CRM_Utils_Array::value('src_contact_sub_type', $pairInfo);
778 $dstContactSubType = CRM_Utils_Array::value('dst_contact_sub_type', $pairInfo);
779 $srcTypeImage = CRM_Contact_BAO_Contact_Utils::getImage($srcContactSubType ?
780 $srcContactSubType : $pairInfo['src_contact_type'],
781 FALSE,
e67dcaf8 782 $pairInfo['entity_id2']
63ef778e 783 );
784 $dstTypeImage = CRM_Contact_BAO_Contact_Utils::getImage($dstContactSubType ?
785 $dstContactSubType : $pairInfo['dst_contact_type'],
786 FALSE,
e67dcaf8 787 $pairInfo['entity_id1']
63ef778e 788 );
6a488035 789
63ef778e 790 $searchRows[$count]['is_selected'] = $pairInfo['is_selected'];
791 $searchRows[$count]['is_selected_input'] = "<input type='checkbox' class='crm-dedupe-select' name='pnid_{$pairInfo['prevnext_id']}' value='{$pairInfo['is_selected']}' onclick='toggleDedupeSelect(this)'>";
792 $searchRows[$count]['src_image'] = $srcTypeImage;
e67dcaf8 793 $searchRows[$count]['src'] = CRM_Utils_System::href($pair['srcName'], 'civicrm/contact/view', "reset=1&cid={$pairInfo['entity_id2']}");
63ef778e 794 $searchRows[$count]['src_email'] = CRM_Utils_Array::value('src_email', $pairInfo);
795 $searchRows[$count]['src_street'] = CRM_Utils_Array::value('src_street', $pairInfo);
796 $searchRows[$count]['src_postcode'] = CRM_Utils_Array::value('src_postcode', $pairInfo);
797 $searchRows[$count]['dst_image'] = $dstTypeImage;
e67dcaf8 798 $searchRows[$count]['dst'] = CRM_Utils_System::href($pair['dstName'], 'civicrm/contact/view', "reset=1&cid={$pairInfo['entity_id1']}");
63ef778e 799 $searchRows[$count]['dst_email'] = CRM_Utils_Array::value('dst_email', $pairInfo);
800 $searchRows[$count]['dst_street'] = CRM_Utils_Array::value('dst_street', $pairInfo);
801 $searchRows[$count]['dst_postcode'] = CRM_Utils_Array::value('dst_postcode', $pairInfo);
da3afd4a 802 $searchRows[$count]['conflicts'] = str_replace("',", "',<br/>", CRM_Utils_Array::value('conflicts', $pair));
63ef778e 803 $searchRows[$count]['weight'] = CRM_Utils_Array::value('weight', $pair);
804
fd630ef9 805 if (!empty($pairInfo['data']['canMerge'])) {
c0cc2ad4 806 $mergeParams = [
807 'reset' => 1,
69078420
SL
808 'cid' => $pairInfo['entity_id1'],
809 'oid' => $pairInfo['entity_id2'],
810 'action' => 'update',
811 'rgid' => $rgid,
812 'criteria' => $criteria,
813 'limit' => CRM_Utils_Request::retrieve('limit', 'Integer'),
814 ];
6a488035 815 if ($gid) {
c0cc2ad4 816 $mergeParams['gid'] = $gid;
6a488035
TO
817 }
818
fd630ef9 819 $searchRows[$count]['actions'] = "<a class='crm-dedupe-flip' href='#' data-pnid={$pairInfo['prevnext_id']}>" . ts('flip') . "</a>&nbsp;|&nbsp;";
da3afd4a 820 $searchRows[$count]['actions'] .= CRM_Utils_System::href(ts('merge'), 'civicrm/contact/merge', $mergeParams);
fd630ef9 821 $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
822 }
823 else {
63ef778e 824 $searchRows[$count]['actions'] = '<em>' . ts('Insufficient access rights - cannot merge') . '</em>';
6a488035 825 }
63ef778e 826 $count++;
6a488035
TO
827 }
828
be2fb01f 829 $dupePairs = [
22b232f3 830 'data' => $searchRows,
831 'recordsTotal' => $iTotal,
832 'recordsFiltered' => $iFilteredTotal,
be2fb01f 833 ];
1f51ef4e 834 if (!empty($_REQUEST['is_unit_test'])) {
835 return $dupePairs;
836 }
22b232f3 837 CRM_Utils_JSON::output($dupePairs);
6a488035
TO
838 }
839
ed92673b 840 /**
841 * Get the searchable options from the request.
842 *
843 * @return array
844 */
845 public static function getSearchOptionsFromRequest() {
be2fb01f 846 $searchParams = [];
ed92673b 847 $searchData = CRM_Utils_Array::value('search', $_REQUEST);
848 $searchData['value'] = CRM_Utils_Type::escape($searchData['value'], 'String');
be2fb01f 849 $selectorElements = [
ed92673b 850 'is_selected',
851 'is_selected_input',
852 'src_image',
853 'src',
854 'src_email',
855 'src_street',
856 'src_postcode',
857 'dst_image',
858 'dst',
859 'dst_email',
860 'dst_street',
861 'dst_postcode',
862 'conflicts',
863 'weight',
864 'actions',
be2fb01f 865 ];
ed92673b 866 $columns = $_REQUEST['columns'];
867
868 foreach ($columns as $column) {
869 if (!empty($column['search']['value']) && in_array($column['data'], $selectorElements)) {
870 $searchParams[$column['data']] = CRM_Utils_Type::escape($column['search']['value'], 'String');
871 }
872 elseif (!empty($searchData['value'])) {
873 $searchParams[$column['data']] = $searchData['value'];
874 }
875 }
876 return $searchParams;
877 }
878
879 /**
880 * Is the query an OR query.
881 *
882 * If a generic search value is passed in - ie. $_REQUEST['search']['value'] = 'abc'
883 * then all fields are searched for this.
884 *
885 * It is unclear if there is any code that still passes this in or whether is is just legacy. It
886 * could cause a server-killing query on a large site so it probably is NOT in use if we haven't
887 * had complaints.
888 *
889 * @return bool
890 */
891 public static function isOrQuery() {
892 $searchData = CRM_Utils_Array::value('search', $_REQUEST);
893 return !empty($searchData['value']);
894 }
895
2d1fefa0 896 /**
897 * Mark not duplicates.
898 *
899 * Note this function would sensibly be replaced by an api-call but extracting here to add a test first.
900 *
901 * I would have like to make it private but test class accesses it & it doesn't warrant being a BAO class
902 * as it should feel very endangered.
903 *
904 * @param int $cid
905 * @param int $oid
041ecc95 906 * @param "dupe-nondupe|nondupe-dupe" $oper
2d1fefa0 907 *
908 * @return \CRM_Core_DAO|mixed|null
909 */
910 public static function markNonDuplicates($cid, $oid, $oper) {
911 $exception = new CRM_Dedupe_DAO_Exception();
912 $exception->contact_id1 = $cid;
913 $exception->contact_id2 = $oid;
914 //make sure contact2 > contact1.
915 if ($cid > $oid) {
916 $exception->contact_id1 = $oid;
917 $exception->contact_id2 = $cid;
918 }
919 $exception->find(TRUE);
920 $status = NULL;
921 if ($oper == 'dupe-nondupe') {
922 $status = $exception->save();
923 }
924 if ($oper == 'nondupe-dupe') {
925 $status = $exception->delete();
926 }
927 return $status;
928 }
929
6a488035 930 /**
fe482240 931 * Retrieve a PDF Page Format for the PDF Letter form.
6a488035 932 */
00be9182 933 public function pdfFormat() {
6a488035
TO
934 $formatId = CRM_Utils_Type::escape($_REQUEST['formatId'], 'Integer');
935
936 $pdfFormat = CRM_Core_BAO_PdfFormat::getById($formatId);
937
ecdef330 938 CRM_Utils_JSON::output($pdfFormat);
6a488035
TO
939 }
940
941 /**
fe482240 942 * Retrieve Paper Size dimensions.
6a488035 943 */
00be9182 944 public static function paperSize() {
6a488035
TO
945 $paperSizeName = CRM_Utils_Type::escape($_REQUEST['paperSizeName'], 'String');
946
947 $paperSize = CRM_Core_BAO_PaperSize::getByName($paperSizeName);
948
ecdef330 949 CRM_Utils_JSON::output($paperSize);
6a488035
TO
950 }
951
183ec330 952 /**
953 * Swap contacts in a dupe pair i.e main with duplicate contact.
ea3ddccf 954 *
955 * @param int $prevNextId
183ec330 956 */
f931b74c 957 public static function flipDupePairs($prevNextId = NULL) {
fd630ef9 958 if (!$prevNextId) {
808c05a9 959 // @todo figure out if this is always POST & specify that rather than inexact GET
6d13d1c4
ML
960
961 // We cannot use CRM_Utils_Request::retrieve() because it might be an array.
962 // It later gets validated in escapeAll below.
963 $prevNextId = $_REQUEST['pnid'];
fd630ef9 964 }
808c05a9 965
966 $onlySelected = FALSE;
fd630ef9 967 if (is_array($prevNextId) && !CRM_Utils_Array::crmIsEmptyArray($prevNextId)) {
808c05a9 968 $onlySelected = TRUE;
fd630ef9 969 }
808c05a9 970 $prevNextId = CRM_Utils_Type::escapeAll((array) $prevNextId, 'Positive');
971 CRM_Core_BAO_PrevNextCache::flipPair($prevNextId, $onlySelected);
558cd7c7 972 CRM_Utils_System::civiExit();
fd630ef9 973 }
974
aeb97cc1
CW
975 /**
976 * Used to store selected contacts across multiple pages in advanced search.
977 */
00be9182 978 public static function selectUnselectContacts() {
353ffa53
TO
979 $name = CRM_Utils_Array::value('name', $_REQUEST);
980 $cacheKey = CRM_Utils_Array::value('qfKey', $_REQUEST);
981 $state = CRM_Utils_Array::value('state', $_REQUEST, 'checked');
6a488035
TO
982 $variableType = CRM_Utils_Array::value('variableType', $_REQUEST, 'single');
983
984 $actionToPerform = CRM_Utils_Array::value('action', $_REQUEST, 'select');
985
986 if ($variableType == 'multiple') {
987 // action post value only works with multiple type variable
988 if ($name) {
989 //multiple names like mark_x_1-mark_x_2 where 1,2 are cids
990 $elements = explode('-', $name);
991 foreach ($elements as $key => $element) {
992 $elements[$key] = self::_convertToId($element);
993 }
91209206 994 CRM_Utils_Type::escapeAll($elements, 'Integer');
0b8038a6 995 Civi::service('prevnext')->markSelection($cacheKey, $actionToPerform, $elements);
6a488035
TO
996 }
997 else {
0b8038a6 998 Civi::service('prevnext')->markSelection($cacheKey, $actionToPerform);
6a488035
TO
999 }
1000 }
1001 elseif ($variableType == 'single') {
1002 $cId = self::_convertToId($name);
91209206 1003 CRM_Utils_Type::escape($cId, 'Integer');
6a488035 1004 $action = ($state == 'checked') ? 'select' : 'unselect';
0b8038a6 1005 Civi::service('prevnext')->markSelection($cacheKey, $action, $cId);
6a488035 1006 }
b7994703 1007 $contactIds = Civi::service('prevnext')->getSelection($cacheKey);
6a488035
TO
1008 $countSelectionCids = count($contactIds[$cacheKey]);
1009
be2fb01f 1010 $arrRet = ['getCount' => $countSelectionCids];
ecdef330 1011 CRM_Utils_JSON::output($arrRet);
6a488035
TO
1012 }
1013
4319322b 1014 /**
100fef9d 1015 * @param string $name
4319322b
EM
1016 *
1017 * @return string
1018 */
00be9182 1019 public static function _convertToId($name) {
6a488035
TO
1020 if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) {
1021 $cId = substr($name, CRM_Core_Form::CB_PREFIX_LEN);
1022 }
1023 return $cId;
1024 }
1025
00be9182 1026 public static function getAddressDisplay() {
a3d827a7 1027 $contactId = CRM_Utils_Request::retrieve('contact_id', 'Positive');
6a488035
TO
1028 if (!$contactId) {
1029 $addressVal["error_message"] = "no contact id found";
1030 }
1031 else {
be2fb01f 1032 $entityBlock = [
408b79bf 1033 'contact_id' => $contactId,
1034 'entity_id' => $contactId,
be2fb01f 1035 ];
6a488035
TO
1036 $addressVal = CRM_Core_BAO_Address::getValues($entityBlock);
1037 }
1038
ecdef330 1039 CRM_Utils_JSON::output($addressVal);
6a488035 1040 }
40458f6c 1041
183ec330 1042 /**
1043 * Mark dupe pairs as selected from un-selected state or vice-versa, in dupe cache table.
1044 */
f931b74c 1045 public static function toggleDedupeSelect() {
63ef778e 1046 $pnid = $_REQUEST['pnid'];
1047 $isSelected = CRM_Utils_Type::escape($_REQUEST['is_selected'], 'Boolean');
9d2f6d53 1048 $cacheKeyString = CRM_Utils_Request::retrieve('cacheKey', 'Alphanumeric', $null, FALSE);
63ef778e 1049
be2fb01f
CW
1050 $params = [
1051 1 => [$isSelected, 'Boolean'],
69078420
SL
1052 // using % to address rows with conflicts as well
1053 3 => ["$cacheKeyString%", 'String'],
be2fb01f 1054 ];
63ef778e 1055
1056 //check pnid is_array or integer
1057 $whereClause = NULL;
1058 if (is_array($pnid) && !CRM_Utils_Array::crmIsEmptyArray($pnid)) {
13c42e60 1059 CRM_Utils_Type::escapeAll($pnid, 'Positive');
63ef778e 1060 $pnid = implode(', ', $pnid);
63ef778e 1061 $whereClause = " id IN ( {$pnid} ) ";
1062 }
1063 else {
1064 $pnid = CRM_Utils_Type::escape($pnid, 'Integer');
1065 $whereClause = " id = %2";
be2fb01f 1066 $params[2] = [$pnid, 'Integer'];
63ef778e 1067 }
1068
783b4b21 1069 $sql = "UPDATE civicrm_prevnext_cache SET is_selected = %1 WHERE {$whereClause} AND cachekey LIKE %3";
63ef778e 1070 CRM_Core_DAO::executeQuery($sql, $params);
1071
1072 CRM_Utils_System::civiExit();
1073 }
1074
40458f6c 1075 /**
fe482240 1076 * Retrieve contact relationships.
40458f6c 1077 */
1078 public static function getContactRelationships() {
1079 $contactID = CRM_Utils_Type::escape($_GET['cid'], 'Integer');
edc80cda 1080 $context = CRM_Utils_Request::retrieve('context', 'Alphanumeric');
7d12de7f 1081 $relationship_type_id = CRM_Utils_Type::escape(CRM_Utils_Array::value('relationship_type_id', $_GET), 'Integer', FALSE);
40458f6c 1082
b0266403
CW
1083 if (!CRM_Contact_BAO_Contact_Permission::allow($contactID)) {
1084 return CRM_Utils_System::permissionDenied();
1085 }
1086
00f11506 1087 $params = CRM_Core_Page_AJAX::defaultSortAndPagerParams();
40458f6c 1088
1089 $params['contact_id'] = $contactID;
1090 $params['context'] = $context;
4c5f31d0 1091 if ($relationship_type_id) {
cdee9432
TM
1092 $params['relationship_type_id'] = $relationship_type_id;
1093 }
40458f6c 1094
1095 // get the contact relationships
1096 $relationships = CRM_Contact_BAO_Relationship::getContactRelationshipSelector($params);
1097
7d12de7f 1098 CRM_Utils_JSON::output($relationships);
40458f6c 1099 }
96025800 1100
6a488035 1101}