Merge remote-tracking branch 'upstream/4.4' into 4.4-master-2014-03-20-15-52-17
[civicrm-core.git] / CRM / Admin / Page / AJAX.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.4 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2013
32 * $Id$
33 *
34 */
35
36 /**
37 * This class contains all the function that are called using AJAX
38 */
39 class CRM_Admin_Page_AJAX {
40
41 /**
42 * CRM-12337 Output navigation menu as executable javascript
43 * @see smarty_function_crmNavigationMenu
44 */
45 static function getNavigationMenu() {
46 $session = CRM_Core_Session::singleton();
47 $contactID = $session->get('userID');
48 if ($contactID) {
49 // Set headers to encourage browsers to cache for a long time
50 // If we want to refresh the menu we will send a different url
51 $year = 60*60*24*364;
52 header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + $year));
53 header('Content-Type: application/javascript');
54 header("Cache-Control: max-age=$year, public");
55
56 // Render template as a javascript file
57 $smarty = CRM_Core_Smarty::singleton();
58 $navigation = CRM_Core_BAO_Navigation::createNavigation($contactID);
59 $smarty->assign('timeGenerated', date('d M Y H:i:s'));
60 $smarty->assign('navigation', $navigation);
61 print $smarty->fetch('CRM/common/Navigation.tpl');
62 }
63 CRM_Utils_System::civiExit();
64 }
65
66 /**
67 * Return menu tree as json data for editing
68 */
69 static function getNavigationList() {
70 echo CRM_Core_BAO_Navigation::buildNavigation(TRUE, FALSE);
71 CRM_Utils_System::civiExit();
72 }
73
74 /**
75 * Function to process drag/move action for menu tree
76 */
77 static function menuTree() {
78 CRM_Core_BAO_Navigation::processNavigation($_GET);
79 }
80
81 /**
82 * Function to build status message while
83 * enabling/ disabling various objects
84 */
85 static function getStatusMsg() {
86 require_once('api/v3/utils.php');
87 $recordID = CRM_Utils_Type::escape($_GET['id'], 'Integer');
88 $entity = CRM_Utils_Type::escape($_GET['entity'], 'String');
89 $ret = array();
90
91 if ($recordID && $entity && $recordBAO = _civicrm_api3_get_BAO($entity)) {
92 switch ($recordBAO) {
93 case 'CRM_Core_BAO_UFGroup':
94 $method = 'getUFJoinRecord';
95 $result = array($recordBAO, $method);
96 $ufJoin = call_user_func_array(($result), array($recordID, TRUE));
97 if (!empty($ufJoin)) {
98 $ret['content'] = ts('This profile is currently used for %1.', array(1 => implode(', ', $ufJoin))) . ' <br/><br/>' . ts('If you disable the profile - it will be removed from these forms and/or modules. Do you want to continue?');
99 }
100 else {
101 $ret['content'] = ts('Are you sure you want to disable this profile?');
102 }
103 break;
104
105 case 'CRM_Price_BAO_PriceSet':
106 $usedBy = CRM_Price_BAO_PriceSet::getUsedBy($recordID);
107 $priceSet = CRM_Price_BAO_PriceSet::getTitle($recordID);
108
109 if (!CRM_Utils_System::isNull($usedBy)) {
110 $template = CRM_Core_Smarty::singleton();
111 $template->assign('usedBy', $usedBy);
112 $comps = array(
113 'Event' => 'civicrm_event',
114 'Contribution' => 'civicrm_contribution_page',
115 'EventTemplate' => 'civicrm_event_template'
116 );
117 $contexts = array();
118 foreach ($comps as $name => $table) {
119 if (array_key_exists($table, $usedBy)) {
120 $contexts[] = $name;
121 }
122 }
123 $template->assign('contexts', $contexts);
124
125 $ret['illegal'] = TRUE;
126 $table = $template->fetch('CRM/Price/Page/table.tpl');
127 $ret['content'] = ts('Unable to disable the \'%1\' price set - it is currently in use by one or more active events, contribution pages or contributions.', array(
128 1 => $priceSet)) . "<br/> $table";
129 }
130 else {
131 $ret['content'] = ts('Are you sure you want to disable \'%1\' Price Set?', array(1 => $priceSet));
132 }
133 break;
134
135 case 'CRM_Event_BAO_Event':
136 $ret['content'] = ts('Are you sure you want to disable this Event?');
137 break;
138
139 case 'CRM_Core_BAO_UFField':
140 $ret['content'] = ts('Are you sure you want to disable this CiviCRM Profile field?');
141 break;
142
143 case 'CRM_Contribute_BAO_ManagePremiums':
144 $ret['content'] = ts('Are you sure you want to disable this premium? This action will remove the premium from any contribution pages that currently offer it. However it will not delete the premium record - so you can re-enable it and add it back to your contribution page(s) at a later time.');
145 break;
146
147 case 'CRM_Contact_BAO_RelationshipType':
148 $ret['content'] = ts('Are you sure you want to disable this relationship type?') . '<br/><br/>' . ts('Users will no longer be able to select this value when adding or editing relationships between contacts.');
149 break;
150
151 case 'CRM_Financial_BAO_FinancialType':
152 $ret['content'] = ts('Are you sure you want to disable this financial type?');
153 break;
154
155 case 'CRM_Financial_BAO_FinancialAccount':
156 if (!CRM_Financial_BAO_FinancialAccount::getARAccounts($recordID)) {
157 $ret['illegal'] = TRUE;
158 $ret['content'] = ts('The selected financial account cannot be disabled because at least one Accounts Receivable type account is required (to ensure that accounting transactions are in balance).');
159 }
160 else {
161 $ret['content'] = ts('Are you sure you want to disable this financial account?');
162 }
163 break;
164
165 case 'CRM_Financial_BAO_PaymentProcessor':
166 $ret['content'] = ts('Are you sure you want to disable this payment processor?') . ' <br/><br/>' . ts('Users will no longer be able to select this value when adding or editing transaction pages.');
167 break;
168
169 case 'CRM_Financial_BAO_PaymentProcessorType':
170 $ret['content'] = ts('Are you sure you want to disable this payment processor type?');
171 break;
172
173 case 'CRM_Core_BAO_LocationType':
174 $ret['content'] = ts('Are you sure you want to disable this location type?') . ' <br/><br/>' . ts('Users will no longer be able to select this value when adding or editing contact locations.');
175 break;
176
177 case 'CRM_Event_BAO_ParticipantStatusType':
178 $ret['content'] = ts('Are you sure you want to disable this Participant Status?') . '<br/><br/> ' . ts('Users will no longer be able to select this value when adding or editing Participant Status.');
179 break;
180
181 case 'CRM_Mailing_BAO_Component':
182 $ret['content'] = ts('Are you sure you want to disable this component?');
183 break;
184
185 case 'CRM_Core_BAO_CustomField':
186 $ret['content'] = ts('Are you sure you want to disable this custom data field?');
187 break;
188
189 case 'CRM_Core_BAO_CustomGroup':
190 $ret['content'] = ts('Are you sure you want to disable this custom data group? Any profile fields that are linked to custom fields of this group will be disabled.');
191 break;
192
193 case 'CRM_Core_BAO_MessageTemplate':
194 $ret['content'] = ts('Are you sure you want to disable this message tempate?');
195 break;
196
197 case 'CRM_ACL_BAO_ACL':
198 $ret['content'] = ts('Are you sure you want to disable this ACL?');
199 break;
200
201 case 'CRM_ACL_BAO_EntityRole':
202 $ret['content'] = ts('Are you sure you want to disable this ACL Role Assignment?');
203 break;
204
205 case 'CRM_Member_BAO_MembershipType':
206 $ret['content'] = ts('Are you sure you want to disable this membership type?');
207 break;
208
209 case 'CRM_Member_BAO_MembershipStatus':
210 $ret['content'] = ts('Are you sure you want to disable this membership status rule?');
211 break;
212
213 case 'CRM_Price_BAO_PriceField':
214 $ret['content'] = ts('Are you sure you want to disable this price field?');
215 break;
216
217 case 'CRM_Contact_BAO_Group':
218 $ret['content'] = ts('Are you sure you want to disable this Group?');
219 break;
220
221 case 'CRM_Core_BAO_OptionGroup':
222 $ret['content'] = ts('Are you sure you want to disable this Option?');
223 break;
224
225 case 'CRM_Contact_BAO_ContactType':
226 $ret['content'] = ts('Are you sure you want to disable this Contact Type?');
227 break;
228
229 case 'CRM_Core_BAO_OptionValue':
230 $label = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', $recordID, 'label');
231 $ret['content'] = ts('Are you sure you want to disable the \'%1\' option ?', array(1 => $label));
232 $ret['content'] .= '<br /><br />' . ts('WARNING - Disabling an option which has been assigned to existing records will result in that option being cleared when the record is edited.');
233 break;
234
235 case 'CRM_Contribute_BAO_ContributionRecur':
236 $recurDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($recordID);
237 $ret['content'] = ts('Are you sure you want to mark this recurring contribution as cancelled?');
238 $ret['content'] .= '<br /><br /><strong>' . ts('WARNING - This action sets the CiviCRM recurring contribution status to Cancelled, but does NOT send a cancellation request to the payment processor. You will need to ensure that this recurring payment (subscription) is cancelled by the payment processor.') . '</strong>';
239 if ($recurDetails->membership_id) {
240 $ret['content'] .= '<br /><br /><strong>' . ts('This recurring contribution is linked to an auto-renew membership. If you cancel it, the associated membership will no longer renew automatically. However, the current membership status will not be affected.') . '</strong>';
241 }
242 break;
243
244 default:
245 $ret['content'] = ts('Are you sure you want to disable this record?');
246 break;
247 }
248 }
249 else {
250 $ret = array('status' => 'error', 'content' => 'Error: Unknown entity type.', 'illegal' => TRUE);
251 }
252 CRM_Core_Page_AJAX::returnJsonResponse($ret);
253 }
254
255 static function getTagList() {
256 $name = CRM_Utils_Type::escape($_GET['name'], 'String');
257 $parentId = CRM_Utils_Type::escape($_GET['parentId'], 'Integer');
258
259 $isSearch = NULL;
260 if (isset($_GET['search'])) {
261 $isSearch = CRM_Utils_Type::escape($_GET['search'], 'Integer');
262 }
263
264 $tags = array();
265
266 // always add current search term as possible tag
267 // here we append :::value to determine if existing / new tag should be created
268 if (!$isSearch) {
269 $tags[] = array(
270 'name' => $name,
271 'id' => $name . ":::value",
272 );
273 }
274
275 $query = "SELECT id, name FROM civicrm_tag WHERE parent_id = {$parentId} and name LIKE '%{$name}%'";
276 $dao = CRM_Core_DAO::executeQuery($query);
277
278 while ($dao->fetch()) {
279 // make sure we return tag name entered by user only if it does not exists in db
280 if ($name == $dao->name) {
281 $tags = array();
282 }
283 // escape double quotes, which break results js
284 $tags[] = array('name' => addcslashes($dao->name, '"'),
285 'id' => $dao->id,
286 );
287 }
288
289 echo json_encode($tags);
290 CRM_Utils_System::civiExit();
291 }
292
293 static function mergeTagList() {
294 $name = CRM_Utils_Type::escape($_GET['term'], 'String');
295 $fromId = CRM_Utils_Type::escape($_GET['fromId'], 'Integer');
296 $limit = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'search_autocomplete_count', NULL, 10);
297
298 // build used-for clause to be used in main query
299 $usedForTagA = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $fromId, 'used_for');
300 $usedForClause = array();
301 if ($usedForTagA) {
302 $usedForTagA = explode(",", $usedForTagA);
303 foreach ($usedForTagA as $key => $value) {
304 $usedForClause[] = "t1.used_for LIKE '%{$value}%'";
305 }
306 }
307 $usedForClause = !empty($usedForClause) ? implode(' OR ', $usedForClause) : '1';
308 sort($usedForTagA);
309
310 // query to list mergable tags
311 $query = "
312 SELECT t1.name, t1.id, t1.used_for, t2.name as parent
313 FROM civicrm_tag t1
314 LEFT JOIN civicrm_tag t2 ON t1.parent_id = t2.id
315 WHERE t1.id <> {$fromId} AND
316 t1.name LIKE '%{$name}%' AND
317 ({$usedForClause})
318 LIMIT $limit";
319 $dao = CRM_Core_DAO::executeQuery($query);
320 $result = array();
321
322 while ($dao->fetch()) {
323 $row = array(
324 'id' => $dao->id,
325 'text' => ($dao->parent ? "{$dao->parent} :: " : '') . $dao->name,
326 );
327 // Add warning about used_for types
328 if (!empty($dao->used_for)) {
329 $usedForTagB = explode(',', $dao->used_for);
330 sort($usedForTagB);
331 $usedForDiff = array_diff($usedForTagA, $usedForTagB);
332 if (!empty($usedForDiff)) {
333 $row['warning'] = TRUE;
334 }
335 }
336 $result[] = $row;
337 }
338 print json_encode($result);
339 CRM_Utils_System::civiExit();
340 }
341
342 static function processTags() {
343 $skipTagCreate = $skipEntityAction = $entityId = NULL;
344 $action = CRM_Utils_Type::escape($_POST['action'], 'String');
345 $parentId = CRM_Utils_Type::escape($_POST['parentId'], 'Integer');
346 if ($_POST['entityId']) {
347 $entityId = CRM_Utils_Type::escape($_POST['entityId'], 'Integer');
348 }
349
350 $entityTable = CRM_Utils_Type::escape($_POST['entityTable'], 'String');
351
352 if ($_POST['skipTagCreate']) {
353 $skipTagCreate = CRM_Utils_Type::escape($_POST['skipTagCreate'], 'Integer');
354 }
355
356 if ($_POST['skipEntityAction']) {
357 $skipEntityAction = CRM_Utils_Type::escape($_POST['skipEntityAction'], 'Integer');
358 }
359
360 // check if user has selected existing tag or is creating new tag
361 // this is done to allow numeric tags etc.
362 $tagValue = explode(':::', $_POST['tagID']);
363
364 $createNewTag = FALSE;
365 $tagID = $tagValue[0];
366 if (isset($tagValue[1]) && $tagValue[1] == 'value') {
367 $createNewTag = TRUE;
368 }
369
370 $tagInfo = array();
371 // if action is select
372 if ($action == 'select') {
373 // check the value of tagID
374 // if numeric that means existing tag
375 // else create new tag
376 if (!$skipTagCreate && $createNewTag) {
377 $params = array(
378 'name' => $tagID,
379 'parent_id' => $parentId,
380 );
381
382 $tagObject = CRM_Core_BAO_Tag::add($params, CRM_Core_DAO::$_nullArray);
383
384 $tagInfo = array(
385 'name' => $tagID,
386 'id' => $tagObject->id,
387 'action' => $action,
388 );
389 $tagID = $tagObject->id;
390 }
391
392 if (!$skipEntityAction && $entityId) {
393 // save this tag to contact
394 $params = array(
395 'entity_table' => $entityTable,
396 'entity_id' => $entityId,
397 'tag_id' => $tagID,
398 );
399
400 CRM_Core_BAO_EntityTag::add($params);
401 }
402 // if action is delete
403 }
404 elseif ($action == 'delete') {
405 if (!is_numeric($tagID)) {
406 $tagID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $tagID, 'id', 'name');
407 }
408 if (!$skipEntityAction && $entityId) {
409 // delete this tag entry for the entity
410 $params = array(
411 'entity_table' => $entityTable,
412 'entity_id' => $entityId,
413 'tag_id' => $tagID,
414 );
415
416 CRM_Core_BAO_EntityTag::del($params);
417 }
418 $tagInfo = array(
419 'id' => $tagID,
420 'action' => $action,
421 );
422 }
423
424 echo json_encode($tagInfo);
425 CRM_Utils_System::civiExit();
426 }
427
428 function mappingList() {
429 $params = array('mappingID');
430 foreach ($params as $param) {
431 $$param = CRM_Utils_Array::value($param, $_POST);
432 }
433
434 if (!$mappingID) {
435 echo json_encode(array('error_msg' => 'required params missing.'));
436 CRM_Utils_System::civiExit();
437 }
438
439 $selectionOptions = CRM_Core_BAO_ActionSchedule::getSelection1($mappingID);
440 extract($selectionOptions);
441
442 $elements = array();
443 foreach ($sel4 as $id => $name) {
444 $elements[] = array(
445 'name' => $name,
446 'value' => $id,
447 );
448 }
449
450 echo json_encode($elements);
451 CRM_Utils_System::civiExit();
452 }
453
454 function mappingList1() {
455 $params = array('mappingID');
456 foreach ($params as $param) {
457 $$param = CRM_Utils_Array::value($param, $_POST);
458 }
459
460 if (!$mappingID) {
461 echo json_encode(array('error_msg' => 'required params missing.'));
462 CRM_Utils_System::civiExit();
463 }
464
465 $selectionOptions = CRM_Core_BAO_ActionSchedule::getSelection1($mappingID);
466 extract($selectionOptions);
467
468 $elements = array();
469 foreach ($sel5 as $id => $name) {
470 $elements['sel5'][] = array(
471 'name' => $name,
472 'value' => $id,
473 );
474 }
475 $elements['recipientMapping'] = $recipientMapping;
476
477 echo json_encode($elements);
478 CRM_Utils_System::civiExit();
479 }
480
481 static function mergeTags() {
482 $tagAId = CRM_Utils_Type::escape($_POST['fromId'], 'Integer');
483 $tagBId = CRM_Utils_Type::escape($_POST['toId'], 'Integer');
484
485 $result = CRM_Core_BAO_EntityTag::mergeTags($tagAId, $tagBId);
486
487 if (!empty($result['tagB_used_for'])) {
488 $usedFor = CRM_Core_OptionGroup::values('tag_used_for');
489 foreach ($result['tagB_used_for'] as & $val) {
490 $val = $usedFor[$val];
491 }
492 $result['tagB_used_for'] = implode(', ', $result['tagB_used_for']);
493 }
494
495 $result['message'] = ts('"%1" has been merged with "%2". All records previously tagged "%1" are now tagged "%2".',
496 array(1 => $result['tagA'], 2 => $result['tagB'])
497 );
498
499 echo json_encode($result);
500 CRM_Utils_System::civiExit();
501 }
502
503 function recipient() {
504 $params = array('recipient');
505 foreach ($params as $param) {
506 $$param = CRM_Utils_Array::value($param, $_POST);
507 }
508
509 if (!$recipient) {
510 echo json_encode(array('error_msg' => 'required params missing.'));
511 CRM_Utils_System::civiExit();
512 }
513
514 switch ($recipient) {
515 case 'Participant Status':
516 $values = CRM_Event_PseudoConstant::participantStatus();
517 break;
518
519 case 'participant_role':
520 $values = CRM_Event_PseudoConstant::participantRole();
521 break;
522
523 default:
524 exit;
525 }
526
527 $elements = array();
528 foreach ($values as $id => $name) {
529 $elements[] = array(
530 'name' => $name,
531 'value' => $id,
532 );
533 }
534
535 echo json_encode($elements);
536 CRM_Utils_System::civiExit();
537 }
538 }
539