Skip to content

Commit

Permalink
Merge pull request #1618 from bolt/enhancement/users
Browse files Browse the repository at this point in the history
Users extension prep
  • Loading branch information
bobdenotter authored Jul 13, 2020
2 parents e249bb5 + 0e66fbb commit abbfbd7
Show file tree
Hide file tree
Showing 20 changed files with 211 additions and 135 deletions.
2 changes: 1 addition & 1 deletion config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,4 @@ services:

Symfony\Component\ErrorHandler\ErrorRenderer\ErrorRendererInterface: '@error_handler.error_renderer.html'

Squirrel\TwigPhpSyntax\PhpSyntaxExtension: ~
Squirrel\TwigPhpSyntax\PhpSyntaxExtension: ~
6 changes: 0 additions & 6 deletions src/Controller/Backend/ContentEditController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
use Bolt\Repository\MediaRepository;
use Bolt\Repository\RelationRepository;
use Bolt\Repository\TaxonomyRepository;
use Bolt\TemplateChooser;
use Bolt\Utils\TranslationsManager;
use Carbon\Carbon;
use Doctrine\ORM\EntityManagerInterface;
Expand Down Expand Up @@ -61,9 +60,6 @@ class ContentEditController extends TwigAwareController implements BackendZoneIn
/** @var UrlGeneratorInterface */
private $urlGenerator;

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

/** @var ContentFillListener */
private $contentFillListener;

Expand All @@ -81,7 +77,6 @@ public function __construct(
EntityManagerInterface $em,
UrlGeneratorInterface $urlGenerator,
ContentFillListener $contentFillListener,
TemplateChooser $templateChooser,
CsrfTokenManagerInterface $csrfTokenManager,
EventDispatcherInterface $dispatcher,
string $defaultLocale
Expand All @@ -93,7 +88,6 @@ public function __construct(
$this->em = $em;
$this->urlGenerator = $urlGenerator;
$this->contentFillListener = $contentFillListener;
$this->templateChooser = $templateChooser;
$this->csrfTokenManager = $csrfTokenManager;
$this->dispatcher = $dispatcher;
$this->defaultLocale = $defaultLocale;
Expand Down
34 changes: 22 additions & 12 deletions src/Controller/Backend/UserEditController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Bolt\Controller\CsrfTrait;
use Bolt\Controller\TwigAwareController;
use Bolt\Entity\User;
use Bolt\Enum\UserStatus;
use Bolt\Event\UserEvent;
use Bolt\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
Expand All @@ -20,6 +22,7 @@
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

/**
* @Security("is_granted('ROLE_ADMIN')")
Expand All @@ -37,32 +40,40 @@ class UserEditController extends TwigAwareController implements BackendZoneInter
/** @var UserPasswordEncoderInterface */
private $passwordEncoder;

/** @var EventDispatcherInterface */
private $dispatcher;

public function __construct(
UrlGeneratorInterface $urlGenerator,
EntityManagerInterface $em,
UserPasswordEncoderInterface $passwordEncoder,
CsrfTokenManagerInterface $csrfTokenManager
CsrfTokenManagerInterface $csrfTokenManager,
EventDispatcherInterface $dispatcher
) {
$this->urlGenerator = $urlGenerator;
$this->em = $em;
$this->passwordEncoder = $passwordEncoder;
$this->csrfTokenManager = $csrfTokenManager;
$this->dispatcher = $dispatcher;
}

/**
* @Route("/user-edit/{id}", methods={"GET"}, name="bolt_user_edit", requirements={"id": "\d+"})
*/
public function edit(?User $user): Response
{
$roles = $this->getParameter('security.role_hierarchy.roles');

if (! $user instanceof User) {
$user = UserRepository::factory();
$suggestedPassword = Str::generatePassword();
} else {
$suggestedPassword = '';
}

$event = new UserEvent($user);
$this->dispatcher->dispatch($event, UserEvent::ON_EDIT);

$roles = array_merge($this->getParameter('security.role_hierarchy.roles'), $event->getRoleOptions()->toArray());

return $this->renderTemplate('@bolt/users/edit.html.twig', [
'display_name' => $user->getDisplayName(),
'userEdit' => $user,
Expand All @@ -72,19 +83,16 @@ public function edit(?User $user): Response
}

/**
* @Route("/user-disable/{id}", methods={"POST", "GET"}, name="bolt_user_disable", requirements={"id": "\d+"})
* @Route("/user-status/{id}", methods={"POST", "GET"}, name="bolt_user_update_status", requirements={"id": "\d+"})
*/
public function disable(?User $user): Response
public function status(?User $user): Response
{
$this->validateCsrf('useredit');

if ($user->isDisabled()) {
$user->enable();
$this->addFlash('success', 'user.enabled_successfully');
} else {
$user->disable();
$this->addFlash('success', 'user.disabled_successfully');
}
$newStatus = $this->request->get('status', UserStatus::DISABLED);

$user->setStatus($newStatus);
$this->addFlash('success', 'user.updated_successfully');

$this->em->persist($user);
$this->em->flush();
Expand Down Expand Up @@ -145,6 +153,8 @@ public function save(?User $user, ValidatorInterface $validator): Response
$user->setLocale($locale);
$user->setRoles($roles);
$user->setbackendTheme($this->getFromRequest('backendTheme'));
$user->setStatus($this->getFromRequest('status', UserStatus::ENABLED));

$newPassword = $this->getFromRequest('password');
// Set the plain password to check for validation
if (! empty($newPassword)) {
Expand Down
13 changes: 7 additions & 6 deletions src/Controller/ErrorController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Bolt\Controller;

use Bolt\Configuration\Config;
use Bolt\Controller\Frontend\DetailController;
use Bolt\Controller\Frontend\DetailControllerInterface;
use Bolt\Controller\Frontend\TemplateController;
use Symfony\Component\ErrorHandler\ErrorRenderer\ErrorRendererInterface;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -20,19 +20,20 @@ class ErrorController extends SymfonyErrorController
/** @var Config */
private $config;

/** @var DetailController */
private $detailController;

/** @var TemplateController */
private $templateController;

public function __construct(HttpKernelInterface $httpKernel, Config $config, DetailController $detailController, TemplateController $templateController, ErrorRendererInterface $errorRenderer)
/** @var DetailControllerInterface */
private $detailController;

public function __construct(HttpKernelInterface $httpKernel, Config $config, DetailControllerInterface $detailController, TemplateController $templateController, ErrorRendererInterface $errorRenderer)
{
$this->config = $config;
$this->detailController = $detailController;
$this->templateController = $templateController;

parent::__construct($httpKernel, $templateController, $errorRenderer);

$this->detailController = $detailController;
}

/**
Expand Down
46 changes: 2 additions & 44 deletions src/Controller/Frontend/DetailController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,21 @@

use Bolt\Configuration\Content\ContentType;
use Bolt\Controller\TwigAwareController;
use Bolt\Entity\Content;
use Bolt\Enum\Statuses;
use Bolt\Repository\ContentRepository;
use Bolt\TemplateChooser;
use Bolt\Utils\ContentHelper;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;

class DetailController extends TwigAwareController implements FrontendZoneInterface
class DetailController extends TwigAwareController implements FrontendZoneInterface, DetailControllerInterface
{
/** @var TemplateChooser */
private $templateChooser;

/** @var ContentRepository */
private $contentRepository;

/** @var ContentHelper */
private $contentHelper;

public function __construct(TemplateChooser $templateChooser, ContentRepository $contentRepository, ContentHelper $contentHelper)
public function __construct(ContentRepository $contentRepository, ContentHelper $contentHelper)
{
$this->templateChooser = $templateChooser;
$this->contentRepository = $contentRepository;
$this->contentHelper = $contentHelper;
}
Expand Down Expand Up @@ -71,38 +63,4 @@ public function contentByFieldValue(string $contentTypeSlug, string $field, stri

return $this->renderSingle($record);
}

public function renderSingle(?Content $record, bool $requirePublished = true, array $templates = []): Response
{
if (! $record) {
throw new NotFoundHttpException('Content not found');
}

// If the content is not 'published' we throw a 404, unless we've overridden it.
if (($record->getStatus() !== Statuses::PUBLISHED) && $requirePublished) {
throw new NotFoundHttpException('Content is not published');
}

// If the ContentType is 'viewless' we also throw a 404.
if (($record->getDefinition()->get('viewless') === true) && $requirePublished) {
throw new NotFoundHttpException('Content is not viewable');
}

$singularSlug = $record->getContentTypeSingularSlug();

$context = [
'record' => $record,
$singularSlug => $record,
];

// We add the record as a _global_ variable. This way we can use that
// later on, if we need to get the root record of a page.
$this->twig->addGlobal('record', $record);

if (empty($templates)) {
$templates = $this->templateChooser->forRecord($record);
}

return $this->renderTemplate($templates, $context);
}
}
15 changes: 15 additions & 0 deletions src/Controller/Frontend/DetailControllerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Bolt\Controller\Frontend;

use Symfony\Component\HttpFoundation\Response;

/**
* Controllers that display a single record must implement this interface.
*/
interface DetailControllerInterface
{
public function record($slugOrId, ?string $contentTypeSlug, bool $requirePublished): Response;
}
15 changes: 1 addition & 14 deletions src/Controller/Frontend/HomepageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,11 @@

use Bolt\Controller\TwigAwareController;
use Bolt\Repository\ContentRepository;
use Bolt\TemplateChooser;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class HomepageController extends TwigAwareController implements FrontendZoneInterface
{
/** @var TemplateChooser */
private $templateChooser;

/** @var DetailController */
private $detailController;

public function __construct(TemplateChooser $templateChooser, DetailController $detailController)
{
$this->templateChooser = $templateChooser;
$this->detailController = $detailController;
}

/**
* @Route("/", methods={"GET|POST"}, name="homepage")
* @Route(
Expand Down Expand Up @@ -62,6 +49,6 @@ public function homepage(ContentRepository $contentRepository): Response

$templates = $this->templateChooser->forHomepage();

return $this->detailController->renderSingle($record, false, $templates);
return $this->renderSingle($record, false, $templates);
}
}
7 changes: 1 addition & 6 deletions src/Controller/Frontend/ListingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,16 @@
use Bolt\Controller\TwigAwareController;
use Bolt\Repository\ContentRepository;
use Bolt\Storage\Query;
use Bolt\TemplateChooser;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class ListingController extends TwigAwareController implements FrontendZoneInterface
{
/** @var TemplateChooser */
private $templateChooser;

/** @var Query */
private $query;

public function __construct(TemplateChooser $templateChooser, Query $query)
public function __construct(Query $query)
{
$this->templateChooser = $templateChooser;
$this->query = $query;
}

Expand Down
9 changes: 0 additions & 9 deletions src/Controller/Frontend/SearchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,13 @@

use Bolt\Controller\TwigAwareController;
use Bolt\Repository\ContentRepository;
use Bolt\TemplateChooser;
use Pagerfanta\Adapter\ArrayAdapter;
use Pagerfanta\Pagerfanta;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class SearchController extends TwigAwareController implements FrontendZoneInterface
{
/** @var TemplateChooser */
private $templateChooser;

public function __construct(TemplateChooser $templateChooser)
{
$this->templateChooser = $templateChooser;
}

/**
* @Route("/search", methods={"GET|POST"}, name="search")
* @Route("/{_locale}/search", methods={"GET|POST"}, name="search_locale")
Expand Down
9 changes: 0 additions & 9 deletions src/Controller/Frontend/TaxonomyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,11 @@
use Bolt\Controller\TwigAwareController;
use Bolt\Entity\Content;
use Bolt\Repository\ContentRepository;
use Bolt\TemplateChooser;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class TaxonomyController extends TwigAwareController implements FrontendZoneInterface
{
/** @var TemplateChooser */
private $templateChooser;

public function __construct(TemplateChooser $templateChooser)
{
$this->templateChooser = $templateChooser;
}

/**
* @Route(
* "/{taxonomyslug}/{slug}",
Expand Down
Loading

0 comments on commit abbfbd7

Please sign in to comment.