Merge branch 'oauth-registration' into dev
This commit is contained in:
commit
fe542461f7
17 changed files with 488 additions and 275 deletions
|
|
@ -33,6 +33,7 @@
|
|||
@import "components/button";
|
||||
@import "components/badge";
|
||||
@import "components/section";
|
||||
@import "components/spacer";
|
||||
@import "components/pagination";
|
||||
@import "components/blankslate";
|
||||
@import "components/request-item";
|
||||
|
|
@ -42,6 +43,7 @@
|
|||
@import "views/landingpage";
|
||||
@import "views/about";
|
||||
@import "views/login";
|
||||
@import "views/register";
|
||||
|
||||
// Plugins
|
||||
@import "vendor/ionicons/ionicons";
|
||||
|
|
|
|||
6
app/assets/less/components/spacer.less
Normal file
6
app/assets/less/components/spacer.less
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.spacer {
|
||||
display: block;
|
||||
border-bottom: 1px solid @gray-light;
|
||||
margin: @spacer-margin;
|
||||
}
|
||||
|
|
@ -154,6 +154,13 @@
|
|||
@blankslate-spacing: 25px 10px;
|
||||
@blankslate-spacing-sm: 15px 5px;
|
||||
|
||||
// ----------------------------------
|
||||
// Spacer
|
||||
// ----------------------------------
|
||||
|
||||
@spacer-color: @gray-light;
|
||||
@spacer-margin: 1em 0;
|
||||
|
||||
// ----------------------------------
|
||||
// Pagination
|
||||
// ----------------------------------
|
||||
|
|
|
|||
6
app/assets/less/views/register.less
Normal file
6
app/assets/less/views/register.less
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.register {
|
||||
&:extend(.section all);
|
||||
.center-block();
|
||||
width: 60%;
|
||||
}
|
||||
|
|
@ -43,6 +43,9 @@ router:
|
|||
oauth-disconnect-confirm:
|
||||
pattern: '/oauth/{provider:([a-z]+)}/disconnect/{confirm}'
|
||||
path: 'User::oauthdisconnect'
|
||||
user-register:
|
||||
pattern: '/register'
|
||||
path: Auth::register
|
||||
user-settings:
|
||||
pattern: '/settings'
|
||||
path:
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\ControllerBase;
|
||||
use App\Controller\ControllerBase,
|
||||
App\Model\Data\User,
|
||||
App\Form\Login as LoginForm,
|
||||
App\Form\Registration as RegistrationForm;
|
||||
|
||||
use App\Form\Login as LoginForm;
|
||||
use Httpcb\OAuth\UserData\UserDataInterface;
|
||||
|
||||
class AuthController extends ControllerBase
|
||||
{
|
||||
|
|
@ -78,17 +81,21 @@ class AuthController extends ControllerBase
|
|||
else {
|
||||
$result = $this->auth->loginOauth($data);
|
||||
|
||||
// There was an error when creating the account
|
||||
if (is_array($result)) {
|
||||
$msg = '';
|
||||
foreach ($result as $message) {
|
||||
$msg .= '<li>' . $message->getMessage() . '</li>';
|
||||
if ($result === false) {
|
||||
|
||||
if (User::findFirstByEmail($data->getEmail())) {
|
||||
$this->flash->error('The email address is already in use.');
|
||||
$this->response->redirect('/login');
|
||||
return;
|
||||
}
|
||||
$this->flash->message('error', "Failed to create account: <ul>{$msg}</ul>");
|
||||
$this->response->redirect('/login');
|
||||
} else {
|
||||
$this->response->redirect('/');
|
||||
|
||||
$this->session->set('auth:register:data', $data);
|
||||
$this->response->redirect(['for' => 'user-register']);
|
||||
return;
|
||||
}
|
||||
|
||||
// User is logged in.
|
||||
$this->response->redirect('/');
|
||||
}
|
||||
} catch(\Exception $e) {
|
||||
$this->flash->message('error', 'Failed to authenticate.');
|
||||
|
|
@ -106,6 +113,42 @@ class AuthController extends ControllerBase
|
|||
}
|
||||
}
|
||||
|
||||
public function registerAction()
|
||||
{
|
||||
$data = $this->session->get('auth:register:data');
|
||||
if (!($data instanceof UserDataInterface)) {
|
||||
$this->response->redirect('/');
|
||||
return;
|
||||
}
|
||||
|
||||
$user = new User();
|
||||
$user->assign($data->toArray(), null,
|
||||
[ 'email', 'username', 'firstname', 'lastname' ]);
|
||||
|
||||
$form = new RegistrationForm($user);
|
||||
|
||||
if ($this->request->isPost()) {
|
||||
|
||||
$formData = $this->request->getPost();
|
||||
if ($form->isValid($formData)) {
|
||||
$user->setOAuthId($data->getProvider(), $data->getId());
|
||||
if ($user->save()) {
|
||||
$this->auth->systemLogin($user);
|
||||
$this->flash->success('User successfully created. Now add your first callback!');
|
||||
$this->response->redirect('/callback/new');
|
||||
} else {
|
||||
$this->flash->error('Could not create user');
|
||||
}
|
||||
}
|
||||
$form->setEntity($formData);
|
||||
} else {
|
||||
$form->isValid($data->toArray());
|
||||
}
|
||||
|
||||
$this->view->provider = $data->getProvider();
|
||||
$this->view->form = $form;
|
||||
}
|
||||
|
||||
public function logoutAction()
|
||||
{
|
||||
$this->auth->clearIdentity();
|
||||
|
|
|
|||
107
app/forms/Registration.php
Normal file
107
app/forms/Registration.php
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
/**
|
||||
* Models
|
||||
*/
|
||||
use App\Model\Data\User;
|
||||
|
||||
/**
|
||||
* Phalcon Form
|
||||
*/
|
||||
use Httpcb\Form as FormBase,
|
||||
Phalcon\Forms\Element as FormElement;
|
||||
|
||||
/**
|
||||
* Element types
|
||||
*/
|
||||
use Phalcon\Forms\Element\Text,
|
||||
Phalcon\Forms\Element\Password,
|
||||
Phalcon\Forms\Element\Submit;
|
||||
|
||||
/**
|
||||
* Validators
|
||||
*/
|
||||
use Phalcon\Validation,
|
||||
Phalcon\Validation\Validator\Callback as CallbackValidator,
|
||||
Phalcon\Validation\Validator\Alnum as AlnumValidator,
|
||||
Phalcon\Validation\Validator\Email as EmailValidator,
|
||||
Phalcon\Validation\Validator\StringLength as StringLengthValidator,
|
||||
Phalcon\Validation\Validator\Identical as IdenticalValidator,
|
||||
Httpcb\Validation\Validator\Alpha as AlphaValidator;
|
||||
|
||||
|
||||
class Registration extends FormBase
|
||||
{
|
||||
public function initialize(User $user)
|
||||
{
|
||||
$this->setValidation(new Validation());
|
||||
|
||||
// Username
|
||||
$username = new Text('username', array(
|
||||
'class' => 'form-control',
|
||||
'placeholder' => 'Username',
|
||||
));
|
||||
|
||||
$username->setLabel('Username');
|
||||
|
||||
$username->addValidators([
|
||||
new AlnumValidator([
|
||||
'message' => 'Username must contain only letters and numbers.'
|
||||
]),
|
||||
new StringLengthValidator([
|
||||
'min' => 2,
|
||||
'messageMinimum' => 'Username must be at least :min characters long.',
|
||||
]),
|
||||
new CallbackValidator([
|
||||
'callback' => function($data) { return User::findFirstByUsername($data['username']) === false; },
|
||||
'message' => 'The username already exists.',
|
||||
'attribute' => 'username',
|
||||
])
|
||||
]);
|
||||
|
||||
$this->add($username);
|
||||
|
||||
// Names
|
||||
foreach([ 'first-name' => 'Firstname', 'last-name' => 'Lastname' ] as $id => $label) {
|
||||
|
||||
$name = new Text($id, array(
|
||||
'class' => 'form-control',
|
||||
'placeholder' => $label,
|
||||
));
|
||||
|
||||
$name->setLabel($label);
|
||||
$name->addValidator(new AlphaValidator([
|
||||
'allowSpace' => false,
|
||||
'allowEmpty' => true,
|
||||
]));
|
||||
|
||||
$this->add($name);
|
||||
}
|
||||
|
||||
// Email
|
||||
$email = new Text('email', array(
|
||||
'class' => 'form-control',
|
||||
'placeholder' => 'Email',
|
||||
'readonly' => '',
|
||||
));
|
||||
|
||||
$email->addValidators([
|
||||
new IdenticalValidator([
|
||||
'accepted' => $user->getEmail(),
|
||||
]),
|
||||
new CallbackValidator([
|
||||
'callback' => function($data) { return User::findFirstByEmail($data['email']) === false; },
|
||||
'message' => 'This email already exist.',
|
||||
])
|
||||
]);
|
||||
|
||||
$email->setLabel('Email');
|
||||
$this->add($email);
|
||||
|
||||
// Submit
|
||||
$submit = new Submit('submit', array('class' => 'button button-success', 'value' => 'Register'));
|
||||
$this->add($submit);
|
||||
}
|
||||
}
|
||||
|
|
@ -44,26 +44,15 @@ class Auth extends Component
|
|||
* Login using OAuth
|
||||
*
|
||||
* @param UserDataInterface $data
|
||||
* @return bool|\Phalcon\Mvc\Model\MessageInterface[]
|
||||
* @return bool
|
||||
*/
|
||||
public function loginOauth(UserDataInterface $data)
|
||||
{
|
||||
$user = User::findFirstByOAuthID($data);
|
||||
|
||||
// Did not find any user.
|
||||
if (!$user) {
|
||||
// Did not find any user. create him.
|
||||
$user = User::createFromOAuthData($data);
|
||||
|
||||
if ($user->save() === false) {
|
||||
return $user->getMessages();
|
||||
}
|
||||
}
|
||||
// Here we activate the user.
|
||||
// As for OAuth we perform registration if the user does not exist.
|
||||
// We should therefore activate deleted accounts.
|
||||
else if ($user->Status == User::STATUS_DELETED) {
|
||||
$user->Status = User::STATUS_ACTIVE;
|
||||
$user->save();
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setIdentity($user->getId());
|
||||
|
|
@ -74,6 +63,17 @@ class Auth extends Component
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The system logs in a user (without credentials).
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function systemLogin(User $user)
|
||||
{
|
||||
$this->setIdentity($user->getId());
|
||||
$this->eventsManager->fire('auth:onLogin', $this, 'System');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $identity
|
||||
* @return Auth
|
||||
|
|
|
|||
70
app/library/Form.php
Normal file
70
app/library/Form.php
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace Httpcb;
|
||||
|
||||
use Phalcon\Forms\Form as FormBase,
|
||||
Phalcon\Forms\Element as FormElement;
|
||||
|
||||
class Form extends FormBase
|
||||
{
|
||||
public function renderDecorated($name, $opt = [])
|
||||
{
|
||||
$options = [
|
||||
'label-class' => 'control-label',
|
||||
'class' => [ 'col-sm-10' ],
|
||||
'message' => ''
|
||||
];
|
||||
|
||||
$ele = $this->get($name);
|
||||
|
||||
if (isset($opt['label-length'])) {
|
||||
$length = (int) $opt['label-length'];
|
||||
} else {
|
||||
$length = 2;
|
||||
}
|
||||
$options['label-class'] .= ' col-sm-' . $length;
|
||||
|
||||
if (isset($opt['length'])) {
|
||||
|
||||
$len = $opt['length'];
|
||||
|
||||
if ($len === 'full') {
|
||||
$options['class'] = [];
|
||||
} else {
|
||||
$options['class'] = [ 'col-sm-' . $len ];
|
||||
}
|
||||
|
||||
unset($opt['length']);
|
||||
}
|
||||
|
||||
if ($ele->hasMessages()) {
|
||||
$options['class'][] = 'has-error';
|
||||
$options['message'] = $ele->getMessages()->current();
|
||||
}
|
||||
|
||||
return $this->_render($ele, $options);
|
||||
}
|
||||
|
||||
protected function _render(FormElement $ele, $opt)
|
||||
{
|
||||
$xhtml = '';
|
||||
|
||||
if (strlen($ele->getLabel()) > 0) {
|
||||
|
||||
$xhtml .= sprintf(
|
||||
'<label class="%s" for="%s">%s</label>',
|
||||
$opt['label-class'], $ele->getName(), $ele->getLabel());
|
||||
}
|
||||
|
||||
$xhtml .= '<div class="' . implode(' ', $opt['class']) . '">'
|
||||
. $ele->render();
|
||||
|
||||
if (strlen($opt['message']) > 0) {
|
||||
$xhtml .= '<span class="help-block">' . $opt['message'] . '</span>';
|
||||
}
|
||||
|
||||
$xhtml .= '</div>';
|
||||
|
||||
return $xhtml;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,67 +2,18 @@
|
|||
|
||||
namespace Httpcb\OAuth\UserData;
|
||||
|
||||
class Github implements UserDataInterface
|
||||
class Github extends UserData
|
||||
{
|
||||
protected $data;
|
||||
protected $_provider = 'Github';
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProvider()
|
||||
{
|
||||
return 'Github';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return (int) $this->data['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->data['login'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->data['name'];
|
||||
}
|
||||
|
||||
public function getFirstname()
|
||||
{
|
||||
$pos = strpos($this->getName(), ' ');
|
||||
return $pos !== false ? substr($this->getName(), 0, $pos) : $this->getName();
|
||||
}
|
||||
|
||||
public function getLastname()
|
||||
{
|
||||
$pos = strpos($this->getName(), ' ');
|
||||
return $pos !== false ? substr($this->getName(), $pos+1) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->data['email'];
|
||||
$this->_id = $data['id'];
|
||||
$this->_username = $data['login'];
|
||||
$this->_name = $data['name'];
|
||||
$this->_email = $data['email'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,72 +2,18 @@
|
|||
|
||||
namespace Httpcb\OAuth\UserData;
|
||||
|
||||
class Gitlab implements UserDataInterface
|
||||
class Gitlab extends UserData
|
||||
{
|
||||
protected $data;
|
||||
protected $_provider = 'Gitlab';
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProvider()
|
||||
{
|
||||
return 'Gitlab';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return (int) $this->data['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->data['username'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->data['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFirstname()
|
||||
{
|
||||
$pos = strpos($this->getName(), ' ');
|
||||
return $pos !== false ? substr($this->getName(), 0, $pos) : $this->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getLastname()
|
||||
{
|
||||
$pos = strpos($this->getName(), ' ');
|
||||
return $pos !== false ? substr($this->getName(), $pos+1) : null;
|
||||
}
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->data['email'];
|
||||
$this->_id = $data['id'];
|
||||
$this->_username = $data['username'];
|
||||
$this->_name = $data['name'];
|
||||
$this->_email = $data['email'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,76 +2,20 @@
|
|||
|
||||
namespace Httpcb\OAuth\UserData;
|
||||
|
||||
class Google implements UserDataInterface
|
||||
class Google extends UserData
|
||||
{
|
||||
protected $data;
|
||||
protected $_provider = 'Google';
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
$this->_id = $data['id'];
|
||||
$this->_name = $data['displayName'];
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProvider()
|
||||
{
|
||||
return 'Google';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return (int) $this->data['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->data['displayName'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFirstname()
|
||||
{
|
||||
$pos = strpos($this->getName(), ' ');
|
||||
return $pos !== false ? substr($this->getName(), 0, $pos) : $this->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getLastname()
|
||||
{
|
||||
$pos = strpos($this->getName(), ' ');
|
||||
return $pos !== false ? substr($this->getName(), $pos+1) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
if (isset($this->data['emails'][0]['value'])) {
|
||||
return $this->data['emails'][0]['value'];
|
||||
if (isset($data['emails'][0]['value'])) {
|
||||
$this->_email = $data['emails'][0]['value'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,78 +2,18 @@
|
|||
|
||||
namespace Httpcb\OAuth\UserData;
|
||||
|
||||
class LinkedIn implements UserDataInterface
|
||||
class LinkedIn extends UserData
|
||||
{
|
||||
protected $data;
|
||||
protected $_provider = 'LinkedIn';
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProvider()
|
||||
{
|
||||
return 'LinkedIn';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->data['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
$name = '';
|
||||
if ($this->getFirstname() !== null) {
|
||||
$name = $this->getFirstname();
|
||||
}
|
||||
if ($this->getLastname() !== null) {
|
||||
$name .= ' ' . $this->getLastname();
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFirstname()
|
||||
{
|
||||
return isset($this->data['firstName']) ? $this->data['firstName'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getLastname()
|
||||
{
|
||||
return isset($this->data['lastName']) ? $this->data['lastName'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->data['emailAddress'];
|
||||
$this->_id = $data['id'];
|
||||
$this->_firstname = isset($data['firstName']) ? $data['firstName'] : null;
|
||||
$this->_lastname = isset($data['lastName']) ? $data['lastName'] : null;
|
||||
$this->_email = $data['emailAddress'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
104
app/library/OAuth/UserData/UserData.php
Normal file
104
app/library/OAuth/UserData/UserData.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace Httpcb\OAuth\UserData;
|
||||
|
||||
abstract class UserData implements UserDataInterface
|
||||
{
|
||||
protected $_provider = null;
|
||||
|
||||
protected $_id = null;
|
||||
|
||||
protected $_username = null;
|
||||
|
||||
protected $_email = null;
|
||||
|
||||
protected $_name = null;
|
||||
|
||||
protected $_firstname = null;
|
||||
|
||||
protected $_lastname = null;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getProvider()
|
||||
{
|
||||
return $this->_provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->_username;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
if ($this->_name === null && strlen($this->_firstname) > 0) {
|
||||
$name = $this->_firstname;
|
||||
if (strlen($this->_lastname) > 0) {
|
||||
$name .= ' ' . $this->_lastname;
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFirstname()
|
||||
{
|
||||
if ($this->_firstname === null) {
|
||||
$pos = strpos($this->getName(), ' ');
|
||||
return $pos !== false ? substr($this->getName(), 0, $pos) : $this->getName();
|
||||
|
||||
}
|
||||
return $this->_firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getLastname()
|
||||
{
|
||||
if ($this->_lastname === null) {
|
||||
$pos = strpos($this->getName(), ' ');
|
||||
return $pos !== false ? substr($this->getName(), $pos+1) : null;
|
||||
}
|
||||
return $this->_lastname;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->_email;
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
$data = [];
|
||||
foreach(get_class_methods($this) as $method) {
|
||||
if (substr($method, 0, 3) == 'get') {
|
||||
$field = lcfirst(substr($method, 3));
|
||||
$data[$field] = $this->$method();
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
@ -54,4 +54,9 @@ interface UserDataInterface
|
|||
* @return string
|
||||
*/
|
||||
public function getEmail();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace App\Model\Data;
|
|||
|
||||
use Phalcon\Mvc\Model,
|
||||
Phalcon\Validation,
|
||||
Phalcon\Validation\Validator\Uniqueness,
|
||||
Phalcon\Validation\Validator\Callback as CallbackValidator,
|
||||
InvalidArgumentException,
|
||||
Httpcb\OAuth\UserData\UserDataInterface;
|
||||
|
||||
|
|
@ -52,8 +52,14 @@ class User extends Model
|
|||
// Validation
|
||||
$validator = new Validation();
|
||||
|
||||
$validator->add('username', new Uniqueness(['message' => 'The username already exists.']));
|
||||
$validator->add('email', new Uniqueness(['message' => 'The email address already exists.']));
|
||||
$validator->add('username', new CallbackValidator([
|
||||
'callback' => function() { return $this->findFirstByUsername($this->getUsername()) === false; },
|
||||
'message' => 'The username already exists.'
|
||||
]));
|
||||
$validator->add('email', new CallbackValidator([
|
||||
'callback' => function() { return $this->findFirstByEmail($this->getEmail()) === false; },
|
||||
'message' => 'The email address already exists.'
|
||||
]));
|
||||
|
||||
return $this->validate($validator);
|
||||
}
|
||||
|
|
@ -295,6 +301,20 @@ class User extends Model
|
|||
return $this->linkedin_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $provider
|
||||
* @param string $id
|
||||
* @return $this
|
||||
*/
|
||||
public function setOAuthId($provider, $id)
|
||||
{
|
||||
$method = 'set' . ucfirst($provider) . 'Id';
|
||||
if (method_exists($this, $method)) {
|
||||
$this->$method($id);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return User
|
||||
|
|
@ -339,8 +359,24 @@ class User extends Model
|
|||
static public function findFirstByUsernameOrEmail($value)
|
||||
{
|
||||
return self::findFirst([
|
||||
"(email = :v: OR username = :v:) AND status = :s:",
|
||||
"bind" => [ 'v' => $value, 's' => self::STATUS_ACTIVE ]
|
||||
"(email = :v: OR username = :v:) AND status != :s:",
|
||||
"bind" => [ 'v' => $value, 's' => self::STATUS_DELETED ]
|
||||
]);
|
||||
}
|
||||
|
||||
static public function findFirstByEmail($email)
|
||||
{
|
||||
return self::findFirst([
|
||||
"email = :email: AND status != :s:",
|
||||
"bind" => [ 'email' => $email, 's' => self::STATUS_DELETED ]
|
||||
]);
|
||||
}
|
||||
|
||||
static public function findFirstByUsername($username)
|
||||
{
|
||||
return self::findFirst([
|
||||
"username = :username: AND status != :s:",
|
||||
"bind" => [ 'username' => $username, 's' => self::STATUS_DELETED ]
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -349,8 +385,8 @@ class User extends Model
|
|||
$column = strtolower($oauth->getProvider());
|
||||
|
||||
return self::findFirst([
|
||||
"{$column}_id = :id:",
|
||||
"bind" => [ 'id' => $oauth->getId() ]
|
||||
"{$column}_id = :id: AND status != :s:",
|
||||
"bind" => [ 'id' => $oauth->getId(), 's' => self::STATUS_DELETED ]
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
43
app/views/auth/register.volt
Normal file
43
app/views/auth/register.volt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
|
||||
<div class="register">
|
||||
|
||||
<h2>Account registration</h2>
|
||||
|
||||
<div class="alert alert-info alert-dismissible" role="alert">
|
||||
|
||||
<strong>Information!</strong>
|
||||
|
||||
<p>
|
||||
The form is prepared with the information provided by <strong>{{ provider }}</strong>.
|
||||
Please check the information and make changes if necessary before continue.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<span class="spacer"></span>
|
||||
|
||||
<form class="form form-horizontal" method="post">
|
||||
|
||||
<div class="form-group">
|
||||
{{ form.renderDecorated('email') }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form.renderDecorated('username') }}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ form.renderDecorated('first-name', ['length': 4]) }}
|
||||
{{ form.renderDecorated('last-name', ['length': 4]) }}
|
||||
</div>
|
||||
|
||||
<span class="spacer"></span>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-xs-12 col-xs-offset-2">
|
||||
{{ form.render('submit') }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
Reference in a new issue