マイグレーション
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('activation_admins', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->string('confirmation_token')->nullable();
$table->timestamp('confirmed_at')->nullable();
$table->timestamp('confirmation_sent_at')->nullable();
$table->rememberToken();
$table->timestamps();
});
}
Cotroller
/**
* @param string $activationCode
* @param Activator $service
* @param CustomerAuthentication $auth
* @param CustomerStatus $customerStatus
* @return RedirectResponse
* @throws \Exception
*/
public function activate(
string $activationCode,
Activator $service,
CustomerAuthentication $auth,
CustomerStatus $customerStatus
): RedirectResponse {
$customer = null;
$this->dbm->beginTransaction();
try {
$customer = $service->activate($activationCode);
$auth->forceLogin($customer->id);
$this->dbm->commit();
} catch (OmsException $e) {
$this->dbm->rollBack();
}
// メール認証後は会員情報入力を促す
if ($customer && $customerStatus->needProfiling($customer)) {
throw new NeedProfilingException('This content is needed profiling.');
}
return redirect()->route('web.top');
}
Activator
<?php
declare(strict_types=1);
namespace Oms\Domain\CustomerRegistration;
use Oms\Models\Interfaces\CustomerInterface;
class Activator
{
/** @var Activation */
protected $activation;
/** @var CustomerRegistration */
protected $customerRegistration;
/**
* Activator constructor.
*
* @param Activation $activation
*/
public function __construct(Activation $activation, CustomerRegistration $customerRegistration)
{
$this->activation = $activation;
$this->customerRegistration = $customerRegistration;
}
/**
* @param string $activationCode
*
* @return \Oms\Models\Interfaces\CustomerInterface
*/
public function activate(string $activationCode): CustomerInterface
{
$activatedCustomer = $this->activation->activate($activationCode);
return $this->customerRegistration->register($activatedCustomer);
}
}
Activation
<?php
declare(strict_types=1);
namespace Oms\Domain\CustomerRegistration;
use Carbon\Carbon;
use Oms\Repositories\ActivationCustomerRepository;
use Oms\Models\ActivationCustomer;
class Activation
{
/** @var ActivationCustomerRepository */
protected $repository;
/**
* Activation constructor.
*
* @param ActivationCustomerRepository $activationCustomerRepository
*/
public function __construct(ActivationCustomerRepository $activationCustomerRepository)
{
$this->repository = $activationCustomerRepository;
}
/**
* @param string $source
*
* @return string
*/
public function issueActivationCode(string $source): string
{
return encrypt($source);
}
/**
* @param ActivationCustomer $temporaryCustomer
*
* @return bool
*/
private function verifyExpiration(ActivationCustomer $temporaryCustomer): bool
{
if (is_null($temporaryCustomer->confirmation_sent_at)) {
return false;
}
// 有効期限は1ヶ月
return $temporaryCustomer->confirmation_sent_at->gt(Carbon::now()->subMonth());
}
/**
* @param $activationToken
*
* @return ActivationCustomer
*/
public function activate($activationToken): ActivationCustomer
{
$temporaryCustomer = $this->repository->findByConfirmationToken($activationToken);
if (!$this->verifyExpiration($temporaryCustomer)) {
// @todo 有効期限切れてます例外
}
return $this->repository->activate($temporaryCustomer);
}
}
CustomerRegistration
<?php
declare(strict_types=1);
namespace Oms\Domain\CustomerRegistration;
use Oms\Models\ActivationCustomer;
use Oms\Models\Customer;
use Oms\Models\Interfaces\CustomerInterface;
use Oms\Repositories\Interfaces\CustomerRepositoryInterface;
class CustomerRegistration
{
/** @var CustomerInterface */
protected $customerRepository;
/**
* CustomerRegistration constructor.
*
* @param CustomerRepositoryInterface $customerRepository
*/
public function __construct(CustomerRepositoryInterface $customerRepository)
{
$this->customerRepository = $customerRepository;
}
/**
* @param ActivationCustomer $activatedCustomer
*
* @return CustomerInterface
*/
public function register(ActivationCustomer $activatedCustomer): CustomerInterface
{
$customer = $this->customerRepository->findByEmail($activatedCustomer->email);
$activatedCustomer->delete();
return $this->customerRepository->update($customer, ['status' => Customer::STATUS_CUSTOMER]);
}
}
TemporaryCustomerRegister
<?php
declare(strict_types=1);
namespace Oms\Domain\CustomerRegistration;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Support\Str;
use Oms\Domain\CustomerRegistration\Entity\NotCustomer;
use Oms\Domain\Front\CustomerAuthentication\CustomerAuthentication;
use Oms\Domain\Front\CustomerStatus\InvalidCustomerStatusException;
use Oms\Models\Interfaces\CustomerInterface;
use Oms\Repositories\ActivationCustomerRepository;
class TemporaryCustomerRegister
{
/** @var TemporaryCustomerRegistration */
protected $domain;
/** @var Activation */
protected $activation;
/** @var Mailer */
protected $mailer;
/** @var CustomerAuthentication */
protected $auth;
/**
* TemporaryCustomerRegister constructor.
*
* @param TemporaryCustomerRegistration $domain
* @param Activation $activation
* @param Mailer $mailer
* @param CustomerAuthentication $auth
*/
public function __construct(
TemporaryCustomerRegistration $domain,
Activation $activation,
Mailer $mailer,
CustomerAuthentication $auth
) {
$this->domain = $domain;
$this->activation = $activation;
$this->mailer = $mailer;
$this->auth = $auth;
}
/**
* @param string $name
* @param string $email
* @param string $password
*
* @return CustomerInterface
*/
public function temporaryRegister(string $name, string $email, string $password): CustomerInterface
{
$lowerEmail = strtolower($email);
/**
* Register a temporary customer.
*/
$notCustomer = $this->makeNotCustomer($name, $lowerEmail, $password);
$activationCode = $this->activation->issueActivationCode(Str::random(20));
$temporaryCustomer = $this->domain->temporaryRegister($notCustomer, $activationCode);
/**
* Send a activation mail to the temporary customer.
*/
$this->sendMail($temporaryCustomer, $activationCode);
/**
* Let temporary customer login
*/
$this->auth->forceLogin($temporaryCustomer->id);
return $temporaryCustomer;
}
/**
* @param string $name
* @param string $email
* @param string $password
*
* @return NotCustomer
*/
protected function makeNotCustomer(string $name, string $email, string $password): NotCustomer
{
return app(NotCustomer::class, [
'name' => $name,
'email' => $email,
'password' => $password,
]);
}
/**
* @param CustomerInterface $temporaryCustomer
* @param string $activationCode
*/
protected function sendMail(CustomerInterface $temporaryCustomer, string $activationCode)
{
$mailable = new TemporaryCustomerRegistrationMail($temporaryCustomer, $activationCode);
$this->mailer->to($temporaryCustomer->email)->send($mailable);
}
/**
* resend email for customer activation
*/
public function reactivate()
{
$temporaryCustomer = $this->auth->customer();
if (!$temporaryCustomer->isTemporaryCustomer()) {
throw new InvalidCustomerStatusException('This content is for temporary customers.');
}
$activationCode = $this->activation->issueActivationCode(Str::random(20));
// 既存のアクティベーション用のコードを再発行したコードで更新する
$activationCustomerRepository = app(ActivationCustomerRepository::class);
$activationCustomer = $activationCustomerRepository->findByEmail($temporaryCustomer->email);
$activationCustomerRepository->update($activationCustomer, ['confirmation_token' => $activationCode]);
// メールを再送する
$this->sendMail($temporaryCustomer, $activationCode);
}
}
TemporaryCustomerRegistration
<?php
declare(strict_types=1);
namespace Oms\Domain\CustomerRegistration;
use Oms\Domain\CustomerRegistration\Entity\NotCustomer;
use Oms\Models\Customer;
use Oms\Models\Interfaces\CustomerInterface;
use Oms\Repositories\ActivationCustomerRepository;
use Oms\Repositories\Interfaces\CustomerRepositoryInterface;
class TemporaryCustomerRegistration
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
/** @var ActivationCustomerRepository */
protected $activationCustomerRepository;
public function __construct(
CustomerRepositoryInterface $customerRepository,
ActivationCustomerRepository $activationCustomerRepository
) {
$this->customerRepository = $customerRepository;
$this->activationCustomerRepository = $activationCustomerRepository;
}
/**
* @param NotCustomer $notCustomer
* @param string $activationCode
*
* @return CustomerInterface
*/
public function temporaryRegister(NotCustomer $notCustomer, $activationCode): CustomerInterface
{
$this->activationCustomerRepository->store([
'name' => $notCustomer->name,
'email' => $notCustomer->email,
'password' => $notCustomer->password,
'confirmation_token' => $activationCode,
]);
$temporaryCustomer = $this->customerRepository->store([
'name' => $notCustomer->name,
'email' => $notCustomer->email,
'password' => $notCustomer->password,
'status' => Customer::STATUS_TEMPORARY_CUSTOMER,
]);
return $temporaryCustomer;
}
}
コメント