Writing an installer for your CakePHP application

Published on and tagged with cakephp  controller

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,..

21 comments baked

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License