Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Command;
use FOS\UserBundle\Util\UserManipulator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
/**
* @author Antoine Hérault <antoine.herault@gmail.com>
*/
class ActivateUserCommand extends Command
{
protected static $defaultName = 'fos:user:activate';
private $userManipulator;
public function __construct(UserManipulator $userManipulator)
{
parent::__construct();
$this->userManipulator = $userManipulator;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('fos:user:activate')
->setDescription('Activate a user')
->setDefinition(array(
new InputArgument('username', InputArgument::REQUIRED, 'The username'),
))
->setHelp(<<<'EOT'
The <info>fos:user:activate</info> command activates a user (so they will be able to log in):
<info>php %command.full_name% matthieu</info>
EOT
);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$username = $input->getArgument('username');
$this->userManipulator->activate($username);
$output->writeln(sprintf('User "%s" has been activated.', $username));
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
if (!$input->getArgument('username')) {
$question = new Question('Please choose a username:');
$question->setValidator(function ($username) {
if (empty($username)) {
throw new \Exception('Username can not be empty');
}
return $username;
});
$answer = $this->getHelper('question')->ask($input, $output, $question);
$input->setArgument('username', $answer);
}
}
}

View File

@@ -0,0 +1,111 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Command;
use FOS\UserBundle\Util\UserManipulator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
class ChangePasswordCommand extends Command
{
protected static $defaultName = 'fos:user:change-password';
private $userManipulator;
public function __construct(UserManipulator $userManipulator)
{
parent::__construct();
$this->userManipulator = $userManipulator;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('fos:user:change-password')
->setDescription('Change the password of a user.')
->setDefinition(array(
new InputArgument('username', InputArgument::REQUIRED, 'The username'),
new InputArgument('password', InputArgument::REQUIRED, 'The password'),
))
->setHelp(<<<'EOT'
The <info>fos:user:change-password</info> command changes the password of a user:
<info>php %command.full_name% matthieu</info>
This interactive shell will first ask you for a password.
You can alternatively specify the password as a second argument:
<info>php %command.full_name% matthieu mypassword</info>
EOT
);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$username = $input->getArgument('username');
$password = $input->getArgument('password');
$this->userManipulator->changePassword($username, $password);
$output->writeln(sprintf('Changed password for user <comment>%s</comment>', $username));
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$questions = array();
if (!$input->getArgument('username')) {
$question = new Question('Please give the username:');
$question->setValidator(function ($username) {
if (empty($username)) {
throw new \Exception('Username can not be empty');
}
return $username;
});
$questions['username'] = $question;
}
if (!$input->getArgument('password')) {
$question = new Question('Please enter the new password:');
$question->setValidator(function ($password) {
if (empty($password)) {
throw new \Exception('Password can not be empty');
}
return $password;
});
$question->setHidden(true);
$questions['password'] = $question;
}
foreach ($questions as $name => $question) {
$answer = $this->getHelper('question')->ask($input, $output, $question);
$input->setArgument($name, $answer);
}
}
}

View File

@@ -0,0 +1,143 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Command;
use FOS\UserBundle\Util\UserManipulator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
/**
* @author Matthieu Bontemps <matthieu@knplabs.com>
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Luis Cordova <cordoval@gmail.com>
*/
class CreateUserCommand extends Command
{
protected static $defaultName = 'fos:user:create';
private $userManipulator;
public function __construct(UserManipulator $userManipulator)
{
parent::__construct();
$this->userManipulator = $userManipulator;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('fos:user:create')
->setDescription('Create a user.')
->setDefinition(array(
new InputArgument('username', InputArgument::REQUIRED, 'The username'),
new InputArgument('email', InputArgument::REQUIRED, 'The email'),
new InputArgument('password', InputArgument::REQUIRED, 'The password'),
new InputOption('super-admin', null, InputOption::VALUE_NONE, 'Set the user as super admin'),
new InputOption('inactive', null, InputOption::VALUE_NONE, 'Set the user as inactive'),
))
->setHelp(<<<'EOT'
The <info>fos:user:create</info> command creates a user:
<info>php %command.full_name% matthieu</info>
This interactive shell will ask you for an email and then a password.
You can alternatively specify the email and password as the second and third arguments:
<info>php %command.full_name% matthieu matthieu@example.com mypassword</info>
You can create a super admin via the super-admin flag:
<info>php %command.full_name% admin --super-admin</info>
You can create an inactive user (will not be able to log in):
<info>php %command.full_name% thibault --inactive</info>
EOT
);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$username = $input->getArgument('username');
$email = $input->getArgument('email');
$password = $input->getArgument('password');
$inactive = $input->getOption('inactive');
$superadmin = $input->getOption('super-admin');
$this->userManipulator->create($username, $password, $email, !$inactive, $superadmin);
$output->writeln(sprintf('Created user <comment>%s</comment>', $username));
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$questions = array();
if (!$input->getArgument('username')) {
$question = new Question('Please choose a username:');
$question->setValidator(function ($username) {
if (empty($username)) {
throw new \Exception('Username can not be empty');
}
return $username;
});
$questions['username'] = $question;
}
if (!$input->getArgument('email')) {
$question = new Question('Please choose an email:');
$question->setValidator(function ($email) {
if (empty($email)) {
throw new \Exception('Email can not be empty');
}
return $email;
});
$questions['email'] = $question;
}
if (!$input->getArgument('password')) {
$question = new Question('Please choose a password:');
$question->setValidator(function ($password) {
if (empty($password)) {
throw new \Exception('Password can not be empty');
}
return $password;
});
$question->setHidden(true);
$questions['password'] = $question;
}
foreach ($questions as $name => $question) {
$answer = $this->getHelper('question')->ask($input, $output, $question);
$input->setArgument($name, $answer);
}
}
}

View File

@@ -0,0 +1,87 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Command;
use FOS\UserBundle\Util\UserManipulator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
/**
* @author Antoine Hérault <antoine.herault@gmail.com>
*/
class DeactivateUserCommand extends Command
{
protected static $defaultName = 'fos:user:deactivate';
private $userManipulator;
public function __construct(UserManipulator $userManipulator)
{
parent::__construct();
$this->userManipulator = $userManipulator;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('fos:user:deactivate')
->setDescription('Deactivate a user')
->setDefinition(array(
new InputArgument('username', InputArgument::REQUIRED, 'The username'),
))
->setHelp(<<<'EOT'
The <info>fos:user:deactivate</info> command deactivates a user (will not be able to log in)
<info>php %command.full_name% matthieu</info>
EOT
);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$username = $input->getArgument('username');
$this->userManipulator->deactivate($username);
$output->writeln(sprintf('User "%s" has been deactivated.', $username));
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
if (!$input->getArgument('username')) {
$question = new Question('Please choose a username:');
$question->setValidator(function ($username) {
if (empty($username)) {
throw new \Exception('Username can not be empty');
}
return $username;
});
$answer = $this->getHelper('question')->ask($input, $output, $question);
$input->setArgument('username', $answer);
}
}
}

View File

@@ -0,0 +1,60 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Command;
use FOS\UserBundle\Util\UserManipulator;
use Symfony\Component\Console\Output\OutputInterface;
/**
* @author Antoine Hérault <antoine.herault@gmail.com>
* @author Lenar Lõhmus <lenar@city.ee>
*/
class DemoteUserCommand extends RoleCommand
{
protected static $defaultName = 'fos:user:demote';
/**
* {@inheritdoc}
*/
protected function configure()
{
parent::configure();
$this
->setName('fos:user:demote')
->setDescription('Demote a user by removing a role')
->setHelp(<<<'EOT'
The <info>fos:user:demote</info> command demotes a user by removing a role
<info>php %command.full_name% matthieu ROLE_CUSTOM</info>
<info>php %command.full_name% --super matthieu</info>
EOT
);
}
/**
* {@inheritdoc}
*/
protected function executeRoleCommand(UserManipulator $manipulator, OutputInterface $output, $username, $super, $role)
{
if ($super) {
$manipulator->demote($username);
$output->writeln(sprintf('User "%s" has been demoted as a simple user. This change will not apply until the user logs out and back in again.', $username));
} else {
if ($manipulator->removeRole($username, $role)) {
$output->writeln(sprintf('Role "%s" has been removed from user "%s". This change will not apply until the user logs out and back in again.', $role, $username));
} else {
$output->writeln(sprintf('User "%s" didn\'t have "%s" role.', $username, $role));
}
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Command;
use FOS\UserBundle\Util\UserManipulator;
use Symfony\Component\Console\Output\OutputInterface;
/**
* @author Matthieu Bontemps <matthieu@knplabs.com>
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Luis Cordova <cordoval@gmail.com>
* @author Lenar Lõhmus <lenar@city.ee>
*/
class PromoteUserCommand extends RoleCommand
{
protected static $defaultName = 'fos:user:promote';
/**
* {@inheritdoc}
*/
protected function configure()
{
parent::configure();
$this
->setName('fos:user:promote')
->setDescription('Promotes a user by adding a role')
->setHelp(<<<'EOT'
The <info>fos:user:promote</info> command promotes a user by adding a role
<info>php %command.full_name% matthieu ROLE_CUSTOM</info>
<info>php %command.full_name% --super matthieu</info>
EOT
);
}
/**
* {@inheritdoc}
*/
protected function executeRoleCommand(UserManipulator $manipulator, OutputInterface $output, $username, $super, $role)
{
if ($super) {
$manipulator->promote($username);
$output->writeln(sprintf('User "%s" has been promoted as a super administrator. This change will not apply until the user logs out and back in again.', $username));
} else {
if ($manipulator->addRole($username, $role)) {
$output->writeln(sprintf('Role "%s" has been added to user "%s". This change will not apply until the user logs out and back in again.', $role, $username));
} else {
$output->writeln(sprintf('User "%s" did already have "%s" role.', $username, $role));
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Command;
use FOS\UserBundle\Util\UserManipulator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
/**
* @author Lenar Lõhmus <lenar@city.ee>
*/
abstract class RoleCommand extends Command
{
private $userManipulator;
public function __construct(UserManipulator $userManipulator)
{
parent::__construct();
$this->userManipulator = $userManipulator;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setDefinition(array(
new InputArgument('username', InputArgument::REQUIRED, 'The username'),
new InputArgument('role', InputArgument::OPTIONAL, 'The role'),
new InputOption('super', null, InputOption::VALUE_NONE, 'Instead specifying role, use this to quickly add the super administrator role'),
));
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$username = $input->getArgument('username');
$role = $input->getArgument('role');
$super = (true === $input->getOption('super'));
if (null !== $role && $super) {
throw new \InvalidArgumentException('You can pass either the role or the --super option (but not both simultaneously).');
}
if (null === $role && !$super) {
throw new \RuntimeException('Not enough arguments.');
}
$manipulator = $this->userManipulator;
$this->executeRoleCommand($manipulator, $output, $username, $super, $role);
}
/**
* @see Command
*
* @param UserManipulator $manipulator
* @param OutputInterface $output
* @param string $username
* @param bool $super
* @param string $role
*/
abstract protected function executeRoleCommand(UserManipulator $manipulator, OutputInterface $output, $username, $super, $role);
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$questions = array();
if (!$input->getArgument('username')) {
$question = new Question('Please choose a username:');
$question->setValidator(function ($username) {
if (empty($username)) {
throw new \Exception('Username can not be empty');
}
return $username;
});
$questions['username'] = $question;
}
if ((true !== $input->getOption('super')) && !$input->getArgument('role')) {
$question = new Question('Please choose a role:');
$question->setValidator(function ($role) {
if (empty($role)) {
throw new \Exception('Role can not be empty');
}
return $role;
});
$questions['role'] = $question;
}
foreach ($questions as $name => $question) {
$answer = $this->getHelper('question')->ask($input, $output, $question);
$input->setArgument($name, $answer);
}
}
}

View File

@@ -0,0 +1,93 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Controller;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
* Controller managing the password change.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Christophe Coevoet <stof@notk.org>
*/
class ChangePasswordController extends Controller
{
private $eventDispatcher;
private $formFactory;
private $userManager;
public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager)
{
$this->eventDispatcher = $eventDispatcher;
$this->formFactory = $formFactory;
$this->userManager = $userManager;
}
/**
* Change user password.
*
* @param Request $request
*
* @return Response
*/
public function changePasswordAction(Request $request)
{
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::CHANGE_PASSWORD_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $this->formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::CHANGE_PASSWORD_SUCCESS, $event);
$this->userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_profile_show');
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(FOSUserEvents::CHANGE_PASSWORD_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
return $this->render('@FOSUser/ChangePassword/change_password.html.twig', array(
'form' => $form->createView(),
));
}
}

View File

@@ -0,0 +1,199 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Controller;
use FOS\UserBundle\Event\FilterGroupResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseGroupEvent;
use FOS\UserBundle\Event\GroupEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\GroupInterface;
use FOS\UserBundle\Model\GroupManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* RESTful controller managing group CRUD.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Christophe Coevoet <stof@notk.org>
*/
class GroupController extends Controller
{
private $eventDispatcher;
private $formFactory;
private $groupManager;
public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, GroupManagerInterface $groupManager)
{
$this->eventDispatcher = $eventDispatcher;
$this->formFactory = $formFactory;
$this->groupManager = $groupManager;
}
/**
* Show all groups.
*/
public function listAction()
{
return $this->render('@FOSUser/Group/list.html.twig', array(
'groups' => $this->groupManager->findGroups(),
));
}
/**
* Show one group.
*
* @param string $groupName
*
* @return Response
*/
public function showAction($groupName)
{
return $this->render('@FOSUser/Group/show.html.twig', array(
'group' => $this->findGroupBy('name', $groupName),
));
}
/**
* Edit one group, show the edit form.
*
* @param Request $request
* @param string $groupName
*
* @return Response
*/
public function editAction(Request $request, $groupName)
{
$group = $this->findGroupBy('name', $groupName);
$event = new GetResponseGroupEvent($group, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::GROUP_EDIT_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $this->formFactory->createForm();
$form->setData($group);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::GROUP_EDIT_SUCCESS, $event);
$this->groupManager->updateGroup($group);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_group_show', array('groupName' => $group->getName()));
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(FOSUserEvents::GROUP_EDIT_COMPLETED, new FilterGroupResponseEvent($group, $request, $response));
return $response;
}
return $this->render('@FOSUser/Group/edit.html.twig', array(
'form' => $form->createView(),
'group_name' => $group->getName(),
));
}
/**
* Show the new form.
*
* @param Request $request
*
* @return Response
*/
public function newAction(Request $request)
{
$group = $this->groupManager->createGroup('');
$this->eventDispatcher->dispatch(FOSUserEvents::GROUP_CREATE_INITIALIZE, new GroupEvent($group, $request));
$form = $this->formFactory->createForm();
$form->setData($group);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::GROUP_CREATE_SUCCESS, $event);
$this->groupManager->updateGroup($group);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_group_show', array('groupName' => $group->getName()));
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(FOSUserEvents::GROUP_CREATE_COMPLETED, new FilterGroupResponseEvent($group, $request, $response));
return $response;
}
return $this->render('@FOSUser/Group/new.html.twig', array(
'form' => $form->createView(),
));
}
/**
* Delete one group.
*
* @param Request $request
* @param string $groupName
*
* @return RedirectResponse
*/
public function deleteAction(Request $request, $groupName)
{
$group = $this->findGroupBy('name', $groupName);
$this->groupManager->deleteGroup($group);
$response = new RedirectResponse($this->generateUrl('fos_user_group_list'));
$this->eventDispatcher->dispatch(FOSUserEvents::GROUP_DELETE_COMPLETED, new FilterGroupResponseEvent($group, $request, $response));
return $response;
}
/**
* Find a group by a specific property.
*
* @param string $key property name
* @param mixed $value property value
*
* @throws NotFoundHttpException if user does not exist
*
* @return GroupInterface
*/
protected function findGroupBy($key, $value)
{
if (!empty($value)) {
$group = $this->groupManager->{'findGroupBy'.ucfirst($key)}($value);
}
if (empty($group)) {
throw new NotFoundHttpException(sprintf('The group with "%s" does not exist for value "%s"', $key, $value));
}
return $group;
}
}

View File

@@ -0,0 +1,107 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Controller;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
* Controller managing the user profile.
*
* @author Christophe Coevoet <stof@notk.org>
*/
class ProfileController extends Controller
{
private $eventDispatcher;
private $formFactory;
private $userManager;
public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager)
{
$this->eventDispatcher = $eventDispatcher;
$this->formFactory = $formFactory;
$this->userManager = $userManager;
}
/**
* Show the user.
*/
public function showAction()
{
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
return $this->render('@FOSUser/Profile/show.html.twig', array(
'user' => $user,
));
}
/**
* Edit the user.
*
* @param Request $request
*
* @return Response
*/
public function editAction(Request $request)
{
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $this->formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_SUCCESS, $event);
$this->userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_profile_show');
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
return $this->render('@FOSUser/Profile/edit.html.twig', array(
'form' => $form->createView(),
));
}
}

View File

@@ -0,0 +1,192 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Controller;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
* Controller managing the registration.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Christophe Coevoet <stof@notk.org>
*/
class RegistrationController extends Controller
{
private $eventDispatcher;
private $formFactory;
private $userManager;
private $tokenStorage;
public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager, TokenStorageInterface $tokenStorage)
{
$this->eventDispatcher = $eventDispatcher;
$this->formFactory = $formFactory;
$this->userManager = $userManager;
$this->tokenStorage = $tokenStorage;
}
/**
* @param Request $request
*
* @return Response
*/
public function registerAction(Request $request)
{
$user = $this->userManager->createUser();
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $this->formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$this->userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, $event);
if (null !== $response = $event->getResponse()) {
return $response;
}
}
return $this->render('@FOSUser/Registration/register.html.twig', array(
'form' => $form->createView(),
));
}
/**
* Tell the user to check their email provider.
*/
public function checkEmailAction(Request $request)
{
$email = $request->getSession()->get('fos_user_send_confirmation_email/email');
if (empty($email)) {
return new RedirectResponse($this->generateUrl('fos_user_registration_register'));
}
$request->getSession()->remove('fos_user_send_confirmation_email/email');
$user = $this->userManager->findUserByEmail($email);
if (null === $user) {
return new RedirectResponse($this->container->get('router')->generate('fos_user_security_login'));
}
return $this->render('@FOSUser/Registration/check_email.html.twig', array(
'user' => $user,
));
}
/**
* Receive the confirmation token from user email provider, login the user.
*
* @param Request $request
* @param string $token
*
* @return Response
*/
public function confirmAction(Request $request, $token)
{
$userManager = $this->userManager;
$user = $userManager->findUserByConfirmationToken($token);
if (null === $user) {
throw new NotFoundHttpException(sprintf('The user with confirmation token "%s" does not exist', $token));
}
$user->setConfirmationToken(null);
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_CONFIRM, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_CONFIRMED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
/**
* Tell the user his account is now confirmed.
*/
public function confirmedAction(Request $request)
{
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
return $this->render('@FOSUser/Registration/confirmed.html.twig', array(
'user' => $user,
'targetUrl' => $this->getTargetUrlFromSession($request->getSession()),
));
}
/**
* @return string|null
*/
private function getTargetUrlFromSession(SessionInterface $session)
{
$key = sprintf('_security.%s.target_path', $this->tokenStorage->getToken()->getProviderKey());
if ($session->has($key)) {
return $session->get($key);
}
return null;
}
}

View File

@@ -0,0 +1,201 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Controller;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseNullableUserEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Mailer\MailerInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Controller managing the resetting of the password.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Christophe Coevoet <stof@notk.org>
*/
class ResettingController extends Controller
{
private $eventDispatcher;
private $formFactory;
private $userManager;
private $tokenGenerator;
private $mailer;
/**
* @var int
*/
private $retryTtl;
/**
* @param EventDispatcherInterface $eventDispatcher
* @param FactoryInterface $formFactory
* @param UserManagerInterface $userManager
* @param TokenGeneratorInterface $tokenGenerator
* @param MailerInterface $mailer
* @param int $retryTtl
*/
public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager, TokenGeneratorInterface $tokenGenerator, MailerInterface $mailer, $retryTtl)
{
$this->eventDispatcher = $eventDispatcher;
$this->formFactory = $formFactory;
$this->userManager = $userManager;
$this->tokenGenerator = $tokenGenerator;
$this->mailer = $mailer;
$this->retryTtl = $retryTtl;
}
/**
* Request reset user password: show form.
*/
public function requestAction()
{
return $this->render('@FOSUser/Resetting/request.html.twig');
}
/**
* Request reset user password: submit form and send email.
*
* @param Request $request
*
* @return Response
*/
public function sendEmailAction(Request $request)
{
$username = $request->request->get('username');
$user = $this->userManager->findUserByUsernameOrEmail($username);
$event = new GetResponseNullableUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::RESETTING_SEND_EMAIL_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
if (null !== $user && !$user->isPasswordRequestNonExpired($this->retryTtl)) {
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::RESETTING_RESET_REQUEST, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
if (null === $user->getConfirmationToken()) {
$user->setConfirmationToken($this->tokenGenerator->generateToken());
}
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::RESETTING_SEND_EMAIL_CONFIRM, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$this->mailer->sendResettingEmailMessage($user);
$user->setPasswordRequestedAt(new \DateTime());
$this->userManager->updateUser($user);
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::RESETTING_SEND_EMAIL_COMPLETED, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
}
return new RedirectResponse($this->generateUrl('fos_user_resetting_check_email', array('username' => $username)));
}
/**
* Tell the user to check his email provider.
*
* @param Request $request
*
* @return Response
*/
public function checkEmailAction(Request $request)
{
$username = $request->query->get('username');
if (empty($username)) {
// the user does not come from the sendEmail action
return new RedirectResponse($this->generateUrl('fos_user_resetting_request'));
}
return $this->render('@FOSUser/Resetting/check_email.html.twig', array(
'tokenLifetime' => ceil($this->retryTtl / 3600),
));
}
/**
* Reset user password.
*
* @param Request $request
* @param string $token
*
* @return Response
*/
public function resetAction(Request $request, $token)
{
$user = $this->userManager->findUserByConfirmationToken($token);
if (null === $user) {
return new RedirectResponse($this->container->get('router')->generate('fos_user_security_login'));
}
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::RESETTING_RESET_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $this->formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::RESETTING_RESET_SUCCESS, $event);
$this->userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_profile_show');
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(
FOSUserEvents::RESETTING_RESET_COMPLETED,
new FilterUserResponseEvent($user, $request, $response)
);
return $response;
}
return $this->render('@FOSUser/Resetting/reset.html.twig', array(
'token' => $token,
'form' => $form->createView(),
));
}
}

View File

@@ -0,0 +1,100 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
/**
* Controller managing security.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Christophe Coevoet <stof@notk.org>
*/
class SecurityController extends Controller
{
private $tokenManager;
public function __construct(CsrfTokenManagerInterface $tokenManager = null)
{
$this->tokenManager = $tokenManager;
}
/**
* @param Request $request
*
* @return Response
*/
public function loginAction(Request $request)
{
/** @var $session Session */
$session = $request->getSession();
$authErrorKey = Security::AUTHENTICATION_ERROR;
$lastUsernameKey = Security::LAST_USERNAME;
// get the error if any (works with forward and redirect -- see below)
if ($request->attributes->has($authErrorKey)) {
$error = $request->attributes->get($authErrorKey);
} elseif (null !== $session && $session->has($authErrorKey)) {
$error = $session->get($authErrorKey);
$session->remove($authErrorKey);
} else {
$error = null;
}
if (!$error instanceof AuthenticationException) {
$error = null; // The value does not come from the security component.
}
// last username entered by the user
$lastUsername = (null === $session) ? '' : $session->get($lastUsernameKey);
$csrfToken = $this->tokenManager
? $this->tokenManager->getToken('authenticate')->getValue()
: null;
return $this->renderLogin(array(
'last_username' => $lastUsername,
'error' => $error,
'csrf_token' => $csrfToken,
));
}
public function checkAction()
{
throw new \RuntimeException('You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.');
}
public function logoutAction()
{
throw new \RuntimeException('You must activate the logout in your security firewall configuration.');
}
/**
* Renders the login template with the given parameters. Overwrite this function in
* an extended controller to provide additional data for the login template.
*
* @param array $data
*
* @return Response
*/
protected function renderLogin(array $data)
{
return $this->render('@FOSUser/Security/login.html.twig', $data);
}
}

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Flex\Recipe;
/**
* Checks to see if the mailer service exists.
*
* @author Ryan Weaver <ryan@knpuniversity.com>
*/
class CheckForMailerPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
// if the mailer isn't needed, then no error needed
if (!$container->has('fos_user.mailer')) {
return;
}
// the mailer exists, so all is good
if ($container->has('mailer')) {
return;
}
if ($container->findDefinition('fos_user.mailer')->hasTag('fos_user.requires_swift')) {
$message = 'A feature you activated in FOSUserBundle requires the "mailer" service to be available.';
if (class_exists(Recipe::class)) {
$message .= ' Run "composer require swiftmailer-bundle" to install SwiftMailer or configure a different mailer in "config/packages/fos_user.yaml".';
}
throw new \LogicException($message);
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Flex\Recipe;
/**
* Checks to see if the session service exists.
*
* @author Ryan Weaver <ryan@knpuniversity.com>
*/
class CheckForSessionPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
if ($container->has('fos_user.session') && !$container->has('session')) {
$message = 'FOSUserBundle requires the "session" service to be available.';
if (class_exists(Recipe::class)) {
$message .= ' Uncomment the "session" section in "config/packages/framework.yaml" to activate it.';
}
throw new \LogicException($message);
}
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Inject RememberMeServices into LoginManager.
*
* @author Vasily Khayrulin <sirianru@gmail.com>
*/
class InjectRememberMeServicesPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
$firewallName = $container->getParameter('fos_user.firewall_name');
$loginManager = $container->getDefinition('fos_user.security.login_manager');
if ($container->hasDefinition('security.authentication.rememberme.services.persistent.'.$firewallName)) {
$loginManager->replaceArgument(4, new Reference('security.authentication.rememberme.services.persistent.'.$firewallName));
} elseif ($container->hasDefinition('security.authentication.rememberme.services.simplehash.'.$firewallName)) {
$loginManager->replaceArgument(4, new Reference('security.authentication.rememberme.services.simplehash.'.$firewallName));
}
}
}

View File

@@ -0,0 +1,37 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Injects firewall's UserChecker into LoginManager.
*
* @author Gocha Ossinkine <ossinkine@ya.ru>
*/
class InjectUserCheckerPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
$firewallName = $container->getParameter('fos_user.firewall_name');
$loginManager = $container->findDefinition('fos_user.security.login_manager');
if ($container->has('security.user_checker.'.$firewallName)) {
$loginManager->replaceArgument(1, new Reference('security.user_checker.'.$firewallName));
}
}
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* Registers the additional validators according to the storage.
*
* @author Christophe Coevoet <stof@notk.org>
*/
class ValidationPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasParameter('fos_user.storage')) {
return;
}
$storage = $container->getParameter('fos_user.storage');
if ('custom' === $storage) {
return;
}
$validationFile = __DIR__.'/../../Resources/config/storage-validation/'.$storage.'.xml';
$container->getDefinition('validator.builder')
->addMethodCall('addXmlMapping', array($validationFile));
}
}

View File

@@ -0,0 +1,277 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection;
use FOS\UserBundle\Form\Type;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This class contains the configuration information for the bundle.
*
* This information is solely responsible for how the different configuration
* sections are normalized, and merged.
*
* @author Christophe Coevoet <stof@notk.org>
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('fos_user');
$supportedDrivers = array('orm', 'mongodb', 'couchdb', 'custom');
$rootNode
->children()
->scalarNode('db_driver')
->validate()
->ifNotInArray($supportedDrivers)
->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($supportedDrivers))
->end()
->cannotBeOverwritten()
->isRequired()
->cannotBeEmpty()
->end()
->scalarNode('user_class')->isRequired()->cannotBeEmpty()->end()
->scalarNode('firewall_name')->isRequired()->cannotBeEmpty()->end()
->scalarNode('model_manager_name')->defaultNull()->end()
->booleanNode('use_authentication_listener')->defaultTrue()->end()
->booleanNode('use_listener')->defaultTrue()->end()
->booleanNode('use_flash_notifications')->defaultTrue()->end()
->booleanNode('use_username_form_type')->defaultTrue()->end()
->arrayNode('from_email')
->isRequired()
->children()
->scalarNode('address')->isRequired()->cannotBeEmpty()->end()
->scalarNode('sender_name')->isRequired()->cannotBeEmpty()->end()
->end()
->end()
->end()
// Using the custom driver requires changing the manager services
->validate()
->ifTrue(function ($v) {
return 'custom' === $v['db_driver'] && 'fos_user.user_manager.default' === $v['service']['user_manager'];
})
->thenInvalid('You need to specify your own user manager service when using the "custom" driver.')
->end()
->validate()
->ifTrue(function ($v) {
return 'custom' === $v['db_driver'] && !empty($v['group']) && 'fos_user.group_manager.default' === $v['group']['group_manager'];
})
->thenInvalid('You need to specify your own group manager service when using the "custom" driver.')
->end();
$this->addProfileSection($rootNode);
$this->addChangePasswordSection($rootNode);
$this->addRegistrationSection($rootNode);
$this->addResettingSection($rootNode);
$this->addServiceSection($rootNode);
$this->addGroupSection($rootNode);
return $treeBuilder;
}
/**
* @param ArrayNodeDefinition $node
*/
private function addProfileSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('profile')
->addDefaultsIfNotSet()
->canBeUnset()
->children()
->arrayNode('form')
->addDefaultsIfNotSet()
->fixXmlConfig('validation_group')
->children()
->scalarNode('type')->defaultValue(Type\ProfileFormType::class)->end()
->scalarNode('name')->defaultValue('fos_user_profile_form')->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('Profile', 'Default'))
->end()
->end()
->end()
->end()
->end()
->end();
}
/**
* @param ArrayNodeDefinition $node
*/
private function addRegistrationSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('registration')
->addDefaultsIfNotSet()
->canBeUnset()
->children()
->arrayNode('confirmation')
->addDefaultsIfNotSet()
->children()
->booleanNode('enabled')->defaultFalse()->end()
->scalarNode('template')->defaultValue('@FOSUser/Registration/email.txt.twig')->end()
->arrayNode('from_email')
->canBeUnset()
->children()
->scalarNode('address')->isRequired()->cannotBeEmpty()->end()
->scalarNode('sender_name')->isRequired()->cannotBeEmpty()->end()
->end()
->end()
->end()
->end()
->arrayNode('form')
->addDefaultsIfNotSet()
->children()
->scalarNode('type')->defaultValue(Type\RegistrationFormType::class)->end()
->scalarNode('name')->defaultValue('fos_user_registration_form')->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('Registration', 'Default'))
->end()
->end()
->end()
->end()
->end()
->end();
}
/**
* @param ArrayNodeDefinition $node
*/
private function addResettingSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('resetting')
->addDefaultsIfNotSet()
->canBeUnset()
->children()
->scalarNode('retry_ttl')->defaultValue(7200)->end()
->scalarNode('token_ttl')->defaultValue(86400)->end()
->arrayNode('email')
->addDefaultsIfNotSet()
->children()
->scalarNode('template')->defaultValue('@FOSUser/Resetting/email.txt.twig')->end()
->arrayNode('from_email')
->canBeUnset()
->children()
->scalarNode('address')->isRequired()->cannotBeEmpty()->end()
->scalarNode('sender_name')->isRequired()->cannotBeEmpty()->end()
->end()
->end()
->end()
->end()
->arrayNode('form')
->addDefaultsIfNotSet()
->children()
->scalarNode('type')->defaultValue(Type\ResettingFormType::class)->end()
->scalarNode('name')->defaultValue('fos_user_resetting_form')->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('ResetPassword', 'Default'))
->end()
->end()
->end()
->end()
->end()
->end();
}
/**
* @param ArrayNodeDefinition $node
*/
private function addChangePasswordSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('change_password')
->addDefaultsIfNotSet()
->canBeUnset()
->children()
->arrayNode('form')
->addDefaultsIfNotSet()
->children()
->scalarNode('type')->defaultValue(Type\ChangePasswordFormType::class)->end()
->scalarNode('name')->defaultValue('fos_user_change_password_form')->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('ChangePassword', 'Default'))
->end()
->end()
->end()
->end()
->end()
->end();
}
/**
* @param ArrayNodeDefinition $node
*/
private function addServiceSection(ArrayNodeDefinition $node)
{
$node
->addDefaultsIfNotSet()
->children()
->arrayNode('service')
->addDefaultsIfNotSet()
->children()
->scalarNode('mailer')->defaultValue('fos_user.mailer.default')->end()
->scalarNode('email_canonicalizer')->defaultValue('fos_user.util.canonicalizer.default')->end()
->scalarNode('token_generator')->defaultValue('fos_user.util.token_generator.default')->end()
->scalarNode('username_canonicalizer')->defaultValue('fos_user.util.canonicalizer.default')->end()
->scalarNode('user_manager')->defaultValue('fos_user.user_manager.default')->end()
->end()
->end()
->end()
->end();
}
/**
* @param ArrayNodeDefinition $node
*/
private function addGroupSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('group')
->canBeUnset()
->children()
->scalarNode('group_class')->isRequired()->cannotBeEmpty()->end()
->scalarNode('group_manager')->defaultValue('fos_user.group_manager.default')->end()
->arrayNode('form')
->addDefaultsIfNotSet()
->fixXmlConfig('validation_group')
->children()
->scalarNode('type')->defaultValue(Type\GroupFormType::class)->end()
->scalarNode('name')->defaultValue('fos_user_group_form')->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('Registration', 'Default'))
->end()
->end()
->end()
->end()
->end()
->end();
}
}

View File

@@ -0,0 +1,302 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
class FOSUserExtension extends Extension
{
/**
* @var array
*/
private static $doctrineDrivers = array(
'orm' => array(
'registry' => 'doctrine',
'tag' => 'doctrine.event_subscriber',
),
'mongodb' => array(
'registry' => 'doctrine_mongodb',
'tag' => 'doctrine_mongodb.odm.event_subscriber',
),
'couchdb' => array(
'registry' => 'doctrine_couchdb',
'tag' => 'doctrine_couchdb.event_subscriber',
'listener_class' => 'FOS\UserBundle\Doctrine\CouchDB\UserListener',
),
);
private $mailerNeeded = false;
private $sessionNeeded = false;
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$processor = new Processor();
$configuration = new Configuration();
$config = $processor->processConfiguration($configuration, $configs);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
if ('custom' !== $config['db_driver']) {
if (isset(self::$doctrineDrivers[$config['db_driver']])) {
$loader->load('doctrine.xml');
$container->setAlias('fos_user.doctrine_registry', new Alias(self::$doctrineDrivers[$config['db_driver']]['registry'], false));
} else {
$loader->load(sprintf('%s.xml', $config['db_driver']));
}
$container->setParameter($this->getAlias().'.backend_type_'.$config['db_driver'], true);
}
if (isset(self::$doctrineDrivers[$config['db_driver']])) {
$definition = $container->getDefinition('fos_user.object_manager');
$definition->setFactory(array(new Reference('fos_user.doctrine_registry'), 'getManager'));
}
foreach (array('validator', 'security', 'util', 'mailer', 'listeners', 'commands') as $basename) {
$loader->load(sprintf('%s.xml', $basename));
}
if (!$config['use_authentication_listener']) {
$container->removeDefinition('fos_user.listener.authentication');
}
if ($config['use_flash_notifications']) {
$this->sessionNeeded = true;
$loader->load('flash_notifications.xml');
}
$container->setAlias('fos_user.util.email_canonicalizer', $config['service']['email_canonicalizer']);
$container->setAlias('fos_user.util.username_canonicalizer', $config['service']['username_canonicalizer']);
$container->setAlias('fos_user.util.token_generator', $config['service']['token_generator']);
$container->setAlias('fos_user.user_manager', new Alias($config['service']['user_manager'], true));
if ($config['use_listener'] && isset(self::$doctrineDrivers[$config['db_driver']])) {
$listenerDefinition = $container->getDefinition('fos_user.user_listener');
$listenerDefinition->addTag(self::$doctrineDrivers[$config['db_driver']]['tag']);
if (isset(self::$doctrineDrivers[$config['db_driver']]['listener_class'])) {
$listenerDefinition->setClass(self::$doctrineDrivers[$config['db_driver']]['listener_class']);
}
}
if ($config['use_username_form_type']) {
$loader->load('username_form_type.xml');
}
$this->remapParametersNamespaces($config, $container, array(
'' => array(
'db_driver' => 'fos_user.storage',
'firewall_name' => 'fos_user.firewall_name',
'model_manager_name' => 'fos_user.model_manager_name',
'user_class' => 'fos_user.model.user.class',
),
));
if (!empty($config['profile'])) {
$this->loadProfile($config['profile'], $container, $loader);
}
if (!empty($config['registration'])) {
$this->loadRegistration($config['registration'], $container, $loader, $config['from_email']);
}
if (!empty($config['change_password'])) {
$this->loadChangePassword($config['change_password'], $container, $loader);
}
if (!empty($config['resetting'])) {
$this->loadResetting($config['resetting'], $container, $loader, $config['from_email']);
}
if (!empty($config['group'])) {
$this->loadGroups($config['group'], $container, $loader, $config['db_driver']);
}
if ($this->mailerNeeded) {
$container->setAlias('fos_user.mailer', $config['service']['mailer']);
}
if ($this->sessionNeeded) {
// Use a private alias rather than a parameter, to avoid leaking it at runtime (the private alias will be removed)
$container->setAlias('fos_user.session', new Alias('session', false));
}
}
/**
* {@inheritdoc}
*/
public function getNamespace()
{
return 'http://friendsofsymfony.github.io/schema/dic/user';
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param array $map
*/
protected function remapParameters(array $config, ContainerBuilder $container, array $map)
{
foreach ($map as $name => $paramName) {
if (array_key_exists($name, $config)) {
$container->setParameter($paramName, $config[$name]);
}
}
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param array $namespaces
*/
protected function remapParametersNamespaces(array $config, ContainerBuilder $container, array $namespaces)
{
foreach ($namespaces as $ns => $map) {
if ($ns) {
if (!array_key_exists($ns, $config)) {
continue;
}
$namespaceConfig = $config[$ns];
} else {
$namespaceConfig = $config;
}
if (is_array($map)) {
$this->remapParameters($namespaceConfig, $container, $map);
} else {
foreach ($namespaceConfig as $name => $value) {
$container->setParameter(sprintf($map, $name), $value);
}
}
}
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param XmlFileLoader $loader
*/
private function loadProfile(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
$loader->load('profile.xml');
$this->remapParametersNamespaces($config, $container, array(
'form' => 'fos_user.profile.form.%s',
));
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param XmlFileLoader $loader
* @param array $fromEmail
*/
private function loadRegistration(array $config, ContainerBuilder $container, XmlFileLoader $loader, array $fromEmail)
{
$loader->load('registration.xml');
$this->sessionNeeded = true;
if ($config['confirmation']['enabled']) {
$this->mailerNeeded = true;
$loader->load('email_confirmation.xml');
}
if (isset($config['confirmation']['from_email'])) {
// overwrite the global one
$fromEmail = $config['confirmation']['from_email'];
unset($config['confirmation']['from_email']);
}
$container->setParameter('fos_user.registration.confirmation.from_email', array($fromEmail['address'] => $fromEmail['sender_name']));
$this->remapParametersNamespaces($config, $container, array(
'confirmation' => 'fos_user.registration.confirmation.%s',
'form' => 'fos_user.registration.form.%s',
));
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param XmlFileLoader $loader
*/
private function loadChangePassword(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
$loader->load('change_password.xml');
$this->remapParametersNamespaces($config, $container, array(
'form' => 'fos_user.change_password.form.%s',
));
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param XmlFileLoader $loader
* @param array $fromEmail
*/
private function loadResetting(array $config, ContainerBuilder $container, XmlFileLoader $loader, array $fromEmail)
{
$this->mailerNeeded = true;
$loader->load('resetting.xml');
if (isset($config['email']['from_email'])) {
// overwrite the global one
$fromEmail = $config['email']['from_email'];
unset($config['email']['from_email']);
}
$container->setParameter('fos_user.resetting.email.from_email', array($fromEmail['address'] => $fromEmail['sender_name']));
$this->remapParametersNamespaces($config, $container, array(
'' => array(
'retry_ttl' => 'fos_user.resetting.retry_ttl',
'token_ttl' => 'fos_user.resetting.token_ttl',
),
'email' => 'fos_user.resetting.email.%s',
'form' => 'fos_user.resetting.form.%s',
));
}
/**
* @param array $config
* @param ContainerBuilder $container
* @param XmlFileLoader $loader
* @param string $dbDriver
*/
private function loadGroups(array $config, ContainerBuilder $container, XmlFileLoader $loader, $dbDriver)
{
$loader->load('group.xml');
if ('custom' !== $dbDriver) {
if (isset(self::$doctrineDrivers[$dbDriver])) {
$loader->load('doctrine_group.xml');
} else {
$loader->load(sprintf('%s_group.xml', $dbDriver));
}
}
$container->setAlias('fos_user.group_manager', new Alias($config['group_manager'], true));
$container->setAlias('FOS\UserBundle\Model\GroupManagerInterface', new Alias('fos_user.group_manager', false));
$this->remapParametersNamespaces($config, $container, array(
'' => array(
'group_class' => 'fos_user.model.group.class',
),
'form' => 'fos_user.group.form.%s',
));
}
}

View File

@@ -0,0 +1,75 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Doctrine\CouchDB;
use Doctrine\Common\EventSubscriber;
use Doctrine\ODM\CouchDB\Event;
use Doctrine\ODM\CouchDB\Event\LifecycleEventArgs;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Util\CanonicalFieldsUpdater;
use FOS\UserBundle\Util\PasswordUpdaterInterface;
class UserListener implements EventSubscriber
{
private $passwordUpdater;
private $canonicalFieldsUpdater;
public function __construct(PasswordUpdaterInterface $passwordUpdater, CanonicalFieldsUpdater $canonicalFieldsUpdater)
{
$this->passwordUpdater = $passwordUpdater;
$this->canonicalFieldsUpdater = $canonicalFieldsUpdater;
}
/**
* {@inheritdoc}
*/
public function getSubscribedEvents()
{
return array(
Event::prePersist,
Event::preUpdate,
);
}
/**
* @param LifecycleEventArgs $args
*/
public function prePersist(LifecycleEventArgs $args)
{
$object = $args->getDocument();
if ($object instanceof UserInterface) {
$this->updateUserFields($object);
}
}
/**
* @param LifecycleEventArgs $args
*/
public function preUpdate(LifecycleEventArgs $args)
{
$object = $args->getDocument();
if ($object instanceof UserInterface) {
$this->updateUserFields($object);
}
}
/**
* Updates the user properties.
*
* @param UserInterface $user
*/
private function updateUserFields(UserInterface $user)
{
$this->canonicalFieldsUpdater->updateCanonicalFields($user);
$this->passwordUpdater->hashPassword($user);
}
}

View File

@@ -0,0 +1,94 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Doctrine;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectRepository;
use FOS\UserBundle\Model\GroupInterface;
use FOS\UserBundle\Model\GroupManager as BaseGroupManager;
class GroupManager extends BaseGroupManager
{
/**
* @var ObjectManager
*/
protected $objectManager;
/**
* @var string
*/
protected $class;
/**
* @var ObjectRepository
*/
protected $repository;
/**
* GroupManager constructor.
*
* @param ObjectManager $om
* @param string $class
*/
public function __construct(ObjectManager $om, $class)
{
$this->objectManager = $om;
$this->repository = $om->getRepository($class);
$metadata = $om->getClassMetadata($class);
$this->class = $metadata->getName();
}
/**
* {@inheritdoc}
*/
public function deleteGroup(GroupInterface $group)
{
$this->objectManager->remove($group);
$this->objectManager->flush();
}
/**
* {@inheritdoc}
*/
public function getClass()
{
return $this->class;
}
/**
* {@inheritdoc}
*/
public function findGroupBy(array $criteria)
{
return $this->repository->findOneBy($criteria);
}
/**
* {@inheritdoc}
*/
public function findGroups()
{
return $this->repository->findAll();
}
/**
* {@inheritdoc}
*/
public function updateGroup(GroupInterface $group, $andFlush = true)
{
$this->objectManager->persist($group);
if ($andFlush) {
$this->objectManager->flush();
}
}
}

View File

@@ -0,0 +1,109 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Doctrine;
use Doctrine\Common\EventSubscriber;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ORM\EntityManager;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Util\CanonicalFieldsUpdater;
use FOS\UserBundle\Util\PasswordUpdaterInterface;
/**
* Doctrine listener updating the canonical username and password fields.
*
* @author Christophe Coevoet <stof@notk.org>
* @author David Buchmann <mail@davidbu.ch>
*/
class UserListener implements EventSubscriber
{
private $passwordUpdater;
private $canonicalFieldsUpdater;
public function __construct(PasswordUpdaterInterface $passwordUpdater, CanonicalFieldsUpdater $canonicalFieldsUpdater)
{
$this->passwordUpdater = $passwordUpdater;
$this->canonicalFieldsUpdater = $canonicalFieldsUpdater;
}
/**
* {@inheritdoc}
*/
public function getSubscribedEvents()
{
return array(
'prePersist',
'preUpdate',
);
}
/**
* Pre persist listener based on doctrine common.
*
* @param LifecycleEventArgs $args
*/
public function prePersist(LifecycleEventArgs $args)
{
$object = $args->getObject();
if ($object instanceof UserInterface) {
$this->updateUserFields($object);
}
}
/**
* Pre update listener based on doctrine common.
*
* @param LifecycleEventArgs $args
*/
public function preUpdate(LifecycleEventArgs $args)
{
$object = $args->getObject();
if ($object instanceof UserInterface) {
$this->updateUserFields($object);
$this->recomputeChangeSet($args->getObjectManager(), $object);
}
}
/**
* Updates the user properties.
*
* @param UserInterface $user
*/
private function updateUserFields(UserInterface $user)
{
$this->canonicalFieldsUpdater->updateCanonicalFields($user);
$this->passwordUpdater->hashPassword($user);
}
/**
* Recomputes change set for Doctrine implementations not doing it automatically after the event.
*
* @param ObjectManager $om
* @param UserInterface $user
*/
private function recomputeChangeSet(ObjectManager $om, UserInterface $user)
{
$meta = $om->getClassMetadata(get_class($user));
if ($om instanceof EntityManager) {
$om->getUnitOfWork()->recomputeSingleEntityChangeSet($meta, $user);
return;
}
if ($om instanceof DocumentManager) {
$om->getUnitOfWork()->recomputeSingleDocumentChangeSet($meta, $user);
}
}
}

View File

@@ -0,0 +1,116 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Doctrine;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectRepository;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManager as BaseUserManager;
use FOS\UserBundle\Util\CanonicalFieldsUpdater;
use FOS\UserBundle\Util\PasswordUpdaterInterface;
class UserManager extends BaseUserManager
{
/**
* @var ObjectManager
*/
protected $objectManager;
/**
* @var string
*/
private $class;
/**
* Constructor.
*
* @param PasswordUpdaterInterface $passwordUpdater
* @param CanonicalFieldsUpdater $canonicalFieldsUpdater
* @param ObjectManager $om
* @param string $class
*/
public function __construct(PasswordUpdaterInterface $passwordUpdater, CanonicalFieldsUpdater $canonicalFieldsUpdater, ObjectManager $om, $class)
{
parent::__construct($passwordUpdater, $canonicalFieldsUpdater);
$this->objectManager = $om;
$this->class = $class;
}
/**
* {@inheritdoc}
*/
public function deleteUser(UserInterface $user)
{
$this->objectManager->remove($user);
$this->objectManager->flush();
}
/**
* {@inheritdoc}
*/
public function getClass()
{
if (false !== strpos($this->class, ':')) {
$metadata = $this->objectManager->getClassMetadata($this->class);
$this->class = $metadata->getName();
}
return $this->class;
}
/**
* {@inheritdoc}
*/
public function findUserBy(array $criteria)
{
return $this->getRepository()->findOneBy($criteria);
}
/**
* {@inheritdoc}
*/
public function findUsers()
{
return $this->getRepository()->findAll();
}
/**
* {@inheritdoc}
*/
public function reloadUser(UserInterface $user)
{
$this->objectManager->refresh($user);
}
/**
* {@inheritdoc}
*/
public function updateUser(UserInterface $user, $andFlush = true)
{
$this->updateCanonicalFields($user);
$this->updatePassword($user);
$this->objectManager->persist($user);
if ($andFlush) {
$this->objectManager->flush();
}
}
/**
* @return ObjectRepository
*/
protected function getRepository()
{
return $this->objectManager->getRepository($this->getClass());
}
}

View File

@@ -0,0 +1,54 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Event;
use FOS\UserBundle\Model\GroupInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class FilterGroupResponseEvent extends GroupEvent
{
/**
* @var Response
*/
private $response;
/**
* FilterGroupResponseEvent constructor.
*
* @param GroupInterface $group
* @param Request $request
* @param Response $response
*/
public function __construct(GroupInterface $group, Request $request, Response $response)
{
parent::__construct($group, $request);
$this->response = $response;
}
/**
* @param Response $response
*/
public function setResponse(Response $response)
{
$this->response = $response;
}
/**
* @return Response|null
*/
public function getResponse()
{
return $this->response;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Event;
use FOS\UserBundle\Model\UserInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class FilterUserResponseEvent extends UserEvent
{
private $response;
/**
* FilterUserResponseEvent constructor.
*
* @param UserInterface $user
* @param Request $request
* @param Response $response
*/
public function __construct(UserInterface $user, Request $request, Response $response)
{
parent::__construct($user, $request);
$this->response = $response;
}
/**
* @return Response
*/
public function getResponse()
{
return $this->response;
}
/**
* Sets a new response object.
*
* @param Response $response
*/
public function setResponse(Response $response)
{
$this->response = $response;
}
}

View File

@@ -0,0 +1,79 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Event;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class FormEvent extends Event
{
/**
* @var FormInterface
*/
private $form;
/**
* @var Request
*/
private $request;
/**
* @var Response
*/
private $response;
/**
* FormEvent constructor.
*
* @param FormInterface $form
* @param Request $request
*/
public function __construct(FormInterface $form, Request $request)
{
$this->form = $form;
$this->request = $request;
}
/**
* @return FormInterface
*/
public function getForm()
{
return $this->form;
}
/**
* @return Request
*/
public function getRequest()
{
return $this->request;
}
/**
* @param Response $response
*/
public function setResponse(Response $response)
{
$this->response = $response;
}
/**
* @return Response|null
*/
public function getResponse()
{
return $this->response;
}
}

View File

@@ -0,0 +1,38 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Event;
use Symfony\Component\HttpFoundation\Response;
class GetResponseGroupEvent extends GroupEvent
{
/**
* @var Response
*/
private $response;
/**
* @param Response $response
*/
public function setResponse(Response $response)
{
$this->response = $response;
}
/**
* @return Response|null
*/
public function getResponse()
{
return $this->response;
}
}

View File

@@ -0,0 +1,35 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Event;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Response user event that allows null user.
*
* @author Konstantinos Christofilos <kostas.christofilos@gmail.com>
*/
class GetResponseNullableUserEvent extends GetResponseUserEvent
{
/**
* GetResponseNullableUserEvent constructor.
*
* @param UserInterface|null $user
* @param Request $request
*/
public function __construct(UserInterface $user = null, Request $request)
{
$this->user = $user;
$this->request = $request;
}
}

View File

@@ -0,0 +1,38 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Event;
use Symfony\Component\HttpFoundation\Response;
class GetResponseUserEvent extends UserEvent
{
/**
* @var Response
*/
private $response;
/**
* @param Response $response
*/
public function setResponse(Response $response)
{
$this->response = $response;
}
/**
* @return Response|null
*/
public function getResponse()
{
return $this->response;
}
}

View File

@@ -0,0 +1,57 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Event;
use FOS\UserBundle\Model\GroupInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;
class GroupEvent extends Event
{
/**
* @var GroupInterface
*/
private $group;
/**
* @var Request
*/
private $request;
/**
* GroupEvent constructor.
*
* @param GroupInterface $group
* @param Request $request
*/
public function __construct(GroupInterface $group, Request $request)
{
$this->group = $group;
$this->request = $request;
}
/**
* @return GroupInterface
*/
public function getGroup()
{
return $this->group;
}
/**
* @return Request
*/
public function getRequest()
{
return $this->request;
}
}

View File

@@ -0,0 +1,57 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Event;
use FOS\UserBundle\Model\UserInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;
class UserEvent extends Event
{
/**
* @var null|Request
*/
protected $request;
/**
* @var UserInterface
*/
protected $user;
/**
* UserEvent constructor.
*
* @param UserInterface $user
* @param Request|null $request
*/
public function __construct(UserInterface $user, Request $request = null)
{
$this->user = $user;
$this->request = $request;
}
/**
* @return UserInterface
*/
public function getUser()
{
return $this->user;
}
/**
* @return Request
*/
public function getRequest()
{
return $this->request;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\EventListener;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Security\LoginManagerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Exception\AccountStatusException;
class AuthenticationListener implements EventSubscriberInterface
{
/**
* @var LoginManagerInterface
*/
private $loginManager;
/**
* @var string
*/
private $firewallName;
/**
* AuthenticationListener constructor.
*
* @param LoginManagerInterface $loginManager
* @param string $firewallName
*/
public function __construct(LoginManagerInterface $loginManager, $firewallName)
{
$this->loginManager = $loginManager;
$this->firewallName = $firewallName;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_COMPLETED => 'authenticate',
FOSUserEvents::REGISTRATION_CONFIRMED => 'authenticate',
FOSUserEvents::RESETTING_RESET_COMPLETED => 'authenticate',
);
}
/**
* @param FilterUserResponseEvent $event
* @param string $eventName
* @param EventDispatcherInterface $eventDispatcher
*/
public function authenticate(FilterUserResponseEvent $event, $eventName, EventDispatcherInterface $eventDispatcher)
{
try {
$this->loginManager->logInUser($this->firewallName, $event->getUser(), $event->getResponse());
$eventDispatcher->dispatch(FOSUserEvents::SECURITY_IMPLICIT_LOGIN, new UserEvent($event->getUser(), $event->getRequest()));
} catch (AccountStatusException $ex) {
// We simply do not authenticate users which do not pass the user
// checker (not enabled, expired, etc.).
}
}
}

View File

@@ -0,0 +1,76 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\EventListener;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Mailer\MailerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class EmailConfirmationListener implements EventSubscriberInterface
{
private $mailer;
private $tokenGenerator;
private $router;
private $session;
/**
* EmailConfirmationListener constructor.
*
* @param MailerInterface $mailer
* @param TokenGeneratorInterface $tokenGenerator
* @param UrlGeneratorInterface $router
* @param SessionInterface $session
*/
public function __construct(MailerInterface $mailer, TokenGeneratorInterface $tokenGenerator, UrlGeneratorInterface $router, SessionInterface $session)
{
$this->mailer = $mailer;
$this->tokenGenerator = $tokenGenerator;
$this->router = $router;
$this->session = $session;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
);
}
/**
* @param FormEvent $event
*/
public function onRegistrationSuccess(FormEvent $event)
{
/** @var $user \FOS\UserBundle\Model\UserInterface */
$user = $event->getForm()->getData();
$user->setEnabled(false);
if (null === $user->getConfirmationToken()) {
$user->setConfirmationToken($this->tokenGenerator->generateToken());
}
$this->mailer->sendConfirmationEmailMessage($user);
$this->session->set('fos_user_send_confirmation_email/email', $user->getEmail());
$url = $this->router->generate('fos_user_registration_check_email');
$event->setResponse(new RedirectResponse($url));
}
}

View File

@@ -0,0 +1,96 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Translation\TranslatorInterface;
class FlashListener implements EventSubscriberInterface
{
/**
* @var string[]
*/
private static $successMessages = array(
FOSUserEvents::CHANGE_PASSWORD_COMPLETED => 'change_password.flash.success',
FOSUserEvents::GROUP_CREATE_COMPLETED => 'group.flash.created',
FOSUserEvents::GROUP_DELETE_COMPLETED => 'group.flash.deleted',
FOSUserEvents::GROUP_EDIT_COMPLETED => 'group.flash.updated',
FOSUserEvents::PROFILE_EDIT_COMPLETED => 'profile.flash.updated',
FOSUserEvents::REGISTRATION_COMPLETED => 'registration.flash.user_created',
FOSUserEvents::RESETTING_RESET_COMPLETED => 'resetting.flash.success',
);
/**
* @var Session
*/
private $session;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* FlashListener constructor.
*
* @param Session $session
* @param TranslatorInterface $translator
*/
public function __construct(Session $session, TranslatorInterface $translator)
{
$this->session = $session;
$this->translator = $translator;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::CHANGE_PASSWORD_COMPLETED => 'addSuccessFlash',
FOSUserEvents::GROUP_CREATE_COMPLETED => 'addSuccessFlash',
FOSUserEvents::GROUP_DELETE_COMPLETED => 'addSuccessFlash',
FOSUserEvents::GROUP_EDIT_COMPLETED => 'addSuccessFlash',
FOSUserEvents::PROFILE_EDIT_COMPLETED => 'addSuccessFlash',
FOSUserEvents::REGISTRATION_COMPLETED => 'addSuccessFlash',
FOSUserEvents::RESETTING_RESET_COMPLETED => 'addSuccessFlash',
);
}
/**
* @param Event $event
* @param string $eventName
*/
public function addSuccessFlash(Event $event, $eventName)
{
if (!isset(self::$successMessages[$eventName])) {
throw new \InvalidArgumentException('This event does not correspond to a known flash message');
}
$this->session->getFlashBag()->add('success', $this->trans(self::$successMessages[$eventName]));
}
/**
* @param string$message
* @param array $params
*
* @return string
*/
private function trans($message, array $params = array())
{
return $this->translator->trans($message, $params, 'FOSUserBundle');
}
}

View File

@@ -0,0 +1,70 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\EventListener;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
class LastLoginListener implements EventSubscriberInterface
{
protected $userManager;
/**
* LastLoginListener constructor.
*
* @param UserManagerInterface $userManager
*/
public function __construct(UserManagerInterface $userManager)
{
$this->userManager = $userManager;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::SECURITY_IMPLICIT_LOGIN => 'onImplicitLogin',
SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin',
);
}
/**
* @param UserEvent $event
*/
public function onImplicitLogin(UserEvent $event)
{
$user = $event->getUser();
$user->setLastLogin(new \DateTime());
$this->userManager->updateUser($user);
}
/**
* @param InteractiveLoginEvent $event
*/
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
$user = $event->getAuthenticationToken()->getUser();
if ($user instanceof UserInterface) {
$user->setLastLogin(new \DateTime());
$this->userManager->updateUser($user);
}
}
}

View File

@@ -0,0 +1,89 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\EventListener;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\FOSUserEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class ResettingListener implements EventSubscriberInterface
{
/**
* @var UrlGeneratorInterface
*/
private $router;
/**
* @var int
*/
private $tokenTtl;
/**
* ResettingListener constructor.
*
* @param UrlGeneratorInterface $router
* @param int $tokenTtl
*/
public function __construct(UrlGeneratorInterface $router, $tokenTtl)
{
$this->router = $router;
$this->tokenTtl = $tokenTtl;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::RESETTING_RESET_INITIALIZE => 'onResettingResetInitialize',
FOSUserEvents::RESETTING_RESET_SUCCESS => 'onResettingResetSuccess',
FOSUserEvents::RESETTING_RESET_REQUEST => 'onResettingResetRequest',
);
}
/**
* @param GetResponseUserEvent $event
*/
public function onResettingResetInitialize(GetResponseUserEvent $event)
{
if (!$event->getUser()->isPasswordRequestNonExpired($this->tokenTtl)) {
$event->setResponse(new RedirectResponse($this->router->generate('fos_user_resetting_request')));
}
}
/**
* @param FormEvent $event
*/
public function onResettingResetSuccess(FormEvent $event)
{
/** @var $user \FOS\UserBundle\Model\UserInterface */
$user = $event->getForm()->getData();
$user->setConfirmationToken(null);
$user->setPasswordRequestedAt(null);
$user->setEnabled(true);
}
/**
* @param GetResponseUserEvent $event
*/
public function onResettingResetRequest(GetResponseUserEvent $event)
{
if (!$event->getUser()->isAccountNonLocked()) {
$event->setResponse(new RedirectResponse($this->router->generate('fos_user_resetting_request')));
}
}
}

View File

@@ -0,0 +1,67 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle;
use Doctrine\Bundle\CouchDBBundle\DependencyInjection\Compiler\DoctrineCouchDBMappingsPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;
use Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\DoctrineMongoDBMappingsPass;
use FOS\UserBundle\DependencyInjection\Compiler\CheckForMailerPass;
use FOS\UserBundle\DependencyInjection\Compiler\CheckForSessionPass;
use FOS\UserBundle\DependencyInjection\Compiler\InjectRememberMeServicesPass;
use FOS\UserBundle\DependencyInjection\Compiler\InjectUserCheckerPass;
use FOS\UserBundle\DependencyInjection\Compiler\ValidationPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
/**
* @author Matthieu Bontemps <matthieu@knplabs.com>
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
*/
class FOSUserBundle extends Bundle
{
/**
* @param ContainerBuilder $container
*/
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new ValidationPass());
$container->addCompilerPass(new InjectUserCheckerPass());
$container->addCompilerPass(new InjectRememberMeServicesPass());
$container->addCompilerPass(new CheckForSessionPass());
$container->addCompilerPass(new CheckForMailerPass());
$this->addRegisterMappingsPass($container);
}
/**
* @param ContainerBuilder $container
*/
private function addRegisterMappingsPass(ContainerBuilder $container)
{
$mappings = array(
realpath(__DIR__.'/Resources/config/doctrine-mapping') => 'FOS\UserBundle\Model',
);
if (class_exists('Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass')) {
$container->addCompilerPass(DoctrineOrmMappingsPass::createXmlMappingDriver($mappings, array('fos_user.model_manager_name'), 'fos_user.backend_type_orm'));
}
if (class_exists('Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\DoctrineMongoDBMappingsPass')) {
$container->addCompilerPass(DoctrineMongoDBMappingsPass::createXmlMappingDriver($mappings, array('fos_user.model_manager_name'), 'fos_user.backend_type_mongodb'));
}
if (class_exists('Doctrine\Bundle\CouchDBBundle\DependencyInjection\Compiler\DoctrineCouchDBMappingsPass')) {
$container->addCompilerPass(DoctrineCouchDBMappingsPass::createXmlMappingDriver($mappings, array('fos_user.model_manager_name'), 'fos_user.backend_type_couchdb'));
}
}
}

View File

@@ -0,0 +1,321 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle;
/**
* Contains all events thrown in the FOSUserBundle.
*/
final class FOSUserEvents
{
/**
* The CHANGE_PASSWORD_INITIALIZE event occurs when the change password process is initialized.
*
* This event allows you to modify the default values of the user before binding the form.
*
* @Event("FOS\UserBundle\Event\GetResponseUserEvent")
*/
const CHANGE_PASSWORD_INITIALIZE = 'fos_user.change_password.edit.initialize';
/**
* The CHANGE_PASSWORD_SUCCESS event occurs when the change password form is submitted successfully.
*
* This event allows you to set the response instead of using the default one.
*
* @Event("FOS\UserBundle\Event\FormEvent")
*/
const CHANGE_PASSWORD_SUCCESS = 'fos_user.change_password.edit.success';
/**
* The CHANGE_PASSWORD_COMPLETED event occurs after saving the user in the change password process.
*
* This event allows you to access the response which will be sent.
*
* @Event("FOS\UserBundle\Event\FilterUserResponseEvent")
*/
const CHANGE_PASSWORD_COMPLETED = 'fos_user.change_password.edit.completed';
/**
* The GROUP_CREATE_INITIALIZE event occurs when the group creation process is initialized.
*
* This event allows you to modify the default values of the user before binding the form.
*
* @Event("FOS\UserBundle\Event\GroupEvent")
*/
const GROUP_CREATE_INITIALIZE = 'fos_user.group.create.initialize';
/**
* The GROUP_CREATE_SUCCESS event occurs when the group creation form is submitted successfully.
*
* This event allows you to set the response instead of using the default one.
*
* @Event("FOS\UserBundle\Event\FormEvent")
*/
const GROUP_CREATE_SUCCESS = 'fos_user.group.create.success';
/**
* The GROUP_CREATE_COMPLETED event occurs after saving the group in the group creation process.
*
* This event allows you to access the response which will be sent.
*
* @Event("FOS\UserBundle\Event\FilterGroupResponseEvent")
*/
const GROUP_CREATE_COMPLETED = 'fos_user.group.create.completed';
/**
* The GROUP_DELETE_COMPLETED event occurs after deleting the group.
*
* This event allows you to access the response which will be sent.
*
* @Event("FOS\UserBundle\Event\FilterGroupResponseEvent")
*/
const GROUP_DELETE_COMPLETED = 'fos_user.group.delete.completed';
/**
* The GROUP_EDIT_INITIALIZE event occurs when the group editing process is initialized.
*
* This event allows you to modify the default values of the user before binding the form.
*
* @Event("FOS\UserBundle\Event\GetResponseGroupEvent")
*/
const GROUP_EDIT_INITIALIZE = 'fos_user.group.edit.initialize';
/**
* The GROUP_EDIT_SUCCESS event occurs when the group edit form is submitted successfully.
*
* This event allows you to set the response instead of using the default one.
*
* @Event("FOS\UserBundle\Event\FormEvent")
*/
const GROUP_EDIT_SUCCESS = 'fos_user.group.edit.success';
/**
* The GROUP_EDIT_COMPLETED event occurs after saving the group in the group edit process.
*
* This event allows you to access the response which will be sent.
*
* @Event("FOS\UserBundle\Event\FilterGroupResponseEvent")
*/
const GROUP_EDIT_COMPLETED = 'fos_user.group.edit.completed';
/**
* The PROFILE_EDIT_INITIALIZE event occurs when the profile editing process is initialized.
*
* This event allows you to modify the default values of the user before binding the form.
*
* @Event("FOS\UserBundle\Event\GetResponseUserEvent")
*/
const PROFILE_EDIT_INITIALIZE = 'fos_user.profile.edit.initialize';
/**
* The PROFILE_EDIT_SUCCESS event occurs when the profile edit form is submitted successfully.
*
* This event allows you to set the response instead of using the default one.
*
* @Event("FOS\UserBundle\Event\FormEvent")
*/
const PROFILE_EDIT_SUCCESS = 'fos_user.profile.edit.success';
/**
* The PROFILE_EDIT_COMPLETED event occurs after saving the user in the profile edit process.
*
* This event allows you to access the response which will be sent.
*
* @Event("FOS\UserBundle\Event\FilterUserResponseEvent")
*/
const PROFILE_EDIT_COMPLETED = 'fos_user.profile.edit.completed';
/**
* The REGISTRATION_INITIALIZE event occurs when the registration process is initialized.
*
* This event allows you to modify the default values of the user before binding the form.
*
* @Event("FOS\UserBundle\Event\UserEvent")
*/
const REGISTRATION_INITIALIZE = 'fos_user.registration.initialize';
/**
* The REGISTRATION_SUCCESS event occurs when the registration form is submitted successfully.
*
* This event allows you to set the response instead of using the default one.
*
* @Event("FOS\UserBundle\Event\FormEvent")
*/
const REGISTRATION_SUCCESS = 'fos_user.registration.success';
/**
* The REGISTRATION_FAILURE event occurs when the registration form is not valid.
*
* This event allows you to set the response instead of using the default one.
* The event listener method receives a FOS\UserBundle\Event\FormEvent instance.
*
* @Event("FOS\UserBundle\Event\FormEvent")
*/
const REGISTRATION_FAILURE = 'fos_user.registration.failure';
/**
* The REGISTRATION_COMPLETED event occurs after saving the user in the registration process.
*
* This event allows you to access the response which will be sent.
*
* @Event("FOS\UserBundle\Event\FilterUserResponseEvent")
*/
const REGISTRATION_COMPLETED = 'fos_user.registration.completed';
/**
* The REGISTRATION_CONFIRM event occurs just before confirming the account.
*
* This event allows you to access the user which will be confirmed.
*
* @Event("FOS\UserBundle\Event\GetResponseUserEvent")
*/
const REGISTRATION_CONFIRM = 'fos_user.registration.confirm';
/**
* The REGISTRATION_CONFIRMED event occurs after confirming the account.
*
* This event allows you to access the response which will be sent.
*
* @Event("FOS\UserBundle\Event\FilterUserResponseEvent")
*/
const REGISTRATION_CONFIRMED = 'fos_user.registration.confirmed';
/**
* The RESETTING_RESET_REQUEST event occurs when a user requests a password reset of the account.
*
* This event allows you to check if a user is locked out before requesting a password.
* The event listener method receives a FOS\UserBundle\Event\GetResponseUserEvent instance.
*
* @Event("FOS\UserBundle\Event\GetResponseUserEvent")
*/
const RESETTING_RESET_REQUEST = 'fos_user.resetting.reset.request';
/**
* The RESETTING_RESET_INITIALIZE event occurs when the resetting process is initialized.
*
* This event allows you to set the response to bypass the processing.
*
* @Event("FOS\UserBundle\Event\GetResponseUserEvent")
*/
const RESETTING_RESET_INITIALIZE = 'fos_user.resetting.reset.initialize';
/**
* The RESETTING_RESET_SUCCESS event occurs when the resetting form is submitted successfully.
*
* This event allows you to set the response instead of using the default one.
*
* @Event("FOS\UserBundle\Event\FormEvent ")
*/
const RESETTING_RESET_SUCCESS = 'fos_user.resetting.reset.success';
/**
* The RESETTING_RESET_COMPLETED event occurs after saving the user in the resetting process.
*
* This event allows you to access the response which will be sent.
*
* @Event("FOS\UserBundle\Event\FilterUserResponseEvent")
*/
const RESETTING_RESET_COMPLETED = 'fos_user.resetting.reset.completed';
/**
* The SECURITY_IMPLICIT_LOGIN event occurs when the user is logged in programmatically.
*
* This event allows you to access the response which will be sent.
*
* @Event("FOS\UserBundle\Event\UserEvent")
*/
const SECURITY_IMPLICIT_LOGIN = 'fos_user.security.implicit_login';
/**
* The RESETTING_SEND_EMAIL_INITIALIZE event occurs when the send email process is initialized.
*
* This event allows you to set the response to bypass the email confirmation processing.
* The event listener method receives a FOS\UserBundle\Event\GetResponseNullableUserEvent instance.
*
* @Event("FOS\UserBundle\Event\GetResponseNullableUserEvent")
*/
const RESETTING_SEND_EMAIL_INITIALIZE = 'fos_user.resetting.send_email.initialize';
/**
* The RESETTING_SEND_EMAIL_CONFIRM event occurs when all prerequisites to send email are
* confirmed and before the mail is sent.
*
* This event allows you to set the response to bypass the email sending.
* The event listener method receives a FOS\UserBundle\Event\GetResponseUserEvent instance.
*
* @Event("FOS\UserBundle\Event\GetResponseUserEvent")
*/
const RESETTING_SEND_EMAIL_CONFIRM = 'fos_user.resetting.send_email.confirm';
/**
* The RESETTING_SEND_EMAIL_COMPLETED event occurs after the email is sent.
*
* This event allows you to set the response to bypass the the redirection after the email is sent.
* The event listener method receives a FOS\UserBundle\Event\GetResponseUserEvent instance.
*
* @Event("FOS\UserBundle\Event\GetResponseUserEvent")
*/
const RESETTING_SEND_EMAIL_COMPLETED = 'fos_user.resetting.send_email.completed';
/**
* The USER_CREATED event occurs when the user is created with UserManipulator.
*
* This event allows you to access the created user and to add some behaviour after the creation.
*
* @Event("FOS\UserBundle\Event\UserEvent")
*/
const USER_CREATED = 'fos_user.user.created';
/**
* The USER_PASSWORD_CHANGED event occurs when the user is created with UserManipulator.
*
* This event allows you to access the created user and to add some behaviour after the password change.
*
* @Event("FOS\UserBundle\Event\UserEvent")
*/
const USER_PASSWORD_CHANGED = 'fos_user.user.password_changed';
/**
* The USER_ACTIVATED event occurs when the user is created with UserManipulator.
*
* This event allows you to access the activated user and to add some behaviour after the activation.
*
* @Event("FOS\UserBundle\Event\UserEvent")
*/
const USER_ACTIVATED = 'fos_user.user.activated';
/**
* The USER_DEACTIVATED event occurs when the user is created with UserManipulator.
*
* This event allows you to access the deactivated user and to add some behaviour after the deactivation.
*
* @Event("FOS\UserBundle\Event\UserEvent")
*/
const USER_DEACTIVATED = 'fos_user.user.deactivated';
/**
* The USER_PROMOTED event occurs when the user is created with UserManipulator.
*
* This event allows you to access the promoted user and to add some behaviour after the promotion.
*
* @Event("FOS\UserBundle\Event\UserEvent")
*/
const USER_PROMOTED = 'fos_user.user.promoted';
/**
* The USER_DEMOTED event occurs when the user is created with UserManipulator.
*
* This event allows you to access the demoted user and to add some behaviour after the demotion.
*
* @Event("FOS\UserBundle\Event\UserEvent")
*/
const USER_DEMOTED = 'fos_user.user.demoted';
}

View File

@@ -0,0 +1,84 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Form\DataTransformer;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
/**
* Transforms between a UserInterface instance and a username string.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
*/
class UserToUsernameTransformer implements DataTransformerInterface
{
/**
* @var UserManagerInterface
*/
protected $userManager;
/**
* UserToUsernameTransformer constructor.
*
* @param UserManagerInterface $userManager
*/
public function __construct(UserManagerInterface $userManager)
{
$this->userManager = $userManager;
}
/**
* Transforms a UserInterface instance into a username string.
*
* @param UserInterface|null $value UserInterface instance
*
* @return string|null Username
*
* @throws UnexpectedTypeException if the given value is not a UserInterface instance
*/
public function transform($value)
{
if (null === $value) {
return;
}
if (!$value instanceof UserInterface) {
throw new UnexpectedTypeException($value, 'FOS\UserBundle\Model\UserInterface');
}
return $value->getUsername();
}
/**
* Transforms a username string into a UserInterface instance.
*
* @param string $value Username
*
* @return UserInterface the corresponding UserInterface instance
*
* @throws UnexpectedTypeException if the given value is not a string
*/
public function reverseTransform($value)
{
if (null === $value || '' === $value) {
return;
}
if (!is_string($value)) {
throw new UnexpectedTypeException($value, 'string');
}
return $this->userManager->findUserByUsername($value);
}
}

View File

@@ -0,0 +1,22 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Form\Factory;
use Symfony\Component\Form\FormInterface;
interface FactoryInterface
{
/**
* @return FormInterface
*/
public function createForm();
}

View File

@@ -0,0 +1,63 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Form\Factory;
use Symfony\Component\Form\FormFactoryInterface;
class FormFactory implements FactoryInterface
{
/**
* @var FormFactoryInterface
*/
private $formFactory;
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $type;
/**
* @var array
*/
private $validationGroups;
/**
* FormFactory constructor.
*
* @param FormFactoryInterface $formFactory
* @param string $name
* @param string $type
* @param array $validationGroups
*/
public function __construct(FormFactoryInterface $formFactory, $name, $type, array $validationGroups = null)
{
$this->formFactory = $formFactory;
$this->name = $name;
$this->type = $type;
$this->validationGroups = $validationGroups;
}
/**
* {@inheritdoc}
*/
public function createForm(array $options = array())
{
$options = array_merge(array('validation_groups' => $this->validationGroups), $options);
return $this->formFactory->createNamed($this->name, $this->type, null, $options);
}
}

View File

@@ -0,0 +1,105 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
use Symfony\Component\Validator\Constraints\NotBlank;
class ChangePasswordFormType extends AbstractType
{
/**
* @var string
*/
private $class;
/**
* @param string $class The User class name
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$constraintsOptions = array(
'message' => 'fos_user.current_password.invalid',
);
if (!empty($options['validation_groups'])) {
$constraintsOptions['groups'] = array(reset($options['validation_groups']));
}
$builder->add('current_password', PasswordType::class, array(
'label' => 'form.current_password',
'translation_domain' => 'FOSUserBundle',
'mapped' => false,
'constraints' => array(
new NotBlank(),
new UserPassword($constraintsOptions),
),
'attr' => array(
'autocomplete' => 'current-password',
),
));
$builder->add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class,
'options' => array(
'translation_domain' => 'FOSUserBundle',
'attr' => array(
'autocomplete' => 'new-password',
),
),
'first_options' => array('label' => 'form.new_password'),
'second_options' => array('label' => 'form.new_password_confirmation'),
'invalid_message' => 'fos_user.password.mismatch',
));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => $this->class,
'csrf_token_id' => 'change_password',
));
}
// BC for SF < 3.0
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->getBlockPrefix();
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'fos_user_change_password';
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class GroupFormType extends AbstractType
{
/**
* @var string
*/
private $class;
/**
* @param string $class The Group class name
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', null, array('label' => 'form.group_name', 'translation_domain' => 'FOSUserBundle'));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => $this->class,
'csrf_token_id' => 'group',
));
}
// BC for SF < 3.0
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->getBlockPrefix();
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'fos_user_group';
}
}

View File

@@ -0,0 +1,108 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
use Symfony\Component\Validator\Constraints\NotBlank;
class ProfileFormType extends AbstractType
{
/**
* @var string
*/
private $class;
/**
* @param string $class The User class name
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->buildUserForm($builder, $options);
$constraintsOptions = array(
'message' => 'fos_user.current_password.invalid',
);
if (!empty($options['validation_groups'])) {
$constraintsOptions['groups'] = array(reset($options['validation_groups']));
}
$builder->add('current_password', PasswordType::class, array(
'label' => 'form.current_password',
'translation_domain' => 'FOSUserBundle',
'mapped' => false,
'constraints' => array(
new NotBlank(),
new UserPassword($constraintsOptions),
),
'attr' => array(
'autocomplete' => 'current-password',
),
));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => $this->class,
'csrf_token_id' => 'profile',
));
}
// BC for SF < 3.0
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->getBlockPrefix();
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'fos_user_profile';
}
/**
* Builds the embedded form representing the user.
*
* @param FormBuilderInterface $builder
* @param array $options
*/
protected function buildUserForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle'))
->add('email', EmailType::class, array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle'))
;
}
}

View File

@@ -0,0 +1,87 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class RegistrationFormType extends AbstractType
{
/**
* @var string
*/
private $class;
/**
* @param string $class The User class name
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class, array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle'))
->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle'))
->add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class,
'options' => array(
'translation_domain' => 'FOSUserBundle',
'attr' => array(
'autocomplete' => 'new-password',
),
),
'first_options' => array('label' => 'form.password'),
'second_options' => array('label' => 'form.password_confirmation'),
'invalid_message' => 'fos_user.password.mismatch',
))
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => $this->class,
'csrf_token_id' => 'registration',
));
}
// BC for SF < 3.0
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->getBlockPrefix();
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'fos_user_registration';
}
}

View File

@@ -0,0 +1,82 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ResettingFormType extends AbstractType
{
/**
* @var string
*/
private $class;
/**
* @param string $class The User class name
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class,
'options' => array(
'translation_domain' => 'FOSUserBundle',
'attr' => array(
'autocomplete' => 'new-password',
),
),
'first_options' => array('label' => 'form.new_password'),
'second_options' => array('label' => 'form.new_password_confirmation'),
'invalid_message' => 'fos_user.password.mismatch',
));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => $this->class,
'csrf_token_id' => 'resetting',
));
}
// BC for SF < 3.0
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->getBlockPrefix();
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'fos_user_resetting';
}
}

View File

@@ -0,0 +1,74 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Form\Type;
use FOS\UserBundle\Form\DataTransformer\UserToUsernameTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
/**
* Form type for representing a UserInterface instance by its username string.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
*/
class UsernameFormType extends AbstractType
{
/**
* @var UserToUsernameTransformer
*/
protected $usernameTransformer;
/**
* Constructor.
*
* @param UserToUsernameTransformer $usernameTransformer
*/
public function __construct(UserToUsernameTransformer $usernameTransformer)
{
$this->usernameTransformer = $usernameTransformer;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addModelTransformer($this->usernameTransformer);
}
/**
* {@inheritdoc}
*/
public function getParent()
{
return TextType::class;
}
// BC for SF < 3.0
/**
* @return string
*/
public function getName()
{
return $this->getBlockPrefix();
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'fos_user_username';
}
}

View File

@@ -0,0 +1,19 @@
Copyright (c) 2010-2016 FriendsOfSymfony
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,107 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Mailer;
use FOS\UserBundle\Model\UserInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
*/
class Mailer implements MailerInterface
{
/**
* @var \Swift_Mailer
*/
protected $mailer;
/**
* @var UrlGeneratorInterface
*/
protected $router;
/**
* @var EngineInterface
*/
protected $templating;
/**
* @var array
*/
protected $parameters;
/**
* Mailer constructor.
*
* @param \Swift_Mailer $mailer
* @param UrlGeneratorInterface $router
* @param EngineInterface $templating
* @param array $parameters
*/
public function __construct($mailer, UrlGeneratorInterface $router, EngineInterface $templating, array $parameters)
{
$this->mailer = $mailer;
$this->router = $router;
$this->templating = $templating;
$this->parameters = $parameters;
}
/**
* {@inheritdoc}
*/
public function sendConfirmationEmailMessage(UserInterface $user)
{
$template = $this->parameters['confirmation.template'];
$url = $this->router->generate('fos_user_registration_confirm', array('token' => $user->getConfirmationToken()), UrlGeneratorInterface::ABSOLUTE_URL);
$rendered = $this->templating->render($template, array(
'user' => $user,
'confirmationUrl' => $url,
));
$this->sendEmailMessage($rendered, $this->parameters['from_email']['confirmation'], (string) $user->getEmail());
}
/**
* {@inheritdoc}
*/
public function sendResettingEmailMessage(UserInterface $user)
{
$template = $this->parameters['resetting.template'];
$url = $this->router->generate('fos_user_resetting_reset', array('token' => $user->getConfirmationToken()), UrlGeneratorInterface::ABSOLUTE_URL);
$rendered = $this->templating->render($template, array(
'user' => $user,
'confirmationUrl' => $url,
));
$this->sendEmailMessage($rendered, $this->parameters['from_email']['resetting'], (string) $user->getEmail());
}
/**
* @param string $renderedTemplate
* @param array|string $fromEmail
* @param array|string $toEmail
*/
protected function sendEmailMessage($renderedTemplate, $fromEmail, $toEmail)
{
// Render the email, use the first line as the subject, and the rest as the body
$renderedLines = explode("\n", trim($renderedTemplate));
$subject = array_shift($renderedLines);
$body = implode("\n", $renderedLines);
$message = (new \Swift_Message())
->setSubject($subject)
->setFrom($fromEmail)
->setTo($toEmail)
->setBody($body);
$this->mailer->send($message);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Mailer;
use FOS\UserBundle\Model\UserInterface;
/**
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
*/
interface MailerInterface
{
/**
* Send an email to a user to confirm the account creation.
*
* @param UserInterface $user
*/
public function sendConfirmationEmailMessage(UserInterface $user);
/**
* Send an email to a user to confirm the password reset.
*
* @param UserInterface $user
*/
public function sendResettingEmailMessage(UserInterface $user);
}

View File

@@ -0,0 +1,40 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Mailer;
use FOS\UserBundle\Model\UserInterface;
/**
* This mailer does nothing.
* It is used when the 'email' configuration is not set,
* and allows to use this bundle without swiftmailer.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
*/
class NoopMailer implements MailerInterface
{
/**
* @param UserInterface $user
*/
public function sendConfirmationEmailMessage(UserInterface $user)
{
// nothing happens.
}
/**
* @param UserInterface $user
*/
public function sendResettingEmailMessage(UserInterface $user)
{
// nothing happens.
}
}

View File

@@ -0,0 +1,122 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Mailer;
use FOS\UserBundle\Model\UserInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* @author Christophe Coevoet <stof@notk.org>
*/
class TwigSwiftMailer implements MailerInterface
{
/**
* @var \Swift_Mailer
*/
protected $mailer;
/**
* @var UrlGeneratorInterface
*/
protected $router;
/**
* @var \Twig_Environment
*/
protected $twig;
/**
* @var array
*/
protected $parameters;
/**
* TwigSwiftMailer constructor.
*
* @param \Swift_Mailer $mailer
* @param UrlGeneratorInterface $router
* @param \Twig_Environment $twig
* @param array $parameters
*/
public function __construct(\Swift_Mailer $mailer, UrlGeneratorInterface $router, \Twig_Environment $twig, array $parameters)
{
$this->mailer = $mailer;
$this->router = $router;
$this->twig = $twig;
$this->parameters = $parameters;
}
/**
* {@inheritdoc}
*/
public function sendConfirmationEmailMessage(UserInterface $user)
{
$template = $this->parameters['template']['confirmation'];
$url = $this->router->generate('fos_user_registration_confirm', array('token' => $user->getConfirmationToken()), UrlGeneratorInterface::ABSOLUTE_URL);
$context = array(
'user' => $user,
'confirmationUrl' => $url,
);
$this->sendMessage($template, $context, $this->parameters['from_email']['confirmation'], (string) $user->getEmail());
}
/**
* {@inheritdoc}
*/
public function sendResettingEmailMessage(UserInterface $user)
{
$template = $this->parameters['template']['resetting'];
$url = $this->router->generate('fos_user_resetting_reset', array('token' => $user->getConfirmationToken()), UrlGeneratorInterface::ABSOLUTE_URL);
$context = array(
'user' => $user,
'confirmationUrl' => $url,
);
$this->sendMessage($template, $context, $this->parameters['from_email']['resetting'], (string) $user->getEmail());
}
/**
* @param string $templateName
* @param array $context
* @param array $fromEmail
* @param string $toEmail
*/
protected function sendMessage($templateName, $context, $fromEmail, $toEmail)
{
$template = $this->twig->load($templateName);
$subject = $template->renderBlock('subject', $context);
$textBody = $template->renderBlock('body_text', $context);
$htmlBody = '';
if ($template->hasBlock('body_html', $context)) {
$htmlBody = $template->renderBlock('body_html', $context);
}
$message = (new \Swift_Message())
->setSubject($subject)
->setFrom($fromEmail)
->setTo($toEmail);
if (!empty($htmlBody)) {
$message->setBody($htmlBody, 'text/html')
->addPart($textBody, 'text/plain');
} else {
$message->setBody($textBody);
}
$this->mailer->send($message);
}
}

View File

@@ -0,0 +1,122 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Model;
/**
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
abstract class Group implements GroupInterface
{
/**
* @var mixed
*/
protected $id;
/**
* @var string
*/
protected $name;
/**
* @var array
*/
protected $roles;
/**
* Group constructor.
*
* @param string $name
* @param array $roles
*/
public function __construct($name, $roles = array())
{
$this->name = $name;
$this->roles = $roles;
}
/**
* {@inheritdoc}
*/
public function addRole($role)
{
if (!$this->hasRole($role)) {
$this->roles[] = strtoupper($role);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getId()
{
return $this->id;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->name;
}
/**
* {@inheritdoc}
*/
public function hasRole($role)
{
return in_array(strtoupper($role), $this->roles, true);
}
/**
* {@inheritdoc}
*/
public function getRoles()
{
return $this->roles;
}
/**
* {@inheritdoc}
*/
public function removeRole($role)
{
if (false !== $key = array_search(strtoupper($role), $this->roles, true)) {
unset($this->roles[$key]);
$this->roles = array_values($this->roles);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* {@inheritdoc}
*/
public function setRoles(array $roles)
{
$this->roles = $roles;
return $this;
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Model;
/**
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Christophe Coevoet <stof@notk.org>
*/
interface GroupInterface
{
/**
* @param string $role
*
* @return static
*/
public function addRole($role);
/**
* @return int
*/
public function getId();
/**
* @return string
*/
public function getName();
/**
* @param string $role
*
* @return bool
*/
public function hasRole($role);
/**
* @return array
*/
public function getRoles();
/**
* @param string $role
*
* @return static
*/
public function removeRole($role);
/**
* @param string $name
*
* @return static
*/
public function setName($name);
/**
* @param array $roles
*
* @return static
*/
public function setRoles(array $roles);
}

View File

@@ -0,0 +1,39 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Model;
/**
* Abstract Group Manager implementation which can be used as base class for your
* concrete manager.
*
* @author Christophe Coevoet <stof@notk.org>
*/
abstract class GroupManager implements GroupManagerInterface
{
/**
* {@inheritdoc}
*/
public function createGroup($name)
{
$class = $this->getClass();
return new $class($name);
}
/**
* {@inheritdoc}
*/
public function findGroupByName($name)
{
return $this->findGroupBy(array('name' => $name));
}
}

View File

@@ -0,0 +1,78 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Model;
/**
* Interface to be implemented by group managers. This adds an additional level
* of abstraction between your application, and the actual repository.
*
* All changes to groups should happen through this interface.
*
* @author Christophe Coevoet <stof@notk.org>
*/
interface GroupManagerInterface
{
/**
* Returns an empty group instance.
*
* @param string $name
*
* @return GroupInterface
*/
public function createGroup($name);
/**
* Deletes a group.
*
* @param GroupInterface $group
*/
public function deleteGroup(GroupInterface $group);
/**
* Finds one group by the given criteria.
*
* @param array $criteria
*
* @return GroupInterface
*/
public function findGroupBy(array $criteria);
/**
* Finds a group by name.
*
* @param string $name
*
* @return GroupInterface
*/
public function findGroupByName($name);
/**
* Returns a collection with all group instances.
*
* @return \Traversable
*/
public function findGroups();
/**
* Returns the group's fully qualified class name.
*
* @return string
*/
public function getClass();
/**
* Updates a group.
*
* @param GroupInterface $group
*/
public function updateGroup(GroupInterface $group);
}

View File

@@ -0,0 +1,61 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Model;
/**
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Christophe Coevoet <stof@notk.org>
*/
interface GroupableInterface
{
/**
* Gets the groups granted to the user.
*
* @return \Traversable
*/
public function getGroups();
/**
* Gets the name of the groups which includes the user.
*
* @return array
*/
public function getGroupNames();
/**
* Indicates whether the user belongs to the specified group or not.
*
* @param string $name Name of the group
*
* @return bool
*/
public function hasGroup($name);
/**
* Add a group to the user groups.
*
* @param GroupInterface $group
*
* @return static
*/
public function addGroup(GroupInterface $group);
/**
* Remove a group from the user groups.
*
* @param GroupInterface $group
*
* @return static
*/
public function removeGroup(GroupInterface $group);
}

View File

@@ -0,0 +1,557 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Model;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* Storage agnostic user object.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
abstract class User implements UserInterface, GroupableInterface
{
/**
* @var mixed
*/
protected $id;
/**
* @var string
*/
protected $username;
/**
* @var string
*/
protected $usernameCanonical;
/**
* @var string
*/
protected $email;
/**
* @var string
*/
protected $emailCanonical;
/**
* @var bool
*/
protected $enabled;
/**
* The salt to use for hashing.
*
* @var string
*/
protected $salt;
/**
* Encrypted password. Must be persisted.
*
* @var string
*/
protected $password;
/**
* Plain password. Used for model validation. Must not be persisted.
*
* @var string
*/
protected $plainPassword;
/**
* @var \DateTime|null
*/
protected $lastLogin;
/**
* Random string sent to the user email address in order to verify it.
*
* @var string|null
*/
protected $confirmationToken;
/**
* @var \DateTime|null
*/
protected $passwordRequestedAt;
/**
* @var GroupInterface[]|Collection
*/
protected $groups;
/**
* @var array
*/
protected $roles;
/**
* User constructor.
*/
public function __construct()
{
$this->enabled = false;
$this->roles = array();
}
/**
* @return string
*/
public function __toString()
{
return (string) $this->getUsername();
}
/**
* {@inheritdoc}
*/
public function addRole($role)
{
$role = strtoupper($role);
if ($role === static::ROLE_DEFAULT) {
return $this;
}
if (!in_array($role, $this->roles, true)) {
$this->roles[] = $role;
}
return $this;
}
/**
* {@inheritdoc}
*/
public function serialize()
{
return serialize(array(
$this->password,
$this->salt,
$this->usernameCanonical,
$this->username,
$this->enabled,
$this->id,
$this->email,
$this->emailCanonical,
));
}
/**
* {@inheritdoc}
*/
public function unserialize($serialized)
{
$data = unserialize($serialized);
if (13 === count($data)) {
// Unserializing a User object from 1.3.x
unset($data[4], $data[5], $data[6], $data[9], $data[10]);
$data = array_values($data);
} elseif (11 === count($data)) {
// Unserializing a User from a dev version somewhere between 2.0-alpha3 and 2.0-beta1
unset($data[4], $data[7], $data[8]);
$data = array_values($data);
}
list(
$this->password,
$this->salt,
$this->usernameCanonical,
$this->username,
$this->enabled,
$this->id,
$this->email,
$this->emailCanonical
) = $data;
}
/**
* {@inheritdoc}
*/
public function eraseCredentials()
{
$this->plainPassword = null;
}
/**
* {@inheritdoc}
*/
public function getId()
{
return $this->id;
}
/**
* {@inheritdoc}
*/
public function getUsername()
{
return $this->username;
}
/**
* {@inheritdoc}
*/
public function getUsernameCanonical()
{
return $this->usernameCanonical;
}
/**
* {@inheritdoc}
*/
public function getSalt()
{
return $this->salt;
}
/**
* {@inheritdoc}
*/
public function getEmail()
{
return $this->email;
}
/**
* {@inheritdoc}
*/
public function getEmailCanonical()
{
return $this->emailCanonical;
}
/**
* {@inheritdoc}
*/
public function getPassword()
{
return $this->password;
}
/**
* {@inheritdoc}
*/
public function getPlainPassword()
{
return $this->plainPassword;
}
/**
* Gets the last login time.
*
* @return \DateTime|null
*/
public function getLastLogin()
{
return $this->lastLogin;
}
/**
* {@inheritdoc}
*/
public function getConfirmationToken()
{
return $this->confirmationToken;
}
/**
* {@inheritdoc}
*/
public function getRoles()
{
$roles = $this->roles;
foreach ($this->getGroups() as $group) {
$roles = array_merge($roles, $group->getRoles());
}
// we need to make sure to have at least one role
$roles[] = static::ROLE_DEFAULT;
return array_unique($roles);
}
/**
* {@inheritdoc}
*/
public function hasRole($role)
{
return in_array(strtoupper($role), $this->getRoles(), true);
}
/**
* {@inheritdoc}
*/
public function isAccountNonExpired()
{
return true;
}
/**
* {@inheritdoc}
*/
public function isAccountNonLocked()
{
return true;
}
/**
* {@inheritdoc}
*/
public function isCredentialsNonExpired()
{
return true;
}
public function isEnabled()
{
return $this->enabled;
}
/**
* {@inheritdoc}
*/
public function isSuperAdmin()
{
return $this->hasRole(static::ROLE_SUPER_ADMIN);
}
/**
* {@inheritdoc}
*/
public function removeRole($role)
{
if (false !== $key = array_search(strtoupper($role), $this->roles, true)) {
unset($this->roles[$key]);
$this->roles = array_values($this->roles);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* {@inheritdoc}
*/
public function setUsernameCanonical($usernameCanonical)
{
$this->usernameCanonical = $usernameCanonical;
return $this;
}
/**
* {@inheritdoc}
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* {@inheritdoc}
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* {@inheritdoc}
*/
public function setEmailCanonical($emailCanonical)
{
$this->emailCanonical = $emailCanonical;
return $this;
}
/**
* {@inheritdoc}
*/
public function setEnabled($boolean)
{
$this->enabled = (bool) $boolean;
return $this;
}
/**
* {@inheritdoc}
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* {@inheritdoc}
*/
public function setSuperAdmin($boolean)
{
if (true === $boolean) {
$this->addRole(static::ROLE_SUPER_ADMIN);
} else {
$this->removeRole(static::ROLE_SUPER_ADMIN);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function setPlainPassword($password)
{
$this->plainPassword = $password;
return $this;
}
/**
* {@inheritdoc}
*/
public function setLastLogin(\DateTime $time = null)
{
$this->lastLogin = $time;
return $this;
}
/**
* {@inheritdoc}
*/
public function setConfirmationToken($confirmationToken)
{
$this->confirmationToken = $confirmationToken;
return $this;
}
/**
* {@inheritdoc}
*/
public function setPasswordRequestedAt(\DateTime $date = null)
{
$this->passwordRequestedAt = $date;
return $this;
}
/**
* Gets the timestamp that the user requested a password reset.
*
* @return null|\DateTime
*/
public function getPasswordRequestedAt()
{
return $this->passwordRequestedAt;
}
/**
* {@inheritdoc}
*/
public function isPasswordRequestNonExpired($ttl)
{
return $this->getPasswordRequestedAt() instanceof \DateTime &&
$this->getPasswordRequestedAt()->getTimestamp() + $ttl > time();
}
/**
* {@inheritdoc}
*/
public function setRoles(array $roles)
{
$this->roles = array();
foreach ($roles as $role) {
$this->addRole($role);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getGroups()
{
return $this->groups ?: $this->groups = new ArrayCollection();
}
/**
* {@inheritdoc}
*/
public function getGroupNames()
{
$names = array();
foreach ($this->getGroups() as $group) {
$names[] = $group->getName();
}
return $names;
}
/**
* {@inheritdoc}
*/
public function hasGroup($name)
{
return in_array($name, $this->getGroupNames());
}
/**
* {@inheritdoc}
*/
public function addGroup(GroupInterface $group)
{
if (!$this->getGroups()->contains($group)) {
$this->getGroups()->add($group);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function removeGroup(GroupInterface $group)
{
if ($this->getGroups()->contains($group)) {
$this->getGroups()->removeElement($group);
}
return $this;
}
}

View File

@@ -0,0 +1,230 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Model;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
/**
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
interface UserInterface extends AdvancedUserInterface, \Serializable
{
const ROLE_DEFAULT = 'ROLE_USER';
const ROLE_SUPER_ADMIN = 'ROLE_SUPER_ADMIN';
/**
* Returns the user unique id.
*
* @return mixed
*/
public function getId();
/**
* Sets the username.
*
* @param string $username
*
* @return static
*/
public function setUsername($username);
/**
* Gets the canonical username in search and sort queries.
*
* @return string
*/
public function getUsernameCanonical();
/**
* Sets the canonical username.
*
* @param string $usernameCanonical
*
* @return static
*/
public function setUsernameCanonical($usernameCanonical);
/**
* @param string|null $salt
*
* @return static
*/
public function setSalt($salt);
/**
* Gets email.
*
* @return string
*/
public function getEmail();
/**
* Sets the email.
*
* @param string $email
*
* @return static
*/
public function setEmail($email);
/**
* Gets the canonical email in search and sort queries.
*
* @return string
*/
public function getEmailCanonical();
/**
* Sets the canonical email.
*
* @param string $emailCanonical
*
* @return static
*/
public function setEmailCanonical($emailCanonical);
/**
* Gets the plain password.
*
* @return string
*/
public function getPlainPassword();
/**
* Sets the plain password.
*
* @param string $password
*
* @return static
*/
public function setPlainPassword($password);
/**
* Sets the hashed password.
*
* @param string $password
*
* @return static
*/
public function setPassword($password);
/**
* Tells if the the given user has the super admin role.
*
* @return bool
*/
public function isSuperAdmin();
/**
* @param bool $boolean
*
* @return static
*/
public function setEnabled($boolean);
/**
* Sets the super admin status.
*
* @param bool $boolean
*
* @return static
*/
public function setSuperAdmin($boolean);
/**
* Gets the confirmation token.
*
* @return string|null
*/
public function getConfirmationToken();
/**
* Sets the confirmation token.
*
* @param string|null $confirmationToken
*
* @return static
*/
public function setConfirmationToken($confirmationToken);
/**
* Sets the timestamp that the user requested a password reset.
*
* @param null|\DateTime $date
*
* @return static
*/
public function setPasswordRequestedAt(\DateTime $date = null);
/**
* Checks whether the password reset request has expired.
*
* @param int $ttl Requests older than this many seconds will be considered expired
*
* @return bool
*/
public function isPasswordRequestNonExpired($ttl);
/**
* Sets the last login time.
*
* @param \DateTime|null $time
*
* @return static
*/
public function setLastLogin(\DateTime $time = null);
/**
* Never use this to check if this user has access to anything!
*
* Use the AuthorizationChecker, or an implementation of AccessDecisionManager
* instead, e.g.
*
* $authorizationChecker->isGranted('ROLE_USER');
*
* @param string $role
*
* @return bool
*/
public function hasRole($role);
/**
* Sets the roles of the user.
*
* This overwrites any previous roles.
*
* @param array $roles
*
* @return static
*/
public function setRoles(array $roles);
/**
* Adds a role to the user.
*
* @param string $role
*
* @return static
*/
public function addRole($role);
/**
* Removes a role to the user.
*
* @param string $role
*
* @return static
*/
public function removeRole($role);
}

View File

@@ -0,0 +1,115 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Model;
use FOS\UserBundle\Util\CanonicalFieldsUpdater;
use FOS\UserBundle\Util\PasswordUpdaterInterface;
/**
* Abstract User Manager implementation which can be used as base class for your
* concrete manager.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
abstract class UserManager implements UserManagerInterface
{
private $passwordUpdater;
private $canonicalFieldsUpdater;
public function __construct(PasswordUpdaterInterface $passwordUpdater, CanonicalFieldsUpdater $canonicalFieldsUpdater)
{
$this->passwordUpdater = $passwordUpdater;
$this->canonicalFieldsUpdater = $canonicalFieldsUpdater;
}
/**
* {@inheritdoc}
*/
public function createUser()
{
$class = $this->getClass();
$user = new $class();
return $user;
}
/**
* {@inheritdoc}
*/
public function findUserByEmail($email)
{
return $this->findUserBy(array('emailCanonical' => $this->canonicalFieldsUpdater->canonicalizeEmail($email)));
}
/**
* {@inheritdoc}
*/
public function findUserByUsername($username)
{
return $this->findUserBy(array('usernameCanonical' => $this->canonicalFieldsUpdater->canonicalizeUsername($username)));
}
/**
* {@inheritdoc}
*/
public function findUserByUsernameOrEmail($usernameOrEmail)
{
if (preg_match('/^.+\@\S+\.\S+$/', $usernameOrEmail)) {
$user = $this->findUserByEmail($usernameOrEmail);
if (null !== $user) {
return $user;
}
}
return $this->findUserByUsername($usernameOrEmail);
}
/**
* {@inheritdoc}
*/
public function findUserByConfirmationToken($token)
{
return $this->findUserBy(array('confirmationToken' => $token));
}
/**
* {@inheritdoc}
*/
public function updateCanonicalFields(UserInterface $user)
{
$this->canonicalFieldsUpdater->updateCanonicalFields($user);
}
/**
* {@inheritdoc}
*/
public function updatePassword(UserInterface $user)
{
$this->passwordUpdater->hashPassword($user);
}
/**
* @return PasswordUpdaterInterface
*/
protected function getPasswordUpdater()
{
return $this->passwordUpdater;
}
/**
* @return CanonicalFieldsUpdater
*/
protected function getCanonicalFieldsUpdater()
{
return $this->canonicalFieldsUpdater;
}
}

View File

@@ -0,0 +1,129 @@
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Model;
/**
* Interface to be implemented by user managers. This adds an additional level
* of abstraction between your application, and the actual repository.
*
* All changes to users should happen through this interface.
*
* The class also contains ACL annotations which will only work if you have the
* SecurityExtraBundle installed, otherwise they will simply be ignored.
*
* @author Gordon Franke <info@nevalon.de>
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
interface UserManagerInterface
{
/**
* Creates an empty user instance.
*
* @return UserInterface
*/
public function createUser();
/**
* Deletes a user.
*
* @param UserInterface $user
*/
public function deleteUser(UserInterface $user);
/**
* Finds one user by the given criteria.
*
* @param array $criteria
*
* @return UserInterface|null
*/
public function findUserBy(array $criteria);
/**
* Find a user by its username.
*
* @param string $username
*
* @return UserInterface|null
*/
public function findUserByUsername($username);
/**
* Finds a user by its email.
*
* @param string $email
*
* @return UserInterface|null
*/
public function findUserByEmail($email);
/**
* Finds a user by its username or email.
*
* @param string $usernameOrEmail
*
* @return UserInterface|null
*/
public function findUserByUsernameOrEmail($usernameOrEmail);
/**
* Finds a user by its confirmationToken.
*
* @param string $token
*
* @return UserInterface|null
*/
public function findUserByConfirmationToken($token);
/**
* Returns a collection with all user instances.
*
* @return \Traversable
*/
public function findUsers();
/**
* Returns the user's fully qualified class name.
*
* @return string
*/
public function getClass();
/**
* Reloads a user.
*
* @param UserInterface $user
*/
public function reloadUser(UserInterface $user);
/**
* Updates a user.
*
* @param UserInterface $user
*/
public function updateUser(UserInterface $user);
/**
* Updates the canonical username and email fields for a user.
*
* @param UserInterface $user
*/
public function updateCanonicalFields(UserInterface $user);
/**
* Updates a user password if a plain password is set.
*
* @param UserInterface $user
*/
public function updatePassword(UserInterface $user);
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.change_password.form.factory" class="FOS\UserBundle\Form\Factory\FormFactory">
<argument type="service" id="form.factory" />
<argument>%fos_user.change_password.form.name%</argument>
<argument>%fos_user.change_password.form.type%</argument>
<argument>%fos_user.change_password.form.validation_groups%</argument>
</service>
<service id="fos_user.change_password.form.type" class="FOS\UserBundle\Form\Type\ChangePasswordFormType">
<tag name="form.type" alias="fos_user_change_password" />
<argument>%fos_user.model.user.class%</argument>
</service>
<service id="fos_user.change_password.controller" class="FOS\UserBundle\Controller\ChangePasswordController" public="true">
<argument type="service" id="event_dispatcher" />
<argument type="service" id="fos_user.change_password.form.factory" />
<argument type="service" id="fos_user.user_manager" />
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
</services>
</container>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.command.activate_user" class="FOS\UserBundle\Command\ActivateUserCommand">
<argument type="service" id="fos_user.util.user_manipulator" />
<tag name="console.command" command="fos:user:activate" />
</service>
<service id="fos_user.command.change_password" class="FOS\UserBundle\Command\ChangePasswordCommand">
<argument type="service" id="fos_user.util.user_manipulator" />
<tag name="console.command" command="fos:user:change-password" />
</service>
<service id="fos_user.command.create_user" class="FOS\UserBundle\Command\CreateUserCommand">
<argument type="service" id="fos_user.util.user_manipulator" />
<tag name="console.command" command="fos:user:create" />
</service>
<service id="fos_user.command.deactivate_user" class="FOS\UserBundle\Command\DeactivateUserCommand">
<argument type="service" id="fos_user.util.user_manipulator" />
<tag name="console.command" command="fos:user:deactivate" />
</service>
<service id="fos_user.command.demote_user" class="FOS\UserBundle\Command\DemoteUserCommand">
<argument type="service" id="fos_user.util.user_manipulator" />
<tag name="console.command" command="fos:user:demote" />
</service>
<service id="fos_user.command.promote_user" class="FOS\UserBundle\Command\PromoteUserCommand">
<argument type="service" id="fos_user.util.user_manipulator" />
<tag name="console.command" command="fos:user:promote" />
</service>
</services>
</container>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping>
<mapped-superclass name="FOS\UserBundle\Model\Group" indexed="true">
<field name="name" fieldName="name" type="string" index="true" />
<field name="roles" fieldName="roles" type="mixed" />
</mapped-superclass>
</doctrine-mapping>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd">
<mapped-superclass name="FOS\UserBundle\Model\Group" collection="fos_user_group">
<field name="name" fieldName="name" type="string" />
<field name="roles" fieldName="roles" type="collection" />
<indexes>
<index>
<key name="name" order="asc" />
<option name="safe" value="true" />
<option name="unique" value="true" />
</index>
</indexes>
</mapped-superclass>
</doctrine-mongo-mapping>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<mapped-superclass name="FOS\UserBundle\Model\Group">
<field name="name" column="name" type="string" length="180" unique="true" />
<field name="roles" column="roles" type="array" />
</mapped-superclass>
</doctrine-mapping>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping>
<mapped-superclass name="FOS\UserBundle\Model\User" indexed="true">
<field name="username" fieldName="username" type="string" index="true" />
<field name="usernameCanonical" fieldName="usernameCanonical" type="string" index="true" />
<field name="email" fieldName="email" type="string" index="true" />
<field name="emailCanonical" fieldName="emailCanonical" type="string" index="true" />
<field name="enabled" fieldName="enabled" type="mixed" />
<field name="salt" fieldName="salt" type="string" />
<field name="password" fieldName="password" type="string" />
<field name="lastLogin" fieldName="lastLogin" type="datetime" />
<field name="confirmationToken" fieldName="confirmationToken" type="string" index="true" />
<field name="passwordRequestedAt" fieldName="passwordRequestedAt" type="datetime" />
<field name="roles" fieldName="roles" type="mixed" />
</mapped-superclass>
</doctrine-mapping>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping xmlns="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd">
<mapped-superclass name="FOS\UserBundle\Model\User" collection="fos_user_user">
<field name="username" fieldName="username" type="string" />
<field name="usernameCanonical" fieldName="usernameCanonical" type="string" />
<field name="email" fieldName="email" type="string" />
<field name="emailCanonical" fieldName="emailCanonical" type="string" />
<field name="enabled" fieldName="enabled" type="boolean" />
<field name="salt" fieldName="salt" type="string" />
<field name="password" fieldName="password" type="string" />
<field name="lastLogin" fieldName="lastLogin" type="date" />
<field name="confirmationToken" fieldName="confirmationToken" type="string" />
<field name="passwordRequestedAt" fieldName="passwordRequestedAt" type="date" />
<field name="roles" fieldName="roles" type="collection" />
<indexes>
<index>
<key name="usernameCanonical" order="asc" />
<option name="safe" value="true" />
<option name="unique" value="true" />
</index>
<index>
<key name="emailCanonical" order="asc" />
<option name="safe" value="true" />
<option name="unique" value="true" />
</index>
<index>
<key name="confirmationToken" order="asc" />
<option name="safe" value="true" />
<option name="sparse" value="true" />
<option name="unique" value="true" />
</index>
</indexes>
</mapped-superclass>
</doctrine-mongo-mapping>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<mapped-superclass name="FOS\UserBundle\Model\User">
<field name="username" column="username" type="string" length="180" />
<field name="usernameCanonical" column="username_canonical" type="string" length="180" unique="true" />
<field name="email" column="email" type="string" length="180" />
<field name="emailCanonical" column="email_canonical" type="string" length="180" unique="true" />
<field name="enabled" column="enabled" type="boolean" />
<field name="salt" column="salt" type="string" nullable="true" />
<field name="password" column="password" type="string" />
<field name="lastLogin" column="last_login" type="datetime" nullable="true" />
<field name="confirmationToken" column="confirmation_token" type="string" length="180" unique="true" nullable="true" />
<field name="passwordRequestedAt" column="password_requested_at" type="datetime" nullable="true" />
<field name="roles" column="roles" type="array" />
</mapped-superclass>
</doctrine-mapping>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.user_manager.default" class="FOS\UserBundle\Doctrine\UserManager" public="false">
<argument type="service" id="fos_user.util.password_updater" />
<argument type="service" id="fos_user.util.canonical_fields_updater" />
<argument type="service" id="fos_user.object_manager" />
<argument>%fos_user.model.user.class%</argument>
</service>
<!-- The factory is configured in the DI extension class to support more Symfony versions -->
<service id="fos_user.object_manager" class="Doctrine\Common\Persistence\ObjectManager" public="false">
<argument>%fos_user.model_manager_name%</argument>
</service>
<service id="fos_user.user_listener" class="FOS\UserBundle\Doctrine\UserListener" public="false">
<argument type="service" id="fos_user.util.password_updater" />
<argument type="service" id="fos_user.util.canonical_fields_updater" />
</service>
</services>
</container>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_user.group_manager.class">FOS\UserBundle\Doctrine\GroupManager</parameter>
</parameters>
<services>
<service id="fos_user.group_manager.default" class="%fos_user.group_manager.class%" public="false">
<argument type="service" id="fos_user.object_manager" />
<argument>%fos_user.model.group.class%</argument>
</service>
</services>
</container>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.listener.email_confirmation" class="FOS\UserBundle\EventListener\EmailConfirmationListener">
<tag name="kernel.event_subscriber" />
<argument type="service" id="fos_user.mailer" />
<argument type="service" id="fos_user.util.token_generator" />
<argument type="service" id="router" />
<argument type="service" id="session" />
</service>
</services>
</container>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.listener.flash" class="FOS\UserBundle\EventListener\FlashListener">
<tag name="kernel.event_subscriber" />
<argument type="service" id="session" />
<argument type="service" id="translator" />
</service>
</services>
</container>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.group.form.factory" class="FOS\UserBundle\Form\Factory\FormFactory">
<argument type="service" id="form.factory" />
<argument>%fos_user.group.form.name%</argument>
<argument>%fos_user.group.form.type%</argument>
<argument>%fos_user.group.form.validation_groups%</argument>
</service>
<service id="fos_user.group.form.type" class="FOS\UserBundle\Form\Type\GroupFormType">
<tag name="form.type" alias="fos_user_group" />
<argument>%fos_user.model.group.class%</argument>
</service>
<service id="fos_user.group.controller" class="FOS\UserBundle\Controller\GroupController" public="true">
<argument type="service" id="event_dispatcher" />
<argument type="service" id="fos_user.group.form.factory" />
<argument type="service" id="fos_user.group_manager" />
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
</services>
</container>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.listener.authentication" class="FOS\UserBundle\EventListener\AuthenticationListener">
<tag name="kernel.event_subscriber" />
<argument type="service" id="fos_user.security.login_manager" />
<argument>%fos_user.firewall_name%</argument>
</service>
</services>
</container>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_user.resetting.email.template">@FOSUser/Resetting/email.txt.twig</parameter>
<parameter key="fos_user.registration.confirmation.template">@FOSUser/Registration/email.txt.twig</parameter>
</parameters>
<services>
<service id="fos_user.mailer.default" class="FOS\UserBundle\Mailer\Mailer" public="false">
<argument type="service" id="mailer" />
<argument type="service" id="router" />
<argument type="service" id="templating" />
<argument type="collection">
<argument key="confirmation.template">%fos_user.registration.confirmation.template%</argument>
<argument key="resetting.template">%fos_user.resetting.email.template%</argument>
<argument key="from_email" type="collection">
<argument key="confirmation">%fos_user.registration.confirmation.from_email%</argument>
<argument key="resetting">%fos_user.resetting.email.from_email%</argument>
</argument>
</argument>
<tag name="fos_user.requires_swift" />
</service>
<service id="fos_user.mailer.twig_swift" class="FOS\UserBundle\Mailer\TwigSwiftMailer" public="false">
<argument type="service" id="mailer" />
<argument type="service" id="router" />
<argument type="service" id="twig" />
<argument type="collection">
<argument key="template" type="collection">
<argument key="confirmation">%fos_user.registration.confirmation.template%</argument>
<argument key="resetting">%fos_user.resetting.email.template%</argument>
</argument>
<argument key="from_email" type="collection">
<argument key="confirmation">%fos_user.registration.confirmation.from_email%</argument>
<argument key="resetting">%fos_user.resetting.email.from_email%</argument>
</argument>
</argument>
<tag name="fos_user.requires_swift" />
</service>
<service id="fos_user.mailer.noop" class="FOS\UserBundle\Mailer\NoopMailer" public="false" />
</services>
</container>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.profile.form.factory" class="FOS\UserBundle\Form\Factory\FormFactory">
<argument type="service" id="form.factory" />
<argument>%fos_user.profile.form.name%</argument>
<argument>%fos_user.profile.form.type%</argument>
<argument>%fos_user.profile.form.validation_groups%</argument>
</service>
<service id="fos_user.profile.form.type" class="FOS\UserBundle\Form\Type\ProfileFormType">
<argument>%fos_user.model.user.class%</argument>
<tag name="form.type" alias="fos_user_profile" />
</service>
<service id="fos_user.profile.controller" class="FOS\UserBundle\Controller\ProfileController" public="true">
<argument type="service" id="event_dispatcher" />
<argument type="service" id="fos_user.profile.form.factory" />
<argument type="service" id="fos_user.user_manager" />
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
</services>
</container>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.registration.form.factory" class="FOS\UserBundle\Form\Factory\FormFactory">
<argument type="service" id="form.factory" />
<argument>%fos_user.registration.form.name%</argument>
<argument>%fos_user.registration.form.type%</argument>
<argument>%fos_user.registration.form.validation_groups%</argument>
</service>
<service id="fos_user.registration.form.type" class="FOS\UserBundle\Form\Type\RegistrationFormType">
<tag name="form.type" alias="fos_user_registration" />
<argument>%fos_user.model.user.class%</argument>
</service>
<service id="fos_user.registration.controller" class="FOS\UserBundle\Controller\RegistrationController" public="true">
<argument type="service" id="event_dispatcher" />
<argument type="service" id="fos_user.registration.form.factory" />
<argument type="service" id="fos_user.user_manager" />
<argument type="service" id="security.token_storage" />
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
</services>
</container>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.resetting.form.factory" class="FOS\UserBundle\Form\Factory\FormFactory">
<argument type="service" id="form.factory" />
<argument>%fos_user.resetting.form.name%</argument>
<argument>%fos_user.resetting.form.type%</argument>
<argument>%fos_user.resetting.form.validation_groups%</argument>
</service>
<service id="fos_user.resetting.form.type" class="FOS\UserBundle\Form\Type\ResettingFormType">
<tag name="form.type" alias="fos_user_resetting" />
<argument>%fos_user.model.user.class%</argument>
</service>
<service id="fos_user.listener.resetting" class="FOS\UserBundle\EventListener\ResettingListener">
<tag name="kernel.event_subscriber" />
<argument type="service" id="router" />
<argument>%fos_user.resetting.token_ttl%</argument>
</service>
<service id="fos_user.resetting.controller" class="FOS\UserBundle\Controller\ResettingController" public="true">
<argument type="service" id="event_dispatcher" />
<argument type="service" id="fos_user.resetting.form.factory" />
<argument type="service" id="fos_user.user_manager" />
<argument type="service" id="fos_user.util.token_generator" />
<argument type="service" id="fos_user.mailer" />
<argument>%fos_user.resetting.retry_ttl%</argument>
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
</services>
</container>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<import
resource="@FOSUserBundle/Resources/config/routing/security.xml" />
<import
resource="@FOSUserBundle/Resources/config/routing/profile.xml"
prefix="/profile" />
<import
resource="@FOSUserBundle/Resources/config/routing/registration.xml"
prefix="/register" />
<import
resource="@FOSUserBundle/Resources/config/routing/resetting.xml"
prefix="/resetting" />
<import
resource="@FOSUserBundle/Resources/config/routing/change_password.xml"
prefix="/profile" />
</routes>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="fos_user_change_password" path="/change-password" methods="GET POST">
<default key="_controller">fos_user.change_password.controller:changePasswordAction</default>
</route>
</routes>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="fos_user_group_list" path="/list" methods="GET">
<default key="_controller">fos_user.group.controller:listAction</default>
</route>
<route id="fos_user_group_new" path="/new" methods="GET POST">
<default key="_controller">fos_user.group.controller:newAction</default>
</route>
<route id="fos_user_group_show" path="/{groupName}" methods="GET">
<default key="_controller">fos_user.group.controller:showAction</default>
</route>
<route id="fos_user_group_edit" path="/{groupName}/edit" methods="GET POST">
<default key="_controller">fos_user.group.controller:editAction</default>
</route>
<route id="fos_user_group_delete" path="/{groupName}/delete" methods="GET">
<default key="_controller">fos_user.group.controller:deleteAction</default>
</route>
</routes>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="fos_user_profile_show" path="/" methods="GET">
<default key="_controller">fos_user.profile.controller:showAction</default>
</route>
<route id="fos_user_profile_edit" path="/edit" methods="GET POST">
<default key="_controller">fos_user.profile.controller:editAction</default>
</route>
</routes>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="fos_user_registration_register" path="/" methods="GET POST">
<default key="_controller">fos_user.registration.controller:registerAction</default>
</route>
<route id="fos_user_registration_check_email" path="/check-email" methods="GET">
<default key="_controller">fos_user.registration.controller:checkEmailAction</default>
</route>
<route id="fos_user_registration_confirm" path="/confirm/{token}" methods="GET">
<default key="_controller">fos_user.registration.controller:confirmAction</default>
</route>
<route id="fos_user_registration_confirmed" path="/confirmed" methods="GET">
<default key="_controller">fos_user.registration.controller:confirmedAction</default>
</route>
</routes>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="fos_user_resetting_request" path="/request" methods="GET">
<default key="_controller">fos_user.resetting.controller:requestAction</default>
</route>
<route id="fos_user_resetting_send_email" path="/send-email" methods="POST">
<default key="_controller">fos_user.resetting.controller:sendEmailAction</default>
</route>
<route id="fos_user_resetting_check_email" path="/check-email" methods="GET">
<default key="_controller">fos_user.resetting.controller:checkEmailAction</default>
</route>
<route id="fos_user_resetting_reset" path="/reset/{token}" methods="GET POST">
<default key="_controller">fos_user.resetting.controller:resetAction</default>
</route>
</routes>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="fos_user_security_login" path="/login" methods="GET POST">
<default key="_controller">fos_user.security.controller:loginAction</default>
</route>
<route id="fos_user_security_check" path="/login_check" methods="POST">
<default key="_controller">fos_user.security.controller:checkAction</default>
</route>
<route id="fos_user_security_logout" path="/logout" methods="GET POST">
<default key="_controller">fos_user.security.controller:logoutAction</default>
</route>
</routes>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_user.security.interactive_login_listener.class">FOS\UserBundle\EventListener\LastLoginListener</parameter>
<parameter key="fos_user.security.login_manager.class">FOS\UserBundle\Security\LoginManager</parameter>
</parameters>
<services>
<service id="fos_user.security.interactive_login_listener" class="%fos_user.security.interactive_login_listener.class%">
<tag name="kernel.event_subscriber" />
<argument type="service" id="fos_user.user_manager" />
</service>
<service id="fos_user.security.login_manager" class="%fos_user.security.login_manager.class%">
<argument type="service" id="security.token_storage" />
<argument type="service" id="security.user_checker" />
<argument type="service" id="security.authentication.session_strategy" />
<argument type="service" id="request_stack" />
<argument>null</argument> <!-- remember_me service -->
</service>
<service id="FOS\UserBundle\Security\LoginManagerInterface" alias="fos_user.security.login_manager" public="false" />
<service id="fos_user.user_provider.username" class="FOS\UserBundle\Security\UserProvider" public="false">
<argument type="service" id="fos_user.user_manager" />
</service>
<service id="fos_user.user_provider.username_email" class="FOS\UserBundle\Security\EmailUserProvider" public="false">
<argument type="service" id="fos_user.user_manager" />
</service>
<service id="fos_user.security.controller" class="FOS\UserBundle\Controller\SecurityController" public="true">
<argument type="service" id="security.csrf.token_manager" on-invalid="null" />
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
</services>
</container>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
<class name="FOS\UserBundle\Model\User">
<constraint name="Doctrine\Bundle\CouchDBBundle\Validator\Constraints\UniqueEntity">
<option name="fields">usernameCanonical</option>
<option name="errorPath">username</option>
<option name="message">fos_user.username.already_used</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
<constraint name="Doctrine\Bundle\CouchDBBundle\Validator\Constraints\UniqueEntity">
<option name="fields">emailCanonical</option>
<option name="errorPath">email</option>
<option name="message">fos_user.email.already_used</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
</class>
<class name="FOS\UserBundle\Model\Group">
<constraint name="Doctrine\Bundle\CouchDBBundle\Validator\Constraints\UniqueEntity">
<option name="fields">name</option>
<option name="errorPath">name</option>
<option name="message">fos_group.name.already_used</option>
<option name="groups">
<value>Registration</value>
</option>
</constraint>
</class>
</constraint-mapping>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
<class name="FOS\UserBundle\Model\User">
<constraint name="Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique">
<option name="fields">usernameCanonical</option>
<option name="errorPath">username</option>
<option name="message">fos_user.username.already_used</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
<constraint name="Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique">
<option name="fields">emailCanonical</option>
<option name="errorPath">email</option>
<option name="message">fos_user.email.already_used</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
</class>
<class name="FOS\UserBundle\Model\Group">
<constraint name="Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique">
<option name="fields">name</option>
<option name="errorPath">name</option>
<option name="message">fos_group.name.already_used</option>
<option name="groups">
<value>Registration</value>
</option>
</constraint>
</class>
</constraint-mapping>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
<class name="FOS\UserBundle\Model\User">
<constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
<option name="fields">usernameCanonical</option>
<option name="errorPath">username</option>
<option name="message">fos_user.username.already_used</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
<constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
<option name="fields">emailCanonical</option>
<option name="errorPath">email</option>
<option name="message">fos_user.email.already_used</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
</class>
<class name="FOS\UserBundle\Model\Group">
<constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
<option name="fields">name</option>
<option name="errorPath">name</option>
<option name="message">fos_group.name.already_used</option>
<option name="groups">
<value>Registration</value>
</option>
</constraint>
</class>
</constraint-mapping>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.username_form_type" class="FOS\UserBundle\Form\Type\UsernameFormType">
<tag name="form.type" alias="fos_user_username" />
<argument type="service" id="fos_user.user_to_username_transformer" />
</service>
<service id="fos_user.user_to_username_transformer" class="FOS\UserBundle\Form\DataTransformer\UserToUsernameTransformer" public="false">
<argument type="service" id="fos_user.user_manager" />
</service>
</services>
</container>

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.util.canonicalizer.default" class="FOS\UserBundle\Util\Canonicalizer" public="false" />
<service id="fos_user.util.user_manipulator" class="FOS\UserBundle\Util\UserManipulator">
<argument type="service" id="fos_user.user_manager" />
<argument type="service" id="event_dispatcher" />
<argument type="service" id="request_stack" />
</service>
<service id="fos_user.util.token_generator.default" class="FOS\UserBundle\Util\TokenGenerator" public="false" />
<service id="FOS\UserBundle\Util\TokenGeneratorInterface" alias="fos_user.util.token_generator" public="false" />
<service id="fos_user.util.password_updater" class="FOS\UserBundle\Util\PasswordUpdater" public="false">
<argument type="service" id="security.encoder_factory" />
</service>
<service id="FOS\UserBundle\Util\PasswordUpdaterInterface" alias="fos_user.util.password_updater" public="false" />
<service id="fos_user.util.canonical_fields_updater" class="FOS\UserBundle\Util\CanonicalFieldsUpdater" public="false">
<argument type="service" id="fos_user.util.username_canonicalizer" />
<argument type="service" id="fos_user.util.email_canonicalizer" />
</service>
<service id="FOS\UserBundle\Util\CanonicalFieldsUpdater" alias="fos_user.util.canonical_fields_updater" public="false" />
<service id="FOS\UserBundle\Model\UserManagerInterface" alias="fos_user.user_manager" public="false" />
</services>
</container>

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
<class name="FOS\UserBundle\Model\User">
<property name="username">
<constraint name="NotBlank">
<option name="message">fos_user.username.blank</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
<constraint name="Length">
<option name="min">2</option>
<option name="minMessage">fos_user.username.short</option>
<option name="max">180</option>
<option name="maxMessage">fos_user.username.long</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
</property>
<property name="email">
<constraint name="NotBlank">
<option name="message">fos_user.email.blank</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
<constraint name="Length">
<option name="min">2</option>
<option name="minMessage">fos_user.email.short</option>
<option name="max">180</option>
<option name="maxMessage">fos_user.email.long</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
<constraint name="Email">
<option name="message">fos_user.email.invalid</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
</option>
</constraint>
</property>
<property name="plainPassword">
<constraint name="NotBlank">
<option name="message">fos_user.password.blank</option>
<option name="groups">
<value>Registration</value>
<value>ResetPassword</value>
<value>ChangePassword</value>
</option>
</constraint>
<constraint name="Length">
<option name="min">2</option>
<option name="max">4096</option>
<option name="minMessage">fos_user.password.short</option>
<option name="groups">
<value>Registration</value>
<value>Profile</value>
<value>ResetPassword</value>
<value>ChangePassword</value>
</option>
</constraint>
</property>
</class>
<class name="FOS\UserBundle\Model\Group">
<property name="name">
<constraint name="NotBlank">
<option name="message">fos_user.group.blank</option>
<option name="groups">Registration</option>
</constraint>
<constraint name="Length">
<option name="min">2</option>
<option name="minMessage">fos_user.group.short</option>
<option name="max">180</option>
<option name="maxMessage">fos_user.group.long</option>
<option name="groups">Registration</option>
</constraint>
</property>
</class>
</constraint-mapping>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_user.validator.initializer" class="FOS\UserBundle\Validator\Initializer" public="false">
<tag name="validator.initializer" />
<argument type="service" id="fos_user.util.canonical_fields_updater" />
</service>
</services>
</container>

View File

@@ -0,0 +1,322 @@
FOSUserBundle Invitation
========================
Require an invitation to create a new user is a pattern mostly used for
early stage of a project. User enter their invitation code in order to
register.
Invitation model
----------------
First we need to add the invitation entity. An invitation is represented
by a unique code/identifier generated in the constructor::
<?php
// src/AppBundle/Entity/Invitation.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/** @ORM\Entity */
class Invitation
{
/** @ORM\Id @ORM\Column(type="string", length=6) */
protected $code;
/** @ORM\Column(type="string", length=256) */
protected $email;
/**
* When sending invitation be sure to set this value to `true`
*
* It can prevent invitations from being sent twice
*
* @ORM\Column(type="boolean")
*/
protected $sent = false;
public function __construct()
{
// generate identifier only once, here a 6 characters length code
$this->code = substr(md5(uniqid(rand(), true)), 0, 6);
}
public function getCode()
{
return $this->code;
}
public function getEmail()
{
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
}
public function isSent()
{
return $this->sent;
}
public function send()
{
$this->sent = true;
}
}
Next we map our ``Invitation`` entity to our ``User`` with a one-to-one association::
<?php
// src/AppBundel/Entity/User.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/** @ORM\Entity */
class User extends \FOS\UserBundle\Model\User
{
/** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue(strategy="AUTO") */
protected $id;
/**
* @ORM\OneToOne(targetEntity="Invitation")
* @ORM\JoinColumn(referencedColumnName="code")
* @Assert\NotNull(message="Your invitation is wrong", groups={"Registration"})
*/
protected $invitation;
public function setInvitation(Invitation $invitation)
{
$this->invitation = $invitation;
}
public function getInvitation()
{
return $this->invitation;
}
}
Add invitation to RegistrationFormType
--------------------------------------
Override the default registration form with your own::
<?php
// src/AppBundle/Form/RegistrationFormType.php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class RegistrationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('invitation', 'AppBundle\Form\InvitationFormType');
}
public function getParent()
{
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
}
public function getBlockPrefix()
{
return 'app_user_registration';
}
// Not necessary on Symfony 3+
public function getName()
{
return 'app_user_registration';
}
}
Create the invitation field::
<?php
// src/AppBundle/Form/InvitationFormType.php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityRepository;
use AppBundle\Form\DataTransformer\InvitationToCodeTransformer;
class InvitationFormType extends AbstractType
{
private $invitationTransformer;
public function __construct(InvitationToCodeTransformer $invitationTransformer)
{
$this->invitationTransformer = $invitationTransformer;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addModelTransformer($this->invitationTransformer);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'class' => 'AppBundle\Entity\Invitation',
'required' => true,
));
}
public function getParent()
{
return 'Symfony\Component\Form\Extension\Core\Type\TextType';
}
public function getBlockPrefix()
{
return 'app_invitation_type';
}
// Not necessary on Symfony 3+
public function getName()
{
return 'app_invitation_type';
}
}
Create the custom data transformer::
<?php
// src/AppBundle/Form/DataTransformer/InvitationToCodeTransformer.php
namespace AppBundle\Form\DataTransformer;
use AppBundle\Entity\Invitation;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
/**
* Transforms an Invitation to an invitation code.
*/
class InvitationToCodeTransformer implements DataTransformerInterface
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function transform($value)
{
if (null === $value) {
return null;
}
if (!$value instanceof Invitation) {
throw new UnexpectedTypeException($value, 'AppBundle\Entity\Invitation');
}
return $value->getCode();
}
public function reverseTransform($value)
{
if (null === $value || '' === $value) {
return null;
}
if (!is_string($value)) {
throw new UnexpectedTypeException($value, 'string');
}
$dql = <<<DQL
SELECT i
FROM AppBundle:Invitation i
WHERE i.code = :code
AND NOT EXISTS(SELECT 1 FROM AppBundle:User u WHERE u.invitation = i)
DQL;
return $this->entityManager
->createQuery($dql)
->setParameter('code', $value)
->setMaxResults(1)
->getOneOrNullResult();
}
}
Register your custom form type in the container:
.. configuration-block::
.. code-block:: yaml
# app/config/services.yml
services:
app.form.registration:
class: AppBundle\Form\RegistrationFormType
tags:
- { name: "form.type", alias: "app_user_registration" }
app.form.invitation:
class: AppBundle\Form\InvitationFormType
arguments: ['@app.form.data_transformer.invitation']
tags:
- { name: "form.type", alias: "app_invitation_type" }
app.form.data_transformer.invitation:
class: AppBundle\Form\DataTransformer\InvitationToCodeTransformer
arguments: ['@doctrine.orm.entity_manager']
public: false
.. code-block:: xml
<!-- app/config/services.xml -->
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="app.form.registration" class="AppBundle\Form\RegistrationFormType">
<tag name="form.type" alias="app_user_registration" />
</service>
<service id="app.form.invitation" class="AppBundle\Form\InvitationFormType">
<argument type="service" id="app.form.data_transformer.invitation"/>
<tag name="form.type" alias="app_invitation_type" />
</service>
<service id="app.form.data_transformer.invitation"
class="AppBundle\Form\DataTransformer\InvitationToCodeTransformer"
public="false
>
<argument type="service" id="doctrine.orm.entity_manager"/>
</service>
</services>
</container>
Next overwrite the default ``RegistrationFormType`` with the one just created :
.. code-block:: yaml
# app/config/config.yml
fos_user:
registration:
form:
type: AppBundle\Form\RegistrationFormType
You are done, go to your registration form to see the result.

View File

@@ -0,0 +1,47 @@
FOSUserBundle Canonicalization
==============================
FOSUserBundle stores canonicalized versions of the username and the email
which are used when querying and checking for uniqueness.
The default implementation simply makes them case-insensitive to avoid having
users whose username only differs because of the case. It uses :phpfunction:`mb_convert_case`
to achieve this result.
.. caution::
If you do not have the mbstring extension installed you will need to
define your own canonicalizer.
Replacing the canonicalizers
----------------------------
If you want to change the way the canonical fields are populated, simply
create a class implementing ``FOS\UserBundle\Util\CanonicalizerInterface``
and register it as a service:
.. code-block:: yaml
# app/config/services.yml
services:
app.my_canonicalizer:
class: AppBundle\Util\CustomCanonicalizer
public: false
You can now configure FOSUserBundle to use your own implementation:
.. code-block:: yaml
# app/config/config.yml
fos_user:
# ...
service:
email_canonicalizer: app.my_canonicalizer
username_canonicalizer: app.my_canonicalizer
You can of course use different services for each field if you don't want
to use the same logic.
.. note::
The default implementation has the id ``fos_user.util.canonicalizer.default``.

View File

@@ -0,0 +1,168 @@
FOSUserBundle Command Line Tools
================================
The FOSUserBundle provides a number of command line utilities to help manage your
application's users. Commands are available for the following tasks:
1. Create a User
2. Activate a User
3. Deactivate a User
4. Promote a User
5. Demote a User
6. Change a User's Password
.. note::
You must have correctly installed and configured the FOSUserBundle before
using these commands.
.. note::
This documentation references the console as ``bin/console``, which is
the Symfony 3 location. If you use Symfony 2.x, use ``app/console`` instead.
Create a User
-------------
You can use the ``fos:user:create`` command to create a new user for your application.
The command takes three arguments, the ``username``, ``email``, and ``password`` for
the user you are creating.
For example if you wanted to create a user with username ``testuser``, with email
``test@example.com`` and password ``p@ssword``, you would run the command as follows.
.. code-block:: bash
$ php bin/console fos:user:create testuser test@example.com p@ssword
If any of the required arguments are not passed to the command, an interactive prompt
will ask you to enter them. For example, if you ran the command as follows, then
you would be prompted to enter the ``email`` and ``password`` for the user
you want to create.
.. code-block:: bash
$ php bin/console fos:user:create testuser
There are two options that you can pass to the command as well. They are
``--super-admin`` and ``--inactive``.
Specifying the ``--super-admin`` option will flag the user as a super admin when
the user is created. A super admin has access to any part of your application.
An example is provided below:
.. code-block:: bash
$ php bin/console fos:user:create adminuser --super-admin
If you specify the ``--inactive`` option, then the user that you create will no be
able to log in until he is activated.
.. code-block:: bash
$ php bin/console fos:user:create testuser --inactive
Activate a User
---------------
The ``fos:user:activate`` command activates an inactive user. The only argument
that the command requires is the ``username`` of the user who should be activated.
If no ``username`` is specified then an interactive prompt will ask you
to enter one. An example of using this command is listed below.
.. code-block:: bash
$ php bin/console fos:user:activate testuser
Deactivate a User
-----------------
The ``fos:user:deactivate`` command deactivates a user. Just like the activate
command, the only required argument is the ``username`` of the user who should be
activated. If no ``username`` is specified then an interactive prompt will ask you
to enter one. Below is an example of using this command.
.. code-block:: bash
$ php bin/console fos:user:deactivate testuser
Promote a User
--------------
The ``fos:user:promote`` command enables you to add a role to a user or make the
user a super administrator.
If you would like to add a role to a user you simply pass the ``username`` of the
user as the first argument to the command and the ``role`` to add to the user as
the second.
.. code-block:: bash
$ php bin/console fos:user:promote testuser ROLE_ADMIN
You can promote a user to a super administrator by passing the ``--super`` option
after specifying the ``username``.
.. code-block:: bash
$ php bin/console fos:user:promote testuser --super
If any of the arguments to the command are not specified then an interactive
prompt will ask you to enter them.
.. note::
You may not specify the ``role`` argument and the ``--super`` option simultaneously.
.. caution::
Changes will not be applied until the user logs out and back in again.
Demote a User
-------------
The ``fos:user:demote`` command is similar to the promote command except that
instead of adding a role to the user it removes it. You can also revoke a user's
super administrator status with this command.
If you would like to remove a role from a user you simply pass the ``username`` of
the user as the first argument to the command and the ``role`` to remove as the
second.
.. code-block:: bash
$ php bin/console fos:user:demote testuser ROLE_ADMIN
To revoke the super administrator status of a user, simply pass the ``username`` as
an argument to the command as well as the ``--super`` option.
.. code-block:: bash
$ php bin/console fos:user:demote testuser --super
If any of the arguments to the command are not specified then an interactive
prompt will ask you to enter them.
.. note::
You may not specify the ``role`` argument and the ``--super`` option simultaneously.
.. caution::
Changes will not be applied until the user logs out and back in again. This has
implications for the way in which you configure sessions in your application since
you want to ensure that users are demoted as quickly as possible.
Change a User's Password
------------------------
The ``fos:user:change-password`` command provides an easy way to change a user's
password. The command takes two arguments, the ``username`` of the user whose
password you would like to change and the new ``password``.
.. code-block:: bash
$ php bin/console fos:user:change-password testuser newp@ssword
If you do not specify the ``password`` argument then an interactive prompt will
ask you to enter one.

View File

@@ -0,0 +1,65 @@
FOSUserBundle Configuration Reference
=====================================
All available configuration options are listed below with their default values.
.. code-block:: yaml
fos_user:
db_driver: ~ # Required
firewall_name: ~ # Required
user_class: ~ # Required
use_listener: true
use_flash_notifications: true
use_authentication_listener: true
use_username_form_type: true
model_manager_name: null # change it to the name of your entity/document manager if you don't want to use the default one.
from_email:
address: webmaster@example.com
sender_name: webmaster
profile:
form:
type: FOS\UserBundle\Form\Type\ProfileFormType
name: fos_user_profile_form
validation_groups: [Profile, Default]openssl_get_cipher_methods will be used. See http://php.net/manual/function.openssl-get-cipher-methods.php
change_password:
form:
type: FOS\UserBundle\Form\Type\ChangePasswordFormType
name: fos_user_change_password_form
validation_groups: [ChangePassword, Default]
registration:
confirmation:
from_email: # Use this node only if you don't want the global email address for the confirmation email
address: ...
sender_name: ...
enabled: false # change to true for required email confirmation
template: '@FOSUser/Registration/email.txt.twig'
form:
type: FOS\UserBundle\Form\Type\RegistrationFormType
name: fos_user_registration_form
validation_groups: [Registration, Default]
resetting:
retry_ttl: 7200 # Value in seconds, logic will use as hours
token_ttl: 86400
email:
from_email: # Use this node only if you don't want the global email address for the resetting email
address: ...
sender_name: ...
template: '@FOSUser/Resetting/email.txt.twig'
form:
type: FOS\UserBundle\Form\Type\ResettingFormType
name: fos_user_resetting_form
validation_groups: [ResetPassword, Default]
service:
mailer: fos_user.mailer.default
email_canonicalizer: fos_user.util.canonicalizer.default
username_canonicalizer: fos_user.util.canonicalizer.default
token_generator: fos_user.util.token_generator.default
user_manager: fos_user.user_manager.default
group:
group_class: ~ # Required when using groups
group_manager: fos_user.group_manager.default
form:
type: FOS\UserBundle\Form\Type\GroupFormType
name: fos_user_group_form
validation_groups: [Registration, Default]

View File

@@ -0,0 +1,104 @@
Hooking into the controllers
============================
The controllers packaged with the FOSUserBundle provide a lot of
functionality that is sufficient for general use cases. But, you might find
that you need to extend that functionality and add some logic that suits the
specific needs of your application.
For this purpose, the controllers are dispatching events in many places in
their logic. All events can be found in the constants of the
``FOS\UserBundle\FOSUserEvents`` class.
All controllers follow the same convention: they dispatch a ``SUCCESS`` event
when the form is valid before saving the user, and a ``COMPLETED`` event when
it is done. Thus, all ``SUCCESS`` events allow you to set a response if you
don't want the default redirection. And all ``COMPLETED`` events give you access
to the response before it is returned.
Controllers with a form also dispatch an ``INITIALIZE`` event after the entity is
fetched, but before the form is created.
For instance, this listener will change the redirection after the password
resetting to go to the homepage instead of the profile::
// src/Acme/UserBundle/EventListener/PasswordResettingListener.php
namespace Acme\UserBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* Listener responsible to change the redirection at the end of the password resetting
*/
class PasswordResettingListener implements EventSubscriberInterface
{
private $router;
public function __construct(UrlGeneratorInterface $router)
{
$this->router = $router;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::RESETTING_RESET_SUCCESS => 'onPasswordResettingSuccess',
);
}
public function onPasswordResettingSuccess(FormEvent $event)
{
$url = $this->router->generate('homepage');
$event->setResponse(new RedirectResponse($url));
}
}
You can then register this listener:
.. configuration-block::
.. code-block:: yaml
# src/Acme/UserBundle/Resources/config/services.yml
services:
acme_user.password_resetting:
class: Acme\UserBundle\EventListener\PasswordResettingListener
arguments: ['@router']
tags:
- { name: kernel.event_subscriber }
.. code-block:: xml
<!-- src/Acme/UserBundle/Resources/config/services.xml -->
<service id="acme_user.password_resetting" class="Acme\UserBundle\EventListener\PasswordResettingListener">
<tag name="kernel.event_subscriber"/>
<argument type="service" id="router"/>
</service>
Registration success listener with enabled confirmation at the same time
------------------------------------------------------------------------
When you have registration confirmation and you want to hook up to
``FOSUserEvents::REGISTRATION_SUCCESS`` event you will have to prioritize this listener to be called
before ``FOS\UserBundle\EventListener\EmailConfirmationListener::onRegistrationSuccess``::
public static function getSubscribedEvents()
{
return [
FOSUserEvents::REGISTRATION_SUCCESS => [
['onRegistrationSuccess', -10],
],
];
}
If you don't do it, ``EmailConfirmationListener`` will be called earlier and you will be redirected to
``fos_user_registration_check_email`` route.

Some files were not shown because too many files have changed in this diff Show More