Agile Data 1.2 is released

Almost a year have passed since release of Agile Data 1.1. For us the primary goal was improve the stability of Agile Data and focus on developing UI extensions. So what was added in the due course?


A new function has a special treatment in the model (just like init)

function validate() {
  if ($this['name'] != 'John') return ['name'=>'must be John'];
  return parent::validate();

Basically here you define all validation logic for your model. There are various details to this, for instance, you can define various validation intents, respond with multiple errors and even use Hook for supplementing model with additional validation, but the Validation support is now official in Agile Data.

Major changes

All database connections are now UTF8 by default. Previously it was left to the driver and your DSN definition, but we had too many problems with non-UTF databases.

The DSN now also supports the classic mysql://user:pass@host/db format, so you don't have to convert it. You should our one and only static method: Persistence::connect() and it will respond with appropriate persistence class based on your DSN schema:

$db = Persistence::connect('mysql://user:pass@host/db');

And finally, it's now easier to create and use arrays as persistences:

$data = [];
$data[1] = ['name'=>'John'];
$data[2] = ['name'=>'Peter'];

$m = new Model(new Persistence_Array($data));

echo $m->load(2)['name']; // Peter

Type Handling

We've cleaned up how we operate with types, always properly type-casting them. For example this code will always respect database timezone and time format configuration:

$report->addCondition('date_from', '>', new DateTime($dt));

We are now proud to be the only Database Management library in PHP which takes typecasting seriously.

CSV Import and Export

Now you can load model from database and export into CSV persistence generating a CSV file with headers and fields as you specify. The opposite is also true, you can import CSV file which would have fields in any order.

Caption and Required

We had "mandatory" property initially, but now we have also added "required" property along with "caption":

$this->addField('name', ['caption'=>'Full Name', 'required'=>true]);

The "mandatory" property was asking us to specify SOME value for the field, even if the value is 0 or "" or false. "required" property requires field to have non-empty value.

If checkbox have to be checked, use 'required'. Also 'required' presented on the form with an asterisk.

OR conditions

You can now define OR condition in your model:

  ['name', 'John'],
  ['surname', 'Smith']

You can still use the expression format if you want:

$user->addCondition($user->expr('([name] = []) or ([surname] = [])', ['John', 'Smith']));

Aggregate Efficiently

If your formula defines SUM(User.Requests.amount) and user has no requests, then sum will be 0 and not NULL.

Hooks support yielding

Hook have been cleaned up over time and now allow not only to execute code before actions but also prevent those actions. For instance in the beforeDelete hook you can decide if you want to skip actual delete action without raising exception. Also in beforeLoad you may decide to skip this record from displaying on the Grid.

Implemented user-defined references

hasOne and hasMany are cool, but now you can use addRef to define your own relation. You get to specify a callback which will return the model.

Serialization support

You can now store field value serialized. This way you can store arrays varchar values.

Support for ID-less models

Unfortunately you can't load records for the model that lacks ID field ($model->id_field = false) but you can iterate it. This is fully compatible with Agile UI Tables so you can output results of custom expressions and aggregates.

Reference property on field

When using hasOne to define a field, it will be linked with a reference, which makes it easy for UI to display dropdown with available values.