Hotfix: Livewire-UI-Komponenten im Ordner Ui (wie der Namespace)
Der Ordner hieß im Repository UI, der Namespace App\Livewire\Web\Components\Ui. Auf dem Mac fällt das nicht auf, auf Linux findet der Autoloader die Klassen nicht: Header, Footer usw. rendern ohne Klasse (500, Undefined variable $logoPath). Wächtertest prüft Pfad und Namespace auf gleiche Schreibweise. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
cbf04e1f9c
commit
a661a68913
7 changed files with 33 additions and 0 deletions
205
app/Livewire/Web/Components/Ui/ContactForm.php
Normal file
205
app/Livewire/Web/Components/Ui/ContactForm.php
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Web\Components\Ui;
|
||||
|
||||
use Acme\ContactForm\ContactFormService;
|
||||
use Acme\ContactForm\SpamDetector;
|
||||
use App\Models\CmsBrand;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Livewire\Component;
|
||||
|
||||
class ContactForm extends Component
|
||||
{
|
||||
public string $firstName = '';
|
||||
|
||||
public string $lastName = '';
|
||||
|
||||
public string $company = '';
|
||||
|
||||
public string $email = '';
|
||||
|
||||
public string $phone = '';
|
||||
|
||||
public string $subject = '';
|
||||
|
||||
public string $message = '';
|
||||
|
||||
public bool $privacy = false;
|
||||
|
||||
public bool $success = false;
|
||||
|
||||
/** @var string Hidden honeypot field */
|
||||
public string $website = '';
|
||||
|
||||
public ?int $formLoadedAt = null;
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
public array $content = [];
|
||||
|
||||
/** Farbwelt der Seite (`interior` | `immobilien`). */
|
||||
public string $world = 'interior';
|
||||
|
||||
public function mount(string $world = 'interior'): void
|
||||
{
|
||||
$this->world = $world === 'immobilien' ? 'immobilien' : 'interior';
|
||||
$this->content = $this->loadContent();
|
||||
$this->formLoadedAt = time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inhalte der Welt. Die Immobilien-Welt liegt als Overlay über der Interior-Sektion:
|
||||
* `contact_form_immobilien` trägt nur, was abweicht (Einstieg, Betreffe) – Adresse,
|
||||
* Beschriftungen und Social Media erbt sie von `contact_form`.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function loadContent(): array
|
||||
{
|
||||
$base = cms_theme_section('contact_form');
|
||||
$base = is_array($base) ? $base : [];
|
||||
|
||||
if ($this->world !== 'immobilien') {
|
||||
return $base;
|
||||
}
|
||||
|
||||
$overlay = cms_theme_section('contact_form_immobilien');
|
||||
|
||||
if (! is_array($overlay)) {
|
||||
return $base;
|
||||
}
|
||||
|
||||
return array_replace_recursive($base, $overlay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Betreffe in Gruppen: Interior (mit den gepflegten Kernmarken vorneweg), Immobilien, B2in.
|
||||
* Die Welt der Seite bestimmt die Reihenfolge – ihre Gruppe steht oben.
|
||||
*
|
||||
* Ohne `subject_groups` (aeltere CMS-Staende) faellt das Formular auf die flache Liste zurueck.
|
||||
*
|
||||
* @return array<string, array{label: string, subjects: array<string, string>}>
|
||||
*/
|
||||
public function getSubjectGroupsProperty(): array
|
||||
{
|
||||
$groups = $this->content['form']['subject_groups'] ?? null;
|
||||
|
||||
if (! is_array($groups) || $groups === []) {
|
||||
$flat = $this->content['form']['subjects'] ?? [];
|
||||
unset($flat['']);
|
||||
|
||||
return $flat === [] ? [] : ['all' => ['label' => '', 'subjects' => $flat]];
|
||||
}
|
||||
|
||||
$brands = [];
|
||||
|
||||
foreach (CmsBrand::forFrontend() as $slug => $brand) {
|
||||
$brands[$slug] = (string) ($brand['name'] ?? $slug);
|
||||
}
|
||||
|
||||
$out = [];
|
||||
|
||||
foreach ($groups as $key => $group) {
|
||||
$subjects = is_array($group['subjects'] ?? null) ? $group['subjects'] : [];
|
||||
|
||||
if ($key === 'interior') {
|
||||
$subjects = $brands + $subjects;
|
||||
}
|
||||
|
||||
$out[$key] = [
|
||||
'label' => (string) ($group['label'] ?? ''),
|
||||
'subjects' => $subjects,
|
||||
];
|
||||
}
|
||||
|
||||
$first = $this->world === 'immobilien' ? 'immobilien' : 'interior';
|
||||
|
||||
if (isset($out[$first])) {
|
||||
$out = [$first => $out[$first]] + $out;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alle waehlbaren Betreffe als flache Liste (Schluessel → Beschriftung).
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getSubjectsProperty(): array
|
||||
{
|
||||
$flat = [];
|
||||
|
||||
foreach ($this->getSubjectGroupsProperty() as $group) {
|
||||
$flat += $group['subjects'];
|
||||
}
|
||||
|
||||
return $flat;
|
||||
}
|
||||
|
||||
public function getSubjectPlaceholderProperty(): string
|
||||
{
|
||||
return (string) ($this->content['form']['subjects'][''] ?? $this->content['form']['subject_placeholder'] ?? __('ui.contact_form.subject_placeholder'));
|
||||
}
|
||||
|
||||
/** @return array<int, array<string, mixed>> */
|
||||
public function getContactInfoProperty(): array
|
||||
{
|
||||
return $this->content['contact_info'] ?? [];
|
||||
}
|
||||
|
||||
public function submit(ContactFormService $service): void
|
||||
{
|
||||
$this->validate([
|
||||
'firstName' => ['required', 'string', 'max:255'],
|
||||
'lastName' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'email:rfc', 'max:255'],
|
||||
'subject' => ['required', 'string', Rule::in(array_keys($this->subjects))],
|
||||
'message' => ['required', 'string', 'max:2000'],
|
||||
'company' => ['nullable', 'string', 'max:255'],
|
||||
'phone' => ['nullable', 'string', 'max:255'],
|
||||
'privacy' => ['accepted'],
|
||||
'website' => ['nullable', 'string', 'max:0'],
|
||||
]);
|
||||
|
||||
$spamDetector = SpamDetector::fromConfig();
|
||||
$payload = [
|
||||
'first_name' => $this->firstName,
|
||||
'last_name' => $this->lastName,
|
||||
'email' => $this->email,
|
||||
'subject' => $this->subject,
|
||||
'message' => $this->message,
|
||||
'company' => $this->company,
|
||||
'phone' => $this->phone,
|
||||
'website' => $this->website,
|
||||
'ip' => request()->ip(),
|
||||
'user_agent' => request()->userAgent(),
|
||||
'is_spam' => false,
|
||||
];
|
||||
|
||||
$payload['is_spam'] = $spamDetector->detect($payload, $this->formLoadedAt);
|
||||
|
||||
$subjectLabel = $this->getSubjectsProperty()[$this->subject] ?? $this->subject;
|
||||
$prefix = $this->world === 'immobilien' ? 'Kontaktanfrage B2in Immobilien' : 'Kontaktanfrage B2in';
|
||||
$subjectLine = $subjectLabel
|
||||
? $prefix.': '.$subjectLabel
|
||||
: __('contact-form::contact-form.default_subject');
|
||||
$service->handle($payload, $subjectLine, 'contact-form');
|
||||
|
||||
$this->success = true;
|
||||
$this->firstName = '';
|
||||
$this->lastName = '';
|
||||
$this->company = '';
|
||||
$this->email = '';
|
||||
$this->phone = '';
|
||||
$this->subject = '';
|
||||
$this->message = '';
|
||||
$this->privacy = false;
|
||||
$this->website = '';
|
||||
$this->formLoadedAt = time();
|
||||
}
|
||||
|
||||
public function render(): \Illuminate\View\View
|
||||
{
|
||||
return view('livewire.web.components.ui.contact-form');
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue