Skip to content

Instantly share code, notes, and snippets.

@suin
Created October 16, 2012 15:28
Show Gist options
  • Save suin/3899969 to your computer and use it in GitHub Desktop.
Save suin/3899969 to your computer and use it in GitHub Desktop.
<?php
/**
* ポリシーエンティティのモック
*/
class Policy
{
/**
* @return DateTime
*/
public function InceptionDate()
{
}
}
/**
* 苦情サービス
*/
class ClaimService
{
/**
* 苦情を登録する
* @param RegisterClaimDTO $claim
* @return void
*/
public function registerClaim(RegisterClaimDTO $claim)
{
// コマンドパターン
$cmd = new RegisterClaim($claim);
$cmd->run();
}
}
/**
* 苦情データ転送オブジェクト
*/
class RegisterClaimDTO
{
const BLANK_DATE = null;
/** @var Notification_Error */
public static $MISSING_POLICY_NUMBER;
/** @var Notification_Error */
public static $UNKNOWN_POLICY_NUMBER;
/** @var Notification_Error */
public static $MISSING_INCIDENT_TYPE;
/** @var Notification_Error */
public static $MISSING_INCIDENT_DATE;
/** @var Notification_Error */
public static $DATE_BEFORE_POLICY_START;
/** @var Notification */
private $notification;
/** @var string */
private $policyID;
/** @var string */
private $type;
/** @var DateTime */
private $incidentDate = self::BLANK_DATE;
public function __construct()
{
$this->notification = new Notification();
self::$MISSING_POLICY_NUMBER = new Notification_Error("Policy number is missing");
self::$UNKNOWN_POLICY_NUMBER = new Notification_Error("This policy number is unknown");
self::$MISSING_INCIDENT_TYPE = new Notification_Error("Incident type is missing");
self::$MISSING_INCIDENT_DATE = new Notification_Error("Incident Date is missing");
self::$DATE_BEFORE_POLICY_START = new Notification_Error("Incident Date is before we started doing this business");
}
/**
* @return Notification
*/
public function getNotification()
{
return $this->notification;
}
/**
* @param Notification $value
*/
public function setNotification(Notification $value)
{
$this->notification = $value;
}
/**
* @return string
*/
public function getPolicyId()
{
return $this->policyID;
}
/**
* @param string $value
*/
public function setPolicyId($value)
{
$this->policyID = $value;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* @param string $value
*/
public function setType($value)
{
$this->type = $value;
}
/**
* @return DateTime|null
*/
public function getIncidentDate()
{
return $this->incidentDate;
}
/**
* @param DateTime $value
*/
public function setIncidentDate($value)
{
$this->incidentDate = $value;
}
}
/**
* The notification class is what we'll use to capture the errors in the domain layer.
* Essentially it's a collection of errors, each one of which is a simple wrapper around a string.
*/
class Notification
{
/** @var ArrayObject */
private $errors;
public function __construct()
{
$this->errors = new ArrayObject();
}
/**
* @return ArrayObject
*/
public function getErrors()
{
return $this->errors;
}
/**
* @param ArrayObject $value
*/
public function setErrors(ArrayObject $value)
{
$this->errors = $value;
}
/**
* @return bool
*/
public function hasErrors()
{
return ( 0 != $this->getErrors()->count() );
}
/**
* @param Notification_Error $error
* @return bool
*/
public function includesError(Notification_Error $error)
{
foreach ( $this->getErrors() as $happenedError ) {
if ( $error == $happenedError ) {
return true;
}
}
return false;
}
}
class Notification_Error
{
/** @var string */
private $message;
/**
* @param string $message
*/
public function __construct($message)
{
$this->message = $message;
}
/**
* @return string
*/
public function toString()
{
return $this->message;
}
}
/**
* 苦情登録サービス
*/
class RegisterClaim
{
/** @var RegisterClaimDTO */
protected $claim;
public function __construct(RegisterClaimDTO $claim)
{
$this->claim = $claim;
}
public function run()
{
$this->_validate();
if ( !$this->claim->getNotification()->hasErrors() ) {
$this->_registerClaimInBackendSystems();
}
}
private function _registerClaimInBackendSystems()
{
// register claim in backend systems
}
/**
* @return void
*/
private function _validate()
{
$this->_failIfNullOrBlank($this->claim->getPolicyId(), RegisterClaimDTO::$MISSING_POLICY_NUMBER);
$this->_failIfNullOrBlank($this->claim->getType(), RegisterClaimDTO::$MISSING_INCIDENT_TYPE);
$this->_fail($this->claim->getIncidentDate() == RegisterClaimDTO::BLANK_DATE, RegisterClaimDTO::$MISSING_INCIDENT_DATE);
if ( $this->_isBlank($this->claim->getPolicyId()) ) {
return;
}
/** @var $policy Policy */
$policy = $this->_findPolicy($this->claim->getPolicyId());
if ( $policy == null ) {
$this->claim->getNotification()->getErrors()->append(RegisterClaimDTO::$UNKNOWN_POLICY_NUMBER);
} else {
$this->_fail(
( $this->claim->getIncidentDate()->diff($policy->InceptionDate()) < 0 ),
RegisterClaimDTO::$DATE_BEFORE_POLICY_START);
}
}
/**
* @param $policyId
* @return Policy
*/
private function _findPolicy($policyId)
{
// Policyエンティティを探す
}
/**
* @param string $string
* @return bool
*/
private function _isBlank($string)
{
return ( $string == "" );
}
/**
* @param string $string
* @param Notification_Error $error
* @return void
*/
private function _failIfNullOrBlank($string, Notification_Error $error)
{
$this->_fail($this->_isBlank($string), $error);
}
/**
* @param bool $isFail
* @param Notification_Error $error
*/
private function _fail($isFail, Notification_Error $error)
{
if ( $isFail ) {
$this->claim->getNotification()->getErrors()->append($error);
}
}
}
/**
* 苦情コントローラ
*/
class ClaimController
{
/** @var RegisterClaimDTO */
private $claim;
/** @var object 入力 */
private $input;
/** @var array */
private $errors = array();
/**
* 苦情提出アクション
* @return array
*/
public function submitAction()
{
$this->claim = new RegisterClaimDTO();
$this->claim->setPolicyId($this->input->policyId->value);
$this->claim->setIncidentDate($this->input->incidentDate->value);
$this->claim->setType($this->input->type->value);
$service = new ClaimService();
$service->registerClaim($this->claim);
if ( $this->claim->getNotification()->hasErrors() ) {
$responseText = "Not registered, see errors";
$this->_indicateErrors();
} else {
$responseText = "Registration Succeeded";
}
// viewに渡す
return array(
'responseText' => $responseText,
'errors' => $this->errors,
);
}
private function _indicateErrors()
{
$this->_checkError(RegisterClaimDTO::$MISSING_POLICY_NUMBER, $this->input->policyId);
$this->_checkError(RegisterClaimDTO::$MISSING_INCIDENT_TYPE, $this->input->type);
$this->_checkError(RegisterClaimDTO::$DATE_BEFORE_POLICY_START, $this->input->incidentDate);
$this->_checkError(RegisterClaimDTO::$MISSING_INCIDENT_DATE, $this->input->incidentDate);
$this->_checkError(RegisterClaimDTO::$DATE_BEFORE_POLICY_START, $this->input->incidentDate);
}
/**
* @param Notification_Error $error
* @param $input
*/
private function _checkError(Notification_Error $error, $input)
{
if ( $this->claim->getNotification()->includesError($error) ) {
$this->errors[] = array($input, $error->toString());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment