[CORE][Controller] Allow routes without text/html response

Improve GET getters
This commit is contained in:
Diogo Peralta Cordeiro 2021-10-18 13:17:08 +01:00
parent 03f6029ce5
commit 99ab24ec23
Signed by: diogo
GPG Key ID: 18D2D35001FBFAB0
3 changed files with 31 additions and 21 deletions

View File

@ -24,6 +24,7 @@ use App\Core\DB\DB;
use App\Core\Event; use App\Core\Event;
use App\Core\GSFile; use App\Core\GSFile;
use App\Core\Modules\Component; use App\Core\Modules\Component;
use App\Core\Router\RouteLoader;
use App\Core\Router\Router; use App\Core\Router\Router;
use App\Util\Common; use App\Util\Common;
use Component\Avatar\Controller as C; use Component\Avatar\Controller as C;
@ -36,7 +37,7 @@ class Avatar extends Component
{ {
} }
public function onAddRoute($r): bool public function onAddRoute(RouteLoader $r): bool
{ {
$r->connect('avatar_actor', '/actor/{actor_id<\d+>}/avatar/{size<full|big|medium|small>?full}', [Controller\Avatar::class, 'avatar_view']); $r->connect('avatar_actor', '/actor/{actor_id<\d+>}/avatar/{size<full|big|medium|small>?full}', [Controller\Avatar::class, 'avatar_view']);
$r->connect('avatar_default', '/avatar/default/{size<full|big|medium|small>?full}', [Controller\Avatar::class, 'default_avatar_view']); $r->connect('avatar_default', '/avatar/default/{size<full|big|medium|small>?full}', [Controller\Avatar::class, 'default_avatar_view']);

View File

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types = 1);
// {{{ License // {{{ License
// This file is part of GNU social - https://www.gnu.org/software/social // This file is part of GNU social - https://www.gnu.org/software/social
// //
@ -24,6 +26,7 @@
* @category Controller * @category Controller
* *
* @author Hugo Sales <hugo@hsal.es> * @author Hugo Sales <hugo@hsal.es>
* @author Diogo Peralta Cordeiro <@diogo.site>
* @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org * @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/ */
@ -48,10 +51,11 @@ use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Validator\Exception\ValidatorException; use Symfony\Component\Validator\Exception\ValidatorException;
/** /**
* @method int int(string $param) * @method int int(string $param)
* @method bool bool(string $param) * @method bool bool(string $param)
* @method string string(string $param) * @method string string(string $param)
* @method mixed handle(Request $request, mixed ...$extra) * @method string params(string $param)
* @method mixed handle(Request $request, mixed ...$extra)
*/ */
abstract class Controller extends AbstractController implements EventSubscriberInterface abstract class Controller extends AbstractController implements EventSubscriberInterface
{ {
@ -72,7 +76,7 @@ abstract class Controller extends AbstractController implements EventSubscriberI
{ {
$this->request = $request; $this->request = $request;
$class = static::class; $class = static::class;
$method = 'on' . ucfirst(strtolower($request->getMethod())); $method = 'on' . ucfirst(mb_strtolower($request->getMethod()));
$attributes = array_diff_key($request->attributes->get('_route_params'), array_flip(['_format', '_fragment', '_locale', 'template', 'accept', 'is_system_path'])); $attributes = array_diff_key($request->attributes->get('_route_params'), array_flip(['_format', '_fragment', '_locale', 'template', 'accept', 'is_system_path']));
if (method_exists($class, $method)) { if (method_exists($class, $method)) {
return $this->{$method}($request, ...$attributes); return $this->{$method}($request, ...$attributes);
@ -108,7 +112,7 @@ abstract class Controller extends AbstractController implements EventSubscriberI
{ {
$request = $event->getRequest(); $request = $event->getRequest();
$response = $event->getControllerResult(); $response = $event->getControllerResult();
if (!is_array($response)) { if (!\is_array($response)) {
// This means it's not one of our custom format responses, nothing to do // This means it's not one of our custom format responses, nothing to do
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
return $event; return $event;
@ -117,7 +121,7 @@ abstract class Controller extends AbstractController implements EventSubscriberI
$this->vars = array_merge_recursive($this->vars, $response); $this->vars = array_merge_recursive($this->vars, $response);
$template = $this->vars['_template']; $template = \array_key_exists('_template', $this->vars) ? $this->vars['_template'] : null;
unset($this->vars['_template'], $response['_template']); unset($this->vars['_template'], $response['_template']);
// Respond in the most preferred acceptable content type // Respond in the most preferred acceptable content type
@ -132,12 +136,17 @@ abstract class Controller extends AbstractController implements EventSubscriberI
'response' => &$potential_response, 'response' => &$potential_response,
]) !== Event::stop) { ]) !== Event::stop) {
switch ($format) { switch ($format) {
case 'html':
$event->setResponse($this->render($template, $this->vars));
break;
case 'json': case 'json':
$event->setResponse(new JsonResponse($response)); $event->setResponse(new JsonResponse($response));
break; break;
case 'html':
if ($template !== null) {
$event->setResponse($this->render($template, $this->vars));
break;
} else {
// no break, goto default
}
// no break
default: default:
throw new ClientException(_m('Unsupported format: {format}', ['format' => $format]), 406); // 406 Not Acceptable throw new ClientException(_m('Unsupported format: {format}', ['format' => $format]), 406); // 406 Not Acceptable
} }
@ -192,22 +201,22 @@ abstract class Controller extends AbstractController implements EventSubscriberI
/** /**
* Get and convert GET parameters. Can be called with `int`, `bool`, `string`, etc * Get and convert GET parameters. Can be called with `int`, `bool`, `string`, etc
* *
* @throws ValidatorException
* @throws Exception * @throws Exception
* @throws ValidatorException
* *
* @return null|mixed the value or null if no paramter exists * @return null|array|bool|int|string the value or null if no parameter exists
*/ */
public function __call(string $method, array $args) public function __call(string $method, array $args): array|bool|int|string|null
{ {
$name = $args[0];
$value = $this->request->query->get($name);
switch ($method) { switch ($method) {
case 'int': case 'int':
return (int) $value; return $this->request->query->getInt($args[0]);
case 'bool': case 'bool':
return (bool) $value; return $this->request->query->getBoolean($args[0]);
case 'string': case 'string':
return (string) $value; return $this->request->query->get($args[0]);
case 'params':
return $this->request->query->all();
default: default:
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
Log::critical($m = "Method '{$method}' on class App\\Core\\Controller not found (__call)"); Log::critical($m = "Method '{$method}' on class App\\Core\\Controller not found (__call)");

View File

@ -307,12 +307,12 @@ class Actor extends Entity
public function getUri(): string public function getUri(): string
{ {
return Router::url('actor_id', ['actor_id' => $this->getId()]); return Router::url('actor_view_id', ['id' => $this->getId()]);
} }
public function getUrl(): string public function getUrl(int $type = Router::ABSOLUTE_PATH): string
{ {
return Router::url('actor_nickname', ['actor_nickname' => $this->getNickname()]); return Router::url('actor_view_nickname', ['nickname' => $this->getNickname()], $type);
} }
public static function schemaDef(): array public static function schemaDef(): array