2007年12月25日 星期二

Writing an installer for your CakePHP application

If you write an application which the user must install on his own server, you have to think about the installation process of your application. In this article I will describe the approach I have used in my application.

This approach is heavily inspired by the one used by WordPress. That means the user has to create the database and to define the database settings in app/config/database.php himself. When this is done, the user must run the installer, which then creates the tables and does some application-specific stuff like creating a default user.

The installer is a usual controller, which is automatically called when the user accesses the application for the first time. For this purpose I added a bit of logic to app/config/routes.php:

if (file_exists(TMP.'installed.txt')) {
// the routes for when the application has been installed
} else {
Router::connect('/:action', array('controller' => 'installer'));
}


So as long as there is no “installed.txt” file, the user gets the first page of the installer when he requests the url of the application. The consequence of this logic is that we have to create such a file at the end of the installation process (see below).

The installer controller itself is straight-forward, each action is one step in the installation process. You can find a minimal version of the installer below:

// app/controllers/
uses('model' . DS . 'connection_manager');


class InstallerController extends AppController {
var $uses = array();

function beforeFilter() {
if (file_exists(TMP.'installed.txt')) {
echo 'Application already installed. Remove app/config/installed.txt to reinstall the application';
exit();
}
}

function index() {
}

function database() {
$db = ConnectionManager::getDataSource('default');

if(!$db->isConnected()) {
echo 'Could not connect to database. Please check the settings in app/config/database.php and try again';
exit();
}

$this->__executeSQLScript($db, CONFIGS.'sql'.DS.'app.sql');

$this->redirect('/installer/thanks');
}

function thanks() {
file_put_contents(TMP.'installed.txt', date('Y-m-d, H:i:s'));
}

function __executeSQLScript($db, $fileName) {
$statements = file_get_contents($fileName);
$statements = explode(';', $statements);

foreach ($statements as $statement) {
if (trim($statement) != '') {
$db->query($statement);
}
}
}
}

It is a pragmatic solution with the drawback that it is not really reusable,..

沒有留言:

wibiya widget