drupal-civicrm/sites/all/modules/civicrm/CRM/Utils/System/Base.php

936 lines
23 KiB
PHP
Raw Permalink Normal View History

2018-01-14 15:10:16 +02:00
<?php
/**
* Base class for UF system integrations
*/
abstract class CRM_Utils_System_Base {
/**
* Deprecated property to check if this is a drupal install.
*
* The correct method is to have functions on the UF classes for all UF specific
* functions and leave the codebase oblivious to the type of CMS
*
* @deprecated
* @var bool
* TRUE, if the CMS is Drupal.
*/
var $is_drupal = FALSE;
/**
* 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
* functions and leave the codebase oblivious to the type of CMS
*
* @deprecated
* @var bool
* TRUE, if the CMS is Joomla!.
*/
var $is_joomla = FALSE;
/**
* 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
* functions and leave the codebase oblivious to the type of CMS
*
* @deprecated
* @var bool
* TRUE, if the CMS is WordPress.
*/
var $is_wordpress = FALSE;
/**
* Does this CMS / UF support a CMS specific logging mechanism?
* @todo - we should think about offering up logging mechanisms in a way that is also extensible by extensions
* @var bool
*/
var $supports_UF_Logging = FALSE;
/**
* @var bool
* TRUE, if the CMS allows CMS forms to be extended by hooks.
*/
var $supports_form_extensions = FALSE;
public function initialize() {
if (\CRM_Utils_System::isSSL()) {
$this->mapConfigToSSL();
}
}
/**
* Append an additional breadcrumb tag to the existing breadcrumb.
*
* @param array $breadCrumbs
*/
public function appendBreadCrumb($breadCrumbs) {
}
/**
* Reset an additional breadcrumb tag to the existing breadcrumb.
*/
public function resetBreadCrumb() {
}
/**
* Append a string to the head of the html file.
*
* @param string $head
* The new string to be appended.
*/
public function addHTMLHead($head) {
}
/**
* Rewrite various system urls to https.
*/
public function mapConfigToSSL() {
// dont need to do anything, let CMS handle their own switch to SSL
}
/**
* Figure out the post url for QuickForm.
*
* @param string $action
* The default url if one is pre-specified.
*
* @return string
* The url to post the form.
*/
public function postURL($action) {
$config = CRM_Core_Config::singleton();
if (!empty($action)) {
return $action;
}
return $this->url(CRM_Utils_Array::value($config->userFrameworkURLVar, $_GET),
NULL, TRUE, NULL, FALSE
);
}
/**
* Generate the url string to a CiviCRM path.
*
* @param string $path
* The path being linked to, such as "civicrm/add".
* @param string $query
* A query string to append to the link.
* @param bool $absolute
* Whether to force the output to be an absolute link (beginning with http).
* Useful for links that will be displayed outside the site, such as in an RSS feed.
* @param string $fragment
* A fragment identifier (named anchor) to append to the link.
* @param bool $frontend
* This link should be to the CMS front end (applies to WP & Joomla).
* @param bool $forceBackend
* This link should be to the CMS back end (applies to WP & Joomla).
*
* @return string
*/
public function url(
$path = NULL,
$query = NULL,
$absolute = FALSE,
$fragment = NULL,
$frontend = FALSE,
$forceBackend = FALSE
) {
return NULL;
}
/**
* Authenticate the user against the CMS db.
*
* @param string $name
* The user name.
* @param string $password
* The password for the above user.
* @param bool $loadCMSBootstrap
* Load cms bootstrap?.
* @param string $realPath
* Filename of script
*
* @return array|bool
* [contactID, ufID, unique string] else false if no auth
*/
public function authenticate($name, $password, $loadCMSBootstrap = FALSE, $realPath = NULL) {
return FALSE;
}
/**
* Set a message in the CMS to display to a user.
*
* @param string $message
* The message to set.
*/
public function setMessage($message) {
}
/**
* Load user into session.
*
* @param obj $user
*
* @return bool
*/
public function loadUser($user) {
return TRUE;
}
/**
* Immediately stop script execution and display a 401 "Access Denied" page.
*/
public function permissionDenied() {
CRM_Core_Error::fatal(ts('You do not have permission to access this page.'));
}
/**
* Immediately stop script execution, log out the user and redirect to the home page.
*
* @deprecated
* This function should be removed in favor of linking to the CMS's logout page
*/
public function logout() {
}
/**
* Clear CMS caches related to the user registration/profile forms.
* Used when updating/embedding profiles on CMS user forms.
* @see CRM-3600
*/
public function updateCategories() {
}
/**
* Get the locale set in the CMS.
*
* @return string|null
* Locale or null for none
*/
public function getUFLocale() {
return NULL;
}
/**
* If we are using a theming system, invoke theme, else just print the content.
*
* @param string $content
* The content that will be themed.
* @param bool $print
* Are we displaying to the screen or bypassing theming?.
* @param bool $maintenance
* For maintenance mode.
*
* @throws Exception
* @return string|null
* NULL, If $print is FALSE, and some other criteria match up.
* The themed string, otherwise.
*
* @todo The return value is inconsistent.
* @todo Better to always return, and never print.
*/
public function theme(&$content, $print = FALSE, $maintenance = FALSE) {
$ret = FALSE;
// TODO: Split up; this was copied verbatim from CiviCRM 4.0's multi-UF theming function
// but the parts should be copied into cleaner subclass implementations
$config = CRM_Core_Config::singleton();
if (
$config->userSystem->is_drupal &&
function_exists('theme') &&
!$print
) {
if ($maintenance) {
drupal_set_breadcrumb('');
drupal_maintenance_theme();
if ($region = CRM_Core_Region::instance('html-header', FALSE)) {
CRM_Utils_System::addHTMLHead($region->render(''));
}
print theme('maintenance_page', array('content' => $content));
exit();
}
// TODO: Figure out why D7 returns but everyone else prints
$ret = TRUE;
}
$out = $content;
$config = &CRM_Core_Config::singleton();
if (
!$print &&
$config->userFramework == 'WordPress'
) {
if (!function_exists('is_admin')) {
throw new \Exception('Function "is_admin()" is missing, even though WordPress is the user framework.');
}
if (!defined('ABSPATH')) {
throw new \Exception('Constant "ABSPATH" is not defined, even though WordPress is the user framework.');
}
if (is_admin()) {
require_once ABSPATH . 'wp-admin/admin-header.php';
}
else {
// FIXME: we need to figure out to replace civicrm content on the frontend pages
}
}
if ($ret) {
return $out;
}
else {
print $out;
return NULL;
}
}
/**
* @return string
*/
public function getDefaultBlockLocation() {
return 'left';
}
/**
* Get the absolute path to the site's base url.
*
* @return bool|mixed|string
*/
public function getAbsoluteBaseURL() {
if (!defined('CIVICRM_UF_BASEURL')) {
return FALSE;
}
$url = CRM_Utils_File::addTrailingSlash(CIVICRM_UF_BASEURL, '/');
//format url for language negotiation, CRM-7803
$url = $this->languageNegotiationURL($url);
if (CRM_Utils_System::isSSL()) {
$url = str_replace('http://', 'https://', $url);
}
return $url;
}
/**
* Get the relative path to the sites base url.
*
* @return bool
*/
public function getRelativeBaseURL() {
$absoluteBaseURL = $this->getAbsoluteBaseURL();
if ($absoluteBaseURL === FALSE) {
return FALSE;
}
$parts = parse_url($absoluteBaseURL);
return $parts['path'];
//$this->useFrameworkRelativeBase = empty($base['path']) ? '/' : $base['path'];
}
/**
* Get CMS Version.
*
* @return string
*/
public function getVersion() {
return 'Unknown';
}
/**
* Format the url as per language Negotiation.
*
* @param string $url
* @param bool $addLanguagePart
* @param bool $removeLanguagePart
*
* @return string
* Formatted url.
*/
public function languageNegotiationURL(
$url,
$addLanguagePart = TRUE,
$removeLanguagePart = FALSE
) {
return $url;
}
/**
* Determine the location of the CMS root.
*
* @return string|null
* Local file system path to CMS root, or NULL if it cannot be determined
*/
public function cmsRootPath() {
return NULL;
}
/**
* Create a user in the CMS.
*
* @param array $params
* @param string $mail
* Email id for cms user.
*
* @return int|bool
* uid if user exists, false otherwise
*/
public function createUser(&$params, $mail) {
return FALSE;
}
/**
* Update a user's email address in the CMS.
*
* @param int $ufID
* User ID in CMS.
* @param string $email
* Primary contact email address.
*/
public function updateCMSName($ufID, $email) {
}
/**
* Check if user is logged in to the CMS.
*
* @return bool
*/
public function isUserLoggedIn() {
return FALSE;
}
/**
* Check if user registration is permitted.
*
* @return bool
*/
public function isUserRegistrationPermitted() {
return FALSE;
}
/**
* Check if user can create passwords or is initially assigned a system-generated one.
*
* @return bool
*/
public function isPasswordUserGenerated() {
return FALSE;
}
/**
* Get user login URL for hosting CMS (method declared in each CMS system class)
*
* @param string $destination
* If present, add destination to querystring (works for Drupal only).
*
* @return string
* loginURL for the current CMS
*/
public abstract function getLoginURL($destination = '');
/**
* Get the login destination string.
*
* When this is passed in the URL the user will be directed to it after filling in the CMS form.
*
* @param CRM_Core_Form $form
* Form object representing the 'current' form - to which the user will be returned.
*
* @return string|NULL
* destination value for URL
*/
public function getLoginDestination(&$form) {
return NULL;
}
/**
* Determine the native ID of the CMS user.
*
* @param string $username
*
* @throws CRM_Core_Exception
*/
public function getUfId($username) {
$className = get_class($this);
throw new CRM_Core_Exception("Not implemented: {$className}->getUfId");
}
/**
* Set the localisation from the user framework.
*
* @param string $civicrm_language
*
* @return bool
*/
public function setUFLocale($civicrm_language) {
return TRUE;
}
/**
* Set a init session with user object.
*
* @param array $data
* Array with user specific data
*/
public function setUserSession($data) {
list($userID, $ufID) = $data;
$session = CRM_Core_Session::singleton();
$session->set('ufID', $ufID);
$session->set('userID', $userID);
}
/**
* Reset any system caches that may be required for proper CiviCRM integration.
*/
public function flush() {
// nullop by default
}
/**
* Flush css/js caches.
*/
public function clearResourceCache() {
// nullop by default
}
/**
* Add a script file.
*
* Note: This function is not to be called directly
* @see CRM_Core_Region::render()
*
* @param string $url absolute path to file
* @param string $region
* location within the document: 'html-header', 'page-header', 'page-footer'.
*
* @return bool
* TRUE if we support this operation in this CMS, FALSE otherwise
*/
public function addScriptUrl($url, $region) {
return FALSE;
}
/**
* Add an inline script.
*
* Note: This function is not to be called directly
* @see CRM_Core_Region::render()
*
* @param string $code javascript code
* @param string $region
* location within the document: 'html-header', 'page-header', 'page-footer'.
*
* @return bool
* TRUE if we support this operation in this CMS, FALSE otherwise
*/
public function addScript($code, $region) {
return FALSE;
}
/**
* Add a css file.
*
* Note: This function is not to be called directly
* @see CRM_Core_Region::render()
*
* @param string $url absolute path to file
* @param string $region
* location within the document: 'html-header', 'page-header', 'page-footer'.
*
* @return bool
* TRUE if we support this operation in this CMS, FALSE otherwise
*/
public function addStyleUrl($url, $region) {
return FALSE;
}
/**
* Add an inline style.
*
* Note: This function is not to be called directly
* @see CRM_Core_Region::render()
*
* @param string $code css code
* @param string $region
* location within the document: 'html-header', 'page-header', 'page-footer'.
*
* @return bool
* TRUE if we support this operation in this CMS, FALSE otherwise
*/
public function addStyle($code, $region) {
return FALSE;
}
/**
* Sets the title of the page.
*
* @param string $title
* Title to set in html header
* @param string|null $pageTitle
* Title to set in html body (if different)
*/
public function setTitle($title, $pageTitle = NULL) {
}
/**
* Return default Site Settings.
*
* @param string $dir
*
* @return array
* - $url, (Joomla - non admin url)
* - $siteName,
* - $siteRoot
*/
public function getDefaultSiteSettings($dir) {
$config = CRM_Core_Config::singleton();
$url = $config->userFrameworkBaseURL;
return array($url, NULL, NULL);
}
/**
* Determine the default location for file storage.
*
* FIXME:
* 1. This was pulled out from a bigger function. It should be split
* into even smaller pieces and marked abstract.
* 2. This would be easier to compute by a calling a CMS API, but
* for whatever reason Civi gets it from config data.
*
* @return array
* - url: string. ex: "http://example.com/sites/foo.com/files/civicrm"
* - path: string. ex: "/var/www/sites/foo.com/files/civicrm"
*/
public function getDefaultFileStorage() {
global $civicrm_root;
$config = CRM_Core_Config::singleton();
$baseURL = CRM_Utils_System::languageNegotiationURL($config->userFrameworkBaseURL, FALSE, TRUE);
$filesURL = NULL;
$filesPath = NULL;
if ($config->userFramework == 'Joomla') {
// gross hack
// we need to remove the administrator/ from the end
$tempURL = str_replace("/administrator/", "/", $baseURL);
$filesURL = $tempURL . "media/civicrm/";
}
elseif ($config->userFramework == 'UnitTests') {
$filesURL = $baseURL . "sites/default/files/civicrm/";
}
else {
throw new CRM_Core_Exception("Failed to locate default file storage ($config->userFramework)");
}
return array(
'url' => $filesURL,
'path' => CRM_Utils_File::baseFilePath(),
);
}
/**
* Determine the location of the CiviCRM source tree.
*
* FIXME:
* 1. This was pulled out from a bigger function. It should be split
* into even smaller pieces and marked abstract.
* 2. This would be easier to compute by a calling a CMS API, but
* for whatever reason we take the hard way.
*
* @return array
* - url: string. ex: "http://example.com/sites/all/modules/civicrm"
* - path: string. ex: "/var/www/sites/all/modules/civicrm"
*/
public function getCiviSourceStorage() {
global $civicrm_root;
$config = CRM_Core_Config::singleton();
// Don't use $config->userFrameworkBaseURL; it has garbage on it.
// More generally, w shouldn't be using $config here.
if (!defined('CIVICRM_UF_BASEURL')) {
throw new RuntimeException('Undefined constant: CIVICRM_UF_BASEURL');
}
$baseURL = CRM_Utils_File::addTrailingSlash(CIVICRM_UF_BASEURL, '/');
if (CRM_Utils_System::isSSL()) {
$baseURL = str_replace('http://', 'https://', $baseURL);
}
if ($config->userFramework == 'Joomla') {
$userFrameworkResourceURL = $baseURL . "components/com_civicrm/civicrm/";
}
elseif ($config->userFramework == 'WordPress') {
$userFrameworkResourceURL = CIVICRM_PLUGIN_URL . "civicrm/";
}
elseif ($this->is_drupal) {
// Drupal setting
// check and see if we are installed in sites/all (for D5 and above)
// we dont use checkURL since drupal generates an error page and throws
// the system for a loop on lobo's macosx box
// or in modules
$cmsPath = $config->userSystem->cmsRootPath();
$userFrameworkResourceURL = $baseURL . str_replace("$cmsPath/", '',
str_replace('\\', '/', $civicrm_root)
);
$siteName = $config->userSystem->parseDrupalSiteNameFromRoot($civicrm_root);
if ($siteName) {
$civicrmDirName = trim(basename($civicrm_root));
$userFrameworkResourceURL = $baseURL . "sites/$siteName/modules/$civicrmDirName/";
}
}
else {
$userFrameworkResourceURL = NULL;
}
return array(
'url' => CRM_Utils_File::addTrailingSlash($userFrameworkResourceURL),
'path' => CRM_Utils_File::addTrailingSlash($civicrm_root),
);
}
/**
* Perform any post login activities required by the CMS.
*
* e.g. for drupal: records a watchdog message about the new session, saves the login timestamp,
* calls hook_user op 'login' and generates a new session.
*
* @param array $params
*
* FIXME: Document values accepted/required by $params
*/
public function userLoginFinalize($params = array()) {
}
/**
* Set timezone in mysql so that timestamp fields show the correct time.
*/
public function setMySQLTimeZone() {
$timeZoneOffset = $this->getTimeZoneOffset();
if ($timeZoneOffset) {
$sql = "SET time_zone = '$timeZoneOffset'";
CRM_Core_DAO::executequery($sql);
}
}
/**
* Get timezone from CMS.
*
* @return string|false|null
*/
public function getTimeZoneOffset() {
$timezone = $this->getTimeZoneString();
if ($timezone) {
if ($timezone == 'UTC' || $timezone == 'Etc/UTC') {
// CRM-17072 Let's short-circuit all the zero handling & return it here!
return '+00:00';
}
$tzObj = new DateTimeZone($timezone);
$dateTime = new DateTime("now", $tzObj);
$tz = $tzObj->getOffset($dateTime);
if (empty($tz)) {
return FALSE;
}
$timeZoneOffset = sprintf("%02d:%02d", $tz / 3600, abs(($tz / 60) % 60));
if ($timeZoneOffset > 0) {
$timeZoneOffset = '+' . $timeZoneOffset;
}
return $timeZoneOffset;
}
return NULL;
}
/**
* Get timezone as a string.
* @return string
* Timezone string e.g. 'America/Los_Angeles'
*/
public function getTimeZoneString() {
return date_default_timezone_get();
}
/**
* Get Unique Identifier from UserFramework system (CMS).
*
* @param object $user
* Object as described by the User Framework.
*
* @return mixed
* Unique identifier from the user Framework system
*/
public function getUniqueIdentifierFromUserObject($user) {
return NULL;
}
/**
* Get User ID from UserFramework system (CMS).
*
* @param object $user
*
* Object as described by the User Framework.
* @return null|int
*/
public function getUserIDFromUserObject($user) {
return NULL;
}
/**
* Get an array of user details for a contact, containing at minimum the user ID & name.
*
* @param int $contactID
*
* @return array
* CMS user details including
* - id
* - name (ie the system user name.
*/
public function getUser($contactID) {
$ufMatch = civicrm_api3('UFMatch', 'getsingle', array(
'contact_id' => $contactID,
'domain_id' => CRM_Core_Config::domainID(),
));
return array(
'id' => $ufMatch['uf_id'],
'name' => $ufMatch['uf_name'],
);
}
/**
* Get currently logged in user uf id.
*
* @return int|null
* logged in user uf id.
*/
public function getLoggedInUfID() {
return NULL;
}
/**
* Get currently logged in user unique identifier - this tends to be the email address or user name.
*
* @return string|null
* logged in user unique identifier
*/
public function getLoggedInUniqueIdentifier() {
return NULL;
}
/**
* Return a UFID (user account ID from the UserFramework / CMS system.
*
* ID is based on the user object passed, defaulting to the logged in user if not passed.
*
* Note that ambiguous situation occurs in CRM_Core_BAO_UFMatch::synchronize - a cleaner approach would
* seem to be resolving the user id before calling the function.
*
* Note there is already a function getUFId which takes $username as a param - we could add $user
* as a second param to it but it seems messy - just overloading it because the name is taken.
*
* @param object $user
*
* @return int
* User ID of UF System
*/
public function getBestUFID($user = NULL) {
if ($user) {
return $this->getUserIDFromUserObject($user);
}
return $this->getLoggedInUfID();
}
/**
* Return a unique identifier (usually an email address or username) from the UserFramework / CMS system.
*
* This is based on the user object passed, defaulting to the logged in user if not passed.
*
* Note that ambiguous situation occurs in CRM_Core_BAO_UFMatch::synchronize - a cleaner approach would seem to be
* resolving the unique identifier before calling the function.
*
* @param object $user
*
* @return string
* unique identifier from the UF System
*/
public function getBestUFUniqueIdentifier($user = NULL) {
if ($user) {
return $this->getUniqueIdentifierFromUserObject($user);
}
return $this->getLoggedInUniqueIdentifier();
}
/**
* List modules installed in the CMS, including enabled and disabled ones.
*
* @return array
* [CRM_Core_Module]
*/
public function getModules() {
return array();
}
/**
* Get Url to view user record.
*
* @param int $contactID
* Contact ID.
*
* @return string|null
*/
public function getUserRecordUrl($contactID) {
return NULL;
}
/**
* Is the current user permitted to add a user.
*
* @return bool
*/
public function checkPermissionAddUser() {
return FALSE;
}
/**
* Output code from error function.
*
* @param string $content
*/
public function outputError($content) {
echo CRM_Utils_System::theme($content);
}
/**
* Log error to CMS.
*
* @param string $message
*/
public function logger($message) {
}
/**
* Append to coreResourcesList.
*
* @param array $list
*/
public function appendCoreResources(&$list) {
}
/**
* @param string $name
* @param string $value
*/
public function setHttpHeader($name, $value) {
header("$name: $value");
}
/**
* Create CRM contacts for all existing CMS users
*
* @return array
* @throws \Exception
*/
public function synchronizeUsers() {
throw new Exception('CMS user creation not supported for this framework');
return array();
}
}