Share » Learn » eZ Publish » The PersistentObject eZ Component:...

The PersistentObject eZ Component: Putting Relations Where Relations Belong

Tuesday 27 February 2007 12:12:00 am

  • Currently 3 out of 5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

We will see how to define, step by step, the persistent objects to reflect our database design and how to make use of them in the action classes.

As already mentioned, the person object is the central model of our application. There are three steps to take before you can make use of PersistentObject:

  1. Create the model class, which will be used in the application itself.
  2. Create a definition for the PersistentObject component to indicate in which way this model class reflects the database structure.
  3. Create an instance of ezcPersistentSession and configure it to make use of the model class and definition.

Step 1: Creating the first model

The PersistentObject component does not require you to inherit from a specific base class, nor to stick to a given naming scheme. The only requirement is to implement two methods in the object class:

getState()
This returns an array representing the current state of the object. The state is represented by the properties of the object; each property name is a key in the array, assigned to its corresponding value.

setState()
This is the corresponding method to set the state of an object. This method must accept the same format that getState() returns and must set the object properties accordingly.

Let's take a look at the model for the person object, which is called ezcappContactPerson:

<?php
 
class ezcappContactPerson
{
 
    public $id;
    public $firstname;
    public $lastname;
    public function getState()
    {
        return array( 
            "id"        => $this->id,
            "firstname" => $this->firstname,
            "lastname"  => $this->lastname,
        );
    }
    public function setState( array $state )
    {
        foreach ( $state as $propertyName => $propertyValue )
        {
            $this->$propertyName = $propertyValue;
        }
    }
 
}
 
?>

The class contains three public properties: $id, $firstname and $lastname, which reflect the fields of the person table in the database. (I'm quite sure that you would not want to have all of the fields to be public in a real application, but remember that this is just an example.)

The getState() and setState() methods perform the desired actions: getState() simply returns an array of all object properties and setState() sets the properties from a given array. You should note that our example implementation of setState() is a bit sloppy (for simplicity reasons) as it would also set non-existent properties.

Step 2: Telling PersistentObject about it

So far, so good. Now we need to tell PersistentObject that our new class ezcappContactPerson should reflect the database table person. PersistentObject is designed to understand different formats for storing information, but there is only one format manager available so far. ezcPersistentCodeManager can load a PHP data structure. Future versions of PersistentObject might include additional format managers that could, for example, load an XML structure. You could also write your own format managers.

ezcPersistentCodeManager requires us to provide a directory with PHP files that can be loaded when an action is requested on a certain persistent object. For this reason, the PHP files must be named after the class names, but in lowercase. The following definition is stored in a file called persistent/ezcappcontactperson.php:

<?php

$def = new ezcPersistentObjectDefinition();
$def->table = 'person';
$def->class = 'ezcappContactPerson';
 
$def->properties['firstname']               = new ezcPersistentObjectProperty();
$def->properties['firstname']->columnName   = 'firstname';
$def->properties['firstname']->propertyName = 'firstname';
$def->properties['firstname']->propertyType = ezcPersistentObjectProperty::PHP_TYPE_STRING;
 
$def->idProperty               = new ezcPersistentObjectIdProperty();
$def->idProperty->columnName   = 'id';
$def->idProperty->propertyName = 'id';
$def->idProperty->generator    = new ezcPersistentGeneratorDefinition( 'ezcPersistentSequenceGenerator' );
 
$def->properties['lastname']               = new ezcPersistentObjectProperty();
$def->properties['lastname']->columnName   = 'lastname';
$def->properties['lastname']->propertyName = 'lastname';
$def->properties['lastname']->propertyType = ezcPersistentObjectProperty::PHP_TYPE_STRING;
 
// ...
 
return $def;
?>

The discussion on defining relations is found later in this article.

First, a definition of a persistent object is created using an instance of ezcPersistentObject. You need to specify two essential things in the definition: the database table and the equivalent class name.

Next, we define the properties of our persistent object, which is done by defining an array called properties in the definition object. (Beware that the term "property" will be used quite often in different contexts.) This array has a key for every property of the persistent object. For example, the property ezcappContactPerson->firstname is defined in $def->properties['firstname']. We need to specify the corresponding column from the database, its datatype and the name of the property.

The ID property, which is commonly called the "primary key" in relational database terminology, is a special case. The ID property is used to uniquely identify a persistent object, in order to manipulate it. The ID property needs a definition object, because it needs a "generator" in addition to the usual information for a property. The generator takes care of creating a unique ID when a new persistent object is stored in the database for the first time. In our example, we are using ezcPersistentSequenceGenerator, which relies on the database to provide a new ID. For MySQL, this is auto_increment and for Oracle this is a sequence.

Finally, the definition we just created is returned from the file. I had a baffled look on my face when I first thought about this. Usually, the return statement is used at the end of a function, but in this case, our definition file is included elsewhere in the application. Therefore, it makes use of the return statement similar to a function. If you want to read more about this, see the PHP manual about include.

Step 3: Using what we have

To perform any kind of action on a persistent object, we need an instance of ezcPersistentSession, which in turn needs a database connection:

<?php
 
$db = ezcDbFactory::create( DSN );
ezcDbInstance::set( $db );
 
$session = new ezcPersistentSession(
    $db,
    new ezcPersistentCodeManager( dirname( __FILE__ ) . "/persistent" )
);
ezcPersistentSessionInstance::set( $session );
 
?>

The first two lines perform the database initialization and store the newly created database connection in a singleton-like mechanism (for more information, see the Database component). After that, we create the persistent session itself. It also needs to load the format manager, as discussed in step 2. Finally, we store the persistent session instance in a singleton container so that it can be accessed throughout our application.

36 542 Users on board!

Tutorial menu

Printable

Printer Friendly version of the full article on one page with plain styles

Author(s)