From 69d6b52a0efdbdf50e07221b5f37cd3a4580acfe Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 11 Jul 2019 15:23:50 +0300 Subject: [PATCH] Fixed `Form` not to use deleted flash object until the end of the request fixing issues with reset --- CHANGELOG.md | 2 + system/src/Grav/Framework/Form/FormFlash.php | 57 +++++++++++++------ .../Form/Interfaces/FormInterface.php | 7 +++ .../Grav/Framework/Form/Traits/FormTrait.php | 4 +- 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f92408c37..5cf9529b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ 1. [](#improved) * Better support for Symfony local server `symfony server:start` * Make `Route` objects immutable +1. [](#bugfix) + * Fixed `Form` not to use deleted flash object until the end of the request fixing issues with reset # v1.7.0-beta.4 ## 07/01/2019 diff --git a/system/src/Grav/Framework/Form/FormFlash.php b/system/src/Grav/Framework/Form/FormFlash.php index e2ba82658..c029efb56 100644 --- a/system/src/Grav/Framework/Form/FormFlash.php +++ b/system/src/Grav/Framework/Form/FormFlash.php @@ -62,6 +62,7 @@ class FormFlash implements FormFlashInterface 'unique_id' => $args[1] ?? null, 'form_name' => $args[2] ?? null, ]; + $config = array_filter($config, static function ($val) { return $val !== null; }); } $this->sessionId = $config['session_id'] ?? 'no-session'; @@ -73,30 +74,50 @@ class FormFlash implements FormFlashInterface $locator = Grav::instance()['locator']; $this->folder = $folder && $locator->isStream($folder) ? $locator->findResource($folder, true, true) : $folder; - $file = $this->getTmpIndex(); - $this->exists = $file->exists(); - if ($this->exists) { - try { - $data = (array)$file->content(); - } catch (\Exception $e) { - $data = []; - } - $this->formName = $content['form'] ?? $config['form_name'] ?? ''; + $this->init($this->loadStoredForm(), $config); + } + + protected function init(?array $data, array $config): void + { + if (null === $data) { + $this->exists = false; + $this->formName = $config['form_name'] ?? ''; + $this->url = ''; + $this->createdTimestamp = $this->updatedTimestamp = time(); + $this->files = []; + } else { + $this->exists = true; + $this->formName = $data['form'] ?? $config['form_name'] ?? ''; $this->url = $data['url'] ?? ''; $this->user = $data['user'] ?? null; $this->updatedTimestamp = $data['timestamps']['updated'] ?? time(); $this->createdTimestamp = $data['timestamps']['created'] ?? $this->updatedTimestamp; $this->data = $data['data'] ?? null; $this->files = $data['files'] ?? []; - } else { - $this->formName = $config['form_name'] ?? ''; - $this->url = ''; - $this->createdTimestamp = $this->updatedTimestamp = time(); - $this->files = []; } } + /** + * Load raw flex flash data from the filesystem. + * + * @return array + */ + protected function loadStoredForm(): ?array + { + $file = $this->getTmpIndex(); + $exists = $file->exists(); + + $data = null; + if ($exists) { + try { + $data = (array)$file->content(); + } catch (\Exception $e) {} + } + + return $data; + } + /** * @inheritDoc */ @@ -200,13 +221,13 @@ class FormFlash implements FormFlashInterface /** * @inheritDoc */ - public function save(): self + public function save(bool $force = false): self { if (!($this->folder && $this->uniqueId)) { return $this; } - if ($this->data || $this->files) { + if ($force || $this->data || $this->files) { // Only save if there is data or files to be saved. $file = $this->getTmpIndex(); $file->save($this->jsonSerialize()); @@ -459,6 +480,10 @@ class FormFlash implements FormFlashInterface protected function removeTmpDir(): void { + // Make sure that index file cache gets always cleared. + $file = $this->getTmpIndex(); + $file->free(); + $tmpDir = $this->getTmpDir(); if ($tmpDir && file_exists($tmpDir)) { Folder::delete($tmpDir); diff --git a/system/src/Grav/Framework/Form/Interfaces/FormInterface.php b/system/src/Grav/Framework/Form/Interfaces/FormInterface.php index d218e7282..96d3145e8 100644 --- a/system/src/Grav/Framework/Form/Interfaces/FormInterface.php +++ b/system/src/Grav/Framework/Form/Interfaces/FormInterface.php @@ -122,6 +122,13 @@ interface FormInterface extends RenderInterface, \Serializable */ public function getValue(string $name); + /** + * Get form flash object. + * + * @return FormFlashInterface + */ + public function getFlash(); + /** * @param ServerRequestInterface $request * @return $this diff --git a/system/src/Grav/Framework/Form/Traits/FormTrait.php b/system/src/Grav/Framework/Form/Traits/FormTrait.php index e9727447f..6bd994f1d 100644 --- a/system/src/Grav/Framework/Form/Traits/FormTrait.php +++ b/system/src/Grav/Framework/Form/Traits/FormTrait.php @@ -180,7 +180,6 @@ trait FormTrait /** @var Twig $twig */ $twig = $grav['twig']; $twig->twig_vars['form'] = $this; - } try { @@ -335,7 +334,7 @@ trait FormTrait * * @return FormFlash */ - public function getFlash(): FormFlash + public function getFlash() { if (null === $this->flash) { $grav = Grav::instance(); @@ -385,7 +384,6 @@ trait FormTrait } return $list; - } /**