Easy_solution/src/Controller/ProjectController.php

163 lines
7.4 KiB
PHP

<?php
namespace App\Controller;
use App\Entity\Apps;
use App\Entity\Project;
use App\Repository\AppsRepository;
use App\Repository\OrganizationsRepository;
use App\Repository\ProjectRepository;
use App\Service\ProjectService;
use App\Service\UserService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Asset\Packages;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
#[Route(path: '/project', name: 'project_')]
final class ProjectController extends AbstractController
{
public function __construct(private readonly EntityManagerInterface $entityManager,
private readonly OrganizationsRepository $organizationsRepository,
private readonly ProjectRepository $projectRepository,
private readonly ProjectService $projectService,
private readonly UserService $userService, private readonly AppsRepository $appsRepository)
{
}
#[Route('/', name: '_index', methods: ['GET'])]
public function index(): Response
{
return $this->render('project/index.html.twig', [
'controller_name' => 'ProjectController',
]);
}
#[Route('/new/ajax', name: '_new', methods: ['POST'])]
public function new(Request $request): JsonResponse
{
$this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
$data = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
if (!$data) {
return new JsonResponse(['error' => 'Invalid JSON'], Response::HTTP_BAD_REQUEST);
} $org = $this->organizationsRepository->findOneBy(['id' => $data['organizationId']]);
if(!$org) {
return new JsonResponse(['error' => 'Organization not found'], Response::HTTP_NOT_FOUND);
}
$sanitizedDbName = $this->projectService->getProjectDbName($data['name'], $org->getProjectPrefix());
if($this->projectRepository->findOneBy(['bddName' => $sanitizedDbName])) {
return new JsonResponse(['error' => 'A project with the same name already exists'], Response::HTTP_CONFLICT);
}
if(!$this->projectService->isApplicationArrayValid($data['applications'])) {
return new JsonResponse(['error' => 'Invalid applications array'], Response::HTTP_BAD_REQUEST);
}
$project = new Project();
$project->setName($data['name']);
$project->setBddName($sanitizedDbName);
$project->setOrganization($org);
$project->setApplications($data['applications']);
$this->entityManager->persist($project);
$this->entityManager->flush();
return new JsonResponse(['message' => 'Project created successfully'], Response::HTTP_CREATED);
}
#[Route(path:'/edit/{id}/ajax', name: '_edit', methods: ['POST'])]
public function edit(Request $request, int $id): JsonResponse
{
$this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
$data = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
if (!$data) {
return new JsonResponse(['error' => 'Invalid JSON'], Response::HTTP_BAD_REQUEST);
} $org = $this->organizationsRepository->findOneBy(['id' => $data['organizationId']]);
if(!$org) {
return new JsonResponse(['error' => 'Organization not found'], Response::HTTP_NOT_FOUND);
}
$project = $this->projectRepository->findOneBy(['id' => $id]);
if(!$project) {
return new JsonResponse(['error' => 'Project not found'], Response::HTTP_NOT_FOUND);
}
$project->setApplications($data['applications']);
$project->setModifiedAt(new \DateTimeImmutable());
$this->entityManager->persist($project);
$this->entityManager->flush();
return new JsonResponse(['message' => 'Project updated successfully'], Response::HTTP_OK);
}
#[Route('/organization/data', name: '_organization_data', methods: ['GET'])]
public function organizationData(Request $request, Packages $assetPackage): JsonResponse {
$this->denyAccessUnlessGranted('ROLE_USER');
$page = $request->query->getInt('page', 1);
$size = $request->query->getInt('size', 15);
$filters = $request->query->all('filter');
$orgId = $request->query->get('orgId');
$org = $this->organizationsRepository->findOneBy(['id' => $orgId, 'isDeleted' => false]);
if(!$org) {
return new JsonResponse(['error' => 'Organization not found'], Response::HTTP_NOT_FOUND);
}
$paginator = $this->projectRepository->findProjectByOrganization($orgId, $page, $size, $filters);
$total = count($paginator);
$data = array_map(function (Project $project) use ($assetPackage) {
// Map ONLY the applications linked to THIS specific project
$projectApps = array_map(function($appId) use ($assetPackage) {
// Note: If $project->getApplications() returns IDs, we need to find the entities.
// If your Project entity has a ManyToMany relationship, use $project->getApps() instead.
$appEntity = $this->appsRepository->find($appId);
return $appEntity ? [
'id' => $appEntity->getId(),
'name' => $appEntity->getName(),
'logoMiniUrl' => $assetPackage->getUrl($appEntity->getLogoMiniUrl()),
] : null;
}, $project->getApplications() ?? []);
return [
'id' => $project->getId(),
'name' => ucfirst($project->getName()),
'applications' => array_filter($projectApps), // Remove nulls
'bddName' => $project->getBddName(),
'isActive' => $project->isActive(),
];
}, iterator_to_array($paginator));
return $this->json([
'data' => $data,
'total' => $total,
'last_page' => (int)ceil($total / $size),
]);
}
#[Route(path: '/data/{id}', name: '_project_data', methods: ['GET'])]
public function projectData(Request $request, int $id): JsonResponse{
$this->denyAccessUnlessGranted('ROLE_USER');
$project = $this->projectRepository->findOneBy(['id' => $id]);
if(!$project) {
return new JsonResponse(['error' => 'Project not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse([
'id' => $project->getId(),
'name' => ucfirst($project->getName()),
'applications' => $project->getApplications(),
]);
}
#[Route(path: '/delete/{id}/ajax', name: '_delete', methods: ['POST'])]
public function delete(int $id): JsonResponse {
$this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
$project = $this->projectRepository->findOneBy(['id' => $id]);
if(!$project) {
return new JsonResponse(['error' => 'Project not found'], Response::HTTP_NOT_FOUND);
}
$project->setIsDeleted(true);
$this->entityManager->persist($project);
$this->entityManager->flush();
return new JsonResponse(['message' => 'Project deleted successfully'], Response::HTTP_OK);
}
}