| @@ -2143,8 +2143,29 @@ | ||
| 2143 | 2143 | return defined( 'SRFM_PRO_VER' ); |
| 2144 | 2144 | } |
| 2145 | 2145 | |
| 2146 | 2146 | /** |
| 2147 | + * Whether SureForms promotional content should be hidden. | |
| 2148 | + * | |
| 2149 | + * Covers review requests, cross-sell banners and announcements. The free | |
| 2150 | + * plugin never hides them on its own; SureForms Pro's Distraction Free mode | |
| 2151 | + * turns this on through the filter. | |
| 2152 | + * | |
| 2153 | + * @since 2.12.8 | |
| 2154 | + * @return bool | |
| 2155 | + */ | |
| 2156 | + public static function hide_promotions() { | |
| 2157 | + /** | |
| 2158 | + * Filter whether SureForms hides its promotional content in wp-admin. | |
| 2159 | + * | |
| 2160 | + * @since 2.12.8 | |
| 2161 | + * | |
| 2162 | + * @param bool $hide Default false. | |
| 2163 | + */ | |
| 2164 | + return (bool) apply_filters( 'srfm_hide_promotions', false ); | |
| 2165 | + } | |
| 2166 | + | |
| 2167 | + /** | |
| 2147 | 2168 | * Verifies the request by checking the nonce and user capabilities. |
| 2148 | 2169 | * |
| 2149 | 2170 | * @param string $request_type The type of request, either 'rest' or 'ajax'. |
| 2150 | 2171 | * @param string $nonce_action The action name for the nonce. |
| @@ -2217,53 +2238,51 @@ | ||
| 2217 | 2238 | * aggressively cached or JS-combining setup can serve a stale token or reorder |
| 2218 | 2239 | * the scripts a form depends on. This is what surfaces that to the site owner |
| 2219 | 2240 | * before it turns into "my form stopped working". |
| 2220 | 2241 | * |
| 2221 | - * Detection is by plugin path, mirroring is_any_smtp_plugin_active(), including | |
| 2222 | - * the multisite network-active merge. | |
| 2223 | - * | |
| 2224 | 2242 | * @since 2.12.6 |
| 2225 | 2243 | * @return string Human-readable plugin name, or '' when none is active. |
| 2226 | 2244 | */ |
| 2227 | 2245 | public static function get_active_caching_plugin() { |
| 2228 | - $caching_plugins = [ | |
| 2229 | - 'litespeed-cache/litespeed-cache.php' => 'LiteSpeed Cache', | |
| 2230 | - 'wp-rocket/wp-rocket.php' => 'WP Rocket', | |
| 2231 | - 'w3-total-cache/w3-total-cache.php' => 'W3 Total Cache', | |
| 2232 | - 'wp-super-cache/wp-cache.php' => 'WP Super Cache', | |
| 2233 | - 'wp-fastest-cache/wpFastestCache.php' => 'WP Fastest Cache', | |
| 2234 | - 'autoptimize/autoptimize.php' => 'Autoptimize', | |
| 2235 | - 'sg-cachepress/sg-cachepress.php' => 'SiteGround Optimizer', | |
| 2236 | - 'wp-optimize/wp-optimize.php' => 'WP-Optimize', | |
| 2237 | - 'cache-enabler/cache-enabler.php' => 'Cache Enabler', | |
| 2238 | - 'comet-cache/comet-cache.php' => 'Comet Cache', | |
| 2239 | - 'hummingbird-performance/wp-hummingbird.php' => 'Hummingbird', | |
| 2240 | - 'breeze/breeze.php' => 'Breeze', | |
| 2241 | - 'nitropack/main.php' => 'NitroPack', | |
| 2242 | - 'swift-performance-lite/performance.php' => 'Swift Performance Lite', | |
| 2243 | - 'wp-cloudflare-page-cache/wp-cloudflare-page-cache.php' => 'Super Page Cache', | |
| 2244 | - 'flying-press/flying-press.php' => 'FlyingPress', | |
| 2245 | - 'redis-cache/redis-cache.php' => 'Redis Object Cache', | |
| 2246 | - 'powered-cache/powered-cache.php' => 'Powered Cache', | |
| 2247 | - 'docket-cache/docket-cache.php' => 'Docket Cache', | |
| 2248 | - 'seraphinite-accelerator/plugin_root.php' => 'Seraphinite Accelerator', | |
| 2249 | - ]; | |
| 2246 | + $entry = self::get_active_caching_plugin_entry(); | |
| 2250 | 2247 | |
| 2251 | - $active_plugins = (array) get_option( 'active_plugins', [] ); | |
| 2248 | + return null === $entry ? '' : $entry[0]; | |
| 2249 | + } | |
| 2252 | 2250 | |
| 2253 | - // For multisite, merge sitewide active plugins. | |
| 2254 | - if ( is_multisite() ) { | |
| 2255 | - $network_plugins = (array) get_site_option( 'active_sitewide_plugins', [] ); | |
| 2256 | - $active_plugins = array_merge( $active_plugins, array_keys( $network_plugins ) ); | |
| 2257 | - } | |
| 2251 | + /** | |
| 2252 | + * Setup guide for the active caching plugin. | |
| 2253 | + * | |
| 2254 | + * Six of the recognised plugins have a guide of their own; the rest, and any | |
| 2255 | + * site with none detected, get the general one. Sending someone to a page that | |
| 2256 | + * names the plugin they actually run is the difference between advice they can | |
| 2257 | + * follow and advice they have to translate. | |
| 2258 | + * | |
| 2259 | + * Falls back to the general guide rather than returning nothing, so the notice | |
| 2260 | + * always has somewhere to send them. | |
| 2261 | + * | |
| 2262 | + * @since 2.12.7 | |
| 2263 | + * @param string $medium Placement the link is rendered in, used as utm_medium. | |
| 2264 | + * Two surfaces show this guide -- the dashboard notice and | |
| 2265 | + * the onboarding step -- and a shared value would make the | |
| 2266 | + * two indistinguishable in reporting, which is the whole | |
| 2267 | + * point of the attribution. | |
| 2268 | + * @return string Absolute documentation URL. | |
| 2269 | + */ | |
| 2270 | + public static function get_caching_plugin_doc_url( $medium = 'form_checks_notice' ) { | |
| 2271 | + $entry = self::get_active_caching_plugin_entry(); | |
| 2272 | + $slug = null === $entry || '' === $entry[1] ? 'how-to-set-up-sureforms-with-caching-plugins' : $entry[1]; | |
| 2258 | 2273 | |
| 2259 | - foreach ( $caching_plugins as $path => $name ) { | |
| 2260 | - if ( in_array( $path, $active_plugins, true ) ) { | |
| 2261 | - return $name; | |
| 2262 | - } | |
| 2263 | - } | |
| 2264 | - | |
| 2265 | - return ''; | |
| 2274 | + // Through the central builder rather than hardcoding the domain, so the | |
| 2275 | + // link carries the same UTM attribution as every other doc link and a | |
| 2276 | + // domain change is one edit. utm_content is the slug, so the caller can be | |
| 2277 | + // told which guide people actually open. | |
| 2278 | + return self::get_sureforms_website_url( | |
| 2279 | + 'docs/' . $slug . '/', | |
| 2280 | + [ | |
| 2281 | + 'utm_medium' => self::get_string_value( $medium ), | |
| 2282 | + 'utm_content' => $slug, | |
| 2283 | + ] | |
| 2284 | + ); | |
| 2266 | 2285 | } |
| 2267 | 2286 | |
| 2268 | 2287 | /** |
| 2269 | 2288 | * Check if any of the top 10 popular WordPress SMTP plugins is active using array_intersect. |
| @@ -2793,7 +2812,80 @@ | ||
| 2793 | 2812 | * @return int |
| 2794 | 2813 | */ |
| 2795 | 2814 | private static function get_geo_failure_ttl() { |
| 2796 | 2815 | return self::get_integer_value( apply_filters( 'srfm_geo_failure_ttl', 5 * MINUTE_IN_SECONDS ) ); |
| 2816 | + } | |
| 2817 | + | |
| 2818 | + /** | |
| 2819 | + * Caching plugins SureForms recognises, and the guide for each. | |
| 2820 | + * | |
| 2821 | + * `path => [ display name, doc slug ]`. An empty slug means there is no | |
| 2822 | + * plugin-specific guide and the general one applies. Name and slug live in one | |
| 2823 | + * array on purpose: keyed separately they drift, and a doc link that silently | |
| 2824 | + * degrades to the generic page is the kind of regression nobody reports. | |
| 2825 | + * | |
| 2826 | + * Order is precedence: the first active plugin in this list wins. The six with | |
| 2827 | + * their own guide are listed first on purpose, so a site running two caching | |
| 2828 | + * plugins is pointed at the specific guide rather than whichever plugin the | |
| 2829 | + * old alphabetical order happened to reach first. That flips the winner on a | |
| 2830 | + * few pairs -- WP Fastest Cache over WP Super Cache, SiteGround Optimizer and | |
| 2831 | + * Autoptimize over their partners -- and in each case the new winner is the | |
| 2832 | + * one that has something to say. Reordering this array changes which guide a | |
| 2833 | + * two-plugin site sees. | |
| 2834 | + * | |
| 2835 | + * @since 2.12.7 | |
| 2836 | + * @return array<string,array{0:string,1:string}> | |
| 2837 | + */ | |
| 2838 | + private static function get_known_caching_plugins() { | |
| 2839 | + return [ | |
| 2840 | + 'litespeed-cache/litespeed-cache.php' => [ 'LiteSpeed Cache', 'how-to-set-up-sureforms-with-litespeed-cache' ], | |
| 2841 | + 'wp-rocket/wp-rocket.php' => [ 'WP Rocket', 'how-to-set-up-sureforms-with-wp-rocket' ], | |
| 2842 | + 'w3-total-cache/w3-total-cache.php' => [ 'W3 Total Cache', 'how-to-set-up-sureforms-with-w3-total-cache' ], | |
| 2843 | + 'wp-fastest-cache/wpFastestCache.php' => [ 'WP Fastest Cache', 'how-to-set-up-sureforms-with-wp-fastest-cache' ], | |
| 2844 | + 'sg-cachepress/sg-cachepress.php' => [ 'SiteGround Optimizer', 'how-to-set-up-sureforms-with-siteground-optimizer' ], | |
| 2845 | + 'autoptimize/autoptimize.php' => [ 'Autoptimize', 'how-to-set-up-sureforms-with-autoptimize' ], | |
| 2846 | + 'wp-super-cache/wp-cache.php' => [ 'WP Super Cache', '' ], | |
| 2847 | + 'wp-optimize/wp-optimize.php' => [ 'WP-Optimize', '' ], | |
| 2848 | + 'cache-enabler/cache-enabler.php' => [ 'Cache Enabler', '' ], | |
| 2849 | + 'comet-cache/comet-cache.php' => [ 'Comet Cache', '' ], | |
| 2850 | + 'hummingbird-performance/wp-hummingbird.php' => [ 'Hummingbird', '' ], | |
| 2851 | + 'breeze/breeze.php' => [ 'Breeze', '' ], | |
| 2852 | + 'nitropack/main.php' => [ 'NitroPack', '' ], | |
| 2853 | + 'swift-performance-lite/performance.php' => [ 'Swift Performance Lite', '' ], | |
| 2854 | + 'wp-cloudflare-page-cache/wp-cloudflare-page-cache.php' => [ 'Super Page Cache', '' ], | |
| 2855 | + 'flying-press/flying-press.php' => [ 'FlyingPress', '' ], | |
| 2856 | + 'redis-cache/redis-cache.php' => [ 'Redis Object Cache', '' ], | |
| 2857 | + 'powered-cache/powered-cache.php' => [ 'Powered Cache', '' ], | |
| 2858 | + 'docket-cache/docket-cache.php' => [ 'Docket Cache', '' ], | |
| 2859 | + 'seraphinite-accelerator/plugin_root.php' => [ 'Seraphinite Accelerator', '' ], | |
| 2860 | + ]; | |
| 2861 | + } | |
| 2862 | + | |
| 2863 | + /** | |
| 2864 | + * The active caching plugin's entry, if there is one. | |
| 2865 | + * | |
| 2866 | + * Detection is by plugin path, mirroring is_any_smtp_plugin_active(), including | |
| 2867 | + * the multisite network-active merge. First match in | |
| 2868 | + * get_known_caching_plugins() wins; that array's order is the precedence. | |
| 2869 | + * | |
| 2870 | + * @since 2.12.7 | |
| 2871 | + * @return array{0:string,1:string}|null Name and doc slug, or null when none is active. | |
| 2872 | + */ | |
| 2873 | + private static function get_active_caching_plugin_entry() { | |
| 2874 | + $active_plugins = (array) get_option( 'active_plugins', [] ); | |
| 2875 | + | |
| 2876 | + // For multisite, merge sitewide active plugins. | |
| 2877 | + if ( is_multisite() ) { | |
| 2878 | + $network_plugins = (array) get_site_option( 'active_sitewide_plugins', [] ); | |
| 2879 | + $active_plugins = array_merge( $active_plugins, array_keys( $network_plugins ) ); | |
| 2880 | + } | |
| 2881 | + | |
| 2882 | + foreach ( self::get_known_caching_plugins() as $path => $entry ) { | |
| 2883 | + if ( in_array( $path, $active_plugins, true ) ) { | |
| 2884 | + return $entry; | |
| 2885 | + } | |
| 2886 | + } | |
| 2887 | + | |
| 2888 | + return null; | |
| 2797 | 2889 | } |
| 2798 | 2890 | |
| 2799 | 2891 | } |