Let plugins run their own PHP code
A plugin can now bring a plugin.php that registers hooks, scheduled tasks, its own tables, public pages and admin screens. Failures stay contained to the plugin; a form on a plugin page can be submitted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b61f958ca1
commit
9825bac3b3
17 files changed
+897
-19
No files matched your search
@@ -9,6 +9,7 @@ use App\Content\PageRepository;
|
||||
use App\Content\SiteSettings;
|
||||
use App\Content\Turnstile;
|
||||
use App\Ops\MailCheck;
|
||||
use App\Plugin\PluginRuntime;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -33,6 +34,7 @@ final class FormController extends AbstractController
|
||||
private string $secret,
|
||||
private string $siteOrigin,
|
||||
private Languages $languages,
|
||||
private PluginRuntime $plugins,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -41,7 +43,8 @@ final class FormController extends AbstractController
|
||||
{
|
||||
$form = $this->forms->findBySlug($slug);
|
||||
$path = trim($request->request->getString('page'), '/') ?: $this->settings->homePath();
|
||||
$page = $this->pages->findPublished($path);
|
||||
// Ein Formular kann auch auf der Seite eines Plugins stehen (ADR 127).
|
||||
$page = $this->pages->findPublished($path) ?? $this->plugins->page('/'.$path);
|
||||
if (null === $form || null === $page) {
|
||||
throw $this->createNotFoundException('Formular oder Seite nicht gefunden.');
|
||||
}
|
||||
@@ -77,8 +80,11 @@ final class FormController extends AbstractController
|
||||
return $this->renderPage($request, $page, $form, ['errors' => ['_form' => 'Gerade gehen sehr viele Anfragen ein. Bitte versuchen Sie es später erneut oder melden Sie sich telefonisch.'], 'values' => $checked['values']], null === $language ? null : ($page['path'] === $this->settings->homePath() ? $language : $language.'/'.$translatedPath));
|
||||
}
|
||||
if (!$silentlyDropped) {
|
||||
// Angaben eines Plugins zur Seite, von der die Anfrage kommt: Name => Text.
|
||||
$extra = array_filter((array) $this->plugins->applyFilters('form.context', [], $form, $path), 'is_string');
|
||||
$checked['values'] += $extra;
|
||||
$submission = $this->forms->store($form['id'], $checked['values'], $checked['consent'], $senderHash);
|
||||
if ($this->deliver($form, $checked['values'])) {
|
||||
if ($this->deliver($form, $checked['values'], $extra)) {
|
||||
$this->forms->markDelivered($submission);
|
||||
}
|
||||
}
|
||||
@@ -101,9 +107,12 @@ final class FormController extends AbstractController
|
||||
return $age >= FormRepository::MIN_SECONDS && $age <= FormRepository::MAX_SECONDS;
|
||||
}
|
||||
|
||||
private function deliver(array $form, array $values): bool
|
||||
private function deliver(array $form, array $values, array $extra = []): bool
|
||||
{
|
||||
$lines = [];
|
||||
foreach ($extra as $name => $text) {
|
||||
$lines[] = $name.': '.$text;
|
||||
}
|
||||
foreach ($form['fields'] as $field) {
|
||||
// Ein Schritt ist eine Überschrift in der Post; ein Feld, das nicht galt, bleibt weg.
|
||||
if ('step' === $field['type']) {
|
||||
|
||||
Reference in new issue
Block a user