Fix Soft credit personal note ton limit to 255 characters (DB limit).
[civicrm-core.git] / CRM / Core / Page / AJAX.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2018 |
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-2018
32 * $Id$
33 *
34 */
35
36 /**
37 * This is base class for all ajax calls
38 */
39 class CRM_Core_Page_AJAX {
40
41 /**
42 * Call generic ajax forms.
43 *
44 */
45 public static function run() {
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)) {
76 $page = new $className();
77 $page->run();
78 }
79 else {
80 $wrapper = new CRM_Utils_Wrapper();
81 $wrapper->run($className);
82 }
83 break;
84
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 /**
92 * Change is_quick_config priceSet to complex.
93 *
94 */
95 public static function setIsQuickConfig() {
96 $id = $context = NULL;
97 if (!empty($_REQUEST['id'])) {
98 $id = CRM_Utils_Type::escape($_REQUEST['id'], 'Integer');
99 }
100
101 if (!empty($_REQUEST['context'])) {
102 $context = CRM_Utils_Type::escape($_REQUEST['context'], 'String');
103 }
104 // return false if $id is null and
105 // $context is not civicrm_event or civicrm_contribution_page
106 if (!$id || !in_array($context, array('civicrm_event', 'civicrm_contribution_page'))) {
107 return FALSE;
108 }
109 $priceSetId = CRM_Price_BAO_PriceSet::getFor($context, $id, NULL);
110 if ($priceSetId) {
111 $sql = "UPDATE
112 civicrm_price_set cps
113 INNER JOIN civicrm_price_set_entity cpse ON cps.id = cpse.price_set_id
114 INNER JOIN {$context} ce ON cpse.entity_id = ce.id AND ce.id = %1
115 SET cps.is_quick_config = 0, cps.financial_type_id = IF(cps.financial_type_id IS NULL, ce.financial_type_id, cps.financial_type_id)
116 ";
117 CRM_Core_DAO::executeQuery($sql, array(1 => array($id, 'Integer')));
118
119 if ($context == 'civicrm_event') {
120 CRM_Core_BAO_Discount::del($id, $context);
121 }
122 }
123
124 CRM_Utils_JSON::output($priceSetId);
125 }
126
127 /**
128 * Determine whether the request is for a valid class/method name.
129 *
130 * @param string $type
131 * 'method'|'class'|''.
132 * @param string $className
133 * 'Class_Name'.
134 * @param string $fnName
135 * Method name.
136 *
137 * @return bool
138 */
139 public static function checkAuthz($type, $className, $fnName = NULL) {
140 switch ($type) {
141 case 'method':
142 if (!preg_match('/^CRM_[a-zA-Z0-9]+_Page_AJAX$/', $className)) {
143 return FALSE;
144 }
145 if (!preg_match('/^[a-zA-Z0-9]+$/', $fnName)) {
146 return FALSE;
147 }
148
149 // ensure that function exists
150 return method_exists($className, $fnName);
151
152 case 'page':
153 case 'class':
154 case '':
155 if (!preg_match('/^CRM_[a-zA-Z0-9]+_(Page|Form)_Inline_[a-zA-Z0-9]+$/', $className)) {
156 return FALSE;
157 }
158 return class_exists($className);
159
160 default:
161 return FALSE;
162 }
163 }
164
165 /**
166 * Outputs the CiviCRM standard json-formatted page/form response
167 * @param array|string $response
168 */
169 public static function returnJsonResponse($response) {
170 // Allow lazy callers to not wrap content in an array
171 if (is_string($response)) {
172 $response = array('content' => $response);
173 }
174 // Add session variables to response
175 $session = CRM_Core_Session::singleton();
176 $response += array(
177 'status' => 'success',
178 'userContext' => htmlspecialchars_decode($session->readUserContext()),
179 'title' => CRM_Utils_System::$title,
180 );
181 // crmMessages will be automatically handled by our ajax preprocessor
182 // @see js/Common.js
183 if ($session->getStatus(FALSE)) {
184 $response['crmMessages'] = $session->getStatus(TRUE);
185 }
186 $output = json_encode($response);
187
188 // CRM-11831 @see http://www.malsup.com/jquery/form/#file-upload
189 if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
190 CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
191 }
192 else {
193 $output = "<textarea>$output</textarea>";
194 }
195 echo $output;
196 CRM_Utils_System::civiExit();
197 }
198
199 /**
200 * Set headers appropriate for a js file.
201 *
202 * @param int|NULL $ttl
203 * Time-to-live (seconds).
204 */
205 public static function setJsHeaders($ttl = NULL) {
206 if ($ttl === NULL) {
207 // Encourage browsers to cache for a long time - 1 year
208 $ttl = 60 * 60 * 24 * 364;
209 }
210 CRM_Utils_System::setHttpHeader('Expires', gmdate('D, d M Y H:i:s \G\M\T', time() + $ttl));
211 CRM_Utils_System::setHttpHeader('Content-Type', 'application/javascript');
212 CRM_Utils_System::setHttpHeader('Cache-Control', "max-age=$ttl, public");
213 }
214
215 /**
216 * Set defaults for sort and pager.
217 *
218 * @param int $defaultOffset
219 * @param int $defaultRowCount
220 * @param string $defaultSort
221 * @param string $defaultsortOrder
222 *
223 * @return array
224 */
225 public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRowCount = 25, $defaultSort = NULL, $defaultsortOrder = 'asc') {
226 $params = array(
227 '_raw_values' => array(),
228 );
229
230 $sortMapper = array();
231 if (isset($_GET['columns'])) {
232 foreach ($_GET['columns'] as $key => $value) {
233 $sortMapper[$key] = CRM_Utils_Type::validate($value['data'], 'MysqlColumnNameOrAlias');
234 };
235 }
236
237 $offset = isset($_GET['start']) ? CRM_Utils_Type::validate($_GET['start'], 'Integer') : $defaultOffset;
238 $rowCount = isset($_GET['length']) ? CRM_Utils_Type::validate($_GET['length'], 'Integer') : $defaultRowCount;
239 // Why is the number of order by columns limited to 1?
240 $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::validate($_GET['order'][0]['column'], 'Integer'), $sortMapper) : $defaultSort;
241 $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::validate($_GET['order'][0]['dir'], 'MysqlOrderByDirection') : $defaultsortOrder;
242
243 if ($sort) {
244 $params['sortBy'] = "{$sort} {$sortOrder}";
245
246 $params['_raw_values']['sort'][0] = $sort;
247 $params['_raw_values']['order'][0] = $sortOrder;
248 }
249
250 $params['offset'] = $offset;
251 $params['rp'] = $rowCount;
252 $params['page'] = ($offset / $rowCount) + 1;
253
254 return $params;
255 }
256
257 /**
258 * Validate ajax input parameters.
259 *
260 * @param array $requiredParams
261 * @param array $optionalParams
262 *
263 * @return array
264 */
265 public static function validateParams($requiredParams = array(), $optionalParams = array()) {
266 $params = array();
267
268 foreach ($requiredParams as $param => $type) {
269 $params[$param] = CRM_Utils_Type::validate(CRM_Utils_Array::value($param, $_GET), $type);
270 }
271
272 foreach ($optionalParams as $param => $type) {
273 if (CRM_Utils_Array::value($param, $_GET)) {
274 $params[$param] = CRM_Utils_Type::validate(CRM_Utils_Array::value($param, $_GET), $type);
275 }
276 }
277
278 return $params;
279
280 }
281
282 }