-
-
Save mapsi/acc32f0e8c3bb5fe635787b455ec2f1d to your computer and use it in GitHub Desktop.
Self Validating Value Objects and Entities (Laravel Implementation)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
abstract class AbstractEntity extends AbstractValueObject | |
{ | |
/** | |
* Offset Set | |
* | |
* @param mixed $offset | |
* @param mixed $value | |
* | |
* @return void | |
*/ | |
public function offsetSet($offset, $value) | |
{ | |
$this->input[$offset] = $value; | |
if ($this->validate) { | |
$this->validate(); | |
} | |
} | |
/** | |
* Offset Unset | |
* | |
* @param mixed $offset | |
* | |
* @return void | |
*/ | |
public function offsetUnset($offset) | |
{ | |
unset($this->input[$offset]); | |
if ($this->validate) { | |
$this->validate(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use ArrayAccess; | |
use Illuminate\Contracts\Support\Arrayable; | |
use Illuminate\Contracts\Support\Jsonable; | |
use JsonSerializable; | |
use ValidatorInvalidArgumentException; | |
abstract class AbstractValueObject implements ArrayAccess, Arrayable, Jsonable, JsonSerializable | |
{ | |
/** | |
* Input | |
* | |
* @var array | |
*/ | |
protected $input; | |
/** | |
* Validate | |
* | |
* @var bool | |
*/ | |
protected $validate; | |
/** | |
* Rules | |
* | |
* @var array | |
*/ | |
public $rules = []; | |
/** | |
* Messages | |
* | |
* @var array | |
*/ | |
public $messages = []; | |
/** | |
* Validator | |
* | |
* @var Illuminate\Validation\Factory | |
*/ | |
protected $validator; | |
/** | |
* Constructor | |
* | |
* @param array $input Input | |
*/ | |
public function __construct(array $input, $validate = true) | |
{ | |
$this->validator = app()->make('validator'); | |
$this->input = $input; | |
$this->validate = $validate; | |
if ($this->validate) { | |
$this->validate(); | |
} | |
} | |
/** | |
* Get Input | |
* | |
* @return array Input | |
*/ | |
public function getInput() | |
{ | |
return $this->input(); | |
} | |
/** | |
* Validate | |
* | |
* @return null|Dingo\Api\Exception\ValidationHttpException | |
*/ | |
public function validate() | |
{ | |
$validator = $this->validator->make($this->input, $this->rules, $this->messages); | |
if ($validator->fails()) { | |
$exception = new ValidatorInvalidArgumentException(); | |
$exception | |
->setMessage('This is invalid') | |
->setErrors($validator->errors()) | |
->setInput($this->input); | |
throw $exception; | |
} | |
} | |
/** | |
* Offset Exists | |
* | |
* @param mixed $offset | |
* | |
* @return bool | |
*/ | |
public function offsetExists($offset) | |
{ | |
return isset($this->input[$offset]); | |
} | |
/** | |
* Offset Get | |
* | |
* @param mixed $offset | |
* | |
* @return mixed | |
*/ | |
public function offsetGet($offset) | |
{ | |
return $this->input[$offset]; | |
} | |
/** | |
* Offset Set | |
* | |
* @param mixed $offset | |
* @param mixed $value | |
* | |
* @return void | |
*/ | |
public function offsetSet($offset, $value) | |
{ | |
return; | |
} | |
/** | |
* Offset Unset | |
* | |
* @param mixed $offset | |
* | |
* @return void | |
*/ | |
public function offsetUnset($offset) | |
{ | |
return; | |
} | |
/** | |
* To Array | |
* | |
* @return array Array of validated inputs | |
*/ | |
public function toArray() | |
{ | |
return array_only($this->input, array_keys($this->rules)); | |
} | |
/** | |
* Json Serialize | |
* | |
* @return array Convert the object into something JSON serializable. | |
*/ | |
public function jsonSerialize() | |
{ | |
return $this->toArray(); | |
} | |
/** | |
* To Json | |
* | |
* @return string Json string of validated inputs | |
*/ | |
public function toJson($options = 0) | |
{ | |
return json_encode($this->jsonSerialize(), $options); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use ValidatorInvalidArgumentException; | |
class AuthController extends ApiController | |
{ | |
/** | |
* Auth Service | |
* | |
* @var AuthService | |
*/ | |
protected $auth_service; | |
/** | |
* Constructor | |
* | |
* @param AuthService $auth_service Auth Service | |
*/ | |
public function __construct(AuthService $auth_service) | |
{ | |
$this->auth_service = $auth_service; | |
} | |
/** | |
* Authenticate | |
* | |
* @param Request $request Request | |
* | |
* @return Response Response | |
*/ | |
public function authenticate(Request $request) | |
{ | |
$credentials = new CredentialsEntity($request->only('email', 'password')); | |
try { | |
$token = $this->auth_service->authenticate($credentials); | |
} catch (ValidatorInvalidArgumentException $exception) { | |
return [ | |
'message' => $exception->getMessage(), | |
'errors' => $exception->getErrors(), | |
'input' => $exception->getInput(), | |
]; | |
} | |
return [ | |
'token' => $token | |
]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class AuthService | |
{ | |
/** | |
* Authenticate | |
* | |
* @param CredentialsEntity $credentials Credentials | |
* | |
* @return string Token | |
*/ | |
public function authenticate(CredentialsEntity $credentials) | |
{ | |
$token = ''; // Do something with valid $credentials here | |
return $token; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class CredentialsEntity extends AbstractEntity | |
{ | |
/** | |
* Rules | |
* | |
* @var array | |
*/ | |
public $rules = [ | |
'email' => 'required|email', | |
'password' => 'required', | |
]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class CredentialsValueObject extends AbstractValueObject | |
{ | |
/** | |
* Rules | |
* | |
* @var array | |
*/ | |
public $rules = [ | |
'email' => 'required|email', | |
'password' => 'required', | |
]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Value Objects are immutable. | |
$credentials = new CredentialsValueObject(['email' => '[email protected]', 'password' => 'baz']); | |
print $credentials['email']; | |
// Prints email. | |
print isset($credentials['email']); | |
// Prints `true`. | |
print_r($credentials->toArray()); | |
// Prints array of input. | |
print $credentials->toJson(); | |
// Prints input in json format. | |
$credentials['something'] = 'else'; | |
print $credentials['something']; | |
// The key will not exist. | |
// Entities are mutable. | |
$credentials = new CredentialsEntity(['email' => '[email protected]', 'password' => 'baz']); | |
unset($credentials['email']); | |
// Removes `email` key from input property in object and then revalidates. Validation fails. | |
$credentials['something'] = 'else'; | |
print $credentials['something']; | |
// Prints `else`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use InvalidArgumentException; | |
use Illuminate\Support\MessageBag; | |
class ValidatorInvalidArgumentException extends InvalidArgumentException | |
{ | |
/** | |
* Errors | |
* | |
* @var Illuminate\Support\MessageBag | |
*/ | |
protected $errors = []; | |
/** | |
* Input | |
* | |
* @var array | |
*/ | |
protected $input = []; | |
/** | |
* Constructor | |
* | |
* @param string $message Message | |
* @param integer $code Code | |
* @param Exception|null $previous Previous | |
*/ | |
public function __construct($message = '', $code = 0, Exception $previous = null) | |
{ | |
parent::__construct($message, $code, $previous); | |
$this->errors = new MessageBag; | |
} | |
/** | |
* Set Message | |
* | |
* @param string $message Message | |
* | |
* @return ValidatorInvalidArgumentException | |
*/ | |
public function setMessage($message = '') | |
{ | |
$this->message = $message; | |
return $this; | |
} | |
/** | |
* Set Errors | |
* | |
* @param MessageBag $errors Errors | |
*/ | |
public function setErrors(MessageBag $errors) | |
{ | |
$this->errors = $errors; | |
return $this; | |
} | |
/** | |
* Get Errors | |
* | |
* @return MessageBag Errors | |
*/ | |
public function getErrors() | |
{ | |
return $this->errors; | |
} | |
/** | |
* Set Input | |
* | |
* @param array $input Input | |
*/ | |
public function setInput(array $input) | |
{ | |
$this->input = $input; | |
return $this; | |
} | |
/** | |
* Get Input | |
* | |
* @return array Input | |
*/ | |
public function getInput() | |
{ | |
return $this->input; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment