Skip to content

Instantly share code, notes, and snippets.

@adrenalinkin
Created January 13, 2019 13:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adrenalinkin/d9bfed953034361b3f60030a35919ac0 to your computer and use it in GitHub Desktop.
Save adrenalinkin/d9bfed953034361b3f60030a35919ac0 to your computer and use it in GitHub Desktop.

We have some DTO which implements DtoResolverInterface:

interface DtoResolverInterface
{
    /**
     * Inject custom resolver
     *
     * @param OptionsResolver $resolver
     */
    public function injectResolver(OptionsResolver $resolver);

    /**
     * Resolves received data into EntryDTO
     *
     * @param array $data
     */
    public function resolve(array $data);
}

Register listener for onKernelControllerArguments:

    /**
     * @param FilterControllerArgumentsEvent $event
     */
    public function onKernelControllerArguments(FilterControllerArgumentsEvent $event): void
    {
        $request = $event->getRequest();

        foreach ($event->getArguments() as $argument) {
            if (!$argument instanceof DtoResolverInterface) {
                continue;
            }

            $resolver = $this->factory->createForDefinition(get_class($argument));
            $argument->injectResolver($resolver);

            try {
                $argument->resolve($request->body->all());
            } catch (InvalidOptionsException $e) {
                throw new ApiException(ApiException::HTTP_BAD_REQUEST_DATA, $e->getMessage());
            }
        }
    }

So finally, in the controller method we receives already resolved DTO instead full Request:

    public function updateServicePhoneNumberAction(UpdateServicePhoneNumberEntryDto $entryDto): Response 
    {
        // some code here
    }

DTO example for better understanding:

/**
 * @SWG\Definition(
 *      type="object",
 *      description="DTO for updating service phone number",
 *      required={"servicePhoneNumber"},
 * )
 */
class UpdateServicePhoneNumberEntryDto extends AbstractDtoResolver // AbstractDtoResolver  implements common logic and implements DtoResolverInterface
{
    /**
     * @var string
     *
     * @SWG\Property(description="Phone number in E.164 format", example="71112223344")
     */
    protected $servicePhoneNumber;

    /**
     * @return string
     */
    public function getServicePhoneNumber(): string
    {
        return $this->servicePhoneNumber;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment