Create your own xPDO SimpleObject

Why? This might be your first question. With larger schemas, it might happen that some of your fields fill be in all (or in most) of your objects. Why not not specify them just in one place?

First step: Schema

Let's pretend we have a schema with just a two objects: MyBox and MyChest. In this case it doesn't matter what's their purpose, important thing is, that we want to store created, updated and deleted metadata (user who did it and time of action) for each object.

Let's say, they are defined by this schema:

<?xml version="1.0" encoding="UTF-8"?>
<model package="bxr" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" phpdoc-package="bxr">
    <object class="MyBox" table="my_boxes" extends="xPDOSimpleObject">
        <field key="description" dbtype="varchar" precision="255" phptype="string" null="false" default="" />
        <field key="size" dbtype="int" precision="10" phptype="integer" null="false" default="1" />
        <field key="created_by" dbtype="int" precision="10" phptype="integer" null="false" />
        <field key="created_on" dbtype="int" precision="20" phptype="timestamp" null="false" />
        <field key="updated_by" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
        <field key="updated_on" dbtype="int" precision="20" phptype="timestamp" null="false" default="0" />
        <field key="deleted_by" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
        <field key="deleted_on" dbtype="int" precision="20" phptype="timestamp" null="false" default="0" />
    </object>
    <object class="MyChest" table="my_chests" extends="xPDOSimpleObject">
        <field key="name" dbtype="varchar" precision="100" phptype="string" null="false" default="" />
        <field key="color" dbtype="varchar" precision="255" phptype="string" null="false" default="white" />
        <field key="created_by" dbtype="int" precision="10" phptype="integer" null="false" />
        <field key="created_on" dbtype="int" precision="20" phptype="timestamp" null="false" />
        <field key="updated_by" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
        <field key="updated_on" dbtype="int" precision="20" phptype="timestamp" null="false" default="0" />
        <field key="deleted_by" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
        <field key="deleted_on" dbtype="int" precision="20" phptype="timestamp" null="false" default="0" />
    </object>
</model>

As you can see, fields for those metadata are duplicate for both objects. If you ever will need to update them, you will have to do it in both objects, with larger number of objects, it might take a while and you are in a potential risk of an error (typo, forgetting to change the field in one object, etc.).

You might noticed that all of our objects are extending xPDOSimpleObject which automatically adds an ID field to your object (yes, the ID is not added by some black magic, but by the xPDOSimpleObject). So, we can create our own SimpleObject and extend it, instead of extending xPDOSimpleObject.

Let's create new object named MySimpleObject and extend our previously created object with it. We should get schema like this:

<?xml version="1.0" encoding="UTF-8"?>
<model package="bxr" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" phpdoc-package="bxr">
    <object class="MySimpleObject" extends="xPDOSimpleObject">
        <field key="created_by" dbtype="int" precision="10" phptype="integer" null="false" />
        <field key="created_on" dbtype="int" precision="20" phptype="timestamp" null="false" />
        <field key="updated_by" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
        <field key="updated_on" dbtype="int" precision="20" phptype="timestamp" null="false" default="0" />
        <field key="deleted_by" dbtype="int" precision="10" phptype="integer" null="false" default="0" />
        <field key="deleted_on" dbtype="int" precision="20" phptype="timestamp" null="false" default="0" />
    </object>
    <object class="MyBox" table="my_boxes" extends="MySimpleObject">
        <field key="description" dbtype="varchar" precision="255" phptype="string" null="false" default="" />
        <field key="size" dbtype="int" precision="10" phptype="integer" null="false" default="1" />
    </object>
    <object class="MyChest" table="my_chests" extends="MySimpleObject">
        <field key="name" dbtype="varchar" precision="100" phptype="string" null="false" default="" />
        <field key="color" dbtype="varchar" precision="255" phptype="string" null="false" default="white" />
    </object>
</model>

Let's run build.schema.php to generate mapping and object classes.

Second step: PHP

After running the build.schema script, you should have three new files under your model/package_name directory: mysimpleobject.class.php, mybox.class.php and mychest.class.php

Update each file (except mysimpleobject.class.php) and add following line, before class definition:

require_once 'mysimpleobject.class.php';

And as a last thing, you will need to update your service class and add following line into your _construct method, right after addPackage call. (This also has to be added to build script and if you are using snippet to create your DB tables, than add it there as well. If you are using GPM, you can follow this guide to create DB: GPM config for database)

$this->modx->loadClass('MySimpleObject');

That's it!

Post By John Peca MODX