bef5c5780f82717f4a5dc1402b0273bfa402ed3c
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
37 * Joomla specific stuff goes here
39 class CRM_Utils_System_Joomla
extends CRM_Utils_System_Base
{
43 function __construct() {
45 * 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
46 * functions and leave the codebase oblivious to the type of CMS
50 $this->is_drupal
= FALSE;
54 * Function to create a user of Joomla.
56 * @param array $params associated array
57 * @param string $mail email id for cms user
59 * @return uid if user exists, false otherwise
63 function createUser(&$params, $mail) {
64 $baseDir = JPATH_SITE
;
65 require_once $baseDir . '/components/com_users/models/registration.php';
67 $userParams = JComponentHelper
::getParams('com_users');
68 $model = new UsersModelRegistration();
71 // get the default usertype
72 $userType = $userParams->get('new_usertype');
77 if (isset($params['name'])) {
78 $fullname = trim($params['name']);
80 elseif (isset($params['contactID'])) {
81 $fullname = trim(CRM_Contact_BAO_Contact
::displayName($params['contactID']));
84 $fullname = trim($params['cms_name']);
87 // Prepare the values for a new Joomla user.
89 $values['name'] = $fullname;
90 $values['username'] = trim($params['cms_name']);
91 $values['password1'] = $values['password2'] = $params['cms_pass'];
92 $values['email1'] = $values['email2'] = trim($params[$mail]);
94 $lang = JFactory
::getLanguage();
95 $lang->load('com_users', $baseDir);
97 $register = $model->register($values);
99 $ufID = JUserHelper
::getUserId($values['username']);
104 * Change user name in host CMS
106 * @param integer $ufID User ID in CMS
107 * @param string $ufName User name
109 function updateCMSName($ufID, $ufName) {
110 $ufID = CRM_Utils_Type
::escape($ufID, 'Integer');
111 $ufName = CRM_Utils_Type
::escape($ufName, 'String');
114 $user = JUser
::getInstance($ufID);
116 $values['email'] = $ufName;
117 $user->bind($values);
123 * Check if username and email exists in the Joomla! db
125 * @params $params array array of name and mail values
126 * @params $errors array array of errors
127 * @params $emailName string field label for the 'email'
131 * @param string $emailName
135 function checkUserNameEmailExists(&$params, &$errors, $emailName = 'email') {
136 $config = CRM_Core_Config
::singleton();
138 $dao = new CRM_Core_DAO();
139 $name = $dao->escape(CRM_Utils_Array
::value('name', $params));
140 $email = $dao->escape(CRM_Utils_Array
::value('mail', $params));
141 //don't allow the special characters and min. username length is two
142 //regex \\ to match a single backslash would become '/\\\\/'
143 $isNotValid = (bool) preg_match('/[\<|\>|\"|\'|\%|\;|\(|\)|\&|\\\\|\/]/im', $name);
144 if ($isNotValid ||
strlen($name) < 2) {
145 $errors['cms_name'] = ts('Your username contains invalid characters or is too short');
149 $JUserTable = &JTable
::getInstance('User', 'JTable');
151 $db = $JUserTable->getDbo();
152 $query = $db->getQuery(TRUE);
153 $query->select('username, email');
154 $query->from($JUserTable->getTableName());
155 $query->where('(LOWER(username) = LOWER(\'' . $name . '\')) OR (LOWER(email) = LOWER(\'' . $email . '\'))');
156 $db->setQuery($query, 0, 10);
157 $users = $db->loadAssocList();
165 $dbName = CRM_Utils_Array
::value('username', $row);
166 $dbEmail = CRM_Utils_Array
::value('email', $row);
167 if (strtolower($dbName) == strtolower($name)) {
168 $errors['cms_name'] = ts('The username %1 is already taken. Please select another username.',
172 if (strtolower($dbEmail) == strtolower($email)) {
173 $resetUrl = str_replace('administrator/', '', $config->userFrameworkBaseURL
) . 'index.php?option=com_users&view=reset';
174 $errors[$emailName] = ts('The email address %1 is already registered. <a href="%2">Have you forgotten your password?</a>',
175 array(1 => $email, 2 => $resetUrl)
182 * sets the title of the page
184 * @param string $title title to set
185 * @param string $pageTitle
190 function setTitle($title, $pageTitle = NULL) {
195 $template = CRM_Core_Smarty
::singleton();
196 $template->assign('pageTitle', $pageTitle);
198 $document = JFactory
::getDocument();
199 $document->setTitle($title);
205 * Append an additional breadcrumb tag to the existing breadcrumb
207 * @param $breadCrumbs
209 * @internal param string $title
210 * @internal param string $url
215 function appendBreadCrumb($breadCrumbs) {
216 $template = CRM_Core_Smarty
::singleton();
217 $bc = $template->get_template_vars('breadcrumb');
219 if (is_array($breadCrumbs)) {
220 foreach ($breadCrumbs as $crumbs) {
221 if (stripos($crumbs['url'], 'id%%')) {
222 $args = array('cid', 'mid');
223 foreach ($args as $a) {
224 $val = CRM_Utils_Request
::retrieve($a, 'Positive', CRM_Core_DAO
::$_nullObject,
228 $crumbs['url'] = str_ireplace("%%{$a}%%", $val, $crumbs['url']);
235 $template->assign_by_ref('breadcrumb', $bc);
240 * Reset an additional breadcrumb tag to the existing breadcrumb
242 * @internal param string $bc the new breadcrumb to be appended
247 function resetBreadCrumb() {
252 * Append a string to the head of the html file
254 * @param null $string
256 * @internal param string $head the new string to be appended
261 static function addHTMLHead($string = NULL) {
263 $document = JFactory
::getDocument();
264 $document->addCustomTag($string);
271 * @param $url: string, absolute path to file
272 * @param $region string, location within the document: 'html-header', 'page-header', 'page-footer'
274 * Note: This function is not to be called directly
275 * @see CRM_Core_Region::render()
277 * @return bool TRUE if we support this operation in this CMS, FALSE otherwise
280 public function addScriptUrl($url, $region) {
285 * Add an inline script
287 * @param $code: string, javascript code
288 * @param $region string, location within the document: 'html-header', 'page-header', 'page-footer'
290 * Note: This function is not to be called directly
291 * @see CRM_Core_Region::render()
293 * @return bool TRUE if we support this operation in this CMS, FALSE otherwise
296 public function addScript($code, $region) {
303 * @param $url: string, absolute path to file
304 * @param $region string, location within the document: 'html-header', 'page-header', 'page-footer'
306 * Note: This function is not to be called directly
307 * @see CRM_Core_Region::render()
309 * @return bool TRUE if we support this operation in this CMS, FALSE otherwise
312 public function addStyleUrl($url, $region) {
313 if ($region == 'html-header') {
314 $document = JFactory
::getDocument();
315 $document->addStyleSheet($url);
322 * Add an inline style
324 * @param $code: string, css code
325 * @param $region string, location within the document: 'html-header', 'page-header', 'page-footer'
327 * Note: This function is not to be called directly
328 * @see CRM_Core_Region::render()
330 * @return bool TRUE if we support this operation in this CMS, FALSE otherwise
333 public function addStyle($code, $region) {
334 if ($region == 'html-header') {
335 $document = JFactory
::getDocument();
336 $document->addStyleDeclaration($code);
343 * Generate an internal CiviCRM URL
345 * @param $path string The path being linked to, such as "civicrm/add"
346 * @param $query string A query string to append to the link.
347 * @param $absolute boolean Whether to force the output to be an absolute link (beginning with http:).
348 * Useful for links that will be displayed outside the site, such as in an
350 * @param $fragment string A fragment identifier (named anchor) to append to the link.
351 * @param $htmlize boolean whether to convert to html eqivalant
352 * @param $frontend boolean a gross joomla hack
354 * @param bool $forceBackend
356 * @return string an HTML string containing a link to the given path.
359 function url($path = NULL, $query = NULL, $absolute = TRUE,
360 $fragment = NULL, $htmlize = TRUE,
361 $frontend = FALSE, $forceBackend = FALSE
363 $config = CRM_Core_Config
::singleton();
364 $separator = $htmlize ?
'&' : '&';
367 $path = CRM_Utils_String
::stripPathChars($path);
369 if ($config->userFrameworkFrontend
) {
370 $script = 'index.php';
371 if (JRequest
::getVar("Itemid")) {
372 $Itemid = "{$separator}Itemid=" . JRequest
::getVar("Itemid");
376 if (isset($fragment)) {
377 $fragment = '#' . $fragment;
380 if (!isset($config->useFrameworkRelativeBase
)) {
381 $base = parse_url($config->userFrameworkBaseURL
);
382 $config->useFrameworkRelativeBase
= $base['path'];
384 $base = $absolute ?
$config->userFrameworkBaseURL
: $config->useFrameworkRelativeBase
;
386 if (!empty($query)) {
387 $url = "{$base}{$script}?option=com_civicrm{$separator}task={$path}{$Itemid}{$separator}{$query}{$fragment}";
390 $url = "{$base}{$script}?option=com_civicrm{$separator}task={$path}{$Itemid}{$fragment}";
393 // gross hack for joomla, we are in the backend and want to send a frontend url
394 if ($frontend && $config->userFramework
== 'Joomla') {
395 // handle both joomla v1.5 and v1.6, CRM-7939
396 $url = str_replace('/administrator/index2.php', '/index.php', $url);
397 $url = str_replace('/administrator/index.php', '/index.php', $url);
400 $url = str_replace('/administrator/', '/index.php', $url);
402 elseif ($forceBackend) {
403 if (defined('JVERSION')) {
404 $joomlaVersion = JVERSION
;
406 $jversion = new JVersion
;
407 $joomlaVersion = $jversion->getShortVersion();
410 if (version_compare($joomlaVersion, '1.6') >= 0) {
411 $url = str_replace('/index.php', '/administrator/index.php', $url);
418 * rewrite various system urls to https
423 function mapConfigToSSL() {
424 // dont need to do anything, let CMS handle their own switch to SSL
429 * figure out the post url for the form
431 * @param $action the default action if one is pre-specified
433 * @return string the url to post the form
436 function postURL($action) {
437 if (!empty($action)) {
441 return $this->url(CRM_Utils_Array
::value('task', $_GET),
442 NULL, TRUE, NULL, FALSE
447 * Function to set the email address of the user
449 * @param object $user handle to the user object
454 function setEmail(&$user) {
456 $query = "SELECT email FROM #__users WHERE id='$user->id'";
457 $database->setQuery($query);
458 $user->email
= $database->loadResult();
462 * Authenticate the user against the joomla db
464 * @param string $name the user name
465 * @param string $password the password for the above user name
466 * @param $loadCMSBootstrap boolean load cms bootstrap?
468 * @return mixed false if no auth
470 contactID, ufID, unique string ) if success
473 function authenticate($name, $password, $loadCMSBootstrap = FALSE) {
474 require_once 'DB.php';
476 $config = CRM_Core_Config
::singleton();
479 if ($loadCMSBootstrap) {
480 $bootStrapParams = array();
481 if ($name && $password) {
482 $bootStrapParams = array(
487 CRM_Utils_System
::loadBootStrap($bootStrapParams, TRUE, TRUE, FALSE);
490 jimport('joomla.application.component.helper');
491 jimport('joomla.database.table');
492 jimport('joomla.user.helper');
494 $JUserTable = JTable
::getInstance('User', 'JTable');
496 $db = $JUserTable->getDbo();
497 $query = $db->getQuery(TRUE);
498 $query->select('id, name, username, email, password');
499 $query->from($JUserTable->getTableName());
500 $query->where('(LOWER(username) = LOWER(\'' . $name . '\')) AND (block = 0)');
501 $db->setQuery($query, 0, 0);
502 $users = $db->loadObjectList();
509 $joomlaBase = dirname(dirname(dirname(dirname(dirname(dirname(dirname(dirname(__FILE__
))))))));
510 if ( !defined('JVERSION') ) {
511 require $joomlaBase . '/libraries/cms/version/version.php';
512 $jversion = new JVersion
;
513 define('JVERSION', $jversion->getShortVersion());
517 $dbPassword = $row->password
;
519 $dbEmail = $row->email
;
521 if ( version_compare(JVERSION
, '2.5.18', 'lt') ||
522 ( version_compare(JVERSION
, '3.0', 'ge') && version_compare(JVERSION
, '3.2.1', 'lt') )
524 // now check password
525 if (strpos($dbPassword, ':') === FALSE) {
526 if ($dbPassword != md5($password)) {
531 list($hash, $salt) = explode(':', $dbPassword);
532 $cryptpass = md5($password . $salt);
533 if ($hash != $cryptpass) {
539 if (!JUserHelper
::verifyPassword($password, $dbPassword, $dbId)) return FALSE;
541 //include additional files required by Joomla 3.2.1+
542 if ( version_compare(JVERSION
, '3.2.1', 'ge') ) {
543 require_once $joomlaBase . '/libraries/cms/application/helper.php';
544 require_once $joomlaBase . '/libraries/cms/application/cms.php';
545 require_once $joomlaBase . '/libraries/cms/application/administrator.php';
549 CRM_Core_BAO_UFMatch
::synchronizeUFMatch($row, $dbId, $dbEmail, 'Joomla');
550 $contactID = CRM_Core_BAO_UFMatch
::getContactId($dbId);
554 return array($contactID, $dbId, mt_rand());
561 * Set a init session with user object
563 * @param array $data array with user specific data
567 function setUserSession($data) {
568 list($userID, $ufID) = $data;
569 $user = new JUser( $ufID );
570 $session = JFactory
::getSession();
571 $session->set('user', $user);
573 parent
::setUserSession($data);
577 * Set a message in the UF to display to a user
579 * @param string $message the message to set
583 function setMessage($message) {
592 function loadUser($user) {
596 function permissionDenied() {
597 CRM_Core_Error
::fatal(ts('You do not have permission to access this page'));
602 header("Location:index.php");
606 * Get the locale set in the hosting CMS
608 * @return string the used locale or null for none
610 function getUFLocale() {
611 if (defined('_JEXEC')) {
612 $conf = JFactory
::getConfig();
613 $locale = $conf->get('language');
614 return str_replace('-', '_', $locale);
622 function getVersion() {
623 if (class_exists('JVersion')) {
624 $version = new JVersion
;
625 return $version->getShortVersion();
633 * load joomla bootstrap
635 * @param $params array with uid or name and password
636 * @param $loadUser boolean load cms user?
637 * @param bool|\throw $throwError throw error on failure?
638 * @param null $realPath
639 * @param bool $loadDefines
643 function loadBootStrap($params = array(), $loadUser = TRUE, $throwError = TRUE, $realPath = NULL, $loadDefines = TRUE) {
644 // Setup the base path related constant.
645 $joomlaBase = dirname(dirname(dirname(dirname(dirname(dirname(dirname(dirname(__FILE__
))))))));
647 // load BootStrap here if needed
648 // We are a valid Joomla entry point.
649 if ( ! defined( '_JEXEC' ) && $loadDefines ) {
651 define('DS', DIRECTORY_SEPARATOR
);
652 define('JPATH_BASE', $joomlaBase . '/administrator');
653 require $joomlaBase . '/administrator/includes/defines.php';
656 // Get the framework.
657 if (file_exists($joomlaBase . '/libraries/import.legacy.php')) {
658 require $joomlaBase . '/libraries/import.legacy.php';
660 require $joomlaBase . '/libraries/import.php';
661 require $joomlaBase . '/libraries/joomla/event/dispatcher.php';
662 require $joomlaBase . '/configuration.php';
664 // Files may be in different places depending on Joomla version
665 if ( !defined('JVERSION') ) {
666 require $joomlaBase . '/libraries/cms/version/version.php';
667 $jversion = new JVersion
;
668 define('JVERSION', $jversion->getShortVersion());
671 if( version_compare(JVERSION
, '3.0', 'lt') ) {
672 require $joomlaBase . '/libraries/joomla/environment/uri.php';
673 require $joomlaBase . '/libraries/joomla/application/component/helper.php';
676 require $joomlaBase . '/libraries/cms.php';
677 require $joomlaBase . '/libraries/joomla/uri/uri.php';
680 jimport('joomla.application.cli');
682 // CRM-14281 Joomla wasn't available during bootstrap, so hook_civicrm_config never executes.
683 $config = CRM_Core_Config
::singleton();
684 CRM_Utils_Hook
::config($config);
690 * check is user logged in.
692 * @return boolean true/false.
694 public function isUserLoggedIn() {
695 $user = JFactory
::getUser();
696 return ($user->guest
) ?
FALSE : TRUE;
700 * Get currently logged in user uf id.
702 * @return int logged in user uf id.
704 public function getLoggedInUfID() {
705 $user = JFactory
::getUser();
706 return ($user->guest
) ?
NULL : $user->id
;
710 * Get currently logged in user unique identifier - this tends to be the email address or user name.
712 * @return string $userID logged in user unique identifier
714 function getLoggedInUniqueIdentifier() {
715 $user = JFactory
::getUser();
716 return $this->getUniqueIdentifierFromUserObject($user);
719 * Get User ID from UserFramework system (Joomla)
720 * @param object $user object as described by the CMS
721 * @return mixed <NULL, number>
723 function getUserIDFromUserObject($user) {
724 return !empty($user->id
) ?
$user->id
: NULL;
728 * Get Unique Identifier from UserFramework system (CMS)
729 * @param object $user object as described by the User Framework
730 * @return mixed $uniqueIdentifer Unique identifier from the user Framework system
733 function getUniqueIdentifierFromUserObject($user) {
734 return ($user->guest
) ?
NULL : $user->email
;
738 * Get a list of all installed modules, including enabled and disabled ones
740 * @return array CRM_Core_Module
742 function getModules() {
745 $db = JFactory
::getDbo();
746 $query = $db->getQuery(true);
747 $query->select('type, folder, element, enabled')
748 ->from('#__extensions')
749 ->where('type =' . $db->Quote('plugin'));
750 $plugins = $db->setQuery($query)->loadAssocList();
751 foreach ($plugins as $plugin) {
752 // question: is the folder really a critical part of the plugin's name?
753 $name = implode('.', array('joomla', $plugin['type'], $plugin['folder'], $plugin['element']));
754 $result[] = new CRM_Core_Module($name, $plugin['enabled'] ?
TRUE : FALSE);
761 * Get user login URL for hosting CMS (method declared in each CMS system class)
763 * @param string $destination - if present, add destination to querystring (works for Drupal only)
765 * @return string - loginURL for the current CMS
768 public function getLoginURL($destination = '') {
769 $config = CRM_Core_Config
::singleton();
770 $loginURL = $config->userFrameworkBaseURL
;
771 $loginURL = str_replace('administrator/', '', $loginURL);
772 $loginURL .= 'index.php?option=com_users&view=login';
774 //CRM-14872 append destination
775 if ( !empty($destination) ) {
776 $loginURL .= '&return='.urlencode(base64_encode($destination));
784 public function getLoginDestination(&$form) {
787 $id = $form->get('id');
792 $gid = $form->get('gid');
794 $args .= "&gid=$gid";
797 // Setup Personal Campaign Page link uses pageId
798 $pageId = $form->get('pageId');
800 $component = $form->get('component');
801 $args .= "&pageId=$pageId&component=$component&action=add";
808 // append destination so user is returned to form they came from after login
809 $args = 'reset=1'.$args;
810 $destination = CRM_Utils_System
::url(CRM_Utils_System
::currentPath(), $args, TRUE, NULL, TRUE, TRUE);
817 * Return default Site Settings
821 * @return array array
822 * - $url, (Joomla - non admin url)
826 function getDefaultSiteSettings($dir){
827 $config = CRM_Core_Config
::singleton();
831 $config->userFrameworkBaseURL
833 $siteRoot = preg_replace(
834 '|/media/civicrm/.*$|',
836 $config->imageUploadDir
838 return array($url, NULL, $siteRoot);
842 * Get Url to view user record
843 * @param integer $contactID Contact ID
847 function getUserRecordUrl($contactID) {
848 $uid = CRM_Core_BAO_UFMatch
::getUFId($contactID);
849 $userRecordUrl = NULL;
850 // if logged in user is super user, then he can view other users joomla profile
851 if (JFactory
::getUser()->authorise('core.admin')) {
852 return CRM_Core_Config
::singleton()->userFrameworkBaseURL
. "index.php?option=com_users&view=user&task=user.edit&id=" . $uid;
854 elseif (CRM_Core_Session
::singleton()->get('userID') == $contactID) {
855 return CRM_Core_Config
::singleton()->userFrameworkBaseURL
. "index.php?option=com_admin&view=profile&layout=edit&id=" . $uid;
860 * Is the current user permitted to add a user
863 function checkPermissionAddUser() {
864 if (JFactory
::getUser()->authorise('core.create', 'com_users')) {
870 * output code from error function
871 * @param string $content
873 function outputError($content) {
874 if (class_exists('JErrorPage')) {
875 $error = new Exception($content);
876 JErrorPage
::render($error);
878 else if (class_exists('JError')) {
879 JError
::raiseError('CiviCRM-001', $content);
882 parent
::outputError($content);
887 * Append to coreResourcesList
889 function appendCoreResources(&$list) {
890 $list[] = 'js/crm.joomla.js';