(Grav GitSync) Automatic Commit from smokephil
This commit is contained in:
commit
4267db646d
2765 changed files with 462171 additions and 0 deletions
543
plugins/flex-objects/classes/Controllers/ObjectController.php
Normal file
543
plugins/flex-objects/classes/Controllers/ObjectController.php
Normal file
|
|
@ -0,0 +1,543 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Grav\Plugin\FlexObjects\Controllers;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Framework\Flex\FlexForm;
|
||||
use Grav\Framework\Flex\FlexObject;
|
||||
use Grav\Framework\Flex\Interfaces\FlexAuthorizeInterface;
|
||||
use Grav\Framework\Route\Route;
|
||||
use Grav\Plugin\FlexObjects\Events\FlexTaskEvent;
|
||||
use Nyholm\Psr7\ServerRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
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();
|
||||
$callable = function (array $data, array $files, FlexObject $object) {
|
||||
if (method_exists($object, 'storeOriginal')) {
|
||||
$object->storeOriginal();
|
||||
}
|
||||
$object->update($data, $files);
|
||||
if (\is_callable([$object, 'check'])) {
|
||||
$object->check($this->user);
|
||||
}
|
||||
|
||||
$event = new FlexTaskEvent($this, $object, 'create');
|
||||
$this->grav->dispatchEvent($event);
|
||||
|
||||
$object->save();
|
||||
};
|
||||
|
||||
$form->setSubmitMethod($callable);
|
||||
$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->object = $form->getObject();
|
||||
$event = new Event(
|
||||
[
|
||||
'task' => 'create',
|
||||
'controller' => $this,
|
||||
'object' => $this->object,
|
||||
'response' => null,
|
||||
'message' => null,
|
||||
]
|
||||
);
|
||||
|
||||
$this->grav->fireEvent("flex.{$this->type}.task.create.after", $event);
|
||||
|
||||
$this->setMessage($event['message'] ?? $this->translate('PLUGIN_FLEX_OBJECTS.STATE.CREATED_SUCCESSFULLY'), 'info');
|
||||
|
||||
if ($event['response']) {
|
||||
return $event['response'];
|
||||
}
|
||||
|
||||
|
||||
$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();
|
||||
$callable = function (array $data, array $files, FlexObject $object) {
|
||||
if (method_exists($object, 'storeOriginal')) {
|
||||
$object->storeOriginal();
|
||||
}
|
||||
$object->update($data, $files);
|
||||
if (\is_callable([$object, 'check'])) {
|
||||
$object->check($this->user);
|
||||
}
|
||||
|
||||
$event = new FlexTaskEvent($this, $object, 'update');
|
||||
$this->grav->dispatchEvent($event);
|
||||
|
||||
$object->save();
|
||||
};
|
||||
|
||||
$form->setSubmitMethod($callable);
|
||||
$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->object = $form->getObject();
|
||||
$event = new Event(
|
||||
[
|
||||
'task' => 'update',
|
||||
'controller' => $this,
|
||||
'object' => $this->object,
|
||||
'response' => null,
|
||||
'message' => null,
|
||||
]
|
||||
);
|
||||
|
||||
$this->grav->fireEvent("flex.{$this->type}.task.update.after", $event);
|
||||
|
||||
$this->setMessage($event['message'] ?? $this->translate('PLUGIN_FLEX_OBJECTS.STATE.UPDATED_SUCCESSFULLY'), 'info');
|
||||
|
||||
if ($event['response']) {
|
||||
return $event['response'];
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
$event = new FlexTaskEvent($this, $object, 'delete');
|
||||
$this->grav->dispatchEvent($event);
|
||||
|
||||
$object->delete();
|
||||
|
||||
// FIXME: make it conditional
|
||||
$grav = $this->grav;
|
||||
$grav->fireEvent('gitsync');
|
||||
|
||||
$event = new Event(
|
||||
[
|
||||
'task' => 'delete',
|
||||
'controller' => $this,
|
||||
'object' => $object,
|
||||
'response' => null,
|
||||
'message' => null,
|
||||
]
|
||||
);
|
||||
|
||||
$this->grav->fireEvent("flex.{$this->type}.task.delete.after", $event);
|
||||
|
||||
$this->setMessage($this->translate($event['message'] ?? 'PLUGIN_FLEX_OBJECTS.STATE.DELETED_SUCCESSFULLY'), 'info');
|
||||
|
||||
if ($event['response']) {
|
||||
return $event['response'];
|
||||
}
|
||||
|
||||
$redirect = $request->getAttribute('redirect', (string)$request->getUri()->getPath());
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function taskMediaList(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$directory = $this->getDirectory();
|
||||
if (!$directory) {
|
||||
throw new RuntimeException('Not Found', 404);
|
||||
}
|
||||
|
||||
return $this->forwardMediaTask('action', 'media.list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function taskMediaUpload(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$directory = $this->getDirectory();
|
||||
if (!$directory) {
|
||||
throw new RuntimeException('Not Found', 404);
|
||||
}
|
||||
|
||||
return $this->forwardMediaTask('task', 'media.upload');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function taskMediaUploadMeta(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$directory = $this->getDirectory();
|
||||
if (!$directory) {
|
||||
throw new RuntimeException('Not Found', 404);
|
||||
}
|
||||
|
||||
return $this->forwardMediaTask('task', 'media.upload.meta');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function taskMediaReorder(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$directory = $this->getDirectory();
|
||||
if (!$directory) {
|
||||
throw new RuntimeException('Not Found', 404);
|
||||
}
|
||||
|
||||
return $this->forwardMediaTask('task', 'media.reorder');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function taskMediaDelete(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$directory = $this->getDirectory();
|
||||
if (!$directory) {
|
||||
throw new RuntimeException('Not Found', 404);
|
||||
}
|
||||
|
||||
return $this->forwardMediaTask('task', 'media.delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function taskGetFilesInFolder(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$directory = $this->getDirectory();
|
||||
if (!$directory) {
|
||||
throw new RuntimeException('Not Found', 404);
|
||||
}
|
||||
|
||||
return $this->forwardMediaTask('action', 'media.picker');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
* @deprecated Do not use
|
||||
*/
|
||||
public function taskFilesUpload(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
/** @var Route $route */
|
||||
$route = $this->grav['route'];
|
||||
if ($route->getParam('task') === 'media.upload') {
|
||||
return $this->taskMediaUpload($request);
|
||||
}
|
||||
|
||||
throw new RuntimeException('Task filesUpload should not be called, please update form plugin!', 400);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
* @deprecated Do not use
|
||||
*/
|
||||
public function taskRemoveMedia(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
/** @var Route $route */
|
||||
$route = $this->grav['route'];
|
||||
if ($route->getParam('task') === 'media.delete') {
|
||||
return $this->taskMediaDelete($request);
|
||||
}
|
||||
|
||||
throw new RuntimeException('Task removeMedia should not be called, please update form plugin!', 400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display object preview.
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public 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
|
||||
* @param string|null $scope
|
||||
* @return void
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function checkAuthorization(string $action, string $scope = null): void
|
||||
{
|
||||
$object = $this->getObject();
|
||||
|
||||
if (!$object) {
|
||||
throw new RuntimeException('Not Found', 404);
|
||||
}
|
||||
|
||||
if ($object instanceof FlexAuthorizeInterface) {
|
||||
if (!$object->isAuthorized($action, $scope, $this->user)) {
|
||||
throw new RuntimeException('Forbidden', 403);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string[] $actions
|
||||
* @return void
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function checkAuthorizations(array $actions): void
|
||||
{
|
||||
$object = $this->getObject();
|
||||
|
||||
if (!$object) {
|
||||
throw new RuntimeException('Not Found', 404);
|
||||
}
|
||||
|
||||
if ($object instanceof FlexAuthorizeInterface) {
|
||||
$test = false;
|
||||
foreach ($actions as $action) {
|
||||
$test |= $object->isAuthorized($action, null, $this->user);
|
||||
}
|
||||
|
||||
if (!$test) {
|
||||
throw new RuntimeException('Forbidden', 403);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param string $name
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
protected function forwardMediaTask(string $type, string $name): ResponseInterface
|
||||
{
|
||||
/** @var Route $route */
|
||||
$route = $this->grav['route']->withGravParam('task', null)->withGravParam($type, $name);
|
||||
$object = $this->getObject();
|
||||
|
||||
/** @var ServerRequest $request */
|
||||
$request = $this->grav['request'];
|
||||
$request = $request
|
||||
->withAttribute($type, $name)
|
||||
->withAttribute('type', $this->type)
|
||||
->withAttribute('key', $this->key)
|
||||
->withAttribute('storage_key', $object && $object->exists() ? $object->getStorageKey() : null)
|
||||
->withAttribute('route', $route)
|
||||
->withAttribute('forwarded', true)
|
||||
->withAttribute('object', $object);
|
||||
|
||||
$controller = new MediaController();
|
||||
if ($this->user) {
|
||||
$controller->setUser($this->user);
|
||||
}
|
||||
|
||||
return $controller->handle($request);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue