' . sprintf( /* translators: %d - Number of completed scans. */ esc_html__( 'Nice work — %d scans completed!', 'defender-security' ), self::NUMBER_COMPLETED_SCANS ); $text .= '
'; $text .= esc_html__( 'Your site’s files have been thoroughly scanned for file modifications and outdated plugins. Defender’s here to keep your site safe — could you share your experience with others on WordPress.org?', 'defender-security' ); $text .= '
'; break; case 'fixed_scans': $text = '' . sprintf( /* translators: %d - Number of fixed scans. */ esc_html__( 'You`ve successfully resolved %d malware scan issues! We are happy to be a part of helping you secure your site, and we would appreciate it if you dropped us a rating on wp.org to help us spread the word and boost our motivation.', 'defender-security' ), self::NUMBER_FIXED_SCANS ); $text .= '
'; break; case 'resolved_tweaks': $tweak_arr = wd_di()->get( Security_Tweaks::class )->get_tweak_types(); $total_tweaks = $tweak_arr['count_fixed'] + $tweak_arr['count_ignored'] + $tweak_arr['count_issues']; $text = '' . sprintf( /* translators: %d - Total number. */ esc_html__( 'You`ve resolved all %d security recommendations - that`s impressive! We are happy to be a part of helping you secure your site, and we would appreciate it if you dropped us a rating on wp.org to help us spread the word and boost our motivation.', 'defender-security' ), $total_tweaks ); $text .= '
'; break; case 'ua_lockouts': $text = '' . sprintf( /* translators: %d - Number of UA lockouts. */ esc_html__( 'Defender has blocked %d malicious bots!', 'defender-security' ), self::NUMBER_UA_LOCKOUTS ); $text .= '
'; $text .= sprintf( /* translators: %d - Number of UA lockouts. */ esc_html__( 'That’s %1$d fake crawlers and bad bots stopped from accessing your site. Defender’s User Agent lockouts keep unwanted traffic away so your site stays safe. If Defender’s helped protect your site, please share your experience with a review on WordPress.org.', 'defender-security' ), self::NUMBER_UA_LOCKOUTS ); $text .= '
'; break; case 'ip_lockouts': $text = '' . sprintf( /* translators: %d - Number of IP lockouts. */ esc_html__( 'Defender has blocked %d suspicious IPs!', 'defender-security' ), self::NUMBER_IP_LOCKOUTS ); $text .= '
'; $text .= sprintf( /* translators: %d - Number of IP lockouts. */ esc_html__( 'That’s %1$d potential threats stopped before they could harm your site. Defender’s Firewall is keeping the bad guys and bots out so you can stay focused on running your site. If you’ve found Defender helpful, please share your experience with a review on WordPress.org.', 'defender-security' ), self::NUMBER_IP_LOCKOUTS ); $text .= '
'; break; case '7_days_installed': $text = '' . esc_html__( 'Enjoying Defender? We’d love to hear your feedback!', 'defender-security' ); $text .= '
'; $text .= esc_html__( 'You’ve been using Defender for over a week now, and we’d love to hear about your experience! We’ve spent countless hours developing it for you, and your feedback is important to us. We’d really appreciate your rating.', 'defender-security' ); $text .= '
'; break; } return $text; } /** * Get label by given slug. No need to translate a returned text. * * @param string $notice_slug Notice slug. * * @return string */ public static function get_label_by_slug( string $notice_slug ): string { switch ( $notice_slug ) { case 'completed_scans': $text = '3 Malware Scan Completed'; break; case 'fixed_scans': $text = '5 Malware Issues Fixed'; break; case 'resolved_tweaks': $text = 'Recommendation Resolved'; break; case 'ua_lockouts': $text = '25 User Agent Lockout'; break; case 'ip_lockouts': $text = '25 IP Lockout'; break; case '7_days_installed': $text = '7 Days installed'; break; default: $text = ''; break; } return $text; } /** * Get label of the current page. * * @return string */ public static function get_current_page_label(): string { switch ( defender_get_current_page() ) { case 'wp-defender': $text = 'Dashboard'; break; case 'wdf-hardener': $text = 'Recommendations'; break; case 'wdf-scan': $text = 'Malware Scan'; break; case 'wdf-logging': $text = 'Audit Log'; break; case 'wdf-ip-lockout': $text = 'Firewall'; break; case 'wdf-2fa': $text = '2FA'; break; case 'wdf-advanced-tools': $text = 'Tools'; break; case 'wdf-notification': $text = 'Notifications'; break; case 'wdf-setting': $text = 'Settings'; break; default: $text = ''; break; } return $text; } /** * Reset counter of all prompts. */ public static function reset_counters(): void { update_site_option( self::SLUG_COMPLETED_SCANS, 0 ); update_site_option( self::SLUG_FIXED_SCAN_ISSUES, 0 ); update_site_option( self::SLUG_UA_LOCKOUTS, 0 ); update_site_option( self::SLUG_IP_LOCKOUTS, 0 ); } /** * Is the rating notice displayed? The priority list of prompts: * 1) completed malware scans, * 2) fixed scans, * 3) resolved tweaks, * 4) UA lockouts, * 5) IP lockouts, * 6) default one after 7 days installed. * Note: items #1-5 are without waiting for 7 days. * No uses in v6.0 but it'll will be implemented in the future. * * @return array */ public static function is_achievement_displayed(): array { $res = array( 'is_displayed' => true, 'slug' => '', ); if ( self::was_rate_request() ) { $res['is_displayed'] = false; return $res; } if ( ! self::is_required_page() ) { $res['is_displayed'] = false; return $res; } // No needed to translate slugs. if ( self::get_count_scans( self::SLUG_COMPLETED_SCANS ) >= self::NUMBER_COMPLETED_SCANS ) { $res['slug'] = 'completed_scans'; } elseif ( self::get_count_scans( self::SLUG_FIXED_SCAN_ISSUES ) >= self::NUMBER_FIXED_SCANS ) { $res['slug'] = 'fixed_scans'; } else { $tweak_arr = wd_di()->get( Security_Tweaks::class )->get_tweak_types(); $total_tweaks = $tweak_arr['count_fixed'] + $tweak_arr['count_ignored'] + $tweak_arr['count_issues']; if ( $tweak_arr['count_fixed'] === $total_tweaks && $total_tweaks > 0 ) { $res['slug'] = 'resolved_tweaks'; } elseif ( self::get_count_scans( self::SLUG_UA_LOCKOUTS ) >= self::NUMBER_UA_LOCKOUTS ) { $res['slug'] = 'ua_lockouts'; } elseif ( self::get_count_scans( self::SLUG_IP_LOCKOUTS ) >= self::NUMBER_IP_LOCKOUTS ) { $res['slug'] = 'ip_lockouts'; } elseif ( self::was_postponed_request() ) { $res['is_displayed'] = false; return $res; } } // If the conditions are met, display the notice about plugin achievements. if ( $res['is_displayed'] && '' !== $res['slug'] ) { return $res; } // If no, display the default one. $res['slug'] = '7_days_installed'; return $res; } /** * Display the rating notice on the Issues page if all malware scans are resolved. * * @param int $count_scan_issues Count of Scan issues. * * @return bool * @since 6.0 */ public static function is_displayed_in_redesigned_version( int $count_scan_issues ): bool { if ( self::was_rate_request() ) { return false; } // Check by required page. if ( 'wdf-scan' !== defender_get_current_page() ) { return false; } if ( self::was_postponed_request() ) { return false; } return 0 === $count_scan_issues; } /** * Have there already been clicks on the Rate or Dismiss buttons? * * @return bool */ private static function was_rate_request(): bool { $display_rating = apply_filters( 'wd_display_rating', false ); $display_rating = is_bool( $display_rating ) ? $display_rating : (bool) $display_rating; // Avoid case with '1'. if ( true === (bool) get_site_option( self::SLUG_FOR_BUTTON_RATE, $display_rating ) ) { return true; } $dismiss_rating = apply_filters( 'wd_dismiss_rating', false ); $dismiss_rating = is_bool( $dismiss_rating ) ? $dismiss_rating : (bool) $dismiss_rating; // Avoid case with '1'. if ( true === (bool) get_site_option( self::SLUG_FOR_BUTTON_THANKS, $dismiss_rating ) ) { return true; } return false; } /** * Have there already been click to postpone the notice? * * @return bool */ private static function was_postponed_request(): bool { $postponed_date = (int) get_site_option( self::SLUG_POSTPONED_NOTICE_DATE, 0 ); return time() <= strtotime( '+7 days', $postponed_date ); } /** * Is this required page? Excluded pages: WAF, Free Plugins, Onboard. * * @return bool */ protected static function is_required_page(): bool { $arr = array( 'wdf-hardener', 'wdf-scan', 'wdf-logging', 'wdf-ip-lockout', 'wdf-2fa', 'wdf-advanced-tools', 'wdf-notification', 'wdf-setting', // Dashboard and Setup Wizard have the same page slug. 'wp-defender', ); return in_array( defender_get_current_page(), $arr, true ); } }