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); } }