-
-
Save victorkurauchi/5542a7a8421612add2456397b0c90841 to your computer and use it in GitHub Desktop.
Example of how to create a custom search feature for the Bolt CMS, by making a local extension
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Bolt\Extension\DesignSpike\ExampleSearch; | |
use Bolt\Extension\SimpleExtension; | |
use Bolt\Routing\ControllerCollection; | |
use Doctrine\DBAL\Query\QueryBuilder; | |
use Silex\Application; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\HttpFoundation\Response; | |
class ExampleSearchExtension extends SimpleExtension | |
{ | |
protected function registerFrontEndRoutes(ControllerCollection $collection) | |
{ | |
$collection->get('/search', [$this, 'callbackProductSearch']); | |
} | |
protected function callbackProductSearch(Application $app, Request $request) | |
{ | |
$number = trim($request->query->get('number')); | |
$name = trim($request->query->get('name')); | |
$cas = trim($request->query->get('cas')); | |
$formula = trim($request->query->get('formula')); | |
$general = trim($request->query->get('q')); | |
$results = []; | |
if ($number or $name or $cas or $formula or $general) { | |
$repo = $app['storage']->getRepository('products'); | |
/** @var $qb QueryBuilder */ | |
$qb = $repo->createQueryBuilder(); | |
} | |
// search for the provided word in any of the main fields | |
if ($general) { | |
$qb->orWhere("number LIKE CONCAT('%', :general, '%')"); | |
$qb->orWhere("cas LIKE CONCAT('%', :general, '%')"); | |
$qb->setParameter('general', $general); | |
// get an array of all words entered in the visitor's search | |
$terms = array_filter(array_map('trim', explode(' ', $general))); | |
// name - search for items where every word in the search is found in the name field | |
$nameAndX = $qb->expr()->andX(); | |
foreach ($terms as $index => $term) { | |
$param_name = "term".$index; | |
$nameAndX->add("name LIKE CONCAT('%', :".$param_name.", '%')"); | |
$qb->setParameter($param_name, $term); | |
} | |
$qb->orWhere($nameAndX); | |
// synonyms - search for items where every word in the search is found in the synonyms field | |
$synonymsAndX = $qb->expr()->andX(); | |
foreach ($terms as $index => $term) { | |
$param_name = "term".$index; | |
$synonymsAndX->add("synonyms LIKE CONCAT('%', :".$param_name.", '%')"); | |
$qb->setParameter($param_name, $term); | |
} | |
$qb->orWhere($synonymsAndX); | |
} | |
if ($number) { | |
$qb->andWhere("number LIKE CONCAT('%', :number, '%')"); | |
$qb->setParameter('number', $number); | |
} | |
if ($name) { | |
// this is where we should start the stuff about synonyms | |
$terms = array_filter(array_map('trim', explode(' ', $name))); | |
foreach ($terms as $index => $term) { | |
$param_name = "nameterm".$index; | |
$qb->andWhere("name LIKE CONCAT('%', :".$param_name.", '%') OR synonyms LIKE CONCAT('%', :".$param_name.", '%')"); | |
$qb->setParameter($param_name, $term); | |
} | |
} | |
if ($cas) { | |
$qb->andWhere("cas LIKE CONCAT('%', :cas, '%')"); | |
$qb->setParameter('cas', $cas); | |
} | |
if ($formula) { | |
// search for chemical formula - in mysql this requires binary search for case sensitivity | |
$qb->andWhere("formula REGEXP BINARY | |
CONCAT( | |
'(>|[[:<:]]|[[:lower:]]|[[:upper:]]|[[:digit:]]|\\\(|\\\))', | |
:formula, | |
'(<|[[:>:]]|[[:upper:]]|[[:digit:]]|\\\(|\\\))' | |
)"); | |
// ensure that user-inputted special characters aren't parsed as regex characters | |
$escaped_formula = preg_quote($formula); | |
$qb->setParameter('formula', $escaped_formula); | |
} | |
if (isset($qb)) { | |
$results = $qb->execute()->fetchAll(); | |
} | |
$html = $app['twig']->render('product_search.twig', [ | |
'results' => $results | |
]); | |
return new Response($html); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment