mDIS and Yii2 PHP Classes
Full inheritance hierarchy
Related Pages
Templates-Manager page
Developer page
PHP Class hierarchy
The following paragraphs explain how an mDIS model object is actually implemented: via several PHP classes in an elaborate hierarchy.
The PHP files mentioned here can be found in the backend/models directory, and in various backend/vendor/yiisoft/yii2/
subdirectories.
Let's explain the Class hierarchy using the Core entity as an example.
An mDIS PHP class is named CoreCore
because the table Core
is part of the Core
tableset. The associated database table would be named core_core
.
# mDIS PHP Class Hierarchy
# Model Classes (and 1 Form Class)
yii\db\ActiveRecord # large parent class, provided by Yii
app\models\base\Base # "Handwritten" Base Class
app\models\base\BaseCoreCore # implements linked table 'core'
app\models\CoreCore # add own behaviors here (optional)
app\forms\CoresForm\ # has only 1 method: scenarios()
# Search Classes
app\models\base\BaseCoreCoreSearch # inherits from BaseCoreCore (!)
app\models\CoreCoreSearch # empty class, no methods on purpose
app\forms\CoreCoreSearch # empty class, no methods on purpose
In the code block above, the indentation means "extends" or "inherits".
At the top, there is a large base class yii\db\ActiveRecord
, provided by Yii.. See also Yii Classes below. The base class has lots of methods.
Beginning on line 3, following ActiveRecord
, are mDIS Model classes, provided by code generation and by customization.
Class app\models\base\Base
is hand-coded; the others are code-generated. They can be customized (by editing), but this is optional.
Actually, for consistency reasons, app\models\base\Base
should be called app\models\base\BaseRecord
(just as mDIS Importers and Reports), but the class hierarchy is already pretty deep and names would get unreasonably long, so we prefer the shorter class names.
mDISModel classes
The Bigger Picture
An mDIS data model object represents one record in the corresponding data table. Every access to the record in the mDIS data tables is done via the model object. This way, it can be assured that validators are checked, behaviors are executed, etc.
These classes are hand-coded, as well as automatically created by the code generator of the mDIS Templates-Manager.
Class Base
Abstract base class for all mDIS data models. Hand-coded.
The behaviors()
method should be modified if a new AttributeBehavior is added system-wide.
Class BaseCoreCore
For every MySQL data table containing science data, a base class (e.g. base/BaseCoreCore.php
) is generated by the Templates-Manager. This file should not be modified, since it could be overridden by the Templates-Manager.
It implements:
- text field default values (in the
DEFAULT_VALUES
constant array and in theinit()
method) - text field data types and validators (in the
rules()
method) - text field labels, column labels (in the
attributeLabels()
method), - calculations (in the lowermost method
beforeSave()
). - lots of
getXXX()
methods that return\yii\db\ActiveQuery
objects TBC
The rules()
method might have some additional value, 'safe'
. This means this attribute is not constrained by some validation rules and still marked as 'safe'. We can assign anything to this field. If it was not marked as 'safe', it would be ignored by the setAttributes()
method of the yii\base\Model
class. That feature allows us to pass the entire content of $_POST to setAttributes()
and be sure that only expected values will be assigned to the model. (See also "'Unsafe' attributes and Scenarios" below)
The GENERATED
constant contains a Unix timestamp.
Class CoreCore
Additionally, the Template-Manager has created a mostly empty class (e.g. CoreCore.php
) that extends the BaseCoreCore
class above. If you want to modify the data model manually, you should do it here:
You can add custom behaviors in the behaviors()
method, for instance.
The fields()
method modifies the capabilities of the Filter Bar.
You can add your own rules()
method here. (Take a look at ImageOfTheDay.php
, ListValues.php
, ListValuesSearch.php
, MessageOfTheDay.php
, Post.php
, Widgets.php
for inspiration.)
Class CoresForm
This class is not a Model Class, but for completeness, we list it here because this class inherits from CoreCore
. Class CoresForm
has only 1 method: scenarios()
, which returns a list of scenarios and the corresponding active attributes.
The CoresForm::scenarios()
method overrides a base-class method 6 levels up, the yii\db\Model::scenarios()
method.
Scenarios
What are Scenarios?
They are Yii built-in features. Scenarios allow you to define different sets of attributes that are active in different conditions.
Form Scenarios: Create, Edit, or View.
??? (A validation scenario represents a search, sort, or filter action requested by the user where the mDIS model objects must validate sets of input parameters or criteria). TBC
Test case Scenarios
It belongs to a different namespace, app\forms
, so the full name is app\forms\CoresForm\
. The file is located in the directory backend/forms
(not backend/models
).
Unsafe attributes and Scenarios
From the PHPdoc of the yii\db\Model::scenarios()
class:
By default, an active attribute is considered "safe" and can be "massively assigned". If an attribute should NOT be massively assigned (thus considered unsafe), please prefix the attribute with an exclamation character (e.g. '!rank'
). (In 2019, we do not use this construct in mDIS PHP code).
The default implementation of this method will return all scenarios found in the rules()
declaration. A special scenario named SCENARIO_DEFAULT
will contain all attributes found in the rules()
. Each scenario will be associated with the attributes that are being validated by the validation rules that apply to the scenario.
The returned array should be in the following format:
[
'scenario1' => ['attribute11', 'attribute12', ...],
'scenario2' => ['attribute21', 'attribute22', ...],
...
]
Search Classes
These are the PHP classes implementing the Hierarchical Filter Bar and the "Filter by Values" search feature of the mDIS data entry forms.
Together with the data model, two search classes have been automatically generated: (1) BaseCoreCoreSearch.php
with some boilerplate code, and (2) CoreCoreSearch.php
, which is mostly empty (on purpose). These classes are used to find records based on query values entered by the mDIS user.
Class BaseCoreCoreSearch
The BaseCoreCoreSearch
class contains a line of generated code for each table attribute. The other code that is needed is highly redundant. Therefore, it has been factored out from each BaseXXXSearch
class to helper class\app\models\SearchModelTrait
, see below.
Class CoreCoreSearch
This class is empty on purpose. Modifications are almost never needed at this time (2019).
Class CoresFormSearch
This class is empty on purpose. Modifications are almost never needed at this time (2019).
Helper Classes
Class SearchModelTrait
The BaseXXXSearch*
classes contain boilerplate code for each table attribute. The classes use
a hand-coded trait class SearchModelTrait.php
that contains methods that would otherwise be identical in every base search class.
If you do not like this code and you need to modify how records of a data model can be searched for, you should override some of the methods in the derived search model class (i.e. CoreCoreSearch.php
), which is empty on purpose and can be customized.
Yii Classes
For completeness, we show the Yii base classes from which the mDIS class app\models\base\Base
inherits.
Note that our app\models\Base
class (in row 7) "stems from" a hierarchy of 5 base classes above it (beginning in row 2).
# Yii Classes
yii\BaseObject
yii\Component
yii\db\Model
yii\db\BaseActiveRecord # implements ActiveRecordInterface
yii\db\ActiveRecord # parent class of mDIS 'Base.php' class
app\models\base\Base # mDIS class
These are the constants and methods that the Yii2 framework provides, from top to bottom:
yii\base\BaseObject
class
BaseObject is the base class that implements the property feature.
Class BaseObject
implements Configurable
. Methods from this interface are not shown here separately.
yii\base\Component
class
Component is the base class that implements the property, event, and behavior features.
yii\db\Model
class
yii\db\Model
is the base class for data models.
yii\db\Model
implements the following commonly used features:
- attribute declaration: by default, every public class member is considered as a model attribute
- attribute labels: each attribute may be associated with a label for display purposes
- "massive" attribute assignment with
setAttributes($_POST)
- scenario-based validation
class Model
extends Component
implements StaticInstanceInterface, IteratorAggregate, ArrayAccess, Arrayable
. The respective methods from these interfaces are not shown here separately.
yii\db\BaseActiveRecord
class
db\BaseActiveRecord
is the base class for classes representing relational data in terms of objects.
See \yii\db\ActiveRecord
for a concrete implementation. Official Documentation
Implements the save()
method which, if successful, magically sets a new CoreCore->id
field value as a side effect. (? Is this important?)
yii\db\ActiveRecord
class
ActiveRecord
is the concrete implementation of its abstract superclass db\BaseActiveRecord
, and represents relational data in terms of objects.
app\models\base\Base
class
The first mDIS class, located at level 6 in the inheritance hierarchy. (See above.)
mDIS adds another 3 hierarchy levels, making it 9 or 10 levels in total. It depends on how you count them.