decodePayload($request); if ($payload instanceof JsonResponse) { return $payload; } $customField = $this->resolveCustomField($payload); if ($customField instanceof JsonResponse) { return $customField; } $target = $this->resolveTarget($payload); if ($target instanceof JsonResponse) { return $target; } $value = new CustomFieldValue(); $value->setCustomField($customField); $value->setValue((string) ($payload['value'] ?? '')); $this->applyTarget($value, $target['type'], $target['entity']); $this->entityManager->persist($value); $this->entityManager->flush(); return $this->json($this->normalizeCustomFieldValue($value)); } #[Route('/upsert', name: 'custom_field_values_upsert', methods: ['POST'])] public function upsert(Request $request): JsonResponse { $payload = $this->decodePayload($request); if ($payload instanceof JsonResponse) { return $payload; } $customField = $this->resolveCustomField($payload); if ($customField instanceof JsonResponse) { return $customField; } $target = $this->resolveTarget($payload); if ($target instanceof JsonResponse) { return $target; } $existing = $this->customFieldValueRepository->findOneBy([ 'customField' => $customField, $target['type'] => $target['entity'], ]); if ($existing instanceof CustomFieldValue) { $existing->setValue((string) ($payload['value'] ?? '')); $this->entityManager->flush(); return $this->json($this->normalizeCustomFieldValue($existing)); } $value = new CustomFieldValue(); $value->setCustomField($customField); $value->setValue((string) ($payload['value'] ?? '')); $this->applyTarget($value, $target['type'], $target['entity']); $this->entityManager->persist($value); $this->entityManager->flush(); return $this->json($this->normalizeCustomFieldValue($value)); } #[Route('/{entityType}/{entityId}', name: 'custom_field_values_list', methods: ['GET'])] public function listByEntity(string $entityType, string $entityId): JsonResponse { $target = $this->resolveTarget([ 'entityType' => $entityType, 'entityId' => $entityId, ]); if ($target instanceof JsonResponse) { return $target; } $values = $this->customFieldValueRepository->findBy([ $target['type'] => $target['entity'], ]); return $this->json(array_map( fn (CustomFieldValue $value) => $this->normalizeCustomFieldValue($value), $values )); } #[Route('/{id}', name: 'custom_field_values_update', methods: ['PATCH'])] public function update(string $id, Request $request): JsonResponse { $value = $this->customFieldValueRepository->find($id); if (!$value instanceof CustomFieldValue) { return $this->json(['success' => false, 'error' => 'Custom field value not found.'], 404); } $payload = $this->decodePayload($request); if ($payload instanceof JsonResponse) { return $payload; } if (array_key_exists('value', $payload)) { $value->setValue((string) $payload['value']); } $this->entityManager->flush(); return $this->json($this->normalizeCustomFieldValue($value)); } #[Route('/{id}', name: 'custom_field_values_delete', methods: ['DELETE'])] public function delete(string $id): JsonResponse { $value = $this->customFieldValueRepository->find($id); if (!$value instanceof CustomFieldValue) { return $this->json(['success' => false, 'error' => 'Custom field value not found.'], 404); } $this->entityManager->remove($value); $this->entityManager->flush(); return $this->json(['success' => true]); } private function decodePayload(Request $request): array|JsonResponse { $payload = json_decode($request->getContent(), true); if (!is_array($payload)) { return $this->json(['success' => false, 'error' => 'Invalid JSON payload.'], 400); } return $payload; } private function resolveCustomField(array $payload): CustomField|JsonResponse { $customFieldId = isset($payload['customFieldId']) ? trim((string) $payload['customFieldId']) : ''; if ('' !== $customFieldId) { $customField = $this->customFieldRepository->find($customFieldId); if ($customField instanceof CustomField) { return $customField; } return $this->json(['success' => false, 'error' => 'Custom field not found.'], 404); } $customFieldName = isset($payload['customFieldName']) ? trim((string) $payload['customFieldName']) : ''; if ('' === $customFieldName) { return $this->json(['success' => false, 'error' => 'customFieldId or customFieldName is required.'], 400); } $customField = new CustomField(); $customField->setName($customFieldName); $customField->setType((string) ($payload['customFieldType'] ?? 'text')); $customField->setRequired((bool) ($payload['customFieldRequired'] ?? false)); $options = $payload['customFieldOptions'] ?? null; if (is_array($options)) { $customField->setOptions($options); } $this->entityManager->persist($customField); return $customField; } private function resolveTarget(array $payload): array|JsonResponse { $entityType = isset($payload['entityType']) ? strtolower((string) $payload['entityType']) : ''; $entityId = isset($payload['entityId']) ? trim((string) $payload['entityId']) : ''; if ('' === $entityType || '' === $entityId) { foreach (['machine', 'composant', 'piece', 'product'] as $candidate) { $key = $candidate.'Id'; if (!isset($payload[$key])) { continue; } $entityType = $candidate; $entityId = trim((string) $payload[$key]); break; } } if ('' === $entityType || '' === $entityId) { return $this->json(['success' => false, 'error' => 'Entity target is missing.'], 400); } return match ($entityType) { 'machine' => $this->resolveEntity('machine', $entityId, $this->machineRepository), 'composant' => $this->resolveEntity('composant', $entityId, $this->composantRepository), 'piece' => $this->resolveEntity('piece', $entityId, $this->pieceRepository), 'product' => $this->resolveEntity('product', $entityId, $this->productRepository), default => $this->json(['success' => false, 'error' => 'Unsupported entity type.'], 400), }; } private function resolveEntity(string $type, string $id, $repository): array|JsonResponse { $entity = $repository->find($id); if (!$entity) { return $this->json(['success' => false, 'error' => sprintf('%s not found.', $type)], 404); } return ['type' => $type, 'entity' => $entity]; } private function applyTarget(CustomFieldValue $value, string $type, object $entity): void { switch ($type) { case 'machine': $value->setMachine($entity); break; case 'composant': $value->setComposant($entity); break; case 'piece': $value->setPiece($entity); break; case 'product': $value->setProduct($entity); break; } } private function normalizeCustomFieldValue(CustomFieldValue $value): array { $customField = $value->getCustomField(); return [ 'id' => $value->getId(), 'value' => $value->getValue(), 'customFieldId' => $customField->getId(), 'customField' => [ 'id' => $customField->getId(), 'name' => $customField->getName(), 'type' => $customField->getType(), 'required' => $customField->isRequired(), 'options' => $customField->getOptions(), 'orderIndex' => $customField->getOrderIndex(), ], 'machineId' => $value->getMachine()?->getId(), 'composantId' => $value->getComposant()?->getId(), 'pieceId' => $value->getPiece()?->getId(), 'productId' => $value->getProduct()?->getId(), 'createdAt' => $value->getCreatedAt()->format(DATE_ATOM), 'updatedAt' => $value->getUpdatedAt()->format(DATE_ATOM), ]; } }