W3 Total Cache - Version 2.0.0

Version Description

  • Feature: Added the Setup Guide wizard for onboarding
  • Update: Updated jQuery compatibility and methods deprecated in WordPress 5.6
  • Fix: Browser Cache: Fixed ExpiresByType code; changed from modified time to client access time
Download this release

Release Info

Developer joemoto
Plugin Icon 128x128 W3 Total Cache
Version 2.0.0
Comparing to
See all releases

Code changes from version 0.15.2 to 2.0.0

Cdn_Environment.php CHANGED
@@ -359,7 +359,7 @@ class Cdn_Environment {
359
 
360
 
361
 
362
- private function canonical( $cdnftp = false, $cors_header ) {
363
  $rules = '';
364
 
365
  $mime_types = include W3TC_INC_DIR . '/mime/other.php';
359
 
360
 
361
 
362
+ private function canonical( $cdnftp = false, $cors_header = true ) {
363
  $rules = '';
364
 
365
  $mime_types = include W3TC_INC_DIR . '/mime/other.php';
Extension_FragmentCache_Api.php CHANGED
@@ -87,7 +87,7 @@ function w3tc_fragmentcache_start( $id, $group = '', $hook = '' ) {
87
  * @param mixed $data the data returned by the filter
88
  * @return mixed
89
  */
90
- function w3tc_fragmentcache_filter_start( $id, $group = '', $hook = '', $data ) {
91
  _w3tc_caching_fragment( $id, $group );
92
  $fragment = w3tc_fragmentcache_get( $id, $group );
93
  if ( false !== $fragment ) {
@@ -125,7 +125,7 @@ function w3tc_fragmentcache_end( $id, $group = '', $debug = false ) {
125
  * @param mixed $data
126
  * @return mixed
127
  */
128
- function w3tc_fragmentcache_filter_end( $id, $group = '', $data ) {
129
  if ( w3tc_is_caching_fragment( $id, $group ) ) {
130
  w3tc_fragmentcache_store( $id, $group, $data );
131
  }
@@ -139,7 +139,7 @@ function w3tc_fragmentcache_filter_end( $id, $group = '', $data ) {
139
  * @param string $group
140
  * @param string $content
141
  */
142
- function w3tc_fragmentcache_store( $id, $group = '', $content ) {
143
  set_transient( "{$group}{$id}", $content,
144
  1000 /* default expiration in a case its not catched by fc plugin */ );
145
  }
87
  * @param mixed $data the data returned by the filter
88
  * @return mixed
89
  */
90
+ function w3tc_fragmentcache_filter_start( $id, $group = '', $hook = '', $data = null ) {
91
  _w3tc_caching_fragment( $id, $group );
92
  $fragment = w3tc_fragmentcache_get( $id, $group );
93
  if ( false !== $fragment ) {
125
  * @param mixed $data
126
  * @return mixed
127
  */
128
+ function w3tc_fragmentcache_filter_end( $id, $group = '', $data = null ) {
129
  if ( w3tc_is_caching_fragment( $id, $group ) ) {
130
  w3tc_fragmentcache_store( $id, $group, $data );
131
  }
139
  * @param string $group
140
  * @param string $content
141
  */
142
+ function w3tc_fragmentcache_store( $id, $group = '', $content = '' ) {
143
  set_transient( "{$group}{$id}", $content,
144
  1000 /* default expiration in a case its not catched by fc plugin */ );
145
  }
Generic_Plugin_Admin.php CHANGED
@@ -249,7 +249,20 @@ class Generic_Plugin_Admin {
249
 
250
  // Define icon styles for the custom post type
251
  function admin_head() {
252
- if ( isset( $_GET['page'] ) && $_GET['page'] == 'w3tc_dashboard' ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  ?>
254
  <script type="text/javascript">
255
  jQuery(function() {
@@ -405,7 +418,7 @@ class Generic_Plugin_Admin {
405
 
406
  if ( $this->is_w3tc_page ) {
407
  wp_localize_script( 'w3tc-options', 'w3tc_nonce',
408
- wp_create_nonce( 'w3tc' ) );
409
  }
410
 
411
 
249
 
250
  // Define icon styles for the custom post type
251
  function admin_head() {
252
+ $page = isset( $_GET['page'] ) ? $_GET['page'] : null;
253
+
254
+ if ( false !== strpos( $page, 'w3tc' ) && 'w3tc_setup_guide' !== $page && ! get_site_option( 'w3tc_setupguide_completed' ) ) {
255
+ $config = new Config();
256
+ $state_master = Dispatcher::config_state_master();
257
+
258
+ if ( is_multisite() ) {
259
+ wp_redirect( esc_url( network_admin_url( 'admin.php?page=w3tc_setup_guide' ) ) );
260
+ } else {
261
+ wp_redirect( esc_url( admin_url( 'admin.php?page=w3tc_setup_guide' ) ) );
262
+ }
263
+ }
264
+
265
+ if ( 'w3tc_dashboard' === $page ) {
266
  ?>
267
  <script type="text/javascript">
268
  jQuery(function() {
418
 
419
  if ( $this->is_w3tc_page ) {
420
  wp_localize_script( 'w3tc-options', 'w3tc_nonce',
421
+ array( wp_create_nonce( 'w3tc' ) ) );
422
  }
423
 
424
 
Generic_WidgetSpreadTheWord_Plugin.php CHANGED
@@ -62,10 +62,10 @@ class Generic_WidgetSpreadTheWord_Plugin {
62
  array( 'jquery' ), '1.0' );
63
 
64
  wp_localize_script( 'w3tc_spread_the_word',
65
- 'w3tc_spread_the_word_product_url', W3TC_SUPPORT_US_PRODUCT_URL );
66
  wp_localize_script( 'w3tc_spread_the_word',
67
- 'w3tc_spread_the_word_tweet', W3TC_SUPPORT_US_TWEET );
68
  wp_localize_script( 'w3tc_spread_the_word',
69
- 'w3tc_spread_the_word_rate_url', W3TC_SUPPORT_US_RATE_URL );
70
  }
71
  }
62
  array( 'jquery' ), '1.0' );
63
 
64
  wp_localize_script( 'w3tc_spread_the_word',
65
+ 'w3tc_spread_the_word_product_url', array( W3TC_SUPPORT_US_PRODUCT_URL ) );
66
  wp_localize_script( 'w3tc_spread_the_word',
67
+ 'w3tc_spread_the_word_tweet', array( W3TC_SUPPORT_US_TWEET ) );
68
  wp_localize_script( 'w3tc_spread_the_word',
69
+ 'w3tc_spread_the_word_rate_url', array( W3TC_SUPPORT_US_RATE_URL ) );
70
  }
71
  }
Licensing_Plugin_Admin.php CHANGED
@@ -251,8 +251,15 @@ class Licensing_Plugin_Admin {
251
  $buttons;
252
  } else {
253
  $notes['licensing_terms'] = sprintf(
254
- __( 'Thanks for using W3 Total Cache! Please review the latest <a href="%s" target="blank">terms of use and privacy policy</a>, and accept them.', 'w3-total-cache' ),
255
- W3TC_TERMS_URL ) .
 
 
 
 
 
 
 
256
  $buttons;
257
  }
258
  }
251
  $buttons;
252
  } else {
253
  $notes['licensing_terms'] = sprintf(
254
+ // translators: 1: HTML break tag, 2: Anchor/link open tag, 3: Anchor/link close tag.
255
+ esc_html__(
256
+ 'By allowing us to collect data about how W3 Total Cache is used, we can improve our features and experience for everyone. This data will not include any personally identifiable information.%1$sFeel free to review our %2$sterms of use and privacy policy%3$s.',
257
+ 'w3-total-cache'
258
+ ),
259
+ '<br />',
260
+ '<a target="_blank" href="' . esc_url( W3TC_TERMS_URL ) . '">',
261
+ '</a>'
262
+ ) .
263
  $buttons;
264
  }
265
  }
Minify_Environment.php CHANGED
@@ -607,8 +607,8 @@ class Minify_Environment {
607
  if ( $expires ) {
608
  $rules .= "<IfModule mod_expires.c>\n";
609
  $rules .= " ExpiresActive On\n";
610
- $rules .= " ExpiresByType text/css M" . $lifetime . "\n";
611
- $rules .= " ExpiresByType application/x-javascript M" . $lifetime . "\n";
612
  $rules .= "</IfModule>\n";
613
  }
614
 
607
  if ( $expires ) {
608
  $rules .= "<IfModule mod_expires.c>\n";
609
  $rules .= " ExpiresActive On\n";
610
+ $rules .= " ExpiresByType text/css A" . $lifetime . "\n";
611
+ $rules .= " ExpiresByType application/x-javascript A" . $lifetime . "\n";
612
  $rules .= "</IfModule>\n";
613
  }
614
 
PageSpeed_Widget_View_FromApi.php CHANGED
@@ -45,9 +45,9 @@ function w3tcps_bar($r, $metric, $name) {
45
 
46
  ?>
47
  <div class="w3tcps_scores">
48
- <section title="Mobile"><?php echo esc_html( $rm['score'] ) ?></section>
49
  <p>|</p>
50
- <section title="Desktop"><?php echo esc_html( $rd['score'] ) ?></section>
51
  </div>
52
 
53
  <div>
45
 
46
  ?>
47
  <div class="w3tcps_scores">
48
+ <section title="Mobile"><?php echo ( isset( $rm['score'] ) ? esc_html( $rm['score'] ) : '' ); ?></section>
49
  <p>|</p>
50
+ <section title="Desktop"><?php echo ( isset( $rd['score'] ) ? esc_html( $rd['score'] ) : '' ); ?></section>
51
  </div>
52
 
53
  <div>
Root_AdminMenu.php CHANGED
@@ -101,11 +101,17 @@ class Root_AdminMenu {
101
  'visible_always' => false,
102
  'order' => 2200
103
  ),
 
 
 
 
 
 
104
  'w3tc_about' => array(
105
  'page_title' => __( 'About', 'w3-total-cache' ),
106
  'menu_text' => __( 'About', 'w3-total-cache' ),
107
  'visible_always' => true,
108
- 'order' => 2300
109
  )
110
  );
111
  $pages = apply_filters( 'w3tc_admin_menu', $pages, $this->_config );
@@ -234,6 +240,11 @@ class Root_AdminMenu {
234
  $options_install->options();
235
  break;
236
 
 
 
 
 
 
237
  case 'w3tc_about':
238
  $options_about = new Generic_Page_About();
239
  $options_about->options();
101
  'visible_always' => false,
102
  'order' => 2200
103
  ),
104
+ 'w3tc_setup_guide' => array(
105
+ 'page_title' => __( 'Setup Guide', 'w3-total-cache' ),
106
+ 'menu_text' => __( 'Setup Guide', 'w3-total-cache' ),
107
+ 'visible_always' => false,
108
+ 'order' => 2300
109
+ ),
110
  'w3tc_about' => array(
111
  'page_title' => __( 'About', 'w3-total-cache' ),
112
  'menu_text' => __( 'About', 'w3-total-cache' ),
113
  'visible_always' => true,
114
+ 'order' => 2400
115
  )
116
  );
117
  $pages = apply_filters( 'w3tc_admin_menu', $pages, $this->_config );
240
  $options_install->options();
241
  break;
242
 
243
+ case 'w3tc_setup_guide':
244
+ $setup_guide = new SetupGuide_Plugin_Admin();
245
+ $setup_guide->load();
246
+ break;
247
+
248
  case 'w3tc_about':
249
  $options_about = new Generic_Page_About();
250
  $options_about->options();
Root_Loader.php CHANGED
@@ -75,6 +75,7 @@ class Root_Loader {
75
  $plugins[] = new Extensions_Plugin_Admin();
76
  $plugins[] = new Generic_Plugin_AdminNotifications();
77
  $plugins[] = new UsageStatistics_Plugin_Admin();
 
78
  } else {
79
  if ( $c->get_boolean( 'jquerymigrate.disabled' ) ) {
80
  $plugins[] = new UserExperience_Plugin_Jquery();
75
  $plugins[] = new Extensions_Plugin_Admin();
76
  $plugins[] = new Generic_Plugin_AdminNotifications();
77
  $plugins[] = new UsageStatistics_Plugin_Admin();
78
+ $plugins[] = new SetupGuide_Plugin_Admin();
79
  } else {
80
  if ( $c->get_boolean( 'jquerymigrate.disabled' ) ) {
81
  $plugins[] = new UserExperience_Plugin_Jquery();
SetupGuide_Plugin_Admin.php ADDED
@@ -0,0 +1,1389 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: SetupGuide_Plugin_Admin.php
4
+ *
5
+ * @since 2.0.0
6
+ *
7
+ * @package W3TC
8
+ */
9
+
10
+ namespace W3TC;
11
+
12
+ /**
13
+ * Class: SetupGuide_Plugin_Admin
14
+ *
15
+ * @since 2.0.0
16
+ */
17
+ class SetupGuide_Plugin_Admin {
18
+ /**
19
+ * Current page.
20
+ *
21
+ * @since 2.0.0
22
+ * @access protected
23
+ *
24
+ * @var string
25
+ */
26
+ protected $_page = 'w3tc_setup_guide'; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore
27
+
28
+ /**
29
+ * Wizard template.
30
+ *
31
+ * @var \W3TC\Wizard\Template
32
+ */
33
+ private static $template;
34
+
35
+ /**
36
+ * Constructor.
37
+ *
38
+ * @since 2.0.0
39
+ */
40
+ public function __construct() {
41
+ require_once W3TC_INC_DIR . '/wizard/template.php';
42
+
43
+ if ( is_null( self::$template ) ) {
44
+ self::$template = new Wizard\Template( $this->get_config() );
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Run.
50
+ *
51
+ * Needed by the Root_Loader.
52
+ *
53
+ * @since 2.0.0
54
+ */
55
+ public function run() {
56
+ }
57
+
58
+ /**
59
+ * Display the setup guide.
60
+ *
61
+ * @since 2.0.0
62
+ *
63
+ * @see \W3TC\Wizard\Template::render()
64
+ */
65
+ public function load() {
66
+ self::$template->render();
67
+ }
68
+
69
+ /**
70
+ * Admin-Ajax: Set option to skip the setup guide.
71
+ *
72
+ * @since 2.0.0
73
+ */
74
+ public function skip() {
75
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
76
+ update_site_option( 'w3tc_setupguide_completed', time() );
77
+ wp_send_json_success();
78
+ } else {
79
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Admin-Ajax: Set the terms of service choice.
85
+ *
86
+ * @since 2.0.0
87
+ *
88
+ * @uses $_POST['choice'] TOS choice: accept/decline.
89
+ */
90
+ public function set_tos_choice() {
91
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
92
+ $choice = empty( $_POST['choice'] ) ? null : sanitize_key( $_POST['choice'] );
93
+ $allowed_choices = array(
94
+ 'accept',
95
+ 'decline',
96
+ );
97
+
98
+ if ( in_array( $choice, $allowed_choices, true ) ) {
99
+ $config = new Config();
100
+
101
+ if ( ! Util_Environment::is_w3tc_pro( $config ) ) {
102
+ $state_master = Dispatcher::config_state_master();
103
+ $state_master->set( 'license.community_terms', $choice );
104
+ $state_master->save();
105
+
106
+ $config->set( 'common.track_usage', ( 'accept' === $choice ) );
107
+ $config->save();
108
+ }
109
+
110
+ wp_send_json_success();
111
+ } else {
112
+ wp_send_json_error( __( 'Invalid choice', 'w3-total-cache' ), 400 );
113
+ }
114
+ } else {
115
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Abbreviate a URL for display in a small space.
121
+ *
122
+ * @since 2.0.0
123
+ *
124
+ * @param string $url URL.
125
+ * @return string
126
+ */
127
+ public function abbreviate_url( $url ) {
128
+ $url = untrailingslashit(
129
+ str_replace(
130
+ array(
131
+ 'https://',
132
+ 'http://',
133
+ 'www.',
134
+ ),
135
+ '',
136
+ $url
137
+ )
138
+ );
139
+
140
+ if ( strlen( $url ) > 35 ) {
141
+ $url = substr( $url, 0, 10 ) . '&hellip;' . substr( $url, -20 );
142
+ }
143
+
144
+ return $url;
145
+ }
146
+
147
+ /**
148
+ * Admin-Ajax: Test Page Cache.
149
+ *
150
+ * @since 2.0.0
151
+ *
152
+ * @see self::abbreviate_url()
153
+ * @see \W3TC\Util_Http::ttfb()
154
+ */
155
+ public function test_pgcache() {
156
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
157
+ $nocache = ! empty( $_POST['nocache'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
158
+ $url = site_url();
159
+ $results = array(
160
+ 'nocache' => $nocache,
161
+ 'url' => $url,
162
+ 'urlshort' => $this->abbreviate_url( $url ),
163
+ );
164
+
165
+ if ( ! $nocache ) {
166
+ Util_Http::get( $url, array( 'user-agent' => 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ) ) );
167
+ }
168
+
169
+ $results['ttfb'] = Util_Http::ttfb( $url, $nocache );
170
+
171
+ wp_send_json_success( $results );
172
+ } else {
173
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Admin-Ajax: Get the page cache settings.
179
+ *
180
+ * @since 2.0.0
181
+ *
182
+ * @see \W3TC\Config::get_boolean()
183
+ * @see \W3TC\Config::get_string()
184
+ */
185
+ public function get_pgcache_settings() {
186
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
187
+ $config = new Config();
188
+
189
+ wp_send_json_success(
190
+ array(
191
+ 'enabled' => $config->get_boolean( 'pgcache.enabled' ),
192
+ 'engine' => $config->get_string( 'pgcache.engine' ),
193
+ )
194
+ );
195
+ } else {
196
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Admin-Ajax: Configure the page cache settings.
202
+ *
203
+ * @since 2.0.0
204
+ *
205
+ * @see \W3TC\Config::get_boolean()
206
+ * @see \W3TC\Config::get_string()
207
+ * @see \W3TC\Util_Installed::$engine()
208
+ * @see \W3TC\Config::set()
209
+ * @see \W3TC\Config::save()
210
+ * @see \W3TC\Dispatcher::component()
211
+ * @see \W3TC\CacheFlush::flush_posts()
212
+ */
213
+ public function config_pgcache() {
214
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
215
+ $enable = ! empty( $_POST['enable'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
216
+ $engine = empty( $_POST['engine'] ) ? '' : esc_attr( trim( $_POST['engine'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
217
+ $is_updating = false;
218
+ $success = false;
219
+ $config = new Config();
220
+ $pgcache_enabled = $config->get_boolean( 'pgcache.enabled' );
221
+ $pgcache_engine = $config->get_string( 'pgcache.engine' );
222
+ $allowed_engines = array(
223
+ '',
224
+ 'file',
225
+ 'file_generic',
226
+ 'redis',
227
+ 'memcached',
228
+ 'nginx_memcached',
229
+ 'apc',
230
+ 'eaccelerator',
231
+ 'xcache',
232
+ 'wincache',
233
+ );
234
+
235
+ if ( in_array( $engine, $allowed_engines, true ) ) {
236
+ if ( empty( $engine ) || 'file' === $engine || 'file_generic' === $engine || Util_Installed::$engine() ) {
237
+ if ( $pgcache_enabled !== $enable ) {
238
+ $config->set( 'pgcache.enabled', $enable );
239
+ $is_updating = true;
240
+ }
241
+
242
+ if ( ! empty( $engine ) && $pgcache_engine !== $engine ) {
243
+ $config->set( 'pgcache.engine', $engine );
244
+ $is_updating = true;
245
+ }
246
+
247
+ if ( $is_updating ) {
248
+ $config->save();
249
+
250
+ $f = Dispatcher::component( 'CacheFlush' );
251
+ $f->flush_posts();
252
+
253
+ $e = Dispatcher::component( 'PgCache_Environment' );
254
+ $e->fix_on_wpadmin_request( $config, true );
255
+ }
256
+
257
+ if ( $config->get_boolean( 'pgcache.enabled' ) === $enable &&
258
+ ( ! $enable || $config->get_string( 'pgcache.engine' ) === $engine ) ) {
259
+ $success = true;
260
+ $message = __( 'Settings updated', 'w3-total-cache' );
261
+ } else {
262
+ $message = __( 'Settings not updated', 'w3-total-cache' );
263
+ }
264
+ } else {
265
+ $message = __( 'Requested cache storage engine is not available', 'w3-total-cache' );
266
+ }
267
+ } elseif ( ! $is_allowed_engine ) {
268
+ $message = __( 'Requested cache storage engine is invalid', 'w3-total-cache' );
269
+ }
270
+
271
+ wp_send_json_success(
272
+ array(
273
+ 'success' => $success,
274
+ 'message' => $message,
275
+ 'enable' => $enable,
276
+ 'engine' => $engine,
277
+ 'current_enabled' => $config->get_boolean( 'pgcache.enabled' ),
278
+ 'current_engine' => $config->get_string( 'pgcache.engine' ),
279
+ 'previous_enabled' => $pgcache_enabled,
280
+ 'previous_engine' => $pgcache_engine,
281
+ )
282
+ );
283
+ } else {
284
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Admin-Ajax: Test database cache.
290
+ *
291
+ * @since 2.0.0
292
+ *
293
+ * @see \W3TC\Config::get_boolean()
294
+ * @see \W3TC\Config::get_string()
295
+ *
296
+ * @global $wpdb WordPress database object.
297
+ */
298
+ public function test_dbcache() {
299
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
300
+ $config = new Config();
301
+ $results = array(
302
+ 'enabled' => $config->get_boolean( 'dbcache.enabled' ),
303
+ 'engine' => $config->get_string( 'dbcache.engine' ),
304
+ 'elapsed' => null,
305
+ );
306
+
307
+ global $wpdb;
308
+
309
+ $wpdb->flush();
310
+
311
+ $start_time = microtime( true );
312
+ $wpdb->timer_start();
313
+
314
+ // Test insert, get, and delete 200 records.
315
+ $table = $wpdb->prefix . 'options';
316
+ $option = 'w3tc_test_dbcache_';
317
+
318
+ // phpcs:disable WordPress.DB.DirectDatabaseQuery
319
+
320
+ for ( $x = 0; $x < 200; $x++ ) {
321
+ $wpdb->insert(
322
+ $table,
323
+ array(
324
+ 'option_name' => $option . $x,
325
+ 'option_value' => 'blah',
326
+ )
327
+ );
328
+
329
+ /*
330
+ * @see https://developer.wordpress.org/reference/classes/wpdb/prepare/
331
+ * I had to use %1$s as the method does not encapsulate the value with quotes,
332
+ * which would be a syntax error.
333
+ */
334
+ $select = $wpdb->prepare(
335
+ 'SELECT `option_value` FROM `%1$s` WHERE `option_name` = %s AND `option_name` NOT LIKE %s', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder
336
+ $table,
337
+ $option . $x,
338
+ 'NotAnOption'
339
+ );
340
+
341
+ $wpdb->get_var( $select ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
342
+
343
+ $wpdb->get_var( $select ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
344
+
345
+ $wpdb->update(
346
+ $table,
347
+ array( 'option_name' => $option . $x ),
348
+ array( 'option_value' => 'This is a dummy test.' )
349
+ );
350
+
351
+ $wpdb->delete( $table, array( 'option_name' => $option . $x ) );
352
+ }
353
+
354
+ // phpcs:enable WordPress.DB.DirectDatabaseQuery
355
+
356
+ $results['wpdb_time'] = $wpdb->timer_stop();
357
+ $results['exec_time'] = microtime( true ) - $start_time;
358
+ $results['elapsed'] = $results['wpdb_time'];
359
+
360
+ wp_send_json_success( $results );
361
+ } else {
362
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Admin-Ajax: Get the database cache settings.
368
+ *
369
+ * @since 2.0.0
370
+ *
371
+ * @see \W3TC\Config::get_boolean()
372
+ * @see \W3TC\Config::get_string()
373
+ */
374
+ public function get_dbcache_settings() {
375
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
376
+ $config = new Config();
377
+
378
+ wp_send_json_success(
379
+ array(
380
+ 'enabled' => $config->get_boolean( 'dbcache.enabled' ),
381
+ 'engine' => $config->get_string( 'dbcache.engine' ),
382
+ )
383
+ );
384
+ } else {
385
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
386
+ }
387
+ }
388
+
389
+ /**
390
+ * Admin-Ajax: Configure the database cache settings.
391
+ *
392
+ * @since 2.0.0
393
+ *
394
+ * @see \W3TC\Config::get_boolean()
395
+ * @see \W3TC\Config::get_string()
396
+ * @see \W3TC\Util_Installed::$engine()
397
+ * @see \W3TC\Config::set()
398
+ * @see \W3TC\Config::save()
399
+ * @see \W3TC\Dispatcher::component()
400
+ * @see \W3TC\CacheFlush::dbcache_flush()
401
+ */
402
+ public function config_dbcache() {
403
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
404
+ $enable = ! empty( $_POST['enable'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
405
+ $engine = empty( $_POST['engine'] ) ? '' : esc_attr( trim( $_POST['engine'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
406
+ $is_updating = false;
407
+ $success = false;
408
+ $config = new Config();
409
+ $old_enabled = $config->get_boolean( 'dbcache.enabled' );
410
+ $old_engine = $config->get_string( 'dbcache.engine' );
411
+ $allowed_engines = array(
412
+ '',
413
+ 'file',
414
+ 'redis',
415
+ 'memcached',
416
+ 'apc',
417
+ 'eaccelerator',
418
+ 'xcache',
419
+ 'wincache',
420
+ );
421
+
422
+ if ( in_array( $engine, $allowed_engines, true ) ) {
423
+ if ( empty( $engine ) || 'file' === $engine || Util_Installed::$engine() ) {
424
+ if ( $old_enabled !== $enable ) {
425
+ $config->set( 'dbcache.enabled', $enable );
426
+ $is_updating = true;
427
+ }
428
+
429
+ if ( ! empty( $engine ) && $old_engine !== $engine ) {
430
+ $config->set( 'dbcache.engine', $engine );
431
+ $is_updating = true;
432
+ }
433
+
434
+ if ( $is_updating ) {
435
+ $config->save();
436
+
437
+ $f = Dispatcher::component( 'CacheFlush' );
438
+ $f->dbcache_flush();
439
+ }
440
+
441
+ if ( $config->get_boolean( 'dbcache.enabled' ) === $enable &&
442
+ ( ! $enable || $config->get_string( 'dbcache.engine' ) === $engine ) ) {
443
+ $success = true;
444
+ $message = __( 'Settings updated', 'w3-total-cache' );
445
+ } else {
446
+ $message = __( 'Settings not updated', 'w3-total-cache' );
447
+ }
448
+ } else {
449
+ $message = __( 'Requested cache storage engine is not available', 'w3-total-cache' );
450
+ }
451
+ } elseif ( ! $is_allowed_engine ) {
452
+ $message = __( 'Requested cache storage engine is invalid', 'w3-total-cache' );
453
+ }
454
+
455
+ wp_send_json_success(
456
+ array(
457
+ 'success' => $success,
458
+ 'message' => $message,
459
+ 'enable' => $enable,
460
+ 'engine' => $engine,
461
+ 'current_enabled' => $config->get_boolean( 'dbcache.enabled' ),
462
+ 'current_engine' => $config->get_string( 'dbcache.engine' ),
463
+ 'previous_enabled' => $old_enabled,
464
+ 'previous_engine' => $old_engine,
465
+ )
466
+ );
467
+ } else {
468
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
469
+ }
470
+ }
471
+
472
+ /**
473
+ * Admin-Ajax: Test object cache.
474
+ *
475
+ * @since 2.0.0
476
+ *
477
+ * @see \W3TC\Config::get_boolean()
478
+ * @see \W3TC\Config::get_string()
479
+ */
480
+ public function test_objcache() {
481
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
482
+ $config = new Config();
483
+ $results = array(
484
+ 'enabled' => $config->get_boolean( 'objectcache.enabled' ),
485
+ 'engine' => $config->get_string( 'objectcache.engine' ),
486
+ 'elapsed' => null,
487
+ );
488
+
489
+ $start_time = microtime( true );
490
+
491
+ $posts = get_posts(
492
+ array(
493
+ 'post_type' => array(
494
+ 'page',
495
+ 'post',
496
+ ),
497
+ )
498
+ );
499
+
500
+ $results['elapsed'] = microtime( true ) - $start_time;
501
+ $results['post_ct'] = count( $posts );
502
+
503
+ wp_send_json_success( $results );
504
+ } else {
505
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
506
+ }
507
+ }
508
+
509
+ /**
510
+ * Admin-Ajax: Get the object cache settings.
511
+ *
512
+ * @since 2.0.0
513
+ *
514
+ * @see \W3TC\Config::get_boolean()
515
+ * @see \W3TC\Config::get_string()
516
+ */
517
+ public function get_objcache_settings() {
518
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
519
+ $config = new Config();
520
+
521
+ wp_send_json_success(
522
+ array(
523
+ 'enabled' => $config->get_boolean( 'objectcache.enabled' ),
524
+ 'engine' => $config->get_string( 'objectcache.engine' ),
525
+ )
526
+ );
527
+ } else {
528
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
529
+ }
530
+ }
531
+
532
+ /**
533
+ * Admin-Ajax: Configure the object cache settings.
534
+ *
535
+ * @since 2.0.0
536
+ *
537
+ * @see \W3TC\Config::get_boolean()
538
+ * @see \W3TC\Config::get_string()
539
+ * @see \W3TC\Util_Installed::$engine()
540
+ * @see \W3TC\Config::set()
541
+ * @see \W3TC\Config::save()
542
+ * @see \W3TC\Dispatcher::component()
543
+ * @see \W3TC\CacheFlush::objcache_flush()
544
+ */
545
+ public function config_objcache() {
546
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
547
+ $enable = ! empty( $_POST['enable'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
548
+ $engine = empty( $_POST['engine'] ) ? '' : esc_attr( trim( $_POST['engine'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
549
+ $is_updating = false;
550
+ $success = false;
551
+ $config = new Config();
552
+ $old_enabled = $config->get_boolean( 'objectcache.enabled' );
553
+ $old_engine = $config->get_string( 'objectcache.engine' );
554
+ $allowed_engines = array(
555
+ '',
556
+ 'file',
557
+ 'redis',
558
+ 'memcached',
559
+ 'apc',
560
+ 'eaccelerator',
561
+ 'xcache',
562
+ 'wincache',
563
+ );
564
+
565
+ if ( in_array( $engine, $allowed_engines, true ) ) {
566
+ if ( empty( $engine ) || 'file' === $engine || Util_Installed::$engine() ) {
567
+ if ( $old_enabled !== $enable ) {
568
+ $config->set( 'objectcache.enabled', $enable );
569
+ $is_updating = true;
570
+ }
571
+
572
+ if ( ! empty( $engine ) && $old_engine !== $engine ) {
573
+ $config->set( 'objectcache.engine', $engine );
574
+ $is_updating = true;
575
+ }
576
+
577
+ if ( $is_updating ) {
578
+ $config->save();
579
+
580
+ $f = Dispatcher::component( 'CacheFlush' );
581
+ $f->objectcache_flush();
582
+ }
583
+
584
+ if ( $config->get_boolean( 'objectcache.enabled' ) === $enable &&
585
+ ( ! $enable || $config->get_string( 'objectcache.engine' ) === $engine ) ) {
586
+ $success = true;
587
+ $message = __( 'Settings updated', 'w3-total-cache' );
588
+ } else {
589
+ $message = __( 'Settings not updated', 'w3-total-cache' );
590
+ }
591
+ } else {
592
+ $message = __( 'Requested cache storage engine is not available', 'w3-total-cache' );
593
+ }
594
+ } elseif ( ! $is_allowed_engine ) {
595
+ $message = __( 'Requested cache storage engine is invalid', 'w3-total-cache' );
596
+ }
597
+
598
+ wp_send_json_success(
599
+ array(
600
+ 'success' => $success,
601
+ 'message' => $message,
602
+ 'enable' => $enable,
603
+ 'engine' => $engine,
604
+ 'current_enabled' => $config->get_boolean( 'objectcache.enabled' ),
605
+ 'current_engine' => $config->get_string( 'objectcache.engine' ),
606
+ 'previous_enabled' => $old_enabled,
607
+ 'previous_engine' => $old_engine,
608
+ )
609
+ );
610
+ } else {
611
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
612
+ }
613
+ }
614
+
615
+ /**
616
+ * Admin-Ajax: Test URL addreses for Browser Cache header.
617
+ *
618
+ * @since 2.0.0
619
+ *
620
+ * @see \W3TC\CacheFlush::browsercache_flush()
621
+ * @see \W3TC\Util_Http::get_headers()
622
+ */
623
+ public function test_browsercache() {
624
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
625
+ $results = array();
626
+ $urls = array(
627
+ trailingslashit( site_url() ),
628
+ esc_url( plugin_dir_url( __FILE__ ) . 'pub/css/setup-guide.css' ),
629
+ esc_url( plugin_dir_url( __FILE__ ) . 'pub/js/setup-guide.js' ),
630
+ );
631
+
632
+ $f = Dispatcher::component( 'CacheFlush' );
633
+ $f->browsercache_flush();
634
+
635
+ $header_missing = esc_html__( 'Not present', 'w3-total-cache' );
636
+
637
+ foreach ( $urls as $url ) {
638
+ $headers = Util_Http::get_headers( $url );
639
+
640
+ $results[] = array(
641
+ 'url' => $url,
642
+ 'filename' => basename( $url ),
643
+ 'header' => empty( $headers['cache-control'] ) ? $header_missing : $headers['cache-control'],
644
+ 'headers' => empty( $headers ) || ! is_array( $headers ) ? array() : $headers,
645
+ );
646
+ }
647
+
648
+ wp_send_json_success( $results );
649
+ } else {
650
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
651
+ }
652
+ }
653
+
654
+ /**
655
+ * Admin-Ajax: Get the browser cache settings.
656
+ *
657
+ * @since 2.0.0
658
+ *
659
+ * @see \W3TC\Config::get_boolean()
660
+ * @see \W3TC\Config::get_string()
661
+ */
662
+ public function get_browsercache_settings() {
663
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
664
+ $config = new Config();
665
+
666
+ wp_send_json_success(
667
+ array(
668
+ 'enabled' => $config->get_boolean( 'browsercache.enabled' ),
669
+ 'cssjs.cache.control' => $config->get_boolean( 'browsercache.cssjs.cache.control' ),
670
+ 'cssjs.cache.policy' => $config->get_string( 'browsercache.cssjs.cache.policy' ),
671
+ 'html.cache.control' => $config->get_boolean( 'browsercache.html.cache.control' ),
672
+ 'html.cache.policy' => $config->get_string( 'browsercache.html.cache.policy' ),
673
+ 'other.cache.control' => $config->get_boolean( 'browsercache.other.cache.control' ),
674
+ 'other.cache.policy' => $config->get_string( 'browsercache.other.cache.policy' ),
675
+ )
676
+ );
677
+ } else {
678
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
679
+ }
680
+ }
681
+
682
+ /**
683
+ * Admin-Ajax: Configure the browser cache settings.
684
+ *
685
+ * @since 2.0.0
686
+ *
687
+ * @see \W3TC\Dispatcher::component()
688
+ * @see \W3TC\Config::get_boolean()
689
+ * @see \W3TC\Config::set()
690
+ * @see \W3TC\Config::save()
691
+ * @see \W3TC\CacheFlush::browsercache_flush()
692
+ * @see \W3TC\BrowserCache_Environment::fix_on_wpadmin_request()
693
+ *
694
+ * @uses $_POST['enable']
695
+ */
696
+ public function config_browsercache() {
697
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
698
+ $enable = ! empty( $_POST['enable'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
699
+ $config = new Config();
700
+ $browsercache_enabled = $config->get_boolean( 'browsercache.enabled' );
701
+
702
+ if ( $browsercache_enabled !== $enable ) {
703
+ $config->set( 'browsercache.enabled', $enable );
704
+ $config->set( 'browsercache.cssjs.cache.control', true );
705
+ $config->set( 'browsercache.cssjs.cache.policy', 'cache_public_maxage' );
706
+ $config->set( 'browsercache.html.cache.control', true );
707
+ $config->set( 'browsercache.html.cache.policy', 'cache_public_maxage' );
708
+ $config->set( 'browsercache.other.cache.control', true );
709
+ $config->set( 'browsercache.other.cache.policy', 'cache_public_maxage' );
710
+ $config->save();
711
+
712
+ $f = Dispatcher::component( 'CacheFlush' );
713
+ $f->browsercache_flush();
714
+
715
+ $e = Dispatcher::component( 'BrowserCache_Environment' );
716
+ $e->fix_on_wpadmin_request( $config, true );
717
+ }
718
+
719
+ $is_enabled = $config->get_boolean( 'browsercache.enabled' );
720
+
721
+ wp_send_json_success(
722
+ array(
723
+ 'success' => $is_enabled === $enable,
724
+ 'enable' => $enable,
725
+ 'browsercache_enabled' => $config->get_boolean( 'browsercache.enabled' ),
726
+ 'browsercache_previous' => $browsercache_enabled,
727
+ )
728
+ );
729
+ } else {
730
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
731
+ }
732
+ }
733
+
734
+ /**
735
+ * Admin-Ajax: Get the lazy load settings.
736
+ *
737
+ * @since 2.0.0
738
+ *
739
+ * @see \W3TC\Config::get_boolean()
740
+ * @see \W3TC\Config::get_string()
741
+ * @see \W3TC\Config::get_array()
742
+ */
743
+ public function get_lazyload_settings() {
744
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
745
+ $config = new Config();
746
+
747
+ wp_send_json_success(
748
+ array(
749
+ 'enabled' => $config->get_boolean( 'lazyload.enabled' ),
750
+ 'process_img' => $config->get_boolean( 'lazyload.process_img' ),
751
+ 'process_background' => $config->get_boolean( 'lazyload_process_background' ),
752
+ 'exclude' => $config->get_array( 'lazyload.exclude' ),
753
+ 'embed_method' => $config->get_string( 'lazyload.embed_method' ),
754
+ )
755
+ );
756
+ } else {
757
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
758
+ }
759
+ }
760
+
761
+ /**
762
+ * Admin-Ajax: Configure lazy load.
763
+ *
764
+ * @since 2.0.0
765
+ *
766
+ * @see \W3TC\Dispatcher::component()
767
+ * @see \W3TC\Config::get_boolean()
768
+ * @see \W3TC\Config::set()
769
+ * @see \W3TC\Config::save()
770
+ * @see \W3TC\Dispatcher::component()
771
+ * @see \W3TC\CacheFlush::flush_posts()
772
+ *
773
+ * @uses $_POST['enable']
774
+ */
775
+ public function config_lazyload() {
776
+ if ( wp_verify_nonce( $_POST['_wpnonce'], 'w3tc_wizard' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
777
+ $enable = ! empty( $_POST['enable'] );
778
+ $config = new Config();
779
+ $lazyload_enabled = $config->get_boolean( 'lazyload.enabled' );
780
+
781
+ if ( $lazyload_enabled !== $enable ) {
782
+ $config->set( 'lazyload.enabled', $enable );
783
+ $config->set( 'lazyload.process_img', true );
784
+ $config->set( 'lazyload_process_background', true );
785
+ $config->set( 'lazyload.embed_method', 'async_head' );
786
+ $config->save();
787
+
788
+ $f = Dispatcher::component( 'CacheFlush' );
789
+ $f->flush_posts();
790
+
791
+ $e = Dispatcher::component( 'PgCache_Environment' );
792
+ $e->fix_on_wpadmin_request( $config, true );
793
+ }
794
+
795
+ $is_enabled = $config->get_boolean( 'lazyload.enabled' );
796
+
797
+ wp_send_json_success(
798
+ array(
799
+ 'success' => $is_enabled === $enable,
800
+ 'enable' => $enable,
801
+ 'lazyload_enabled' => $config->get_boolean( 'lazyload.enabled' ),
802
+ 'lazyload_previous' => $lazyload_enabled,
803
+ )
804
+ );
805
+ } else {
806
+ wp_send_json_error( __( 'Security violation', 'w3-total-cache' ), 403 );
807
+ }
808
+ }
809
+
810
+ /**
811
+ * Get the terms of service choice.
812
+ *
813
+ * @since 2.0.0
814
+ *
815
+ * @see \W3TC\Util_Environment::is_w3tc_pro()
816
+ * @see \W3TC\Dispatcher::config_state()
817
+ * @see \W3TC\Dispatcher::config_state_master()
818
+ * @see \W3TC\ConfigState::get_string()
819
+ *
820
+ * @return string
821
+ */
822
+ private function get_tos_choice() {
823
+ $config = new Config();
824
+
825
+ if ( Util_Environment::is_w3tc_pro( $config ) ) {
826
+ $state = Dispatcher::config_state();
827
+ $terms = $state->get_string( 'license.terms' );
828
+ } else {
829
+ $state_master = Dispatcher::config_state_master();
830
+ $terms = $state_master->get_string( 'license.community_terms' );
831
+ }
832
+
833
+ return $terms;
834
+ }
835
+
836
+ /**
837
+ * Display the terms of service dialog if needed.
838
+ *
839
+ * @since 2.0.0
840
+ * @access private
841
+ *
842
+ * @see self::get_tos_choice()
843
+ *
844
+ * @return bool
845
+ */
846
+ private function maybe_ask_tos() {
847
+ if ( defined( 'W3TC_PRO' ) ) {
848
+ return false;
849
+ }
850
+
851
+ $terms = $this->get_tos_choice();
852
+
853
+ return 'accept' !== $terms && 'decline' !== $terms && 'postpone' !== $terms;
854
+ }
855
+
856
+ /**
857
+ * Get configuration.
858
+ *
859
+ * @since 2.0.0
860
+ * @access private
861
+ *
862
+ * @global $wp_version WordPress version string.
863
+ * @global $wpdb WordPress database connection.
864
+ *
865
+ * @see \W3TC\Config::get_boolean()
866
+ * @see \W3TC\Util_Request::get_string()
867
+ * @see \W3TC\Dispatcher::config_state()
868
+ * @see \W3TC\Util_Environment::home_url_host()
869
+ * @see \W3TC\Util_Environment::w3tc_edition()
870
+ * @see \W3TC\Util_Widget::list_widgets()
871
+ *
872
+ * @return array
873
+ */
874
+ private function get_config() {
875
+ global $wp_version, $wpdb;
876
+
877
+ $config = new Config();
878
+ $browsercache_enabled = $config->get_boolean( 'browsercache.enabled' );
879
+ $page = Util_Request::get_string( 'page' );
880
+ $state = Dispatcher::config_state();
881
+
882
+ if ( 'w3tc_extensions' === $page ) {
883
+ $page = 'extensions/' . Util_Request::get_string( 'extension' );
884
+ }
885
+
886
+ return array(
887
+ 'title' => esc_html__( 'Setup Guide', 'w3-total-cache' ),
888
+ 'scripts' => array(
889
+ array(
890
+ 'handle' => 'setup-guide',
891
+ 'src' => esc_url( plugin_dir_url( __FILE__ ) . 'pub/js/setup-guide.js' ),
892
+ 'deps' => array( 'jquery' ),
893
+ 'version' => W3TC_VERSION,
894
+ 'in_footer' => false,
895
+ 'localize' => array(
896
+ 'object_name' => 'W3TC_SetupGuide',
897
+ 'data' => array(
898
+ 'page' => $page,
899
+ 'wp_version' => $wp_version,
900
+ 'php_version' => phpversion(),
901
+ 'w3tc_version' => W3TC_VERSION,
902
+ 'server_software' => isset( $_SERVER['SERVER_SOFTWARE'] ) ?
903
+ sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : null,
904
+ 'db_version' => $wpdb->db_version(),
905
+ 'home_url_host' => Util_Environment::home_url_host(),
906
+ 'install_version' => esc_attr( $state->get_string( 'common.install_version' ) ),
907
+ 'w3tc_edition' => esc_attr( Util_Environment::w3tc_edition( $config ) ),
908
+ 'list_widgets' => esc_attr( Util_Widget::list_widgets() ),
909
+ 'ga_profile' => ( defined( 'W3TC_DEBUG' ) && W3TC_DEBUG ) ? 'UA-2264433-7' : 'UA-2264433-8',
910
+ 'tos_choice' => $this->get_tos_choice(),
911
+ 'test_complete_msg' => __(
912
+ 'Testing complete. Click Next to advance to the section and see the results.',
913
+ 'w3-total-cache'
914
+ ),
915
+ 'test_error_msg' => __(
916
+ 'Could not perform this test. Please reload the page to try again or click skip button to abort the setup guide.',
917
+ 'w3-total-cache'
918
+ ),
919
+ 'config_error_msg' => __(
920
+ 'Could not update configuration. Please reload the page to try again or click skip button to abort the setup guide.',
921
+ 'w3-total-cache'
922
+ ),
923
+ 'unavailable_text' => __( 'Unavailable', 'w3-total-cache' ),
924
+ 'none' => __( 'None', 'w3-total-cache' ),
925
+ 'disk' => __( 'Disk', 'w3-total-cache' ),
926
+ 'disk_basic' => __( 'Disk: Basic', 'w3-total-cache' ),
927
+ 'disk_enhanced' => __( 'Disk: Enhanced', 'w3-total-cache' ),
928
+ 'enabled' => __( 'Enabled', 'w3-total-cache' ),
929
+ 'notEnabled' => __( 'Not Enabled', 'w3-total-cache' ),
930
+ 'dashboardUrl' => esc_url( admin_url( 'admin.php?page=w3tc_dashboard' ) ),
931
+ ),
932
+ ),
933
+ ),
934
+ ),
935
+ 'styles' => array(
936
+ array(
937
+ 'handle' => 'setup-guide',
938
+ 'src' => esc_url( plugin_dir_url( __FILE__ ) . 'pub/css/setup-guide.css' ),
939
+ 'version' => W3TC_VERSION,
940
+ ),
941
+ ),
942
+ 'actions' => array(
943
+ array(
944
+ 'tag' => 'wp_ajax_w3tc_wizard_skip',
945
+ 'function' => array(
946
+ $this,
947
+ 'skip',
948
+ ),
949
+ ),
950
+ array(
951
+ 'tag' => 'wp_ajax_w3tc_tos_choice',
952
+ 'function' => array(
953
+ $this,
954
+ 'set_tos_choice',
955
+ ),
956
+ ),
957
+ array(
958
+ 'tag' => 'wp_ajax_w3tc_get_pgcache_settings',
959
+ 'function' => array(
960
+ $this,
961
+ 'get_pgcache_settings',
962
+ ),
963
+ ),
964
+ array(
965
+ 'tag' => 'wp_ajax_w3tc_test_pgcache',
966
+ 'function' => array(
967
+ $this,
968
+ 'test_pgcache',
969
+ ),
970
+ ),
971
+ array(
972
+ 'tag' => 'wp_ajax_w3tc_config_pgcache',
973
+ 'function' => array(
974
+ $this,
975
+ 'config_pgcache',
976
+ ),
977
+ ),
978
+ array(
979
+ 'tag' => 'wp_ajax_w3tc_get_dbcache_settings',
980
+ 'function' => array(
981
+ $this,
982
+ 'get_dbcache_settings',
983
+ ),
984
+ ),
985
+ array(
986
+ 'tag' => 'wp_ajax_w3tc_test_dbcache',
987
+ 'function' => array(
988
+ $this,
989
+ 'test_dbcache',
990
+ ),
991
+ ),
992
+ array(
993
+ 'tag' => 'wp_ajax_w3tc_config_dbcache',
994
+ 'function' => array(
995
+ $this,
996
+ 'config_dbcache',
997
+ ),
998
+ ),
999
+ array(
1000
+ 'tag' => 'wp_ajax_w3tc_get_objcache_settings',
1001
+ 'function' => array(
1002
+ $this,
1003
+ 'get_objcache_settings',
1004
+ ),
1005
+ ),
1006
+ array(
1007
+ 'tag' => 'wp_ajax_w3tc_test_objcache',
1008
+ 'function' => array(
1009
+ $this,
1010
+ 'test_objcache',
1011
+ ),
1012
+ ),
1013
+ array(
1014
+ 'tag' => 'wp_ajax_w3tc_config_objcache',
1015
+ 'function' => array(
1016
+ $this,
1017
+ 'config_objcache',
1018
+ ),
1019
+ ),
1020
+ array(
1021
+ 'tag' => 'wp_ajax_w3tc_get_browsercache_settings',
1022
+ 'function' => array(
1023
+ $this,
1024
+ 'get_browsercache_settings',
1025
+ ),
1026
+ ),
1027
+ array(
1028
+ 'tag' => 'wp_ajax_w3tc_test_browsercache',
1029
+ 'function' => array(
1030
+ $this,
1031
+ 'test_browsercache',
1032
+ ),
1033
+ ),
1034
+ array(
1035
+ 'tag' => 'wp_ajax_w3tc_config_browsercache',
1036
+ 'function' => array(
1037
+ $this,
1038
+ 'config_browsercache',
1039
+ ),
1040
+ ),
1041
+ array(
1042
+ 'tag' => 'wp_ajax_w3tc_get_lazyload_settings',
1043
+ 'function' => array(
1044
+ $this,
1045
+ 'get_lazyload_settings',
1046
+ ),
1047
+ ),
1048
+ array(
1049
+ 'tag' => 'wp_ajax_w3tc_config_lazyload',
1050
+ 'function' => array(
1051
+ $this,
1052
+ 'config_lazyload',
1053
+ ),
1054
+ ),
1055
+ ),
1056
+ 'steps_location' => 'left',
1057
+ 'steps' => array(
1058
+ array(
1059
+ 'id' => 'welcome',
1060
+ 'text' => __( 'Welcome', 'w3-total-cache' ),
1061
+ ),
1062
+ array(
1063
+ 'id' => 'pgcache',
1064
+ 'text' => __( 'Page Cache', 'w3-total-cache' ),
1065
+ ),
1066
+ array(
1067
+ 'id' => 'dbcache',
1068
+ 'text' => __( 'Database Cache', 'w3-total-cache' ),
1069
+ ),
1070
+ array(
1071
+ 'id' => 'objectcache',
1072
+ 'text' => __( 'Object Cache', 'w3-total-cache' ),
1073
+ ),
1074
+ array(
1075
+ 'id' => 'browsercache',
1076
+ 'text' => __( 'Browser Cache', 'w3-total-cache' ),
1077
+ ),
1078
+ array(
1079
+ 'id' => 'lazyload',
1080
+ 'text' => __( 'Lazy Load', 'w3-total-cache' ),
1081
+ ),
1082
+ array(
1083
+ 'id' => 'more',
1084
+ 'text' => __( 'More Caching Options', 'w3-total-cache' ),
1085
+ ),
1086
+ ),
1087
+ 'slides' => array(
1088
+ array( // Welcome.
1089
+ 'headline' => __( 'Welcome to the W3 Total Cache Setup Guide!', 'w3-total-cache' ),
1090
+ 'id' => 'welcome',
1091
+ 'markup' => '<div id="w3tc-welcome"' . ( $this->maybe_ask_tos() ? ' class="hidden"' : '' ) . '>
1092
+ <p>' .
1093
+ esc_html__(
1094
+ 'You have selected the Performance Suite that professionals have consistently ranked #1 for options and speed improvements.',
1095
+ 'w3-total-cache'
1096
+ ) . '</p>
1097
+ <p><strong>' . esc_html__( 'W3 Total Cache', 'w3-total-cache' ) . '</strong>
1098
+ ' . esc_html__(
1099
+ 'provides many options to help your website perform faster. While the ideal settings vary for every website, there are a few settings we recommend that you enable now.',
1100
+ 'w3-total-cache'
1101
+ ) . '</p>
1102
+ ' .
1103
+ sprintf(
1104
+ // translators: 1: Anchor/link open tag, 2: Anchor/link close tag.
1105
+ esc_html__(
1106
+ 'If you prefer to configure the settings on your own, you can %1$sskip this setup guide%2$s.',
1107
+ 'w3-total-cache'
1108
+ ),
1109
+ '<a id="w3tc-wizard-skip-link" href="#">',
1110
+ '</a>'
1111
+ ) . '</p>
1112
+ </div>' . ( $this->maybe_ask_tos() ?
1113
+ '<div id="w3tc-licensing-terms" class="notice notice-info inline">
1114
+ <p>' .
1115
+ sprintf(
1116
+ // translators: 1: Anchor/link open tag, 2: Anchor/link close tag.
1117
+ esc_html__(
1118
+ 'By allowing us to collect data about how W3 Total Cache is used, we can improve our features and experience for everyone. This data will not include any personally identifiable information. Feel free to review our %1$sterms of use and privacy policy%2$s.',
1119
+ 'w3-total-cache'
1120
+ ),
1121
+ '<a target="_blank" href="' . esc_url( 'https://api.w3-edge.com/v1/redirects/policies-terms' ) . '">',
1122
+ '</a>'
1123
+ ) . '</p>
1124
+ <p>
1125
+ <input type="button" class="button" data-choice="accept" value="' . esc_html__( 'Accept', 'w3-total-cache' ) . '" /> &nbsp;
1126
+ <input type="button" class="button" data-choice="decline" value="' . esc_html__( 'Decline', 'w3-total-cache' ) . '" />
1127
+ </p>
1128
+ </div>' : '' ),
1129
+ ),
1130
+ array( // Page Cache.
1131
+ 'headline' => __( 'Page Cache', 'w3-total-cache' ),
1132
+ 'id' => 'pc1',
1133
+ 'markup' => '<p>' . sprintf(
1134
+ // translators: 1: HTML emphesis open tag, 2: HTML emphesis close tag.
1135
+ esc_html__(
1136
+ 'The time it takes between a visitor\'s browser page request and receiving the first byte of a response is referred to as %1$sTime to First Byte%2$s.',
1137
+ 'w3-total-cache'
1138
+ ),
1139
+ '<em>',
1140
+ '</em>'
1141
+ ) . '</p>
1142
+ <p>
1143
+ <strong>' . esc_html__( 'W3 Total Cache', 'w3-total-cache' ) . '</strong> ' .
1144
+ esc_html__( 'can help you speed up', 'w3-total-cache' ) .
1145
+ ' <em>' . esc_html__( 'Time to First Byte', 'w3-total-cache' ) . '</em> by using Page Cache.
1146
+ </p>
1147
+ <p>' .
1148
+ esc_html__(
1149
+ 'We\'ll test your homepage with Page Cache disabled and then with several storage engines. You should review the test results and choose the best for your website.',
1150
+ 'w3-total-cache'
1151
+ ) . '</p>
1152
+ <p>
1153
+ <input id="w3tc-test-pgcache" class="button-primary" type="button" value="' .
1154
+ esc_html__( 'Test Page Cache', 'w3-total-cache' ) . '">
1155
+ <span class="hidden"><span class="spinner inline"></span>' . esc_html__( 'Measuring', 'w3-total-cache' ) .
1156
+ ' <em>' . esc_html__( 'Time to First Byte', 'w3-total-cache' ) . '</em>&hellip;
1157
+ </span>
1158
+ </p>
1159
+ <p class="hidden">
1160
+ ' . esc_html__( 'Test URL:', 'w3-total-cache' ) . ' <span id="w3tc-test-url"></span>
1161
+ </p>
1162
+ <table id="w3tc-pgcache-table" class="w3tc-setupguide-table widefat striped hidden">
1163
+ <thead>
1164
+ <tr>
1165
+ <th>' . esc_html__( 'Select', 'w3-total-cache' ) . '</th>
1166
+ <th>' . esc_html__( 'Storage Engine', 'w3-total-cache' ) . '</th>
1167
+ <th>' . esc_html__( 'Time (ms)', 'w3-total-cache' ) . '</th>
1168
+ </tr>
1169
+ </thead>
1170
+ <tbody></tbody>
1171
+ </table>',
1172
+ ),
1173
+ array( // Database Cache.
1174
+ 'headline' => __( 'Database Cache', 'w3-total-cache' ),
1175
+ 'id' => 'dbc1',
1176
+ 'markup' => '<p>' .
1177
+ esc_html__(
1178
+ 'Many database queries are made in every dynamic page request. A database cache may speed up the generation of dynamic pages. Database Cache serves query results directly from a storage engine.',
1179
+ 'w3-total-cache'
1180
+ ) . '</p>
1181
+ <p>
1182
+ <input id="w3tc-test-dbcache" class="button-primary" type="button" value="' .
1183
+ esc_html__( 'Test Database Cache', 'w3-total-cache' ) . '">
1184
+ <span class="hidden"><span class="spinner inline"></span>' . esc_html__( 'Testing', 'w3-total-cache' ) .
1185
+ ' <em>' . esc_html__( 'Database Cache', 'w3-total-cache' ) . '</em>&hellip;
1186
+ </span>
1187
+ </p>
1188
+ <table id="w3tc-dbc-table" class="w3tc-setupguide-table widefat striped hidden">
1189
+ <thead>
1190
+ <tr>
1191
+ <th>' . esc_html__( 'Select', 'w3-total-cache' ) . '</th>
1192
+ <th>' . esc_html__( 'Storage Engine', 'w3-total-cache' ) . '</th>
1193
+ <th>' . esc_html__( 'Time (ms)', 'w3-total-cache' ) . '</th>
1194
+ </tr>
1195
+ </thead>
1196
+ <tbody></tbody>
1197
+ </table>
1198
+ <div id="w3tc-dbcache-recommended" class="notice notice-info inline hidden">
1199
+ <div class="w3tc-notice-recommended"><span class="dashicons dashicons-lightbulb"></span> Recommended</div>
1200
+ <div><p>' .
1201
+ esc_html__(
1202
+ 'By default, this feature is disabled. We recommend using Redis or Memcached, otherwise leave this feature disabled as the server database engine may be faster than using disk caching.',
1203
+ 'w3-total-cache'
1204
+ ) . '</p></div>
1205
+ </div>',
1206
+ ),
1207
+ array( // Object Cache.
1208
+ 'headline' => __( 'Object Cache', 'w3-total-cache' ),
1209
+ 'id' => 'oc1',
1210
+ 'markup' => '<p>' .
1211
+ esc_html__(
1212
+ 'WordPress caches objects used to build pages, but does not reuse them for future page requests.',
1213
+ 'w3-total-cache'
1214
+ ) . '</p>
1215
+ <p><strong>' . esc_html__( 'W3 Total Cache', 'w3-total-cache' ) . '</strong> ' .
1216
+ esc_html__( 'can help you speed up dynamic pages by persistently storing objects.', 'w3-total-cache' ) .
1217
+ '</p>
1218
+ <p>
1219
+ <input id="w3tc-test-objcache" class="button-primary" type="button" value="' .
1220
+ esc_html__( 'Test Object Cache', 'w3-total-cache' ) . '">
1221
+ <span class="hidden"><span class="spinner inline"></span>' . esc_html__( 'Testing', 'w3-total-cache' ) .
1222
+ ' <em>' . esc_html__( 'Object Cache', 'w3-total-cache' ) . '</em>&hellip;
1223
+ </span>
1224
+ </p>
1225
+ <table id="w3tc-objcache-table" class="w3tc-setupguide-table widefat striped hidden">
1226
+ <thead>
1227
+ <tr>
1228
+ <th>' . esc_html__( 'Select', 'w3-total-cache' ) . '</th>
1229
+ <th>' . esc_html__( 'Storage Engine', 'w3-total-cache' ) . '</th>
1230
+ <th>' . esc_html__( 'Time (ms)', 'w3-total-cache' ) . '</th>
1231
+ </tr>
1232
+ </thead>
1233
+ <tbody></tbody>
1234
+ </table>',
1235
+ ),
1236
+ array( // Browser Cache.
1237
+ 'headline' => __( 'Browser Cache', 'w3-total-cache' ),
1238
+ 'id' => 'bc1',
1239
+ 'markup' => '<p>' .
1240
+ esc_html__(
1241
+ 'To render your website, browsers must download many different types of assets, including javascript files, CSS stylesheets, images, and more. For most assets, once a browser has downloaded them, they shouldn\'t have to download them again.',
1242
+ 'w3-total-cache'
1243
+ ) . '</p>
1244
+ <p><strong>' . esc_html__( 'W3 Total Cache', 'w3-total-cache' ) . '</strong> ' .
1245
+ esc_html__(
1246
+ 'can help ensure browsers are properly caching your assets.',
1247
+ 'w3-total-cache'
1248
+ ) . '</p>
1249
+ <p>' . sprintf(
1250
+ // translators: 1: HTML emphesis open tag, 2: HTML emphesis close tag.
1251
+ esc_html__(
1252
+ 'The %1$sCache-Control%2$s header tells your browser how it should cache specific files. The %1$smax-age%2$s setting tells your browser how long, in seconds, it should use its cached version of a file before requesting an updated one.',
1253
+ 'w3-total-cache'
1254
+ ),
1255
+ '<em>',
1256
+ '</em>'
1257
+ ) . '</p>
1258
+ <p>' . sprintf(
1259
+ // translators: 1: HTML emphesis open tag, 2: HTML emphesis close tag.
1260
+ esc_html__(
1261
+ 'To improve %1$sBrowser Cache%2$s, we recommend enabling %1$sBrowser Cache%2$s.',
1262
+ 'w3-total-cache'
1263
+ ),
1264
+ '<em>',
1265
+ '</em>'
1266
+ ) . '</p>
1267
+ <input id="w3tc-test-browsercache" class="button-primary" type="button" value="' .
1268
+ esc_html__( 'Test Browser Cache', 'w3-total-cache' ) . '">
1269
+ <span class="hidden"><span class="spinner inline"></span>' . esc_html__( 'Testing', 'w3-total-cache' ) .
1270
+ ' <em>' . esc_html__( 'Browser Cache', 'w3-total-cache' ) . '</em>&hellip;
1271
+ </span>
1272
+ </p>
1273
+ <table id="w3tc-browsercache-table" class="w3tc-setupguide-table widefat striped hidden">
1274
+ <thead>
1275
+ <tr>
1276
+ <th>' . esc_html__( 'Setting', 'w3-total-cache' ) . '</th>
1277
+ <th>' . esc_html__( 'File', 'w3-total-cache' ) . '</th>
1278
+ <th>' . esc_html__( 'Cache-Control Header', 'w3-total-cache' ) . '</th>
1279
+ </tr>
1280
+ </thead>
1281
+ <tbody></tbody>
1282
+ </table>',
1283
+ ),
1284
+ array( // Lazy load.
1285
+ 'headline' => __( 'Lazy Load', 'w3-total-cache' ),
1286
+ 'id' => 'll1',
1287
+ 'markup' => '<p>' .
1288
+ esc_html__(
1289
+ 'Pages containing images and other objects can have their load time reduced by deferring them until they are needed. For example, images can be loaded when a visitor scrolls down the page to make them visible.',
1290
+ 'w3-total-cache'
1291
+ ) . '</p>
1292
+ <p>
1293
+ <input type="checkbox" id="lazyload-enable" value="1" /> <label for="lazyload-enable">' .
1294
+ esc_html__( 'Lazy Load Images', 'w3-total-cache' ) . '</label></p>',
1295
+ ),
1296
+ array( // Setup complete.
1297
+ 'headline' => __( 'Setup Complete!', 'w3-total-cache' ),
1298
+ 'id' => 'complete',
1299
+ 'markup' => '<p>' .
1300
+ sprintf(
1301
+ // translators: 1: HTML strong open tag, 2: HTML strong close tag.
1302
+ esc_html__(
1303
+ '%1$sTime to First Byte%2$s has change by %3$s!',
1304
+ 'w3-total-cache'
1305
+ ),
1306
+ '<strong>',
1307
+ '</strong>',
1308
+ '<span id="w3tc-ttfb-diff">0%</span>'
1309
+ ) . '</p>
1310
+ <p>' .
1311
+ sprintf(
1312
+ // translators: 1: HTML strong open tag, 2: HTML strong close tag, 3: Label.
1313
+ esc_html__(
1314
+ '%1$sDatabase Cache%2$s engine set to %1$s%3$s%2$s',
1315
+ 'w3-total-cache'
1316
+ ),
1317
+ '<strong>',
1318
+ '</strong>',
1319
+ '<span id="w3tc-dbcache-engine">' . esc_html__( 'UNKNOWN', 'w3-total-cache' ) . '</span>'
1320
+ ) . '</p>
1321
+ <p>' .
1322
+ sprintf(
1323
+ // translators: 1: HTML strong open tag, 2: HTML strong close tag, 3: Label.
1324
+ esc_html__(
1325
+ '%1$sObject Cache%2$s engine set to %1$s%3$s%2$s',
1326
+ 'w3-total-cache'
1327
+ ),
1328
+ '<strong>',
1329
+ '</strong>',
1330
+ '<span id="w3tc-objcache-engine">' . esc_html__( 'UNKNOWN', 'w3-total-cache' ) . '</span>'
1331
+ ) . '</p>
1332
+ <p>' .
1333
+ sprintf(
1334
+ // translators: 1: HTML strong open tag, 2: HTML strong close tag, 3: Label.
1335
+ esc_html__(
1336
+ '%1$sBrowser Cache%2$s headers set for JavaScript, CSS, and images? %1$s%3$s%2$s',
1337
+ 'w3-total-cache'
1338
+ ),
1339
+ '<strong>',
1340
+ '</strong>',
1341
+ '<span id="w3tc-browsercache-setting">' . esc_html__( 'UNKNOWN', 'w3-total-cache' ) . '</span>'
1342
+ ) . '</p>
1343
+ <p>' . sprintf(
1344
+ // translators: 1: HTML strong open tag, 2: HTML strong close tag, 3: Label.
1345
+ esc_html__(
1346
+ '%1$sLazy Load%2$s images? %1$s%3$s%2$s',
1347
+ 'w3-total-cache'
1348
+ ),
1349
+ '<strong>',
1350
+ '</strong>',
1351
+ '<span id="w3tc-lazyload-setting">' . esc_html__( 'UNKNOWN', 'w3-total-cache' ) . '</span>'
1352
+ ) . '</p>
1353
+ <h3>' . esc_html__( 'What\'s Next?', 'w3-total-cache' ) . '</h3>
1354
+ <p>' .
1355
+ sprintf(
1356
+ // translators: 1: HTML emphesis open tag, 2: HTML emphesis close tag.
1357
+ esc_html__(
1358
+ 'Your website\'s performance can still be improved by configuring %1$sminify%2$s settings, setting up a %1$sCDN%2$s, and more!',
1359
+ 'w3-total-cache'
1360
+ ),
1361
+ '<strong>',
1362
+ '</strong>'
1363
+ ) . '</p>
1364
+ <p>' .
1365
+ sprintf(
1366
+ // translators: 1: Anchor/link open tag, 2: Anchor/link close tag.
1367
+ esc_html__(
1368
+ 'Please visit %1$sGeneral Settings%2$s to learn more about these features.',
1369
+ 'w3-total-cache'
1370
+ ),
1371
+ '<a href="' . esc_url( admin_url( 'admin.php?page=w3tc_general' ) ) . '">',
1372
+ '</a>'
1373
+ ) . '</p>
1374
+ <h3>' . esc_html__( 'Need help?', 'w3-total-cache' ) . '</h3>
1375
+ <p>' .
1376
+ sprintf(
1377
+ // translators: 1: Anchor/link open tag, 2: Anchor/link close tag.
1378
+ esc_html__(
1379
+ 'We\'re here to help you! Visit our %1$sSupport Center%2$s for helpful information and to ask questions.',
1380
+ 'w3-total-cache'
1381
+ ),
1382
+ '<a href="' . esc_url( 'https://www.boldgrid.com/support/w3-total-cache/' ) . '" target="_blank">',
1383
+ '</a>'
1384
+ ) . '</p>',
1385
+ ),
1386
+ ),
1387
+ );
1388
+ }
1389
+ }
Util_Http.php CHANGED
@@ -103,4 +103,112 @@ class Util_Http {
103
 
104
  return $upload_info;
105
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  }
103
 
104
  return $upload_info;
105
  }
106
+
107
+ /**
108
+ * Test the time to first byte.
109
+ *
110
+ * @param string $url URL address.
111
+ * @param bool $nocache Whether or not to request no cache response, by sending a Cache-Control header.
112
+ * @return float|false Time in seconds until the first byte is about to be transferred or false on error.
113
+ */
114
+ public static function ttfb( $url, $nocache = false ) {
115
+ $ch = curl_init( esc_url( $url ) ); // phpcs:ignore WordPress.WP.AlternativeFunctions
116
+ $pass = (bool) $ch;
117
+ $ttfb = false;
118
+ $opts = array(
119
+ CURLOPT_FORBID_REUSE => 1,
120
+ CURLOPT_FRESH_CONNECT => 1,
121
+ CURLOPT_HEADER => 0,
122
+ CURLOPT_RETURNTRANSFER => 1,
123
+ CURLOPT_FOLLOWLOCATION => 1,
124
+ CURLOPT_SSL_VERIFYPEER => false,
125
+ CURLOPT_USERAGENT => 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ),
126
+ );
127
+
128
+ if ( $nocache ) {
129
+ $opts[ CURLOPT_HTTPHEADER ] = array(
130
+ 'Cache-Control: no-cache',
131
+ 'Pragma: no-cache',
132
+ );
133
+
134
+ $qs_arr = explode( '&', wp_parse_url( $url, PHP_URL_QUERY ) );
135
+ array_push( $qs_arr, 'time=' . microtime( true ) );
136
+
137
+ $opts[ CURLOPT_URL ] = $url . '?' . implode( '&', $qs_arr );
138
+ }
139
+
140
+ if ( $ch ) {
141
+ $pass = curl_setopt_array( $ch, $opts ); // phpcs:ignore WordPress.WP.AlternativeFunctions
142
+ }
143
+
144
+ if ( $pass ) {
145
+ $pass = (bool) curl_exec( $ch ); // phpcs:ignore WordPress.WP.AlternativeFunctions
146
+ }
147
+
148
+ if ( $pass ) {
149
+ $ttfb = curl_getinfo( $ch, CURLINFO_STARTTRANSFER_TIME ); // phpcs:ignore WordPress.WP.AlternativeFunctions
150
+ }
151
+
152
+ if ( $ch ) {
153
+ curl_close( $ch ); // phpcs:ignore WordPress.WP.AlternativeFunctions
154
+ }
155
+
156
+ return $ttfb;
157
+ }
158
+
159
+ /**
160
+ * Retrieve HTTP headers.
161
+ *
162
+ * @param string $url URL address.
163
+ * @return array
164
+ */
165
+ public static function get_headers( $url ) {
166
+ $ch = curl_init( $url ); // phpcs:ignore WordPress.WP.AlternativeFunctions
167
+ $pass = (bool) $ch;
168
+ $headers = array();
169
+ $opts = array(
170
+ CURLOPT_FORBID_REUSE => 1,
171
+ CURLOPT_FRESH_CONNECT => 1,
172
+ CURLOPT_HEADER => 1,
173
+ CURLOPT_RETURNTRANSFER => 1,
174
+ CURLOPT_FOLLOWLOCATION => 1,
175
+ CURLOPT_SSL_VERIFYPEER => false,
176
+ CURLOPT_USERAGENT => 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ),
177
+ CURLOPT_HTTPHEADER => array(
178
+ 'Cache-Control: no-cache',
179
+ 'Pragma: no-cache',
180
+ ),
181
+ );
182
+
183
+ if ( $pass ) {
184
+ $pass = curl_setopt_array( $ch, $opts ); // phpcs:ignore WordPress.WP.AlternativeFunctions
185
+ }
186
+
187
+ if ( $pass ) {
188
+ $response = curl_exec( $ch ); // phpcs:ignore WordPress.WP.AlternativeFunctions
189
+ }
190
+
191
+ if ( $response ) {
192
+ $header_size = curl_getinfo( $ch, CURLINFO_HEADER_SIZE ); // phpcs:ignore WordPress.WP.AlternativeFunctions
193
+ $header = substr( $response, 0, $header_size );
194
+
195
+ foreach ( explode( "\r\n", $header ) as $index => $line ) {
196
+ if ( 0 === $index ) {
197
+ $headers['http_code'] = $line;
198
+ $http_code_arr = explode( ' ', $line );
199
+ $headers['protocol'] = $http_code_arr[0];
200
+ $headers['status'] = $http_code_arr[1];
201
+ } elseif ( ! empty( $line ) && false !== strpos( $line, ':' ) ) {
202
+ list ( $key, $value ) = explode( ': ', $line );
203
+ $headers[ $key ] = $value;
204
+ }
205
+ }
206
+ }
207
+
208
+ if ( $ch ) {
209
+ curl_close( $ch ); // phpcs:ignore WordPress.WP.AlternativeFunctions
210
+ }
211
+
212
+ return $headers;
213
+ }
214
  }
Util_PageUrls.php CHANGED
@@ -440,7 +440,6 @@ class Util_PageUrls {
440
  }
441
  $pages_urls[$key] = $full_urls;
442
  }
443
-
444
  return $pages_urls[$key];
445
  }
446
 
440
  }
441
  $pages_urls[$key] = $full_urls;
442
  }
 
443
  return $pages_urls[$key];
444
  }
445
 
inc/lightbox/self_test.php CHANGED
@@ -269,7 +269,7 @@ if ( Util_Environment::is_apache() ):
269
  <?php foreach ( $modules as $module ): ?>
270
  <li>
271
  <?php echo $module; ?>:
272
- <?php if ( $apache_modules ): ?>
273
  <?php if ( in_array( $module, $apache_modules ) ): ?>
274
  <span style="background-color: #33cc33"><?php _e( 'Installed', 'w3-total-cache' ); ?></span>
275
  <?php else: ?>
269
  <?php foreach ( $modules as $module ): ?>
270
  <li>
271
  <?php echo $module; ?>:
272
+ <?php if ( ! empty( $apache_modules ) ): ?>
273
  <?php if ( in_array( $module, $apache_modules ) ): ?>
274
  <span style="background-color: #33cc33"><?php _e( 'Installed', 'w3-total-cache' ); ?></span>
275
  <?php else: ?>
inc/options/common/header.php CHANGED
@@ -171,7 +171,5 @@ $licensing_visible = ( ( !Util_Environment::is_wpmu() || is_network_admin() ) &&
171
  </p>
172
  <?php
173
  break;
174
- ?>
175
- <?php
176
  }
177
  ?>
171
  </p>
172
  <?php
173
  break;
 
 
174
  }
175
  ?>
inc/options/pgcache.php CHANGED
@@ -460,7 +460,7 @@ if ( $this->_config->get_string( 'pgcache.engine' ) == 'memcached' ||
460
  w3tc-data-validator="regexps"
461
  <?php Util_Ui::sealing_disabled( 'pgcache.' ) ?>
462
  cols="40" rows="5"><?php echo esc_textarea( implode( "\r\n", $this->_config->get_array( 'pgcache.accept.uri' ) ) ); ?></textarea>
463
- <p class="description"><?php _e( 'Cache the specified pages even if they don\'t have tailing slash.', 'w3-total-cache' ); ?></p>
464
  </td>
465
  </tr>
466
  <?php endif; ?>
460
  w3tc-data-validator="regexps"
461
  <?php Util_Ui::sealing_disabled( 'pgcache.' ) ?>
462
  cols="40" rows="5"><?php echo esc_textarea( implode( "\r\n", $this->_config->get_array( 'pgcache.accept.uri' ) ) ); ?></textarea>
463
+ <p class="description"><?php _e( 'Cache the specified pages even if they don\'t have trailing slash.', 'w3-total-cache' ); ?></p>
464
  </td>
465
  </tr>
466
  <?php endif; ?>
inc/wizard/template.php ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: template.php
4
+ *
5
+ * @since 2.0.0
6
+ *
7
+ * @package W3TC
8
+ * @subpackage W3TC\Wizard
9
+ */
10
+
11
+ namespace W3TC\Wizard;
12
+
13
+ if ( ! defined( 'W3TC' ) ) {
14
+ die();
15
+ }
16
+
17
+ /**
18
+ * Class: Template
19
+ *
20
+ * Wizard template class.
21
+ *
22
+ * @since 2.0.0
23
+ */
24
+ class Template {
25
+ /**
26
+ * Configuration.
27
+ *
28
+ * @since 2.0.0
29
+ *
30
+ * @var array
31
+ */
32
+ private $config = array();
33
+
34
+
35
+ /**
36
+ * Constructor.
37
+ *
38
+ * @since 2.0.0
39
+ *
40
+ * @see self::add_hooks();
41
+ *
42
+ * @param array $config Configuration.
43
+ */
44
+ public function __construct( array $config ) {
45
+ $this->config = $config;
46
+
47
+ $this->add_hooks();
48
+ }
49
+
50
+ /**
51
+ * Render the wizard.
52
+ *
53
+ * @since 2.0.0
54
+ *
55
+ * @see self::enqueue_scripts()
56
+ * @see self::enqueue_styles()
57
+ */
58
+ public function render() {
59
+ $this->enqueue_scripts();
60
+ $this->enqueue_styles();
61
+
62
+ $allowed_html = array(
63
+ 'a' => array(
64
+ 'href' => array(),
65
+ 'id' => array(),
66
+ 'target' => array(),
67
+ ),
68
+ 'br' => array(),
69
+ 'div' => array(
70
+ 'class' => array(),
71
+ 'id' => array(),
72
+ ),
73
+ 'em' => array(),
74
+ 'h3' => array(),
75
+ 'input' => array(
76
+ 'checked' => array(),
77
+ 'class' => array(),
78
+ 'data-choice' => array(),
79
+ 'id' => array(),
80
+ 'name' => array(),
81
+ 'type' => array(),
82
+ 'value' => array(),
83
+ ),
84
+ 'label' => array(
85
+ 'for' => array(),
86
+ ),
87
+ 'p' => array(
88
+ 'class' => array(),
89
+ 'id' => array(),
90
+ ),
91
+ 'span' => array(
92
+ 'class' => array(),
93
+ 'id' => array(),
94
+ ),
95
+ 'strong' => array(),
96
+ 'table' => array(
97
+ 'class' => array(),
98
+ 'id' => array(),
99
+ ),
100
+ 'tbody' => array(),
101
+ 'td' => array(),
102
+ 'th' => array(),
103
+ 'thead' => array(),
104
+ 'tr' => array(),
105
+ );
106
+
107
+ ?>
108
+
109
+ <div id="w3tc-wizard-container">
110
+
111
+ <div id="w3tc_wizard_header">
112
+ <img id="w3tc_wizard_icon" src="<?php echo esc_url( plugins_url( '/w3-total-cache/pub/img/w3tc_cube-shadow.png' ) ); ?>" />
113
+ <div id="w3tc_wizard_title">
114
+ <span>TOTAL</span> <span>CACHE</span><span>:</span> <span><?php echo esc_html( $this->config['title'] ); ?></span>
115
+ </div>
116
+ </div>
117
+
118
+ <div id="w3tc_wizard_content">
119
+
120
+ <ul id="w3tc-options-menu">
121
+ <?php
122
+ foreach ( $this->config['steps'] as $number => $step ) {
123
+ $number++;
124
+ $element_id = 'w3tc-wizard-step-' . ( isset( $step['id'] ) ? $step['id'] : $number );
125
+ if ( isset( $this->config['steps_location'] ) && 'left' === $this->config['steps_location'] ) {
126
+ ?>
127
+ <li id="<?php echo esc_attr( $element_id ); ?>">
128
+ <?php echo esc_html( $step['text'] ); ?>
129
+ </li>
130
+ <?php
131
+ } else {
132
+ ?>
133
+ <li id="<?php echo esc_attr( $element_id ); ?>"><?php echo esc_html( $number ); ?></li>
134
+ <li id="<?php echo esc_attr( $element_id ); ?>-text"><?php echo esc_html( $step['text'] ); ?></li>
135
+ <?php
136
+ }
137
+ }
138
+ ?>
139
+ </ul>
140
+
141
+ <?php
142
+ // The first slide is visible.
143
+ $hidden = '';
144
+
145
+ foreach ( $this->config['slides'] as $number => $slide ) {
146
+ $number++;
147
+ $element_id = 'w3tc-wizard-slide-' . ( isset( $slide['id'] ) ? $slide['id'] : $number );
148
+ ?>
149
+ <div id="<?php echo esc_attr( $element_id ); ?>" class="w3tc-wizard-slides<?php echo esc_attr( $hidden ); ?>">
150
+ <h3><?php echo wp_kses( $slide['headline'], $allowed_html ); ?></h3>
151
+ <?php echo wp_kses( $slide['markup'], $allowed_html ); ?>
152
+ </div>
153
+ <?php
154
+ // All subsequent slides are hidden.
155
+ $hidden = ' hidden';
156
+ }
157
+
158
+ unset( $hidden );
159
+ ?>
160
+
161
+ </div>
162
+
163
+ <div id="w3tc_wizard_footer">
164
+ <div id="w3tc-wizard-buttons">
165
+ <span>
166
+ <button id="w3tc-wizard-skip" class="w3tc-wizard-buttons"><?php esc_html_e( 'SKIP', 'w3-total-cache' ); ?></button>
167
+ </span>
168
+ <span id="w3tc-wizard-previous-span" class="hidden">
169
+ <button id="w3tc-wizard-previous" class="w3tc-wizard-buttons"><?php esc_html_e( 'PREVIOUS', 'w3-total-cache' ); ?></button>
170
+ </span>
171
+ <span>
172
+ <button id="w3tc-wizard-next" class="w3tc-wizard-buttons"><?php esc_html_e( 'NEXT', 'w3-total-cache' ); ?></button>
173
+ </span>
174
+ <span id="w3tc-wizard-dashboard-span" class="hidden">
175
+ <button id="w3tc-wizard-dashboard" class="w3tc-wizard-buttons"><?php esc_html_e( 'DASHBOARD', 'w3-total-cache' ); ?></button>
176
+ </span>
177
+ </div>
178
+ </div>
179
+
180
+ <?php wp_nonce_field( 'w3tc_wizard' ); ?>
181
+ <div id="test-results" class="hidden"></div>
182
+ </div>
183
+
184
+ <?php
185
+ require W3TC_INC_DIR . '/options/common/footer.php';
186
+ }
187
+
188
+ /**
189
+ * Add hooks.
190
+ *
191
+ * @since 2.0.0
192
+ */
193
+ private function add_hooks() {
194
+ if ( isset( $this->config['actions'] ) && is_array( $this->config['actions'] ) ) {
195
+ foreach ( $this->config['actions'] as $action ) {
196
+ add_action(
197
+ $action['tag'],
198
+ $action['function'],
199
+ empty( $action['priority'] ) ? 10 : $action['priority'],
200
+ empty( $action['accepted_args'] ) ? 1 : $action['accepted_args']
201
+ );
202
+ }
203
+ }
204
+
205
+ if ( isset( $this->config['filters'] ) && is_array( $this->config['filters'] ) ) {
206
+ foreach ( $this->config['filters'] as $filter ) {
207
+ add_filter(
208
+ $filter['tag'],
209
+ $filter['function'],
210
+ empty( $filter['priority'] ) ? 10 : $filter['priority'],
211
+ empty( $filter['accepted_args'] ) ? 1 : $filter['accepted_args']
212
+ );
213
+ }
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Rnqueue scripts.
219
+ *
220
+ * @since 2.0.0
221
+ */
222
+ private function enqueue_scripts() {
223
+ wp_enqueue_script(
224
+ 'w3tc_wizard',
225
+ esc_url( plugin_dir_url( dirname( dirname( __FILE__ ) ) ) . 'pub/js/wizard.js' ),
226
+ array( 'jquery' ),
227
+ W3TC_VERSION,
228
+ false
229
+ );
230
+
231
+ if ( isset( $this->config['scripts'] ) && is_array( $this->config['scripts'] ) ) {
232
+ foreach ( $this->config['scripts'] as $script ) {
233
+ wp_register_script(
234
+ $script['handle'],
235
+ $script['src'],
236
+ is_array( $script['deps'] ) ? $script['deps'] : array(),
237
+ empty( $script['version'] ) ? gmdate( 'YmdHm' ) : $script['version'],
238
+ ! empty( $script['in_footer'] )
239
+ );
240
+
241
+ if ( isset( $script['localize'] ) && is_array( $script['localize'] ) ) {
242
+ wp_localize_script(
243
+ $script['handle'],
244
+ $script['localize']['object_name'],
245
+ (array) $script['localize']['data']
246
+ );
247
+ }
248
+
249
+ wp_enqueue_script( $script['handle'] );
250
+ }
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Enqueue styles.
256
+ *
257
+ * @since 2.0.0
258
+ */
259
+ private function enqueue_styles() {
260
+ wp_enqueue_style(
261
+ 'w3tc_wizard',
262
+ esc_url( plugin_dir_url( dirname( dirname( __FILE__ ) ) ) . 'pub/css/wizard.css' ),
263
+ array(),
264
+ 'all'
265
+ );
266
+
267
+ if ( isset( $this->config['styles'] ) && is_array( $this->config['styles'] ) ) {
268
+ foreach ( $this->config['styles'] as $style ) {
269
+ wp_enqueue_style(
270
+ $style['handle'],
271
+ $style['src'],
272
+ isset( $style['deps'] ) && is_array( $style['deps'] ) ?
273
+ $style['deps'] : array(),
274
+ ! empty( $style['version'] ) ? $style['version'] : gmdate( 'YmdHm' ),
275
+ ! empty( $style['media'] ) ? $style['media'] : 'all'
276
+ );
277
+ }
278
+ }
279
+ }
280
+ }
pub/css/options.css CHANGED
@@ -665,4 +665,26 @@ table:not(.w3tc-pro-feature) .w3tc-gopro:after {
665
  #w3tc #w3tc_dashboard_banner .inside > p:first-of-type {
666
  padding-top: initial;
667
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
668
  }
665
  #w3tc #w3tc_dashboard_banner .inside > p:first-of-type {
666
  padding-top: initial;
667
  }
668
+ }
669
+
670
+
671
+ /**
672
+ * Labels.
673
+ */
674
+
675
+ .w3tc-label {
676
+ color: #fff;
677
+ padding: 0px 4px;
678
+ border-radius: 5px;
679
+ display: inline-block;
680
+ font-size: 11px;
681
+ }
682
+
683
+ .w3tc-label-success {
684
+ background: green;
685
+ }
686
+
687
+ .w3tc-label-danger {
688
+ /* Same color as "update plugin count" in WP Dashboard left nav. */
689
+ background: #ca4a1f;;
690
  }
pub/css/setup-guide.css ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ .w3tc-setupguide-table th,
3
+ .w3tc-setupguide-table td {
4
+ text-align: left;
5
+ }
6
+
7
+ #w3tc-dbc-table th,
8
+ #w3tc-objcache-table th,
9
+ #w3tc-browsercache-table td {
10
+ white-space: nowrap;
11
+ }
12
+
13
+ .w3tc-option-disabled {
14
+ color: darkgray;
15
+ }
16
+
17
+ #w3tc-browsercache-table tr {
18
+ vertical-align: top;
19
+ }
20
+
21
+ .w3tc-option-recommended {
22
+ font-size: 0.9em;
23
+ }
pub/css/wizard.css ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Main container */
2
+ #w3tc-wizard-container {
3
+ background: #fff;
4
+ padding: 10px;
5
+ border-radius: 8px;
6
+ max-width: 900px;
7
+ }
8
+
9
+ /* Header */
10
+ #w3tc_wizard_header {
11
+ background: #0e1920;
12
+ border-bottom: 6px solid #cdeae7;
13
+ height: 6em;
14
+ position: relative;
15
+ }
16
+
17
+ /* Main title */
18
+ #w3tc_wizard_title {
19
+ color: #fff;
20
+ position: absolute;
21
+ bottom: 0;
22
+ }
23
+
24
+ /* Title text: "TOTAL CACHE:" */
25
+ #w3tc_wizard_title > span:nth-of-type(1),
26
+ #w3tc_wizard_title > span:nth-of-type(2),
27
+ #w3tc_wizard_title > span:nth-of-type(3) {
28
+ font-size: 2.5em;
29
+ }
30
+
31
+ /* Title text: "CACHE" */
32
+ #w3tc_wizard_title > span:nth-of-type(2) {
33
+ color: #30bec4;
34
+ }
35
+
36
+ /* Title text: "$this->config['title']" */
37
+ #w3tc_wizard_title > span:nth-of-type(4) {
38
+ font-size: 2.1em;
39
+ font-style: italic;
40
+ }
41
+
42
+ /* Wizard icon (w3 cube with shadow) */
43
+ #w3tc_wizard_icon {
44
+ position: absolute;
45
+ top: 10px;
46
+ left: -2px;
47
+ }
48
+
49
+ /**
50
+ * Left nav / steps.
51
+ */
52
+
53
+ ul#w3tc-options-menu {
54
+ position: absolute;
55
+ left: 0;
56
+ top: 30px;
57
+ margin: 0;
58
+ }
59
+
60
+ #w3tc-options-menu li {
61
+ display: block;
62
+ padding: 5px;
63
+ margin: 0;
64
+ border: 1px solid #ddd;
65
+ border-bottom: 0;
66
+ }
67
+
68
+ #w3tc-options-menu li:last-of-type {
69
+ border-bottom: 1px solid #ddd;
70
+ }
71
+
72
+ /* Active step */
73
+ #w3tc-options-menu li.is-active {
74
+ background-color: #0073aa;
75
+ color: #fff;
76
+ }
77
+
78
+ /* Wizard content */
79
+ #w3tc_wizard_content {
80
+ background-image:
81
+ url(../img/moon-bottom-left.png),
82
+ url(../img/moon-bottom-right.png);
83
+ background-size: 15% !Important;
84
+ background-repeat:
85
+ no-repeat,
86
+ no-repeat;
87
+ background-position:
88
+ bottom left,
89
+ bottom right;
90
+ background-size:
91
+ auto,
92
+ auto 60%;
93
+ min-height: 545px;
94
+ padding-bottom: 70px;
95
+ padding-right: 160px;
96
+ position: relative;
97
+ }
98
+
99
+ /* Footer */
100
+ #w3tc_wizard_footer {
101
+ width: 100%;
102
+ }
103
+
104
+ /* Buttons */
105
+ #w3tc-wizard-buttons {
106
+ display: flex;
107
+ }
108
+
109
+ #w3tc-wizard-buttons > span {
110
+ flex: 1;
111
+ }
112
+
113
+ /* All buttons. */
114
+ #w3tc-wizard-buttons > span > button {
115
+ width: 100%;
116
+ border: 0;
117
+ padding: 10px 0;
118
+ cursor: pointer;
119
+ }
120
+
121
+ /* Next and Dashboard buttons. */
122
+ #w3tc-wizard-next:enabled,
123
+ #w3tc-wizard-dashboard {
124
+ background-color: #825772;
125
+ color: #fff;
126
+ }
127
+
128
+ /* Miscellaneous */
129
+ #w3tc_wizard_title,
130
+ #w3tc_wizard_content {
131
+ padding-left: 160px;
132
+ }
133
+
134
+ /* Spinner */
135
+ .spinner.inline {
136
+ float: none;
137
+ visibility: visible;
138
+ vertical-align: top;
139
+ margin-left: 0px;
140
+ }
141
+
142
+ .spinner.spinner-left {
143
+ margin-left: 5px;
144
+ }
145
+
146
+ /* Notices */
147
+ .w3tc_note,
148
+ #setting-error-tgmpa {
149
+ display: none;
150
+ visibility: hidden;
151
+ }
152
+
153
+ .w3tc-notice-recommended {
154
+ padding-top: 5px;
155
+ }
156
+
157
+ .w3tc-notice-recommended .dashicons-lightbulb {
158
+ color: #00a0d2;
159
+ }
160
+
161
+ #w3tc-dbcache-recommended {
162
+ margin: 10px 0px;
163
+ }
164
+
165
+ /* Tables */
166
+ .widefat thead th,
167
+ .widefat td {
168
+ line-height: 1em;
169
+ }
pub/img/moon-bottom-left.png ADDED
Binary file
pub/img/moon-bottom-right.png ADDED
Binary file
pub/img/w3tc_cube-shadow.png ADDED
Binary file
pub/js/lightbox.js CHANGED
@@ -26,7 +26,7 @@ var W3tc_Lightbox = {
26
  me.resize();
27
  });
28
 
29
- this.container.find('.lightbox-close').click(function() {
30
  me.close();
31
  });
32
 
@@ -310,7 +310,7 @@ function w3tc_lightbox_minify_recommendations(nonce) {
310
  lightbox.load('admin.php?page=w3tc_minify&w3tc_test_minify_recommendations&theme_key=' + jQuery(this).val() + '&_wpnonce=' + nonce, lightbox.options.callback);
311
  });
312
 
313
- jQuery('#recom_js_check').click(function() {
314
  if (jQuery('#recom_js_files :checkbox:checked').length) {
315
  jQuery('#recom_js_files :checkbox').removeAttr('checked');
316
  } else {
@@ -320,7 +320,7 @@ function w3tc_lightbox_minify_recommendations(nonce) {
320
  return false;
321
  });
322
 
323
- jQuery('#recom_css_check').click(function() {
324
  if (jQuery('#recom_css_files :checkbox:checked').length) {
325
  jQuery('#recom_css_files :checkbox').removeAttr('checked');
326
  } else {
@@ -330,7 +330,7 @@ function w3tc_lightbox_minify_recommendations(nonce) {
330
  return false;
331
  });
332
 
333
- jQuery('.recom_apply', lightbox.container).click(function() {
334
  var theme = jQuery('#recom_theme').val();
335
 
336
  jQuery('#js_files li').each(function() {
@@ -375,7 +375,7 @@ function w3tc_lightbox_self_test(nonce) {
375
  minHeight: 300,
376
  url: 'admin.php?page=w3tc_dashboard&w3tc_test_self&_wpnonce=' + w3tc_nonce,
377
  callback: function(lightbox) {
378
- jQuery('.button-primary', lightbox.container).click(function() {
379
  lightbox.close();
380
  });
381
  }
@@ -402,14 +402,14 @@ function w3tc_lightbox_upgrade(nonce, data_src, renew_key) {
402
  callback: function(lightbox) {
403
  lightbox.options.height = jQuery('#w3tc-upgrade').outerHeight();
404
 
405
- jQuery('.button-primary', lightbox.container).click(function() {
406
  lightbox.close();
407
  });
408
- jQuery('#w3tc-purchase', lightbox.container).click(function() {
409
  lightbox.close();
410
  w3tc_lightbox_buy_plugin(nonce, data_src, renew_key, client_id);
411
  });
412
- jQuery('#w3tc-purchase-link', lightbox.container).click(function() {
413
  lightbox.close();
414
 
415
  jQuery([document.documentElement, document.body]).animate({
@@ -469,7 +469,7 @@ function w3tc_lightbox_buy_plugin(nonce, data_src, renew_key, client_id) {
469
  attachEvent("onmessage", w3tc_license_listener);
470
  }
471
 
472
- jQuery('.button-primary', lightbox.container).click(function() {
473
  lightbox.close();
474
  });
475
  }
@@ -490,19 +490,19 @@ function w3tc_lightbox_save_licence_key(license_key, nonce, callback) {
490
  }
491
 
492
  jQuery(function() {
493
- jQuery('.button-minify-recommendations').click(function() {
494
  var nonce = jQuery(this).metadata().nonce;
495
  w3tc_lightbox_minify_recommendations(nonce);
496
  return false;
497
  });
498
 
499
- jQuery('.button-self-test').click(function() {
500
  var nonce = jQuery(this).metadata().nonce;
501
  w3tc_lightbox_self_test(nonce);
502
  return false;
503
  });
504
 
505
- jQuery('.button-buy-plugin').click(function() {
506
  var data_src = jQuery(this).data('src');
507
  var nonce = jQuery(this).data('nonce');
508
  if (!nonce) {
26
  me.resize();
27
  });
28
 
29
+ this.container.find('.lightbox-close').on( 'click', function() {
30
  me.close();
31
  });
32
 
310
  lightbox.load('admin.php?page=w3tc_minify&w3tc_test_minify_recommendations&theme_key=' + jQuery(this).val() + '&_wpnonce=' + nonce, lightbox.options.callback);
311
  });
312
 
313
+ jQuery('#recom_js_check').on( 'click', function() {
314
  if (jQuery('#recom_js_files :checkbox:checked').length) {
315
  jQuery('#recom_js_files :checkbox').removeAttr('checked');
316
  } else {
320
  return false;
321
  });
322
 
323
+ jQuery('#recom_css_check').on( 'click', function() {
324
  if (jQuery('#recom_css_files :checkbox:checked').length) {
325
  jQuery('#recom_css_files :checkbox').removeAttr('checked');
326
  } else {
330
  return false;
331
  });
332
 
333
+ jQuery('.recom_apply', lightbox.container).on( 'click', function() {
334
  var theme = jQuery('#recom_theme').val();
335
 
336
  jQuery('#js_files li').each(function() {
375
  minHeight: 300,
376
  url: 'admin.php?page=w3tc_dashboard&w3tc_test_self&_wpnonce=' + w3tc_nonce,
377
  callback: function(lightbox) {
378
+ jQuery('.button-primary', lightbox.container).on( 'click', function() {
379
  lightbox.close();
380
  });
381
  }
402
  callback: function(lightbox) {
403
  lightbox.options.height = jQuery('#w3tc-upgrade').outerHeight();
404
 
405
+ jQuery('.button-primary', lightbox.container).on( 'click', function() {
406
  lightbox.close();
407
  });
408
+ jQuery('#w3tc-purchase', lightbox.container).on( 'click', function() {
409
  lightbox.close();
410
  w3tc_lightbox_buy_plugin(nonce, data_src, renew_key, client_id);
411
  });
412
+ jQuery('#w3tc-purchase-link', lightbox.container).on( 'click', function() {
413
  lightbox.close();
414
 
415
  jQuery([document.documentElement, document.body]).animate({
469
  attachEvent("onmessage", w3tc_license_listener);
470
  }
471
 
472
+ jQuery('.button-primary', lightbox.container).on( 'click', function() {
473
  lightbox.close();
474
  });
475
  }
490
  }
491
 
492
  jQuery(function() {
493
+ jQuery('.button-minify-recommendations').on( 'click', function() {
494
  var nonce = jQuery(this).metadata().nonce;
495
  w3tc_lightbox_minify_recommendations(nonce);
496
  return false;
497
  });
498
 
499
+ jQuery('.button-self-test').on( 'click', function() {
500
  var nonce = jQuery(this).metadata().nonce;
501
  w3tc_lightbox_self_test(nonce);
502
  return false;
503
  });
504
 
505
+ jQuery('.button-buy-plugin').on( 'click', function() {
506
  var data_src = jQuery(this).data('src');
507
  var nonce = jQuery(this).data('nonce');
508
  if (!nonce) {
pub/js/options.js CHANGED
@@ -182,7 +182,7 @@ function w3tc_toggle(name, check) {
182
 
183
  var id = '#' + name, cls = '.' + name;
184
 
185
- jQuery(cls).click(function() {
186
  var checked = check;
187
 
188
  jQuery(cls).each(function() {
@@ -202,7 +202,7 @@ function w3tc_toggle(name, check) {
202
  }
203
  });
204
 
205
- jQuery(id).click(function() {
206
  var checked = jQuery(this).is(':checked');
207
  jQuery(cls).each(function() {
208
  if (checked) {
@@ -219,7 +219,7 @@ function w3tc_toggle2(name, dependent_ids) {
219
  for (n = 0; n < dependent_ids.length; n++)
220
  dependants += (n > 0 ? ',' : '') + '#' + dependent_ids[n];
221
 
222
- jQuery(dependants).click(function() {
223
  var total_checked = true;
224
 
225
  jQuery(dependants).each(function() {
@@ -236,7 +236,7 @@ function w3tc_toggle2(name, dependent_ids) {
236
  }
237
  });
238
 
239
- jQuery(id).click(function() {
240
  var checked = jQuery(this).is(':checked');
241
  jQuery(dependants).each(function() {
242
  if (checked) {
@@ -300,7 +300,7 @@ function w3tc_security_headers() {
300
  }
301
  };
302
 
303
- jQuery('#browsercache_security_hsts_directive,#browsercache_security_xfo_directive,#browsercache_security_xss_directive,#browsercache_security_pkp_extra,#browsercache_security_pkp_report_only').change(
304
  function() {
305
  jQuery('#' + jQuery(this).attr('id') + '_description').html('<i>' + directive_description[jQuery(this).attr('id')][jQuery(this).val()] + '</i>');
306
  if (jQuery(this).attr('id') == 'browsercache_security_xfo_directive') {
@@ -318,7 +318,7 @@ function w3tc_security_headers() {
318
  } else {
319
  jQuery('#browsercache_security_xfo_allow').hide();
320
  }
321
- jQuery('#browsercache_security_hsts_directive,#browsercache_security_xfo_directive,#browsercache_security_xss_directive,#browsercache_security_pkp_extra,#browsercache_security_pkp_report_only').change();
322
  }
323
  }
324
 
@@ -331,18 +331,18 @@ function w3tc_csp_reference() {
331
  url: ajaxurl + '?action=w3tc_ajax&_wpnonce=' + w3tc_nonce +
332
  '&w3tc_action=browsercache_quick_reference',
333
  });
334
- jQuery('div#overlay,.lightbox-content').click(function() {
335
  W3tc_Lightbox.close();
336
  });
337
  }
338
 
339
  jQuery(function() {
340
  // general page
341
- jQuery('.w3tc_read_technical_info').click(function() {
342
  jQuery('.w3tc_technical_info').toggle();
343
  });
344
 
345
- jQuery('#plugin_license_key_verify').click(function() {
346
  jQuery('.w3tc_license_verification').html("Checking...");
347
 
348
  var license_key = jQuery('#plugin_license_key').val();
@@ -382,7 +382,7 @@ jQuery(function() {
382
  if(jQuery('#pgcache__cache__nginx_handle_xml').is('*'))
383
  jQuery('#pgcache__cache__nginx_handle_xml').attr('checked',jQuery('#pgcache__cache__feed').is(':checked'));
384
 
385
- jQuery('#pgcache__cache__feed').change(function(){
386
  if(jQuery('#pgcache__cache__nginx_handle_xml').is('*'))
387
  jQuery('#pgcache__cache__nginx_handle_xml').attr('checked',this.checked);
388
  });
@@ -426,15 +426,15 @@ jQuery(function() {
426
  w3tc_minify_js_theme(jQuery('#js_themes').val());
427
  w3tc_minify_css_theme(jQuery('#css_themes').val());
428
 
429
- jQuery('#minify__html__enable').click(function() {
430
  w3tc_input_enable('.html_enabled', this.checked);
431
  });
432
 
433
- jQuery('#minify__js__enable').click(function() {
434
  w3tc_input_enable('.js_enabled', jQuery(this).is(':checked'));
435
  });
436
 
437
- jQuery('#minify__css__enable').click(function() {
438
  w3tc_input_enable('.css_enabled', jQuery(this).is(':checked'));
439
  });
440
 
@@ -487,23 +487,23 @@ jQuery(function() {
487
  return false;
488
  });
489
 
490
- jQuery('#js_file_add').click(function() {
491
  w3tc_minify_js_file_add(jQuery('#js_themes').val(), 'default', 'include', '');
492
  });
493
 
494
- jQuery('#css_file_add').click(function() {
495
  w3tc_minify_css_file_add(jQuery('#css_themes').val(), 'default', '');
496
  });
497
 
498
- jQuery('#js_themes').change(function() {
499
  w3tc_minify_js_theme(jQuery(this).val());
500
  });
501
 
502
- jQuery('#css_themes').change(function() {
503
  w3tc_minify_css_theme(jQuery(this).val());
504
  });
505
 
506
- jQuery('#minify_form').submit(function() {
507
  var js = [], css = [], invalid_js = [], invalid_css = [], duplicate = false, query_js = [], query_css = [];
508
 
509
  jQuery('#js_files :text').each(function() {
@@ -593,7 +593,7 @@ jQuery(function() {
593
  });
594
 
595
  // CDN
596
- jQuery('.w3tc-tab').click(function() {
597
  jQuery('.w3tc-tab-content').hide();
598
  jQuery(this.rel).show();
599
  });
@@ -603,44 +603,44 @@ jQuery(function() {
603
  w3tc_input_enable('#cdn_reject_roles input[type=checkbox]', jQuery('#cdn__reject__logged_roles:checked').length);
604
  });
605
 
606
- jQuery('#cdn_export_library').click(function() {
607
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_export_library&_wpnonce=' + jQuery(this).metadata().nonce, 'cdn_export_library');
608
  });
609
 
610
- jQuery('#cdn_import_library').click(function() {
611
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_import_library&_wpnonce=' + jQuery(this).metadata().nonce, 'cdn_import_library');
612
  });
613
 
614
- jQuery('#cdn_queue').click(function() {
615
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_queue&_wpnonce=' + jQuery(this).metadata().nonce, 'cdn_queue');
616
  });
617
 
618
- jQuery('#cdn_rename_domain').click(function() {
619
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_rename_domain&_wpnonce=' + jQuery(this).metadata().nonce, 'cdn_rename_domain');
620
  });
621
 
622
- jQuery('#cdn_purge').click(function() {
623
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_purge&_wpnonce=' + jQuery(this).metadata().nonce, 'cdn_purge');
624
  });
625
 
626
- jQuery('.cdn_export').click(function() {
627
  var metadata = jQuery(this).metadata();
628
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_export&cdn_export_type=' + metadata.type + '&_wpnonce=' + metadata.nonce, 'cdn_export_' + metadata.type);
629
  });
630
 
631
- jQuery('#validate_cdn_key').click(function() {
632
  var me = jQuery(this);
633
  var metadata = me.metadata();
634
  w3tc_validate_cdn_key_result(metadata.type, metadata.nonce);
635
  });
636
 
637
- jQuery('#use_poll_zone').click(function() {
638
  var me = jQuery(this);
639
  var metadata = me.metadata();
640
  w3tc_use_poll_zone(metadata.type, metadata.nonce);
641
  });
642
 
643
- jQuery('#cdn_test').click(function() {
644
  var me = jQuery(this);
645
  var metadata = me.metadata();
646
  var cnames = w3tc_cdn_get_cnames();
@@ -956,7 +956,7 @@ jQuery(function() {
956
  });
957
  });
958
 
959
- jQuery('#memcached_test').click(function() {
960
  var status = jQuery('#memcached_test_status');
961
  status.removeClass('w3tc-error');
962
  status.removeClass('w3tc-success');
@@ -976,7 +976,7 @@ jQuery(function() {
976
  });
977
  });
978
 
979
- jQuery('.w3tc_common_redis_test').click(function() {
980
  var status = jQuery('.w3tc_common_redis_test_result');
981
  status.removeClass('w3tc-error');
982
  status.removeClass('w3tc-success');
@@ -998,7 +998,7 @@ jQuery(function() {
998
  });
999
  });
1000
 
1001
- jQuery('.minifier_test').click(function() {
1002
  var me = jQuery(this);
1003
  var metadata = me.metadata();
1004
  var params = {
@@ -1065,7 +1065,7 @@ jQuery(function() {
1065
  }
1066
  });
1067
 
1068
- jQuery('#cdn_form').submit(function() {
1069
  var cnames = [], ret = true;
1070
 
1071
  jQuery('#cdn_cnames input[type=text]').each(function() {
@@ -1087,7 +1087,7 @@ jQuery(function() {
1087
  });
1088
 
1089
  // mobile tab
1090
- jQuery('#mobile_form').submit(function() {
1091
  var error = false;
1092
 
1093
  jQuery('#mobile_groups li').each(function() {
@@ -1139,7 +1139,7 @@ jQuery(function() {
1139
  }
1140
  });
1141
 
1142
- jQuery('#mobile_add').click(function() {
1143
  var group = prompt('Enter group name (only "0-9", "a-z", "_" symbols are allowed).');
1144
 
1145
  if (group !== null) {
@@ -1189,7 +1189,7 @@ jQuery(function() {
1189
  w3tc_mobile_groups_clear();
1190
 
1191
  // referrer tab
1192
- jQuery('#referrer_form').submit(function() {
1193
  var error = false;
1194
 
1195
  jQuery('#referrer_groups li').each(function() {
@@ -1241,7 +1241,7 @@ jQuery(function() {
1241
  }
1242
  });
1243
 
1244
- jQuery('#referrer_add').click(function() {
1245
  var group = prompt('Enter group name (only "0-9", "a-z", "_" symbols are allowed).');
1246
 
1247
  if (group !== null) {
@@ -1326,7 +1326,7 @@ jQuery(function() {
1326
  }
1327
 
1328
  // show hide rules
1329
- jQuery('.w3tc-show-rules').click(function() {
1330
  var btn = jQuery(this), rules = btn.parent().find('.w3tc-rules');
1331
 
1332
  if (rules.is(':visible')) {
@@ -1340,7 +1340,7 @@ jQuery(function() {
1340
 
1341
 
1342
  // show hide missing files
1343
- jQuery('.w3tc-show-required-changes').click(function() {
1344
  var btn = jQuery(this), rules = jQuery('.w3tc-required-changes');
1345
 
1346
  if (rules.is(':visible')) {
@@ -1353,7 +1353,7 @@ jQuery(function() {
1353
  });
1354
 
1355
  // show hide missing files
1356
- jQuery('.w3tc-show-ftp-form').click(function() {
1357
  var btn = jQuery(this), rules = jQuery('.w3tc-ftp-form');
1358
 
1359
  if (rules.is(':visible')) {
@@ -1366,7 +1366,7 @@ jQuery(function() {
1366
  });
1367
 
1368
  // show hide missing files
1369
- jQuery('.w3tc-show-technical-info').click(function() {
1370
  var btn = jQuery(this), info = jQuery('.w3tc-technical-info');
1371
 
1372
  if (info.is(':visible')) {
@@ -1384,7 +1384,7 @@ jQuery(function() {
1384
  });
1385
 
1386
  // toggle hiddent content
1387
- jQuery('.w3tc_link_more').click(function() {
1388
  var target_class = jQuery(this).metadata().for_class;
1389
  jQuery('.' + target_class).slideToggle();
1390
  });
@@ -1407,13 +1407,13 @@ jQuery(function() {
1407
  jQuery('body').on('click', '.w3tc-button-save', w3tc_beforeupload_unbind);
1408
 
1409
 
1410
- jQuery('.contextual-help-tabs ul li a').click(function() {
1411
  var id = jQuery(this).attr('aria-controls');
1412
  var i = jQuery('#' + id + ' .w3tchelp_content');
1413
  w3tc_load_faq_section(i);
1414
  });
1415
 
1416
- jQuery('#contextual-help-link').click(function() {
1417
  var i = jQuery('.w3tchelp_content').first();
1418
  w3tc_load_faq_section(i);
1419
  });
@@ -1443,7 +1443,7 @@ jQuery(function() {
1443
  }
1444
 
1445
  // extensions page
1446
- jQuery('.w3tc_extensions_manage_input_checkall').click(function(v) {
1447
  var c = jQuery(this).is(':checked');
1448
 
1449
  jQuery('.w3tc_extensions_manage_input_checkall').prop('checked', c);
@@ -1454,7 +1454,7 @@ jQuery(function() {
1454
  });
1455
 
1456
  // gopro block
1457
- jQuery('.w3tc-gopro-more').click(function(e) {
1458
  e.preventDefault();
1459
  if (!jQuery(this).data('expanded')) {
1460
  jQuery(this).data('expanded', '1');
182
 
183
  var id = '#' + name, cls = '.' + name;
184
 
185
+ jQuery(cls).on( 'click', function() {
186
  var checked = check;
187
 
188
  jQuery(cls).each(function() {
202
  }
203
  });
204
 
205
+ jQuery(id).on( 'click', function() {
206
  var checked = jQuery(this).is(':checked');
207
  jQuery(cls).each(function() {
208
  if (checked) {
219
  for (n = 0; n < dependent_ids.length; n++)
220
  dependants += (n > 0 ? ',' : '') + '#' + dependent_ids[n];
221
 
222
+ jQuery(dependants).on( 'click', function() {
223
  var total_checked = true;
224
 
225
  jQuery(dependants).each(function() {
236
  }
237
  });
238
 
239
+ jQuery(id).on( 'click', function() {
240
  var checked = jQuery(this).is(':checked');
241
  jQuery(dependants).each(function() {
242
  if (checked) {
300
  }
301
  };
302
 
303
+ jQuery('#browsercache_security_hsts_directive,#browsercache_security_xfo_directive,#browsercache_security_xss_directive,#browsercache_security_pkp_extra,#browsercache_security_pkp_report_only').on( 'change',
304
  function() {
305
  jQuery('#' + jQuery(this).attr('id') + '_description').html('<i>' + directive_description[jQuery(this).attr('id')][jQuery(this).val()] + '</i>');
306
  if (jQuery(this).attr('id') == 'browsercache_security_xfo_directive') {
318
  } else {
319
  jQuery('#browsercache_security_xfo_allow').hide();
320
  }
321
+ jQuery('#browsercache_security_hsts_directive,#browsercache_security_xfo_directive,#browsercache_security_xss_directive,#browsercache_security_pkp_extra,#browsercache_security_pkp_report_only').on( 'change', );
322
  }
323
  }
324
 
331
  url: ajaxurl + '?action=w3tc_ajax&_wpnonce=' + w3tc_nonce +
332
  '&w3tc_action=browsercache_quick_reference',
333
  });
334
+ jQuery('div#overlay,.lightbox-content').on( 'click', function() {
335
  W3tc_Lightbox.close();
336
  });
337
  }
338
 
339
  jQuery(function() {
340
  // general page
341
+ jQuery('.w3tc_read_technical_info').on( 'click', function() {
342
  jQuery('.w3tc_technical_info').toggle();
343
  });
344
 
345
+ jQuery('#plugin_license_key_verify').on( 'click', function() {
346
  jQuery('.w3tc_license_verification').html("Checking...");
347
 
348
  var license_key = jQuery('#plugin_license_key').val();
382
  if(jQuery('#pgcache__cache__nginx_handle_xml').is('*'))
383
  jQuery('#pgcache__cache__nginx_handle_xml').attr('checked',jQuery('#pgcache__cache__feed').is(':checked'));
384
 
385
+ jQuery('#pgcache__cache__feed').on( 'change', function(){
386
  if(jQuery('#pgcache__cache__nginx_handle_xml').is('*'))
387
  jQuery('#pgcache__cache__nginx_handle_xml').attr('checked',this.checked);
388
  });
426
  w3tc_minify_js_theme(jQuery('#js_themes').val());
427
  w3tc_minify_css_theme(jQuery('#css_themes').val());
428
 
429
+ jQuery('#minify__html__enable').on( 'click', function() {
430
  w3tc_input_enable('.html_enabled', this.checked);
431
  });
432
 
433
+ jQuery('#minify__js__enable').on( 'click', function() {
434
  w3tc_input_enable('.js_enabled', jQuery(this).is(':checked'));
435
  });
436
 
437
+ jQuery('#minify__css__enable').on( 'click', function() {
438
  w3tc_input_enable('.css_enabled', jQuery(this).is(':checked'));
439
  });
440
 
487
  return false;
488
  });
489
 
490
+ jQuery('#js_file_add').on( 'click', function() {
491
  w3tc_minify_js_file_add(jQuery('#js_themes').val(), 'default', 'include', '');
492
  });
493
 
494
+ jQuery('#css_file_add').on( 'click', function() {
495
  w3tc_minify_css_file_add(jQuery('#css_themes').val(), 'default', '');
496
  });
497
 
498
+ jQuery('#js_themes').on( 'change', function() {
499
  w3tc_minify_js_theme(jQuery(this).val());
500
  });
501
 
502
+ jQuery('#css_themes').on( 'change', function() {
503
  w3tc_minify_css_theme(jQuery(this).val());
504
  });
505
 
506
+ jQuery('#minify_form').on( 'submit', function() {
507
  var js = [], css = [], invalid_js = [], invalid_css = [], duplicate = false, query_js = [], query_css = [];
508
 
509
  jQuery('#js_files :text').each(function() {
593
  });
594
 
595
  // CDN
596
+ jQuery('.w3tc-tab').on( 'click', function() {
597
  jQuery('.w3tc-tab-content').hide();
598
  jQuery(this.rel).show();
599
  });
603
  w3tc_input_enable('#cdn_reject_roles input[type=checkbox]', jQuery('#cdn__reject__logged_roles:checked').length);
604
  });
605
 
606
+ jQuery('#cdn_export_library').on( 'click', function() {
607
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_export_library&_wpnonce=' + jQuery(this).metadata().nonce, 'cdn_export_library');
608
  });
609
 
610
+ jQuery('#cdn_import_library').on( 'click', function() {
611
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_import_library&_wpnonce=' + jQuery(this).metadata().nonce, 'cdn_import_library');
612
  });
613
 
614
+ jQuery('#cdn_queue').on( 'click', function() {
615
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_queue&_wpnonce=' + jQuery(this).metadata().nonce, 'cdn_queue');
616
  });
617
 
618
+ jQuery('#cdn_rename_domain').on( 'click', function() {
619
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_rename_domain&_wpnonce=' + jQuery(this).metadata().nonce, 'cdn_rename_domain');
620
  });
621
 
622
+ jQuery('#cdn_purge').on( 'click', function() {
623
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_purge&_wpnonce=' + jQuery(this).metadata().nonce, 'cdn_purge');
624
  });
625
 
626
+ jQuery('.cdn_export').on( 'click', function() {
627
  var metadata = jQuery(this).metadata();
628
  w3tc_popup('admin.php?page=w3tc_cdn&w3tc_cdn_export&cdn_export_type=' + metadata.type + '&_wpnonce=' + metadata.nonce, 'cdn_export_' + metadata.type);
629
  });
630
 
631
+ jQuery('#validate_cdn_key').on( 'click', function() {
632
  var me = jQuery(this);
633
  var metadata = me.metadata();
634
  w3tc_validate_cdn_key_result(metadata.type, metadata.nonce);
635
  });
636
 
637
+ jQuery('#use_poll_zone').on( 'click', function() {
638
  var me = jQuery(this);
639
  var metadata = me.metadata();
640
  w3tc_use_poll_zone(metadata.type, metadata.nonce);
641
  });
642
 
643
+ jQuery('#cdn_test').on( 'click', function() {
644
  var me = jQuery(this);
645
  var metadata = me.metadata();
646
  var cnames = w3tc_cdn_get_cnames();
956
  });
957
  });
958
 
959
+ jQuery('#memcached_test').on( 'click', function() {
960
  var status = jQuery('#memcached_test_status');
961
  status.removeClass('w3tc-error');
962
  status.removeClass('w3tc-success');
976
  });
977
  });
978
 
979
+ jQuery('.w3tc_common_redis_test').on( 'click', function() {
980
  var status = jQuery('.w3tc_common_redis_test_result');
981
  status.removeClass('w3tc-error');
982
  status.removeClass('w3tc-success');
998
  });
999
  });
1000
 
1001
+ jQuery('.minifier_test').on( 'click', function() {
1002
  var me = jQuery(this);
1003
  var metadata = me.metadata();
1004
  var params = {
1065
  }
1066
  });
1067
 
1068
+ jQuery('#cdn_form').on( 'submit', function() {
1069
  var cnames = [], ret = true;
1070
 
1071
  jQuery('#cdn_cnames input[type=text]').each(function() {
1087
  });
1088
 
1089
  // mobile tab
1090
+ jQuery('#mobile_form').on( 'submit', function() {
1091
  var error = false;
1092
 
1093
  jQuery('#mobile_groups li').each(function() {
1139
  }
1140
  });
1141
 
1142
+ jQuery('#mobile_add').on( 'click', function() {
1143
  var group = prompt('Enter group name (only "0-9", "a-z", "_" symbols are allowed).');
1144
 
1145
  if (group !== null) {
1189
  w3tc_mobile_groups_clear();
1190
 
1191
  // referrer tab
1192
+ jQuery('#referrer_form').on( 'submit', function() {
1193
  var error = false;
1194
 
1195
  jQuery('#referrer_groups li').each(function() {
1241
  }
1242
  });
1243
 
1244
+ jQuery('#referrer_add').on( 'click', function() {
1245
  var group = prompt('Enter group name (only "0-9", "a-z", "_" symbols are allowed).');
1246
 
1247
  if (group !== null) {
1326
  }
1327
 
1328
  // show hide rules
1329
+ jQuery('.w3tc-show-rules').on( 'click', function() {
1330
  var btn = jQuery(this), rules = btn.parent().find('.w3tc-rules');
1331
 
1332
  if (rules.is(':visible')) {
1340
 
1341
 
1342
  // show hide missing files
1343
+ jQuery('.w3tc-show-required-changes').on( 'click', function() {
1344
  var btn = jQuery(this), rules = jQuery('.w3tc-required-changes');
1345
 
1346
  if (rules.is(':visible')) {
1353
  });
1354
 
1355
  // show hide missing files
1356
+ jQuery('.w3tc-show-ftp-form').on( 'click', function() {
1357
  var btn = jQuery(this), rules = jQuery('.w3tc-ftp-form');
1358
 
1359
  if (rules.is(':visible')) {
1366
  });
1367
 
1368
  // show hide missing files
1369
+ jQuery('.w3tc-show-technical-info').on( 'click', function() {
1370
  var btn = jQuery(this), info = jQuery('.w3tc-technical-info');
1371
 
1372
  if (info.is(':visible')) {
1384
  });
1385
 
1386
  // toggle hiddent content
1387
+ jQuery('.w3tc_link_more').on( 'click', function() {
1388
  var target_class = jQuery(this).metadata().for_class;
1389
  jQuery('.' + target_class).slideToggle();
1390
  });
1407
  jQuery('body').on('click', '.w3tc-button-save', w3tc_beforeupload_unbind);
1408
 
1409
 
1410
+ jQuery('.contextual-help-tabs ul li a').on( 'click', function() {
1411
  var id = jQuery(this).attr('aria-controls');
1412
  var i = jQuery('#' + id + ' .w3tchelp_content');
1413
  w3tc_load_faq_section(i);
1414
  });
1415
 
1416
+ jQuery('#contextual-help-link').on( 'click', function() {
1417
  var i = jQuery('.w3tchelp_content').first();
1418
  w3tc_load_faq_section(i);
1419
  });
1443
  }
1444
 
1445
  // extensions page
1446
+ jQuery('.w3tc_extensions_manage_input_checkall').on( 'click', function(v) {
1447
  var c = jQuery(this).is(':checked');
1448
 
1449
  jQuery('.w3tc_extensions_manage_input_checkall').prop('checked', c);
1454
  });
1455
 
1456
  // gopro block
1457
+ jQuery('.w3tc-gopro-more').on( 'click', function(e) {
1458
  e.preventDefault();
1459
  if (!jQuery(this).data('expanded')) {
1460
  jQuery(this).data('expanded', '1');
pub/js/setup-guide.js ADDED
@@ -0,0 +1,1286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * File: setup-guide.js
3
+ *
4
+ * JavaScript for the Setup Guide page.
5
+ *
6
+ * @since 2.0.0
7
+ *
8
+ * @global W3TC-setup-guide Localized array variable.
9
+ */
10
+
11
+ jQuery(function() {
12
+ var $container = jQuery( '#w3tc-wizard-container'),
13
+ $nextButton = $container.find( '#w3tc-wizard-next '),
14
+ $tosNotice = $container.find( '#w3tc-licensing-terms' );
15
+
16
+ // GA.
17
+ if ( 'accept' === W3TC_SetupGuide.tos_choice ) {
18
+ w3tc_ga( 'create', W3TC_SetupGuide.ga_profile, 'auto' );
19
+ w3tc_ga( 'send', 'event', 'button', 'w3tc_setup_guide', 'w3tc-wizard-step-welcome' );
20
+ }
21
+
22
+ // Handle the terms of service notice.
23
+ if ( $tosNotice.length ) {
24
+ $nextButton.prop( 'disabled', true );
25
+ $container.find( '.dashicons-yes' ).hide();
26
+
27
+ $tosNotice.find( '.button' ).on( 'click', function() {
28
+ var $this = jQuery( this ),
29
+ choice = $this.data( 'choice' );
30
+
31
+ jQuery.ajax({
32
+ method: 'POST',
33
+ url: ajaxurl,
34
+ data: {
35
+ _wpnonce: $container.find( '[name="_wpnonce"]' ).val(),
36
+ action: "w3tc_tos_choice",
37
+ choice: choice
38
+ }
39
+ })
40
+ .done(function( response ) {
41
+ $tosNotice.hide();
42
+ $nextButton.prop( 'disabled', false );
43
+ $container.find( '#w3tc-welcome' ).show();
44
+ $container.find( '.dashicons-yes' ).show();
45
+ })
46
+ .fail(function() {
47
+ $this.text( 'Error with Ajax; reloading page...' );
48
+
49
+ location.reload();
50
+ });
51
+
52
+ if ( 'accept' === choice ) {
53
+ W3TC_SetupGuide.tos_choice = choice;
54
+
55
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
56
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
57
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
58
+ })(window,document,'script','https://api.w3-edge.com/v1/analytics','w3tc_ga');
59
+
60
+ if (window.w3tc_ga) {
61
+ w3tc_ga( 'create', W3TC_SetupGuide.ga_profile, 'auto' );
62
+ w3tc_ga( 'set', {
63
+ 'dimension1': 'w3-total-cache',
64
+ 'dimension2': W3TC_SetupGuide.w3tc_version,
65
+ 'dimension3': W3TC_SetupGuide.wp_version,
66
+ 'dimension4': W3TC_SetupGuide.php_version,
67
+ 'dimension5': W3TC_SetupGuide.server_software,
68
+ 'dimension6': W3TC_SetupGuide.db_version,
69
+ 'dimension7': W3TC_SetupGuide.home_url_host,
70
+ 'dimension9': W3TC_SetupGuide.install_version,
71
+ 'dimension10': W3TC_SetupGuide.w3tc_edition,
72
+ 'dimension11': W3TC_SetupGuide.list_widgets,
73
+ 'page': W3TC_SetupGuide.page
74
+ });
75
+
76
+ w3tc_ga( 'send', 'pageview' );
77
+ }
78
+ }
79
+ });
80
+ }
81
+ });
82
+
83
+ jQuery( '#w3tc-wizard-step-welcome' )
84
+ .addClass( 'is-active' )
85
+ .append( '<span class="dashicons dashicons-yes"></span>' );
86
+
87
+ /**
88
+ * Wizard actions.
89
+ *
90
+ * @since 2.0.0
91
+ *
92
+ * @param object $slide The div of the slide displayed.
93
+ */
94
+ function w3tc_wizard_actions( $slide ) {
95
+ var configSuccess = false,
96
+ pgcacheSettings = {
97
+ enabled: null,
98
+ engine: null
99
+ },
100
+ dbcacheSettings = {
101
+ enabled: null,
102
+ engine: null
103
+ },
104
+ objcacheSettings = {
105
+ enabled: null,
106
+ engine: null
107
+ },
108
+ browsercacheSettings = {
109
+ enabled: null
110
+ },
111
+ lazyloadSettings = {
112
+ enabled: null
113
+ },
114
+ slideId = $slide.prop( 'id' ),
115
+ $container = jQuery( '#w3tc-wizard-container' ),
116
+ nonce = $container.find( '[name="_wpnonce"]' ).val(),
117
+ $nextButton = $container.find( '#w3tc-wizard-next' ),
118
+ $prevButton = $container.find( '#w3tc-wizard-previous' ),
119
+ $skipButton = $container.find( '#w3tc-wizard-skip' ),
120
+ $dashboardButton = $container.find( '#w3tc-wizard-dashboard' );
121
+
122
+ /**
123
+ * Configure Page Cache.
124
+ *
125
+ * @since 2.0.0
126
+ *
127
+ * @param int enable Enable Page Cache.
128
+ * @param string engine Page Cache storage engine.
129
+ * @return jqXHR
130
+ */
131
+ function configPgcache( enable, engine = '' ) {
132
+ var $jqXHR = jQuery.ajax({
133
+ method: 'POST',
134
+ url: ajaxurl,
135
+ data: {
136
+ _wpnonce: nonce,
137
+ action: 'w3tc_config_pgcache',
138
+ enable: enable,
139
+ engine: engine
140
+ }
141
+ });
142
+
143
+ configSuccess = null;
144
+
145
+ $jqXHR.done(function( response ) {
146
+ configSuccess = response.data.success;
147
+ });
148
+
149
+ return $jqXHR;
150
+ }
151
+
152
+ /**
153
+ * Get Page Cache settings.
154
+ *
155
+ * @since 2.0.0
156
+ *
157
+ * @return jqXHR
158
+ */
159
+ function getPgcacheSettings() {
160
+ return jQuery.ajax({
161
+ method: 'POST',
162
+ url: ajaxurl,
163
+ data: {
164
+ _wpnonce: nonce,
165
+ action: 'w3tc_get_pgcache_settings'
166
+ }
167
+ })
168
+ .done(function( response ) {
169
+ pgcacheSettings = response.data;
170
+ });
171
+ }
172
+
173
+ /**
174
+ * Configure Database Cache.
175
+ *
176
+ * @since 2.0.0
177
+ *
178
+ * @param int enable Enable database cache.
179
+ * @param string engine Database cache storage engine.
180
+ * @return jqXHR
181
+ */
182
+ function configDbcache( enable, engine = '' ) {
183
+ var $jqXHR = jQuery.ajax({
184
+ method: 'POST',
185
+ url: ajaxurl,
186
+ data: {
187
+ _wpnonce: nonce,
188
+ action: 'w3tc_config_dbcache',
189
+ enable: enable,
190
+ engine: engine
191
+ }
192
+ });
193
+
194
+ configSuccess = null;
195
+
196
+ $jqXHR.done(function( response ) {
197
+ configSuccess = response.data.success;
198
+ });
199
+
200
+ return $jqXHR;
201
+ }
202
+
203
+ /**
204
+ * Get Database Cache settings.
205
+ *
206
+ * @since 2.0.0
207
+ *
208
+ * @return jqXHR
209
+ */
210
+ function getDbcacheSettings() {
211
+ return jQuery.ajax({
212
+ method: 'POST',
213
+ url: ajaxurl,
214
+ data: {
215
+ _wpnonce: nonce,
216
+ action: 'w3tc_get_dbcache_settings'
217
+ }
218
+ })
219
+ .done(function( response ) {
220
+ dbcacheSettings = response.data;
221
+ });
222
+ }
223
+
224
+ /**
225
+ * Configure Object Cache.
226
+ *
227
+ * @since 2.0.0
228
+ *
229
+ * @param int enable Enable cache.
230
+ * @param string engine Cache storage engine.
231
+ * @return jqXHR
232
+ */
233
+ function configObjcache( enable, engine = '' ) {
234
+ var $jqXHR = jQuery.ajax({
235
+ method: 'POST',
236
+ url: ajaxurl,
237
+ data: {
238
+ _wpnonce: nonce,
239
+ action: 'w3tc_config_objcache',
240
+ enable: enable,
241
+ engine: engine
242
+ }
243
+ });
244
+
245
+ configSuccess = null;
246
+
247
+ $jqXHR.done(function( response ) {
248
+ configSuccess = response.data.success;
249
+ });
250
+
251
+ return $jqXHR;
252
+ }
253
+
254
+ /**
255
+ * Get Object Cache settings.
256
+ *
257
+ * @since 2.0.0
258
+ *
259
+ * @return jqXHR
260
+ */
261
+ function getObjcacheSettings() {
262
+ return jQuery.ajax({
263
+ method: 'POST',
264
+ url: ajaxurl,
265
+ data: {
266
+ _wpnonce: nonce,
267
+ action: 'w3tc_get_objcache_settings'
268
+ }
269
+ })
270
+ .done(function( response ) {
271
+ objcacheSettings = response.data;
272
+ });
273
+ }
274
+
275
+ /**
276
+ * Configure Browser Cache.
277
+ *
278
+ * @since 2.0.0
279
+ *
280
+ * @param int enable Enable browser cache.
281
+ * @return jqXHR
282
+ */
283
+ function configBrowsercache( enable ) {
284
+ configSuccess = null;
285
+
286
+ return jQuery.ajax({
287
+ method: 'POST',
288
+ url: ajaxurl,
289
+ data: {
290
+ _wpnonce: nonce,
291
+ action: 'w3tc_config_browsercache',
292
+ enable: enable
293
+ }
294
+ })
295
+ .done(function( response ) {
296
+ configSuccess = response.data.success;
297
+ });
298
+ }
299
+
300
+ /**
301
+ * Get Browser Cache settings.
302
+ *
303
+ * @since 2.0.0
304
+ *
305
+ * @return jqXHR
306
+ */
307
+ function getBrowsercacheSettings() {
308
+ return jQuery.ajax({
309
+ method: 'POST',
310
+ url: ajaxurl,
311
+ data: {
312
+ _wpnonce: nonce,
313
+ action: 'w3tc_get_browsercache_settings'
314
+ }
315
+ })
316
+ .done(function( response ) {
317
+ browsercacheSettings = response.data;
318
+ });
319
+ }
320
+
321
+ /**
322
+ * Configure Lazy Load.
323
+ *
324
+ * @since 2.0.0
325
+ *
326
+ * @param int enable Enable lazyload.
327
+ * @return jqXHR
328
+ */
329
+ function configLazyload( enable ) {
330
+ configSuccess = null;
331
+
332
+ return jQuery.ajax({
333
+ method: 'POST',
334
+ url: ajaxurl,
335
+ data: {
336
+ _wpnonce: nonce,
337
+ action: 'w3tc_config_lazyload',
338
+ enable: enable
339
+ }
340
+ })
341
+ .done(function( response ) {
342
+ configSuccess = response.data.success;
343
+ });
344
+ }
345
+
346
+ /**
347
+ * Get Lazt Load settings.
348
+ *
349
+ * @since 2.0.0
350
+ *
351
+ * @return jqXHR
352
+ */
353
+ function getLazyloadSettings() {
354
+ return jQuery.ajax({
355
+ method: 'POST',
356
+ url: ajaxurl,
357
+ data: {
358
+ _wpnonce: nonce,
359
+ action: 'w3tc_get_lazyload_settings'
360
+ }
361
+ })
362
+ .done(function( response ) {
363
+ lazyloadSettings = response.data;
364
+ });
365
+ }
366
+
367
+ /**
368
+ * Configuration failed.
369
+ *
370
+ * @since 2.0.0
371
+ */
372
+ function configFailed() {
373
+ $slide.append(
374
+ '<div class="notice notice-error"><p><strong>' +
375
+ W3TC_SetupGuide.config_error_msg +
376
+ '</strong></p></div>'
377
+ );
378
+ $nextButton.closest( 'span' ).hide();
379
+ $prevButton.closest( 'span' ).hide();
380
+ $skipButton.closest( 'span' ).show();
381
+ }
382
+
383
+ /**
384
+ * Test failed.
385
+ *
386
+ * @since 2.0.0
387
+ */
388
+ function testFailed() {
389
+ $slide.append(
390
+ '<div class="notice notice-error"><p><strong>' +
391
+ W3TC_SetupGuide.config_error_msg +
392
+ '</strong></p></div>'
393
+ );
394
+ $nextButton.closest( 'span' ).hide();
395
+ $prevButton.closest( 'span' ).hide();
396
+ $skipButton.closest( 'span' ).show();
397
+ }
398
+
399
+ // GA.
400
+ if ( 'accept' === W3TC_SetupGuide.tos_choice ) {
401
+ w3tc_ga( 'send', 'event', 'button', 'w3tc_setup_guide', slideId );
402
+ }
403
+
404
+ switch ( slideId ) {
405
+ case 'w3tc-wizard-slide-welcome':
406
+ $container.find( '#w3tc-options-menu li' ).removeClass( 'is-active' );
407
+ $container.find( '#w3tc-wizard-step-welcome' ).addClass( 'is-active' );
408
+
409
+ break;
410
+
411
+ case 'w3tc-wizard-slide-pc1':
412
+ // Test Page Cache.
413
+ $container.find( '#w3tc-options-menu li' ).removeClass( 'is-active' );
414
+ $container.find( '#w3tc-wizard-step-pgcache' ).addClass( 'is-active' );
415
+
416
+ if ( ! $container.find( '#test-results' ).data( 'pgcache-none' ) ) {
417
+ $nextButton.prop( 'disabled', 'disabled' );
418
+ }
419
+
420
+ $slide.find( '#w3tc-test-pgcache' ).off('click').on('click', function () {
421
+ var $spinnerParent = $slide.find( '.spinner' ).addClass( 'is-active' ).parent(),
422
+ $this = jQuery( this );
423
+
424
+ $this.prop( 'disabled', 'disabled' );
425
+ $slide.find( '.notice-error' ).remove();
426
+ $container.find( '#w3tc-pgcache-table tbody' ).empty();
427
+ $prevButton.prop( 'disabled', 'disabled' );
428
+ $nextButton.prop( 'disabled', 'disabled' );
429
+
430
+ $spinnerParent.show();
431
+
432
+ /**
433
+ * Add a test result table row.
434
+ *
435
+ * @since 2.0.0
436
+ *
437
+ * @param object testResponse Data.
438
+ * @param string engine Cache storage engine.
439
+ * @param string label Text label for the engine.
440
+ */
441
+ function addResultRow( testResponse, engine, label ) {
442
+ var baseline,
443
+ results = '<tr',
444
+ percentChange,
445
+ changeLabelType,
446
+ changeLabel,
447
+ isCurrentSetting = ( ! pgcacheSettings.enabled && 'none' === engine ) ||
448
+ ( pgcacheSettings.enabled && pgcacheSettings.engine === engine );
449
+
450
+ if ( ! configSuccess ) {
451
+ results += ' class="w3tc-option-disabled"';
452
+ }
453
+
454
+ results += '><td><input type="radio" id="pgcache-engine-' +
455
+ engine +
456
+ '" name="pgcache_engine" value="' +
457
+ engine +
458
+ '"';
459
+
460
+ if ( ! configSuccess ) {
461
+ results += ' disabled="disabled"';
462
+ }
463
+
464
+ if ( isCurrentSetting ) {
465
+ results += ' checked';
466
+ }
467
+
468
+ if ( configSuccess && 'file_generic' === engine ) {
469
+ label += '<br /><span class="w3tc-option-recommended">(Recommended)</span>';
470
+ }
471
+
472
+ results += '>';
473
+
474
+ if ( isCurrentSetting ) {
475
+ results += '<span class="dashicons dashicons-admin-settings" title="Current setting"></span>';
476
+ }
477
+
478
+ results += '</td><td><label for="pgcache-engine-' +
479
+ engine +
480
+ '">' +
481
+ label +
482
+ '</label></td><td>';
483
+
484
+ if ( testResponse.success ) {
485
+ results += ( testResponse.data.ttfb * 1000 ).toFixed( 2 );
486
+ if ( 'none' !== engine ) {
487
+ baseline = $container.find( '#test-results' ).data( 'pgcache-none' ).ttfb;
488
+ percentChange = ( ( testResponse.data.ttfb - baseline ) / baseline * 100 ).toFixed( 2 );
489
+ changeLabelType = percentChange < 0 ? 'w3tc-label-success' : 'w3tc-label-danger';
490
+ changeLabel = '<span class="w3tc-label ' + changeLabelType + '">' + percentChange + '%</span>';
491
+
492
+ $container.find( '#test-results' ).data( 'pgcacheDiffPercent-' + engine, percentChange );
493
+ results += ' ' + changeLabel;
494
+ }
495
+ } else {
496
+ results += W3TC_SetupGuide.unavailable_text;
497
+ }
498
+
499
+ results += '</td></tr>';
500
+
501
+ $container.find( '#w3tc-pgcache-table tbody' ).append( results );
502
+ $container.find( '#w3tc-pgcache-table' ).show();
503
+ }
504
+
505
+ /**
506
+ * Test Page Cache.
507
+ *
508
+ * @since 2.0.0
509
+ *
510
+ * @param string engine Cache storage engine.
511
+ * @param string label Text label for the engine.
512
+ * @return jqXHR
513
+ */
514
+ function testPgcache( engine, label ) {
515
+ if ( configSuccess ) {
516
+ return jQuery.ajax({
517
+ method: 'POST',
518
+ url: ajaxurl,
519
+ data: {
520
+ _wpnonce: nonce,
521
+ action: 'w3tc_test_pgcache'
522
+ }
523
+ })
524
+ .done(function( testResponse ) {
525
+ $container.find( '#test-results' ).data( 'pgcache-' + engine, testResponse.data );
526
+ addResultRow( testResponse, engine, label );
527
+ });
528
+ } else {
529
+ addResultRow( [ success => false ], engine, label );
530
+ }
531
+ }
532
+
533
+ // Run config and tests.
534
+ getPgcacheSettings()
535
+ .then( function() {
536
+ return configPgcache( 0 );
537
+ }, configFailed )
538
+ .then( function() {
539
+ return testPgcache( 'none', W3TC_SetupGuide.none );
540
+ }, configFailed )
541
+ .then( function() {
542
+ return configPgcache( 1, 'file' );
543
+ } , testFailed )
544
+ .then( function() {
545
+ return testPgcache( 'file', W3TC_SetupGuide.disk_basic );
546
+ }, configFailed )
547
+ .then( function() {
548
+ return configPgcache( 1, 'file_generic' );
549
+ } , testFailed )
550
+ .then( function() {
551
+ return testPgcache( 'file_generic', W3TC_SetupGuide.disk_enhanced );
552
+ }, configFailed )
553
+ .then( function() {
554
+ return configPgcache( 1, 'redis' );
555
+ }, testFailed )
556
+ .then( function() {
557
+ return testPgcache( 'redis', 'Redis' );
558
+ }, configFailed )
559
+ .then( function() {
560
+ return configPgcache( 1, 'memcached' );
561
+ }, testFailed )
562
+ .then( function() {
563
+ return testPgcache( 'memcached', 'Memcached' );
564
+ }, configFailed )
565
+ .then( function() {
566
+ return configPgcache( 1, 'apc' );
567
+ }, testFailed )
568
+ .then( function() {
569
+ return testPgcache( 'apc', 'APC' );
570
+ }, configFailed )
571
+ .then( function() {
572
+ return configPgcache( 1, 'eaccelerator' );
573
+ }, testFailed )
574
+ .then( function() {
575
+ return testPgcache( 'eaccelerator', 'eAccelerator' );
576
+ }, configFailed )
577
+ .then( function() {
578
+ return configPgcache( 1, 'xcache' );
579
+ }, testFailed )
580
+ .then( function() {
581
+ return testPgcache( 'xcache', 'XCache' );
582
+ }, configFailed )
583
+ .then( function() {
584
+ return configPgcache( 1, 'wincache' );
585
+ }, testFailed )
586
+ .then( function() {
587
+ return testPgcache( 'wincache', 'WinCache' );
588
+ }, configFailed )
589
+ .then(function() {
590
+ $spinnerParent.hide();
591
+ $this.prop( 'disabled', false );
592
+ $prevButton.prop( 'disabled', false );
593
+ $nextButton.prop( 'disabled', false );
594
+ return true;
595
+ }, testFailed )
596
+ // Restore the original database cache settings.
597
+ .then( function() {
598
+ return configPgcache( ( pgcacheSettings.enabled ? 1 : 0 ), pgcacheSettings.engine );
599
+ },
600
+ function() {
601
+ $spinnerParent.hide();
602
+ return configFailed();
603
+ });
604
+ });
605
+
606
+ break;
607
+
608
+ case 'w3tc-wizard-slide-dbc1':
609
+ // Save the page cache engine setting from the previous slide.
610
+ var pgcacheEngine = $container.find( 'input:checked[name="pgcache_engine"]' ).val();
611
+
612
+ configPgcache( ( 'none' === pgcacheEngine ? 0 : 1 ), 'none' === pgcacheEngine ? '' : pgcacheEngine )
613
+ .fail( function() {
614
+ $slide.append(
615
+ '<div class="notice notice-error"><p><strong>' +
616
+ W3TC_SetupGuide.config_error_msg +
617
+ '</strong></p></div>'
618
+ );
619
+ });
620
+
621
+ if ( ! jQuery( '#w3tc-wizard-step-pgcache .dashicons-yes' ).length ) {
622
+ jQuery( '#w3tc-wizard-step-pgcache' ).append( '<span class="dashicons dashicons-yes"></span>' );
623
+ }
624
+
625
+ // Present the Database Cache slide.
626
+ $container.find( '#w3tc-options-menu li' ).removeClass( 'is-active' );
627
+ $container.find( '#w3tc-wizard-step-dbcache' ).addClass( 'is-active' );
628
+
629
+ if ( ! $container.find( '#test-results' ).data( 'dbc-none' ) ) {
630
+ $nextButton.prop( 'disabled', 'disabled' );
631
+ }
632
+
633
+ $slide.find( '#w3tc-test-dbcache' ).off('click').on('click', function () {
634
+ var $spinnerParent = $slide.find( '.spinner' ).addClass( 'is-active' ).parent(),
635
+ $this = jQuery( this );
636
+
637
+ $this.prop( 'disabled', 'disabled' );
638
+ $slide.find( '.notice-error' ).remove();
639
+ $container.find( '#w3tc-dbc-table tbody' ).empty();
640
+ $container.find( '#w3tc-dbcache-recommended' ).hide();
641
+ $prevButton.prop( 'disabled', 'disabled' );
642
+ $nextButton.prop( 'disabled', 'disabled' );
643
+
644
+ $spinnerParent.show();
645
+
646
+ /**
647
+ * Add a test result table row.
648
+ *
649
+ * @since 2.0.0
650
+ *
651
+ * @param object testResponse Data.
652
+ * @param string engine Cache storage engine.
653
+ * @param string label Text label for the engine.
654
+ */
655
+ function addResultRow( testResponse, engine, label ) {
656
+ var baseline,
657
+ results = '<tr',
658
+ percentChange,
659
+ changeLabelType,
660
+ changeLabel,
661
+ isCurrentSetting = ( ! dbcacheSettings.enabled && 'none' === engine ) ||
662
+ ( dbcacheSettings.enabled && dbcacheSettings.engine === engine );
663
+
664
+ if ( ! configSuccess ) {
665
+ results += ' class="w3tc-option-disabled"';
666
+ }
667
+
668
+ results += '><td><input type="radio" id="dbcache-engine-' +
669
+ engine +
670
+ '" name="dbcache_engine" value="' +
671
+ engine +
672
+ '"';
673
+
674
+ if ( ! configSuccess ) {
675
+ results += ' disabled="disabled"';
676
+ }
677
+
678
+ if ( isCurrentSetting ) {
679
+ results += ' checked';
680
+ }
681
+
682
+ results += '>';
683
+
684
+ if ( isCurrentSetting ) {
685
+ results += '<span class="dashicons dashicons-admin-settings" title="Current setting"></span>';
686
+ }
687
+
688
+ results += '</td><td><label for="dbcache-engine-' +
689
+ engine +
690
+ '">' +
691
+ label +
692
+ '</label></td><td>';
693
+
694
+ if ( testResponse.success ) {
695
+ results += ( testResponse.data.elapsed * 1000 ).toFixed( 2 );
696
+
697
+ if ( 'none' !== engine ) {
698
+ baseline = $container.find( '#test-results' ).data( 'dbc-none' ).elapsed;
699
+ percentChange = ( ( testResponse.data.elapsed - baseline ) / baseline * 100 ).toFixed( 2 );
700
+ changeLabelType = percentChange < 0 ? 'w3tc-label-success' : 'w3tc-label-danger';
701
+ changeLabel = '<span class="w3tc-label ' + changeLabelType + '">'+ percentChange + '%</span>';
702
+
703
+ results += ' ' + changeLabel;
704
+ }
705
+ } else {
706
+ results += W3TC_SetupGuide.unavailable_text;
707
+ }
708
+
709
+ results += '</td></tr>';
710
+
711
+ $container.find( '#w3tc-dbc-table tbody' ).append( results );
712
+ $container.find( '#w3tc-dbc-table' ).show();
713
+ }
714
+
715
+ /**
716
+ * Test database cache.
717
+ *
718
+ * @since 2.0.0
719
+ *
720
+ * @param string engine Cache storage engine.
721
+ * @param string label Text label for the engine.
722
+ * @return jqXHR
723
+ */
724
+ function testDbcache( engine, label ) {
725
+ if ( configSuccess ) {
726
+ return jQuery.ajax({
727
+ method: 'POST',
728
+ url: ajaxurl,
729
+ data: {
730
+ _wpnonce: nonce,
731
+ action: 'w3tc_test_dbcache'
732
+ }
733
+ })
734
+ .done(function( testResponse ) {
735
+ $container.find( '#test-results' ).data( 'dbc-' + engine, testResponse.data );
736
+ addResultRow( testResponse, engine, label );
737
+ });
738
+ } else {
739
+ addResultRow( [ success => false ], engine, label );
740
+ }
741
+ }
742
+
743
+ // Run config and tests.
744
+ getDbcacheSettings()
745
+ .then( function() {
746
+ return configDbcache( 0 );
747
+ }, configFailed )
748
+ .then( function() {
749
+ return testDbcache( 'none', W3TC_SetupGuide.none );
750
+ }, configFailed )
751
+ .then( function() {
752
+ return configDbcache( 1, 'file' );
753
+ } , testFailed )
754
+ .then( function() {
755
+ return testDbcache( 'file', W3TC_SetupGuide.disk );
756
+ }, configFailed )
757
+ .then( function() {
758
+ return configDbcache( 1, 'redis' );
759
+ }, testFailed )
760
+ .then( function() {
761
+ return testDbcache( 'redis', 'Redis' );
762
+ }, configFailed )
763
+ .then( function() {
764
+ return configDbcache( 1, 'memcached' );
765
+ }, testFailed )
766
+ .then( function() {
767
+ return testDbcache( 'memcached', 'Memcached' );
768
+ }, configFailed )
769
+ .then( function() {
770
+ return configDbcache( 1, 'apc' );
771
+ }, testFailed )
772
+ .then( function() {
773
+ return testDbcache( 'apc', 'APC' );
774
+ }, configFailed )
775
+ .then( function() {
776
+ return configDbcache( 1, 'eaccelerator' );
777
+ }, testFailed )
778
+ .then( function() {
779
+ return testDbcache( 'eaccelerator', 'eAccelerator' );
780
+ }, configFailed )
781
+ .then( function() {
782
+ return configDbcache( 1, 'xcache' );
783
+ }, testFailed )
784
+ .then( function() {
785
+ return testDbcache( 'xcache', 'XCache' );
786
+ }, configFailed )
787
+ .then( function() {
788
+ return configDbcache( 1, 'wincache' );
789
+ }, testFailed )
790
+ .then( function() {
791
+ return testDbcache( 'wincache', 'WinCache' );
792
+ }, configFailed )
793
+ .then(function() {
794
+ $spinnerParent.hide();
795
+ $this.prop( 'disabled', false );
796
+ $prevButton.prop( 'disabled', false );
797
+ $nextButton.prop( 'disabled', false );
798
+ return true;
799
+ }, testFailed )
800
+ .then( function() {
801
+ $container.find( '#w3tc-dbcache-recommended' ).show();
802
+ // Restore the original database cache settings.
803
+ return configDbcache( ( dbcacheSettings.enabled ? 1 : 0 ), dbcacheSettings.engine );
804
+ },
805
+ function() {
806
+ $spinnerParent.hide();
807
+ return configFailed();
808
+ });
809
+ });
810
+
811
+ break;
812
+
813
+ case 'w3tc-wizard-slide-oc1':
814
+ // Save the database cache engine setting from the previous slide.
815
+ var dbcEngine = $container.find( 'input:checked[name="dbcache_engine"]' ).val();
816
+
817
+ configDbcache( ( 'none' === dbcEngine ? 0 : 1 ), 'none' === dbcEngine ? '' : dbcEngine )
818
+ .fail( function() {
819
+ $slide.append(
820
+ '<div class="notice notice-error"><p><strong>' +
821
+ W3TC_SetupGuide.config_error_msg +
822
+ '</strong></p></div>'
823
+ );
824
+ });
825
+
826
+ if ( ! jQuery( '#w3tc-wizard-step-dbcache .dashicons-yes' ).length ) {
827
+ jQuery( '#w3tc-wizard-step-dbcache' ).append( '<span class="dashicons dashicons-yes"></span>' );
828
+ }
829
+
830
+ // Present the Object Cache slide.
831
+ $container.find( '#w3tc-options-menu li' ).removeClass( 'is-active' );
832
+ $container.find( '#w3tc-wizard-step-objectcache' ).addClass( 'is-active' );
833
+
834
+ if ( ! $container.find( '#test-results' ).data( 'oc-none' ) ) {
835
+ $nextButton.prop( 'disabled', 'disabled' );
836
+ }
837
+
838
+ $slide.find( '#w3tc-test-objcache' ).off('click').on('click', function () {
839
+ var $spinnerParent = $slide.find( '.spinner' ).addClass( 'is-active' ).parent(),
840
+ $this = jQuery( this );
841
+
842
+ $this.prop( 'disabled', 'disabled' );
843
+ $slide.find( '.notice-error' ).remove();
844
+ $container.find( '#w3tc-objcache-table tbody' ).empty();
845
+ $prevButton.prop( 'disabled', 'disabled' );
846
+ $nextButton.prop( 'disabled', 'disabled' );
847
+
848
+ $spinnerParent.show();
849
+
850
+ /**
851
+ * Add a test result table row.
852
+ *
853
+ * @since 2.0.0
854
+ *
855
+ * @param object testResponse Data.
856
+ * @param string engine Cache storage engine.
857
+ * @param string label Text label for the engine.
858
+ */
859
+ function addResultRow( testResponse, engine, label ) {
860
+ var baseline,
861
+ results = '<tr',
862
+ percentChange,
863
+ changeLabelType,
864
+ changeLabel,
865
+ isCurrentSetting = ( ! objcacheSettings.enabled && 'none' === engine ) ||
866
+ ( objcacheSettings.enabled && objcacheSettings.engine === engine );
867
+
868
+ if ( ! configSuccess ) {
869
+ results += ' class="w3tc-option-disabled"';
870
+ }
871
+
872
+ results += '><td><input type="radio" id="objcache-engine-' +
873
+ engine +
874
+ '" name="objcache_engine" value="' +
875
+ engine +
876
+ '"';
877
+
878
+ if ( ! configSuccess ) {
879
+ results += ' disabled="disabled"';
880
+ }
881
+
882
+ if ( isCurrentSetting ) {
883
+ results += ' checked';
884
+ }
885
+
886
+ results += '>';
887
+
888
+ if ( isCurrentSetting ) {
889
+ results += '<span class="dashicons dashicons-admin-settings" title="Current setting"></span>';
890
+ }
891
+
892
+ results += '</td><td><label for="objcache-engine-' +
893
+ engine +
894
+ '">' +
895
+ label +
896
+ '</label></td><td>';
897
+
898
+ if ( testResponse.success ) {
899
+ results += ( testResponse.data.elapsed * 1000 ).toFixed( 2 );
900
+ if ( 'none' !== engine ) {
901
+ baseline = $container.find( '#test-results' ).data( 'oc-none' ).elapsed;
902
+ percentChange = ( ( testResponse.data.elapsed - baseline ) / baseline * 100 ).toFixed( 2 );
903
+ changeLabelType = percentChange < 0 ? 'w3tc-label-success' : 'w3tc-label-danger';
904
+ changeLabel = '<span class="w3tc-label ' + changeLabelType + '">' + percentChange + '%</span>';
905
+
906
+ results += ' ' + changeLabel;
907
+ }
908
+ } else {
909
+ results += W3TC_SetupGuide.unavailable_text;
910
+ }
911
+
912
+ results += '</td></tr>';
913
+
914
+ $container.find( '#w3tc-objcache-table tbody' ).append( results );
915
+ $container.find( '#w3tc-objcache-table' ).show();
916
+ }
917
+
918
+ /**
919
+ * Test object cache cache.
920
+ *
921
+ * @since 2.0.0
922
+ *
923
+ * @param string engine Cache storage engine.
924
+ * @param string label Text label for the engine.
925
+ * @return jqXHR
926
+ */
927
+ function testObjcache( engine, label ) {
928
+ if ( configSuccess ) {
929
+ return jQuery.ajax({
930
+ method: 'POST',
931
+ url: ajaxurl,
932
+ data: {
933
+ _wpnonce: nonce,
934
+ action: 'w3tc_test_objcache'
935
+ }
936
+ })
937
+ .done(function( testResponse ) {
938
+ $container.find( '#test-results' ).data( 'oc-' + engine, testResponse.data );
939
+ addResultRow( testResponse, engine, label );
940
+ });
941
+ } else {
942
+ addResultRow( [ success => false ], engine, label );
943
+ }
944
+ }
945
+
946
+ // Run config and tests.
947
+ getObjcacheSettings()
948
+ .then( function() {
949
+ return configObjcache( 0 );
950
+ }, configFailed )
951
+ .then( function() {
952
+ return testObjcache( 'none', W3TC_SetupGuide.none );
953
+ }, configFailed )
954
+ .then( function() {
955
+ return configObjcache( 1, 'file' );
956
+ } , testFailed )
957
+ .then( function() {
958
+ return testObjcache( 'file', W3TC_SetupGuide.disk );
959
+ }, configFailed )
960
+ .then( function() {
961
+ return configObjcache( 1, 'redis' );
962
+ }, testFailed )
963
+ .then( function() {
964
+ return testObjcache( 'redis', 'Redis' );
965
+ }, configFailed )
966
+ .then( function() {
967
+ return configObjcache( 1, 'memcached' );
968
+ }, testFailed )
969
+ .then( function() {
970
+ return testObjcache( 'memcached', 'Memcached' );
971
+ }, configFailed )
972
+ .then( function() {
973
+ return configObjcache( 1, 'apc' );
974
+ }, testFailed )
975
+ .then( function() {
976
+ return testObjcache( 'apc', 'APC' );
977
+ }, configFailed )
978
+ .then( function() {
979
+ return configObjcache( 1, 'eaccelerator' );
980
+ }, testFailed )
981
+ .then( function() {
982
+ return testObjcache( 'eaccelerator', 'eAccelerator' );
983
+ }, configFailed )
984
+ .then( function() {
985
+ return configObjcache( 1, 'xcache' );
986
+ }, testFailed )
987
+ .then( function() {
988
+ return testObjcache( 'xcache', 'XCache' );
989
+ }, configFailed )
990
+ .then( function() {
991
+ return configObjcache( 1, 'wincache' );
992
+ }, testFailed )
993
+ .then( function() {
994
+ return testObjcache( 'wincache', 'WinCache' );
995
+ }, configFailed )
996
+ .then(function() {
997
+ $spinnerParent.hide();
998
+ $this.prop( 'disabled', false );
999
+ $prevButton.prop( 'disabled', false );
1000
+ $nextButton.prop( 'disabled', false );
1001
+ return true;
1002
+ }, testFailed )
1003
+ // Restore the original object cache settings.
1004
+ .then( function() {
1005
+ return configObjcache( ( objcacheSettings.enabled ? 1 : 0 ), objcacheSettings.engine );
1006
+ },
1007
+ function() {
1008
+ $spinnerParent.hide();
1009
+ return configFailed();
1010
+ });
1011
+ });
1012
+
1013
+ break;
1014
+
1015
+ case 'w3tc-wizard-slide-bc1':
1016
+ // Save the object cache engine setting from the previous slide.
1017
+ var objcacheEngine = $container.find( 'input:checked[name="objcache_engine"]' ).val();
1018
+
1019
+ configObjcache( ( 'none' === objcacheEngine ? 0 : 1 ), 'none' === objcacheEngine ? '' : objcacheEngine )
1020
+ .fail( function() {
1021
+ $slide.append(
1022
+ '<div class="notice notice-error"><p><strong>' +
1023
+ W3TC_SetupGuide.config_error_msg +
1024
+ '</strong></p></div>'
1025
+ );
1026
+ });
1027
+
1028
+ if ( ! jQuery( '#w3tc-wizard-step-objectcache .dashicons-yes' ).length ) {
1029
+ jQuery( '#w3tc-wizard-step-objectcache' ).append( '<span class="dashicons dashicons-yes"></span>' );
1030
+ }
1031
+
1032
+ // Present the Browser Cache slide.
1033
+ $container.find( '#w3tc-options-menu li' ).removeClass( 'is-active' );
1034
+ $container.find( '#w3tc-wizard-step-browsercache' ).addClass( 'is-active' );
1035
+
1036
+ if ( ! $container.find( '#test-results' ).data( 'bc-off' ) ) {
1037
+ $nextButton.prop( 'disabled', 'disabled' );
1038
+ }
1039
+
1040
+ $slide.find( '#w3tc-test-browsercache' ).off('click').on('click', function () {
1041
+ var bcEnabled,
1042
+ $spinnerParent = $slide.find( '.spinner' ).addClass( 'is-active' ).parent(),
1043
+ $this = jQuery( this );
1044
+
1045
+ $this.prop( 'disabled', 'disabled' );
1046
+ $slide.find( '.notice-error' ).remove();
1047
+ $container.find( '#w3tc-browsercache-table tbody' ).empty();
1048
+ $prevButton.prop( 'disabled', 'disabled' );
1049
+ $nextButton.prop( 'disabled', 'disabled' );
1050
+
1051
+ $spinnerParent.show();
1052
+
1053
+ /**
1054
+ * Add a Browser Cache test result table row.
1055
+ *
1056
+ * @since 2.0.0
1057
+ *
1058
+ * @param object testResponse An object (success, data) containing a data array of objects
1059
+ * (url, filename, header, headers).
1060
+ */
1061
+ function addResultRow( testResponse ) {
1062
+ var label = bcEnabled ? W3TC_SetupGuide.enabled : W3TC_SetupGuide.notEnabled,
1063
+ results = '<tr',
1064
+ isCurrentSetting = bcEnabled == browsercacheSettings.enabled;
1065
+
1066
+ if ( ! configSuccess ) {
1067
+ results += ' class="w3tc-option-disabled"';
1068
+ }
1069
+
1070
+ results += '><td><input type="radio" id="browsercache-enable-' +
1071
+ label +
1072
+ '" name="browsercache_enable" value="' +
1073
+ bcEnabled +
1074
+ '"';
1075
+
1076
+ if ( ! configSuccess ) {
1077
+ results += ' disabled="disabled"';
1078
+ }
1079
+
1080
+ if ( isCurrentSetting ) {
1081
+ results += ' checked';
1082
+ }
1083
+
1084
+ results += '> <label for="browsercache-enable-' +
1085
+ label +
1086
+ '">' +
1087
+ label +
1088
+ '</label>';
1089
+
1090
+ if ( isCurrentSetting ) {
1091
+ results += ' <span class="dashicons dashicons-admin-settings" title="Current setting"></span>';
1092
+ }
1093
+
1094
+ results += '</td>';
1095
+
1096
+ if ( testResponse.success ) {
1097
+ results += '<td>';
1098
+
1099
+ testResponse.data.forEach( function( item, index ) {
1100
+ results += '<a href="' +
1101
+ item.url +
1102
+ '">' +
1103
+ item.filename +
1104
+ '</a></td><td>' +
1105
+ item.header +
1106
+ '</td></tr>';
1107
+
1108
+ // If not the last entry, then start the next row.
1109
+ if ( index !== ( testResponse.data.length - 1 ) ) {
1110
+ results += '<tr><td></td><td>';
1111
+ }
1112
+ } );
1113
+ } else {
1114
+ results = '<td colspan="2">' +
1115
+ W3TC_SetupGuide.test_error_msg +
1116
+ '</td></tr>';
1117
+ }
1118
+
1119
+ $container.find( '#w3tc-browsercache-table > tbody' ).append( results );
1120
+ $container.find( '#w3tc-browsercache-table' ).show();
1121
+ }
1122
+
1123
+ /**
1124
+ * Test browser cache.
1125
+ *
1126
+ * @since 2.0.0
1127
+ *
1128
+ * @return jqXHR
1129
+ */
1130
+ function testBrowsercache() {
1131
+ if ( configSuccess ) {
1132
+ return jQuery.ajax({
1133
+ method: 'POST',
1134
+ url: ajaxurl,
1135
+ data: {
1136
+ _wpnonce: nonce,
1137
+ action: 'w3tc_test_browsercache'
1138
+ }
1139
+ })
1140
+ .done(function( testResponse ) {
1141
+ var enabled = bcEnabled ? 'on' : 'off';
1142
+
1143
+ $container.find( '#test-results' ).data( 'bc-' + enabled, testResponse.data );
1144
+ addResultRow( testResponse );
1145
+ });
1146
+ } else {
1147
+ addResultRow( [ success => false ] );
1148
+ }
1149
+ }
1150
+
1151
+ // Run config and tests.
1152
+ getBrowsercacheSettings()
1153
+ .then( function() {
1154
+ bcEnabled = 0;
1155
+ return configBrowsercache( bcEnabled );
1156
+ }, configFailed )
1157
+ .then( testBrowsercache, configFailed )
1158
+ .then( function() {
1159
+ bcEnabled = 1;
1160
+ return configBrowsercache( bcEnabled );
1161
+ } , testFailed )
1162
+ .then( testBrowsercache, configFailed )
1163
+ .then(function() {
1164
+ $spinnerParent.hide();
1165
+ $this.prop( 'disabled', false );
1166
+ $prevButton.prop( 'disabled', false );
1167
+ $nextButton.prop( 'disabled', false );
1168
+ return true;
1169
+ }, testFailed )
1170
+ // Restore the original browser cache settings.
1171
+ .then( function() {
1172
+ return configBrowsercache( ( browsercacheSettings.enabled ? 1 : 0 ) );
1173
+ },
1174
+ function() {
1175
+ $spinnerParent.hide();
1176
+ return configFailed();
1177
+ });
1178
+ });
1179
+
1180
+ break;
1181
+
1182
+ case 'w3tc-wizard-slide-ll1':
1183
+ // Save the browser cache setting from the previous slide.
1184
+ var browsercacheEnabled = $container.find( 'input:checked[name="browsercache_enable"]' ).val();
1185
+
1186
+ configBrowsercache( ( '1' === browsercacheEnabled ? 1 : 0 ) )
1187
+ .fail( function() {
1188
+ $slide.append(
1189
+ '<div class="notice notice-error"><p><strong>' +
1190
+ W3TC_SetupGuide.config_error_msg +
1191
+ '</strong></p></div>'
1192
+ );
1193
+ });
1194
+
1195
+ if ( ! jQuery( '#w3tc-wizard-step-browsercache .dashicons-yes' ).length ) {
1196
+ jQuery( '#w3tc-wizard-step-browsercache' ).append( '<span class="dashicons dashicons-yes"></span>' );
1197
+ }
1198
+
1199
+ // Present the Lazy Load slide.
1200
+ $container.find( '#w3tc-options-menu li' ).removeClass( 'is-active' );
1201
+ $container.find( '#w3tc-wizard-step-lazyload' ).addClass( 'is-active' );
1202
+ $dashboardButton.closest( 'span' ).hide();
1203
+ $nextButton.closest( 'span' ).show();
1204
+ $nextButton.prop( 'disabled', 'disabled' );
1205
+
1206
+ // Update the lazy load enable chackbox from saved config.
1207
+ getLazyloadSettings()
1208
+ .then( function() {
1209
+ $container.find( 'input#lazyload-enable' ).prop( 'checked', lazyloadSettings.enabled );
1210
+ $nextButton.prop( 'disabled', false );
1211
+ }, configFailed );
1212
+
1213
+ break;
1214
+
1215
+ case 'w3tc-wizard-slide-complete':
1216
+ var html,
1217
+ pgcacheEngine = $container.find( 'input:checked[name="pgcache_engine"]' ).val();
1218
+ pgcacheDiffPercent = $container.find( '#test-results' ).data( 'pgcacheDiffPercent-' + pgcacheEngine ),
1219
+ dbcacheEngine = $container.find( 'input:checked[name="dbcache_engine"]' ).val(),
1220
+ dbcacheEngineLabel = $container.find( 'input:checked[name="dbcache_engine"]' )
1221
+ .closest('td').next('td').text(),
1222
+ objcacheEngine = $container.find( 'input:checked[name="objcache_engine"]' ).val(),
1223
+ objcacheEngineLabel = $container.find( 'input:checked[name="objcache_engine"]' )
1224
+ .closest('td').next('td').text(),
1225
+ browsercacheEnabled = $container.find( 'input:checked[name="browsercache_enable"]' ).val(),
1226
+ lazyloadEnabled = $container.find( 'input:checked#lazyload-enable' ).val();
1227
+
1228
+ // Save the lazyload setting from the previous slide.
1229
+ configLazyload( ( '1' === lazyloadEnabled ? 1 : 0 ) )
1230
+ .fail( function() {
1231
+ $slide.append(
1232
+ '<div class="notice notice-error"><p><strong>' +
1233
+ W3TC_SetupGuide.config_error_msg +
1234
+ '</strong></p></div>'
1235
+ );
1236
+ });
1237
+
1238
+ if ( ! jQuery( '#w3tc-wizard-step-lazyload .dashicons-yes' ).length ) {
1239
+ jQuery( '#w3tc-wizard-step-lazyload' ).append( '<span class="dashicons dashicons-yes"></span>' );
1240
+ }
1241
+
1242
+ // Present the Setup Complete slide.
1243
+ $container.find( '#w3tc-options-menu li' ).removeClass( 'is-active' );
1244
+ $container.find( '#w3tc-options-menu li' ).last().addClass( 'is-active' );
1245
+
1246
+ html = ( pgcacheDiffPercent > 0 ? '+' : '' ) +
1247
+ pgcacheDiffPercent +
1248
+ '%';
1249
+
1250
+ $container.find( '#w3tc-ttfb-diff' ).html( html );
1251
+
1252
+ $container.find( '#w3tc-dbcache-engine' ).html( dbcacheEngineLabel );
1253
+
1254
+ $container.find( '#w3tc-objcache-engine' ).html( objcacheEngineLabel );
1255
+
1256
+ $container.find( '#w3tc-browsercache-setting' ).html(
1257
+ browsercacheEnabled ? W3TC_SetupGuide.enabled : W3TC_SetupGuide.none
1258
+ );
1259
+
1260
+ $container.find( '#w3tc-lazyload-setting' ).html(
1261
+ lazyloadEnabled ? W3TC_SetupGuide.enabled : W3TC_SetupGuide.none
1262
+ );
1263
+
1264
+ if ( ! jQuery( '#test-results' ).data( 'completed' ) ) {
1265
+ jQuery.ajax({
1266
+ method: 'POST',
1267
+ url: ajaxurl,
1268
+ data: {
1269
+ _wpnonce: nonce,
1270
+ action: "w3tc_wizard_skip"
1271
+ }
1272
+ })
1273
+ .done(function () {
1274
+ $container.find( '#test-results' ).data( 'completed', true );
1275
+ });
1276
+ }
1277
+
1278
+ $nextButton.closest( 'span' ).hide();
1279
+ $dashboardButton.closest( 'span' ).show();
1280
+
1281
+ break;
1282
+
1283
+ default:
1284
+ break;
1285
+ }
1286
+ };
pub/js/wizard.js ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * File: wizard.js
3
+ *
4
+ * JavaScript for the wizard.
5
+ *
6
+ * @since 2.0.0
7
+ */
8
+
9
+ jQuery(function() {
10
+ var $container = jQuery( '#w3tc-wizard-container'),
11
+ $skipLink = $container.find( '#w3tc-wizard-skip-link '),
12
+ $skipButton = $container.find( '#w3tc-wizard-skip '),
13
+ $nextButton = $container.find( '#w3tc-wizard-next '),
14
+ $previousButton = $container.find( '#w3tc-wizard-previous ');
15
+
16
+ jQuery( '.button-buy-plugin' ).parent().remove();
17
+
18
+ $skipLink.on( 'click', skipFunction );
19
+ $skipButton.on( 'click', skipFunction );
20
+
21
+ // Listen for clicks to go to the W3TC Dashboard.
22
+ $container.find( '#w3tc-wizard-dashboard' ).on( 'click', function () {
23
+ jQuery( window ).off( 'beforeunload' );
24
+ document.location = W3TC_SetupGuide.dashboardUrl;
25
+ });
26
+
27
+ /**
28
+ * Process the skip action.
29
+ *
30
+ * Saves and option to mark the wizard completed.
31
+ *
32
+ * @since 2.0.0
33
+ */
34
+ function skipFunction() {
35
+ var $this = jQuery( this ),
36
+ nodeName = $this.prop('nodeName'),
37
+ page = location.href.replace(/^.+page=/, '' );
38
+
39
+ if ( 'BUTTON' === nodeName ) {
40
+ $this
41
+ .prop( 'disabled', true )
42
+ .css( 'color', '#000' )
43
+ .text( 'Skipping...' );
44
+ }
45
+
46
+ // GA.
47
+ if ( window.w3tc_ga ) {
48
+ w3tc_ga( 'send', 'event', 'button', page, 'skip' );
49
+ }
50
+
51
+ jQuery.ajax({
52
+ method: 'POST',
53
+ url: ajaxurl,
54
+ data: {
55
+ _wpnonce: $container.find( '[name="_wpnonce"]' ).val(),
56
+ action: "w3tc_wizard_skip"
57
+ }
58
+ })
59
+ .done(function( response ) {
60
+ if ( 'BUTTON' === nodeName ) {
61
+ $this.text( 'Redirecting...' );
62
+ }
63
+
64
+ window.location.replace( location.href.replace(/page=.+$/, 'page=w3tc_dashboard') );
65
+ })
66
+ .fail(function() {
67
+ if ( 'BUTTON' === nodeName ) {
68
+ $this.text( 'Error with Ajax; reloading page...' );
69
+ }
70
+
71
+ location.reload();
72
+ });
73
+ };
74
+
75
+ $previousButton.on( 'click', function() {
76
+ var $currentSlide = $container.find( '.w3tc-wizard-slides:visible' ),
77
+ $previousSlide = $currentSlide.prev( '.w3tc-wizard-slides' );
78
+
79
+ if ( $previousSlide.length ) {
80
+ $currentSlide.hide();
81
+ $previousSlide.show();
82
+ $nextButton.prop( 'disabled', false );
83
+ }
84
+
85
+ // Hide the previous button and show the skip button on the first slide.
86
+ if ( 0 === $previousSlide.prev( '.w3tc-wizard-slides' ).length ) {
87
+ $previousButton.closest( 'span' ).hide();
88
+ $skipButton.closest( 'span' ).show();
89
+ }
90
+
91
+ w3tc_wizard_actions( $previousSlide );
92
+ });
93
+
94
+ $nextButton.on( 'click', function() {
95
+ var $currentSlide = $container.find( '.w3tc-wizard-slides:visible' ),
96
+ $nextSlide = $currentSlide.next( '.w3tc-wizard-slides' );
97
+
98
+ if ( $skipButton.is( ':visible' ) ) {
99
+ $skipButton.closest( 'span' ).hide();
100
+ $previousButton.closest( 'span' ).show();
101
+ }
102
+
103
+ if ( $nextSlide.length ) {
104
+ $currentSlide.hide();
105
+ $nextSlide.show();
106
+ }
107
+
108
+ // Disable the next button on the last slide.
109
+ if ( 0 === $nextSlide.next( '.w3tc-wizard-slides' ).length ) {
110
+ jQuery( this ).prop( 'disabled', 'disabled' );
111
+ }
112
+
113
+ w3tc_wizard_actions( $nextSlide );
114
+ });
115
+ });
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: boldgrid, fredericktownes, maxicusc, gidomanders, bwmarkle, harryj
3
  Tags: seo, cache, optimize, pagespeed, performance, caching, compression, maxcdn, nginx, varnish, redis, new relic, aws, amazon web services, s3, cloudfront, rackspace, cloudflare, azure, apache
4
  Requires at least: 3.2
5
  Tested up to: 5.6
6
- Stable tag: 0.15.2
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -275,6 +275,11 @@ Please reach out to all of these people and support their projects if you're so
275
 
276
  == Changelog ==
277
 
 
 
 
 
 
278
  = 0.15.2 =
279
  * Fix: Minify: Do not remove quotes around meta tags
280
  * Fix: Minify: Removal of spaces in calc function was breaking CSS
@@ -312,7 +317,7 @@ Please reach out to all of these people and support their projects if you're so
312
  * Update: Support background-image: together with background: for lazy loading
313
 
314
  = 0.14.2 =
315
- * Fixed WP-CLI rediect issue in multisite
316
  * Fix: Avoid PREG_JIT_STACKLIMIT_ERROR in minify
317
  * Fix: Prevent empty needle PHP warning
318
  * Update: Allow to specify URIs with a query string in Additional Pages
3
  Tags: seo, cache, optimize, pagespeed, performance, caching, compression, maxcdn, nginx, varnish, redis, new relic, aws, amazon web services, s3, cloudfront, rackspace, cloudflare, azure, apache
4
  Requires at least: 3.2
5
  Tested up to: 5.6
6
+ Stable tag: 2.0.0
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
275
 
276
  == Changelog ==
277
 
278
+ = 2.0.0 =
279
+ * Feature: Added the Setup Guide wizard for onboarding
280
+ * Update: Updated jQuery compatibility and methods deprecated in WordPress 5.6
281
+ * Fix: Browser Cache: Fixed ExpiresByType code; changed from modified time to client access time
282
+
283
  = 0.15.2 =
284
  * Fix: Minify: Do not remove quotes around meta tags
285
  * Fix: Minify: Removal of spaces in calc function was breaking CSS
317
  * Update: Support background-image: together with background: for lazy loading
318
 
319
  = 0.14.2 =
320
+ * Fixed WP-CLI redirect issue in multisite
321
  * Fix: Avoid PREG_JIT_STACKLIMIT_ERROR in minify
322
  * Fix: Prevent empty needle PHP warning
323
  * Update: Allow to specify URIs with a query string in Additional Pages
w3-total-cache-api.php CHANGED
@@ -5,7 +5,7 @@ if ( !defined( 'ABSPATH' ) ) {
5
  }
6
 
7
  define( 'W3TC', true );
8
- define( 'W3TC_VERSION', '0.15.2' );
9
  define( 'W3TC_POWERED_BY', 'W3 Total Cache' );
10
  define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' );
11
  define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' );
5
  }
6
 
7
  define( 'W3TC', true );
8
+ define( 'W3TC_VERSION', '2.0.0' );
9
  define( 'W3TC_POWERED_BY', 'W3 Total Cache' );
10
  define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' );
11
  define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' );
w3-total-cache.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
- /*
3
  * Plugin Name: W3 Total Cache
4
  * Plugin URI: https://www.boldgrid.com/totalcache/
5
  * Description: The highest rated and most complete WordPress performance plugin. Dramatically improve the speed and user experience of your site. Add browser, page, object and database caching as well as minify and content delivery network (CDN) to WordPress.
6
- * Version: 0.15.2
7
  * Requires at least: 3.2
8
  * Requires PHP: 5.3
9
  * Author: BoldGrid
@@ -12,6 +12,8 @@
12
  * License URI: https://www.gnu.org/licenses/gpl-2.0.html
13
  * Text Domain: w3-total-cache
14
  * Network: True
 
 
15
  */
16
 
17
  /*
@@ -47,28 +49,25 @@ if ( ! defined( 'ABSPATH' ) ) {
47
  die();
48
  }
49
 
50
- /**
51
- * Abort W3TC loading if WordPress is upgrading.
52
- */
53
  if ( defined( 'WP_INSTALLING' ) && WP_INSTALLING ) {
54
  return;
55
  }
56
 
57
- if ( version_compare( PHP_VERSION, '5.3.0', '<') ) {
58
  require_once dirname( __FILE__ ) . '/w3-total-cache-old-php.php';
59
  register_activation_hook( __FILE__, 'w3tc_old_php_activate' );
60
  return;
61
  }
62
 
63
  if ( ! defined( 'W3TC_IN_MINIFY' ) ) {
64
- /**
65
- * Require plugin configuration.
66
- */
67
  require_once dirname( __FILE__ ) . '/w3-total-cache-api.php';
68
 
69
  // Load the wp cli command - if run from wp-cli.
70
- if ( defined( 'WP_CLI' ) && WP_CLI )
71
  require_once W3TC_DIR . '/Cli.php';
 
72
 
73
  // Include to prevent syntax error for older php.
74
  require_once dirname( __FILE__ ) . '/Root_Loader.php';
1
  <?php
2
+ /**
3
  * Plugin Name: W3 Total Cache
4
  * Plugin URI: https://www.boldgrid.com/totalcache/
5
  * Description: The highest rated and most complete WordPress performance plugin. Dramatically improve the speed and user experience of your site. Add browser, page, object and database caching as well as minify and content delivery network (CDN) to WordPress.
6
+ * Version: 2.0.0
7
  * Requires at least: 3.2
8
  * Requires PHP: 5.3
9
  * Author: BoldGrid
12
  * License URI: https://www.gnu.org/licenses/gpl-2.0.html
13
  * Text Domain: w3-total-cache
14
  * Network: True
15
+ *
16
+ * phpcs:disable Squiz.Commenting.FileComment.MissingPackageTag
17
  */
18
 
19
  /*
49
  die();
50
  }
51
 
52
+ // Abort W3TC loading if WordPress is upgrading.
 
 
53
  if ( defined( 'WP_INSTALLING' ) && WP_INSTALLING ) {
54
  return;
55
  }
56
 
57
+ if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) {
58
  require_once dirname( __FILE__ ) . '/w3-total-cache-old-php.php';
59
  register_activation_hook( __FILE__, 'w3tc_old_php_activate' );
60
  return;
61
  }
62
 
63
  if ( ! defined( 'W3TC_IN_MINIFY' ) ) {
64
+ // Require plugin configuration.
 
 
65
  require_once dirname( __FILE__ ) . '/w3-total-cache-api.php';
66
 
67
  // Load the wp cli command - if run from wp-cli.
68
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
69
  require_once W3TC_DIR . '/Cli.php';
70
+ }
71
 
72
  // Include to prevent syntax error for older php.
73
  require_once dirname( __FILE__ ) . '/Root_Loader.php';