From 29157a3011c097abdbc4232a7ff1425bcc43a466 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 28 Sep 2021 13:41:38 +0300 Subject: [PATCH] Fixed images from plugins/themes disappearing when saving twice --- CHANGELOG.md | 2 + classes/plugin/Admin.php | 65 +++++++++++++++++- classes/plugin/AdminBaseController.php | 91 +++++++++----------------- classes/plugin/AdminController.php | 2 +- 4 files changed, 99 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcb3b72e..3a4d69ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ 1. [](#new) * Updated SCSS compiler to v1.8 +2. [](#bugfix) + * Fixed images from plugins/themes disappearing when saving twice # v1.10.22 ## 09/16/2021 diff --git a/classes/plugin/Admin.php b/classes/plugin/Admin.php index a84df7b5..29c94dea 100644 --- a/classes/plugin/Admin.php +++ b/classes/plugin/Admin.php @@ -38,6 +38,7 @@ use Grav\Framework\Route\RouteFactory; use Grav\Plugin\AdminPlugin; use Grav\Plugin\Login\Login; use Grav\Plugin\Login\TwoFactorAuth\TwoFactorAuth; +use JsonException; use PicoFeed\Parser\MalformedXmlException; use Psr\Http\Message\ServerRequestInterface; use RocketTheme\Toolbox\Event\Event; @@ -873,7 +874,7 @@ class Admin public function data($type, array $post = []) { if (!$post) { - $post = $this->grav['uri']->post()['data'] ?? []; + $post = $this->preparePost($this->grav['uri']->post()['data'] ?? []); } try { @@ -2427,4 +2428,66 @@ class Admin return $changelog; } + + /** + * Prepare and return POST data. + * + * @param array $post + * @return array + */ + public function preparePost($post): array + { + if (!is_array($post)) { + return []; + } + + unset($post['task']); + + // Decode JSON encoded fields and merge them to data. + if (isset($post['_json'])) { + $post = array_replace_recursive($post, $this->jsonDecode($post['_json'])); + unset($post['_json']); + } + + return $this->cleanDataKeys($post); + } + + /** + * Recursively JSON decode data. + * + * @param array $data + * @return array + * @throws JsonException + */ + private function jsonDecode(array $data): array + { + foreach ($data as &$value) { + if (is_array($value)) { + $value = $this->jsonDecode($value); + } else { + $value = json_decode($value, true, 512, JSON_THROW_ON_ERROR); + } + } + + return $data; + } + + /** + * @param array $source + * @return array + */ + private function cleanDataKeys(array $source): array + { + $out = []; + foreach ($source as $key => $value) { + $key = str_replace(['%5B', '%5D'], ['[', ']'], $key); + if (is_array($value)) { + $out[$key] = $this->cleanDataKeys($value); + } else { + $out[$key] = $value; + } + } + + return $out; + } } diff --git a/classes/plugin/AdminBaseController.php b/classes/plugin/AdminBaseController.php index d2f2935b..ebdb45f5 100644 --- a/classes/plugin/AdminBaseController.php +++ b/classes/plugin/AdminBaseController.php @@ -19,6 +19,7 @@ use Grav\Common\Plugin; use Grav\Common\Theme; use Grav\Framework\Controller\Traits\ControllerResponseTrait; use Grav\Framework\RequestHandler\Exception\RequestException; +use JsonException; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use RocketTheme\Toolbox\Event\Event; @@ -34,56 +35,31 @@ class AdminBaseController { use ControllerResponseTrait; - /** - * @var Grav - */ + /** @var Grav */ public $grav; - - /** - * @var string - */ + /** @var string */ public $view; - - /** - * @var string - */ + /** @var string */ public $task; - - /** - * @var string - */ + /** @var string */ public $route; - - /** - * @var array - */ + /** @var array */ public $post; - - /** - * @var array|null - */ + /** @var array|null */ public $data; + /** @var array */ + public $blacklist_views = []; - /** - * @var \Grav\Common\Uri - */ + /** @var Uri */ protected $uri; - - /** - * @var Admin - */ + /** @var Admin */ protected $admin; - - /** - * @var string - */ + /** @var string */ protected $redirect; - - /** - * @var int - */ + /** @var int */ protected $redirectCode; + /** @var string[] */ protected $upload_errors = [ 0 => 'There is no error, the file uploaded with success', 1 => 'The uploaded file exceeds the max upload size', @@ -95,9 +71,6 @@ class AdminBaseController 8 => 'A PHP extension stopped the file upload' ]; - /** @var array */ - public $blacklist_views = []; - /** * Performs a task. * @@ -105,6 +78,10 @@ class AdminBaseController */ public function execute() { + if (null === $this->admin) { + $this->admin = $this->grav['admin']; + } + // Ignore blacklisted views. if (in_array($this->view, $this->blacklist_views, true)) { return false; @@ -671,7 +648,6 @@ class AdminBaseController * Prepare and return POST data. * * @param array $post - * * @return array */ protected function getPost($post) @@ -688,25 +664,24 @@ class AdminBaseController unset($post['_json']); } - $post = $this->cleanDataKeys($post); - - return $post; + return $this->cleanDataKeys($post); } /** * Recursively JSON decode data. * - * @param array $data - * + * @param array $data * @return array + * @throws JsonException + * @internal Do not use directly! */ - protected function jsonDecode(array $data) + protected function jsonDecode(array $data): array { foreach ($data as &$value) { if (is_array($value)) { $value = $this->jsonDecode($value); } else { - $value = json_decode($value, true); + $value = json_decode($value, true, 512, JSON_THROW_ON_ERROR); } } @@ -716,19 +691,17 @@ class AdminBaseController /** * @param array $source * @return array + * @internal Do not use directly! */ - protected function cleanDataKeys($source = []) + protected function cleanDataKeys(array $source): array { $out = []; - - if (is_array($source)) { - foreach ($source as $key => $value) { - $key = str_replace(['%5B', '%5D'], ['[', ']'], $key); - if (is_array($value)) { - $out[$key] = $this->cleanDataKeys($value); - } else { - $out[$key] = $value; - } + foreach ($source as $key => $value) { + $key = str_replace(['%5B', '%5D'], ['[', ']'], $key); + if (is_array($value)) { + $out[$key] = $this->cleanDataKeys($value); + } else { + $out[$key] = $value; } } diff --git a/classes/plugin/AdminController.php b/classes/plugin/AdminController.php index ac3e14ca..c73def8a 100644 --- a/classes/plugin/AdminController.php +++ b/classes/plugin/AdminController.php @@ -56,6 +56,7 @@ class AdminController extends AdminBaseController public function initialize(Grav $grav = null, $view = null, $task = null, $route = null, $post = null) { $this->grav = $grav; + $this->admin = $this->grav['admin']; $this->view = $view; $this->task = $task ?: 'display'; if (isset($post['data'])) { @@ -67,7 +68,6 @@ class AdminController extends AdminBaseController } $this->post = $this->getPost($post); $this->route = $route; - $this->admin = $this->grav['admin']; $this->grav->fireEvent('onAdminControllerInit', new Event(['controller' => &$this])); }