Home arrow PHP arrow Roll Your Own Repository in PHP: Data Mapper Finishing Touches

Roll Your Own Repository in PHP: Data Mapper Finishing Touches

In this fourth tutorial of the series, I added three methods to the data mapper class. They will be used for saving and deleting the table rows related to a specified entity. With this parent class fully implementing the methods declared by the “DataMapperInterface” interface, it will be easy to create a refined subclass that can specifically map user objects.

TABLE OF CONTENTS:
  1. Roll Your Own Repository in PHP: Data Mapper Finishing Touches
  2. Saving and deleting entity-related table records with additional methods
By: Alejandro Gervasio
Rating: starstarstarstarstar / 4
December 01, 2010

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

If you’re a PHP developer who is just starting out with Domain-driven Design (DDD) and want to learn in a step-by-step fashion how to build a repository from scratch, then look no further; you’ve come to the right place. In this set of tutorials, you’ll be guided through the development of a sample web application which will use the functionality provided by a basic repository to manipulate collections of user objects in a simple manner.

If you've read the previous installments, you're already familiar with the concepts that surround the implementation of the user repository. In those parts I progressively created the domain, data access and mapping layers of this example application, setting up the scenario for building the repository.

Well, to be frank the scenario isn’t completely set yet; the abstract mapper class that composes the application’s mapping layer still must implement some additional methods that permit us to insert, update and delete the table records associated with a specified entity. To address this issue and get this layer finally up and running, in this article I’m going to add to this class the extra methods just mentioned.

Want to see how this will be accomplished? Then begin reading now!

Building a basic mapping layer: a quick look at the previous data mapper

Since my plan here is to complete the definition of the data mapper class created in the previous part of the series, it’d be useful to take a brief look at this class in its current state. In consonance with this,  here’s the interface implemented by this generic mapper:

(DataMapperInterface.php)

<?php

interface DataMapperInterface
{
    public function findById($id);
   
    public function findAll();
   
    public function search($criteria);
   
    public function insert(EntityAbstract $entity);
   
    public function update(EntityAbstract $entity);
   
    public function delete($id);         
}

Definitely, the contract defined by the above “DataMapperInterface” interface is very easy to follow, right? So, move on and look at the source code of the mapper, which is an implementer of the pertinent interface:

(DataMapperAbstract.php)

<?php

abstract class DataMapperAbstract implements DataMapperInterface
{
    protected $_adapter;
    protected $_collection;
    protected $_entityClass;
    protected $_entityTable; 
        
    /**
     * Class constructor
     */
    public function __construct(MySQLAdapter $adapter, CollectionAbstract $collection, array $entityOptions = array())
    {
        $this->_adapter = $adapter;
        $this->_collection = $collection;
        if (isset($entityOptions['entityClass'])) {
            $this->setEntityClass($entityOptions['entityClass']);
        }
        if (isset($entityOptions['entityTable'])) {
            $this->setEntityTable($entityOptions['entityTable']);
        }
        $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 the mapper uses
     */
    public function getCollection()
    {
        return $this->_collection;
    }
   
    /**
     * Set the class for reconstructing entities
     */
    public function setEntityClass($entityClass)
    {
        if (!class_exists($entityClass, false)) {
            throw new DataMapperException('The specified entity class ' . $entityClass . ' does not exist.');
        }
        $this->_entityClass = $entityClass;
    }
   
    /**
     * Get the class for reconstructing entities
     */
    public function getEntityClass()
    {
        return $this->_entityClass;
    }
   
    /**
     * Set the entity database table the mapper works with
     */
    public function setEntityTable($entityTable)
    {
        if (!is_string($entityTable) || empty($entityTable)) {
            throw new DataMapperException('The specified entity table ' . $entityTable . ' is invalid.');
        }
        $this->_entityTable = $entityTable;
    }
   
    /**
     * Get the entity database table the mapper works with
     */
    public function getEntityTable()
    {
        return $this->_entityTable;
    }
   
    /**
     * Find an entity by its ID
     */
    public function findById($id)
    {
        $id = (int) $id;
        $this->_adapter->select($this->_entityTable, "id = $id");
        if ($data = $this->_adapter->fetch()) {
            return new $this->_entityClass($data);
        }
        return null;
    }
   
    /**
     * Find all the entities
     */
    public function findAll()
    {
        $this->_collection->clear();
        $this->_adapter->select($this->_entityTable);
        while ($data = $this->_adapter->fetch()) {
            $this->_collection->add($data['id'], new $this->_entityClass($data));   
        }
        return $this->_collection->count() !== 0 ?
               $this->_collection :
               null;
    }
   
    /**
     * Find all the entities that match the specified criteria
     */
    public function search($criteria)
    {
        $this->_collection->clear();
        $this->_adapter->select($this->_entityTable, $criteria);
        while ($data = $this->_adapter->fetch()) {
            $this->_collection->add($data['id'], new $this->_entityClass($data));   
        }
        return $this->_collection->count() !== 0 ?
               $this->_collection :
               null;
    }
}

 

(DataMapperException.php)

<?php

class DataMapperException extends Exception{}

As you can see from the above code fragment, the “DataMapperAbstract” class includes a set of finders that allow you to find entities by their ID or even retrieve all of them in one go. While this is effective, the class in its current state is still unfinished. It doesn’t implement all of the methods declared by the “DataMapperInterface” interface. Too bad.

To solve this issue, in the following section I’m going to add these methods to the mapper, thus providing it with the ability to save and delete the table rows associated with a given entity.

To learn how these additional methods will be defined, click on the link that appears below and keep reading.     



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