123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- <?php
- declare(strict_types=1);
- namespace Grav\Plugin\FlexObjects\Controllers;
- use Grav\Common\Config\Config;
- use Grav\Common\Grav;
- use Grav\Common\Inflector;
- use Grav\Common\Language\Language;
- use Grav\Common\Session;
- use Grav\Common\Uri;
- use Grav\Common\User\Interfaces\UserInterface;
- use Grav\Common\Utils;
- use Grav\Framework\Controller\Traits\ControllerResponseTrait;
- use Grav\Framework\Flex\FlexDirectory;
- use Grav\Framework\Flex\FlexForm;
- use Grav\Framework\Flex\FlexFormFlash;
- use Grav\Framework\Flex\Interfaces\FlexFormInterface;
- use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
- use Grav\Framework\Psr7\Response;
- use Grav\Framework\RequestHandler\Exception\NotFoundException;
- use Grav\Framework\RequestHandler\Exception\PageExpiredException;
- use Grav\Framework\Route\Route;
- use Grav\Plugin\FlexObjects\Flex;
- use Grav\Plugin\Form\Forms;
- use Psr\Http\Message\ResponseInterface;
- use Psr\Http\Message\ServerRequestInterface;
- use Psr\Http\Server\RequestHandlerInterface;
- use RocketTheme\Toolbox\Event\Event;
- use RocketTheme\Toolbox\Session\Message;
- use function in_array;
- use function is_callable;
- /**
- * Class AbstractController
- * @package Grav\Plugin\FlexObjects\Controllers
- */
- abstract class AbstractController implements RequestHandlerInterface
- {
- use ControllerResponseTrait;
- /** @var string */
- protected $nonce_action = 'flex-object';
- /** @var string */
- protected $nonce_name = 'nonce';
- /** @var ServerRequestInterface */
- protected $request;
- /** @var Grav */
- protected $grav;
- /** @var UserInterface|null */
- protected $user;
- /** @var string */
- protected $type;
- /** @var string */
- protected $key;
- /** @var FlexDirectory */
- protected $directory;
- /** @var FlexObjectInterface */
- protected $object;
- /**
- * Handle request.
- *
- * Fires event: flex.[directory].[task|action].[command]
- *
- * @param ServerRequestInterface $request
- * @return Response
- */
- public function handle(ServerRequestInterface $request): ResponseInterface
- {
- $attributes = $request->getAttributes();
- $this->request = $request;
- $this->grav = $attributes['grav'] ?? Grav::instance();
- $this->type = $attributes['type'] ?? null;
- $this->key = $attributes['key'] ?? null;
- if ($this->type) {
- $this->directory = $this->getFlex()->getDirectory($this->type);
- $this->object = $attributes['object'] ?? null;
- if (!$this->object && $this->key && $this->directory) {
- $this->object = $this->directory->getObject($this->key) ?? $this->directory->createObject([], $this->key ?? '');
- if (is_callable([$this->object, 'refresh'])) {
- $this->object->refresh();
- }
- }
- }
- /** @var Route $route */
- $route = $attributes['route'];
- $post = $this->getPost();
- if ($this->isFormSubmit()) {
- $form = $this->getForm();
- $this->nonce_name = $attributes['nonce_name'] ?? $form->getNonceName();
- $this->nonce_action = $attributes['nonce_action'] ?? $form->getNonceAction();
- }
- try {
- $task = $request->getAttribute('task') ?? $post['task'] ?? $route->getParam('task');
- if ($task) {
- if (empty($attributes['forwarded'])) {
- $this->checkNonce($task);
- }
- $type = 'task';
- $command = $task;
- } else {
- $type = 'action';
- $command = $request->getAttribute('action') ?? $post['action'] ?? $route->getParam('action') ?? 'display';
- }
- $command = strtolower($command);
- $event = new Event(
- [
- 'controller' => $this,
- 'response' => null
- ]
- );
- $this->grav->fireEvent("flex.{$this->type}.{$type}.{$command}", $event);
- $response = $event['response'];
- if (!$response) {
- /** @var Inflector $inflector */
- $inflector = $this->grav['inflector'];
- $method = $type . $inflector::camelize($command);
- if ($method && method_exists($this, $method)) {
- $response = $this->{$method}($request);
- } else {
- throw new NotFoundException($request);
- }
- }
- } catch (\Exception $e) {
- $response = $this->createErrorResponse($e);
- }
- if ($response instanceof Response) {
- return $response;
- }
- return $this->createJsonResponse($response);
- }
- /**
- * @return ServerRequestInterface
- */
- public function getRequest(): ServerRequestInterface
- {
- return $this->request;
- }
- /**
- * @param string|null $name
- * @param mixed $default
- * @return mixed
- */
- public function getPost(string $name = null, $default = null)
- {
- $body = $this->request->getParsedBody();
- if ($name) {
- return $body[$name] ?? $default;
- }
- return $body;
- }
- /**
- * @return bool
- */
- public function isFormSubmit(): bool
- {
- return (bool)$this->getPost('__form-name__');
- }
- /**
- * @param string|null $type
- * @return FlexForm
- */
- public function getForm(string $type = null): FlexFormInterface
- {
- $object = $this->getObject();
- if (!$object) {
- throw new \RuntimeException('Not Found', 404);
- }
- $formName = $this->getPost('__form-name__');
- if ($formName) {
- /** @var Forms $forms */
- $forms = $this->getGrav()['forms'];
- $form = $forms->getActiveForm();
- if ($form instanceof FlexForm && $form->getName() === $formName && $form->getObject()->getFlexKey() === $object->getFlexKey()) {
- return $form;
- }
- }
- return $object->getForm($type ?? 'edit');
- }
- /**
- * @param FlexObjectInterface $object
- * @param string $type
- * @return FlexFormFlash
- */
- protected function getFormFlash(FlexObjectInterface $object, string $type = '')
- {
- /** @var Uri $uri */
- $uri = $this->grav['uri'];
- $url = $uri->url;
- $formName = $this->getPost('__form-name__');
- if (!$formName) {
- $form = $object->getForm($type);
- $formName = $form->getName();
- $uniqueId = $form->getUniqueId();
- } else {
- $uniqueId = $this->getPost('__unique_form_id__') ?: $formName ?: sha1($url);
- }
- /** @var Session $session */
- $session = $this->grav['session'];
- $config = [
- 'session_id' => $session->getId(),
- 'unique_id' => $uniqueId,
- 'form_name' => $formName,
- ];
- $flash = new FlexFormFlash($config);
- if (!$flash->exists()) {
- $flash->setUrl($url)->setUser($this->grav['user']);
- }
- return $flash;
- }
- /**
- * @return Grav
- */
- public function getGrav(): Grav
- {
- return $this->grav;
- }
- /**
- * @return Session
- */
- public function getSession(): Session
- {
- return $this->grav['session'];
- }
- /**
- * @return Flex
- */
- public function getFlex(): Flex
- {
- return $this->grav['flex_objects'];
- }
- /**
- * @return string
- */
- public function getDirectoryType(): string
- {
- return $this->type;
- }
- /**
- * @return string
- */
- public function getObjectKey(): string
- {
- return $this->key;
- }
- /**
- * @return FlexDirectory|null
- */
- public function getDirectory(): ?FlexDirectory
- {
- return $this->directory;
- }
- /**
- * @return FlexObjectInterface|null
- */
- public function getObject(): ?FlexObjectInterface
- {
- return $this->object;
- }
- /**
- * @param string $string
- * @return string
- */
- public function translate(string $string): string
- {
- /** @var Language $language */
- $language = $this->grav['language'];
- return $language->translate($string);
- }
- /**
- * @param string $message
- * @param string $type
- * @return $this
- */
- public function setMessage(string $message, string $type = 'info'): self
- {
- /** @var Message $messages */
- $messages = $this->grav['messages'];
- $messages->add($message, $type);
- return $this;
- }
- /**
- * @param UserInterface $user
- * @return void
- */
- public function setUser(UserInterface $user): void
- {
- $this->user = $user;
- }
- /**
- * @return Config
- */
- protected function getConfig(): Config
- {
- return $this->grav['config'];
- }
- /**
- * @param string $task
- * @return void
- * @throws PageExpiredException
- */
- protected function checkNonce(string $task): void
- {
- $nonce = null;
- if (in_array(strtoupper($this->request->getMethod()), ['POST', 'PUT', 'PATCH', 'DELETE'])) {
- $nonce = $this->getPost($this->nonce_name);
- }
- if (!$nonce) {
- $nonce = $this->grav['uri']->param($this->nonce_name);
- }
- if (!$nonce) {
- $nonce = $this->grav['uri']->query($this->nonce_name);
- }
- if (!$nonce || !Utils::verifyNonce($nonce, $this->nonce_action)) {
- throw new PageExpiredException($this->request);
- }
- }
- }
|