Kohana CRUD Scaffold project (0.6beta)
We’ve been using the awesome Kohana framework in our office for some time now, and it’s made out lives a hell of a lot easier – with the wide range of libraries, helpers and of course, the elegant MVC model, we’ve been able to knock out some fantastic sites in relatively short time periods.
The biggest thing we noticed whilst building these sites was the amount of repetition we seemed to encounter – for us, 80% of the work was creating basic CRUD (create, replace, update, delete) interfaces for our clients (and ourselves) to use. Following the DRY principles, I decided to keep refactoring our code until we ended up with a flexible and easy to use CRUD scaffold, upon which we could build simple and elegant interfaces.
This is the first draft of the CRUD scaffold project (a public beta if you wish). I’ve no doubt that it’ll contain bugs – and hopefully these’ll get ironed out over time. The code currently sits on the office SVN server, to which I can’t (or rather won’t) open up global access, however, should this become popular enough, we may be able to convinced the nice folks over at Kohana to create a project repo for us, which we’ll be able to use to further grow the project.
So, to start…
First, download yourself a copy of Kohana from here, and pop it onto your webserver. Configure it how you normally would, set up your database access, and check all is working. We’ve tested it with Kohana 2.3.4, and a modified copy of 2.3.1 – all seems ok.
Next, download a copy of the Formo module here – we like the Formo module (props to Benjamin M for creating and maintaining an awesome package), and love how simple it makes our form generation.
Pop the Formo module in the /modules directory, and don’t forget to add it to your config modules array.
Now, download the crud_scaffold module from here.
Unzip the crud_scaffold module, pop it into your /modules directory, and don’t forget to add it to your config modules array.
I’ve also included the stylesheet and icons used (from the awesome FAM FAM FAM silk set) in a handy zip file here:
static.zip (please note, this file is around 1MB – that’s because I’ve included ALL the FAM FAM FAM silk icons in the zip – hopefully I’ll get time to remove the unneeded ones soon)
*note* I use a folder structure whereby all items such as css, images and JS uploaded by myself (not user generated) are put into a /static/ folder at the root of the site. Your setup may differ – if it does, and you don’t want to use my folder structure, you’re free to change it – just remember to update the location of the icons, stylesheet, etc, thoughout the files and CSS. If you get missing icons/crap looking pages, you haven’t sorted them all – please don’t leave a comment asking why they don’t work. Thanks for listening.*/note*
Now test that your site still works.
Seeing the nice green Kohana page? All is well so far. Let’s continue.
Using the CRUD Scaffold in your code.
Normally, your controllers will extend Template_Controller like this:
class Artists_Controller extends Template_Controller { ... }
To use the CRUD scaffolder, all you need to do is make your controller extend Crud_Scaffold_Controller instead – like this:
class Artists_Controller extends Crud_Scaffold_Controller { ... }
Easy right? Good. If you open up the Crud_Scaffold_Controller code, you’ll see it’s got several protected variables – some of these you’ll need to override in order for the CRUD Scaffolder to know what to do. For the moment, I’ll just explain the basics (with the aid of an example)
class Artists_Controller extends Crud_Scaffold_Controller {
protected $model = 'artist';
protected $base_url = 'artists';
protected $model_friendly_name = 'Artist';
protected $crud_listing_display_keys = array('name' => 'Name', 'phone_number' => 'Phone', 'email' => 'Email');
protected $crud_listing_ordering_keys = array('name', 'phone_number');
}
Firstly, you’ll need to override $model. This just lets the scaffolder know which model it should be working with. We’ll create an Artist model in a bit – for the meanwhile, lets assume that’s what we’re using.
Next is the $base_url – this lets the scaffolder know what URL it should be using – we’re using “artists” here, so our URLs will look like the following:
http://yoursite.com/artists/listing http://yoursite.com/artists/add http://yoursite.com/artists/edit/1
Next comes the $model_friendly_name - sometimes your well thought out model name (Pikwil_Model…) doesn’t make much sense (People I Know Who I Like?)- let people know what it is in a human friendly way – keep it singular, the inflector will look after the rest. We’re using “Artist” here.
Now it’s the turn of $crud_listing_display_keys – here we let the listing page know which fields to show, and the label it should give them. Set the array keys to be the field name, and the values to be the labels.
Finally, we have $crud_listing_ordering_keys – these are the columns you want to be able to sort by – just the field names here will be fine.
Save your controller and start making your model.
The Model
Set up your model as usual – any relationships such as $has_one, $has_and_belongs_to_many will be sorted out by the scaffolder (with a boat load of help from the Formo module).
As we’re using Formo to generate the forms, you may also want to set some field types, and maybe a bit of validation (the scaffolder will work with these too).
Here is a sample model to get you going:
class Artist_Model extends ORM {
public $formo_defaults = array
(
'id' => array (
'type' => 'hidden',
'required' => false
),
'name' => array (
'type' => 'text',
'required' => true,
),
'phone_number' => array (
'type' => 'text',
'required' => false,
'label' => 'Telephone number',
),
'email' => array (
'type' => 'text',
'required' => false,
'label' => 'Email address',
),
'notes' => array (
'type' => 'textarea',
'required' => false,
),
'last_updated' => array (
'type' => 'hidden',
'required' => false,
),
);
}
Pop some SQL into your database (I’m using MySQL here):
CREATE DATABASE `your_test_db` ; CREATE TABLE `your_test_db`.`artists` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `name` VARCHAR( 255 ) NOT NULL , `phone_number` VARCHAR( 30 ) NOT NULL , `email` VARCHAR( 255 ) NOT NULL, `notes` TEXT, `last_updated` INT(11) ) ENGINE = MYISAM ;
And we’re away.
Navigate to the module, and it should, as default, send you to the listing page (where there will be no results).
i.e. http://yoursite.org/artists/listing
You should be presented with something like the following:
I’ve packaged up a sample module with a couple of controllers and a couple of models to demo some of the functionality. You can grab that here:
Pop that into your modules folder, add it to your config, add the tables in the sql.txt file to your database, and navigate your way to:
http://yoursite.local/artists/listing
http://yoursite.local/record_labels/listing
http://yoursite.local/cds/listing
Adding, editing, deleting, and so on…
Here are a couple of example screenshots from the test module above – you can hopefully see how things work:
Adding a new “artist”:
If you’ve got validation turned on, this will be highlighted when you try and save:
If you fill in the fields correctly, you’ll either be taken back to the listing page, or to the edit page if you chose to do so:
Clicking cancel (or if you chose to return to the listing page) will display:
Clicking on the table headers (where they are hyperlinks) will allow you to sort by asc/desc order:
Above you can see that I’ve ordered phone number by descending order.
Next steps…
It’s currently 8pm, and I’m still sat in my office, hungry and tired. I’m pretty sure that by this point, I’ll have made some mistakes, or will have missed something vital. There’s a substantial lack of documentation, and examples.
All of the above needs remedying. Tune in for more details soon (leave your email address in the comments section if you want me to contact you with updates), and with any luck, I’ll have some form of bug tracking, and public repository going on.
I’d love to get your feedback – both positive and negative (though try to keep it constructive – if you really don’t like it, feel free to mosey on by).
Over the next week (time permitting), I’ll try to cover complex relationships, permissions, and manipulation of data (for such things as uploading and storing images, files and anything else you can think of).
Over and out…
Nath.






July 16th, 2009 at 8:33 pm
Please leave your comments here – if you can’t get this working, please let me know – preferably with the error message you’re getting and the platform you’re running it on.
Cheers!
July 16th, 2009 at 8:35 pm
[...] Here’s the first public beta of the Kohana CRUD Scaffold project [...]
July 23rd, 2009 at 1:15 pm
Thanks for this tutorial. I’m going to try this out soon. Any chance you could write a user registration and auth tutorial as well?
July 24th, 2009 at 3:06 am
I had some issues while running an application outside of the root web directory. I fixed this by changing
echo ‘base_url.’/listing’.$url.’”>’.$display_value.’ ‘.$current_ordering_direction.’‘.”\n”;
in _crud_listing.php to
echo ” . html::anchor($base_url.’/listing/’.$url,$display_value . ‘ ‘ . $current_ordering_direction) . ” . “\n”;
July 24th, 2009 at 9:19 am
Thanks Andrew, well spotted! I’ve applied your fix and will release it shortly.
Cheers,
Nathan.
July 27th, 2009 at 4:27 am
I have tried several times to get the procedures you have posted to work. I know I must be doing something wrong as I am very new to Kohana, let alone the CRUD_scaffold. So to explain what I am doing:
First I install the Kohana in the root of my webserver and get all of that working.
Second I add the Formo and CRUD_scaffold to the Modules directory.
Third edit the Modules arrray to include the two new additions.
Download and expand the static.zip into the root directory.
Download the artists.zip and install that into my modules directory with the Formo and Crid_scaffold and update the Modules array again.
At this time I created the SQL tables in a new database using your provided SQL.
Updated the database.php file in the Systems/config directory.
At this point I think I can run the tests to the url you define and I receive an error.
The requested page was not found. It may have moved, been deleted, or archived.
/Users/johnh/Sites/wcaf_app/system/core/Kohana.php [841]:
The page you requested, artists/listing, could not be found.
I am developing on a macintosh. The directory structure shows I am using a directory in my Sites folder. The examples and the Welcome pages display correctly, so I feel that Kohana is installed correctly. I do really want to try to get this to work for a project I am about to undertake.
July 29th, 2009 at 1:41 pm
Well I am quite stupid. The above post about getting the scaffold to work is now fixed. The problem is when you add items to your modules directory the permissions were not set for the browser to access them. It may be important to note that in the instructions for others.
August 3rd, 2009 at 4:47 pm
Thanks for this, I’m really liking it a lot. Although I’m still getting my head around using it with relationships and default values… any chance for an advanced tutorial?
August 10th, 2009 at 3:54 pm
One question on has_many, say I have a model agent that has many phone numbers, is there a way to show several inputs to save to tbl_numbers from controller agents… (has_one shows a select, habtm shows tick)
August 10th, 2009 at 7:49 pm
Hi guys, i’ve just installed Kohana 2.3.4 and Crud Scaffold I get a error when accessing the ‘add’ page.
Fatal error: Class ‘Formo’ not found in /etc…/modules/crud_scaffold/controllers/crud_scaffold.php on line 108
I’ve added Formo to the config.php file. So I’ve got no idea where this is coming from. Do you have any tips? Thank you very much.
August 10th, 2009 at 8:03 pm
Ok, i figured it out.
Permissions on the /formo directory were to low.
By the way, this module is great.
Thank you very much for sharing.
August 11th, 2009 at 10:02 am
@mon if I understand you correctly, you want to be able to input multiple telephone numbers (creating a new record for each one) for each agent – we haven’t yet found a quick and easy solution to this, but are looking into it – if you have a solution that helps, please feel free to submit a patch – alternatively, please visit the project site (http://projects.nathanbentley.com/projects/crudscaffold/issues) and add a new feature request – when we get time, we’ll look into it and add it to the project roadmap.
August 18th, 2009 at 12:49 am
Thank you for the project. I was able to hook it up quickly and build an admin section for a small business site. I have however made a few modifications that you might find helpful (or not). Let me know how to communicate them. Also, the css looks great. Thanks again.
August 18th, 2009 at 9:41 am
Hi David,
You can add a new feature request to the project page here: http://projects.nathanbentley.com/projects/show/crudscaffold (register, log in, and click new issue)
Alternatively, email me at mail (at) nathanbentley (dot) com and I’ll add the request for you.
Cheers,
September 14th, 2009 at 7:02 am
Really, really nice module! So thankful for not having to write this from scratch myself
Although I do have a problem with a file upload field. The files get uploaded alright, but only sometimes (like 5% of the time) the filename gets saved into the table field associated with the file. Anyone knows why this is?
September 14th, 2009 at 9:38 am
Hi Magnus,
Glad you like the module! With regards to the file field, I had similar problems, as well as a host of issues relating to how it uploads and validates, and so eventually ended up creating a new file upload driver for formo. My understanding is that to get the file driver to work, you’ll need to capture the output of the file driver, and save the specific part(s) to the database (I believe there are a number of different values returned). You can do this inside either the add_save() or edit_save() methods, which you can override in your controller.
I’ll try to post up my modified file driver for formo sometime soon.
September 14th, 2009 at 11:44 pm
Hi again! Nice to hear that it wasn’t only me who has the problem, thought for a second I did something wrong. I currently don’t have the time it takes to make this sort of hack you are describing, please keep posting about improvements to crud-scaffold and the file upload thing!
I cannot praise this module enough. Kohana together with this module takes PHP frameworks a big leap forward. Now PHP frameworks are almost as easy to use as Django for example. The old PHP4 based monsters like Symfony and Cake are just too much hassle. Hope Kohana includes this module in the framework once it has matured.
November 8th, 2009 at 4:18 am
What of this working with KO3??
Has anyone done it?
Total noob to Kohana, so speak in single syllable words please
-Alister
November 8th, 2009 at 8:52 pm
Hi Alister,
Hasn’t been ported to KO3 yet I’m afraid – I was hoping to make a start on it soon, but I’m fairly snowed under at work, so it may be a while yet. Of course, if someone else fancies giving it a go, I’ll happily create a branch in the project repo and give them access.
Otherwise, I’m afraid we’ll have to wait until things calm down (most likely after the new year sometime).
Nathan.
January 25th, 2010 at 9:16 pm
Greetings, Nathan!
First of all I’m grateful for this cool module. There is a problem though: when adding record autonumber id is lost.
public function add()
…
if ($form->validate())
{
$this->add_save($form);
$form->save();
die( ‘##’ . $form->get_model($this->model)->id );
On this line I get 0 every time. What is very strange is that when I print same ID from Formo ORM plugin I get proper value.
Have you got any idea what’s happening there? Does it work at your testbed? To represent just add something and click ‘add new something and edit’.
January 26th, 2010 at 10:55 am
Hi Shaine,
I’ve noticed this problem occuring when using a copy of Formo newer than revision 130 – it looks like Ben Midget (owner of the Formo module) has re-architected the loading of values, causing the CRUD scaffolding module to break.
I’m reasonably convinced that the problem is either an unexpected bug in Formo, or needs a clearer definition of how to access and manipulate models within Formo itself.
At the moment, the I’ve found two fixes – either use a version of Formo earlier than r130, or patch the new Formo code to ensure that fill_models() is only called once.
I’m hoping Ben will respond soon with an update on this issue.
Cheers,
Nathan.
March 7th, 2010 at 12:23 am
Hello,
I’m using your exelent module for a while, but now i stuck into one thing:
When I’m saving a file – its name is timestamp+name on disk, but only name in database. Is it possible to easyly change this behaaviour ? I need a real file name in database (with) timestamps.