Created
August 27, 2014 11:08
-
-
Save saksmt/d820ad527756407c1ac1 to your computer and use it in GitHub Desktop.
Finds providers
This file contains 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 FS\MyOnCallDocBundle\Model\Provider; | |
use Buzz\Browser; | |
use Doctrine\ORM\Query; | |
use Doctrine\ORM\QueryBuilder; | |
use Symfony\Component\Form\Form; | |
use FS\UserBundle\Entity\Patient; | |
use Symfony\Component\Form\FormFactory; | |
use Knp\Component\Pager\PaginatorInterface; | |
use Symfony\Component\HttpFoundation\Request; | |
use Doctrine\Common\Persistence\ObjectManager; | |
use Symfony\Component\HttpFoundation\RequestStack; | |
use FS\MyOnCallDocBundle\Form\Type\DoctorFilterType; | |
use Lexik\Bundle\FormFilterBundle\Filter\FilterBuilderUpdaterInterface; // ladder of dependencies :) | |
/** | |
* Class ProviderFinder | |
* @package FS\MyOnCallDocBundle\Model\Provider | |
* Provides find actions | |
*/ | |
class ProviderFinder implements ProviderFinderInterface | |
{ | |
/** | |
* @var QueryBuilder | |
*/ | |
private $builder; | |
/** | |
* @var ObjectManager | |
*/ | |
private $em; | |
/** | |
* @var array | |
*/ | |
private $favorites = array(); | |
/** | |
* @var array | |
*/ | |
private $notifications = array(); | |
/** | |
* @var Request | |
*/ | |
private $request; | |
/** | |
* @var array | |
*/ | |
private static $doctorsPriorities; | |
/** | |
* @var FilterBuilderUpdaterInterface | |
*/ | |
private $filterBuilder; | |
/** | |
* @var Form | |
*/ | |
private $form; | |
/** | |
* @var FormFactory | |
*/ | |
private $formFactory; | |
/** | |
* @var Browser | |
*/ | |
private $browser; | |
/** | |
* @var PaginatorInterface | |
*/ | |
private $paginator; | |
public function __construct( | |
ObjectManager $objectManager, | |
RequestStack $requestStack, | |
FilterBuilderUpdaterInterface $updaterInterface, | |
FormFactory $formFactory, | |
Browser $browser, | |
PaginatorInterface $paginator | |
) | |
{ | |
$this->em = $objectManager; | |
$this->request = $requestStack->getCurrentRequest(); | |
$this->filterBuilder = $updaterInterface; | |
$this->formFactory = $formFactory; | |
$this->browser = $browser; | |
$this->paginator = $paginator; | |
} | |
public function findForUser(Patient $patient) | |
{ | |
$this->processForUser($patient); | |
return array( | |
'paginator' => $this->createPagination(), | |
'form' => $this->form->createView(), | |
'favourites' => $this->favorites, | |
'notifications' => $this->notifications, | |
); | |
} | |
public function processForUser(Patient $patient) | |
{ | |
$this->initQueryBuilder(); | |
$this->processUserSpecific($patient); | |
$this->buildRest($patient->getState()); | |
$this->processForm(); | |
return $this; | |
} | |
public function processForAnonymous() | |
{ | |
$this->initQueryBuilder(); | |
$this->buildRest($this->getUserState()); | |
$this->processForm(); | |
return $this; | |
} | |
public function getQueryBuilder() | |
{ | |
return clone $this->builder; | |
} | |
public function findForAnonymous() | |
{ | |
$this->processForAnonymous(); | |
return array( | |
'paginator' => $this->createPagination(), | |
'form' => $this->form->createView(), | |
'favourites' => $this->favorites, | |
'notifications' => $this->notifications, | |
); | |
} | |
private function initDoctorPriorities() | |
{ | |
if (!isset(self::$doctorsPriorities)) { | |
self::$doctorsPriorities = array( | |
'd.id IN (:favorites) AND c IS NOT NULL', | |
'd.id IN (:favorites) AND c IS NULL', | |
'd.id NOT IN (:favorites) AND c IS NOT NULL', | |
); | |
} | |
} | |
private function initQueryBuilder() | |
{ | |
$this->builder = $this->em->getRepository('FSUserBundle:Doctor')->createQueryBuilder('d'); | |
$this->builder | |
->select('d') | |
->leftJoin('d.certifiedStates', 'c', 'WITH', 'c.state = :state') | |
->andWhere('d.enabled = 1'); | |
} | |
private function buildRest($patientState) | |
{ | |
$orderClause = $this->buildDoctorPriorities(); | |
$this->builder->addSelect('('.$orderClause.') AS HIDDEN DoctorOrder'); | |
$this->builder->setParameters(array( | |
'favorites' => $this->favorites, | |
'state' => $patientState, | |
)); | |
$this->setSort(); | |
} | |
private function processUserSpecific(Patient $patient) | |
{ | |
$favorites = $this->favorites; | |
$notifications = $this->notifications; | |
$patientFavorites = $patient->getFavourites(); | |
foreach ($patientFavorites as $patientFavorite) { | |
$favorites[] = $patientFavorite->getDoctorId()->getId(); | |
if ($patientFavorite->getNotifications()) { | |
$notifications[] = $patientFavorite->getDoctorId()->getId(); | |
} | |
} | |
$this->favorites = $favorites; | |
$this->notifications = $notifications; | |
} | |
private function buildDoctorPriorities() | |
{ | |
$this->initDoctorPriorities(); | |
$priority = 0; | |
$orderClause = 'CASE '; | |
foreach (self::$doctorsPriorities as $doctorPriority) { | |
$orderClause .= 'WHEN '; | |
$orderClause .= $doctorPriority; | |
$orderClause .= ' THEN '; | |
$orderClause .= $priority++; | |
$orderClause .= ' '; | |
} | |
$orderClause .= 'ELSE '.$priority; | |
$orderClause .= ' END'; | |
return $orderClause; | |
} | |
private function buildFilterForm() | |
{ | |
$doctorCertifiedStates = $this->em | |
->getRepository('FSMyOnCallDocBundle:CertifiedState') | |
->getDoctorCertifiedStates(); | |
$this->form = $this->formFactory->create(new DoctorFilterType($doctorCertifiedStates)); | |
} | |
private function getUserState() | |
{ | |
$apiRequest = $this->browser->get('http://freegeoip.net/json/' . $_SERVER['REMOTE_ADDR']); | |
$response = $apiRequest->getContent(); | |
if ($response) { | |
$result = json_decode($response); | |
if (is_object($result) && $result->region_code != '') { | |
return $result->region_code; | |
} | |
} | |
return null; | |
} | |
private function processForm() | |
{ | |
$this->buildFilterForm(); | |
if ($this->request->query->has('submit-filter')) { | |
$this->form->submit($this->request); | |
$filterBuilder = $this->builder; | |
$this->builder = $this->filterBuilder->addFilterConditions($this->form, $filterBuilder); | |
} | |
} | |
private function setSort() | |
{ | |
$this->builder | |
->addOrderBy('DoctorOrder') | |
->addOrderBy('d.rating', 'DESC') | |
->addOrderBy('d.lastLogin', 'DESC') | |
->addOrderBy('d.firstName', 'ASC') | |
->addOrderBy('d.lastName', 'ASC'); | |
} | |
private function createPagination() | |
{ | |
return $this->paginator->paginate( | |
$this->builder->getQuery(), | |
$this->request->query->get('page', 1), | |
10 | |
); | |
} | |
public function getFavorites() | |
{ | |
return $this->favorites; | |
} | |
public function getNotifications() | |
{ | |
return $this->notifications; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment