Skip to content
This repository has been archived by the owner on Mar 1, 2023. It is now read-only.

Commit

Permalink
scopes
Browse files Browse the repository at this point in the history
  • Loading branch information
romm committed Sep 22, 2017
1 parent 180b74e commit 67e2145
Show file tree
Hide file tree
Showing 19 changed files with 335 additions and 116 deletions.
10 changes: 5 additions & 5 deletions Classes/Controller/AjaxValidationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use Romm\Formz\Form\FormObject\FormObjectFactory;
use Romm\Formz\Middleware\Processor\MiddlewareProcessor;
use Romm\Formz\Middleware\Request\Exception\StopPropagationException;
use Romm\Formz\Middleware\Scope\FieldValidationScope;
use Romm\Formz\Service\ContextService;
use Romm\Formz\Service\ExtensionService;
use Romm\Formz\Service\MessageService;
Expand Down Expand Up @@ -229,20 +230,19 @@ public function runAction($name, $className, $fieldName, $validatorName, $formDa
/**
* Will call all middlewares of the form.
*
* Note that the "single field validation context" is activated, meaning
* some middlewares wont be called.
* Note that the field validation scope is used, meaning some middlewares
* wont be called.
*
* @see \Romm\Formz\Middleware\Processor\RemoveFromSingleFieldValidationContext
* @see \Romm\Formz\Middleware\Scope\FieldValidationScope
*/
protected function invokeMiddlewares()
{
try {
$controllerProcessor = ControllerProcessor::prepare($this->request, $this->arguments);
$controllerProcessor = ControllerProcessor::prepare($this->request, $this->arguments, FieldValidationScope::class);

/** @var MiddlewareProcessor $middlewareProcessor */
$middlewareProcessor = Core::instantiate(MiddlewareProcessor::class, $this->formObject, $controllerProcessor);

$middlewareProcessor->activateSingleFieldValidationContext();
$middlewareProcessor->run();
} catch (StopPropagationException $exception) {
// @todo exception if forward/redirect?
Expand Down
40 changes: 39 additions & 1 deletion Classes/Controller/FormActionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,54 @@
namespace Romm\Formz\Controller;

use Romm\Formz\Controller\Processor\ControllerProcessor;
use Romm\Formz\Middleware\Scope\MainScope;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

abstract class FormActionController extends ActionController
{
/**
* In case an exception (any exception type) is thrown during the
* middlewares execution, it can be automatically caught by FormZ, and the
* request will be forwarded to an action of the controller.
*
* You can use it for instance to log your exception in some log service; to
* render a view that contains a message explaining to the user that
* something went wrong.
*
* Just fill the property below with the name of an existing action of the
* controller. The method will have a single parameter which is the
* exception.
*
* @var string
*/
protected $actionForException;

/**
* @todo
*
* @var string
*/
protected $formScope = MainScope::class;

/**
* IMPORTANT: if you need to override this method in your own controller, do
* not forget to call `parent::initializeAction()`!
*/
public function initializeAction()
{
ControllerProcessor::prepare($this->request, $this->arguments)->dispatch();
$processor = ControllerProcessor::prepare($this->request, $this->arguments, $this->formScope);

if (null !== $this->actionForException) {
$vendorName = $this->request->getControllerVendorName();
$extensionName = $this->request->getControllerExtensionName();
$controllerName = $this->request->getControllerName();

$processor->setExceptionCallback(function ($exception) use ($vendorName, $controllerName, $extensionName) {
$this->request->setControllerVendorName($vendorName);
$this->forward($this->actionForException, $controllerName, $extensionName, ['exception' => $exception]);
});
}

$processor->dispatch();
}
}
20 changes: 12 additions & 8 deletions Classes/Controller/FormController.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,10 @@ class FormController extends ActionController
*/
public function processFormAction()
{
$exception = null;

try {
$this->invokeMiddlewares();
$this->manageRequestResult();
} catch (Exception $exception) {
}

if ($exception instanceof Exception) {
if ($exception instanceof StopPropagationException) {
if ($exception instanceof RedirectException) {
$this->redirectFromException($exception);
Expand Down Expand Up @@ -143,17 +138,26 @@ protected function continueRequest()
*/
protected function forwardToReferrer()
{
$originalRequest = $this->processor->getRequest();
$referringRequest = $originalRequest->getReferringRequest();
/*
* If the original request is filled, a forward to referrer has already
* been done.
*/
if ($this->request->getOriginalRequest()) {
return;
}

$referringRequest = $this->processor->getRequest()->getReferringRequest();

if ($referringRequest) {
$originalRequest = clone $this->request;
$this->request->setDispatched(false);

$this->request->setControllerVendorName($referringRequest->getControllerVendorName());
$this->request->setControllerVendorName($referringRequest->getControllerVendorName());
$this->request->setControllerExtensionName($referringRequest->getControllerExtensionName());
$this->request->setControllerName($referringRequest->getControllerName());
$this->request->setControllerActionName($referringRequest->getControllerActionName());
$this->request->setArguments($this->processor->getRequest()->getArguments());
$this->request->setOriginalRequest($originalRequest);

throw new StopActionException;
} else {
Expand Down
67 changes: 63 additions & 4 deletions Classes/Controller/Processor/ControllerProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Romm\Formz\Form\FormInterface;
use Romm\Formz\Form\FormObject\FormObject;
use Romm\Formz\Form\FormObject\FormObjectFactory;
use Romm\Formz\Middleware\Scope\ScopeInterface;
use Romm\Formz\Service\Traits\ExtendedSelfInstantiateTrait;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\Argument;
Expand Down Expand Up @@ -58,6 +59,17 @@ class ControllerProcessor implements SingletonInterface
*/
protected $requestArguments;

/**
* An interface name that does implement:
*
* @see \Romm\Formz\Middleware\Scope\ScopeInterface
*
* It will be used to filter the middlewares that will be called.
*
* @var string
*/
protected $scope;

/**
* @var array
*/
Expand All @@ -71,14 +83,20 @@ class ControllerProcessor implements SingletonInterface
*/
protected $lastDispatchedRequest;

/**
* @var callable
*/
protected $exceptionCallback;

/**
* @param MvcRequest $request
* @param Arguments $requestArguments
* @param string $scope
* @return $this
*/
public static function prepare(MvcRequest $request, Arguments $requestArguments)
public static function prepare(MvcRequest $request, Arguments $requestArguments, $scope)
{
return self::get()->setData($request, $requestArguments, []);
return self::get()->setData($request, $requestArguments, $scope, []);
}

/**
Expand All @@ -87,20 +105,26 @@ public static function prepare(MvcRequest $request, Arguments $requestArguments)
*
* @param MvcRequest $request
* @param Arguments $requestArguments
* @param string $scope
* @param array $settings
* @return $this
*/
public function setData(MvcRequest $request, Arguments $requestArguments, array $settings)
public function setData(MvcRequest $request, Arguments $requestArguments, $scope, array $settings)
{
if (false === in_array(ScopeInterface::class, class_implements($scope))) {
throw new \Exception('todo scope : ' . $scope); // @todo
}

/** @var Request $request */
$dispatchedRequest = $request->getControllerObjectName() . '::' . $request->getControllerActionName();
$dispatchedRequest = $request->getControllerObjectName() . '::' . $request->getControllerActionName() . '::' . $scope;

if ($dispatchedRequest !== $this->lastDispatchedRequest) {
$this->lastDispatchedRequest = $dispatchedRequest;

$this->originalRequest = $request;
$this->request = clone $request;
$this->requestArguments = $requestArguments;
$this->scope = $scope;
$this->settings = $settings;
$this->formArguments = null;
$this->dispatched = false;
Expand Down Expand Up @@ -216,6 +240,41 @@ public function getSettings()
return $this->settings;
}

/**
* @return string
*/
public function getScope()
{
return $this->scope;
}

/**
* @param callable $callback
* @return $this
*/
public function setExceptionCallback(callable $callback)
{
$this->exceptionCallback = $callback;

return $this;
}

/**
* @return callable
*/
public function getExceptionCallback()
{
return $this->exceptionCallback;
}

/**
* @return bool
*/
public function hasExceptionCallback()
{
return null !== $this->exceptionCallback;
}

/**
* @param FormObjectFactory $formObjectFactory
*/
Expand Down
12 changes: 5 additions & 7 deletions Classes/Domain/Middleware/Begin/BeginMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function initialize()
public function execute()
{
/** @var SignalObject $signalObject */
$signalObject = GeneralUtility::makeInstance(SignalObject::class,$this->processor, BeginSignal::class, After::class);
$signalObject = GeneralUtility::makeInstance(SignalObject::class, $this->processor, BeginSignal::class, After::class);
$signalObject->dispatch();
}

Expand All @@ -52,19 +52,17 @@ public function execute()
*/
protected function checkFormSubmission()
{
if ($this->processor->inSingleFieldValidationContext()) {
/*
* In "single field validation context", there is no need to check
* for the form submission.
*/
$formObject = $this->processor->getFormObject();

if ($formObject->hasForm()) {
return;
}

$request = $this->processor->getRequest();
$formObject = $this->processor->getFormObject();
$formName = $formObject->getName();

if ($request->getMethod() === 'POST'
&& null === $request->getOriginalRequest()
&& $this->processor->getRequestArguments()->hasArgument($formName)
) {
if (false === $request->hasArgument('formData')) {
Expand Down
8 changes: 0 additions & 8 deletions Classes/Domain/Middleware/End/EndMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,6 @@ protected function injectFormInRequest()
*/
protected function injectFormResultInRequest()
{
if ($this->processor->inSingleFieldValidationContext()) {
/*
* In "single field validation context", there is no need to inject
* the form result in the request.
*/
return;
}

$request = $this->processor->getRequest();
$result = $this->processor->getFormObject()->getFormResult();
$formName = $this->processor->getFormObject()->getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Romm\Formz\Core\Core;
use Romm\Formz\Middleware\Application\OnBeginMiddleware;
use Romm\Formz\Middleware\PresetMiddlewareInterface;
use Romm\Formz\Middleware\Processor\RemoveFromSingleFieldValidationContext;
use Romm\Formz\Middleware\Signal\SendsSignal;

/**
Expand All @@ -30,7 +29,7 @@
* The goal is to provide a form instance to the controller in every case, so
* the developer can manipulate it easily, for instance by pre-setting values.
*/
class FormInjectionMiddleware extends OnBeginMiddleware implements PresetMiddlewareInterface, SendsSignal, RemoveFromSingleFieldValidationContext
class FormInjectionMiddleware extends OnBeginMiddleware implements PresetMiddlewareInterface, SendsSignal
{
/**
* @var int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,17 @@
use Romm\Formz\Domain\Middleware\FieldValidation\FieldValidationSignal;
use Romm\Formz\Middleware\Application\OnBeginMiddleware;
use Romm\Formz\Middleware\PresetMiddlewareInterface;
use Romm\Formz\Middleware\Processor\RemoveFromSingleFieldValidationContext;
use Romm\Formz\Middleware\Signal\SendsSignal;
use Romm\Formz\Validation\Validator\Form\AbstractFormValidator;
use Romm\Formz\Validation\Form\AbstractFormValidator;

/**
* This middleware takes care of validating the form instance, with a proper
* form validator instance.
*
* You can bind middlewares to the signal `FormValidationSignal`, which will be
* dispatched if and only if the form was submitted by the user.
*
* Please note that this middleware will not be called when being in a "single
* field validation context".
*
* @see \Romm\Formz\Middleware\Processor\RemoveFromSingleFieldValidationContext
*/
class FormValidationMiddleware extends OnBeginMiddleware implements PresetMiddlewareInterface, SendsSignal, RemoveFromSingleFieldValidationContext
class FormValidationMiddleware extends OnBeginMiddleware implements PresetMiddlewareInterface, SendsSignal
{
/**
* @var \Romm\Formz\Domain\Middleware\FormValidation\FormValidationMiddlewareOption
Expand Down
6 changes: 5 additions & 1 deletion Classes/Form/Definition/Middleware/MiddlewareResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Romm\ConfigurationObject\Service\Items\MixedTypes\MixedTypesInterface;
use Romm\ConfigurationObject\Service\Items\MixedTypes\MixedTypesResolver;
use Romm\Formz\Validation\Validator\Internal\MiddlewareIsValidValidator;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Error\Error;

class MiddlewareResolver implements MixedTypesInterface
Expand All @@ -33,7 +34,10 @@ final public static function getInstanceClassName(MixedTypesResolver $resolver)

if (isset($data['className'])) {
$middlewareClassName = $data['className'];
$validator = new MiddlewareIsValidValidator;

/** @var MiddlewareIsValidValidator $validator */
$validator = GeneralUtility::makeInstance(MiddlewareIsValidValidator::class);

$result = $validator->validate($middlewareClassName);

if ($result->hasErrors()) {
Expand Down

0 comments on commit 67e2145

Please sign in to comment.