Commit c038dea1 authored by François Agneray's avatar François Agneray
Browse files

Merge branch '27-fusionner-la-table-option-dans-la-table-attribute-json' into 'develop'

Resolve "Changement de la base metamodel (simplification)"

Closes #27

See merge request !24
parents fdae4652 de55f291
Pipeline #1225 passed with stages
in 4 minutes and 23 seconds
UID := $(shell id -u)
GID := $(shell id -g)
UID := $(id -u)
GID := $(id -g)
list:
@echo ""
......@@ -15,6 +15,7 @@ list:
@echo " phpunit > run php unit test suite"
@echo " phpcs > run php code sniffer test suite"
@echo " init-db > generate a new metadata database (anis-v3-server containers running needed)"
@echo " remove-db > remove the metadata database"
@echo " validate-db > validate the doctrine mapping entity files (anis-v3-server containers running needed)"
@echo " add-superuser > add an Anis server superuser. Example: make email=admin@anis.fr password=admin add-superuser"
@echo " gen-key > generate a new encryption key that you can use to encrypt data (see anis server config file)"
......@@ -58,6 +59,9 @@ phpcs:
init-db:
@docker-compose exec php sh ./conf-dev/metamodel_init.sh
remove-db:
@docker volume rm anis-server_pgdata
validate-db:
@docker-compose exec php ./vendor/bin/doctrine orm:validate-schema
......
documentation/mcd/anis_v3_mcd.png

142 KB | W: | H:

documentation/mcd/anis_v3_mcd.png

91.6 KB | W: | H:

documentation/mcd/anis_v3_mcd.png
documentation/mcd/anis_v3_mcd.png
documentation/mcd/anis_v3_mcd.png
documentation/mcd/anis_v3_mcd.png
  • 2-up
  • Swipe
  • Onion skin
http://www.mocodo.net/
dataset_family: id, label, description, display
output_family: id, label
DF9, 11 dataset_x_outputfamily, 0N output_family
database: id, label, dbname, type, host, port, login, password
DF, 0N database, 11 project
project: name, label, description, link, manager
DF, 0N database, 11 project
database: id, label, dbname, type, host, port, login, password
DF1, 0N project, 11 dataset
DF2, ON dataset_family, 11 dataset
DF8, 11 dataset_x_outputfamily, 0N dataset
dataset_x_outputfamily: id, display
dataset_outputfamily_x_category, 0N dataset_x_outputfamily, 0N category, 01 attribute: display
category: id, label
dataset_family: id, label, description, display
output_family: id, label, display
DF8, 11 output_category, 0N output_family
file: id, label, file_loc, type, display, visible
DF5, ON dataset, 11 file
dataset: name, table_ref, label, description, illustration, display, count, vo, data_path
dataset: name, table_ref, label, description, display, count, vo, data_path
DF4, 0N dataset, 11 attribute
attribute: id, name, table_name, label, form_label, description, output_display, criteria_display, search_flag, search_type, operator, type, min, max, placeholder_min, placeholder_max, uri_action, renderer, display_detail, selected, order_by, order_display, detail, renderer_detail, vo_utype, vo_ucd, vo_unit, vo_description, vo_datatype, vo_size
DF6, ON attribute, 11 option
option: id, label, value, display
join: id, table_ref, attribute_ref, table_join, attribute_join, rank
DF3, ON dataset, 11 join
attribute: id, name, table_name, label, form_label, description, output_display, criteria_display, search_flag, search_type, operator, type, min, max, placeholder_min, placeholder_max, uri_action, renderer, display_detail, selected, order_by, order_display, detail, renderer_detail, options, vo_utype, vo_ucd, vo_unit, vo_description, vo_datatype, vo_size
DF9, 0N output_category, 01 attribute
output_category: id, label, display
dataset_privileges, 0N anis_group, 0N dataset: visible, create_row, delete_row
dataset_privileges, 0N anis_group, 0N dataset: visible
anis_group: id, label
criteria_family: id, label
dataset_x_criteriafamily, 0N dataset, 0N criteria_family, 01 attribute: display
criteria_family: id, label, display
DF3, 0N criteria_family, 01 attribute
DF7, 0N anis_group, 11 anis_user
anis_user: email, password, activation_key, activated, adminsi, superuser
anis_user: email, password, activation_key, activated, adminsi, superuser
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Action\Meta;
use Psr\Log\LoggerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use App\Utils\ActionTrait;
use App\Entity\Dataset;
use App\Entity\Attribute;
use App\Entity\CriteriaFamily;
use App\Entity\OutputCategory;
final class AttributeAction
{
use ActionTrait;
private $logger;
private $em;
public function __construct(LoggerInterface $logger, EntityManagerInterface $em)
{
$this->logger = $logger;
$this->em = $em;
}
public function __invoke(Request $request, Response $response, array $args): Response
{
$this->logger->info('Attribute list action dispatched');
if ($request->isOptions()) {
return $response->withHeader('Access-Control-Allow-Methods', 'GET, PUT, OPTIONS');
}
$attribute = $this->em->getRepository('App\Entity\Attribute')->findOneBy(array('dataset' => $args['name'], 'id' => $args['id']));
if (is_null($attribute)) {
return $this->dispatchHttpError(
$response,
'Invalid request',
'Attribute with dataset name ' . $args['name'] . ' and attribute id ' . $args['id'] . 'is not found'
)->withStatus(404);
}
if ($request->isGet()) {
$newResponse = $response->withJson($attribute);
}
if ($request->isPut()) {
$parsedBody = $request->getParsedBody();
$criteriaFamily = is_null($parsedBody['id_criteria_family']) ? null : $this->em->find('App\Entity\CriteriaFamily', $parsedBody['id_criteria_family']);
$outputCategory = is_null($parsedBody['id_output_category']) ? null : $this->em->find('App\Entity\OutputCategory', $parsedBody['id_output_category']);
$this->editAttribute($attribute, $parsedBody, $criteriaFamily, $outputCategory);
$this->em->flush();
$newResponse = $response->withJson($attribute);
}
return $newResponse;
}
private function editAttribute(Attribute $attribute, array $parsedBody, CriteriaFamily $criteriaFamily = null, OutputCategory $outputCategory = null): void
{
$attribute->setLabel($parsedBody['label']);
$attribute->setFormLabel($parsedBody['form_label']);
$attribute->setDescription($parsedBody['description']);
$attribute->setOutputDisplay($parsedBody['output_display']);
$attribute->setCriteriaDisplay($parsedBody['criteria_display']);
$attribute->setSearchFlag($parsedBody['search_flag']);
$attribute->setSearchType($parsedBody['search_type']);
$attribute->setOperator($parsedBody['operator']);
$attribute->setType($parsedBody['type']);
$attribute->setMin($parsedBody['min']);
$attribute->setMax($parsedBody['max']);
$attribute->setPlaceholderMin($parsedBody['placeholder_min']);
$attribute->setPlaceholderMax($parsedBody['placeholder_max']);
$attribute->setUriAction($parsedBody['uri_action']);
$attribute->setRenderer($parsedBody['renderer']);
$attribute->setDisplayDetail($parsedBody['display_detail']);
$attribute->setSelected($parsedBody['selected']);
$attribute->setOrderBy($parsedBody['order_by']);
$attribute->setOrderDisplay($parsedBody['order_display']);
$attribute->setDetail($parsedBody['detail']);
$attribute->setRendererDetail($parsedBody['renderer_detail']);
$attribute->setOptions($parsedBody['options']);
$attribute->setVoUtype($parsedBody['vo_utype']);
$attribute->setVoUcd($parsedBody['vo_ucd']);
$attribute->setVoUnit($parsedBody['vo_unit']);
$attribute->setVoDescription($parsedBody['vo_description']);
$attribute->setVoDatatype($parsedBody['vo_datatype']);
$attribute->setVoSize($parsedBody['vo_size']);
$attribute->setCriteriaFamily($criteriaFamily);
$attribute->setOutputCategory($outputCategory);
}
}
......@@ -16,6 +16,10 @@ use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use App\Utils\ActionTrait;
use App\Entity\Dataset;
use App\Entity\Attribute;
use App\Entity\CriteriaFamily;
use App\Entity\OutputCategory;
final class AttributeListAction
{
......@@ -23,31 +27,19 @@ final class AttributeListAction
private $logger;
private $em;
private $datasetCriteriaFamilyMaxDisplay;
private $datasetCriteriaFamilyList;
private $datasetOutputFamilyMaxDisplay;
private $datasetOutputFamilyList;
private $datasetOutputFamilyCategoryMaxDisplay;
private $datasetOutputFamilyCategoryList;
public function __construct(LoggerInterface $logger, EntityManagerInterface $em)
{
$this->logger = $logger;
$this->em = $em;
$this->datasetCriteriaFamilyMaxDisplay = 0;
$this->datasetCriteriaFamilyList = array();
$this->datasetOutputFamilyMaxDisplay = 0;
$this->datasetOutputFamilyList = array();
$this->datasetOutputFamilyCategoryMaxDisplay = array();
$this->datasetOutputFamilyCategoryList = array();
}
public function __invoke(Request $request, Response $response, array $args): Response
{
$this->logger->info('Category action dispatched');
$this->logger->info('Attribute list action dispatched');
if ($request->isOptions()) {
return $response->withHeader('Access-Control-Allow-Methods', 'GET, PUT, OPTIONS');
return $response->withHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
}
$dataset = $this->em->find('App\Entity\Dataset', $args['name']);
......@@ -67,176 +59,7 @@ final class AttributeListAction
}
$newResponse = $response->withJson($attributes);
}
if ($request->isPut()) {
$this->deleteDatasetCriteriaFamily($dataset);
$this->deleteDatasetOutputFamily($dataset);
$parsedBody = $request->getParsedBody();
foreach ($parsedBody as $datum) {
$attribute = $this->em->getRepository('App\Entity\Attribute')->findBy(array('id' => $datum['id'], 'dataset' => $dataset))[0];
$this->editAttribute($dataset, $attribute, $datum);
}
$this->em->flush();
$attributes = $dataset->getAttributes();
$newResponse = $response->withJson($attributes);
}
return $newResponse;
}
private function editAttribute($dataset, $attribute, $datum): void
{
$attribute->setLabel($datum['label']);
$attribute->setFormLabel($datum['form_label']);
$attribute->setDescription($datum['description']);
$attribute->setOutputDisplay($datum['output_display']);
$attribute->setCriteriaDisplay($datum['criteria_display']);
$attribute->setSearchFlag($datum['search_flag']);
$attribute->setSearchType($datum['search_type']);
$attribute->setOperator($datum['operator']);
$attribute->setType($datum['type']);
$attribute->setMin($datum['min']);
$attribute->setMax($datum['max']);
$attribute->setPlaceholderMin($datum['placeholder_min']);
$attribute->setPlaceholderMax($datum['placeholder_max']);
$attribute->setUriAction($datum['uri_action']);
$attribute->setRenderer($datum['renderer']);
$attribute->setDisplayDetail($datum['display_detail']);
$attribute->setSelected($datum['selected']);
$attribute->setOrderBy($datum['order_by']);
$attribute->setOrderDisplay($datum['order_display']);
$attribute->setDetail($datum['detail']);
$attribute->setRendererDetail($datum['renderer_detail']);
$attribute->setVoUtype($datum['vo_utype']);
$attribute->setVoUcd($datum['vo_ucd']);
$attribute->setVoUnit($datum['vo_unit']);
$attribute->setVoDescription($datum['vo_description']);
$attribute->setVoDatatype($datum['vo_datatype']);
$attribute->setVoSize($datum['vo_size']);
$idCriteriaFamily = array_key_exists('id_criteria_family', $datum) ? $datum['id_criteria_family'] : null;
$this->editAttributeCriteriaFamily($dataset, $attribute, $idCriteriaFamily);
$idOutputFamily = array_key_exists('id_output_family', $datum) ? $datum['id_output_family'] : null;
$idCategory = array_key_exists('id_category', $datum) ? $datum['id_category'] : null;
$this->editAttributeOutputFamilyCategory($dataset, $attribute, $idOutputFamily, $idCategory);
$this->editOptions($attribute, $datum['options']);
}
private function deleteDatasetCriteriaFamily($dataset): void
{
foreach ($dataset->getAttributes() as $attribute) {
$attribute->setDatasetCriteriaFamily(null);
}
foreach ($dataset->getDatasetCriteriaFamilies() as $datasetCriteriaFamily) {
$this->em->remove($datasetCriteriaFamily);
}
$this->em->flush();
}
private function deleteDatasetOutputFamily($dataset): void
{
foreach ($dataset->getAttributes() as $attribute) {
$attribute->setDatasetOutputFamilyCategory(null);
}
foreach ($dataset->getDatasetOutputFamilies() as $datasetOutputFamily) {
$this->em->remove($datasetOutputFamily);
}
$this->em->flush();
}
private function editAttributeCriteriaFamily($dataset, $attribute, $idCriteriaFamily): void
{
if (is_null($idCriteriaFamily)) {
if ($attribute->getDatasetCriteriaFamily()) {
$attribute->setDatasetCriteriaFamily(null);
}
return ;
}
if (array_key_exists($idCriteriaFamily, $this->datasetCriteriaFamilyList)) {
$datasetCriteriaFamily = $this->datasetCriteriaFamilyList[$idCriteriaFamily];
} else {
$this->datasetCriteriaFamilyMaxDisplay += 10;
$criteriaFamily = $this->em->find('App\Entity\CriteriaFamily', $idCriteriaFamily);
$datasetCriteriaFamily = new \App\Entity\DatasetCriteriaFamily($dataset, $criteriaFamily);
$datasetCriteriaFamily->setDisplay($this->datasetCriteriaFamilyMaxDisplay);
$this->em->persist($datasetCriteriaFamily);
$this->datasetCriteriaFamilyList[$idCriteriaFamily] = $datasetCriteriaFamily;
}
$attribute->setDatasetCriteriaFamily($datasetCriteriaFamily);
}
private function getCriteriaFamilyMaxDisplay($dataset)
{
$qb = $this->em->createQueryBuilder();
$qb->select($qb->expr()->max('e.display'))
->from('App\Entity\DatasetCriteriaFamily', 'e')
->where('e.dataset = ?1')
->setParameter(1, $dataset);
$single = $qb->getQuery()->getSingleScalarResult();
if (is_null($single)) {
return 0;
} else {
return $single;
}
}
private function editAttributeOutputFamilyCategory($dataset, $attribute, $idOutputFamily, $idCategory): void
{
if (is_null($idOutputFamily) || is_null($idCategory)) {
if ($attribute->getDatasetOutputFamilyCategory()) {
$attribute->setDatasetOutputFamilyCategory(null);
}
return ;
}
if (array_key_exists($idOutputFamily, $this->datasetOutputFamilyList)) {
$datasetOutputFamily = $this->datasetOutputFamilyList[$idOutputFamily];
} else {
$this->datasetOutputFamilyMaxDisplay += 10;
$outputFamily = $this->em->find('App\Entity\OutputFamily', $idOutputFamily);
$datasetOutputFamily = new \App\Entity\DatasetOutputFamily($dataset, $outputFamily);
$datasetOutputFamily->setDisplay($this->datasetOutputFamilyMaxDisplay);
$this->em->persist($datasetOutputFamily);
$this->datasetOutputFamilyList[$idOutputFamily] = $datasetOutputFamily;
$this->datasetOutputFamilyCategoryList[$idOutputFamily] = array();
$this->datasetOutputFamilyCategoryMaxDisplay[$idOutputFamily] = 0;
}
if (array_key_exists($idCategory, $this->datasetOutputFamilyCategoryList[$idOutputFamily])) {
$datasetOutputFamilyCategory = $this->datasetOutputFamilyCategoryList[$idOutputFamily][$idCategory];
} else {
$this->datasetOutputFamilyCategoryMaxDisplay[$idOutputFamily] += 10;
$category = $this->em->find('App\Entity\Category', $idCategory);
$datasetOutputFamilyCategory = new \App\Entity\DatasetOutputFamilyCategory($datasetOutputFamily, $category);
$datasetOutputFamilyCategory->setDisplay($this->datasetOutputFamilyCategoryMaxDisplay[$idOutputFamily]);
$this->em->persist($datasetOutputFamilyCategory);
$this->datasetOutputFamilyCategoryList[$idOutputFamily][$idCategory] = $datasetOutputFamilyCategory;
}
$attribute->setDatasetOutputFamilyCategory($datasetOutputFamilyCategory);
}
private function editOptions($attribute, $options): void
{
if (empty($attribute->getOptions()) && empty($options)) {
return ;
}
foreach ($attribute->getOptions() as $option) {
$this->em->remove($option);
}
foreach ($options as $option) {
$newOption = new \App\Entity\Option($attribute);
$newOption->setLabel($option['label']);
$newOption->setValue($option['value']);
$newOption->setDisplay($option['display']);
$this->em->persist($newOption);
}
}
}
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Action\Meta;
use Psr\Log\LoggerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use App\Utils\ActionTrait;
final class DatasetCriteriaFamilyListAction
{
use ActionTrait;
private $logger;
private $em;
public function __construct(LoggerInterface $logger, EntityManagerInterface $em)
{
$this->logger = $logger;
$this->em = $em;
}
public function __invoke(Request $request, Response $response, array $args): Response
{
$this->logger->info('Dataset criteria family list action dispatched');
if ($request->isOptions()) {
return $response->withHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
}
$dataset = $this->em->find('App\Entity\Dataset', $args['name']);
if (is_null($dataset)) {
return $this->dispatchHttpError(
$response,
'Invalid request',
'Dataset with name ' . $args['name'] . ' is not found'
)->withStatus(404);
}
if ($request->isGet()) {
$datasetCriteriaFamilies = $dataset->getDatasetCriteriaFamilies()->getValues();
$newResponse = $response->withJson($datasetCriteriaFamilies);
}
return $newResponse;
}
}
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Action\Meta;
use Psr\Log\LoggerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use App\Utils\ActionTrait;
final class DatasetOutputFamilyListAction
{
use ActionTrait;
private $logger;
private $em;
public function __construct(LoggerInterface $logger, EntityManagerInterface $em)
{
$this->logger = $logger;
$this->em = $em;
}
public function __invoke(Request $request, Response $response, array $args): Response
{
$this->logger->info('Dataset output family list action dispatched');
if ($request->isOptions()) {
return $response->withHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
}
$dataset = $this->em->find('App\Entity\Dataset', $args['name']);
if (is_null($dataset)) {
return $this->dispatchHttpError(
$response,
'Invalid request',
'Dataset with name ' . $args['name'] . ' is not found'
)->withStatus(404);
}
if ($request->isGet()) {
$datasetOutputFamilies = $dataset->getDatasetOutputFamilies()->getValues();
$newResponse = $response->withJson($datasetOutputFamilies);
}
return $newResponse;
}
}
......@@ -67,10 +67,7 @@ final class FamilyAction
$parsedBody = $request->getParsedBody();
// Vérification des champs vides
$fields = array('label');
if ($type === 'dataset') {
$fields = array_merge(array('description', 'display'), $fields);
}
$fields = array('label', 'display');
foreach ($fields as $a) {
if ($this->isEmptyField($a, $parsedBody)) {
return $this->dispatchHttpError(
......@@ -127,10 +124,7 @@ final class FamilyAction
private function editFamily(Object $family, array $parsedBody): void
{
$family->setLabel($parsedBody['label']);
if ($family instanceof \App\Entity\DatasetFamily) {
$family->setDescription($parsedBody['description']);
$family->setDisplay($parsedBody['display']);
}
$family->setDisplay($parsedBody['display']);
$this->em->flush();
}
}
......@@ -61,10 +61,7 @@ final class FamilyListAction
$parsedBody = $request->getParsedBody();
// Vérification des champs vides
$fields = array('label');
if ($type === 'dataset') {
$fields = array_merge(array('description', 'display'), $fields);
}
$fields = array('label', 'display');
foreach ($fields as $a) {
if ($this->isEmptyField($a, $parsedBody)) {
return $this->dispatchHttpError(
......@@ -102,10 +99,7 @@ final class FamilyListAction
{
$family = new $class;
$family->setLabel($parsedBody['label']);
if ($family instanceof \App\Entity\DatasetFamily) {
$family->setDescription($parsedBody['description']);
$family->setDisplay($parsedBody['display']);
}
$family->setDisplay($parsedBody['display']);
$this->em->persist($family);
$this->em->flush();
......
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Action\Meta;
use Psr\Log\LoggerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use App\Utils\ActionTrait;