Skip to content

Instantly share code, notes, and snippets.

@vojtech-dobes
Created August 3, 2011 15:39
Show Gist options
  • Save vojtech-dobes/1122930 to your computer and use it in GitHub Desktop.
Save vojtech-dobes/1122930 to your computer and use it in GitHub Desktop.
Login Form as service (behavior via event callbacks)
<?php
namespace Clevispace;
use Nette\DI;
class ComponentFactory extends DI\Container
{
/**
* @param \Nette\DI\Container
*/
public function __construct(DI\Container $context)
{
$this->context = $context;
}
public function createLoginForm()
{
return new Forms\LoginForm($this->context->user);
}
}
<?php
namespace Clevispace\Forms;
use InvalidArgumentException;
use Nette\ComponentModel\IContainer;
use Nette\Application\UI;
use Nette\Http\User;
use Nette\Security\AuthenticationException;
/**
* Authentication form
*
* Register as service:
* <code>
* common:
* services:
* components:
* class: Clevispace\ComponentFactory
* arguments: [@container]
* </code>
*
* And prepare as component in presenter:
* <code>
* protected function createComponentLoginForm()
* {
* $form = $this->context->components->createLoginForm();
* $form->onAuthenticationSuccess[] = callback( ... );
* $form->onAuthenticationFail[] = callback( ... );
* return $form;
* }
* </code>
*
* @author Vojtech Dobes
*/
class LoginForm extends UI\Form
{
/** @var \Nette\Http\User */
private $user;
/** @var array callback() */
public $onAuthenticationSuccess;
/** @var array callback(AuthenticationException $e, LoginForm $form) */
public $onAuthenticationFail;
/** @var string */
private $usernameField = 'username';
/** @var string */
private $passwordField = 'password';
/**
* @param \Nette\Http\User
* @param array
*/
public function __construct(User $user, $params = array())
{
parent::__construct();
$this->user = $user;
if (count($params) > 2 || (count($params) > 0 && (!isset($params['usernameField']) || !isset($params['passwordField'])))) {
throw new InvalidArgumentException("Provided params for LoginForm can be only 'usernameField' or 'passwordField'.");
} else {
if (isset($params['usernameField'])) {
$this->usernameField = $params['usernameField'];
}
if (isset($params['passwordField'])) {
$this->passwordField = $params['passwordField'];
}
}
}
/**
* Builds form
*
* @param \Nette\Application\UI\Presenter
*/
public function attached($parent)
{
if (!$parent instanceof UI\Presenter) {
throw InvalidStateException("LoginForm must be attached to Presenter.");
}
parent::attached($parent);
$this->addText($this->usernameField, 'Username')
->addRule($this::FILLED, 'Please fill %label.');
$this->addPassword($this->passwordField, 'Password')
->addRule($this::FILLED, 'Please fill %label.');
$this->addSubmit('send', 'Login');
$this->onSuccess[] = array($this, 'callOnSuccess');
}
/**
* Sets name of username field
*
* @param string
* @return provides a fluent interface
*/
public function setUsernameField($field)
{
$this->usernameField = $field;
}
/**
* Sets name of password field
*
* @param string
* @return provides a fluent interface
*/
public function setPasswordField($field)
{
$this->passwordField = $field;
return $this;
}
/**
* @param \Clevispace\Forms\LoginForm
*/
public function callOnSuccess(LoginForm $form)
{
$values = $this->getValues();
try {
$this->user->login($values[$this->usernameField], $values[$this->passwordField]);
$this->onAuthenticationSuccess($form);
} catch (AuthenticationException $e) {
if (!count($this->onAuthenticationFail)) {
throw $e;
} else {
$this->onAuthenticationFail($e, $this);
}
}
}
}
@vojtech-dobes
Copy link
Author

Form as a service is bullshit... better create instance in Presenter or prepare some factory class / inherit DIContainer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment