src/OceanExpertBundle/Controller/DefaultController.php line 121

Open in your IDE?
  1. <?php
  2. namespace OceanExpertBundle\Controller;
  3. use Doctrine\ORM\AbstractQuery;
  4. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  5. use Symfony\Component\HttpFoundation\JsonResponse;
  6. use Symfony\Component\HttpFoundation\Request;
  7. use Symfony\Component\HttpFoundation\Response;
  8. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  9. use Symfony\Component\Security\Core\Security;
  10. use Symfony\Component\Security\Core\SecurityContextInterface;
  11. class DefaultController extends AbstractController
  12. {
  13.     /**
  14.      * @param Request $request
  15.      *
  16.      * @return Response
  17.      */
  18.     public function indexAction(Request $request): Response
  19.     {
  20.         // this should be handled already by nelmio_cors package
  21.         // see config/packages/nelmio_cors.yaml
  22.         // see https://github.com/iobis/web/issues/133
  23.         // header('Access-Control-Allow-Origin: *');
  24.         $session $request->getSession();
  25.         $authErrorKey Security::AUTHENTICATION_ERROR;
  26.         $lastUsernameKey Security::LAST_USERNAME;
  27.         // get the error if any (works with forward and redirect -- see below)
  28.         if ($request->attributes->has($authErrorKey)) {
  29.             $error $request->attributes->get($authErrorKey);
  30.         } elseif (null !== $session
  31.             && $session->has($authErrorKey)
  32.         ) {
  33.             $error $session->get($authErrorKey);
  34.             $session->remove($authErrorKey);
  35.         } else {
  36.             $error null;
  37.         }
  38.         if (!$error instanceof AuthenticationException) {
  39.             $error null// The value does not come from the security component.
  40.         }
  41.         // last username entered by the user
  42.         $lastUsername = (null === $session) ? '' $session->get($lastUsernameKey);
  43.         if ($request->attributes->has($authErrorKey)) {
  44.             $error $request->attributes->get($authErrorKey);
  45.         } elseif (null !== $session
  46.             && $session->has($authErrorKey)
  47.         ) {
  48.             $error $session->get($authErrorKey);
  49.             $session->remove($authErrorKey);
  50.         } else {
  51.             $error null;
  52.         }
  53.         if ($this->has('security.csrf.token_manager')) {
  54.             $csrfToken $this->get('security.csrf.token_manager')
  55.                 ->getToken('authenticate')
  56.                 ->getValue();
  57.         } else {
  58.             // BC for SF < 2.4
  59.             $csrfToken $this->has('form.csrf_provider')
  60.                 ? $this->get('form.csrf_provider')
  61.                     ->generateCsrfToken('authenticate')
  62.                 : null;
  63.         }
  64.         $indSeaAreas = array();
  65.         $instSeaAreas = array();
  66.         $subjects = array();
  67.         $instType = array();
  68.         $resultLname = array();
  69.         $countryList = array();
  70.         $instNameList = array();
  71.         $instCountryList = array();
  72.         $searchOptions['indSeas'] = $indSeaAreas;
  73.         $searchOptions['instSeas'] = $instSeaAreas;
  74.         $searchOptions['subjects'] = $subjects;
  75.         $searchOptions['instType'] = $instType;
  76.         $searchOptions['expertLname'] = $resultLname;
  77.         $searchOptions['countryNames'] = $countryList;
  78.         $searchOptions['instName'] = $instNameList;
  79.         $searchOptions['instCountryList'] = $instCountryList;
  80.         $noresult = array();
  81.         if (null !== $request->attributes->get('noresult')) {
  82.             $noresult['message'] = $request->attributes->get('noresult');
  83.             $noresult['query'] = $request->attributes->get('query');
  84.         }
  85.         return $this->render(
  86.             'index.html.twig',
  87.             array(
  88.                 'last_username' => $lastUsername,
  89.                 'error' => $error,
  90.                 'csrf_token' => $csrfToken,
  91.                 'searchOptions' => $searchOptions,
  92.                 'noresult' => $noresult,
  93.             )
  94.         );
  95.     }
  96.     /**
  97.      * show some stats about OE
  98.      * - number of experts
  99.      * - number of institutes
  100.      * - number of events
  101.      * - number of documents
  102.      *
  103.      * @return Response
  104.      */
  105.     public function statisticsAction(): Response
  106.     {
  107.         //get info about the countries
  108.         $countryInfo = array();
  109.         $countries $this->getDoctrine()
  110.             ->getManager()
  111.             ->getRepository('OceanExpertBundle:Countries')
  112.             ->findAll();
  113.         $data = array();
  114.         $em $this->getDoctrine()->getManager();
  115.         //info about the number of experts
  116.         $qb $em->createQueryBuilder();
  117.         $expr $qb->expr();
  118.         $qb->select(
  119.             'count(i.idInd)'
  120.         )->from(
  121.             'OceanExpertBundle:Indiv',
  122.             'i'
  123.         )->where(
  124.             'i.status = 1'
  125.         )->andWhere(
  126.             $expr->neq('i.deceased'1)
  127.         );
  128.         $data['countExperts'] = $qb->getQuery()->getSingleScalarResult();
  129.         //info about the number of experts per country
  130.         //this is done in 2 steps as we need those with their own address
  131.         //and those that use the address of their institute
  132.         $data['expertsPerCountry'] = $this->getExpertsPerCountry();
  133.         //info about the number of institutes
  134.         $qb $em->createQueryBuilder();
  135.         $qb->select('count(i.idInst)');
  136.         $qb->from('OceanExpertBundle:Institutions''i');
  137.         $qb->where('i.activated = 1');
  138.         $data['countInstitutes'] = $qb->getQuery()->getSingleScalarResult();
  139.         //info about the number of events
  140.         $qb $em->createQueryBuilder();
  141.         $qb->select('count(e.idEvent)');
  142.         $qb->from('OceanExpertBundle:Events''e');
  143.         $qb->where('e.status = 1');
  144.         $data['countEvents'] = $qb->getQuery()->getSingleScalarResult();
  145.         //info about the number of documents
  146.         $qb $em->createQueryBuilder();
  147.         $qb->select('count(d.idDoc)');
  148.         $qb->from('OceanExpertBundle:Documents''d');
  149.         $qb->where('d.approved = 1');
  150.         $data['countDocuments'] = $qb->getQuery()->getSingleScalarResult();
  151.         return $this->render(
  152.             'statistics.html.twig',
  153.             array(
  154.                 'data' => $data
  155.             )
  156.         );
  157.     }
  158.     /**
  159.      * show the disclaimer
  160.      *
  161.      * @return Response
  162.      */
  163.     public function disclaimerAction(): Response
  164.     {
  165.         return $this->render('Static/disclaimer.html.twig');
  166.     }
  167.     /**
  168.      * download the list of experts per country as CSV
  169.      *
  170.      * @return Response
  171.      **/
  172.     public function downloadExpertsPerCountryAction()
  173.     {
  174.         $expertsPerCountry $this->getExpertsPerCountry();
  175.         $response = new Response();
  176.         $response->headers->set('Content-Type''text/csv; charset=utf-8');
  177.         $response->headers->set(
  178.             'Content-Disposition',
  179.             'attachment; filename="experts_per_country.csv"'
  180.         );
  181.         $fp fopen('php://output''w');
  182.         fputcsv($fp, array('Country''Number of experts'));
  183.         foreach ($expertsPerCountry as $countryId => $expert ) {
  184.             fputcsv($fp, array($expert['countryName'], $expert['nrOfExperts']));
  185.         }
  186.         fclose($fp);
  187.         return $response;
  188.     }
  189.     /**
  190.      * create the json files that are needed to make the map on the homepage
  191.      * - experts
  192.      * - institutes
  193.      *
  194.      * @return Response
  195.      */
  196.     public function createMapJsonAction(): Response
  197.     {
  198.         $em $this->get('doctrine')->getManager();
  199.         $connection $em->getConnection();
  200.         $stmtInd $connection->prepare(
  201.             "SELECT (
  202.                 CASE 
  203.                     WHEN i.use_inst_addr = 1 
  204.                     THEN inst.country_code 
  205.                     ELSE i.country_code END
  206.             ) AS country_id  
  207.             FROM indiv i 
  208.             LEFT JOIN indiv_institution iinst ON i.id_ind = iinst.id_ind
  209.             LEFT JOIN institutions inst ON inst.id_inst = iinst.id_inst
  210.             WHERE i.status = 1
  211.             ORDER BY country_id ASC"
  212.         );
  213.         $stmtInd->execute();
  214.         $indiv $stmtInd->fetchAll();
  215.         $countries = array();
  216.         foreach ($indiv as $value) {
  217.             if ((trim($value['country_id']) != '')
  218.                 && ($value['country_id']) != 0
  219.             ) {
  220.                 $countries[] = $value['country_id'];
  221.             }
  222.         }
  223.         $count array_count_values($countries);
  224.         $statement $connection->prepare(
  225.             "SELECT 
  226.                 latitude, 
  227.                 longitude, 
  228.                 country, 
  229.                 id_country 
  230.             FROM countries"
  231.         );
  232.         $statement->execute();
  233.         $countryList $statement->fetchAll();
  234.         $countryData = array();
  235.         foreach ($countryList as $value) {
  236.             $countryData[$value['id_country']]['latitude'] = $value['latitude'];
  237.             $countryData[$value['id_country']]['longitude'] = $value['longitude'];
  238.             $countryData[$value['id_country']]['country'] = $value['country'];
  239.             if (!isset($count[$value['id_country']])) {
  240.                 $count[$value['id_country']] = 0;
  241.             }
  242.             $countryData[$value['id_country']]['count'] = $count[$value['id_country']];
  243.         }
  244.         //we want to put the files here
  245.         $filePath $this->get('kernel')->getProjectDir();
  246.         $filePath .= '/web/js/';
  247.         //make the experts json file
  248.         $fp fopen($filePath 'experts.json''w');
  249.         fwrite($fp"var experts = [");
  250.         fwrite($fpjson_encode($countryData));
  251.         fwrite($fp"]");
  252.         fclose($fp);
  253.         $statement $connection->prepare("
  254.             SELECT 
  255.                    latitude, 
  256.                    longitude, 
  257.                    country, 
  258.                    count(*) AS count 
  259.             FROM institutions 
  260.                 LEFT JOIN countries ON institutions.country_code = countries.id_country 
  261.             WHERE activated = 1 
  262.               AND country IS NOT NULL 
  263.             GROUP BY country");
  264.         $statement->execute();
  265.         $countryList $statement->fetchAll();
  266.         $fp fopen($filePath 'institutes.json''w');
  267.         fwrite($fp"var institutes = [");
  268.         fwrite($fpjson_encode($countryList));
  269.         fwrite($fp"]");
  270.         fclose($fp);
  271.         $response "Generated <a href='/js/experts.json'>experts.json</a> and <a href='/js/institutes.json'>institutes.json</a>";
  272.         return new Response($response);
  273.     }
  274.     /**
  275.      * give the number of experts per searegion
  276.      *
  277.      * @return JsonResponse
  278.      */
  279.     public function getExpertsSeaRegionsAction(): JsonResponse
  280.     {
  281.         $repository $this->getDoctrine()->getRepository('OceanExpertBundle:Indiv');
  282.         $seaRegionsInd $repository->createQueryBuilder('i')
  283.             ->select('DISTINCT i.studyregion')
  284.             ->getQuery()
  285.             ->getResult();
  286.         $seaRegions = array();
  287.         foreach ($seaRegionsInd as $value) {
  288.             foreach (explode(','$value['studyregion']) as $item) {
  289.                 if (is_numeric($item)) {
  290.                     $seaRegions[] = trim($this->getRegionById($item));
  291.                 }
  292.             }
  293.         }
  294.         $seaRegions array_unique($seaRegions);
  295.         $allSeas $this->getDoctrine()
  296.             ->getManager()
  297.             ->getRepository('OceanExpertBundle:Regions')
  298.             ->findBy(
  299.                 [],
  300.                 ['name' => 'ASC']
  301.             );
  302.         $availableSeas = array();
  303.         foreach ($allSeas as $value) {
  304.             $availableSeas[$value->getIdRegion()] = $value->getName();
  305.         }
  306.         $indSeaAreas array_intersect(
  307.             $availableSeas,
  308.             $seaRegions
  309.         );
  310.         return new JsonResponse($indSeaAreas);
  311.     }
  312.     /**
  313.      * give the name of a region using the id
  314.      *
  315.      * @param int $id id of the region
  316.      *
  317.      * @return string
  318.      */
  319.     public function getRegionById(int $id): string
  320.     {
  321.         $region $this->getDoctrine()
  322.             ->getRepository('OceanExpertBundle:Regions')
  323.             ->findOneBy(array('idRegion' => $id));
  324.         if ($region) {
  325.             return $region->getName();
  326.         } else {
  327.             return '';
  328.         }
  329.     }
  330.     /**
  331.      * @return JsonResponse
  332.      */
  333.     function getInstitutesSeaRegionsAction(): JsonResponse
  334.     {
  335.         $repository $this->getDoctrine()
  336.             ->getRepository('OceanExpertBundle:Institutions');
  337.         $seaRegionsInst $repository->createQueryBuilder('i')
  338.             ->select('DISTINCT i.instRegion')
  339.             ->getQuery()
  340.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  341.         $seaRegions = array();
  342.         foreach ($seaRegionsInst as $value) {
  343.             foreach (explode(','$value['instRegion']) as $item) {
  344.                 if (trim($item) != '') {
  345.                     array_push($seaRegionstrim($item));
  346.                 }
  347.             }
  348.         }
  349.         $seaRegions array_unique($seaRegions);
  350.         $repository $this->getDoctrine()->getRepository('OceanExpertBundle:Regions');
  351.         $instSeaAreas $repository->createQueryBuilder('r')
  352.             ->select('r.idRegion, r.name')
  353.             ->where('r.idRegion IN(:seaRegions) ')
  354.             ->setParameter('seaRegions'array_values($seaRegions))
  355.             ->getQuery()->getResult();
  356.         return new JsonResponse($instSeaAreas);
  357.     }
  358.     /**
  359.      * @return JsonResponse
  360.      */
  361.     function getExpertsSubjectsAction(): JsonResponse
  362.     {
  363.         $subjects $this->getDoctrine()
  364.             ->getRepository('OceanExpertBundle:Subjects')
  365.             ->createQueryBuilder('s')
  366.             ->select('s.subname, s.idSub')
  367.             ->orderBy('s.subname''ASC')
  368.             ->getQuery()
  369.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  370.         return new JsonResponse($subjects);
  371.     }
  372.     /**
  373.      * get all possible first letters of the experts names
  374.      *
  375.      * @return JsonResponse
  376.      */
  377.     function getExpertsLastNameAction(): JsonResponse
  378.     {
  379.         $em $this->getDoctrine()->getManager();
  380.         $connection $em->getConnection();
  381.         $statement $connection->prepare("SELECT DISTINCT 
  382.                 UPPER(LEFT(sname, 1)) AS letter 
  383.             FROM indiv 
  384.             ORDER BY letter"
  385.         );
  386.         $statement->execute();
  387.         $lnameList $statement->fetchAll();
  388.         $resultLname array_column($lnameList'letter');
  389.         return new JsonResponse($resultLname);
  390.     }
  391.     /**
  392.      * @return JsonResponse
  393.      */
  394.     function getExpertCountryListAction(): JsonResponse
  395.     {
  396.         $em $this->getDoctrine()->getManager();
  397.         $connection $em->getConnection();
  398.         $statement $connection->prepare("
  399.             SELECT DISTINCT 
  400.                 UPPER(LEFT(country, 1)) AS letter 
  401.             FROM countries 
  402.             WHERE id_country IN (SELECT DISTINCT(country_code) FROM indiv) 
  403.             ORDER BY letter"
  404.         );
  405.         $statement->execute();
  406.         $countries $statement->fetchAll();
  407.         $countryList array_column($countries'letter');
  408.         return new JsonResponse($countryList);
  409.     }
  410.     /**
  411.      * @return JsonResponse
  412.      */
  413.     function getInstitutionTypesAction(): JsonResponse
  414.     {
  415.         $instType $this->getDoctrine()
  416.             ->getRepository('OceanExpertBundle:Insttypes')
  417.             ->createQueryBuilder('i')
  418.             ->select('i.insttypeName, i.idInsttype')
  419.             ->orderBy('i.insttypeName''ASC')
  420.             ->getQuery()
  421.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  422.         return new JsonResponse($instType);
  423.     }
  424.     /**
  425.      * @return JsonResponse
  426.      */
  427.     function getInstitutionNameListAction(): JsonResponse
  428.     {
  429.         $em $this->getDoctrine()->getManager();
  430.         $connection $em->getConnection();
  431.         $statement $connection->prepare(
  432.             "SELECT DISTINCT 
  433.                 UPPER(LEFT(inst_name, 1)) AS letter 
  434.             FROM institutions 
  435.             ORDER BY letter"
  436.         );
  437.         $statement->execute();
  438.         $institutes $statement->fetchAll();
  439.         $instNameList array_column($institutes'letter');
  440.         return new JsonResponse($instNameList);
  441.     }
  442.     /**
  443.      * @return JsonResponse
  444.      */
  445.     function getInstitutionCountryListAction(): JsonResponse
  446.     {
  447.         $em $this->getDoctrine()->getManager();
  448.         $connection $em->getConnection();
  449.         $statement $connection->prepare(
  450.             "SELECT DISTINCT 
  451.                 UPPER(LEFT(country, 1)) AS letter 
  452.             FROM countries 
  453.             WHERE id_country IN (SELECT DISTINCT(country_code) 
  454.             FROM institutions) 
  455.             ORDER BY letter"
  456.         );
  457.         $statement->execute();
  458.         $instCountries $statement->fetchAll();
  459.         $instCountryList array_column($instCountries'letter');
  460.         return new JsonResponse($instCountryList);
  461.     }
  462.     /**
  463.      * make a list of the number of experts per country
  464.      *
  465.      * @return array
  466.      */
  467.     private function getExpertsPerCountry()
  468.     {
  469.         //get info about the countries
  470.         $countryInfo = array();
  471.         $countries $this->getDoctrine()
  472.             ->getManager()
  473.             ->getRepository('OceanExpertBundle:Countries')
  474.             ->findAll();
  475.         $returnValue = array();
  476.         $em $this->getDoctrine()->getManager();
  477.         //step 1 : those with their own address
  478.         $qb $em->createQueryBuilder();
  479.         $expr $qb->expr();
  480.         $qb->select(
  481.             "count('i.idInd') AS nr",
  482.             'c.country'
  483.         )->from(
  484.             'OceanExpertBundle:Indiv',
  485.             'i'
  486.         )->leftJoin(
  487.             'OceanExpertBundle:Countries',
  488.             'c',
  489.             'WITH',
  490.             'i.countryCode = c.idCountry'
  491.         )->where(
  492.             'i.status = 1'
  493.         )->andWhere(
  494.             $expr->neq('i.deceased'1)
  495.         )->andWhere(
  496.             $expr->neq('i.retired'1)
  497.         )->andWhere(
  498.             $expr->neq('i.useInstAddr'1)
  499.         )->andWhere(
  500.             'c.idCountry IS NOT NULL'
  501.         )->groupBy(
  502.             'i.countryCode'
  503.         );
  504.         $experts $qb->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY);
  505.         foreach ($experts as $expert) {
  506.             $expertsPerCountry[$expert['country']] = intval($expert['nr']);
  507.         }
  508.         //step 2 : those that use the address of their institute
  509.         $qb $em->createQueryBuilder();
  510.         $expr $qb->expr();
  511.         $qb->select(
  512.             "count('i.idInd') AS nr",
  513.             'c.country'
  514.         )->from(
  515.             'OceanExpertBundle:Indiv',
  516.             'i'
  517.         )->leftJoin(
  518.             'OceanExpertBundle:IndivInstitution',
  519.             'ii',
  520.             'WITH',
  521.             'i.idInd = ii.idInd'
  522.         )->leftJoin(
  523.             'OceanExpertBundle:Institutions',
  524.             'inst',
  525.             'WITH',
  526.             'ii.idInst = inst.idInst'
  527.         )->leftJoin(
  528.             'OceanExpertBundle:Countries',
  529.             'c',
  530.             'WITH',
  531.             'inst.countryCode = c.idCountry'
  532.         )->where(
  533.             'i.status = 1'
  534.         )->andWhere(
  535.             $expr->neq('i.deceased'1)
  536.         )->andWhere(
  537.             $expr->neq('i.retired'1)
  538.         )->andWhere(
  539.             'i.useInstAddr = 1'
  540.         )->andWhere(
  541.             'c.idCountry IS NOT NULL'
  542.         )->groupBy(
  543.             'inst.countryCode'
  544.         );
  545.         $experts $qb->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY);
  546.         foreach ($experts as $expert) {
  547.             $expertsPerInstCountry[$expert['country']] = intval($expert['nr']);
  548.         }
  549.         foreach ($countries as $country) {
  550.             $countryId $country->getIdCountry();
  551.             $countryName $country->getCountry();
  552.             $countryCode $country->getCountryCode();
  553.             $nrOfExperts 0;
  554.             if (isset($expertsPerCountry[$countryName])) {
  555.                 $nrOfExperts += $expertsPerCountry[$countryName];
  556.             }
  557.             if (isset($expertsPerInstCountry[$countryName])) {
  558.                 $nrOfExperts += $expertsPerInstCountry[$countryName];
  559.             }
  560.             $returnValue[$countryId]['nrOfExperts'] = $nrOfExperts;
  561.             $returnValue[$countryId]['countryName'] = $countryName;
  562.             $returnValue[$countryId]['countryId'] = $countryId;
  563.             $returnValue[$countryId]['countryCode'] = $countryCode;
  564.         }
  565.         ksort($returnValue);
  566.         return $returnValue;
  567.     }
  568. }