Home arrow PHP arrow Page 2 - Building a Unit of Work in PHP: Creating a Data Mapper and Handling Entities

Adding a collaborator to the UoW: defining a simple abstract data mapper - PHP

In this second tutorial of the series, I add to the previous UoW class a pair of collaborators that it needs to function properly. These are an abstract data mapper tasked with interacting with the persistence layer, and an additional abstract class responsible for modeling generic entities.

TABLE OF CONTENTS:
  1. Building a Unit of Work in PHP: Creating a Data Mapper and Handling Entities
  2. Adding a collaborator to the UoW: defining a simple abstract data mapper
By: Alejandro Gervasio
Rating: starstarstarstarstar / 3
December 27, 2010

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

To keep the entire sample code understandable and uncluttered, the implementation of the abstract data mapper injected into the internals of the previous UoW will be really short. In this case, it will act like a mediator between the persistence layer and the UoW itself, and will be capable of handling collections of entities as well.

With that said, here’s how this abstract data mapper looks. Check it out:

(DataMapperAbstract.php)

<?php

abstract class DataMapperAbstract
{
    protected $_adapter;
    protected $_collection;
        
    /**
     * Class constructor
     */
    public function __construct(DatabaseAdapterInterface $adapter, CollectionAbstract $collection)
    {
        $this->_adapter = $adapter;
        $this->_collection = $collection;
        $this->init();
    }
   
    /**
     * Initialize the data mapper here
     */
    public function init(){}
   
    /**
     * Get the instance of the database adapter
     */ 
    public function getAdapter()
    {
        return $this->_adapter;
    }
   
    /**
     * Get the collection
     */
    public function getCollection()
    {
        return $this->_collection;
    } 
}

As you can see above, the functionality encapsulated by the “DataMapperAbstract” class is rather limited. All it does is take two dependencies through its constructor, which are stored as protected properties. The first one is the database adapter, used to talk to the persistence layer, while the last one is an object tasked with handling collections of entities. As I've stated before, don’t be concerned about the definitions of these dependencies, since they’ll be shown in forthcoming parts of this series.

Of course, if you’re anything like me, you may be wondering why I didn’t make this abstract mapper a bit more functional, right? In fact I could have, but since my objective here is to build a sample web application that will use the previous UoW to synchronize and handle user entities, any form of refined functionality will be delegated to a concrete user mapper, rather than implemented within the abstract one.

All in all, now that you've grasped how this simple data mapper does its business, the next step is to create a class capable of modeling generic entities, so they can be properly manipulated by the UoW.
     
The definition of this whole new class will be shown below, so just keep reading.

Modeling generic entities: building an abstract entity class

As you may have realized, there are many approaches that can be taken to model generic entities. In this case, though, I will use an abstract class which acts like a simple proxy for the “__get()” and “__set()” PHP magic methods and permits you to assign, on the fly, a number of fields to an entity. I used a similar class in a series that I wrote previously (http://www.devshed.com/c/a/PHP/Roll-Your-Own-Repository-in-PHP-Building-the-Domain-Layer/1/), so feel free to skip over the following code sample if you’re already familiar with the topic.

Having clarified that, here’s the definition of this entity-modeling class:  

(EntityAbstract.php)

<?php

abstract class EntityAbstract
{
    protected $_values = array();
    protected $_allowedFields = array();
   
    /**
     * Class constructor
     */
    public function __construct(array $data = array())
    {
        foreach ($data as $name => $value) {
            $this->$name = $value;
        }
    }
   
    /**
     * Assign a value to the specified field via the corresponding mutator (if it exists);
     * otherwise, assign the value directly to the '$_values' protected array
     */
    public function __set($name, $value)
    {  
        if (!in_array($name, $this->_allowedFields)) {
            throw new EntityException('The field ' . $name . ' is not allowed for this entity.'); 
        }
        $mutator = 'set' . ucfirst($name);
        if (method_exists($this, $mutator) && is_callable(array($this, $mutator))) {
            $this->$mutator($value);          
        }
        else {
            $this->_values[$name] = $value;
        }   
    }
   
    /**
     * Get the value assigned to the specified field via the corresponding getter (if it exists);
    otherwise, get the value directly from the '$_values' protected array
     */
    public function __get($name)
    {
        if (!in_array($name, $this->_allowedFields)) {
            throw new EntityException('The field ' . $name . ' is not allowed for this entity.');   
        }
        $accessor = 'get' . ucfirst($name);
        if (method_exists($this, $accessor) && is_callable(array($this, $accessor))) {
            return $this->$accessor;   
        }
        return array_key_exists($name, $this->_values) ?
               $this->_values[$name] :
               null;
    }
   
    /**
     * Get an associative array with the values assigned to the fields of the entity
     */
    public function toArray()
    {
        return $this->_values;
    }             
}

 

(EntityException.php)

<?php

class EntityException extends Exception {}

As I just explained, the above “EntityAbstract” class takes advantage of property overloading to assign pairs of fields/values to a given entity. The assignment and retrieval processes can be performed either through the corresponding mutators and getters (if they have been implemented) or by direct manipulation of the protected $_values array. That was pretty easy to code and read, wasn’t it?

Although the creation of this class seems to be somewhat irrelevant, at least when it comes to demonstrating how to use the previous UoW, this is only a misconception, trust me. When I show you how to put all of these classes (and others that remain undefined) to work together, all of the pieces of this puzzle will fit nicely. In the interim, just be patient.  

Final thoughts

In this second tutorial of the series, I added to the previous UoW class a pair of collaborators that it needs to function properly, namely an abstract data mapper tasked with interacting with the persistence layer, and an additional abstract class responsible for modeling generic entities. Since similar implementations of these classes were shown and discussed in other articles published here at the Developer Shed network, you shouldn’t have major trouble understanding what they do.

And speaking of collaborators, you may have already noticed that the earlier mapper has its own collaborate, which turns out to be an instance of an abstract database adapter. Obviously, before you’ll see this sample Unit of Work in action, it’s necessary to define the adapter in question, right?

This is exactly the subject that I plan to cover in the next tutorial, so you don’t have any excuses to miss it! 



 
 
>>> 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: