Newer
Older
<?php
/**
* Copyright Maarch since 2008 under licence GPLv3.
* See LICENCE.txt file at the root folder for more details.
* This file is part of Maarch software.
* @brief ParametersController
* @author dev <dev@maarch.org>
* @ingroup core
*/
/**
* @brief Indexing Model Controller
* @author dev@maarch.org
*/
namespace IndexingModel\controllers;
use CustomField\models\CustomFieldModel;
use Entity\models\EntityModel;
use Group\controllers\PrivilegeController;

Florian Azizian
committed
use History\controllers\HistoryController;
use IndexingModel\models\IndexingModelFieldModel;
use IndexingModel\models\IndexingModelModel;
use Resource\controllers\IndexingController;
use Resource\models\ResModel;
use Respect\Validation\Validator;
use Slim\Http\Request;
use Slim\Http\Response;
class IndexingModelController
{
const INDEXABLE_DATES = ['documentDate', 'departureDate', 'arrivalDate', 'processLimitDate'];
public function get(Request $request, Response $response)
Guillaume Heurtier
committed
$query = $request->getQueryParams();
$where = ['(owner = ? OR private = ?)'];
Guillaume Heurtier
committed
$showDisabled = false;
if (Validator::notEmpty()->validate($query['showDisabled'])) {
$showDisabled = $query['showDisabled'] == 'true';
}
if (!$showDisabled) {
$where[] = 'enabled = TRUE';
} elseif (!PrivilegeController::hasPrivilege(['privilegeId' => 'admin_indexing_models', 'userId' => $GLOBALS['id']])) {
$where[] = 'enabled = TRUE';
}
$models = IndexingModelModel::get(['where' => $where, 'data' => [$GLOBALS['id'], 'false']]);

Florian Azizian
committed
foreach ($models as $key => $value) {
$models[$key]['used'] = false;
$resources = ResModel::get([
'select' => [1],
'where' => ['model_id = ?'],
'data' => [$value['model_id']]
]);
if (!empty($resources)) {
$models[$key]['used'] = true;
}
}
return $response->withJson(['indexingModels' => $models]);
}
public function getById(Request $request, Response $response, array $args)
{
$model = IndexingModelModel::getById(['id' => $args['id']]);
if (empty($model)) {
return $response->withStatus(400)->withJson(['errors' => 'Model not found']);
} elseif ($model['private'] && $model['owner'] != $GLOBALS['id']) {
return $response->withStatus(400)->withJson(['errors' => 'Model out of perimeter']);

Florian Azizian
committed
}
$fields = IndexingModelFieldModel::get(['select' => ['identifier', 'mandatory', 'default_value', 'unit'], 'where' => ['model_id = ?'], 'data' => [$args['id']]]);
foreach ($fields as $key => $value) {
$fields[$key]['default_value'] = json_decode($value['default_value'], true);
}
$model['fields'] = $fields;
return $response->withJson(['indexingModel' => $model]);
}
public function create(Request $request, Response $response)
{
$body = $request->getParsedBody();
$categories = ResModel::getCategories();
$categories = array_column($categories, 'id');
if (!Validator::stringType()->notEmpty()->length(1, 256)->validate($body['label'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body label is empty or not a string or more than 256 characters']);
} elseif (!Validator::stringType()->notEmpty()->validate($body['category']) || !in_array($body['category'], $categories)) {
return $response->withStatus(400)->withJson(['errors' => "Body category is empty, not a string or not a valid category"]);
} elseif (!Validator::arrayType()->notEmpty()->validate($body['fields'])) {
return $response->withStatus(400)->withJson(['errors' => "Body fields is empty or not an array"]);
}
$foundDoctype = false;
$foundSubject = false;
foreach ($body['fields'] as $key => $field) {
if (!Validator::stringType()->notEmpty()->validate($field['identifier'])) {
return $response->withStatus(400)->withJson(['errors' => "Body fields[{$key}] identifier is empty or not a string"]);
}
if ($field['identifier'] == 'doctype') {
$foundDoctype = true;
} elseif ($field['identifier'] == 'subject') {
$foundSubject = true;
}
}
if (!$foundDoctype) {
return $response->withStatus(400)->withJson(['errors' => "Mandatory 'doctype' field is missing"]);
}
if (!$foundSubject) {
return $response->withStatus(400)->withJson(['errors' => "Mandatory 'subject' field is missing"]);
Guillaume Heurtier
committed
$master = null;
if (Validator::intVal()->notEmpty()->validate($body['master'])) {
$masterModel = IndexingModelModel::getById(['id' => $body['master']]);
if (empty($masterModel)) {
return $response->withStatus(400)->withJson(['errors' => 'Master model not found']);
}
Guillaume Heurtier
committed
if ($masterModel['private']) {
return $response->withStatus(400)->withJson(['errors' => 'Master model is a private model']);
}
$master = $body['master'];
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
$fieldsMaster = IndexingModelFieldModel::get(['select' => ['identifier', 'mandatory', 'default_value', 'unit'], 'where' => ['model_id = ?'], 'data' => [$body['master']]]);
foreach ($fieldsMaster as $key => $value) {
$fieldsMaster[$key]['default_value'] = json_decode($value['default_value'], true);
}
// Look for fields in master model
// if field in master is not in child, return an error
// if field is not in master but in child, is ignored
$arrayTmp = [];
foreach ($fieldsMaster as $field) {
$found = false;
foreach ($body['fields'] as $value) {
if ($value['identifier'] == $field['identifier'] && $value['mandatory'] == $field['mandatory'] && $value['unit'] == $field['unit']) {
array_push($arrayTmp, $value);
$found = true;
break;
}
}
if (!$found) {
return $response->withStatus(400)->withJson(['errors' => "Field '" . $field['identifier'] . "' from master model is missing"]);
}
}
$body['fields'] = $arrayTmp;
}
if (PrivilegeController::hasPrivilege(['privilegeId' => 'admin_indexing_models', 'userId' => $GLOBALS['id']])) {
$body['private'] = empty($body['private']) ? 'false' : 'true';
$defaultModel = IndexingModelModel::get(['select' => [1], 'where' => ['"default" = ?'], 'data' => ['true']]);
$body['default'] = empty($defaultModel) ? 'true' : 'false';
$body['private'] = 'true';
$body['default'] = 'false';
}
$modelId = IndexingModelModel::create([
'label' => $body['label'],
'category' => $body['category'],
'default' => $body['default'],
'owner' => $GLOBALS['id'],
'private' => $body['private'],
Guillaume Heurtier
committed
'master' => $master
]);
foreach ($body['fields'] as $field) {
if (in_array($field['identifier'], IndexingModelController::INDEXABLE_DATES) && !empty($field['default_value']) && $field['default_value'] != '_TODAY') {
$date = new \DateTime($field['default_value']);
$field['default_value'] = $date->format('Y-m-d');
}
if (strpos($field['identifier'], 'indexingCustomField_') !== false && !empty($field['default_value']) && $field['default_value'] != '_TODAY') {
$customFieldId = explode('_', $field['identifier'])[1];
$customField = CustomFieldModel::getById(['id' => $customFieldId, 'select' => ['type']]);
if ($customField['type'] == 'date') {
$date = new \DateTime($field['default_value']);
$field['default_value'] = $date->format('Y-m-d');
}
}
IndexingModelFieldModel::create([
'model_id' => $modelId,
'identifier' => $field['identifier'],
'mandatory' => empty($field['mandatory']) ? 'false' : 'true',
'default_value' => !isset($field['default_value']) ? null : json_encode($field['default_value']),
'unit' => $field['unit']

Florian Azizian
committed
HistoryController::add([
'tableName' => 'indexing_models',
'recordId' => $modelId,
'eventType' => 'ADD',
'info' => _INDEXINGMODEL_CREATION . " : {$body['label']}",
'moduleId' => 'indexingModel',
'eventId' => 'indexingModelCreation',
]);
return $response->withJson(['id' => $modelId]);
}
public function update(Request $request, Response $response, array $args)
{
if (!PrivilegeController::hasPrivilege(['privilegeId' => 'admin_indexing_models', 'userId' => $GLOBALS['id']])) {
return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
}
$body = $request->getParsedBody();

Florian Azizian
committed
if (!Validator::intVal()->notEmpty()->validate($args['id'])) {

Florian Azizian
committed
return $response->withStatus(400)->withJson(['errors' => 'Param id is empty or not an integer']);
}
if (!Validator::stringType()->notEmpty()->length(1, 256)->validate($body['label'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body label is empty or not a string or more than 256 characters']);
} elseif (!Validator::stringType()->notEmpty()->validate($body['category'])) {
return $response->withStatus(400)->withJson(['errors' => "Body category is empty or not a string"]);
} elseif (!Validator::boolType()->validate($body['default'])) {
Guillaume Heurtier
committed
return $response->withStatus(400)->withJson(['errors' => 'Body default is empty or not a boolean']);

Florian Azizian
committed
}
Guillaume Heurtier
committed
$foundDoctype = false;
$foundSubject = false;
foreach ($body['fields'] as $key => $field) {
if (!Validator::stringType()->notEmpty()->validate($field['identifier'])) {
return $response->withStatus(400)->withJson(['errors' => "Body fields[{$key}] identifier is empty or not a string"]);
Guillaume Heurtier
committed
if ($field['identifier'] == 'doctype') {
$foundDoctype = true;
} elseif ($field['identifier'] == 'subject') {
$foundSubject = true;
}
}
if (!$foundDoctype) {
return $response->withStatus(400)->withJson(['errors' => "Mandatory 'doctype' field is missing"]);
}
if (!$foundSubject) {
return $response->withStatus(400)->withJson(['errors' => "Mandatory 'subject' field is missing"]);
$model = IndexingModelModel::getById(['select' => ['owner', 'private'], 'id' => $args['id']]);
if (empty($model)) {
return $response->withStatus(400)->withJson(['errors' => 'Model not found']);
return $response->withStatus(400)->withJson(['errors' => 'Model out of perimeter']);
}
IndexingModelModel::update(['set' => ['"default"' => 'false'], 'where' => ['"default" = ?'], 'data' => ['true']]);

Florian Azizian
committed
}
IndexingModelModel::update([
'set' => [
'label' => $body['label'],
'category' => $body['category'],

Florian Azizian
committed
'"default"' => $body['default'] ? 'true' : 'false'
],
'where' => ['id = ?'],
'data' => [$args['id']]
]);
$childrenModels = IndexingModelModel::get(['select' => ['id', 'label'], 'where' => ['master = ?'], 'data' => [$args['id']]]);
Guillaume Heurtier
committed
// If model has children, update the children
if (!empty($childrenModels)) {
// Update children models of master
foreach ($childrenModels as $child) {
$childFields = IndexingModelFieldModel::get(['select' => ['identifier', 'mandatory', 'default_value', 'unit'], 'where' => ['model_id = ?'], 'data' => [$child['id']]]);
foreach ($childFields as $key => $value) {
$childFields[$key]['default_value'] = json_decode($value['default_value'], true);
}
// Look for fields in master model
$fieldsToKeep = [];
foreach ($body['fields'] as $field) {
$found = false;
foreach ($childFields as $value) {
if ($value['identifier'] == $field['identifier'] && $value['mandatory'] == $field['mandatory'] && $value['unit'] == $field['unit']) {
Guillaume Heurtier
committed
$found = true;
}
}
if (!$found) {
Guillaume Heurtier
committed
}
}
IndexingModelFieldModel::delete(['where' => ['model_id = ?'], 'data' => [$child['id']]]);
foreach ($fieldsToKeep as $field) {
if (in_array($field['identifier'], IndexingModelController::INDEXABLE_DATES) && !empty($field['default_value']) && $field['default_value'] != '_TODAY') {
$date = new \DateTime($field['default_value']);
$field['default_value'] = $date->format('Y-m-d');
}
if (strpos($field['identifier'], 'indexingCustomField_') !== false && !empty($field['default_value']) && $field['default_value'] != '_TODAY') {
$customFieldId = explode('_', $field['identifier'])[1];
$customField = CustomFieldModel::getById(['id' => $customFieldId, 'select' => ['type']]);
if ($customField['type'] == 'date') {
$date = new \DateTime($field['default_value']);
$field['default_value'] = $date->format('Y-m-d');
}
}
Guillaume Heurtier
committed
IndexingModelFieldModel::create([
'model_id' => $child['id'],
'identifier' => $field['identifier'],
'mandatory' => empty($field['mandatory']) ? 'false' : 'true',
'default_value' => !isset($field['default_value']) ? null : json_encode($field['default_value']),
Guillaume Heurtier
committed
]);
}
Guillaume Heurtier
committed
HistoryController::add([
'tableName' => 'indexing_models',
'recordId' => $child['id'],
'eventType' => 'UP',
'info' => _INDEXINGMODEL_MODIFICATION . " : {$child['label']}",
'moduleId' => 'indexingModel',
'eventId' => 'indexingModelModification',
]);
Guillaume Heurtier
committed
}
}
IndexingModelFieldModel::delete(['where' => ['model_id = ?'], 'data' => [$args['id']]]);
foreach ($body['fields'] as $field) {
if (in_array($field['identifier'], IndexingModelController::INDEXABLE_DATES) && !empty($field['default_value']) && $field['default_value'] != '_TODAY') {
$date = new \DateTime($field['default_value']);
$field['default_value'] = $date->format('Y-m-d');
}
if (strpos($field['identifier'], 'indexingCustomField_') !== false && !empty($field['default_value']) && $field['default_value'] != '_TODAY') {
$customFieldId = explode('_', $field['identifier'])[1];
$customField = CustomFieldModel::getById(['id' => $customFieldId, 'select' => ['type']]);
if ($customField['type'] == 'date') {
$date = new \DateTime($field['default_value']);
$field['default_value'] = $date->format('Y-m-d');
}
}
IndexingModelFieldModel::create([
'model_id' => $args['id'],
'identifier' => $field['identifier'],
'mandatory' => empty($field['mandatory']) ? 'false' : 'true',
'default_value' => !isset($field['default_value']) ? null : json_encode($field['default_value']),

Florian Azizian
committed
HistoryController::add([
'tableName' => 'indexing_models',
'recordId' => $args['id'],
'eventType' => 'UP',
'info' => _INDEXINGMODEL_MODIFICATION . " : {$body['label']}",
'moduleId' => 'indexingModel',
'eventId' => 'indexingModelModification',
]);
return $response->withStatus(204);
}
public function delete(Request $request, Response $response, array $args)
{

Florian Azizian
committed
if (!Validator::intVal()->notEmpty()->validate($args['id'])) {

Florian Azizian
committed
return $response->withStatus(400)->withJson(['errors' => 'Param id is empty or not an integer']);
}
Guillaume Heurtier
committed
$model = IndexingModelModel::getById(['select' => ['owner', 'private', '"default"', 'label'], 'id' => $args['id']]);
if (empty($model)) {
return $response->withStatus(400)->withJson(['errors' => 'Model not found']);
} elseif ($model['private'] && $model['owner'] != $GLOBALS['id']) {
return $response->withStatus(400)->withJson(['errors' => 'Model out of perimeter']);
} elseif (!$model['private'] && !PrivilegeController::hasPrivilege(['privilegeId' => 'admin_indexing_models', 'userId' => $GLOBALS['id']])) {
return $response->withStatus(400)->withJson(['errors' => 'Model out of perimeter']);
} elseif ($model['default']) {
return $response->withStatus(400)->withJson(['errors' => 'Default model can not be deleted']);
$resources = ResModel::get([
Guillaume Heurtier
committed
'select' => [1],
'where' => ['model_id = ?'],
'data' => [$args['id']]
]);
if (!empty($resources)) {
return $response->withStatus(400)->withJson(['errors' => 'Model is used by at least one resource']);
}
Guillaume Heurtier
committed
$childrenModels = IndexingModelModel::get(['select' => ['id', 'label'], 'where' => ['"master" = ?'], 'data' => [$args['id']]]);
if (!empty($childrenModels)) {
foreach ($childrenModels as $child) {
IndexingModelFieldModel::delete(['where' => ['model_id = ?'], 'data' => [$child['id']]]);
HistoryController::add([
'tableName' => 'indexing_models',
'recordId' => $child['id'],
'eventType' => 'DEL',
'info' => _INDEXINGMODEL_SUPPRESSION . " : {$child['label']}",
'moduleId' => 'indexingModel',
'eventId' => 'indexingModelSuppression',
]);
}
}

Florian Azizian
committed
Guillaume Heurtier
committed
'where' => ['(id = ? or master = ?)'],
'data' => [$args['id'], $args['id']]
]);
IndexingModelFieldModel::delete(['where' => ['model_id = ?'], 'data' => [$args['id']]]);

Florian Azizian
committed
HistoryController::add([
'tableName' => 'indexing_models',
'recordId' => $args['id'],
'eventType' => 'DEL',
'info' => _INDEXINGMODEL_SUPPRESSION . " : {$model['label']}",
'moduleId' => 'indexingModel',
'eventId' => 'indexingModelSuppression',
]);
return $response->withStatus(204);
}
public function disable(Request $request, Response $response, array $args)
{
if (!PrivilegeController::hasPrivilege(['privilegeId' => 'admin_indexing_models', 'userId' => $GLOBALS['id']])) {
return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
}
if (!Validator::intVal()->notEmpty()->validate($args['id'])) {
return $response->withStatus(400)->withJson(['errors' => 'Route id is empty or not an integer']);
}
$model = IndexingModelModel::getById(['select' => ['enabled', '"default"'], 'id' => $args['id']]);
if (empty($model)) {
return $response->withStatus(400)->withJson(['errors' => 'Model not found']);
}
if ($model['default']) {
return $response->withStatus(400)->withJson(['errors' => 'Can not disable this model because this is the default model']);
}
IndexingModelModel::update([
'set' => [
'enabled' => 'false'
],
'where' => ['id = ? or master = ?'],
'data' => [$args['id'], $args['id']]
]);
return $response->withStatus(204);
}
public function enable(Request $request, Response $response, array $args)
{
if (!PrivilegeController::hasPrivilege(['privilegeId' => 'admin_indexing_models', 'userId' => $GLOBALS['id']])) {
return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
}
if (!Validator::intVal()->notEmpty()->validate($args['id'])) {
return $response->withStatus(400)->withJson(['errors' => 'Route id is empty or not an integer']);
}
$model = IndexingModelModel::getById(['select' => ['enabled'], 'id' => $args['id']]);
if (empty($model)) {
return $response->withStatus(400)->withJson(['errors' => 'Model not found']);
}
IndexingModelModel::update([
'set' => [
'enabled' => 'true'
],
'where' => ['id = ? or master = ?'],
'data' => [$args['id'], $args['id']]
]);
return $response->withStatus(204);
}
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
public function getEntities(Request $request, Response $response, array $aArgs)
{
$entitiesTmp = EntityModel::get([
'select' => ['id', 'entity_label', 'entity_id'],
'where' => ['enabled = ?', '(parent_entity_id is null OR parent_entity_id = \'\')'],
'data' => ['Y'],
'orderBy' => ['entity_label']
]);
if (!empty($entitiesTmp)) {
foreach ($entitiesTmp as $key => $value) {
$entitiesTmp[$key]['level'] = 0;
}
$entitiesId = array_column($entitiesTmp, 'entity_id');
$entitiesChild = IndexingController::getEntitiesChildrenLevel(['entitiesId' => $entitiesId, 'level' => 1]);
$entitiesTmp = array_merge([$entitiesTmp], $entitiesChild);
}
$entities = [];
foreach ($entitiesTmp as $keyLevel => $levels) {
foreach ($levels as $entity) {
if ($keyLevel == 0) {
$entities[] = $entity;
continue;
} else {
foreach ($entities as $key => $oEntity) {
if ($oEntity['entity_id'] == $entity['parent_entity_id']) {
array_splice($entities, $key+1, 0, [$entity]);
continue;
}
}
}
}
}
return $response->withJson(['entities' => $entities]);
}