Skip to content

Instantly share code, notes, and snippets.

@christianwach
Last active October 24, 2020 19:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christianwach/5ca120670152df3dbfb8d3ca42079a96 to your computer and use it in GitHub Desktop.
Save christianwach/5ca120670152df3dbfb8d3ca42079a96 to your computer and use it in GitHub Desktop.
<?php
/**
* Define CiviCRM Multisite Domain constants and settings.
*
* When a WordPress site is accessed, CiviCRM needs to know a number of settings
* that enable Multisite Domain functionality. Define that data here.
*
* Once the Domain has been created (e.g. via the form on the "Domains" tab of
* the CiviCRM Admin Utilities network settings page) add the corresponding data
* array for the Domain to the array below. The four uncommented entries are
* required. Do this *before* enabling CiviCRM on the WordPress sub-site.
*
* The good thing about separating this functionality out in this way is that we
* can now read the correspondences between WordPress sites and CiviCRM Domains.
* The main array is keyed by the `home_url()` of the relevant WordPress site.
*
* If you want easy access to the `domain_group_id` and/or the `domain_org_id` for
* a WordPress site, then these can be filled out and uncommented, though they are
* not strictly necessary for multiple CiviCRM Domains to work and can be discovered
* by other means.
*
* @return array $data The CiviCRM Multisite Domain data.
*/
function civicrm_multisite_get_domain_data() {
// Define CiviCRM Multisite Domain data.
$data = array(
// Always put the data for the main site first.
'http://civicrm.multisite.stable' => array(
'domain_id' => 1,
//'domain_group_id' => 5, // Uncomment if required by other plugins.
//'domain_org_id' => 1, // Uncomment if required by other plugins.
'extensionsDir' => '/path/to/civicrm.multisite.stable/httpdocs/wp-content/uploads/civicrm/ext/',
'extensionsURL' => 'http://civicrm.multisite.stable/wp-content/uploads/civicrm/ext/',
'userFrameworkResourceURL' => 'http://civicrm.multisite.stable/wp-content/plugins/civicrm/civicrm/',
),
// Add sub-sites after the main site.
'http://civicrm.multisite.stable/first' => array(
'domain_id' => 2,
//'domain_group_id' => 6, // Uncomment if required by other plugins.
//'domain_org_id' => 203, // Uncomment if required by other plugins.
'extensionsDir' => '/path/to/civicrm.multisite.stable/httpdocs/wp-content/uploads/civicrm/ext/',
'extensionsURL' => 'http://civicrm.multisite.stable/first/wp-content/uploads/civicrm/ext/',
'userFrameworkResourceURL' => 'http://civicrm.multisite.stable/first/wp-content/plugins/civicrm/civicrm/',
),
);
// --<
return $data;
}
/**
* Get the URL for the requested WordPress site.
*
* @return str $url The URL for the requested WordPress site.
*/
function civicrm_multisite_get_url_from_server_vars() {
// We first need to find the URL of the current site.
if ( function_exists( 'home_url' ) ) {
// When WordPress is bootstrapped, this is always correct.
$url = home_url();
} else {
/*
* The following code deals with WordPress multisite when it is configured
* for sub-directories.
*
* If your multisite uses subdomains and you are not routing all calls to
* CiviCRM via WordPress (e.g. by using WP-REST instead of `extern/*.php`
* or `bin/*.php`) then you'll have to amend this.
*
* Q: How do we discover sub-directory paths from $_SERVER alone?
* A: There isn't a reliable way unless all sites are known.
*
* The true solution to this guesswork is never to bootstrap CiviCRM except
* via WordPress. I'm looking at you `extern/*.php`.
*
* tl;dr Always route via WordPress.
*/
// Protocol is easy:
$protocol = strstr( 'HTTPS', $_SERVER['SERVER_PROTOCOL'] ) ? 'https://' : 'http://';
// Get "site path" - the first part of the path.
$path = '';
if ( ! empty( $_SERVER['REQUEST_URI'] ) ) {
$tmp_path = explode( '/', $_SERVER['REQUEST_URI'] );
$path = isset( $tmp_path[0] ) ? '/' . $tmp_path[0] : '';
}
// Put it all together.
$url = $protocol . $_SERVER['SERVER_NAME'] . $path;
}
// --<
return $url;
}
/**
* Set CiviCRM Multisite Domain constants and settings.
*
* When a WordPress site is accessed, CiviCRM needs to know what Domain is being
* accessed. This is far from trivial :(
*/
function civicrm_multisite_set_domain_data_for_site() {
// We need access to some CiviCRM globals.
global $civicrm_setting, $civicrm_paths;
// Get the URL for the requested site.
$url = civicrm_multisite_get_url_from_server_vars();
// Get CiviCRM data.
$data = civicrm_multisite_get_domain_data();
// Use Main Site if we don't have an entry.
if ( empty( $data[$url] ) ) {
$settings = array_shift( $data );
} else {
$settings = $data[$url];
}
// Always set the Base URL.
define( 'CIVICRM_UF_BASEURL', $url );
// Set the CiviCRM Domain ID.
if ( isset( $settings['domain_id'] ) ) {
define( 'CIVICRM_DOMAIN_ID', $settings['domain_id'] );
}
// CiviCRM does not need these two constants, but you may wish to set them for reference.
if ( isset( $settings['domain_group_id'] ) ) {
define( 'CIVICRM_DOMAIN_GROUP_ID', $settings['domain_group_id'] );
}
if ( isset( $settings['domain_org_id'] ) ) {
define( 'CIVICRM_DOMAIN_ORG_ID', $settings['domain_org_id'] );
}
// These paths are crucial for CiviCRM.
if ( isset( $settings['extensionsDir'] ) ) {
$civicrm_setting['domain']['extensionsDir'] = $settings['extensionsDir'];
}
if ( isset( $settings['extensionsURL'] ) ) {
$civicrm_setting['domain']['extensionsURL'] = $settings['extensionsURL'];
}
if ( isset( $settings['userFrameworkResourceURL'] ) ) {
$civicrm_setting['domain']['userFrameworkResourceURL'] = $settings['userFrameworkResourceURL'];
}
}
// Trigger Multisite discovery immediately.
civicrm_multisite_set_domain_data_for_site();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment