ActivityReportJob.php
2 days ago
CleanupJob.php
2 days ago
DeleteExpiredJob.php
2 days ago
Job.php
2 days ago
JobBuilder.php
2 days ago
JobHandler.php
2 days ago
SendEmailJob.php
2 days ago
SendEmailJob.php
210 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Send Email Job |
| 4 | * |
| 5 | * Handles sending emails asynchronously. |
| 6 | * |
| 7 | * @package WPDM\__\Jobs |
| 8 | * @since 7.0.1 |
| 9 | */ |
| 10 | |
| 11 | namespace WPDM\__\Jobs; |
| 12 | |
| 13 | use WPDM\__\Email; |
| 14 | |
| 15 | class SendEmailJob extends Job |
| 16 | { |
| 17 | /** |
| 18 | * Execute the send email job |
| 19 | * |
| 20 | * @param object|array $data Job payload containing: |
| 21 | * - to: Email recipient(s) |
| 22 | * - subject: Email subject |
| 23 | * - message: Email body (HTML or plain text) |
| 24 | * - template: (optional) Email template name |
| 25 | * - headers: (optional) Additional headers |
| 26 | * - attachments: (optional) Array of file paths |
| 27 | * @return bool |
| 28 | */ |
| 29 | public function handle($data): bool |
| 30 | { |
| 31 | $to = $this->get('to'); |
| 32 | $subject = $this->get('subject'); |
| 33 | $message = $this->get('message'); |
| 34 | |
| 35 | if (empty($to) || empty($subject)) { |
| 36 | $this->log('Missing required email fields (to or subject)', 'error'); |
| 37 | return false; |
| 38 | } |
| 39 | |
| 40 | $this->log("Sending email to {$to}: {$subject}"); |
| 41 | |
| 42 | // Check if using WPDM Email class with template |
| 43 | $template = $this->get('template'); |
| 44 | if ($template && class_exists('\WPDM\__\Email')) { |
| 45 | return $this->sendWithTemplate($template); |
| 46 | } |
| 47 | |
| 48 | // Standard wp_mail |
| 49 | return $this->sendStandardEmail(); |
| 50 | } |
| 51 | |
| 52 | /** |
| 53 | * Send email using WPDM Email template system |
| 54 | * |
| 55 | * @param string $template Template name |
| 56 | * @return bool |
| 57 | */ |
| 58 | private function sendWithTemplate(string $template): bool |
| 59 | { |
| 60 | $emailData = [ |
| 61 | 'to_email' => $this->get('to'), |
| 62 | 'subject' => $this->get('subject'), |
| 63 | 'message' => $this->get('message'), |
| 64 | ]; |
| 65 | |
| 66 | // Add optional fields |
| 67 | $optionalFields = ['to_name', 'from_email', 'from_name', 'reply_to', 'cc', 'bcc']; |
| 68 | foreach ($optionalFields as $field) { |
| 69 | $value = $this->get($field); |
| 70 | if ($value) { |
| 71 | $emailData[$field] = $value; |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | // Merge any template variables |
| 76 | $vars = $this->get('vars', []); |
| 77 | if (is_array($vars) || is_object($vars)) { |
| 78 | $emailData = array_merge($emailData, (array) $vars); |
| 79 | } |
| 80 | |
| 81 | try { |
| 82 | Email::send($template, $emailData); |
| 83 | $this->log('Email sent successfully using template: ' . $template); |
| 84 | return true; |
| 85 | } catch (\Throwable $e) { |
| 86 | $this->log('Failed to send email: ' . $e->getMessage(), 'error'); |
| 87 | throw $e; |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | /** |
| 92 | * Send email using standard wp_mail |
| 93 | * |
| 94 | * @return bool |
| 95 | */ |
| 96 | private function sendStandardEmail(): bool |
| 97 | { |
| 98 | $to = $this->get('to'); |
| 99 | $subject = $this->get('subject'); |
| 100 | $message = $this->get('message'); |
| 101 | $headers = $this->get('headers', []); |
| 102 | $attachments = $this->get('attachments', []); |
| 103 | |
| 104 | // Ensure headers is an array |
| 105 | if (!is_array($headers)) { |
| 106 | $headers = [$headers]; |
| 107 | } |
| 108 | |
| 109 | // Add content-type for HTML if message contains HTML |
| 110 | if ($this->containsHtml($message)) { |
| 111 | $headers[] = 'Content-Type: text/html; charset=UTF-8'; |
| 112 | } |
| 113 | |
| 114 | // Add from header if specified |
| 115 | $fromName = $this->get('from_name'); |
| 116 | $fromEmail = $this->get('from_email'); |
| 117 | if ($fromEmail) { |
| 118 | $from = $fromName ? "{$fromName} <{$fromEmail}>" : $fromEmail; |
| 119 | $headers[] = "From: {$from}"; |
| 120 | } |
| 121 | |
| 122 | // Add reply-to if specified |
| 123 | $replyTo = $this->get('reply_to'); |
| 124 | if ($replyTo) { |
| 125 | $headers[] = "Reply-To: {$replyTo}"; |
| 126 | } |
| 127 | |
| 128 | // Add CC if specified |
| 129 | $cc = $this->get('cc'); |
| 130 | if ($cc) { |
| 131 | $headers[] = "Cc: {$cc}"; |
| 132 | } |
| 133 | |
| 134 | // Add BCC if specified |
| 135 | $bcc = $this->get('bcc'); |
| 136 | if ($bcc) { |
| 137 | $headers[] = "Bcc: {$bcc}"; |
| 138 | } |
| 139 | |
| 140 | // Ensure attachments is an array |
| 141 | if (!is_array($attachments)) { |
| 142 | $attachments = $attachments ? [$attachments] : []; |
| 143 | } |
| 144 | |
| 145 | $result = wp_mail($to, $subject, $message, $headers, $attachments); |
| 146 | |
| 147 | if ($result) { |
| 148 | $this->log('Email sent successfully via wp_mail'); |
| 149 | } else { |
| 150 | $this->log('Failed to send email via wp_mail', 'error'); |
| 151 | } |
| 152 | |
| 153 | return $result; |
| 154 | } |
| 155 | |
| 156 | /** |
| 157 | * Check if content contains HTML tags |
| 158 | * |
| 159 | * @param string $content |
| 160 | * @return bool |
| 161 | */ |
| 162 | private function containsHtml(string $content): bool |
| 163 | { |
| 164 | return $content !== strip_tags($content); |
| 165 | } |
| 166 | |
| 167 | /** |
| 168 | * Handle job failure - log the error |
| 169 | * |
| 170 | * @param \Throwable $e |
| 171 | * @param object|array $data |
| 172 | * @return void |
| 173 | */ |
| 174 | public function failed(\Throwable $e, $data): void |
| 175 | { |
| 176 | parent::failed($e, $data); |
| 177 | |
| 178 | // Log additional details |
| 179 | $to = is_object($data) ? ($data->to ?? 'unknown') : ($data['to'] ?? 'unknown'); |
| 180 | $subject = is_object($data) ? ($data->subject ?? 'unknown') : ($data['subject'] ?? 'unknown'); |
| 181 | |
| 182 | error_log(sprintf( |
| 183 | '[WPDM SendEmailJob] Failed to send email to %s with subject "%s": %s', |
| 184 | $to, |
| 185 | $subject, |
| 186 | $e->getMessage() |
| 187 | )); |
| 188 | } |
| 189 | |
| 190 | /** |
| 191 | * Get job name |
| 192 | * |
| 193 | * @return string |
| 194 | */ |
| 195 | public static function getName(): string |
| 196 | { |
| 197 | return 'Send Email'; |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * Get job description |
| 202 | * |
| 203 | * @return string |
| 204 | */ |
| 205 | public static function getDescription(): string |
| 206 | { |
| 207 | return 'Sends emails asynchronously'; |
| 208 | } |
| 209 | } |
| 210 |