generated from boboko/starter
73 lines
2.3 KiB
PHP
73 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Requests\ContactRequest;
|
|
use App\Mail\ContactConfirmationMail;
|
|
use App\Mail\ContactMessageMail;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
use Illuminate\View\View;
|
|
use Throwable;
|
|
|
|
/**
|
|
* Contact form. Nothing is stored: the message is emailed to the store
|
|
* (CONTACT_EMAIL) and the sender gets a generic confirmation. Both are sent
|
|
* synchronously so a failed store email can be reported back on the form.
|
|
*
|
|
* Limited per IP in here rather than with throttle middleware, so the limit
|
|
* shows as a message on the form instead of a bare 429 page.
|
|
*/
|
|
class ContactController extends Controller
|
|
{
|
|
private const SEND_LIMIT = 3;
|
|
private const SEND_DECAY_SECONDS = 600;
|
|
|
|
public function index(string $locale): View
|
|
{
|
|
return view('contact');
|
|
}
|
|
|
|
public function send(string $locale, ContactRequest $request): RedirectResponse
|
|
{
|
|
$key = 'contact:'.$request->ip();
|
|
|
|
if (RateLimiter::tooManyAttempts($key, self::SEND_LIMIT)) {
|
|
return back()->withInput()->with('contact_error', __('storefront.contact.too_many'));
|
|
}
|
|
|
|
RateLimiter::hit($key, self::SEND_DECAY_SECONDS);
|
|
|
|
$data = $request->validated();
|
|
$to = config('services.contact.email');
|
|
|
|
try {
|
|
if (blank($to)) {
|
|
throw new \RuntimeException('CONTACT_EMAIL is not set.');
|
|
}
|
|
|
|
Mail::to($to)->send(new ContactMessageMail(
|
|
$data['name'],
|
|
$data['email'],
|
|
$data['message'],
|
|
$locale,
|
|
));
|
|
} catch (Throwable $e) {
|
|
Log::error('Contact form: store email failed', ['exception' => $e]);
|
|
|
|
return back()->withInput()->with('contact_error', __('storefront.contact.send_failed'));
|
|
}
|
|
|
|
// The store already has the message, so a failed confirmation is only logged.
|
|
try {
|
|
Mail::to($data['email'])->locale($locale)->send(new ContactConfirmationMail);
|
|
} catch (Throwable $e) {
|
|
Log::warning('Contact form: confirmation email failed', ['exception' => $e]);
|
|
}
|
|
|
|
return redirect()->route('contact')->with('status', __('storefront.contact.sent'));
|
|
}
|
|
}
|