Commit | Line | Data |
---|---|---|
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 | +--------------------------------------------------------------------+ | |
26 | */ | |
27 | ||
28 | /** | |
29 | * | |
30 | * @package CRM | |
06b69b18 | 31 | * @copyright CiviCRM LLC (c) 2004-2014 |
6a488035 TO |
32 | * $Id$ |
33 | * | |
34 | */ | |
35 | ||
36 | /** | |
37 | * System wide utilities. | |
38 | * | |
39 | */ | |
40 | class CRM_Utils_System { | |
41 | ||
42 | static $_callbacks = NULL; | |
43 | ||
5af8c999 CW |
44 | /** |
45 | * @var string Page title | |
46 | */ | |
47 | static $title = ''; | |
48 | ||
6a488035 | 49 | /** |
9911500f | 50 | * Compose a new URL string from the current URL string. |
7890c493 | 51 | * |
6a488035 TO |
52 | * Used by all the framework components, specifically, |
53 | * pager, sort and qfc | |
54 | * | |
7890c493 RS |
55 | * @param string $urlVar |
56 | * The url variable being considered (i.e. crmPageID, crmSortID etc). | |
57 | * @param bool $includeReset | |
58 | * (optional) Whether to include the reset GET string (if present). | |
59 | * @param bool $includeForce | |
60 | * (optional) Whether to include the force GET string (if present). | |
414e3596 | 61 | * @param string $path |
7890c493 | 62 | * (optional) The path to use for the new url. |
f4aaa82a | 63 | * @param bool|string $absolute |
7890c493 | 64 | * (optional) Whether to return an absolute URL. |
6a488035 | 65 | * |
7890c493 RS |
66 | * @return string |
67 | * The URL fragment. | |
6a488035 | 68 | */ |
00be9182 | 69 | public static function makeURL($urlVar, $includeReset = FALSE, $includeForce = TRUE, $path = NULL, $absolute = FALSE) { |
6a488035 TO |
70 | if (empty($path)) { |
71 | $config = CRM_Core_Config::singleton(); | |
72 | $path = CRM_Utils_Array::value($config->userFrameworkURLVar, $_GET); | |
73 | if (empty($path)) { | |
74 | return ''; | |
75 | } | |
76 | } | |
77 | ||
3ab88a8c DL |
78 | return |
79 | self::url( | |
80 | $path, | |
81 | CRM_Utils_System::getLinksUrl($urlVar, $includeReset, $includeForce), | |
82 | $absolute | |
83 | ); | |
6a488035 TO |
84 | } |
85 | ||
86 | /** | |
7890c493 RS |
87 | * Get the query string and clean it up. |
88 | * | |
9911500f | 89 | * Strips some variables that should not be propagated, specifically variables |
7890c493 | 90 | * like 'reset'. Also strips any side-affect actions (e.g. export). |
6a488035 TO |
91 | * |
92 | * This function is copied mostly verbatim from Pager.php (_getLinksUrl) | |
93 | * | |
7890c493 RS |
94 | * @param string $urlVar |
95 | * The URL variable being considered (e.g. crmPageID, crmSortID etc). | |
96 | * @param bool $includeReset | |
9911500f RS |
97 | * (optional) By default this is FALSE, meaning that the reset parameter |
98 | * is skipped. Set to TRUE to leave the reset parameter as-is. | |
7890c493 | 99 | * @param bool $includeForce |
9911500f | 100 | * (optional) |
7890c493 | 101 | * @param bool $skipUFVar |
9911500f | 102 | * (optional) |
6a488035 TO |
103 | * |
104 | * @return string | |
6a488035 | 105 | */ |
00be9182 | 106 | public static function getLinksUrl($urlVar, $includeReset = FALSE, $includeForce = TRUE, $skipUFVar = TRUE) { |
6a488035 TO |
107 | // Sort out query string to prevent messy urls |
108 | $querystring = array(); | |
353ffa53 TO |
109 | $qs = array(); |
110 | $arrays = array(); | |
6a488035 TO |
111 | |
112 | if (!empty($_SERVER['QUERY_STRING'])) { | |
113 | $qs = explode('&', str_replace('&', '&', $_SERVER['QUERY_STRING'])); | |
114 | for ($i = 0, $cnt = count($qs); $i < $cnt; $i++) { | |
115 | // check first if exist a pair | |
116 | if (strstr($qs[$i], '=') !== FALSE) { | |
117 | list($name, $value) = explode('=', $qs[$i]); | |
118 | if ($name != $urlVar) { | |
119 | $name = rawurldecode($name); | |
120 | //check for arrays in parameters: site.php?foo[]=1&foo[]=2&foo[]=3 | |
121 | if ((strpos($name, '[') !== FALSE) && | |
122 | (strpos($name, ']') !== FALSE) | |
123 | ) { | |
124 | $arrays[] = $qs[$i]; | |
125 | } | |
126 | else { | |
127 | $qs[$name] = $value; | |
128 | } | |
129 | } | |
130 | } | |
131 | else { | |
132 | $qs[$qs[$i]] = ''; | |
133 | } | |
134 | unset($qs[$i]); | |
135 | } | |
136 | } | |
137 | ||
138 | if ($includeForce) { | |
139 | $qs['force'] = 1; | |
140 | } | |
141 | ||
d8249fcb | 142 | // Ok this is a big assumption but usually works |
9911500f RS |
143 | // If we are in snippet mode, retain the 'section' param, if not, get rid |
144 | // of it. | |
d8249fcb CW |
145 | if (!empty($qs['snippet'])) { |
146 | unset($qs['snippet']); | |
147 | } | |
148 | else { | |
149 | unset($qs['section']); | |
150 | } | |
6a488035 TO |
151 | |
152 | if ($skipUFVar) { | |
153 | $config = CRM_Core_Config::singleton(); | |
154 | unset($qs[$config->userFrameworkURLVar]); | |
155 | } | |
156 | ||
157 | foreach ($qs as $name => $value) { | |
158 | if ($name != 'reset' || $includeReset) { | |
159 | $querystring[] = $name . '=' . $value; | |
160 | } | |
161 | } | |
162 | ||
163 | $querystring = array_merge($querystring, array_unique($arrays)); | |
6a488035 | 164 | |
fe010227 | 165 | $url = implode('&', $querystring); |
3ab88a8c | 166 | if ($urlVar) { |
fe010227 | 167 | $url .= (!empty($querystring) ? '&' : '') . $urlVar . '='; |
3ab88a8c DL |
168 | } |
169 | ||
170 | return $url; | |
6a488035 TO |
171 | } |
172 | ||
173 | /** | |
7890c493 RS |
174 | * If we are using a theming system, invoke theme, else just print the |
175 | * content. | |
6a488035 | 176 | * |
7890c493 RS |
177 | * @param string $content |
178 | * The content that will be themed. | |
414e3596 | 179 | * @param bool $print |
7890c493 RS |
180 | * (optional) Are we displaying to the screen or bypassing theming? |
181 | * @param bool $maintenance | |
182 | * (optional) For maintenance mode. | |
6a488035 | 183 | * |
a75c13cc | 184 | * @return string |
6a488035 | 185 | */ |
971d41b1 | 186 | public static function theme( |
6a488035 | 187 | &$content, |
e7292422 | 188 | $print = FALSE, |
6a488035 TO |
189 | $maintenance = FALSE |
190 | ) { | |
191 | $config = &CRM_Core_Config::singleton(); | |
192 | return $config->userSystem->theme($content, $print, $maintenance); | |
193 | } | |
194 | ||
195 | /** | |
7890c493 | 196 | * Generate a query string if input is an array. |
6a488035 | 197 | * |
7890c493 RS |
198 | * @param array|string $query |
199 | * @return string | |
6a488035 | 200 | */ |
00be9182 | 201 | public static function makeQueryString($query) { |
6a488035 TO |
202 | if (is_array($query)) { |
203 | $buf = ''; | |
204 | foreach ($query as $key => $value) { | |
205 | $buf .= ($buf ? '&' : '') . urlencode($key) . '=' . urlencode($value); | |
206 | } | |
207 | $query = $buf; | |
208 | } | |
209 | return $query; | |
210 | } | |
211 | ||
212 | /** | |
7890c493 | 213 | * Generate an internal CiviCRM URL. |
6a488035 | 214 | * |
7890c493 RS |
215 | * @param string $path |
216 | * The path being linked to, such as "civicrm/add". | |
217 | * @param array|string $query | |
218 | * A query string to append to the link, or an array of key-value pairs. | |
219 | * @param bool $absolute | |
220 | * Whether to force the output to be an absolute link (beginning with a | |
9911500f | 221 | * URI-scheme such as 'http:'). Useful for links that will be displayed |
7890c493 RS |
222 | * outside the site, such as in an RSS feed. |
223 | * @param string $fragment | |
224 | * A fragment identifier (named anchor) to append to the link. | |
6a488035 | 225 | * |
fe010227 CW |
226 | * @param bool $htmlize |
227 | * @param bool $frontend | |
228 | * @param bool $forceBackend | |
7890c493 RS |
229 | * @return string |
230 | * An HTML string containing a link to the given path. | |
6a488035 | 231 | */ |
971d41b1 | 232 | public static function url( |
6a488035 | 233 | $path = NULL, |
e7292422 | 234 | $query = NULL, |
6a488035 TO |
235 | $absolute = FALSE, |
236 | $fragment = NULL, | |
e7292422 | 237 | $htmlize = TRUE, |
6a488035 TO |
238 | $frontend = FALSE, |
239 | $forceBackend = FALSE | |
240 | ) { | |
241 | $query = self::makeQueryString($query); | |
242 | ||
243 | // we have a valid query and it has not yet been transformed | |
244 | if ($htmlize && !empty($query) && strpos($query, '&') === FALSE) { | |
245 | $query = htmlentities($query); | |
246 | } | |
247 | ||
248 | $config = CRM_Core_Config::singleton(); | |
249 | return $config->userSystem->url($path, $query, $absolute, $fragment, $htmlize, $frontend, $forceBackend); | |
250 | } | |
251 | ||
5bc392e6 EM |
252 | /** |
253 | * @param $text | |
254 | * @param null $path | |
255 | * @param null $query | |
256 | * @param bool $absolute | |
257 | * @param null $fragment | |
258 | * @param bool $htmlize | |
259 | * @param bool $frontend | |
260 | * @param bool $forceBackend | |
261 | * | |
262 | * @return string | |
263 | */ | |
971d41b1 | 264 | public static function href( |
a3e55d9c | 265 | $text, $path = NULL, $query = NULL, $absolute = TRUE, |
6a488035 TO |
266 | $fragment = NULL, $htmlize = TRUE, $frontend = FALSE, $forceBackend = FALSE |
267 | ) { | |
268 | $url = self::url($path, $query, $absolute, $fragment, $htmlize, $frontend, $forceBackend); | |
269 | return "<a href=\"$url\">$text</a>"; | |
270 | } | |
271 | ||
5bc392e6 EM |
272 | /** |
273 | * @return mixed | |
274 | */ | |
00be9182 | 275 | public static function permissionDenied() { |
6a488035 TO |
276 | $config = CRM_Core_Config::singleton(); |
277 | return $config->userSystem->permissionDenied(); | |
278 | } | |
279 | ||
5bc392e6 EM |
280 | /** |
281 | * @return mixed | |
282 | */ | |
00be9182 | 283 | public static function logout() { |
6a488035 TO |
284 | $config = CRM_Core_Config::singleton(); |
285 | return $config->userSystem->logout(); | |
286 | } | |
287 | ||
546b78fa CW |
288 | /** |
289 | * this is a very drupal specific function for now | |
290 | */ | |
00be9182 | 291 | public static function updateCategories() { |
6a488035 TO |
292 | $config = CRM_Core_Config::singleton(); |
293 | if ($config->userSystem->is_drupal) { | |
294 | $config->userSystem->updateCategories(); | |
295 | } | |
296 | } | |
297 | ||
298 | /** | |
299 | * What menu path are we currently on. Called for the primary tpl | |
300 | * | |
a6c01b45 CW |
301 | * @return string |
302 | * the current menu path | |
6a488035 | 303 | */ |
00be9182 | 304 | public static function currentPath() { |
6a488035 TO |
305 | $config = CRM_Core_Config::singleton(); |
306 | return trim(CRM_Utils_Array::value($config->userFrameworkURLVar, $_GET), '/'); | |
307 | } | |
308 | ||
309 | /** | |
dc195289 | 310 | * called from a template to compose a url. |
6a488035 | 311 | * |
7890c493 RS |
312 | * @param array $params |
313 | * List of parameters. | |
6a488035 | 314 | * |
a6c01b45 CW |
315 | * @return string |
316 | * url | |
6a488035 | 317 | */ |
00be9182 | 318 | public static function crmURL($params) { |
6a488035 TO |
319 | $p = CRM_Utils_Array::value('p', $params); |
320 | if (!isset($p)) { | |
321 | $p = self::currentPath(); | |
322 | } | |
323 | ||
496e07aa DL |
324 | return self::url( |
325 | $p, | |
6a488035 TO |
326 | CRM_Utils_Array::value('q', $params), |
327 | CRM_Utils_Array::value('a', $params, FALSE), | |
328 | CRM_Utils_Array::value('f', $params), | |
329 | CRM_Utils_Array::value('h', $params, TRUE), | |
330 | CRM_Utils_Array::value('fe', $params, FALSE), | |
331 | CRM_Utils_Array::value('fb', $params, FALSE) | |
332 | ); | |
333 | } | |
334 | ||
335 | /** | |
7890c493 | 336 | * Sets the title of the page. |
6a488035 TO |
337 | * |
338 | * @param string $title | |
339 | * @param string $pageTitle | |
6a488035 | 340 | */ |
00be9182 | 341 | public static function setTitle($title, $pageTitle = NULL) { |
5af8c999 | 342 | self::$title = $title; |
6a488035 TO |
343 | $config = CRM_Core_Config::singleton(); |
344 | return $config->userSystem->setTitle($title, $pageTitle); | |
345 | } | |
346 | ||
347 | /** | |
7890c493 | 348 | * Figures and sets the userContext. |
6a488035 | 349 | * |
7890c493 RS |
350 | * Uses the referer if valid else uses the default. |
351 | * | |
352 | * @param array $names | |
353 | * Refererer should match any str in this array. | |
354 | * @param string $default | |
355 | * (optional) The default userContext if no match found. | |
6a488035 | 356 | */ |
00be9182 | 357 | public static function setUserContext($names, $default = NULL) { |
6a488035 TO |
358 | $url = $default; |
359 | ||
360 | $session = CRM_Core_Session::singleton(); | |
361 | $referer = CRM_Utils_Array::value('HTTP_REFERER', $_SERVER); | |
362 | ||
363 | if ($referer && !empty($names)) { | |
364 | foreach ($names as $name) { | |
365 | if (strstr($referer, $name)) { | |
366 | $url = $referer; | |
367 | break; | |
368 | } | |
369 | } | |
370 | } | |
371 | ||
372 | if ($url) { | |
373 | $session->pushUserContext($url); | |
374 | } | |
375 | } | |
376 | ||
377 | /** | |
7890c493 | 378 | * Gets a class name for an object. |
6a488035 | 379 | * |
7890c493 RS |
380 | * @param object $object |
381 | * Object whose class name is needed. | |
6a488035 | 382 | * |
7890c493 RS |
383 | * @return string |
384 | * The class name of the object. | |
6a488035 | 385 | */ |
00be9182 | 386 | public static function getClassName($object) { |
6a488035 TO |
387 | return get_class($object); |
388 | } | |
389 | ||
390 | /** | |
7890c493 | 391 | * Redirect to another URL. |
6a488035 | 392 | * |
7890c493 RS |
393 | * @param string $url |
394 | * The URL to provide to the browser via the Location header. | |
6a488035 | 395 | */ |
00be9182 | 396 | public static function redirect($url = NULL) { |
6a488035 TO |
397 | if (!$url) { |
398 | $url = self::url('civicrm/dashboard', 'reset=1'); | |
399 | } | |
400 | ||
401 | // replace the & characters with & | |
402 | // this is kinda hackish but not sure how to do it right | |
403 | $url = str_replace('&', '&', $url); | |
0a94ab7d CW |
404 | |
405 | // If we are in a json context, respond appropriately | |
406 | if (CRM_Utils_Array::value('snippet', $_GET) === 'json') { | |
407 | CRM_Core_Page_AJAX::returnJsonResponse(array( | |
408 | 'status' => 'redirect', | |
409 | 'userContext' => $url, | |
410 | )); | |
411 | } | |
412 | ||
6a488035 TO |
413 | header('Location: ' . $url); |
414 | self::civiExit(); | |
415 | } | |
416 | ||
417 | /** | |
7890c493 RS |
418 | * Redirect to another URL using JavaScript. |
419 | * | |
420 | * Use an html based file with javascript embedded to redirect to another url | |
6a488035 TO |
421 | * This prevent the too many redirect errors emitted by various browsers |
422 | * | |
7890c493 RS |
423 | * @param string $url |
424 | * (optional) The destination URL. | |
425 | * @param string $title | |
426 | * (optional) The page title to use for the redirect page. | |
427 | * @param string $message | |
428 | * (optional) The message to provide in the body of the redirect page. | |
6a488035 | 429 | */ |
971d41b1 | 430 | public static function jsRedirect( |
e7292422 TO |
431 | $url = NULL, |
432 | $title = NULL, | |
6a488035 TO |
433 | $message = NULL |
434 | ) { | |
435 | if (!$url) { | |
436 | $url = self::url('civicrm/dashboard', 'reset=1'); | |
437 | } | |
438 | ||
439 | if (!$title) { | |
440 | $title = ts('CiviCRM task in progress'); | |
441 | } | |
442 | ||
443 | if (!$message) { | |
444 | $message = ts('A long running CiviCRM task is currently in progress. This message will be refreshed till the task is completed'); | |
445 | } | |
446 | ||
447 | // replace the & characters with & | |
448 | // this is kinda hackish but not sure how to do it right | |
449 | $url = str_replace('&', '&', $url); | |
450 | ||
451 | $template = CRM_Core_Smarty::singleton(); | |
452 | $template->assign('redirectURL', $url); | |
453 | $template->assign('title', $title); | |
454 | $template->assign('message', $message); | |
455 | ||
456 | $html = $template->fetch('CRM/common/redirectJS.tpl'); | |
457 | ||
458 | echo $html; | |
459 | ||
460 | self::civiExit(); | |
461 | } | |
462 | ||
463 | /** | |
7890c493 | 464 | * Append an additional breadcrumb tag to the existing breadcrumbs. |
6a488035 | 465 | * |
7890c493 | 466 | * @param $breadCrumbs |
6a488035 | 467 | */ |
00be9182 | 468 | public static function appendBreadCrumb($breadCrumbs) { |
6a488035 TO |
469 | $config = CRM_Core_Config::singleton(); |
470 | return $config->userSystem->appendBreadCrumb($breadCrumbs); | |
471 | } | |
472 | ||
473 | /** | |
7890c493 | 474 | * Reset an additional breadcrumb tag to the existing breadcrumb. |
6a488035 | 475 | */ |
00be9182 | 476 | public static function resetBreadCrumb() { |
6a488035 TO |
477 | $config = CRM_Core_Config::singleton(); |
478 | return $config->userSystem->resetBreadCrumb(); | |
479 | } | |
480 | ||
481 | /** | |
7890c493 | 482 | * Append a string to the head of the HTML file. |
6a488035 | 483 | * |
7890c493 | 484 | * @param string $bc |
6a488035 | 485 | */ |
00be9182 | 486 | public static function addHTMLHead($bc) { |
6a488035 TO |
487 | $config = CRM_Core_Config::singleton(); |
488 | return $config->userSystem->addHTMLHead($bc); | |
489 | } | |
490 | ||
491 | /** | |
7890c493 | 492 | * Determine the post URL for a form |
6a488035 | 493 | * |
7890c493 RS |
494 | * @param $action |
495 | * The default action if one is pre-specified. | |
6a488035 | 496 | * |
7890c493 RS |
497 | * @return string |
498 | * The URL to post the form. | |
6a488035 | 499 | */ |
00be9182 | 500 | public static function postURL($action) { |
6a488035 TO |
501 | $config = CRM_Core_Config::singleton(); |
502 | return $config->userSystem->postURL($action); | |
503 | } | |
504 | ||
505 | /** | |
7890c493 | 506 | * Rewrite various system URLs to https. |
6a488035 | 507 | */ |
00be9182 | 508 | public static function mapConfigToSSL() { |
6a488035 | 509 | $config = CRM_Core_Config::singleton(); |
7113f506 | 510 | $config->userFrameworkResourceURL = str_replace('http://', 'https://', $config->userFrameworkResourceURL); |
6a488035 | 511 | $config->resourceBase = $config->userFrameworkResourceURL; |
7113f506 | 512 | |
353ffa53 | 513 | if (!empty($config->extensionsURL)) { |
7113f506 ML |
514 | $config->extensionsURL = str_replace('http://', 'https://', $config->extensionsURL); |
515 | } | |
516 | ||
6a488035 TO |
517 | return $config->userSystem->mapConfigToSSL(); |
518 | } | |
519 | ||
520 | /** | |
7890c493 | 521 | * Get the base URL of the system. |
6a488035 TO |
522 | * |
523 | * @return string | |
6a488035 | 524 | */ |
00be9182 | 525 | public static function baseURL() { |
6a488035 TO |
526 | $config = CRM_Core_Config::singleton(); |
527 | return $config->userFrameworkBaseURL; | |
528 | } | |
529 | ||
7890c493 | 530 | /** |
7890c493 | 531 | */ |
00be9182 | 532 | public static function authenticateAbort($message, $abort) { |
6a488035 TO |
533 | if ($abort) { |
534 | echo $message; | |
535 | self::civiExit(0); | |
536 | } | |
537 | else { | |
538 | return FALSE; | |
539 | } | |
540 | } | |
541 | ||
7890c493 RS |
542 | /** |
543 | * @param bool $abort | |
544 | * (optional) Whether to exit; defaults to true. | |
77b97be7 EM |
545 | * |
546 | * @return bool | |
7890c493 | 547 | */ |
00be9182 | 548 | public static function authenticateKey($abort = TRUE) { |
6a488035 TO |
549 | // also make sure the key is sent and is valid |
550 | $key = trim(CRM_Utils_Array::value('key', $_REQUEST)); | |
551 | ||
552 | $docAdd = "More info at:" . CRM_Utils_System::docURL2("Managing Scheduled Jobs", TRUE, NULL, NULL, NULL, "wiki"); | |
553 | ||
554 | if (!$key) { | |
0af0e4c9 DL |
555 | return self::authenticateAbort( |
556 | "ERROR: You need to send a valid key to execute this file. " . $docAdd . "\n", | |
6a488035 TO |
557 | $abort |
558 | ); | |
559 | } | |
560 | ||
561 | $siteKey = defined('CIVICRM_SITE_KEY') ? CIVICRM_SITE_KEY : NULL; | |
562 | ||
0af0e4c9 DL |
563 | if (!$siteKey || empty($siteKey)) { |
564 | return self::authenticateAbort( | |
565 | "ERROR: You need to set a valid site key in civicrm.settings.php. " . $docAdd . "\n", | |
6a488035 TO |
566 | $abort |
567 | ); | |
568 | } | |
569 | ||
570 | if (strlen($siteKey) < 8) { | |
0af0e4c9 DL |
571 | return self::authenticateAbort( |
572 | "ERROR: Site key needs to be greater than 7 characters in civicrm.settings.php. " . $docAdd . "\n", | |
6a488035 TO |
573 | $abort |
574 | ); | |
575 | } | |
576 | ||
577 | if ($key !== $siteKey) { | |
0af0e4c9 DL |
578 | return self::authenticateAbort( |
579 | "ERROR: Invalid key value sent. " . $docAdd . "\n", | |
6a488035 TO |
580 | $abort |
581 | ); | |
582 | } | |
583 | ||
584 | return TRUE; | |
585 | } | |
586 | ||
7890c493 | 587 | /** |
f4aaa82a EM |
588 | * @param bool $abort |
589 | * @param null $name | |
590 | * @param null $pass | |
591 | * @param bool $storeInSession | |
592 | * @param bool $loadCMSBootstrap | |
593 | * @param bool $requireKey | |
594 | * | |
7890c493 | 595 | * @return bool |
7890c493 | 596 | */ |
00be9182 | 597 | public static function authenticateScript($abort = TRUE, $name = NULL, $pass = NULL, $storeInSession = TRUE, $loadCMSBootstrap = TRUE, $requireKey = TRUE) { |
7890c493 | 598 | // auth to make sure the user has a login/password to do a shell operation |
6a488035 TO |
599 | // later on we'll link this to acl's |
600 | if (!$name) { | |
601 | $name = trim(CRM_Utils_Array::value('name', $_REQUEST)); | |
602 | $pass = trim(CRM_Utils_Array::value('pass', $_REQUEST)); | |
603 | } | |
604 | ||
605 | // its ok to have an empty password | |
606 | if (!$name) { | |
0af0e4c9 DL |
607 | return self::authenticateAbort( |
608 | "ERROR: You need to send a valid user name and password to execute this file\n", | |
6a488035 TO |
609 | $abort |
610 | ); | |
611 | } | |
612 | ||
bec3fc7c | 613 | if ($requireKey && !self::authenticateKey($abort)) { |
6a488035 TO |
614 | return FALSE; |
615 | } | |
616 | ||
617 | $result = CRM_Utils_System::authenticate($name, $pass, $loadCMSBootstrap); | |
618 | if (!$result) { | |
0af0e4c9 DL |
619 | return self::authenticateAbort( |
620 | "ERROR: Invalid username and/or password\n", | |
6a488035 TO |
621 | $abort |
622 | ); | |
623 | } | |
624 | elseif ($storeInSession) { | |
625 | // lets store contact id and user id in session | |
626 | list($userID, $ufID, $randomNumber) = $result; | |
627 | if ($userID && $ufID) { | |
bec3fc7c | 628 | $config = CRM_Core_Config::singleton(); |
481a74f4 | 629 | $config->userSystem->setUserSession(array($userID, $ufID)); |
6a488035 TO |
630 | } |
631 | else { | |
0af0e4c9 DL |
632 | return self::authenticateAbort( |
633 | "ERROR: Unexpected error, could not match userID and contactID", | |
6a488035 TO |
634 | $abort |
635 | ); | |
636 | } | |
637 | } | |
638 | ||
639 | return $result; | |
640 | } | |
641 | ||
642 | /** | |
7890c493 | 643 | * Authenticate the user against the uf db. |
6a488035 | 644 | * |
7890c493 RS |
645 | * In case of succesful authentication, returns an array consisting of |
646 | * (contactID, ufID, unique string). Returns FALSE if authentication is | |
647 | * unsuccessful. | |
6a488035 | 648 | * |
7890c493 RS |
649 | * @param string $name |
650 | * The username. | |
651 | * @param string $password | |
652 | * The password. | |
653 | * @param bool $loadCMSBootstrap | |
654 | * @param $realPath | |
655 | * | |
656 | * @return false|array | |
6a488035 | 657 | */ |
00be9182 | 658 | public static function authenticate($name, $password, $loadCMSBootstrap = FALSE, $realPath = NULL) { |
6a488035 | 659 | $config = CRM_Core_Config::singleton(); |
c1e1e8b8 | 660 | |
7890c493 RS |
661 | /* Before we do any loading, let's start the session and write to it. |
662 | * We typically call authenticate only when we need to bootstrap the CMS | |
663 | * directly via Civi and hence bypass the normal CMS auth and bootstrap | |
664 | * process typically done in CLI and cron scripts. See: CRM-12648 | |
665 | */ | |
c1e1e8b8 | 666 | $session = CRM_Core_Session::singleton(); |
481a74f4 | 667 | $session->set('civicrmInitSession', TRUE); |
c1e1e8b8 DL |
668 | |
669 | $dbDrupal = DB::connect($config->userFrameworkDSN); | |
6a488035 TO |
670 | return $config->userSystem->authenticate($name, $password, $loadCMSBootstrap, $realPath); |
671 | } | |
672 | ||
673 | /** | |
7890c493 | 674 | * Set a message in the UF to display to a user. |
6a488035 | 675 | * |
7890c493 RS |
676 | * @param string $message |
677 | * The message to set. | |
6a488035 | 678 | */ |
00be9182 | 679 | public static function setUFMessage($message) { |
6a488035 TO |
680 | $config = CRM_Core_Config::singleton(); |
681 | return $config->userSystem->setMessage($message); | |
682 | } | |
683 | ||
684 | ||
7890c493 RS |
685 | /** |
686 | * Determine whether a value is null-ish. | |
687 | * | |
688 | * @param $value | |
689 | * The value to check for null. | |
690 | * @return bool | |
7890c493 | 691 | */ |
00be9182 | 692 | public static function isNull($value) { |
6a488035 TO |
693 | // FIXME: remove $value = 'null' string test when we upgrade our DAO code to handle passing null in a better way. |
694 | if (!isset($value) || $value === NULL || $value === '' || $value === 'null') { | |
695 | return TRUE; | |
696 | } | |
697 | if (is_array($value)) { | |
26659f0c | 698 | // @todo Reuse of the $value variable = asking for trouble. |
6a488035 TO |
699 | foreach ($value as $key => $value) { |
700 | if (!self::isNull($value)) { | |
701 | return FALSE; | |
702 | } | |
703 | } | |
704 | return TRUE; | |
705 | } | |
706 | return FALSE; | |
707 | } | |
708 | ||
7890c493 RS |
709 | /** |
710 | * Obscure all but the last few digits of a credit card number. | |
711 | * | |
712 | * @param string $number | |
713 | * The credit card number to obscure. | |
714 | * @param int $keep | |
715 | * (optional) The number of digits to preserve unmodified. | |
716 | * @return string | |
717 | * The obscured credit card number. | |
7890c493 | 718 | */ |
00be9182 | 719 | public static function mungeCreditCard($number, $keep = 4) { |
6a488035 TO |
720 | $number = trim($number); |
721 | if (empty($number)) { | |
722 | return NULL; | |
723 | } | |
724 | $replace = str_repeat('*', strlen($number) - $keep); | |
725 | return substr_replace($number, $replace, 0, -$keep); | |
726 | } | |
727 | ||
414e3596 | 728 | /** |
7890c493 RS |
729 | * Determine which PHP modules are loaded. |
730 | * | |
731 | * @return array | |
7890c493 | 732 | */ |
fcc5922d | 733 | public static function parsePHPModules() { |
6a488035 TO |
734 | ob_start(); |
735 | phpinfo(INFO_MODULES); | |
736 | $s = ob_get_contents(); | |
737 | ob_end_clean(); | |
738 | ||
353ffa53 TO |
739 | $s = strip_tags($s, '<h2><th><td>'); |
740 | $s = preg_replace('/<th[^>]*>([^<]+)<\/th>/', "<info>\\1</info>", $s); | |
741 | $s = preg_replace('/<td[^>]*>([^<]+)<\/td>/', "<info>\\1</info>", $s); | |
742 | $vTmp = preg_split('/(<h2>[^<]+<\/h2>)/', $s, -1, PREG_SPLIT_DELIM_CAPTURE); | |
6a488035 TO |
743 | $vModules = array(); |
744 | for ($i = 1; $i < count($vTmp); $i++) { | |
745 | if (preg_match('/<h2>([^<]+)<\/h2>/', $vTmp[$i], $vMat)) { | |
746 | $vName = trim($vMat[1]); | |
747 | $vTmp2 = explode("\n", $vTmp[$i + 1]); | |
e7292422 | 748 | foreach ($vTmp2 as $vOne) { |
353ffa53 | 749 | $vPat = '<info>([^<]+)<\/info>'; |
6a488035 TO |
750 | $vPat3 = "/$vPat\s*$vPat\s*$vPat/"; |
751 | $vPat2 = "/$vPat\s*$vPat/"; | |
752 | // 3cols | |
753 | if (preg_match($vPat3, $vOne, $vMat)) { | |
754 | $vModules[$vName][trim($vMat[1])] = array(trim($vMat[2]), trim($vMat[3])); | |
755 | // 2cols | |
756 | } | |
757 | elseif (preg_match($vPat2, $vOne, $vMat)) { | |
758 | $vModules[$vName][trim($vMat[1])] = trim($vMat[2]); | |
759 | } | |
760 | } | |
761 | } | |
762 | } | |
763 | return $vModules; | |
764 | } | |
765 | ||
7890c493 RS |
766 | /** |
767 | * Get a setting from a loaded PHP module. | |
7890c493 | 768 | */ |
fcc5922d | 769 | public static function getModuleSetting($pModuleName, $pSetting) { |
6a488035 TO |
770 | $vModules = self::parsePHPModules(); |
771 | return $vModules[$pModuleName][$pSetting]; | |
772 | } | |
773 | ||
7890c493 RS |
774 | /** |
775 | * @param $title | |
776 | * (optional) | |
f4aaa82a EM |
777 | * |
778 | * @return mixed|string | |
7890c493 | 779 | */ |
00be9182 | 780 | public static function memory($title = NULL) { |
6a488035 TO |
781 | static $pid = NULL; |
782 | if (!$pid) { | |
783 | $pid = posix_getpid(); | |
784 | } | |
785 | ||
786 | $memory = str_replace("\n", '', shell_exec("ps -p" . $pid . " -o rss=")); | |
787 | $memory .= ", " . time(); | |
788 | if ($title) { | |
789 | CRM_Core_Error::debug_var($title, $memory); | |
790 | } | |
791 | return $memory; | |
792 | } | |
793 | ||
7890c493 RS |
794 | /** |
795 | * @param string $name | |
796 | * @param string $mimeType | |
797 | * @param $buffer | |
798 | * @param string $ext | |
799 | * @param bool $output | |
f4aaa82a | 800 | * @param string $disposition |
7890c493 | 801 | */ |
971d41b1 | 802 | public static function download( |
a3e55d9c | 803 | $name, $mimeType, &$buffer, |
6a488035 | 804 | $ext = NULL, |
8f176433 M |
805 | $output = TRUE, |
806 | $disposition = 'attachment' | |
6a488035 TO |
807 | ) { |
808 | $now = gmdate('D, d M Y H:i:s') . ' GMT'; | |
809 | ||
810 | header('Content-Type: ' . $mimeType); | |
811 | header('Expires: ' . $now); | |
812 | ||
813 | // lem9 & loic1: IE need specific headers | |
814 | $isIE = strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE'); | |
815 | if ($ext) { | |
816 | $fileString = "filename=\"{$name}.{$ext}\""; | |
817 | } | |
818 | else { | |
819 | $fileString = "filename=\"{$name}\""; | |
820 | } | |
821 | if ($isIE) { | |
822 | header("Content-Disposition: inline; $fileString"); | |
823 | header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); | |
824 | header('Pragma: public'); | |
825 | } | |
826 | else { | |
8f176433 | 827 | header("Content-Disposition: $disposition; $fileString"); |
6a488035 TO |
828 | header('Pragma: no-cache'); |
829 | } | |
830 | ||
831 | if ($output) { | |
832 | print $buffer; | |
833 | self::civiExit(); | |
834 | } | |
835 | } | |
836 | ||
7890c493 | 837 | /** |
9911500f RS |
838 | * Gather and print (and possibly log) amount of used memory. |
839 | * | |
840 | * @param string $title | |
841 | * @param bool $log | |
842 | * (optional) Whether to log the memory usage information. | |
7890c493 | 843 | */ |
00be9182 | 844 | public static function xMemory($title = NULL, $log = FALSE) { |
e7292422 | 845 | $mem = (float ) xdebug_memory_usage() / (float ) (1024); |
6a488035 TO |
846 | $mem = number_format($mem, 5) . ", " . time(); |
847 | if ($log) { | |
848 | echo "<p>$title: $mem<p>"; | |
849 | flush(); | |
850 | CRM_Core_Error::debug_var($title, $mem); | |
851 | } | |
852 | else { | |
853 | echo "<p>$title: $mem<p>"; | |
854 | flush(); | |
855 | } | |
856 | } | |
857 | ||
7890c493 | 858 | /** |
9911500f RS |
859 | * Take a URL (or partial URL) and make it better. |
860 | * | |
861 | * Currently, URLs pass straight through unchanged unless they are "seriously | |
862 | * malformed" (see http://us2.php.net/parse_url). | |
863 | * | |
7890c493 RS |
864 | * @param string $url |
865 | * The URL to operate on. | |
9911500f RS |
866 | * @return string |
867 | * The fixed URL. | |
7890c493 | 868 | */ |
00be9182 | 869 | public static function fixURL($url) { |
6a488035 TO |
870 | $components = parse_url($url); |
871 | ||
872 | if (!$components) { | |
873 | return NULL; | |
874 | } | |
875 | ||
876 | // at some point we'll add code here to make sure the url is not | |
877 | // something that will mess up up, so we need to clean it up here | |
878 | return $url; | |
879 | } | |
880 | ||
881 | /** | |
7890c493 | 882 | * Make sure a callback is valid in the current context. |
6a488035 | 883 | * |
7890c493 RS |
884 | * @param string $callback |
885 | * Name of the function to check. | |
6a488035 | 886 | * |
7890c493 | 887 | * @return bool |
6a488035 | 888 | */ |
00be9182 | 889 | public static function validCallback($callback) { |
6a488035 TO |
890 | if (self::$_callbacks === NULL) { |
891 | self::$_callbacks = array(); | |
892 | } | |
893 | ||
894 | if (!array_key_exists($callback, self::$_callbacks)) { | |
895 | if (strpos($callback, '::') !== FALSE) { | |
896 | list($className, $methodName) = explode('::', $callback); | |
897 | $fileName = str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; | |
898 | // ignore errors if any | |
e7292422 | 899 | @include_once $fileName; |
6a488035 TO |
900 | if (!class_exists($className)) { |
901 | self::$_callbacks[$callback] = FALSE; | |
902 | } | |
903 | else { | |
904 | // instantiate the class | |
905 | $object = new $className(); | |
906 | if (!method_exists($object, $methodName)) { | |
907 | self::$_callbacks[$callback] = FALSE; | |
908 | } | |
909 | else { | |
910 | self::$_callbacks[$callback] = TRUE; | |
911 | } | |
912 | } | |
913 | } | |
914 | else { | |
915 | self::$_callbacks[$callback] = function_exists($callback); | |
916 | } | |
917 | } | |
918 | return self::$_callbacks[$callback]; | |
919 | } | |
920 | ||
921 | /** | |
7890c493 RS |
922 | * Like PHP's built-in explode(), but always return an array of $limit items. |
923 | * | |
924 | * This serves as a wrapper to the PHP explode() function. In the event that | |
925 | * PHP's explode() returns an array with fewer than $limit elements, pad | |
926 | * the end of the array with NULLs. | |
927 | * | |
928 | * @param string $separator | |
929 | * @param string $string | |
930 | * @param int $limit | |
931 | * @return string[] | |
6a488035 | 932 | */ |
00be9182 | 933 | public static function explode($separator, $string, $limit) { |
6a488035 TO |
934 | $result = explode($separator, $string, $limit); |
935 | for ($i = count($result); $i < $limit; $i++) { | |
936 | $result[$i] = NULL; | |
937 | } | |
938 | return $result; | |
939 | } | |
940 | ||
7890c493 RS |
941 | /** |
942 | * @param string $url | |
943 | * The URL to check. | |
944 | * @param bool $addCookie | |
945 | * (optional) | |
f4aaa82a EM |
946 | * |
947 | * @return mixed | |
7890c493 | 948 | */ |
00be9182 | 949 | public static function checkURL($url, $addCookie = FALSE) { |
6a488035 TO |
950 | // make a GET request to $url |
951 | $ch = curl_init($url); | |
952 | if ($addCookie) { | |
953 | curl_setopt($ch, CURLOPT_COOKIE, http_build_query($_COOKIE)); | |
954 | } | |
955 | // it's quite alright to use a self-signed cert | |
956 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); | |
957 | ||
958 | // lets capture the return stuff rather than echo | |
481a74f4 | 959 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); |
6a488035 | 960 | |
8d1adeef NG |
961 | // CRM-13227, CRM-14744: only return the SSL error status |
962 | return (curl_exec($ch) !== FALSE); | |
6a488035 TO |
963 | } |
964 | ||
7890c493 RS |
965 | /** |
966 | * Assert that we are running on a particular PHP version. | |
967 | * | |
968 | * @param int $ver | |
969 | * The major version of PHP that is required. | |
970 | * @param bool $abort | |
414e3596 | 971 | * (optional) Whether to fatally abort if the version requirement is not |
7890c493 RS |
972 | * met. Defaults to TRUE. |
973 | * @return bool | |
974 | * Returns TRUE if the requirement is met, FALSE if the requirement is not | |
9911500f RS |
975 | * met and we're not aborting due to the failed requirement. If $abort is |
976 | * TRUE and the requirement fails, this function does not return. | |
7890c493 | 977 | */ |
00be9182 | 978 | public static function checkPHPVersion($ver = 5, $abort = TRUE) { |
6a488035 TO |
979 | $phpVersion = substr(PHP_VERSION, 0, 1); |
980 | if ($phpVersion >= $ver) { | |
981 | return TRUE; | |
982 | } | |
983 | ||
984 | if ($abort) { | |
985 | CRM_Core_Error::fatal(ts('This feature requires PHP Version %1 or greater', | |
353ffa53 TO |
986 | array(1 => $ver) |
987 | )); | |
6a488035 TO |
988 | } |
989 | return FALSE; | |
990 | } | |
991 | ||
7890c493 | 992 | /** |
f4aaa82a EM |
993 | * @param $string |
994 | * @param bool $encode | |
995 | * | |
7890c493 | 996 | * @return string |
7890c493 | 997 | */ |
00be9182 | 998 | public static function formatWikiURL($string, $encode = FALSE) { |
6a488035 TO |
999 | $items = explode(' ', trim($string), 2); |
1000 | if (count($items) == 2) { | |
1001 | $title = $items[1]; | |
1002 | } | |
1003 | else { | |
1004 | $title = $items[0]; | |
1005 | } | |
1006 | ||
1007 | // fix for CRM-4044 | |
1008 | $url = $encode ? self::urlEncode($items[0]) : $items[0]; | |
1009 | return "<a href=\"$url\">$title</a>"; | |
1010 | } | |
1011 | ||
7890c493 RS |
1012 | /** |
1013 | * @param string $url | |
f4aaa82a EM |
1014 | * |
1015 | * @return null|string | |
7890c493 | 1016 | */ |
00be9182 | 1017 | public static function urlEncode($url) { |
6a488035 TO |
1018 | $items = parse_url($url); |
1019 | if ($items === FALSE) { | |
1020 | return NULL; | |
1021 | } | |
1022 | ||
a7488080 | 1023 | if (empty($items['query'])) { |
6a488035 TO |
1024 | return $url; |
1025 | } | |
1026 | ||
1027 | $items['query'] = urlencode($items['query']); | |
1028 | ||
1029 | $url = $items['scheme'] . '://'; | |
a7488080 | 1030 | if (!empty($items['user'])) { |
6a488035 TO |
1031 | $url .= "{$items['user']}:{$items['pass']}@"; |
1032 | } | |
1033 | ||
1034 | $url .= $items['host']; | |
a7488080 | 1035 | if (!empty($items['port'])) { |
6a488035 TO |
1036 | $url .= ":{$items['port']}"; |
1037 | } | |
1038 | ||
1039 | $url .= "{$items['path']}?{$items['query']}"; | |
a7488080 | 1040 | if (!empty($items['fragment'])) { |
6a488035 TO |
1041 | $url .= "#{$items['fragment']}"; |
1042 | } | |
1043 | ||
1044 | return $url; | |
1045 | } | |
1046 | ||
1047 | /** | |
7890c493 | 1048 | * Return the running civicrm version. |
6a488035 | 1049 | * |
7890c493 RS |
1050 | * @return string |
1051 | * civicrm version | |
6a488035 | 1052 | */ |
00be9182 | 1053 | public static function version() { |
6a488035 TO |
1054 | static $version; |
1055 | ||
1056 | if (!$version) { | |
1057 | $verFile = implode(DIRECTORY_SEPARATOR, | |
1058 | array(dirname(__FILE__), '..', '..', 'civicrm-version.php') | |
1059 | ); | |
1060 | if (file_exists($verFile)) { | |
e7292422 | 1061 | require_once $verFile; |
6a488035 TO |
1062 | if (function_exists('civicrmVersion')) { |
1063 | $info = civicrmVersion(); | |
1064 | $version = $info['version']; | |
1065 | } | |
1066 | } | |
1067 | else { | |
1068 | // svn installs don't have version.txt by default. In that case version.xml should help - | |
1069 | $verFile = implode(DIRECTORY_SEPARATOR, | |
1070 | array(dirname(__FILE__), '..', '..', 'xml', 'version.xml') | |
1071 | ); | |
1072 | if (file_exists($verFile)) { | |
353ffa53 TO |
1073 | $str = file_get_contents($verFile); |
1074 | $xmlObj = simplexml_load_string($str); | |
6a488035 TO |
1075 | $version = (string) $xmlObj->version_no; |
1076 | } | |
1077 | } | |
1078 | ||
1079 | // pattern check | |
1080 | if (!CRM_Utils_System::isVersionFormatValid($version)) { | |
1081 | CRM_Core_Error::fatal('Unknown codebase version.'); | |
1082 | } | |
1083 | } | |
1084 | ||
1085 | return $version; | |
1086 | } | |
1087 | ||
7890c493 RS |
1088 | /** |
1089 | * Determines whether a string is a valid CiviCRM version string. | |
1090 | * | |
1091 | * @param string $version | |
1092 | * Version string to be checked. | |
1093 | * @return bool | |
7890c493 | 1094 | */ |
00be9182 | 1095 | public static function isVersionFormatValid($version) { |
6a488035 TO |
1096 | return preg_match("/^(\d{1,2}\.){2,3}(\d{1,2}|(alpha|beta)\d{1,2})(\.upgrade)?$/", $version); |
1097 | } | |
1098 | ||
7890c493 RS |
1099 | /** |
1100 | * Wraps or emulates PHP's getallheaders() function. | |
7890c493 | 1101 | */ |
00be9182 | 1102 | public static function getAllHeaders() { |
6a488035 TO |
1103 | if (function_exists('getallheaders')) { |
1104 | return getallheaders(); | |
1105 | } | |
1106 | ||
1107 | // emulate get all headers | |
1108 | // http://www.php.net/manual/en/function.getallheaders.php#66335 | |
1109 | $headers = array(); | |
1110 | foreach ($_SERVER as $name => $value) { | |
1111 | if (substr($name, 0, 5) == 'HTTP_') { | |
1112 | $headers[str_replace(' ', | |
1113 | '-', | |
1114 | ucwords(strtolower(str_replace('_', | |
353ffa53 TO |
1115 | ' ', |
1116 | substr($name, 5) | |
1117 | ) | |
1118 | )) | |
6a488035 TO |
1119 | )] = $value; |
1120 | } | |
1121 | } | |
1122 | return $headers; | |
1123 | } | |
1124 | ||
7890c493 | 1125 | /** |
7890c493 | 1126 | */ |
00be9182 | 1127 | public static function getRequestHeaders() { |
6a488035 TO |
1128 | if (function_exists('apache_request_headers')) { |
1129 | return apache_request_headers(); | |
1130 | } | |
1131 | else { | |
1132 | return $_SERVER; | |
1133 | } | |
1134 | } | |
1135 | ||
1136 | /** | |
7890c493 RS |
1137 | * Determine whether this is an SSL request. |
1138 | * | |
1139 | * Note that we inline this function in install/civicrm.php, so if you change | |
1140 | * this function, please go and change the code in the install script as well. | |
6a488035 | 1141 | */ |
e7292422 | 1142 | public static function isSSL() { |
6a488035 TO |
1143 | return |
1144 | (isset($_SERVER['HTTPS']) && | |
1145 | !empty($_SERVER['HTTPS']) && | |
688ad538 | 1146 | strtolower($_SERVER['HTTPS']) != 'off') ? TRUE : FALSE; |
6a488035 TO |
1147 | } |
1148 | ||
7890c493 | 1149 | /** |
7890c493 | 1150 | */ |
00be9182 | 1151 | public static function redirectToSSL($abort = FALSE) { |
6a488035 TO |
1152 | $config = CRM_Core_Config::singleton(); |
1153 | $req_headers = self::getRequestHeaders(); | |
1154 | if (CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'enableSSL') && | |
1155 | !self::isSSL() && | |
1156 | strtolower(CRM_Utils_Array::value('X_FORWARDED_PROTO', $req_headers)) != 'https' | |
1157 | ) { | |
1158 | // ensure that SSL is enabled on a civicrm url (for cookie reasons etc) | |
1159 | $url = "https://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"; | |
1160 | if (!self::checkURL($url, TRUE)) { | |
1161 | if ($abort) { | |
1162 | CRM_Core_Error::fatal('HTTPS is not set up on this machine'); | |
1163 | } | |
1164 | else { | |
e7292422 | 1165 | CRM_Core_Session::setStatus(ts('HTTPS is not set up on this machine'), ts('Warning'), 'alert'); |
6a488035 TO |
1166 | // admin should be the only one following this |
1167 | // since we dont want the user stuck in a bad place | |
1168 | return; | |
1169 | } | |
1170 | } | |
1171 | CRM_Utils_System::redirect($url); | |
1172 | } | |
1173 | } | |
1174 | ||
d424ffde | 1175 | /** |
5df36634 PJ |
1176 | * Get logged in user's IP address. |
1177 | * | |
7890c493 RS |
1178 | * Get IP address from HTTP REMOTE_ADDR header. If the CMS is Drupal then use |
1179 | * the Drupal function as this also handles reverse proxies (based on proper | |
1180 | * configuration in settings.php) | |
5df36634 | 1181 | * |
7890c493 RS |
1182 | * @param bool $strictIPV4 |
1183 | * (optional) Whether to return only IPv4 addresses. | |
1184 | * | |
1185 | * @return string | |
1186 | * IP address of logged in user. | |
5df36634 | 1187 | */ |
00be9182 | 1188 | public static function ipAddress($strictIPV4 = TRUE) { |
6a488035 TO |
1189 | $address = CRM_Utils_Array::value('REMOTE_ADDR', $_SERVER); |
1190 | ||
1191 | $config = CRM_Core_Config::singleton(); | |
414e3596 | 1192 | if ($config->userSystem->is_drupal && function_exists('ip_address')) { |
1193 | //drupal function handles the server being behind a proxy securely. We still have legacy ipn methods | |
1194 | // that reach this point without bootstrapping hence the check that the fn exists | |
e7292422 | 1195 | $address = ip_address(); |
6a488035 TO |
1196 | } |
1197 | ||
1198 | // hack for safari | |
1199 | if ($address == '::1') { | |
1200 | $address = '127.0.0.1'; | |
1201 | } | |
1202 | ||
5df36634 PJ |
1203 | // when we need to have strictly IPV4 ip address |
1204 | // convert ipV6 to ipV4 | |
1205 | if ($strictIPV4) { | |
1206 | // this converts 'IPV4 mapped IPV6 address' to IPV4 | |
1207 | if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && strstr($address, '::ffff:')) { | |
1208 | $address = ltrim($address, '::ffff:'); | |
1209 | } | |
1210 | } | |
1211 | ||
6a488035 TO |
1212 | return $address; |
1213 | } | |
1214 | ||
1215 | /** | |
7890c493 | 1216 | * Get the referring / previous page URL. |
6a488035 | 1217 | * |
7890c493 RS |
1218 | * @return string |
1219 | * The previous page URL | |
6a488035 | 1220 | */ |
00be9182 | 1221 | public static function refererPath() { |
6a488035 TO |
1222 | return CRM_Utils_Array::value('HTTP_REFERER', $_SERVER); |
1223 | } | |
1224 | ||
1225 | /** | |
7890c493 | 1226 | * Get the documentation base URL. |
6a488035 | 1227 | * |
7890c493 RS |
1228 | * @return string |
1229 | * Base URL of the CRM documentation. | |
6a488035 | 1230 | */ |
00be9182 | 1231 | public static function getDocBaseURL() { |
6a488035 TO |
1232 | // FIXME: move this to configuration at some stage |
1233 | return 'http://book.civicrm.org/'; | |
1234 | } | |
1235 | ||
1236 | /** | |
7890c493 | 1237 | * Returns wiki (alternate) documentation URL base. |
6a488035 | 1238 | * |
a6c01b45 CW |
1239 | * @return string |
1240 | * documentation url | |
6a488035 | 1241 | */ |
00be9182 | 1242 | public static function getWikiBaseURL() { |
6a488035 TO |
1243 | // FIXME: move this to configuration at some stage |
1244 | return 'http://wiki.civicrm.org/confluence/display/CRMDOC/'; | |
1245 | } | |
1246 | ||
1247 | /** | |
1248 | * Returns URL or link to documentation page, based on provided parameters. | |
7890c493 | 1249 | * |
6a488035 | 1250 | * For use in PHP code. |
7890c493 RS |
1251 | * WARNING: Always returns URL, if ts function is not defined ($URLonly has |
1252 | * no effect). | |
6a488035 | 1253 | * |
7890c493 RS |
1254 | * @param string $page |
1255 | * Title of documentation wiki page. | |
77855840 | 1256 | * @param bool $URLonly |
7890c493 RS |
1257 | * (optional) Whether to return URL only or full HTML link (default). |
1258 | * @param string $text | |
1259 | * (optional) Text of HTML link (no effect if $URLonly = false). | |
1260 | * @param string $title | |
1261 | * (optional) Tooltip text for HTML link (no effect if $URLonly = false) | |
1262 | * @param string $style | |
1263 | * (optional) Style attribute value for HTML link (no effect if $URLonly = false) | |
6a488035 | 1264 | * |
f4aaa82a EM |
1265 | * @param null $resource |
1266 | * | |
7890c493 RS |
1267 | * @return string |
1268 | * URL or link to documentation page, based on provided parameters. | |
6a488035 | 1269 | */ |
00be9182 | 1270 | public static function docURL2($page, $URLonly = FALSE, $text = NULL, $title = NULL, $style = NULL, $resource = NULL) { |
6a488035 TO |
1271 | // if ts function doesn't exist, it means that CiviCRM hasn't been fully initialised yet - |
1272 | // return just the URL, no matter what other parameters are defined | |
1273 | if (!function_exists('ts')) { | |
1274 | if ($resource == 'wiki') { | |
e7292422 | 1275 | $docBaseURL = self::getWikiBaseURL(); |
0db6c3e1 TO |
1276 | } |
1277 | else { | |
6a488035 TO |
1278 | $docBaseURL = self::getDocBaseURL(); |
1279 | } | |
1280 | return $docBaseURL . str_replace(' ', '+', $page); | |
1281 | } | |
1282 | else { | |
1283 | $params = array( | |
1284 | 'page' => $page, | |
1285 | 'URLonly' => $URLonly, | |
1286 | 'text' => $text, | |
1287 | 'title' => $title, | |
1288 | 'style' => $style, | |
1289 | 'resource' => $resource, | |
1290 | ); | |
1291 | return self::docURL($params); | |
1292 | } | |
1293 | } | |
1294 | ||
1295 | /** | |
1296 | * Returns URL or link to documentation page, based on provided parameters. | |
7890c493 | 1297 | * |
6a488035 TO |
1298 | * For use in templates code. |
1299 | * | |
7890c493 RS |
1300 | * @param array $params |
1301 | * An array of parameters (see CRM_Utils_System::docURL2 method for names) | |
6a488035 | 1302 | * |
971d41b1 | 1303 | * @return string|void |
7890c493 | 1304 | * URL or link to documentation page, based on provided parameters. |
6a488035 | 1305 | */ |
00be9182 | 1306 | public static function docURL($params) { |
6a488035 TO |
1307 | |
1308 | if (!isset($params['page'])) { | |
1309 | return; | |
1310 | } | |
1311 | ||
1312 | if (CRM_Utils_Array::value('resource', $params) == 'wiki') { | |
1313 | $docBaseURL = self::getWikiBaseURL(); | |
0db6c3e1 TO |
1314 | } |
1315 | else { | |
6a488035 TO |
1316 | $docBaseURL = self::getDocBaseURL(); |
1317 | } | |
1318 | ||
1319 | if (!isset($params['title']) or $params['title'] === NULL) { | |
1320 | $params['title'] = ts('Opens documentation in a new window.'); | |
1321 | } | |
1322 | ||
1323 | if (!isset($params['text']) or $params['text'] === NULL) { | |
1324 | $params['text'] = ts('(learn more...)'); | |
1325 | } | |
1326 | ||
1327 | if (!isset($params['style']) || $params['style'] === NULL) { | |
1328 | $style = ''; | |
1329 | } | |
1330 | else { | |
1331 | $style = "style=\"{$params['style']}\""; | |
1332 | } | |
1333 | ||
1334 | $link = $docBaseURL . str_replace(' ', '+', $params['page']); | |
1335 | ||
1336 | if (isset($params['URLonly']) && $params['URLonly'] == TRUE) { | |
1337 | return $link; | |
1338 | } | |
1339 | else { | |
16e71c83 | 1340 | return "<a href=\"{$link}\" $style target=\"_blank\" class=\"crm-doc-link no-popup\" title=\"{$params['title']}\">{$params['text']}</a>"; |
6a488035 TO |
1341 | } |
1342 | } | |
1343 | ||
1344 | /** | |
1345 | * Get the locale set in the hosting CMS | |
1346 | * | |
7890c493 RS |
1347 | * @return string |
1348 | * The used locale or null for none. | |
6a488035 | 1349 | */ |
00be9182 | 1350 | public static function getUFLocale() { |
6a488035 TO |
1351 | $config = CRM_Core_Config::singleton(); |
1352 | return $config->userSystem->getUFLocale(); | |
1353 | } | |
1354 | ||
1355 | /** | |
7890c493 | 1356 | * Execute external or internal URLs and return server response. |
6a488035 | 1357 | * |
7890c493 RS |
1358 | * @param string $url |
1359 | * Request URL. | |
1360 | * @param bool $addCookie | |
1361 | * Whether to provide a cookie. Should be true to access internal URLs. | |
6a488035 | 1362 | * |
7890c493 RS |
1363 | * @return string |
1364 | * Response from URL. | |
6a488035 | 1365 | */ |
00be9182 | 1366 | public static function getServerResponse($url, $addCookie = TRUE) { |
532ee86f | 1367 | CRM_Core_TemporaryErrorScope::ignoreException(); |
6a488035 TO |
1368 | require_once 'HTTP/Request.php'; |
1369 | $request = new HTTP_Request($url); | |
1370 | ||
1371 | if ($addCookie) { | |
1372 | foreach ($_COOKIE as $name => $value) { | |
1373 | $request->addCookie($name, $value); | |
1374 | } | |
1375 | } | |
1376 | ||
1377 | if (isset($_SERVER['AUTH_TYPE'])) { | |
1378 | $request->setBasicAuth($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); | |
1379 | } | |
1380 | ||
1381 | $config = CRM_Core_Config::singleton(); | |
1382 | if ($config->userFramework == 'WordPress') { | |
1383 | session_write_close(); | |
1384 | } | |
1385 | ||
1386 | $request->sendRequest(); | |
1387 | $response = $request->getResponseBody(); | |
1388 | ||
6a488035 TO |
1389 | return $response; |
1390 | } | |
1391 | ||
7890c493 | 1392 | /** |
7890c493 | 1393 | */ |
00be9182 | 1394 | public static function isDBVersionValid(&$errorMessage) { |
6a488035 TO |
1395 | $dbVersion = CRM_Core_BAO_Domain::version(); |
1396 | ||
1397 | if (!$dbVersion) { | |
1398 | // if db.ver missing | |
1399 | $errorMessage = ts('Version information found to be missing in database. You will need to determine the correct version corresponding to your current database state.'); | |
1400 | return FALSE; | |
1401 | } | |
1402 | elseif (!CRM_Utils_System::isVersionFormatValid($dbVersion)) { | |
1403 | $errorMessage = ts('Database is marked with invalid version format. You may want to investigate this before you proceed further.'); | |
1404 | return FALSE; | |
1405 | } | |
1406 | elseif (stripos($dbVersion, 'upgrade')) { | |
1407 | // if db.ver indicates a partially upgraded db | |
1408 | $upgradeUrl = CRM_Utils_System::url("civicrm/upgrade", "reset=1"); | |
1409 | $errorMessage = ts('Database check failed - the database looks to have been partially upgraded. You may want to reload the database with the backup and try the <a href=\'%1\'>upgrade process</a> again.', array(1 => $upgradeUrl)); | |
1410 | return FALSE; | |
1411 | } | |
1412 | else { | |
1413 | $codeVersion = CRM_Utils_System::version(); | |
1414 | ||
1415 | // if db.ver < code.ver, time to upgrade | |
1416 | if (version_compare($dbVersion, $codeVersion) < 0) { | |
1417 | $upgradeUrl = CRM_Utils_System::url("civicrm/upgrade", "reset=1"); | |
1418 | $errorMessage = ts('New codebase version detected. You might want to visit <a href=\'%1\'>upgrade screen</a> to upgrade the database.', array(1 => $upgradeUrl)); | |
1419 | return FALSE; | |
1420 | } | |
1421 | ||
1422 | // if db.ver > code.ver, sth really wrong | |
1423 | if (version_compare($dbVersion, $codeVersion) > 0) { | |
42daf119 | 1424 | $errorMessage = '<p>' . ts('Your database is marked with an unexpected version number: %1. The v%2 codebase may not be compatible with your database state. You will need to determine the correct version corresponding to your current database state. You may want to revert to the codebase you were using until you resolve this problem.', |
353ffa53 TO |
1425 | array(1 => $dbVersion, 2 => $codeVersion) |
1426 | ) . '</p>'; | |
42daf119 | 1427 | $errorMessage .= "<p>" . ts('OR if this is a manual install from git, you might want to fix civicrm-version.php file.') . "</p>"; |
6a488035 TO |
1428 | return FALSE; |
1429 | } | |
1430 | } | |
1431 | // FIXME: there should be another check to make sure version is in valid format - X.Y.alpha_num | |
1432 | ||
1433 | return TRUE; | |
1434 | } | |
1435 | ||
7890c493 RS |
1436 | /** |
1437 | * Exit with provided exit code. | |
1438 | * | |
1439 | * @param int $status | |
1440 | * (optional) Code with which to exit. | |
7890c493 | 1441 | */ |
00be9182 | 1442 | public static function civiExit($status = 0) { |
6a488035 TO |
1443 | // move things to CiviCRM cache as needed |
1444 | CRM_Core_Session::storeSessionObjects(); | |
1445 | ||
1446 | exit($status); | |
1447 | } | |
1448 | ||
1449 | /** | |
7890c493 | 1450 | * Reset the various system caches and some important static variables. |
6a488035 | 1451 | */ |
e7292422 | 1452 | public static function flushCache() { |
6a488035 TO |
1453 | // flush out all cache entries so we can reload new data |
1454 | // a bit aggressive, but livable for now | |
1455 | $cache = CRM_Utils_Cache::singleton(); | |
1456 | $cache->flush(); | |
1457 | ||
1458 | // also reset the various static memory caches | |
1459 | ||
1460 | // reset the memory or array cache | |
1461 | CRM_Core_BAO_Cache::deleteGroup('contact fields', NULL, FALSE); | |
1462 | ||
1463 | // reset ACL cache | |
1464 | CRM_ACL_BAO_Cache::resetCache(); | |
1465 | ||
1466 | // reset various static arrays used here | |
971d41b1 CW |
1467 | CRM_Contact_BAO_Contact::$_importableFields |
1468 | = CRM_Contact_BAO_Contact::$_exportableFields | |
1469 | = CRM_Contribute_BAO_Contribution::$_importableFields | |
1470 | = CRM_Contribute_BAO_Contribution::$_exportableFields | |
1471 | = CRM_Pledge_BAO_Pledge::$_exportableFields | |
1472 | = CRM_Contribute_BAO_Query::$_contributionFields | |
1473 | = CRM_Core_BAO_CustomField::$_importFields | |
1474 | = CRM_Core_BAO_Cache::$_cache | |
1475 | = CRM_Core_DAO::$_dbColumnValueCache | |
1476 | = NULL; | |
6a488035 TO |
1477 | |
1478 | CRM_Core_OptionGroup::flushAll(); | |
1479 | CRM_Utils_PseudoConstant::flushAll(); | |
1480 | } | |
1481 | ||
1482 | /** | |
7890c493 | 1483 | * Load CMS bootstrap. |
6a488035 | 1484 | * |
7890c493 RS |
1485 | * @param array $params |
1486 | * Array with uid name and pass | |
1487 | * @param bool $loadUser | |
1488 | * Boolean load user or not. | |
1489 | * @param bool $throwError | |
1490 | * @param $realPath | |
6a488035 | 1491 | */ |
00be9182 | 1492 | public static function loadBootStrap($params = array(), $loadUser = TRUE, $throwError = TRUE, $realPath = NULL) { |
6a488035 TO |
1493 | if (!is_array($params)) { |
1494 | $params = array(); | |
1495 | } | |
1496 | $config = CRM_Core_Config::singleton(); | |
1497 | return $config->userSystem->loadBootStrap($params, $loadUser, $throwError, $realPath); | |
1498 | } | |
1499 | ||
1500 | /** | |
7890c493 | 1501 | * Check if user is logged in. |
6a488035 | 1502 | * |
7890c493 | 1503 | * @return bool |
6a488035 TO |
1504 | */ |
1505 | public static function isUserLoggedIn() { | |
1506 | $config = CRM_Core_Config::singleton(); | |
1507 | return $config->userSystem->isUserLoggedIn(); | |
1508 | } | |
1509 | ||
1510 | /** | |
1511 | * Get current logged in user id. | |
1512 | * | |
7890c493 RS |
1513 | * @return int |
1514 | * ufId, currently logged in user uf id. | |
6a488035 TO |
1515 | */ |
1516 | public static function getLoggedInUfID() { | |
1517 | $config = CRM_Core_Config::singleton(); | |
1518 | return $config->userSystem->getLoggedInUfID(); | |
1519 | } | |
1520 | ||
7890c493 | 1521 | /** |
7890c493 | 1522 | */ |
00be9182 | 1523 | public static function baseCMSURL() { |
6a488035 TO |
1524 | static $_baseURL = NULL; |
1525 | if (!$_baseURL) { | |
1526 | $config = CRM_Core_Config::singleton(); | |
1527 | $_baseURL = $userFrameworkBaseURL = $config->userFrameworkBaseURL; | |
1528 | ||
1529 | if ($config->userFramework == 'Joomla') { | |
1530 | // gross hack | |
1531 | // we need to remove the administrator/ from the end | |
1532 | $_baseURL = str_replace("/administrator/", "/", $userFrameworkBaseURL); | |
1533 | } | |
1534 | else { | |
1535 | // Drupal setting | |
1536 | global $civicrm_root; | |
1537 | if (strpos($civicrm_root, | |
1538 | DIRECTORY_SEPARATOR . 'sites' . | |
1539 | DIRECTORY_SEPARATOR . 'all' . | |
1540 | DIRECTORY_SEPARATOR . 'modules' | |
353ffa53 TO |
1541 | ) === FALSE |
1542 | ) { | |
6a488035 TO |
1543 | $startPos = strpos($civicrm_root, |
1544 | DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR | |
1545 | ); | |
1546 | $endPos = strpos($civicrm_root, | |
1547 | DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR | |
1548 | ); | |
1549 | if ($startPos && $endPos) { | |
1550 | // if component is in sites/SITENAME/modules | |
1551 | $siteName = substr($civicrm_root, | |
1552 | $startPos + 7, | |
1553 | $endPos - $startPos - 7 | |
1554 | ); | |
1555 | ||
1556 | $_baseURL = $userFrameworkBaseURL . "sites/$siteName/"; | |
1557 | } | |
1558 | } | |
1559 | } | |
1560 | } | |
1561 | return $_baseURL; | |
1562 | } | |
1563 | ||
7890c493 RS |
1564 | /** |
1565 | * Given a URL, return a relative URL if possible. | |
1566 | * | |
1567 | * @param string $url | |
1568 | * @return string | |
7890c493 | 1569 | */ |
00be9182 | 1570 | public static function relativeURL($url) { |
6a488035 TO |
1571 | // check if url is relative, if so return immediately |
1572 | if (substr($url, 0, 4) != 'http') { | |
1573 | return $url; | |
1574 | } | |
1575 | ||
1576 | // make everything relative from the baseFilePath | |
1577 | $baseURL = self::baseCMSURL(); | |
1578 | ||
1579 | // check if baseURL is a substr of $url, if so | |
1580 | // return rest of string | |
1581 | if (substr($url, 0, strlen($baseURL)) == $baseURL) { | |
1582 | return substr($url, strlen($baseURL)); | |
1583 | } | |
1584 | ||
1585 | // return the original value | |
1586 | return $url; | |
1587 | } | |
1588 | ||
7890c493 RS |
1589 | /** |
1590 | * Produce an absolute URL from a possibly-relative URL. | |
1591 | * | |
1592 | * @param string $url | |
f4aaa82a EM |
1593 | * @param bool $removeLanguagePart |
1594 | * | |
7890c493 | 1595 | * @return string |
7890c493 | 1596 | */ |
00be9182 | 1597 | public static function absoluteURL($url, $removeLanguagePart = FALSE) { |
6a488035 TO |
1598 | // check if url is already absolute, if so return immediately |
1599 | if (substr($url, 0, 4) == 'http') { | |
1600 | return $url; | |
1601 | } | |
1602 | ||
1603 | // make everything absolute from the baseFileURL | |
1604 | $baseURL = self::baseCMSURL(); | |
1605 | ||
1606 | //CRM-7622: drop the language from the URL if requested (and it’s there) | |
1607 | $config = CRM_Core_Config::singleton(); | |
1608 | if ($removeLanguagePart) { | |
1609 | $baseURL = self::languageNegotiationURL($baseURL, FALSE, TRUE); | |
1610 | } | |
1611 | ||
1612 | return $baseURL . $url; | |
1613 | } | |
1614 | ||
1615 | /** | |
100fef9d | 1616 | * Clean url, replaces first '&' with '?' |
6a488035 TO |
1617 | * |
1618 | * @param string $url | |
1619 | * | |
a6c01b45 CW |
1620 | * @return string |
1621 | * , clean url | |
6a488035 | 1622 | */ |
00be9182 | 1623 | public static function cleanUrl($url) { |
6a488035 TO |
1624 | if (!$url) { |
1625 | return NULL; | |
1626 | } | |
1627 | ||
1628 | if ($pos = strpos($url, '&')) { | |
1629 | $url = substr_replace($url, '?', $pos, 1); | |
1630 | } | |
1631 | ||
1632 | return $url; | |
1633 | } | |
1634 | ||
1635 | /** | |
1636 | * Format the url as per language Negotiation. | |
1637 | * | |
1638 | * @param string $url | |
1639 | * | |
f4aaa82a EM |
1640 | * @param bool $addLanguagePart |
1641 | * @param bool $removeLanguagePart | |
1642 | * | |
a6c01b45 CW |
1643 | * @return string |
1644 | * , formatted url. | |
6a488035 | 1645 | */ |
971d41b1 | 1646 | public static function languageNegotiationURL( |
a3e55d9c | 1647 | $url, |
6a488035 TO |
1648 | $addLanguagePart = TRUE, |
1649 | $removeLanguagePart = FALSE | |
1650 | ) { | |
1651 | $config = &CRM_Core_Config::singleton(); | |
1652 | return $config->userSystem->languageNegotiationURL($url, $addLanguagePart, $removeLanguagePart); | |
1653 | } | |
1654 | ||
1655 | /** | |
1656 | * Append the contents of an 'extra' smarty template file if it is present in | |
1657 | * the custom template directory. This does not work if there are | |
1658 | * multiple custom template directories | |
1659 | * | |
9911500f RS |
1660 | * @param string $fileName |
1661 | * The name of the tpl file that we are processing. | |
1662 | * @param string $content | |
1663 | * The current content string. May be modified by this function. | |
1664 | * @param string $overideFileName | |
1665 | * (optional) Sent by contribution/event reg/profile pages which uses a id | |
1666 | * specific extra file name if present. | |
6a488035 | 1667 | */ |
971d41b1 | 1668 | public static function appendTPLFile( |
a3e55d9c | 1669 | $fileName, |
6a488035 TO |
1670 | &$content, |
1671 | $overideFileName = NULL | |
1672 | ) { | |
1673 | $template = CRM_Core_Smarty::singleton(); | |
1674 | if ($overideFileName) { | |
1675 | $additionalTPLFile = $overideFileName; | |
1676 | } | |
1677 | else { | |
1678 | $additionalTPLFile = str_replace('.tpl', '.extra.tpl', $fileName); | |
1679 | } | |
1680 | ||
1681 | if ($template->template_exists($additionalTPLFile)) { | |
1682 | $content .= $template->fetch($additionalTPLFile); | |
1683 | } | |
1684 | } | |
1685 | ||
1686 | /** | |
1687 | * Get a list of all files that are found within the directories | |
1688 | * that are the result of appending the provided relative path to | |
1689 | * each component of the PHP include path. | |
1690 | * | |
1691 | * @author Ken Zalewski | |
1692 | * | |
9911500f RS |
1693 | * @param string $relpath |
1694 | * A relative path, typically pointing to a directory with multiple class | |
1695 | * files. | |
6a488035 | 1696 | * |
9911500f RS |
1697 | * @return array |
1698 | * An array of files that exist in one or more of the directories that are | |
1699 | * referenced by the relative path when appended to each element of the PHP | |
1700 | * include path. | |
6a488035 | 1701 | */ |
00be9182 | 1702 | public static function listIncludeFiles($relpath) { |
6a488035 TO |
1703 | $file_list = array(); |
1704 | $inc_dirs = explode(PATH_SEPARATOR, get_include_path()); | |
1705 | foreach ($inc_dirs as $inc_dir) { | |
1706 | $target_dir = $inc_dir . DIRECTORY_SEPARATOR . $relpath; | |
1707 | if (is_dir($target_dir)) { | |
1708 | $cur_list = scandir($target_dir); | |
1709 | foreach ($cur_list as $fname) { | |
1710 | if ($fname != '.' && $fname != '..') { | |
1711 | $file_list[$fname] = $fname; | |
1712 | } | |
1713 | } | |
1714 | } | |
1715 | } | |
1716 | return $file_list; | |
1717 | } | |
1718 | // listIncludeFiles() | |
1719 | ||
1720 | /** | |
1721 | * Get a list of all "plugins" (PHP classes that implement a piece of | |
1722 | * functionality using a well-defined interface) that are found in a | |
1723 | * particular CiviCRM directory (both custom and core are searched). | |
1724 | * | |
1725 | * @author Ken Zalewski | |
1726 | * | |
9911500f RS |
1727 | * @param string $relpath |
1728 | * A relative path referencing a directory that contains one or more | |
1729 | * plugins. | |
1730 | * @param string $fext | |
1731 | * (optional) Only files with this extension will be considered to be | |
1732 | * plugins. | |
1733 | * @param array $skipList | |
1734 | * (optional) List of files to skip. | |
6a488035 | 1735 | * |
9911500f RS |
1736 | * @return array |
1737 | * List of plugins, where the plugin name is both the key and the value of | |
1738 | * each element. | |
6a488035 | 1739 | */ |
00be9182 | 1740 | public static function getPluginList($relpath, $fext = '.php', $skipList = array()) { |
c490a46a CW |
1741 | $fext_len = strlen($fext); |
1742 | $plugins = array(); | |
6a488035 TO |
1743 | $inc_files = CRM_Utils_System::listIncludeFiles($relpath); |
1744 | foreach ($inc_files as $inc_file) { | |
1745 | if (substr($inc_file, 0 - $fext_len) == $fext) { | |
1746 | $plugin_name = substr($inc_file, 0, 0 - $fext_len); | |
1747 | if (!in_array($plugin_name, $skipList)) { | |
1748 | $plugins[$plugin_name] = $plugin_name; | |
1749 | } | |
1750 | } | |
1751 | } | |
1752 | return $plugins; | |
1753 | } | |
1754 | // getPluginList() | |
1755 | ||
1756 | /** | |
6a488035 | 1757 | */ |
00be9182 | 1758 | public static function executeScheduledJobs() { |
6a488035 TO |
1759 | $facility = new CRM_Core_JobManager(); |
1760 | $facility->execute(FALSE); | |
1761 | ||
1762 | $redirectUrl = self::url('civicrm/admin/job', 'reset=1'); | |
1763 | ||
1764 | CRM_Core_Session::setStatus( | |
1765 | ts('Scheduled jobs have been executed according to individual timing settings. Please check log for messages.'), | |
1766 | ts('Complete'), 'success'); | |
1767 | ||
1768 | CRM_Utils_System::redirect($redirectUrl); | |
1769 | } | |
1770 | ||
efceedd4 | 1771 | /** |
9911500f | 1772 | * Evaluate any tokens in a URL. |
efceedd4 TO |
1773 | * |
1774 | * @param string|FALSE $url | |
1775 | * @return string|FALSE | |
1776 | */ | |
1777 | public static function evalUrl($url) { | |
efceedd4 TO |
1778 | if ($url === FALSE) { |
1779 | return FALSE; | |
1780 | } | |
1781 | else { | |
1782 | $config = CRM_Core_Config::singleton(); | |
1783 | $vars = array( | |
1784 | '{ver}' => CRM_Utils_System::version(), | |
1785 | '{uf}' => $config->userFramework, | |
1786 | '{php}' => phpversion(), | |
c4e76569 TO |
1787 | '{sid}' => md5('sid_' . (defined('CIVICRM_SITE_KEY') ? CIVICRM_SITE_KEY : '') . '_' . $config->userFrameworkBaseURL), |
1788 | '{baseUrl}' => $config->userFrameworkBaseURL, | |
1789 | '{lang}' => $config->lcMessages, | |
1790 | '{co}' => $config->defaultContactCountry, | |
efceedd4 | 1791 | ); |
c4e76569 TO |
1792 | foreach (array_keys($vars) as $k) { |
1793 | $vars[$k] = urlencode($vars[$k]); | |
1794 | } | |
efceedd4 TO |
1795 | return strtr($url, $vars); |
1796 | } | |
1797 | } | |
1798 | ||
1799 | ||
6a488035 TO |
1800 | /** |
1801 | * Determine whether this is a developmental system. | |
1802 | * | |
1803 | * @return bool | |
1804 | */ | |
00be9182 | 1805 | public static function isDevelopment() { |
6a488035 TO |
1806 | static $cache = NULL; |
1807 | if ($cache === NULL) { | |
1808 | global $civicrm_root; | |
1809 | $cache = file_exists("{$civicrm_root}/.svn") || file_exists("{$civicrm_root}/.git"); | |
1810 | } | |
1811 | return $cache; | |
1812 | } | |
5da97e99 | 1813 | |
5bc392e6 EM |
1814 | /** |
1815 | * @return bool | |
1816 | */ | |
00be9182 | 1817 | public static function isInUpgradeMode() { |
252e6dbc PJ |
1818 | $args = explode('/', $_GET['q']); |
1819 | $upgradeInProcess = CRM_Core_Session::singleton()->get('isUpgradePending'); | |
1820 | if ((isset($args[1]) && $args[1] == 'upgrade') || $upgradeInProcess) { | |
1821 | return TRUE; | |
1822 | } | |
1823 | else { | |
1824 | return FALSE; | |
1825 | } | |
1826 | } | |
688ad538 TO |
1827 | |
1828 | /** | |
1829 | * Determine the standard URL for viewing or editing the specified link | |
1830 | * | |
1831 | * This function delegates the decision-making to (a) the hook system and | |
1832 | * (b) the BAO system. | |
1833 | * | |
77855840 TO |
1834 | * @param array $crudLinkSpec |
1835 | * With keys:. | |
16b10e64 CW |
1836 | * - action: int, CRM_Core_Action::UPDATE or CRM_Core_Action::VIEW [default: VIEW] |
1837 | * - entity_table: string, eg "civicrm_contact" | |
1838 | * - entity_id: int | |
72b3a70c CW |
1839 | * @return array|NULL |
1840 | * NULL if unavailable, or an array. array has keys: | |
16b10e64 CW |
1841 | * - path: string |
1842 | * - query: array | |
1843 | * - title: string | |
1844 | * - url: string | |
688ad538 | 1845 | */ |
00be9182 | 1846 | public static function createDefaultCrudLink($crudLinkSpec) { |
688ad538 TO |
1847 | $crudLinkSpec['action'] = CRM_Utils_Array::value('action', $crudLinkSpec, CRM_Core_Action::VIEW); |
1848 | $daoClass = CRM_Core_DAO_AllCoreTables::getClassForTable($crudLinkSpec['entity_table']); | |
1849 | if (!$daoClass) { | |
1850 | return NULL; | |
1851 | } | |
1852 | ||
1853 | $baoClass = str_replace('_DAO_', '_BAO_', $daoClass); | |
1854 | if (!class_exists($baoClass)) { | |
1855 | return NULL; | |
1856 | } | |
1857 | ||
1858 | $bao = new $baoClass(); | |
1859 | $bao->id = $crudLinkSpec['entity_id']; | |
1860 | if (!$bao->find(TRUE)) { | |
1861 | return NULL; | |
1862 | } | |
1863 | ||
1864 | $link = array(); | |
1865 | CRM_Utils_Hook::crudLink($crudLinkSpec, $bao, $link); | |
1866 | if (empty($link) && is_callable(array($bao, 'createDefaultCrudLink'))) { | |
1867 | $link = $bao->createDefaultCrudLink($crudLinkSpec); | |
1868 | } | |
1869 | ||
1870 | if (!empty($link)) { | |
1871 | if (!isset($link['url'])) { | |
1872 | $link['url'] = self::url($link['path'], $link['query'], TRUE, NULL, FALSE); | |
1873 | } | |
1874 | return $link; | |
1875 | } | |
1876 | ||
1877 | return NULL; | |
1878 | } | |
5bc392e6 | 1879 | } |