Implementing new research behaviour refs #377

This commit is contained in:
Julien Fastré 2014-12-31 02:34:33 +01:00
parent 707046d8cc
commit 383fe786c7

View File

@ -20,11 +20,12 @@
namespace Chill\PersonBundle\Search;
use Chill\MainBundle\Search\AbstractSearch;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityManagerInterface;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Chill\MainBundle\Search\ParsingException;
class PersonSearch extends AbstractSearch
{
@ -32,14 +33,14 @@ class PersonSearch extends AbstractSearch
/**
*
* @var ObjectManager
* @var EntityManagerInterface
*/
private $om;
private $em;
public function __construct(ObjectManager $om)
public function __construct(EntityManagerInterface $em)
{
$this->om = $om;
$this->em = $em;
}
/*
@ -68,21 +69,24 @@ class PersonSearch extends AbstractSearch
{
return true;
}
public function supports($domain)
{
return 'person' === $domain;
}
/*
* (non-PHPdoc)
* @see \Chill\MainBundle\Search\SearchInterface::renderResult()
*/
public function renderResult($pattern, $start = 0, $limit = 50, array $options = array())
public function renderResult(array $terms, $start = 0, $limit = 50, array $options = array())
{
$persons = $this->search($pattern, $start, $limit, $options);
return $this->container->get('templating')->render('ChillPersonBundle:Person:list.html.twig',
array(
'persons' => $persons,
'pattern' => trim($pattern),
'total' => count($persons)
'persons' => $this->search($terms, $start, $limit, $options),
'pattern' => 'trim($pattern)',
'total' => $this->count($terms)
));
}
@ -94,19 +98,108 @@ class PersonSearch extends AbstractSearch
* @param array $options
* @return Person[]
*/
protected function search($pattern, $start, $limit, array $options = array())
protected function search(array $terms, $start, $limit, array $options = array())
{
$dql = 'SELECT p FROM ChillPersonBundle:Person p'
. ' WHERE'
. ' LOWER(p.firstName) like LOWER(:q)'
. ' OR LOWER(p.lastName) like LOWER(:q)'
. 'ORDER BY p.lastName, p.firstName';
$qb = $this->createQuery($terms, 'search');
$query = $this->om->createQuery($dql)
->setParameter('q', '%'.trim($pattern).'%')
->setFirstResult($start)
->setMaxResults($limit);
$qb->select('p')
->setMaxResults($limit)
->setFirstResult($start);
return $query->getResult() ;
return $qb->getQuery()->getResult();
}
protected function count(array $terms)
{
$qb = $this->createQuery($terms);
$qb->select('COUNT(p.id)');
return $qb->getQuery()->getSingleScalarResult();
}
private $_cacheQuery = array();
/**
*
* @param array $terms
* @return \Doctrine\ORM\QueryBuilder
*/
protected function createQuery(array $terms)
{
//get from cache
$cacheKey = md5(serialize($terms));
if (array_key_exists($cacheKey, $this->_cacheQuery)) {
return $this->_cacheQuery[$cacheKey];
}
$qb = $this->em->createQueryBuilder();
$qb->from('ChillPersonBundle:Person', 'p');
if (array_key_exists('firstname', $terms)) {
$qb->andWhere($qb->expr()->like('LOWER(p.firstName)', ':firstname'))
->setParameter('firstname', '%'.$terms['firstname'].'%');
}
if (array_key_exists('lastname', $terms)) {
$qb->andWhere($qb->expr()->like('LOWER(p.lastName)', ':lastname'))
->setParameter('lastname', '%'.$terms['lastname'].'%');
}
if (array_key_exists('birthdate', $terms)) {
try {
$date = new \DateTime($terms['birthdate']);
} catch (\Exception $ex) {
throw new ParsingException('The date is '
. 'not parsable', 0, $ex);
}
$qb->andWhere($qb->expr()->eq('p.dateOfBirth', ':birthdate'))
->setParameter('birthdate', $date);
}
if (array_key_exists('gender', $terms)) {
if (!in_array($terms['gender'], array(Person::GENRE_MAN, Person::GENRE_WOMAN))) {
throw new ParsingException('The gender '
.$terms['gender'].' is not accepted. Should be "'.Person::GENRE_MAN
.'" or "'.Person::GENRE_WOMAN.'"');
}
$qb->andWhere($qb->expr()->eq('p.genre', ':gender'))
->setParameter('gender', $terms['gender']);
}
if (array_key_exists('nationality', $terms)) {
try {
$country = $this->em->createQuery('SELECT c FROM '
. 'ChillMainBundle:Country c WHERE '
. 'LOWER(c.countryCode) LIKE :code')
->setParameter('code', $terms['nationality'])
->getSingleResult();
} catch (\Doctrine\ORM\NoResultException $ex) {
throw new ParsingException('The country code "'.$terms['nationality'].'" '
. ', used in nationality, is unknow', 0, $ex);
}
$qb->andWhere($qb->expr()->eq('p.nationality', ':nationality'))
->setParameter('nationality', $country);
}
if ($terms['_default'] !== '') {
$grams = explode(' ', $terms['_default']);
foreach($grams as $key => $gram) {
$qb->andWhere($qb->expr()
->like('LOWER(CONCAT(p.firstName, \' \', p.lastName))', ':default'))
->setParameter('default', '%'.$gram.'%');
}
}
$this->_cacheQuery[$cacheKey] = $qb;
return $qb;
}
}