From 90b7b0b7855dd1c4d18499a2c3a74d5584e9b2f9 Mon Sep 17 00:00:00 2001 From: essae Date: Sat, 10 May 2025 16:55:50 -0400 Subject: [PATCH] Contact form initial updates --- app/Controllers/ContactController.php | 96 +++++++++++++++++++------- app/Core/Router.php | 97 ++++++++++++++------------- public/assets/js/contact-form.js | 56 ++++++++++++++++ public/index.php | 36 +++++----- resources/views/layouts/arsha.php | 9 +++ resources/views/pages/landing.php | 56 +++++++++------- 6 files changed, 236 insertions(+), 114 deletions(-) create mode 100644 public/assets/js/contact-form.js diff --git a/app/Controllers/ContactController.php b/app/Controllers/ContactController.php index b1dc03b..8a4a035 100644 --- a/app/Controllers/ContactController.php +++ b/app/Controllers/ContactController.php @@ -1,38 +1,88 @@ 'Contact Us - Wizdom Networks', - 'heroConfig' => [ - 'title' => 'Get in Touch', - 'description' => 'Reach out to our team for inquiries and support.', - 'image' => '/assets/images/contact-hero.jpg', - 'cta' => ['text' => 'Send a Message', 'link' => '/contact'], - 'style' => 'default', - 'position' => 'top' - ], - 'content' => "

Contact Us

-

We're here to help. Send us a message and we'll get back to you as soon as possible.

" - ]; + // Sanitize and validate input + $firstName = trim($_POST['first_name'] ?? ''); + $lastName = trim($_POST['last_name'] ?? ''); + $email = trim($_POST['email'] ?? ''); + $phone = trim($_POST['phone'] ?? ''); + $message = trim($_POST['message'] ?? ''); + + if (!$firstName || !$lastName || !$email || !$phone || !$message) { + throw new \Exception("All fields except phone must be filled out."); + } + + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + throw new \Exception("Invalid email address."); + } + + // Store in database + $pdo = new \PDO($_ENV['DB_DSN'], $_ENV['DB_USER'], $_ENV['DB_PASS']); + $stmt = $pdo->prepare("INSERT INTO contact_messages (first_name, last_name, email, phone, message, ip_address, user_agent) + VALUES (?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([ + $firstName, + $lastName, + $email, + $phone, + $message, + $_SERVER['REMOTE_ADDR'] ?? 'unknown', + $_SERVER['HTTP_USER_AGENT'] ?? 'unknown' + ]); + + Logger::info("Contact form submitted by $firstName $lastName <$email>"); + + // Email notification + $mail = new PHPMailer(true); + $mail->isSMTP(); + $mail->Host = $_ENV['SMTP_HOST']; + $mail->Port = $_ENV['SMTP_PORT']; + $mail->SMTPAuth = $_ENV['SMTP_AUTH'] === 'true'; + $mail->SMTPSecure = $_ENV['SMTP_ENCRYPTION'] !== 'none' ? $_ENV['SMTP_ENCRYPTION'] : ''; + $mail->Username = $_ENV['SMTP_USERNAME']; + $mail->Password = $_ENV['SMTP_PASSWORD']; + $mail->setFrom($_ENV['SMTP_FROM_EMAIL'], $_ENV['SMTP_FROM_NAME']); + $mail->addAddress($_ENV['SALES_EMAILS'] ?? $_ENV['ADMIN_EMAILS']); + + $mail->Subject = "New Contact Message from $firstName $lastName"; + $mail->Body = "You received a message from: \n\n" + . "Name: $firstName $lastName\n" + . "Email: $email\n" + . "Phone: $phone\n" + . "Message:\n$message\n"; + + $mail->send(); + + http_response_code(200); + echo json_encode(['success' => true, 'message' => 'Thank you. We will be in touch.']); - Logger::debug("ContactController::index() - Data prepared successfully."); - View::render('pages/contact', $data); - Logger::info("ContactController::index() - Contact page rendered successfully."); } catch (\Throwable $e) { - Logger::error("ContactController::index() - Error rendering contact page: " . $e->getMessage()); - ErrorHandler::exception($e); + Logger::error("Contact form error: " . $e->getMessage()); + ErrorHandler::handleException($e); + http_response_code(400); + echo json_encode(['success' => false, 'error' => $e->getMessage()]); } } } diff --git a/app/Core/Router.php b/app/Core/Router.php index 454f34c..9d28bd1 100644 --- a/app/Core/Router.php +++ b/app/Core/Router.php @@ -1,77 +1,80 @@ $controller::$method"); - $this->routes[trim($path, '/')] = [$controller, $method]; + $routeKey = strtoupper($httpMethod) . ':' . trim($path, '/'); + Logger::debug("Registering route: [$httpMethod] $path -> $controller::$method"); + $this->routes[$routeKey] = [$controller, $method]; } /** - * Dispatches the request to the appropriate controller and method. - * - * @param string $path The requested URL path. + * Dispatch the request based on the path and HTTP method. + * + * @param string $path The requested path (from index.php). */ public function dispatch($path) { - $path = trim($path, '/'); - Logger::debug("Dispatching path: $path"); + $httpMethod = $_SERVER['REQUEST_METHOD']; + $routeKey = $httpMethod . ':' . trim($path, '/'); - if (isset($this->routes[$path])) { - [$controllerName, $method] = $this->routes[$path]; - Logger::debug("Loading controller: $controllerName::$method"); + Logger::debug("Dispatching [$httpMethod] $path"); + + if (isset($this->routes[$routeKey])) { + [$controllerName, $method] = $this->routes[$routeKey]; + Logger::debug("Matched route -> $controllerName::$method"); try { - if (class_exists($controllerName)) { - $controller = new $controllerName(); - - if (method_exists($controller, $method)) { - Logger::info("Successfully dispatched: $controllerName::$method"); - $controller->$method(); - } else { - Logger::error("Method not found: $controllerName::$method"); - throw new \Exception("Method $method not found in $controllerName"); - } - } else { - Logger::error("Controller not found: $controllerName"); - throw new \Exception("Controller $controllerName not found."); + if (!class_exists($controllerName)) { + throw new \Exception("Controller not found: $controllerName"); } - } //catch (\Throwable $e) { - //ErrorHandler::exception($e); - //Logger::error("Router dispatch error: " . $e->getMessage()); - //echo "500 Internal Server Error"; - catch (\Throwable $e) { - echo "
";
-                    echo "Exception: " . $e->getMessage() . "\n";
-                    echo "File: " . $e->getFile() . "\n";
-                    echo "Line: " . $e->getLine() . "\n";
-                    echo "Trace:\n" . $e->getTraceAsString();
-                    echo "
"; - exit; + + $controller = new $controllerName(); + + if (!method_exists($controller, $method)) { + throw new \Exception("Method $method not found in $controllerName"); + } + + Logger::info("Executing controller: $controllerName::$method"); + $controller->$method(); + } catch (\Throwable $e) { + echo "
";
+                echo "Exception: " . $e->getMessage() . "\n";
+                echo "File: " . $e->getFile() . "\n";
+                echo "Line: " . $e->getLine() . "\n";
+                echo "Trace:\n" . $e->getTraceAsString();
+                echo "
"; + exit; } } else { - Logger::error("Route not found: $path"); + Logger::error("Route not found: [$httpMethod] $path"); + http_response_code(404); echo "404 Not Found"; } } diff --git a/public/assets/js/contact-form.js b/public/assets/js/contact-form.js new file mode 100644 index 0000000..e64a4dc --- /dev/null +++ b/public/assets/js/contact-form.js @@ -0,0 +1,56 @@ +document.addEventListener('DOMContentLoaded', function () { + const form = document.querySelector('.php-email-form'); + if (!form) return; + + const loading = document.createElement('div'); + const errorMsg = document.createElement('div'); + const successMsg = document.createElement('div'); + + loading.className = 'loading mt-3'; + loading.textContent = 'Sending message...'; + + errorMsg.className = 'error-message mt-3'; + errorMsg.style.display = 'none'; + + successMsg.className = 'sent-message mt-3'; + successMsg.style.display = 'none'; + + form.appendChild(loading); + form.appendChild(errorMsg); + form.appendChild(successMsg); + + loading.style.display = 'none'; + + form.addEventListener('submit', async function (e) { + e.preventDefault(); + + loading.style.display = 'block'; + errorMsg.style.display = 'none'; + successMsg.style.display = 'none'; + + const formData = new FormData(form); + + try { + const response = await fetch(form.action, { + method: 'POST', + body: formData + }); + + const result = await response.json(); + loading.style.display = 'none'; + + if (response.ok && result.success) { + successMsg.textContent = result.message || 'Your message was sent successfully.'; + successMsg.style.display = 'block'; + form.reset(); + } else { + throw new Error(result.error || 'Submission failed.'); + } + } catch (err) { + loading.style.display = 'none'; + errorMsg.textContent = err.message || 'An unexpected error occurred.'; + errorMsg.style.display = 'block'; + } + }); + }); + \ No newline at end of file diff --git a/public/index.php b/public/index.php index 1495442..118a292 100644 --- a/public/index.php +++ b/public/index.php @@ -4,22 +4,20 @@ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); - // File: public/index.php -// Version: v1.1 +// Version: v1.2 // Purpose: Application entry point with Arsha one-pager routing // Project: Wizdom Networks Website require_once __DIR__ . '/../vendor/autoload.php'; - - use Dotenv\Dotenv; use WizdomNetworks\WizeWeb\Core\Router; use WizdomNetworks\WizeWeb\Utils\Logger; use WizdomNetworks\WizeWeb\Utils\ErrorHandler; use WizdomNetworks\WizeWeb\Controllers\LandingController; -// ✅ Load .env variables +use WizdomNetworks\WizeWeb\Controllers\ContactController; // <-- Missing + $dotenv = Dotenv::createImmutable(__DIR__ . '/../'); $dotenv->load(); @@ -27,24 +25,26 @@ Logger::info("Bootstrapping application"); $router = new Router(); -// ✅ Register new Arsha landing route +// Arsha landing routes $router->add('', LandingController::class, 'index'); $router->add('/', LandingController::class, 'index'); $router->add('index.php', LandingController::class, 'index'); -//$router->add('/', WizdomNetworks\WizeWeb\Controllers\LandingController::class, 'index'); -// 🛑 Optional: Disable old route to avoid conflict -// use WizdomNetworks\WizeWeb\Controllers\HomeController; -//router->add('', HomeController::class, 'index'); +// Contact form submission +$router->add('/contact', ContactController::class, 'submit', 'POST'); -// DEBUG -//echo "
";
-//echo "REQUEST_URI: " . $_SERVER['REQUEST_URI'] . "\n";
-//echo "Parsed path: " . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) . "\n";
-//echo "Trimmed: " . trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/') . "\n";
-//echo "
"; -//exit; -//END DEBUG +// Optional: fallback for /contact without leading slash (rare case) +// $router->add('contact', ContactController::class, 'submit', 'POST'); + +// Debug block — safe to leave commented +/* +echo "
";
+echo "REQUEST_URI: " . $_SERVER['REQUEST_URI'] . "\n";
+echo "Parsed path: " . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) . "\n";
+echo "Trimmed: " . trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/') . "\n";
+echo "
"; +exit; +*/ $requestedPath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $router->dispatch($requestedPath); diff --git a/resources/views/layouts/arsha.php b/resources/views/layouts/arsha.php index a0b109f..bd50c7d 100644 --- a/resources/views/layouts/arsha.php +++ b/resources/views/layouts/arsha.php @@ -82,6 +82,15 @@ + + + diff --git a/resources/views/pages/landing.php b/resources/views/pages/landing.php index d94a3ca..64eaa96 100644 --- a/resources/views/pages/landing.php +++ b/resources/views/pages/landing.php @@ -709,39 +709,43 @@
-
-
+ -
- - -
+
+
+ + +
-
- - -
+
+ + +
+
-
- - -
+
+
+ + +
-
- - -
+
+ + +
+
-
-
Loading
-
-
Your message has been sent. Thank you!
+
+ + +
- -
+
+ +
+ + -
-