Multisite Support for CakePHP 3.x
A plugin that allows you to have a single Cakephp 3.x app which supports multiple websites, while being
flexible enough that you can customize individual files on a per site basis., (*1)
For example: if a request is made to example.com, you might have some files like
APP/sites/example.com/config/app.php
, and APP/sites/example.com/vendor/CakeDC/Users/src/Controllers/UsersController.php
,
both of which would override the respective default file in the core APP on a per site basis., (*2)
Installation
In console run, (*3)
composer require buildrr/multisite
Replace the first 6 lines of APP/config/bootstrap.php with the following., (*4)
<?php
/**
* Configure paths required to find CakePHP + general filepath
* constants
*/
require __DIR__ . '/paths.php';
/**
* Get multisites
*/
require ROOT . DS . 'sites' . DS . 'bootstrap.php';
Find Configure::config('default', new PhpConfig());
and replace with:, (*5)
$__config_path = false;
if(defined('SITE_DIR')) $__config_path = SITE_DIR . DS . 'config' . DS;
Configure::config('default', new PhpConfig($__config_path));
In APP/composer.json add ```"BuildrrMultiSite\Console\AutoLoader::postAutoloadDump"to
"post-autoload-dump"`` like this:, (*6)
"scripts": {
"post-install-cmd": "App\\Console\\Installer::postInstall",
"post-autoload-dump": [
"Cake\\Composer\\Installer\\PluginInstaller::postAutoloadDump",
"BuildrrMultiSite\\Console\\AutoLoader::postAutoloadDump"
]
},
In SITE_DIR/config/app.php set App.paths.templates like this:, (*7)
'App' => [
'paths' => [
'templates' => [
ROOT . DS . SITE_DIR . DS . 'vendor' . DS . '%s' . DS . 'src' . DS . 'Template',
ROOT . DS . SITE_DIR . DS . 'src' . DS . 'Template' . DS,
APP . 'Template' . DS,
CORE_PATH . 'src'. DS . 'Template' . DS
],
],
],
In APP/src/View/AppView.php add both of the following:, (*8)
// near the top of the file, outside of class AppView()
use BuildrrMultiSite\View\MultisiteView;
// inside of class AppView()
/**
* Overwrites Cake/View::_paths()
*
* @param null $plugin
* @param bool $cached
* @return mixed
*/
protected function _paths($plugin = null, $cached = true)
{
$multisite = new MultisiteView();
$multisite->theme = $this->theme;
return $multisite->_paths($plugin, $cached);
}
Usage
- Create a folder at APP/sites/example.com and APP/sites/example-app-folder.
- Within those folders you can create custom versions of core app files.
- ex. APP/sites/example.com/config/app.php (create your own db connection here)
- ex. APP/sites/example-app-folder/config/app.php (create a different db connection for this site here)
Create a folder and file at APP/sites/bootstrap.php (these are examples, change the names to domains that you actually want to use), (*9)
<?php
/**
* Map domains this install will support, to where that site's files are located.
* The incoming request domain is on the left, the folder within the sites
* directory that the request maps to is on the right.
*/
$domains['example.com'] = 'example.com';
$domains['example-app.com'] = 'example-app-folder';
/**
* find the folder that is being requested by the domain
*/
if (!empty($domains[$_SERVER['HTTP_HOST']])) {
if (!defined('SITE_DIR')) {
// this is the site combined local and remote sites directory
define('SITE_DIR', 'sites/' . $domains[$_SERVER['HTTP_HOST']]);
}
}
If there is a plugin that you want individual sites to have access to customize or override you need to add it to the
autoload parameter of your main APP/composer.json
file.
Formatted as "VendorName\\PluginName\\": "./SITE_DIR/vendor/[vendor name]/[plugin name]/src"
, for example..., (*10)
// APP/composer.json
"autoload": {
"psr-4": {
"App\\": "src",
"BuildrrMultiSite\\": "./SITE_DIR/vendor/buildrr/multisite/src"
}
},
Anytime you add a new plugin to this autoload you'll need to run this in console, (*11)
composer dump-autoload