Skip to content

Instantly share code, notes, and snippets.

@carousel
Forked from fesor/AbstractRequest.php
Created March 17, 2018 10:23
Show Gist options
  • Save carousel/703806403225c5919a2e4b0deb958391 to your computer and use it in GitHub Desktop.
Save carousel/703806403225c5919a2e4b0deb958391 to your computer and use it in GitHub Desktop.
DTO example
<?php
namespace SomeApp\Application\DTO;
use Symfony\Component\OptionsResolver\OptionsResolver;
abstract class AbstractRequest
{
public function __construct(array $data)
{
$options = new OptionsResolver();
$this->configureOptions($options);
$this->map($options);
}
abstract protected function configureOptions(OptionsResolver $options);
protected function map(OptionsResolver $options)
{
// just plain mapping, all other things
// like snake case to camel case convertion or keys aliases resolving
// should be done in controller
// values normalization could be done via option resolver's normalizers
$options->resolve($data);
foreach ($options->getDefinedOptions() as $prop) {
$this->$prop = $options[$prop];
}
}
}
<?php
namespace SomeApp\Application\DTO\Something;
use Symfony\Component\OptionsResolver\OptionsResolver;
use SomeApp\Infrastructure\Security\UserSession;
class DoSomethingRequest extends AbstractRequest
{
protected $userSession;
protected $foo;
protected $fooBar;
/**
* @param UserSession $userSession - id of user
* @param array $data - array of options to be resolved
*/
public function __construct(UserSession $userSession, array $data)
{
// this is only for example,
// I usually have UserSession object wich implements UserInterface
// UserSession isn't doctrine entity, it just data container which hydrates from JWT token
// It contains user Id, some other information (isAdmin flag for example) and so on.
$this->userSession = $userSession;
parent::__contruct($data);
}
protected function configureOptions(OptionsResolver $options)
{
$options
->setRequired(['foo', 'bar'])
->setAllowedTypes([
'foo' => 'string',
'fooBar' => ['int', 'string']
])
;
}
public function getUserID()
{
return $this->userSession->getUserID();
}
public function getFoo()
{
return $this->foo;
}
public function getFooBar()
{
return $this->fooBar;
}
}
<?php
class SomethingController extends Controller
{
public function createSomething(Request $request) {
// handled via symfony/serializer in middleware
// or you can map it with jms serializer or just by yourself here in controller
$requestData = $request->request->all();
// create request DTO
$requestDTO = new DoSomethingRequest($this->getUser(), $requestData);
// pass it to application layer, which will return response dto
$responseDTO = $this->get('something_maker')->doStuff($requestDTO);
return $responseDTO; // middleware will serialize it, or we can use JsonResponse and map data to array...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment