Skip to content

Commit

Permalink
Merge pull request #10 from crim3hound/master
Browse files Browse the repository at this point in the history
Fixes for Issues 7, 9 and 11
  • Loading branch information
I-Valchev authored Oct 29, 2020
2 parents e62735c + 2ed5c20 commit 6a49db9
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 45 deletions.
1 change: 1 addition & 0 deletions config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ default:
redirect_on_register: / # Provide either a route name, or a URL
initial_status: enabled # email_confirmation, admin_confirmation
redirect_on_login: / # Provide either a route name, or a URL
redirect_on_session_null: / # Redirection route if no valid user session

## Define groups below
groups:
Expand Down
147 changes: 104 additions & 43 deletions src/Controller/FrontendUsersProfileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Bolt\UsersExtension\Controller;

use Bolt\Controller\Backend\BackendZoneInterface;
use Bolt\Configuration\Config;
use Bolt\Configuration\Content\ContentType;
use Bolt\Controller\Backend\ContentEditController;
Expand All @@ -15,11 +16,12 @@
use Bolt\Repository\ContentRepository;
use Bolt\UsersExtension\ExtensionConfigTrait;
use Bolt\UsersExtension\Utils\ExtensionTemplateChooser;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class FrontendUsersProfileController extends AccessAwareController
class FrontendUsersProfileController extends AccessAwareController implements BackendZoneInterface
{
use ExtensionConfigTrait;

Expand All @@ -32,27 +34,29 @@ class FrontendUsersProfileController extends AccessAwareController
/** @var TwigAwareController */
private $twigAwareController;

/** @var ContentEditController */
private $contentEditController;

/** @var ExtensionTemplateChooser */
private $templateChooser;

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

public function __construct(
Config $config,
ContentRepository $contentRepository,
ContentEditController $contentEditController,
ContentFillListener $contentFillListener,
TwigAwareController $twigAwareController,
ContentEditController $contentEditController,
ExtensionTemplateChooser $templateChooser)
ExtensionTemplateChooser $templateChooser,
EntityManagerInterface $em)
{
parent::__construct($config);

$this->contentRepository = $contentRepository;
$this->contentEditController = $contentEditController;
$this->contentFillListener = $contentFillListener;
$this->twigAwareController = $twigAwareController;
$this->contentEditController = $contentEditController;
$this->templateChooser = $templateChooser;
$this->em = $em;
}

/**
Expand All @@ -65,69 +69,126 @@ public function view(): Response
if ($user instanceof User && $this->isGranted('ROLE_ADMIN')) {
return $this->redirectToRoute('bolt_user_edit', ['id' => $user->getId()]);
}

$contentTypeSlug = $this->getExtension()->getExtConfig('contenttype', $user->getRoles()[0]);

/** @var ContentType $contentType */
$contentType = $this->getBoltConfig()->getContentType($contentTypeSlug);
$this->applyAllowForGroupsGuard($contentType);

return $this->twigAwareController->renderSingle($this->getUserRecord($contentType));

if ($user !== null /* Ensure there is an active user logged on*/ ) {
$contentTypeSlug = $this->getExtension()->getExtConfig('contenttype', $user->getRoles()[0]);

/** @var ContentType $contentType */
$contentType = $this->getBoltConfig()->getContentType($contentTypeSlug);
$this->applyAllowForGroupsGuard($contentType);

return $this->twigAwareController->renderSingle($this->getUserRecord($contentType));
}
else {
// If session was invalidated or ended, redirect user as needed when they try to access profile
// For instance, redirect to login page to prompt re-authentication
$redirectRoute = $this->getExtension()->getExtConfig('redirect_on_session_null');
return $this->redirect($redirectRoute);
}
}

/**
* @Route("/profile/edit", methods={"GET", "POST"}, name="extension_frontend_user_edit")
*/
public function edit(Request $request): Response
public function edit(ContentType $contentType, Request $request): Response
{
$this->applyIsAuthenticatedGuard();

$contentTypeSlug = $this->getExtension()->getExtConfig('contenttype', $this->getUser()->getRoles()[0]);
$user = $this->getUser();

if ($user !== null /* Ensure there is an active user logged on*/ ) {

$this->applyIsAuthenticatedGuard();

/** @var ContentType $contentType */
$contentType = $this->getBoltConfig()->getContentType($contentTypeSlug);
$this->applyAllowForGroupsGuard($contentType);
$this->applyEditProfileGuard();
$contentTypeSlug = $this->getExtension()->getExtConfig('contenttype', $this->getUser()->getRoles()[0]);

$content = $this->getUserRecord($contentType);
/** @var ContentType $contentType */
$contentType = $this->getBoltConfig()->getContentType($contentTypeSlug);
$this->applyAllowForGroupsGuard($contentType);
$this->applyEditProfileGuard();

if ($request->getMethod() === 'POST') {
$this->contentEditController->save($content);
$content = $this->getUserRecord($contentType);

return $this->redirectToRoute('extension_frontend_user_profile');
}
if ($request->getMethod() === 'POST') {
$this->contentEditController->save($content);
return $this->redirectToRoute('extension_frontend_user_profile');
}

$templates = $this->templateChooser->forProfileEdit($this->getUser()->getRoles()[0]);
$templates = $this->templateChooser->forProfileEdit($this->getUser()->getRoles()[0]);

$parameters = [
'record' => $content,
$content->getContentTypeSingularSlug() => $content,
];
$parameters = [
'record' => $content,
$content->getContentTypeSingularSlug() => $content,
];

return $this->twigAwareController->renderTemplate($templates, $parameters);
return $this->twigAwareController->renderTemplate($templates, $parameters);
}
else {
// If session was invalidated or ended, redirect user as needed when they try to access profile
// For instance, redirect to login page to prompt re-authentication
$redirectRoute = $this->getExtension()->getExtConfig('redirect_on_session_null');
return $this->redirect($redirectRoute);
}
}

private function getUserRecord(ContentType $contentType): Content
{
/** @var User $user */
$user = $this->getUser();

// Access user record, if available
$contentTypeSlug = $this->getExtension()->getExtConfig('contenttype', $user->getRoles()[0]);
$contentType = $this->getBoltConfig()->getContentType($contentTypeSlug);

$content = $this->contentRepository->findBy([
'author' => $user,
'contentType' => $contentType->getSlug(),
]);


// If user record unavailable, create it
if (empty($content)) {
$content = new Content($contentType);
$content->setAuthor($user);
$content->setPublishedAt(new \DateTime());
$content->setStatus(Statuses::PUBLISHED);
$contentTypeName = strtolower($contentType->get('name', $contentType->get('slug')));
$content->setContentType($contentTypeName);
$this->contentFillListener->fillContent($content);
} elseif (is_iterable($content)) {
return $this->new($contentType);
}
elseif (is_iterable($content)) {
$content = end($content);
}

return $content;
}

// Define the user record content
private function new(ContentType $contentType): Content
{
/** @var User $user */
$user = $this->getUser();
$contentTypeSlug = $this->getExtension()->getExtConfig('contenttype', $user->getRoles()[0]);
$contentType = $this->getBoltConfig()->getContentType($contentTypeSlug);

$content = new Content($contentType);
$content->setAuthor($user);
$content->setCreatedAt(new \DateTime());
$content->setPublishedAt(new \DateTime());
$content->setStatus(Statuses::PUBLISHED);
$contentTypeName = strtolower($contentType->get('name', $contentType->get('slug')));
$content->setContentType($contentTypeName);
$content->setFieldValue('displayName', $user->getDisplayName()); // Hidden field for record title
$content->setFieldValue('username', $user->getUsername()); // Hidden field with copy of username

// Initialise ALL extra fields as defined in the contenttype with empty strings.
// This ensures they are displayed on the /profile/edit route without backend intervention
$content->setFieldValue('dob', '');

$content->setFieldValue('slug', $user->getUsername()); // Make slugs unique to users
$this->contentFillListener->fillContent($content);

// Persist in DB
$this->saveContent($content);
return $content;
}

// Saves user record to the database
private function saveContent(Content $content): void
{
$this->em->persist($content);
$this->em->flush();
}

}
2 changes: 1 addition & 1 deletion src/Controller/RegisterFrontendUsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function save(?User $user, ValidatorInterface $validator): Response
return $this->redirect($referer);
}

$user = UserRepository::factory('', $this->request->get('username'), $this->request->get('email'));
$user = UserRepository::factory($this->request->get('displayname'), $this->request->get('username'), $this->request->get('email'));

$user->setDisplayName($this->request->get('displayname', $user->getUsername()));

Expand Down
14 changes: 13 additions & 1 deletion src/Twig/RegistrationFormExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function getFunctions(): array

return [
new TwigFunction('registration_form', [$this, 'getRegistrationForm'], $safe),
new TwigFunction('registration_form_displayname', [$this, 'getDisplayNameField'], $safe),
new TwigFunction('registration_form_username', [$this, 'getUsernameField'], $safe),
new TwigFunction('registration_form_password', [$this, 'getPasswordField'], $safe),
new TwigFunction('registration_form_email', [$this, 'getEmailField'], $safe),
Expand All @@ -45,6 +46,7 @@ public function getFunctions(): array

public function getRegistrationForm(string $group, bool $withLabels = true, array $labels = []): string
{
$displayname = $this->getDisplayNameField($withLabels, $labels);
$username = $this->getUsernameField($withLabels, $labels);
$password = $this->getPasswordField($withLabels, $labels);
$email = $this->getEmailField($withLabels, $labels);
Expand All @@ -53,7 +55,17 @@ public function getRegistrationForm(string $group, bool $withLabels = true, arra
$submit = $this->getSubmitButton($labels);
$postUrl = $this->router->generate('extension_edit_frontend_user');

return sprintf("<form method='post' action='%s'>%s %s %s %s %s %s</form>", $postUrl, $username, $password, $email, $group, $submit, $csrf);
return sprintf("<form method='post' action='%s'>%s %s %s %s %s %s %s</form>", $postUrl, $displayname, $username, $password, $email, $group, $submit, $csrf);
}

public function getDisplayNameField(bool $withLabel, array $labels): string
{
$text = in_array('displayname', $labels, true) ? $labels['displayname'] : 'Display Name';
$label = $withLabel ? sprintf('<label for="displayname">%s</label>', $text) : '';

$input = '<input type="text" id="displayname" name="displayname">';

return $label . $input;
}

public function getUsernameField(bool $withLabel, array $labels): string
Expand Down

0 comments on commit 6a49db9

Please sign in to comment.