Inspirados en One core, one app, multiple domains un sencillo pero bien pensado artículo de CakePHP Bakery que ilustra como es posible tener una sola aplicación o core de CakePHP y usar varios dominios y bases de datos completamente separadas (Multi-Tenant, multiple database), hicimos una adaptación para permitir, basados en el mismo principio de detección de dominios, tener una sola base de datos e inyectar automáticamente el tenant id correspondiente. Esto también permite administrar fácilmente nuevos dominios usando la base de datos.
1. Detectar el Tenant o Cliente por el dominio que accede: bootstrap.php
$serverName='localhost';
// Thanks to eimermusic
if ( isset($_SERVER['SERVER_NAME']) ) { // web
$serverName = $_SERVER['SERVER_NAME'];
} elseif ( count($_SERVER['argv']) ) { // cli
$serverName = $_SERVER['argv'][count($_SERVER['argv'])-1];
}
$_SERVER['SERVER_NAME'] = $serverName;
Configure::write('Config.serverName', $serverName);
2. Hacer Match de a que TenantId pertence el dominio que esta accediendo: AppController.php
public function beforeFilter(){
$tenantModel = ClassRegistry::init('Tenant');
$amountTenants = $tenantModel->find('count');
if($amountTenants == 0 ){
//This is for load the default configuration in database the first time the app loads
$tenantModel->saveDefaultTenants();
}
//Custom find to get the tenant by ServerName
$currentTenant = $tenantModel->getTenantByServerName(Configure::read('Config.serverName'));
$tenantId = isset($currentTenant['Tenant']['id'])?$currentTenant['Tenant']['id']:0;
if(!empty($currentTenant)){
Configure::write('Config.tenantId',$tenantId);
}
}
3. Insertar el tentantId en las búsquedas: AppModel.php
public function beforeFind($queryData){
if($this->name!='Tenant'){
$tenantId = Configure::read('Config.tenantId');
if(isset($tenantId) && $tenantId!=''){
$queryData['conditions'][$this->name.'.tenant_id'] = $tenantId;
}
}
}
public function beforeSave($queryData){
$tenantId = Configure::read('Config.tenantId');
if(isset($tenantId) && $tenantId!=''){
$this->data[$this->name]['tenant_id'] = $tenantId;
}
return true;
}