redirect('error'); } try { $uploadedFiles = $this->storeUploadedFiles(); $fullRequestText = $this->buildRequestText($paymentType, $activityType, $requestText, $uploadedFiles); $statement = Database::pdo()->prepare( 'INSERT INTO price_requests (customer_name, phone, email, company_name, request_text, file_path, status, client_ip, user_agent) VALUES (:customer_name, :phone, :email, :company_name, :request_text, :file_path, :status, :client_ip, :user_agent)' ); $statement->execute([ 'customer_name' => $companyName, 'phone' => $phone !== '' ? $phone : null, 'email' => $email !== '' ? $email : null, 'company_name' => $companyName, 'request_text' => $fullRequestText, 'file_path' => $uploadedFiles[0] ?? null, 'status' => 'new', 'client_ip' => $_SERVER['REMOTE_ADDR'] ?? null, 'user_agent' => substr((string) ($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 255), ]); $requestId = (int) Database::pdo()->lastInsertId(); $this->sendNotification($requestId, $companyName, $phone, $email, $fullRequestText); } catch (Throwable) { $this->redirect('error'); } $this->redirect('sent'); } /** * @return array */ private function storeUploadedFiles(): array { if (!isset($_FILES['request_files']) || !is_array($_FILES['request_files']['name'])) { return []; } $stored = []; $uploadDir = base_path('storage/price_requests/' . date('Y/m')); if (!is_dir($uploadDir)) { mkdir($uploadDir, 0775, true); } foreach ($_FILES['request_files']['name'] as $index => $originalName) { $error = (int) ($_FILES['request_files']['error'][$index] ?? UPLOAD_ERR_NO_FILE); if ($error === UPLOAD_ERR_NO_FILE) { continue; } if ($error !== UPLOAD_ERR_OK) { continue; } $tmpName = (string) ($_FILES['request_files']['tmp_name'][$index] ?? ''); if ($tmpName === '' || !is_uploaded_file($tmpName)) { continue; } $extension = strtolower(pathinfo((string) $originalName, PATHINFO_EXTENSION)); $safeExtension = preg_replace('/[^a-z0-9]/', '', $extension) ?: 'file'; $fileName = date('Ymd-His') . '-' . bin2hex(random_bytes(4)) . '.' . $safeExtension; $targetPath = $uploadDir . '/' . $fileName; if (move_uploaded_file($tmpName, $targetPath)) { $stored[] = str_replace('\\', '/', substr($targetPath, strlen(base_path()) + 1)); } } return $stored; } /** * @param array $uploadedFiles */ private function buildRequestText(string $paymentType, string $activityType, string $requestText, array $uploadedFiles): string { $paymentLabel = $paymentType === 'invoice' ? 'Расчетный счет' : 'Наличные'; $lines = [ 'Форма оплаты: ' . $paymentLabel, 'Тип деятельности: ' . ($activityType !== '' ? $activityType : 'не указан'), '', 'Позиции, объем и нужная цена:', $requestText, ]; if ($uploadedFiles !== []) { $lines[] = ''; $lines[] = 'Файлы:'; foreach ($uploadedFiles as $path) { $lines[] = '- ' . $path; } } return implode("\n", $lines); } private function sendNotification(int $requestId, string $companyName, string $phone, string $email, string $requestText): void { $settings = (new SettingRepository())->allKeyed(); $to = trim((string) (($settings['price_request_email'] ?? '') ?: ($settings['admin_email'] ?? '') ?: 'zakaz@rybstock.ru')); if ($to === '') { return; } $subject = 'Запрос проходных цен #' . $requestId . ' - ' . $companyName; $body = implode("\n", [ 'Новая бизнес-заявка на проходные цены.', '', 'Номер заявки: ' . $requestId, 'Организация: ' . $companyName, 'Телефон: ' . ($phone !== '' ? $phone : 'не указан'), 'Email: ' . ($email !== '' ? $email : 'не указан'), '', $requestText, ]); $headers = [ 'Content-Type: text/plain; charset=UTF-8', 'From: Рыбсток ', ]; @mail($to, $subject, $body, implode("\r\n", $headers)); } private function redirect(string $status): never { header('Location: /?price_request=' . rawurlencode($status) . '#price-request', true, 303); exit; } }