163 lines
7.4 KiB
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);
|
|
}
|
|
}
|