* (c) Chrystel Moreau * * 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 Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; use App\Utils\ActionTrait; use App\Utils\DBALConnectionFactory; use App\Utils\MetaEntityManagerFactory; use App\Entity\Metamodel\Dataset; use App\Entity\Metamodel\Attribute; use App\Entity\Metamodel\Project; use App\Entity\Metamodel\DatasetFamily; /** * Route: /metadata/dataset * * This action is used to: * - Get all datasets * - Add a new dataset * * @author François Agneray * @package App\Action\Meta */ final class DatasetListAction { use ActionTrait; /** * The logger interface is the central access point to log anis information * * @var LoggerInterface */ private $logger; /** * The MetaEntityManagerFactory create the doctrine entity manager for the metamodel database. * The entity manager is the central access point to Doctrine ORM functionality (metadata database) * * @var MetaEntityManagerFactory */ private $memf; /** * Factory that provides a connection to the business database * * @var DBALConnectionFactory */ private $dcf; /** * The key needed to decrypt the password of the database * * @var string */ private $encryptionKey; /** * Create the classe before call __invoke to execute the action * * @param LoggerInterface $logger * @param MetaEntityManagerFactory $memf * @param DBALConnectionFactory $dcf * @param string $encryptionKey */ public function __construct( LoggerInterface $logger, MetaEntityManagerFactory $memf, DBALConnectionFactory $dcf, string $encryptionKey ) { $this->logger = $logger; $this->memf = $memf; $this->dcf = $dcf; $this->encryptionKey = $encryptionKey; } /** * `GET` Returns the list of datasets * `POST` Add a new dataset. The program will search the business database for * the columns of the table (table_ref) to transform them into attributes * * @param ServerRequestInterface $request This object contains the HTTP request * @param ResponseInterface $response This object represents the HTTP response * @param string[] $args This table contains information transmitted in the URL (see routes.php) * * @return ResponseInterface */ public function __invoke(Request $request, Response $response, array $args): Response { $this->logger->info('Dataset list action dispatched'); if ($request->isOptions()) { return $response->withHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); } // Create the doctrine Entity Manager object for the instance metamodel database $this->memf->createMetaEntityManager($args['instance']); if ($request->isGet()) { $datasets = $this->memf->getMetaEntityManager()->getRepository('App\Entity\Metamodel\Dataset')->findBy( array(), array('display' => 'ASC') ); $newResponse = $response->withJson($datasets); } if ($request->isPost()) { $parsedBody = $request->getParsedBody(); // If mandatories empty fields 400 $fields = array( 'name', 'table_ref', 'label', 'description', 'display', 'count', 'vo', 'data_path', 'selectable_row', 'project_name', 'id_dataset_family' ); foreach ($fields as $a) { if ($this->isEmptyField($a, $parsedBody)) { return $this->dispatchHttpError( $response, 'Invalid request', 'Param ' . $a . ' needed to add a new dataset' ); } } $project = $this->memf->getMetaEntityManager()->find( 'App\Entity\Metamodel\Project', $parsedBody['project_name'] ); if (is_null($project)) { return $this->dispatchHttpError( $response, 'Invalid request', 'Project with name ' . $parsedBody['project_name'] . ' is not found' )->withStatus(404); } $family = $this->memf->getMetaEntityManager()->find( 'App\Entity\Metamodel\DatasetFamily', $parsedBody['id_dataset_family'] ); if (is_null($family)) { return $this->dispatchHttpError( $response, 'Invalid request', 'Dataset family with id ' . $parsedBody['id_dataset_family'] . ' is not found' )->withStatus(404); } $dataset = $this->postDataset($parsedBody, $project, $family); $newResponse = $response->withJson($dataset); } return $newResponse; } /** * Create a new dataset doctrine object and save it * * @param string[] $parsedBody Contains the values ​​of the new dataset sent by the user * @param Project $project Contains the project doctrine object * @param DatasetFamily $datasetFamily Contains the dataset family doctrine object * * @return Dataset */ private function postDataset(array $parsedBody, Project $project, DatasetFamily $family): Dataset { $dataset = new Dataset($parsedBody['name']); $dataset->setTableRef($parsedBody['table_ref']); $dataset->setLabel($parsedBody['label']); $dataset->setDescription($parsedBody['description']); $dataset->setDisplay($parsedBody['display']); $dataset->setCount($parsedBody['count']); $dataset->setVo($parsedBody['vo']); $dataset->setDataPath($parsedBody['data_path']); $dataset->setSelectableRow($parsedBody['selectable_row']); $dataset->setProject($project); $dataset->setDatasetFamily($family); $this->memf->getMetaEntityManager()->persist($dataset); $this->postAttributes($dataset); $this->memf->getMetaEntityManager()->flush(); return $dataset; } /** * Access to the business database dans get all the columns of the table (table_ref) * and makes the corresponding doctrine attribute objects * * @param Dataset $dataset Contains the new dataset doctrine object */ private function postAttributes(Dataset $dataset): void { $database = $dataset->getProject()->getDatabase(); $decryptedPassword = $this->decryptData($database->getPassword()); $connection = $this->dcf->create($database, $decryptedPassword); $sm = $connection->getSchemaManager(); $columns = $sm->listTableColumns($dataset->getTableRef()); $i = 10; $id = 1; foreach ($columns as $column) { $columnName = $column->getName(); $columnType = $column->getType()->getName(); $attribute = new Attribute($id, $dataset); $attribute->setName($columnName); $attribute->setTableName($dataset->getTableRef()); $attribute->setLabel($columnName); $attribute->setFormLabel($columnName); $attribute->setType($columnType); $attribute->setCriteriaDisplay($i); $attribute->setOutputDisplay($i); $attribute->setDisplayDetail($i); $attribute->setOrderDisplay($i); $attribute->setSelected(true); $this->memf->getMetaEntityManager()->persist($attribute); $i = $i + 10; $id++; } } }