diff --git a/app/Controllers/AboutController.php b/app/Controllers/AboutController.php index 27bfcd9..3c330aa 100644 --- a/app/Controllers/AboutController.php +++ b/app/Controllers/AboutController.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class AboutController { diff --git a/app/Controllers/ClientsController.php b/app/Controllers/ClientsController.php index 7715523..3045c4c 100644 --- a/app/Controllers/ClientsController.php +++ b/app/Controllers/ClientsController.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class ClientsController { diff --git a/app/Controllers/ContactController.php b/app/Controllers/ContactController.php index 41d77e4..4ac09ed 100644 --- a/app/Controllers/ContactController.php +++ b/app/Controllers/ContactController.php @@ -1,89 +1,93 @@ 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' + $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; + $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown'; + + // Insert into database + $contact = new ContactModel(); + $result = $contact->save([ + 'first_name' => $firstName, + 'last_name' => $lastName, + 'email' => $email, + 'message' => $message, + 'ip_address' => $ip, + 'user_agent' => $userAgent, ]); - Logger::info("Contact form submitted by $firstName $lastName <$email>"); + if (!$result) { + Logger::logError("Failed to save contact form submission for email: $email"); + Response::serverError('An error occurred while submitting your message. Please try again later.'); + } - // Send internal notification email - EmailUtility::sendInternalContactAlert([ - 'first_name' => $firstName, - 'last_name' => $lastName, - 'email' => $email, - 'phone' => $phone, - 'message' => $message + Response::json([ + 'success' => true, + 'message' => 'Your message has been successfully submitted. Thank you!' ]); - - // Send confirmation to user - EmailUtility::sendContactConfirmation($email, $firstName); - - Response::jsonSuccess('Thank you. We will be in touch shortly.'); - - } catch (\Throwable $e) { - ErrorHandler::exception($e); - Response::jsonError('An internal error occurred. Please try again later.'); + } catch (Exception $e) { + Logger::logError("Exception during contact form submission: " . $e->getMessage()); + Response::serverError('A server error occurred. Please try again later.'); } } } diff --git a/app/Controllers/EmergencySupportController.php b/app/Controllers/EmergencySupportController.php index 22a42c5..87e0709 100644 --- a/app/Controllers/EmergencySupportController.php +++ b/app/Controllers/EmergencySupportController.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class EmergencySupportController { diff --git a/app/Controllers/HelpDeskController.php b/app/Controllers/HelpDeskController.php index 737c6fb..bad1335 100644 --- a/app/Controllers/HelpDeskController.php +++ b/app/Controllers/HelpDeskController.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class HelpDeskController { diff --git a/app/Controllers/HomeController.php b/app/Controllers/HomeController.php index b0c59ae..44e3cdf 100644 --- a/app/Controllers/HomeController.php +++ b/app/Controllers/HomeController.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class HomeController { diff --git a/app/Controllers/ITConsultingController.php b/app/Controllers/ITConsultingController.php index acaebe5..7511c23 100644 --- a/app/Controllers/ITConsultingController.php +++ b/app/Controllers/ITConsultingController.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class ITConsultingController { diff --git a/app/Controllers/LandingController.php b/app/Controllers/LandingController.php index 257c6f7..d71fcf0 100644 --- a/app/Controllers/LandingController.php +++ b/app/Controllers/LandingController.php @@ -7,7 +7,7 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; +use WizdomNetworks\WizeWeb\Utilities\Logger; class LandingController { diff --git a/app/Controllers/ManagedServicesController.php b/app/Controllers/ManagedServicesController.php index c734c79..cf2ba8f 100644 --- a/app/Controllers/ManagedServicesController.php +++ b/app/Controllers/ManagedServicesController.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class ManagedServicesController { diff --git a/app/Controllers/OnlineBrandManagement.php b/app/Controllers/OnlineBrandManagement.php index fcb504b..8a92620 100644 --- a/app/Controllers/OnlineBrandManagement.php +++ b/app/Controllers/OnlineBrandManagement.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class OnlineBrandManagementController { diff --git a/app/Controllers/ProjectManagementController.php b/app/Controllers/ProjectManagementController.php index 2376dbf..3b2da4f 100644 --- a/app/Controllers/ProjectManagementController.php +++ b/app/Controllers/ProjectManagementController.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class ProjectManagementController { diff --git a/app/Controllers/ServicesController.php b/app/Controllers/ServicesController.php index 94c466c..d318142 100644 --- a/app/Controllers/ServicesController.php +++ b/app/Controllers/ServicesController.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class ServicesController { diff --git a/app/Controllers/TestimonialsController.php b/app/Controllers/TestimonialsController.php index e550557..d97ea14 100644 --- a/app/Controllers/TestimonialsController.php +++ b/app/Controllers/TestimonialsController.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Controllers; use WizdomNetworks\WizeWeb\Core\View; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class TestimonialsController { diff --git a/app/Core/Controller.php b/app/Core/Controller.php index 0537fda..0bdf373 100644 --- a/app/Core/Controller.php +++ b/app/Core/Controller.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Core; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; /** * Base Controller diff --git a/app/Core/Router.php b/app/Core/Router.php index 9d28bd1..9f89ddd 100644 --- a/app/Core/Router.php +++ b/app/Core/Router.php @@ -12,8 +12,8 @@ namespace WizdomNetworks\WizeWeb\Core; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; class Router { diff --git a/app/Core/View.php b/app/Core/View.php index 4265f65..7288ef8 100644 --- a/app/Core/View.php +++ b/app/Core/View.php @@ -12,8 +12,8 @@ namespace WizdomNetworks\WizeWeb\Core; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; /** * View Renderer diff --git a/app/Models/ClientModel.php b/app/Models/ClientModel.php index 4e5921b..cb9ff81 100644 --- a/app/Models/ClientModel.php +++ b/app/Models/ClientModel.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Models; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; /** * Client Model diff --git a/app/Models/ContactModel.php b/app/Models/ContactModel.php index 985edc8..46f5c76 100644 --- a/app/Models/ContactModel.php +++ b/app/Models/ContactModel.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Models; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; /** * Contact Model diff --git a/app/Models/ServiceModel.php b/app/Models/ServiceModel.php index 479858b..ef28b68 100644 --- a/app/Models/ServiceModel.php +++ b/app/Models/ServiceModel.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Models; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; /** * Service Model diff --git a/app/Models/TestimonialModel.php b/app/Models/TestimonialModel.php index 479858b..ef28b68 100644 --- a/app/Models/TestimonialModel.php +++ b/app/Models/TestimonialModel.php @@ -2,8 +2,8 @@ namespace WizdomNetworks\WizeWeb\Models; -use WizdomNetworks\WizeWeb\Utils\Logger; -use WizdomNetworks\WizeWeb\Utils\ErrorHandler; +use WizdomNetworks\WizeWeb\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; /** * Service Model diff --git a/app/Utils/ClassInspector.php b/app/Utilities/ClassInspector.php similarity index 99% rename from app/Utils/ClassInspector.php rename to app/Utilities/ClassInspector.php index 7d3b813..4d3510b 100644 --- a/app/Utils/ClassInspector.php +++ b/app/Utilities/ClassInspector.php @@ -1,6 +1,6 @@ queueDir = $queueDir; + + // Ensure the queue directory exists + if (!is_dir($this->queueDir)) { + mkdir($this->queueDir, 0755, true); + Logger::logInfo("Queue directory created at: $this->queueDir"); + } + } + + /** + * Add a task to the queue with priority and expiration. + * + * @param string $queueName The name of the queue. + * @param array $task The task to enqueue. + * @param int $priority The priority of the task (lower value = higher priority). + * @param int $ttl Time-to-live in seconds (0 for no expiration). + * @return bool True if the task is added successfully, false otherwise. + */ + public function enqueue(string $queueName, array $task, int $priority = 0, int $ttl = 0): bool + { + $queueFile = $this->queueDir . "/$queueName.queue"; + $expiry = $ttl > 0 ? time() + $ttl : 0; + + try { + $taskData = serialize(['priority' => $priority, 'expiry' => $expiry, 'task' => $task]); + file_put_contents($queueFile, $taskData . PHP_EOL, FILE_APPEND | LOCK_EX); + Logger::logInfo("Task added to queue: $queueName with priority $priority and expiry $expiry"); + return true; + } catch (\Throwable $e) { + Logger::logError("Failed to enqueue task: " . $e->getMessage()); + return false; + } + } + + /** + * Retrieve and remove the next task from the queue, considering priority and expiration. + * + * @param string $queueName The name of the queue. + * @return array|null The next task, or null if the queue is empty. + */ + public function dequeue(string $queueName): ?array + { + $queueFile = $this->queueDir . "/$queueName.queue"; + + if (!file_exists($queueFile)) { + Logger::logInfo("Queue file does not exist: $queueFile"); + return null; + } + + try { + $lines = file($queueFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (empty($lines)) { + unlink($queueFile); + Logger::logInfo("Queue is empty: $queueName"); + return null; + } + + // Sort tasks by priority and expiration + $tasks = array_map('unserialize', $lines); + usort($tasks, function ($a, $b) { + return $a['priority'] <=> $b['priority'] ?: $a['expiry'] <=> $b['expiry']; + }); + + // Find the next valid task + $updatedLines = []; + $nextTask = null; + + foreach ($tasks as $taskData) { + if ($taskData['expiry'] > 0 && $taskData['expiry'] < time()) { + Logger::logInfo("Skipping expired task in queue: $queueName"); + continue; + } + + if ($nextTask === null) { + $nextTask = $taskData['task']; + } else { + $updatedLines[] = serialize($taskData); + } + } + + file_put_contents($queueFile, implode(PHP_EOL, $updatedLines) . PHP_EOL, LOCK_EX); + + return $nextTask; + } catch (\Throwable $e) { + Logger::logError("Failed to dequeue task: " . $e->getMessage()); + return null; + } + } + + /** + * Retry a failed task by re-adding it to the queue. + * + * @param string $queueName The name of the queue. + * @param array $task The task to retry. + * @param int $priority The priority of the task. + * @param int $retryLimit The maximum number of retries allowed. + * @param int $currentRetry The current retry count (default: 0). + * @return bool True if the task is retried successfully, false otherwise. + */ + public function retryTask(string $queueName, array $task, int $priority = 0, int $retryLimit = 3, int $currentRetry = 0): bool + { + if ($currentRetry >= $retryLimit) { + Logger::logWarning("Task moved to dead letter queue after exceeding retry limit: $queueName"); + $this->enqueue("dead_letter_$queueName", $task, $priority); + return false; + } + + Logger::logInfo("Retrying task in queue: $queueName, attempt: " . ($currentRetry + 1)); + return $this->enqueue($queueName, $task, $priority); + } + + /** + * Get the status of a queue. + * + * @param string $queueName The name of the queue. + * @return array|null Queue statistics or null if the queue does not exist. + */ + public function getQueueStats(string $queueName): ?array + { + $queueFile = $this->queueDir . "/$queueName.queue"; + + if (!file_exists($queueFile)) { + return null; + } + + $lines = file($queueFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + $tasks = array_map('unserialize', $lines); + + return [ + 'total_tasks' => count($tasks), + 'last_modified' => date('Y-m-d H:i:s', filemtime($queueFile)), + 'oldest_task' => $tasks[0]['task'] ?? null, + ]; + } + + /** + * Clear all tasks in a queue. + * + * @param string $queueName The name of the queue. + * @return bool True if the queue is cleared successfully, false otherwise. + */ + public function clearQueue(string $queueName): bool + { + $queueFile = $this->queueDir . "/$queueName.queue"; + + if (!file_exists($queueFile)) { + Logger::logInfo("Queue file does not exist: $queueFile"); + return false; + } + + try { + unlink($queueFile); + Logger::logInfo("Queue cleared: $queueName"); + return true; + } catch (\Throwable $e) { + Logger::logError("Failed to clear queue: " . $e->getMessage()); + return false; + } + } + + /** + * List all available queues. + * + * @return array List of queue names. + */ + public function listQueues(): array + { + $files = glob($this->queueDir . '/*.queue'); + return array_map(function ($file) { + return basename($file, '.queue'); + }, $files); + } + + /** + * Clear all queues in the directory. + * + * @return bool True if all queues are cleared successfully, false otherwise. + */ + public function clearAllQueues(): bool + { + try { + $files = glob($this->queueDir . '/*.queue'); + foreach ($files as $file) { + unlink($file); + } + Logger::logInfo("All queues cleared."); + return true; + } catch (\Throwable $e) { + Logger::logError("Failed to clear all queues: " . $e->getMessage()); + return false; + } + } + + /** + * Retrieve and remove a batch of tasks from the queue. + * + * @param string $queueName The name of the queue. + * @param int $batchSize The number of tasks to dequeue. + * @return array List of tasks. + */ + public function dequeueBatch(string $queueName, int $batchSize = 10): array + { + $queueFile = "$this->queueDir/$queueName.queue"; + + if (!file_exists($queueFile)) { + Logger::logInfo("Queue file does not exist: $queueFile"); + return []; + } + + try { + $lines = file($queueFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (empty($lines)) { + unlink($queueFile); + Logger::logInfo("Queue is empty: $queueName"); + return []; + } + + $tasks = array_map('unserialize', $lines); + usort($tasks, fn($a, $b) => $a['priority'] <=> $b['priority']); + + $batch = array_splice($tasks, 0, $batchSize); + file_put_contents($queueFile, implode(PHP_EOL, array_map('serialize', $tasks)) . PHP_EOL); + + return array_map(fn($task) => $task['task'], $batch); + } catch (Throwable $e) { + Logger::logError("Failed to dequeue batch: " . $e->getMessage()); + return []; + } + } +} + +?> diff --git a/app/Utilities/Sanitizer.php b/app/Utilities/Sanitizer.php index 649be2e..b131f0b 100644 --- a/app/Utilities/Sanitizer.php +++ b/app/Utilities/Sanitizer.php @@ -1,86 +1,98 @@ $value) { - if (is_array($value)) { - $clean[$key] = self::sanitizeArray($value); - } else { - $clean[$key] = self::sanitizeString((string) $value); - } + try { + $sanitizedArray = array_map(function ($item) { + return is_array($item) + ? self::sanitizeArray($item) + : self::sanitizeInput((string)$item); + }, $values); + Logger::info("Sanitized array: Original: " . json_encode($values) . " | Sanitized: " . json_encode($sanitizedArray)); + return $sanitizedArray; + } catch (\Throwable $e) { + Logger::error("Failed to sanitize array: " . json_encode($values)); + ErrorHandler::exception($e); + return []; } - return $clean; } } diff --git a/app/Utils/StructureGenerator.php b/app/Utilities/StructureGenerator.php similarity index 98% rename from app/Utils/StructureGenerator.php rename to app/Utilities/StructureGenerator.php index 30fdb57..01d4434 100644 --- a/app/Utils/StructureGenerator.php +++ b/app/Utilities/StructureGenerator.php @@ -1,9 +1,9 @@ connect(); - } - - /** - * Establishes a connection to the database. - */ - private function connect(): void - { - $dsn = sprintf('mysql:host=%s;dbname=%s;charset=utf8mb4', $_ENV['DB_HOST'], $_ENV['DB_NAME']); - - try { - $this->connection = new PDO($dsn, $_ENV['DB_USER'], $_ENV['DB_PASSWORD']); - $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - Logger::info('Database connection established successfully.'); - } catch (PDOException $e) { - Logger::error('Database connection failed: ' . $e->getMessage()); - throw $e; - } - } - - /** - * Executes a query and returns the result. - * - * @param string $query The SQL query to execute. - * @param array $params Parameters for prepared statements (optional). - * @return array The query result. - */ - public function query(string $query, array $params = []): array - { - try { - $stmt = $this->connection->prepare($query); - $stmt->execute($params); - Logger::info('Query executed successfully: ' . $query); - return $stmt->fetchAll(PDO::FETCH_ASSOC); - } catch (PDOException $e) { - Logger::error('Query failed: ' . $query . ' | Error: ' . $e->getMessage()); - throw $e; - } - } - - /** - * Retrieves the PDO connection instance. - * - * @return PDO The PDO instance. - */ - public function getConnection(): PDO - { - return $this->connection; - } -} diff --git a/app/Utils/Mailer.php b/app/Utils/Mailer.php deleted file mode 100644 index a2111f4..0000000 --- a/app/Utils/Mailer.php +++ /dev/null @@ -1,97 +0,0 @@ -mailer = new PHPMailer(true); - $this->configure(); - } catch (Exception $e) { - Logger::error('Failed to initialize Mailer: ' . $e->getMessage()); - ErrorHandler::exception($e); - throw $e; - } - } - - /** - * Configures the PHPMailer instance. - * - * Reads email configuration from environment variables such as MAIL_HOST, MAIL_USER, MAIL_PASSWORD, etc. - * - * @throws Exception If any configuration errors occur. - */ - protected function configure(): void - { - try { - $this->mailer->isSMTP(); - $this->mailer->Host = $_ENV['MAIL_HOST']; - $this->mailer->SMTPAuth = true; - $this->mailer->Username = $_ENV['MAIL_USER']; - $this->mailer->Password = $_ENV['MAIL_PASSWORD']; - $this->mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; - $this->mailer->Port = (int) $_ENV['MAIL_PORT']; - $this->mailer->setFrom($_ENV['MAIL_FROM_EMAIL'], $_ENV['MAIL_FROM_NAME']); - Logger::info('Mailer configured successfully.'); - } catch (Exception $e) { - Logger::error('Mailer configuration failed: ' . $e->getMessage()); - ErrorHandler::exception($e); - throw $e; - } - } - - /** - * Sends an email. - * - * @param string $to The recipient's email address. - * @param string $subject The email subject. - * @param string $body The HTML content of the email. - * @param string $altBody The plain-text alternative content of the email (optional). - * - * @return bool True if the email was sent successfully, false otherwise. - */ - public function send(string $to, string $subject, string $body, string $altBody = ''): bool - { - try { - $this->mailer->clearAddresses(); - $this->mailer->addAddress($to); - $this->mailer->Subject = $subject; - $this->mailer->Body = $body; - $this->mailer->AltBody = $altBody; - - $this->mailer->send(); - Logger::info("Email sent successfully to $to with subject: $subject."); - return true; - } catch (Exception $e) { - Logger::error("Failed to send email to $to: " . $e->getMessage()); - ErrorHandler::exception($e); - return false; - } - } -} diff --git a/app/Utils/Sanitizer.php b/app/Utils/Sanitizer.php deleted file mode 100644 index b0a6c3e..0000000 --- a/app/Utils/Sanitizer.php +++ /dev/null @@ -1,91 +0,0 @@ -= $minLength; - - if (!$isValid) { - Logger::warning("[WARNING] String is shorter than minimum length: $string"); - } - - return $isValid; - } catch (\Throwable $e) { - ErrorHandler::exception($e); - return false; - } - } - - /** - * Check if a string has a maximum length. - * - * @param string $string The string to check. - * @param int $maxLength The maximum length. - * @return bool True if the string meets the maximum length, false otherwise. - */ - public static function hasMaxLength(string $string, int $maxLength): bool - { - try { - Logger::info("[DEBUG] Checking if string has maximum length: $maxLength"); - - $isValid = strlen(trim($string)) <= $maxLength; - - if (!$isValid) { - Logger::warning("[WARNING] String exceeds maximum length: $string"); - } - - return $isValid; - } catch (\Throwable $e) { - ErrorHandler::exception($e); - return false; - } - } - - /** - * Validate a string length. - * - * @param string $input The string to validate. - * @param int $min Minimum length. - * @param int $max Maximum length. - * @return bool True if the string length is valid, false otherwise. - */ - public static function validateStringLength(string $input, int $min, int $max): bool - { - try { - Logger::info("[DEBUG] Validating string length: Input='$input', Min=$min, Max=$max"); - - $length = strlen($input); - $isValid = $length >= $min && $length <= $max; - - if (!$isValid) { - Logger::warning("[WARNING] Invalid string length: $length (Expected between $min and $max)"); - } - - return $isValid; - } catch (\Throwable $e) { - ErrorHandler::exception($e); - return false; - } - } - - /** - * Validate a boolean value. - * - * @param mixed $input The input to validate as a boolean. - * @return bool True if the input is a valid boolean, false otherwise. - */ - public static function validateBoolean($input): bool - { - try { - Logger::info("[DEBUG] Validating boolean input: $input"); - - $isValid = is_bool(filter_var($input, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); - - if (!$isValid) { - Logger::warning("[WARNING] Invalid boolean input: $input"); - } - - return $isValid; - } catch (\Throwable $e) { - ErrorHandler::exception($e); - return false; - } - } - - /** - * Validate a date format. - * - * @param string $date The date string to validate. - * @param string $format The expected date format (e.g., 'Y-m-d'). - * @return bool True if the date matches the format, false otherwise. - */ - public static function validateDate(string $date, string $format = 'Y-m-d'): bool - { - try { - Logger::info("[DEBUG] Validating date: $date with format: $format"); - - $dateTime = \DateTime::createFromFormat($format, $date); - $isValid = $dateTime && $dateTime->format($format) === $date; - - if (!$isValid) { - Logger::warning("[WARNING] Invalid date: $date (Expected format: $format)"); - } - - return $isValid; - } catch (\Throwable $e) { - ErrorHandler::exception($e); - return false; - } - } -} diff --git a/copy-email-utilities.sh b/copy-email-utilities.sh new file mode 100755 index 0000000..34813bd --- /dev/null +++ b/copy-email-utilities.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Set source and destination paths +SRC_UTILS="../dev.helpdeskplus.ca-main/app/Utilities" +DEST_UTILS="./app/Utils" +SRC_TEMPLATES="../dev.helpdeskplus.ca-main/resources/templates/emails" +DEST_TEMPLATES="./resources/templates/emails" + +# Create destination folders if they don't exist +mkdir -p "$DEST_UTILS" +mkdir -p "$DEST_TEMPLATES" + +echo "🔁 Copying utility files..." + +# List of utility files to copy and update namespaces in +FILES=("EmailUtility.php" "TemplateUtility.php" "QueueUtility.php") + +for FILE in "${FILES[@]}"; do + if [ -f "$SRC_UTILS/$FILE" ]; then + echo " 📁 $FILE -> $DEST_UTILS" + sed 's|App\\Utilities|WizdomNetworks\\WizeWeb\\Utilities|g' "$SRC_UTILS/$FILE" > "$DEST_UTILS/$FILE" + else + echo " ⚠️ $FILE not found in $SRC_UTILS" + fi +done + +echo "📄 Copying email templates..." + +cp -r "$SRC_TEMPLATES"/* "$DEST_TEMPLATES"/ + +echo "✅ Done. All utilities and templates copied." + diff --git a/public/assets/img/person/sa-shadows.png b/public/assets/img/person/sa-shadows.png new file mode 100644 index 0000000..6e7b440 Binary files /dev/null and b/public/assets/img/person/sa-shadows.png differ diff --git a/public/index.php b/public/index.php index 118a292..9a542a0 100644 --- a/public/index.php +++ b/public/index.php @@ -5,7 +5,7 @@ ini_set('display_startup_errors', 1); error_reporting(E_ALL); // File: public/index.php -// Version: v1.2 +// Version: v1.3 // Purpose: Application entry point with Arsha one-pager routing // Project: Wizdom Networks Website @@ -13,10 +13,10 @@ 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\Utilities\Logger; +use WizdomNetworks\WizeWeb\Utilities\ErrorHandler; use WizdomNetworks\WizeWeb\Controllers\LandingController; -use WizdomNetworks\WizeWeb\Controllers\ContactController; // <-- Missing +use WizdomNetworks\WizeWeb\Controllers\ContactController; // $dotenv = Dotenv::createImmutable(__DIR__ . '/../'); $dotenv->load(); @@ -30,8 +30,10 @@ $router->add('', LandingController::class, 'index'); $router->add('/', LandingController::class, 'index'); $router->add('index.php', LandingController::class, 'index'); -// Contact form submission -$router->add('/contact', ContactController::class, 'submit', 'POST'); +// Contact form +$router->add('/contact', ContactController::class, 'index', 'GET'); // Show contact form +$router->add('/contact', ContactController::class, 'submit', 'POST'); // Handle submission + // Optional: fallback for /contact without leading slash (rare case) // $router->add('contact', ContactController::class, 'submit', 'POST'); diff --git a/resources/templates/emails/contact_confirmation.php b/resources/templates/emails/contact_confirmation.php new file mode 100644 index 0000000..677e364 --- /dev/null +++ b/resources/templates/emails/contact_confirmation.php @@ -0,0 +1,4 @@ + + +
+ + +Dear {{name}},
+ +Thank you for reaching out to HelpDesk+. We’ve received your message and will get back to you shortly. Here’s what you submitted:
+ +++ +Message: {{message}}
+
If you have any further questions or concerns, feel free to reply to this email.
+ +Best regards,
The HelpDesk+ Team
An error occurred during a contact form submission:
+{{formData}}Stack Trace:
+{{trace}}
diff --git a/resources/templates/emails/email.html b/resources/templates/emails/email.html
new file mode 100644
index 0000000..dcf074a
--- /dev/null
+++ b/resources/templates/emails/email.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+ Dear {{name}},
+ +Thank you for reaching out to HelpDesk+. We’ve received your message and will get back to you shortly. Here’s what you submitted:
+ +++ +Message: {{message}}
+
If you have any further questions or concerns, feel free to reply to this email.
+ +Best regards,
The HelpDesk+ Team
We’ve received your message.
+You will receive a confirmation email shortly. We aim to respond within 1 business day.
+