<?php declare(strict_types=1);
namespace DkcLocations\Storefront\Controller;
use DkcLocations\Core\Content\Location\LocationEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use Shopware\Storefront\Page\GenericPageLoaderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
/**
* @RouteScope(scopes={"storefront"})
*/
class DkcLocationController extends StorefrontController
{
private EntityRepositoryInterface $locationRepository;
private EntityRepositoryInterface $employeeRepository;
private GenericPageLoaderInterface $genericPageLoader;
public function __construct(
EntityRepositoryInterface $locationRepository,
EntityRepositoryInterface $employeeRepository,
GenericPageLoaderInterface $genericPageLoader
) {
$this->locationRepository = $locationRepository;
$this->employeeRepository = $employeeRepository;
$this->genericPageLoader = $genericPageLoader;
}
/**
* @Route("/standorte/{slug}", name="frontend.dkc.location.detail", methods={"GET"}, defaults={"_routeScope"={"storefront"}})
*/
public function detail(string $slug, Request $request, SalesChannelContext $salesChannelContext): Response
{
$salesChannelId = $salesChannelContext->getSalesChannel()->getId();
// Load generic page (header, footer, navigation, breadcrumb)
$page = $this->genericPageLoader->load($request, $salesChannelContext);
// Load all active locations for this sales channel to find by slug
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('active', true));
$criteria->addFilter(new EqualsFilter('locationSalesChannels.salesChannelId', $salesChannelId));
$criteria->addAssociation('country');
$locations = $this->locationRepository->search($criteria, $salesChannelContext->getContext());
/** @var LocationEntity|null $location */
$location = null;
foreach ($locations as $loc) {
if (self::generateSlug($loc->getName()) === $slug) {
$location = $loc;
break;
}
}
if (!$location) {
throw new NotFoundHttpException('Standort nicht gefunden.');
}
// Set meta title
$metaInformation = $page->getMetaInformation();
if ($metaInformation) {
$metaInformation->setMetaTitle($location->getName() . ' | ' . $salesChannelContext->getSalesChannel()->getName());
}
// Load employees for this location AND sales channel
$empCriteria = new Criteria();
$empCriteria->addFilter(new EqualsFilter('employeeLocations.locationId', $location->getId()));
$empCriteria->addFilter(new EqualsFilter('employeeSalesChannels.salesChannelId', $salesChannelId));
$empCriteria->addAssociation('employeeDepartments.department');
$empCriteria->addAssociation('image');
$empCriteria->addSorting(new FieldSorting('lastName', FieldSorting::ASCENDING));
$employees = $this->employeeRepository->search($empCriteria, $salesChannelContext->getContext());
// Group employees by department (employee can be in multiple departments)
$groupedEmployees = [];
foreach ($employees as $employee) {
$departments = $employee->getEmployeeDepartments();
if ($departments === null || $departments->count() === 0) {
// No department assigned
$key = '999_Allgemein';
if (!isset($groupedEmployees[$key])) {
$groupedEmployees[$key] = [
'name' => 'Allgemein',
'position' => 999,
'employees' => [],
];
}
$groupedEmployees[$key]['employees'][] = $employee;
} else {
foreach ($departments as $empDept) {
$dept = $empDept->getDepartment();
$deptName = $dept ? $dept->getName() : 'Allgemein';
$deptPos = $dept ? $dept->getPosition() : 999;
$key = $deptPos . '_' . $deptName;
if (!isset($groupedEmployees[$key])) {
$groupedEmployees[$key] = [
'name' => $deptName,
'position' => $deptPos,
'employees' => [],
];
}
$groupedEmployees[$key]['employees'][] = $employee;
}
}
}
ksort($groupedEmployees);
return $this->renderStorefront('@DkcLocations/storefront/page/location-detail.html.twig', [
'page' => $page,
'location' => $location,
'groupedEmployees' => $groupedEmployees,
]);
}
public static function generateSlug(string $name): string
{
$slug = mb_strtolower($name, 'UTF-8');
$slug = str_replace(
['ä', 'ö', 'ü', 'ß', 'Ä', 'Ö', 'Ü'],
['ae', 'oe', 'ue', 'ss', 'ae', 'oe', 'ue'],
$slug
);
$slug = preg_replace('/[^a-z0-9]+/', '-', $slug);
$slug = trim($slug, '-');
return $slug;
}
}