Skip to content
Permalink
Browse files

Add handling of result from action* and handle*

  • Loading branch information...
Thoronir42 committed Aug 17, 2019
1 parent 9483f43 commit c99c04ed665e69ca547df6c490d2ccc47d47855f
Showing with 146 additions and 24 deletions.
  1. +60 −20 src/Application/UI/Component.php
  2. +52 −0 src/Application/UI/HandleResult.php
  3. +34 −4 src/Application/UI/Presenter.php
@@ -10,6 +10,7 @@
namespace Nette\Application\UI;
use Nette;
use Nette\ComponentModel\IComponent;
/**
@@ -32,6 +33,9 @@ abstract class Component extends Nette\ComponentModel\Container implements ISign
/** @var array */
protected $params = [];
/** @var HandleResult */
private $signalResult;
/**
* Returns the presenter where this component belongs to.
@@ -75,27 +79,39 @@ protected function validateParent(Nette\ComponentModel\IContainer $parent): void
}
/**
* Calls public method if exists.
* @return bool does method exist?
*/
protected function tryCall(string $method, array $params): bool
/**
* Calls public method if exists.
*
* @param string $method name of the method to be called
* @param array $params parameters for the method
*
* @return HandleResult result of the method if it exists
*/
protected function tryCall(string $method, array $params): ?HandleResult
{
$rc = $this->getReflection();
if ($rc->hasMethod($method)) {
$rm = $rc->getMethod($method);
if ($rm->isPublic() && !$rm->isAbstract() && !$rm->isStatic()) {
$this->checkRequirements($rm);
try {
$args = $rc->combineArgs($rm, $params);
} catch (Nette\InvalidArgumentException $e) {
throw new Nette\Application\BadRequestException($e->getMessage());
}
$rm->invokeArgs($this, $args);
return true;
}
}
return false;
if (!$rc->hasMethod($method)) {
return null;
}
$rm = $rc->getMethod($method);
if (!$rm->isPublic() || $rm->isAbstract() || $rm->isStatic()) {
return null;
}
$this->checkRequirements($rm);
try {
$args = $rc->combineArgs($rm, $params);
} catch (Nette\InvalidArgumentException $e) {
throw new Nette\Application\BadRequestException($e->getMessage());
}
$result = $rm->invokeArgs($this, $args);
if ($result) {
return new HandleResult($result, get_class($this) . '::' . $method);
}
return null;
}
@@ -206,13 +222,37 @@ public function saveState(array &$params): void
/**
* Calls signal handler method.
* @throws BadSignalException if there is not handler method
*
* @return HandleResult - result of the signal handler
*/
public function signalReceived(string $signal): void
{
if (!$this->tryCall($this->formatSignalMethod($signal), $this->params)) {
$signalMethod = $this->formatSignalMethod($signal);
if (!method_exists($this, $signalMethod)) {
$class = get_class($this);
throw new BadSignalException("There is no handler for signal '$signal' in class $class.");
}
$result = $this->tryCall($signalMethod, $this->params);
$this->setSignalResult($result, get_class($this) . "::$signalMethod");
}
private function setSignalResult($value, $origin)
{
if ($value instanceof HandleResult) {
$result = $value;
} elseif ($value) {
$result = new HandleResult($value, $origin);
} else {
$result = null;
}
$this->signalResult = $result;
}
protected function getSignalResult(): ?HandleResult
{
return $this->signalResult;
}
@@ -0,0 +1,52 @@
<?php
/**
* This file is part of the Nette Framework (https://nette.org)
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
*/
declare(strict_types=1);
namespace Nette\Application\UI;
/**
* Wrapper class of a value and origin pair.
*
* Used for action and signal result handling.
*
* @package Nette\Application\UI
*/
class HandleResult
{
/** @var mixed */
private $value;
/** @var string */
private $origin;
/**
* HandleResult constructor.
*
* @param mixed $value
* @param string $origin
*/
public function __construct($value, string $origin)
{
$this->value = $value;
$this->origin = $origin;
}
/** @return mixed */
public function getValue()
{
return $this->value;
}
/** @return string */
public function getOrigin(): string
{
return $this->origin;
}
}
@@ -196,7 +196,7 @@ public function run(Application\Request $request): Application\IResponse
throw new Nette\InvalidStateException("Method $class::startup() or its descendant doesn't call parent::startup().");
}
// calls $this->action<Action>()
$this->tryCall(static::formatActionMethod($this->action), $this->params);
$this->handleActionResult($this->tryCall(static::formatActionMethod($this->action), $this->params));
// autoload components
foreach ($this->globalParams as $id => $foo) {
@@ -212,7 +212,7 @@ public function run(Application\Request $request): Application\IResponse
// SIGNAL HANDLING
// calls $this->handle<Signal>()
$this->processSignal();
$this->handleActionResult($this->processSignal());
// RENDERING VIEW
$this->beforeRender();
@@ -271,6 +271,34 @@ protected function startup()
$this->startupCheck = true;
}
/**
* @param HandleResult $result - result of action or signal
* @throws Application\AbortException
*/
protected function handleActionResult(HandleResult $result = null): void
{
if (!$result) {
return;
}
$response = null;
$value = $result->getValue();
if ($value instanceof Application\IResponse) {
$response = $value;
} elseif (is_array($value) || is_scalar($value)) {
$response = new Responses\JsonResponse($value);
} else {
$origin = $result->getOrigin();
$type = is_object($value) ? get_class($value) : gettype($value);
throw new Nette\InvalidArgumentException("Result of $origin must be application response" .
", array or scalar. Got $type.");
}
$this->sendResponse($response);
}
/**
* Common render method.
@@ -329,10 +357,10 @@ public function detectedCsrf(): void
/**
* @throws BadSignalException
*/
public function processSignal(): void
public function processSignal(): ?HandleResult
{
if ($this->signal === null) {
return;
return null;
}
$component = $this->signalReceiver === '' ? $this : $this->getComponent($this->signalReceiver, false);
@@ -345,6 +373,8 @@ public function processSignal(): void
$component->signalReceived($this->signal);
$this->signal = null;
return $component->getSignalResult();
}

0 comments on commit c99c04e

Please sign in to comment.
You can’t perform that action at this time.