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/Blocks/BlockManager.php +161 -13 2.4.0 → 2.4.1 View file →
@@ -12,9 +12,8 @@
12 12
13 13 use Better_Payment\Lite\Admin\DB;
14 14 use Better_Payment\Lite\Classes\Handler;
15 15 use Better_Payment\Lite\Classes\Helper;
16 -use Better_Payment\Lite\Classes\ProSubscriptionTransactionData;
17 16 use Better_Payment\Lite\Traits\Helper as TraitsHelper;
18 17
19 18 if ( ! defined( 'ABSPATH' ) ) {
20 19 exit;
@@ -161,14 +160,10 @@
161 160 return '';
162 161 }
163 162
164 163 return '<div ' . $wrapper_attributes . '>' .
165 - '<div class="better-payment-block__notice">' .
166 - '<p>' . esc_html__( 'Payment form: enable at least one payment gateway (PayPal, Stripe or Paystack) in Better Payment settings. This notice is only visible to you.', 'better-payment' ) . '</p>' .
167 - '<p><a href="' . esc_url( admin_url( 'admin.php?page=better-payment-admin&tab=settings&section=general' ) ) . '">' .
168 - esc_html__( 'Open Better Payment settings', 'better-payment' ) .
169 - '</a></p>' .
170 - '</div></div>';
164 + $this->render_gateway_notice( $attributes, $global_settings ) .
165 + '</div>';
171 166 }
172 167
173 168 // Enqueue scripts/styles before manage_response() so they are present even when the
174 169 // block returns the pending or success state early (the AJAX poller needs better-payment.js).
@@ -1013,8 +1008,165 @@
1013 1008 );
1014 1009 }
1015 1010
1016 1011 /**
1012 + * Why a Payment Form block has no gateway, decided per gateway.
1013 + *
1014 + * Each gateway resolves in `build_block_settings()` from the block's own
1015 + * toggle when the block saved one, and from the site setting only when it
1016 + * did not. So a gateway is off for one of two reasons, and they are fixed in
1017 + * different places:
1018 + *
1019 + * - `block` — the site has a gateway enabled, but this block switches it
1020 + * off. Settings cannot fix it: the gateway is already on there.
1021 + * - `global` — no gateway is enabled site-wide. Settings fixes it on its own
1022 + * for any gateway the block leaves to the site (`settings_fixes`); a
1023 + * gateway the block also switched off needs both (`needs_block`). A new
1024 + * block seeds its toggles from the settings, so on a site with nothing
1025 + * enabled `needs_block` is the usual case.
1026 + *
1027 + * Mirrors the editor's `gatewayNoticeState()` (helpers/gatewayNotice.js), so
1028 + * the editor and the page never give two different answers.
1029 + *
1030 + * @param array $attributes Block attributes.
1031 + * @param array $global_settings Global plugin settings.
1032 + * @return array{reason: string, site_gateways: string[], settings_fixes: string[], needs_block: bool}
1033 + */
1034 + public static function gateway_notice_state( $attributes, $global_settings ) {
1035 + $gateways = array(
1036 + 'PayPal' => array( 'paypalEnabled', 'better_payment_settings_general_general_paypal' ),
1037 + 'Stripe' => array( 'stripeEnabled', 'better_payment_settings_general_general_stripe' ),
1038 + 'Paystack' => array( 'paystackEnabled', 'better_payment_settings_general_general_paystack' ),
1039 + );
1040 +
1041 + $site_gateways = array();
1042 + $settings_fixes = array();
1043 +
1044 + foreach ( $gateways as $label => $keys ) {
1045 + if ( isset( $global_settings[ $keys[1] ] ) && 'yes' === $global_settings[ $keys[1] ] ) {
1046 + $site_gateways[] = $label;
1047 + }
1048 + if ( ! isset( $attributes[ $keys[0] ] ) ) {
1049 + $settings_fixes[] = $label;
1050 + }
1051 + }
1052 +
1053 + $reason = empty( $site_gateways ) ? 'global' : 'block';
1054 +
1055 + return array(
1056 + 'reason' => $reason,
1057 + 'site_gateways' => $site_gateways,
1058 + 'settings_fixes' => $settings_fixes,
1059 + 'needs_block' => 'block' === $reason || empty( $settings_fixes ),
1060 + );
1061 + }
1062 +
1063 + /**
1064 + * The admin-only notice printed in place of a form with no gateway.
1065 + *
1066 + * Names the gateways and the place that fixes them, and links to each place
1067 + * the fix needs: Better Payment settings, this block's editor, or both. The
1068 + * editor link is offered only when the block is really in the current post's
1069 + * content — in a template, template part, synced pattern or widget area the
1070 + * current post's editor does not contain it, so the notice says where to look
1071 + * instead of linking to the wrong screen.
1072 + *
1073 + * @param array $attributes Block attributes.
1074 + * @param array $global_settings Global plugin settings.
1075 + * @return string Notice HTML.
1076 + */
1077 + private function render_gateway_notice( $attributes, $global_settings ) {
1078 + $state = self::gateway_notice_state( $attributes, $global_settings );
1079 +
1080 + if ( 'block' === $state['reason'] ) {
1081 + $message = sprintf(
1082 + /* translators: %s: gateway names, e.g. "PayPal or Stripe". */
1083 + __( 'Payment form: every payment method is switched off in this block’s settings. Turn on %s under Payment Settings in the block sidebar.', 'better-payment' ),
1084 + self::join_gateway_names( $state['site_gateways'] )
1085 + );
1086 + } elseif ( $state['needs_block'] ) {
1087 + $message = __( 'Payment form: no payment gateway is enabled in Better Payment settings, and every payment method is switched off in this block’s settings. Enable PayPal, Stripe or Paystack in Better Payment settings, then turn the same gateway on under Payment Settings in the block sidebar.', 'better-payment' );
1088 + } else {
1089 + $message = sprintf(
1090 + /* translators: %s: gateway names, e.g. "PayPal, Stripe or Paystack". */
1091 + __( 'Payment form: enable at least one payment gateway (%s) in Better Payment settings.', 'better-payment' ),
1092 + self::join_gateway_names( $state['settings_fixes'] )
1093 + );
1094 + }
1095 +
1096 + $links = array();
1097 +
1098 + if ( 'global' === $state['reason'] ) {
1099 + $links[] = '<a href="' . esc_url( admin_url( 'admin.php?page=better-payment-admin&tab=settings&section=general' ) ) . '">' .
1100 + esc_html__( 'Open Better Payment settings', 'better-payment' ) . '</a>';
1101 + }
1102 +
1103 + $hint = '';
1104 +
1105 + if ( $state['needs_block'] ) {
1106 + $edit_url = self::block_edit_url();
1107 +
1108 + if ( '' !== $edit_url ) {
1109 + $links[] = '<a href="' . esc_url( $edit_url ) . '">' .
1110 + esc_html__( 'Edit this form in the block editor', 'better-payment' ) . '</a>';
1111 + } else {
1112 + $hint = '<p>' . esc_html__( 'This form is not part of this page’s content. Open the template, template part, pattern or widget area that contains it to change its settings.', 'better-payment' ) . '</p>';
1113 + }
1114 + }
1115 +
1116 + return '<div class="better-payment-block__notice">' .
1117 + '<p>' . esc_html( $message ) . ' ' . esc_html__( 'This notice is only visible to you.', 'better-payment' ) . '</p>' .
1118 + $hint .
1119 + ( $links ? '<p class="better-payment-block__notice-actions">' . implode( ' ', $links ) . '</p>' : '' ) .
1120 + '</div>';
1121 + }
1122 +
1123 + /**
1124 + * The editor URL of the current post, when it holds a Payment Form block.
1125 + *
1126 + * Empty when there is no current post, the user may not edit it, or its
1127 + * content has no Payment Form block (the block came from a template, template
1128 + * part, synced pattern or widget area).
1129 + *
1130 + * @return string Raw edit URL, or ''.
1131 + */
1132 + private static function block_edit_url() {
1133 + $post_id = (int) get_the_ID();
1134 +
1135 + if ( $post_id <= 0 || ! current_user_can( 'edit_post', $post_id ) ) {
1136 + return '';
1137 + }
1138 +
1139 + if ( ! has_block( 'better-payment/payment-form', $post_id ) ) {
1140 + return '';
1141 + }
1142 +
1143 + return (string) get_edit_post_link( $post_id, 'raw' );
1144 + }
1145 +
1146 + /**
1147 + * "A", "A or B", "A, B or C".
1148 + *
1149 + * @param string[] $names Gateway names (brand names, not translated).
1150 + * @return string Joined list.
1151 + */
1152 + private static function join_gateway_names( $names ) {
1153 + $names = array_values( $names );
1154 + $last = array_pop( $names );
1155 +
1156 + if ( empty( $names ) ) {
1157 + return (string) $last;
1158 + }
1159 +
1160 + return sprintf(
1161 + /* translators: 1: comma-separated gateway names, 2: the last gateway name. */
1162 + __( '%1$s or %2$s', 'better-payment' ),
1163 + implode( ', ', $names ),
1164 + $last
1165 + );
1166 + }
1167 +
1168 + /**
1017 1169 * Resolve the correct Stripe key based on live mode setting.
1018 1170 *
1019 1171 * This matches Elementor's behavior where the key is resolved before being stored
1020 1172 * in better_payment_stripe_public_key/better_payment_stripe_secret_key.
@@ -1793,14 +1945,10 @@
1793 1945 foreach ( $user_subscriptions as $tx ) {
1794 1946 $ffi = is_array( $tx->form_fields_info ) ? $tx->form_fields_info : array();
1795 1947
1796 1948 // The subscription columns come from the same place as UserAPI's REST rows: Pro fills
1797 - // `better_payment/user_api/subscription_row`, and Lite's copy serves only an active Pro
1798 - // that does not (ProSubscriptionTransactionData, <= 1.4.3).
1799 - $row = array();
1800 - if ( ProSubscriptionTransactionData::lite_copy_applies() ) {
1801 - $row = ProSubscriptionTransactionData::subscription_row( $row, $ffi );
1802 - }
1949 + // `better_payment/user_api/subscription_row`.
1950 + $row = array();
1803 1951 $built = apply_filters( 'better_payment/user_api/subscription_row', $row, $ffi, $tx );
1804 1952 $row = is_array( $built ) ? $built : $row;
1805 1953
1806 1954 foreach ( $row as $key => $value ) {