Developing a Form Director Class

Are you interested in expanding your knowledge of creational design patterns and learning how to work with director and builder objects in PHP 5? If your answer is yes, then I think you should start reading this article right now! Welcome to the concluding part of the series “How to Use Builder Objects in PHP 5.” This series leads you through the application of the builder pattern in PHP, and shows you how to use it with copious hands-on examples.

Introduction

When it comes to using creational patterns with PHP, undoubtedly the builder pattern is one of the most understandable, since the logic that stands behind its application is fairly easy to grasp. On the one hand you have a target object, which needs to be programmatically created, while on the other one you count on two objects, called “director” and “builder” respectively, that control the entire creation process.

In this situation, the director instructs the builder as to what pieces and parts should be included in the target object, a process that is usually performed by injecting the builder directly into the director’s constructor. Of course, this definition can be extended beyond this bunch of buzzwords, and used in the context of a real world application, which helps in understanding how this pattern works.

Keeping in mind this practical approach, during the previous article I showed you how to use a few form element objects, along with a form builder class, to create online forms. However, as you’ll possibly recall, the implementation of the builder pattern was rather incomplete because the respective form director class remained undefined, a fact that I plan to fix quickly over the course of this last tutorial.

As I expressed above, in this article I’ll complete the builder pattern, since I’ll demonstrate how to define and use a form director class, in this way putting the final strokes on the example that you learned in the previous tutorial.

With the preliminaries out of our way, let’s find out together how to create a form director class!

{mospagebreak title=Refreshing some core concepts}

Before I proceed to creating the mentioned form director class that completes the schema imposed by the builder pattern, it’s convenient to take a brief look at the classes that were defined in the previous article.

Doing so, you’ll have a fresh idea of how each of the components that implements the builder mechanism look. Keeping in mind this relevant concept, I’ll start by listing the first two classes involved into the creation process, that is the pair responsible for generating different form elements. The definitions for these classes are as follows:

 

// define abstract 'AbstractFormElement' class abstract class AbstractFormElement{ abstract function getHTML(); } // define concrete 'formElement' class class FormElement extends AbstractFormElement{ private $html=''; public function __construct($type='text',$attributes=array
('name'=>'default'),$options=array()){ // check for <input> elements if(preg_match("/^(text|radio|checkbox|password|hidden|submit|
reset|button|image|file)$/",$type)){ $openTag='<input type="'.$type.'" '; $closeChar='';           $closeTag='/>'; } // check for <textarea> and <select> element else if(preg_match("/^(textarea|select)$/",$type)){           $openTag='<'.$type.' '; $closeChar='>';          $closeTag='</'.$type.'>'; } else{ throw new Exception('Invalid form element type'); }         if(!is_array($attributes)||count($attributes)<1){ throw new Exception('Invalid number of attributes for
<'.type.'> element'); } // loop over element attribute        $elemAttributes='';         foreach($attributes as $attribute=>$value){ if(!$attribute||!$value){ throw new Exception('Invalid attribute or
value for <'.type.'> element'); }            $elemAttributes.=$attribute.'="'.$value.'" '; } // check for <select> option $selOptions='';         if(count($options)>0){           foreach($options as $value=>$text){             if(!$value||!$text){ throw new Exception('Invalid value or text
for <'.type.'> element'); }               $selOptions.='<option value="'.$value.'">'
.$text.'</option>'; } } // build form element(X)HTML output         $this->html.=$openTag.trim($elemAttributes).$closeChar.
$selOptions.$closeTag; } // return overall (X)HTML output public function getHTML(){< return $this->html; } }

 

As shown above, these two classes represent the target element being created by the corresponding builder. In simple terms, the above “FormElement” class is tasked with rendering the different components that are found in typical online forms, such as input boxes, radio buttons, text areas, and so forth.

Now, and getting rid for a moment of the handy features that come with the “FormElement” class, I need you to pay strong attention again to the definition of the builder pattern: it is two objects, the director and the builder respectively, that play a relevant role within the creation of a third object.

In this case, since the target element is represented by all the form element objects eventually instantiated from the corresponding class, it’s necessary to have at our disposal a builder class, which must be provided with the ability to create different form elements. At this moment, do you recall how all the objects that implement the builder pattern fit into the overall schema? I suppose you do.

To keep fresh in your mind the definition of the pertinent “FormBuilder” class that was created in the previous article, during the following section I’ll be taking a quick look at it. Therefore, if you need to recall how the aforementioned form builder class looked originally, please read the next few lines.

{mospagebreak title=The form builder class}

In order to get the schema imposed by the builder pattern nearer to completion, it’s convenient to recall quickly the signature of the respective “FormBuilder” class, along with its corresponding abstract parent.

Below I have listed the full source code that corresponds to these two classes:

// define abstract 'AbstractFormBuilder' class abstract class AbstractFormBuilder{ abstract function getForm(); } // define concrete 'FormBuilder' class class FormBuilder extends AbstractFormBuilder{ private $html=array(); private $action; private $method; public function __construct($action='',$method='post'){ // setup form attribute        $this->action=!$action?$_SERVER['PHP_SELF']:$action; $this->method=$method!='post'||$method!='get'?
'post':$method; } // add form element public function addElement($type='text',$attributes=array
('name'=>'default'),$options=array()){ if(!$elem=new FormElement($type,$attributes,$options)){ throw new Exception
('Failed to instantiate '.$type.' object'); }       $this->html[]=$elem->getHTML(); } // add form part public function addFormPart($formPart='<br />'){         $this->html[]=trim($formPart)==''?'<br />':$formPart; } // get web form public function getForm(){       $formOutput='<form action="'.
$this->action.'" method="'.$this->method.'">';        foreach($this->html as $html){          $formOutput.=$html; }         $formOutput.='</form>'; return $formOutput; } }

All right, now I firmly believe that the two classes listed above are fresh in your mind. If they aren’t yet, let me explain briefly how they fit into the builder pattern schema. As you’ll see, the prior “FormBuilder” class is tasked with generating the whole online form, in accordance with some input parameters passed to its constructor, such as the $method and $action variables.

In addition, the class also comes with the “addElement()” method, which is pretty handy for adding different form elements to the general structure. In this way it allows for the dynamic generation of regular online forms. Of course, the remaining class methods speak for themselves, therefore I’ll skip rapidly over them.

At this stage, and based on the set of classes that were listed earlier, the schema established by the pattern builder is very close to completion. After all, I have on one hand a “FormElement” class (in this case referenced as the target element) that obviously renders different form controls, while on the other hand there’s the form builder class that you saw before, responsible for using the mentioned form elements to create the complete online form.

So, the question that comes up now is, what’s the missing piece here? Obviously, the element that remains undefined is a form director class, which will instruct to the form builder on how the online form in question must be constructed. Indeed, that makes a lot of sense!

Regarding the definition of the corresponding form director class, in the upcoming section I’ll show you its complete signature. If you want to see how this brand new class looks, please keep reading.

{mospagebreak title=Defining a form director class}

Undoubtedly, when it comes to applying the builder pattern with PHP, the heart of the matter is the director class. After all, this one is the boss that instructs the builder on how to construct a given object.

In this case, since the builder in question is responsible for building online forms, logically the director must be represented by another class, capable of giving some specific instructions that are aimed at controlling the whole process for creating a web form.

Based on this simple principle, below I coded two new classes. The first one is the abstract form director, and the second one consists of the corresponding sub class that implements concretely all the required methods. Please, examine them:

// define abstract 'AbstractFormDirector' class abstract class AbstractFormDirector{ abstract function __construct(AbstractFormBuilder $formBuilder); abstract function buildForm(); abstract function getForm(); } // define concrete 'FormDirector' class class FormDirector extends AbstractFormDirector{ private $formBuilder=NULL; public function __construct(AbstractFormBuilder $formBuilder){ $this->formBuilder=$formBuilder; } public function buildForm(){        $this->formBuilder->addFormPart('<table>');      $this->formBuilder->addFormPart('<tr><td>First
Name</td><td>');       $this->formBuilder->addElement
('text',array('name'=>'fname'));        $this->formBuilder->addFormPart('</tr>');       $this->formBuilder->addFormPart('<tr><td>Last
Name</td><td>');         $this->formBuilder->addElement('text',array
('name'=>'lname'));        $this->formBuilder->addFormPart('</tr>'); $this->formBuilder->addFormPart
('<tr><td>Email</td><td>');        $this->formBuilder->addElement
('text',array('name'=>'email'));        $this->formBuilder->addFormPart('</tr>');        $this->formBuilder->addFormPart
('<tr><td>Comments</td><td>'); $this->formBuilder->addElement
('textarea',array('name'=>'comments','rows'=>'10','cols'=>'20'));         $this->formBuilder->addFormPart('</tr>');      $this->formBuilder->addFormPart
('<tr><td>&nbsp;</td><td>');         $this->formBuilder->addElement
('submit',array('name'=>'send','value'=>'Send Data'));        $this->formBuilder->addFormPart('</tr></table>'); } public function getForm(){ return $this->formBuilder->getForm(); } }

Indeed, this is the point where things get really exciting! Notice how the above “FormDirector” class first takes up the respective builder object via its constructor, and second indicates to it how the online form must be constructed. The “buildForm()” method reflects this process in a nutshell, since it shows how the different controls that comprise the web form are added during the complete creation procedure. Here you can see that being the boss has some advantages!

Now that you know how the long-awaited form director class looks, it’s time to see how all the previous classes work together for creating a simple contact form. Here is a simple script that implements the builder pattern and displays the referenced online form:

try{ // instantiate 'FormBuilder' object $formBuilder=new FormBuilder(); // instantiate 'FormDirector' object $formDirector=new FormDirector($formBuilder); // build web form    $formDirector->buildForm(); // display web form echo $formDirector->getForm(); } catch(Exception $e){ echo $e->displayMessage(); exit(); }

The script shown above demonstrates with a few lines of code how the builder pattern works. In this example, first a form builder object is instantiated and then it is passed to the respective form director, which uses its “buildForm()” method to build the sample contact form.

As you’ll realize, the entire process aimed at displaying the mentioned form has been simplified to working with only two objects in conjunction with a few method calls. After studying the prior snippet, you’ll agree with me that the builder pattern is actually useful!

Final thought

In this series, I went through the implementation of the builder pattern with PHP 5. During this set of three tutorials, hopefully you learned a few more things on pattern-based web programming, particularly in the terrain of creational patterns. Whether you’re starting to use design patterns with your web applications or you’re an experienced developer, I hope this series helped to expand your existing background in PHP.

See you in the next PHP tutorial!

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye