How to serve multiple domain name websites with one CakePHP application

Say you have a need to deliver multiple websites which have same structure but each site is served on different domain names and have different content.

For example, perhaps you are selling a product in many different countries and you want to have a separate website for each country.

This solution allows you to use one CakePHP application and one MySQL database to serve multiple websites each with different domain and content.

The domains need to be hosted on shared hosting which allows multiple domain hosting and allows some way of pointing multiple domains to a single application or route.

You would create your CakePHP application as normal but modify it as per this solution so that it can identify the domain the request is coming from and then serve up content for that domain only!

The modifications are summarized here and the complete PHP code is in Github:

    • Create a table called ‘domain’ (or whatever you want with as many columns as you need) that will hold domain specific values that are retrieved to be used in in application. At a minimum it should have the each site’s domain so you can do a lookup to match it to the domain being requested.
    • Add domain table foreign key (domain_id) to other tables so that they can be filtered by domain when retrieving data. (This means likely you will require additional steps to ensure that the foreign key is written to your tables. How you do that is up to you but for example if you allow users to create accounts or post comments then you can simply record the domain_id (for example you CakePHP Configure::read value when new user or comment is added.)
    • Create a new function  (I called min ‘getDomainSettings‘ ) in the CakePHP AppController beforeFilter section. This function will read domain name from current site visitor request and use it as parameter to filter database records to just that domain’s values. I used the built-in CakePHP Configure::write variables for these domain values that can be used throughout the CakePHP application.
    • Add optional conditions when retrieving model data using these CakePHP Configure:write variables in other CakePHP controllers’ to retrieve specific model records for the current domain and as well as modify view presentation based on model records. Lots of potential here, you could also swap out css styles or CakePHP themes based on domain and make sites totally different.

Introducing Speedvisit – a quick and easy way to record visits from people

Here is a demo web application / SaaS called SpeedVisit that individuals and companies can use to easily and quickly record visits from people to record basic customer demographic information.

Features include:

  • Groups – create a group so you add other users, locations and referrers to it.
  • Users – add additional users to your group as you want.
  • Locations – add locations where visits will take place.
  • Referrers – add referrers to record how visitor was referred.

The definition of ‘visit’ is pretty broad. It could be customers, co-workers, classmates, attendees in many situations including:

  • Retail Stores
  • Staff Meetings
  • Convenience Stores
  • Restaurants
  • Street Vendors
  • Art Studios
  • Non-Profits
  • Community Clubs
  • Sports Events
  • Social Events
  • Trade Shows

The demographic information that you can record currently includes:

  • Gender
  • Age
  • Zipcode or postal code
  • Income
  • Prev Visit
  • Referrer
  • Location
  • Purchase
  • Email
  • Comments

The site is mobile friendly responsive design so it works on phones, tablets, laptops and desktops.

The data is totally portable with easy export of all visits to csv file. It is setup with SSL so your data will be securely transferred between your browser and the server.

This is a screenshot of the top of the visit capture page which is the central feature of the application and workflow.  Simply use radio buttons and choosers to select categorize the visitor and add record. The page will then be ready for the next visitor.

speedvisit1

 

The data is available for anyone else to view it, to view aggregated statistics, etc. This is screenshot of the recorded visit data.

speedvisit2

You can sign into the demo account to see what sample account and visits look like too.

Single CakePHP application & MySQL database to serve multiple domains

I have a bunch of websites that have the same structure and content that vary only by the category for each site. So content for all sites can reside in a single database schema and filtered to specific categories for each site.

In order to do this I created a custom CakePHP application with one MySQL database to serve multiple public facing websites each with their own unique domain.

In order to make this work you need a hosting account that will allow you to map website serving directories to domain names. Different hosting providers may have different methods of doing this.

The secret to make this work is to have the application parse the domain name that is calling the application and then use that to filter the database records for that domain category.

In CakePHP do this by creating a function in the AppController that will check to see what domain the visitor is browsing to and then to retrieve that domain’s specific values from the special table to filter the CakePHP application. You will need to to call this function in the AppController beforeFilter function. I have included an example function named ‘fetchSettings’ below.

It will also be very helpful to make a table that contains meta data for each domain such as keywords, analytics tracking code, etc. I didn’t do include a different CSS file for each domain but you could include CSS file variable to refer to separate CSS file for each domain.

 

Check Github repository for more information:

https://github.com/sitrucp/single_cakephp_mysql_multiple_domain_app

<?php

App::uses('Controller', 'Controller');

class AppController extends Controller {
    
    public function beforeFilter() {
        $this-> getDomainSettings(); 	
    }
    
    //function which reads settings from domain table  
    function getDomainSettings(){
        //get current domain from server name as variable
        $domain = preg_replace('/^www\./', '', $_SERVER['SERVER_NAME']);
        //Load domain model data
        $this->loadModel('Domain');
        //retrieve only current domain table record
        $domain_settings = $this->Domain->find('all', array('conditions' => 
        array('Domain.domain' => $domain)));  
        foreach($domain_settings as $value){
            //create Configure::Write variables from domain record to use elsewhere in application
            Configure::write('domain', $value['Domain']['domain']);
            Configure::write('domain_id', $value['Domain']['id']);
            Configure::write('ga_code', $value['Domain']['ga_code']);
            Configure::write('meta_title', $value['Domain']['meta_title']);
            Configure::write('meta_keywords', $value['Domain']['meta_keywords']);
            Configure::write('meta_description', $value['Domain']['meta_description']); 
            
            //etc retrieve as many domain specific values as required from database
        }
    }
}

?>