How to validate multiple forms on one page in CodeIgniter?               

In this tutorial I will show how to create a controller and a view in CodeIgniter to render, validate and output forms, validation error messages and results for multiple forms on one page.

We will start from creating the controller.

The controller

On top of every CodeIgniter controller script file we need to put the following line

1
if (!defined('BASEPATH')) exit('No direct script access allowed');

which prevents from accessing the controller from the outside.

Now we’ll create a CodeIgniter controller script for rendering forms, validation and getting the validation results. As you probably know all controller scripts are placed in application/controller directory in you app’s root folder and each script has the same filename as the class inside.

More about this you can find [here; link for external CI site or other article].

Let’s create a class called “Forms” which will extends from the main CodeIgniter controller class (CI_Controller)

1
class Forms extends CI_Controller {

Then we have to create a class constructor to initialize parent class constructor first to we will have access to all CI_Controller methods then we load form helper which contains functions that assist in working with forms.

1
2
3
4
5
6
7
// Controller constructor
public function __construct()
{
    parent::__construct();
    // Load form helper required to validate forms
    $this->load->helper('form');     
}

We will write a method (function) for defining form elements and passing that data to the view so it can be rendered. Index function is executed by default when accessing controller. In index method we’ll define three forms. First one will go with username and key text input fields and the rest will go with just a username text input field. And the end of this function we take all the arguments and pass it on to our view which will render the forms.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Prepare data for the view to output the forms
public function index()
{
    // Defining form1 elements
    $data['form_1'] = array('class' => 'main_form', 'id' => 'form_1');
    $data['form_1']['username'] = array('name' => 'username', 'value' => 'Default username');
    $data['form_1']['key'] = array('name' => 'key', 'value' => 'Key');
    $data['form_1']['submit'] = array('value' => 'Submit!', 'type' => 'submit');
 
    // Defining form2 elements
    $data['form_2'] = array('class' => 'main_form', 'id' => 'form_2');
    $data['form_2']['username'] = array('name' => 'username', 'value' => 'Default username');
    $data['form_2']['submit'] = array('value' => 'Submit!', 'type' => 'submit');
 
    // Defining form3 elements
    $data['form_3'] = array('class' => 'main_form', 'id' => 'form_3');
    $data['form_3']['username'] = array('name' => 'username', 'value' => 'Default username');
    $data['form_3']['submit'] = array('value' => 'Submit!', 'type' => 'submit');     
    // Load the forms view and pass data to the view
    $this->load->view('forms', $data);       
}

New we’ll create a function that will assign validation rules to each of form elements and return the validation status.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Form validation function
private function validate_form($validation_rules, $callback=NULL)
{
    $array_index = 0;  
    // Load the form validation CodeIgniter library
    $this->load->library('form_validation');                     
    // Loop through validation rules and set it up for each element
    foreach($validation_rules as $form_rules)
    {
        list($name, $title, $rules) = $form_rules;
        $this->form_validation->set_rules($name, $title, $rules);
    }                          
    // Run the validation and resturn the result
    return $this->form_validation->run();
}

Now is the time to focus on main validation function. It will be picking up the form name to be validated from the current URL than it will run it against validation rules that we specify for each form element.

So for example for form_1 we are setting up validation rules for username and key input fields. In that case username and key fields will be required. We can use more advanced validation but now we will stick up with basic validation so you could get a better overview of it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Validate forms with set rules
    public function validate()
    {      
        // Get the form name from URI
        $form_name = $this->uri->segment(3);
 
        // Setting validation rules for form1
        $rules['form_1'] = array(
            array('username', 'Username', 'required'),
            array('key', 'Key', 'required'),
        ); 
        // Setting validation rules for form2
        $rules['form_2'] = array(
            array('username', 'Username', 'required'),
        );
        // Setting validation rules for form3
        $rules['form_3'] = array(
            array('username', 'Username', 'required'),
        );
        // Validate specific form according to form name given in URL
        $this->validate_form($rules[$form_name]);   
        // Return to forms and display the result
        $this->index();     
    }  
}

So now we have finished writing our forms controller. New we are going to create a view which will hold our forms.

The view

In our view we will make sure that we output any validation errors, generate three forms and get the validation results. So first of all we’ll get (if there are any) validation errors.

1
<?php echo validation_errors(); ?>

Then we will generate three forms with elements specified in controller.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<h2>Form 1</h2>
<?php   
print form_open(base_url('forms/validate/form_1'), $form_1) .
form_input($form_1['username']) .
form_input($form_1['key']) .
form_input($form_1['submit']) .
form_close();
?>
 
<h2>Form 2</h2>
<?php   
print form_open(base_url('forms/validate/form_2'), $form_2) .
form_input($form_2['username']) .
form_input($form_2['submit']) .
form_close();
?>
 
<h2>Form 3</h2>
<?php   
print form_open(base_url('forms/validate/form_3'), $form_3) .
form_input($form_2['username']) .
form_input($form_2['submit']) .
form_close();
?>

At the end of our view we will output validation results.

1
2
3
4
5
6
7
<?php
if (isset($result) && $result)
{
    echo '<h1>Result</h1>';
    echo $result;
}
?>

If you followed this tutorial now you should be able to validate all three forms according to submission.

You can download the source code for this tutorial at the bottom.

Good luck and have fun with validation.

FROM_UNIXTIME(unix_timestamp), FROM_UNIXTIME(unix_timestamp,format)

Returns a representation of the unix_timestamp argument as a value in ‘YYYY-MM-DD HH:MM:SS’ or YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context. The value is expressed in the current time zone. unix_timestamp is an internal timestamp value such as is produced by the UNIX_TIMESTAMP() function.

If format is given, the result is formatted according to the format string, which is used the same way as listed in the entry for the DATE_FORMAT() function.

mysql> SELECT FROM_UNIXTIME(1196440219);
        -> ‘2007-11-30 10:30:19’
mysql> SELECT FROM_UNIXTIME(1196440219) + 0;
        -> 20071130103019.000000
mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(),
    ->                      ’%Y %D %M %h:%i:%s %x’);
        -> ‘2007 30th November 10:30:59 2007’
Note: If you use UNIX_TIMESTAMP() and FROM_UNIXTIME() to convert between TIMESTAMP values and Unix timestamp values, the conversion is lossy because the mapping is not one-to-one in both directions. For details, see the description of the UNIX_TIMESTAMP() function.

FROM_UNIXTIME(unix_timestamp), FROM_UNIXTIME(unix_timestamp,format)

Returns a representation of the unix_timestamp argument as a value in ‘YYYY-MM-DD HH:MM:SS’ or YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context. The value is expressed in the current time zone. unix_timestamp is an internal timestamp value such as is produced by the UNIX_TIMESTAMP() function.

If format is given, the result is formatted according to the format string, which is used the same way as listed in the entry for the DATE_FORMAT() function.

mysql> SELECT FROM_UNIXTIME(1196440219);
        -> ‘2007-11-30 10:30:19’
mysql> SELECT FROM_UNIXTIME(1196440219) + 0;
        -> 20071130103019.000000
mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(),
    ->                      ‘%Y %D %M %h:%i:%s %x’);
        -> ‘2007 30th November 10:30:59 2007’
Note: If you use UNIX_TIMESTAMP() and FROM_UNIXTIME() to convert between TIMESTAMP values and Unix timestamp values, the conversion is lossy because the mapping is not one-to-one in both directions. For details, see the description of the UNIX_TIMESTAMP() function.

Introduction

The Open Graph protocol enables any web page to become a rich object in a social graph. For instance, this is used on Facebook to allow any web page to have the same functionality as any other object on Facebook.

While many different technologies and schemas exist and could be combined together, there isn’t a single technology which provides enough information to richly represent any web page within the social graph. The Open Graph protocol builds on these existing technologies and gives developers one thing to implement. Developer simplicity is a key goal of the Open Graph protocol which has informed many of the technical design decisions.


Basic Metadata

To turn your web pages into graph objects, you need to add basic metadata to your page. We’ve based the initial version of the protocol on RDFa which means that you’ll place additional <meta> tags in the <head> of your web page. The four required properties for every page are:

  • og:title – The title of your object as it should appear within the graph, e.g., “The Rock”.
  • og:type – The type of your object, e.g., “video.movie”. Depending on the type you specify, other properties may also be required.
  • og:image – An image URL which should represent your object within the graph.
  • og:url – The canonical URL of your object that will be used as its permanent ID in the graph, e.g., “http://www.imdb.com/title/tt0117500/”.

As an example, the following is the Open Graph protocol markup for The Rock on IMDB:

<html prefix="og: http://ogp.me/ns#">
<head>
<title>The Rock (1996)</title>
<meta property="og:title" content="The Rock" />
<meta property="og:type" content="video.movie" />
<meta property="og:url" content="http://www.imdb.com/title/tt0117500/" />
<meta property="og:image" content="http://ia.media-imdb.com/images/rock.jpg" />
...
</head>
...
</html>

Optional Metadata

The following properties are optional for any object and are generally recommended:

  • og:audio – A URL to an audio file to accompany this object.
  • og:description – A one to two sentence description of your object.
  • og:determiner – The word that appears before this object’s title in a sentence. An enum of (a, an, the, “”, auto). If auto is chosen, the consumer of your data should chose between “a” or “an”. Default is “” (blank).
  • og:locale – The locale these tags are marked up in. Of the format language_TERRITORY. Default is en_US.
  • og:locale:alternate – An array of other locales this page is available in.
  • og:site_name – If your object is part of a larger web site, the name which should be displayed for the overall site. e.g., “IMDb”.
  • og:video – A URL to a video file that complements this object.

For example (line-break solely for display purposes):

<meta property="og:audio" content="http://example.com/bond/theme.mp3" />
<meta property="og:description" 
  content="Sean Connery found fame and fortune as the
           suave, sophisticated British agent, James Bond." />
<meta property="og:determiner" content="the" />
<meta property="og:locale" content="en_GB" />
<meta property="og:locale:alternate" content="fr_FR" />
<meta property="og:locale:alternate" content="es_ES" />
<meta property="og:site_name" content="IMDb" />
<meta property="og:video" content="http://example.com/bond/trailer.swf" />

The RDF schema (in Turtle) can be found at ogp.me/ns.


Structured Properties

Some properties can have extra metadata attached to them. These are specified in the same way as other metadata with property and content, but the property will have extra :.

The og:image property has some optional structured properties:

  • og:image:url – Identical to og:image.
  • og:image:secure_url – An alternate url to use if the webpage requires HTTPS.
  • og:image:type – A MIME type for this image.
  • og:image:width – The number of pixels wide.
  • og:image:height – The number of pixels high.

A full image example:

<meta property="og:image" content="http://example.com/ogp.jpg" />
<meta property="og:image:secure_url" content="https://secure.example.com/ogp.jpg" />
<meta property="og:image:type" content="image/jpeg" />
<meta property="og:image:width" content="400" />
<meta property="og:image:height" content="300" />

The og:video tag has the identical tags as og:image. Here is an example:

<meta property="og:video" content="http://example.com/movie.swf" />
<meta property="og:video:secure_url" content="https://secure.example.com/movie.swf" />
<meta property="og:video:type" content="application/x-shockwave-flash" />
<meta property="og:video:width" content="400" />
<meta property="og:video:height" content="300" />

The og:audio tag only has the first 3 properties available (since size doesn’t make sense for sound):

<meta property="og:audio" content="http://example.com/sound.mp3" />
<meta property="og:audio:secure_url" content="https://secure.example.com/sound.mp3" />
<meta property="og:audio:type" content="audio/mpeg" />

Arrays

If a tag can have multiple values, just put multiple versions of the same <meta> tag on your page. The first tag (from top to bottom) is given preference during conflicts.

<meta property="og:image" content="http://example.com/rock.jpg" />
<meta property="og:image" content="http://example.com/rock2.jpg" />

Put structured properties after you declare their root tag. Whenever another root element is parsed, that structured property is considered to be done and another one is started.

For example:

<meta property="og:image" content="http://example.com/rock.jpg" />
<meta property="og:image:width" content="300" />
<meta property="og:image:height" content="300" />
<meta property="og:image" content="http://example.com/rock2.jpg" />
<meta property="og:image" content="http://example.com/rock3.jpg" />
<meta property="og:image:height" content="1000" />

means there are 3 images on this page, the first image is 300x300, the middle one has unspecified dimensions, and the last one is 1000px tall.


Object Types

In order for your object to be represented within the graph, you need to specify its type. This is done using the og:type property:

<meta property="og:type" content="website" />

When the community agrees on the schema for a type, it is added to the list of global types. All other objects in the type system are CURIEs of the form

<head prefix="my_namespace: http://example.com/ns#">
<meta property="og:type" content="my_namespace:my_type" />

The global types are grouped into verticals. Each vertical has its own namespace. The og:type values for a namespace are always prefixed with the namespace and then a period. This is to reduce confusion with user-defined namespaced types which always have colons in them.

Music

og:type values:

music.song

  • music:durationinteger >=1 – The song’s length in seconds.
  • music:albummusic.album array – The album this song is from.
  • music:album:discinteger >=1 – Which disc of the album this song is on.
  • music:album:trackinteger >=1 – Which track this song is.
  • music:musicianprofile array – The musician that made this song.

music.album

  • music:songmusic.song – The song on this album.
  • music:song:discinteger >=1 – The same as music:album:disc but in reverse.
  • music:song:trackinteger >=1 – The same as music:album:track but in reverse.
  • music:musicianprofile – The musician that made this song.
  • music:release_datedatetime – The date the album was released.

music.playlist

  • music:song – Identical to the ones on music.album
  • music:song:disc
  • music:song:track
  • music:creatorprofile – The creator of this playlist.

music.radio_station

  • music:creatorprofile – The creator of this station.

Video

og:type values:

video.movie

  • video:actorprofile array – Actors in the movie.
  • video:actor:rolestring – The role they played.
  • video:directorprofile array – Directors of the movie.
  • video:writerprofile array – Writers of the movie.
  • video:durationinteger >=1 – The movie’s length in seconds.
  • video:release_datedatetime – The date the movie was released.
  • video:tagstring array – Tag words associated with this movie.

video.episode

  • video:actor – Identical to video.movie
  • video:actor:role
  • video:director
  • video:writer
  • video:duration
  • video:release_date
  • video:tag
  • video:seriesvideo.tv_show – Which series this episode belongs to.

video.tv_show

A multi-episode TV show. The metadata is identical to video.movie.

video.other

A video that doesn’t belong in any other category. The metadata is identical to video.movie.

No Vertical

These are globally defined objects that just don’t fit into a vertical but yet are broadly used and agreed upon.

og:type values:

article – Namespace URI: http://ogp.me/ns/article#

  • article:published_timedatetime – When the article was first published.
  • article:modified_timedatetime – When the article was last changed.
  • article:expiration_timedatetime – When the article is out of date after.
  • article:authorprofile array – Writers of the article.
  • article:sectionstring – A high-level section name. E.g. Technology
  • article:tagstring array – Tag words associated with this article.

book – Namespace URI: http://ogp.me/ns/book#

  • book:authorprofile array – Who wrote this book.
  • book:isbnstring – The ISBN
  • book:release_datedatetime – The date the book was released.
  • book:tagstring array – Tag words associated with this book.

profile – Namespace URI: http://ogp.me/ns/profile#

  • profile:first_namestring – A name normally given to an individual by a parent or self-chosen.
  • profile:last_namestring – A name inherited from a family or marriage and by which the individual is commonly known.
  • profile:usernamestring – A short unique string to identify them.
  • profile:genderenum(male, female) – Their gender.

website – Namespace URI: http://ogp.me/ns/website#

No additional properties other than the basic ones. Any non-marked up webpage should be treated as og:type website.


Types

The following types are used when defining attributes in Open Graph protocol.

Type Description Literals Boolean A Boolean represents a true or false value true, false, 1, 0 DateTime A DateTime represents a temporal value composed of a date (year, month, day) and an optional time component (hours, minutes) ISO 8601 Enum A type consisting of bounded set of constant string values (enumeration members). A string value that is a member of the enumeration Float A 64-bit signed floating point number All literals that conform to the following formats:

1.234
-1.234
1.2e3
-1.2e3
7E-10
Integer A 32-bit signed integer. In many languages integers over 32-bits become floats, so we limit Open Graph protocol for easy multi-language use. All literals that conform to the following formats:

1234
-123
String A sequence of Unicode characters All literals composed of Unicode characters with no escape characters URLA sequence of Unicode characters that identify an Internet resource.All valid URLs that utilize the http:// or https:// protocols


Discussion and support

You can discuss the Open Graph Protocol in the Facebook group or on the developer mailing list. It is currently being consumed by Facebook (see their documentation), Google (see their documentation), and mixi. It is being published by IMDb, Microsoft, NHL, Posterous, Rotten Tomatoes, TIME, Yelp, and many many others.


Implementations

The open source community has developed a number of parsers and publishing tools. Let the Facebook group know if you’ve built something awesome too!