Registration.php 5.67 KB
<?php

namespace FootyRoom\Services\Registration;

use FootyRoom\User\User;
use EmailChecker\EmailChecker;
use FootyRoom\Core\CoreException;
use EmailChecker\Adapter\ArrayAdapter;
use FootyRoom\Repositories\IUserRepository;
use Illuminate\Contracts\Events\Dispatcher;
use FootyRoom\App\Registration\ReservedUsernames;
use FootyRoom\Services\Registration\EmailValidator;
use FootyRoom\Services\Registration\ActivationKeyMailer;

class Registration
{
    protected $userId;
    protected $username;
    protected $email;
    protected $password;
    protected $passwordHash;
    protected $nationalTeam;
    protected $clubTeam;
    protected $dob;
    protected $email_invalid;
    protected $email_exists;
    protected $username_valid;
    protected $password_valid;
    protected $registered;
    protected $activationKey;

    /**
     * @var array
     */
    public $errors = [];

    /**
     * @var \FootyRoom\Repositories\UserRepository
     */
    protected $userRepo;

    /**
     * @var \FootyRoom\Services\Registration\ActivationKeyMailer
     */
    protected $activationKeyMailer;

    /**
     * @var \Illuminate\Contracts\Events\Dispatcher;
     */
    protected $events;

    /**
     * Constructor.
     *
     * @param array $userData
     * @param IUserRepository $userRepo
     * @param ActivationKeyMailer $activationKeyMailer
     * @param \Illuminate\Contracts\Events\Dispatcher $events
     */
    public function __construct(
        array $userData,
        IUserRepository $userRepo,
        ActivationKeyMailer $activationKeyMailer,
        Dispatcher $events
    ) {
        $this->userRepo = $userRepo;
        $this->activationKeyMailer = $activationKeyMailer;
        $this->events = $events;

        $this->init($userData);
    }

    protected function init($userData)
    {
        $this->userData = $userData;

        $this->userId        = (int) @$userData['userId'];
        $this->username      = @$userData['username'];
        $this->email         = @$userData['email'];
        $this->password      = @$userData['password'];
        $this->passwordHash  = md5($this->password);
        $this->activationKey = @$userData['activationKey'];
        $this->fullname      = @$userData['fullName'];
        $this->newsletterConsent = @$userData['newsletterConsent'];

        $this->clubTeam      = @$userData['clubTeam'];
        $this->nationalTeam  = @$userData['nationalTeam'];

        if (isset($userData['status'])) {
            $this->status = $userData['status'];
        } else {
            $this->status = 'activation';
        }
    }

    /**
     * Input validation.
     */
    public function validate(): bool
    {
        // Check if email adress is of valid pattern.
        if (!preg_match('/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+$/', $this->email)) {
            $this->errors['email'][] = 'pattern';
        }

        // Check email is not a disposable one.
        $emailChecker = new EmailChecker(
            new ArrayAdapter(
                require(__DIR__.'/../../../../config/throwaway-domains.php')
            )
        );

        if (!$emailChecker->isValid($this->email)) {
            $this->errors['email'][] = 'disposable';
        }

        // Check if email already registered.
        if ($this->userRepo->findByEmail($this->email)) {
            $this->errors['email'][] = 'available';
        }

        // Username pattern check.
        if (!preg_match('/^[a-zA-Z0-9_]{6,20}$/', $this->username)) {
            $this->errors['username'][] = 'pattern';
        }

        // Check if username already registered and Forbidden username check
        if ($this->userRepo->findByUsername($this->username) || ReservedUsernames::isReserved($this->username)) {
            $this->errors['username'][] = 'available';
        }

        // Password pattern check.
        if (strlen($this->password) < 6) {
            $this->errors['password'][] = 'minlength';
        }

        if (count($this->errors) > 0) {
            return false;
        } else {
            return true;
        }
    }

    public function register()
    {
        $date_registered = date('Y-m-d');

        $user = new User([
            'username' => $this->username,
            'email' => $this->email,
            'password' => $this->passwordHash,
            'club_team' => $this->clubTeam,
            'national_team' => $this->nationalTeam,
            'date_registered' => $date_registered,
            'status' => $this->status,
        ]);

        $this->userId = $this->userRepo->create($user);

        if (!$this->userId) {
            throw new CoreException('Some unexpected error happened while trying to register you. Please try again. If error persists please report to us. Error: #1.');
        }

        // Subscribe user to newsletter if her email is not a bounce risk
        // and she consented to receiving it during registration.
        if (!EmailValidator::isBounceRisk($this->email) && $this->newsletterConsent) {
            $this->userRepo->setDigestSubscription($this->userId, true);
        }

        $user->register($this->userId);

        foreach ($user->releaseEvents() as $event) {
            $this->events->fire($event);
        }

        if ($this->status === 'activation') {
            $this->setupActivationKey();
        }
    }

    protected function setupActivationKey()
    {
        $this->activationKey = md5(uniqid(rand(), true));

        $this->userRepo->setActivationKey($this->userId, $this->activationKey);

        $this->sendActivationEmail();
    }

    public function sendActivationEmail()
    {
        $this->activationKeyMailer->send(
            $this->userId,
            $this->username,
            $this->email,
            $this->activationKey
        );
    }
}