Skip to content

Commit

Permalink
[WIP][TASK] Use Formframework for comment form
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminkott committed May 13, 2019
1 parent cd1c276 commit 185aaa5
Show file tree
Hide file tree
Showing 15 changed files with 319 additions and 275 deletions.
91 changes: 1 addition & 90 deletions Classes/Controller/CommentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,12 @@
use T3G\AgencyPack\Blog\Domain\Model\Comment;
use T3G\AgencyPack\Blog\Domain\Model\Post;
use T3G\AgencyPack\Blog\Domain\Repository\PostRepository;
use T3G\AgencyPack\Blog\Notification\CommentAddedNotification;
use T3G\AgencyPack\Blog\Notification\NotificationManager;
use T3G\AgencyPack\Blog\Service\CacheService;
use T3G\AgencyPack\Blog\Service\CommentService;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;

class CommentController extends ActionController
{
protected static $messages = [
CommentService::STATE_ERROR => [
'title' => 'message.addComment.error.title',
'text' => 'message.addComment.error.text',
'severity' => FlashMessage::ERROR,
],
CommentService::STATE_MODERATION => [
'title' => 'message.addComment.moderation.title',
'text' => 'message.addComment.moderation.text',
'severity' => FlashMessage::INFO,
],
CommentService::STATE_SUCCESS => [
'title' => 'message.addComment.success.title',
'text' => 'message.addComment.success.text',
'severity' => FlashMessage::OK,
],
];

/**
* @var PostRepository
*/
Expand Down Expand Up @@ -81,81 +58,15 @@ public function injectBlogCacheService(CacheService $cacheService): void
$this->blogCacheService = $cacheService;
}

/**
* Pre-process request and ensure a valid protocol for submitted URL
*/
protected function initializeAddCommentAction(): void
{
$arguments = $this->request->getArguments();
if (!empty($arguments['comment']['url'])) {
$re = '/^(http([s]*):\/\/)(.*)/';
if (preg_match($re, $arguments['comment']['url'], $matches) === 0) {
$arguments['comment']['url'] = 'http://' . $arguments['comment']['url'];
}
$this->request->setArguments($arguments);
}
}

protected function getErrorFlashMessage(): bool
{
return false;
}

/**
* Show comment form.
*
* @param Comment|null $comment
* @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
*/
public function formAction(Comment $comment = null): void
public function formAction(): void
{
$this->view->assign('post', $this->postRepository->findCurrentPost());
$this->view->assign('comment', $comment);
}

/**
* Add comment to blog post.
*
* @param Comment $comment
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException
* @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
*/
public function addCommentAction(Comment $comment): void
{
$this->commentService->injectSettings($this->settings['comments']);
$post = $this->postRepository->findCurrentPost();
$state = $this->commentService->addComment($post, $comment);
$this->addFlashMessage(
LocalizationUtility::translate(self::$messages[$state]['text'], 'blog'),
LocalizationUtility::translate(self::$messages[$state]['title'], 'blog'),
self::$messages[$state]['severity']
);
if ($state !== CommentService::STATE_ERROR) {
$comment->setCrdate(new \DateTime());
GeneralUtility::makeInstance(NotificationManager::class)
->notify(GeneralUtility::makeInstance(CommentAddedNotification::class, '', '', [
'comment' => $comment,
'post' => $post,
]));
$this->blogCacheService->flushCacheByTag('tx_blog_post_' . $post->getUid());
}
$this->redirectToUri(
$this->controllerContext
->getUriBuilder()
->reset()
->setTargetPageUid($post->getUid())
->setUseCacheHash(false)
->setAddQueryString(true)
->setArgumentsToBeExcludedFromQueryString(['tx_blog_commentform', 'cHash'])
->buildFrontendUri()
);
}

/**
Expand Down
113 changes: 113 additions & 0 deletions Classes/Domain/Factory/CommentFormFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php
declare(strict_types = 1);

/*
* This file is part of the package t3g/blog.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

namespace T3G\AgencyPack\Blog\Domain\Factory;

use T3G\AgencyPack\Blog\Domain\Finisher\CommentFormFinisher;
use T3G\AgencyPack\Blog\Domain\Validator\GoogleCaptchaValidator;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Extbase\Validation\Validator\EmailAddressValidator;
use TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator;
use TYPO3\CMS\Extbase\Validation\Validator\StringLengthValidator;
use TYPO3\CMS\Extbase\Validation\Validator\UrlValidator;
use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
use TYPO3\CMS\Form\Domain\Factory\AbstractFormFactory;
use TYPO3\CMS\Form\Domain\Finishers\RedirectFinisher;
use TYPO3\CMS\Form\Domain\Model\FormDefinition;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

class CommentFormFactory extends AbstractFormFactory
{
/**
* Build a FormDefinition.
* This example build a FormDefinition manually,
* so $configuration and $prototypeName are unused.
*
* @param array $configuration
* @param string $prototypeName
* @return FormDefinition
*/
public function build(array $configuration, string $prototypeName = null): FormDefinition
{
$prototypeName = 'standard';
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$formConfigurationService = $objectManager->get(ConfigurationService::class);
$prototypeConfiguration = $formConfigurationService->getPrototypeConfiguration($prototypeName);
$prototypeConfiguration['formElementsDefinition']['GoogleCaptcha'] = [
'implementationClassName' => 'TYPO3\CMS\Form\Domain\Model\FormElements\GenericFormElement'
];

$configurationManager = $objectManager->get(ConfigurationManagerInterface::class);
$blogSettings = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS, 'blog');
$captcha = [];
$captcha['enable'] = (bool) ($blogSettings['comments']['google_recaptcha']['_typoScriptNodeValue'] ?? false);
$captcha['sitekey'] = (string) trim($blogSettings['comments']['google_recaptcha']['website_key'] ?? '');
$captcha['secret'] = (string) trim($blogSettings['comments']['google_recaptcha']['secret_key'] ?? '');

$form = $objectManager->get(FormDefinition::class, 'postcomment', $prototypeConfiguration);
$form->setRenderingOption('controllerAction', 'form');
$form->setRenderingOption('submitButtonLabel', LocalizationUtility::translate('form.comment.submit', 'blog'));
$renderingOptions = $form->getRenderingOptions();
$renderingOptions['partialRootPaths'][] = 'EXT:blog/Resources/Private/Partials/Form/';
$form->setRenderingOption('partialRootPaths', $renderingOptions['partialRootPaths']);

$page = $form->createPage('commentform');

// Form
$nameField = $page->createElement('name', 'Text');
$nameField->setLabel(LocalizationUtility::translate('form.comment.name', 'blog'));
$nameField->addValidator($objectManager->get(NotEmptyValidator::class));

$emailField = $page->createElement('email', 'Text');
$emailField->setLabel(LocalizationUtility::translate('form.comment.email', 'blog'));
$emailField->addValidator($objectManager->get(NotEmptyValidator::class));
$emailField->addValidator($objectManager->get(EmailAddressValidator::class));

$urlField = $page->createElement('url', 'Text');
$urlField->setLabel(LocalizationUtility::translate('form.comment.url', 'blog'));
$urlField->addValidator($objectManager->get(UrlValidator::class));

$commentField = $page->createElement('comment', 'Textarea');
$commentField->setLabel(LocalizationUtility::translate('form.comment.comment', 'blog'));
$commentField->addValidator($objectManager->get(NotEmptyValidator::class));
$commentField->addValidator($objectManager->get(StringLengthValidator::class, ['minimum' => 5]));

$explanationText = $page->createElement('headline', 'StaticText');
$explanationText->setProperty('text', LocalizationUtility::translate('label.required.field', 'blog') . ' ' . LocalizationUtility::translate('label.required.field.explanation', 'blog'));

if ($captcha['enable'] && $captcha['sitekey'] && $captcha['secret']) {
$captchaField = $page->createElement('captcha', 'GoogleCaptcha');
$captchaField->setProperty('sitekey', $captcha['sitekey']);
$captchaField->addValidator($objectManager->get(GoogleCaptchaValidator::class));
}

// Finisher
$commentFinisher = $objectManager->get(CommentFormFinisher::class);
$form->addFinisher($commentFinisher);

$redirectFinisher = $objectManager->get(RedirectFinisher::class);
$redirectFinisher->setOption('pageUid', $this->getTypoScriptFrontendController()->id);
$form->addFinisher($redirectFinisher);

$this->triggerFormBuildingFinished($form);
return $form;
}

/**
* @return TypoScriptFrontendController
*/
protected function getTypoScriptFrontendController(): ?TypoScriptFrontendController
{
return $GLOBALS['TSFE'];
}
}
89 changes: 89 additions & 0 deletions Classes/Domain/Finisher/CommentFormFinisher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php
declare(strict_types = 1);

/*
* This file is part of the package t3g/blog.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

namespace T3G\AgencyPack\Blog\Domain\Finisher;

use T3G\AgencyPack\Blog\Domain\Model\Comment;
use T3G\AgencyPack\Blog\Domain\Repository\PostRepository;
use T3G\AgencyPack\Blog\Notification\CommentAddedNotification;
use T3G\AgencyPack\Blog\Notification\NotificationManager;
use T3G\AgencyPack\Blog\Service\CacheService;
use T3G\AgencyPack\Blog\Service\CommentService;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher;

/**
* This finisher redirects to another Controller.
*
* Scope: frontend
*/
class CommentFormFinisher extends AbstractFinisher
{
protected static $messages = [
CommentService::STATE_ERROR => [
'title' => 'message.addComment.error.title',
'text' => 'message.addComment.error.text',
'severity' => FlashMessage::ERROR,
],
CommentService::STATE_MODERATION => [
'title' => 'message.addComment.moderation.title',
'text' => 'message.addComment.moderation.text',
'severity' => FlashMessage::INFO,
],
CommentService::STATE_SUCCESS => [
'title' => 'message.addComment.success.title',
'text' => 'message.addComment.success.text',
'severity' => FlashMessage::OK,
],
];

protected function executeInternal()
{
$configurationManager = $this->objectManager->get(ConfigurationManagerInterface::class);
$settings = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS, 'blog');
$postRepository = $this->objectManager->get(PostRepository::class);
$cacheService = $this->objectManager->get(CacheService::class);
$commentService = $this->objectManager->get(CommentService::class);
$commentService->injectSettings($settings['comments']);

// Create Comment
$values = $this->finisherContext->getFormValues();
$comment = new Comment();
$comment->setName($values['name'] ?? '');
$comment->setEmail($values['email'] ?? '');
$comment->setUrl($values['url'] ?? '');
$comment->setComment($values['comment'] ?? '');
$post = $postRepository->findCurrentPost();
$state = $commentService->addComment($post, $comment);

// Add FlashMessage
$flashMessage = $this->objectManager->get(
FlashMessage::class,
LocalizationUtility::translate(self::$messages[$state]['text'], 'blog'),
LocalizationUtility::translate(self::$messages[$state]['title'], 'blog'),
self::$messages[$state]['severity'],
true
);
$this->finisherContext->getControllerContext()->getFlashMessageQueue()->addMessage($flashMessage);

if ($state !== CommentService::STATE_ERROR) {
$comment->setCrdate(new \DateTime());
GeneralUtility::makeInstance(NotificationManager::class)
->notify(GeneralUtility::makeInstance(CommentAddedNotification::class, '', '', [
'comment' => $comment,
'post' => $post,
]));
$cacheService->flushCacheByTag('tx_blog_post_' . $post->getUid());
}
}
}
Loading

0 comments on commit 185aaa5

Please sign in to comment.