From e9967fa22781d922ba4eb8fb44fe72d200ac4b14 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Mon, 10 Nov 2025 21:04:10 +0000
Subject: [PATCH] =IconsManager.php update

---
 inc/managers/EmailManager.php |  324 ++++++++++++++++++++++++++---------------------------
 1 files changed, 161 insertions(+), 163 deletions(-)

diff --git a/inc/managers/EmailManager.php b/inc/managers/EmailManager.php
index e351a99..7f2315e 100644
--- a/inc/managers/EmailManager.php
+++ b/inc/managers/EmailManager.php
@@ -24,17 +24,15 @@
 class EmailManager
 {
 
-    // Brand colors
-    private string $action_color = '#FF0080';
-    private string $bg_light = '#F9F9F9';
-    private string $bg_dark = '#1B1B1B';
-    private string $text_color = '#151515';
-    private string $text_light = '#F9F9F9';
+   private array $colours = JVB_EMAIL['colours'];
+   private string $title = JVB_EMAIL['content']['title'];
+   private string $prefix = JVB_EMAIL['content']['subjectPrefix'];
+   private string $signature = JVB_EMAIL['content']['signature'];
+   private string $footer;
 
     // Site info
     private string $site_name;
     private string $site_url;
-    private string $signature;
 
     /**
      * Constructor - sets up all filters
@@ -43,7 +41,7 @@
     {
         $this->site_name = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
         $this->site_url = get_site_url();
-        $this->signature = jvbSignature();
+		$this->footer = (is_array(JVB_EMAIL['content']['footer'])) ? implode('', JVB_EMAIL['content']['footer']) : JVB_EMAIL['content']['footer'];
 
         add_filter('wp_mail_content_type', [$this, 'setHtmlContentType']);
         // User registration emails
@@ -109,12 +107,11 @@
      */
     private function getEmailTemplate(string $content, string $header = ''):string
     {
-        // Get logo URL (replace with your actual logo path)
-        $logo_url = esc_url(wp_get_attachment_image_url(get_theme_mod('custom_logo'), 'medium'));
+        $logo = get_custom_logo();
 
         // Default header if none provided
         if (empty($header)) {
-            $header = 'edmonton.ink';
+            $header = $this->title;
         }
 
         return '<!DOCTYPE html>
@@ -122,17 +119,17 @@
         <head>
             <meta charset="UTF-8">
             <meta name="viewport" content="width=device-width, initial-scale=1.0">
-            <title>' . $this->site_name . '</title>
+            <title>' . $this->title . ' | ' . $this->site_name .'</title>
             <style>
                 body, table, td, p, a, li, blockquote {
                     line-height: 1.5;
                 }
 
                 body {
-                    background-color: ' . $this->bg_light . ';
+                    background-color: ' . $this->colours['light'] . ';
                     margin: 0;
                     padding: 0;
-                    color: ' . $this->text_color . ';
+                    color: ' . $this->colours['dark'] . ';
                 }
 
                 .email-container {
@@ -147,10 +144,10 @@
                 }
 
                 .header {
-                    background-color: ' . $this->bg_dark . ';
+                    background-color: ' . $this->colours['dark'] . ';
                     padding: 5px;
                     text-align: center;
-                    color: ' . $this->text_light . ';
+                    color: ' . $this->colours['light'] . ';
                     font-size: 24px;
                     font-weight: 900;
                     letter-spacing: 1.5px;
@@ -169,7 +166,7 @@
                 }
 
                 .content {
-                    background-color: #ffffff;
+                    background-color: ' . $this->colours['light-50'] . ';
                     padding: 30px;
                     border-bottom-left-radius: 5px;
                     border-bottom-right-radius: 5px;
@@ -178,8 +175,8 @@
                 .button {
                     display: inline-block;
                     padding: 12px 24px;
-                    background-color: ' . $this->action_color . ';
-                    color: ' . $this->text_light . ' !important;
+                    background-color: ' . $this->colours['action-0'] . ';
+                    color: ' . $this->colours['action-contrast'] . ' !important;
                     text-decoration: none;
                     border-radius: 3px;
                     font-weight: bold;
@@ -189,7 +186,7 @@
                 }
 
                 .text-link {
-                    color: ' . $this->action_color . ';
+                    color: ' . $this->colours['action-0'] . ';
                     text-decoration: underline;
                 }
 
@@ -197,13 +194,14 @@
                     text-align: center;
                     margin-top: 20px;
                     font-size: 12px;
-                    color: #666666;
+                    backgorund-color: ' . $this->colours['light-200'] . ';
+                    color: ' . $this->colours['dark-200'] . ';
                     padding: 10px;
                     line-height: 1.6;
                 }
 
                 .divider {
-                    border-top: 1px solid #dddddd;
+                    border-top: 1px solid ' . $this->colours['dark-200'] . ';
                     margin: 25px 0;
                 }
 
@@ -282,25 +280,23 @@
 
 /* Dark mode support for clients that support it */
 @media (prefers-color-scheme: dark) {
-    .email-container {
-        background-color: #1B1B1B !important;
+    .body {
+        background-color: ' . $this->colours['dark'] . ';
+        color: ' . $this->colours['light'] . ';
+    }
+
+    .header {
+    	background-color: ' . $this->colours['light'] . ';
+    	color: ' . $this->colours['dark'] . ';
     }
 
     .content {
-        background-color: #2A2A2A !important;
-        color: #F9F9F9 !important;
-    }
-
-    h1, h2, h3, p, li, a.text-link {
-        color: #F9F9F9 !important;
+    	background-color: ' . $this->colours['dark-50'] . ';
     }
 
     .footer {
-        color: #999999 !important;
-    }
-
-    .divider {
-        border-color: #444444 !important;
+    	background-color: ' . $this->colours['dark-200'] . ';
+    	color: ' . $this->colours['light-200'] . ';
     }
 }
             </style>
@@ -310,7 +306,7 @@
 
                 <div class="header">
                     <a href="' . $this->site_url . '">
-                        <img src="' . $logo_url . '" alt="Edmonton Ink">
+                        ' . $logo . '
                     </a>
                     <p>' . $header . '</p>
                 </div>
@@ -318,8 +314,7 @@
                     ' . $content . '
                 </div>
                 <div class="footer">
-                    <p>&copy; ' . date('Y') . ' edmonton.ink — Your tattoo scene on your screen.</p>
-                    <p><a href="' . $this->site_url . '" class="text-link">edmonton.ink</a></p>
+                    ' . $this->footer . '
                 </div>
             </div>
         </body>
@@ -331,54 +326,24 @@
      */
     public function customizeNewUserEmail($wp_new_user_notification_email, $user, $blogname)
     {
-        $user_login = $user->user_login;
+		$message = sprintf(
+			'<p>Hi %s!</p>
+					<p>Thanks for signing up for an account on %s.</p>
+					<p><b>Your username:</b> %s</p>
+					<p><b>Your password:</b> <i>Your chosen password.</i></p>',
+			$user->display_name,
+			get_bloginfo('name'),
+			$user->user_login,
+		);
+		$message = apply_filters('jvbNewUserEmail', $message, $user);
 
-        // Only create the password key if the user can change their password
-        $key = get_password_reset_key($user);
-        if (!is_wp_error($key)) {
-            $reset_url = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
-
-            $message = sprintf('<p>Hey %s!</p>', $user->first_name);
-            $message .= '<p>Thanks for joining Edmonton\'s tattoo scene. Here\'s your login information:</p>';
-            $message .= sprintf('<p><strong>Username:</strong> %s</p>', $user_login);
-            $message .= '<p>To set your password and access your account, click the button below:</p>';
-            $message .= sprintf('<p style="text-align: center;"><a href="%s" class="button">Set Your Password</a></p>', $reset_url);
-            $message .= '<p>Or copy and paste this link into your browser:</p>';
-            $message .= sprintf('<p style="user-select:all;">%s</p>', $reset_url);
-            $message .= '<p>This link will expire in 24 hours, for security reasons.</p>';
-            if (in_array('jvb_artist', array_values($user->roles))) {
-                $message .= '<div class="divider"></div>';
-                $message .= '<h3>NOTE:</h3>
-                    <p>Once you set your password, you\'ll have access to your custom dashboard where you can:</p>
-                    <ul>
-                        <li>Manage your profile information</li>
-                        <li>Upload tattoos/piercings, and artwork</li>
-                    </ul>
-                    <p>Nothing will be published until you\'ve been approved by 3 already approved artists, or the admin.</p>
-                    <p>Admins check every day or three, but, if you are in a rush, you can contact us directly by replying to this email, or texting us at 825-925-9916.</p>';
-            } elseif (in_array('jvb_partner', array_values($user->roles))) {
-                $message .= '<div class="divider"></div>';
-                $message .= '<h3>NOTE:</h3>
-                    <p>Once you set your password, you\'ll have access to your custom dashboard where you can:</p>
-                    <ul>
-                        <li>Manage your profile information</li>
-                        <li>Create offers for enthusiasts or partners or both</li>
-                    </ul>
-                    <p>Nothing will be published until you\'ve been approved by the admin.</p>
-                    <p>Admins check every day or three, but, if you are in a rush, you can contact us directly by replying to this email, or texting us at 825-925-9916.</p>
-                    <p><strong>Note:</strong>Even after approval by admin, your ability to publish depends on your karmic standing by artists. Artists each have a vote they can cast (UP or DOWN) - if your karmic score dips too far in the negative, you account is subject to reconsideration or even a ban.</p>';
-            }
-            $message .= '<div class="divider"></div>';
-            $message = apply_filters(BASE.'new_user_email_content', $message, $user);
-
-			$message .= '<p>If you didn\'t create this account, please ignore this email and the link will expire.</p>';
-            $message .= sprintf('<p>Ink on, %s</p>', $user->first_name);
-            $message .= $this->signature;
-            $wp_new_user_notification_email['message'] = $this->getEmailTemplate($message, 'Welcome to edmonton.ink');
-        }
+		$message .= $this->signature;
+		$wp_new_user_notification_email['message'] = $this->getEmailTemplate($message, JVB_EMAIL['subjects']['newUser']);
 
         // Change the subject line
-        $wp_new_user_notification_email['subject'] = sprintf('Welcome to %s! Confirm your account', $this->site_name);
+		$prefix = JVB_EMAIL['types']['newUser']['showPrefix']??true;
+		$prefix = ($prefix) ? $this->prefix : '';
+        $wp_new_user_notification_email['subject'] = $prefix.JVB_EMAIL['types']['newUser']['subject'];
 
         return $wp_new_user_notification_email;
     }
@@ -394,12 +359,12 @@
     public function customizeNewUserEmailAdmin(array $emailData, WP_User $user, string $blogname):array
     {
         $message = '<p>A new user has registered on <strong>' . $this->site_name . '</strong>:</p>';
-        $message .= '<p><strong>Username:</strong> ' . $user->user_login . '<br>';
-        $message .= '<strong>Email:</strong> ' . $user->user_email . '<br>';
-        $message .= '<strong>Role:</strong> ' . str_replace(BASE, '', array_values($user->roles)[0]).'</p>';
+        $message .= '<p><strong>Username:</strong> ' . $user->user_login . '</p>';
+        $message .= '<p><strong>Email:</strong> ' . $user->user_email . '</p>';
+		$message = apply_filters('jvbNewUserAdminEmail', $message, $user);
         $message .= $this->signature;
         $emailData['message'] = $this->getEmailTemplate($message, 'New User Registration');
-        $emailData['subject'] = '[' . $this->site_name . '] New ' . str_replace(BASE, '', array_values($user->roles)[0]).': '.$user->display_name;
+        $emailData['subject'] = $this->prefix .'New ' . str_replace(BASE, '', array_values($user->roles)[0]).': '.$user->display_name;
 
         return $emailData;
     }
@@ -413,21 +378,27 @@
      *
      * @return string
      */
-    public function customizePasswordResetEmail(string $message, string $key, string $user_login, WP_User $user_data):string
+    public function customizePasswordResetEmail(string $message, string $key, string $user_login, WP_User $user):string
     {
-        $reset_url = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
-
-        $content = '<p>Hey bud,</p>';
-        $content = '<p>We received a request to reset the password for an account associated with this email:</p>';
-        $content .= '<p><strong>Username:</strong> ' . $user_login . '</p>';
-        $content .= '<p>If you didn\'t make this request, you can safely ignore this email and nothing will happen to your account.</p>';
-        $content .= '<p>To reset your password, click the button below:</p>';
-        $content .= '<p style="text-align: center;"><a href="' . $reset_url . '" class="button">Reset Password</a></p>';
-        $content .= '<p>Or copy and paste this link into your browser:</p>';
-        $content .= '<p style="user-select:all;">' . $reset_url . '</p>';
-        $content .= '<div class="divider"></div>';
-        $content .= '<p>This password reset link is only valid for 24 hours.</p>';
-            $content .= $this->signature;
+		$reset_url = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
+		$content = sprintf(
+			'<p>Hi %s!</p>
+			<p>We received a request to reset the password for an account associated with this email:</p>
+			<p><strong>Username:</strong> %s</p>
+			<p>If you didn\'t make this request, you can safely ignore this email and nothing will happen to your account.</p>
+			<p>To reset your password, click the button below:</p>
+			%s
+			<p>Or copy and paste this link into your browser:</p>
+			%s
+			<div class="divider"></div>
+			<p>This password reset link is only valid for 24 hours.</p>',
+			$user->display_name,
+			$user_login,
+			jvbMailButton($reset_url,'Reset Password'),
+			jvbEmailLink($reset_url)
+		);
+		$content = apply_filters('jvbPasswordResetEmail', $content, $user_login, $user, $reset_url);
+		$content .= $this->signature;
         return $this->getEmailTemplate($content, 'Password Reset');
     }
 
@@ -440,29 +411,42 @@
      */
     public function customizePasswordResetTitle(string $title, string $user_login, WP_User $user_data):string
     {
-        return '[' . $this->site_name . '] Password Reset Request';
-    }
+		$prefix = JVB_EMAIL['types']['resetPass']['showPrefix']??true;
+		$prefix = ($prefix) ? $this->prefix : '';
+		return $prefix.JVB_EMAIL['types']['resetPass']['subject'];
+
+	}
 
     /**
      * Email change notification to admin
      * @param array $email_change_email
-     * @param array $user
-     * @param array $userdata
+     * @param array $oldUser
+     * @param array $newUser
      *
      * @return array
      */
-    public function customizeEmailChangeEmail(array $email_change_email, array $user, array $userdata):array
+    public function customizeEmailChangeEmail(array $email_change_email, array $oldUser, array $newUser):array
     {
-        $content = sprintf('<p>Hi %s,</p>', $user['first_name']);
-        $content .= '<p>Ideally you already know this: you asked to change your email, and here we are.</p>';
-        $content .= '<p><strong>Old Email:</strong> ' . $email_change_email['to'] . '<br>';
-        $content .= '<strong>New Email:</strong> ' . $user['user_email'] . '</p>';
-
-        $content .= '<p>If this is news, or you did not change your email, please contact us immediately. You can <a href="sms:+18258239916">text us</a> or reply to this email."></a></p>';
-        $content .= '<p style="text-align: center;"><a href="' . wp_login_url() . '" class="button">Log In to Your Account</a></p>';
+        $content = sprintf(
+			'<p>Hi %s,</p>
+        <p>Ideally you already know this: someone asked to change the email for your account.</p>
+        <p><strong>Old Email:</strong> %s</p>
+        <p><strong>New Email:</strong> %s</p>
+        <div class="divider"></div>
+        <p>If this is news to you, or you did not request this - please contact us immediately. You can <a href="sms:+18258239916">text us</a> or reply to this email."></a></p>
+        %s',
+			$newUser['first_name'],
+			$oldUser['user_email'],
+			$newUser['user_email'],
+			jvbMailButton(wp_login_url(), 'Log In To Your Account')
+		);
+		$content = apply_filters('jvbEmailChangeRequestEmail', $content, $oldUser, $newUser);
         $content .= $this->signature;
         $email_change_email['message'] = $this->getEmailTemplate($content, 'Email Address Changed');
-        $email_change_email['subject'] = '[' . $this->site_name . '] Email Address Changed';
+		$prefix = JVB_EMAIL['types']['emailChange']['showPrefix']??true;
+		$prefix = ($prefix) ? $this->prefix : '';
+		$email_change_email['subject'] = $prefix.JVB_EMAIL['types']['emailChange']['subject'];
+
 
         return $email_change_email;
     }
@@ -474,21 +458,23 @@
      *
      * @return string
      */
-    public function customizeNewUserEmailContent(string $email_text, array $user):string
+    public function customizeNewUserEmailContent(string $email_text, array $new_user_email):string
     {
+		$confirm_url = esc_url( add_query_arg('newuseremail', $new_user_email['hash'], self_admin_url('profile.php')));
+		$content = sprintf(
+			'<p>Hey,</p>
+			<p>There was a request to change the email address associated with your account to this one.</p>
+			<p>This is just a friendly email to ensure you would like this change.</p>
+			<p>You can confirm this change by clicking the button below:</p>
+			%s
+			<p>Or copy and paste this link into your browser:</p>
+			%s',
+			jvbMailButton($confirm_url, 'Confirm this Email'),
+			jvbEmailLink($confirm_url)
+		);
 
-        // Extract the confirmation link from the default message
-        $pattern = '/###CONFIRM_URL### (.*?)(?=\n|\r|$)/';
-                                                                         preg_match($pattern, $email_text, $matches);
-        $confirm_url = isset($matches[1]) ? $matches[1] : admin_url('profile.php?newuseremail=' . $user['hash']);
+		$content = apply_filters('jvbEmailChangedEmail', $content, $confirm_url);
 
-        $content = '<p>Hey human,</p>';
-        $content .= '<p>Seems you want to change the email associated with your account.</p>';
-        $content .= '<p>You\'d like to change your email to: <strong>' . $user['newemail'] . '</strong></p>';
-        $content .= '<p>Please confirm this change by clicking the button below:</p>';
-        $content .= '<p style="text-align: center;"><a href="' . $confirm_url . '" class="button">Confirm Email Change</a></p>';
-        $content .= '<p>Or copy and paste this link into your browser:</p>';
-        $content .= '<p style="user-select:all">' . $confirm_url . '</p>';
         $content .= '<div class="divider"></div>';
         $content .= '<p>If you did not request this change, you can safely ignore this email and nothing will change.</p>';
         $content .= $this->signature;
@@ -499,23 +485,29 @@
         /**
          * Password change notification
          * @param array $pass_change_email
-         * @param array $user
-         * @param array $userdata
+         * @param array $oldUser
+         * @param array $newUser
          *
          * @return array
      */
-    public function customizePasswordChangeEmail(array $pass_change_email, array $user, array $userdata):array
+    public function customizePasswordChangeEmail(array $pass_change_email, array $oldUser, array $newUser):array
     {
-
-        $content = '<p>Hey bud,</p>';
-        $content .= '<p>Ideally, you\'re expecting this email. You wanted to change your password, and this is to let you know that it\'s definitely updated.</p>';
-        $content .= '<p>If you did not change your password, please contact us immediately.</p>';
-        $content .= '<p>You can <a href="sms:+18259257398">text us</a>, or reply to this email.</p>';
-        $content .= '<p style="text-align: center;"><a href="' . wp_login_url() . '" class="button">Log In to Your Account</a></p>';
+		$content = sprintf(
+			'<p>Hi %s,</p>
+			<p>This is a confirmation email to let you know your password has successfully been changed.</p>
+			<p>If you\'re not expecting this email, and did not change your password - please <strong>contact us immediately</strong></p>
+			<p>You can <a href="sms:+18259257398">text us</a>, or reply to this email.</p>
+			%s',
+			$oldUser['first_name'],
+			jvbMailButton(wp_login_url(), 'Log In to Your Account')
+		);
+		$content = apply_filters('jvbPasswordChangeEmail', $content, $oldUser, $newUser);
         $content .= $this->signature;
 
         $pass_change_email['message'] = $this->getEmailTemplate($content, 'Password Changed');
-        $pass_change_email['subject'] = '[' . $this->site_name . '] Password Changed';
+		$prefix = JVB_EMAIL['types']['passwordChange']['showPrefix']??true;
+		$prefix = ($prefix) ? $this->prefix : '';
+		$pass_change_email['subject'] = $prefix.JVB_EMAIL['types']['passwordChange']['subject'];
 
         return $pass_change_email;
     }
@@ -527,16 +519,11 @@
      *
      * @return string
      */
-    public function customizeUserRequestEmail(string $content, array $request_data):string
+    public function customizeUserRequestEmail(string $content, array $email_data):string
     {
 
-        // Extract the confirmation URL from the content
-        $pattern = '/<a href="([^"]+)"[^>]*>/';
-        preg_match($pattern, $content, $matches);
-        $confirm_url = isset($matches[1]) ? $matches[1] : '';
-
-        $request_type = $request_data['action_name'];
-        $request_name = '';
+       	$confirm_url = $email_data['confirm_url'];
+        $request_type = $email_data['action_name'];
 
         switch ($request_type) {
             case 'export_personal_data':
@@ -549,13 +536,20 @@
                 $request_name = 'Data Request';
         }
 
-        $message = '<p>Hi privacy enthusiast,</p>';
-        $message .= '<p>A request has been made to perform the following action on your account:</p>';
-        $message .= '<p><strong>' . $request_name . '</strong></p>';
-        $message .= '<p>If you made this request, you can confirm it by clicking the button below:</p>';
-        $message .= '<p style="text-align: center;"><a href="' . $confirm_url . '" class="button">Confirm Request</a></p>';
-        $message .= '<p>Or copy and paste this link into your browser:</p>';
-        $message .= '<p style="user-select:all;">' . $confirm_url . '</p>';
+
+		$message = sprintf(
+			'<p>Hi,</p>
+			<p>You\'re receiving this email because a request has been made to <strong>%s</strong></p>
+			<p>If you\'re the one who made this request, you can confirm it by clicking the button below:</p>
+			%s
+			<p>Or copy and paste this link into your browser:</p>
+			%s',
+			$request_name,
+			jvbMailButton($confirm_url, 'Confirm'),
+			jvbEmailLink($confirm_url)
+		);
+		$message = apply_filters('jvbPersonalDataExport', $message, $request_type, $confirm_url, $email_data);
+
         $message .= '<div class="divider"></div>';
         $message .= '<p>If you did not make this request, you can safely ignore this email.</p>';
         $message .= $this->signature;
@@ -573,19 +567,23 @@
      */
     public function customizePersonalDataEmail(string $content, int $request_id, array $email_data):string
     {
+        $download_url = $email_data['export_file_url'];
+		$expiresAt = $email_data['expiration_date'];
 
-        // Extract the download link
-        $pattern = '/<a href="([^"]+)"[^>]*>/';
-        preg_match($pattern, $content, $matches);
-        $download_url = isset($matches[1]) ? $matches[1] : '';
-
-        $message = '<p>Your request for an export of personal data has been completed.</p>';
-        $message .= '<p>You can download your personal data by clicking the button below.</p>';
-        $message .= '<p style="text-align: center;"><a href="' . $download_url . '" class="button">Download Personal Data</a></p>';
-        $message .= '<p>Or copy and paste this link into your browser:</p>';
-        $message .= '<p style="user-select:all;">' . $download_url . '</p>';
-        $message .= '<div class="divider"></div>';
-        $message .= '<p><strong>Important:</strong> For privacy reasons, this link will expire in ' . $email_data['expiration'] . '.</p>';
+		$message = sprintf(
+			'<p>Hi,</p>
+			<p>You\'re receiving this email because you requested an export of your personal data.</p>
+			<p>You can download your personal data by clicking the button below:</p>
+			%s
+			<p>Or you can copy and paste this link into your browser:</p>
+			%s
+			<div class="divider"></div>
+			<p><strong>Important:</strong> For privacy and security, this link will expire at %s.</p>',
+			jvbMailButton($download_url, 'Download Your Data'),
+			jvbEmailLink($download_url),
+			$expiresAt
+		);
+		$message = apply_filters('jvbPersonalDataExported', $message, $download_url, $expiresAt, $email_data);
         $message .= $this->signature;
 
         return $this->getEmailTemplate($message, 'Your Personal Data Export');

--
Gitblit v1.10.0