Merge remote-tracking branch 'upstream/4.5' into 4.5-master-2015-03-09-21-44-34
[civicrm-core.git] / CRM / Core / Page / AJAX.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
39de6fd5 4 | CiviCRM version 4.6 |
6a488035 5 +--------------------------------------------------------------------+
06b69b18 6 | Copyright CiviCRM LLC (c) 2004-2014 |
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
06b69b18 31 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
32 * $Id$
33 *
34 */
35
36/**
37 * This is base class for all ajax calls
38 */
39class CRM_Core_Page_AJAX {
40
41 /**
fe482240 42 * Call generic ajax forms.
6a488035 43 *
6a488035 44 */
00be9182 45 public static function run() {
6a488035
TO
46 $className = CRM_Utils_Type::escape($_REQUEST['class_name'], 'String');
47 $type = '';
48 if (!empty($_REQUEST['type'])) {
49 $type = CRM_Utils_Type::escape($_REQUEST['type'], 'String');
50 }
51
52 if (!$className) {
53 CRM_Core_Error::fatal(ts('Invalid className: %1', array(1 => $className)));
54 }
55
56 $fnName = NULL;
57 if (isset($_REQUEST['fn_name'])) {
58 $fnName = CRM_Utils_Type::escape($_REQUEST['fn_name'], 'String');
59 }
60
61 if (!self::checkAuthz($type, $className, $fnName)) {
62 CRM_Utils_System::civiExit();
63 }
64
65 switch ($type) {
66 case 'method':
67 call_user_func(array($className, $fnName));
68 break;
69
70 case 'page':
71 case 'class':
72 case '':
73 // FIXME: This is done to maintain current wire protocol, but it might be
74 // simpler to just require different 'types' for pages and forms
75 if (preg_match('/^CRM_[a-zA-Z0-9]+_Page_Inline_/', $className)) {
7c550ca0 76 $page = new $className();
6a488035
TO
77 $page->run();
78 }
79 else {
80 $wrapper = new CRM_Utils_Wrapper();
81 $wrapper->run($className);
82 }
83 break;
2aa397bc 84
6a488035
TO
85 default:
86 CRM_Core_Error::debug_log_message('Unsupported inline request type: ' . var_export($type, TRUE));
87 }
88 CRM_Utils_System::civiExit();
89 }
90
91 /**
fe482240 92 * Change is_quick_config priceSet to complex.
6a488035 93 *
6a488035 94 */
00be9182 95 public static function setIsQuickConfig() {
6a488035 96 $id = $context = NULL;
a7488080 97 if (!empty($_REQUEST['id'])) {
6a488035
TO
98 $id = CRM_Utils_Type::escape($_REQUEST['id'], 'Integer');
99 }
cbb7c7e0 100
a7488080 101 if (!empty($_REQUEST['context'])) {
6a488035
TO
102 $context = CRM_Utils_Type::escape($_REQUEST['context'], 'String');
103 }
cbb7c7e0 104 // return false if $id is null and
6a488035
TO
105 // $context is not civicrm_event or civicrm_contribution_page
106 if (!$id || !in_array($context, array('civicrm_event', 'civicrm_contribution_page'))) {
2aa397bc 107 return FALSE;
6a488035 108 }
9da8dc8c 109 $priceSetId = CRM_Price_BAO_PriceSet::getFor($context, $id, NULL);
6a488035 110 if ($priceSetId) {
9da8dc8c 111 $result = CRM_Price_BAO_PriceSet::setIsQuickConfig($priceSetId, 0);
6a488035
TO
112 if ($context == 'civicrm_event') {
113 $sql = "UPDATE
114 civicrm_price_set cps
115 INNER JOIN civicrm_discount cd ON cd.price_set_id = cps.id
116 SET cps.is_quick_config = 0
117 WHERE cd.entity_id = (%1) AND cd.entity_table = 'civicrm_event' ";
118 $params = array(1 => array($id, 'Integer'));
119 CRM_Core_DAO::executeQuery($sql, $params);
120 CRM_Core_BAO_Discount::del($id, $context);
121 }
122 }
123 if (!$result) {
2aa397bc 124 $priceSetId = NULL;
6a488035 125 }
ecdef330 126 CRM_Utils_JSON::output($priceSetId);
6a488035
TO
127 }
128
129 /**
130 * Determine whether the request is for a valid class/method name.
131 *
6a0b768e
TO
132 * @param string $type
133 * 'method'|'class'|''.
134 * @param string $className
135 * 'Class_Name'.
136 * @param string $fnName
137 * Method name.
77b97be7
EM
138 *
139 * @return bool
6a488035 140 */
2aa397bc 141 public static function checkAuthz($type, $className, $fnName = NULL) {
6a488035
TO
142 switch ($type) {
143 case 'method':
144 if (!preg_match('/^CRM_[a-zA-Z0-9]+_Page_AJAX$/', $className)) {
145 return FALSE;
146 }
147 if (!preg_match('/^[a-zA-Z0-9]+$/', $fnName)) {
148 return FALSE;
149 }
150
151 // ensure that function exists
152 return method_exists($className, $fnName);
153
154 case 'page':
155 case 'class':
156 case '':
157 if (!preg_match('/^CRM_[a-zA-Z0-9]+_(Page|Form)_Inline_[a-zA-Z0-9]+$/', $className)) {
158 return FALSE;
159 }
160 return class_exists($className);
2aa397bc 161
6a488035
TO
162 default:
163 return FALSE;
164 }
165 }
03a7ec8f
CW
166
167 /**
168 * Outputs the CiviCRM standard json-formatted page/form response
169 * @param array|string $response
170 */
00be9182 171 public static function returnJsonResponse($response) {
03a7ec8f
CW
172 // Allow lazy callers to not wrap content in an array
173 if (is_string($response)) {
174 $response = array('content' => $response);
175 }
0e017a41 176 // Add session variables to response
03a7ec8f
CW
177 $session = CRM_Core_Session::singleton();
178 $response += array(
179 'status' => 'success',
180 'userContext' => htmlspecialchars_decode($session->readUserContext()),
0e017a41 181 'title' => CRM_Utils_System::$title,
03a7ec8f 182 );
0e017a41
CW
183 // crmMessages will be automatically handled by our ajax preprocessor
184 // @see js/Common.js
03a7ec8f
CW
185 if ($session->getStatus(FALSE)) {
186 $response['crmMessages'] = $session->getStatus(TRUE);
187 }
5d76705d 188 $output = json_encode($response);
03a7ec8f
CW
189
190 // CRM-11831 @see http://www.malsup.com/jquery/form/#file-upload
5d76705d
CW
191 if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
192 header('Content-Type: application/json');
03a7ec8f 193 }
5d76705d
CW
194 else {
195 $output = "<textarea>$output</textarea>";
03a7ec8f 196 }
5d76705d 197 echo $output;
03a7ec8f
CW
198 CRM_Utils_System::civiExit();
199 }
d6408252 200
4cc9b813 201 /**
fe482240 202 * Set headers appropriate for a js file.
e5afbdad
TO
203 *
204 * @param int|NULL $ttl
205 * Time-to-live (seconds).
4cc9b813 206 */
e5afbdad
TO
207 public static function setJsHeaders($ttl = NULL) {
208 if ($ttl === NULL) {
209 // Encourage browsers to cache for a long time - 1 year
210 $ttl = 60 * 60 * 24 * 364;
211 }
212 header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + $ttl));
4cc9b813 213 header('Content-Type: application/javascript');
e5afbdad 214 header("Cache-Control: max-age=$ttl, public");
4cc9b813
CW
215 }
216
6a488035 217}