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

  • Damian

    That’s a pretty nice solution. How would you prevent someone from deleting the installed.txt and accidentally re-running the installation? Provide some sort of install prompt? Maybe write a some junk to installed.txt and save the md5sum in the db for comparison?

  • cakebaker

    @Damian: Hm, good question. A possible solution could be to have a command line installer so you don’t need that “installed.txt” file.

  • majna

    nate suggested:
    add route file with default route to /install/
    after install, replace route.php with app production route.php
    chmod before…

  • brandon

    Nice! Now, all Cake needs is a package manager :)

  • cakebaker

    @majna: Good idea, thanks!

    @brandon: Yeah, a package manager would be cool :)

  • Digital Spaghetti

    Yea, a package manager would be great. I think a good way of doing this would be to have the installer check if /app/config/database.php exisits. If it does, prompt the user to type in their database details and have the installer write it.

    As well as then executing the SQL, you could use something like the ConfComponent from the bakery to manage all main site settings.

  • cakebaker

    @Digital Spaghetti: Yes, that’s a possible approach. I was too lazy to implement it as I saw the WordPress guys simply force the users to make the settings directly in the database config file ;-)

  • charlie

    Maybe it would be better to have a not_installed.txt file, so once installed it gets deleted. Then no problems about people deleting it by accident.

  • cakebaker

    @charlie: That’s a good idea, thanks!

  • CCDC

    Per @Digital Spaghetti’s comments, I want to display a form that allows the user to enter in database connection info that is stored in database.php, but I am getting a “Missing Database Connection” error due to the cake framework checking the connection before executing my installer controller.

    Is there any way to allow the installer_controller to run without cake making it’s database connection attempts?

    Here is my routes.php:

    if (file_exists(TMP.'not_installed.txt')) {
        Router::connect('/:action', array('controller' => 'installer'));    
    } else {
          Router::connect('/', array('controller' => 'users', 'action' => 'login'));
    }

    Here’s the installer_controller.php:

    <?php
    // app/controllers/
    uses('model' . DS . 'connection_manager');
    
    class InstallerController extends AppController {
        var $name = 'Installer';
        var $uses = array();
        var $helpers = array('Html');
    
        function beforeFilter() {        
            if (!file_exists(TMP.'not_installed.txt')) {
                echo('Application is already installed. Create app/config/not_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';
            }
        }
    
        function thanks() {
            if (unlink(TMP.'not_installed.txt')) {
                $this->set('message', 'Installation is complete');
            } else {
                $this->set('message', 'The final step of the installation failed because ' . TMP.'not_installed.txt' . ' could not be deleted.');
            }
        }
    
        private function __createTables() {
            echo "__createTables()<br>";
    
            $this->__executeSQLScript($db, CONFIGS.'sql'.DS.'app.sql');
    
            $this->redirect('/installer/thanks');
        }
        
        private function __executeSQLScript($db, $fileName) {
            echo "__executeSQLScript()<br>";
            
            $statements = file_get_contents($fileName);
            $statements = explode(';', $statements);
    
            foreach ($statements as $statement) {
                if (trim($statement) != '') {
                    $db->query($statement);
                }
            }
        }
    }
    ?>

    database_form.ctp:

    <div id="database_form">
    	<?=$form->create('database')?>
    	<?=$form->input('database')?>
    	<?=$form->input('username')?>
    	<?=$form->input('password')?>
    	<?=$form->input('host')?>
    	<?=$form->end()?>
    </div>
  • cakebaker

    @CCDC: Hm, unless you use some database functionality in your AppController or you are calling the “database” action in the InstallerController I don’t see why you should get a “missing database connection” error. Maybe you can be more specific on when you get the error?

  • Symen Timmermans

    The problem CCDC describes is a very valid one.
    I’m struggling with this one also.
    Perhaps the installer should run some php script outside of Cakephp to circumvent this problem…

  • cakebaker

    @Symen: Ah, now I see the problem CCDC described. The problem is that the FormHelper tries to access the database, hence the “missing database connection” error. If you use plain HTML the error should disappear, but then you probably will have the problem that you cannot write database.php…

    As I described in the article, I think you can expect a user will be able to modify database.php manually if you describe it in the installation instructions.

    Another option is, as you mention, to write an installation script. Either as a php script independent of cakephp, or as a cake shell script.

    Hope that helps!

  • scls19fr

    There is an other problem with this kind of installation script…

    Your are trying to execute a SQL script inside the php code… but your SQL script contains informations such as table prefix when you are building tables… but this kind of information could be modified by user… (it would be a very bad idea to have to change both app/config/database.php and the SQL script)

    So the solution could be to have a SQL script with variables instead of table prefix (and database name)

    Unfortunately I don’t know how to do this.

    I like CakePHP very much but I really think that a well suported installation method for application which are build with CakePHP should be supported

    Two kinds of installations should be supported

    – the first one, modifying manually app/config/database.php , executing a SQL script (with database name and table prefix as variable), and executing other PHP code for post install

    – a second one with a form that user could fill in.

  • cakebaker

    @scls19fr: Thanks for your comment!

    Yes, table prefixes are a problem when using plain SQL. However, I think in the meantime this problem has been solved with the introduction of the schema concept, which allows you to specify the tables with PHP (and I assume it takes the table prefix in account when it translates those settings to SQL).

    I don’t think there should be support for installation methods in the core framework because only a minority of applications would benefit from it. And so far no solution emerged from the community, which could mean nobody is interested in it, or that it is not that easy to write a generic solution…

  • scls19fr

    Let’s imagine you want to build a wiki, a little CMS, a blog based on the CakePHP framework…

    I’m personnaly very interrested in writing a wiki with a wikka like syntax)
    The IBM tutorial http://www.ibm.com/developerworks/edu/os-dw-os-php-wiki1.html
    Create an interactive production wiki using PHP seems to be a good starting point for this !

    if you don’t provide a convenient installation method the project wouldn’t be available for the mass users.

  • cakebaker

    @scls19fr: Yes, I fully agree with you that you need a good installation method if you write a product people have to install. And for such projects this is important. However, of all projects realized with CakePHP I think only a minority will fall into this product category, most are custom web applications. And so providing an installer infrastructure probably has a low (or no) priority for the core devs.

    Hence it is something which has to be realized by some community members with a need for such an installer infrastructure…

  • scls19fr

    I’m using wikis since several years.
    When you have a look at the code it’s often so messy !
    (I won’t say what wiki I’m using ;-) )
    Using a good framework such as CakePHP would be interresting because medium users could more easily change layout, add new functionnality, …

  • scls19fr

    I’m using wikis since several years.
    When you have a look at the code it’s often so messy !
    (I won’t say what wiki I’m using ;-) )
    Using a good framework such as CakePHP would be interresting because medium users could more easily change layout, add new features, …

    Moreover if an application based on the framework is well know it full urge many other developpers to have a look at the framework.

  • cakebaker

    @scls19fr: Your point about messy code is true, and not only for wiki software ;-)

    Using a framework can prevent this to some degree by offering you a certain structure, but in the end it is up to the developers whether the code ends in a mess… However, it definitely decreases the learning curve for users (developers) who already know the framework.

    And yes, a well-known application could be a good promoter of the framework itself.

    Anyway, I am looking forward to your wiki application :)

  • CakePHP Developer Links - PRONIQUE Software

    […] […]

  • betebet

    …Recent Blogroll Additions

    […]I am not positive the place you’re getting your information, but great topic.[…]

  • Google

    Google

    Sites of interest we’ve a link to.

  • Nidhi company registration services

    Nidhi company registration services

    […]one of our guests not too long ago advised the following website[…]

  • 토토사이트

    토토사이트

    […]very few websites that happen to become in depth beneath, from our point of view are undoubtedly very well worth checking out[…]

  • 먹튀검증

    먹튀검증

    […]Wonderful story, reckoned we could combine several unrelated data, nevertheless truly worth taking a appear, whoa did one learn about Mid East has got more problerms as well […]

  • 메이저공원

    메이저공원

    […]check below, are some totally unrelated web sites to ours, having said that, they are most trustworthy sources that we use[…]

  • 토토사이트

    토토사이트

    […]the time to read or take a look at the material or web sites we’ve linked to beneath the[…]

  • 네임드사다리

    네임드사다리

    […]always a major fan of linking to bloggers that I appreciate but do not get a good deal of link really like from[…]

  • 안전공원

    안전공원

    […]just beneath, are many entirely not related web sites to ours, however, they are surely worth going over[…]

  • 먹튀검증

    먹튀검증

    […]although sites we backlink to below are considerably not connected to ours, we feel they may be truly really worth a go by, so have a look[…]

  • home care

    home care

    […]Wonderful story, reckoned we could combine a number of unrelated information, nevertheless truly really worth taking a search, whoa did one particular understand about Mid East has got far more problerms as well […]

  • сызнова

    сызнова

    […]usually posts some extremely interesting stuff like this. If you are new to this site[…]

  • острое с отеком поражение гортани 4 буквы

    острое с отеком поражение гортани 4 буквы

    […]below you will discover the link to some web pages that we assume you must visit[…]

  • vps server

    vps server

    […]the time to study or go to the material or web sites we’ve linked to beneath the[…]

  • бесплатно mp3

    бесплатно mp3

    […]below you will discover the link to some web sites that we believe you should visit[…]

  • ferienwohnung büsum avc

    ferienwohnung büsum avc

    […]Sites of interest we’ve a link to[…]

  • فیلم سوپر سکسی

    فیلم سوپر سکسی

    […]always a huge fan of linking to bloggers that I enjoy but really don’t get a great deal of link appreciate from[…]

  • سكس زنوج 2019

    سكس زنوج 2019

    […]that is the end of this report. Here you will come across some web sites that we think you will appreciate, just click the hyperlinks over[…]

  • LolyCam 18+

    LolyCam 18+

    […]Here are several of the internet sites we suggest for our visitors[…]

  • سكسي ايراني

    سكسي ايراني

    […]one of our visitors just lately proposed the following website[…]

  • شركة نقل عفش في الكويت

    شركة نقل عفش في الكويت

    […]please check out the web pages we stick to, such as this one, as it represents our picks from the web[…]

  • シルバーパーツ

    シルバーパーツ

    […]Here is a great Weblog You may Find Intriguing that we Encourage You[…]

  • La teologia nazista

    La teologia nazista

    […]Wonderful story, reckoned we could combine a handful of unrelated information, nevertheless truly really worth taking a search, whoa did one particular learn about Mid East has got more problerms at the same time […]

  • l'umanesimo e il rinascimento

    l’umanesimo e il rinascimento

    […]usually posts some incredibly interesting stuff like this. If youÂ’re new to this site[…]

  • Don Chisciotte della Mancia

    Don Chisciotte della Mancia

    […]Every the moment in a while we decide on blogs that we read. Listed below would be the most up-to-date websites that we choose […]

  • top 20 law firms in cape town

    top 20 law firms in cape town

    […]Sites of interest we have a link to[…]

  • Google

    Google

    The time to study or take a look at the content material or sites we have linked to beneath.

  • weekend payday loans direct lenders

    weekend payday loans direct lenders

    […]please stop by the web-sites we comply with, which includes this one particular, as it represents our picks in the web[…]

  • podruga sestry

    podruga sestry

    […]usually posts some really fascinating stuff like this. If you are new to this site[…]

Bake a comment




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

© daniel hofstetter. Licensed under a Creative Commons License