src/Controller/SearchController.php line 21

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Annotation\CmsComponent;
  4. use App\Entity\Page;
  5. use App\Service\ServiceController;
  6. use Doctrine\ORM\EntityManagerInterface;
  7. use Knp\Component\Pager\PaginatorInterface;
  8. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\HttpFoundation\Response;
  11. use Symfony\Component\Routing\Annotation\Route;
  12. class SearchController extends AbstractController
  13. {
  14.     /**
  15.      * @CmsComponent("Search Results", active=true, routeName="process_search")
  16.      */
  17.     #[Route(path'/cms-search'name'process_search')]
  18.     public function processSearch(Request $requestEntityManagerInterface $emServiceController $serviceControllerPaginatorInterface $paginator)
  19.     {
  20.         $resultsPerPage 20;
  21.         $titleFields = ['title''kicker''subtitle','headline''name'];
  22.         $descriptionFields = ['content''content2''description''information''taggedin''excerpt'];
  23.         $searchableFields array_merge($titleFields$descriptionFields);
  24.         $criteria $request->get('search-terms');
  25.         $string $request->get('search-terms');
  26.         $totalResults 0;
  27.         $pageHits = [];
  28.         $criteriaArray = [];
  29.         if ($criteria) {
  30.             $criteriaArray explode(' ', (string) $criteria);
  31.             // print_r($criteriaArray);
  32.             foreach ($criteriaArray as $key => $criteriaCheck) {
  33.                 if (strlen($criteriaCheck) < 3) {
  34.                     unset($criteriaArray[$key]);
  35.                 }
  36.                 if ('' == $criteriaCheck) {
  37.                     unset($criteriaArray[$key]);
  38.                 }
  39.             }
  40.             $cmsComponentArray $serviceController->fetchCmsComponents();
  41.             $pages $em->getRepository(Page::class)->findBy(['deleted' => false'active' => true]);
  42.             // get only active pages with componets - to prevent fetching routes without any possible links
  43.             // 2 arrays - one for quick searching(activePageRoutes) and sluggedPages for full details - just ensure they have both have the same key
  44.             $activePageRoutes = [];
  45.             $sluggedPages = [];
  46.             foreach ($pages as $page) {
  47.                 $pageComps $page->getComponents();
  48.                 foreach ($pageComps as $pageComp) {
  49.                     if ('' != $pageComp['route']) {
  50.                         $sluggedPages[] = $page;
  51.                         $activePageRoutes[] = $pageComp['route'];
  52.                     }
  53.                 }
  54.             }
  55.             // echo "<pre>".print_r($activePageRoutes, true)."</pre>";
  56.             // get only componets which have the 'slugEntity' annotation
  57.             $activeRoutes = [];
  58.             $sluggedComponents = [];
  59.             foreach ($cmsComponentArray as $cmsComponent) {
  60.                 if ('' != $cmsComponent['slugEntity']) {
  61.                     $sluggedComponents[] = $cmsComponent;
  62.                     $activeRoutes[] = $cmsComponent['route'];
  63.                 }
  64.             }
  65.             // echo "<pre>".print_r($sluggedComponents, true)."</pre>";
  66.             $hits = [];
  67.             // loop through all criteria
  68.             foreach ($criteriaArray as $criteria) {
  69.                 // search page content first - as its easier ;)
  70.                 foreach ($pages as $page) {
  71.                     // loop through all searchable fields
  72.                     foreach ($searchableFields as $searchableField) {
  73.                         $getter 'get'.ucwords($searchableField);
  74.                         // check that the field exists
  75.                         // search content - convert to lowercase
  76.                         if (method_exists($page$getter) && strstr(strtolower((string) $page->{$getter}()), strtolower($criteria))) {
  77.                             // we have a hit - added a field called hits - if a entity gets more than 1 hit
  78.                             // increase the hits, i'll use this to calculate weighting
  79.                             $key 'page'.$page->getId();
  80.                             if (!array_key_exists($key$hits)) {
  81.                                 $hits[$key] = [
  82.                                     'hits' => 1,
  83.                                     'title' => $page->getTitle(),
  84.                                     'description' => $page->getContent() ?? $page->getKicker(),
  85.                                     'link' => $page->getSlug(),
  86.                                     'image' => $page->getFullImagePath(),
  87.                                 ];
  88.                             } else {
  89.                                 // same entity hit - so increase hit count
  90.                                 ++$hits[$key]['hits'];
  91.                             }
  92.                             dump($key,$page->getTitle());
  93.                             ++$totalResults;
  94.                         }
  95.                     }
  96.                 }
  97.             }
  98.             foreach ($criteriaArray as $criteria) {
  99.                 // search other bundles
  100.                 // find entites to check - make sure they have a page to link to
  101.                 foreach ($sluggedComponents as $key => $sluggedComponent) {
  102.                     if (in_array($sluggedComponent['route'], $activePageRoutes)) {
  103.                         // its an active page so search it
  104.                         $checkComponent $sluggedComponents[$key];
  105.                         // get page info - so i know where to link the result
  106.                         $pageKey array_search($sluggedComponent['route'], $activePageRoutes);
  107.                         $pageEntity $sluggedPages[$pageKey];
  108.                         $queryEntity str_replace('\\'''$checkComponent['bundle'].':'.$checkComponent['slugEntity']);
  109.                         $queryEntity str_replace('/'''$queryEntity);
  110.                         $queryEntity str_replace('App:''\\App\Entity\\'$queryEntity);
  111.                         $entities $em->getRepository($queryEntity)->findBy(['deleted' => 0'active' => 1]);
  112.                         foreach ($entities as $entity) {
  113.                             // loop through all searchable fields
  114.                             foreach ($searchableFields as $searchableField) {
  115.                                 $getter 'get'.ucwords($searchableField);
  116.                                 // check that the field exists
  117.                                 // search content - convert to lowercase
  118.                                 if (method_exists($entity$getter) && strstr(strtolower((string) $entity->{$getter}()), strtolower($criteria))) {
  119.                                     // we have a hit - added a field called hits - if a entity gets more than 1 hit
  120.                                     // increase the hits, i'll use this to calculate weighting
  121.                                     // used key as a way to uniquly reference to increase hits
  122.                                     $key $checkComponent['slugEntity'].$entity->getId();
  123.                                     $title '';
  124.                                     $description '';
  125.                                     $link '';
  126.                                     $image '';
  127.                                     // get title field
  128.                                     foreach (array_reverse($titleFields) as $titleField) {
  129.                                         $getter 'get'.ucwords($titleField);
  130.                                         if (method_exists($entity$getter)) {
  131.                                             $title $entity->{$getter}();
  132.                                         }
  133.                                     }
  134.                                     // get description field
  135.                                     foreach (array_reverse($descriptionFields) as $descriptionField) {
  136.                                         $getter 'get'.ucwords($descriptionField);
  137.                                         if (method_exists($entity$getter)) {
  138.                                             $description $entity->{$getter}();
  139.                                         }
  140.                                     }
  141.                                     // use excerpt if exists
  142.                                     if (method_exists($entity'getExcerpt')) {
  143.                                         $description $entity->getExcerpt();
  144.                                     }
  145.                                     // check if image exists
  146.                                     if (method_exists($entity'getFullImagePath')) {
  147.                                         $image $entity->getFullImagePath();
  148.                                     }
  149.                                     // get link
  150.                                     $link str_replace(
  151.                                         $checkComponent['slug'],
  152.                                         $entity->getSlug(),
  153.                                         $pageEntity->getSlug()
  154.                                     );
  155.                                     if (!array_key_exists($key$hits)) {
  156.                                         $hits[$key] = [
  157.                                             'hits' => 1,
  158.                                             'title' => $title,
  159.                                             'description' => $description,
  160.                                             'link' => $link,
  161.                                             'image' => $image,
  162.                                         ];
  163.                                     } else {
  164.                                         // same entity hit - so increase hit count
  165.                                         ++$hits[$key]['hits'];
  166.                                         if ($title) {
  167.                                             $hits[$key]['title'] = $title;
  168.                                         }
  169.                                         if ($description) {
  170.                                             $hits[$key]['description'] = $description;
  171.                                         }
  172.                                         if ($link) {
  173.                                             $hits[$key]['link'] = $link;
  174.                                         }
  175.                                         if ($image) {
  176.                                             $hits[$key]['image'] = $image;
  177.                                         }
  178.                                     }
  179.                                     ++$totalResults;
  180.                                 }
  181.                             }
  182.                         }
  183.                     }
  184.                 }
  185.             }
  186.             // echo "<pre>".print_r($hits, true)."</pre>";
  187.             $sortedHits $this->subvalSort($hits'hits');
  188.             $pageHits $paginator->paginate(
  189.                 array_reverse($sortedHits),
  190.                 $request->query->getInt('page'1),
  191.                 $resultsPerPage
  192.             );
  193.         }
  194. dump($pageHits);
  195.         return $this->render('@theme/common/search-results.html.twig', [
  196.             'pageHits' => $pageHits,
  197.             'criteriaArray' => $criteriaArray,
  198.             'criteria' => $string,
  199.             'totalResults' => $totalResults,
  200.         ]);
  201.         return new Response('The search criteria is invalid');
  202.     }
  203.     public function subvalSort($a$subkey)
  204.     {
  205.         $c = [];
  206.         $b = [];
  207.         foreach ($a as $k => $v) {
  208.             $b[$k] = strtolower((string) $v[$subkey]);
  209.         }
  210.         if (isset($b) && is_array($b)) {
  211.             asort($b);
  212.             foreach (array_keys($b) as $key) {
  213.                 $c[] = $a[$key];
  214.             }
  215.             return $c;
  216.         }
  217.         return [];
  218.     }
  219. }