Merge pull request #13987 from seamuslee001/new_coder_pcp_pledge_profile_queue_report
[civicrm-core.git] / CRM / Utils / System / Base.php
1 <?php
2
3 /**
4 * Base class for UF system integrations
5 */
6 abstract class CRM_Utils_System_Base {
7
8 /**
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
12 * functions and leave the codebase oblivious to the type of CMS
13 *
14 * @var bool
15 * @deprecated
16 * TRUE, if the CMS is Drupal.
17 */
18 public $is_drupal = FALSE;
19
20 /**
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
22 * functions and leave the codebase oblivious to the type of CMS
23 *
24 * @var bool
25 * @deprecated
26 * TRUE, if the CMS is Joomla!.
27 */
28 public $is_joomla = FALSE;
29
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 *
34 * @var bool
35 * @deprecated
36 * TRUE, if the CMS is WordPress.
37 */
38 public $is_wordpress = FALSE;
39
40 /**
41 * Does this CMS / UF support a CMS specific logging mechanism?
42 * @var bool
43 * @todo - we should think about offering up logging mechanisms in a way that is also extensible by extensions
44 */
45 public $supports_UF_Logging = FALSE;
46
47 /**
48 * @var bool
49 * TRUE, if the CMS allows CMS forms to be extended by hooks.
50 */
51 public $supports_form_extensions = FALSE;
52
53 public function initialize() {
54 if (\CRM_Utils_System::isSSL()) {
55 $this->mapConfigToSSL();
56 }
57 }
58
59 abstract public function loadBootStrap($params = [], $loadUser = TRUE, $throwError = TRUE, $realPath = NULL);
60
61 /**
62 * Append an additional breadcrumb tag to the existing breadcrumb.
63 *
64 * @param array $breadCrumbs
65 */
66 public function appendBreadCrumb($breadCrumbs) {
67 }
68
69 /**
70 * Reset an additional breadcrumb tag to the existing breadcrumb.
71 */
72 public function resetBreadCrumb() {
73 }
74
75 /**
76 * Append a string to the head of the html file.
77 *
78 * @param string $head
79 * The new string to be appended.
80 */
81 public function addHTMLHead($head) {
82 }
83
84 /**
85 * Rewrite various system urls to https.
86 */
87 public function mapConfigToSSL() {
88 // dont need to do anything, let CMS handle their own switch to SSL
89 }
90
91 /**
92 * Figure out the post url for QuickForm.
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.
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).
127 *
128 * @return string
129 */
130 public function url(
131 $path = NULL,
132 $query = NULL,
133 $absolute = FALSE,
134 $fragment = NULL,
135 $frontend = FALSE,
136 $forceBackend = FALSE
137 ) {
138 return NULL;
139 }
140
141 /**
142 * Authenticate the user against the CMS db.
143 *
144 * @param string $name
145 * The user name.
146 * @param string $password
147 * The password for the above user.
148 * @param bool $loadCMSBootstrap
149 * Load cms bootstrap?.
150 * @param string $realPath
151 * Filename of script
152 *
153 * @return array|bool
154 * [contactID, ufID, unique string] else false if no auth
155 */
156 public function authenticate($name, $password, $loadCMSBootstrap = FALSE, $realPath = NULL) {
157 return FALSE;
158 }
159
160 /**
161 * Set a message in the CMS to display to a user.
162 *
163 * @param string $message
164 * The message to set.
165 */
166 public function setMessage($message) {
167 }
168
169 /**
170 * Load user into session.
171 *
172 * @param obj $user
173 *
174 * @return bool
175 */
176 public function loadUser($user) {
177 return TRUE;
178 }
179
180 /**
181 * Immediately stop script execution and display a 401 "Access Denied" page.
182 */
183 public function permissionDenied() {
184 CRM_Core_Error::fatal(ts('You do not have permission to access this page.'));
185 }
186
187 /**
188 * Immediately stop script execution, log out the user and redirect to the home page.
189 *
190 * @deprecated
191 * This function should be removed in favor of linking to the CMS's logout page
192 */
193 public function logout() {
194 }
195
196 /**
197 * Clear CMS caches related to the user registration/profile forms.
198 * Used when updating/embedding profiles on CMS user forms.
199 * @see CRM-3600
200 */
201 public function updateCategories() {
202 }
203
204 /**
205 * Get the locale set in the CMS.
206 *
207 * @return string|null
208 * Locale or null for none
209 */
210 public function getUFLocale() {
211 return NULL;
212 }
213
214 /**
215 * If we are using a theming system, invoke theme, else just print the content.
216 *
217 * @param string $content
218 * The content that will be themed.
219 * @param bool $print
220 * Are we displaying to the screen or bypassing theming?.
221 * @param bool $maintenance
222 * For maintenance mode.
223 *
224 * @throws Exception
225 * @return string|null
226 * NULL, If $print is FALSE, and some other criteria match up.
227 * The themed string, otherwise.
228 *
229 * @todo The return value is inconsistent.
230 * @todo Better to always return, and never print.
231 */
232 public function theme(&$content, $print = FALSE, $maintenance = FALSE) {
233 $ret = FALSE;
234
235 // TODO: Split up; this was copied verbatim from CiviCRM 4.0's multi-UF theming function
236 // but the parts should be copied into cleaner subclass implementations
237 $config = CRM_Core_Config::singleton();
238 if (
239 $config->userSystem->is_drupal &&
240 function_exists('theme') &&
241 !$print
242 ) {
243 if ($maintenance) {
244 drupal_set_breadcrumb('');
245 drupal_maintenance_theme();
246 if ($region = CRM_Core_Region::instance('html-header', FALSE)) {
247 CRM_Utils_System::addHTMLHead($region->render(''));
248 }
249 print theme('maintenance_page', ['content' => $content]);
250 exit();
251 }
252 // TODO: Figure out why D7 returns but everyone else prints
253 $ret = TRUE;
254 }
255 $out = $content;
256
257 $config = &CRM_Core_Config::singleton();
258 if (
259 !$print &&
260 $config->userFramework == 'WordPress'
261 ) {
262 if (!function_exists('is_admin')) {
263 throw new \Exception('Function "is_admin()" is missing, even though WordPress is the user framework.');
264 }
265 if (!defined('ABSPATH')) {
266 throw new \Exception('Constant "ABSPATH" is not defined, even though WordPress is the user framework.');
267 }
268 if (is_admin()) {
269 require_once ABSPATH . 'wp-admin/admin-header.php';
270 }
271 else {
272 // FIXME: we need to figure out to replace civicrm content on the frontend pages
273 }
274 }
275
276 if ($ret) {
277 return $out;
278 }
279 else {
280 print $out;
281 return NULL;
282 }
283 }
284
285 /**
286 * @return string
287 */
288 public function getDefaultBlockLocation() {
289 return 'left';
290 }
291
292 /**
293 * Get the absolute path to the site's base url.
294 *
295 * @return bool|mixed|string
296 */
297 public function getAbsoluteBaseURL() {
298 if (!defined('CIVICRM_UF_BASEURL')) {
299 return FALSE;
300 }
301
302 $url = CRM_Utils_File::addTrailingSlash(CIVICRM_UF_BASEURL, '/');
303
304 //format url for language negotiation, CRM-7803
305 $url = $this->languageNegotiationURL($url);
306
307 if (CRM_Utils_System::isSSL()) {
308 $url = str_replace('http://', 'https://', $url);
309 }
310
311 return $url;
312 }
313
314 /**
315 * Get the relative path to the sites base url.
316 *
317 * @return bool
318 */
319 public function getRelativeBaseURL() {
320 $absoluteBaseURL = $this->getAbsoluteBaseURL();
321 if ($absoluteBaseURL === FALSE) {
322 return FALSE;
323 }
324 $parts = parse_url($absoluteBaseURL);
325 return $parts['path'];
326 //$this->useFrameworkRelativeBase = empty($base['path']) ? '/' : $base['path'];
327 }
328
329 /**
330 * Get CMS Version.
331 *
332 * @return string
333 */
334 public function getVersion() {
335 return 'Unknown';
336 }
337
338 /**
339 * Format the url as per language Negotiation.
340 *
341 * @param string $url
342 * @param bool $addLanguagePart
343 * @param bool $removeLanguagePart
344 *
345 * @return string
346 * Formatted url.
347 */
348 public function languageNegotiationURL(
349 $url,
350 $addLanguagePart = TRUE,
351 $removeLanguagePart = FALSE
352 ) {
353 return $url;
354 }
355
356 /**
357 * Determine the location of the CMS root.
358 *
359 * @return string|null
360 * Local file system path to CMS root, or NULL if it cannot be determined
361 */
362 public function cmsRootPath() {
363 return NULL;
364 }
365
366 /**
367 * Create a user in the CMS.
368 *
369 * @param array $params
370 * @param string $mail
371 * Email id for cms user.
372 *
373 * @return int|bool
374 * uid if user exists, false otherwise
375 */
376 public function createUser(&$params, $mail) {
377 return FALSE;
378 }
379
380 /**
381 * Update a user's email address in the CMS.
382 *
383 * @param int $ufID
384 * User ID in CMS.
385 * @param string $email
386 * Primary contact email address.
387 */
388 public function updateCMSName($ufID, $email) {
389 }
390
391 /**
392 * Check if user is logged in to the CMS.
393 *
394 * @return bool
395 */
396 public function isUserLoggedIn() {
397 return FALSE;
398 }
399
400 /**
401 * Check if user registration is permitted.
402 *
403 * @return bool
404 */
405 public function isUserRegistrationPermitted() {
406 return FALSE;
407 }
408
409 /**
410 * Check if user can create passwords or is initially assigned a system-generated one.
411 *
412 * @return bool
413 */
414 public function isPasswordUserGenerated() {
415 return FALSE;
416 }
417
418 /**
419 * Get user login URL for hosting CMS (method declared in each CMS system class)
420 *
421 * @param string $destination
422 * If present, add destination to querystring (works for Drupal only).
423 *
424 * @return string
425 * loginURL for the current CMS
426 */
427 abstract public function getLoginURL($destination = '');
428
429 /**
430 * Get the login destination string.
431 *
432 * When this is passed in the URL the user will be directed to it after filling in the CMS form.
433 *
434 * @param CRM_Core_Form $form
435 * Form object representing the 'current' form - to which the user will be returned.
436 *
437 * @return string|NULL
438 * destination value for URL
439 */
440 public function getLoginDestination(&$form) {
441 return NULL;
442 }
443
444 /**
445 * Determine the native ID of the CMS user.
446 *
447 * @param string $username
448 *
449 * @throws CRM_Core_Exception
450 */
451 public function getUfId($username) {
452 $className = get_class($this);
453 throw new CRM_Core_Exception("Not implemented: {$className}->getUfId");
454 }
455
456 /**
457 * Set the localisation from the user framework.
458 *
459 * @param string $civicrm_language
460 *
461 * @return bool
462 */
463 public function setUFLocale($civicrm_language) {
464 return TRUE;
465 }
466
467 /**
468 * Set a init session with user object.
469 *
470 * @param array $data
471 * Array with user specific data
472 */
473 public function setUserSession($data) {
474 list($userID, $ufID) = $data;
475 $session = CRM_Core_Session::singleton();
476 $session->set('ufID', $ufID);
477 $session->set('userID', $userID);
478 }
479
480 /**
481 * Reset any system caches that may be required for proper CiviCRM integration.
482 */
483 public function flush() {
484 // nullop by default
485 }
486
487 /**
488 * Flush css/js caches.
489 */
490 public function clearResourceCache() {
491 // nullop by default
492 }
493
494 /**
495 * Add a script file.
496 *
497 * Note: This function is not to be called directly
498 * @see CRM_Core_Region::render()
499 *
500 * @param string $url absolute path to file
501 * @param string $region
502 * location within the document: 'html-header', 'page-header', 'page-footer'.
503 *
504 * @return bool
505 * TRUE if we support this operation in this CMS, FALSE otherwise
506 */
507 public function addScriptUrl($url, $region) {
508 return FALSE;
509 }
510
511 /**
512 * Add an inline script.
513 *
514 * Note: This function is not to be called directly
515 * @see CRM_Core_Region::render()
516 *
517 * @param string $code javascript code
518 * @param string $region
519 * location within the document: 'html-header', 'page-header', 'page-footer'.
520 *
521 * @return bool
522 * TRUE if we support this operation in this CMS, FALSE otherwise
523 */
524 public function addScript($code, $region) {
525 return FALSE;
526 }
527
528 /**
529 * Add a css file.
530 *
531 * Note: This function is not to be called directly
532 * @see CRM_Core_Region::render()
533 *
534 * @param string $url absolute path to file
535 * @param string $region
536 * location within the document: 'html-header', 'page-header', 'page-footer'.
537 *
538 * @return bool
539 * TRUE if we support this operation in this CMS, FALSE otherwise
540 */
541 public function addStyleUrl($url, $region) {
542 return FALSE;
543 }
544
545 /**
546 * Add an inline style.
547 *
548 * Note: This function is not to be called directly
549 * @see CRM_Core_Region::render()
550 *
551 * @param string $code css code
552 * @param string $region
553 * location within the document: 'html-header', 'page-header', 'page-footer'.
554 *
555 * @return bool
556 * TRUE if we support this operation in this CMS, FALSE otherwise
557 */
558 public function addStyle($code, $region) {
559 return FALSE;
560 }
561
562 /**
563 * Sets the title of the page.
564 *
565 * @param string $title
566 * Title to set in html header
567 * @param string|null $pageTitle
568 * Title to set in html body (if different)
569 */
570 public function setTitle($title, $pageTitle = NULL) {
571 }
572
573 /**
574 * Return default Site Settings.
575 *
576 * @param string $dir
577 *
578 * @return array
579 * - $url, (Joomla - non admin url)
580 * - $siteName,
581 * - $siteRoot
582 */
583 public function getDefaultSiteSettings($dir) {
584 $config = CRM_Core_Config::singleton();
585 $url = $config->userFrameworkBaseURL;
586 return [$url, NULL, NULL];
587 }
588
589 /**
590 * Determine the default location for file storage.
591 *
592 * FIXME:
593 * 1. This was pulled out from a bigger function. It should be split
594 * into even smaller pieces and marked abstract.
595 * 2. This would be easier to compute by a calling a CMS API, but
596 * for whatever reason Civi gets it from config data.
597 *
598 * @return array
599 * - url: string. ex: "http://example.com/sites/foo.com/files/civicrm"
600 * - path: string. ex: "/var/www/sites/foo.com/files/civicrm"
601 */
602 public function getDefaultFileStorage() {
603 global $civicrm_root;
604 $config = CRM_Core_Config::singleton();
605 $baseURL = CRM_Utils_System::languageNegotiationURL($config->userFrameworkBaseURL, FALSE, TRUE);
606
607 $filesURL = NULL;
608 $filesPath = NULL;
609
610 if ($config->userFramework == 'Joomla') {
611 // gross hack
612 // we need to remove the administrator/ from the end
613 $tempURL = str_replace("/administrator/", "/", $baseURL);
614 $filesURL = $tempURL . "media/civicrm/";
615 }
616 elseif ($config->userFramework == 'UnitTests') {
617 $filesURL = $baseURL . "sites/default/files/civicrm/";
618 }
619 else {
620 throw new CRM_Core_Exception("Failed to locate default file storage ($config->userFramework)");
621 }
622
623 return [
624 'url' => $filesURL,
625 'path' => CRM_Utils_File::baseFilePath(),
626 ];
627 }
628
629 /**
630 * Determine the location of the CiviCRM source tree.
631 *
632 * FIXME:
633 * 1. This was pulled out from a bigger function. It should be split
634 * into even smaller pieces and marked abstract.
635 * 2. This would be easier to compute by a calling a CMS API, but
636 * for whatever reason we take the hard way.
637 *
638 * @return array
639 * - url: string. ex: "http://example.com/sites/all/modules/civicrm"
640 * - path: string. ex: "/var/www/sites/all/modules/civicrm"
641 */
642 public function getCiviSourceStorage() {
643 global $civicrm_root;
644 $config = CRM_Core_Config::singleton();
645
646 // Don't use $config->userFrameworkBaseURL; it has garbage on it.
647 // More generally, w shouldn't be using $config here.
648 if (!defined('CIVICRM_UF_BASEURL')) {
649 throw new RuntimeException('Undefined constant: CIVICRM_UF_BASEURL');
650 }
651 $baseURL = CRM_Utils_File::addTrailingSlash(CIVICRM_UF_BASEURL, '/');
652 if (CRM_Utils_System::isSSL()) {
653 $baseURL = str_replace('http://', 'https://', $baseURL);
654 }
655
656 if ($config->userFramework == 'Joomla') {
657 $userFrameworkResourceURL = $baseURL . "components/com_civicrm/civicrm/";
658 }
659 elseif ($config->userFramework == 'WordPress') {
660 $userFrameworkResourceURL = CIVICRM_PLUGIN_URL . "civicrm/";
661 }
662 elseif ($this->is_drupal) {
663 // Drupal setting
664 // check and see if we are installed in sites/all (for D5 and above)
665 // we dont use checkURL since drupal generates an error page and throws
666 // the system for a loop on lobo's macosx box
667 // or in modules
668 $cmsPath = $config->userSystem->cmsRootPath();
669 $userFrameworkResourceURL = $baseURL . str_replace("$cmsPath/", '',
670 str_replace('\\', '/', $civicrm_root)
671 );
672
673 $siteName = $config->userSystem->parseDrupalSiteNameFromRoot($civicrm_root);
674 if ($siteName) {
675 $civicrmDirName = trim(basename($civicrm_root));
676 $userFrameworkResourceURL = $baseURL . "sites/$siteName/modules/$civicrmDirName/";
677 }
678 }
679 else {
680 $userFrameworkResourceURL = NULL;
681 }
682
683 return [
684 'url' => CRM_Utils_File::addTrailingSlash($userFrameworkResourceURL),
685 'path' => CRM_Utils_File::addTrailingSlash($civicrm_root),
686 ];
687 }
688
689 /**
690 * Perform any post login activities required by the CMS.
691 *
692 * e.g. for drupal: records a watchdog message about the new session, saves the login timestamp,
693 * calls hook_user op 'login' and generates a new session.
694 *
695 * @param array $params
696 *
697 * FIXME: Document values accepted/required by $params
698 */
699 public function userLoginFinalize($params = []) {
700 }
701
702 /**
703 * Set timezone in mysql so that timestamp fields show the correct time.
704 */
705 public function setMySQLTimeZone() {
706 $timeZoneOffset = $this->getTimeZoneOffset();
707 if ($timeZoneOffset) {
708 $sql = "SET time_zone = '$timeZoneOffset'";
709 CRM_Core_DAO::executequery($sql);
710 }
711 }
712
713 /**
714 * Get timezone from CMS.
715 *
716 * @return string|false|null
717 */
718 public function getTimeZoneOffset() {
719 $timezone = $this->getTimeZoneString();
720 if ($timezone) {
721 if ($timezone == 'UTC' || $timezone == 'Etc/UTC') {
722 // CRM-17072 Let's short-circuit all the zero handling & return it here!
723 return '+00:00';
724 }
725 $tzObj = new DateTimeZone($timezone);
726 $dateTime = new DateTime("now", $tzObj);
727 $tz = $tzObj->getOffset($dateTime);
728
729 if ($tz === 0) {
730 // CRM-21422
731 return '+00:00';
732 }
733
734 if (empty($tz)) {
735 return FALSE;
736 }
737
738 $timeZoneOffset = sprintf("%02d:%02d", $tz / 3600, abs(($tz / 60) % 60));
739
740 if ($timeZoneOffset > 0) {
741 $timeZoneOffset = '+' . $timeZoneOffset;
742 }
743 return $timeZoneOffset;
744 }
745 return NULL;
746 }
747
748 /**
749 * Get timezone as a string.
750 * @return string
751 * Timezone string e.g. 'America/Los_Angeles'
752 */
753 public function getTimeZoneString() {
754 return date_default_timezone_get();
755 }
756
757 /**
758 * Get Unique Identifier from UserFramework system (CMS).
759 *
760 * @param object $user
761 * Object as described by the User Framework.
762 *
763 * @return mixed
764 * Unique identifier from the user Framework system
765 */
766 public function getUniqueIdentifierFromUserObject($user) {
767 return NULL;
768 }
769
770 /**
771 * Get User ID from UserFramework system (CMS).
772 *
773 * @param object $user
774 *
775 * Object as described by the User Framework.
776 * @return null|int
777 */
778 public function getUserIDFromUserObject($user) {
779 return NULL;
780 }
781
782 /**
783 * Get an array of user details for a contact, containing at minimum the user ID & name.
784 *
785 * @param int $contactID
786 *
787 * @return array
788 * CMS user details including
789 * - id
790 * - name (ie the system user name.
791 */
792 public function getUser($contactID) {
793 $ufMatch = civicrm_api3('UFMatch', 'getsingle', [
794 'contact_id' => $contactID,
795 'domain_id' => CRM_Core_Config::domainID(),
796 ]);
797 return [
798 'id' => $ufMatch['uf_id'],
799 'name' => $ufMatch['uf_name'],
800 ];
801 }
802
803 /**
804 * Get currently logged in user uf id.
805 *
806 * @return int|null
807 * logged in user uf id.
808 */
809 public function getLoggedInUfID() {
810 return NULL;
811 }
812
813 /**
814 * Get currently logged in user unique identifier - this tends to be the email address or user name.
815 *
816 * @return string|null
817 * logged in user unique identifier
818 */
819 public function getLoggedInUniqueIdentifier() {
820 return NULL;
821 }
822
823 /**
824 * Return a UFID (user account ID from the UserFramework / CMS system.
825 *
826 * ID is based on the user object passed, defaulting to the logged in user if not passed.
827 *
828 * Note that ambiguous situation occurs in CRM_Core_BAO_UFMatch::synchronize - a cleaner approach would
829 * seem to be resolving the user id before calling the function.
830 *
831 * Note there is already a function getUFId which takes $username as a param - we could add $user
832 * as a second param to it but it seems messy - just overloading it because the name is taken.
833 *
834 * @param object $user
835 *
836 * @return int
837 * User ID of UF System
838 */
839 public function getBestUFID($user = NULL) {
840 if ($user) {
841 return $this->getUserIDFromUserObject($user);
842 }
843 return $this->getLoggedInUfID();
844 }
845
846 /**
847 * Return a unique identifier (usually an email address or username) from the UserFramework / CMS system.
848 *
849 * This is based on the user object passed, defaulting to the logged in user if not passed.
850 *
851 * Note that ambiguous situation occurs in CRM_Core_BAO_UFMatch::synchronize - a cleaner approach would seem to be
852 * resolving the unique identifier before calling the function.
853 *
854 * @param object $user
855 *
856 * @return string
857 * unique identifier from the UF System
858 */
859 public function getBestUFUniqueIdentifier($user = NULL) {
860 if ($user) {
861 return $this->getUniqueIdentifierFromUserObject($user);
862 }
863 return $this->getLoggedInUniqueIdentifier();
864 }
865
866 /**
867 * List modules installed in the CMS, including enabled and disabled ones.
868 *
869 * @return array
870 * [CRM_Core_Module]
871 */
872 public function getModules() {
873 return [];
874 }
875
876 /**
877 * Get Url to view user record.
878 *
879 * @param int $contactID
880 * Contact ID.
881 *
882 * @return string|null
883 */
884 public function getUserRecordUrl($contactID) {
885 return NULL;
886 }
887
888 /**
889 * Is the current user permitted to add a user.
890 *
891 * @return bool
892 */
893 public function checkPermissionAddUser() {
894 return FALSE;
895 }
896
897 /**
898 * Output code from error function.
899 *
900 * @param string $content
901 */
902 public function outputError($content) {
903 echo CRM_Utils_System::theme($content);
904 }
905
906 /**
907 * Log error to CMS.
908 *
909 * @param string $message
910 */
911 public function logger($message) {
912 }
913
914 /**
915 * Append to coreResourcesList.
916 *
917 * @param array $list
918 */
919 public function appendCoreResources(&$list) {
920 }
921
922 /**
923 * @param string $name
924 * @param string $value
925 */
926 public function setHttpHeader($name, $value) {
927 header("$name: $value");
928 }
929
930 /**
931 * Create CRM contacts for all existing CMS users
932 *
933 * @return array
934 * @throws \Exception
935 */
936 public function synchronizeUsers() {
937 throw new Exception('CMS user creation not supported for this framework');
938 return [];
939 }
940
941 }