| @@ -51,9 +51,28 @@ | ||
| 51 | 51 | */ |
| 52 | 52 | public function add_global_styles() { |
| 53 | 53 | echo '<style> |
| 54 | 54 | #toplevel_page_wp-defender ul.wp-submenu li a[href="admin.php?page=wdf-ip-lockout"] { display: flex; justify-content: space-between; align-items: center; } |
| 55 | + #adminmenu li.wp-has-current-submenu a.wp-has-current-submenu { background-color: #4763E4 !important; } | |
| 56 | + #adminmenu .toplevel_page_wp-defender div.wp-menu-image.svg { width: 16px; height: 16px; margin-top: 10px; margin-left: 10px; background-size: 16px auto; } | |
| 55 | 57 | </style>'; |
| 58 | + if ( ! $this->is_wp_org_version ) { | |
| 59 | + echo '<style> | |
| 60 | + #adminmenu .defender-admin-menu-pro-tag { | |
| 61 | + display: inline-block; | |
| 62 | + padding: 0; | |
| 63 | + color: inherit; | |
| 64 | + border: 1px solid currentColor; | |
| 65 | + border-radius: 9px; | |
| 66 | + line-height: 16px; | |
| 67 | + font-size: 11px; | |
| 68 | + height: 16px; | |
| 69 | + width: 28px; | |
| 70 | + text-align: center; | |
| 71 | + margin-left: 5px; | |
| 72 | + } | |
| 73 | + </style>'; | |
| 74 | + } | |
| 56 | 75 | } |
| 57 | 76 | |
| 58 | 77 | /** |
| 59 | 78 | * Init admin actions. |
| @@ -77,15 +96,25 @@ | ||
| 77 | 96 | ); |
| 78 | 97 | // For submenu callout. |
| 79 | 98 | add_action( 'admin_head', array( $this, 'retarget_submenu_callout' ) ); |
| 80 | 99 | if ( ! wd_di()->get( WPMUDEV::class )->is_wpmu_hosting() ) { |
| 100 | + $upsell_menu_title = sprintf( | |
| 101 | + '<span class="defender-upsell-label">%1$s<span class="defender-upsell-pro-tag">%2$s</span></span><svg class="defender-upsell-arrow" width="9" height="9" viewBox="0 0 9 9" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0.225625 8.7625C0.0881251 8.62917 0.013125 8.47083 0.000624999 8.2875C-0.00770833 8.10417 0.0672918 7.93125 0.225625 7.76875L5.86313 2.125L7.16313 0.93125C7.31313 0.789584 7.47146 0.722917 7.63812 0.73125C7.80479 0.739583 7.94854 0.804167 8.06938 0.925C8.19021 1.04583 8.25062 1.18958 8.25062 1.35625C8.25479 1.52292 8.18812 1.67708 8.05062 1.81875L6.85063 3.11875L1.21313 8.75C1.05896 8.90417 0.890209 8.97917 0.706875 8.975C0.527709 8.975 0.367292 8.90417 0.225625 8.7625ZM7.61938 4.4625L7.76312 1.24375L4.43188 1.3625H2.30687C2.11521 1.3625 1.94854 1.29792 1.80688 1.16875C1.66521 1.03542 1.59438 0.875 1.59438 0.6875C1.59438 0.5 1.66104 0.339584 1.79438 0.20625C1.93188 0.0687502 2.10688 0 2.31938 0H8.25688C8.48188 0 8.66104 0.0687502 8.79437 0.20625C8.92771 0.34375 8.99438 0.520834 8.99438 0.7375V6.66875C8.99438 6.87292 8.92563 7.04583 8.78813 7.1875C8.65063 7.325 8.48812 7.39375 8.30062 7.39375C8.10896 7.39375 7.94646 7.325 7.81313 7.1875C7.68396 7.04583 7.61938 6.87708 7.61938 6.68125V4.4625Z" fill="white"/></svg>', | |
| 102 | + esc_html__( 'Upgrade', 'defender-security' ), | |
| 103 | + esc_html__( 'Pro', 'defender-security' ) | |
| 104 | + ); | |
| 81 | 105 | add_submenu_page( |
| 82 | 106 | 'wp-defender', |
| 83 | - esc_html__( 'Get Defender Pro', 'defender-security' ), | |
| 84 | - esc_html__( 'Get Defender Pro', 'defender-security' ), | |
| 107 | + esc_html__( 'Upgrade to Pro', 'defender-security' ), | |
| 108 | + $upsell_menu_title, | |
| 85 | 109 | is_multisite() ? 'manage_network_options' : 'manage_options', |
| 86 | - $this->get_link( 'upsell', 'defender_submenu_upsell' ) | |
| 110 | + $this->get_link( 'upsell', 'defender_new-submenu_upsell' ) | |
| 87 | 111 | ); |
| 112 | + global $submenu; | |
| 113 | + if ( isset( $submenu['wp-defender'] ) && is_array( $submenu['wp-defender'] ) && array() !== $submenu['wp-defender'] ) { | |
| 114 | + $last = array_key_last( $submenu['wp-defender'] ); | |
| 115 | + $submenu['wp-defender'][ $last ][4] = 'defender-menu-upsell'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited | |
| 116 | + } | |
| 88 | 117 | } |
| 89 | 118 | } |
| 90 | 119 | |
| 91 | 120 | // Display IP detection notice. |
| @@ -144,14 +173,8 @@ | ||
| 144 | 173 | return $plugin_label . ' - '; |
| 145 | 174 | } |
| 146 | 175 | |
| 147 | 176 | /** |
| 148 | - * The method is a stub without content. | |
| 149 | - */ | |
| 150 | - private function menu_nope(): void { | |
| 151 | - } | |
| 152 | - | |
| 153 | - /** | |
| 154 | 177 | * Generates the submenu callout for the WP Defender plugin. |
| 155 | 178 | * |
| 156 | 179 | * @return void |
| 157 | 180 | */ |
| @@ -157,27 +180,62 @@ | ||
| 157 | 180 | */ |
| 158 | 181 | public function retarget_submenu_callout(): void { |
| 159 | 182 | ?> |
| 160 | 183 | <style> |
| 161 | - #toplevel_page_wp-defender > ul > li:last-child > a[href^="https://wpmudev.com/"], | |
| 162 | - #toplevel_page_wp-defender > ul > li:last-child > a[href^="https://wpmudev.com/"]:hover, | |
| 163 | - #toplevel_page_wp-defender > ul > li:last-child > a[href^="https://wpmudev.com/"]:active, | |
| 164 | - #toplevel_page_wp-defender > ul > li:last-child > a[href^="https://wpmudev.com/"]:focus { | |
| 165 | - background: #8D00B1; | |
| 184 | + #adminmenu .wp-submenu li.defender-menu-upsell > a, | |
| 185 | + #adminmenu .wp-submenu li.defender-menu-upsell > a:hover, | |
| 186 | + #adminmenu .wp-submenu li.defender-menu-upsell > a:active, | |
| 187 | + #adminmenu .wp-submenu li.defender-menu-upsell > a:focus { | |
| 188 | + display: flex; | |
| 189 | + align-items: center; | |
| 190 | + justify-content: space-between; | |
| 191 | + height: 32px; | |
| 192 | + padding: 7px 12px; | |
| 193 | + box-sizing: border-box; | |
| 194 | + background: #571EE7; | |
| 166 | 195 | color: #ffffff; |
| 167 | - font-weight: 500; | |
| 196 | + font-size: 14px; | |
| 197 | + font-weight: 400; | |
| 198 | + line-height: 18px; | |
| 168 | 199 | } |
| 169 | 200 | |
| 170 | - #toplevel_page_wp-defender.wp-not-current-submenu > ul > li:last-child > a[href^="https://wpmudev.com/"], | |
| 171 | - #toplevel_page_wp-defender.wp-not-current-submenu > ul > li:last-child > a[href^="https://wpmudev.com/"]:hover, | |
| 172 | - #toplevel_page_wp-defender.wp-not-current-submenu > ul > li:last-child > a[href^="https://wpmudev.com/"]:active, | |
| 173 | - #toplevel_page_wp-defender.wp-not-current-submenu > ul > li:last-child > a[href^="https://wpmudev.com/"]:focus { | |
| 201 | + #adminmenu .wp-submenu li.defender-menu-upsell > a .defender-upsell-label { | |
| 202 | + display: inline-flex; | |
| 203 | + align-items: center; | |
| 204 | + } | |
| 205 | + | |
| 206 | + #adminmenu .wp-submenu li.defender-menu-upsell > a .defender-upsell-pro-tag { | |
| 207 | + display: inline-flex; | |
| 208 | + align-items: center; | |
| 209 | + justify-content: center; | |
| 210 | + margin-left: 6px; | |
| 211 | + padding: 0 5px; | |
| 212 | + border: 1px solid #ffffff; | |
| 213 | + border-radius: 9px; | |
| 214 | + width: 30px; | |
| 215 | + height: 18px; | |
| 216 | + box-sizing: border-box; | |
| 217 | + font-family: 'Roboto', Arial, sans-serif; | |
| 218 | + font-size: 12px; | |
| 219 | + font-weight: 400; | |
| 220 | + line-height: 20px; | |
| 221 | + letter-spacing: 0.1px; | |
| 222 | + } | |
| 223 | + | |
| 224 | + #adminmenu .wp-submenu li.defender-menu-upsell > a .defender-upsell-arrow { | |
| 225 | + margin-right: 4px; | |
| 226 | + } | |
| 227 | + | |
| 228 | + #toplevel_page_wp-defender.wp-not-current-submenu .wp-submenu li.defender-menu-upsell > a, | |
| 229 | + #toplevel_page_wp-defender.wp-not-current-submenu .wp-submenu li.defender-menu-upsell > a:hover, | |
| 230 | + #toplevel_page_wp-defender.wp-not-current-submenu .wp-submenu li.defender-menu-upsell > a:active, | |
| 231 | + #toplevel_page_wp-defender.wp-not-current-submenu .wp-submenu li.defender-menu-upsell > a:focus { | |
| 174 | 232 | margin-left: -4px; |
| 175 | 233 | } |
| 176 | 234 | </style> |
| 177 | 235 | <script type='text/javascript'> |
| 178 | 236 | jQuery(function ($) { |
| 179 | - $('#toplevel_page_wp-defender > ul > li:last-child > a[href^="https://wpmudev.com/"]').attr("target", "_blank"); | |
| 237 | + $('#adminmenu li.defender-menu-upsell > a').attr("target", "_blank"); | |
| 180 | 238 | }); |
| 181 | 239 | </script> |
| 182 | 240 | <?php |
| 183 | 241 | } |
| @@ -544,15 +602,29 @@ | ||
| 544 | 602 | // Change model's data. |
| 545 | 603 | $model_firewall = wd_di()->get( Model\Setting\Firewall::class ); |
| 546 | 604 | $model_firewall->http_ip_header = 'HTTP_X_FORWARDED_FOR'; |
| 547 | 605 | $xff_ip = defender_get_data_from_request( 'HTTP_X_FORWARDED_FOR', 's' ); |
| 606 | + $xff_parts = preg_split( '/\s*,\s*/', $xff_ip ); | |
| 607 | + $xff_parts = is_array( $xff_parts ) ? $xff_parts : array(); | |
| 608 | + $xff_parts = array_map( 'trim', $xff_parts ); | |
| 609 | + $xff_parts = array_filter( | |
| 610 | + $xff_parts, | |
| 611 | + static function ( $ip ) { | |
| 612 | + return false !== filter_var( $ip, FILTER_VALIDATE_IP ); | |
| 613 | + } | |
| 614 | + ); | |
| 615 | + $separator = "\r\n"; | |
| 616 | + $xff_parts = array_unique( $xff_parts ); | |
| 617 | + $xff_ip = implode( $separator, $xff_parts ); | |
| 618 | + if ( '' === $xff_ip ) { | |
| 619 | + wp_send_json_error( | |
| 620 | + array( 'message' => esc_html__( 'Invalid trusted proxy IP(s) detected in X-Forwarded-For header.', 'defender-security' ) ) | |
| 621 | + ); | |
| 622 | + } | |
| 548 | 623 | if ( '' === $model_firewall->trusted_proxies_ip ) { |
| 549 | 624 | $model_firewall->trusted_proxies_ip = $xff_ip; |
| 550 | 625 | } else { |
| 551 | 626 | // Todo: improve the code using a separate method. This will be useful when the user switches between different proxy headeres (IP detection options). |
| 552 | - $separator = "\r\n"; | |
| 553 | - // Check if the XFF header contains multiple IPs. | |
| 554 | - $xff_ip = str_replace( array( ',', ' ,' ), $separator, $xff_ip ); | |
| 555 | 627 | $model_firewall->trusted_proxies_ip = $model_firewall->trusted_proxies_ip . $separator . $xff_ip; |
| 556 | 628 | } |
| 557 | 629 | $model_firewall->save(); |
| 558 | 630 | // Save Dismiss slug. |
| @@ -575,9 +647,14 @@ | ||
| 575 | 647 | } |
| 576 | 648 | |
| 577 | 649 | // Data to be passed to the template file. |
| 578 | 650 | $is_pro = wd_di()->get( WPMUDEV::class )->is_pro(); |
| 579 | - $docs_link = $this->get_link( 'support_with_utm', 'defender_deactivation_survey_help', '', $is_pro ? 'defender-pro' : 'defender' ); | |
| 651 | + $docs_link = $this->get_link( | |
| 652 | + 'support_with_utm', | |
| 653 | + 'defender_deactivation_survey_help', | |
| 654 | + '', | |
| 655 | + $is_pro ? 'defender-pro' : 'defender' | |
| 656 | + ); | |
| 580 | 657 | |
| 581 | 658 | ob_start(); |
| 582 | 659 | require_once $deactivation_survey_template_file; |
| 583 | 660 | // Everything escaped in all template files. |