Added FlexObject::getDiff() to see difference to the saved object

This commit is contained in:
Matias Griese
2021-11-11 20:06:24 +02:00
parent 33b473c290
commit 2a04628459
2 changed files with 52 additions and 14 deletions

View File

@@ -3,10 +3,12 @@
1. [](#new)
* Updated phpstan to v1.0
* Added `FlexObject::getDiff()` to see difference to the saved object
2. [](#improved)
* Use Symfony `dump` instead of PHP's `vardump` in side the `{{ vardump(x) }}` Twig vardump function
* Added `route` and `request` to `onPagesInitialized` event
* Improved page cloning, added method `Page::initialize()`
* Improved `FlexObject::getChanges()`: return changed lists and arrays as whole instead of just changed keys/values
3. [](#bugfix)
* Fixed path traversal vulnerability when using `bin/grav server`
* Fixed unescaped error messages in JSON error responses

View File

@@ -12,6 +12,7 @@ namespace Grav\Framework\Flex;
use ArrayAccess;
use Exception;
use Grav\Common\Data\Blueprint;
use Grav\Common\Data\Data;
use Grav\Common\Debugger;
use Grav\Common\Grav;
use Grav\Common\Inflector;
@@ -72,8 +73,6 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
private $_meta;
/** @var array */
protected $_original;
/** @var array */
protected $_changes;
/** @var string */
protected $storage_key;
/** @var int */
@@ -454,13 +453,50 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
}
/**
* Get any changes based on data sent to update
* Get diff array from the object.
*
* @return array
*/
public function getDiff(): array
{
$blueprint = $this->getBlueprint();
$flattenOriginal = $blueprint->flattenData($this->getOriginalData());
$flattenElements = $blueprint->flattenData($this->getElements());
$removedElements = array_diff_key($flattenOriginal, $flattenElements);
$diff = [];
// Include all added or changed keys.
foreach ($flattenElements as $key => $value) {
$orig = $flattenOriginal[$key] ?? null;
if ($orig !== $value) {
$diff[$key] = ['old' => $orig, 'new' => $value];
}
}
// Include all removed keys.
foreach ($removedElements as $key => $value) {
$diff[$key] = ['old' => $value, 'new' => null];
}
return $diff;
}
/**
* Get any changes from the object.
*
* @return array
*/
public function getChanges(): array
{
return $this->_changes ?? [];
$diff = $this->getDiff();
$data = new Data();
foreach ($diff as $key => $change) {
$data->set($key, $change['new']);
}
return $data->toArray();
}
/**
@@ -641,14 +677,19 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
public function update(array $data, array $files = [])
{
if ($data) {
// Get currently stored data.
$elements = $this->getElements();
// Store original version of the object.
if ($this->_original === null) {
$this->_original = $elements;
}
$blueprint = $this->getBlueprint();
// Process updated data through the object filters.
$this->filterElements($data);
// Get currently stored data.
$elements = $this->getElements();
// Merge existing object to the test data to be validated.
$test = $blueprint->mergeData($elements, $data);
@@ -657,19 +698,14 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
$data = $blueprint->filter($data, true, true);
// Finally update the object.
foreach ($blueprint->flattenData($data) as $key => $value) {
$flattenData = $blueprint->flattenData($data);
foreach ($flattenData as $key => $value) {
if ($value === null) {
$this->unsetNestedProperty($key);
} else {
$this->setNestedProperty($key, $value);
}
}
// Store the changes
if ($this->_original === null) {
$this->_original = $elements;
}
$this->_changes = Utils::arrayDiffMultidimensional($this->_original, $this->getElements());
}
if ($files && method_exists($this, 'setUpdatedMedia')) {