CodeExtinguisher - Tame the Fire

Overview

The JTaby Backend system was created to fill a hole in CodeIgniter. Sure you can setup a full site in 20 minutes, but to your client, the site is useless if there isn't a single-entry/exit point through which to control the content of the site. As it turns out, most of these actions can be generalizes into what is called a CRUD (Create / Retrieve / Update / Delete). The system allows you to generate a user-friendly CRUD.

The System was designed with one thing in mind: Rapid Development. As a result, you can see from the provided examples that you can get a page up with only one, small controller file. The controller simply provides the parameters necessary for the system to know what you want to edit and what you want the client to see.

Back to Top

Installation

Setting up the Backend could not be any easier. Simply unarchive into your web root and you're almost done. All you have to do then is setup the database. Here is the code you need to run to get everything working.

IMPORTANT NOTE:

Please make sure that you create a new user and delete the default one after you login for the first time.

Note: This sql sets up a table called template . This is a table that is needed for the bundled template to work. You don't need it for the system to work.

    CREATE TABLE `ci_sessions` (
      `session_id` varchar(40) NOT NULL default '0',
      `session_start` int(10) unsigned NOT NULL default '0',
      `session_last_activity` int(10) unsigned NOT NULL default '0',
      `session_ip_address` varchar(16) NOT NULL default '0',
      `session_user_agent` varchar(50) NOT NULL,
      `session_data` text NOT NULL,
      PRIMARY KEY  (`session_id`)
    );

    CREATE TABLE `users` (
      `id` int(11) NOT NULL auto_increment,
      `username` varchar(40) NOT NULL,
      `password` varchar(40) NOT NULL,
      `access_level` int(11) NOT NULL,
      PRIMARY KEY  (`id`)
    );
    INSERT INTO `users` (
        `id` ,
        `username` ,
        `password` ,
        `access_level`
    )
    VALUES (
        NULL , 'username', '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', '1'
    );

    CREATE TABLE `template` (
        `id` int(11) NOT NULL auto_increment,
        `checkbox_test` set('yes','no') NOT NULL,
        `date_test` date NOT NULL,
        `dropdown_test` varchar(100) NOT NULL,
        `editor_test` text NOT NULL,
        `file_test` varchar(100) NOT NULL,
        `password_test` varchar(100) NOT NULL,
        `radiogroup_test` varchar(100) NOT NULL,
        `sessiondata_test` varchar(100) NOT NULL,
        `textarea_test` text NOT NULL,
        `textbox_test` varchar(100) NOT NULL,
        `time_test` int(11) NOT NULL,
        PRIMARY KEY (`id`)
    );
    

After you unarchive, you need to setup the database configuration (backend/config/database.php).

When you have setup the system, you can login using the username: username and the password: password. As noted, please create a new account and delete the default one.

Now you're done :) To access the backend, simply add backend.php to the end of the url.

Back to Top

Setting Up Your First Page

To setup your first page using the JTaby Backend System, it is useful to reference the bundled template. It can be found in backend/controllers/template.php.

Here's a copy of the template controller:

<?php 
include("jtabycontroller.php");

class Template extends jTabyController 
{ 
    function Template () 
    { 
		jTabyController::jTabyController();
        $this->load->library('spyc');                
        $this->load->helper('inflector');
        //Validation Rules

        $config = array(
                    'db_table' => 'template',
                    'form_setup' => $this->spyc->YAMLLOAD('definitions/template_form.yml'),
                    'controller_name' => 'Template',
                    'list_text' => array('textbox_test','textarea_test'),
                    );
        $this->setConfig($config);
    } 
}
?>
    

You may notice that this example uses the bundled spyc library to parse a YAML file. This is absolutely optional, refer to the "To YAML or Not To YAML?" section for more information.

Back to Top

jTabyAdmin Options

The system takes 13 options. Here's is a list of them and their respective purposes:

Required Type Option Description Example
Yes string db_table Defines the database table to use in the current controller. 'db_table'=>'blog',
Yes array form_setup This is the form definition of your array. The form is created from these parameters. See the "Customizing your Forms" section.
Yes string controller_name The controller name as it appears in the class definition. 'controller_name'=> 'Blog'
Yes array list_text This is the list of table field which will show up in the list. Usually you would choose the most descriptive fields here. The sorting list is also based on this parameter. 'list_text'=>array('name'),
Yes string list_header This is the header displayed before the list in your list-view page. 'list_text'=>'Template Page',
No string ordery_type This defined what type of sorting you want; either asc or desc. 'order_type'=>'asc',
No associative array table_access_restriction This defined the criteria you want to be matched when pulling the data for the list view. 'table_access_restriction'=>array('user_id'=>'foo'), Would generate: ( WHERE `user_id` = 'foo' )
No string ordery_by This defined what field you are going to oranize the list in. 'order_by'=>'title',
No string form_prefix This is the form prefix, it goes before the label of each element. 'form_prefix'=>'<div class="form-element">'
No string form_suffix This is the form suffix, it goes after the input field of each element. 'form_prefix'=>'</div>'
No array excluded_fields This is an array of fields that are in the form, but not in the database. 'excluded_fields' => array('passowrd_confirmation')
No associative array rules This is the array used to setup form validation. Refer to CodeIgniter's Validation library documentation for instructions on how to set the form up. array('name'=> 'trim|required')
No associative array messages Contains the array which defines the messages to be relayed to the user. Possible keys are: add_success, add_failure, edit_success, edit_failure, edit_no_change, delete_success, delete_failure, upload_success, upload_failure, upload_remove_success, upload_remove_failure See 'Customizing Your Messages' Section

Customizing Your Messages

Customizing the messages is extremely simple. To change the default messages, simply add a messages option in your controller. Here's an example:

$messages['add_success'] = 'Hurray for personalized messages!';
$messages['upload_remove_success'] = 'Oh hai i delete ur filz!';

$config = array(
            'messages' => $messages
            );

As you can see, we only defined two messages here. You don't have to define all or none of the messages, you can only define the ones you want to change. Here's a list of the available messages, their role, and their default values:

Name Role Default Message
add_success Is displayed when an item is added successfully Item was added successfully.
add_failure Is displayed when an item is not added successfully Item was not added successfully.
edit_success Is displayed when an item is edited successfully Item was edited successfully.
edit_no_change Is displayed when an item is submitted, without making any changes There was no change to apply!
delete_success Displayed when an item is successfully removed from the database Item was deleted successfully.
delete_confirm Displayed to confirm a deletion You are about to permanently delete an item.
delete_confirm_link Contains the text that's displayed in the confirmation button It's ok, go ahead.
delete_failure Is displayed when an item is not deleted successfully Item was not deleted successfully.
upload_success Is displayed when a file is uploaded successfully Associated file was uploaded successfully.
upload_failure Is displayed when a file is not uploaded successfully Associated file was not uploaded successfully.
upload_remove_success Is displayed when a file is deleted successfully Associated file was deleted successfully.
upload_remove_failure Is displayed when a file is not deleted successfully Associated file was not deleted successfully.
Back to Top

Taking the System Further

You may be wondering how the system works if your contains only one function. Well, in the system, you may have noticed that the controllers don't extend the Controller class, instead they extend a special kind of class: jTabyController. This is added for your convenience and is optional. However, if you opt-out of using it, please make sure you implement jTabyController's functionality in your own code.

However you may not like the way the way the system adds new items, but you don't want to recreate jTabyController, in that case, you can simply overload (define a function of the same name) the insertNewItem function in your own controller. Here's a list of function you can overload to add special functionality:

index()

This function loads the view. The default one sets up the list to display.

insertNewItem($fill_with_post = false)

This method iteratively calls prepForDisplay on every form element, then displays the form. If there was a validation error, it populates the form with $_POST, otherwise, it populates the form with the corresponding database data.

editExistingItem($fill_with_post = false)

This method iteratively calls prepForDisplay on every form element, then displays the form. If there was a validation error, it populates the form with $_POST, otherwise, it populates the form with the corresponding database data.

executeInsert($extra_fields=array())

This method iteratively calls prepForDb on every form element, then inserts the data into the database.

executeEdit()

This method iteratively calls prepForDb on every form element, then it updates the record

delete_confirm($id)

This method loads the jtaby_delete_confirm.php view, to ask the user for confirmation before a delete.

delete()

This method called prepForDelete on every form element, then removes the record from the database.

Back to Top

jTabyValidation

The system comes with a library called jTabyValidation. This is actually the stock validation library which ships with CodeIgniter. This version however, uses the jTabyMessages library to communicate with the user. It does this to provide a more uniform way of reporting errors. Validation errors are displayed as 'info' messages to the user. You can, however, change the prefix and the suffix of these messages in the constructor of the jTabyForms library located in backend/libraries/.

Note: Validation currently does not work in PHP 4. Moreover, if you define your own form element which contains an array (multiple input fields with the same name, suffixed by []), then validation errors related to those fields seem to log the user out. These are known bugs and are being worked out.
Back to Top

jTabyForms

To create a form, you simply define the elements in your controllers. All form elements take a 'class' parameter which defines which class is associated with that element. For example, a textbox's class would be TextBox. Moreover, all of them take a required 'name' key which has to correspond to the databases' field name.

All elements also take an optional 'label' parameter which defines the label to be shown alongside the form field. If you don't define a label, then it'll use a humanized version of the name parameter. However, this requires the inflector helper to be initiated. If it is not, then it will simply capitalize the first letter of the name parameter. You can also define a 'value' parameter which will give the element an initial value. Next, you can define an 'attributes' parameter which is an array. The keys of the array refer to the name of the attribute, and the value of the array to the value of the attribute. Finally, you can define a 'params' parameter to provide extra parameters required by that element.

Back to Top

To YAML or Not To YAML?

As noted in the "Setting up your first page" section, the system comes bundled with YAML capability. Those familiar with Symfony know exactly what I am talking about, to others, YAML is simply a human-friendly markup language. The choice of whether or not to use YAML is totally up to you. Here are the pros and cons of it:

Pros

Cons

Back to Top

Customizing Your Forms

The system takes a very specific form_setup array structure. If you deviate from this structure, you can break the system. Here is an exhaustive example which shows you how to setup each of the bundled form elements. (This definition is found for the template_form.yml file, if you want to see it in action.

YAML PHP
            checkbox_test:
                class: CheckBox
                value: true
            date_test:
                class: Date
            dropdown_test:
                class: Dropdown
                params:
                    list:
                        1: One
                        2: Two
                        3: Three
                value: 2
            editor_test:
                class: Editor
                value: initial value
                attributes:
                    rows:20
                    cols:100
                params:
                    theme:advanced
            file_test:
                class: File
                params:
                    upload_path: /full/path/to/upload/dir
            password_test:
                class: Password
            radiogroup_test:
                class: RadioGroup
                params:
                    list:
                        1: One
                        2: Two
                        3: Three
            sessiondata_test:
                class: SessionData
                params:
                    item: user_name
            textarea_test:
                class: TextArea
                attributes:
                    rows:5
                    cols:50
            textbox_test:
                class: TextBox
                value: Initial Value
            time_test:
                class: Time
        
Array
(
    [checkbox_test] => Array
        (
            [class] => CheckBox
            [value] => 1
        )

    [date_test] => Array
        (
            [class] => Date
        )

    [dropdown_test] => Array
        (
            [class] => Dropdown
            [params] => Array
                (
                    [list] => Array
                        (
                            [1] => One
                            [2] => Two
                            [3] => Three
                        )

                )

            [value] => 2
        )

    [editor_test] => Array
        (
            [class] => Editor
            [value] => initial value
            [attributes] => Array
                (
                    [rows] => 20
                    [cols] => 100
                )

            [params] => Array
                (
                    [theme] => advanced
                )

        )

    [file_test] => Array
        (
            [class] => File
            [params] => Array
                (
                    [upload_path] => /full/path/to/upload/dir
                )

        )

    [password_test] => Array
        (
            [class] => Password
        )

    [radiogroup_test] => Array
        (
            [class] => RadioGroup
            [params] => Array
                (
                    [list] => Array
                        (
                            [1] => One
                            [2] => Two
                            [3] => Three
                        )

                )

        )

    [sessiondata_test] => Array
        (
            [class] => SessionData
            [params] => Array
                (
                    [item] => user_name
                )

        )

    [textarea_test] => Array
        (
            [class] => TextArea
            [attributes] => Array
                (
                    [rows] => 5
                    [cols] => 50
                )

        )

    [textbox_test] => Array
        (
            [class] => TextBox
            [value] => Initial Value
        )

    [time_test] => Array
        (
            [class] => Time
        )

)
        

As of this version, the system allows you to define prefix's and suffix's to your form. These go before the label, and after the input field (or whatever field is associated with that form element). You define the prefix and the suffix in the configuration in your controller using the keys: form_prefix and form_suffix. In a future version of the system I hope to add layout strings. As of this version however, if you want to modify the way the elements are displayed in any major way you can modify the form library to your hearts content.

Back to Top

Extending the Forms library - Adding your own elements

To add your own custom form elements, you have to create a new file in the application/backend/plugins/ directory. The name of the file must be a minimized version of the class name. Here's the skeleton of a library:

class Name extends jTabyForms
{
    function Name($name,$params) { 
        jTabyForms::initiate($name,$params);
    }

    //This method returns the html of the form.
    function getHTML()
    {
        $html = "";
        ...
        return $html;
    }
}

Should your class require it, you can specify the following methods:

prepForDb($value)

This gets called everytime the data ($value) is getting prepped to be inserted into the database. By default, the data goes through mysql_real_escape_string(). If you need to, you can overload this to specify your own prepping rules.

prepForDisplay($value)

This gets called everytime the data ($value) is getting prepped to be displayed to the screen. By default, the data goes through htmlentities(). If you need to, you can overload this to specify your own prepping rules.

prepForDelete($value)

This gets called everytime the data ($value) is getting prepped to be deleted from the database. By default, the data is simply returned. If you need to, you can overload this to specify your own prepping rules.

getHTML()

This method returns the html that will be used to print the form to the screen.

Back to Top

jTabyMessages

The bundled jTabyMessages library provides a way for the system to communicate with the user. It takes 3 types of messages by default: success, failure, and info. The wrappers for these types can be set independently using the setWrappers() method.

add($type,$message,$id="",$mark_as_old=false)

This method adds the provided message to the flashdata. $id is optional and defines a special kind of message (other than success/failure/info) Note however that any new types default as info messages. This can be changed by calling the setWrappers method. $mark_as_old is also optional and when true, sets the new message as old so that they would show on the current page, not the next one.

How messages are stored:

Flashdata is a special kind of session data. It is stored in the database as a serialized array. When a flashdata item is first set, it is set as "new", then on the next request (usually the next page loaded), it is marked as "old" and can be retrieved using the flashdata() function (called on jtabysession). For validation errors however, we need them to be displayed instantly (not on the next request), to do that, we need to manually set them as old using the $mark_as_old option.

getAsArray($type="")

This method returns the messages of the specified type (if none defined, it'll get them all) as an array.

getAsHTML($type="")

This method returns the messages of the specified type (if none defined, it'll get them all) as a html.

setWrappers($type,$prefix="",$suffix="")

This method sets the prefix and suffix wrappers of the specified type.

Back to Top

jTabyLogin

The jTabyLogin library was designed to work behind the scenes. Your controllers shouldn't have any login logic in them. All you need to do to secure controllers is to add the rules to the access_levels.php file in backend/config/.

The $config array takes controller names (as they appear in the url), and optionally methods as keys, their value identifies the level of security. The levels are integers, 0 being public by convention. The public_level config item, defines the level which is public and unsecured. Any controller who's level is set to the same one as $config['public_level'] will not require access. If a controller doesn't have any definition, it will have the value of $confi['default_level'] applied to it.

How information is stored:

The session_id and the user_id are stored as userdata (in a session) to check for login. However, other information such as validation errors and system errors are stored as flashdata.

Back to Top

Known Bugs

As of the alpha release, there are a few known bugs: