PluginProbe
StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More / 2.2.0
StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More v2.2.0
2.3.0 2.2.0 2.1.1 2.1.0 2.0.0 1.10.0 1.9.1 1.9.0 1.2.1 1.2.2 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 All 59 releases
storeengine / includes / classes / email-log.php

email-log.php in StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More 2.2.0, at includes/classes/email-log.php

183 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Email log entry — one row per email send attempt across the whole plugin
4 * (orders, refunds, abandoned-cart recoveries, account, subscription, etc.).
5 *
6 * This is customer-communication audit. For technical diagnostics use the
7 * separate `Logger` class + `storeengine_logs` table.
8 *
9 * @version 1.0.0
10 */
11
12 namespace StoreEngine\Classes;
13
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 class EmailLog extends AbstractEntity {
19 protected string $table = 'storeengine_email_log';
20
21 protected string $object_type = 'email_log';
22
23 protected array $data = [
24 'sent_at_gmt' => null,
25 'email_type' => null,
26 'recipient' => null,
27 'subject' => null,
28 'status' => 'queued',
29 'customer_id' => null,
30 'order_id' => null,
31 'related_entity_type' => null,
32 'related_entity_id' => null,
33 'error_message' => null,
34 'payload' => null,
35 ];
36
37 protected array $data_format = [
38 'sent_at_gmt' => '%s',
39 'email_type' => '%s',
40 'recipient' => '%s',
41 'subject' => '%s',
42 'status' => '%s',
43 'customer_id' => '%d',
44 'order_id' => '%d',
45 'related_entity_type' => '%s',
46 'related_entity_id' => '%d',
47 'error_message' => '%s',
48 'payload' => '%s',
49 ];
50
51 protected array $valid_stati = [ 'queued', 'sent', 'failed' ];
52
53 public function get_sent_at_gmt( string $context = 'view' ) {
54 return $this->get_prop( 'sent_at_gmt', $context );
55 }
56
57 public function set_sent_at_gmt( $value ) {
58 $this->set_prop( 'sent_at_gmt', $value );
59 }
60
61 public function get_email_type( string $context = 'view' ) {
62 return $this->get_prop( 'email_type', $context );
63 }
64
65 public function set_email_type( $value ) {
66 $this->set_prop( 'email_type', $value );
67 }
68
69 public function get_recipient( string $context = 'view' ) {
70 return $this->get_prop( 'recipient', $context );
71 }
72
73 public function set_recipient( $value ) {
74 $this->set_prop( 'recipient', $value );
75 }
76
77 public function get_subject( string $context = 'view' ) {
78 return $this->get_prop( 'subject', $context );
79 }
80
81 public function set_subject( $value ) {
82 $this->set_prop( 'subject', $value );
83 }
84
85 public function get_status( string $context = 'view' ): ?string {
86 return $this->get_prop( 'status', $context );
87 }
88
89 public function set_status( $value ) {
90 if ( ! in_array( $value, $this->valid_stati, true ) ) {
91 $value = 'queued';
92 }
93
94 $this->set_prop( 'status', $value );
95 }
96
97 public function get_customer_id( string $context = 'view' ): int {
98 return absint( $this->get_prop( 'customer_id', $context ) );
99 }
100
101 public function set_customer_id( $value ) {
102 $value = absint( $value );
103 $this->set_prop( 'customer_id', $value ?: null );
104 }
105
106 public function get_order_id( string $context = 'view' ): int {
107 return absint( $this->get_prop( 'order_id', $context ) );
108 }
109
110 public function set_order_id( $value ) {
111 $value = absint( $value );
112 $this->set_prop( 'order_id', $value ?: null );
113 }
114
115 public function get_related_entity_type( string $context = 'view' ) {
116 return $this->get_prop( 'related_entity_type', $context );
117 }
118
119 public function set_related_entity_type( $value ) {
120 $this->set_prop( 'related_entity_type', $value ?: null );
121 }
122
123 public function get_related_entity_id( string $context = 'view' ): int {
124 return absint( $this->get_prop( 'related_entity_id', $context ) );
125 }
126
127 public function set_related_entity_id( $value ) {
128 $value = absint( $value );
129 $this->set_prop( 'related_entity_id', $value ?: null );
130 }
131
132 public function get_error_message( string $context = 'view' ) {
133 return $this->get_prop( 'error_message', $context );
134 }
135
136 public function set_error_message( $value ) {
137 $this->set_prop( 'error_message', $value ?: null );
138 }
139
140 /**
141 * Raw JSON column accessor. Exists so AbstractEntity::prepare_for_db()
142 * can preserve the existing value across update() calls — without this
143 * getter, prepare_for_db falls back to `$raw_data['payload'] ?? null`
144 * when 'payload' isn't in the change set, nulling out the column.
145 */
146 public function get_payload( string $context = 'view' ): ?string {
147 $value = $this->get_prop( 'payload', $context );
148
149 return is_string( $value ) && '' !== $value ? $value : null;
150 }
151
152 /**
153 * Return the meta JSON column as a decoded array.
154 *
155 * Sender-side context (headers list, attachment names, the source class
156 * that called wp_mail, resent_from_log_id, etc.) lives here. Decoupled
157 * from get_meta_data() on AbstractEntity which manages WP-style metadata
158 * tables we don't have for this entity.
159 */
160 public function get_meta_payload(): array {
161 $raw = $this->get_prop( 'payload', 'edit' );
162 if ( ! is_string( $raw ) || '' === $raw ) {
163 return [];
164 }
165
166 $decoded = json_decode( $raw, true );
167
168 return is_array( $decoded ) ? $decoded : [];
169 }
170
171 public function set_meta_payload( array $value ) {
172 $this->set_prop( 'payload', $value ? wp_json_encode( $value ) : null );
173 }
174
175 /**
176 * Merge an associative array into the existing meta payload.
177 * Used by the resend flow to tag the new row with provenance.
178 */
179 public function merge_meta_payload( array $value ) {
180 $this->set_meta_payload( array_merge( $this->get_meta_payload(), $value ) );
181 }
182 }
183