source/View/Controller/CodebookController.php line 56

Open in your IDE?
  1. <?php
  2. namespace App\View\Controller;
  3. use App\Domain\Model\Codebook\DatasetVariables;
  4. use App\Domain\Model\Filemanagement\Dataset;
  5. use App\Domain\Model\Study\MeasureMetaDataGroup;
  6. use Doctrine\Common\Collections\Collection;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use League\Csv\Reader;
  9. use League\Csv\UnableToProcessCsv;
  10. use League\Flysystem\FileNotFoundException;
  11. use League\Flysystem\Filesystem;
  12. use Psr\Log\LoggerInterface;
  13. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Symfony\Component\HttpFoundation\JsonResponse;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. /**
  20.  * @Route("/codebook", name="codebook_")
  21.  * @IsGranted("ROLE_USER")
  22.  *
  23.  * Class CodebookController
  24.  * @package App\View\Controller
  25.  */
  26. class CodebookController extends AbstractController
  27. {
  28.     protected EntityManagerInterface $em;
  29.     protected LoggerInterface $logger;
  30.     private Filesystem $filesystem;
  31.     /**
  32.      * @param EntityManagerInterface $em
  33.      * @param LoggerInterface $logger
  34.      * @param Filesystem $filesystem
  35.      */
  36.     public function __construct(EntityManagerInterface $emLoggerInterface $loggerFilesystem $filesystem)
  37.     {
  38.         $this->em $em;
  39.         $this->logger $logger;
  40.         $this->filesystem $filesystem;
  41.     }
  42.     /**
  43.      * @Route("/{uuid}", name="index")
  44.      *
  45.      * @param string $uuid
  46.      * @return Response
  47.      */
  48.     public function codebookIndexAction(string $uuid): Response
  49.     {
  50.         return $this->render('Pages/Codebook/index.html.twig', [
  51.             'codebook' => $this->em->getRepository(Dataset::class)->find($uuid),
  52.         ]);
  53.     }
  54.     /**
  55.      * @Route("/{uuid}/data", name="dataupdate")
  56.      *
  57.      * @param string $uuid
  58.      * @param Request $request
  59.      * @return JsonResponse
  60.      */
  61.     public function performUpdateAction(string $uuidRequest $request): JsonResponse
  62.     {
  63.         $this->logger->debug("Enter CodebookController::performUpdateAction with [UUID: $uuid]");
  64.         $dataset $this->em->getRepository(Dataset::class)->find($uuid);
  65.         if ($dataset && $request->isMethod("POST")) {
  66.             $postedData json_decode($request->getContent(), true);
  67.             $this->saveCodebookVariables($postedData);
  68.         }
  69.         $jsonCodebook $this->codebookCollectionToJsonArray($dataset->getCodebook());
  70.         return new JsonResponse($jsonCodebook$jsonCodebook != null && sizeof($jsonCodebook) > Response::HTTP_OK Response::HTTP_NO_CONTENT);
  71.     }
  72.     /**
  73.      * @Route("/{uuid}/measures", name="measures")
  74.      *
  75.      * @param string $uuid
  76.      * @return JsonResponse
  77.      */
  78.     public function createViewMeasuresAction(string $uuid): JsonResponse
  79.     {
  80.         $this->logger->debug("Enter CodebookController::createViewMeasuresAction with [UUID: $uuid]");
  81.         $dataset $this->em->getRepository(Dataset::class)->find($uuid);
  82.         $viewMeasures = [];
  83.         if ($dataset) {
  84.             $measures $this->em->getRepository(MeasureMetaDataGroup::class)->findOneBy(['experiment' => $dataset->getExperiment()]);
  85.             if ($measures && $measures->getMeasures() && sizeof($measures->getMeasures()) > 0) {
  86.                 $viewMeasures = [];
  87.                 foreach ($measures->getMeasures() as $measure) {
  88.                     if ($measure && "" != $measure) {
  89.                         $viewMeasures['measures'][] = $measure;
  90.                     }
  91.                 }
  92.             }
  93.         }
  94.         return new JsonResponse($viewMeasureskey_exists('measures'$viewMeasures) ? Response::HTTP_OK Response::HTTP_NO_CONTENT);
  95.     }
  96.     /**
  97.      * @Route("/{uuid}/matrix", name="matrix")
  98.      *
  99.      * @param string $uuid
  100.      * @return JsonResponse
  101.      */
  102.     public function datasetMatrixAction(Request $requeststring $uuid): JsonResponse
  103.     {
  104.         $size $request->get('size') ?? 0;
  105.         $page $request->get('page') ?? 1;
  106.         $this->logger->debug("Enter CodebookController::datasetMatrixAction with [UUID: $uuid]");
  107.         $dataset $this->em->getRepository(Dataset::class)->find($uuid);
  108.         $response null;
  109.         if ($dataset) {
  110.             foreach ($dataset->getCodebook() as $var) {
  111.                 $response['header'][] = $var->getName();
  112.             }
  113.         }
  114.         if ($this->filesystem->has("matrix/".$uuid.".csv")) {
  115.             try {
  116.                 $file Reader::createFromString($this->filesystem->read("matrix/".$uuid.".csv"));
  117.                 if ($file->count() != 0) {
  118.                     if (== $size) {
  119.                         $response['content'] = $file;
  120.                         $response['pagination']['max_items'] = $file->count();
  121.                         $response['pagination']['items'] = $file->count();
  122.                         $response['pagination']['current_page'] = 1;
  123.                         $response['pagination']['max_pages'] = 1;
  124.                     } else {
  125.                         $min != $page ? ($page 1) * $size 0;
  126.                         $max $min $size;
  127.                         for ($count $min$count $max$count++) {
  128.                             $response['content'][] = $file->fetchOne($count);
  129.                         }
  130.                         $response['pagination']['max_items'] = $file->count();
  131.                         $response['pagination']['items'] = $size;
  132.                         $response['pagination']['current_page'] = $page;
  133.                         $response['pagination']['max_pages'] = ceil(!= $file->count() ? ($file->count() / $size) : 0);
  134.                     }
  135.                 } else {
  136.                     $response['error'] = 'error.dataset.matrix.empty';
  137.                 }
  138.             } catch (FileNotFoundException $e) {
  139.                 $this->logger->critical("FileNotFoundException in CodebookController::createViewMeasuresAction [UUID: $uuid] Exception: ".$e->getMessage());
  140.                 $response['error'] = 'error.dataset.matrix.notFound';
  141.             } catch (UnableToProcessCsv $e) {
  142.                 $this->logger->critical("UnableToProcessCsv in CodebookController::createViewMeasuresAction [UUID: $uuid] Exception: ".$e->getMessage());
  143.                 $response['error'] = 'error.dataset.matrix.unprocessable';
  144.             }
  145.         }
  146.         return new JsonResponse(
  147.             $response,
  148.             key_exists('error'$response) && !empty($response['error']) ? Response::HTTP_UNPROCESSABLE_ENTITY Response::HTTP_OK
  149.         );
  150.     }
  151.     /**
  152.      * @param Collection|null $codebook
  153.      * @return null|array
  154.      */
  155.     private function codebookCollectionToJsonArray(?Collection $codebook): ?array
  156.     {
  157.         $jsonCodebook null;
  158.         if ($codebook && is_iterable($codebook)) {
  159.             $jsonCodebook = [];
  160.             foreach ($codebook as $var) {
  161.                 $jsonCodebook['variables'][] = [
  162.                     "id" => $var->getVarId(),
  163.                     "name" => $var->getName() ?? "",
  164.                     "label" => $var->getLabel() ?? "",
  165.                     "itemText" => $var->getItemText() ?? "",
  166.                     "values" => $var->getValues() ?? [
  167.                             [
  168.                                 "name" => "",
  169.                                 "label" => "",
  170.                             ],
  171.                         ],
  172.                     "missings" => $var->getMissings() ?? [
  173.                             [
  174.                                 "name" => "",
  175.                                 "label" => "",
  176.                             ],
  177.                         ],
  178.                     "measure" => $var->getMeasure() ?? "",
  179.                     "var_db_id" => $var->getId(),
  180.                 ];
  181.             }
  182.         }
  183.         return $jsonCodebook;
  184.     }
  185.     /**
  186.      * @param array $arr
  187.      */
  188.     private function saveCodebookVariables(array $arr)
  189.     {
  190.         if ($arr && is_iterable($arr) && key_exists('variables'$arr) && !empty($arr['variables']) && is_iterable($arr['variables'])) {
  191.             foreach ($arr['variables'] as $variable) {
  192.                 if (key_exists("var_db_id"$variable)) {
  193.                     $values $variable["values"] ? $this->setMissingArrayFields(array_values(array_filter($variable["values"]))) : null;
  194.                     $missings $variable["missings"] ? $this->setMissingArrayFields(array_values(array_filter($variable["missings"]))) : null;
  195.                     $var $this->em->getRepository(DatasetVariables::class)->find($variable["var_db_id"]);
  196.                     $var->setName($variable["name"] ?? $var->getName());
  197.                     $var->setLabel($variable["label"] ?? null);
  198.                     $var->setItemText($variable["itemText"] ?? null);
  199.                     $var->setValues(null != $values && != sizeof($values) ? $values null);
  200.                     $var->setMissings(null != $missings && != sizeof($missings) ? $missings null);
  201.                     $var->setMeasure($variable["measure"] ?? null);
  202.                     $this->em->persist($var);
  203.                     $this->em->flush();
  204.                 }
  205.             }
  206.         }
  207.     }
  208.     private function setMissingArrayFields(?array $arr): ?array
  209.     {
  210.         if (null != $arr) {
  211.             foreach ($arr as &$item) {
  212.                 if (key_exists('name'$item) && !key_exists('label'$item)) {
  213.                     $item['label'] = '';
  214.                 }
  215.                 if (!key_exists('name'$item) && key_exists('label'$item)) {
  216.                     $item['name'] = '';
  217.                 }
  218.             }
  219.         }
  220.         return $arr;
  221.     }
  222. }