Another set of PHPdoc corrections
[civicrm-core.git] / CRM / Utils / System / Base.php
CommitLineData
6a488035
TO
1<?php
2
3/**
4 * Base class for UF system integrations
5 */
6abstract class CRM_Utils_System_Base {
2b0e7d03 7
4caaa696 8 /**
2b0e7d03
EM
9 * Deprecated property to check if this is a drupal install.
10 *
11 * The correct method is to have functions on the UF classes for all UF specific
4caaa696 12 * functions and leave the codebase oblivious to the type of CMS
7cdf0f5b 13 *
4caaa696 14 * @var bool
6714d8d2 15 * @deprecated
7cdf0f5b 16 * TRUE, if the CMS is Drupal.
4caaa696 17 */
6714d8d2 18 public $is_drupal = FALSE;
4caaa696
EM
19
20 /**
100fef9d 21 * Deprecated property to check if this is a joomla install. The correct method is to have functions on the UF classes for all UF specific
4caaa696 22 * functions and leave the codebase oblivious to the type of CMS
7cdf0f5b 23 *
4caaa696 24 * @var bool
6714d8d2 25 * @deprecated
7cdf0f5b 26 * TRUE, if the CMS is Joomla!.
4caaa696 27 */
6714d8d2 28 public $is_joomla = FALSE;
4caaa696 29
7cdf0f5b
AH
30 /**
31 * deprecated property to check if this is a wordpress install. The correct method is to have functions on the UF classes for all UF specific
32 * functions and leave the codebase oblivious to the type of CMS
33 *
7cdf0f5b 34 * @var bool
6714d8d2 35 * @deprecated
7cdf0f5b
AH
36 * TRUE, if the CMS is WordPress.
37 */
6714d8d2 38 public $is_wordpress = FALSE;
6a488035 39
e0dd98a5
EM
40 /**
41 * Does this CMS / UF support a CMS specific logging mechanism?
e0dd98a5 42 * @var bool
6714d8d2 43 * @todo - we should think about offering up logging mechanisms in a way that is also extensible by extensions
e0dd98a5 44 */
6714d8d2 45 public $supports_UF_Logging = FALSE;
e0dd98a5 46
7cdf0f5b
AH
47 /**
48 * @var bool
49 * TRUE, if the CMS allows CMS forms to be extended by hooks.
6a488035 50 */
6714d8d2 51 public $supports_form_extensions = FALSE;
6a488035 52
d4330c62
TO
53 public function initialize() {
54 if (\CRM_Utils_System::isSSL()) {
55 $this->mapConfigToSSL();
56 }
57 }
58
6714d8d2 59 abstract public function loadBootStrap($params = [], $loadUser = TRUE, $throwError = TRUE, $realPath = NULL);
9ba02e3e 60
17f443df 61 /**
fe482240 62 * Append an additional breadcrumb tag to the existing breadcrumb.
17f443df
CW
63 *
64 * @param array $breadCrumbs
65 */
66 public function appendBreadCrumb($breadCrumbs) {
67 }
68
69 /**
fe482240 70 * Reset an additional breadcrumb tag to the existing breadcrumb.
17f443df
CW
71 */
72 public function resetBreadCrumb() {
73 }
74
75 /**
fe482240 76 * Append a string to the head of the html file.
17f443df
CW
77 *
78 * @param string $head
79 * The new string to be appended.
80 */
81 public function addHTMLHead($head) {
82 }
83
84 /**
fe482240 85 * Rewrite various system urls to https.
17f443df
CW
86 */
87 public function mapConfigToSSL() {
88 // dont need to do anything, let CMS handle their own switch to SSL
89 }
90
91 /**
fe482240 92 * Figure out the post url for QuickForm.
17f443df
CW
93 *
94 * @param string $action
95 * The default url if one is pre-specified.
96 *
97 * @return string
98 * The url to post the form.
99 */
100 public function postURL($action) {
101 $config = CRM_Core_Config::singleton();
102 if (!empty($action)) {
103 return $action;
104 }
105
106 return $this->url(CRM_Utils_Array::value($config->userFrameworkURLVar, $_GET),
107 NULL, TRUE, NULL, FALSE
108 );
109 }
110
111 /**
112 * Generate the url string to a CiviCRM path.
113 *
114 * @param string $path
115 * The path being linked to, such as "civicrm/add".
116 * @param string $query
117 * A query string to append to the link.
118 * @param bool $absolute
119 * Whether to force the output to be an absolute link (beginning with http).
120 * Useful for links that will be displayed outside the site, such as in an RSS feed.
121 * @param string $fragment
122 * A fragment identifier (named anchor) to append to the link.
17f443df
CW
123 * @param bool $frontend
124 * This link should be to the CMS front end (applies to WP & Joomla).
125 * @param bool $forceBackend
126 * This link should be to the CMS back end (applies to WP & Joomla).
8de2a34e
SL
127 * @param bool $htmlize
128 * Whether to encode special html characters such as &.
17f443df
CW
129 *
130 * @return string
131 */
132 public function url(
133 $path = NULL,
134 $query = NULL,
135 $absolute = FALSE,
136 $fragment = NULL,
17f443df 137 $frontend = FALSE,
8de2a34e
SL
138 $forceBackend = FALSE,
139 $htmlize = TRUE
17f443df
CW
140 ) {
141 return NULL;
142 }
143
cd95cfbe
CW
144 /**
145 * Return the Notification URL for Payments.
146 *
147 * The default is to pass the params through to `url()`. However the WordPress
148 * CMS class overrides this method because Notification URLs must always target
149 * the Base Page to avoid IPN failures when Forms are embedded in pages that
150 * require authentication.
151 *
152 * @param string $path
153 * The path being linked to, such as "civicrm/add".
154 * @param string $query
155 * A query string to append to the link.
156 * @param bool $absolute
157 * Whether to force the output to be an absolute link (beginning with http).
158 * Useful for links that will be displayed outside the site, such as in an RSS feed.
159 * @param string $fragment
160 * A fragment identifier (named anchor) to append to the link.
161 * @param bool $frontend
162 * This link should be to the CMS front end (applies to WP & Joomla).
163 * @param bool $forceBackend
164 * This link should be to the CMS back end (applies to WP & Joomla).
165 * @param bool $htmlize
166 * Whether to encode special html characters such as &.
167 *
168 * @return string
169 * The Notification URL.
170 */
171 public function getNotifyUrl(
172 $path = NULL,
173 $query = NULL,
174 $absolute = FALSE,
175 $fragment = NULL,
176 $frontend = FALSE,
177 $forceBackend = FALSE,
178 $htmlize = TRUE
179 ) {
180 return $this->url($path, $query, $absolute, $fragment, $frontend, $forceBackend, $htmlize);
181 }
182
17f443df 183 /**
fe482240 184 * Authenticate the user against the CMS db.
17f443df
CW
185 *
186 * @param string $name
187 * The user name.
188 * @param string $password
189 * The password for the above user.
190 * @param bool $loadCMSBootstrap
191 * Load cms bootstrap?.
192 * @param string $realPath
193 * Filename of script
194 *
195 * @return array|bool
196 * [contactID, ufID, unique string] else false if no auth
309310bf 197 * @throws \CRM_Core_Exception.
17f443df
CW
198 */
199 public function authenticate($name, $password, $loadCMSBootstrap = FALSE, $realPath = NULL) {
200 return FALSE;
201 }
202
203 /**
fe482240 204 * Set a message in the CMS to display to a user.
17f443df
CW
205 *
206 * @param string $message
207 * The message to set.
208 */
209 public function setMessage($message) {
210 }
211
212 /**
fe482240 213 * Load user into session.
17f443df 214 *
2b0e7d03 215 * @param obj $user
17f443df
CW
216 *
217 * @return bool
218 */
219 public function loadUser($user) {
220 return TRUE;
221 }
222
223 /**
2b0e7d03 224 * Immediately stop script execution and display a 401 "Access Denied" page.
309310bf 225 * @throws \CRM_Core_Exception
17f443df
CW
226 */
227 public function permissionDenied() {
309310bf 228 throw new CRM_Core_Exception(ts('You do not have permission to access this page.'));
17f443df
CW
229 }
230
231 /**
2b0e7d03 232 * Immediately stop script execution, log out the user and redirect to the home page.
17f443df
CW
233 *
234 * @deprecated
235 * This function should be removed in favor of linking to the CMS's logout page
236 */
237 public function logout() {
238 }
239
240 /**
241 * Clear CMS caches related to the user registration/profile forms.
242 * Used when updating/embedding profiles on CMS user forms.
243 * @see CRM-3600
244 */
245 public function updateCategories() {
246 }
247
248 /**
fe482240 249 * Get the locale set in the CMS.
17f443df
CW
250 *
251 * @return string|null
252 * Locale or null for none
253 */
254 public function getUFLocale() {
255 return NULL;
256 }
257
6a488035 258 /**
2b0e7d03 259 * If we are using a theming system, invoke theme, else just print the content.
6a488035 260 *
77855840
TO
261 * @param string $content
262 * The content that will be themed.
263 * @param bool $print
264 * Are we displaying to the screen or bypassing theming?.
265 * @param bool $maintenance
266 * For maintenance mode.
6a488035 267 *
7cdf0f5b
AH
268 * @throws Exception
269 * @return string|null
270 * NULL, If $print is FALSE, and some other criteria match up.
271 * The themed string, otherwise.
26659f0c
AH
272 *
273 * @todo The return value is inconsistent.
274 * @todo Better to always return, and never print.
6a488035 275 */
00be9182 276 public function theme(&$content, $print = FALSE, $maintenance = FALSE) {
6a488035
TO
277 $ret = FALSE;
278
279 // TODO: Split up; this was copied verbatim from CiviCRM 4.0's multi-UF theming function
280 // but the parts should be copied into cleaner subclass implementations
1e305b0b
DL
281 $config = CRM_Core_Config::singleton();
282 if (
283 $config->userSystem->is_drupal &&
284 function_exists('theme') &&
285 !$print
286 ) {
6a488035
TO
287 if ($maintenance) {
288 drupal_set_breadcrumb('');
289 drupal_maintenance_theme();
10221f8a
TO
290 if ($region = CRM_Core_Region::instance('html-header', FALSE)) {
291 CRM_Utils_System::addHTMLHead($region->render(''));
292 }
be2fb01f 293 print theme('maintenance_page', ['content' => $content]);
6a488035
TO
294 exit();
295 }
2b0e7d03
EM
296 // TODO: Figure out why D7 returns but everyone else prints
297 $ret = TRUE;
6a488035
TO
298 }
299 $out = $content;
300
1e305b0b
DL
301 if (
302 !$print &&
f3a87cf4 303 CRM_Core_Config::singleton()->userFramework == 'WordPress'
6a488035 304 ) {
aecede9a
AH
305 if (!function_exists('is_admin')) {
306 throw new \Exception('Function "is_admin()" is missing, even though WordPress is the user framework.');
307 }
308 if (!defined('ABSPATH')) {
309 throw new \Exception('Constant "ABSPATH" is not defined, even though WordPress is the user framework.');
310 }
6a488035 311 if (is_admin()) {
e7292422 312 require_once ABSPATH . 'wp-admin/admin-header.php';
6a488035
TO
313 }
314 else {
7cdf0f5b 315 // FIXME: we need to figure out to replace civicrm content on the frontend pages
6a488035
TO
316 }
317 }
318
319 if ($ret) {
320 return $out;
321 }
322 else {
323 print $out;
85c5f34c 324 return NULL;
6a488035
TO
325 }
326 }
327
bb3a214a
EM
328 /**
329 * @return string
330 */
00be9182 331 public function getDefaultBlockLocation() {
6a488035
TO
332 return 'left';
333 }
334
8246bca4 335 /**
336 * Get the absolute path to the site's base url.
337 *
338 * @return bool|mixed|string
339 */
d4330c62
TO
340 public function getAbsoluteBaseURL() {
341 if (!defined('CIVICRM_UF_BASEURL')) {
342 return FALSE;
343 }
344
345 $url = CRM_Utils_File::addTrailingSlash(CIVICRM_UF_BASEURL, '/');
346
347 //format url for language negotiation, CRM-7803
348 $url = $this->languageNegotiationURL($url);
349
350 if (CRM_Utils_System::isSSL()) {
351 $url = str_replace('http://', 'https://', $url);
352 }
353
354 return $url;
355 }
356
8246bca4 357 /**
358 * Get the relative path to the sites base url.
359 *
fa3fdebc 360 * @return string|false
8246bca4 361 */
d4330c62
TO
362 public function getRelativeBaseURL() {
363 $absoluteBaseURL = $this->getAbsoluteBaseURL();
364 if ($absoluteBaseURL === FALSE) {
365 return FALSE;
366 }
367 $parts = parse_url($absoluteBaseURL);
368 return $parts['path'];
369 //$this->useFrameworkRelativeBase = empty($base['path']) ? '/' : $base['path'];
370 }
371
bb3a214a 372 /**
fe482240 373 * Get CMS Version.
17f443df 374 *
bb3a214a
EM
375 * @return string
376 */
00be9182 377 public function getVersion() {
6a488035
TO
378 return 'Unknown';
379 }
380
381 /**
382 * Format the url as per language Negotiation.
383 *
384 * @param string $url
77b97be7
EM
385 * @param bool $addLanguagePart
386 * @param bool $removeLanguagePart
387 *
7cdf0f5b
AH
388 * @return string
389 * Formatted url.
6a488035 390 */
d5cc0fc2 391 public function languageNegotiationURL(
6a488035
TO
392 $url,
393 $addLanguagePart = TRUE,
394 $removeLanguagePart = FALSE
395 ) {
396 return $url;
397 }
398
e29aefb4
TO
399 /**
400 * Determine the location of the CMS root.
401 *
7cdf0f5b
AH
402 * @return string|null
403 * Local file system path to CMS root, or NULL if it cannot be determined
6a488035 404 */
00be9182 405 public function cmsRootPath() {
e29aefb4 406 return NULL;
6a488035
TO
407 }
408
17f443df
CW
409 /**
410 * Create a user in the CMS.
411 *
412 * @param array $params
413 * @param string $mail
414 * Email id for cms user.
415 *
416 * @return int|bool
417 * uid if user exists, false otherwise
418 */
419 public function createUser(&$params, $mail) {
420 return FALSE;
421 }
422
423 /**
424 * Update a user's email address in the CMS.
425 *
426 * @param int $ufID
427 * User ID in CMS.
428 * @param string $email
429 * Primary contact email address.
430 */
431 public function updateCMSName($ufID, $email) {
432 }
433
434 /**
435 * Check if user is logged in to the CMS.
436 *
437 * @return bool
438 */
439 public function isUserLoggedIn() {
440 return FALSE;
441 }
442
8caad0ce 443 /**
444 * Check if user registration is permitted.
445 *
446 * @return bool
447 */
448 public function isUserRegistrationPermitted() {
449 return FALSE;
450 }
451
63df6889
HD
452 /**
453 * Check if user can create passwords or is initially assigned a system-generated one.
454 *
455 * @return bool
456 */
1a6630be 457 public function isPasswordUserGenerated() {
63df6889
HD
458 return FALSE;
459 }
460
68e3bc34 461 /**
462 * Is a front end page being accessed.
463 *
464 * Generally this would be a contribution form or other public page as opposed to a backoffice page (like contact edit).
465 *
466 * @todo Drupal uses the is_public setting - clarify & rationalise. See https://github.com/civicrm/civicrm-drupal/pull/546/files
467 *
468 * @return bool
469 */
470 public function isFrontEndPage() {
471 return CRM_Core_Config::singleton()->userFrameworkFrontend;
472 }
473
6a488035
TO
474 /**
475 * Get user login URL for hosting CMS (method declared in each CMS system class)
476 *
77855840 477 * @param string $destination
7cecea88 478 * If present, add destination to querystring (works for Drupal and WordPress only).
6a488035 479 *
a6c01b45
CW
480 * @return string
481 * loginURL for the current CMS
6a488035 482 */
6714d8d2 483 abstract public function getLoginURL($destination = '');
6a488035 484
17f443df 485 /**
2b0e7d03
EM
486 * Get the login destination string.
487 *
488 * When this is passed in the URL the user will be directed to it after filling in the CMS form.
17f443df
CW
489 *
490 * @param CRM_Core_Form $form
491 * Form object representing the 'current' form - to which the user will be returned.
2b0e7d03 492 *
17f443df
CW
493 * @return string|NULL
494 * destination value for URL
495 */
496 public function getLoginDestination(&$form) {
497 return NULL;
498 }
499
46b6363c 500 /**
fe482240 501 * Determine the native ID of the CMS user.
46b6363c 502 *
100fef9d 503 * @param string $username
f4aaa82a
EM
504 *
505 * @throws CRM_Core_Exception
46b6363c 506 */
00be9182 507 public function getUfId($username) {
46b6363c
TO
508 $className = get_class($this);
509 throw new CRM_Core_Exception("Not implemented: {$className}->getUfId");
510 }
511
bc854509 512 /**
513 * Set the localisation from the user framework.
514 *
515 * @param string $civicrm_language
516 *
517 * @return bool
518 */
a7c57397
TO
519 public function setUFLocale($civicrm_language) {
520 return TRUE;
521 }
522
5d0eb86b 523 /**
fe482240 524 * Set a init session with user object.
5d0eb86b 525 *
7cdf0f5b
AH
526 * @param array $data
527 * Array with user specific data
5d0eb86b 528 */
00be9182 529 public function setUserSession($data) {
5d0eb86b
BS
530 list($userID, $ufID) = $data;
531 $session = CRM_Core_Session::singleton();
532 $session->set('ufID', $ufID);
533 $session->set('userID', $userID);
534 }
d8a4acc0
C
535
536 /**
2b0e7d03 537 * Reset any system caches that may be required for proper CiviCRM integration.
d8a4acc0 538 */
00be9182 539 public function flush() {
d8a4acc0
C
540 // nullop by default
541 }
82d9c21e 542
f091327b 543 /**
2b0e7d03 544 * Flush css/js caches.
f091327b 545 */
00be9182 546 public function clearResourceCache() {
f091327b
CW
547 // nullop by default
548 }
549
17f443df 550 /**
fe482240 551 * Add a script file.
17f443df
CW
552 *
553 * Note: This function is not to be called directly
554 * @see CRM_Core_Region::render()
555 *
2b0e7d03 556 * @param string $url absolute path to file
17f443df
CW
557 * @param string $region
558 * location within the document: 'html-header', 'page-header', 'page-footer'.
559 *
560 * @return bool
561 * TRUE if we support this operation in this CMS, FALSE otherwise
562 */
563 public function addScriptUrl($url, $region) {
564 return FALSE;
565 }
566
567 /**
fe482240 568 * Add an inline script.
17f443df
CW
569 *
570 * Note: This function is not to be called directly
571 * @see CRM_Core_Region::render()
572 *
2b0e7d03 573 * @param string $code javascript code
17f443df
CW
574 * @param string $region
575 * location within the document: 'html-header', 'page-header', 'page-footer'.
576 *
577 * @return bool
578 * TRUE if we support this operation in this CMS, FALSE otherwise
579 */
580 public function addScript($code, $region) {
581 return FALSE;
582 }
583
584 /**
fe482240 585 * Add a css file.
17f443df
CW
586 *
587 * Note: This function is not to be called directly
588 * @see CRM_Core_Region::render()
589 *
2b0e7d03 590 * @param string $url absolute path to file
17f443df
CW
591 * @param string $region
592 * location within the document: 'html-header', 'page-header', 'page-footer'.
593 *
594 * @return bool
595 * TRUE if we support this operation in this CMS, FALSE otherwise
596 */
597 public function addStyleUrl($url, $region) {
598 return FALSE;
599 }
600
601 /**
fe482240 602 * Add an inline style.
17f443df
CW
603 *
604 * Note: This function is not to be called directly
605 * @see CRM_Core_Region::render()
606 *
2b0e7d03 607 * @param string $code css code
17f443df
CW
608 * @param string $region
609 * location within the document: 'html-header', 'page-header', 'page-footer'.
610 *
611 * @return bool
612 * TRUE if we support this operation in this CMS, FALSE otherwise
613 */
614 public function addStyle($code, $region) {
615 return FALSE;
616 }
617
618 /**
fe482240 619 * Sets the title of the page.
17f443df
CW
620 *
621 * @param string $title
622 * Title to set in html header
623 * @param string|null $pageTitle
624 * Title to set in html body (if different)
625 */
626 public function setTitle($title, $pageTitle = NULL) {
627 }
628
c8950569 629 /**
fe482240 630 * Return default Site Settings.
f4aaa82a 631 *
7cdf0f5b 632 * @param string $dir
f4aaa82a 633 *
7cdf0f5b 634 * @return array
d5cc0fc2 635 * - $url, (Joomla - non admin url)
636 * - $siteName,
637 * - $siteRoot
9977c6f5 638 */
00be9182 639 public function getDefaultSiteSettings($dir) {
9977c6f5 640 $config = CRM_Core_Config::singleton();
641 $url = $config->userFrameworkBaseURL;
be2fb01f 642 return [$url, NULL, NULL];
9977c6f5 643 }
c8950569 644
f6f958e4
TO
645 /**
646 * Determine the default location for file storage.
647 *
648 * FIXME:
649 * 1. This was pulled out from a bigger function. It should be split
650 * into even smaller pieces and marked abstract.
651 * 2. This would be easier to compute by a calling a CMS API, but
652 * for whatever reason Civi gets it from config data.
653 *
654 * @return array
655 * - url: string. ex: "http://example.com/sites/foo.com/files/civicrm"
656 * - path: string. ex: "/var/www/sites/foo.com/files/civicrm"
657 */
658 public function getDefaultFileStorage() {
659 global $civicrm_root;
660 $config = CRM_Core_Config::singleton();
661 $baseURL = CRM_Utils_System::languageNegotiationURL($config->userFrameworkBaseURL, FALSE, TRUE);
662
663 $filesURL = NULL;
664 $filesPath = NULL;
665
666 if ($config->userFramework == 'Joomla') {
667 // gross hack
668 // we need to remove the administrator/ from the end
669 $tempURL = str_replace("/administrator/", "/", $baseURL);
670 $filesURL = $tempURL . "media/civicrm/";
671 }
f6f958e4
TO
672 elseif ($config->userFramework == 'UnitTests') {
673 $filesURL = $baseURL . "sites/default/files/civicrm/";
674 }
675 else {
676 throw new CRM_Core_Exception("Failed to locate default file storage ($config->userFramework)");
677 }
678
be2fb01f 679 return [
f6f958e4
TO
680 'url' => $filesURL,
681 'path' => CRM_Utils_File::baseFilePath(),
be2fb01f 682 ];
f6f958e4
TO
683 }
684
685 /**
686 * Determine the location of the CiviCRM source tree.
687 *
688 * FIXME:
689 * 1. This was pulled out from a bigger function. It should be split
690 * into even smaller pieces and marked abstract.
691 * 2. This would be easier to compute by a calling a CMS API, but
692 * for whatever reason we take the hard way.
693 *
694 * @return array
695 * - url: string. ex: "http://example.com/sites/all/modules/civicrm"
696 * - path: string. ex: "/var/www/sites/all/modules/civicrm"
697 */
698 public function getCiviSourceStorage() {
699 global $civicrm_root;
700 $config = CRM_Core_Config::singleton();
701
702 // Don't use $config->userFrameworkBaseURL; it has garbage on it.
703 // More generally, w shouldn't be using $config here.
704 if (!defined('CIVICRM_UF_BASEURL')) {
705 throw new RuntimeException('Undefined constant: CIVICRM_UF_BASEURL');
706 }
707 $baseURL = CRM_Utils_File::addTrailingSlash(CIVICRM_UF_BASEURL, '/');
708 if (CRM_Utils_System::isSSL()) {
709 $baseURL = str_replace('http://', 'https://', $baseURL);
710 }
711
38dab72a 712 // @todo this function is only called / code is only reached when is_drupal is true - move this to the drupal classes
713 // and don't implement here.
714 if ($this->is_drupal) {
3403e54b
TO
715 // Drupal setting
716 // check and see if we are installed in sites/all (for D5 and above)
717 // we dont use checkURL since drupal generates an error page and throws
718 // the system for a loop on lobo's macosx box
719 // or in modules
720 $cmsPath = $config->userSystem->cmsRootPath();
721 $userFrameworkResourceURL = $baseURL . str_replace("$cmsPath/", '',
722 str_replace('\\', '/', $civicrm_root)
723 );
724
725 $siteName = $config->userSystem->parseDrupalSiteNameFromRoot($civicrm_root);
726 if ($siteName) {
727 $civicrmDirName = trim(basename($civicrm_root));
728 $userFrameworkResourceURL = $baseURL . "sites/$siteName/modules/$civicrmDirName/";
729 }
730 }
f6f958e4
TO
731 else {
732 $userFrameworkResourceURL = NULL;
733 }
734
be2fb01f 735 return [
6ee26d90 736 'url' => CRM_Utils_File::addTrailingSlash($userFrameworkResourceURL, '/'),
f6f958e4 737 'path' => CRM_Utils_File::addTrailingSlash($civicrm_root),
be2fb01f 738 ];
f6f958e4
TO
739 }
740
82d9c21e 741 /**
2b0e7d03
EM
742 * Perform any post login activities required by the CMS.
743 *
53980972 744 * e.g. for drupal: records a watchdog message about the new session, saves the login timestamp,
745 * calls hook_user op 'login' and generates a new session.
e43cc689 746 *
7cdf0f5b 747 * @param array $params
95d68223
TO
748 *
749 * FIXME: Document values accepted/required by $params
c8950569 750 */
be2fb01f 751 public function userLoginFinalize($params = []) {
82d9c21e 752 }
5a604d61
E
753
754 /**
fe482240 755 * Set timezone in mysql so that timestamp fields show the correct time.
5a604d61 756 */
9b873358 757 public function setMySQLTimeZone() {
5a604d61 758 $timeZoneOffset = $this->getTimeZoneOffset();
9b873358 759 if ($timeZoneOffset) {
5a604d61
E
760 $sql = "SET time_zone = '$timeZoneOffset'";
761 CRM_Core_DAO::executequery($sql);
762 }
763 }
764
765 /**
fe482240 766 * Get timezone from CMS.
7cdf0f5b
AH
767 *
768 * @return string|false|null
6491539b 769 */
9b873358 770 public function getTimeZoneOffset() {
6491539b 771 $timezone = $this->getTimeZoneString();
8b647c3a 772 if ($timezone) {
2451c06a 773 if ($timezone == 'UTC' || $timezone == 'Etc/UTC') {
030113f0 774 // CRM-17072 Let's short-circuit all the zero handling & return it here!
775 return '+00:00';
776 }
6491539b
DL
777 $tzObj = new DateTimeZone($timezone);
778 $dateTime = new DateTime("now", $tzObj);
779 $tz = $tzObj->getOffset($dateTime);
780
f2173d64 781 if ($tz === 0) {
278460dd
AS
782 // CRM-21422
783 return '+00:00';
784 }
785
8b647c3a
AH
786 if (empty($tz)) {
787 return FALSE;
6491539b
DL
788 }
789
e7292422 790 $timeZoneOffset = sprintf("%02d:%02d", $tz / 3600, abs(($tz / 60) % 60));
6491539b 791
8b647c3a 792 if ($timeZoneOffset > 0) {
6491539b
DL
793 $timeZoneOffset = '+' . $timeZoneOffset;
794 }
795 return $timeZoneOffset;
796 }
85c5f34c 797 return NULL;
6491539b
DL
798 }
799
800 /**
fe482240 801 * Get timezone as a string.
7cdf0f5b 802 * @return string
17f443df 803 * Timezone string e.g. 'America/Los_Angeles'
6491539b 804 */
00be9182 805 public function getTimeZoneString() {
48ec57ab 806 return date_default_timezone_get();
5a604d61 807 }
2b617cb0
EM
808
809 /**
2b0e7d03
EM
810 * Get Unique Identifier from UserFramework system (CMS).
811 *
77855840
TO
812 * @param object $user
813 * Object as described by the User Framework.
2b0e7d03 814 *
72b3a70c 815 * @return mixed
2b0e7d03 816 * Unique identifier from the user Framework system
2b617cb0 817 */
e7292422 818 public function getUniqueIdentifierFromUserObject($user) {
17f443df 819 return NULL;
e7292422 820 }
2b617cb0 821
32998c82 822 /**
2b0e7d03
EM
823 * Get User ID from UserFramework system (CMS).
824 *
77855840 825 * @param object $user
2b0e7d03 826 *
77855840 827 * Object as described by the User Framework.
17f443df 828 * @return null|int
32998c82 829 */
e7292422 830 public function getUserIDFromUserObject($user) {
17f443df 831 return NULL;
e7292422 832 }
32998c82 833
2b0e7d03
EM
834 /**
835 * Get an array of user details for a contact, containing at minimum the user ID & name.
836 *
837 * @param int $contactID
838 *
839 * @return array
840 * CMS user details including
841 * - id
842 * - name (ie the system user name.
843 */
844 public function getUser($contactID) {
be2fb01f 845 $ufMatch = civicrm_api3('UFMatch', 'getsingle', [
2b0e7d03
EM
846 'contact_id' => $contactID,
847 'domain_id' => CRM_Core_Config::domainID(),
be2fb01f
CW
848 ]);
849 return [
2b0e7d03
EM
850 'id' => $ufMatch['uf_id'],
851 'name' => $ufMatch['uf_name'],
be2fb01f 852 ];
2b0e7d03
EM
853 }
854
32998c82
EM
855 /**
856 * Get currently logged in user uf id.
857 *
17f443df
CW
858 * @return int|null
859 * logged in user uf id.
32998c82 860 */
e7292422 861 public function getLoggedInUfID() {
17f443df 862 return NULL;
e7292422 863 }
32998c82 864
2b617cb0
EM
865 /**
866 * Get currently logged in user unique identifier - this tends to be the email address or user name.
867 *
17f443df 868 * @return string|null
a6c01b45 869 * logged in user unique identifier
2b617cb0 870 */
e7292422 871 public function getLoggedInUniqueIdentifier() {
17f443df 872 return NULL;
e7292422 873 }
2b617cb0 874
32998c82 875 /**
2b0e7d03
EM
876 * Return a UFID (user account ID from the UserFramework / CMS system.
877 *
878 * ID is based on the user object passed, defaulting to the logged in user if not passed.
879 *
880 * Note that ambiguous situation occurs in CRM_Core_BAO_UFMatch::synchronize - a cleaner approach would
881 * seem to be resolving the user id before calling the function.
32998c82
EM
882 *
883 * Note there is already a function getUFId which takes $username as a param - we could add $user
2b0e7d03
EM
884 * as a second param to it but it seems messy - just overloading it because the name is taken.
885 *
2b617cb0 886 * @param object $user
2b0e7d03 887 *
a6c01b45 888 * @return int
2b0e7d03 889 * User ID of UF System
32998c82 890 */
00be9182 891 public function getBestUFID($user = NULL) {
22e263ad 892 if ($user) {
32998c82
EM
893 return $this->getUserIDFromUserObject($user);
894 }
895 return $this->getLoggedInUfID();
896 }
2b617cb0
EM
897
898 /**
2b0e7d03
EM
899 * Return a unique identifier (usually an email address or username) from the UserFramework / CMS system.
900 *
901 * This is based on the user object passed, defaulting to the logged in user if not passed.
902 *
903 * Note that ambiguous situation occurs in CRM_Core_BAO_UFMatch::synchronize - a cleaner approach would seem to be
904 * resolving the unique identifier before calling the function.
2b617cb0
EM
905 *
906 * @param object $user
2b0e7d03 907 *
a6c01b45
CW
908 * @return string
909 * unique identifier from the UF System
2b617cb0 910 */
00be9182 911 public function getBestUFUniqueIdentifier($user = NULL) {
22e263ad 912 if ($user) {
2b617cb0
EM
913 return $this->getUniqueIdentifierFromUserObject($user);
914 }
915 return $this->getLoggedInUniqueIdentifier();
916 }
59f97da6 917
66e42142
CW
918 /**
919 * List modules installed in the CMS, including enabled and disabled ones.
920 *
921 * @return array
922 * [CRM_Core_Module]
923 */
924 public function getModules() {
be2fb01f 925 return [];
66e42142
CW
926 }
927
59f97da6 928 /**
fe482240 929 * Get Url to view user record.
2b0e7d03 930 *
77855840
TO
931 * @param int $contactID
932 * Contact ID.
59f97da6 933 *
17f443df 934 * @return string|null
59f97da6 935 */
00be9182 936 public function getUserRecordUrl($contactID) {
59f97da6
EM
937 return NULL;
938 }
353ffa53 939
59f97da6 940 /**
fe482240 941 * Is the current user permitted to add a user.
2b0e7d03 942 *
59f97da6
EM
943 * @return bool
944 */
00be9182 945 public function checkPermissionAddUser() {
59f97da6
EM
946 return FALSE;
947 }
f85b1d20
EM
948
949 /**
fe482240 950 * Output code from error function.
2b0e7d03 951 *
f85b1d20
EM
952 * @param string $content
953 */
00be9182 954 public function outputError($content) {
f85b1d20
EM
955 echo CRM_Utils_System::theme($content);
956 }
e0dd98a5
EM
957
958 /**
fe482240 959 * Log error to CMS.
17f443df 960 *
ad37ac8e 961 * @param string $message
e0dd98a5 962 */
00be9182 963 public function logger($message) {
e0dd98a5 964 }
f9f361d0
CW
965
966 /**
fe482240 967 * Append to coreResourcesList.
17f443df 968 *
303017a1 969 * @param \Civi\Core\Event\GenericHookEvent $e
f9f361d0 970 */
303017a1 971 public function appendCoreResources(\Civi\Core\Event\GenericHookEvent $e) {
e7292422 972 }
96025800 973
62c20d1e
CW
974 /**
975 * Modify dynamic assets.
976 *
977 * @param \Civi\Core\Event\GenericHookEvent $e
978 */
979 public function alterAssetUrl(\Civi\Core\Event\GenericHookEvent $e) {
980 }
981
d42a224c
CW
982 /**
983 * @param string $name
984 * @param string $value
985 */
986 public function setHttpHeader($name, $value) {
987 header("$name: $value");
988 }
989
03d5592a
CW
990 /**
991 * Create CRM contacts for all existing CMS users
992 *
993 * @return array
994 * @throws \Exception
995 */
996 public function synchronizeUsers() {
997 throw new Exception('CMS user creation not supported for this framework');
be2fb01f 998 return [];
03d5592a
CW
999 }
1000
79dd7fe9 1001 /**
46dddc5c
SL
1002 * Send an HTTP Response base on PSR HTTP RespnseInterface response.
1003 *
1004 * @param \Psr\Http\Message\ResponseInterface $response
79dd7fe9 1005 */
46dddc5c 1006 public function sendResponse(\Psr\Http\Message\ResponseInterface $response) {
fcfcd0f7 1007 http_response_code($response->getStatusCode());
90f6c8df
SL
1008 foreach ($response->getHeaders() as $name => $values) {
1009 CRM_Utils_System::setHttpHeader($name, implode(', ', (array) $values));
79dd7fe9 1010 }
46dddc5c
SL
1011 echo $response->getBody();
1012 CRM_Utils_System::civiExit();
79dd7fe9
SL
1013 }
1014
671f655b 1015 /**
1016 * Start a new session.
1017 */
1018 public function sessionStart() {
1019 session_start();
1020 }
1021
4d4d87f1 1022 /**
1023 * This exists because of https://www.drupal.org/node/3006306 where
1024 * they changed so that they don't start sessions for anonymous, but we
1025 * want that.
1026 */
1027 public function getSessionId() {
1028 return session_id();
1029 }
1030
08d5b4df
JP
1031 /**
1032 * Get role names
1033 *
1034 * @return array|null
1035 */
1036 public function getRoleNames() {
1037 return NULL;
1038 }
1039
9a8fe710
SL
1040 /**
1041 * Determine if the Views module exists.
1042 *
1043 * @return bool
1044 */
1045 public function viewsExists() {
1046 return FALSE;
1047 }
1048
bef5923d
CW
1049 /**
1050 * Perform any necessary actions prior to redirecting via POST.
1051 */
1052 public function prePostRedirect() {
1053 }
1054
839834b4 1055 /**
1056 * Return the CMS-specific url for its permissions page
1057 * @return array
1058 */
1059 public function getCMSPermissionsUrlParams() {
1060 return [];
1061 }
1062
6440c50d
EM
1063 /**
1064 * Get the CRM database as a 'prefix'.
1065 *
1066 * This returns a string that can be prepended to a query to include a CRM table.
1067 *
1068 * However, this string should contain backticks, or not, in accordance with the
1069 * CMS's drupal views expectations, if any.
1070 */
1071 public function getCRMDatabasePrefix(): string {
1072 $crmDatabase = DB::parseDSN(CRM_Core_Config::singleton()->dsn)['database'];
1073 $cmsDatabase = DB::parseDSN(CRM_Core_Config::singleton()->userFrameworkDSN)['database'];
1074 if ($crmDatabase === $cmsDatabase) {
1075 return '';
1076 }
1077 return "`$crmDatabase`.";
1078 }
1079
a11c1084
MT
1080 /**
1081 * Invalidates the cache of dynamic routes and forces a rebuild.
1082 */
1083 public function invalidateRouteCache() {
1084 }
1085
0e69cbc3 1086 /**
1087 * Should the admin be able to set the password when creating a user
1088 * or does the CMS want it a different way.
1089 */
1090 public function showPasswordFieldWhenAdminCreatesUser() {
1091 return TRUE;
1092 }
1093
3514b4c8
HD
1094 /**
1095 * Return the CMS-specific UF Group Types for profiles.
1096 * @return array
1097 */
1098 public function getUfGroupTypes() {
1099 return [];
1100 }
1101
6a488035 1102}