Эх сурвалжийг харах

adding impressum to mail footer, adding default checked for datenschutz checkbox

Medowar 1 сар өмнө
parent
commit
3bd58a85d0

+ 1 - 0
config/form_schema.php

@@ -547,6 +547,7 @@ return [
                     'label'    => 'Einverständniserklärung zur Veröffentlichung von Fotos und Filmaufnahmen',
                     'label'    => 'Einverständniserklärung zur Veröffentlichung von Fotos und Filmaufnahmen',
                     'type'     => 'checkbox',
                     'type'     => 'checkbox',
                     'required' => false,
                     'required' => false,
+                    'checked'  => true,
                     'subtext'  => 'Ich willige ein, dass im Rahmen von Veranstaltungen und Einsätzen angefertigte Foto- und Filmaufnahmen für Veröffentlichungen, Berichte, in Printmedien, Neuen Medien und auf der Internetseite des Vereines und seinen übergeordneten Verbänden unentgeltlich verwendet werden dürfen. Eine Verwendung der Aufnahmen für andere als die beschriebenen Zwecke oder ein Inverkehrbringen durch Überlassung der Aufnahme an Dritte außer der Dachorganisation des Vereins ist unzulässig. Diese Einwilligung ist freiwillig. Durch eine nicht erteilte Einwilligung entstehen mir als Mitglied keine Nachteile. Die Einwilligung kann jederzeit mit Wirkung für die Zukunft widerrufen werden.',
                     'subtext'  => 'Ich willige ein, dass im Rahmen von Veranstaltungen und Einsätzen angefertigte Foto- und Filmaufnahmen für Veröffentlichungen, Berichte, in Printmedien, Neuen Medien und auf der Internetseite des Vereines und seinen übergeordneten Verbänden unentgeltlich verwendet werden dürfen. Eine Verwendung der Aufnahmen für andere als die beschriebenen Zwecke oder ein Inverkehrbringen durch Überlassung der Aufnahme an Dritte außer der Dachorganisation des Vereins ist unzulässig. Diese Einwilligung ist freiwillig. Durch eine nicht erteilte Einwilligung entstehen mir als Mitglied keine Nachteile. Die Einwilligung kann jederzeit mit Wirkung für die Zukunft widerrufen werden.',
                 ],
                 ],
             ],
             ],

+ 2 - 0
docs/form_schema.md

@@ -18,6 +18,7 @@
           'label' => 'Label',
           'label' => 'Label',
           'type' => 'text|email|date|select|textarea|checkbox|file|table',
           'type' => 'text|email|date|select|textarea|checkbox|file|table',
           'required' => true|false,
           'required' => true|false,
+          'checked' => true, // nur für type=checkbox: beim Öffnen des Formulars vorausgewählt
           'required_if' => ['field' => 'anderes_feld', 'equals' => 'Wert'],
           'required_if' => ['field' => 'anderes_feld', 'equals' => 'Wert'],
           'options' => [['value' => 'x', 'label' => 'X']],
           'options' => [['value' => 'x', 'label' => 'X']],
           'rows' => 4, // nur für type=table
           'rows' => 4, // nur für type=table
@@ -40,6 +41,7 @@
 ## Validierungslogik
 ## Validierungslogik
 
 
 - `required: true` macht Feld immer verpflichtend.
 - `required: true` macht Feld immer verpflichtend.
+- `checked: true` (nur `type: checkbox`) rendert die Checkbox beim Öffnen eines neuen Formulars bereits aktiviert. Der Nutzer kann sie weiterhin abwählen. Beim Laden eines gespeicherten Entwurfs gilt der zuvor gespeicherte Zustand, nicht der Default.
 - `required_if` macht Feld verpflichtend, wenn Quellfeld exakt `equals` entspricht.
 - `required_if` macht Feld verpflichtend, wenn Quellfeld exakt `equals` entspricht.
 - Upload-Pflicht wird gegen vorhandene Upload-Metadaten geprüft.
 - Upload-Pflicht wird gegen vorhandene Upload-Metadaten geprüft.
 - Für `type: table` gilt ein Feld als leer, wenn in allen Datenzeilen alle Zellen leer sind.
 - Für `type: table` gilt ein Feld als leer, wenn in allen Datenzeilen alle Zellen leer sind.

+ 2 - 1
index.php

@@ -75,7 +75,8 @@ function renderField(array $field, string $addressDisclaimerText): void
     echo '<div class="' . $fieldClass . '" data-field="' . $key . '">';
     echo '<div class="' . $fieldClass . '" data-field="' . $key . '">';
 
 
     if ($type === 'checkbox') {
     if ($type === 'checkbox') {
-        echo '<label class="checkbox-label"><input type="checkbox" name="form_data[' . $key . ']" value="1" ' . $required . '> ' . $label . $requiredLabel . '</label>';
+        $checkedAttr = !empty($field['checked']) ? ' checked' : '';
+        echo '<label class="checkbox-label"><input type="checkbox" name="form_data[' . $key . ']" value="1" ' . $required . $checkedAttr . '> ' . $label . $requiredLabel . '</label>';
     } else {
     } else {
         $labelFor = $type === 'table' ? htmlspecialchars($keyRaw . '__r0__c0') : $key;
         $labelFor = $type === 'table' ? htmlspecialchars($keyRaw . '__r0__c0') : $key;
         echo '<label for="' . $labelFor . '">' . $label . $requiredLabel . '</label>';
         echo '<label for="' . $labelFor . '">' . $label . $requiredLabel . '</label>';

+ 56 - 2
src/mail/mailer.php

@@ -316,6 +316,7 @@ final class Mailer
             $h .= '</ul>';
             $h .= '</ul>';
         }
         }
 
 
+        $h .= $this->renderFooterHtml();
         $h .= '</body></html>';
         $h .= '</body></html>';
         return $h;
         return $h;
     }
     }
@@ -354,6 +355,7 @@ final class Mailer
             }
             }
         }
         }
 
 
+        $t .= $this->renderFooterText();
         return $t;
         return $t;
     }
     }
 
 
@@ -399,6 +401,7 @@ final class Mailer
         }
         }
 
 
         $h .= '<p style="color:#888;font-size:0.9em">Bei Rückfragen kontaktieren Sie bitte den Verein.</p>';
         $h .= '<p style="color:#888;font-size:0.9em">Bei Rückfragen kontaktieren Sie bitte den Verein.</p>';
+        $h .= $this->renderFooterHtml();
         $h .= '</body></html>';
         $h .= '</body></html>';
         return $h;
         return $h;
     }
     }
@@ -435,6 +438,7 @@ final class Mailer
         }
         }
 
 
         $t .= "Bei Rückfragen kontaktieren Sie bitte den Verein.\n";
         $t .= "Bei Rückfragen kontaktieren Sie bitte den Verein.\n";
+        $t .= $this->renderFooterText();
         return $t;
         return $t;
     }
     }
 
 
@@ -455,6 +459,52 @@ final class Mailer
         return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
         return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
     }
     }
 
 
+    /**
+     * Footer appended to every outgoing mail: organisation name and imprint link.
+     */
+    private function renderFooterHtml(): string
+    {
+        $orgName = trim((string) ($this->appConfig['project_name'] ?? ''));
+        $impressumUrl = trim((string) ($this->appConfig['impressum_url'] ?? ''));
+
+        $lines = [];
+        if ($orgName !== '') {
+            $lines[] = '<strong>' . $this->esc($orgName) . '</strong>';
+        }
+        if ($impressumUrl !== '') {
+            $lines[] = 'Impressum: <a href="' . $this->esc($impressumUrl) . '" style="color:#888">'
+                . $this->esc($impressumUrl) . '</a>';
+        }
+
+        if ($lines === []) {
+            return '';
+        }
+
+        return '<hr style="border:none;border-top:1px solid #ddd;margin:24px 0 8px">'
+            . '<p style="color:#888;font-size:0.8em;line-height:1.5;margin:0">'
+            . implode('<br>', $lines) . '</p>';
+    }
+
+    private function renderFooterText(): string
+    {
+        $orgName = trim((string) ($this->appConfig['project_name'] ?? ''));
+        $impressumUrl = trim((string) ($this->appConfig['impressum_url'] ?? ''));
+
+        $lines = [];
+        if ($orgName !== '') {
+            $lines[] = $orgName;
+        }
+        if ($impressumUrl !== '') {
+            $lines[] = 'Impressum: ' . $impressumUrl;
+        }
+
+        if ($lines === []) {
+            return '';
+        }
+
+        return "\n" . str_repeat('-', 40) . "\n" . implode("\n", $lines) . "\n";
+    }
+
     private function renderMinorAdminNoticeHtml(): string
     private function renderMinorAdminNoticeHtml(): string
     {
     {
         return '<div style="background:#fff3cd;border:1px solid #f0c36d;padding:10px 12px;margin:12px 0">'
         return '<div style="background:#fff3cd;border:1px solid #f0c36d;padding:10px 12px;margin:12px 0">'
@@ -492,6 +542,7 @@ final class Mailer
             $h .= $this->signedFormReceivedRowHtml('Bestätigt durch', $confirmedBy);
             $h .= $this->signedFormReceivedRowHtml('Bestätigt durch', $confirmedBy);
         }
         }
         $h .= '</table>';
         $h .= '</table>';
+        $h .= $this->renderFooterHtml();
         $h .= '</body></html>';
         $h .= '</body></html>';
 
 
         return $h;
         return $h;
@@ -516,6 +567,7 @@ final class Mailer
             $t .= 'Bestätigt durch: ' . $confirmedBy . "\n";
             $t .= 'Bestätigt durch: ' . $confirmedBy . "\n";
         }
         }
 
 
+        $t .= $this->renderFooterText();
         return $t;
         return $t;
     }
     }
 
 
@@ -738,7 +790,8 @@ final class Mailer
             $template = "Ihr Sicherheitscode lautet: {{code}}\nDer Code ist {{ttl_minutes}} Minuten gültig.";
             $template = "Ihr Sicherheitscode lautet: {{code}}\nDer Code ist {{ttl_minutes}} Minuten gültig.";
         }
         }
 
 
-        return $this->replaceOtpTemplateVars($template, $code, $ttlSeconds, false);
+        return $this->replaceOtpTemplateVars($template, $code, $ttlSeconds, false)
+            . $this->renderFooterText();
     }
     }
 
 
     private function renderOtpHtml(string $code, int $ttlSeconds): string
     private function renderOtpHtml(string $code, int $ttlSeconds): string
@@ -749,7 +802,8 @@ final class Mailer
             $template = '<p>Ihr Sicherheitscode lautet: <strong>{{code}}</strong></p><p>Der Code ist {{ttl_minutes}} Minuten gültig.</p>';
             $template = '<p>Ihr Sicherheitscode lautet: <strong>{{code}}</strong></p><p>Der Code ist {{ttl_minutes}} Minuten gültig.</p>';
         }
         }
 
 
-        return $this->replaceOtpTemplateVars($template, $code, $ttlSeconds, true);
+        return $this->replaceOtpTemplateVars($template, $code, $ttlSeconds, true)
+            . $this->renderFooterHtml();
     }
     }
 
 
     private function replaceOtpTemplateVars(string $template, string $code, int $ttlSeconds, bool $htmlContext): string
     private function replaceOtpTemplateVars(string $template, string $code, int $ttlSeconds, bool $htmlContext): string