<?php
namespace App\Application\Controller;
use App\Admin\Document\Chain;
use App\Admin\Document\Hub;
use App\Admin\Document\Review;
use AvenueAdminBundle\Filter\MongoDB\StringFilter;
use AvenueAdminBundle\Util\FileUtil;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use \Symfony\Component\Routing\Annotation\Route;
class HubsController extends AbstractController
{
const TOP_CHAINS_LIMIT = 5;
/**
* @Route("/hubs/", name="hubs")
*/
public function index(): Response
{
return $this->getHubsView();
}
private function getHubsView($openHubId = null) {
$hubs = $this->getHubs();
return $this->render(
'application/hubs/index.html.twig', [
'topChains' => $this->getDocumentRepository(Chain::class)->findBy(['active' => true],
['hubCount' => 'desc'], self::TOP_CHAINS_LIMIT),
'showMoreChains' => $this->getQueryBuilder(Chain::class)->field('active')->equals(true)
->count()->getQuery()->execute() > self::TOP_CHAINS_LIMIT,
'hubs' => $hubs,
'hubPoints' => $this->getHubPoints($hubs),
'ratings' => Review::RATINGS,
'openHubId' => $openHubId
]
);
}
/**
* @Route("/hubs/{id}", name="hubs-hub")
*/
public function hub($id) {
return $this->getHubsView($id);
}
/**
* @Route("/select-chain/", name="select-chain")
*/
public function selectChain(Request $request): Response
{
/**
* @var Chain $chain
*/
$chain = $this->getDocumentRepository(Chain::class)->find($request->get('id'));
if ($chain) {
$hubs = [];
foreach ($chain->getHubs() as $hub) {
if ($hub->getActive()) {
$hubs[] = $hub;
}
}
usort($hubs, function (Hub $a, Hub $b) {
return $a->getName() > $b->getName() ? 1
: ($a->getName() < $b->getName() ? -1 : 0);
});
} else {
$hubs = $this->getHubs();
}
return new JsonResponse([
'hubPoints' => $this->getHubPoints($hubs),
'html' => $this->renderView(
'application/hubs/hub-table.html.twig', [
'hubs' => $hubs,
]
)
]);
}
private function getHubFromRequest(Request $request): Hub {
$id = $request->get('id');
$hub = $this->getDocumentRepository(Hub::class)->find($id);
if (!$hub) {
throw new \Exception('no hub with id: ' . $id);
}
return $hub;
}
/**
* @Route("/hub-panel/", name="hub-panel")
*/
public function hubPanel(Request $request): Response
{
$hub = $this->getHubFromRequest($request);
return $this->render(
'application/hubs/hub-panel.html.twig', [
'hub' => $hub
]
);
}
/**
* @Route("/hub-search/", name="hub-search")
*/
public function hubSearch(Request $request): Response
{
$text = $request->get('text');
$hubs = [];
foreach (array_merge($this->getHubs('name', $text), $this->getHubs('address', $text)) as $hub) {
if (!isset($hubs[$hub->getId()])) {
$hubs[$hub->getId()] = $hub;
}
}
usort($hubs, function (Hub $a, Hub $b) {
return $a->getName() > $b->getName() ? 1
: ($a->getName() < $b->getName() ? -1 : 0);
});
return new JsonResponse([
'hubPoints' => $this->getHubPoints($hubs),
'html' => $this->renderView(
'application/hubs/hub-table.html.twig', [
'hubs' => $hubs,
]
)
]);
}
/**
* @Route("/hub-search-chain/", name="hub-search-chain")
*/
public function hubSearchChain(Request $request): Response
{
$text = $request->get('text');
$items = [];
/**
* @var Hub $hub
*/
foreach ($this->getHubs('name', $text) as $hub) {
$items[$hub->getName()] = [
'name' => $hub->getName(),
'id' => null,
'image' => $hub->getChain() ? $hub->getChain()->getImage() : null,
];;
}
$qb = $this->getQueryBuilder(Chain::class);
$qb->field('active')->equals(true);
$qb->sort('hubCount', 'desc');
$qb->limit(10);
$filter = new StringFilter();
$filter->filter($qb, 'name', $request->get('text'));
/**
* @var Chain $chain
*/
foreach ($qb->getQuery()->execute() as $chain) {
$items[$chain->getName()] = [
'name' => $chain->getName(),
'id' => $chain->getId(),
'image' => $chain->getImage(),
];
}
ksort($items);
return $this->render(
'application/hubs/search-result.html.twig', [
'items' => array_values($items)
]
);
}
private function getHubs($field = null, $text = null) {
$qb = $this->getQueryBuilder(Hub::class);
$qb->field('active')->equals(true);
$qb->sort('name');
if ($field && $text) {
$filter = new StringFilter();
$filter->filter($qb, $field, $text);
$qb->limit(50);
}
return $qb->getQuery()->toArray();
}
/**
* @param Hub[] $hubs
*/
private function getHubPoints($hubs) {
$result = [];
foreach ($hubs as $hub) {
$result[] = [
'id' => $hub->getId(),
'name' => $hub->getName(),
'coordinates' => $hub->getCoordinatesAsArray(),
'icon' => $hub->getChain() && $hub->getChain()->getImage() ? '/' . $hub->getChain()->getImage() : null
];
}
return $result;
}
/**
* @Route("/hubs-add-to-favorites/", name="hubs-add-to-favorites")
*/
public function addToFavorites(Request $request) {
if ($this->getLoggedInUser()->getPerson()) {
$hub = $this->getHubFromRequest($request);
$this->getLoggedInUser()->getPerson()->addFavoriteHub($hub);
$this->getDocumentManager()->flush();
}
return new JsonResponse();
}
/**
* @Route("/hubs-delete-from-favorites/", name="hubs-delete-from-favorites")
*/
public function deleteFromFavorites(Request $request) {
if ($this->getLoggedInUser()->getPerson()) {
$hub = $this->getHubFromRequest($request);
$this->getLoggedInUser()->getPerson()->deleteFavoriteHub($hub);
$this->getDocumentManager()->flush();
}
return new JsonResponse();
}
}