← All changes
|
includes/admin/settings/class-charitable-settings.php
+229
-14
1.8.11
→
1.8.13
View file →
| @@ -101,19 +101,20 @@ | ||
| 101 | 101 | 'privacy' => __( 'Privacy', 'charitable' ), |
| 102 | 102 | 'advanced' => __( 'Advanced', 'charitable' ), |
| 103 | 103 | ); |
| 104 | 104 | |
| 105 | - // Only show marketing tab if newsletter connect addon is not active. | |
| 106 | - if ( ! class_exists( 'Charitable_Newsletter_Connect' ) ) { | |
| 107 | - $tabs = charitable_add_settings_tab( | |
| 108 | - $tabs, | |
| 109 | - 'marketing', | |
| 110 | - __( 'Marketing', 'charitable' ), | |
| 111 | - array( | |
| 112 | - 'index' => 5, | |
| 113 | - ) | |
| 114 | - ); | |
| 115 | - } | |
| 105 | + // Always show marketing tab. Sub-tabs (Newsletters, Conversion Tracking, Google Analytics) | |
| 106 | + // handle the per-feature display: Newsletter Connect addon (which works with Lite) renders | |
| 107 | + // its real UI under the Newsletters sub-tab when active; Conversion Tracking and Google | |
| 108 | + // Analytics always render Pro CTAs in Lite. | |
| 109 | + $tabs = charitable_add_settings_tab( | |
| 110 | + $tabs, | |
| 111 | + 'marketing', | |
| 112 | + __( 'Marketing', 'charitable' ), | |
| 113 | + array( | |
| 114 | + 'index' => 5, | |
| 115 | + ) | |
| 116 | + ); | |
| 116 | 117 | |
| 117 | 118 | // Always show security tab. |
| 118 | 119 | // When spam blocker is active, it will handle the settings. |
| 119 | 120 | // When spam blocker is inactive, core security features will handle the settings. |
| @@ -136,8 +137,60 @@ | ||
| 136 | 137 | return apply_filters( 'charitable_settings_tabs', $tabs ); |
| 137 | 138 | } |
| 138 | 139 | |
| 139 | 140 | /** |
| 141 | + * Return the array of sub tabs used on the Marketing settings page. | |
| 142 | + * | |
| 143 | + * Each label carries an inline "Pro" badge: | |
| 144 | + * - Newsletters: the Newsletter Connect addon works on Lite, but the badge | |
| 145 | + * still appears since the bulk of newsletter functionality is Pro-tier. | |
| 146 | + * - Conversion Tracking / Google Analytics: Pro-only — badge always shown. | |
| 147 | + * | |
| 148 | + * @since 1.8.11.3 | |
| 149 | + * | |
| 150 | + * @return string[] key => label. | |
| 151 | + */ | |
| 152 | + public function get_sub_sections_marketing() { | |
| 153 | + $pro_badge = ' <span class="charitable-pro-badge">' . esc_html__( 'PRO', 'charitable' ) . '</span>'; | |
| 154 | + | |
| 155 | + return apply_filters( | |
| 156 | + 'charitable_settings_sub_tabs_marketing', | |
| 157 | + array( | |
| 158 | + 'marketing__newsletters' => __( 'Newsletters', 'charitable' ) . $pro_badge, | |
| 159 | + 'marketing__conversion_tracking' => __( 'Conversion Tracking', 'charitable' ) . $pro_badge, | |
| 160 | + 'marketing__google_analytics' => __( 'Google Analytics', 'charitable' ) . $pro_badge, | |
| 161 | + ) | |
| 162 | + ); | |
| 163 | + } | |
| 164 | + | |
| 165 | + /** | |
| 166 | + * Redirect to the default Marketing sub-tab when no sub_tab is supplied. | |
| 167 | + * | |
| 168 | + * @since 1.8.11.3 | |
| 169 | + * | |
| 170 | + * @return void | |
| 171 | + */ | |
| 172 | + public function marketing_sub_tab_default() { | |
| 173 | + // Don't redirect during form submissions. | |
| 174 | + if ( ! empty( $_POST ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 175 | + return; | |
| 176 | + } | |
| 177 | + | |
| 178 | + if ( ! charitable_is_settings_view( 'marketing' ) ) { | |
| 179 | + return; | |
| 180 | + } | |
| 181 | + | |
| 182 | + if ( isset( $_GET['sub_tab'] ) || isset( $_GET['group'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 183 | + return; | |
| 184 | + } | |
| 185 | + | |
| 186 | + wp_safe_redirect( | |
| 187 | + admin_url( 'admin.php?page=charitable-settings&tab=marketing&sub_tab=newsletters' ) | |
| 188 | + ); | |
| 189 | + exit; | |
| 190 | + } | |
| 191 | + | |
| 192 | + /** | |
| 140 | 193 | * Optionally add the extensions tab. |
| 141 | 194 | * |
| 142 | 195 | * @since 1.3.0 |
| 143 | 196 | * @version 1.8.5.1 Adjust index so it comes before the advanced tab. |
| @@ -221,10 +274,32 @@ | ||
| 221 | 274 | } |
| 222 | 275 | |
| 223 | 276 | register_setting( 'charitable_settings', 'charitable_settings', array( $this, 'sanitize_settings' ) ); |
| 224 | 277 | |
| 278 | + // Bridge the Newsletter Connect addon (which gates its filter on | |
| 279 | + // charitable_is_settings_view('extensions')) so its fields contribute | |
| 280 | + // when the user is on Marketing → Newsletters. We spoof $_GET['tab'] | |
| 281 | + // for the duration of get_fields() so the addon's gate passes; the | |
| 282 | + // extensions section is what the view's form group already targets | |
| 283 | + // on the Newsletters sub-tab. The Extensions top-level tab continues | |
| 284 | + // to work as before — this only adds an additional render path. | |
| 285 | + $charitable_bridge_newsletters = ( | |
| 286 | + isset( $_GET['tab'] ) && 'marketing' === $_GET['tab'] // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 287 | + && isset( $_GET['sub_tab'] ) && 'newsletters' === $_GET['sub_tab'] // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 288 | + && class_exists( 'Charitable_Newsletter_Connect' ) | |
| 289 | + ); | |
| 290 | + | |
| 291 | + if ( $charitable_bridge_newsletters ) { | |
| 292 | + $charitable_real_tab = $_GET['tab']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 293 | + $_GET['tab'] = 'extensions'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 294 | + } | |
| 295 | + | |
| 225 | 296 | $fields = $this->get_fields(); |
| 226 | 297 | |
| 298 | + if ( $charitable_bridge_newsletters ) { | |
| 299 | + $_GET['tab'] = $charitable_real_tab; // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 300 | + } | |
| 301 | + | |
| 227 | 302 | if ( empty( $fields ) ) { |
| 228 | 303 | return; |
| 229 | 304 | } |
| 230 | 305 | |
| @@ -891,11 +966,18 @@ | ||
| 891 | 966 | 'donors', |
| 892 | 967 | 'security', |
| 893 | 968 | ); |
| 894 | 969 | |
| 895 | - $tab_value = isset( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : ''; // phpcs:ignore | |
| 970 | + $tab_value = isset( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : ''; // phpcs:ignore | |
| 971 | + $sub_tab_value = isset( $_GET['sub_tab'] ) ? esc_attr( $_GET['sub_tab'] ) : ''; // phpcs:ignore | |
| 896 | 972 | |
| 897 | 973 | if ( in_array( $tab_value, $tab_values_to_check ) ) { // phpcs:ignore |
| 974 | + // UTM medium follows the sub_tab when present (e.g. marketing-conversion-tracking) | |
| 975 | + // so each upgrade button is attributable. | |
| 976 | + $upgrade_medium = ( 'marketing' === $tab_value && ! empty( $sub_tab_value ) ) | |
| 977 | + ? 'marketing-' . str_replace( '_', '-', $sub_tab_value ) | |
| 978 | + : $tab_value; | |
| 979 | + | |
| 898 | 980 | ob_start(); |
| 899 | 981 | ?> |
| 900 | 982 | |
| 901 | 983 | <div class="charitable-education-page"> |
| @@ -901,9 +983,20 @@ | ||
| 901 | 983 | <div class="charitable-education-page"> |
| 902 | 984 | |
| 903 | 985 | <?php |
| 904 | 986 | if ( 'marketing' === $tab_value ) { |
| 905 | - $this->get_settings_cta_education_content_marketing_settings(); | |
| 987 | + // Default to the Newsletters CTA when no sub_tab is supplied | |
| 988 | + // (the marketing_sub_tab_default redirect should normally prevent this, | |
| 989 | + // but render safely if a redirect was skipped — e.g. during POST). | |
| 990 | + $marketing_sub_tab = '' !== $sub_tab_value ? $sub_tab_value : 'newsletters'; | |
| 991 | + | |
| 992 | + if ( 'conversion_tracking' === $marketing_sub_tab ) { | |
| 993 | + $this->get_settings_cta_education_content_conversion_tracking(); | |
| 994 | + } elseif ( 'google_analytics' === $marketing_sub_tab ) { | |
| 995 | + $this->get_settings_cta_education_content_google_analytics(); | |
| 996 | + } else { | |
| 997 | + $this->get_settings_cta_education_content_marketing_settings(); | |
| 998 | + } | |
| 906 | 999 | } elseif ( 'donors' === $tab_value ) { |
| 907 | 1000 | $this->get_settings_cta_education_content_donor_settings(); |
| 908 | 1001 | } elseif ( 'security' === $tab_value && ! charitable_is_pro() ) { |
| 909 | 1002 | $this->get_settings_cta_education_content_advanced_security_settings(); |
| @@ -922,9 +1015,9 @@ | ||
| 922 | 1015 | </p> |
| 923 | 1016 | </div> |
| 924 | 1017 | <?php else : ?> |
| 925 | 1018 | <div class="charitable-education-page-button"> |
| 926 | - <a href="<?php echo esc_url( charitable_utm_link( 'https://wpcharitable.com/lite-upgrade/', $tab_value, __( 'Upgrade to Charitable Pro', 'charitable' ) ) ); ?>" class="button button-primary" target="_blank"><?php esc_html_e( 'Upgrade to Charitable Pro', 'charitable' ); ?></a> | |
| 1019 | + <a href="<?php echo esc_url( charitable_utm_link( 'https://wpcharitable.com/lite-upgrade/', $upgrade_medium, __( 'Upgrade to Charitable Pro', 'charitable' ) ) ); ?>" class="button button-primary" target="_blank"><?php esc_html_e( 'Upgrade to Charitable Pro', 'charitable' ); ?></a> | |
| 927 | 1020 | </div> |
| 928 | 1021 | <?php endif; ?> |
| 929 | 1022 | </div> |
| 930 | 1023 | <?php |
| @@ -1044,8 +1137,130 @@ | ||
| 1044 | 1137 | <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Automatically add donors to your email list', 'charitable' ); ?></li> |
| 1045 | 1138 | <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Organize donors with tags', 'charitable' ); ?></li> |
| 1046 | 1139 | <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Send email series to keep donors engaged', 'charitable' ); ?></li> |
| 1047 | 1140 | <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Enable multiple email services', 'charitable' ); ?></li> |
| 1141 | + </ul> | |
| 1142 | + </div> | |
| 1143 | + <?php | |
| 1144 | + } | |
| 1145 | + | |
| 1146 | + /** | |
| 1147 | + * Get the settings CTA education content for the Marketing → Conversion Tracking sub-tab. | |
| 1148 | + * | |
| 1149 | + * @since 1.8.11.3 | |
| 1150 | + * | |
| 1151 | + * @return void | |
| 1152 | + */ | |
| 1153 | + public function get_settings_cta_education_content_conversion_tracking() { | |
| 1154 | + $assets_url = charitable()->get_path( 'assets', false ); | |
| 1155 | + ?> | |
| 1156 | + | |
| 1157 | + <div class="charitable-education-page-heading"> | |
| 1158 | + <h4><?php esc_html_e( 'Conversion Tracking', 'charitable' ); ?></h4> | |
| 1159 | + <p><?php esc_html_e( 'Send Charitable donation events into Meta Pixel, TikTok Pixel, and Google Tag Manager. Native, code-free conversion tracking that ties every completed donation to the ad campaigns and audiences that drove it.', 'charitable' ); ?></p> | |
| 1160 | + <p><?php esc_html_e( 'See which ads actually produce donations, optimize spend toward real revenue, and build remarketing audiences from your highest-value supporters.', 'charitable' ); ?></p> | |
| 1161 | + </div> | |
| 1162 | + | |
| 1163 | + <div class="charitable-education-page-media"> | |
| 1164 | + <div class="charitable-education-page-video"> | |
| 1165 | + <figure> | |
| 1166 | + <div class="charitable-education-page-video-embed"> | |
| 1167 | + <iframe src="https://www.youtube-nocookie.com/embed/sS-F6x6F-Fs?rel=0&modestbranding=1&iv_load_policy=3&loop=1&playlist=sS-F6x6F-Fs" title="<?php esc_attr_e( 'Introducing Conversion Tracking', 'charitable' ); ?>" allow="accelerometer; autoplay; clipboard-write; encrypted-media; picture-in-picture" allowfullscreen frameborder="0"></iframe> | |
| 1168 | + </div> | |
| 1169 | + <figcaption><a href="https://youtu.be/sS-F6x6F-Fs" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Watch: Introducing Conversion Tracking', 'charitable' ); ?></a></figcaption> | |
| 1170 | + </figure> | |
| 1171 | + </div> | |
| 1172 | + <div class="charitable-education-page-images"> | |
| 1173 | + <figure> | |
| 1174 | + <div class="charitable-education-page-images-image"> | |
| 1175 | + <img src="<?php echo esc_url( $assets_url ); ?>images/education/conversion-tracking/education-1.png" alt="<?php esc_attr_e( 'Conversion tracking settings', 'charitable' ); ?>"> | |
| 1176 | + <a href="<?php echo esc_url( $assets_url ); ?>images/education/conversion-tracking/education-1.png" class="hover" data-lity="" data-lity-desc="<?php esc_attr_e( 'Pixel + GTM settings', 'charitable' ); ?>"></a> | |
| 1177 | + </div> | |
| 1178 | + <figcaption><?php esc_html_e( 'Pixel + GTM settings', 'charitable' ); ?></figcaption> | |
| 1179 | + </figure> | |
| 1180 | + <figure> | |
| 1181 | + <div class="charitable-education-page-images-image"> | |
| 1182 | + <img src="<?php echo esc_url( $assets_url ); ?>images/education/conversion-tracking/education-2.png" alt="<?php esc_attr_e( 'Per-donation tracking status', 'charitable' ); ?>"> | |
| 1183 | + <a href="<?php echo esc_url( $assets_url ); ?>images/education/conversion-tracking/education-2.png" class="hover" data-lity="" data-lity-desc="<?php esc_attr_e( 'Per-donation tracking status', 'charitable' ); ?>"></a> | |
| 1184 | + </div> | |
| 1185 | + <figcaption><?php esc_html_e( 'Per-donation tracking status', 'charitable' ); ?></figcaption> | |
| 1186 | + </figure> | |
| 1187 | + <figure> | |
| 1188 | + <div class="charitable-education-page-images-image"> | |
| 1189 | + <img src="<?php echo esc_url( $assets_url ); ?>images/education/conversion-tracking/education-3.png" alt="<?php esc_attr_e( 'WP Consent API compliant', 'charitable' ); ?>"> | |
| 1190 | + <a href="<?php echo esc_url( $assets_url ); ?>images/education/conversion-tracking/education-3.png" class="hover" data-lity="" data-lity-desc="<?php esc_attr_e( 'WP Consent API compliant', 'charitable' ); ?>"></a> | |
| 1191 | + </div> | |
| 1192 | + <figcaption><?php esc_html_e( 'WP Consent API compliant', 'charitable' ); ?></figcaption> | |
| 1193 | + </figure> | |
| 1194 | + </div> | |
| 1195 | + </div> | |
| 1196 | + | |
| 1197 | + <div class="charitable-education-page-caps"> | |
| 1198 | + <p><?php esc_html_e( 'Track conversions with…', 'charitable' ); ?></p> | |
| 1199 | + <ul> | |
| 1200 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Meta Pixel (Facebook / Instagram)', 'charitable' ); ?></li> | |
| 1201 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'TikTok Pixel', 'charitable' ); ?></li> | |
| 1202 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Google Tag Manager (GTM)', 'charitable' ); ?></li> | |
| 1203 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Campaign page view tracking', 'charitable' ); ?></li> | |
| 1204 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Donation form open tracking', 'charitable' ); ?></li> | |
| 1205 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'WP Consent API (GDPR) integration', 'charitable' ); ?></li> | |
| 1206 | + </ul> | |
| 1207 | + </div> | |
| 1208 | + <?php | |
| 1209 | + } | |
| 1210 | + | |
| 1211 | + /** | |
| 1212 | + * Get the settings CTA education content for the Marketing → Google Analytics sub-tab. | |
| 1213 | + * | |
| 1214 | + * @since 1.8.11.3 | |
| 1215 | + * | |
| 1216 | + * @return void | |
| 1217 | + */ | |
| 1218 | + public function get_settings_cta_education_content_google_analytics() { | |
| 1219 | + $assets_url = charitable()->get_path( 'assets', false ); | |
| 1220 | + ?> | |
| 1221 | + | |
| 1222 | + <div class="charitable-education-page-heading"> | |
| 1223 | + <h4><?php esc_html_e( 'Google Analytics', 'charitable' ); ?></h4> | |
| 1224 | + <p><?php esc_html_e( 'Send Charitable donation events into Google Analytics 4. Native GA4 integration fires purchase, refund, sign-up, and login events both browser-side via gtag.js and server-side via the Measurement Protocol — so every donation, including off-site gateways and webhook-confirmed completions, makes it into GA4.', 'charitable' ); ?></p> | |
| 1225 | + <p><?php esc_html_e( 'See which campaigns and sources actually produce donations, stitch sessions across devices with hashed-email user_id, and stay EEA-compliant out of the box via Google Consent Mode v2 and the WP Consent API.', 'charitable' ); ?></p> | |
| 1226 | + </div> | |
| 1227 | + | |
| 1228 | + <div class="charitable-education-page-media"> | |
| 1229 | + <div class="charitable-education-page-images"> | |
| 1230 | + <figure> | |
| 1231 | + <div class="charitable-education-page-images-image"> | |
| 1232 | + <img src="<?php echo esc_url( $assets_url ); ?>images/education/google-analytics/education-1.png" alt="<?php esc_attr_e( 'Google Analytics settings', 'charitable' ); ?>"> | |
| 1233 | + <a href="<?php echo esc_url( $assets_url ); ?>images/education/google-analytics/education-1.png" class="hover" data-lity="" data-lity-desc="<?php esc_attr_e( 'GA4 settings + Test Connection', 'charitable' ); ?>"></a> | |
| 1234 | + </div> | |
| 1235 | + <figcaption><?php esc_html_e( 'GA4 settings + Test Connection', 'charitable' ); ?></figcaption> | |
| 1236 | + </figure> | |
| 1237 | + <figure> | |
| 1238 | + <div class="charitable-education-page-images-image"> | |
| 1239 | + <img src="<?php echo esc_url( $assets_url ); ?>images/education/google-analytics/education-2.png" alt="<?php esc_attr_e( 'Per-donation GA metabox', 'charitable' ); ?>"> | |
| 1240 | + <a href="<?php echo esc_url( $assets_url ); ?>images/education/google-analytics/education-2.png" class="hover" data-lity="" data-lity-desc="<?php esc_attr_e( 'Per-donation tracking metabox', 'charitable' ); ?>"></a> | |
| 1241 | + </div> | |
| 1242 | + <figcaption><?php esc_html_e( 'Per-donation tracking metabox', 'charitable' ); ?></figcaption> | |
| 1243 | + </figure> | |
| 1244 | + <figure> | |
| 1245 | + <div class="charitable-education-page-images-image"> | |
| 1246 | + <img src="<?php echo esc_url( $assets_url ); ?>images/education/google-analytics/education-3.png" alt="<?php esc_attr_e( 'Test connection success', 'charitable' ); ?>"> | |
| 1247 | + <a href="<?php echo esc_url( $assets_url ); ?>images/education/google-analytics/education-3.png" class="hover" data-lity="" data-lity-desc="<?php esc_attr_e( 'Validate your GA4 setup', 'charitable' ); ?>"></a> | |
| 1248 | + </div> | |
| 1249 | + <figcaption><?php esc_html_e( 'Validate your GA4 setup', 'charitable' ); ?></figcaption> | |
| 1250 | + </figure> | |
| 1251 | + </div> | |
| 1252 | + </div> | |
| 1253 | + | |
| 1254 | + <div class="charitable-education-page-caps"> | |
| 1255 | + <p><?php esc_html_e( 'Track donations in GA4 with…', 'charitable' ); ?></p> | |
| 1256 | + <ul> | |
| 1257 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'GA4 purchase events (browser + Measurement Protocol)', 'charitable' ); ?></li> | |
| 1258 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Server-side refund, sign_up, and login events', 'charitable' ); ?></li> | |
| 1259 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Full UTM capture (including utm_term and utm_id)', 'charitable' ); ?></li> | |
| 1260 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Hashed-email user_id for cross-device session stitching', 'charitable' ); ?></li> | |
| 1261 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( 'Google Consent Mode v2 + WP Consent API integration', 'charitable' ); ?></li> | |
| 1262 | + <li><i class="fa fa-solid fa-check"></i> <?php esc_html_e( '"Test Connection" button to validate your GA4 setup', 'charitable' ); ?></li> | |
| 1048 | 1263 | </ul> |
| 1049 | 1264 | </div> |
| 1050 | 1265 | <?php |
| 1051 | 1266 | } |