Location: PHPKode > scripts > FormClass > formclass/readme.txt
FormClass :

This class was developed from the scratch by  my ex-collegue R.L.Shiva prasad.I am releasing this version after making some enhancements.So for any changes u can contact me at hide@address.com or hide@address.com

FormClass is a phplib extension class for performing any form related functions. It automates the task of form submission as well as processing of all form submitted values.

Why do we need ‘Form Class’?

As we all know, forms are the most adequate and frequently used HTML element in all web-based projects. Any such web project uses forms as a primary source, to gather information from the user. However, such most often used form element often demands considerable amount of development time as each form processing routine is written and customized specifically for each and every single form. This is ideally not the best approach, especially when you have lots of forms to take care!.

The “FormClass” is targeted to automate this painfully simple task and let the developers concentrate on what they do best; code, code and code the business logic of the project. In addition, modifying the structure of the form content or causing any major changes to the forms itself or even to database at any point of time will not require any modification to the underlying code. Just edit a couple of lines and the FormClass will handle the changes for you. That’s the powerful feature and flexibility that FormClass provides.

FormClass originally written for handling registration forms in shipstaff.com, can however be used invariably as a generic form handler for several purposes in all projects (using php) without any/much modifications. Thereby by reusing the code we substantially reduce the time taken to develop and write applications than involves forms.

Ok, enuf said.. now lets get into the action. The normal sequence of operations in handling forms are as follows.

1. Display one or more number of forms one after the other as the user fills out and submits each of them.

2. Obtain the user submitted values and store them in your database.

The first operation is achieved quite easily. Just add a list of names of html files that contains the forms, into an array specified by FormClass. The FormClass will then use this array to display it to the user in the same order as it was created.

Processing the submitted values in each form, requires a little more work. We need to clearly define which value goes to which table and to which field in our database. We accomplish this task by specifying certain ‘rules’ that needs to be followed.
Form Rules:

As explained above, Rules are simple ways of specifying where in our database should we store the values in the forms. These rules can either be expressed as client side rules (ie within HTML files) or as server side rules within the php files. Though server side rules are more secure, the current implementation of form class supports only the client side rules. Thus this document will only deal on how to make use of it. Future versions of FormClass will include the support for server side rules.

On the positive side of it, the client side rules are much easier to write and doesn’t require you to edit any of server side files (php). In addition, some security methods provided by FormClass makes client side rules safely usable for normal purposes. So, that shouldn’t worry us for the time being. Let’s now meet the beast: FormClass

Consider, we have a simple form as shown below:

   <form action=forms.php method=post>

   Firstname : <input type=text name=&#8221;firstname&#8221; value=&#8221;&#8221;> <br>
   Lastname  : <input type=text name=&#8221;lastname&#8221; value=&#8221;&#8221;>  <br>
   Address     : <input type=text name=&#8221;address&#8221; value=&#8221;&#8221;> <br>

        <input type=submit name=submit value=submit>
   </form>

A quick glance will tell you that the above form displays three text fields to get the firstname, lastname and address. The form is submitted to a php file called &#8216;forms.php&#8217;. This file (forms.php) which we&#8217;ll later discuss in detail, will make use of our FormClass to handle form submissions. 

Also, we shall assume that when the form is submitted, we want to store these values into our table called &#8216;usermaster&#8217;, which has three fields namely &#8216;firstname&#8217;, &#8216;lastname&#8217;, and &#8216;address&#8217;. This is fairly straightforward and intentionally kept as simple as possible. The real power of FormClass comes only when you have a larger task at hand managing several forms in a website. For our purpose, this form will do a good job explaining the basics.

Just, before getting onto the details of forms.php, lets quickly get down to learn how to write &#8216;client side rules&#8217;. The client side rules are very simple and easy to learn. They are specified on the same file as we have our form.

A few important conventions and guidelines to be followed in writing a client side rules are explained in the next section. 
 Guidelines in writing Client Side Rules:

a) All client side rules are specified within &#8220;hidden input tags&#8221; (ie. <input> tag with type=&#8216;hidden&#8217;.) 

Each rule will give instruction on what table and fields have to be altered. If required, you can add more than one rule within the same form when more than one table has to be altered when the form is submitted. In that case, each rule should be specified in a different hidden input tag.

b) The name attribute of the hidden input tag should start with keyword &#8216;Table&#8217;. When more than one rule is to be given, a number is specified after the keyword &#8216;Table&#8217;  inorder to avoid name attribute conflicts.
        Eg. 
                     <input type=hidden name=&#8217;Table&#8217;     value = &#8220;&#8230;..&#8221;>  
                     <input type=hidden name=&#8217;Table2&#8217;     value = &#8220;&#8230;..&#8221;>

c) The value attribute in the hidden input tag is the rule definition, that defines the table name and the fields that are to be updated. It has the following format.

                    value = &#8220;<tablename>,<field 1>,<field 2>,<field 3>&#8230;<field n>&#8221;

    The first parameter is the name of the table to be updated, followed by the list of  fields/column names in the table separated by comma &#8216;,&#8217;. 

Let&#8217;s say the table that the values have to be inserted is &#8220;Usermaster&#8221;. The example form with client side rules will look like..

       <form action=forms.php method=post>

 Firstname : <input type=text name=&#8221;firstname&#8221; value=&#8221;&#8221;>
 Lastname  : <input type=text name=&#8221;lastname&#8221; value=&#8221;&#8221;>
 Address   : <input type=text name=&#8221;address&#8221; value=&#8221;&#8221;>

 <input type=hidden name=&#8221;Table&#8221; 
  value=&#8221;Usermaster,firstname,lastname,address&#8221;>
 
 <input type=submit name=submit value=submit>
 </form>
As you can see, we have named the form variables exactly the same as the column names in &#8216;Usermaster&#8217;. This is not just a mere coincidence but it is a necessity (see point (d) below). If form variables are different from column names in the table, it  will result in error.

d) &#8220;The field names specified in the rule (<field1>, <field2> etc..) must exactly match with the form variable names used in that form and with the corresponding  fields/column names in the table <tablename>&#8221;
In other words, the name of the columns in the table and the names of the form   variables used and the names specified in the rule all should be one and the same. 

Mismatch in names between the table fields and form variables will result in error. So, the conventions in naming the form elements are based upon column names in the table. Simply put, &#8216;Use the same column name as form variable name&#8217;.
 	
e) Adding Multiple rows:  
So far, we&#8217;ve only discussed using FormClass with forms that will insert exactly one row into a table. Sometimes we may arrive into a situation where we have to insert multiple rows into the same table from the same form. (note: don&#8217;t use two rules with same table names, that won&#8217;t work) 

In order to insert multiple rows, a small placeholder  in the value attribute next to <tablename> has to be specified.
	    
		 Eg.  value = &#8220;<tablename>#N,<field 1>,<field 2>,<field 3>&#8230;<field n>&#8221;
 
The #N is the place holder that was just mentioned. Its nothing but the number of rows that has to be inserted. If the number of rows is 3, then the complete rule in the form will be as follows,

<form action=forms.php method=post>
Firstname : <input type=text name=&#8221;firstname[]&#8221; value=&#8221;&#8221;> <br>
Lastname  : <input type=text name=&#8221;lastname[]&#8221; value=&#8221;&#8221;> <br>
Address   : <input type=text name=&#8221;address[]&#8221; value=&#8221;&#8221;> <br>

Firstname : <input type=text name=&#8221;firstname[]&#8221; value=&#8221;&#8221;> <br>
Lastname  : <input type=text name=&#8221;lastname[]&#8221; value=&#8221;&#8221;> <br>
Address   : <input type=text name=&#8221;address[]&#8221; value=&#8221;&#8221;> <br>

Firstname : <input type=text name=&#8221;firstname[]&#8221; value=&#8221;&#8221;> <br>
Lastname  : <input type=text name=&#8221;lastname[]&#8221; value=&#8221;&#8221;> <br>
Address   : <input type=text name=&#8221;address[]&#8221; value=&#8221;&#8221;> <br>

<input type=hidden name=&#8221;Table&#8221; 
  value=&#8221;Usermaster#3,firstname,lastname,address&#8221;>

<input type=submit name=submit value=submit>
     </form>

The above rule will exactly insert 3 rows in table Usermaster. Please note that the form variables have been changed to array type from firstname, lastname, address to firstname[ ],lastname[ ], address[ ]. This is required step.

f) Multiple Forms and Variables :

When you use more than one form, you can use the form variable value from any of the previous forms to add into the current table.

To illustrate this, lets consider you have two forms in two html files. In the first form you get the userid and password from the user, in the second form you get the list of names & email addresses of his friends to store in his addressbook. 

Now assume we have two database tables. Table &#8220;Auth_user&#8221; to store the userid and password, and table &#8220;addressbook&#8221; to store the list of names and emails of person&#8217;s contacts. Clearly, the address book table has three columns userid, name, email.

First form  :

<form action=forms.php method=post>

    Userid   : <input type=text name=&#8221;userid&#8221; value=&#8221;&#8221;>  <br>
       Password : <input type=text name=&#8221;password&#8221; value=&#8221;&#8221;><br>
    Confirm Password : <input type=text name=&#8221;confirmpasswsd&#8221;> 

 <input type=hidden name=&#8221;Table&#8221; 
value=&#8221;auth_user,userid,password&#8221;>

    <input type=submit name=submit value=submit>
</form>

Second form :
<form action=forms.php method=post>

   Name   : <input type=text name=&#8221;name[]&#8221; value=&#8221;&#8221;>  <br>
     Email   : <input type=text name=&#8221;email[]&#8221; value=&#8221;&#8221;> <br>

   Name   : <input type=text name=&#8221;name[]&#8221; value=&#8221;&#8221;>  <br>
     Email   : <input type=text name=&#8221;email[]&#8221; value=&#8221;&#8221;> <br>

   Name   : <input type=text name=&#8221;name[]&#8221; value=&#8221;&#8221;>  <br>
     Email   : <input type=text name=&#8221;email[]&#8221; value=&#8221;&#8221;> <br>

 <input type=hidden name=&#8221;Table&#8221; 
value=&#8221;addressbook#3,userid,name,email&#8221;>
    <input type=submit name=submit value=submit>

</form>

     Interestingly, this example illustrates a couple of points. First, from the second form 
we  can refer to the userid in the first form. This is perfectly valid because, the value of userid is already obtained from the previous form. 

Secondly, we have also declared the placeholder and declared the form variables as array type as we have three names/email pairs. Thus, 3 rows will be inserted when the form2 is submitted with the same userid obtained from the previous form.


Using FormClass (forms.php):

So far, we have covered the guidelines in writing client side rules. Using these guidelines the rules are specified. Next, we need to write a small script at server side that makes use of FormClass to handle form submissions and validate the client side rules. This is the form (forms.php) that all forms are submitted to in our previous examples.

We&#8217;ll first see the basic usage of FormClass.

              <?
	     1	/*   File : forms.php   */
               2
	     3	include &#8220;forms.inc&#8221;;
	     4 	$forms = new formclass();
               5
	     6	$forms->add(&#8220;myform1.html&#8221;, &#8220;registerform&#8221;);
	     7	$forms->show(&#8220;registerform&#8221;);
             ?>

On line 4, we instantiate an object of class formclass. This is the first step. We need to do this to make use of the FormClass in our program.

On line 6, we add an html file to our form list. This html file will contain the form that has to be displayed. We refer to this html file using a filehandle called &#8216;registerform&#8217;. More number of forms can be added by repeatedly calling the add()  method of formclass. All forms/filenames are maintained in an array which will be displayed in the same order that was added to the list.

To explicitly show a particular form, we use &#8220;show()&#8221; method call. Pass the filehandle as the parameter and the formclass will display it for you. Alternatively we can pass a number as parameter. The number will then be used to index the file list array. 

When we have more than one form, passing number as parameter will be easy. On each formsubmit we can increment a form counter and pass the form counter to show() function to display the next form.

Alternatively, we can pass the form counter as hidden form variable from the previous form so the increment need not be done on the php page.

We&#8217;ll now see the details of other FormClass functions and how to use them. For this purpose, I&#8217;ll be using the shipstaff.com registration forms as example. 

Here&#8217;s the code from shipstaff, forms.php file :

<?
    global $forms, $pageno, $id;

    if(!isset($pageno)) $pageno = 0;
    if(!isset($forms) || ($forms->get_form() != $id)) {
        initialize();
    }

    // get form values (if any) after form submit
    $forms->gethttpvars();

    // validate Form values with primary keys(for uniqueness).
    $errors = $forms->validate();
    if($errors)  printerrors($errors);

    $forms->show($pageno);

    if($forms->end()) finish();
?>

We will see below in detail what the above lines of code do. 

In shipstaff, registration forms are available for shipper, seafarer, and broker. With FormClass at hand, I decided to handle all of them from the same file. So I&#8217;ll have a single forms.php file and pass a variable &#8216;$id&#8217; in the query string to differentiate between the three registration modes.

When id=1, the seafarer registration forms are displayed. When id=2 shipper registration forms are displayed and when id=3 broker registration forms are displayed.

Now, the first step in using FormClass is as I said earlier to instantiate an object of the form class. This instantiation has to be done only once when the form is submitted for the first time. Since in all my forms the action attribute are set to &#8216;forms.php&#8217; the same php file will be called repeatedly for each form submission.

Hence, I&#8217;ll first write  a funtion called initialize() where I will put all instantiation and other initialization functions (which you&#8217;ll learn soon). This initialize() function is called only when the forms.php is called for the first time.

The code to perform this is ,

global $forms, $pageno, $id;

if(!isset($forms) || ($forms->get_form() != $id)) {
        initialize();
}

The above piece of code will first check if there exists already a &#8216;form&#8217; object, if there is no such object, the function initialize() is called. On otherhand, if there exists one such object, get_form() will return the id of the existing form, if its not the same as the current id then the initialize() function is called. The second check is additional check to prevent accidental skipping of initialize routine.

Next, if the form is not called for the first time, it means that a form has been submitted previously. Which implies we need to get the form variables posted by previous form. Otherwise all values submitted in previous form will be lost. Hence we call a method of FormClass called  gethttpvars(); 

// get form values (if any) after form submit
$forms->gethttpvars();  

After this line, the values posted in the previous form are stored internally in FormClass.

During initialization, we may specify to optionally check for uniqueness of the primary key fields. (for eg: when you get username from a form, you may want to verify, if that username is not already taken before proceeding to the next form). So we include a in-built validation routine provided by Form Class.

// validate Form values with primary keys(for uniqueness).
$errors = $forms->validate(); 
if($errors)  printerrors($errors);

Validate() function will validate for uniqueness of the specified fields against the tables specified in initialization and will return a set of error messages, if any. If there are some errors we write our own function to handle this error.


Once we&#8217;re done without any errors, we show the next form in the array. 

    $forms->show($pageno);

The pageno is obtained as hidden form variable from the previous form. This value will specify the number of the next form to be displayed. In our case the number will be 1 when the first form is submitted.

And finally before we end our script, we make a check to see if there are any more forms to display. 

    if($forms->end()) finish();

If we are in the last form and have reached the end of  form list then we write our own function to do some action on exit. (like updating the database/inserting the values into the database etc..). Otherwise the current form will be displayed and when the user submits the form the same routine explained above will be executed.

Thus we are now left with writing three custom functions.

  1) function initialize()  ? to instantiate formclass and to initialize other variables.
  2) function printerrors() ? to handle error which may occur after form submit.
  3) function finish() 	? function to handle the end action, when all forms are processed.

1) Function initialize() 

The first step in initialize function is to instantiate an object of form class.
$forms = new formclass();

      Next, we must  register the form object to be persistent until the registration is 
      complete.
 	      $sess->register("forms");

 Then we write some initializing functions like adding the html files etc.. for each registration mode. Here we will see the explanation for seafarer ($id=1) . The initialization procedure is very similar for the shipper and broker pages.

if($id == 1) {
    $forms->set_form(1);

    $forms->add("templates/register01a.tf");
    $forms->add("templates/register01b.tf");
    $forms->add("templates/register01c.tf");
    set_template_values();

 $forms->set_allowed_tables(array( 
 "sf_master","sf_exprofile","auth_user"));

    $forms->set_primary_keys(array("auth_user" => "username"));
    $forms->set_default_values(array(
                      "member_type" => "20",
                      "dateadded" => date("Y/m/d"),
                      "lastvisited" => date("Y/m/d"),
                      "perms" => "seafarer",
                      "user_id" => md5(uniqid("seafarer"))
                       ));
}


Set_form():

In the first few lines, we first set the form id (it&#8217;s the same as the registration mode). We set this to check them in the beginning of the page before the call to initialize().

Add() :

Next we add the form pages to the FormClass object using add() method. The pages containing the forms may either be html files or template files. (here we&#8217;re adding template files instead of html files) 

Set_tf_values() :

When template files are added, FormClass provides us a function to set template variables within the added form pages. These template values can be set in much advance during initialization itself, even before the actual form is processed. 

The FormClass function to set template variables is  set_tf_values(); (refer forms.php for details) These template variables are set in set_template_values() function.

Set_allowed_tables() :

Since client side rules can be altered by the end user, we need some security check to prevent any malicious user to tamper with our tables. So before the operation is performed we set the list of allowed tables that can be accessed. The table names specified in this list will alone be allowed.



Set_primary_keys() :

Inorder to prevent primary key conflicts in the database, we set the list of primary keys that must be validated when validate() function is called. The set_primary_keys() function takes tablename and primary key field in table as parameters. 

When a primary key is defined here, the FormClass&#8217;s Validate() function will return error when there is a primary key conflict. (eg: when username in table auth_user is defined as primary key, it will return an error when a username in auth_user table already exists)

Set_default_values() :

	Certain values to be inserted may not be available from the form. For example, 
the current system time , randomly server generated userid, date, permission level etc&#8230; These values can be set beforehand using the function set_default_values(). Pass an array of variable names and values to assign to it.
 
When the default values are specified here, we must specify the field in the client side rule inorder to get inserted into the table. 
   
2) Function printerrors()

Within the printerror function we write our own error handling routine. The list of errors are passed on as an array as a parameter to this function. We can display each of the error messages returned by traversing the array.

3) Function finish()

In the finish routine, the final steps are either inserting into the database or updating the database is performed. When finished, the form object is unregistered as its no longer used.

        $queryset = $forms->generate_insertion_queries();
        $forms->execute_queryset($queryset);
      
	generate_insertion_queries() :

As the name says, this function will generate queries to insert into the 
 database. Until this point no change is made to the database. The list of queries   
 are stored as array in $queryset.



	generate_updation_queries() :

As the name says, this function will generate queries to update into the database. For this funtion to work properly, the primary keys must  be defined using the set_primary_keys() function. The primary key defined will be used in &#8216;where&#8217; clause of the update query.

    Execute_queryset(): 

The generated queryset is passed on as a parameter to this function. Only when this function is called the actual query gets executed. 	
Return current item: FormClass