Home arrow PHP arrow Page 2 - PHP: Creating Single View Objects with the Composite View Design Pattern

Handling single view objects - PHP

In this third part of a series on the Composite View pattern, I develop a concrete class derived from the abstract parent built previously. This new class will be responsible for creating simple view objects.

TABLE OF CONTENTS:
  1. PHP: Creating Single View Objects with the Composite View Design Pattern
  2. Handling single view objects
By: Alejandro Gervasio
Rating: starstarstarstarstar / 2
August 24, 2010

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Be honest and ask yourself how many movies you've seen where a character said in a solemn tone: “the hardest part is over.” A lot, right? However, in this case the phrase is not extracted from a Hollywood script; the previous “View” class really does the hard work of handling single and multiple view objects via the same “render()” method. However, there is still a missing piece in this schema that needs to be created, to get the earlier hierarchy of classes up and running.

Yes, as you may have guessed, it’s necessary to derive yet another concrete class from the corresponding abstract parent that only handles single view objects and not composite ones. The following class, which has been called “Partial” does exactly that:

(Partial.php)


<?php

class Partial extends AbstractView
{
    // throw an exception as a partial view (leaf) cannot add another view
    public function addView(AbstractView $view)
    {
        throw new ViewException('A partial view cannot add another view.');  
    }
   
    // throw an exception as a partial view (leaf) cannot remove another view
    public function removeView(AbstractView $view)
    {
        throw new ViewException('A partial view cannot remove another view.');  
    }   
}// End Partial class

Trust me, I don’t want to sound like I’m bragging, but you’ll have to agree that the definition of the previous “Partial” class is ridiculously simple. It only throws a couple of custom exceptions within the inherited “addView()” and “removeView()” methods. The reason to implement these methods in that way is pretty obvious; the class only handles single view objects and therefore can’t remove or add others. Got this point? Great.

So far, so good. At this stage, the hierarchy of classes required to use the Composite View pattern in a useful fashion has been completed. It's time to list the classes all together, so you can have them at your disposal in one single place for editing purposes.

This will be done below, so keep reading.     

Showing all of the composite view classes defined previously

As I said above, I included the definitions corresponding to all the sample classes created so far below. This way, you can edit their source code and add your own improvements to them.

First, here’s the abstract parent that encapsulates the functionality and behavior of generic view objects:

(AbstractView.php)


<?php

abstract class AbstractView
{
    protected $_template = 'default.php';
    protected $_properties = array();

    // constructor
    public function __construct($template = '', array $data = array())
    {
        if ($template !== '') {
            $this->setTemplate($template);
        }
        if (!empty($data)) {
            foreach ($data as $name => $value) {
                $this->$name = $value;
            }
        }
    }
   
    // set a new view template
    public function setTemplate($template)
    {
        $template = $template . '.php';
        if (!file_exists($template)) {
            throw new ViewException('The specified view template does not exist.');  
        }
        $this->_template = $template;
    }
     
    // get the view template
    public function getTemplate()
    {
        return $this->_template;
    }
     
    // set a new property for the view
    public function __set($name, $value)
    {
        $this->_properties[$name] = $value;
    }

    // get the specified property from the view
    public function __get($name)
    {
        if (!isset($this->_properties[$name])) {
            throw new ViewException('The requested property is not valid for this view.');     
        }
        return $this->_properties[$name];
    }

    // remove the specified property from the view
    public function __unset($name)
    {
        if (isset($this->_properties[$name])) {
            unset($this->_properties[$name]);
        }
    }
   
    // add a new view (implemented by view subclasses)
    abstract public function addView(AbstractView $view);
   
    // remove a view (implemented by view subclasses)
    abstract public function removeView(AbstractView $view);
   
    // render the view template
    public function render()
    {
        if ($this->_template !== '') {
           extract($this->_properties);
           ob_start();
           include($this->_template);
           return ob_get_clean();
        }
    }
}// End AbstractView class

 

<?php

class ViewException extends Exception{}

Having shown the abstract parent, which is seated at the top of this hierarchy of composite view classes, it’s time to list the one that renders single and multiple view objects through the “render()” method discussed previously. Here it is:

(View.php)


<?php

class View extends AbstractView
{
    protected $_views = array();
       
    // factory method (chainable)
    public static function factory($view, array $data = array())
    {
        return new self($viewfile, $data);
    }
   
    // add a new view object
    public function addView(AbstractView $view)
    {
        if (!in_array($view, $this->_views, TRUE)) {
            $this->_views[] = $view; 
        }
        return $this;
    }
   
    // remove an existing view object
    public function removeView(AbstractView $view)
    {
        if (in_array($view, $this->_views, TRUE)) {
            $views = array();
            foreach ($this->_views as $_view) {
                if ($_view !== $view) {
                    $views[] = $_view;
                }
            }
            $this->_views = $views;
        }
        return $this;
    }
   
    // render each partial view (leaf) and optionally the composite view
    public function render()
    {
        $innerView = '';
        if (!empty($this->_views)) {
            foreach ($this->_views as $view) {
                $innerView .= $view->render();
            }
            $this->content = $innerView;
        }
        $compositeView = parent::render();   
        return !empty($compositeView) ? $compositeView : $innerView;
    }  
}// End View class

And finally, below you'll find the definition of the concrete “Partial” class, which is tasked with creating single view objects. Check it out:

(Partial.php)


<?php

class Partial extends AbstractView
{
    // throw an exception as a partial view (leaf) cannot add another view
    public function addView(AbstractView $view)
    {
        throw new ViewException('A partial view cannot add another view.');  
    }
   
    // throw an exception as a partial view (leaf) cannot remove another view
    public function removeView(AbstractView $view)
    {
        throw new ViewException('A partial view cannot remove another view.');  
    }   
}// End Partial class

Mission accomplished. Now that you have all of the composite view classes created in this series available in a single place, feel free to give them a try and see if they really can be used for building web pages by using partial sections and master layouts.

Anyway, if you feel intimidated and don’t know yet how to tackle this process with confidence, don’t feel concerned, since it’ll be covered in depth in the forthcoming tutorial.

Final thoughts

That’s all for now. In this third part of the series, I went through the development of a concrete class derived from the abstract parent built previously, which was charged with creating simple view objects. As you saw, this class isn’t capable of aggregating new objects or even removing existing ones, so the inherited “addView()” and “removeView()” methods simply throw a couple of exceptions when called by client code.

Having already created a hierarchy of composite view classes, the next step we must take is to put these classes into action. This way, you'll see how flexible they can really be when rendering (X)HTML templates. With that premise in mind, in the following article I’m going to set up a concrete example that will use all of the sample classes defined so far.

Here’s my final piece of advice: don’t miss the next part!



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: