Forms and Crud
PHPDevShell provides a complete yet easy extendible Forms and CRUD plugin to deal with Forms in a clean and neat way. There are always some cases where you would need to deviate and have a custom form manager. However, for all general forms, the PHPDevShell Form & CRUD will be more than enough. In later articles it can be made even easier with the build in ORM.
Many know just how tricky and limited Forms can be when creating a general Form controller to make development life easier. We came to the conclusion that Form and CRUD support should not be a do all end all solution, just a supportive tool. In summery;
- Dont auto-generate forms, HTML is easy enough to write forms by hand leaving full control with layout and parameters to the developer. And besides learning code to write forms with while you already know HTML is pretty unproductive.
- You need a CRUD to make the FORM data ready for saving after validating without affecting the standard HTML you created the FORM with.
- Option type fields should be easy to keep selected or be selected when editing.
- Using standard queries for saving or using ORM to save FORM data should be mostly the same.
- You should not have to define variables when the form is not yet submitted.
When you are done with this tutorial you will have a full working form;

01So the formula and rules for our Forms system seems pretty straight forward, lets dive right into our controller and begin the form development. For this tutorial we will be using MVC to keep things as need as possible. Lets start with our example and call the required CRUD plugin.
controller file : plugins/ExamplePlugin/controllers/manage-example.php
<?php
class manageExample extends PHPDS_controller
{
public function execute()
{
// Note the comment format, this is to enable IDE auto completion.
/* @var $crud crud */
$crud = $this->factory('crud');
// Some application information.
$this->template->heading(_('Example Simple Form'));
$this->template->info(_('On this page we will show you how to do a simple form and save data to the database using Models. We will use Models instead of ORM here. There are other examples of easier forms using ORM.'));
}
}
?>
02
Ok now that our controller is running, lets start working on the view and create the form using standard HTML. You will also note I will be adding the variables inside the HTML so that when editing or submitting the values should be filled in and the correct options should be selected.
controller file : plugins/ExamplePlugin/views/manage-example.tpl
We wont see the form display just yet, we still need to tell our controller about the view and setup the validation and everything. So lets complete our controller that we started with above.
Check out the crud API generated docs to see all the validation options available to you.
Let me finish the controller and add as many comments as possible, I will highlight some points afterwards;
controller file : plugins/ExamplePlugin/controllers/manage-example.php
<?php
/**
* Controller Class: New example and edit example.
* Like always we start our node with the controller.
* @author Jason Schoeman
* @return string
*/
class manageExample extends PHPDS_controller
{
/**
* Execute Controller
* @author Jason Schoeman
*/
public function execute()
{
// Load CRUD to make form validation slightly easier...
/* @var $crud crud */
$crud = $this->factory('crud');
// Do we have an id, this we check if url contains an &id=12 for editing for instance.
if ($crud->REQUEST('id'))
$crud->f->id = $crud->REQUEST('id');
// Lets create header information.
$this->template->heading(_('Example Simple Form'));
$this->template->info(_('On this page we will show you how to do a simple form and save data to the database using Models. We will use Models instead of ORM here. There are other examples of easier forms using ORM.'));
// If item gets posted, lets read it, validate it and save it to the database.
if ($crud->POST('save')) {
// For instance, name must be Alpha letters only, else write to fail log with message.
if (!$crud->isAlpha('example_name'))
$crud->error("This field cannot be empty and may not contain spaces");
// For instance, must meet minimum lenght of 20 characters.
if (!$crud->isMinLength('example_note', 20))
$crud->error("This is too short, it needs to be at least 100 characters");
// All must be lower case.
if (!$crud->isLower('alias'))
$crud->error("Alias can only be lower case letters");
// Multiple options require a seperate table to store values, lets treat this now.
if (!$crud->isMultipleOption('example_multi_select_crud'))
$crud->error("Please pick at least one option");
// If everything is ok and we have no errors written in $crud->error we can continue.
if ($crud->ok()) {
$crud->f->id = $this->db->invokeQuery('ExamplePlugin_writeExampleQuery', $crud->f->id, $crud->f->example_name, $crud->f->example_note, $crud->f->alias);
// Show item updated.
$this->template->ok(sprintf(_('Nice, %s was saved to the database.'), $crud->f->example_name));
} else {
$this->template->notice('Form was not saved due to errors.');
// We can now show the errors and mark all fields automaticall... so simple, so clean, so much fun.
$crud->errorShow();
}
}
// Edit example and load data for example.
// This is when we have an id var in the url and we want to show and edit the data.
if ($crud->GET('id'))
// The import fields is a nice way to write the results of the query array to the $crud tables $crud->f fields.
$crud->importFields($this->db->invokeQuery('ExamplePlugin_editExampleQuery', $crud->GET('id')));
// Load views plugin.
$view = $this->factory('views');
// Just some example options.
$options = array(1=>'Option 1', 2=>'Option 2', 3=>'Option 3');
// Set Values for Views variables.
$view->set('self_url', $this->navigation->selfUrl());
$view->set('id', $crud->f->id);
$view->set('example_name', $crud->f->example_name);
$view->set('example_note', $crud->f->example_note);
// For multiple option we can take this a step further...
$view->set('example_multi_select_crud', $crud->select($options, $crud->multiSelected('example_multi_select_crud', $crud->f->id)));
$view->set('alias', $crud->f->alias);
// Output to view.
$view->show();
}
}
return 'manageExample';
As you can see, the controller looks pretty neat and clean, we can read it easily. But there are a we things I would like to clear up.
Here we just check if the user is editing a form or if the form was submitted, we want the data not to clear after submit, the id field is a good starting point. All fields are assigned to $crud->f property, this property ensures that the field is not undefined when used before data is available and also servers as a data field collector.
if ($crud->REQUEST('id'))
$crud->f->id = $crud->REQUEST('id');
There are over 50 validation methods available for your fields, each time you use a validator method the field automatically gets assigned to $crud->f too, making the field name data available immediately, like $this->f->example_name
Here we check if there was any $crud->error() messages that succeeded, if there was any, it would fail and the $crud->errorShow() methods does the work of failing the form and showing the error message, now work from you!
if ($crud->ok()) {
$crud->f->id = $this->db->invokeQuery('ExamplePlugin_writeExampleQuery', $crud->f->id, $crud->f->example_name, $crud->f->example_note, $crud->f->alias);
// Show item updated.
$this->template->ok(sprintf(_('Nice, %s was saved to the database.'), $crud->f->example_name));
} else {
$this->template->notice('Form was not saved due to errors.');
// We can now show the errors and mark all fields automaticall... so simple, so clean, so much fun.
$crud->errorShow();
}
To make life easier when you have selection boxes and a standard database table for the selection (could also be a give array), you can use one line to show the option and default to the selected one with this line :
$options = array(1=>'Option 1', 2=>'Option 2', 3=>'Option 3');
$view->set('example_multi_select_crud', $crud->select($options, $crud->multiSelected('example_multi_select_crud', $crud->f->id)));
$crud->select($available_options(array), $selected_options(array)) just draws the options, where $crud->multiSelected() returns an array of selected values for this form, remember it can be multiple. Note how the database structure look for above multi selected options:
CREATE TABLE `_db_example_multi_select_crud` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `join_id` tinyint(3) unsigned DEFAULT NULL, `value` tinyint(3) unsigned DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
03We are not done yet, we need to create the model and sql data which is called by $this->db->invokeQuery(), the database model file normally consists of a set of classes and its queries, lets create it now:
controller file : plugins/ExamplePlugin/models/manage-example.query.php
/**
* This model will save new data to database.
* @author Jason Schoeman, Contact: titan [at] phpdevshell [dot] org.
*
*/
class ExamplePlugin_writeExampleQuery extends PHPDS_query
{
protected $sql = "
REPLACE INTO
_db_ExamplePlugin_example (id, example_name, example_note, alias)
VALUES
(%u, '%s', '%s', '%s')
";
protected $returnId = true;
}
/**
* This model will show data when we are editing.
* @author Jason Schoeman, Contact: titan [at] phpdevshell [dot] org.
*
*/
class ExamplePlugin_editExampleQuery extends PHPDS_query
{
protected $sql = "
SELECT
id, example_name, example_note, alias
FROM
_db_ExamplePlugin_example
WHERE
id = %u
";
protected $singleRow = true;
}
Conclusion
It might seem slightly daunting at first, however, once you get used to it, it is quite simple, remember to check out many form examples in the PHPDevShell plugin and ExamplePlugin, you should be getting along with it in no time at all!
