<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Attribute;
use AppBundle\Entity\Page;
use AppBundle\Entity\ProjectPortal;
use AppBundle\Entity\UnitPortal;
use AppBundle\Form\Type\UnitsFilterType;
use AppBundle\Util\ChromeItemsHelperTrait;
use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Translation\Translator;
/**
* Units controller.
*
* @Route("units")
*/
class UnitController extends Controller
{
use ChromeItemsHelperTrait;
/**
* @Route("/", name="units_list")
* @param Request $request
* @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\Response
*/
public function listAction(Request $request, Translator $translator)
{
$page = $request->get('page', 1);
$limit = $request->get('limit', 30);
$view_type = $request->get('view', 'table');
$locale = $request->getLocale();
$paginator = $this->get('knp_paginator');
$em = $this->getDoctrine()->getManager();
$units_repo = $em->getRepository(UnitPortal::class);
$attributes = $em->getRepository(Attribute::class)->getIndexedByKey();
$form = $this->createForm(UnitsFilterType::class);
$form->handleRequest($request);
$filterData = $form->getData() ?? [];
$view_type = $filterData['view'] ?? 'table';
$sort = $filterData['sort'] ?? null;
$direction = $filterData['direction'] ?? null;
// get filtered/sorted attributes
$units = $units_repo->getPriceList($filterData, $page, $limit);
// handle AJAX request for pagination (load more button)
if ($request->isXmlHttpRequest()) {
if ($view_type == 'table') {
$template = 'AppBundle:Unit:rows.html.twig';
} else {
$template = 'AppBundle:Unit:grid.html.twig';
}
$view = $this->renderView($template, [
'projectsPortalData' => $this->getPortalData(),
'units' => $units,
]);
return $this->json([
'view' => $view,
'hide_button' => empty($units) || count($units) < $limit,
]);
}
$page = $em->getRepository(Page::class)
->findOneBy(['type' => Page::PRICE_LIST, 'published' => true]);
//TODO: static approach. Possible solution: create page type for unit detail and use it along with pricelist type
//TODO: or you can create admin module for managing static breadcrumbs according to route
$crumbsPath = [];
$breadHomePage = $em->getRepository(Page::class)->getHomePage();
//check if homepage is defined
if ($breadHomePage) {
$crumbsPath["/"] = (string)$breadHomePage->getTitle();
} else {
$crumbsPath["/"] = "Homepage";
}
$crumbsPath["/units"] = (string)$page->getTitle();
# TODO: remove attribute_values table and replace it with attribute_enum_values
// pagination is used only for sorting applying, so it is no manage to display any data
$pagination = $paginator->paginate([]);
$ctx = [
'pagination' => $pagination,
'params' => ['units_filter[sort]' => $sort],
'crumbsPath' => $crumbsPath,
'units' => $units,
'projectsPortalData' => $this->getPortalData(),
'page' => $page,
'view' => $view_type,
'attributes' => $attributes,
'hide_button' => empty($units) || count($units) < $limit,
'customForm' => (new UnitsFilterType($this->get('service_container')))->renderCustomFilterTemplate($filterData),
'form' => $form->createView(),
];
$this->prepareItemsInController($request, $page, $em, $translator, $ctx);
// override banner if we are looking at one project only
if (!empty($filterData[UnitsFilterType::PROJECT])) {
$projectPortal = $em->getRepository(ProjectPortal::class)
->findOneBy(['rpEntity' => $filterData[UnitsFilterType::PROJECT]]);
if ($projectPortal->getBanner()) {
$ctx['bannerSlides'] = $projectPortal->getBanner()->getPreparedStructure();
}
}
return $this->render('AppBundle:Unit:list.html.twig', $ctx);
}
/**
* @Route("/getContactForm", name="get_contact_form")
* @Method("GET")
* @return \Symfony\Component\HttpFoundation\Response
*/
public function getContactFormAction()
{
return $this->render('AppBundle:Form:contact_form.html.twig');
}
/**
* @Route("/getWhistleblowingForm", name="get_whistleblowing_form")
* @Method("GET")
* @return \Symfony\Component\HttpFoundation\Response
*/
public function getWhistleblowingFormAction()
{
return $this->render('AppBundle:Form:whistleblowing_form.html.twig');
}
/**
* @Route("/{id}", name="units_details")
* @Method("GET")
* @return \Symfony\Component\HttpFoundation\Response
*/
public function showAction(Request $request, $id, Translator $translator, LoggerInterface $logger)
{
if ($request->isXmlHttpRequest()) {
return $this->json([
'redirect_url' => $request->getRequestUri()
]);
}
$unit = $this->findUnitByIdOrInternalId($id);
if (!$unit) {
return new RedirectResponse("/units");
}
$em = $this->getDoctrine()->getManager();
$page = $em->getRepository(Page::class)
->findOneBy(['type' => Page::PRICE_LIST, 'published' => true]);
$projectID = $unit->getRpEntity()->getProject()->getId();
$projectPortal = $em->getRepository(ProjectPortal::class)
->findOneBy(['rpEntity' => $projectID]);
$projectPage = $em->getRepository(Page::class)
->findOneBy(['type' => Page::PROJECT_PAGE, 'published' => true, 'projectPortal' => $projectPortal]);
$crumbsPath = [];
$breadHomePage = $em->getRepository(Page::class)->getHomePage();
// check if homepage is defined
if ($breadHomePage) {
$crumbsPath["/"] = (string)$breadHomePage->getTitle();
} else {
$crumbsPath["/"] = "Homepage";
}
$crumbsPath["/units"] = (string)$page->getTitle();
$crumbsPath["/units/" . $id] = $unit->getRpEntity()->getName();
//$unitContentPage = null;
$unitContentPage = $projectPage->getUnitContent();
$unitContentPage = $unitContentPage !== null ? $unitContentPage->getContentBlocks() : "";
$ctx = [
'unit' => $unit,
'page' => $page,
'unitContent' => $unitContentPage,
'crumbsPath' => $crumbsPath,
'project_page' => $projectPage,
'projectsPortalData' => $this->getPortalData(),
];
$this->prepareItemsInController($request, $page, $em, $translator, $ctx);
if ($projectPortal->getBanner()) {
$ctx['bannerSlides'] = $projectPortal->getBanner()->getPreparedStructure();
}
$internalId = $unit->getRpEntity()->getName();
if (strpos($internalId, '.1') !== false) {
// ground floor unit, replace the . with _
$ctx['hashtag'] = str_replace(".", "_", $internalId);
} else {
// other unit, replace:
// C1.[digit] -> C1_
// C2.[digit] -> C2_
// D1.[digit] -> D_
// D2.[digit] -> D_
$ctx['hashtag'] =
preg_replace("/D2\.[0-9]/", "D_",
preg_replace("/D1\.[0-9]/", "D_",
preg_replace("/C2\.[0-9]/", "C2_",
preg_replace("/C1\.[0-9]/", "C1_", $internalId))));
}
return $this->render('AppBundle:Unit:detail.html.twig', $ctx);
}
private function findUnitByIdOrInternalId($id)
{
$em = $this->getDoctrine()->getManager();
$zeroedId = $id;
if (strpos($id, "SM2-") !== false) {
$zeroedId = str_replace("SM2-", "SM2-0", $id);
}
if (ctype_digit($id)) {
$sql = "SELECT up FROM AppBundle\Entity\UnitPortal up JOIN up.rpEntity u WHERE up.id = :id OR JSON_GET_TEXT(u.attributes, 'flat_internal_id') = :id OR JSON_GET_TEXT(u.attributes, 'flat_internal_id') = :zeroedid ORDER BY up.id DESC";
} else {
$sql = "SELECT up FROM AppBundle\Entity\UnitPortal up JOIN up.rpEntity u WHERE JSON_GET_TEXT(u.attributes, 'flat_internal_id') = :id OR JSON_GET_TEXT(u.attributes, 'flat_internal_id') = :zeroedid ORDER BY up.id DESC";
}
$query = $em->createQuery($sql)
->setMaxResults(1)
->setParameters(["id" => $id, "zeroedid" => $zeroedId]);
return $query->getOneOrNullResult();
}
/**
* Save unit coordinates based on floor plan
*
* @Route("/{id}/coordinates", name="units_save_coordinates")
* @Method("POST")
* @param Request $request
* @param UnitPortal $unit
* @return \Symfony\Component\HttpFoundation\Response
*/
public function saveCoordinates(Request $request, UnitPortal $unit)
{
$coordinates = $request->get('coordinates');
$unit->setCoordinates($coordinates);
$em = $this->getDoctrine()->getManager();
$em->persist($unit);
$em->flush();
return $this->json([
'status' => 'success'
]);
}
public function getPortalData()
{
$em = $this->getDoctrine()->getManager();
$projectPortal_repo = $em->getRepository(ProjectPortal::class);
$projectsPortal = $projectPortal_repo->getProjectsDisplayName();
$projectsPortalData = [];
foreach ($projectsPortal as $key => $project) {
$projectsPortalData[$project->getRpEntity()->getId()] =
[
'displayName' => $project->getDisplayName(),
'project' => $project
];
}
return $projectsPortalData;
}
}