280 lines
7.7 KiB
PHP
280 lines
7.7 KiB
PHP
|
<?php
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace Grav\Plugin\FlexObjects\Controllers;
|
||
|
|
||
|
use Grav\Common\Grav;
|
||
|
use Grav\Framework\Flex\FlexForm;
|
||
|
use Grav\Framework\Flex\Interfaces\FlexAuthorizeInterface;
|
||
|
use Psr\Http\Message\ResponseInterface;
|
||
|
use Psr\Http\Message\ServerRequestInterface;
|
||
|
use RuntimeException;
|
||
|
|
||
|
/**
|
||
|
* Object controller is for the frontend.
|
||
|
*
|
||
|
* Currently following tasks are supported:
|
||
|
*
|
||
|
* - save (create or update)
|
||
|
* - create
|
||
|
* - update
|
||
|
* - delete
|
||
|
* - reset
|
||
|
* - preview
|
||
|
*/
|
||
|
class ObjectController extends AbstractController
|
||
|
{
|
||
|
/**
|
||
|
* Save object.
|
||
|
*
|
||
|
* Forwards call to either create or update task.
|
||
|
*
|
||
|
* @param ServerRequestInterface $request
|
||
|
* @return ResponseInterface
|
||
|
*/
|
||
|
public function taskSave(ServerRequestInterface $request): ResponseInterface
|
||
|
{
|
||
|
$form = $this->getForm();
|
||
|
$object = $form->getObject();
|
||
|
|
||
|
return $object->exists() ? $this->taskUpdate($request) : $this->taskCreate($request);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create object.
|
||
|
*
|
||
|
* Task fails if object exists.
|
||
|
*
|
||
|
* @param ServerRequestInterface $request
|
||
|
* @return ResponseInterface
|
||
|
*/
|
||
|
public function taskCreate(ServerRequestInterface $request): ResponseInterface
|
||
|
{
|
||
|
$this->checkAuthorization('create');
|
||
|
|
||
|
$form = $this->getForm();
|
||
|
$form->handleRequest($request);
|
||
|
if (!$form->isValid()) {
|
||
|
$error = $form->getError();
|
||
|
if ($error) {
|
||
|
$this->setMessage($error, 'error');
|
||
|
}
|
||
|
$errors = $form->getErrors();
|
||
|
foreach ($errors as $field) {
|
||
|
foreach ($field as $error) {
|
||
|
$this->setMessage($error, 'error');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$data = $form->getData();
|
||
|
if (null !== $data) {
|
||
|
$object = $form->getObject();
|
||
|
$flash = $form->getFlash();
|
||
|
$flash->setObject($object);
|
||
|
$flash->setData($data->toArray());
|
||
|
$flash->save();
|
||
|
}
|
||
|
|
||
|
return $this->createDisplayResponse();
|
||
|
}
|
||
|
|
||
|
// FIXME: make it conditional
|
||
|
$grav = $this->grav;
|
||
|
$grav->fireEvent('gitsync');
|
||
|
|
||
|
$this->setMessage($this->translate('PLUGIN_FLEX_OBJECTS.STATE.CREATED_SUCCESSFULLY'), 'info');
|
||
|
|
||
|
$redirect = $request->getAttribute('redirect', (string)$request->getUri());
|
||
|
|
||
|
return $this->createRedirectResponse($redirect, 303);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update object.
|
||
|
*
|
||
|
* Task fails if object does not exist.
|
||
|
*
|
||
|
* @param ServerRequestInterface $request
|
||
|
* @return ResponseInterface
|
||
|
*/
|
||
|
public function taskUpdate(ServerRequestInterface $request): ResponseInterface
|
||
|
{
|
||
|
$this->checkAuthorization('update');
|
||
|
|
||
|
$form = $this->getForm();
|
||
|
$form->handleRequest($request);
|
||
|
if (!$form->isValid()) {
|
||
|
$error = $form->getError();
|
||
|
if ($error) {
|
||
|
$this->setMessage($error, 'error');
|
||
|
}
|
||
|
$errors = $form->getErrors();
|
||
|
foreach ($errors as $field) {
|
||
|
foreach ($field as $error) {
|
||
|
$this->setMessage($error, 'error');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$data = $form->getData();
|
||
|
if (null !== $data) {
|
||
|
$object = $form->getObject();
|
||
|
$flash = $form->getFlash();
|
||
|
$flash->setObject($object);
|
||
|
$flash->setData($data->toArray());
|
||
|
$flash->save();
|
||
|
}
|
||
|
|
||
|
return $this->createDisplayResponse();
|
||
|
}
|
||
|
|
||
|
// FIXME: make it conditional
|
||
|
$grav = $this->grav;
|
||
|
$grav->fireEvent('gitsync');
|
||
|
|
||
|
$this->setMessage($this->translate('PLUGIN_FLEX_OBJECTS.STATE.UPDATED_SUCCESSFULLY'), 'info');
|
||
|
|
||
|
$redirect = $request->getAttribute('redirect', (string)$request->getUri()->getPath());
|
||
|
|
||
|
return $this->createRedirectResponse($redirect, 303);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Delete object.
|
||
|
*
|
||
|
* @param ServerRequestInterface $request
|
||
|
* @return ResponseInterface
|
||
|
*/
|
||
|
public function taskDelete(ServerRequestInterface $request): ResponseInterface
|
||
|
{
|
||
|
$this->checkAuthorization('delete');
|
||
|
|
||
|
$object = $this->getObject();
|
||
|
if (!$object) {
|
||
|
throw new RuntimeException('Not Found', 404);
|
||
|
}
|
||
|
|
||
|
$object->delete();
|
||
|
|
||
|
$this->setMessage($this->translate('PLUGIN_FLEX_OBJECTS.STATE.DELETED_SUCCESSFULLY'), 'info');
|
||
|
|
||
|
// FIXME: make it conditional
|
||
|
$grav = $this->grav;
|
||
|
$grav->fireEvent('gitsync');
|
||
|
|
||
|
$redirect = $request->getAttribute('redirect', $this->getFlex()->adminRoute($this->getDirectory()));
|
||
|
|
||
|
return $this->createRedirectResponse($redirect, 303);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reset form to original values.
|
||
|
*
|
||
|
* @param ServerRequestInterface $request
|
||
|
* @return ResponseInterface
|
||
|
*/
|
||
|
public function taskReset(ServerRequestInterface $request): ResponseInterface
|
||
|
{
|
||
|
$this->checkAuthorization('save');
|
||
|
|
||
|
$flash = $this->getForm()->getFlash();
|
||
|
$flash->delete();
|
||
|
|
||
|
$redirect = $request->getAttribute('redirect', (string)$request->getUri()->getPath());
|
||
|
|
||
|
return $this->createRedirectResponse($redirect, 303);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Preview object.
|
||
|
*
|
||
|
* Takes a form input and converts it to visible presentation of the object.
|
||
|
*
|
||
|
* @param ServerRequestInterface $request
|
||
|
* @return ResponseInterface
|
||
|
*/
|
||
|
public function taskPreview(ServerRequestInterface $request): ResponseInterface
|
||
|
{
|
||
|
$this->checkAuthorization('save');
|
||
|
|
||
|
/** @var FlexForm $form */
|
||
|
$form = $this->getForm('edit');
|
||
|
$form->setRequest($request);
|
||
|
if (!$form->validate()) {
|
||
|
$error = $form->getError();
|
||
|
if ($error) {
|
||
|
$this->setMessage($error, 'error');
|
||
|
}
|
||
|
$errors = $form->getErrors();
|
||
|
foreach ($errors as $field) {
|
||
|
foreach ($field as $error) {
|
||
|
$this->setMessage($error, 'error');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $this->createRedirectResponse((string)$request->getUri(), 303);
|
||
|
}
|
||
|
|
||
|
$this->object = $form->updateObject();
|
||
|
|
||
|
return $this->actionDisplayPreview();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Display object preview.
|
||
|
*
|
||
|
* @return ResponseInterface
|
||
|
*/
|
||
|
protected function actionDisplayPreview(): ResponseInterface
|
||
|
{
|
||
|
$this->checkAuthorization('save');
|
||
|
$this->checkAuthorization('read');
|
||
|
|
||
|
$object = $this->getObject();
|
||
|
if (!$object) {
|
||
|
throw new RuntimeException('No object found!', 404);
|
||
|
}
|
||
|
|
||
|
$grav = Grav::instance();
|
||
|
|
||
|
$grav['twig']->init();
|
||
|
$grav['theme'];
|
||
|
$content = [
|
||
|
'code' => 200,
|
||
|
'id' => $object->getKey(),
|
||
|
'exists' => $object->exists(),
|
||
|
'html' => (string)$object->render('preview', ['nocache' => []])
|
||
|
];
|
||
|
|
||
|
$accept = $this->getAccept(['application/json', 'text/html']);
|
||
|
if ($accept === 'text/html') {
|
||
|
return $this->createHtmlResponse($content['html']);
|
||
|
}
|
||
|
if ($accept === 'application/json') {
|
||
|
return $this->createJsonResponse($content);
|
||
|
}
|
||
|
|
||
|
throw new RuntimeException('Not found', 404);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $action
|
||
|
* @return void
|
||
|
* @throws RuntimeException
|
||
|
*/
|
||
|
protected function checkAuthorization(string $action): void
|
||
|
{
|
||
|
$object = $this->getObject();
|
||
|
|
||
|
if (!$object) {
|
||
|
throw new RuntimeException('Not Found', 404);
|
||
|
}
|
||
|
|
||
|
if ($object instanceof FlexAuthorizeInterface) {
|
||
|
if (!$object->isAuthorized($action, null, $this->user)) {
|
||
|
throw new RuntimeException('Forbidden', 403);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|