Skip to content
Snippets Groups Projects
Unverified Commit a04dda49 authored by kcristiano's avatar kcristiano
Browse files

Update WP Multi-Site CiviCRM Multi-Domain Documentation

parent 5e6e63e9
No related branches found
No related tags found
1 merge request!36Update WP Multi-Site CiviCRM Multi-Domain Documentation
Showing
with 320 additions and 74 deletions
docs/images/wpms/image-20201027174136563.png

85.9 KiB

docs/images/wpms/image-20201027175354535.png

11.4 KiB

docs/images/wpms/image-20201027175658226.png

41.1 KiB

docs/images/wpms/image-20201027175824708.png

30.9 KiB

docs/images/wpms/image-20201027175950175.png

38.8 KiB

docs/images/wpms/image-20201027180035261.png

28.6 KiB

docs/images/wpms/image-20201027180145841.png

31.5 KiB

docs/images/wpms/image-20201027180252729.png

30.9 KiB

docs/images/wpms/image-20201027180332753.png

26.1 KiB

docs/images/wpms/image-20201027183932098.png

39.2 KiB

docs/images/wpms/image-20201027191613282.png

95.8 KiB

docs/images/wpms/image-20201027191715602.png

26.4 KiB

docs/images/wpms/image-20201027191823532.png

70.4 KiB

docs/images/wpms/image-20201027192106159.png

10.3 KiB

docs/images/wpms/image-20201027192425361.png

8.3 KiB

# WordPress Multisite
# WordPress Multisite, CiviCRM Multi-Domain Setup
If using a WordPress multisite when CiviCRM is activated the `civicrm.settings.php` file is added within the [uploads directory for that site](https://wordpress.org/support/article/multisite-network-administration/#uploaded-file-path). Site 1, generally the main site of the multisite, uses the default upload path `/wp-content/uploads/civicrm`.
These instructions are for setting up a network from scratch. If you already have an existing WordPress Multisite, then some of the procedures will need to be skipped and some will need to be amended for your situation. This is the recommended procedure, however, since getting the basics right means that whatever is built on top of that is based on solid foundations.
If you are looking to share one CiviCRM database across multiple websites, for a chapter like setup, the following needs to be added to your `wp-config.php` file.
## Install WordPress Single Site as normal
``` php
// define CiviCRM constants here
if ( ! defined( 'CIVICRM_SETTINGS_PATH' ) ) {
define( 'CIVICRM_SETTINGS_PATH', '/path/to/wordpress/website/wp-content/uploads/civicrm/civicrm.settings.php' );
}
Add the following plugins but do not activate them:
- [_CiviCRM_](https://civicrm.org/download)
- [_CiviCRM Admin Utilities_](https://wordpress.org/plugins/civicrm-admin-utilities/)
- [_CiviCRM Permissions Sync_](https://develop.tadpole.cc/plugins/civicrm-permissions-sync)
## Enable WordPress Multisite
Add the following to `wp-config.php`
```php
/**
* Allow multisite.
*
* This can be commented out once Multisite has been set up - the only thing it
* does is enable the "Network Setup" menu item.
*/
define( 'WP_ALLOW_MULTISITE', true );
```
This will define the path for all websites on the multisite and when enabled they will access the CiviCRM instance defined by the path settings and access is managed through the `civicrm.settings.php` as this example outlines.
Run WordPress Multisite "Network Setup" under Tools
## WordPress Multisite using Subdomains
If you have your multisite set up as subdomains, follow these steps.
![image-20201027174136563](../images/wpms/image-20201027174136563.png)
!!! note "Change your `civicrm.settings.php` file"
Keep in mind, you should **only** change the `civicrm.settings.php` file that lives in `wp-content/uploads/civicrm` (the parent/main site's uploads folder).
- Choose subdomain or sub-directory. Both work the same way.
- Example is subdomain as that takes slightly more setup.
- Update `wp-config.php` add the following lines:
Find the block of code that resembles this:
```php
if (!defined('CIVICRM_UF_BASEURL')) {
define( 'CIVICRM_UF_BASEURL' , 'http://example.org/');
/**
* WordPress Multisite setup.
*/
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', true);
define('DOMAIN_CURRENT_SITE', 'wpcvms.test');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);
```
- Update `.htaccess` and replace all existing WordPress rules with:
```bash
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
# add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]
RewriteRule . index.php [L]
```
- Log back in and now we have a network
## _CiviCRM_ Setup
### Site 1
Activate the following plugins:
- _CiviCRM Permissions Sync_
- Check that the `CIVICRM_PERMISSIONS_SYNC_MODE` constant is set to your liking. The choices can be found [in the plugin's code](https://develop.tadpole.cc/plugins/civicrm-permissions-sync/-/blob/master/civicrm-permissions-sync.php#L19-38). For this kind of install, the default of `groups` is fine.
- Network Activate
- _CiviCRM_
- Activate _only_ on Site 1
- Run Installer
- Using a separate database for CiviCRM is probably a wise choice.
- _CiviCRM Admin Utilities_
- Network Activate
Go To _CiviCRM_
- Create a Group for Site 1
- This will be the Domain Group for Domain 1
- Add the [Multisite Extension](https://lab.civicrm.org/extensions/multisite)
- On Site 1 Go to _CiviCRM Admin Utilities_ Settings, then Domain tab
- You should see:
![image-20201027175354535](../images/wpms/image-20201027175354535.png)
- Follow the link and set up Site 1 "Multisite" (in the CiviCRM sense)
- Go back to _CiviCRM Admin Utilities_
- The "Domain" tab should look like:
![image-20201027175658226](../images/wpms/image-20201027175658226.png)
- Go to WordPress Network Admin, then _CiviCRM Admin Utilities_ Settings
- The "Domain" tab should look like:
![image-20201027175824708](../images/wpms/image-20201027175824708.png)
### Site 2
- Create a new WordPress Sub-site (Site 2)
![image-20201027175950175](../images/wpms/image-20201027175950175.png)
- Edit the new site
- Look at the URL
- It MUST match what you will be setting _CiviCRM_ to. Make sure the URL begins with `https` not `http` - edit if necessary
![image-20201027180035261](../images/wpms/image-20201027180035261.png)
![image-20201027180145841](../images/wpms/image-20201027180145841.png)
- Update `wp-config.php` to use a single `civicrm.settings.php` file
- Add the following:
```php
/**
* Force CiviCRM to use a single settings file.
*/
if ( ! defined( 'CIVICRM_SETTINGS_PATH' ) ) {
define( 'CIVICRM_SETTINGS_PATH', '/srv/www/wpcvms/wp-content/uploads/civicrm/civicrm.settings.php' );
}
```
**Remove it entirely**, and replace it with the following code:
- Add `civicrm.domains.php` to same directory as `civicrm.settings.php`
```php
<?php
/**
* CiviCRM Multisite Domain functionality.
*
* @see https://gist.github.com/christianwach/5ca120670152df3dbfb8d3ca42079a96
*/
/**
* 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(
'https://example.org' => array(
'domain_id' => 1,
'domain_group_id' => 7,
'domain_org_id' => 1,
//'wp.frontend.base.url' => 'https://example.org/',
//'wp.backend.base.url' => 'https://example.org/wp-admin/',
'extensionsDir' => '<path to extensions folder>',
'extensionsURL' => '<URL to extensions directory>',
'userFrameworkResourceURL' => 'https://example.org/wp-content/plugins/civicrm/civicrm/',
),
'https://sub.example.org' => array(
'domain_id' => 21,
'domain_group_id' => 13,
'domain_org_id' => 35603,
//'wp.frontend.base.url' => 'https://sub.example.org/',
//'wp.backend.base.url' => 'https://sub.example.org/wp-admin/',
'extensionsDir' => '<path to extensions folder>',
'extensionsURL' => '<URL to extensions directory>',
'userFrameworkResourceURL' => 'https://example.org/wp-content/plugins/civicrm/civicrm/',
),
'https://sub0.example.org' => array(
'domain_id' => 20,
'domain_group_id' => 23,
'domain_org_id' => 35604,
//'wp.frontend.base.url' => 'https://sub0.example.org/',
//'wp.backend.base.url' => 'https://sub0.example.org/wp-admin/',
'extensionsDir' => '<path to extensions folder>',
'extensionsURL' => '<URL to extensions directory>',
'userFrameworkResourceURL' => 'https://example.org/wp-content/plugins/civicrm/civicrm/',
),
)
// Define CiviCRM Multisite Domain data.
$data = array(
// Always put the data for the main site first.
'https://wpcvms.test' => array(
'domain_id' => 1,
//'domain_group_id' => 5,
//'domain_org_id' => 1,
'extensionsDir' => '/srv/www/wpcvms/wp-content/uploads/civicrm/ext/',
'extensionsURL' => 'https://wpcvms.test/wp-content/uploads/civicrm/ext/',
'userFrameworkResourceURL' => 'https://wpcvms.test/wp-content/plugins/civicrm/civicrm/',
),
// Add sub-sites after the main site.
'https://ny.wpcvms.test' => array(
'domain_id' => 2,
//'domain_group_id' => 6,
//'domain_org_id' => 203,
'extensionsDir' => '/srv/www/wpcvms/wp-content/uploads/civicrm/ext/',
'extensionsURL' => 'https://ny.wpcvms.test/wp-content/uploads/civicrm/ext/',
'userFrameworkResourceURL' => 'https://ny.wpcvms.test/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'];
}
}
```
Rinse and repeat for any additional subdomains.
// Trigger Multisite discovery immediately.
civicrm_multisite_set_domain_data_for_site();
```
Big thanks to **Christian Wach** for [this code](https://gist.github.com/christianwach/5ca120670152df3dbfb8d3ca42079a96), which was adapted to fit subdomain setup.
- Now go back and edit `civicrm.settings.php`:
* Around line 80 or so, comment out the paths and URL settings:
You do **not** need to do the **Create the domain record** step (stated above) if you use the [multisite extension](https://lab.civicrm.org/extensions/multisite). It is recommended you copy and paste the following command into your shell/terminal:
```php
// Additional settings generated by installer:
/*
$civicrm_paths['wp.frontend.base']['url'] = 'https://wpms.test/';
$civicrm_paths['wp.backend.base']['url'] = 'https://wpms.test/wp-admin/';
$civicrm_setting['domain']['userFrameworkResourceURL'] = 'https://wpms.test/wp-content/plugins/civicrm/civicrm';
*/
`wp cv api MultisiteDomain.create debug=1 sequential=1 name="Sub1ExampleOrg" is_transactional=0 group_id="2" contact_id="4"`
```
!!! note "Important Note"
- Further down the `civicrm.settings.php` file:
* Around line 235 or so, comment out the code that defines `CIVICRM_UF_BASEURL`
* Include/require the `civicrm.domains.php` file
* (The settings could be included here, but it's cleaner to have a separate file)
* `Sub1ExampleOrg`: This should be replaced with a name for the domain.
* `group_id`: This can be found as the `group_id` column in the table called `civicrm_group_organization`.
* `contact_id`: This can be found as the `organization_id` column in the table called `civicrm_group_organization`.
```php
/*
if (!defined('CIVICRM_UF_BASEURL')) {
define( 'CIVICRM_UF_BASEURL' , 'https://wpms.test');
}
*/
**You will need to do this for each subdomain, so keyboard shortcuts are strongly encouraged.**
// Include the Domain settings file.
require_once 'civicrm.domains.php';
```
After you've done this, if you don't have it already, download and install the [CiviCRM Admin Utilities plugin for WordPress](https://wordpress.org/plugins/civicrm-admin-utilities/). **Make sure it (and CiviCRM itself) is Network Activated!** You will need it in a second.
- Now back to WordPress Network Admin, _CiviCRM Admin Utilities_, "Domain" tab
Visit one of your sites via it's subdomain in your browser.
![image-20201027180252729](../images/wpms/image-20201027180252729.png)
Along your left menu, find **Settings**, and hover over it. Click **CiviCRM Admin Utilities** when the menu pops out.
- Create a new _CiviCRM_ Domain
Scroll to the bottom, find where it says **Miscellaneous Utilities**.
![image-20201027180332753](../images/wpms/image-20201027180332753.png)
1. Check the box next to **Clear Caches**.
2. Once it refreshes the page, return to the CiviCRM Admin Utilities page. Click the link that says **Click this to rebuild the CiviCRM menu.**
3. Again, once it refreshes, return to the CiviCRM Admin Utilities page. Click the last link that says **Click this to rebuild the triggers in the CiviCRM database.**
- Activate _CiviCRM_ on Site 2
- Go To Site 2 Settings menu --> _CiviCRM Admin Utilities_ --> "Domain" tab
Once you have that, you should be good to go!
![image-20201027183932098](../images/wpms/image-20201027183932098.png)
**However...**
- Repeat for other Domains
If you still experience errors or problems at this point, make sure to clear your browser cache. If to no avail, try private/incognito browsing. Finally, as a last point, clear your DNS cache.
## Permissions
* Windows (Terminal/CMD): `ipconfig /flushdns`
* Mac/Linux: `sudo killall -HUP mDNSResponder`
- You will need to set permissions to limit access. Administrators and Network Admins will have pre-defined rights.
**Recommendation**: Create a Site Admin role for any administrator of sub-sites that are sharing CiviCRM, meaning the default Administrator role is only used on the main site. This is recommended since by default all Adminstrators automatically get access to Administer CiviCRM and will be able to create things like custom data fields. By creating a Site Admin role the CiviCRM permissions can be managed from [Administer > Users and Permissions > Permissions (Access Control)](https://docs.civicrm.org/user/en/latest/initial-set-up/permissions-and-access-control/#access-control-permissions-in-wordpress) and will allow only main site administrator access to Administer CiviCRM.
![image-20201027192106159](../images/wpms/image-20201027192106159.png)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment