src/OceanExpertBundle/Controller/SearchController.php line 2484

Open in your IDE?
  1. <?php
  2. namespace OceanExpertBundle\Controller;
  3. use Doctrine\Common\Persistence\ManagerRegistry;
  4. use Doctrine\ORM\AbstractQuery;
  5. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  6. use Symfony\Component\HttpFoundation\JsonResponse;
  7. use Symfony\Component\HttpFoundation\Response;
  8. use Symfony\Component\HttpFoundation\Request;
  9. class SearchController extends AbstractController
  10. {
  11.     public function generalSearchAction(Request $request): Response
  12.     {
  13.         $searchParams['searchQuery'] = $request->query->get('q');
  14.         $searchParams['searchQuery'] = self::cleaned($searchParams['searchQuery']);
  15.         if (null !== ($request->query->get('limit'))) {
  16.             $limit $request->query->get('limit');
  17.         } else {
  18.             $limit 10;
  19.         }
  20.         $em self::getDoctrine()->getManager();
  21.         $connection $em->getConnection();
  22.         $statement $connection->prepare("
  23.             SELECT 
  24.                 * 
  25.             FROM 
  26.                 indiv 
  27.             WHERE 
  28.                 ( 
  29.                      MATCH (fname,mname,sname) AGAINST (:searchQuery IN BOOLEAN MODE) 
  30.                      OR fname LIKE :percSearchQuery 
  31.                      OR fname LIKE :searchQueryPerc  
  32.                      OR mname LIKE :percSearchQuery 
  33.                      OR mname LIKE :searchQueryPerc 
  34.                      OR sname LIKE :percSearchQuery 
  35.                      OR sname LIKE :searchQueryPerc
  36.                 ) 
  37.                 AND status = 1;
  38.             ");
  39.         $statement->bindValue('searchQuery'$searchParams['searchQuery']);
  40.         $statement->bindValue('percSearchQuery''%' $searchParams['searchQuery']);
  41.         $statement->bindValue('searchQueryPerc'$searchParams['searchQuery'] . '%');
  42.         $statement->execute();
  43.         $query $statement->fetchAll();
  44.         $paginator $this->get('knp_paginator');
  45.         $pagination $paginator->paginate(
  46.             $query,
  47.             $request->query->getInt('experts'1),
  48.             $limit,
  49.             array('pageParameterName' => 'experts''sortDirectionParameterName' => 'dir')
  50.         );
  51.         $ids = array();
  52.         foreach ($pagination->getItems() as $value) {
  53.             $ids[] = $value['id_ind'];
  54.         }
  55.         $indiv $em->getRepository('OceanExpertBundle:Indiv');
  56.         $experts $indiv->createQueryBuilder('i')
  57.             ->select('i,ix.instName,g.groupname,m.idGroup,m.role,c.country')
  58.             ->leftJoin('OceanExpertBundle:IndivInstitution''ii''WITH''ii.idInd = i.idInd')
  59.             ->leftJoin('OceanExpertBundle:Institutions''ix''WITH''ix.idInst = ii.idInst')
  60.             ->leftJoin('OceanExpertBundle:MemberGroups''m''WITH''i.idInd = m.idInd')
  61.             ->leftJoin('OceanExpertBundle:Groups''g''WITH''g.idGroup = m.idGroup')
  62.             ->leftJoin('OceanExpertBundle:Countries''c''WITH''c.idCountry = i.countryCode')
  63.             ->where('i.idInd IN (:group)')
  64.             ->andWhere('i.status = 1')
  65.             ->setParameter('group'$ids)
  66.             ->addOrderBy('ix.instName''DESC')
  67.             ->addOrderBy('i.sname''ASC')
  68.             ->getQuery()
  69.             ->getResult();
  70.         $em self::getDoctrine()->getManager();
  71.         $connection $em->getConnection();
  72.         $statement $connection->prepare("
  73.             SELECT 
  74.                 * 
  75.             FROM 
  76.                 institutions 
  77.             WHERE 
  78.                 (
  79.                     MATCH (inst_name,inst_name_eng,acronym) AGAINST (:searchQuery IN BOOLEAN MODE)
  80.                     OR inst_name LIKE :percSearchQuery 
  81.                     OR inst_name LIKE :searchQueryPerc 
  82.                     OR inst_name_eng LIKE :percSearchQuery 
  83.                     OR inst_name_eng LIKE :searchQueryPerc 
  84.                     OR acronym LIKE :percSearchQuery 
  85.                     OR acronym LIKE :searchQueryPerc
  86.                     OR activities LIKE :percSearchQueryPerc
  87.                 )
  88.                 AND activated = 1;
  89.         ");
  90.         $statement->bindValue('searchQuery'$searchParams['searchQuery']);
  91.         $statement->bindValue('percSearchQuery''%' $searchParams['searchQuery']);
  92.         $statement->bindValue('searchQueryPerc'$searchParams['searchQuery'] . '%');
  93.         $statement->bindValue('percSearchQueryPerc''%' $searchParams['searchQuery'] . '%');
  94.         $statement->execute();
  95.         $institutes $statement->fetchAll();
  96.         $institutesPage $paginator->paginate(
  97.             $institutes,
  98.             $request->query->getInt('insts'1),
  99.             12,
  100.             array(
  101.                 'pageParameterName' => 'insts',
  102.                 'sortDirectionParameterName' => 'dir'
  103.             )
  104.         );
  105.         $events $em->getRepository('OceanExpertBundle:Events');
  106.         $events $events->createQueryBuilder('e')
  107.             ->select('e')
  108.             ->where('e.title LIKE :searchQuery')
  109.             ->where('e.shorttitle LIKE :searchQuery')
  110.             ->where('e.summary LIKE :searchQuery')
  111.             ->setParameter('searchQuery''%' $searchParams['searchQuery'] . '%')
  112.             ->addOrderBy('e.title''ASC')
  113.             ->getQuery()
  114.             ->getResult();
  115.         $eventsPage $paginator->paginate(
  116.             $events,
  117.             $request->query->getInt('events'1),
  118.             10,
  119.             array('pageParameterName' => 'events''sortDirectionParameterName' => 'dir')
  120.         );
  121.         return $this->render(
  122.             'Search/generalSearch.html.twig',
  123.             array(
  124.                 'pagination' => $pagination,
  125.                 'experts' => $experts,
  126.                 'institutions' => $institutesPage,
  127.                 'events' => $eventsPage,
  128.                 'items' => array(),
  129.                 'qry' => $searchParams['searchQuery']
  130.             )
  131.         );
  132.     }
  133.     /**
  134.      * extract the possible filters from the results
  135.      * these can be used to filter down the results even move (especially in the webinterface)
  136.      *
  137.      * @param array $dataResult the results from a search
  138.      *
  139.      * @return array
  140.      */
  141.     static function getFilters(array $dataResult): array
  142.     {
  143.         $filters = array();
  144.         foreach(['type''country'] as $type) {
  145.             $filters[$type] = SearchController::getUnique(
  146.                 $dataResult,
  147.               $type
  148.             );
  149.         }
  150.         return $filters;
  151.     }
  152.     /**
  153.      * Extract all the params we need to do the search.
  154.      * These params should be reflected in the documentation of the API.
  155.      * As these are all the possible params that can be given and have effect on the result.
  156.      * They are shown here in alphabetic order to be sure there are no doubles in the variables.
  157.      *
  158.      * @param Request $request
  159.      *
  160.      * @return array all the params in an array
  161.      */
  162.     static function extractParams(Request $request): array
  163.     {
  164.         $searchParams['queryString']    = $request->query->all();
  165.         $searchParams['action']         = $request->query->get('action') ?? 'advSearch';
  166.         $searchParams['countryName']    = $request->query->get('countryName') ?? '';
  167.         $searchParams['endDate']        = $request->query->get('endDate');
  168.         $searchParams['expertLname']    = $request->query->get('expertLname') ?? '';
  169.         $searchParams['expertSubject']  = $request->query->get('expertSubject') ?? '';
  170.         $searchParams['expertRegion']   = $request->query->get('expertRegion') ?? '';
  171.         $searchParams['instCountry']    = $request->query->get('instCountry') ?? '';
  172.         $searchParams['instName']       = $request->query->get('instName') ?? '';
  173.         $searchParams['instRegion']     = $request->query->get('instRegion') ?? '';
  174.         $searchParams['instType']       = $request->query->get('instType') ?? '';
  175.         $searchParams['searchKeywords'] = $request->query->get('keywords', array());
  176.         $searchParams['limit']          = $request->query->get('limit') ?? 10;
  177.         $searchParams['sortOrder']      = $request->query->get('order') ?? 'ASC';
  178.         $searchParams['searchQuery']    = $request->query->get('query') ?? '';
  179.         $searchParams['sortby']         = $request->query->get('sortby') ?? '';
  180.         $searchParams['startDate']      = $request->query->get('startDate');
  181.         $searchParams['searchToggle']   = $request->query->get('toggle');
  182.         //what kind of items are we looking for
  183.         $searchParams['searchType']     = $request->query->get('type', array());
  184.         //default value for the type when using browse should be 'all'
  185.         if (null == $request->query->get('type')
  186.             || $request->query->get('type') == ''
  187.             || (is_array($searchParams['searchType'])
  188.                 && !count($searchParams['searchType']))
  189.         ) {
  190.             $searchParams['searchType'] = array('all');
  191.         }
  192.         //search types should always be an array, even with one element
  193.         if (!is_array($searchParams['searchType'])) {
  194.             $searchParams['searchType'] = array($searchParams['searchType']);
  195.         }
  196.         //get rid of those empty types that get added somewhere by javascript
  197.         foreach ($searchParams['searchType'] as $key => $val) {
  198.             if ($val === '') {
  199.                 unset($searchParams['searchType'][$key]);
  200.             }
  201.         }
  202.         //independent of the searchType, what type should we use to filter the results
  203.         //typically after a search with searchType == all
  204.         $searchParams['searchFilterType']= $request->query->get('filterType');
  205.         //cleanup the filters
  206.         $searchParams['searchFilterType'] = array_unique(
  207.             explode(
  208.                 ',',
  209.                 $searchParams['searchFilterType']
  210.             )
  211.         );
  212.         if ($searchParams['searchFilterType'][0] == '') {
  213.             unset($searchParams['searchFilterType']);
  214.         }
  215.         //special case of FilterType
  216.         $searchParams['filterCountry']  = $request->query->get('filterCountry');
  217.         //not sure if this is used everywhere/somewhere and what it should do
  218.         $searchParams['searchFilter']   = $request->query->get('filter');
  219.         //cleanup the query
  220.         $searchParams['searchQuery'] = self::cleaned($searchParams['searchQuery']);
  221.         //remember the search conditions, so we can recreate the search in the interface
  222.         $conditions = array();
  223.         foreach ($searchParams['searchType'] as $i => $value) {
  224.             $conditions[$i]['type'] = $value;
  225.             if (!isset($searchParams['searchFilter'][$i])) {
  226.                 $searchParams['searchFilter'][$i] = '';
  227.             }
  228.             $conditions[$i]['filter'] = $searchParams['searchFilter'][$i];
  229.             $conditions[$i]['keywords'] = $searchParams['searchKeywords'][$i] ?? '';
  230.             if (!isset($searchParams['searchToggle'][$i])) {
  231.                 $searchParams['searchToggle'][$i] = ' OR ';
  232.             }
  233.             $conditions[$i]['toggle'] = $searchParams['searchToggle'][$i];
  234.             if (!isset($searchParams['startDate'][$i])) {
  235.                 $searchParams['startDate'][$i] = '';
  236.             }
  237.             $conditions[$i]['startDate'] = $searchParams['startDate'][$i];
  238.             if (!isset($searchParams['endDate'][$i])) {
  239.                 $searchParams['endDate'][$i] = '';
  240.             }
  241.             $conditions[$i]['endDate'] = $searchParams['endDate'][$i];
  242.         }
  243.         $searchParams['conditions'] = $conditions;
  244.         //what to do with the sortby if there is none defined (yet)
  245.         $sortFields = array(
  246.             'relevance' => 'Relevance'
  247.         );
  248.         if ($searchParams['sortby'] == '') {
  249.             //for all, experts and institutions use 'relevance' as sortby in case we have a search for 'name contains'
  250.             //in other cases use inst_name for institutions
  251.             // or sname for experts
  252.             if (!empty(array_intersect($searchParams['searchType'], array('all''experts''institutions')))
  253.                 && !empty(array_intersect(['Name contains'], $searchParams['searchFilter']))
  254.             ) {
  255.                 $searchParams['sortby'] = 'relevance';
  256.                 $sortFields['relevance'] = 'Relevance';
  257.             } elseif (!empty(array_intersect($searchParams['searchType'], array('experts')))) {
  258.                 $searchParams['sortby'] = 'sname';
  259.                 $sortFields['sname'] = 'Last Name';
  260.             } elseif (!empty(array_intersect($searchParams['searchType'], array('documents')))) {
  261.                 $searchParams['sortby'] = 'title';
  262.                 $sortFields['country'] = 'Country';
  263.             } elseif (!empty(array_intersect($searchParams['searchType'], array('institutions')))) {
  264.                 $searchParams['sortby'] = 'inst_name';
  265.                 $sortFields['inst_name'] = 'Institute Name';
  266.             }
  267.         }
  268.         //if we still have no sortby, default to sname for both browse and advSearch
  269.         if ($searchParams['sortby'] == ''
  270.             && ($searchParams['action'] == 'browse'
  271.                 || $searchParams['action'] == 'advSearch')
  272.         ) {
  273.             $searchParams['sortby'] = 'sname';
  274.             unset($sortFields['relevance']);
  275.             $sortFields['sname'] = 'Last Name';
  276.         }
  277.         if (count($searchParams['searchType'])) {
  278.             if (in_array('institutions'$searchParams['searchType'])) {
  279.                 unset($sortFields['relevance']);
  280.                 $sortFields['instType'] = 'Institute Type';
  281.                 $sortFields['name'] = 'Institute Name';
  282.             }
  283.             if (in_array('experts'$searchParams['searchType'])) {
  284.                 $sortFields['jobtitle'] = 'Position';
  285.                 $sortFields['sname'] = 'Last Name';
  286.             }
  287.             if (in_array('events'$searchParams['searchType'])) {
  288.                 $sortFields['eventtype'] = 'Event Type';
  289.             }
  290.             $sortFields['country'] = 'Country';
  291.         }
  292.         $searchParams['sortFields'] = $sortFields;
  293.         return $searchParams;
  294.     }
  295.     /**
  296.      * get the results for the search when action=browse
  297.      *
  298.      * @param array  $searchParams all the search parameters that have been passed in this request
  299.      * @param object $doctrine
  300.      *
  301.      * @return array with the results
  302.      */
  303.     public static function getBrowseSearchResults(array $searchParamsobject $doctrine): array
  304.     {
  305.         $connection $doctrine->getManager()->getConnection();
  306.         $searchResultType 'Browse Results';
  307.         $dataResult = array();
  308.         $sortFields $searchParams['sortFields'];
  309.         $message '';
  310.         //status=0 means everything is ok
  311.         $status 0;
  312.         if (is_array($searchParams['searchType'])
  313.             && count($searchParams['searchType']) > 1
  314.         ) {
  315.             //impossible for action=browse, this should be a simple query in the end
  316.             $message 'You can only have one (filter)type when you use action=browse.';
  317.             $message .= ' Provided (filter)types: ' implode(', '$searchParams['searchType']);
  318.             return array(
  319.                 'status' => 1,
  320.                 'message' => $message
  321.             );
  322.         }
  323.         //for the searchtype 'browse' we do not need an array of search types
  324.         if (isset($searchParams['searchType'])
  325.             && is_array($searchParams['searchType'])
  326.             && count($searchParams['searchType'])
  327.         ) {
  328.             $searchParams['searchType'] = $searchParams['searchType'][0];
  329.         }
  330.         if ($searchParams['searchQuery'] != '') {
  331.             $indiv = array();
  332.             $indivNames = array();
  333.             $indivGroups = array();
  334.             if (($searchParams['searchType'] == 'all'
  335.                     || $searchParams['searchType'] == 'experts'
  336.                 )
  337.                 && !(isset($searchParams['queryString']['searchType'])
  338.                     && $searchParams['queryString']['searchType'] === 'group')
  339.             ) {
  340.                 $newString self::fulltext($searchParams['searchQuery']);
  341.                 $stmtInd $connection->prepare("
  342.                         SELECT 
  343.                             'experts' AS type, 
  344.                             i.status, 
  345.                             i.id_ind, 
  346.                             i.title,   
  347.                             concat(i.fname,' ',i.sname) AS name,
  348.                             i.fname,
  349.                             i.mname,
  350.                             i.sname,
  351.                             i.jobtitle,
  352.                             i.addr_1,
  353.                             i.addr_2,
  354.                             i.city,
  355.                             i.state,
  356.                             i.postcode,
  357.                             i.use_inst_addr, 
  358.                             i.deceased, 
  359.                             i.retired, 
  360.                             i.quality_checked, 
  361.                             inst.inst_name,
  362.                             inst.inst_address,
  363.                             inst.addr_2 AS instAddr2,
  364.                             inst.city AS instCity,
  365.                             inst.state AS instState,
  366.                             inst.postcode AS instPostCode, 
  367.                             (IF(i.use_inst_addr = 1, ic.country, c.country)) AS country, 
  368.                             MATCH (i.fname,i.sname) AGAINST (:newString IN BOOLEAN MODE) AS relevance, 
  369.                             'zz' AS instType, 
  370.                             'zz' AS eventtype, 
  371.                             '' AS inst_logo, 
  372.                             'zz' AS name
  373.                         FROM 
  374.                             indiv i
  375.                             LEFT JOIN countries c ON c.id_country = i.country_code
  376.                             LEFT JOIN indiv_institution ii ON ii.id_ind = i.id_ind
  377.                             LEFT JOIN institutions inst ON inst.id_inst = ii.id_inst
  378.                             LEFT JOIN countries ic ON ic.id_country = inst.country_code
  379.                         WHERE 
  380.                             ( 
  381.                                 MATCH (fname, mname, sname) AGAINST (:newString IN BOOLEAN MODE) 
  382.                                 OR i.fname LIKE :percSearchQuery
  383.                                 OR i.fname LIKE :searchQueryPerc 
  384.                                 OR i.mname LIKE :percSearchQuery
  385.                                 OR i.mname LIKE :searchQueryPerc 
  386.                                 OR i.sname LIKE :percSearchQuery
  387.                                 OR i.sname LIKE :searchQueryPerc
  388.                                 OR i.private_address LIKE :percSearchQueryPerc
  389.                                 OR i.addr_1 LIKE :percSearchQueryPerc
  390.                                 OR i.addr_2 LIKE :percSearchQueryPerc
  391.                                 OR i.city LIKE :percSearchQueryPerc
  392.                                 OR i.state LIKE :percSearchQueryPerc
  393.                             ) 
  394.                             " $searchParams['indivStatus'] . '
  395.                         ORDER BY relevance DESC, sname ASC;
  396.                     ');
  397.                 $stmtInd->bindValue('newString'$newString);
  398.                 $stmtInd->bindValue('percSearchQuery''%' $searchParams['searchQuery']);
  399.                 $stmtInd->bindValue('searchQueryPerc'$searchParams['searchQuery'] . '%');
  400.                 $stmtInd->bindValue('percSearchQueryPerc''%' $searchParams['searchQuery'] . '%');
  401.                 $stmtInd->execute();
  402.                 $indiv $stmtInd->fetchAll();
  403.                 $sortFields['jobtitle'] = 'Position';
  404.             }
  405.             if ($searchParams['searchType'] == 'name') {
  406.                 $newString self::fulltext($searchParams['searchQuery']);
  407.                 $stmtInd $connection->prepare("
  408.                         SELECT 
  409.                             'experts' AS type, 
  410.                             i.status, 
  411.                             i.id_ind, 
  412.                             i.title,   
  413.                             concat(i.fname,' ',i.sname) AS name,
  414.                             i.fname,
  415.                             i.mname,
  416.                             i.sname,
  417.                             i.jobtitle,
  418.                             i.addr_1,
  419.                             i.addr_2,
  420.                             i.city,
  421.                             i.state,
  422.                             i.postcode,
  423.                             i.use_inst_addr, 
  424.                             i.deceased, 
  425.                             i.retired, 
  426.                             i.quality_checked, 
  427.                             inst.inst_name,
  428.                             inst.inst_address,
  429.                             inst.addr_2 AS instAddr2,
  430.                             inst.city AS instCity,
  431.                             inst.state AS instState,
  432.                             inst.postcode AS instPostCode, 
  433.                             (IF(i.use_inst_addr = 1, ic.country, c.country)) AS country, 
  434.                             MATCH (i.fname,i.sname) AGAINST (:newString IN BOOLEAN MODE) AS relevance, 
  435.                             'zz' AS instType, 
  436.                             'zz' AS eventtype, 
  437.                             '' AS inst_logo, 
  438.                             'zz' AS name
  439.                         FROM 
  440.                             indiv i
  441.                             LEFT JOIN countries c ON c.id_country = i.country_code
  442.                             LEFT JOIN indiv_institution ii ON ii.id_ind = i.id_ind
  443.                             LEFT JOIN institutions inst ON inst.id_inst = ii.id_inst
  444.                             LEFT JOIN countries ic ON ic.id_country = inst.country_code
  445.                         WHERE 
  446.                             ( 
  447.                                 MATCH (fname, mname, sname) AGAINST (:newString IN BOOLEAN MODE) 
  448.                                 OR i.fname LIKE :percSearchQuery
  449.                                 OR i.fname LIKE :searchQueryPerc 
  450.                                 OR i.mname LIKE :percSearchQuery
  451.                                 OR i.mname LIKE :searchQueryPerc 
  452.                                 OR i.sname LIKE :percSearchQuery
  453.                                 OR i.sname LIKE :searchQueryPerc
  454.                             ) 
  455.                             " $searchParams['indivStatus'] . '
  456.                         ORDER BY relevance DESC, sname ASC;
  457.                     ');
  458.                 $stmtInd->bindValue('newString'$newString);
  459.                 $stmtInd->bindValue('percSearchQuery''%' $searchParams['searchQuery']);
  460.                 $stmtInd->bindValue('searchQueryPerc'$searchParams['searchQuery'] . '%');
  461.                 $stmtInd->execute();
  462.                 $indivNames $stmtInd->fetchAll();
  463.                 $sortFields['jobtitle'] = 'Position';
  464.             }
  465.             if ($searchParams['searchType'] == 'all'
  466.                 || (isset($searchParams['queryString']['searchType'])
  467.                 && $searchParams['queryString']['searchType'] == 'group'
  468.                 && $searchParams['searchType'] == 'experts')
  469.                 || $searchParams['searchType'] == 'group'
  470.             ) {
  471.                 //looking for experts that are in a group that matches the searchTerm
  472.                 $newString self::fulltext($searchParams['searchQuery']);
  473.                 $stmtInd $connection->prepare("
  474.                         SELECT 
  475.                             'experts' AS type, 
  476.                             i.status, 
  477.                             i.id_ind, 
  478.                             i.title,   
  479.                             concat(i.fname,' ',i.sname) AS name,
  480.                             i.fname,
  481.                             i.mname,
  482.                             i.sname,
  483.                             i.jobtitle,
  484.                             i.addr_1,
  485.                             i.addr_2,
  486.                             i.city,
  487.                             i.state,
  488.                             i.postcode,
  489.                             i.use_inst_addr, 
  490.                             i.deceased, 
  491.                             i.retired, 
  492.                             i.quality_checked, 
  493.                             inst.inst_name,
  494.                             inst.inst_address,
  495.                             inst.addr_2 AS instAddr2,
  496.                             inst.city AS instCity,
  497.                             inst.state AS instState,
  498.                             inst.postcode AS instPostCode, 
  499.                             g.groupname AS groupName,
  500.                             g.id_group AS groupId,
  501.                             '' AS relevance,   
  502.                             (IF(i.use_inst_addr = 1, ic.country, c.country)) AS country
  503.                         FROM 
  504.                             indiv i
  505.                             LEFT JOIN countries c ON c.id_country = i.country_code
  506.                             LEFT JOIN indiv_institution ii ON ii.id_ind = i.id_ind
  507.                             LEFT JOIN institutions inst ON inst.id_inst = ii.id_inst
  508.                             LEFT JOIN countries ic ON ic.id_country = inst.country_code
  509.                             LEFT JOIN member_groups mg ON mg.id_ind = i.id_ind
  510.                             LEFT JOIN groups g ON mg.id_group = g.id_group
  511.                         WHERE 
  512.                             ( 
  513.                                 g.groupname LIKE :percSearchQueryPerc
  514.                             ) 
  515.                             " $searchParams['indivStatus'] . '
  516.                         ORDER BY sname ASC;
  517.                     ');
  518.                 $stmtInd->bindValue('percSearchQueryPerc''%' $searchParams['searchQuery'] . '%');
  519.                 $stmtInd->execute();
  520.                 $indivGroups $stmtInd->fetchAll();
  521.                 $sortFields['jobtitle'] = 'Position';
  522.             }
  523.             $institutes = array();
  524.             if ($searchParams['searchType'] == 'all'
  525.                 || $searchParams['searchType'] == 'institutions'
  526.             ) {
  527.                 $newString self::fulltext($searchParams['searchQuery']);
  528.                 $stmtInst $connection->prepare("
  529.                         SELECT 
  530.                             'institutions' AS type, 
  531.                             i.activated, 
  532.                             i.id_inst, 
  533.                             insttype_name AS instType, 
  534.                             inst_name,
  535.                             inst_name_eng,
  536.                             inst_address,
  537.                             addr_2,
  538.                             city AS instCity,
  539.                             state AS instState,
  540.                             postcode AS instPostCode,
  541.                             country,
  542.                             inst_logo,
  543.                             activities, 
  544.                             MATCH (inst_name,inst_name_eng,acronym) AGAINST (:newString) AS relevance, 
  545.                             'zz' AS jobtitle, 
  546.                             'zz' AS eventtype,
  547.                             'zz' AS fname,  
  548.                             'zz' AS sname, 
  549.                             'zz' AS name
  550.                         FROM 
  551.                             institutions i
  552.                             LEFT JOIN countries c ON c.id_country =  i.country_code
  553.                             LEFT JOIN insttypes it ON it.id_insttype =  i.inst_type_id
  554.                         WHERE 
  555.                             (
  556.                                 MATCH (inst_name,inst_name_eng,acronym) AGAINST (:newString IN BOOLEAN MODE)
  557.                                 OR inst_name LIKE :percSearchQueryPerc 
  558.                                 OR inst_name_eng LIKE :percSearchQueryPerc 
  559.                                 OR inst_address LIKE :percSearchQueryPerc 
  560.                                 OR addr_2 LIKE :percSearchQueryPerc 
  561.                                 OR city LIKE :percSearchQueryPerc 
  562.                                 OR state LIKE :percSearchQueryPerc 
  563.                                 OR acronym LIKE :percSearchQueryPerc 
  564.                                 OR activities LIKE :percSearchQueryPerc
  565.                             )
  566.                             " $searchParams['instStatus'] . '
  567.                         ORDER BY relevance DESC, i.inst_name ASC;
  568.                     ');
  569.                 $stmtInst->bindValue('newString'$newString);
  570.                 $stmtInst->bindValue('percSearchQueryPerc''%'.$searchParams['searchQuery'].'%');
  571.                 $stmtInst->execute();
  572.                 $institutes $stmtInst->fetchAll();
  573.                 $sortFields['instType'] = 'Institution Type';
  574.             }
  575.             $events = array();
  576.             if ($searchParams['searchType'] == 'all'
  577.                 || $searchParams['searchType'] == 'events'
  578.             ) {
  579.                 $sortFields['name'] = 'Event Title';
  580.                 if ($searchParams['sortby'] == '') {
  581.                     $searchParams['sortby'] = 'name';
  582.                 }
  583.                 $query "
  584.                         SELECT 
  585.                             'events' AS type, 
  586.                             et.eventtype_name AS eventtype, 
  587.                             e.status AS activated,
  588.                             e.id_event, 
  589.                             e.title AS name, 
  590.                             e.start_on,
  591.                             e.end_on, 
  592.                             e.address AS addr_1,
  593.                             e.city, 
  594.                             e.state, 
  595.                             c.country AS country,
  596.                             'zz' AS jobtitle, 
  597.                             'zz' AS instType,
  598.                             'zz' AS fname,
  599.                             'zz' AS sname,
  600.                             'zz' AS inst_name
  601.                         FROM 
  602.                             events e
  603.                             LEFT JOIN countries c on c.id_country =  e.id_country
  604.                             LEFT JOIN eventtypes et on et.id_eventtype =  e.id_eventtype
  605.                         WHERE 
  606.                             (
  607.                                 e.title LIKE :percSearchQueryPerc 
  608.                                 OR e.summary LIKE :percSearchQueryPerc
  609.                                 OR e.shorttitle LIKE :percSearchQueryPerc
  610.                                 OR e.keywords LIKE :percSearchQueryPerc
  611.                                 OR e.website LIKE :percSearchQueryPerc
  612.                                 OR e.city LIKE :percSearchQueryPerc
  613.                                 OR e.address LIKE :percSearchQueryPerc
  614.                             )
  615.                             " $searchParams['eventStatus'] . '
  616.                          ORDER BY e.title ASC;
  617.                      ';
  618.                 $stmtEvent $connection->prepare($query);
  619.                 $stmtEvent->bindValue('searchQuery'$searchParams['searchQuery']);
  620.                 $stmtEvent->bindValue('percSearchQueryPerc''%' $searchParams['searchQuery'] . '%');
  621.                 $stmtEvent->execute();
  622.                 $events $stmtEvent->fetchAll();
  623.                 $sortFields['eventtype'] = 'Event Type';
  624.             }
  625.             $documents = array();
  626.             if ($searchParams['searchType'] == 'all'
  627.                 || $searchParams['searchType'] == 'documents'
  628.             ) {
  629.                 $sortFields['title'] = 'Document Title';
  630.                 if ($searchParams['sortby'] == '') {
  631.                     $searchParams['sortby'] = 'title';
  632.                 }
  633.                 $query "
  634.                         SELECT 
  635.                             'documents' AS type, 
  636.                             d.id_doc,
  637.                             dt.doctypename AS documenttype, 
  638.                             d.title, 
  639.                             d.created_at,
  640.                             'undefined' AS country
  641.                         FROM 
  642.                              documents d, 
  643.                              doctypes dt 
  644.                         WHERE 
  645.                             dt.id_doctype = d.id_doctype
  646.                             AND d.title LIKE :percSearchQueryPerc
  647.                         ORDER BY d.title ASC
  648.                     ";
  649.                 $stmtDocument $connection->prepare($query);
  650.                 $stmtDocument->bindValue('percSearchQueryPerc''%' $searchParams['searchQuery'] . '%');
  651.                 $stmtDocument->execute();
  652.                 $documents $stmtDocument->fetchAll();
  653.                 $sortFields['documenttype'] = 'Document Type';
  654.             }
  655.             $dataResult array_unique(
  656.                 array_merge(
  657.                     $indiv,
  658.                     $indivNames,
  659.                     $indivGroups,
  660.                     $institutes,
  661.                     $events,
  662.                     $documents
  663.                 ),
  664.                 SORT_REGULAR
  665.             );
  666.             if ($searchParams['searchType'] == 'all') {
  667.                 if (count($dataResult) == 0) {
  668.                     $message 'We could not find any results matching "<strong>' self::cleaned($searchParams['searchQuery']) . ' </strong>". ';
  669.                     $message.= 'Please try again with different keyword(s).';
  670.                     return array(
  671.                         'status' => 3,
  672.                         'message' => $message,
  673.                         'dataResult' => array(),
  674.                         'searchResultType' => '',
  675.                         'sortFields' => array()
  676.                     );
  677.                 }
  678.                 $message 'Your search for "<strong>' self::cleaned($searchParams['searchQuery']) . '</strong>" ';
  679.                 $message.= 'returned <strong>' count($dataResult) . '</strong> result(s).';
  680.             } elseif ($searchParams['searchType'] == 'experts') {
  681.                 if (count($dataResult) == 0) {
  682.                     $message 'We could not find any results matching "<strong>' self::cleaned($searchParams['searchQuery']) . '</strong>" in Experts. ';
  683.                     $message.= 'Please try again with different keyword(s).';
  684.                     return array(
  685.                         'status' => 3,
  686.                         'message' => $message,
  687.                         'dataResult' => array(),
  688.                         'searchResultType' => '',
  689.                         'sortFields' => array()
  690.                     );
  691.                 }
  692.                 $message 'Your search for "<strong>' self::cleaned($searchParams['searchQuery']) . '</strong>" in "<strong>Experts</strong>" ';
  693.                 $message.= 'returned <strong>' count($dataResult) . '</strong> result(s).';
  694.             } elseif ($searchParams['searchType'] == 'institutions') {
  695.                 if (count($dataResult) == 0) {
  696.                     $message 'We could not find any results matching "<strong>' self::cleaned($searchParams['searchQuery']) . '</strong>" in Institutions. ';
  697.                     $message.= 'Please try again with different keyword(s).';
  698.                     return array(
  699.                         'status' => 3,
  700.                         'message' => $message,
  701.                         'dataResult' => array(),
  702.                         'searchResultType' => '',
  703.                         'sortFields' => array()
  704.                     );
  705.                 }
  706.                 $message 'Your search for "<strong>' self::cleaned($searchParams['searchQuery']) . '</strong>" in "<strong>Institutions</strong>" ';
  707.                 $message.= 'returned <strong>' count($dataResult) . '</strong> result(s).';
  708.             } elseif ($searchParams['searchType'] == 'documents') {
  709.                 $searchParams['countryName'] = '';
  710.                 $searchParams['expertLname'] = '';
  711.                 if (count($dataResult) == 0) {
  712.                     $message 'We could not find any results matching "<strong>' self::cleaned($searchParams['searchQuery']) . '</strong>" in the title of Documents. ';
  713.                     $message .= 'Please try again with different word(s).';
  714.                     return array(
  715.                         'status' => 3,
  716.                         'message' => $message,
  717.                         'dataResult' => array(),
  718.                         'searchResultType' => '',
  719.                         'sortFields' => array()
  720.                     );
  721.                 }
  722.                 $message "Your search for \"<strong>" self::cleaned($searchParams['searchQuery']) . "</strong>\" ";
  723.                 $message .= "in \"<strong>Documents</strong>\" ";
  724.                 $message .= "returned <strong>" count($dataResult) . "</strong> result(s).";
  725.             }
  726.         }
  727.         if ($searchParams['expertLname'] != '') {
  728.             $stmtInd $connection->prepare("
  729.                     SELECT 
  730.                         'experts' AS type, 
  731.                         i.status, 
  732.                         i.id_ind, 
  733.                         concat(i.fname, ' ', i.sname) AS name,
  734.                         i.fname,
  735.                         i.mname,
  736.                         i.sname,
  737.                         inst_name,
  738.                         jobtitle,
  739.                         i.addr_1,
  740.                         i.addr_2,
  741.                         i.city,
  742.                         i.state,
  743.                         i.postcode,
  744.                         inst.inst_address,
  745.                         inst.addr_2 AS instAddr2,
  746.                         inst.city AS instCity,
  747.                         inst.state AS instState,
  748.                         inst.postcode AS instPostCode, 
  749.                         use_inst_addr, 
  750.                         deceased, 
  751.                         retired, 
  752.                         quality_checked, 
  753.                         (IF(use_inst_addr = 1, ic.country, c.country)) AS country, 
  754.                         'zz' AS instType, 
  755.                         'zz' AS eventtype, 
  756.                         '' AS inst_logo
  757.                     FROM 
  758.                         indiv i
  759.                         LEFT JOIN countries c on c.id_country =  i.country_code
  760.                         LEFT JOIN indiv_institution ii on ii.id_ind = i.id_ind
  761.                         LEFT JOIN institutions inst on inst.id_inst = ii.id_inst
  762.                         LEFT JOIN countries ic on ic.id_country =  inst.country_code
  763.                     WHERE 
  764.                         (sname LIKE :expertLNamePerc)
  765.                         " $searchParams['indivStatus'] . 
  766.                     ORDER BY sname, fname ASC
  767.                 ');
  768.             $stmtInd->bindValue('expertLNamePerc'$searchParams['expertLname'] . '%');
  769.             $stmtInd->execute();
  770.             $dataResult $stmtInd->fetchAll();
  771.             $sortFields['jobtitle'] = 'Position';
  772.             $message 'There are <strong>' count($dataResult) . '</strong> experts ';
  773.             $message.= 'with their <strong>last name</strong> starting with "<strong>' self::cleaned($searchParams['expertLname']) . '</strong>".';
  774.         }
  775.         if ($searchParams['countryName'] != '') {
  776.             if ($searchParams['searchType'] == 'experts') {
  777.                 $query "
  778.                         SELECT 
  779.                             'experts' AS type, 
  780.                             i.status, 
  781.                             i.id_ind, 
  782.                             concat(i.fname,' ',i.sname) AS name,
  783.                             i.fname,
  784.                             i.mname,
  785.                             i.sname,
  786.                             inst_name,
  787.                             jobtitle,
  788.                             i.addr_1,
  789.                             i.addr_2,
  790.                             i.city,
  791.                             i.state,
  792.                             i.postcode,
  793.                             inst.inst_address,
  794.                             inst.addr_2 AS instAddr2,
  795.                             inst.city AS instCity,
  796.                             inst.state AS instState,
  797.                             inst.postcode AS instPostCode, 
  798.                             use_inst_addr, 
  799.                             deceased, 
  800.                             retired, 
  801.                             quality_checked, 
  802.                             (IF(use_inst_addr = 1, ic.country, c.country)) AS country, 
  803.                             'zz' AS instType, 
  804.                             'zz' AS eventtype, 
  805.                             '' AS inst_logo
  806.                         FROM    
  807.                             indiv i
  808.                             LEFT JOIN countries c on c.id_country =  i.country_code
  809.                             LEFT JOIN indiv_institution ii on ii.id_ind = i.id_ind
  810.                             LEFT JOIN institutions inst on inst.id_inst = ii.id_inst
  811.                             LEFT JOIN countries ic on ic.id_country =  inst.country_code
  812.                         WHERE 
  813.                             ( CASE WHEN use_inst_addr = 1 THEN ";
  814.                 if (strlen($searchParams['countryName']) === 1) {
  815.                     $query .= 'ic.country LIKE :countryNamePerc ELSE c.country LIKE :countryNamePerc END) ';
  816.                 } else {
  817.                     $query .= 'ic.country LIKE :countryName ELSE c.country LIKE :countryName END) ';
  818.                 }
  819.                 $query .=  $searchParams['indivStatus'] . ' ORDER BY sname ASC ';
  820.                 $stmtInd $connection->prepare($query);
  821.                 $stmtInd->bindValue('countryName'$searchParams['countryName']);
  822.                 $stmtInd->bindValue('countryNamePerc'$searchParams['countryName'] . '%');
  823.                 $stmtInd->execute();
  824.                 $dataResult $stmtInd->fetchAll();
  825.                 $sortFields['jobtitle'] = 'Position';
  826.                 $message 'There are <strong>' count($dataResult) . '</strong> experts ';
  827.                 $message.= 'located in <strong>countries with names</strong> starting with "<strong>' self::cleaned($searchParams['countryName']) . '</strong>".';
  828.                 if (isset($searchParams['referrer'])
  829.                     && ($searchParams['referrer'] == 'map')
  830.                 ) {
  831.                     $message 'There are <strong>' count($dataResult) . '</strong> experts ';
  832.                     $message.= 'located in  "<strong>' self::cleaned($searchParams['countryName']) . '</strong>".';
  833.                 }
  834.             } elseif ($searchParams['searchType'] == 'institution') {
  835.                 $stmtInd $connection->prepare("
  836.                         SELECT 
  837.                             'institutions' AS type, 
  838.                             insttype_name AS jobtitle, 
  839.                             i.activated, 
  840.                             i.id_inst, 
  841.                             insttype_name AS instType, 
  842.                             inst_name,
  843.                             inst_name_eng,
  844.                             inst_address,
  845.                             addr_2,
  846.                             city AS instCity,
  847.                             state AS instState,
  848.                             postcode AS instPostCode,
  849.                             country,
  850.                             activities, 
  851.                             inst_logo, 
  852.                             'zz' AS jobtitle,
  853.                             'zz' AS fname, 
  854.                             'zz' AS sname
  855.                         FROM 
  856.                             institutions i
  857.                             LEFT JOIN countries c on c.id_country =  i.country_code
  858.                             LEFT JOIN insttypes it on it.id_insttype =  i.inst_type_id
  859.                         WHERE 
  860.                             ( c.country LIKE '" $searchParams['countryName'] . "' )
  861.                             " $searchParams['instStatus'] . 
  862.                         ORDER BY inst_name ASC
  863.                     ');
  864.                 $stmtInd->execute();
  865.                 $dataResult $stmtInd->fetchAll();
  866.                 $sortFields['instType'] = 'Institution Type';
  867.                 $message 'There are <strong>' count($dataResult) . '</strong> experts ';
  868.                 $message.= 'located in <strong>countries with names</strong> starting with "<strong>' self::cleaned($searchParams['countryName']) . '</strong>".';
  869.                 if (isset($searchParams['referrer'])
  870.                     && ($searchParams['referrer'] == 'map')
  871.                 ) {
  872.                     $message 'There are <strong>' count($dataResult) . '</strong> experts ';
  873.                     $message.= 'located in  "<strong>' self::cleaned($searchParams['countryName']) . '</strong>".';
  874.                 }
  875.             }
  876.         }
  877.         if ($searchParams['expertSubject'] != '') {
  878.             $stmtInd $connection->prepare("
  879.                     SELECT 
  880.                         'experts' AS type, 
  881.                         i.status, 
  882.                         i.id_ind, 
  883.                         concat(i.fname,' ',i.sname) AS name,
  884.                         i.fname,
  885.                         i.mname,
  886.                         i.sname,
  887.                         inst_name,
  888.                         jobtitle,
  889.                         i.addr_1,
  890.                         i.addr_2,
  891.                         i.city,
  892.                         i.state,
  893.                         i.postcode,
  894.                         inst.inst_address,
  895.                         inst.addr_2 AS instAddr2,
  896.                         inst.city AS instCity,
  897.                         inst.state AS instState,
  898.                         inst.postcode AS instPostCode, 
  899.                         use_inst_addr, 
  900.                         deceased, 
  901.                         retired, 
  902.                         quality_checked, 
  903.                         (IF(use_inst_addr = 1, ic.country, c.country)) AS country, 
  904.                         'zz' AS instType, 
  905.                         'zz' AS eventtype, 
  906.                         '' AS inst_logo
  907.                     FROM 
  908.                         indiv i
  909.                         LEFT JOIN countries c on c.id_country =  i.country_code
  910.                         LEFT JOIN indiv_institution ii on ii.id_ind = i.id_ind
  911.                         LEFT JOIN institutions inst on inst.id_inst = ii.id_inst
  912.                         LEFT JOIN indiv_subjects ins on ins.id_ind = i.id_ind
  913.                         LEFT JOIN countries ic on ic.id_country =  inst.country_code
  914.                     WHERE 
  915.                         (ins.id_sub = :expertSubject)
  916.                         " $searchParams['indivStatus'] . 
  917.                     ORDER BY sname ASC
  918.                 ');
  919.             $stmtInd->bindValue('expertSubject'$searchParams['expertSubject']);
  920.             $stmtInd->execute();
  921.             $dataResult $stmtInd->fetchAll();
  922.             $sortFields['jobtitle'] = 'Position';
  923.             $message 'There are <strong>' count($dataResult) . '</strong> experts ';
  924.             $message.= "working in \"<strong>" self::getSubjectAreaById($searchParams['expertSubject'], $doctrine) . "</strong>\".";
  925.         }
  926.         if ($searchParams['expertRegion'] != '') {
  927.             $stmtInd $connection->prepare("
  928.                     SELECT 
  929.                         'experts' AS type, 
  930.                         i.status, 
  931.                         i.id_ind, 
  932.                         concat(i.fname,' ',i.sname) AS name,
  933.                         i.fname,
  934.                         i.mname,
  935.                         i.sname,
  936.                         inst_name,
  937.                         jobtitle,
  938.                         i.addr_1,
  939.                         i.addr_2,
  940.                         i.city,
  941.                         i.state,
  942.                         i.postcode,
  943.                         inst.inst_address,
  944.                         inst.addr_2 AS instAddr2,
  945.                         inst.city AS instCity,
  946.                         inst.state AS instState,
  947.                         inst.postcode AS instPostCode, 
  948.                         use_inst_addr, 
  949.                         deceased, 
  950.                         retired, 
  951.                         quality_checked, 
  952.                         (IF(use_inst_addr = 1, ic.country, c.country)) AS country, 
  953.                         'zz' AS instType, 
  954.                         'zz' AS eventtype, 
  955.                         '' AS inst_logo
  956.                     FROM 
  957.                         indiv i
  958.                         LEFT JOIN countries c on c.id_country =  i.country_code
  959.                         LEFT JOIN indiv_institution ii on ii.id_ind = i.id_ind
  960.                         LEFT JOIN institutions inst on inst.id_inst = ii.id_inst
  961.                         LEFT JOIN countries ic on ic.id_country =  inst.country_code
  962.                     WHERE 
  963.                         FIND_IN_SET (
  964.                             :expertRegion, 
  965.                             i.studyregion
  966.                         )
  967.                         " $searchParams['indivStatus'] . 
  968.                     ORDER BY sname ASC
  969.                 ');
  970.             $stmtInd->bindValue('expertRegion'$searchParams['expertRegion']);
  971.             $stmtInd->execute();
  972.             $dataResult $stmtInd->fetchAll();
  973.             $sortFields['jobtitle'] = 'Position';
  974.             $message 'There are <strong>' count($dataResult) . '</strong> experts ';
  975.             $message.= "working in the \"<strong>" self::getSeaRegionById($searchParams['expertRegion'], $doctrine) . "</strong>\".";
  976.         }
  977.         if ($searchParams['instName'] != '') {
  978.             $stmtInst $connection->prepare("
  979.                     SELECT 
  980.                         'institutions' AS type, 
  981.                         i.activated, 
  982.                         i.id_inst, 
  983.                         insttype_name AS instType, 
  984.                         inst_name,
  985.                         inst_name_eng,
  986.                         inst_address,
  987.                         addr_2,
  988.                         city AS instCity,
  989.                         state AS instState,
  990.                         postcode AS instPostCode,
  991.                         country,
  992.                         activities, 
  993.                         inst_logo, 
  994.                         'zz' AS jobtitle, 
  995.                         'zz' AS eventtype,
  996.                         'zz' AS fname, 
  997.                         'zz' AS sname
  998.                     FROM 
  999.                         institutions i
  1000.                         LEFT JOIN countries c on c.id_country =  i.country_code
  1001.                         LEFT JOIN insttypes it on it.id_insttype =  i.inst_type_id
  1002.                     WHERE 
  1003.                         ( 
  1004.                             inst_name LIKE :instNamePerc
  1005.                             OR inst_name_eng LIKE :instNamePerc 
  1006.                             OR acronym LIKE :instNamePerc
  1007.                         )
  1008.                         " $searchParams['instStatus'] . 
  1009.                     ORDER BY inst_name ASC 
  1010.                 ");
  1011.             $stmtInst->bindValue('instNamePerc'$searchParams['instName'] . '%');
  1012.             $stmtInst->execute();
  1013.             $dataResult $stmtInst->fetchAll();
  1014.             $sortFields['instType'] = 'Institution Type';
  1015.             $sortFields['inst_name'] = 'Institution Name';
  1016.             $searchParams['sortby'] = 'inst_name';
  1017.             $message 'There are <strong>' count($dataResult) . '</strong> institutions ';
  1018.             $message.= 'with their name starting with "<strong>' self::cleaned($searchParams['instName']) . '</strong>".';
  1019.         }
  1020.         if ($searchParams['instCountry'] != '') {
  1021.             $stmtInst $connection->prepare("
  1022.                     SELECT 
  1023.                         'institutions' AS type, 
  1024.                         i.activated, 
  1025.                         i.id_inst, 
  1026.                         insttype_name AS instType, 
  1027.                         inst_name,
  1028.                         inst_name_eng,
  1029.                         inst_address,
  1030.                         addr_2,
  1031.                         city AS instCity,
  1032.                         state AS instState,
  1033.                         postcode AS instPostCode,
  1034.                         country,
  1035.                         activities, 
  1036.                         inst_logo, 
  1037.                         'zz' AS jobtitle, 
  1038.                         'zz' AS eventtype,
  1039.                         'zz' AS fname, 
  1040.                         'zz' AS sname
  1041.                     FROM 
  1042.                         institutions i
  1043.                         LEFT JOIN countries c on c.id_country =  i.country_code
  1044.                         LEFT JOIN insttypes it on it.id_insttype =  i.inst_type_id
  1045.                     WHERE 
  1046.                         ( c.country LIKE :instCountryPerc )
  1047.                         " $searchParams['instStatus'] . 
  1048.                     ORDER BY inst_name ASC 
  1049.                 ');
  1050.             $stmtInst->bindValue('instCountryPerc'$searchParams['instCountry'] . '%');
  1051.             $stmtInst->execute();
  1052.             $dataResult $stmtInst->fetchAll();
  1053.             $sortFields['instType'] = 'Institution Type';
  1054.             $sortFields['inst_name'] = 'Institution Name';
  1055.             $searchParams['sortby'] = 'inst_name';
  1056.             $message 'There are <strong>' count($dataResult) . '</strong> institutions ';
  1057.             $message.= 'located in countries with names starting with "<strong>' self::cleaned($searchParams['instCountry']) . '</strong>".';
  1058.         }
  1059.         if ($searchParams['instRegion'] != '') {
  1060.             $stmtInst $connection->prepare("
  1061.                     SELECT 
  1062.                         'institutions' AS type, 
  1063.                         i.activated, 
  1064.                         i.id_inst, 
  1065.                         insttype_name AS instType, 
  1066.                         inst_name,
  1067.                         inst_name_eng,
  1068.                         inst_address,
  1069.                         addr_2,
  1070.                         city AS instCity,
  1071.                         state AS instState,
  1072.                         postcode AS instPostCode,
  1073.                         country,
  1074.                         activities,
  1075.                         inst_logo, 
  1076.                         'zz' AS jobtitle, 
  1077.                         'zz' AS eventtype,
  1078.                         'zz' AS fname, 
  1079.                         'zz' AS sname
  1080.                     FROM 
  1081.                         institutions i
  1082.                         LEFT JOIN countries c on c.id_country =  i.country_code
  1083.                         LEFT JOIN insttypes it on it.id_insttype =  i.inst_type_id
  1084.                     WHERE 
  1085.                         FIND_IN_SET (
  1086.                             :instRegion, 
  1087.                             i.inst_region
  1088.                         )
  1089.                         " $searchParams['instStatus'] . 
  1090.                     ORDER BY inst_name ASC 
  1091.                 ');
  1092.             $stmtInst->bindValue('instRegion'$searchParams['instRegion']);
  1093.             $stmtInst->execute();
  1094.             $dataResult $stmtInst->fetchAll();
  1095.             $sortFields['instType'] = 'Institution Type';
  1096.             $sortFields['inst_name'] = 'Institution Name';
  1097.             $searchParams['sortby'] = 'inst_name';
  1098.             $message 'There are <strong>' count($dataResult) . '</strong> institutions ';
  1099.             $message.= 'working in the "<strong>' self::getSeaRegionById($searchParams['instRegion'], $doctrine) . '</strong>".';
  1100.         }
  1101.         if ($searchParams['instType'] != '') {
  1102.             $stmtInst $connection->prepare("
  1103.                     SELECT 
  1104.                         'institutions' AS type, 
  1105.                         i.activated, 
  1106.                         i.id_inst, 
  1107.                         insttype_name AS instType, 
  1108.                         inst_name,
  1109.                         inst_name_eng,
  1110.                         inst_address,
  1111.                         addr_2,
  1112.                         city AS instCity,
  1113.                         state AS instState,
  1114.                         postcode AS instPostCode,
  1115.                         country,
  1116.                         activities,
  1117.                         inst_logo, 
  1118.                         'zz' AS jobtitle, 
  1119.                         'zz' AS eventtype,
  1120.                         'zz' AS fname, 
  1121.                         'zz' AS sname
  1122.                     FROM 
  1123.                         institutions i
  1124.                         LEFT JOIN countries c on c.id_country =  i.country_code
  1125.                         LEFT JOIN insttypes it on it.id_insttype =  i.inst_type_id
  1126.                     WHERE 
  1127.                         ( i.inst_type_id = :instType) 
  1128.                         " $searchParams['instStatus'] . 
  1129.                     ORDER BY inst_name ASC 
  1130.                 ');
  1131.             $stmtInst->bindValue('instType'$searchParams['instType']);
  1132.             $stmtInst->execute();
  1133.             $dataResult $stmtInst->fetchAll();
  1134.             $sortFields['instType'] = 'Institution Type';
  1135.             $sortFields['inst_name'] = 'Institution Name';
  1136.             $searchParams['sortby'] = 'inst_name';
  1137.             $message 'There are <strong>' count($dataResult) . '</strong> institutions ';
  1138.             $message.= 'with type "<strong>' SearchController::getInstituteTypeById($searchParams['instType'], $doctrine) . '</strong>".';
  1139.         }
  1140.         //status=0 means everything is ok
  1141.         return array(
  1142.             'status' => $status,
  1143.             'dataResult' => $dataResult,
  1144.             'sortFields' => $sortFields,
  1145.             'sortby' => $searchParams['sortby'],
  1146.             'message' => $message,
  1147.             'searchResultType' => $searchResultType
  1148.         );
  1149.     }
  1150.     /**
  1151.      * get the results for the search when action=advSearch
  1152.      *
  1153.      * @param array  $searchParams all the search parameters that have been passed in this request
  1154.      * @param object $doctrine
  1155.      *
  1156.      * @return array with the results
  1157.      */
  1158.     public static function getAdvSearchResults(array $searchParamsobject $doctrine): array
  1159.     {
  1160.         $connection $doctrine->getManager()->getConnection();
  1161.         $searchResultType 'Advanced Search Results';
  1162.         $dataResult = array();
  1163.         $sortBy $searchParams['sortby'];
  1164.         //$searchParams['sortby'] = 'sname';
  1165.         $messageStart 'Your search for ';
  1166.         $messagePart '';
  1167.         $sortFields $searchParams['sortFields'];
  1168.         if (isset($searchParams['searchType'])
  1169.             && isset($searchParams['searchType'][0])
  1170.             && $searchParams['searchType'][0] === 'all'
  1171.             && !count($searchParams['queryString'])
  1172.         ) {
  1173.             //we don't want a search for all types with specific search params
  1174.             return array(
  1175.                 'status' => 0,
  1176.                 'dataResult' => array(),
  1177.                 'sortFields' => $sortFields,
  1178.                 'sortby' => 'relevance',
  1179.                 'message' => 'we cannot show the results, too many results!!!!',
  1180.                 'searchResultType' => $searchResultType
  1181.             );
  1182.         } elseif (isset($searchParams['searchType'])
  1183.             && count($searchParams['searchType']) > 0
  1184.         ) {
  1185.             //dump($searchParams);
  1186.             //where to store the results for the different types
  1187.             $dataResultInd = array();
  1188.             $dataResultInst = array();
  1189.             $dataResultEvent = array();
  1190.             $dataResultDocument = array();
  1191.             $instCondCnt 1;
  1192.             $endQueryInst false;
  1193.             $endQueryInd false;
  1194.             $endQueryEvent false;
  1195.             $endQueryDocument false;
  1196.             $whereInd ' WHERE ( 1=1 ';
  1197.             $whereInst ' WHERE ( 1=1 ';
  1198.             $whereEvent ' WHERE ( 1=1 ';
  1199.             $whereDocument '';
  1200.             $joinsInd '';
  1201.             $searchParams['searchToggle'][-1] = ' AND ';
  1202.             $operationInd ' AND ';
  1203.             $operationInst ' AND ';
  1204.             $operationEvent ' AND ';
  1205.             $operation '';
  1206.             foreach ($searchParams['searchType'] as $key => $type) {
  1207.                 if (isset($searchParams['searchKeywords'])
  1208.                     && isset($searchParams['searchKeywords'][$key])
  1209.                 ) {
  1210.                     if (is_array($searchParams['searchKeywords'][$key])) {
  1211.                         foreach($searchParams['searchKeywords'][$key] as $value) {
  1212.                             $string[] = addcslashes($value,'\'');
  1213.                         }
  1214.                     } else {
  1215.                         $string addcslashes($searchParams['searchKeywords'][$key], '\'');
  1216.                     }
  1217.                 } else {
  1218.                     $string '';
  1219.                 }
  1220.                 //what kind of filter are we using
  1221.                 //there should be one at least, except for type=all
  1222.                 if (isset($searchParams['searchFilter'][$key])) {
  1223.                     $value $searchParams['searchFilter'][$key] ?? '';
  1224.                 } else {
  1225.                     $value $searchParams['searchFilter'][array_key_last($searchParams['searchFilter'])];
  1226.                 }
  1227.                 if ($type != 'all'
  1228.                     && $value == ''
  1229.                 ) {
  1230.                     continue;
  1231.                 }
  1232.                 if ($type == 'experts') {
  1233.                     if ($sortBy == '') {
  1234.                         $sortBy 'sname';
  1235.                     }
  1236.                     $bindValues[$type][$key] = array();
  1237.                     $selectQryInd "
  1238.                             SELECT 
  1239.                                 'experts' AS type, 
  1240.                                 i.status, 
  1241.                                 i.id_ind, 
  1242.                                 concat(i.fname,' ',i.sname) AS name,
  1243.                                 i.fname,
  1244.                                 i.mname,
  1245.                                 i.sname,
  1246.                                 inst.inst_name,
  1247.                                 i.jobtitle,
  1248.                                 i.addr_1,
  1249.                                 i.addr_2,
  1250.                                 i.city,
  1251.                                 i.state,
  1252.                                 i.postcode,
  1253.                                 inst.inst_address,
  1254.                                 inst.addr_2 AS instAddr2,
  1255.                                 inst.city AS instCity,
  1256.                                 inst.state AS instState,
  1257.                                 inst.postcode AS instPostCode, 
  1258.                                 i.use_inst_addr, 
  1259.                                 deceased, 
  1260.                                 retired, 
  1261.                                 quality_checked, 
  1262.                                 (CASE WHEN i.use_inst_addr = 1 THEN ic.country ELSE c.country END) AS country, 
  1263.                                 'zz' AS instType, 
  1264.                                 'zz' AS eventtype, 
  1265.                                 '' AS inst_logo ";
  1266.                     $commonJoins ' LEFT JOIN countries c on c.id_country =  i.country_code
  1267.                                 LEFT JOIN indiv_institution ii on ii.id_ind = i.id_ind
  1268.                                 LEFT JOIN institutions inst on inst.id_inst = ii.id_inst
  1269.                                 LEFT JOIN countries ic on ic.id_country =  inst.country_code ';
  1270.                     $matchOrder '';
  1271.                     switch ($value) {
  1272.                         case 'Name contains':
  1273.                             $newString self::fulltext($string);
  1274.                             $selectQryInd .= " , MATCH (fname, mname, sname) AGAINST ('$newString' IN BOOLEAN MODE) AS relevance ";
  1275.                             $whereInd .= ' ' $operationInd " ( i.fname LIKE  :percString$key
  1276.                                                     OR i.fname LIKE  :stringPerc$key
  1277.                                                     OR i.mname LIKE  :percString$key
  1278.                                                     OR i.mname LIKE  :stringPerc$key
  1279.                                                     OR i.sname LIKE  :percString$key
  1280.                                                     OR i.sname LIKE  :stringPerc$key
  1281.                                                     OR MATCH (fname, mname, sname) AGAINST ('$newString' IN BOOLEAN MODE) ) ";
  1282.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1283.                             $messagePart .= "in $type ";
  1284.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1285.                             $matchOrder ' ORDER BY relevance DESC';
  1286.                             //remember what value has to be bound to what placeholder
  1287.                             $bindValues[$type][$key] = array(
  1288.                                 'percString' $key => '%' $string,
  1289.                                 'stringPerc' $key => $string '%'
  1290.                             );
  1291.                             break;
  1292.                         case 'First name contains':
  1293.                             $whereInd .= ' ' $operationInd " ( 
  1294.                                                        i.fname LIKE  :percString$key
  1295.                                                     OR i.fname LIKE  :stringPerc$key ) ";
  1296.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1297.                             $messagePart .= "in $type ";
  1298.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1299.                             //remember what value has to be bound to what placeholder
  1300.                             $bindValues[$type][$key] = array(
  1301.                                 'percString' $key => '%' $string,
  1302.                                 'stringPerc' $key => $string '%'
  1303.                             );
  1304.                             break;
  1305.                         case 'Last name contains':
  1306.                             $whereInd .= ' ' $operationInd "( 
  1307.                                                        i.sname LIKE  :percString$key
  1308.                                                     OR i.sname LIKE  :stringPerc$key ) ";
  1309.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1310.                             $messagePart .= "in $type ";
  1311.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1312.                             //remember what value has to be bound to what placeholder
  1313.                             $bindValues[$type][$key] = array(
  1314.                                 'percString' $key => '%' $string,
  1315.                                 'stringPerc' $key => $string '%'
  1316.                             );
  1317.                             break;
  1318.                         case 'Worklocation contains':
  1319.                             $whereInd .= ' ' $operationInd 
  1320.                                         ( CASE 
  1321.                                             WHEN i.use_inst_addr = 1 THEN 
  1322.                                                 inst.inst_address LIKE  :percStringPerc$key
  1323.                                                     OR inst.addr_2 LIKE  :percStringPerc$key
  1324.                                                     OR inst.city LIKE  :percStringPerc$key
  1325.                                                     OR inst.state LIKE  :percStringPerc$key
  1326.                                             ELSE 
  1327.                                                 i.addr_1 LIKE  :percStringPerc$key
  1328.                                                     OR i.addr_2 LIKE  :percStringPerc$key
  1329.                                                     OR i.city LIKE  :percStringPerc$key
  1330.                                                     OR i.state LIKE  :percStringPerc$key
  1331.                                                     OR i.private_address LIKE  :percStringPerc$key
  1332.                                             END
  1333.                                         ) ";
  1334.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1335.                             $messagePart .= "in $type ";
  1336.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1337.                             //remember what value has to be bound to what placeholder
  1338.                             $bindValues[$type][$key] = array(
  1339.                                 'percStringPerc' $key => '%' $string '%'
  1340.                             );
  1341.                             break;
  1342.                         /*
  1343.                          * should not be used
  1344.                          * #680
  1345.                         case 'Current/Previous addresses contain':
  1346.                             $joinsInd .= ' LEFT JOIN previous_addresses pa on pa.id_record = i.id_ind ';
  1347.                             $whereInd .= ' ' . $operationInd . "
  1348.                                             ( CASE
  1349.                                                 WHEN i.use_inst_addr = 1 THEN
  1350.                                                     inst.inst_address LIKE  :percStringPerc$key
  1351.                                                         OR inst.addr_2 LIKE  :percStringPerc$key
  1352.                                                         OR inst.city LIKE  :percStringPerc$key
  1353.                                                         OR inst.state LIKE  :percStringPerc$key
  1354.                                                 ELSE
  1355.                                                     i.addr_1 LIKE  :percStringPerc$key
  1356.                                                         OR i.addr_2 LIKE  :percStringPerc$key
  1357.                                                         OR i.city LIKE  :percStringPerc$key
  1358.                                                         OR i.state LIKE  :percStringPerc$key
  1359.                                                         OR i.private_address LIKE  :percStringPerc$key
  1360.                                                         OR pa.city LIKE  :percStringPerc$key
  1361.                                                         OR pa.state LIKE  :percStringPerc$key
  1362.                                                         OR pa.address LIKE  :percStringPerc$key
  1363.                                                 END
  1364.                                             ) ";
  1365.                             $messagePart .= "$operation \"<strong>" . self::cleaned($string) . "</strong>\" ";
  1366.                             $messagePart .= "in $type ";
  1367.                             $messagePart .= "using filter \"<strong>" . self::readableFilter($value) . "</strong>\" ";
  1368.                             //remember what value has to be bound to what placeholder
  1369.                             $bindValues[$type][$key] = array(
  1370.                                 'percStringPerc' . $key => '%' . $string . '%'
  1371.                             );
  1372.                             break;
  1373.                         */
  1374.                         case 'Phone/Fax contains':
  1375.                             $whereInd .= ' ' $operationInd " (
  1376.                                                        i.tel LIKE  :percStringPerc$key
  1377.                                                     OR i.fax LIKE  :percStringPerc$key
  1378.                                                     )";
  1379.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1380.                             $messagePart .= "in $type ";
  1381.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1382.                             //remember what value has to be bound to what placeholder
  1383.                             $bindValues[$type][$key] = array(
  1384.                                 'percStringPerc' $key => '%' $string '%'
  1385.                             );
  1386.                             break;
  1387.                         case 'Email contains':
  1388.                             $whereInd .= ' ' $operationInd " (
  1389.                                                        i.email1 LIKE  :percStringPerc$key
  1390.                                                     OR i.email2 LIKE  :percStringPerc$key
  1391.                                                     OR i.email3 LIKE  :percStringPerc$key
  1392.                                                     ) ";
  1393.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1394.                             $messagePart .= "in $type ";
  1395.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1396.                             //remember what value has to be bound to what placeholder
  1397.                             $bindValues[$type][$key] = array(
  1398.                                 'percStringPerc' $key => '%' $string '%'
  1399.                             );
  1400.                             break;
  1401.                         case 'Website URL contains':
  1402.                             $whereInd .= ' ' $operationInd " (
  1403.                                                        i.url1 LIKE  :percStringPerc$key
  1404.                                                     OR i.url2 LIKE  :percStringPerc$key
  1405.                                                     OR i.url3 LIKE  :percStringPerc$key
  1406.                                                     ) ";
  1407.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1408.                             $messagePart .= "in $type ";
  1409.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1410.                             //remember what value has to be bound to what placeholder
  1411.                             $bindValues[$type][$key] = array(
  1412.                                 'percStringPerc' $key => '%' $string '%'
  1413.                             );
  1414.                             break;
  1415.                         case 'Worklocation is':
  1416.                             $whereInd .= ' ' $operationInd 
  1417.                                             ( CASE 
  1418.                                                 WHEN i.use_inst_addr = 1 THEN
  1419.                                                        inst.country_code = $string
  1420.                                                 ELSE
  1421.                                                        i.country_code = $string
  1422.                                                 END
  1423.                                             ) ";
  1424.                             $messagePart .= "$operation $type from  \"<strong>" self::getCountryById($string$doctrine) . "</strong>\" ";
  1425.                             break;
  1426.                         case 'Worklocation in countries':
  1427.                             $string implode(','$string);
  1428.                             $whereInd .= ' ' $operationInd 
  1429.                                             ( CASE 
  1430.                                                 WHEN i.use_inst_addr = 1 THEN
  1431.                                                     inst.country_code in ($string)
  1432.                                                 ELSE
  1433.                                                     i.country_code in ($string)
  1434.                                                 END
  1435.                                             ) ";
  1436.                             $messagePart .= "$operation $type from  \"<strong>" implode(', 'self::getMultipleCountriesById($string$doctrine)) . "</strong>\" ";
  1437.                             break;
  1438.                         case 'Worklocation in region':
  1439.                             //get the countries that are in that region
  1440.                             //the rest of the query is identical to 'Worklocation in countries'
  1441.                             $idRegion $string;
  1442.                             //reset $string, will be an array
  1443.                             $string = array();
  1444.                             //get the countries in that region
  1445.                             //and create an array with the ids of the countries
  1446.                             $countriesInRegion self::getCountriesInRegion($idRegion$doctrine);
  1447.                             foreach ($countriesInRegion as $country) {
  1448.                                 $string[] = $country->getIdCountry();
  1449.                             }
  1450.                             $string implode(','$string);
  1451.                             //this is identical to 'Worklocation in countries'
  1452.                             $whereInd .= ' ' $operationInd 
  1453.                                             ( CASE 
  1454.                                                 WHEN i.use_inst_addr = 1 THEN
  1455.                                                     inst.country_code in ($string)
  1456.                                                 ELSE
  1457.                                                     i.country_code in ($string)
  1458.                                                 END
  1459.                                             ) ";
  1460.                             $messagePart .= "$operation $type from the region ";
  1461.                             $messagePart .= '"<strong>' self::getRegionById($idRegion$doctrine) . '</strong>" ';
  1462.                             $messagePart .= ' (' implode(', 'self::getMultipleCountriesById($string$doctrine)) . ') ';
  1463.                             break;
  1464.                         case 'Sea regions of study is':
  1465.                             $whereInd .= ' ' $operationInd " (
  1466.                                                        FIND_IN_SET ('$string', i.studyregion)
  1467.                                                     ) ";
  1468.                             $messagePart .= "$operation \"<strong>" self::getSeaRegionById($string$doctrine) . "</strong>\" ";
  1469.                             $messagePart .= "in $type ";
  1470.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1471.                             break;
  1472.                         case 'Member of group or sub-group':
  1473.                             $groups implode(','self::getChildGroup($string$doctrine));
  1474.                             $joinsInd .= ' LEFT JOIN member_groups mg ON mg.id_ind = i.id_ind ';
  1475.                             $whereInd .= ' ' $operationInd " (
  1476.                                                         mg.id_group IN ($groups)
  1477.                                                     ) ";
  1478.                             $messagePart .= "$operation \"<strong>" self::getGroupById($string$doctrine) . "</strong>\" ";
  1479.                             $messagePart .= "in $type ";
  1480.                             $messagePart .= "using filter \"<strong>Member of group OR sub-group</strong>\" ";
  1481.                             break;
  1482.                         case 'Job type is':
  1483.                             $joinsInd .= " LEFT JOIN indiv_jobtype ij ON ij.id_ind = i.id_ind ";
  1484.                             $whereInd .= ' ' $operationInd " (
  1485.                                                        id_job = $string
  1486.                                                     ) ";
  1487.                             $messagePart .= "$operation \"<strong>" self::getJobTypesById($string$doctrine) . "</strong>\" ";
  1488.                             $messagePart .= "in $type ";
  1489.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1490.                             break;
  1491.                         case 'Job title contains':
  1492.                             $whereInd .= ' ' $operationInd " (
  1493.                                                        i.jobtitle LIKE  :percString$key
  1494.                                                     OR i.jobtitle LIKE  :stringPerc$key
  1495.                                                     ) ";
  1496.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1497.                             $messagePart .= "in $type ";
  1498.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1499.                             //remember what value has to be bound to what placeholder
  1500.                             $bindValues[$type][$key] = array(
  1501.                                 'percString' $key => '%' $string,
  1502.                                 'stringPerc' $key => $string '%'
  1503.                             );
  1504.                             break;
  1505.                         case 'Department contains':
  1506.                             $whereInd .= ' ' $operationInd " (
  1507.                                                        i.dept LIKE  :percString$key
  1508.                                                     OR i.dept LIKE  :stringPerc$key
  1509.                                                     ) ";
  1510.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1511.                             $messagePart .= "in $type ";
  1512.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1513.                             //remember what value has to be bound to what placeholder
  1514.                             $bindValues[$type][$key] = array(
  1515.                                 'percString' $key => '%' $string,
  1516.                                 'stringPerc' $key => $string '%'
  1517.                             );
  1518.                             break;
  1519.                         case 'Institution name contains':
  1520.                             $whereInd .= ' ' $operationInd " (
  1521.                                                        inst.inst_name LIKE  :percStringPerc$key
  1522.                                                     OR inst.inst_name_eng LIKE  :percStringPerc$key
  1523.                                                     OR inst.acronym LIKE  :percStringPerc$key
  1524.                                                     ) ";
  1525.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1526.                             $messagePart .= "in $type ";
  1527.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1528.                             //remember what value has to be bound to what placeholder
  1529.                             $bindValues[$type][$key] = array(
  1530.                                 'percStringPerc' $key => '%' $string '%'
  1531.                             );
  1532.                             break;
  1533.                         case 'Subject Area is':
  1534.                             $joinsInd .= " LEFT JOIN indiv_meta im ON im.indiv_id = i.id_ind ";
  1535.                             $whereInd .= ' ' $operationInd " (
  1536.                                                        im.meta_option = 'researcharea'
  1537.                                                     AND im.meta_value LIKE  :percStringPerc$key
  1538.                                                     ) ";
  1539.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1540.                             $messagePart .= "in $type ";
  1541.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1542.                             //remember what value has to be bound to what placeholder
  1543.                             $bindValues[$type][$key] = array(
  1544.                                 'percStringPerc' $key => '%' $string '%'
  1545.                             );
  1546.                             break;
  1547.                         case 'Activities include':
  1548.                             $whereInd .= ' ' $operationInd " (
  1549.                                                        i.activeng LIKE  :percStringPerc$key
  1550.                                                     ) ";
  1551.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1552.                             $messagePart .= "in $type ";
  1553.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1554.                             //remember what value has to be bound to what placeholder
  1555.                             $bindValues[$type][$key] = array(
  1556.                                 'percStringPerc' $key => '%' $string '%'
  1557.                             );
  1558.                             break;
  1559.                         case 'Citations include':
  1560.                             $joinsInd .= " LEFT JOIN indiv_meta im ON im.indiv_id = i.id_ind ";
  1561.                             $whereInd .= ' ' $operationInd " (
  1562.                                                         (
  1563.                                                             im.meta_option = 'researcharea'
  1564.                                                             AND im.meta_value LIKE  :percStringPerc$key
  1565.                                                         )
  1566.                                                         OR (
  1567.                                                             im.meta_option = 'other-citation'
  1568.                                                             AND im.meta_value LIKE  :percStringPerc$key
  1569.                                                         )
  1570.                                                         OR (
  1571.                                                             im.meta_option = 'researchgate'
  1572.                                                             AND im.meta_value LIKE  :percStringPerc$key
  1573.                                                         )
  1574.                                                     ) ";
  1575.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1576.                             $messagePart .= "in $type ";
  1577.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1578.                             //remember what value has to be bound to what placeholder
  1579.                             $bindValues[$type][$key] = array(
  1580.                                 'percStringPerc' $key => '%' $string '%'
  1581.                             );
  1582.                             break;
  1583.                         case 'Working languages includes':
  1584.                             $whereInd .= ' ' $operationInd " (
  1585.                                                        FIND_IN_SET ('$string', i.languages)
  1586.                                                     ) ";
  1587.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1588.                             $messagePart .= "in $type ";
  1589.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1590.                             break;
  1591.                         case 'Degree contains':
  1592.                             $whereInd .= ' ' $operationInd " (
  1593.                                                        i.degree LIKE  :percStringPerc$key
  1594.                                                     ) ";
  1595.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1596.                             $messagePart .= "in $type ";
  1597.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1598.                             //remember what value has to be bound to what placeholder
  1599.                             $bindValues[$type][$key] = array(
  1600.                                 'percStringPerc' $key => '%' $string '%'
  1601.                             );
  1602.                             break;
  1603.                         case 'Is retired':
  1604.                             $whereInd .= ' ' $operationInd " (
  1605.                                                        i.retired = $string
  1606.                                                     ) ";
  1607.                             $messagePart .= "$operation experts who are \"<strong>Retired</strong>\" ";
  1608.                             break;
  1609.                         case 'Is deceased':
  1610.                             $whereInd .= ' ' $operationInd " (
  1611.                                                        i.deceased = $string
  1612.                                                     ) ";
  1613.                             $messagePart .= "$operation  experts who are \"<strong>Deceased</strong>\" ";
  1614.                             break;
  1615.                         case 'Is quality checked':
  1616.                             $whereInd .= ' ' $operationInd " (
  1617.                                                        i.quality_checked = $string
  1618.                                                     ) ";
  1619.                             $messagePart .= "$operation experts who are \"<strong>Quality checked</strong>\" ";
  1620.                             break;
  1621.                         case 'Comment contains':
  1622.                             $whereInd .= ' ' $operationInd " (
  1623.                                                        i.comments LIKE  :percStringPerc$key
  1624.                                                     ) ";
  1625.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1626.                             $messagePart .= "in $type ";
  1627.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1628.                             //remember what value has to be bound to what placeholder
  1629.                             $bindValues[$type][$key] = array(
  1630.                                 'percStringPerc' $key => '%' $string '%'
  1631.                             );
  1632.                             break;
  1633.                         case 'Is Active':
  1634.                             $whereInd .= ' ' $operationInd " (
  1635.                                                         i.status = $string
  1636.                                                 ) ";
  1637.                             if ($string == '1') {
  1638.                                 $messagePart .= "$operation expert is <strong>Active</strong> ";
  1639.                             } else {
  1640.                                 $messagePart .= "$operation expert is <strong>not active</strong> ";
  1641.                             }
  1642.                             break;
  1643.                         case 'Gender is':
  1644.                             // #734 we have different values for this 'gender' filter
  1645.                             // 'male' and 'female' are simple
  1646.                             // but we have 'na', 'other' and '' in the database
  1647.                             // '' and 'na' mean 'prefer not to say'
  1648.                             // 'other' means 'other'
  1649.                             $whereInd .= ' ' $operationInd " ( 
  1650.                                                         i.gender = '$string' ";
  1651.                             if ($string == 'na') {
  1652.                                 $whereInd .= ' OR i.gender = "" ';
  1653.                                 $string 'Prefer not to say';
  1654.                             } else {
  1655.                                 $string ucfirst($string);
  1656.                             }
  1657.                             $whereInd .= ' ) ';
  1658.                             $messagePart .= "$operation $type \"<strong>" self::readableFilter($value) . "</strong>\"  \"<strong>$string</strong>\" ";
  1659.                             break;
  1660.                         case 'Do Not Invite':
  1661.                             $whereInd .= ' ' $operationInd " (
  1662.                                                         i.do_not_invite = 1
  1663.                                                 ) ";
  1664.                             $messagePart .= "$operation $type using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1665.                             break;
  1666.                         case 'Unique Identifier':
  1667.                             $whereInd .= ' ' $operationInd " (
  1668.                                                 i.id_ind = '$string'
  1669.                                                 ) ";
  1670.                             $messagePart .= "$operation $type having unique identifier \"<strong>$string</strong>\" ";
  1671.                             break;
  1672.                         case 'Updated':
  1673.                             $startDate = isset($searchParams['startDate'][$key]) ? "l_date_upd >= '" self::cleanDate($searchParams['startDate'][$key]) . "' " "1=1 ";
  1674.                             $endDate = isset($searchParams['endDate'][$key]) ? "and l_date_upd <= '" self::cleanDate($searchParams['endDate'][$key]) . "' " " AND 1=1 ";
  1675.                             $whereInd .= ' ' $operationInd ' ' $startDate ' ' $endDate;
  1676.                             $messagePart .= "$operation $type updated ";
  1677.                             $messagePart .= "between \"<strong>" self::cleaned($searchParams['startDate'][$key]) . "</strong>\" ";
  1678.                             $messagePart .= "and \"<strong>" self::cleaned($searchParams['endDate'][$key]) . "</strong>\" ";
  1679.                             break;
  1680.                         case 'Created':
  1681.                             $startDate = isset($searchParams['startDate'][$key]) ? "f_date_ent >= '" self::cleanDate($searchParams['startDate'][$key]) . "' " "1=1 ";
  1682.                             $endDate = isset($searchParams['endDate'][$key]) ? "and f_date_ent <= '" self::cleanDate($searchParams['endDate'][$key]) . "' " " AND 1=1 ";
  1683.                             $whereInd .= ' ' $operationInd ' ' $startDate ' ' $endDate;
  1684.                             $messagePart .= "$operation $type \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1685.                             $messagePart .= "between \"<strong>" self::cleaned($searchParams['startDate'][$key]) . "</strong>\" ";
  1686.                             $messagePart .= "and \"<strong>" self::cleaned($searchParams['endDate'][$key]) . "</strong>\" ";
  1687.                             break;
  1688.                         case 'Quality last checked':
  1689.                             $startDate = isset($searchParams['startDate'][$key]) ? "quality_checked_date > '" self::cleanDate($searchParams['startDate'][$key]) . "' " "1=1 ";
  1690.                             $endDate = isset($searchParams['endDate'][$key]) ? "and quality_checked_date < '" self::cleanDate($searchParams['endDate'][$key]) . "' " " AND 1=1 ";
  1691.                             $whereInd .= ' ' $operationInd ' ' $startDate ' ' $endDate;
  1692.                             $messagePart .= "$operation $type \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1693.                             $messagePart .= "between \"<strong>" self::cleaned($searchParams['startDate'][$key]) . "</strong>\" ";
  1694.                             $messagePart .= "and \"<strong>" self::cleaned($searchParams['endDate'][$key]) . "</strong>\" ";
  1695.                             break;
  1696.                         default:
  1697.                             break;
  1698.                     }
  1699.                     $operationInd $searchParams['searchToggle'][$key] ?? " OR ";
  1700.                     $operation $searchParams['searchToggle'][$key] ?? " OR ";
  1701.                 } elseif ($type == 'institutions') {
  1702.                     if ($sortBy == '') {
  1703.                         $sortBy 'name';
  1704.                     }
  1705.                     $bindValues[$type][$key] = array();
  1706.                     $selectQryInst "
  1707.                             SELECT 
  1708.                                 'institutions' AS type, 
  1709.                                 i.activated, 
  1710.                                 i.id_inst, 
  1711.                                 it.insttype_name AS instType, 
  1712.                                 i.inst_name,
  1713.                                 i.inst_name_eng,
  1714.                                 i.inst_address,
  1715.                                 i.addr_2,
  1716.                                 i.city AS instCity,
  1717.                                 i.state AS instState,
  1718.                                 i.postcode AS instPostCode,
  1719.                                 c.country,
  1720.                                 i.activities,
  1721.                                 i.inst_logo,
  1722.                                 i.parent_id,   
  1723.                                 '' AS jobtitle, 
  1724.                                 '' AS eventtype,
  1725.                                 '' AS fname, 
  1726.                                 '' AS sname
  1727.                             FROM 
  1728.                                 institutions i
  1729.                         ";
  1730.                     $joinsInst ' LEFT JOIN countries c ON c.id_country =  i.country_code
  1731.                                         LEFT JOIN insttypes it ON it.id_insttype =  i.inst_type_id ';
  1732.                     switch ($value) {
  1733.                         case 'Name contains':
  1734.                             $whereInst .= ' ' $operationInst " ( 
  1735.                                                    i.inst_name LIKE  :percStringPerc$key
  1736.                                                 OR i.inst_name_eng LIKE  :percStringPerc$key
  1737.                                                 OR i.acronym LIKE  :percStringPerc$key
  1738.                                                         ) ";
  1739.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1740.                             $messagePart .= "in $type ";
  1741.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1742.                             //remember what value has to be bound to what placeholder
  1743.                             $bindValues[$type][$key] = array(
  1744.                                 'percStringPerc' $key => '%' $string '%'
  1745.                             );
  1746.                             break;
  1747.                         /**
  1748.                          * does not exist
  1749.                          *
  1750.                         case 'Worklocation contains':
  1751.                             $whereInst .= ' ' . $operationInst . " ( 
  1752.                                                           i.inst_address LIKE  :percStringPerc$key
  1753.                                                     OR i.addr_2 LIKE  :percStringPerc$key
  1754.                                                     OR i.city LIKE  :percStringPerc$key
  1755.                                                     OR i.state LIKE  :percStringPerc$key
  1756.                                                        ) ";
  1757.                             $messagePart .= "$operation \"<strong>" . self::cleaned($string) . "</strong>\" ";
  1758.                             $messagePart .= "in $type ";
  1759.                             $messagePart .= "using filter \"<strong>" . self::readableFilter($value) . "</strong>\" ";
  1760.                             //remember what value has to be bound to what placeholder
  1761.                             $bindValues[$type][$key] = array(
  1762.                                 'percStringPerc' . $key => '%' . $string . '%'
  1763.                             );
  1764.                             break;
  1765.                         */
  1766.                         /*
  1767.                          * #680
  1768.                          *
  1769.                         case 'Current/Previous addresses contain':
  1770.                             $whereInst .= ' ' . $operationInst . " (
  1771.                                                           i.inst_address LIKE  :percString$key
  1772.                                                     OR i.addr_2 LIKE  :percStringPerc$key
  1773.                                                     OR i.city LIKE  :percStringPerc$key
  1774.                                                     OR i.state LIKE  :percStringPerc$key
  1775.                                                        ) ";
  1776.                             $messagePart .= "$operation \"<strong>" . self::cleaned($string) . "</strong>\" ";
  1777.                             $messagePart .= "in $type ";
  1778.                             $messagePart .= "using filter \"<strong>" . self::readableFilter($value) . "</strong>\" ";
  1779.                             //remember what value has to be bound to what placeholder
  1780.                             $bindValues[$type][$key] = array(
  1781.                                 'percString' . $key => '%' . $string,
  1782.                                 'percStringPerc' . $key => '%' . $string . '%'
  1783.                             );
  1784.                             break;
  1785.                         */
  1786.                         case 'Country is':
  1787.                             $whereInst .= ' ' $operationInst " ( 
  1788.                                                           i.country_code = $string
  1789.                                                        ) ";
  1790.                             $messagePart .= "$operation $type ";
  1791.                             $messagePart .= "from  \"<strong>" self::getCountryById($string$doctrine) . "</strong>\" ";
  1792.                             break;
  1793.                         case 'Country in region':
  1794.                             $idRegion $string;
  1795.                             //reset $string, will be an array
  1796.                             $string = array();
  1797.                             //get the countries in that region
  1798.                             //and create an array with the ids of the countries
  1799.                             $countriesInRegion self::getCountriesInRegion($idRegion$doctrine);
  1800.                             foreach ($countriesInRegion as $country) {
  1801.                                 $string[] = $country->getIdCountry();
  1802.                             }
  1803.                             $string implode(','$string);
  1804.                             //this is identical to 'Worklocation in countries'
  1805.                             $whereInst .= ' ' $operationInd " ( 
  1806.                                                     i.country_code in ($string)
  1807.                                             ) ";
  1808.                             $messagePart .= "$operation $type from the region ";
  1809.                             $messagePart .= '"<strong>' self::getRegionById($idRegion$doctrine) . '</strong>" ';
  1810.                             $messagePart .= ' (' implode(', 'self::getMultipleCountriesById($string$doctrine)) . ') ';
  1811.                             break;
  1812.                         case 'Sea regions of study is':
  1813.                             $whereInst .= ' ' $operationInst " ( 
  1814.                                                           FIND_IN_SET ('$string', i.inst_region)
  1815.                                                        ) ";
  1816.                             $messagePart .= "$operation $type ";
  1817.                             $messagePart .= "having $value \"<strong>" self::getSeaRegionById($string$doctrine) . "</strong>\" ";
  1818.                             break;
  1819.                         case 'Type is':
  1820.                             $whereInst .= ' ' $operationInst " ( 
  1821.                                                           i.inst_type_id = $string
  1822.                                                        ) ";
  1823.                             $messagePart .= "$operation $type having " self::readableFilter($value) . " \"<strong>";
  1824.                             $messagePart .= SearchController::getInstituteTypeById($string$doctrine) . "</strong>\"";
  1825.                             break;
  1826.                         case 'Activities contains':
  1827.                             $whereInst .= ' ' $operationInst " (
  1828.                                                     i.activities LIKE  :percStringPerc$key
  1829.                                                     ) ";
  1830.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1831.                             $messagePart .= "in $type ";
  1832.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1833.                             //remember what value has to be bound to what placeholder
  1834.                             $bindValues[$type][$key] = array(
  1835.                                 'percStringPerc' $key => '%' $string '%'
  1836.                             );
  1837.                             break;
  1838.                         case 'Tel/Fax contains':
  1839.                             $whereInst .= ' ' $operationInst " ( 
  1840.                                                           i.inst_tel LIKE  :percStringPerc$key
  1841.                                                     OR i.inst_fax LIKE  :percStringPerc$key
  1842.                                                        ) ";
  1843.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1844.                             $messagePart .= "in $type ";
  1845.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1846.                             //remember what value has to be bound to what placeholder
  1847.                             $bindValues[$type][$key] = array(
  1848.                                 'percStringPerc' $key => '%' $string '%'
  1849.                             );
  1850.                             break;
  1851.                         case 'Website URL contains':
  1852.                             $whereInst .= ' ' $operationInst " ( 
  1853.                                                           i.inst_url LIKE  :percStringPerc$key
  1854.                                                        ) ";
  1855.                             $messagePart .= "$operation \"<strong" self::cleaned($string) . "</strong>\" ";
  1856.                             $messagePart .= "in $type ";
  1857.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1858.                             //remember what value has to be bound to what placeholder
  1859.                             $bindValues[$type][$key] = array(
  1860.                                 'percStringPerc' $key => '%' $string '%'
  1861.                             );
  1862.                             break;
  1863.                         case 'EDMO Code is':
  1864.                             $whereInst .= ' ' $operationInst " ( 
  1865.                                                           i.edmo_code = '$string'
  1866.                                                           AND edmo_code != 0
  1867.                                                           ) ";
  1868.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  1869.                             $messagePart .= "in $type ";
  1870.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1871.                             break;
  1872.                         case 'Updated':
  1873.                             $startDate = isset($searchParams['startDate'][$key]) ? "l_date_updated >= '" self::cleanDate($searchParams['startDate'][$key]) . "' " "1=1 ";
  1874.                             $endDate = isset($searchParams['endDate'][$key]) ? "AND l_date_updated <= '" self::cleanDate($searchParams['endDate'][$key]) . "' " " AND 1=1 ";
  1875.                             $whereInst .= ' ' $operationInst ' ' $startDate ' ' $endDate;
  1876.                             $messagePart .= "$operation $type \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1877.                             $messagePart .= "between \"<strong>" self::cleaned($searchParams['startDate'][$key]) . "</strong>\" ";
  1878.                             $messagePart .= "and \"<strong>" self::cleaned($searchParams['endDate'][$key]) . "</strong>\" ";
  1879.                             break;
  1880.                         case 'Created':
  1881.                             $startDate = isset($searchParams['startDate'][$key]) ? "f_date_entered >= '" self::cleanDate($searchParams['startDate'][$key]) . "' " "1=1 ";
  1882.                             $endDate = isset($searchParams['endDate'][$key]) ? "AND f_date_entered <= '" self::cleanDate($searchParams['endDate'][$key]) . "' " " AND 1=1 ";
  1883.                             $whereInst .= ' ' $operationInst ' ' $startDate ' ' $endDate;
  1884.                             $messagePart .= "$operation $type \"<strong>" self::readableFilter($value) . "</strong>\" ";
  1885.                             $messagePart .= "between \"<strong>" self::cleaned($searchParams['startDate'][$key]) . "</strong>\" ";
  1886.                             $messagePart .= "and \"<strong>" self::cleaned($searchParams['endDate'][$key]) . "</strong>\" ";
  1887.                             break;
  1888.                     }
  1889.                     $instCondCnt++;
  1890.                     $operationInst $searchParams['searchToggle'][$key] ?? " OR ";
  1891.                     $operation $searchParams['searchToggle'][$key] ?? " OR ";
  1892.                 } elseif ($type == 'all') {
  1893.                     $newString self::fulltext($string);
  1894.                     $stmtInd $connection->prepare("
  1895.                             SELECT 
  1896.                                 'experts' AS type, 
  1897.                                 i.status, 
  1898.                                 i.id_ind, 
  1899.                                 concat(i.fname,' ',i.sname) AS name, 
  1900.                                 i.fname,
  1901.                                 i.mname,
  1902.                                 i.sname, 
  1903.                                 inst_name,
  1904.                                 jobtitle,
  1905.                                 i.addr_1,
  1906.                                 i.addr_2,
  1907.                                 i.city,
  1908.                                 i.state,
  1909.                                 i.postcode,
  1910.                                 inst.inst_address,
  1911.                                 inst.addr_2 AS instAddr2,
  1912.                                 inst.city AS instCity,
  1913.                                 inst.state AS instState,
  1914.                                 inst.postcode AS instPostCode, 
  1915.                                 use_inst_addr, 
  1916.                                 deceased, 
  1917.                                 retired, 
  1918.                                 quality_checked, 
  1919.                                 (IF(use_inst_addr = 1, ic.country, c.country)) AS country, 
  1920.                                 MATCH (fname, sname) AGAINST (:newString IN BOOLEAN MODE) AS relevance, 
  1921.                                 'zz' AS instType, 
  1922.                                 'zz' AS eventtype, 
  1923.                                 '' AS inst_logo
  1924.                             FROM 
  1925.                                 indiv i
  1926.                                 LEFT JOIN countries c ON c.id_country =  i.country_code
  1927.                                 LEFT JOIN indiv_institution ii ON ii.id_ind = i.id_ind
  1928.                                 LEFT JOIN institutions inst ON inst.id_inst = ii.id_inst
  1929.                                 LEFT JOIN countries ic ON ic.id_country =  inst.country_code
  1930.                             WHERE 
  1931.                                 ( 
  1932.                                     MATCH (fname, mname, sname) AGAINST (:newString IN BOOLEAN MODE)
  1933.                                     OR fname LIKE :string
  1934.                                     OR fname LIKE :stringPerc
  1935.                                     OR fname LIKE :percString
  1936.                                     OR mname LIKE :stringPerc
  1937.                                     OR mname LIKE :percString
  1938.                                     OR sname LIKE :stringPerc
  1939.                                     OR sname LIKE :percString
  1940.                                 )
  1941.                                 " $searchParams['indivStatus'] . '
  1942.                             ORDER BY relevance DESC, i.sname ASC;
  1943.                         ');
  1944.                     $stmtInd->bindValue('newString'$newString);
  1945.                     $stmtInd->bindValue('string'$string);
  1946.                     $stmtInd->bindValue('percString''%' $string);
  1947.                     $stmtInd->bindValue('stringPerc'$string '%');
  1948.                     $stmtInd->bindValue('percStringPerc''%' $string '%');
  1949.                     $stmtInd->execute();
  1950.                     $dataResultInd $stmtInd->fetchAll();
  1951.                     $sortFields['jobtitle'] = 'Position';
  1952.                     $stmtInst $connection->prepare("
  1953.                             SELECT 
  1954.                                 'institutions' AS type, 
  1955.                                 i.activated, 
  1956.                                 i.id_inst, 
  1957.                                 insttype_name AS instType, 
  1958.                                 inst_name,
  1959.                                 inst_name_eng,
  1960.                                 inst_address,
  1961.                                 addr_2,
  1962.                                 city AS instCity,
  1963.                                 state AS instState,
  1964.                                 postcode AS instPostCode,
  1965.                                 country,
  1966.                                 activities,
  1967.                                 inst_logo,
  1968.                                 'zz' AS jobtitle, 
  1969.                                 MATCH (inst_name,inst_name_eng,acronym) AGAINST (:newString) AS relevance, 
  1970.                                 'zz' AS eventtype, 
  1971.                                 'zz' AS fname, 
  1972.                                 'zz' AS sname
  1973.                             FROM 
  1974.                                 institutions i
  1975.                                 LEFT JOIN countries c ON c.id_country =  i.country_code
  1976.                                 LEFT JOIN insttypes it ON it.id_insttype =  i.inst_type_id
  1977.                             WHERE 
  1978.                                 (
  1979.                                     MATCH (inst_name, inst_name_eng, acronym) AGAINST (:newString IN BOOLEAN MODE)
  1980.                                     OR inst_name LIKE :percStringPerc
  1981.                                     OR inst_name_eng LIKE :percStringPerc
  1982.                                     OR acronym LIKE :percStringPerc
  1983.                                     OR activities LIKE :percStringPerc
  1984.                                 )
  1985.                                  " $searchParams['instStatus'] . '
  1986.                             ORDER BY relevance DESC, i.inst_name ASC;
  1987.                         ');
  1988.                     $stmtInst->bindValue('newString'$newString);
  1989.                     $stmtInst->bindValue('percStringPerc''%' $string '%');
  1990.                     $stmtInst->execute();
  1991.                     $dataResultInst $stmtInst->fetchAll();
  1992.                     $sortFields['instType'] = 'Institution Type';
  1993.                     /**
  1994.                      *    Will be taken care when PPC
  1995.                      */
  1996.                     $stmtEvent $connection->prepare("
  1997.                             SELECT 
  1998.                                 'events' AS type, 
  1999.                                 et.eventtype_name AS eventtype, 
  2000.                                 e.status AS activated, 
  2001.                                 e.id_event, 
  2002.                                 e.title AS name, 
  2003.                                 e.start_on, 
  2004.                                 e.end_on, 
  2005.                                 e.address AS addr_1, 
  2006.                                 e.city, 
  2007.                                 e.state, 
  2008.                                 c.country AS country, 
  2009.                                 'zz' AS jobtitle, 
  2010.                                 'zz' AS instType, 
  2011.                                 'zz' AS fname, 
  2012.                                 'zz' AS sname, 
  2013.                                 'zz' AS inst_name
  2014.                             FROM 
  2015.                                 events e
  2016.                                 LEFT JOIN countries c on c.id_country =  e.id_country
  2017.                                 LEFT JOIN eventtypes et on et.id_eventtype =  e.id_eventtype
  2018.                             WHERE 
  2019.                                 (
  2020.                                     title LIKE  :percStringPerc
  2021.                                     OR shorttitle LIKE  :percStringPerc
  2022.                                     OR summary LIKE  :percStringPerc
  2023.                                     OR keywords LIKE  :percStringPerc
  2024.                                 )
  2025.                                 " $searchParams['eventStatus'] . '
  2026.                             ORDER BY start_on desc
  2027.                         ');
  2028.                     $stmtEvent->bindValue('percStringPerc''%' $string '%');
  2029.                     $stmtEvent->execute();
  2030.                     $dataResultEvent $stmtEvent->fetchAll();
  2031.                     $messagePart .= ' "<strong>' self::cleaned($string) . '</strong>" ';
  2032.                 } elseif ($type == 'events') {
  2033.                     $sortFields['name'] = 'Event Title';
  2034.                     if ($sortBy == '') {
  2035.                         $sortBy 'name';
  2036.                     }
  2037.                     $bindValues[$type][$key] = array();
  2038.                     $selectQryEvent "
  2039.                             SELECT 
  2040.                                 'events' AS type, 
  2041.                                 et.eventtype_name AS eventtype, 
  2042.                                 e.status AS activated, 
  2043.                                 e.id_event, 
  2044.                                 e.title AS name, 
  2045.                                 e.start_on, 
  2046.                                 e.end_on, 
  2047.                                 e.address AS addr_1, 
  2048.                                 e.city, 
  2049.                                 e.state, 
  2050.                                 c.country AS country, 
  2051.                                 'zz' AS jobtitle, 
  2052.                                 'zz' AS instType,
  2053.                                 'zz' AS fname, 
  2054.                                 'zz' AS sname
  2055.                             FROM 
  2056.                                  events e ";
  2057.                     $joinsEvent ' LEFT JOIN countries c ON c.id_country = e.id_country
  2058.                                        LEFT JOIN eventtypes et ON et.id_eventtype = e.id_eventtype ';
  2059.                     switch ($value) {
  2060.                         case 'Title contains':
  2061.                             $whereEvent .= ' ' $operationEvent " (
  2062.                                                   e.title LIKE  :percStringPerc$key
  2063.                                                        ) ";
  2064.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  2065.                             $messagePart .= "in $type ";
  2066.                             $messagePart .= "using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2067.                             //remember what value has to be bound to what placeholder
  2068.                             $bindValues[$type][$key] = array(
  2069.                                 'percStringPerc' $key => '%' $string '%'
  2070.                             );
  2071.                             break;
  2072.                         case 'eType is':
  2073.                             $whereEvent .= ' ' $operationEvent " (
  2074.                                                   e.id_eventtype = $string
  2075.                                                        ) ";
  2076.                             $messagePart .= "$operation $type ";
  2077.                             $messagePart .= "having Event Type \"<strong>" SearchController::getInstituteTypeById($string$doctrine) . "</strong>\" ";
  2078.                             break;
  2079.                         case 'Summary contains':
  2080.                             $whereEvent .= ' ' $operationEvent " (
  2081.                                                   e.summary LIKE  :percStringPerc$key
  2082.                                                        ) ";
  2083.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  2084.                             $messagePart .= "in $type using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2085.                             //remember what value has to be bound to what placeholder
  2086.                             $bindValues[$type][$key] = array(
  2087.                                 'percStringPerc' $key => '%' $string '%'
  2088.                             );
  2089.                             break;
  2090.                         case 'Keywords contain':
  2091.                             $whereEvent .= ' ' $operationEvent " (
  2092.                                                e.keywords LIKE  :percStringPerc$key
  2093.                                               ) ";
  2094.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  2095.                             $messagePart .= "in $type using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2096.                             //remember what value has to be bound to what placeholder
  2097.                             $bindValues[$type][$key] = array(
  2098.                                 'percStringPerc' $key => '%' $string '%'
  2099.                             );
  2100.                             break;
  2101.                         case 'Address contains':
  2102.                             $whereEvent .= ' ' $operationEvent " (
  2103.                                                e.address LIKE  :percStringPerc$key
  2104.                                                OR e.city LIKE  :percStringPerc$key
  2105.                                                OR e.state LIKE  :percStringPerc$key
  2106.                                               ) ";
  2107.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  2108.                             $messagePart .= "in $type using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2109.                             //remember what value has to be bound to what placeholder
  2110.                             $bindValues[$type][$key] = array(
  2111.                                 'percStringPerc' $key => '%' $string '%'
  2112.                             );
  2113.                             break;
  2114.                         case 'Country is':
  2115.                             dump($string);
  2116.                             $whereEvent .= ' ' $operationEvent " (
  2117.                                                e.id_country = $string
  2118.                                               ) ";
  2119.                             $messagePart .= "$operation $type ";
  2120.                             $messagePart .= "from  \"<strong>" self::getCountryById($string$doctrine) . "</strong>\" ";
  2121.                             break;
  2122.                         case 'Country in region':
  2123.                             $idRegion $string;
  2124.                             //reset $string, will be an array
  2125.                             $string = array();
  2126.                             //get the countries in that region
  2127.                             //and create an array with the ids of the countries
  2128.                             $countriesInRegion self::getCountriesInRegion($idRegion$doctrine);
  2129.                             foreach ($countriesInRegion as $country) {
  2130.                                 $string[] = $country->getIdCountry();
  2131.                             }
  2132.                             $string implode(','$string);
  2133.                             $whereEvent .= ' ' $operationInd " ( 
  2134.                                                     e.id_country in ($string)
  2135.                                              ) ";
  2136.                             $messagePart .= "$operation $type from the region ";
  2137.                             $messagePart .= '"<strong>' self::getRegionById($idRegion$doctrine) . '</strong>" ';
  2138.                             $messagePart .= ' (' implode(', 'self::getMultipleCountriesById($string$doctrine)) . ') ';
  2139.                             break;
  2140.                         case 'Date between':
  2141.                             $date '';
  2142.                             $messagePart .= "$operation $type with parameters '<strong>" self::readableFilter($value) . "</strong>': ";
  2143.                             if (isset($searchParams['startDate'][$key])
  2144.                                 && $searchParams['startDate'][$key] != ''
  2145.                                 && isset($searchParams['endDate'][$key])
  2146.                                 && $searchParams['endDate'][$key] != ''
  2147.                             ) {
  2148.                                 $startDate self::cleanDate($searchParams['startDate'][$key]);
  2149.                                 $endDate self::cleanDate($searchParams['endDate'][$key]);
  2150.                                 $date " start_on >= '$startDate
  2151.                                         AND end_on <= '$endDate' ";
  2152.                                 $messagePart .= "between '<strong>$startDate</strong>' ";
  2153.                                 $messagePart .= "and '<strong>$endDate</strong>' ";
  2154.                             } elseif (isset($searchParams['startDate'][$key])
  2155.                                 && (!$searchParams['endDate'][$key]
  2156.                                     || $searchParams['endDate'][$key] == '')
  2157.                             ) {
  2158.                                 $startDate self::cleanDate($searchParams['startDate'][$key]);
  2159.                                 $date " start_on >= '$startDate' ";
  2160.                                 $messagePart .= " -> after '<strong>$startDate</strong>' ";
  2161.                             } elseif (isset($searchParams['endDate'][$key])
  2162.                                 && (!$searchParams['startDate'][$key]
  2163.                                     || $searchParams['startDate'][$key] == '')
  2164.                             ) {
  2165.                                 $endDate self::cleanDate($searchParams['endDate'][$key]);
  2166.                                 $date " end_on <= '$endDate' ";
  2167.                                 $messagePart .= " -> before '<strong>$endDate</strong>' ";
  2168.                             } else {
  2169.                                 $whereEvent .= '';
  2170.                             }
  2171.                             $whereEvent .= ' ' $operationInst ' ' $date;
  2172.                             break;
  2173.                         case 'Updated':
  2174.                             $endDate = isset($searchParams['endDate'][$key]) ? "AND updated_at <= '" self::cleanDate($searchParams['endDate'][$key]) . "' " " AND 1=1 ";
  2175.                             $whereEvent .= ' ' $operationInst ' ' self::cleaned($searchParams['startDate'][$key]) . ' ' $endDate;
  2176.                             $messagePart .= "$operation $type \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2177.                             $messagePart .= "between \"<strong>" self::cleaned($searchParams['startDate'][$key]) . "</strong>\" ";
  2178.                             $messagePart .= "and \"<strong>" self::cleaned($searchParams['endDate'][$key]) . "</strong>\" ";
  2179.                             break;
  2180.                         case 'Created':
  2181.                             $startDate = isset($searchParams['startDate'][$key]) ? "created_at >= '" self::cleanDate($searchParams['startDate'][$key]) . "' " "1=1 ";
  2182.                             $endDate = isset($searchParams['endDate'][$key]) ? "AND created_at <= '" self::cleanDate($searchParams['endDate'][$key]) . "' " " AND 1=1 ";
  2183.                             $whereEvent .= ' ' $operationInst ' ' $startDate ' ' $endDate;
  2184.                             $messagePart .= "$operation $type \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2185.                             $messagePart .= "between \"<strong>" self::cleaned($searchParams['startDate'][$key]) . "</strong>\" ";
  2186.                             $messagePart .= "and \"<strong>" self::cleaned($searchParams['endDate'][$key]) . "</strong>\" ";
  2187.                             break;
  2188.                     }
  2189.                     $operationEvent $searchParams['searchToggle'][$key] ?? " OR ";
  2190.                 } elseif ($type == 'documents') {
  2191.                     $sortFields['name'] = 'Document Title';
  2192.                     if ($sortBy == '') {
  2193.                         $sortBy 'title';
  2194.                     }
  2195.                     $bindValues[$type][$key] = array();
  2196.                     $selectQryDocument "
  2197.                             SELECT 
  2198.                                 'documents' AS type, 
  2199.                                 d.id_doc,
  2200.                                 dt.id_doctype AS id_doctype, 
  2201.                                 dt.doctypename AS documenttype, 
  2202.                                 d.title, 
  2203.                                 d.created_at,
  2204.                                 d.doc_code,
  2205.                                 'undefined' AS country
  2206.                             FROM 
  2207.                                  documents d, 
  2208.                                  doctypes dt 
  2209.                             WHERE 
  2210.                                   dt.id_doctype = d.id_doctype ";
  2211.                     switch ($value) {
  2212.                         case 'Title contains':
  2213.                             $whereDocument .= ' ' $operationEvent " (
  2214.                                                   d.title LIKE  :percStringPerc$key
  2215.                                                        ) ";
  2216.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  2217.                             $messagePart .= "in $type using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2218.                             //remember what value has to be bound to what placeholder
  2219.                             $bindValues[$type][$key] = array(
  2220.                                 'percStringPerc' $key => '%' $string '%'
  2221.                             );
  2222.                             break;
  2223.                         case 'Document type is':
  2224.                             $whereDocument .= ' ' $operationEvent " (
  2225.                                                   dt.id_doctype = :idDoctype
  2226.                                                        ) ";
  2227.                             $messagePart .= "$operation $type having Document Type ";
  2228.                             $messagePart .= "\"<strong> " self::readableFilter($value) . "</strong>\" ";
  2229.                             //remember what value has to be bound to what placeholder
  2230.                             $bindValues[$type][$key] = array(
  2231.                                 'idDoctype' => $string
  2232.                             );
  2233.                             break;
  2234.                         case 'Document code is':
  2235.                             $whereDocument .= ' ' $operationEvent " (
  2236.                                                   d.doc_code LIKE  :percStringPerc$key
  2237.                                                        ) ";
  2238.                             $messagePart .= "$operation $type having Document Code ";
  2239.                             $messagePart .= "\"<strong> " self::readableFilter($value) . "</strong>\" ";
  2240.                             //remember what value has to be bound to what placeholder
  2241.                             $bindValues[$type][$key] = array(
  2242.                                 'percStringPerc' $key => '%' $string '%'
  2243.                             );
  2244.                             break;
  2245.                         case 'Summary contains':
  2246.                             $whereDocument .= ' ' $operationEvent " (
  2247.                                                   d.summary LIKE  :percStringPerc$key
  2248.                                                        ) ";
  2249.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  2250.                             $messagePart .= "in $type using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2251.                             //remember what value has to be bound to what placeholder
  2252.                             $bindValues[$type][$key] = array(
  2253.                                 'percStringPerc' $key => '%' $string '%'
  2254.                             );
  2255.                             break;
  2256.                         case 'Keywords contain':
  2257.                             $whereDocument .= ' ' $operationEvent " (
  2258.                                                d.keywords LIKE  :percStringPerc$key
  2259.                                               ) ";
  2260.                             $messagePart .= "$operation \"<strong>" self::cleaned($string) . "</strong>\" ";
  2261.                             $messagePart .= "in $type using filter \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2262.                             //remember what value has to be bound to what placeholder
  2263.                             $bindValues[$type][$key] = array(
  2264.                                 'percStringPerc' $key => '%' $string '%'
  2265.                             );
  2266.                             break;
  2267.                         case 'Updated':
  2268.                             if (isset($searchParams['endDate'][$key])) {
  2269.                                 $endDate self::cleanDate($searchParams['endDate'][$key]);
  2270.                                 $endDate "AND updated_at <= '$endDate' ";
  2271.                             } else {
  2272.                                 $endDate ' AND 1=1 ';
  2273.                             }
  2274.                             $whereDocument .= ' ' $operationInst ' ' self::cleaned($searchParams['startDate'][$key]) . ' ' $endDate;
  2275.                             $messagePart .= "$operation $type \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2276.                             $messagePart .= "between \"<strong>" self::cleaned($searchParams['startDate'][$key]) . "</strong>\" ";
  2277.                             $messagePart .= "and \"<strong>" self::cleaned($searchParams['endDate'][$key]) . "</strong>\" ";
  2278.                             break;
  2279.                         case 'Created':
  2280.                             if (isset($searchParams['startDate'][$key])) {
  2281.                                 $startDate self::cleanDate($searchParams['startDate'][$key]);
  2282.                                 $startDate "created_at >= '$startDate' ";
  2283.                             } else {
  2284.                                 $startDate '1=1 ';
  2285.                             }
  2286.                             if (isset($searchParams['endDate'][$key])) {
  2287.                                 $endDate self::cleanDate($searchParams['endDate'][$key]);
  2288.                                 $endDate "AND created_at <= '$endDate' ";
  2289.                             } else {
  2290.                                 $endDate ' AND 1=1 ';
  2291.                             }
  2292.                             $whereDocument .= ' ' $operationInst ' ' $startDate ' ' $endDate;
  2293.                             $messagePart .= "$operation $type \"<strong>" self::readableFilter($value) . "</strong>\" ";
  2294.                             $messagePart .= "between \"<strong>" self::cleaned($searchParams['startDate'][$key]) . "</strong>\" ";
  2295.                             $messagePart .= "and \"<strong>" self::cleaned($searchParams['endDate'][$key]) . "</strong>\" ";
  2296.                             break;
  2297.                     }
  2298.                     $operationEvent $searchParams['searchToggle'][$key] ?? " OR ";
  2299.                 }
  2300.             }
  2301.             if (isset($selectQryInd)) {
  2302.                 $selectQryInd .= " FROM indiv i ";
  2303.                 if ($endQueryInd == false) {
  2304.                     $whereInd .= ' ) ' $searchParams['indivStatus'] . 'GROUP BY i.id_ind';
  2305.                 }
  2306.                 $queryInd $selectQryInd ' ' $commonJoins ' ' $joinsInd ' ' $whereInd ' ' $matchOrder;
  2307.                 $stmtInd $connection->prepare($queryInd);
  2308.                 foreach($bindValues['experts'] as $bindValue) {
  2309.                     foreach($bindValue as $placeholder => $value) {
  2310.                         $stmtInd->bindValue($placeholder$value);
  2311.                     }
  2312.                 }
  2313.                 $stmtInd->execute();
  2314.                 $dataResultInd $stmtInd->fetchAll();
  2315.                 $sortFields['jobtitle'] = 'Position';
  2316.             }
  2317.             if (isset($selectQryInst)) {
  2318.                 if ($endQueryInst == false) {
  2319.                     $whereInst .= " ) " $searchParams['instStatus'] . " GROUP BY i.id_inst ";
  2320.                 }
  2321.                 $queryInst $selectQryInst ' ' $joinsInst ' ' $whereInst "  ORDER BY i.inst_name ASC";
  2322.                 $stmtInst $connection->prepare($queryInst);
  2323.                 foreach($bindValues['institutions'] as $bindValue) {
  2324.                     foreach($bindValue as $placeholder => $value) {
  2325.                         $stmtInst->bindValue($placeholder$value);
  2326.                     }
  2327.                 }
  2328.                 $stmtInst->execute();
  2329.                 $dataResultInst $stmtInst->fetchAll();
  2330.                 $sortFields["instType"] = "Institution Type";
  2331.             }
  2332.             if (isset($selectQryEvent)) {
  2333.                 if ($endQueryEvent == false) {
  2334.                     $whereEvent .= ' ) ' $searchParams['eventStatus'];
  2335.                     $whereEvent.= ' GROUP BY e.id_event ORDER BY start_on DESC ';
  2336.                 }
  2337.                 $queryEvent $selectQryEvent ' ' $joinsEvent ' ' $whereEvent;
  2338.                 $stmtEvent $connection->prepare($queryEvent);
  2339.                 foreach($bindValues['events'] as $bindValue) {
  2340.                     foreach($bindValue as $placeholder => $value) {
  2341.                         $stmtEvent->bindValue($placeholder$value);
  2342.                     }
  2343.                 }
  2344.                 $stmtEvent->execute();
  2345.                 $dataResultEvent $stmtEvent->fetchAll();
  2346.             }
  2347.             if (isset($selectQryDocument)) {
  2348.                 if ($endQueryDocument == false) {
  2349.                     $whereDocument .= ' ORDER BY created_at DESC';
  2350.                 }
  2351.                 $queryDocument $selectQryDocument ' ' $whereDocument;
  2352.                 $stmtDocument $connection->prepare($queryDocument);
  2353.                 foreach($bindValues['documents'] as $bindValue) {
  2354.                     foreach($bindValue as $placeholder => $value) {
  2355.                         $stmtDocument->bindValue($placeholder$value);
  2356.                     }
  2357.                 }
  2358.                 $stmtDocument->execute();
  2359.                 $dataResultDocument $stmtDocument->fetchAll();
  2360.             }
  2361.             $dataResult array_merge(
  2362.                 $dataResultInd,
  2363.                 $dataResultInst,
  2364.                 $dataResultEvent,
  2365.                 $dataResultDocument
  2366.             );
  2367.         }
  2368.         if ($messagePart == '') {
  2369.             $message 'no data found at all';
  2370.         } else {
  2371.             $messageEnd 'returned <strong>' count($dataResult) . '</strong> result(s).';
  2372.             $message $messageStart $messagePart $messageEnd;
  2373.         }
  2374.         //status 0 means there are no errors to be mentioned
  2375.         $return = array(
  2376.             'status' => 0,
  2377.             'dataResult' => $dataResult,
  2378.             'sortFields' => $sortFields,
  2379.             'sortby' => $sortBy,
  2380.             'message' => $message,
  2381.             'searchResultType' => $searchResultType
  2382.         );
  2383.         return $return;
  2384.     }
  2385.     /**
  2386.      * show the results of the advanced search
  2387.      *
  2388.      * @param Request $request
  2389.      *
  2390.      * @return Response
  2391.      */
  2392.     public function advancedSearchAction(Request $request): Response
  2393.     {
  2394.         //if we do a 'browse' search (from the homepage)
  2395.         //AND we try to filter the results (this can be the case after searching for a word in 'all')
  2396.         //we should redirect this to a more complex = advanced search type
  2397.         $searchParams $this::extractParams($request);
  2398.         //dump($searchParams);
  2399.         //we want to see inactive/unapproved/... results as a global editor
  2400.         //normal users should not see that
  2401.         if ($this->get('security.authorization_checker')->isGranted('ROLE_GLOBAL_EDITOR')) {
  2402.             $indivStatus ' ';
  2403.             $instStatus ' ';
  2404.             $eventStatus ' ';
  2405.         } else {
  2406.             $indivStatus ' AND status = 1 ';
  2407.             $instStatus ' AND activated = 1 ';
  2408.             $eventStatus ' AND status = 1 ';
  2409.         }
  2410.         $searchParams['indivStatus'] = $indivStatus;
  2411.         $searchParams['instStatus'] = $instStatus;
  2412.         $searchParams['eventStatus'] = $eventStatus;
  2413.         //remember the filters that we have applied
  2414.         //used to add action to the filter labels shown above the results
  2415.         $appliedFilters = array();
  2416.         $appliedCountryFilters = array();
  2417.         $doctrine $this->get('doctrine');
  2418.         //get the results depending on the defined action
  2419.         if ($searchParams['action'] == 'browse') {
  2420.             $results self::getBrowseSearchResults($searchParams$doctrine);
  2421.         } elseif ($searchParams['action'] == 'advSearch') {
  2422.             $results self::getAdvSearchResults($searchParams$doctrine);
  2423.         } else {
  2424.             $results = array(
  2425.                 'status' => 2,
  2426.                 'message' => 'we need at least the parameter "action" (browse or advSearch)'
  2427.             );
  2428.         }
  2429.         //this means we have an error somewhere, or we have no results (status == 4)
  2430.         if ($results['status']
  2431.             && $results['status'] != 3
  2432.         ) {
  2433.             return $this->render(
  2434.                 'Exception/error.html.twig',
  2435.                 array(
  2436.                     'message' => $results['message']
  2437.                 )
  2438.             );
  2439.         }
  2440.         $dataResult $results['dataResult'];
  2441.         $searchResultType $results['searchResultType'];
  2442.         //only keep the results that match one of the filtertypes (experts, institutions,....) we are asking
  2443.         if (isset($searchParams['searchFilterType'])
  2444.             && is_array($searchParams['searchFilterType'])
  2445.         ) {
  2446.             $filterData = array();
  2447.             foreach (array_unique($searchParams['searchFilterType']) as $type) {
  2448.                 $filterData array_merge(
  2449.                     $filterData,
  2450.                     $this->addFilter(
  2451.                       $type,
  2452.                         'type',
  2453.                         $dataResult
  2454.                     )
  2455.                 );
  2456.                 $appliedFilters[] = $type;
  2457.             }
  2458.             $dataResult $filterData;
  2459.         }
  2460.         //only show the results for the country we are filtering
  2461.         if (isset($searchParams['filterCountry'])
  2462.             && trim($searchParams['filterCountry']) != ''
  2463.         ) {
  2464.             $filterData = array();
  2465.             foreach (explode(','$searchParams['filterCountry']) as $countryValue) {
  2466.                 if (trim($countryValue) != '') {
  2467.                     $filterData array_merge(
  2468.                         $filterData,
  2469.                         $this->addFilter(
  2470.                             $countryValue,
  2471.                             'country',
  2472.                             $dataResult
  2473.                         )
  2474.                     );
  2475.                     $appliedCountryFilters[] = $countryValue;
  2476.                 }
  2477.             }
  2478.             $dataResult $filterData;
  2479.         }
  2480.         //if sortby is defined other than relevance, then manually sort by name;
  2481.         if (isset($results['sortby'])
  2482.             && $results['sortby'] != 'relevance'
  2483.         ) {
  2484.             $this->sortBy(
  2485.                 $results['sortby'],
  2486.                 $dataResult,
  2487.                 $searchParams['sortOrder']
  2488.             );
  2489.         } else {
  2490.             $results['sortby'] = 'relevance';
  2491.         }
  2492.         $data $this->get('knp_paginator')
  2493.             ->paginate(
  2494.                 $dataResult,
  2495.                 $request->query->getInt('page'1),
  2496.                 $searchParams['limit'],
  2497.                 array(
  2498.                     'pageParameterName' => 'page',
  2499.                     'sortDirectionParameterName' => 'dir'
  2500.                 )
  2501.             );
  2502.         //gather all the email address already
  2503.         //could be done at the receiving end also...
  2504.         //or are we the receiving end already?
  2505.         $emailusers = array();
  2506.         foreach ($dataResult as $expert) {
  2507.             if ($expert['type'] == 'experts') {
  2508.                 $emailusers[] = $expert['id_ind'];
  2509.             }
  2510.         }
  2511.         //who is making this query
  2512.         //this is used for searches where we want to send emails to the resulting experts
  2513.         $user self::getDoctrine()
  2514.             ->getRepository('OceanExpertBundle:Indiv')
  2515.             ->findOneBy(
  2516.                 array(
  2517.                     'idInd' => $this->get('security.token_storage')->getToken()->getUser()
  2518.                 )
  2519.             );
  2520.         //show what we have
  2521.         return $this->render(
  2522.             'Search/advancedSearch.html.twig',
  2523.             array(
  2524.                 'action' => $searchParams['action'],
  2525.                 'data' => $data,
  2526.                 'filters' => self::getFilters($dataResult),
  2527.                 'searchResultText' => $results['message'],
  2528.                 'appliedFilters' => $appliedFilters,
  2529.                 'appliedCountryFilters' => $appliedCountryFilters,
  2530.                 'searchResultType' => $searchResultType,
  2531.                 'searchConditions' => $searchParams['conditions'],
  2532.                 'sortfields' => $results['sortFields'],
  2533.                 'user' => $user,
  2534.                 'emailUsers' => $emailusers,
  2535.                 'sortby' => $results['sortby']
  2536.             )
  2537.         );
  2538.     }
  2539.     public static function sortBy($field, &$array$direction 'ASC'): bool
  2540.     {
  2541.         usort($array, function($a$b) use ($field$direction) {
  2542.             $a $a[$field] ?? '';
  2543.             $b $b[$field] ?? '';
  2544.             if ($a == $b) {
  2545.                 return 0;
  2546.             }
  2547.             if (strtolower($direction) == 'desc') {
  2548.                 return $a $b ? -1;
  2549.             } else {
  2550.                 return $a $b ? -1;
  2551.             }
  2552.         });
  2553.         return true;
  2554.     }
  2555.     /**
  2556.      * @param $dataArr
  2557.      * @param $type
  2558.      * @return array
  2559.      *
  2560.      */
  2561.     public static function getUnique($dataArr$type): array
  2562.     {
  2563.         SearchController::sortBy($type$dataArr'ASC');
  2564.         $fields = array();
  2565.         foreach ($dataArr as $value) {
  2566.             if (isset($value[$type])
  2567.                 && trim($value[$type]) != ''
  2568.             ) {
  2569.                 if (array_key_exists($value[$type], $fields)) {
  2570.                     $fields[$value[$type]] += 1;
  2571.                 } else {
  2572.                     $fields[$value[$type]] = 1;
  2573.                 }
  2574.             }
  2575.         }
  2576.         ksort($fields);
  2577.         return $fields;
  2578.     }
  2579.     public static function addFilter($filter$filterKey$dataArr): array
  2580.     {
  2581.         $filterData = array();
  2582.         foreach ($dataArr as $key => $value) {
  2583.             if ($filter == 'all'
  2584.                 || (isset($value[$filterKey])
  2585.                 && $value[$filterKey] == $filter)
  2586.             ) {
  2587.                 $filterData[$key] = $value;
  2588.             }
  2589.         }
  2590.         return $filterData;
  2591.     }
  2592.     /**
  2593.      * get the subject area name by its id
  2594.      *
  2595.      * @param int    $id id of the subject area
  2596.      * @param object $doctrine
  2597.      *
  2598.      * @return string
  2599.      */
  2600.     public static function getSubjectAreaById(int $idobject $doctrine): string
  2601.     {
  2602.         $subjectArea $doctrine
  2603.             ->getRepository('OceanExpertBundle:Subjects')
  2604.             ->findOneBy(array('idSub' => $id));
  2605.         return $subjectArea->getSubname();
  2606.     }
  2607.     /**
  2608.      * get the name of the sea region by its id
  2609.      * used to be getRegionById()
  2610.      *
  2611.      * @param int    $id       id of the sea area
  2612.      * @param object $doctrine doctrine
  2613.      *
  2614.      * @return string
  2615.      */
  2616.     public static function getSeaRegionById(int $idobject $doctrine): string
  2617.     {
  2618.         $seaRegion $doctrine
  2619.             ->getRepository('OceanExpertBundle:Searegions')
  2620.             ->findOneBy(array('idSearegion' => $id));
  2621.         return $seaRegion->getName();
  2622.     }
  2623.     /**
  2624.      * get the name of the institution type
  2625.      * replaced by getInstituteTypeNameById()
  2626.      *
  2627.      * @param int    $id       the id of the institution type
  2628.      * @param object $doctrine doctrine
  2629.      *
  2630.      * @return string
  2631.      */
  2632.     public static function getInstituteTypeById(int $idobject $doctrine): string
  2633.     {
  2634.         return self::getInstituteTypeNameById($id$doctrine);
  2635.     }
  2636.     /**
  2637.      * get the name of the institution type
  2638.      * used to be getInstituteTypeById()
  2639.      *
  2640.      * @param int    $id       the id of the institution type
  2641.      * @param object $doctrine doctrine
  2642.      *
  2643.      * @return string
  2644.      */
  2645.     public function getInstituteTypeNameById(int $idobject $doctrine): string
  2646.     {
  2647.         $instType $doctrine
  2648.             ->getRepository('OceanExpertBundle:Insttypes')
  2649.             ->findOneBy(
  2650.                 array(
  2651.                     'idInsttype' => $id
  2652.                 )
  2653.             );
  2654.         if ($instType) {
  2655.             return $instType->getInsttypeName();
  2656.         } else {
  2657.             return 'no institution found';
  2658.         }
  2659.     }
  2660.     public static function getJobTypesById($id$doctrine)
  2661.     {
  2662.         $jobType $doctrine
  2663.             ->getRepository('OceanExpertBundle:Jobtypes')
  2664.             ->findOneBy(array('idJob' => $id));
  2665.         return $jobType->getJobName();
  2666.     }
  2667.     /**
  2668.      * get the name of the country by its id
  2669.      * used to be getCountryById()
  2670.      *
  2671.      * @param int $id id of the country
  2672.      * @param object $doctrine
  2673.      *
  2674.      * @return string|bool
  2675.      */
  2676.     public static function getCountryById(int $idobject $doctrine): string
  2677.     {
  2678.         if ($id != 0) {
  2679.             $country $doctrine
  2680.                 ->getRepository('OceanExpertBundle:Countries')
  2681.                 ->findOneBy(array('idCountry' => $id));
  2682.             return $country->getCountry();
  2683.         } else {
  2684.             return '';
  2685.         }
  2686.     }
  2687.     public static function getMultipleCountriesById($id$doctrine): array
  2688.     {
  2689.         $id explode(','$id);
  2690.         $countries $doctrine
  2691.             ->getRepository('OceanExpertBundle:Countries')
  2692.             ->createQueryBuilder('c')
  2693.             ->select('c.country')
  2694.             ->where('c.idCountry in (:idCountries)')
  2695.             ->setParameter('idCountries'$id)
  2696.             ->orderBy('c.country')
  2697.             ->getQuery()
  2698.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  2699.         return array_column($countries'country');
  2700.     }
  2701.     /**
  2702.      * get the name of the region by its id
  2703.      *
  2704.      * @param int    $id       id of the region
  2705.      * @param object $doctrine doctrine
  2706.      *
  2707.      * @return string
  2708.      */
  2709.     public static function getRegionById(int $idobject $doctrine): string
  2710.     {
  2711.         $region $doctrine
  2712.             ->getRepository('OceanExpertBundle:Regions')
  2713.             ->findOneBy(array('idRegion' => $id));
  2714.         return $region->getName();
  2715.     }
  2716.     /**
  2717.      * get all regions
  2718.      * can be used by the search to provide a dropdown menu
  2719.      *
  2720.      * @return JsonResponse
  2721.      */
  2722.     public function getRegionsAction()
  2723.     {
  2724.         $regions self::getDoctrine()
  2725.             ->getRepository('OceanExpertBundle:Regions')
  2726.             ->findAll();
  2727.         $regions array_map(function ($region)
  2728.             {
  2729.                 return array(
  2730.                     'id' => $region->getIdRegion(),
  2731.                     'name' => $region->getName()
  2732.                 );
  2733.             },
  2734.             $regions
  2735.         );
  2736.         return new JsonResponse($regions);
  2737.     }
  2738.     /**
  2739.      * get all all the country id's that are in this region
  2740.      *
  2741.      * @return array
  2742.      */
  2743.     public static function getCountriesInRegion($idRegion$doctrine): array
  2744.     {
  2745.         $countryIds $doctrine
  2746.             ->getRepository('OceanExpertBundle:RegionCountries')
  2747.             ->findBy(
  2748.                 array(
  2749.                     'idRegion' => $idRegion
  2750.                 )
  2751.             );
  2752.         return $countryIds;
  2753.     }
  2754.     public static function getGroupById($id$doctrine)
  2755.     {
  2756.         $group $doctrine
  2757.             ->getRepository('OceanExpertBundle:Groups')
  2758.             ->findOneBy(array('idGroup' => $id));
  2759.         return $group->getGroupName();
  2760.     }
  2761.     public static function readableFilter($filter): string
  2762.     {
  2763.         return ucfirst(preg_replace('/_/'' '$filter));
  2764.     }
  2765.     /**
  2766.      * get all sea regions
  2767.      * can be used by the search to provide a dropdown menu
  2768.      *
  2769.      * @return Response
  2770.      */
  2771.     public function getSeaRegionsAction(): Response
  2772.     {
  2773.         $regions self::getDoctrine()
  2774.             ->getRepository('OceanExpertBundle:Searegions')
  2775.             ->seaRegions();
  2776.         return new JsonResponse($regions);
  2777.     }
  2778.     public function getMemberGroupsAction(): Response
  2779.     {
  2780.         $groups self::getDoctrine()
  2781.             ->getRepository('OceanExpertBundle:Groups')
  2782.             ->createQueryBuilder('e')
  2783.             ->select('e.idGroup AS id,e.groupname AS name')
  2784.             ->orderBy('e.groupname')
  2785.             ->getQuery()
  2786.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  2787.         return new JsonResponse($groups);
  2788.     }
  2789.     public static function getChildGroup($group$doctrine): array
  2790.     {
  2791.         $groupids = array();
  2792.         $allgroups = array($group);
  2793.         $groups $doctrine
  2794.             ->getRepository('OceanExpertBundle:Groups')
  2795.             ->createQueryBuilder('e')
  2796.             ->select('e.idGroup,e.groupname')
  2797.             ->orderBy('e.groupname')
  2798.             ->where('e.idParentgroup = :group')
  2799.             ->setParameter('group'$group)
  2800.             ->getQuery()
  2801.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  2802.         foreach ($groups as $value) {
  2803.             $groupids[] = $value['idGroup'];
  2804.             $allgroups[] = $value['idGroup'];
  2805.         }
  2806.         if (count($groupids) > 0) {
  2807.             do {
  2808.                 $group2 $doctrine
  2809.                     ->getRepository('OceanExpertBundle:Groups')
  2810.                     ->createQueryBuilder('e')
  2811.                     ->select('e.idGroup AS id,e.groupname AS name')
  2812.                     ->orderBy('e.groupname')
  2813.                     ->where('e.idParentgroup in(:groupids)')
  2814.                     ->setParameter('groupids'$groupids)
  2815.                     ->getQuery()
  2816.                     ->getResult(AbstractQuery::HYDRATE_ARRAY);
  2817.                 $groupids = array();
  2818.                 foreach ($group2 as $value) {
  2819.                     $groupids[] = $value['id'];
  2820.                     $allgroups[] = $value['id'];
  2821.                 }
  2822.             } while (count($group2) > 0);
  2823.         }
  2824.         return $allgroups;
  2825.     }
  2826.     public function getJobTypesAction(): Response
  2827.     {
  2828.         $jobTypes self::getDoctrine()
  2829.             ->getRepository('OceanExpertBundle:Jobtypes')
  2830.             ->createQueryBuilder('e')
  2831.             ->select('e.idJob AS id,e.jobname AS name')
  2832.             ->orderBy('e.jobname')
  2833.             ->getQuery()
  2834.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  2835.         return new JsonResponse($jobTypes);
  2836.     }
  2837.     /**
  2838.      * get all countries
  2839.      * can be used by the search to provide a dropdown menu
  2840.      *
  2841.      * @return Response
  2842.      */
  2843.     public function getCountriesAction(): Response
  2844.     {
  2845.         $countries self::getDoctrine()
  2846.             ->getRepository('OceanExpertBundle:Countries')
  2847.             ->createQueryBuilder('e')
  2848.             ->select('e.idCountry AS id,e.country AS name')
  2849.             ->orderBy('e.country')
  2850.             ->getQuery()
  2851.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  2852.         return new JsonResponse($countries);
  2853.     }
  2854.     public function getSubjectAreaAction(): Response
  2855.     {
  2856.         $subjectArea self::getDoctrine()
  2857.             ->getRepository('OceanExpertBundle:Subjects')
  2858.             ->createQueryBuilder('e')
  2859.             ->select('e.subname AS id,e.subname AS name')
  2860.             ->orderBy('e.subname')
  2861.             ->getQuery()
  2862.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  2863.         return new JsonResponse($subjectArea);
  2864.     }
  2865.     public function getEventTypesAction(): Response
  2866.     {
  2867.         $eventTypes self::getDoctrine()
  2868.             ->getRepository('OceanExpertBundle:Eventtypes')
  2869.             ->createQueryBuilder('e')
  2870.             ->select('e.idEventtype AS id,e.eventtypeName AS name')
  2871.             ->orderBy('e.eventtypeName')
  2872.             ->getQuery()
  2873.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  2874.         return new JsonResponse($eventTypes);
  2875.     }
  2876.     /**
  2877.      * here for backward compatibility
  2878.      *
  2879.      * @deprecated
  2880.      *
  2881.      * @return JsonResponse
  2882.      */
  2883.     function getInstitutionTypesAction(): JsonResponse
  2884.     {
  2885.         return $this->getInstituteTypesAction();
  2886.     }
  2887.     /**
  2888.      * @return JsonResponse
  2889.      */
  2890.     public function getInstituteTypesAction(): JsonResponse
  2891.     {
  2892.         $instTypes self::getDoctrine()
  2893.             ->getRepository('OceanExpertBundle:Insttypes')
  2894.             ->createQueryBuilder('i')
  2895.             ->select('i.idInsttype AS id,i.insttypeName AS name')
  2896.             ->orderBy('i.insttypeName')
  2897.             ->getQuery()
  2898.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  2899.         return new JsonResponse($instTypes);
  2900.     }
  2901.     /**
  2902.      * get all possible document types
  2903.      * can be used by the search to provide a dropdown menu
  2904.      * @see #609
  2905.      *
  2906.      * @return Response
  2907.      */
  2908.     public function getDocumentTypesAction(): Response
  2909.     {
  2910.         $documentTypes self::getDoctrine()
  2911.             ->getRepository('OceanExpertBundle:Doctypes')
  2912.             ->createQueryBuilder('i')
  2913.             ->select('i.idDoctype AS id,i.doctypename AS name')
  2914.             ->orderBy('i.doctypename')
  2915.             ->getQuery()
  2916.             ->getResult(AbstractQuery::HYDRATE_ARRAY);
  2917.         return new JsonResponse($documentTypes);
  2918.     }
  2919.     public function getMembersAction(Request $request): Response
  2920.     {
  2921.         $doctrine self::getDoctrine();
  2922.         $members = array();
  2923.         if (null !== $request->request->get('searchterm')) {
  2924.             $searchTerm $request->request->get('searchterm');
  2925.             $type $request->request->get('searchparam');
  2926.         } elseif (null !== $request->query->get('searchterm')) {
  2927.             $searchTerm $request->query->get('searchterm');
  2928.             $type $request->query->get('searchparam');
  2929.         } else {
  2930.             return new JsonResponse(
  2931.                 array(
  2932.                     'status' => 1,
  2933.                     'error' => 'please send "searchparam" and "searchterm"'
  2934.                 )
  2935.             );
  2936.         }
  2937.         $searchParams $this::extractParams($request);
  2938.         $searchParams['searchQuery'] = $searchTerm;
  2939.         $searchParams['searchType'] = $type;
  2940.         $searchParams['searchFilterType'] = ['experts'];
  2941.         $connection $doctrine->getManager()->getConnection();
  2942.         if ($type == 'name'
  2943.             || $type == 'all'
  2944.         ) {
  2945.             /*
  2946.             $statement = $connection->prepare("
  2947.                 SELECT
  2948.                     i.id_ind AS DT_RowId,
  2949.                     i.id_ind,
  2950.                     i.title,
  2951.                     i.fname,
  2952.                     i.mname,
  2953.                     i.sname,
  2954.                     inst.inst_name,
  2955.                     c.country,
  2956.                     i.status,
  2957.                     MATCH (i.fname,i.sname) AGAINST (:searchQuery IN BOOLEAN MODE) AS relevance
  2958.                 FROM
  2959.                     indiv i
  2960.                     LEFT JOIN countries c ON c.id_country =  i.country_code
  2961.                     LEFT JOIN indiv_institution ii ON ii.id_ind = i.id_ind
  2962.                     LEFT JOIN institutions inst ON inst.id_inst = ii.id_inst
  2963.                 WHERE
  2964.                     (
  2965.                          MATCH (i.fname,i.mname,i.sname) AGAINST (:searchQuery IN BOOLEAN MODE)
  2966.                         OR i.fname LIKE :percSearchQuery
  2967.                         OR i.fname LIKE :searchQueryPerc
  2968.                         OR i.mname LIKE :percSearchQuery
  2969.                         OR i.mname LIKE :searchQueryPerc
  2970.                         OR i.sname LIKE :percSearchQuery
  2971.                         OR i.sname LIKE :searchQueryPerc
  2972.                     )
  2973.                 ORDER BY relevance DESC, sname ASC;
  2974.             ");
  2975.             $statement->bindValue('searchQuery', $searchParams['searchQuery']);
  2976.             $statement->bindValue('searchQueryPerc', $searchParams['searchQuery'] . '%');
  2977.             $statement->bindValue('percSearchQuery', '%' . $searchParams['searchQuery']);
  2978.             $statement->execute();
  2979.             $members = array_merge($members, $statement->fetchAll());
  2980.             */
  2981.             //we only need the active ones
  2982.             $indivStatus ' AND status = 1 ';
  2983.             $instStatus ' AND activated = 1 ';
  2984.             $eventStatus ' AND status = 1 ';
  2985.             $searchParams['indivStatus'] = $indivStatus;
  2986.             $searchParams['instStatus'] = $instStatus;
  2987.             $searchParams['eventStatus'] = $eventStatus;
  2988.             $membersTmp self::getBrowseSearchResults($searchParams$doctrine);
  2989.             //recreate the array we expected here (see old code)
  2990.             foreach($membersTmp['dataResult'] as $dataResult) {
  2991.                 if (!isset($dataResult['id_ind'])) {
  2992.                     //this is not an expert, skip
  2993.                     continue;
  2994.                 }
  2995.                 $members[] = array(
  2996.                     "DT_RowId" => $dataResult['id_ind'],
  2997.                     "id_ind" => $dataResult['id_ind'],
  2998.                     "title" => $dataResult['title'],
  2999.                     "fname" => $dataResult['fname'],
  3000.                     "mname" => $dataResult['mname'],
  3001.                     "sname" => $dataResult['sname'],
  3002.                     "inst_name" => $dataResult['inst_name'],
  3003.                     "country" => $dataResult['country'],
  3004.                     "status" => $dataResult['status'],
  3005.                     "relevance" => $dataResult['relevance'],
  3006.                 );
  3007.             }
  3008.         } elseif ($type == 'email') {
  3009.             $statement $connection->prepare("
  3010.                 SELECT 
  3011.                     i.id_ind AS DT_RowId,
  3012.                     i.id_ind, 
  3013.                     i.title, 
  3014.                     i.fname, 
  3015.                     i.mname, 
  3016.                     i.sname,
  3017.                     inst.inst_name,
  3018.                     c.country, 
  3019.                     i.status, 
  3020.                     MATCH (i.email1) AGAINST (:searchQuery IN BOOLEAN MODE) AS relevance 
  3021.                 FROM 
  3022.                     indiv i
  3023.                     LEFT JOIN countries c ON c.id_country =  i.country_code
  3024.                     LEFT JOIN indiv_institution ii ON ii.id_ind = i.id_ind
  3025.                     LEFT JOIN institutions inst ON inst.id_inst = ii.id_inst
  3026.                 WHERE 
  3027.                     email1 = :searchQuery
  3028.                     OR email2 = :searchQuery
  3029.                     OR email3 = :searchQuery
  3030.                 ORDER BY relevance DESC;
  3031.             ");
  3032.             $statement->bindValue(':searchQuery'$searchParams['searchQuery']);
  3033.             $statement->execute();
  3034.             $members array_merge(
  3035.                 $members,
  3036.                 $statement->fetchAll()
  3037.             );
  3038.         } elseif ($type == 'group') {
  3039.             //we only need the active ones
  3040.             $indivStatus ' AND status = 1 ';
  3041.             $instStatus ' AND activated = 1 ';
  3042.             $eventStatus ' AND status = 1 ';
  3043.             $searchParams['indivStatus'] = $indivStatus;
  3044.             $searchParams['instStatus'] = $instStatus;
  3045.             $searchParams['eventStatus'] = $eventStatus;
  3046.             $membersTmp self::getBrowseSearchResults($searchParams$doctrine);
  3047.             //recreate the array we expected here (see old code)
  3048.             foreach($membersTmp['dataResult'] as $dataResult) {
  3049.                 if (!isset($dataResult['id_ind'])) {
  3050.                     //this is not an experts, skip
  3051.                     continue;
  3052.                 }
  3053.                 $members[] = array(
  3054.                     "DT_RowId" => $dataResult['id_ind'],
  3055.                     "id_ind" => $dataResult['id_ind'],
  3056.                     "title" => $dataResult['title'],
  3057.                     "fname" => $dataResult['fname'],
  3058.                     "mname" => $dataResult['mname'],
  3059.                     "sname" => $dataResult['sname'],
  3060.                     "inst_name" => $dataResult['inst_name'],
  3061.                     "country" => $dataResult['country'],
  3062.                     "status" => $dataResult['status'],
  3063.                     "relevance" => $dataResult['relevance'],
  3064.                     "groupName" => $dataResult['groupName'],
  3065.                     "groupId" => $dataResult['groupId']
  3066.                 );
  3067.             }
  3068.             /*
  3069.             $statement = $connection->prepare('
  3070.                 SELECT
  3071.                     i.id_ind AS DT_RowId,
  3072.                     i.id_ind,
  3073.                     i.title,
  3074.                     i.fname,
  3075.                     i.mname,
  3076.                     i.sname,
  3077.                     inst.inst_name,
  3078.                     c.country,
  3079.                     i.status,
  3080.                     1 AS relevance
  3081.                 FROM
  3082.                     indiv i
  3083.                     LEFT JOIN countries c ON c.id_country =  i.country_code
  3084.                     LEFT JOIN indiv_institution ii ON ii.id_ind = i.id_ind
  3085.                     LEFT JOIN institutions inst ON inst.id_inst = ii.id_inst
  3086.                     LEFT JOIN member_groups m ON i.id_ind = m.id_ind
  3087.                 WHERE
  3088.                     m.id_group like "%t%"
  3089.                 ORDER BY relevance DESC;
  3090.             ');
  3091.             $statement->bindValue('searchQuery', $searchParams['searchQuery']);
  3092.             $statement->execute();
  3093.             $members = array_merge($members, $statement->fetchAll());
  3094.             */
  3095.         }
  3096.         return new JsonResponse(
  3097.             array(
  3098.                 'data' => $members
  3099.             )
  3100.         );
  3101.     }
  3102.     /**
  3103.      * @param int $expert expert id
  3104.      *
  3105.      * @return int
  3106.      *
  3107.      * @todo is this used somewhere??? Arno 15/04/2022
  3108.      */
  3109.     function getExpertEvents(int $expert): int
  3110.     {
  3111.         $em self::getDoctrine()->getManager();
  3112.         $qb $em->createQueryBuilder();
  3113.         $qb->select('e.idEvent');
  3114.         $qb->from('OceanExpertBundle:EventParticipants''e');
  3115.         $qb->where('e.idInd = :idInd');
  3116.         $qb->setParameter('idInd'$expert);
  3117.         $participants $qb->getQuery()->getResult();
  3118.         $participants array_map('current'$participants);
  3119.         $qb $em->createQueryBuilder();
  3120.         $qb->select('e.idEvent');
  3121.         $qb->from('OceanExpertBundle:EventStaff''e');
  3122.         $qb->where('e.idInd = :idInd');
  3123.         $qb->setParameter('idInd'$expert);
  3124.         $staff $qb->getQuery()->getResult();
  3125.         $staff array_map('current'$staff);
  3126.         $qb $em->createQueryBuilder();
  3127.         $qb->select('e.idEvent');
  3128.         $qb->from('OceanExpertBundle:EventContacts''e');
  3129.         $qb->where('e.idInd = :idInd');
  3130.         $qb->setParameter('idInd'$expert);
  3131.         $contacts $qb->getQuery()->getResult();
  3132.         $contacts array_map('current'$contacts);
  3133.         $result array_merge($participants$staff$contacts);
  3134.         $results array_unique($resultSORT_REGULAR);
  3135.         return count($results);
  3136.     }
  3137.     /**
  3138.      * clean input strings to prevent XSS and other problems
  3139.      *
  3140.      * @param string $string input string
  3141.      *
  3142.      * @return string
  3143.      */
  3144.     public static function cleaned(string $string): string
  3145.     {
  3146.         $string nl2br(stripslashes($string));
  3147.         return preg_replace(
  3148.             '/[<>]/',
  3149.             '--*--',
  3150.             $string
  3151.         );
  3152.     }
  3153.     /**
  3154.      * in case we get the wrong format for the date
  3155.      * cleanup and return the correct format
  3156.      * we want a string like 'yyyy-mm-dd'
  3157.      *
  3158.      * @param string $string the date to be checked
  3159.      *
  3160.      * @return string
  3161.      */
  3162.     public static function cleanDate(string $string): string
  3163.     {
  3164.         if (strpos($string'/')) {
  3165.             $date explode('/'$string);
  3166.             if (strlen($date[0]) == 4) {
  3167.                 // this was something like yyyy/mm/dd I guess
  3168.                 return $date[0] . '-' $date[1] . '-' $date[2];
  3169.             } else {
  3170.                 // this was something like dd/mm/yyyy I guess
  3171.                 return $date[2] . '-' $date[1] . '-' $date[0];
  3172.             }
  3173.         } elseif (strpos($string'-')) {
  3174.             $date explode('-'$string);
  3175.             if (strlen($date[0]) == 4) {
  3176.                 // this was something like yyyy-mm-dd I guess
  3177.                 //that is the correct format already
  3178.                 return $string;
  3179.             } else {
  3180.                 // this was something like dd-mm-yyyy I guess
  3181.                 return $date[2] . '-' $date[1] . '-' $date[0];
  3182.             }
  3183.         } else {
  3184.             //no idea what to clean up
  3185.             return $string;
  3186.         }
  3187.     }
  3188.     public static function fulltext($string): string
  3189.     {
  3190.         $newString '';
  3191.         if (trim($string) != '') {
  3192.             $arrStr explode(' '$string);
  3193.             foreach ($arrStr as &$value) {
  3194.                 $value '+' $value;
  3195.             }
  3196.             $newString implode(' '$arrStr);
  3197.         }
  3198.         return $newString;
  3199.     }
  3200. }