PluginProbe
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More / 2.4.1
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More v2.4.1
2.4.1 2.4.0 2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.2 2.2.1 2.2.0 2.1.2 2.1.1 trunk 0.0.1 0.0.2 0.0.3 0.0.4 0.0.5 0.0.6 0.0.7 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 All 68 releases
← All changes | includes/Classes/Import.php +34 -8 2.4.0 → 2.4.1 View file →
@@ -34,8 +34,40 @@
34 34
35 35 }
36 36
37 37 /**
38 + * A CSV `payment_date` cell as the UTC `Y-m-d H:i:s` the table stores.
39 + *
40 + * The export writes the date in site time, in the site's date and time
41 + * format (`Export`: `wp_date()`), so a cell without a timezone is read as
42 + * site time and converted. It used to be stored as if it were UTC, so an
43 + * export → import round trip moved every row by the site's UTC offset. A
44 + * cell that names its own timezone (`Z`, `+06:00`, `UTC`, `GMT`) is honoured
45 + * as given. An unparseable cell keeps the old result (the epoch).
46 + *
47 + * @since 2.4.1
48 + *
49 + * @param string $value Cell value.
50 + * @return string
51 + */
52 + public static function payment_date_from_csv( $value ) {
53 + $value = trim( (string) $value );
54 + $timestamp = strtotime( $value );
55 +
56 + if ( false === $timestamp ) {
57 + return gmdate( 'Y-m-d H:i:s', 0 );
58 + }
59 +
60 + if ( preg_match( '/(?:Z|[+-]\d{2}:?\d{2}|\bUTC|\bGMT)$/i', $value ) ) {
61 + return gmdate( 'Y-m-d H:i:s', $timestamp );
62 + }
63 +
64 + // strtotime() read the wall-clock time as UTC (WordPress runs PHP in UTC);
65 + // it is site time, so convert it.
66 + return get_gmt_from_date( gmdate( 'Y-m-d H:i:s', $timestamp ), 'Y-m-d H:i:s' );
67 + }
68 +
69 + /**
38 70 * Decode a CSV `form_fields_info` cell into an array.
39 71 *
40 72 * The cell comes from an uploaded file, so it is never handed to maybe_unserialize():
41 73 * that instantiates any class a serialized payload names, which turns an import into an
@@ -117,9 +149,9 @@
117 149 // 'payment_type' => sanitize_text_field( $record['payment_type'] ),
118 150 'transaction_id' => sanitize_text_field( $record['transaction_id'] ),
119 151 'source' => sanitize_text_field( $record['source'] ),
120 152 'status' => sanitize_text_field( $record['status'] ),
121 - 'payment_date' => date( 'Y-m-d H:i:s', strtotime( sanitize_text_field( $record['payment_date'] ) ) ),
153 + 'payment_date' => self::payment_date_from_csv( sanitize_text_field( $record['payment_date'] ) ),
122 154 'form_fields_info' => maybe_serialize( $better_form_fields ),
123 155 );
124 156 }
125 157
@@ -149,11 +181,9 @@
149 181 *
150 182 * Lite keeps the name, email and source and marks the row imported.
151 183 * `better_payment/import/form_fields_info` receives that, the CSV row and the
152 184 * row's decoded `form_fields_info` cell: Pro adds the subscription keys of a
153 - * "Subscription" row there. Lite's copy of that
154 - * (ProSubscriptionTransactionData::import_fields()) serves only an active Pro
155 - * that does not (<= 1.4.3).
185 + * "Subscription" row there.
156 186 *
157 187 * @since 2.4.0
158 188 *
159 189 * @param mixed $record CSV row keyed by header; anything else is treated as empty.
@@ -170,12 +200,8 @@
170 200 ];
171 201
172 202 // Decoded without instantiating objects; see decode_form_fields_info().
173 203 $decoded = isset( $record['form_fields_info'] ) ? self::decode_form_fields_info( $record['form_fields_info'] ) : [];
174 -
175 - if ( ProSubscriptionTransactionData::lite_copy_applies() ) {
176 - $better_form_fields = ProSubscriptionTransactionData::import_fields( $better_form_fields, $record, $decoded );
177 - }
178 204
179 205 $filtered = apply_filters( 'better_payment/import/form_fields_info', $better_form_fields, $record, $decoded );
180 206
181 207 return is_array( $filtered ) ? $filtered : $better_form_fields;