Database layer class API

The classes automatically generated by the MidCOM Database abstraction layer can currently not be documented using PHPDoc (they are generated on-the-fly). The documentation here is considered to be as current as I can.

This document outlines the API of the automatically generated MidCOM Database classes. They are not yet covered by PHPDoc. It is recommended that you read the article Why do we need a DB abstraction for MidCOM first.

If you know your way through MidCOMs internals a bit, you can find the actual implementation documentation at the static methods of the midcom_baseclasses_core_dbobject class in the MidCOM API documentation.

Variables

All variables outlined here are for informational purposes only and are therefore to be considered read-only. All such variables have two underscores both prepended and appended to their name.

Class definition

The parameters of the class definition are stored in this variables and should be self-explanatory:

string $__table__;
string $__old_class_name__;
string $__new_class_name__;
string $__midcom_class_name__;

Class loader information


The class name and CVS revision of the MidCOM class loader which generated the intermediate class are stored in it as well:
string $__midcom_generator__;
string $__midcom_generator_version__;

Public API reference

This part is the API publicly available to the outside world. If you just want to use existing MgdSchema classes, you should be fine with them. Be aware that all these functions go through the MidCOM layer and their usage is mandatory. The legacy function outlined in the last part of this chapter are already deprecated and only there for transition purposes.

Although discouraged, you may override most of these functions but you should know what you're doing and never forget to call the base class function as well. Instead, use the Event Handlers provided by the framework to customize behavoir; see below.

Midgard object manipulation

These functions are used to mainpulate the object itself, not any sub-objects like parameters or attachments, they have their own sections below.

bool create();
bool delete();
bool update();

This triplet mostly matches the original Midgard/MgdSchema functions but calls a couple of event handlers for internal class usage (see below). They return true on success, false otherwise.

The behavoir of delete() has been changed a bit, it does now automatically remove all object extensions (parameters and attachments) prior to the actual deletion of the object itself.

create() has also changed, this is the main point of incompatibility: It does no longer return a mixture of boolean and integer values. It just returns the success state, not the new object id. If you need that, access $object->id after successful creation.

midcom_database_object get_parent();

This function is special and might be superseeded by MgdSchema on the long run. It must return the immediate parent of the object in the content tree. Obviously, this is very much context dependant. In case you do not have an immediate parent (for example for a root topic), you may return null.

One example: The old style Midgard Article's immediate parent can be of two different types. It is another article if and only if the article is a reply article and has its up field set to some other article instead of 0. If and only if it is no uplink article, the parent is its topic instead.

MidCOM is currently unable to implement this method automatically, therefore your actual base class derived from the intermediate class must override this if the object in question has a parent.

bool is_owner($person);

This is a temporary implementation of the owner write access checks. They are mapped to the various mgd_is_xxx_owner functions available. If there is no such function available, ownership is denied. This hack will be replaced with a MgdSchema solution as soon as one is available.

Parameter manipulation

This is my proposal to a next generation Parameter API. It provides explicit operations instead of one catch-all parameter function to make your code both more readable and more explicit.

bool delete_parameter(string $domain, string $name)
string get_parameter(string $domain, string $name)
Array list_parameters()
Array list_parameters(string $domain)
bool set_parameter(string $domain, string $name, string $value)

This API should be mostly self-explanatory, with two annotations:

The set_parameter call still contains the old magic functionality automatically unsetting parameters which have an empty value (to be precise: whose value evaluates to false). This has been kept for convenience and should be mostly transparent.

list_parameters returns an array with all parameters. This is either a simple accociative array for the version restricted to a domain:

Array
(
[lang] => en_US
[act] => view
[actloc] => tree
)

On the other hand, if you query all parameters, you'll have an Array of these arrays:

Array
(
[Asgard] => Array
(
[lang] => en_US
[act] => view
[actloc] => tree
)
[AsgardTreeHost] => Array
(
[selected] => host0
[sitegroup0_host0] => 1
[sitegroup1_host0] => 1
)
)

Attachment Manipulation

The same as for parameters goes here too: This is my coer API proposal. In addition the functions always deliver MidCOM framework types, simplifying things quite a bit.

The uniqueness of the attachment names per parent object is ensured by the code explicitly (at least unless the core supports this.)

midcom_baseclasses_database_attachment
create_attachment(string $name, string $title, string $mimetype);
bool delete_attachment($name);
midcom_baseclasses_database_attachment
get_attachment(string $name);
MidgardQueryBuilder get_attachment_qb();
Array list_attachments();
handle open_attachment($name, $mode = 'w')

Again, I believe these functions are mostly self-explanatory. Noteworthy is the function get_attachment_qb which gives you an already prepared query builder instance to list attachments you need for a specific location. You may execute this instance directly using $_MIDCOM->dbfactory->exec_query_builder().

Additonally, the get and create methods both return not the id of the attachment (not very useful) but the actual attachment object instead, so you can immediately open it for writing using the midcom_baseclasses_database_attachment::open() call.

Finally, list_attachments returns an array of midcom_baseclasses_database_attachment objects as if you would have executed a QueryBuilder obtained by get_attachment_qb unchanged.

Privilege Management Functions

This is, naturally, MidCOM only stuff. A quick tutorial can be found here.

Array get_privileges();
bool set_privilege(string $privilege, mixed $assignee, int $value);
bool unset_all_privileges();
bool unset_privilege(string $privilege, mixed $assignee);

These calls operate only on the privileges of the given object. They do not do any merging whatsoever, this is the job of the auth framework itself (midcom_services_auth).

Assingees are either a user instance (midcom_core_user), a group instance (a subclass of midcom_core_group) or one of the magic words EVERYONE, USERS, ANONYMOUS, a CLASS special array and SELF, where the last two are only valid for user and group records.

For usage of the CLASS special array, see the Introduction into the ACL structures.

Unsetting a privilege does not deny it, but clears the privilege specification on the current object and sets it to INHERIT internally. As you might have guessed, if you want to clear all privileges on a given object, call unset_all_privileges() on the DBA object in question.

Legacy Midgard API

The legacy functions provided by the current MgdSchema core are passed to the generated classes unmodified. There is no MidCOM level reimplementation or control over them at this time, and their usage in new projects is strongly discouraged.

As the needs arise the MidCOM DB classes will add some legacy method implementations of their own, but I'll not document all of those here, as they match the old Midgard API.

Event Handler Reference

Generally, there are two kinds of event handlers: Notifications (event handlers returning void) and Inquiries (event handlers returning bool).

You use notifications to react on successful events (for example after an object has been successfully created).

Inquiries, on the other hand, give you a degree of control over operations; if you return false, you indicate that the operation should be aborted for whatever reason you hopefully logged using the debug_* commands. Inquiries are always done before the actual operatiopn, so the _on_creating inquiry can be used to abort object creation if you return false.

Midgard object manipulation

void _on_created();
bool _on_creating();
void _on_deleted();
bool _on_deleting();
bool _on_loaded();
void _on_updated();
bool _on_updating();

Note, that there is no _on_loading event at this time. Tell me if you need it.

QueryBuilder operation

The operation of MidgardQueryBuiders on your classes can be controlled using these event handlers:

bool _on_prepare_exec_query_builder(MidgardQueryBuilder &$qb);
void _on_prepare_new_query_builder(MidgardQueryBuilder &$qb);
void _on_process_query_result(Array &$result);

All three event handlers operate on references to the data structures in question. They allow you to, for example, automatically add sorting constraints to the query or to filter resultsets for some arbitary reason not covered by the QB.

Private API

These functions are documented here for completeness, as they are of interest for framework developers and, in very rare cases, component authors as well.

You should never touch these functions unless you really know what you are doing.

Data I/O mappings for external access

To make the generated classes work more easily, three functions are there to call their base class equivalents:

bool __exec_create();
bool __exec_delete();
bool __exec_update();

For example, __exec_create calls parent::create().

Internal helpers

bool _load_from_database(mixed $id);

This is essentially the class constructor call, it initializes an empty class. You can either use a row-id, a GUID or another class instance of the same type (or subtype thereoff) as a basis for class initialization.