Creating Cough models for our CoughPHP/LightVC application

April 10, 2009
Tags: ,

In this tutorial, we continue to create an MVC application using the bare LightVC and CoughPHP distributions, focusing on creating working cough model classes and using them in the application, as well as best practices for different deployment environment files for LightVC applications, CoughPHP generation config, and suggested db schema patterns.

For this tutorial, you will need to have the skeleton application created in the previous article on combining CoughPHP and LightVC, as well as a working installation of MySQL. Installing and configuring MySQL is outside the scope of this tutorial, but there are many pre-packaged versions available.

Step 1: Create our Post table
Actually step 0 is to create the database in mysql. For the purposes of this tutorial, we’re going to be using a database called ‘cms’, with a user also called ‘cms’. Note that unlike many ORMs, CoughPHP has no trouble with cross-database object relationships, so at a later point we may be using multiple databases for the purpose of organization.

		CREATE DATABASE IF NOT EXISTS `cms` ;
		GRANT ALL PRIVILEGES ON `cms` . * TO 'cms'@'localhost';
	

Now we’re going to create our sample Post table:

		CREATE TABLE `cms`.`post` (
		`post_id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
		`name` VARCHAR( 255 ) NULL DEFAULT NULL ,
		`body` TEXT NULL DEFAULT NULL ,
		`is_deleted` TINYINT( 1 ) NOT NULL DEFAULT '0',
		`date_created` DATETIME NULL DEFAULT NULL ,
		`date_modified` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NULL DEFAULT NULL
		) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
	

A few notes on some of the conventions we will be using here:
* Singular table names:
Cough generates its objects names based on the table names and it would be confusing if the class representing a single row in the ‘posts’ table was called Posts, and your aggregate object was called Posts_Collection.
* is_deleted column: in general, it is a common idea to do logical deletes rather than actually deleting data from the db, and an is_deleted flag is one of the simpler paradigms. In future articles we will go into more detail about logical deletions, the reasonings behind them and how CoughPHP can work with them most effectively.
* c_style_naming: This is just convention, deal with it.
* table_name_id primary key: CoughPHP by default will look for joins to other tables by looking for columns named _id. This can be configured, and joins can be manually specified, but we will take use the default for now.

Step 2: Create models directory, set up generate script, set up generator config:
Now that we have created a table to generate our objects from, we need to set up the CoughPHP generator to point at the right database, put the objects where we went them, etc.

First, create a directory in the cms project to hold our generated classes:

mkdir models

Next, we’ll create a shell script that will generate the classes:
edit config/generate:

		#!/bin/sh
		../modules/coughphp/scripts/cough -g generator_config $@
	

and make it executable”

chmod +x config/generate

And create our base generator configs:

mkdir config/generator_config
cp ../modules/coughphp/config_examples/default/*.php generator_config/

Now to actually set up the generator configs. We’re going to tell it to put the generated classes into the models/ directory we just created.

edit config/generator_config/cough_generator.inc.php and add the following line:

		$generated = dirname(dirname(dirname(__FILE__))) . '/models/';
	

Now we need to tell the generator the connection information we’ll be using, as well as which databases to generate objects for.
Edit config/generator_config/database_schema_generator.inc.php and change the $config array:

		$config = array(
			'dsn' => array(
				'host' => 'localhost',
				'user' => 'cms',
				'pass' => 'mypassword',
				'port' => 3306,
				'driver' => 'mysql'
			),

			'database_settings' => array(
				'include_databases_matching_regex' => '/cms/x',
				'exclude_databases_matching_regex' => '/(_bak$)|(^bak_)|(^temp_)/',
			),
		);
	

Step 3: Generate
To generate the Cough objects:

cd config
./generate

You should get output similar to the following:

		Generating for ../config/generator_config
		=========================================
		Success writing 4 classes (220 lines) with 0 one-to-one relationships and 0 one-to-many relationships!
	

Now we only have 1 table, why is did it generating 4 classes?
For each table, Cough generates classes of two forms, a single and an aggregate. For each of these forms, it generates a base-class and if it doesn’t already exist, a sub-class.
This latter distinction is important. For a table called post, it will generate a Post_Generated class, which contains all the getters/setters/base CRUD logic/etc. It will also create an empty Post class for the developer to add functionality to. Similarly for the aggregate collections, it will create a Post_Colllection_Generated class and a Post_Collection class. Each time you re-run the generator, the *_Generated classes will be overwritten by the generator, but if the Post/Post_Collection classes already exist, they will be left untouched.

Step 4: App changes
Now that we have the models generated, we’ll need to modify the autoloader setClassPaths in config/application.php:

		Autoloader::setClassPaths(array(
			APP_PATH . 'classes/',
			APP_PATH . 'models/',
		));
	

Next we need to set up the application to include our database credentials. However, we might want to change database credentials between say the development and production versions of the application, so we’ll create a separate file with the credentials and include a symlink to it from inside application.php. That way when we deploy to production, we can just change the symlink.


mkdir config/environment

Create a file config/environment/dev.php:

		<?php
		// Setup database config
		CoughDatabaseFactory::addConfig(array(
			'adapter' => 'as',
			'driver' => 'mysql',
			'host' => '127.0.0.1',
			'user' => 'cms',
			'pass' => 'mypassword',
			'aliases' => array('cms'),
		));
		?>
	

Now symlink the file:

cd config/
ln -s environment/dev.php environment.php

Edit config/application.php and add the following lines before the line about loading routes:

	// Include env specific confs
	include('environment.php');
	

Step 5: Test Cough
Congratulations, you’ve successfully set up CoughPHP! Let’s test it out:
We’re going to add some code to the view action in the page controller, just to create a Post object, set some fields on it and then save it to the db. Next time we’ll talk about pulling it back out, and really doing something with it, with collections and actually using the View/Controller parts of the MVC paradigm.

For now, edit controllers/page.php and add the following to the actionPage method:

		$post = new Post();
		$post->setName('Test Post');
		$post->setBody('This is a test post.');
		$post->setDateCreated(date("Y-m-d H:i:s",time()));
		
		$post->save();
	

Now hit your http://cms.rhp.org or equivalent URL. If you get any error messages, make sure that all the CoughPHP classes are accessible by your apache user, make sure your config/application.php has the following lines in it:

		include(APP_PATH . 'modules/coughphp/load.inc.php');
		include(APP_PATH . 'modules/coughphp/as_database/load.inc.php');
	

And make sure your database is readable/writable by the user specified in your db configuration above.

Given a lack of errors, check your database. You should see a row in the post table!

Next Time:
We’ll create a simple list of all posts in the db, create/edit/view actions, and more!

12 Responses to “Creating Cough models for our CoughPHP/LightVC application”

  1. Re: * table_name_id primary key: CoughPHP by default will look for joins to other tables by looking for columns named _id. This can be configured, and joins can be manually specified, but we will take use the default for now.

    CoughPHP will also find relationships through any foreign keys. But, following the convention is still a good idea as it allows cross-database relationships to be found (cross-database foreign keys aren’t supported in MySQL).

  2. It’s a very interesting subject I was looking around about more information but you got really what i was looking for in your article so thanks and keep it up you have a great blog .
    I’m very interested in CMS and all its related subjects.

  3. John,

    Thanks for the comment! I’m in the middle of crunch time during my day job, so it may be a couple of weeks, but I’ll get to the next article as soon as I can free up some time!

  4. […] this tutorial, you will need to have the skeleton application created in the previous article on combining CoughPHP and LightVC, as well as our database table and generated CoughPHP […]

  5. I use wamp ( apache on windows with php5) and dont know how to work around those shell commands and script you have here? Could you help me with that, i am really excited about your tutorial and have been wanting to understand MVC for quite some time now. Please consider my request

  6. For the symlinks in the environment directory, try copying the file.
    To generate CoughPHP, see This question on launchpad.

  7. your above mentioned method “actionPage” does not exist in page.php in the controllers folder. The only method that is in there is called actionView. and by putting your $post code in there it does work, but am i doing something wrong – why dont i have that method.

    Is it necessary to be giving in the database information in dev.php and environment.php. could you explain a little on that please.

  8. Great text. Waiting for you to continue the topic.

    Avril Benedict
    polish escort in warsaw

  9. Forgot how to do most of this! Thanks Richard.

  10. No problem Chris! Glad I’m of use to somebody!

  11. Hallo

    I have tried LightVC and CoughPHP. I use Windows. After many unsuccessful attempts, I finally succeeded. The article you write does not help me. I want to give some information for you.

    1. LightVC and CoughPHP Maintainers seem unresponsive to the visitors request. These visitors are potential users of both. You should pay attention to this potential users coming from Windows environment, if you want your work widespread. You already know that more Windows users than Mac users (like it or not). Working in a Windows environment is different then in the MacOS. So you should write articles related to Windows.

    2. Why this tutorial is not on the official website of CoughPHP or LightVC. This kind articles is very important in the offical website. Without this, the credibility of both sites is dropped. I found this article through Google. You certainly can imagine when visitors of both sites did not seek other information. In my opinion, they will lose interest. Moreover, they will realize that very little information is available out there.

    3. Folders that exist in CoughPHP package are confusing. There is no information on what folders contain library and what folders contain examples. It took me days just to find out where it should be placed in LighVC structure. Give enough information so that other people do not spend a long time for something simple.

    4. I’ve read LightVC and CoughPHP. LightVC is very simple and its maintainers do the right work to make it as easy as possible. I can learn it easily. CoughPHP is also simple. But because too many files and organized in several folders, I was a little difficult to learn. CoughPHP must imitate the simplicity LighVC, if necessary, make it into one file.

    5. I always fail to use CoughPHP generator (/scripts/cough). Finally I changed the script to be used. This is bad thing. In my opinion, the script must be changed into an interactive one, so users can enter the parameters later, if they fail to give previously.

  12. Do you have any other documentation for CoughPHP? Any information would be appreciated.

    Thank you.