Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature completion listener and form #11

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
89 changes: 89 additions & 0 deletions Controller/CompletionController.php
@@ -0,0 +1,89 @@
<?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 Sulu\Bundle\CommunityBundle\EventListener\CompletionListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;

/**
* Handles the completion page.
*/
class CompletionController extends AbstractController
{
const TYPE = Configuration::TYPE_COMPLETION;

/**
* Handle registration form.
*
* @param Request $request
*
* @return Response
*/
public function indexAction(Request $request)
{
$user = $this->getUser();

if (!$user) {
throw new HttpException(403, 'You need to be logged in for completion form.');
}

$communityManager = $this->getCommunityManager($this->getWebspaceKey());

// Create Form
$form = $this->createForm(
$communityManager->getConfigTypeProperty(self::TYPE, Configuration::FORM_TYPE),
$user,
$communityManager->getConfigTypeProperty(self::TYPE, Configuration::FORM_TYPE_OPTIONS)
);

$form->handleRequest($request);
$success = false;

// Handle Form Success
if ($form->isSubmitted() && $form->isValid()) {
$user = $form->getData();

// Completion User
$communityManager->completion($user);

// Save User
$this->saveEntities();

// Redirect
$session = $request->getSession();
$redirectTo = $session->get(CompletionListener::SESSION_STORE);

if (!$redirectTo) {
$redirectTo = $communityManager->getConfigTypeProperty(self::TYPE, Configuration::REDIRECT_TO);
} else {
$session->remove(CompletionListener::SESSION_STORE);
}

if ($redirectTo) {
return $this->redirect($redirectTo);
}

$success = true;
}

return $this->renderTemplate(
self::TYPE,
[
'form' => $form->createView(),
'success' => $success,
]
);
}
}
@@ -0,0 +1,56 @@
<?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\DependencyInjection\CompilerPass;

use Sulu\Bundle\CommunityBundle\DependencyInjection\Configuration;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
* Register the completion listener when validators are configured.
*/
class CommunityValidatorCompilerPass implements CompilerPassInterface
{
const COMPLETION_LISTENER_SERVICE_ID = 'sulu_community.completion_listener';

/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
// If no listener exists do nothing
if (!$container->hasDefinition(self::COMPLETION_LISTENER_SERVICE_ID)) {
return;
}

// Create Validator References
$config = $container->getParameter('sulu_community.config');

foreach ($config[Configuration::WEBSPACES] as $webspaceKey => $webspaceConfig) {
// Get Completion Validator
$validatorId = $webspaceConfig[Configuration::TYPE_COMPLETION][Configuration::SERVICE];

if ($validatorId) {
$validators[$webspaceKey] = new Reference($validatorId);
}
}

// Register request listener only when validator exists.
if (!empty($validators)) {
$definition = $container->getDefinition(self::COMPLETION_LISTENER_SERVICE_ID);
$definition->replaceArgument(3, $validators);
} else {
$container->removeDefinition(self::COMPLETION_LISTENER_SERVICE_ID);
}
}
}
25 changes: 25 additions & 0 deletions DependencyInjection/Configuration.php
Expand Up @@ -11,6 +11,7 @@

namespace Sulu\Bundle\CommunityBundle\DependencyInjection;

use Sulu\Bundle\CommunityBundle\Form\Type\CompletionType;
use Sulu\Bundle\CommunityBundle\Form\Type\PasswordForgetType;
use Sulu\Bundle\CommunityBundle\Form\Type\PasswordResetType;
use Sulu\Bundle\CommunityBundle\Form\Type\RegistrationType;
Expand All @@ -36,6 +37,7 @@ class Configuration implements ConfigurationInterface
// Form types
const TYPE_LOGIN = 'login';
const TYPE_REGISTRATION = 'registration';
const TYPE_COMPLETION = 'completion';
const TYPE_CONFIRMATION = 'confirmation';
const TYPE_PASSWORD_FORGET = 'password_forget';
const TYPE_PASSWORD_RESET = 'password_reset';
Expand All @@ -51,6 +53,7 @@ class Configuration implements ConfigurationInterface

// Type configurations
const TEMPLATE = 'template';
const SERVICE = 'service';
const EMBED_TEMPLATE = 'embed_template';
const FORM_TYPE = 'type';
const FORM_TYPE_OPTIONS = 'options';
Expand Down Expand Up @@ -224,6 +227,28 @@ public function getConfigTreeBuilder()
->end()
->end()
->end()
// Completion
->arrayNode(self::TYPE_COMPLETION)
->addDefaultsIfNotSet()
->children()
// Completion Configuration
->scalarNode(self::SERVICE)->defaultValue(null)->end()
->scalarNode(self::TEMPLATE)->defaultValue('SuluCommunityBundle:community:completion.html.twig')->end()
->scalarNode(self::FORM_TYPE)->defaultValue(CompletionType::class)->end()
->arrayNode(self::FORM_TYPE_OPTIONS)
->addDefaultsIfNotSet()
->end()
->scalarNode(self::REDIRECT_TO)->defaultValue('/')->end()
->arrayNode(self::EMAIL)
->addDefaultsIfNotSet()
->children()
->scalarNode(self::EMAIL_SUBJECT)->defaultValue('Completion')->end()
->scalarNode(self::EMAIL_ADMIN_TEMPLATE)->defaultValue(null)->end()
->scalarNode(self::EMAIL_USER_TEMPLATE)->defaultValue(null)->end()
->end()
->end()
->end()
->end()
->end()
->end()
->end()
Expand Down
136 changes: 136 additions & 0 deletions EventListener/CompletionListener.php
@@ -0,0 +1,136 @@
<?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 Sulu\Bundle\CommunityBundle\Validator\User\CompletionInterface;
use Sulu\Bundle\SecurityBundle\Entity\User;
use Sulu\Component\Webspace\Analyzer\RequestAnalyzerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;

/**
* Validates the current user entity.
*/
class CompletionListener
{
/**
* @var string
*/
const SESSION_STORE = 'sulu_community/completion/redirect_to';

/**
* @var RequestAnalyzerInterface
*/
protected $requestAnalyzer;

/**
* @var RouterInterface
*/
protected $router;

/**
* @var TokenStorage
*/
protected $tokenStorage;

/**
* @var CompletionInterface[]
*/
protected $validators;

/**
* CompletionListener constructor.
*
* @param RequestAnalyzerInterface $requestAnalyzer
* @param RouterInterface $router
* @param TokenStorage $tokenStorage
* @param array $validators
*/
public function __construct(
RequestAnalyzerInterface $requestAnalyzer,
RouterInterface $router,
TokenStorage $tokenStorage,
array $validators
) {
$this->requestAnalyzer = $requestAnalyzer;
$this->router = $router;
$this->tokenStorage = $tokenStorage;
$this->validators = $validators;
}

/**
* Will call a specific user completion validator of a webspace.
*
* @param GetResponseEvent $event
*/
public function onRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$completionUrl = $this->router->generate('sulu_community.completion');

if (!$event->isMasterRequest()
|| $request->isMethod('post')
|| $request->isXmlHttpRequest()
|| $request->getPathInfo() === $completionUrl
) {
return;
}

$token = $this->tokenStorage->getToken();

/** @var User $user */
$user = $token->getUser();

if (!$user instanceof User) {
// don't do anything if no user is login
return;
}

if ($request->attributes->get('_route') !== 'sulu_community.confirmation') {
$session = $request->getSession();
$session->set(self::SESSION_STORE, $request->getUri());
}

$webspaceKey = $this->requestAnalyzer->getWebspace()->getKey();
$validator = $this->getValidator($webspaceKey);

if ($validator && !$validator->validate($user, $webspaceKey)) {
$response = new RedirectResponse($completionUrl);
$event->setResponse($response);
}
}

/**
* @param CompletionInterface $validator
* @param string $webspaceKey
*/
public function addValidator(CompletionInterface $validator, $webspaceKey)
{
$this->validators[$webspaceKey] = $validator;
}

/**
* @param string $webspaceKey
*
* @return CompletionInterface
*/
protected function getValidator($webspaceKey)
{
if (!isset($this->validators[$webspaceKey])) {
return;
}

return $this->validators[$webspaceKey];
}
}
10 changes: 10 additions & 0 deletions EventListener/MailListener.php
Expand Up @@ -74,6 +74,16 @@ public function sendPasswordResetEmails(CommunityEvent $event)
$this->sendTypeEmails($event, Configuration::TYPE_PASSWORD_RESET);
}

/**
* Send password reset emails.
*
* @param CommunityEvent $event
*/
public function sendCompletionEmails(CommunityEvent $event)
{
$this->sendTypeEmails($event, Configuration::TYPE_COMPLETION);
}

/**
* Send emails for specific type.
*
Expand Down