Skip to content

Sample Registration Setup

Alexandre Lemaire edited this page Dec 14, 2016 · 1 revision

I've been asked a few times "What do your Registration controllers look like?". Here's a sample setup from a working project; Controller, Form, and Form Factory.

Controller

use Application\Entity\User;
use CirclicalUser\Service\AccessService;
use CirclicalUserUI\Form\UserForm;
use CirclicalUser\Mapper\UserMapper;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\JsonModel;
use CirclicalUser\Mapper\UserAtomMapper;
use Zend\View\Model\ViewModel;
use Application\Service\EmailService;

class RegisterController extends AbstractActionController
{

    private $userMapper;

    private $accessService;

    private $formElementManager;

    private $emailService;

    public function __construct($formElementManager, AccessService $accessService, UserMapper $userMapper, EmailService $emailService)
    {
        $this->accessService = $accessService;
        $this->formElementManager = $formElementManager;
        $this->userMapper = $userMapper;
        $this->emailService = $emailService;
    }

    public function indexAction()
    {
        $viewModel = new ViewModel();
        $user = $this->auth()->getIdentity();

        if ($user) {
            $this->redirect()->toUrl("/dashboard/");
        } else {
            $form = $this->formElementManager->get(UserForm::class, ['captcha' => true, 'country' => 'US']);
            $viewModel->setVariable('form', $form);
        }

        return $viewModel;
    }

    public function submitAction()
    {
        return $this->json()->wrap(function () {
            $request = $this->getRequest();

            if (!$request->isPost()) {
                throw new \Exception("What just happened there Jimmy!");
            }

            $post = $this->params()->fromPost();
            $form = $this->formElementManager->get(UserForm::class, ['captcha' => true]);
            $form->setData($post);

            if ($form->isValid()) {
                $user = $form->getObject();
                $user->setTimeRegistered(new \DateTime("now"));
                $this->userMapper->save($user);
                $this->accessService->setUser($user);
                $this->accessService->addRoleByName('user');

                $this->auth()->create($user, $user->getEmail(), $form->get('password')->getValue());

                $this->emailService->sendVerificationEmail($user);

                return [
                    'success' => true,
                    'user_id' => $user->getId(),
                ];
            } else {
                return [
                    'success' => false,
                    'message' => "Sorry, we weren't able to make it happen. Check the form for errors.",
                    'form_errors' => $form->getMessages(),
                ];
            }
        });
    }
}

Form

use Zend\Captcha;
use Zend\Form\Element\Password;
use Zend\Form\Element\Text;
use Zend\Form\Form;
use Zend\Form\Element\Hidden;
use Zend\Form\Element\Email;
use CirclicalRecaptcha\Form\Element\Recaptcha;


class UserForm extends Form
{
    private $countries;
    private $states;
    private $captcha;
    private $editOnly;

    public function __construct($countries = [], $states = [], $options = [])
    {
        $this->countries = $countries;
        $this->states = $states;
        $this->captcha = isset($options['captcha']) && $options['captcha'];
        $this->editOnly = isset($options['edit_only']) && $options['edit_only'];

        parent::__construct('user', []);
    }


    public function init()
    {

        $this->add([
            'name' => 'email',
            'type' => Email::class,
            'attributes' => [
                'maxlength' => 254,
                'id' => 'email-input',
                'placeholder' => _('Email'),
            ],
        ]);

        if (!$this->editOnly) {
            $this->add([
                'name' => 'email_confirm',
                'type' => Email::class,
                'attributes' => [
                    'maxlength' => 254,
                    'id' => 'confirm-email-input',
                    'placeholder' => _('Confirm Email'),
                ],
            ]);

            $this->add([
                'name' => 'password',
                'type' => Password::class,
                'attributes' => [
                    'maxlength' => 24,
                    'autocomplete' => 'off',
                    'class' => 'mdl-textfield__input',
                    'id' => 'password-input',
                    'placeholder' => _('Password'),
                ],
            ]);
        }

        $this->add([
            'name' => 'first_name',
            'type' => Text::class,
            'attributes' => [
                'maxlength' => 64,
                'id' => 'first-name-input',
                'placeholder' => _('First Name'),
            ],
        ]);

        $this->add([
            'name' => 'last_name',
            'type' => Text::class,
            'attributes' => [
                'maxlength' => 64,
                'id' => 'last-name-input',
                'placeholder' => _('Last Name'),
            ],
        ]);

        if ($this->captcha) {
            $this->add([
                'name' => 'g-recaptcha-response',
                'type' => Recaptcha::class,
                'options' => [
                    'label' => _("Please complete the challenge below"),
                    'label_attributes' => [
                        'class' => 'captcha-label',
                    ],
                ],
                'attributes' => [
                    'id' => 'captcha-area',
                ],
            ]);
        }

        $this->add([
            'name' => 'axis',
            'type' => Hidden::class,
        ]);
    }

}

Form Factory

use Application\Entity\User;
use CirclicalUserUI\Form\UserForm;
use CirclicalUserUI\InputFilter\UserInputFilter;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\MutableCreationOptionsInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject;
use Phine\Country\Loader\Loader;

/**
 * Class UserFormFactory
 *
 * @package CirclicalUser\Factory\Form
 */
class UserFormFactory implements FactoryInterface, MutableCreationOptionsInterface
{

    /**
     * @var array
     */
    protected $options;

    /**
     * Set creation options
     *
     * @param  array $options
     *
     * @return void
     */
    public function setCreationOptions(array $options)
    {
        $this->options = $options;
    }

    /**
     * {@inheritdoc}
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $serviceManager = $serviceLocator->getServiceLocator();
        $countryLoader = new Loader();
        $countries = $countryLoader->loadCountries();
        $countries = array_map(function ($country) {
            return $country->getShortName();
        }, $countries);

        $states = [];
        if (isset($this->options['country'])) {
            $subdivisions = $countryLoader->loadSubdivisions($this->options['country']);
            foreach ($subdivisions as $s => $d) {
                list(, $code) = explode('-', $s, 2);
                $states[$code] = $d->getName();
            }
        }

        $form = new UserForm($countries, $states, $this->options);
        $form->setInputFilter($serviceManager->get('InputFilterManager')->get(UserInputFilter::class, $this->options));
        $form->setObject(new User());
        $form->setHydrator(new DoctrineObject($serviceManager->get('doctrine.entitymanager.orm_default'), false));

        return $form;
    }

}
Clone this wiki locally