Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

Abstract class for objects saved to the DB.

Copyright: 2015 Damyon Wiese
License: http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
File Size: 950 lines (32 kb)
Included or required:0 times
Referenced: 0 times
Includes or requires: 0 files

Defines 1 class


Class: persistent  - X-Ref

Abstract class for core objects saved to the DB.

__construct($id = 0, stdClass $record = null)   X-Ref
Create an instance of this class.

param: int $id If set, this is the id of an existing record, used to load the data.
param: stdClass $record If set will be passed to {@link self::from_record()}.

verify_protected_methods()   X-Ref
This function is used to verify that custom getters and setters are declared as protected.

Persistent properties should always be accessed via get('property') and set('property', 'value') which
will call the custom getter or setter if it exists. We do not want to allow inconsistent access to the properties.

set($property, $value)   X-Ref
Data setter.

This is the main setter for all the properties. Developers can implement their own setters (set_propertyname)
and they will be called by this function. Custom setters should call internal_set() to finally set the value.
Internally this is not used {@link self::to_record()} or
{@link self::from_record()} because the data is not expected to be validated or changed when reading/writing
raw records from the DB.

param: string $property The property name.
return: $this

get($property)   X-Ref
Data getter.

This is the main getter for all the properties. Developers can implement their own getters (get_propertyname)
and they will be called by this function. Custom getters can use raw_get to get the raw value.
Internally this is not used by {@link self::to_record()} or
{@link self::from_record()} because the data is not expected to be validated or changed when reading/writing
raw records from the DB.

param: string $property The property name.
return: mixed

raw_get($property)   X-Ref
Internal Data getter.

This is the main getter for all the properties. Developers can implement their own getters
but they should be calling {@link self::get()} in order to retrieve the value. Essentially
the getters defined by the developers would only ever be used as helper methods and will not
be called internally at this stage. In other words, do not expect {@link self::to_record()} or
{@link self::from_record()} to use them.

This is protected because it is only for raw low level access to the data fields.
Note this function is named raw_get and not get_raw to avoid naming clashes with a property named raw.

param: string $property The property name.
return: mixed

raw_set($property, $value)   X-Ref
Data setter.

This is the main setter for all the properties. Developers can implement their own setters
but they should always be calling {@link self::set()} in order to set the value. Essentially
the setters defined by the developers are helper methods and will not be called internally
at this stage. In other words do not expect {@link self::to_record()} or
{@link self::from_record()} to use them.

This is protected because it is only for raw low level access to the data fields.

param: string $property The property name.
param: mixed $value The value.
return: $this

define_properties()   X-Ref
Return the custom definition of the properties of this model.

Each property MUST be listed here.

The result of this method is cached internally for the whole request.

The 'default' value can be a Closure when its value may change during a single request.
For example if the default value is based on a $CFG property, then it should be wrapped in a closure
to avoid running into scenarios where the true value of $CFG is not reflected in the definition.
Do not abuse closures as they obviously add some overhead.

Examples:

array(
'property_name' => array(
'default' => 'Default value',        // When not set, the property is considered as required.
'message' => new lang_string(...),   // Defaults to invalid data error message.
'null' => NULL_ALLOWED,              // Defaults to NULL_NOT_ALLOWED. Takes NULL_NOW_ALLOWED or NULL_ALLOWED.
'type' => PARAM_TYPE,                // Mandatory.
'choices' => array(1, 2, 3)          // An array of accepted values.
)
)

array(
'dynamic_property_name' => array(
'default' => function() {
return $CFG->something;
},
'type' => PARAM_INT,
)
)

return: array Where keys are the property names.

properties_definition()   X-Ref
Get the properties definition of this model..

return: array

get_formatted_properties()   X-Ref
Gets all the formatted properties.

Formatted properties are properties which have a format associated with them.

return: array Keys are property names, values are property format names.

get_property_default_value($property)   X-Ref
Gets the default value for a property.

This assumes that the property exists.

param: string $property The property name.
return: mixed

get_property_error_message($property)   X-Ref
Gets the error message for a property.

This assumes that the property exists.

param: string $property The property name.
return: lang_string

has_property($property)   X-Ref
Returns whether or not a property was defined.

param: string $property The property name.
return: boolean

is_property_required($property)   X-Ref
Returns whether or not a property is required.

By definition a property with a default value is not required.

param: string $property The property name.
return: boolean

from_record(stdClass $record)   X-Ref
Populate this class with data from a DB record.

Note that this does not use any custom setter because the data here is intended to
represent what is stored in the database.

param: \stdClass $record A DB record.
return: static

to_record()   X-Ref
Create a DB record from this class.

Note that this does not use any custom getter because the data here is intended to
represent what is stored in the database.

return: \stdClass

read()   X-Ref
Load the data from the DB.

return: static

before_create()   X-Ref
Hook to execute before a create.

Please note that at this stage the data has already been validated and therefore
any new data being set will not be validated before it is sent to the database.

This is only intended to be used by child classes, do not put any logic here!

return: void

create()   X-Ref
Insert a record in the DB.

return: static

after_create()   X-Ref
Hook to execute after a create.

This is only intended to be used by child classes, do not put any logic here!

return: void

before_update()   X-Ref
Hook to execute before an update.

Please note that at this stage the data has already been validated and therefore
any new data being set will not be validated before it is sent to the database.

This is only intended to be used by child classes, do not put any logic here!

return: void

update()   X-Ref
Update the existing record in the DB.

return: bool True on success.

after_update($result)   X-Ref
Hook to execute after an update.

This is only intended to be used by child classes, do not put any logic here!

param: bool $result Whether or not the update was successful.
return: void

save()   X-Ref
Saves the record to the database.

If this record has an ID, then {@link self::update()} is called, otherwise {@link self::create()} is called.
Before and after hooks for create() or update() will be called appropriately.

return: void

before_delete()   X-Ref
Hook to execute before a delete.

This is only intended to be used by child classes, do not put any logic here!

return: void

delete()   X-Ref
Delete an entry from the database.

return: bool True on success.

after_delete($result)   X-Ref
Hook to execute after a delete.

This is only intended to be used by child classes, do not put any logic here!

param: bool $result Whether or not the delete was successful.
return: void

before_validate()   X-Ref
Hook to execute before the validation.

This hook will not affect the validation results in any way but is useful to
internally set properties which will need to be validated.

This is only intended to be used by child classes, do not put any logic here!

return: void

validate()   X-Ref
Validates the data.

Developers can implement addition validation by defining a method as follows. Note that
the method MUST return a lang_string() when there is an error, and true when the data is valid.

protected function validate_propertyname($value) {
if ($value !== 'My expected value') {
return new lang_string('invaliddata', 'error');
}
return true
}

It is OK to use other properties in your custom validation methods when you need to, however note
they might not have been validated yet, so try not to rely on them too much.

Note that the validation methods should be protected. Validating just one field is not
recommended because of the possible dependencies between one field and another,also the
field ID can be used to check whether the object is being updated or created.

When validating foreign keys the persistent should only check that the associated model
exists. The validation methods should not be used to check for a change in that relationship.
The API method setting the attributes on the model should be responsible for that.
E.g. On a course model, the method validate_categoryid will check that the category exists.
However, if a course can never be moved outside of its category it would be up to the calling
code to ensure that the category ID will not be altered.

return: array|true Returns true when the validation passed, or an array of properties with errors.

is_valid()   X-Ref
Returns whether or not the model is valid.

return: boolean True when it is.

get_errors()   X-Ref
Returns the validation errors.

return: array

extract_record($row, $prefix = null)   X-Ref
Extract a record from a row of data.

Most likely used in combination with {@link self::get_sql_fields()}. This method is
simple enough to be used by non-persistent classes, keep that in mind when modifying it.

e.g. persistent::extract_record($row, 'user'); should work.

param: stdClass $row The row of data.
param: string $prefix The prefix the data fields are prefixed with, defaults to the table name followed by underscore.
return: stdClass The extracted data.

get_records($filters = array()   X-Ref
Load a list of records.

param: array $filters Filters to apply.
param: string $sort Field to sort by.
param: string $order Sort order.
param: int $skip Limitstart.
param: int $limit Number of rows to return.
return: static[]

get_record($filters = array()   X-Ref
Load a single record.

param: array $filters Filters to apply.
return: false|static

get_records_select($select, $params = null, $sort = '', $fields = '*', $limitfrom = 0, $limitnum = 0)   X-Ref
Load a list of records based on a select query.

param: string $select
param: array $params
param: string $sort
param: string $fields
param: int $limitfrom
param: int $limitnum
return: static[]

get_sql_fields($alias, $prefix = null)   X-Ref
Return the list of fields for use in a SELECT clause.

Having the complete list of fields prefixed allows for multiple persistents to be fetched
in a single query. Use {@link self::extract_record()} to extract the records from the query result.

param: string $alias The alias used for the table.
param: string $prefix The prefix to use for each field, defaults to the table name followed by underscore.
return: string The SQL fragment.

count_records(array $conditions = array()   X-Ref
Count a list of records.

param: array $conditions An array of conditions.
return: int

count_records_select($select, $params = null)   X-Ref
Count a list of records.

param: string $select
param: array $params
return: int

record_exists($id)   X-Ref
Check if a record exists by ID.

param: int $id Record ID.
return: bool

record_exists_select($select, array $params = null)   X-Ref
Check if a records exists.

param: string $select
param: array $params
return: bool