Class: Model

A class you can extend to create model objects in your application. Assumes table and class name are identical, but that the table is lowercase. Assumes primary key field is named 'id'. Both of these can be changed by specifying custom table and key properties. Note that this class doesn't impose field names. It provides an easy way to get at the usual query methods for a database table, but mainly to encapsulate your logic around that data.

Usage:

<?php

class MyTable extends Model {
    function get_all_by_x () {
        return MyTable::query ()
            ->order ('x desc')
            ->fetch ();
    }
}

$one = new MyTable (array (
    'id' => 123,
    'fieldname' => 'Some value'
));
$one->put ();

$two = MyTable::get (123);

$two->fieldname = 'Some other value';
$two->put ();

$res = MyTable::query ()
    ->where ('fieldname', 'Some other value')
    ->where ('id = 123')
    ->order ('fieldname asc')
    ->fetch (10, 5); // limit, offset

$res = MyTable::get_all_by_x ();

foreach ($res as $row) {
    $row->remove ();
}

?>

Also supports validation of values via:

<?php

class MyTable extends Model {
    var $verify = array (
        'email' => array (
            'email' => 1,
            'contains' => '@ourdomain.com'
        ),
        'name' => array (
            'not empty' => 1
        )
    );
}

?>

Or specified as an INI file:

<?php

class MyTable extends Model {
    var $verify = 'apps/myapp/forms/mytable.php';
}

?>

See Form::verify_values for more info on validation rules and file formats.

Properties

public static $batch_error = false

The error message from a batch() call if an error occurred, or false if there was no error.

public static $display_name

A display name for this class, for use in Elefant's version control, and in the admin/util/editbuttons helper.

public static $plural_name

A plural name for this class, for use in Elefant's version control.

private static $_prefetch = array ()

Cache store for prefetch_field.

public $table = ''

The database table to map to.

public $key = 'id'

The primary key field name.

public $keyval = false

The primary key value of the current object.

public $data = array ()

The properties of the current object are stored in this array.

public $fields = array ()

Settings about fields such as relations to other tables.

public $error = false

The error message if an error occurred, or false if there was no error.

public $is_new = false

Keeps track of whether the current object is new and needs to be inserted or updated on save.

public $query_type = 'select'

The type of query being built for the current query.

public $query_fields = '*'

Fields to return for the current query.

public $query_order = ''

The order by clause for the current query.

public $query_group = ''

The group by clause for the current query.

public $query_filters = array ()

A list of where clauses for the current query.

public $query_params = array ()

A list of parameter values for the current query.

public $query_having = array ()

A list of having clauses for the current query.

public $query_from = false

An alternate table listing for the current query.

public $verify = array ()

A list of validation rules to apply to ensure data is valid on save.

public $failed = array ()

A list of fields that failed validation on the last put() call.

Methods

public __construct ($vals = false, $is_new = true, $lock_level = 0)

If $vals is false, we're creating a new object from scratch. If it contains an array, it's a new object from an array. If $is_new is false, then the array is an existing field (mainly used internally by fetch()). If $vals contains a single value, the object is retrieved from the database. If $lock_level is set to MODEL_LOCK_EXCLUSIVE (1), it will add a FOR UPDATE exclusive lock on the selected row. If $lock_level is set to MODEL_LOCK_SHARED (2), it will add a FOR SHARE / LOCK IN SHARE MODE shared lock on the selected row.

public __call ($name, $arguments)

Custom caller to handle references to related models. Handles one-to-one and one-to-many relationships via dynamic methods based on the field names.

Arguments are all optional, and are as follows:

  • $reset_cache = false
  • $limit = false
  • $offset = 0

For example, to fetch the first 20 articles by author (these are made up models):

$articles = $author->articles (false, 20, 0);

public __get ($key)

Custom getter that uses $this->data array.

public __set ($key, $val)

Custom setter that saves to $this->data array.

public put ()

Save the object to the database. If $verify is set, it will validate the data against any rules in the array, or in the specified INI file if $verify is a string matching a file name.

public remove ($id = false)

Delete the specified or the current element if no id is specified.

public static get ($id)

Get a single object and update the current instance with that data.

public static query ($fields = false)

Begin a new query. Resets the internal state for a new query. Optionally you can pass the fields you want to return in the query, so you can optimize and not return them all.

public select ($fields = false)

Begin a new select query on the same object, resetting the internal query state in the process. Optionally you can pass the fields you want to return in the query, so you can optimize and not return them all.

public reset ()

Resets the query parameters for building a new query. Note that this is not necessary for most queries, since ::query() begins by creating a new instance and select() resets the query state automatically, however there may be cases where queries may be built dynamically and need resetting without beginning a new query yet.

public fields ($fields)

Specify a new field list for an SQL query. Overrides any values set in query() or select() and sets the value of $this->query_fields with a custom value.

public from ($from)

Specify an alternate from clause for an SQL query. Overrides using $this->table with a custom value.

public order ($by, $order = false)

Order the query by the specified clauses. Can be called multiple times to create complex sorting.

Usage:

->order ('field_name', 'asc') // preferred method ->order ('another_field asc') // alternate usage

public group ($group)

Group the query by the specific clauses. Can be called multiple times to group by multiple fields.

Usage:

->group ('field_name') ->group ('another_field')

public where ($key, $val)

Add a where condition to the query. Can be either a field/value combo, or if no value is present the first parameter can be one of the following:

  • A custom where clause, e.g., name like "%value%"
  • An associative array of clauses grouped by parentheses
  • A closure function that creates one or more grouped clauses

public where_in ($key, $vals)

Add a where key in(values) condition to the query from a list of values.

public and_where ($key, $val)

Creates an AND clause with additional where conditions. Accepts the same parameters as where().

public or_where ($key, $val)

Creates an OR clause with additional where conditions. Accepts the same parameters as where().

public where_search ($query, $fields, $exact = array ())

Searches a list of fields for the specified query using a LIKE '%query%' clause, resulting in a query of the form:

(field1 like '%query%' or field2 like '%query%')

Providing a list of exact fields, you can also add exact qualifiers using the form field:value or field:"Some Value", resulting in a query of the form:

field1 = "Some Value" and (field2 like '%query%' or field3 like '%query%')

Query examples:

Smith
Joe Smith
published:yes Joe Smith
author:"Joe Smith" Chemistry

These would become:

(field1 like '%Smith%' or field2 like '%Smith%')
(field1 like '%Joe Smith%' or field2 like '%Joe Smith%')
published = "yes" and (field1 like '%Joe Smith%' or field2 like '%Joe Smith%')
author = "Joe Smith" and (field1 like '%Chemistry%' or field2 like '%Chemistry%')

public having ($key, $val)

Add a having condition to the query. Can be either a field/value combo, or if no value is present the first parameter can be one of the following:

  • A custom having clause, e.g., name like "%value%"
  • An associative array of clauses grouped by parentheses
  • A closure function that creates one or more grouped clauses

public limit_offset_ok ($limit, $offset)

Verify that the limit is false or numeric, and that the offset is always numeric. Prevents SQL injection via these values.

public sql ($limit = false, $offset = 0)

Generates the SQL query used for execution. If the limit or offset values are invalid, it will return false. Otherwise, it returns the SQL string with ? for parameters to be filled with $this->query_params.

public fetch ($limit = false, $offset = 0)

Fetch as an array of model objects.

public single ()

Fetch a single result as a model object.

public count ($limit = false, $offset = 0)

Fetch the number of results for a query.

public fetch_orig ($limit = false, $offset = 0)

Fetch as an array of the original objects as returned from the database.

public fetch_assoc ($key, $value, $limit = false, $offset = 0)

Fetch as an associative array of the specified key/value fields.

public fetch_field ($value, $limit = false, $offset = 0)

Fetch as an array of the specified field name.

public delete ($limit = false, $offset = 0)

Turn a query into a deletion and execute it.

public orig ()

Return the original data as an object.

public static prefetch_field ($ids, $field)

Pre-fetch the values of a field for a given list of IDs, to reduce the number of database calls when using field() repeatedly.

public static field ($id, $field)

Return a single field's value for the object with the given ID. This is often useful for filters, for example:

{{ user_id|User::field (%s, 'name') }}

public static backticks ($item)

Add backticks to a name or list of names to prevent clashing with reserved words in SQL.

public static batch ($tasks)

Performs a batch of changes wrapped in a database transaction. The batch $task can be an array of items to insert at once, or a closure function that executes a series of tasks and performs whatever logic necessary. If any insert fails, or if the function returns false, the transaction will be rolled back, otherwise it will be committed. For databases that support it, records will be inserted using a single SQL insert statement for greater efficiency.

public next ($field = false)

Fetch the next incremental value for the specified field. If no field name is specified, it will use the primary key field by default.

public static table ()

Get the table name for this model.

public static key ()

Get the primary key field for this model.