| 1 |
<?php |
| 2 |
|
| 3 |
namespace WP_Defender; |
| 4 |
|
| 5 |
use WP_Defender\Behavior\WPMUDEV; |
| 6 |
|
| 7 |
if ( ! defined( 'ABSPATH' ) ) { |
| 8 |
die(); |
| 9 |
} |
| 10 |
|
| 11 |
/** |
| 12 |
* Class Admin |
| 13 |
* |
| 14 |
* @since 2.4 |
| 15 |
*/ |
| 16 |
class Admin { |
| 17 |
|
| 18 |
/** |
| 19 |
* @var bool |
| 20 |
*/ |
| 21 |
public $is_pro; |
| 22 |
|
| 23 |
/** |
| 24 |
* Init admin actions. |
| 25 |
*/ |
| 26 |
public function init() { |
| 27 |
$this->is_pro = ( new WPMUDEV() )->is_pro(); |
| 28 |
$is_def_page = defender_current_page(); |
| 29 |
$this->init_constants(); |
| 30 |
// Display plugin links. |
| 31 |
add_filter( 'network_admin_plugin_action_links_' . DEFENDER_PLUGIN_BASENAME, array( $this, 'settings_link' ) ); |
| 32 |
add_filter( 'plugin_action_links_' . DEFENDER_PLUGIN_BASENAME, array( $this, 'settings_link' ) ); |
| 33 |
add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 3 ); |
| 34 |
// WP_DEFENDER_PRO sometimes doesn't match $this->is_pro, e.g. WPMU DEV Dashboard is deactivated. |
| 35 |
if ( defined( 'WP_DEFENDER_PRO' ) && WP_DEFENDER_PRO ) { |
| 36 |
// This area is only for Pro version. |
| 37 |
add_action( |
| 38 |
'load-plugins.php', |
| 39 |
function () { |
| 40 |
add_action( 'after_plugin_row_' . DEFENDER_PLUGIN_BASENAME, array( |
| 41 |
$this, |
| 42 |
'show_upgrade_notice' |
| 43 |
), 10, 2 ); |
| 44 |
}, |
| 45 |
22 |
| 46 |
); |
| 47 |
} else { |
| 48 |
// This area is only for wordpress.org members. |
| 49 |
// Add plugin upgrade notification. |
| 50 |
add_action( 'in_plugin_update_message-' . DEFENDER_PLUGIN_BASENAME, array( $this, 'show_upgrade_notice' ), 10, 2 ); |
| 51 |
if ( $is_def_page && ! is_multisite() ) { |
| 52 |
add_action( 'admin_notices', array( $this, 'show_rating_notice' ) ); |
| 53 |
} elseif ( $is_def_page && is_multisite() && is_main_site() ) { |
| 54 |
add_action( 'network_admin_notices', array( $this, 'show_rating_notice' ) ); |
| 55 |
} |
| 56 |
add_action( 'wp_ajax_defender_dismiss_notification', array( $this, 'dismiss_notice' ) ); |
| 57 |
add_action( 'admin_init', array( $this, 'register_free_modules' ), 20 ); |
| 58 |
} |
| 59 |
} |
| 60 |
|
| 61 |
/** |
| 62 |
* Initialize constants in the admin panel. |
| 63 |
* |
| 64 |
* @since 3.1.0 |
| 65 |
*/ |
| 66 |
protected function init_constants() { |
| 67 |
if ( ! defined( 'WP_DEFENDER_SUPPORT_LINK' ) ) { |
| 68 |
define( 'WP_DEFENDER_SUPPORT_LINK', 'https://wpmudev.com/hub2/support/#get-support' ); |
| 69 |
} |
| 70 |
} |
| 71 |
|
| 72 |
/** |
| 73 |
* Return URL link. |
| 74 |
* |
| 75 |
* @param string $link_for Accepts: 'docs', 'plugin', 'rate', 'support', 'roadmap'. |
| 76 |
* @param string $campaign Utm campaign tag to be used in link. Default: ''. |
| 77 |
* @param string $adv_path Advanced path. Default: ''. |
| 78 |
* |
| 79 |
* @return string |
| 80 |
*/ |
| 81 |
public function get_link( $link_for, $campaign = '', $adv_path = '' ) { |
| 82 |
$domain = 'https://wpmudev.com'; |
| 83 |
$wp_org = 'https://wordpress.org'; |
| 84 |
$utm_tags = "?utm_source=defender&utm_medium=plugin&utm_campaign={$campaign}"; |
| 85 |
switch ( $link_for ) { |
| 86 |
case 'docs': |
| 87 |
$link = "{$domain}/docs/wpmu-dev-plugins/defender/{$utm_tags}"; |
| 88 |
break; |
| 89 |
case 'plugin': |
| 90 |
$link = "{$domain}/project/wp-defender/{$utm_tags}"; |
| 91 |
break; |
| 92 |
case 'rate': |
| 93 |
$link = "{$wp_org}/support/plugin/defender-security/reviews/#new-post"; |
| 94 |
break; |
| 95 |
case 'support': |
| 96 |
$link = $this->is_pro ? "{$domain}/get-support/" : "{$wp_org}/support/plugin/defender-security/"; |
| 97 |
break; |
| 98 |
case 'roadmap': |
| 99 |
$link = "{$domain}/roadmap/"; |
| 100 |
break; |
| 101 |
case 'pro_link': |
| 102 |
$link = "{$domain}/$adv_path"; |
| 103 |
break; |
| 104 |
default: |
| 105 |
$link = ''; |
| 106 |
break; |
| 107 |
} |
| 108 |
|
| 109 |
return $link; |
| 110 |
} |
| 111 |
|
| 112 |
|
| 113 |
/** |
| 114 |
* Adds a settings link on plugin page. |
| 115 |
* |
| 116 |
* @param array $links Current links. |
| 117 |
* |
| 118 |
* @return array |
| 119 |
*/ |
| 120 |
public function settings_link( $links ) { |
| 121 |
$action_links = []; |
| 122 |
$wpmu_dev = new WPMUDEV(); |
| 123 |
// Settings link. |
| 124 |
$action_links['dashboard'] = '<a href="' . network_admin_url( 'admin.php?page=wdf-setting' ) . '" aria-label="' . esc_attr( __( 'Go to Defender Settings', 'wpdef' ) ) . '">' . esc_html__( 'Settings', 'wpdef' ) . '</a>'; |
| 125 |
// Documentation link. |
| 126 |
$action_links['docs'] = '<a target="_blank" href="' . $this->get_link('docs', 'defender_pluginlist_docs') . '" aria-label="' . esc_attr(__('Docs', 'wpdef')) . '">' . esc_html__('Docs', 'wpdef') . '</a>'; |
| 127 |
if ( ! $wpmu_dev->is_member() ) { |
| 128 |
if ( WP_DEFENDER_PRO_PATH !== DEFENDER_PLUGIN_BASENAME ) { |
| 129 |
$action_links['upgrade'] = '<a style="color: #8D00B1;" target="_blank" href="' . $this->get_link( 'plugin', 'defender_pluginlist_upgrade' ) . '" aria-label="' . esc_attr( __( 'Upgrade to Defender Pro', 'wpdef' ) ) . '">' . esc_html__( 'Upgrade', 'wpdef' ) . '</a>'; |
| 130 |
} else { |
| 131 |
$action_links['renew'] = '<a style="color: #8D00B1;" target="_blank" href="' . $this->get_link( 'plugin', 'defender_pluginlist_renew' ) . '" aria-label="' . esc_attr( __( 'Renew Your Membership', 'wpdef' ) ) . '">' . esc_html__( 'Renew Membership', 'wpdef' ) . '</a>'; |
| 132 |
} |
| 133 |
} |
| 134 |
|
| 135 |
return array_merge( $action_links, $links ); |
| 136 |
} |
| 137 |
|
| 138 |
/** |
| 139 |
* Show row meta on the plugin screen. |
| 140 |
* |
| 141 |
* @param mixed $links Plugin Row Meta. |
| 142 |
* @param mixed $file Plugin Base file. |
| 143 |
* @param array $plugin_data Plugin data. |
| 144 |
* |
| 145 |
* @return array |
| 146 |
*/ |
| 147 |
public function plugin_row_meta( $links, $file, $plugin_data ) { |
| 148 |
$row_meta = []; |
| 149 |
if ( ! defined( 'DEFENDER_PLUGIN_BASENAME' ) || DEFENDER_PLUGIN_BASENAME !== $file ) { |
| 150 |
return $links; |
| 151 |
} |
| 152 |
|
| 153 |
// Change AuthorURI link. |
| 154 |
if ( isset( $links[1] ) ) { |
| 155 |
$author_uri = $this->is_pro ? 'https://wpmudev.com/' : 'https://profiles.wordpress.org/wpmudev/'; |
| 156 |
$author_uri = sprintf( |
| 157 |
'<a href="%s" target="_blank">%s</a>', |
| 158 |
$author_uri, |
| 159 |
__( 'WPMU DEV' ) |
| 160 |
); |
| 161 |
$links[1] = sprintf( /* translators: ... */ __( 'By %s' ), $author_uri ); |
| 162 |
} |
| 163 |
|
| 164 |
if ( ! $this->is_pro ) { |
| 165 |
// Change AuthorURI link. |
| 166 |
if ( isset( $links[2] ) && false === strpos( $links[2], 'target="_blank"' ) ) { |
| 167 |
if ( ! isset( $plugin_data['slug'] ) && $plugin_data['Name'] ) { |
| 168 |
$links[2] = sprintf( |
| 169 |
'<a href="%s" class="thickbox open-plugin-details-modal" aria-label="%s" data-title="%s">%s</a>', |
| 170 |
esc_url( |
| 171 |
network_admin_url( |
| 172 |
'plugin-install.php?tab=plugin-information&plugin=defender-security' . |
| 173 |
'&TB_iframe=true&width=600&height=550' |
| 174 |
) |
| 175 |
), |
| 176 |
/* translators: %s: Plugin name. */ |
| 177 |
esc_attr( sprintf( __( 'More information about %s' ), $plugin_data['Name'] ) ), |
| 178 |
esc_attr( $plugin_data['Name'] ), |
| 179 |
__( 'View details' ) |
| 180 |
); |
| 181 |
} else { |
| 182 |
$links[2] = str_replace( 'href=', 'target="_blank" href=', $links[2] ); |
| 183 |
} |
| 184 |
} |
| 185 |
$row_meta['rate'] = '<a href="' . esc_url( $this->get_link( 'rate' ) ) . '" aria-label="' . esc_attr__( 'Rate Defender', 'wpdef' ) . '" target="_blank">' . esc_html__( 'Rate Defender', 'wpdef' ) . '</a>'; |
| 186 |
$row_meta['support'] = '<a href="' . esc_url( $this->get_link( 'support' ) ) . '" aria-label="' . esc_attr__( 'Support', 'wpdef' ) . '" target="_blank">' . esc_html__( 'Support', 'wpdef' ) . '</a>'; |
| 187 |
} else { |
| 188 |
// Change 'Visit plugins' link to 'View details'. |
| 189 |
if ( isset( $links[2] ) && false !== strpos( $links[2], 'project/wp-defender' ) ) { |
| 190 |
$links[2] = sprintf( |
| 191 |
'<a href="%s" target="_blank">%s</a>', |
| 192 |
esc_url( $this->get_link( 'pro_link', '', 'project/wp-defender/' ) ), |
| 193 |
__( 'View details' ) |
| 194 |
); |
| 195 |
} |
| 196 |
$row_meta['support'] = '<a href="' . esc_url( $this->get_link( 'support' ) ) . '" aria-label="' . esc_attr__( 'Premium Support', 'wpdef' ) . '" target="_blank">' . esc_html__( 'Premium Support', 'wpdef' ) . '</a>'; |
| 197 |
} |
| 198 |
$row_meta['roadmap'] = '<a href="' . esc_url( $this->get_link( 'roadmap' ) ) . '" aria-label="' . esc_attr__( 'Roadmap', 'wpdef' ) . '" target="_blank">' . esc_html__( 'Roadmap', 'wpdef' ) . '</a>'; |
| 199 |
|
| 200 |
return array_merge( $links, $row_meta ); |
| 201 |
} |
| 202 |
|
| 203 |
/** |
| 204 |
* Dismiss notice. |
| 205 |
*/ |
| 206 |
public function dismiss_notice() { |
| 207 |
if ( ! current_user_can( 'manage_options' ) || ! check_ajax_referer( 'defender_dismiss_notification' ) ) { |
| 208 |
wp_send_json_error( |
| 209 |
array( |
| 210 |
'message' => __( 'Invalid request, you are not allowed to do that action.', 'wpdef' ), |
| 211 |
) |
| 212 |
); |
| 213 |
} |
| 214 |
|
| 215 |
$notification_name = ! empty( $_POST['prop'] ) ? sanitize_text_field( $_POST['prop'] ) : false; |
| 216 |
if ( false === $notification_name ) { |
| 217 |
wp_send_json_error( |
| 218 |
array( |
| 219 |
'message' => __( 'Invalid request, allowed data not provided.', 'wpdef' ), |
| 220 |
) |
| 221 |
); |
| 222 |
} |
| 223 |
update_site_option( $notification_name, true ); |
| 224 |
|
| 225 |
wp_send_json_success(); |
| 226 |
} |
| 227 |
|
| 228 |
/** |
| 229 |
* Register sub-modules. |
| 230 |
*/ |
| 231 |
public function register_free_modules() { |
| 232 |
if ( |
| 233 |
! file_exists( defender_path( 'extra/free-dashboard/module.php' ) ) |
| 234 |
|| ! file_exists( defender_path( 'extra/recommended-plugins-notice/notice.php' ) ) |
| 235 |
) { |
| 236 |
return; |
| 237 |
} |
| 238 |
/* @noinspection PhpIncludeInspection */ |
| 239 |
require_once( defender_path( 'extra/free-dashboard/module.php' ) ); |
| 240 |
/* @noinspection PhpIncludeInspection */ |
| 241 |
require_once( defender_path( 'extra/recommended-plugins-notice/notice.php' ) ); |
| 242 |
|
| 243 |
// Register the current plugin. |
| 244 |
do_action( |
| 245 |
'wdev_register_plugin', |
| 246 |
/* 1 Plugin ID */ DEFENDER_PLUGIN_BASENAME, |
| 247 |
/* 2 Plugin Title */ 'Defender', |
| 248 |
/* 3 https://wordpress.org */ '/plugins/defender-security/', |
| 249 |
/* 4 Email Button CTA */ __( 'Get Fast!', 'wpdef' ) |
| 250 |
/* 5 Mailchimp List id for the plugin - No */ |
| 251 |
); |
| 252 |
|
| 253 |
// Recommended plugin notice. |
| 254 |
do_action( |
| 255 |
'wpmudev-recommended-plugins-register-notice', |
| 256 |
DEFENDER_PLUGIN_BASENAME, // Plugin basename |
| 257 |
'Defender', // Plugin Name |
| 258 |
array( |
| 259 |
'toplevel_page_wp-defender', |
| 260 |
'toplevel_page_wp-defender-network', |
| 261 |
), |
| 262 |
array( 'after', '.sui-wrap .sui-header' ) |
| 263 |
); |
| 264 |
} |
| 265 |
|
| 266 |
/** |
| 267 |
* Show the rating notice. |
| 268 |
*/ |
| 269 |
public function show_rating_notice() { |
| 270 |
// @since 2.6.1 |
| 271 |
if ( get_site_option( 'defender_rating_success', apply_filters( 'wd_display_rating', false ) ) ) { |
| 272 |
return; |
| 273 |
} |
| 274 |
|
| 275 |
$install_date = get_site_option( 'defender_free_install_date', false ); |
| 276 |
// @since 2.6.1 |
| 277 |
$days_later_dismiss = get_site_option( 'defender_days_rating_later_dismiss', |
| 278 |
apply_filters( 'wd_dismiss_rating', false ) |
| 279 |
); |
| 280 |
|
| 281 |
if ( |
| 282 |
$install_date && ! $days_later_dismiss |
| 283 |
&& current_time( 'timestamp' ) > strtotime( '+7 days', $install_date ) |
| 284 |
) { ?> |
| 285 |
<div id="defender-free-usage-notice" |
| 286 |
class="defender-rating-notice notice notice-info" |
| 287 |
data-nonce="<?php echo esc_attr( wp_create_nonce( 'defender_dismiss_notification' ) ); ?>"> |
| 288 |
|
| 289 |
<p style="color: #72777C; line-height: 22px;"><?php esc_html_e( 'We\'ve spent countless hours developing Defender and making it free for you to use. We would really appreciate it if you dropped us a quick rating!', 'wpdef' ); ?></p> |
| 290 |
|
| 291 |
<p> |
| 292 |
<button type="button" class="button button-primary button-large" |
| 293 |
data-prop="defender_rating_success"><?php esc_html_e( 'Rate Defender', 'wpdef' ); ?></button> |
| 294 |
<a href="#" class="dismiss" |
| 295 |
style="margin-left: 11px; color: #555; line-height: 16px; font-weight: 500; text-decoration: none;" |
| 296 |
data-prop="defender_days_rating_later_dismiss"><?php esc_html_e( 'Maybe later', 'wpdef' ); ?></a> |
| 297 |
</p> |
| 298 |
</div> |
| 299 |
<?php |
| 300 |
} |
| 301 |
?> |
| 302 |
|
| 303 |
<script type="text/javascript"> |
| 304 |
jQuery('.defender-rating-notice a, .defender-rating-notice button').on('click', function (e) { |
| 305 |
e.preventDefault(); |
| 306 |
|
| 307 |
var $notice = jQuery(e.currentTarget).closest('.defender-rating-notice'), |
| 308 |
prop = jQuery(this).data('prop'), |
| 309 |
ajaxUrl = '<?php echo admin_url( 'admin-ajax.php' ); ?>'; |
| 310 |
|
| 311 |
if ('defender_rating_success' === prop) { |
| 312 |
window.open('https://wordpress.org/support/plugin/defender-security/reviews/#new-post', '_blank'); |
| 313 |
} |
| 314 |
|
| 315 |
jQuery.post( |
| 316 |
ajaxUrl, |
| 317 |
{ |
| 318 |
action: 'defender_dismiss_notification', |
| 319 |
prop: prop, |
| 320 |
_ajax_nonce: $notice.data('nonce') |
| 321 |
} |
| 322 |
).always(function () { |
| 323 |
$notice.hide(); |
| 324 |
}); |
| 325 |
}); |
| 326 |
</script> |
| 327 |
|
| 328 |
<?php |
| 329 |
} |
| 330 |
|
| 331 |
/** |
| 332 |
* Show plugin update notice. |
| 333 |
* |
| 334 |
* @param string $plugin_file |
| 335 |
* @param array $response |
| 336 |
* |
| 337 |
* @since 2.8.3 |
| 338 |
*/ |
| 339 |
public function show_upgrade_notice( $plugin_file, $response ) { |
| 340 |
if ( version_compare( PHP_VERSION, '7.2', '>=' ) ) { |
| 341 |
return; |
| 342 |
} |
| 343 |
$plugin_data = (object) $response; |
| 344 |
// Preparing for the next major plugin v3.0.0 and subsequent versions. |
| 345 |
if ( isset( $plugin_data->new_version ) |
| 346 |
&& '3' === substr( trim( $plugin_data->new_version ), 0, 1 ) |
| 347 |
&& version_compare( DEFENDER_VERSION, '3', '<' ) |
| 348 |
){ |
| 349 |
// Major plugin version or subsequent versions. |
| 350 |
$new_version = ( '3' === $plugin_data->new_version ) ? '3.0.0' : $plugin_data->new_version; |
| 351 |
// Collect notice. |
| 352 |
$notice = '<p>' . esc_html__( 'There is a new version of Defender available - Deprecating PHP version 7.1. and lower.', 'wpdef' ) . '</p>'; |
| 353 |
$notice .= '<span style="display: inherit;background: #D63638;color: #FFFFFF;margin-top: 12px;padding: 10px 12px;border-radius: 2px;">'; |
| 354 |
$notice .= '<strong>'; |
| 355 |
$notice .= esc_html__( 'Important Upgrade Notice:', 'wpdef' ); |
| 356 |
$notice .= '</strong> '; |
| 357 |
$notice .= sprintf( |
| 358 |
/* translators: %s: Version number. */ |
| 359 |
esc_html__( 'The upcoming version %s is compatible only with PHP 7.2.0 and higher. Please make sure to upgrade your PHP version.', 'wpdef' ), |
| 360 |
$new_version |
| 361 |
); |
| 362 |
$notice .= '</span>'; |
| 363 |
|
| 364 |
echo "<script type='text/javascript'> |
| 365 |
(function ($) { |
| 366 |
$(document).ready(function () { |
| 367 |
$( '.wp-list-table tr[data-plugin=\"" . esc_attr( $plugin_data->plugin ) . "\"] .notice-warning' ).html( '" . addslashes( $notice ) . "' ).css('padding-bottom', '10px'); |
| 368 |
}); |
| 369 |
})(jQuery); |
| 370 |
</script>"; |
| 371 |
} |
| 372 |
} |
| 373 |
} |
| 374 |
|