Model

Every data model must inherit from this abstract class directly or indirectly. A class will only be respected as a model if it has a constructor which calls this class's constructor and passes the first argument to it "Model" as:
 public function __construct($params=Null) {
     parent::__construct('ModelGroupName', $params);
 }

The first argument is reserved for model's internal uses.
A model object is a special object, any public property which is not starting and ending with '__' is considered as a data property which define model's data attributes and lets data to be stored and queried. There are modifier properties which are left public on purpose, this properties always start and end with '__' e.g. "__key__". This properties reduce the model object's encapsulation at a limited level to expose hooks and hacks for model plugins. It is recommended to use methods for further exposures, but you may add this type of properties with trailing and leading '__' for your own uses.
Source
Model.php
Implements
IModel , Iterator
Depends on
IDbAbstract , Paging , Arta , Database , Localization , IModel , Binder , MakeReadable , T

Constants

N = 'null'

When a model data property is set to null then the property value is ignored by "add", "update", "delete" and "query" methods. To force this methods use a null valued property set it to "Model::N".

See also
http://artaengin.com
Since
Artaengine 1.2.5

NN = 'not

When querying data set a property to "Model::NN" so that null values for that property would not be included in the data set.

OBJECT = 2

To address model's Model object data properties to filter an action based on the data property type.

OBJECT_LIST = 3

To address model's Model object list data properties to filter an action based on the data property type.

QUERY_DELETED = '_deleted'

When "Model::QUERY_deleted" is passed to method "query" only the data marked as deleted will be queried.

QUERY_FULL = '_full'

When "Model::QUERY_FULL" is passed to method "query" the data for all model's properties at any level will be queried.

QUERY_L1 = '_1'

When "Model::QUERY_L1" is passed to method "query" only the data for model's scalar properties and Model object properties will be queried.

QUERY_SELF = ''

When "Model::QUERY_SELF" is passed to method "query" only the data for model's scalar properties and the key property of Model object properties will be queried.

SCALAR = 1

To address model's scalar data properties to filter an action based on the data property type.

Static Properties

__instance__

Model::$__instance__

Only used internally by the framework - unique model instance count.

__langwhere__

Model::$__langwhere__

Only used internally by the framework - cached SQL for i18n properties.

__mdic__ = array

Model::$__mdic__ = array()

Only used internally by the framework - maps app model classes to a uid {model-class-name: model-id,}

__optimize__ = 1

Model::$__optimize__ = 1

Only used internally by the framework - model optimizing level. Optimization is mainly done by creating a more compact and optimal class(cache) for each model class, this classes are placed in the temp and used under the hood. 0 = use the optimized models, 1 = use the original models, 2 = create optimized models but use the original models.

modelDbo

Model::$modelDbo

Database object name of model groups.

Properties

__dbo__

$obj->__dbo__

Database access.

__def__

$obj->__def__

Dictionary of the model's data property definitions. This provides a way for utilities and plugins to get a hook to info about model's data properties, and tweak them. Use method "def()" to get this info.

__delete__ = true

$obj->__delete__ = true

false=Model.delete() will not physically remove the data cols from the database but will mark them as deleted and the data will be hidden for queries.

__fk__

$obj->__fk__

Read-only - model key as foreign key in queries at database level.

__group__

$obj->__group__

Read-only - model group name.

__ignoreObjectLists__ = false

$obj->__ignoreObjectLists__ = false

true=methods and utilities must ignore model properties which are object lists.

__ignoreObjects__ = false

$obj->__ignoreObjects__ = false

true=methods and utilities must ignore model properties which are objects.

__key__

$obj->__key__

Read-only - key property name - all models must have a key property with unique values which is used as model table primary key at database level.

__locale__

$obj->__locale__

Model's current set locale(s) e.g. This will be used for querying i18n properties by default it is set to user's selected LOCALE. To change use the "setLocale()" method instead of setting this property, this property is left public for utilities and plugins.

__nulls__

$obj->__nulls__

A list of property names. When updating model data, the properties set to null will be ignored however to update property values to null you can either set the property value to "Model::NULL" or add the property name to this array.

__operator__ = 'AND'

$obj->__operator__ = 'AND'

Operator to be used between (property=value)s when querying data.

__page__

$obj->__page__

Instance of class Paging. If "slice()" is called when querying model data a Paging instance will be available through this property which is set to the appropriate values (based on model's query) ad can be used to render the paging links.

__present__

$obj->__present__

Read-only - The property(properties) that present a model when. e.g. when model data are shown in a widget the data of this property(properties) are displayed. To explicitly identify one or more properties set "present" to true in their definition otherwise a property will be selected automatically: if a property exists with this names: "name", "description" or "title" otherwise model's key property will be selected.

__pureSql__ = false

$obj->__pureSql__ = false

true=assign pure database SQL conditions to "where()".

__readable__ = false

$obj->__readable__ = false

To make all model property values human readable after querying data set this to true. This must only be used to ease displaying model data and no action should be done on such data. e.g. keys are replaced by their values...

See also
Readable

__rows__

$obj->__rows__

After querying model data this will be set to a list of data rows.

__table__

$obj->__table__

Database table which is used to store model data.

__where__

$obj->__where__

Exposes the SQL WHERE clause set by the model, public=to make it tweak-able.

Array
[SQL-WHERE-str, {WHERE-params}]

Static Methods

getDbIndex

string Model::getDbIndex(string group, string model)

Get a model's index used in the database views. Each model name is mapped to an index, this index is used instead of table name in the db views.

Arguments

    group (string)
    Model group name
    model (string)
    Model name

Returns

string
The model index used in views

midware

mixed Model::midware(mixed value, array def, int type=0)

A midware can be set or each data property (setting "midware-classname" to the "midware" key in the property's definitions). A midware class may contain static methods "afterNext", "beforeStore" and "beforeQuery", when the event happens on the property the appropriate midware method (if exists) will be called passing property-value and using the returned value instead. This method is used internally to check for a midware, pass and get the values however it is left public to be freely used.

Since
Artaengine 1.2.0

Arguments

    value (mixed)
    Property value to be passed to the midware method
    def (array)
    Property definition
    type=0 (int)
    Mid-ware method to be called, 0=afterNext() 1=beforeStore() 2=beforeQuery()

Returns

mixed
The value returned by the midware

Methods

__construct

Model $obj = new Model(string group=null, array params=null)

Each model class must call this in it's constructor as "parent::__construct(model-group, $params);". The model's constructor must have an argument "$params" and pass it here.

Arguments

    group=null (string)
    Model group name
    params=null (array)
    Reserved for internal use

Returns

void

add

IModel $obj->add(bool exists=false)

Add model's data. Requires "commit()" to take effect on the database.

Arguments

    exists=false (bool)
    true=do not insert data if data exists

Returns

IModel
For method chaining

afterAdd

void $obj->afterAdd(bool $success, array $data)

After add event handler. This is an optional method (not included in the IModel) that can be added to a model class. If a model has this method, after model data has been added to the database and committed(successful or unsuccessful) this method will be called.

Arguments

    $success (bool)
    true=data successfully added to the database
    $data (array)
    Model property data before the action: {property: data,}

Returns

void

afterNext

void $obj->afterNext()

After next event handler. This is an optional method (not included in the IModel) that can be added to a model class. If a model has this method, after fetching a row of queried data into model's properties using this method will be called. This method can for example format and update certain property values.

Returns

void

afterQuery

void $obj->afterQuery()

After query event handler. This is an optional method (not included in the IModel) that can be added to a model class. If a model has this method, after querying model's data from the database using "query()" this method will be called.

Returns

void

afterUpdate

void $obj->afterUpdate(bool $success, array $data)

After delete event handler. This is an optional method (not included in the IModel) that can be added to a model class. If a model has this method, after model data has been deleted from the database and committed(successful or unsuccessful) this method will be called.

Arguments

    $success (bool)
    true=data successfully deleted from the database
    $data (array)
    Model property data before the action: {property: data,}

Returns

void

beforeAdd

bool $obj->beforeAdd()

Before add event handler. This is an optional method (not included in the IModel) that can be added to a model class. If a model has this method, before adding model's data to the database using "add()" this method will be called, this method can for example change or validate model's data and let the adding to proceed or be canceled.

Returns

bool
true=proceed adding, false=cancel adding

beforeDelete

bool|array $obj->beforeDelete()

Before delete event handler. This is an optional method (not included in the IModel) that can be added to a model class. If a model has this method, before deleting model's data from the database using "delete()" this method will be called, this method can for example change or validate model's data and let the deleting to proceed or be canceled. If a model is configured for logical deleting only ("public $__delete__ = false;") then "delete()" will only mark rows as deleted, "beforeDelete()" makes it possible to update other columns in the database while deleting if it returns an array of property names and their new values.

Returns

bool|array
true=proceed update, false=cancel update, array={property: new-val,}

beforeQuery

void $obj->beforeQuery()

Before query event handler. This is an optional method (not included in the IModel) that can be added to a model class. If a model has this method, before querying model's data from the database using "query()" this method will be called. This method can for example change conditions, property values etc.

Returns

void

beforeUpdate

bool $obj->beforeUpdate()

Before update event handler. This is an optional method (not included in the IModel) that can be added to a model class. If a model has this method, before updating model's data in the database using "update()" this method will be called, this method can for example change or validate model's data and let the adding to proceed or be canceled.

Returns

bool
true=proceed update, false=cancel update

between

IModel $obj->between(int from=1, int to=10)

Limit query result between two rows including the rows themselves. e.g. "$model->between(5, 10)->query();"

Arguments

    from=1 (int)
    From row number (first row = 0)
    to=10 (int)
    To row number (first row = 0)

Returns

IModel
For method chaining

cancel

IModel $obj->cancel()

Cancel all uncommitted add/update/delete.

Returns

IModel
For method chaining

commit

bool $obj->commit(bool transaction=true)

Commit model data manipulations to the database. Actions add/update/delete are performed on the database only after calling this method.

Arguments

    transaction=true (bool)
    true=execute the SQLs in a database transaction, false=execute SQLs outside a transaction

Returns

bool
State of success

Throws

count

int $obj->count()

Number of queried data rows.

Returns

int
Number of rows

current

IModel $obj->current()

Iterator - current.

Returns

IModel
For method chaining

delete

IModel $obj->delete(string conditions=null, array | [mixed] conditionParams=null)

Delete model data. If model has dependencies, dependencies will be removed too. Requires "commit()" to take effect on the database. To delete data you have to either set model's key(pk) to a value that would mean "DELETE ... WHERE key=value" or pass conditions to this method manually.

Arguments

    conditions=null (string)
    The condition string.
    Conditions params may be used inside the string:
    
    Params from a list:
    "id = $1 AND (name = $2 OR name IN ($3))"
    
    Params from a dictionary:
    "id = $id AND (name = $name OR name IN ($names))"
    
    To address properties of IModel properties at any level.
    e.g. if Group and Permission are IModel classes:
    "Group.Permission.id = 5"
    
    conditionParams=null (array | [mixed])
    Condition params {param: val,} | [val,] | val1, val2,...
    When params are used inside the condition string, values for the params can be
    passed to this method as shown below. Values will be sanitized before being
    inserted into the condition string.
    
    List, passed as individual method arguments:
    5, 'Ronnie', ['James', 'Dio',]
    
    Dictionary, passed as one array argument:
    {'id': 5, 'name': 'Ronnie', 'names': ['James', 'Dio',],}
    

Returns

IModel
For method chaining

extendWhere

IModel $obj->extendWhere(
    string conditions=null,
    array | [mixed] conditionParams=null
)

Add conditions for querying data. Adds to previously set conditions.

Arguments

    conditions=null (string)
    The condition string.
    Conditions params may be used inside the string:
    
    Params from a list:
    "id = $1 AND (name = $2 OR name IN ($3))"
    
    Params from a dictionary:
    "id = $id AND (name = $name OR name IN ($names))"
    
    To address properties of IModel properties at any level.
    e.g. if Group and Permission are IModel classes:
    "Group.Permission.id = 5"
    
    conditionParams=null (array | [mixed])
    Condition params {param: val,} | [val,] | val1, val2,...
    When params are used inside the condition string, values for the params can be
    passed to this method as shown below. Values will be sanitized before being
    inserted into the condition string.
    
    List, passed as individual method arguments:
    5, 'Ronnie', ['James', 'Dio',]
    
    Dictionary, passed as one array argument:
    {'id': 5, 'name': 'Ronnie', 'names': ['James', 'Dio',],}
    

Returns

IModel
For method chaining

getLabel

string $obj->getLabel(string pm)

Get the appropriate label for a data-property, method or object-path relative to the current model instance. Always use this method to get a label instead of going other ways. This method traverses the object-path and returns the first label found for it. Object-path e.g. "User.Group.name.".

Since
Artaengine 1.2.2

Arguments

    pm (string)
    Model property-name, method-name or object-path to get label for

Returns

string
The label

groupBy

IModel $obj->groupBy(array cols)

Experimental, to hack a GROUP BY statement into model's query.

Arguments

    cols (array)
    GROUP BY column list

Returns

IModel
For method chaining

has

IModel $obj->has(
    string keyword,
    bool equals=false,
    const | array type=null,
    string op=OR
)

Search for a keyword inside all scalar properties. Adds a condition to the current query for searching a keyword against all scalar properties. e.g. "$model->has("keyword")->query();"

Arguments

    keyword (string)
    The keyword to be searched for
    equals=false (bool)
    false=use "LIKE" operator true=use "=" operator
    type=null (const | array)
    To restrict to properties with a specific data type e.g. T::STRING or [T::STRING, T::EMAIL]
    op=OR (string)
    Search operator, "OR"=filter any row with a property match "AND"=filter rows with all properties matching

Returns

IModel
For method chaining

ignore

IModel $obj->ignore(const item=null)

Ignore fetching model object property data after a query. If you don't use data properties which are objects or lists then ignoring them may improve performance.

Arguments

    item=null (const)
    Property types to ignore: can be "Model::OBJECT" or "Model::OBJECT_LIST" or "Model::OBJECT+Model::OBJECT_LIST" or null=undo ignore

Returns

IModel
For method chaining

isnull

bool $obj->isnull(string property)

Check if a model property value is null or not. Returns true if property is set to "Model::N".

Arguments

    property (string)
    Model property name

Returns

bool
true=is null or not

join

IModel $obj->join(string sql)

Experimental, to inject JOINs to model's query. Sometimes joins are more efficient than conditions.

Arguments

    sql (string)
    Joins

Returns

IModel
For method chaining

key

int $obj->key()

Iterator - key.

Returns

int
Row number

keyVal

mixed|array $obj->keyVal(bool newKey=true)

Get the value of model's key property and set the value to the property.
if model's key property is already set to a value return it.
if model's key property is serial(auto inc) and newKey=true return the last inserted value
query the model based on set property values and set conditions and return the key values(s)

Arguments

    newKey=true (bool)
    true=if key type is SERIAL return the last inserted key value

Returns

mixed|array
Value or an array of values (if a query is done and result has more than one rows)

limit

IModel $obj->limit(int limit=10, int $offset=0)

Limit query result the same way as SQL LIMIT OFFSET. e.g. "$model->limit(20, 21)->query();"

Arguments

    limit=10 (int)
    Max number of rows to query
    $offset=0 (int)
    Row offset to start from (first row = 0)

Returns

IModel
For method chaining

next

bool $obj->next(int i=null)

Fill the current row of the queried data into model's properties and move to next row.

Arguments

    i=null (int)
    Fill model with the i'th row data, null=current row

Returns

bool
true=next row exists

present

array|string $obj->present(string sep=null)

Get the data of model's presenter property(s). Each model can be presented by one or more properties. Presenting means when in a form or table a list or column is going to show a model's data as an object of another model then which property(s)'s data must be displayed.

Arguments

    sep=null (string)
    Separator. string=return a string of data glued with this string

Returns

array|string
{property-name: data,} | "data" or "data1SEPdata2SEPdata3"

properties

array $obj->properties()

Get a list of model data properties.

Returns

array
[property-name,]

propertyDefs

mixed $obj->propertyDefs(string property=null, string key=null, string default=null)

Get a dictionary of all model data properties and their definitions. Arguments can be passed to filter the result.

Arguments

    property=null (string)
    null=return all, property-name=only return info for this property
    key=null (string)
    Return the value of a certain key in property's definition array
    default=null (string)
    If key not exists in the array then return this value instead

Returns

mixed
not-array=value of a property definition key, array=

query

IModel $obj->query(string view=Model::QUERY_FULL)

Queries data from the database to be filled into the model.

Arguments

    view=Model::QUERY_FULL (string)
    The database view can be "Model::QUERY_SELF" or "Model::QUERY_FULL" "Model::QUERY_L1"

Returns

IModel
For method chaining

reset

IModel $obj->reset(string | int keyVal=null)

Reset model instancing state.

Arguments

    keyVal=null (string | int)
    If provided, after resetting the model's key property will be set to this value

Returns

IModel
For method chaining

rewind

void $obj->rewind()

Iterator - rewind.

Returns

void

select

IModel $obj->select(array cols)

Experimental, to add extra columns into the model's query SELECT.

Arguments

    cols (array)
    Column list

Returns

IModel
For method chaining

setLocale

IModel $obj->setLocale(string | array | [string] locale=null)

Set model locale(s). A data property will be localized if "i18n" is set to true in it's definition. Query and actions on this properties will be locale aware. By default the model locale is set to user's selected LOCALE, you can manually change it with this method. If you set an array of locales then the data will be queried for all those locales. Same thing is valid for other actions. All app's available locales="Arta::$globals['locales']", users locale="LOCALE".

Arguments

    locale=null (string | array | [string])
    Locale(s) e.g. "en-US", "fa-IR"

Returns

IModel
For method chaining

shuffle

IModel $obj->shuffle()

Shuffle query result. e.g. "$model->query()->shuffle();"

Returns

IModel
For method chaining

slice

IModel $obj->slice(array configs)

Slice query result into pages. Use this for querying a paging and producing paging links. e.g. "$model->slice($configs)->query();". After query get paging links from. "$model->__page__->render();"

Arguments

    configs (array)
    Paging configs
    {
        int    page      : 1
            current page number,
        string url       : CURRENT_URL
            URL to be used for paging links,
        const  link      : Paging::LINK_QUERY
            paging link type,
        string key       : Paging::URL_KEY=page
            the key to be used in query string or URL to assign page number
            to it. e.g ?page=2 or url/page/2,
        int    max_rows  : Paging::MAX_ROWS
            max number of rows per page,
        int    max_links : Paging::MAX_LINKS
            number of links to show previous and next to the current page link.
            e.g. 6 = 2|3|4(5)6|7|8,
        int    count     :
            the total data row count,
        bool   abstract  : false
            the raw output shape. false=return a verbose array true=return a
            short and simple array,
        string js        : Arta.pageList(Paging::PAGE)
            if link=LINK_JS then you can set the JavaScript function for
            paging link clicks to this key. "Paging::PAGE" and "Paging::URL"
            strings can be used in the value and will be replaced by their
            real values in the paging links,
        const style      : Paging::LINK_NOM
            render setting - the paging links text display style e.g.
            "Paging::LINK_FROM_TO"=[1-10][11-20][21-30] or
            "Paging::LINK_NOM"=[1][2][3],
        string next      : _(next)
            render setting - text label for the "next" link,
        string previous  : _(prev)
            render setting - text label for the "previous" link,
        string first     : _(first)
            render setting - text label for the "first" link,
        string last      : _(last)
            render setting - text label for the "last" link,
        string tag       : li
            render setting - link container tags,
        string info      : _(Paging::FROM - Paging::TO / Paging::COUNT)
            render setting - template for the extra info being shown beside
            the links. "Paging::FROM", "Paging::TO" and "Paging::COUNT" will
            be replaced with their real values. set to null to disable
            this feature,
        string infopos   : right
            render setting - the place to show the extra info
            may be "right or "left" to the paging links,
        string midware   : null
            render setting - name of a static class method as "Class::method"
            all the link labels will be passed to this method and the
            returned value  will be used instead. this can be useful to
            customize the label texts,
        string leftbox   : null
            render setting - a custom string to be placed left to the links,
        string rightbox  : null
            render setting - a custom string to be placed right to the links,
    }
    

Returns

IModel
For method chaining

sort

IModel $obj->sort([string] properties)

Sort query data by property names. e.g. "$model->sort('Group.id ASC', 'id DESC')->query();"

Arguments

    properties ([string])
    Can be name of a model's data property e.g. "name" or if a property is an IModel object then the name of the model and it's property to sort on e.g. "Group.id" and so on... "ASC" and "DESC" may be added to each item

Returns

IModel
For method chaining

top

IModel $obj->top(int top=10)

Limit query result to the first n rows. e.g. "$model->top(10)->query();"

Arguments

    top=10 (int)
    Top n rows

Returns

IModel
For method chaining

translateToSql

string $obj->translateToSql(string str, bool useTable=false)

Translate Model codition to database SQL condition. Mostly for internal uses only.

Arguments

    str (string)
    Model condition
    useTable=false (bool)
    false=use views, true=use tables

Returns

string
Database query-able SQL condition string

trim

IModel $obj->trim(int start, int end)

Trim queried result. Cut off rows from the start or/and end of the result. e.g. "$model->query()->trim(5, 5);"

Arguments

    start (int)
    Trim all rows before this row number (zero based)
    end (int)
    Trim all rows after this row number (zero based)

Returns

IModel
For method chaining

update

IModel $obj->update(string conditions=null, array | [mixed] conditionParams=null)

Update model's data. Requires "commit()" to take effect on the database. To update data you have to either set model's key(pk) to a value that would mean "UPDATE ... WHERE key=value" or pass conditions to this method manually.

Arguments

    conditions=null (string)
    The condition string.
    Conditions params may be used inside the string:
    
    Params from a list:
    "id = $1 AND (name = $2 OR name IN ($3))"
    
    Params from a dictionary:
    "id = $id AND (name = $name OR name IN ($names))"
    
    To address properties of IModel properties at any level.
    e.g. if Group and Permission are IModel classes:
    "Group.Permission.id = 5"
    
    conditionParams=null (array | [mixed])
    Condition params {param: val,} | [val,] | val1, val2,...
    When params are used inside the condition string, values for the params can be
    passed to this method as shown below. Values will be sanitized before being
    inserted into the condition string.
    
    List, passed as individual method arguments:
    5, 'Ronnie', ['James', 'Dio',]
    
    Dictionary, passed as one array argument:
    {'id': 5, 'name': 'Ronnie', 'names': ['James', 'Dio',],}
    

Returns

IModel
For method chaining

valid

bool $obj->valid()

Iterator - valid. (only to be called by iterator, never call this method)

Returns

bool
true=valid row

where

IModel $obj->where(string conditions=null, array | [mixed] conditionParams=null)

Set conditions for querying data. Removed previously set conditions.

Arguments

    conditions=null (string)
    The condition string.
    Conditions params may be used inside the string:
    
    Params from a list:
    "id = $1 AND (name = $2 OR name IN ($3))"
    
    Params from a dictionary:
    "id = $id AND (name = $name OR name IN ($names))"
    
    To address properties of IModel properties at any level.
    e.g. if Group and Permission are IModel classes:
    "Group.Permission.id = 5"
    
    conditionParams=null (array | [mixed])
    Condition params {param: val,} | [val,] | val1, val2,...
    When params are used inside the condition string, values for the params can be
    passed to this method as shown below. Values will be sanitized before being
    inserted into the condition string.
    
    List, passed as individual method arguments:
    5, 'Ronnie', ['James', 'Dio',]
    
    Dictionary, passed as one array argument:
    {'id': 5, 'name': 'Ronnie', 'names': ['James', 'Dio',],}
    

Returns

IModel
For method chaining