Webservice
Generic Model CRUD
Overview
ModelCRUD is a helper to create XELOS\Modules\Webservice\Hook\Base\Service\Method objects for classes derived from XELOS\Framework\Module\Model\Model with basic Create, Count, Read, Read All, Update, Delete and Delete All functionality.
The use case for ModelCRUD, is to enable an outside service to conveniently interface with XELOS through models, providing or accesing information.
Usage
Each of the C(C)RUD functions is optional and not created by default. To tell ModelCRUD which functions to create, it needs an associative array with below function names as index:
* For create, update, read, and read_all an array with the names of the properties to be exposed.
* For count, delete and delete_all a boolean truehas to be set.
The Model must have a single property primary key defined, models without a PK or with composite PKs are not supported.
Method Naming
The methods are postfixed with the model name, for example the CRUD functions for the model Article would be:
* create_article
* count_article
* read_article
* read_all_article
* update_article
* delete_article
* delete_all_article
Caveat
Currently there are no permission checks (can_read, can_write) performned on individual model objects. Which means that if a user can read, write or delete one model, they can also access all models of the same class. Check for permissions before you call ModelCRUD::Create() and subsequently return the Methods to the webservice inside the Hook.
Date Time datatypes
XML Soap requires the date time to be formatted as "xs:dateTime" (2002-05-30T09:00:00) with a T between the date and time. We currently return the date time as a MySQL date time string and some XML parsers might throw serialization errors. Workaround is to use timestamps, seperate the date from the time or use the JSON RPC interface.
ModelCRUD expects recieved date time strings to be compatible with the MySQL date time string format or timestamps.
Example Usage
declare(strict_types=1);
namespace XELOS\Vendor\Blueend\Modules\SomeModule\Hook\Webservice;
use XELOS\Framework\Module\Model\Model;
use XELOS\Framework\XF;
use XELOS\Vendor\Blueend\Modules\SomeModule\SomeModuleController;
use XELOS\Modules\Webservice\Hook\Base\Service;
use XELOS\Modules\Webservice\Hook\Base\Service\Method;
use XELOS\Modules\Webservice\Hook\Base\Service\ModelCRUD;
class RoomBookingService extends Service {
/**
* @var SomeModuleController
*/
public $mod;
/**
* @return Method[]
*/
public function setupMethods(): array {
$XF = XF::instance();
$methods = [];
//simple access control
if(!$XF->user->in_group('admin') && !$XF->user->in_group('api')){
return [];
}
//setup a crud interface for a set of models from the module
$exposedModels = ['MyModel', 'ThisModel', 'ThatModel'];
foreach($exposedModels as $modelName) {
/** @var Model $model */
$model = $this->mod->model->$modelName;
//we want to expose all properties in this case
$properties = array_keys($model->get_properties());
$functions = [];
$functions['create'] = $properties;
$functions['read'] = $properties;
$functions['read_all'] = $properties;
$functions['update'] = $properties;
$functions['delete'] = true;
$functions['delete_all'] = true;
$functions['count'] = true;
$crudMethods = ModelCRUD::create($model, $functions);
$methods = array_merge($crudMethods, $methods);
}
/** @var ComplexExampleModel $model */
$model = $this->mod->model->ComplexExampleModel;
//we need to have access to the PK in all cases
$propertiesBase[] = $model->get_table_primary_key();
$functions = [];
$functions['create'] = array_merge($propertiesBase, ['user_id', 'title_i18n', 'content_text']);
//only expose title_i18n and content_text property for this operation
$functions['read'] = array_merge($propertiesBase, ['title_i18n', 'content_text']);
//only expose title_i18n property for this operation
$functions['read_all'] = array_merge($propertiesBase, ['title_i18n']);
///only expose title_i18n and content_text property for this operation
$functions['update'] = array_merge($propertiesBase, ['title_i18n', 'content_text']);;
//dont wan't to allow delete_all, just selected models, so leave it out since its default false
//$functions['delete_all'] = false;
//no permissions are cheked, all models can still be deleted if their PKs are known
$functions['delete'] = true;
//retieve a count of ALL models, no scoping or permission checks on induhvidual models
$functions['count'] = true;
$crudMethods = ModelCRUD::create($model, $functions);
$methods = array_merge($crudMethods, $methods);
return $methods;
}
}