Skip to content

Instantly share code, notes, and snippets.

@lfbn
Last active December 17, 2022 23:39
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save lfbn/a92776cbeeceb929c15454231160c35b to your computer and use it in GitHub Desktop.
Save lfbn/a92776cbeeceb929c15454231160c35b to your computer and use it in GitHub Desktop.
<?php
namespace App\Services\Dto;
abstract class AbstractDto
{
/**
* AbstractRequestDto constructor.
* @param array $data
*/
public function __construct(array $data)
{
// We create a validator, with all the data we receive.
// The rules come from the child class.
$validator = Validator::make(
$data,
$this->configureValidatorRules()
);
// We now validate the data we receive, for this DTO.
// If it fails we throw an exception.
if (!$validator->validate()) {
throw new InvalidArgumentException(
'Error: ' . $validator->errors()->first()
);
}
// The data is valid.
// Now we map it.
if (!$this->map($data)) {
throw new InvalidArgumentException('The mapping failed');
}
}
/* @return array */
abstract protected function configureValidatorRules(): array;
/**
* @param array $data
* @return bool
*/
abstract protected function map(array $data): bool;
}
<?php
namespace App\Services\Dto;
class CreateUserDto extends AbstractDto implements DtoInterface
{
/* @var string */
protected $email;
/* @return array */
protected function configureValidatorRules(): array
{
return [
'email' => 'required'
];
}
/**
* @inheritDoc
*/
protected function map(array $data): bool
{
$this->email = $data['email'];
return true;
}
}
<?php
namespace App\Services;
use InvalidArgumentException;
class CreateUserService implements ServiceInterface
{
/**
* @var CreateUserDto
*/
private $createUserDto;
/**
* CreateUserService constructor.
* @param CreateUserDto $createUserDto
*/
public function __construct(CreateUserDto $createUserDto)
{
$this->createUserDto = $createUserDto;
}
/**
* @return bool
*/
public function execute(): bool
{
// All is done. We create the user.
// Everything good. We return the result.
return true;
}
/**
* @param DtoInterface $dto
* @return ServiceInterface
*/
public static function make(DtoInterface $dto): ServiceInterface
{
// We check if this is a CreateUserDTO
if (!$dto instanceof CreateUserDto) {
throw new InvalidArgumentException('CreateUserService needs to receive a CreateUserDto.');
}
// All good. We create the instance, and tell the IDE the type of our DTO.
/* @var CreateUserDto $dto */
return new CreateUserService($dto);
}
}
<?php
namespace App\Services\Dto;
interface DtoInterface
{
}
<?php
use App\Services\Dto\CreateUserDto;
use use App\Services\CreateUserService;
// First, we create the DTO. We need it to use the service.
$createUserDto = new CreateUserDto(
['email' => 'some.user@gmail.com']
);
// Now we have the DTO. We also know that he is valid.
// Let's make our service, and execute it.
$createUserService = CreateUserService::make($createUserDto);
$createUserService->execute();
<?php
namespace App\Services;
interface ServiceInterface
{
/**
* @return bool
*/
public function execute(): bool;
/**
* @param DtoInterface $dto
* @return ServiceInterface
*/
public static function make(DtoInterface $dto): ServiceInterface;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment