CakePHP: Setting Up Multiple DataSources

I am working on a project using CakePHP where I initially created JSON objects to store the data. Once I began to add the JSON data to a MySQL database, I grew weary of all the input. I decided to keep one the JSON objects as is. It was data that would never change (and a lot of data). Fortunately with CakePHP you can use multiple DataSources in a project. And the DataSources don’t have to be an actual database, you can use JSON (or XML for that mater).

Database Setup

First, open your database file (app/config/database.php). Add your DataSource after the default DataSource. I added a DataSource named jsonCategories.

class DATABASE_CONFIG {
	var $default = array(
		'driver' => 'mysql',
		'persistent' => false,
		'host' => '127.0.0.1',
		'port' => '',
		'login' => 'guestUser',
		'password' => 'Lf5nwENtAMpKDFVm',
		'database' => 'digitalvilliage',
		'schema' => '',
		'prefix' => '',
		'encoding' => ''
	);
 
	var $jsonCategories = array(
		'datasource' => 'categories',
		'readonly' => true,
		'file' => 'categories.js' 
	);
}

I named the datasource the same as the file name (categories), but I don’t think this is necessary. In this case, my datasource is a .js file.

DataSource File

Next I created the DataSource file (categories.js). This file is saved in webroot/files/categories.js.

?View Code JAVASCRIPT
[
{"name": "automotive", "label": "auto, ..."}
...
]

CakePHP DataSource File

In order for CakePHP to be able to interact with your DataSource, you have to create a DataSource file. The name of your source file must the datasource value that you entered when you set up the datasource in the database.php file. You also must add ‘_source’ to the name (categories_source.php). The file must be saved under app/models/datasources/.

class CategoriesSource extends DataSource {
    	var $description = 'Categories DataSource';
	var $File = null;
	var $FileUtil = null;
 
	function __construct($config=null) {
		parent::__construct($config);
		$this->connected = $this->connect();
		return $config;
	}
 
	function __destruct() {
		$this->connected = $this->close();
		parent::__destruct();
	}
 
	function connect() {
		App::import('Core','File');
		$this->FileUtil =& new File(WWW_ROOT.'files/'.$this->config['file']);
		$this->File = $this->FileUtil->read();
		if (!$this->File) {
			return false;
		} else {
			return true;
		}
	}
 
	function findAll() {
		return $this->File;
	}	
 
	function close() {
		if ($this->FileUtil->close()) {
			return false;
		} else {
			return true;
		}
	}
 
	function read() {}
 
	function query() {}
 
	function describe() {}
 
	function column() {}
 
	function isConnected() {}
 
	function showLog() {}
}

Name your class the same as the datasource value in your database.php (with Source as the suffix).

You need a constructor and destructor, but the most important methods are connect() and findAll(). As the name suggests, the connect() method enables Cake to connect to your datasource. In this case, you are just using the File utility to read the JSON file:

function connect() {
	App::import('Core','File');
	$this->FileUtil =& new File(WWW_ROOT.'files/'.$this->config['file']);
	$this->File = $this->FileUtil->read();
	if (!$this->File) {
		return false;
	} else {
		return true;
	}
}

The findAll() method will be used in the model (or controller).

Using the DataSource

So in my controller file, I have a method named getCategories. I use CakePHP’s Connection Manager to connect to my DataSource. I then call findAll() to retrieve the data.

function getCategories() {
	if ( $this->RequestHandler->isAjax() ) {
	   Configure::write ( 'debug', 0 );
	}
	$this->autoRender = false;
	App::import('ConnectionManager');
	$cats =& ConnectionManager::getDataSource("jsonCategories"); 
	return $cats->findAll();
}

That’s it. The autoRender and debug statements are used because I’m calling this method via Ajax. See my previous post regarding the usage.

So, as you can see, creating multiple datasources with CakePHP is rather straightforward. Enjoy.

Be Sociable, Share!

Checkout My New Site - T-shirts For Geeks