招待会員・仮会員

マイグレーション

    /**
     * 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;
    }
}

コメント

タイトルとURLをコピーしました