OutputOnlySnakeToCamelNameConverter.php 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. <?php
  2. namespace Webkul\BagistoApi\Serializer;
  3. use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
  4. /**
  5. * Delegates to the same logic as SnakeCaseToCamelCaseNameConverter
  6. * (which is final and cannot be extended).
  7. *
  8. * - normalize: snake_case → camelCase (output)
  9. * - denormalize: camelCase → snake_case (input/property reading)
  10. *
  11. * This works correctly for Eloquent models and GraphQL.
  12. * For REST DTOs with camelCase properties, processors read
  13. * directly from the request JSON body as a fallback.
  14. *
  15. * IMPORTANT — DTO property naming over GraphQL: API Platform resolves a GraphQL
  16. * field's VALUE by `denormalize()`-ing the camelCase field name to a property
  17. * name and reading that property. It calls this converter WITHOUT class context
  18. * (the class arg is null in that path), so the converter cannot special-case
  19. * individual DTOs. Consequence: output DTO properties MUST be snake_case
  20. * (`order_id`, not `orderId`) — snake properties round-trip correctly over both
  21. * REST and GraphQL and still surface as camelCase to clients. camelCase DTO
  22. * properties resolve over REST but come back null over GraphQL.
  23. */
  24. class OutputOnlySnakeToCamelNameConverter implements NameConverterInterface
  25. {
  26. public function normalize(string $propertyName): string
  27. {
  28. // Preserve leading underscores (e.g. _lft, _rgt, _id)
  29. $prefix = '';
  30. $name = $propertyName;
  31. if (str_starts_with($name, '_')) {
  32. $prefix = '_';
  33. $name = substr($name, 1);
  34. }
  35. return $prefix.lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $name))));
  36. }
  37. public function denormalize(string $propertyName): string
  38. {
  39. // Preserve leading underscores
  40. $prefix = '';
  41. $name = $propertyName;
  42. if (str_starts_with($name, '_')) {
  43. $prefix = '_';
  44. $name = substr($name, 1);
  45. }
  46. return $prefix.strtolower(preg_replace('/[A-Z]/', '_$0', lcfirst($name)));
  47. }
  48. }