Skip to content

Commit

Permalink
Merge branch 'release/7.2.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
rhukster committed Jun 27, 2023
2 parents 11aa715 + 69f459a commit fed50ab
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 30 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# v7.2.1
## 06/27/2023

1. [](#improved)
* Added some optional debug output to help isolate form loading problems
1. [](#bugfix)
* More robust fix for multi-language form caching

# v7.2.0
## 06/21/2023

Expand Down
13 changes: 12 additions & 1 deletion blueprints.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Form
slug: form
type: plugin
version: 7.2.0
version: 7.2.1
description: Enables forms handling and processing
icon: check-square
author:
Expand Down Expand Up @@ -34,6 +34,17 @@ form:
title: PLUGIN_FORM.GENERAL

fields:
debug:
type: toggle
label: Debug
highlight: 1
default: 0
options:
1: PLUGIN_ADMIN.ENABLED
0: PLUGIN_ADMIN.DISABLED
validate:
type: bool

built_in_css:
type: toggle
label: PLUGIN_FORM.USE_BUILT_IN_CSS
Expand Down
95 changes: 66 additions & 29 deletions form.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use Grav\Plugin\Form\Forms;
use Grav\Plugin\Form\TwigExtension;
use Grav\Common\HTTP\Client;
use Monolog\Logger;
use ReCaptcha\ReCaptcha;
use ReCaptcha\RequestMethod\CurlPost;
use RecursiveArrayIterator;
Expand Down Expand Up @@ -66,6 +67,7 @@ class FormPlugin extends Plugin
/** @var array */
protected $json_response = [];


/**
* @return bool
*/
Expand Down Expand Up @@ -147,6 +149,8 @@ class_alias(Form::class, 'Grav\Plugin\Form');
'onTwigSiteVariables' => ['onTwigVariables', 0],
'onFormValidationProcessed' => ['onFormValidationProcessed', 0],
]);


}

/**
Expand Down Expand Up @@ -224,9 +228,8 @@ public function onPageInitialized(): void
/** @var PageInterface $page */
$page = $this->grav['page'];

// Force rebuild form when form has not been built and form cache expired.
// This happens when form cache expires before the page cache
// and then does not trigger 'onPageProcessed' event.

// DEPRECATED: This should no longer ever happen
if (!$this->forms) {
$this->onPageProcessed(new Event(['page' => $page]));
}
Expand Down Expand Up @@ -311,9 +314,11 @@ public function onPageInitialized(): void
/** @var Forms $forms */
$forms = $this->grav['forms'];

$lang = $this->grav['language']->getLanguage();

/** @var Route $route */
$route = $this->grav['route'];
$pageForms = $this->forms[$route->getRoute()] ?? [];
$pageForms = $this->forms[$lang][$route->getRoute()] ?? [];

/**
* @var string $name
Expand Down Expand Up @@ -828,10 +833,11 @@ public function onFormValidationError(Event $event): void
public function addFormDefinition(PageInterface $page, string $name, array $form): void
{
$route = ($page->home() ? '/' : $page->route()) ?? '/';
$lang = $this->grav['language']->getLanguage();

if (!isset($this->forms[$route][$name])) {
if (!isset($this->forms[$lang][$route][$name])) {
$form['_page_routable'] = !$page->isModule();
$this->forms[$route][$name] = $form;
$this->forms[$lang][$route][$name] = $form;
$this->saveCachedForms();
}
}
Expand All @@ -849,12 +855,13 @@ public function addForm(?string $route, ?FormInterface $form): void
return;
}

$lang = $this->grav['language']->getLanguage();
$name = $form->getName();

if (!isset($this->forms[$route][$name])) {
if (!isset($this->forms[$lang][$route][$name])) {
$form['_page_routable'] = true;

$this->forms[$route][$name] = $form;
$this->forms[$lang][$route][$name] = $form;
$this->saveCachedForms();
}
}
Expand All @@ -869,6 +876,7 @@ public function getForm($data = null): ?FormInterface
{
/** @var Pages $pages */
$pages = $this->grav['pages'];
$lang = $this->grav['language']->getLanguage();

// Handle parameters.
if (is_array($data)) {
Expand Down Expand Up @@ -914,7 +922,7 @@ public function getForm($data = null): ?FormInterface

// Attempt to find the form from the page.
if ('' !== $route) {
$forms = $this->forms[$route] ?? [];
$forms = $this->forms[$lang][$route] ?? [];

if (!$unnamed) {
// Get form by the name.
Expand All @@ -930,9 +938,7 @@ public function getForm($data = null): ?FormInterface
if (null === $form) {
// First check if we requested a specific form which didn't exist.
if ($route_provided || $unnamed) {
/** @var Debugger $debugger */
$debugger = $this->grav['debugger'];
$debugger->addMessage(sprintf('Form %s not found in page %s', $name ?? 'unnamed', $route), 'warning');
$this->grav['debugger']->addMessage(sprintf('Form %s not found in page %s', $name ?? 'unnamed', $route), 'warning');

return null;
}
Expand All @@ -946,8 +952,7 @@ public function getForm($data = null): ?FormInterface

// Check for naming conflicts.
if (count($forms) > 1) {
$debugger = $this->grav['debugger'];
$debugger->addMessage(sprintf('Fetching form by its name, but there are multiple pages with the same form name %s', $name), 'warning');
$this->grav['debugger']->addMessage(sprintf('Fetching form by its name, but there are multiple pages with the same form name %s', $name), 'warning');
}

[$route, $name, $form] = $first;
Expand All @@ -959,9 +964,7 @@ public function getForm($data = null): ?FormInterface
if (is_array($form)) {
// Form was cached as an array, try to create the object.
if (null === $page) {
/** @var Debugger $debugger */
$debugger = $this->grav['debugger'];
$debugger->addMessage(sprintf('Form %s cannot be created as page %s does not exist', $name, $route), 'warning');
$this->grav['debugger']->addMessage(sprintf('Form %s cannot be created as page %s does not exist', $name, $route), 'warning');

return null;
}
Expand Down Expand Up @@ -1096,7 +1099,10 @@ protected function getCurrentPageRoute()
protected function findFormByName(string $name): array
{
$list = [];
foreach ($this->forms as $route => $forms) {
$lang = $this->grav['language']->getLanguage();
$lang_forms = $this->forms[$lang] ?? [];

foreach ($lang_forms as $route => $forms) {
foreach ($forms as $key => $form) {
if ($name === $key && !empty($form['_page_routable'])) {
$list[] = [$route, $key, $form];
Expand Down Expand Up @@ -1233,12 +1239,9 @@ protected function loadCachedForms(): void
/** @var Cache $cache */
$cache = $this->grav['cache'];

[$forms] = $cache->fetch($this->getFormCacheId());
$forms = $cache->fetch($this->getFormCacheId());
} catch (Exception $e) {
/** @var Debugger $debugger */
$debugger = Grav::instance()['debugger'];
$debugger->addMessage(sprintf('Unserializing cached forms failed: %s', $e->getMessage()), 'error');

$this->grav['debugger']->addMessage(sprintf('Unserializing cached forms failed: %s', $e->getMessage()), 'error');
$forms = null;
}

Expand All @@ -1248,7 +1251,11 @@ protected function loadCachedForms(): void

// Only update the forms if it's not empty
if ($forms) {
$this->forms = array_merge($this->forms, $forms);
$this->forms = Utils::arrayMergeRecursiveUnique($this->forms, $forms);
if ($this->config()['debug']) {
$this->grav['log']->addDebug(sprintf("<<<< Loaded cached forms: %s\n%s", $this->getFormCacheId(), $this->arrayToString($this->forms)));
}

}
}

Expand All @@ -1261,8 +1268,17 @@ protected function saveCachedForms(): void
{
/** @var Cache $cache */
$cache = $this->grav['cache'];
$cache_id = $this->getFormCacheId();

$forms = $cache->fetch($cache_id);
if ($forms) {
$this->forms = Utils::arrayMergeRecursiveUnique($this->forms, $forms);
}

$cache->save($this->getFormCacheId(), [$this->forms]);
$cache->save($cache_id, $this->forms);
if ($this->config()['debug']) {
$this->grav['log']->addDebug(sprintf(">>>> Saved cached forms: %s\n%s", $this->getFormCacheId(), $this->arrayToString($this->forms)));
}
}

/**
Expand All @@ -1272,10 +1288,10 @@ protected function saveCachedForms(): void
*/
protected function getFormCacheId(): string
{
/** @var Pages $pages */
$pages = $this->grav['pages'];

return $pages->getPagesCacheId() . '-form-plugin';
/** @var \Grav\Common\Cache $cache */
$cache = $this->grav['cache'];
$cache_id = $cache->getKey() . '-form-plugin';
return $cache_id;
}

/**
Expand Down Expand Up @@ -1308,4 +1324,25 @@ protected function processBasicCaptchaImage(Uri $uri)
exit;
}
}

protected function arrayToString($array, $level = 2) {
$result = $this->limitArrayLevels($array, $level);
return json_encode($result, JSON_UNESCAPED_SLASHES);
}

protected function limitArrayLevels($array, $levelsToKeep, $currentLevel = 0) {
if ($currentLevel >= $levelsToKeep) {
return '-';
}

$result = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$value = $this->limitArrayLevels($value, $levelsToKeep, $currentLevel + 1);
}
$result[$key] = $value;
}

return $result;
}
}
1 change: 1 addition & 0 deletions form.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ built_in_css: true
inline_css: true
refresh_prevention: false
client_side_validation: true
debug: false
inline_errors: false
files:
multiple: false # To allow multiple files, default is single
Expand Down

0 comments on commit fed50ab

Please sign in to comment.