Skip to content

Commit

Permalink
implemented email-confirmation
Browse files Browse the repository at this point in the history
  • Loading branch information
wachterjohannes committed Jun 27, 2016
1 parent f8da13c commit 60c4c37
Show file tree
Hide file tree
Showing 21 changed files with 725 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Controller/AbstractController.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ protected function checkAutoLogin($type)
*
* @return Response
*/
protected function renderTemplate($type, $data)
protected function renderTemplate($type, $data = [])
{
return $this->render(
$this->getCommunityManager($this->getWebspaceKey())->getConfigTypeProperty(
Expand Down
50 changes: 50 additions & 0 deletions Controller/EmailConfirmationController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

/*
* This file is part of Sulu.
*
* (c) MASSIVE ART WebServices GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\CommunityBundle\Controller;

use Sulu\Bundle\CommunityBundle\DependencyInjection\Configuration;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* Handle email confirmation.
*/
class EmailConfirmationController extends AbstractController
{
const TYPE = Configuration::TYPE_EMAIL_CONFIRMATION;

/**
* Overwrite user email with contact email.
*
* @param Request $request
*
* @return Response
*/
public function indexAction(Request $request)
{
$repository = $this->get('sulu_community.email_confirmation.repository');

$success = false;
$token = $repository->findByToken($request->get('token'));

if ($token !== null) {
$user = $token->getUser();
$user->setEmail($user->getContact()->getMainEmail());
$this->get('doctrine.orm.entity_manager')->remove($token);
$this->saveEntities();

$success = true;
}

return $this->renderTemplate(self::TYPE, ['success' => $success]);
}
}
17 changes: 17 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Configuration implements ConfigurationInterface
const TYPE_BLACKLIST_CONFIRMED = 'blacklist_confirmed';
const TYPE_BLACKLIST_DENIED = 'blacklist_denied';
const TYPE_PROFILE = 'profile';
const TYPE_EMAIL_CONFIRMATION = 'email_confirmation';

public static $TYPES = [
self::TYPE_LOGIN,
Expand Down Expand Up @@ -139,6 +140,22 @@ public function getConfigTreeBuilder()
->end()
->end()
->end()
// Email change
->arrayNode(self::TYPE_EMAIL_CONFIRMATION)
->addDefaultsIfNotSet()
->children()
// Email change configuration
->scalarNode(self::TEMPLATE)->defaultValue('SuluCommunityBundle:EmailConfirmation:success.html.twig')->end()
->arrayNode(self::EMAIL)
->addDefaultsIfNotSet()
->children()
->scalarNode(self::EMAIL_SUBJECT)->defaultValue('E-Mail change')->end()
->scalarNode(self::EMAIL_ADMIN_TEMPLATE)->defaultValue(null)->end()
->scalarNode(self::EMAIL_USER_TEMPLATE)->defaultValue('SuluCommunityBundle:EmailConfirmation:email.html.twig')->end()
->end()
->end()
->end()
->end()
// Confirmation
->arrayNode(self::TYPE_CONFIRMATION)
->addDefaultsIfNotSet()
Expand Down
87 changes: 87 additions & 0 deletions Entity/EmailConfirmationToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

/*
* This file is part of Sulu.
*
* (c) MASSIVE ART WebServices GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\CommunityBundle\Entity;

use Sulu\Component\Security\Authentication\UserInterface;

/**
* Represents a email-confirmation request.
*/
class EmailConfirmationToken
{
/**
* @var int
*/
private $id;

/**
* @var string
*/
private $token;

/**
* @var UserInterface
*/
private $user;

/**
* @param UserInterface $user
*/
public function __construct(UserInterface $user)
{
$this->user = $user;
}

/**
* Returns id.
*
* @return int
*/
public function getId()
{
return $this->id;
}

/**
* Returns token.
*
* @return string
*/
public function getToken()
{
return $this->token;
}

/**
* Set token.
*
* @param string $token
*
* @return $this
*/
public function setToken($token)
{
$this->token = $token;

return $this;
}

/**
* Returns user.
*
* @return UserInterface
*/
public function getUser()
{
return $this->user;
}
}
59 changes: 59 additions & 0 deletions Entity/EmailConfirmationTokenRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/*
* This file is part of Sulu.
*
* (c) MASSIVE ART WebServices GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\CommunityBundle\Entity;

use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Sulu\Component\Persistence\Repository\ORM\EntityRepository;
use Symfony\Component\Security\Core\User\UserInterface;

/**
* Provides special queries for email-confirmation-tokens.
*/
class EmailConfirmationTokenRepository extends EntityRepository
{
/**
* Return email-confirmation for given token.
*
* @param string $token
*
* @return EmailConfirmationToken
*/
public function findByToken($token)
{
try {
return $this->findOneBy(['token' => $token]);
} catch (NonUniqueResultException $e) {
return;
} catch (NoResultException $e) {
return;
}
}

/**
* Return email-confirmation for given token.
*
* @param UserInterface $user
*
* @return EmailConfirmationToken
*/
public function findByUser($user)
{
try {
return $this->findOneBy(['user' => $user]);
} catch (NonUniqueResultException $e) {
return;
} catch (NoResultException $e) {
return;
}
}
}
99 changes: 99 additions & 0 deletions EventListener/EmailConfirmationListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

/*
* This file is part of Sulu.
*
* (c) MASSIVE ART WebServices GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\CommunityBundle\EventListener;

use Doctrine\ORM\EntityManagerInterface;
use Sulu\Bundle\CommunityBundle\DependencyInjection\Configuration;
use Sulu\Bundle\CommunityBundle\Entity\EmailConfirmationToken;
use Sulu\Bundle\CommunityBundle\Entity\EmailConfirmationTokenRepository;
use Sulu\Bundle\CommunityBundle\Event\CommunityEvent;
use Sulu\Bundle\CommunityBundle\Mail\Mail;
use Sulu\Bundle\CommunityBundle\Mail\MailFactoryInterface;
use Sulu\Bundle\SecurityBundle\Util\TokenGeneratorInterface;

/**
* Compares user-email and contact main-email.
* If they are different a confirmation link will be send.
*/
class EmailConfirmationListener
{
/**
* @var MailFactoryInterface
*/
private $mailFactory;

/**
* @var EntityManagerInterface
*/
private $entityManager;

/**
* @var TokenGeneratorInterface
*/
private $tokenGenerator;

/**
* @var EmailConfirmationTokenRepository
*/
private $emailConformationRepository;

/**
* @param MailFactoryInterface $mailFactory
* @param EntityManagerInterface $entityManager
* @param EmailConfirmationTokenRepository $emailConformationRepository
* @param TokenGeneratorInterface $tokenGenerator
*/
public function __construct(
MailFactoryInterface $mailFactory,
EntityManagerInterface $entityManager,
EmailConfirmationTokenRepository $emailConformationRepository,
TokenGeneratorInterface $tokenGenerator
) {
$this->mailFactory = $mailFactory;
$this->entityManager = $entityManager;
$this->emailConformationRepository = $emailConformationRepository;
$this->tokenGenerator = $tokenGenerator;
}

/**
* Send confirmation-email if email-address has changed.
*
* @param CommunityEvent $event
*/
public function sendConfirmationOnEmailChange(CommunityEvent $event)
{
$user = $event->getUser();
if ($user->getEmail() === $user->getContact()->getMainEmail()) {
return;
}

$entity = $this->emailConformationRepository->findByUser($user);
$token = $this->tokenGenerator->generateToken();
if (null === $entity) {
$entity = new EmailConfirmationToken($user);
$this->entityManager->persist($entity);
}

$entity->setToken($token);
$this->entityManager->flush();

$this->mailFactory->sendEmails(
Mail::create(
$event->getConfigProperty(Configuration::EMAIL_FROM),
$event->getConfigProperty(Configuration::EMAIL_TO),
$event->getConfigTypeProperty(Configuration::TYPE_EMAIL_CONFIRMATION, Configuration::EMAIL)
)->setUserEmail($user->getContact()->getMainEmail()),
$user,
['token' => $entity->getToken()]
);
}
}
2 changes: 2 additions & 0 deletions Form/Type/ProfileContactType.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
Expand Down Expand Up @@ -45,6 +46,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)

$builder->add('first_name', TextType::class);
$builder->add('last_name', TextType::class);
$builder->add('main_email', EmailType::class);
$builder->add('avatar', FileType::class, ['mapped' => false, 'required' => false]);

$builder->add(
Expand Down
18 changes: 18 additions & 0 deletions Form/Type/ProfileNoteType.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@

use Sulu\Bundle\ContactBundle\Entity\Note;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
* Profile note form.
*/
class ProfileNoteType extends AbstractType
{
/**
Expand All @@ -25,6 +29,20 @@ class ProfileNoteType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('value', TextType::class, ['required' => false, 'label' => 'Note']);
$builder->get('value')->addViewTransformer(
new CallbackTransformer(
function ($value) {
return $value;
},
function ($value) {
if ($value === null) {
return '';
}

return $value;
}
)
);
}

/**
Expand Down
Loading

0 comments on commit 60c4c37

Please sign in to comment.