DBObject
From Platform Documentation
XOMBO.ORG Platform makes getting started as easy as possible. Control DBObjects are one of the most complex components to build on your own. Thankfully, templates are provided with XOMBO.ORG Platform to assist you in getting started quickly. You can also use the Object Builder scripts to create templates on-the-fly.
Spending a little time up-front planning your objects and how they will relate to each other will aid in designing them. Moreover, editing an existing object is made easy with XOMBO.ORG Platform since you don't have to write any of your own SQL.
File ./library/dbobject.class.php ★ SVN http://svn.xombo.org/svn/platform/current/trunk/library/dbobject.class.php API DOCS
Contents |
Creating the Table
Begin by creating a table in the database. The XOMBO.ORG Platform has certain expectations about how a table should be organized. Each table must have an auto_increment default index called “ID” of Integer type. When you reference a row of data from this table in another table, you must reference it by its ID. XOMBO.ORG Platform doesn't natively support associating tables together by any other field.
Let's consider an example while creating our first objects. Let's say we want to reference a table of breeds to a table of pets. In this simple scenario we would have a table called “breed” and a table called “pet”. Notice how we are encouraged to use the singular form when naming each table.
Table “breed” has these columns:
- `ID` Integer
- `Species` VARCHAR (100)
- `BreedName` VARCHAR (100)
Table “pet” has columns:
- `ID` Integer
- `Breed_ID` Integer
- `PetName` VARCHAR (100)
You can see how “pet” references “breed” with its column `Breed_ID`. Notice how the table reference column `Breed_ID` is also singular, just like the table's name. The “_ID” is the important part. When using joins with XOMBO.ORG Platform, this will become particularly handy. Proper capitalization is encouraged when naming your table columns because it will reflect the naming convention of your object variables.
The data type of the field is also of importance, as it determines how data is displayed, how forms are prepared, and whether or not to compress data when loading/savng.
Creating the DBOBject
Setup your DBObject to use the table you just created by opening the ./scripts/templates/control.template file. Rename the class to the name of your table with the extension .obj.php and place it in the root control directory. Our example table `breed` requires a DBObject called “Breed” and named /control/breed.obj.php.
File ./scripts/templates/control.template ★ SVN http://svn.xombo.org/svn/platform/current/trunk/scripts/templates/control.template API DOCS
Immediately below the class declaration, specify the columns in the table by adding public variables to the class (`ID` is included already for you).
Change $this->table in the __construct function to the name of the table (in our case, “breed”). Naming tables something other than the name of the object is not natively supported.
<?php
class Breed extends DBObject {
public $Species;
public $BreedName;
static $staticclass;
function __construct ($ID = NULL) {
$this->table = 'breed';
$this->ID = $ID;
parent::__construct();
}
function ... (truncated)
Repeat this process for the “Pet” object.
You now have two, fully functional control objects. The advantage is that you don't have to manually write your database queries or manually load/save data, it handles this for you.
Referential Integrity
If you have to maintain referential integrity, you can specify multiple tables in the __construct function. If we wanted to make the example more complex and introduce R.I., whenever a Breed is deleted, it should automatically delete it's associated Pets.
To do this, set $this->table to an array of strings i.e. array ('breed', 'pet') in the Breed DBObject. When you run the $Obj->delete () function (described later) it will automatically delete the main object data (breed) as well as any subsequently linked table entries (pet) referencing the object.
Note: the subsequent table(s) must reference the master table's ID. I.e. Pet must have a Breed_ID column. If the subsequent table(s) don't reference the first, the entries will not be deleted. Referential integrity works for two or more tables.
Linking Tables Automatically
Similar to referential integrity, linking tables is very easy. Unlike R.I., linking doesn't require that you have the first table's linking ID in the second. That will cause R.I. to occur whenever deleted. If you do not wish for R.I. deletion to occur automatically, you must change the associated records to a new reference prior to deleting the reference.
Simply add the second table to the object's $this->table array. Then, add public values to the object from the second table's columns. We're going to ammend our Pet object from before to import the BreedName automatically from the Breed table.
<?php
class Pet extends DBObject {
public $PetName;
public $Breed_ID;
public $BreedName;
static $staticclass;
function __construct ($ID = NULL) {
$this->table[] = 'pet';
$this->table[] = 'breed';
$this->ID = $ID;
parent::__construct();
}
function ... (truncated)
Creating new Instances
You can create a new instance of Breed in the database as follows:
$MyObj = new Breed (); // create a new instance of the Breed object $MyObj->Species = 'Canine'; // set Species $MyObj->BreedName = 'Greyhound'; // set BreedName unset ($MyObj); /* unloads the breed from memory and saves it to the database (this will happen automatically as the program ends if you don't explicitly do it) */
Loading Instances
You can load an instance of Breed from the database as follows:
$MyObj = new Breed (1); // load Breed instance #1 from the DB $MyObj->BreedName = 'Schnauzer'; // change the name unset ($MyObj); /* optional, unload & save */
Static Utility Functions
Since you're using a DBObject, it provides some basic utilities:
MyClass::table
string = MyClass::table ()
Returns a string of XHTML with a sortable table of data. You can pass additional variables to this function to achieve different effects. They will be detailed further in the Library documentation.
MyClass::populate
array = MyClass::populate ((array) $values, (string/array) $sortBy, (int) $limit, (int) $offset)
Returns an array of Breed objects. Pass $values as an associative array. For instance, I could limit myself to only show dog breeds with:
$Dogs = Breed::populate (array('Species' => 'Canine'));
if (is_array ($Dogs) && count ($Dogs)) foreach ($Dogs as $Dog) {
echo $Dog->BreedName . "\n";
}
Pass the column name to sort by as a string. You can limit the number of results to return with $limit and specify an offset to begin returning results with $offset.
You can also use advanced $values parameters. For each associative array pair, simply prepend the value with an ! to find instances which are not equal to the value. You can use < and > to perform numeric value comparison in a similar fashion.
For sorting, $sortBy can be an array. If you want to specify the field & direction, pass “ASC” or “DESC” as an array value.
Instance Functions
DBObject also has a few functions for dealing with instances:
$MyObj->editor
$MyObj->editor ((string) $callback, (array) $fields)
Specify the view action to run when the editor's save button is clicked with $callback. Specify which fields to include by passing an array of strings to $fields i.e. array ('Species','BreedName'). This will automatically create an editor form. If you don't specify any fields it will default to show all fields. You can show a field but prevent it from being editable by passing an ! in front of the field name i.e. array ('!Species','BreedName').
You can access data posted by an editor by using $this->GetRequest('Editor') within your View. It will return an associative array containing the values of the form.
$MyObj->inject
$MyObj->inject ((array) $values)
Pass an associative array as $values to have it assign them. This is most often used in conjunction with $MyBreed->editor in its $callback view function. You will see this more as you learn how to create views.
Note: inject requires that the data passed to it come from a form setup with the Form:: library. Failing to do so will result in a security violation notification to the user.
$MyObj->search
$MyObj->search ((array) $values)
You can selectively populate an empty instance from the database by searching for field values. For example, if I have a breed called “Schnauzer”, I could find it without knowing its ID by using search:
$MyObj = new Breed (); $MyObj->search (array ('BreedName' => 'Schnauzer'));
Like MyClass::populate , search can take advanced $values parameters. $MyObj->search can only return the first matching record. If you need to return multiple records, use MyClass::populate. You can test to see if a record was found by seeing if ($MyObj->ID > 0).
$MyObj->delete
$MyObj->delete ()
Delete the instance of the object from the database. This will maintain referential integrity if setup to do so.
Advanced DBObject Tactics
As a developer, you may wish to extend the objects you have created with your own functions. Choosing where to put those functions and how to implement them is an important part of maintaining a scalable system. This section will aid you in determining the method to use.
If your function manipulates several instances (rows) of data with only one DBObject, you should try to use a static public function in the Control DBObject you have created. If your function manipulates the local instance or uses $this statements, it must be a non-static public or protected function in the Control DBObject you have created.
If your function contains business logic which manipulates several different types of objects, it should probably be part of a View. This is a grey area and is left up to the developer. In the event that multiple views use the same function, a case may be made for creating a new Library.

