Fixed FlexObject::update() call with partial object update

This commit is contained in:
Matias Griese
2018-11-30 14:30:50 +02:00
parent 77f035eb2d
commit eb770e95d5
4 changed files with 227 additions and 40 deletions

View File

@@ -13,6 +13,7 @@
* Fixed a broken language string [#2261](https://github.com/getgrav/grav/issues/2261)
* Fixed clearing cache having no effect on Doctrine cache
* Fixed `Medium::relativePath()` for streams
* Fixed `FlexObject::update()` call with partial object update
# v1.6.0-beta.6
## 11/12/2018

View File

@@ -14,6 +14,8 @@ use Grav\Common\Data\Data;
use Grav\Common\Data\ValidationException;
use Grav\Common\Grav;
use Grav\Common\Utils;
use Grav\Framework\Flex\Interfaces\FlexFormInterface;
use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
use Grav\Framework\Route\Route;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UploadedFileInterface;
@@ -22,7 +24,7 @@ use Psr\Http\Message\UploadedFileInterface;
* Class FlexForm
* @package Grav\Framework\Flex
*/
class FlexForm implements \Serializable
class FlexForm implements FlexFormInterface
{
/** @var string */
private $name;
@@ -38,15 +40,15 @@ class FlexForm implements \Serializable
private $data;
/** @var UploadedFileInterface[] */
private $files;
/** @var FlexObject */
/** @var FlexObjectInterface */
private $object;
/**
* FlexForm constructor.
* @param string $name
* @param FlexObject|null $object
* @param FlexObjectInterface|null $object
*/
public function __construct(string $name = '', FlexObject $object = null)
public function __construct(string $name = '', FlexObjectInterface $object = null)
{
$this->reset();
@@ -58,12 +60,18 @@ class FlexForm implements \Serializable
$this->id = $this->getName();
}
public function getId() : string
/**
* @return string
*/
public function getId(): string
{
return $this->id;
}
public function setId(string $id)
/**
* @param string $id
*/
public function setId(string $id): void
{
$this->id = $id;
}
@@ -71,7 +79,7 @@ class FlexForm implements \Serializable
/**
* @return string
*/
public function getName() : string
public function getName(): string
{
$object = $this->object;
$name = $this->name ?: 'object';
@@ -83,7 +91,7 @@ class FlexForm implements \Serializable
/**
* @return string
*/
public function getNonceName()
public function getNonceName(): string
{
return 'nonce';
}
@@ -91,7 +99,7 @@ class FlexForm implements \Serializable
/**
* @return string
*/
public function getNonceAction()
public function getNonceAction(): string
{
return 'flex-object';
}
@@ -99,7 +107,7 @@ class FlexForm implements \Serializable
/**
* @return string
*/
public function getUniqueId() : string
public function getUniqueId(): string
{
if (null === $this->uniqueid) {
$this->uniqueid = Utils::generateRandomString(20);
@@ -111,7 +119,7 @@ class FlexForm implements \Serializable
/**
* @return string
*/
public function getAction() : string
public function getAction(): string
{
// TODO:
return '';
@@ -120,7 +128,7 @@ class FlexForm implements \Serializable
/**
* @return array
*/
public function getButtons() : array
public function getButtons(): array
{
return [
[
@@ -131,7 +139,7 @@ class FlexForm implements \Serializable
}
/**
* @return Data|FlexObject
* @return Data|FlexObjectInterface
*/
public function getData()
{
@@ -159,7 +167,7 @@ class FlexForm implements \Serializable
/**
* @return UploadedFileInterface[]
*/
public function getFiles() : array
public function getFiles(): array
{
return $this->files;
}
@@ -167,7 +175,7 @@ class FlexForm implements \Serializable
/**
* @return Route|null
*/
public function getFileUploadAjaxRoute()
public function getFileUploadAjaxRoute(): ?Route
{
$object = $this->getObject();
if (!method_exists($object, 'route')) {
@@ -182,7 +190,7 @@ class FlexForm implements \Serializable
* @param $filename
* @return Route|null
*/
public function getFileDeleteAjaxRoute($field, $filename)
public function getFileDeleteAjaxRoute($field, $filename): ?Route
{
$object = $this->getObject();
if (!method_exists($object, 'route')) {
@@ -195,10 +203,10 @@ class FlexForm implements \Serializable
/**
* Note: this method clones the object.
*
* @param FlexObject $object
* @param FlexObjectInterface $object
* @return $this
*/
public function setObject(FlexObject $object) : self
public function setObject(FlexObjectInterface $object): FlexFormInterface
{
$this->object = clone $object;
@@ -206,9 +214,9 @@ class FlexForm implements \Serializable
}
/**
* @return FlexObject
* @return FlexObjectInterface
*/
public function getObject() : FlexObject
public function getObject(): FlexObjectInterface
{
if (!$this->object) {
throw new \RuntimeException('FlexForm: Object is not defined');
@@ -221,7 +229,7 @@ class FlexForm implements \Serializable
* @param ServerRequestInterface $request
* @return $this
*/
public function handleRequest(ServerRequestInterface $request) : self
public function handleRequest(ServerRequestInterface $request): FlexFormInterface
{
try {
$method = $request->getMethod();
@@ -243,7 +251,7 @@ class FlexForm implements \Serializable
/**
* @return bool
*/
public function isValid() : bool
public function isValid(): bool
{
return !$this->errors;
}
@@ -251,7 +259,7 @@ class FlexForm implements \Serializable
/**
* @return array
*/
public function getErrors() : array
public function getErrors(): array
{
return $this->errors;
}
@@ -259,7 +267,7 @@ class FlexForm implements \Serializable
/**
* @return bool
*/
public function isSubmitted() : bool
public function isSubmitted(): bool
{
return $this->submitted;
}
@@ -269,7 +277,7 @@ class FlexForm implements \Serializable
* @param UploadedFileInterface[] $files
* @return $this
*/
public function submit(array $data, array $files = null) : self
public function submit(array $data, array $files = null): FlexFormInterface
{
try {
if ($this->isSubmitted()) {
@@ -314,7 +322,7 @@ class FlexForm implements \Serializable
/**
* @return $this
*/
public function reset() : self
public function reset(): FlexFormInterface
{
$this->data = null;
$this->files = [];
@@ -329,7 +337,7 @@ class FlexForm implements \Serializable
*
* @return array
*/
public function getFields() : array
public function getFields(): array
{
return $this->getBlueprint()->fields();
}
@@ -337,7 +345,7 @@ class FlexForm implements \Serializable
/**
* @return Blueprint
*/
public function getBlueprint() : Blueprint
public function getBlueprint(): Blueprint
{
return $this->getObject()->getBlueprint($this->name);
}
@@ -347,7 +355,7 @@ class FlexForm implements \Serializable
*
* @return string
*/
public function serialize() : string
public function serialize(): string
{
$data = [
'name' => $this->name,
@@ -366,7 +374,7 @@ class FlexForm implements \Serializable
*
* @param string $data
*/
public function unserialize($data) : void
public function unserialize($data): void
{
$data = unserialize($data, ['allowed_classes' => [FlexObject::class]]);
@@ -379,7 +387,7 @@ class FlexForm implements \Serializable
}
public function getMediaTaskRoute() : string
public function getMediaTaskRoute(): string
{
$grav = Grav::instance();
/** @var Flex $flex */
@@ -392,7 +400,7 @@ class FlexForm implements \Serializable
return '';
}
public function getMediaRoute() : string
public function getMediaRoute(): string
{
return '/' . $this->object->getKey();
}
@@ -400,14 +408,14 @@ class FlexForm implements \Serializable
/**
* @throws \Exception
*/
protected function validate() : void
protected function validate(): void
{
$this->data->validate();
$this->data->filter();
$this->checkUploads($this->files);
}
protected function checkUploads(array $files) : void
protected function checkUploads(array $files): void
{
foreach ($files as $file) {
if ($file instanceof UploadedFileInterface) {
@@ -418,7 +426,7 @@ class FlexForm implements \Serializable
}
}
protected function checkUpload(UploadedFileInterface $file) : void
protected function checkUpload(UploadedFileInterface $file): void
{
// Handle bad filenames.
$filename = $file->getClientFilename();
@@ -438,7 +446,7 @@ class FlexForm implements \Serializable
* @param array $data
* @return array
*/
protected function decodeData($data) : array
protected function decodeData($data): array
{
if (!\is_array($data)) {
return [];
@@ -460,7 +468,7 @@ class FlexForm implements \Serializable
*
* @return array
*/
protected function jsonDecode(array $data) : array
protected function jsonDecode(array $data): array
{
foreach ($data as $key => &$value) {
if (\is_array($value)) {

View File

@@ -18,7 +18,6 @@ use Grav\Common\Page\Medium\MediumFactory;
use Grav\Common\Twig\Twig;
use Grav\Framework\ContentBlock\HtmlBlock;
use Grav\Framework\Flex\Interfaces\FlexAuthorizeInterface;
use Grav\Framework\Flex\Interfaces\FlexStorageInterface;
use Grav\Framework\Flex\Traits\FlexAuthorizeTrait;
use Grav\Framework\Object\Access\NestedArrayAccessTrait;
use Grav\Framework\Object\Access\NestedPropertyTrait;
@@ -117,8 +116,6 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
{
// Validate and filter the incoming data.
$blueprint = $this->getFlexDirectory()->getBlueprint();
$blueprint->validate($data + ['storage_key' => $this->getStorageKey(), 'timestamp' => $this->getTimestamp()]);
$data = $blueprint->filter($data);
if (!$isFullUpdate) {
// Partial update: merge data to the existing object.
@@ -129,6 +126,9 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
// Filter object data.
$this->filterElements($data);
$blueprint->validate($data + ['storage_key' => $this->getStorageKey(), 'timestamp' => $this->getTimestamp()]);
$data = $blueprint->filter($data);
if ($data) {
$this->setElements($data);
}

View File

@@ -0,0 +1,178 @@
<?php
/**
* @package Grav\Framework\Flex
*
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Framework\Flex\Interfaces;
use Grav\Common\Data\Blueprint;
use Grav\Common\Data\Data;
use Grav\Framework\Route\Route;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UploadedFileInterface;
/**
* Class FlexForm
* @package Grav\Framework\Flex
*/
interface FlexFormInterface extends \Serializable
{
/**
* @return string
*/
public function getId(): string;
/**
* @param string $id
*/
public function setId(string $id): void;
/**
* @return string
*/
public function getName(): string;
/**
* @return string
*/
public function getNonceName(): string;
/**
* @return string
*/
public function getNonceAction(): string;
/**
* @return string
*/
public function getUniqueId(): string;
/**
* @return string
*/
public function getAction(): string;
/**
* @return array
*/
public function getButtons() : array;
/**
* @return Data|FlexObjectInterface
*/
public function getData();
/**
* Get a value from the form.
*
* Note: Used in form fields.
*
* @param string $name
* @return mixed
*/
public function getValue(string $name);
/**
* @return UploadedFileInterface[]
*/
public function getFiles() : array;
/**
* @return Route|null
*/
public function getFileUploadAjaxRoute(): ?Route;
/**
* @param $field
* @param $filename
* @return Route|null
*/
public function getFileDeleteAjaxRoute($field, $filename): ?Route;
/**
* Note: this method clones the object.
*
* @param FlexObjectInterface $object
* @return $this
*/
public function setObject(FlexObjectInterface $object): self;
/**
* @return FlexObjectInterface
*/
public function getObject(): FlexObjectInterface;
/**
* @param ServerRequestInterface $request
* @return $this
*/
public function handleRequest(ServerRequestInterface $request): self;
/**
* @return bool
*/
public function isValid(): bool;
/**
* @return array
*/
public function getErrors(): array;
/**
* @return bool
*/
public function isSubmitted(): bool;
/**
* @param array $data
* @param UploadedFileInterface[] $files
* @return $this
*/
public function submit(array $data, array $files = null): self;
/**
* @return $this
*/
public function reset(): self;
/**
* Note: Used in form fields.
*
* @return array
*/
public function getFields(): array;
/**
* @return Blueprint
*/
public function getBlueprint(): Blueprint;
/**
* Implements \Serializable::serialize().
*
* @return string
*/
public function serialize(): string;
/**
* Implements \Serializable::unserialize().
*
* @param string $data
*/
public function unserialize($data): void;
/**
* @return string
*/
public function getMediaTaskRoute(): string;
/**
* @return string
*/
public function getMediaRoute(): string;
}