<?php declare(strict_types=1);
namespace App\StartPlatz\Bundle\AcceleratorBundle\Controller;
use App\StartPlatz\Bundle\MemberBundle\Entity\Member;
use App\StartPlatz\Bundle\MemberBundle\Entity\MemberTeam;
use App\StartPlatz\Bundle\MemberBundle\Entity\Team;
use App\StartPlatz\Bundle\MentorsBundle\Service\WordPressMenuService;
use App\StartPlatz\Bundle\StartupBundle\Entity\Startup;
use App\StartPlatz\Bundle\StartupBundle\Entity\StartupRelevance;
use App\StartPlatz\Bundle\UserBundle\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route;
/**
* Controller für öffentliche Accelerator Startup Seiten.
*
* Handles:
* - Grid-Übersicht aller KI-Accelerator Startups
* - Detail-Ansicht einzelner Startups
*/
class AcceleratorStartupController extends AbstractController
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly SessionInterface $session,
private readonly WordPressMenuService $wordPressMenuService
) {
}
/**
* Grid-Übersicht aller KI-Accelerator Startups.
*/
#[Route('/accelerator/startups', name: 'accelerator_startups')]
#[Route('/en/accelerator/startups', name: 'accelerator_startups_en')]
public function indexAction(Request $request): Response
{
$isEnglish = str_contains($request->getPathInfo(), '/en/');
$menu = $this->wordPressMenuService->getAcceleratorMenu($isEnglish, $request->getPathInfo());
// Layout-Parameter für A/B-Testing (v1, v2, v7, v7a, v7b, etc.)
$layout = $request->query->get('layout', 'v1');
if (!preg_match('/^v[0-9]+[a-z]*$/', $layout)) {
$layout = 'v1';
}
$startups = $this->entityManager->getRepository(Startup::class)->findKiAcceleratorStartups();
$teamIds = array_map(fn ($entity) => $entity->getTeamId(), $startups);
$teams = $this->entityManager->getRepository(Team::class)->findBy(['id' => $teamIds]);
$teamIds = array_map(fn ($entity) => $entity->getId(), $teams);
$teams = array_combine($teamIds, $teams);
return $this->render('@StartPlatzAccelerator/AcceleratorStartup/index.html.twig', [
'startups' => $startups,
'teams' => $teams,
'menu' => $menu,
'isEnglish' => $isEnglish,
'pageTitle' => $isEnglish ? 'AI Accelerator Startups' : 'KI Accelerator Startups',
'layout' => $layout,
]);
}
/**
* Detail-Ansicht eines einzelnen KI-Accelerator Startups.
*/
#[Route('/accelerator/startup/{id}-{slug}', name: 'accelerator_startup_detail', requirements: ['id' => '\d+'])]
#[Route('/en/accelerator/startup/{id}-{slug}', name: 'accelerator_startup_detail_en', requirements: ['id' => '\d+'])]
public function detailAction(Request $request, int $id, string $slug): Response
{
$isEnglish = str_contains($request->getPathInfo(), '/en/');
$menu = $this->wordPressMenuService->getAcceleratorMenu($isEnglish, $request->getPathInfo());
// User activity tracking
if ($user = $this->getUser()) {
$this->entityManager->getRepository(User::class)->writeActivity($user);
}
// Find startup - must be KI Accelerator and have public visibility
$startup = $this->entityManager->getRepository(Startup::class)->findOneBy([
'id' => $id,
'visibility' => 'public'
]);
if (!$startup || $startup->getKiAccelerator() === null) {
$this->session->getFlashBag()->add('notice', 'Startup nicht gefunden');
return $this->redirectToRoute($isEnglish ? 'accelerator_startups_en' : 'accelerator_startups');
}
// Redirect to correct slug if needed
if ($slug !== $startup->getSlug()) {
return $this->redirectToRoute(
$isEnglish ? 'accelerator_startup_detail_en' : 'accelerator_startup_detail',
['id' => $id, 'slug' => $startup->getSlug()]
);
}
// Team and access rights
$team = null;
$rightToAccessTeam = false;
$userMember = null;
if ($user = $this->getUser()) {
$userMember = $this->entityManager->getRepository(Member::class)->find($user->getMemberId());
}
if ($teamId = $startup->getTeamId()) {
$team = $this->entityManager->getRepository(Team::class)->find($teamId);
if ($team && $userMember) {
$rightToAccessTeam = $this->entityManager->getRepository(MemberTeam::class)->checkAccessRight($userMember, $team);
}
}
// Track relevance
$this->entityManager->getRepository(StartupRelevance::class)->updateByUserAction($id, 'click');
// Back URL for navigation
$backUrl = $this->generateUrl($isEnglish ? 'accelerator_startups_en' : 'accelerator_startups');
// Internal page URL (for CTA on public page)
$internalPageUrl = $this->generateUrl(
$isEnglish ? 'accelerator_startup_internal_en' : 'accelerator_startup_internal',
['id' => $id, 'slug' => $startup->getSlug()]
);
return $this->render('@StartPlatzAccelerator/AcceleratorStartup/detail.html.twig', [
'startup' => $startup,
'team' => $team,
'rightToAccessTeam' => $rightToAccessTeam,
'userMember' => $userMember,
'menu' => $menu,
'isEnglish' => $isEnglish,
'pageTitle' => $startup->getName(),
'backUrl' => $backUrl,
'internalPageUrl' => $internalPageUrl,
]);
}
/**
* Interne Detail-Ansicht eines KI-Accelerator Startups (Login erforderlich).
* Ebene 3: Vertiefte Informationen nur für eingeloggte Mitglieder.
*/
#[Route('/accelerator/startup/{id}-{slug}/internal', name: 'accelerator_startup_internal', requirements: ['id' => '\d+'])]
#[Route('/en/accelerator/startup/{id}-{slug}/internal', name: 'accelerator_startup_internal_en', requirements: ['id' => '\d+'])]
public function internalAction(Request $request, int $id, string $slug): Response
{
$isEnglish = str_contains($request->getPathInfo(), '/en/');
$menu = $this->wordPressMenuService->getAcceleratorMenu($isEnglish, $request->getPathInfo());
// Find startup
$startup = $this->entityManager->getRepository(Startup::class)->findOneBy([
'id' => $id,
'visibility' => 'public'
]);
if (!$startup || $startup->getKiAccelerator() === null) {
$this->session->getFlashBag()->add('notice', 'Startup nicht gefunden');
return $this->redirectToRoute($isEnglish ? 'accelerator_startups_en' : 'accelerator_startups');
}
// Redirect to correct slug if needed
if ($slug !== $startup->getSlug()) {
return $this->redirectToRoute(
$isEnglish ? 'accelerator_startup_internal_en' : 'accelerator_startup_internal',
['id' => $id, 'slug' => $startup->getSlug()]
);
}
// Check if user is logged in
$user = $this->getUser();
if (!$user) {
// Redirect to login with return URL
return $this->redirectToRoute('login', [
'targetPath' => $request->getUri()
]);
}
// User activity tracking
$this->entityManager->getRepository(User::class)->writeActivity($user);
// Get member for role-based CTAs
$userMember = $this->entityManager->getRepository(Member::class)->find($user->getMemberId());
// Team and access rights
$team = null;
$rightToAccessTeam = false;
if ($teamId = $startup->getTeamId()) {
$team = $this->entityManager->getRepository(Team::class)->find($teamId);
if ($team && $userMember) {
$rightToAccessTeam = $this->entityManager->getRepository(MemberTeam::class)->checkAccessRight($userMember, $team);
}
}
// Track relevance (internal view = higher engagement)
$this->entityManager->getRepository(StartupRelevance::class)->updateByUserAction($id, 'click');
// Back URL to public page
$publicPageUrl = $this->generateUrl(
$isEnglish ? 'accelerator_startup_detail_en' : 'accelerator_startup_detail',
['id' => $id, 'slug' => $startup->getSlug()]
);
return $this->render('@StartPlatzAccelerator/AcceleratorStartup/internal.html.twig', [
'startup' => $startup,
'team' => $team,
'rightToAccessTeam' => $rightToAccessTeam,
'userMember' => $userMember,
'menu' => $menu,
'isEnglish' => $isEnglish,
'pageTitle' => $startup->getName() . ' - ' . ($isEnglish ? 'Internal' : 'Intern'),
'publicPageUrl' => $publicPageUrl,
]);
}
}