Models
SCI WP allows to create models, link them to database tables and execute queries directly from the models in the same way you would do it with any other PHP framework. The idea behind the SCI WP core Model class is to provide a zero configuration abstraction, so the model just works by setting the database table matching the model.
Bundled version: If you bundle the framework with your Plugin, you should prepend your plugin namespace to the Sci namespace when referencing framework components. For example, if you use the bundled version you should reference the MyPlugin\Sci\View class instead of the Sci\View class.
Defining Models
To create a model you just need to extend the class Sci\Database\Model. Here is an example of how to create a model:
namespace MyPlugin\App\Models;use Sci\Database\Model;class Orc extends Model;{}
And the model is created. You don't need to configure anything else if you don't want to.
Instantiation
You can create a new instance of a model like with any other PHP class:
use \MyPlugin\App\Models\Orc;$orc = new Orc(['name' => 'Thrall','job' => "warchief']);
As you can see, When creating a new instance, the attributes are sent along with an array. You can also create it by using the create static method:
use \MyPlugin\App\Models\Orc;$orc = Orc::create(['name' => 'Thrall','job' => "warchief']);
Model attributes
In SCI WP the attributes of the models are stored in the $attributes
attribute. The attributes will be mapped with the model database table. You can set or get the attributes just like a standard attribute of any other PHP class, as SCI WP hooks into the __get
and __set
magic methods:
// Set an attribute$orc->faction = 'alliance';// This will print _alliance_echo($orc->faction);
You don't need to define the attributes in the class definition, as they will be mapped automatically based on its name with the database fields. However, you can use the $attributes array to set default values to the model attributes:
Default attributes
Let's create a instance of the Orc class and assing default values to some attributes:
namespace MyPlugin\App\Models;use Sci\Database\Model;class Orc extends Model;{protected $attributes = ['faction' => 'horde','strength' => 20,'armor' => 10];}
Model Conventions
The previous example was simple, but there are some consideration and conventions you need to know.
Table Names
The class Orc we previously created will be matched with a table which name is the plural of Orc, in lowercase. The wordpress table prefix will also be added by default, so, for this model to work, the database table should be named wp_orcs if the prefix of the tables is the default one.
You can customize moth the table name and the database prefix using the TABLE_NAME
and the TABLE_PREFIX
constansts. You can write any name for the name of the table and enable or disable the TABLE_PREFIX
setting it to true or to false
.
namespace MyPlugin\App\Models;use Sci\Database\Model;class Orcs extends Model;{// The table nameconst TABLE_NAME = 'orcs_table';// Enable or disable the table prefixconst TABLE_PREFIX = false;}
In this example we are Assigning the table orcs_table
to the Orc model and disabling the table prefix so it's not prended to the table name. The prefix is enabled by default.
Primary key
SCI WP assumes that each table has a primary key column named id
. You can define another colum for the primary key by using the PRIMARY_KEY
constant in the model definition:
namespace MyPlugin\App\Models;use Sci\Database\Model;class Orc extends Model;{// Primary key column nameconst PRIMARY_KEY= 'orcId';}
In this examble we assign the column orcId as the primary key column for the model.
Auto increment
By default, a new field with an auto incremente value is expected for the primary key by default. However, this can be disabled by setting the value off the AUTO_INCREMENT
constant to false. Here is an example:
namespace MyPlugin\App\Models;use Sci\Database\Model;class Orc extends Model;{// Disable auto incrementconst AUTO_INCREMENT= false;}
When disabling the auto increment option, you should also set a value for the primary key of each model instance, as it will not be generated automatically by the database. If the primary key value is not set and the model is saved, a unique id will be generated, although it will not have a relation with the primary key value of the previous element wich was saved.
Timestamps
The timestamps are a set of optional fields to track the changes of a database record, so it's possible to know when a record was created, when it was updated for the last time and when it was deleted, if that's the case. To enable the timestamps, just set the TIMESTAMPS
constant to tru when defining a model.
namespace MyPlugin\App\Models;use Sci\Database\Model;class Orc extends Model;{const TIMESTAMPS = true;}
By default, the model will search for the fields created_at
, updated_at
and deleted_at
, which you need to add to the database table used by the model. However, you can configure the name of these fields by changing the value of the CREATED_AT
, UPDATED_AT
and DELETED_AT
constants:
namespace MyPlugin\App\Models;use Sci\Database\Model;class Orc extends Model;{const TIMESTAMPS = true;const CREATED_AT = 'date_created';const UPDATED_AT = 'date_updated';const DELETED_AT = 'date_deleted';}
When these fields are set, SCI WP will update them when the records of a model change.
Save, Update and Delete operations
With SCI WP it is possible to save or update a model instance using functions of the model.
Save a model instance
To save or store an instance into the database you just need to use the save
method:
$instance = $orc->save();
When a model is saved and if it does not exist in the database, the id of the object will be added to the model as an attribute. The save method returns the instance itself, so you can continue executing additional model functions.
echo($instance->id);
The model instance has now an id which was generated by the database.
Update a model instance
Although we cover the model basic queries in the next section, let's get the previously saved record form the database to create a model instance.
$orc = App\Models\Orc::find(2);
If you want to update some attributes and then update the matching record in the database, just use the save method again.
$orc->faction = 'neutral';$orc->save();
Delete a model instance
Our orc has completed its mission bringing diplomacy between the alliance and the order, so it´s time to say him goodbye. To delete an instace from the database, just use the delete method.
$orc->delete();
The delete
method will permanently remove the record from the database. However, you can use the remove method to soft delete the record, as it will just set deleted_at
timestamp value to the current date. To use this method, the TIMESTAMP
constant must be set to true.
$orc->remove();
In case tyou want to use another field to store the date, you just need to set the name of the field as the value for the DELETED_AT
constant in the model definition:
namespace MyPlugin\App\Models;use Sci\Database\Model;class MyModel extends Model;{// Enable timestampsconst TIMESTAMPS = true;// Switch the default fieldconst DELETED_AT = 'field_name';}
Retrieving Models
Once you have created a model and the matching database table, you can start retrieving data from the database. Before entering in detail with the query builder, we are going to see how to retrieve both single model records or collections of records.
Retrieving all records
You can retrieve all records of a model using the method findAll
. Here is an example of how to retrieve all records of the model we previously created:
$orcs = App\Models\Orc::findAll()foreach ($orcs as $orc) {echo $orc->name;}
However, it's not always the most optimum to get all records of a database table. You can easily paginate them via the $skip and $limit parameters, selecting only a range of records. If we wanto to create a list of orcs and we want to display 10 orcs per page, we can use the findAll
method in this way to, for example, get the elements in the third page:
$orcs = App\Models\Orc::findAll(20, 10);foreach ($orcs as $orc) {echo $orc->name;}
You can also use the all
method to archive the same results, as it's just an alias to the findAll
method:
$orcs = App\Models\Orc::all(20, 10);
Retrieve a set of records
You can use the the find
method to add constraints and search for a set of specific records. This is a dynamic method which allows to filter the data in many different ways. The constraints are added via arrays composed of a field to filter, an comparation operator and a value. Here is an example:
$orcs = App\Models\Orc::find(['strength', '<', 20 ]);foreach ($orcs as $orc) {echo $orc->name;}
The previous code will print the name of all the orcs whose strenght is lower than 20.
You can also add more conditions by just adding them as parameters of the find
method:
$orcs = App\Models\Orc::find(['strength', '<', 20 ], ['armor', '>=', 30]);foreach ($orcs as $orc) {echo $orc->name;}
The previous code will print the name of all the orcs whose strenght is lower than 20 and whose armor points are more or equals than 30. You can add all conditions you want, without limit.
What happens if you want to get all orcs whose strenght is lower than 20 or whose armor points are more or equals than 30?. Easy; just add a third element to the second constraint array, which can take an OR or an AND value.
$orcs = App\Models\Orc::find(['strength', '<', 20 ], ['armor', '>=', 30, 'OR']);
You don't need to specify this fourth value of the condition if you want to add an AND value, as it's the default value. You can even especify just an attribute name and the value it should take, in which case, the operator value will default to equals (=), and the condition will be added as an AND condition. So, if for example you want to get all orcs which armor value is exactly 15, you can just use this query:
$orcs = App\Models\Orc::find(['armor', 30]);
In case you only have one constraint, you can omit the brackets:
$orcs = App\Models\Orc::find('armor', 30);
And that's not all, as you can just specify an element in the constraint array, in which case, the field name will default to the model primary key. For example, you can get the or whose primary key is 2 by this way:
$orcs = App\Models\Orc::find([2]);
You can also omit the brackets and get the same results:
$orcs = App\Models\Orc::find(2);
If you want to paginate the result or get a specific range, you can add the $skip
and the $limit parameters at the end, as the last two arguments. However, if you want to use the pagination all constraints must be between brackets, using the array format.
$orcs = App\Models\Orc::find(['strength', '<', 20 ], ['armor', '>=', 30, 'OR'], 20, 10);
This will get the third page of orcs, displaying ten per page.
You can add many values in a constraint to, for instance, check if the value of a a field is equals to any value of a set. Here is an example:
$orcs = App\Models\Orc::find(['name', '=', ['Thrall', 'Orgrim']);
Retrieve a single record
To get a single record for a model you can use the one
method, which works almos exatly as the find method, but limiting the results to one record. For example to get a single record you can use this function, which look for the orc whose primary key is 2.
$orcs = App\Models\Orc::one(2);
It's important to say that this function will not get an array of instanves, but the instance it self in case it was found, or false if it was not found. You can use this function exactly like the find
method, seatching for many records, but only the first instance found will be returned.
Model Queries
You can query the database table used by a model by using the query
method:
$orcs = App\Models\Orc::query()->get();foreach ($orcs as $orc) {echo $orc->name;}
The query
method starts a standed query. In the next example we apply some conditions:
$orcs = App\Models\Orc::query()->where(['name', // Apply the constraint to the name filed'=', //The condition operator['Trall', 'Orgrim'], // Value or array of values to compare'AND', // Relation with the previous constraints if many are specifiedtrue, // The condition is not negated'OR' // Match any of the specified values])->get();
Yo learn more about the database queries, check the queries section