Version Description
- Fix: Error clearing all cache when using Cloudfront full CDN in Pro
Download this release
Release Info
Developer | joemoto |
Plugin | W3 Total Cache |
Version | 2.2.6 |
Comparing to | |
See all releases |
Code changes from version 2.2.4 to 2.2.6
- Base_Page_Settings.php +63 -16
- Cache_File.php +2 -1
- Cdn_Core.php +1 -1
- Cdn_Plugin.php +519 -443
- Cdn_Util.php +155 -59
- Cdnfsd_CacheFlush.php +109 -94
- DbCache_WpdbInjection_QueryCaching.php +89 -36
- Generic_Plugin_Admin.php +434 -357
- Root_Loader.php +123 -71
- inc/options/cdn.php +7 -1
- inc/options/cdn/s3.php +10 -4
- pub/js/options.js +5 -0
- readme.txt +14 -2
- w3-total-cache-api.php +1 -1
- w3-total-cache.php +2 -2
Base_Page_Settings.php
CHANGED
@@ -1,6 +1,17 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
namespace W3TC;
|
3 |
|
|
|
|
|
|
|
|
|
|
|
4 |
class Base_Page_Settings {
|
5 |
/**
|
6 |
* Config
|
@@ -44,24 +55,34 @@ class Base_Page_Settings {
|
|
44 |
*/
|
45 |
protected $_page;
|
46 |
|
47 |
-
|
|
|
|
|
|
|
48 |
$this->_config = Dispatcher::config();
|
49 |
$this->_config_master = Dispatcher::config_master();
|
50 |
$this->_page = Util_Admin::get_current_page();
|
51 |
}
|
52 |
|
53 |
-
|
|
|
|
|
|
|
54 |
$this->view();
|
55 |
}
|
56 |
|
|
|
|
|
|
|
57 |
public function render_footer() {
|
58 |
include W3TC_INC_OPTIONS_DIR . '/common/footer.php';
|
59 |
}
|
60 |
|
61 |
/**
|
62 |
-
* Returns true if config section is sealed
|
|
|
|
|
63 |
*
|
64 |
-
* @param string $section
|
65 |
* @return boolean
|
66 |
*/
|
67 |
protected function is_sealed( $section ) {
|
@@ -69,7 +90,7 @@ class Base_Page_Settings {
|
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
-
* Returns true if we edit master config
|
73 |
*
|
74 |
* @return boolean
|
75 |
*/
|
@@ -78,12 +99,13 @@ class Base_Page_Settings {
|
|
78 |
}
|
79 |
|
80 |
/**
|
81 |
-
* Prints checkbox with config option value
|
82 |
*
|
83 |
-
* @param string $option_id
|
84 |
-
* @param bool $disabled
|
85 |
-
* @param string $class_prefix
|
86 |
-
* @param bool $label
|
|
|
87 |
*/
|
88 |
protected function checkbox( $option_id, $disabled = false, $class_prefix = '', $label = true, $force_value = null ) {
|
89 |
$disabled = $disabled || $this->_config->is_sealed( $option_id );
|
@@ -101,6 +123,14 @@ class Base_Page_Settings {
|
|
101 |
|
102 |
if ( ! is_null( $force_value ) ) {
|
103 |
checked( $force_value, true );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
} else {
|
105 |
checked( $this->_config->get_boolean( $option_id ), true );
|
106 |
}
|
@@ -115,10 +145,10 @@ class Base_Page_Settings {
|
|
115 |
/**
|
116 |
* Prints a radio button and if config value matches value
|
117 |
*
|
118 |
-
* @param string $option_id
|
119 |
-
* @param unknown $value
|
120 |
-
* @param bool $disabled
|
121 |
-
* @param string $class_prefix
|
122 |
*/
|
123 |
protected function radio( $option_id, $value, $disabled = false, $class_prefix = '' ) {
|
124 |
if ( is_bool( $value ) ) {
|
@@ -143,9 +173,9 @@ class Base_Page_Settings {
|
|
143 |
}
|
144 |
|
145 |
/**
|
146 |
-
* Prints checkbox for debug option
|
147 |
*
|
148 |
-
* @param string $option_id
|
149 |
*/
|
150 |
protected function checkbox_debug( $option_id ) {
|
151 |
if ( is_array( $option_id ) ) {
|
@@ -175,6 +205,13 @@ class Base_Page_Settings {
|
|
175 |
echo ' />';
|
176 |
}
|
177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
protected function checkbox_debug_pro( $option_id, $label, $label_pro ) {
|
179 |
if ( is_array( $option_id ) ) {
|
180 |
$section = $option_id[0];
|
@@ -220,6 +257,13 @@ class Base_Page_Settings {
|
|
220 |
echo '</label>';
|
221 |
}
|
222 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
protected function value_with_disabled( $option_id, $disabled, $value_when_disabled ) {
|
224 |
if ( $disabled ) {
|
225 |
echo 'value="' . esc_attr( $value_when_disabled ) . '" disabled="disabled" ';
|
@@ -228,6 +272,9 @@ class Base_Page_Settings {
|
|
228 |
}
|
229 |
}
|
230 |
|
|
|
|
|
|
|
231 |
protected function view() {
|
232 |
include W3TC_INC_DIR . '/options/common/header.php';
|
233 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* File: Base_Page_Settings.php
|
4 |
+
*
|
5 |
+
* @package W3TC
|
6 |
+
*/
|
7 |
+
|
8 |
namespace W3TC;
|
9 |
|
10 |
+
/**
|
11 |
+
* Class: Base_Page_Settings
|
12 |
+
*
|
13 |
+
* phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
|
14 |
+
*/
|
15 |
class Base_Page_Settings {
|
16 |
/**
|
17 |
* Config
|
55 |
*/
|
56 |
protected $_page;
|
57 |
|
58 |
+
/**
|
59 |
+
* Constructor.
|
60 |
+
*/
|
61 |
+
public function __construct() {
|
62 |
$this->_config = Dispatcher::config();
|
63 |
$this->_config_master = Dispatcher::config_master();
|
64 |
$this->_page = Util_Admin::get_current_page();
|
65 |
}
|
66 |
|
67 |
+
/**
|
68 |
+
* Render header.
|
69 |
+
*/
|
70 |
+
public function options() {
|
71 |
$this->view();
|
72 |
}
|
73 |
|
74 |
+
/**
|
75 |
+
* Render footer.
|
76 |
+
*/
|
77 |
public function render_footer() {
|
78 |
include W3TC_INC_OPTIONS_DIR . '/common/footer.php';
|
79 |
}
|
80 |
|
81 |
/**
|
82 |
+
* Returns true if config section is sealed.
|
83 |
+
*
|
84 |
+
* @param string $section Config section.
|
85 |
*
|
|
|
86 |
* @return boolean
|
87 |
*/
|
88 |
protected function is_sealed( $section ) {
|
90 |
}
|
91 |
|
92 |
/**
|
93 |
+
* Returns true if we edit master config.
|
94 |
*
|
95 |
* @return boolean
|
96 |
*/
|
99 |
}
|
100 |
|
101 |
/**
|
102 |
+
* Prints checkbox with config option value.
|
103 |
*
|
104 |
+
* @param string $option_id Option ID.
|
105 |
+
* @param bool $disabled Disabled flag.
|
106 |
+
* @param string $class_prefix Class prefix.
|
107 |
+
* @param bool $label Label.
|
108 |
+
* @param bool $force_value Override value.
|
109 |
*/
|
110 |
protected function checkbox( $option_id, $disabled = false, $class_prefix = '', $label = true, $force_value = null ) {
|
111 |
$disabled = $disabled || $this->_config->is_sealed( $option_id );
|
123 |
|
124 |
if ( ! is_null( $force_value ) ) {
|
125 |
checked( $force_value, true );
|
126 |
+
} elseif ( 'cdn.flush_manually' === $option_id ) {
|
127 |
+
checked(
|
128 |
+
$this->_config->get_boolean(
|
129 |
+
$option_id,
|
130 |
+
Cdn_Util::get_flush_manually_default_override( $this->_config->get_string( 'cdn.engine' ) )
|
131 |
+
),
|
132 |
+
true
|
133 |
+
);
|
134 |
} else {
|
135 |
checked( $this->_config->get_boolean( $option_id ), true );
|
136 |
}
|
145 |
/**
|
146 |
* Prints a radio button and if config value matches value
|
147 |
*
|
148 |
+
* @param string $option_id Option id.
|
149 |
+
* @param unknown $value Value.
|
150 |
+
* @param bool $disabled Disabled flag.
|
151 |
+
* @param string $class_prefix Class prefix.
|
152 |
*/
|
153 |
protected function radio( $option_id, $value, $disabled = false, $class_prefix = '' ) {
|
154 |
if ( is_bool( $value ) ) {
|
173 |
}
|
174 |
|
175 |
/**
|
176 |
+
* Prints checkbox for debug option.
|
177 |
*
|
178 |
+
* @param string $option_id Option ID.
|
179 |
*/
|
180 |
protected function checkbox_debug( $option_id ) {
|
181 |
if ( is_array( $option_id ) ) {
|
205 |
echo ' />';
|
206 |
}
|
207 |
|
208 |
+
/**
|
209 |
+
* Prints checkbox for debug option for pro.
|
210 |
+
*
|
211 |
+
* @param string $option_id Option ID.
|
212 |
+
* @param unknown $label Label.
|
213 |
+
* @param unknown $label_pro Pro label.
|
214 |
+
*/
|
215 |
protected function checkbox_debug_pro( $option_id, $label, $label_pro ) {
|
216 |
if ( is_array( $option_id ) ) {
|
217 |
$section = $option_id[0];
|
257 |
echo '</label>';
|
258 |
}
|
259 |
|
260 |
+
/**
|
261 |
+
* Prints checkbox for debug option for pro.
|
262 |
+
*
|
263 |
+
* @param string $option_id Option ID.
|
264 |
+
* @param bool $disabled Disabled flag.
|
265 |
+
* @param unknown $value_when_disabled Override value when disabled.
|
266 |
+
*/
|
267 |
protected function value_with_disabled( $option_id, $disabled, $value_when_disabled ) {
|
268 |
if ( $disabled ) {
|
269 |
echo 'value="' . esc_attr( $value_when_disabled ) . '" disabled="disabled" ';
|
272 |
}
|
273 |
}
|
274 |
|
275 |
+
/**
|
276 |
+
* Render header.
|
277 |
+
*/
|
278 |
protected function view() {
|
279 |
include W3TC_INC_DIR . '/options/common/header.php';
|
280 |
}
|
Cache_File.php
CHANGED
@@ -156,8 +156,9 @@ class Cache_File extends Cache_Base {
|
|
156 |
return array( null, $has_old_data );
|
157 |
|
158 |
$fp = @fopen( $path, 'rb' );
|
159 |
-
if (
|
160 |
return array( null, $has_old_data );
|
|
|
161 |
|
162 |
if ( $this->_locking )
|
163 |
@flock( $fp, LOCK_SH );
|
156 |
return array( null, $has_old_data );
|
157 |
|
158 |
$fp = @fopen( $path, 'rb' );
|
159 |
+
if ( ! $fp || 4 > filesize( $path ) ) {
|
160 |
return array( null, $has_old_data );
|
161 |
+
}
|
162 |
|
163 |
if ( $this->_locking )
|
164 |
@flock( $fp, LOCK_SH );
|
Cdn_Core.php
CHANGED
@@ -727,7 +727,7 @@ class Cdn_Core {
|
|
727 |
}
|
728 |
}
|
729 |
|
730 |
-
return ltrim( $remote_uri, '/' );
|
731 |
}
|
732 |
|
733 |
/**
|
727 |
}
|
728 |
}
|
729 |
|
730 |
+
return apply_filters( 'w3tc_uri_cdn_uri', ltrim( $remote_uri, '/' ) );
|
731 |
}
|
732 |
|
733 |
/**
|
Cdn_Plugin.php
CHANGED
@@ -1,122 +1,104 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
/**
|
5 |
-
*
|
|
|
|
|
|
|
6 |
*/
|
7 |
class Cdn_Plugin {
|
8 |
-
|
9 |
/**
|
10 |
-
*
|
11 |
*
|
12 |
* @var string
|
13 |
*/
|
14 |
-
|
15 |
|
16 |
/**
|
17 |
-
* Config
|
|
|
|
|
18 |
*/
|
19 |
private $_config = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
private $_debug = false;
|
21 |
|
|
|
|
|
|
|
|
|
|
|
22 |
private $_attachments_action = array();
|
23 |
|
24 |
-
|
|
|
|
|
|
|
25 |
$this->_config = Dispatcher::config();
|
26 |
-
$this->_debug
|
27 |
}
|
28 |
|
29 |
/**
|
30 |
* Runs plugin
|
31 |
*/
|
32 |
-
function run() {
|
33 |
$cdn_engine = $this->_config->get_string( 'cdn.engine' );
|
34 |
|
35 |
-
add_filter( 'cron_schedules', array(
|
36 |
-
|
37 |
-
'cron_schedules'
|
38 |
-
) );
|
39 |
-
|
40 |
-
add_filter( 'w3tc_footer_comment', array(
|
41 |
-
$this,
|
42 |
-
'w3tc_footer_comment'
|
43 |
-
) );
|
44 |
-
|
45 |
-
if ( !Cdn_Util::is_engine_mirror( $cdn_engine ) ) {
|
46 |
-
add_action( 'w3_cdn_cron_queue_process', array(
|
47 |
-
$this,
|
48 |
-
'cron_queue_process'
|
49 |
-
) );
|
50 |
-
|
51 |
-
add_action( 'w3_cdn_cron_upload', array(
|
52 |
-
$this,
|
53 |
-
'cron_upload'
|
54 |
-
) );
|
55 |
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
add_filter( 'update_feedback', array(
|
62 |
-
$this,
|
63 |
-
'update_feedback'
|
64 |
-
) );
|
65 |
|
|
|
66 |
}
|
67 |
|
68 |
-
$
|
|
|
69 |
|
70 |
if ( $flush_on_actions ) {
|
71 |
-
add_action( 'delete_attachment',
|
72 |
-
|
73 |
-
|
74 |
-
add_filter( '
|
75 |
-
array( $this, 'check_inserting_new_attachment' ), 10, 2 );
|
76 |
-
|
77 |
-
add_filter( 'update_attached_file',
|
78 |
-
array( $this, 'update_attached_file' ) );
|
79 |
-
|
80 |
-
add_filter( 'wp_update_attachment_metadata',
|
81 |
-
array( $this, 'update_attachment_metadata' ) );
|
82 |
}
|
83 |
|
84 |
-
add_filter( 'w3tc_preflush_cdn_all',
|
85 |
-
|
86 |
-
|
87 |
-
add_filter( 'w3tc_admin_bar_menu',
|
88 |
-
array( $this, 'w3tc_admin_bar_menu' ) );
|
89 |
|
90 |
if ( is_admin() ) {
|
91 |
-
add_action( 'w3tc_config_ui_save-w3tc_cdn', array(
|
92 |
-
$this, 'change_canonical_header' ), 0, 0 );
|
93 |
add_filter( 'w3tc_module_is_running-cdn', array( $this, 'cdn_is_running' ) );
|
94 |
}
|
95 |
|
96 |
-
if ( !is_admin() || $this->_config->get_boolean( 'cdn.admin.media_library' ) ) {
|
97 |
-
add_filter( 'wp_prepare_attachment_for_js',
|
98 |
-
array( $this, 'wp_prepare_attachment_for_js' ), 0 );
|
99 |
-
|
100 |
-
add_filter( 'wp_get_attachment_image_src',
|
101 |
-
array( $this, 'wp_get_attachment_image_src' ), 0 );
|
102 |
}
|
103 |
|
104 |
-
|
105 |
-
* Start rewrite engine
|
106 |
-
*/
|
107 |
if ( $this->can_cdn() ) {
|
108 |
Util_Bus::add_ob_callback( 'cdn', array( $this, 'ob_callback' ) );
|
109 |
}
|
110 |
|
111 |
if ( is_admin() && Cdn_Util::can_purge( $cdn_engine ) ) {
|
112 |
-
add_filter( 'media_row_actions', array(
|
113 |
-
$this,
|
114 |
-
'media_row_actions'
|
115 |
-
), 0, 2 );
|
116 |
}
|
117 |
|
118 |
-
add_filter( 'w3tc_minify_http2_preload_url',
|
119 |
-
array( $this, 'w3tc_minify_http2_preload_url' ), 3000 );
|
120 |
}
|
121 |
|
122 |
/**
|
@@ -124,14 +106,14 @@ class Cdn_Plugin {
|
|
124 |
*
|
125 |
* @return Cdn_Core_Admin
|
126 |
*/
|
127 |
-
function get_admin() {
|
128 |
return Dispatcher::component( 'Cdn_Core_Admin' );
|
129 |
}
|
130 |
|
131 |
/**
|
132 |
* Cron queue process event
|
133 |
*/
|
134 |
-
function cron_queue_process() {
|
135 |
$queue_limit = $this->_config->get_integer( 'cdn.queue.limit' );
|
136 |
return $this->get_admin()->queue_process( $queue_limit );
|
137 |
}
|
@@ -139,32 +121,49 @@ class Cdn_Plugin {
|
|
139 |
/**
|
140 |
* Cron upload event
|
141 |
*/
|
142 |
-
function cron_upload() {
|
143 |
$files = $this->get_files();
|
144 |
|
145 |
-
$upload
|
146 |
$results = array();
|
147 |
|
148 |
$common = Dispatcher::component( 'Cdn_Core' );
|
149 |
|
150 |
foreach ( $files as $file ) {
|
151 |
-
$local_path
|
152 |
$remote_path = $common->uri_to_cdn_uri( $common->docroot_filename_to_uri( $file ) );
|
153 |
-
$upload[]
|
154 |
}
|
155 |
|
156 |
$common->upload( $upload, true, $results );
|
157 |
}
|
158 |
|
159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
$this->_attachments_action[ $postarr['file'] ] = empty( $postarr['ID'] ) ? 'insert' : 'update';
|
161 |
|
162 |
return $data;
|
163 |
}
|
164 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
public function w3tc_preflush_cdn_all( $do_flush, $extras = array() ) {
|
166 |
-
|
167 |
-
|
|
|
168 |
$do_flush = false;
|
169 |
}
|
170 |
}
|
@@ -177,19 +176,20 @@ class Cdn_Plugin {
|
|
177 |
*
|
178 |
* Upload _wp_attached_file
|
179 |
*
|
180 |
-
* @param string
|
|
|
181 |
* @return string
|
182 |
*/
|
183 |
-
function update_attached_file( $attached_file ) {
|
184 |
$common = Dispatcher::component( 'Cdn_Core' );
|
185 |
-
$files
|
186 |
-
$files
|
187 |
|
188 |
$results = array();
|
189 |
|
190 |
$cdn_engine = $this->_config->get_string( 'cdn.engine' );
|
191 |
if ( Cdn_Util::is_engine_mirror( $cdn_engine ) ) {
|
192 |
-
if ( ! array_key_exists( $attached_file, $this->_attachments_action ) || $this->_attachments_action[ $attached_file ]
|
193 |
$common->purge( $files, $results );
|
194 |
}
|
195 |
} else {
|
@@ -204,12 +204,12 @@ class Cdn_Plugin {
|
|
204 |
*
|
205 |
* Delete _wp_attached_file, _wp_attachment_metadata, _wp_attachment_backup_sizes
|
206 |
*
|
207 |
-
* @param integer $attachment_id
|
208 |
*/
|
209 |
-
function delete_attachment( $attachment_id ) {
|
210 |
$common = Dispatcher::component( 'Cdn_Core' );
|
211 |
-
$files
|
212 |
-
$files
|
213 |
|
214 |
$results = array();
|
215 |
|
@@ -226,19 +226,20 @@ class Cdn_Plugin {
|
|
226 |
*
|
227 |
* Upload _wp_attachment_metadata
|
228 |
*
|
229 |
-
* @param array
|
|
|
230 |
* @return array
|
231 |
*/
|
232 |
-
function update_attachment_metadata( $metadata ) {
|
233 |
$common = Dispatcher::component( 'Cdn_Core' );
|
234 |
-
$files
|
235 |
-
$files
|
236 |
|
237 |
$results = array();
|
238 |
|
239 |
$cdn_engine = $this->_config->get_string( 'cdn.engine' );
|
240 |
if ( Cdn_Util::is_engine_mirror( $cdn_engine ) ) {
|
241 |
-
if ($this->_config->get_boolean( 'cdn.uploads.enable' )) {
|
242 |
$common->purge( $files, $results );
|
243 |
}
|
244 |
} else {
|
@@ -251,54 +252,66 @@ class Cdn_Plugin {
|
|
251 |
/**
|
252 |
* Cron schedules filter
|
253 |
*
|
254 |
-
* @param array
|
|
|
255 |
* @return array
|
256 |
*/
|
257 |
-
function cron_schedules( $schedules ) {
|
258 |
$c = $this->_config;
|
259 |
|
260 |
-
if ( $c->get_boolean( 'cdn.enabled' ) &&
|
261 |
-
!Cdn_Util::is_engine_mirror( $c->get_string( 'cdn.engine' ) ) ) {
|
262 |
$queue_interval = $c->get_integer( 'cdn.queue.interval' );
|
|
|
263 |
$schedules['w3_cdn_cron_queue_process'] = array(
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
|
|
|
|
|
|
|
|
|
|
269 |
}
|
270 |
|
271 |
if ( $c->get_boolean( 'cdn.enabled' ) &&
|
272 |
$c->get_boolean( 'cdn.autoupload.enabled' ) &&
|
273 |
-
!Cdn_Util::is_engine_mirror( $c->get_string( 'cdn.engine' ) ) ) {
|
274 |
$autoupload_interval = $c->get_integer( 'cdn.autoupload.interval' );
|
|
|
275 |
$schedules['w3_cdn_cron_upload'] = array(
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
|
|
|
|
|
|
|
|
|
|
281 |
}
|
282 |
|
283 |
return $schedules;
|
284 |
}
|
285 |
|
286 |
/**
|
287 |
-
* Switch theme action
|
288 |
*/
|
289 |
-
function switch_theme() {
|
290 |
$state = Dispatcher::config_state();
|
291 |
$state->set( 'cdn.show_note_theme_changed', true );
|
292 |
$state->save();
|
293 |
}
|
294 |
|
295 |
/**
|
296 |
-
* WP Upgrade action hack
|
297 |
*
|
298 |
-
* @param string
|
299 |
*/
|
300 |
-
function update_feedback( $message ) {
|
301 |
-
if (
|
302 |
$state = Dispatcher::config_state();
|
303 |
$state->set( 'cdn.show_note_wp_upgraded', true );
|
304 |
$state->save();
|
@@ -306,21 +319,21 @@ class Cdn_Plugin {
|
|
306 |
}
|
307 |
|
308 |
/**
|
309 |
-
* OB Callback
|
|
|
|
|
310 |
*
|
311 |
-
* @param string $buffer
|
312 |
* @return string
|
313 |
*/
|
314 |
-
function ob_callback( $buffer ) {
|
315 |
-
if ( $buffer
|
316 |
if ( $this->can_cdn2( $buffer ) ) {
|
317 |
$srcset_helper = new _Cdn_Plugin_ContentFilter();
|
318 |
-
$buffer
|
319 |
|
320 |
if ( $this->_debug ) {
|
321 |
$replaced_urls = $srcset_helper->get_replaced_urls();
|
322 |
-
$buffer
|
323 |
-
$buffer, $replaced_urls );
|
324 |
}
|
325 |
}
|
326 |
}
|
@@ -329,11 +342,11 @@ class Cdn_Plugin {
|
|
329 |
}
|
330 |
|
331 |
/**
|
332 |
-
* Returns array of files to upload
|
333 |
*
|
334 |
* @return array
|
335 |
*/
|
336 |
-
function get_files() {
|
337 |
$files = array();
|
338 |
|
339 |
if ( $this->_config->get_boolean( 'cdn.includes.enable' ) ) {
|
@@ -360,13 +373,15 @@ class Cdn_Plugin {
|
|
360 |
*
|
361 |
* @return array
|
362 |
*/
|
363 |
-
function get_files_includes() {
|
364 |
$includes_root = Util_Environment::normalize_path( ABSPATH . WPINC );
|
365 |
-
$doc_root
|
366 |
$includes_path = ltrim( str_replace( $doc_root, '', $includes_root ), '/' );
|
367 |
|
368 |
$files = Cdn_Util::search_files(
|
369 |
-
$includes_root,
|
|
|
|
|
370 |
);
|
371 |
|
372 |
return $files;
|
@@ -377,69 +392,66 @@ class Cdn_Plugin {
|
|
377 |
*
|
378 |
* @return array
|
379 |
*/
|
380 |
-
function get_files_theme() {
|
381 |
-
|
382 |
-
|
383 |
-
* we should upload whole themes directory
|
384 |
-
*/
|
385 |
-
if ( $this->_config->get_boolean( 'mobile.enabled' )
|
386 |
-
|| $this->_config->get_boolean( 'referrer.enabled' ) ) {
|
387 |
$themes_root = get_theme_root();
|
388 |
} else {
|
389 |
$themes_root = get_stylesheet_directory();
|
390 |
}
|
391 |
|
392 |
$themes_root = Util_Environment::normalize_path( $themes_root );
|
393 |
-
$themes_path = ltrim( str_replace(
|
394 |
-
|
395 |
-
|
396 |
-
$
|
|
|
397 |
);
|
398 |
|
399 |
return $files;
|
400 |
}
|
401 |
|
402 |
/**
|
403 |
-
* Exports min files to CDN
|
404 |
*
|
405 |
* @return array
|
406 |
*/
|
407 |
-
function get_files_minify() {
|
408 |
$files = array();
|
409 |
|
410 |
if ( $this->_config->get_boolean( 'minify.rewrite' ) &&
|
411 |
Util_Rule::can_check_rules() &&
|
412 |
-
(
|
413 |
-
|
414 |
-
|
|
|
415 |
|
416 |
$minify = Dispatcher::component( 'Minify_Plugin' );
|
417 |
|
418 |
-
$document_root = Util_Environment::normalize_path(
|
419 |
-
|
420 |
-
$minify_root
|
421 |
-
|
422 |
-
$minify_path = ltrim( str_replace( $document_root, '', $minify_root ), '/' );
|
423 |
$urls = $minify->get_urls();
|
424 |
|
425 |
-
//
|
426 |
// common minify files are stored under context of main blog (i.e. 1)
|
427 |
-
// but have urls of 0 blog, so download has to be used
|
428 |
-
if ( $this->_config->get_string( 'minify.engine' )
|
429 |
-
!( Util_Environment::is_wpmu() && is_network_admin() ) ) {
|
430 |
-
|
431 |
foreach ( $urls as $url ) {
|
432 |
Util_Http::get( $url );
|
433 |
}
|
434 |
|
435 |
-
$files = Cdn_Util::search_files(
|
436 |
-
$
|
437 |
-
|
|
|
|
|
438 |
} else {
|
439 |
foreach ( $urls as $url ) {
|
440 |
$file = Util_Environment::normalize_file_minify( $url );
|
441 |
|
442 |
-
if ( !Util_Environment::is_url( $file ) ) {
|
443 |
$file = $document_root . '/' . $file;
|
444 |
$file = ltrim( str_replace( $minify_root, '', $file ), '/' );
|
445 |
|
@@ -465,47 +477,47 @@ class Cdn_Plugin {
|
|
465 |
*
|
466 |
* @return array
|
467 |
*/
|
468 |
-
function get_files_custom() {
|
469 |
-
$files
|
470 |
-
$document_root = Util_Environment::normalize_path(
|
471 |
-
|
472 |
-
$custom_files
|
473 |
-
$
|
474 |
-
$
|
475 |
-
$path = Util_Environment::site_url_uri();
|
476 |
$site_root_dir = str_replace( $document_root, '', $site_root );
|
477 |
if ( strstr( WP_CONTENT_DIR, Util_Environment::site_root() ) === false ) {
|
478 |
$site_root = Util_Environment::normalize_path( Util_Environment::document_root() );
|
479 |
-
$path
|
480 |
}
|
481 |
|
482 |
$content_path = trim( str_replace( WP_CONTENT_DIR, '', $site_root ), '/\\' );
|
483 |
|
484 |
foreach ( $custom_files as $custom_file ) {
|
485 |
-
if ( $custom_file
|
486 |
$custom_file = Cdn_Util::replace_folder_placeholders( $custom_file );
|
487 |
$custom_file = Util_Environment::normalize_file( $custom_file );
|
488 |
|
489 |
-
|
490 |
-
|
491 |
-
$rel_path = trim( dirname( $custom_file ), '/\\' );
|
492 |
-
} else
|
493 |
-
$rel_path = $dir = trim( dirname( $custom_file ), '/\\' );
|
494 |
|
495 |
-
if ( strpos( $dir, '<currentblog>' )
|
496 |
-
$
|
497 |
-
|
498 |
-
. Util_Environment::blog_id(), $dir
|
499 |
-
);
|
500 |
}
|
501 |
|
502 |
-
if (
|
503 |
-
$
|
|
|
504 |
}
|
505 |
-
|
|
|
506 |
$files = array_merge(
|
507 |
-
$files,
|
508 |
-
|
|
|
|
|
|
|
|
|
509 |
);
|
510 |
}
|
511 |
}
|
@@ -518,48 +530,38 @@ class Cdn_Plugin {
|
|
518 |
*
|
519 |
* @return boolean
|
520 |
*/
|
521 |
-
function can_cdn() {
|
522 |
-
|
523 |
-
* Skip if admin
|
524 |
-
*/
|
525 |
if ( defined( 'WP_ADMIN' ) ) {
|
526 |
-
$this->cdn_reject_reason = 'wp-admin';
|
527 |
|
528 |
return false;
|
529 |
}
|
530 |
|
531 |
-
|
532 |
-
* Check for WPMU's and WP's 3.0 short init
|
533 |
-
*/
|
534 |
if ( defined( 'SHORTINIT' ) && SHORTINIT ) {
|
535 |
-
$this->cdn_reject_reason = 'Short init';
|
536 |
|
537 |
return false;
|
538 |
}
|
539 |
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
if ( !$this->check_ua() ) {
|
544 |
-
$this->cdn_reject_reason = 'user agent is rejected';
|
545 |
|
546 |
return false;
|
547 |
}
|
548 |
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
if ( !$this->_check_request_uri() ) {
|
553 |
-
$this->cdn_reject_reason = 'request URI is rejected';
|
554 |
|
555 |
return false;
|
556 |
}
|
557 |
|
558 |
-
|
559 |
-
* Do not replace urls if SSL and SSL support is do not replace
|
560 |
-
*/
|
561 |
if ( Util_Environment::is_https() && $this->_config->get_boolean( 'cdn.reject.ssl' ) ) {
|
562 |
-
$this->cdn_reject_reason = 'SSL is rejected';
|
563 |
|
564 |
return false;
|
565 |
}
|
@@ -570,26 +572,21 @@ class Cdn_Plugin {
|
|
570 |
/**
|
571 |
* Returns true if we can do CDN logic
|
572 |
*
|
573 |
-
* @param unknown $buffer
|
|
|
574 |
* @return string
|
575 |
*/
|
576 |
-
function can_cdn2( $buffer ) {
|
577 |
-
|
578 |
-
* Check for DONOTCDN constant
|
579 |
-
*/
|
580 |
if ( defined( 'DONOTCDN' ) && DONOTCDN ) {
|
581 |
-
$this->cdn_reject_reason = 'DONOTCDN constant is defined';
|
582 |
|
583 |
return false;
|
584 |
}
|
585 |
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
if ( $this->_config->get_boolean(
|
590 |
-
'cdn.reject.logged_roles' ) && !$this->_check_logged_in_role_allowed()
|
591 |
-
) {
|
592 |
-
$this->cdn_reject_reason = 'logged in role is rejected';
|
593 |
|
594 |
return false;
|
595 |
}
|
@@ -598,17 +595,18 @@ class Cdn_Plugin {
|
|
598 |
}
|
599 |
|
600 |
/**
|
601 |
-
* Checks User Agent
|
602 |
*
|
603 |
* @return boolean
|
604 |
*/
|
605 |
-
function check_ua() {
|
606 |
-
$uas = array_merge(
|
607 |
-
|
608 |
-
|
|
|
609 |
|
610 |
foreach ( $uas as $ua ) {
|
611 |
-
if ( !empty( $ua ) ) {
|
612 |
if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && stristr( sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ), $ua ) !== false ) {
|
613 |
return false;
|
614 |
}
|
@@ -619,11 +617,11 @@ class Cdn_Plugin {
|
|
619 |
}
|
620 |
|
621 |
/**
|
622 |
-
* Checks request URI
|
623 |
*
|
624 |
* @return boolean
|
625 |
*/
|
626 |
-
function _check_request_uri() {
|
627 |
$reject_uri = $this->_config->get_array( 'cdn.reject.uri' );
|
628 |
$reject_uri = array_map( array( '\W3TC\Util_Environment', 'parse_path' ), $reject_uri );
|
629 |
|
@@ -631,14 +629,14 @@ class Cdn_Plugin {
|
|
631 |
$expr = trim( $expr );
|
632 |
$expr = str_replace( '~', '\~', $expr );
|
633 |
|
634 |
-
if ( $expr
|
635 |
return false;
|
636 |
}
|
637 |
}
|
638 |
|
639 |
-
|
640 |
-
if ( Util_Request::get_string( 'wp_customize' ) )
|
641 |
return false;
|
|
|
642 |
|
643 |
return true;
|
644 |
}
|
@@ -650,42 +648,45 @@ class Cdn_Plugin {
|
|
650 |
private function _check_logged_in_role_allowed() {
|
651 |
$current_user = wp_get_current_user();
|
652 |
|
653 |
-
if ( !is_user_logged_in() )
|
654 |
return true;
|
|
|
655 |
|
656 |
$roles = $this->_config->get_array( 'cdn.reject.roles' );
|
657 |
|
658 |
-
if ( empty( $roles ) || empty( $current_user->roles ) ||
|
659 |
-
!is_array( $current_user->roles ) )
|
660 |
return true;
|
|
|
661 |
|
662 |
foreach ( $current_user->roles as $role ) {
|
663 |
-
if ( in_array( $role, $roles ) )
|
664 |
return false;
|
|
|
665 |
}
|
666 |
|
667 |
return true;
|
668 |
}
|
669 |
|
670 |
/**
|
671 |
-
*
|
|
|
|
|
|
|
672 |
*
|
673 |
-
* @param array $actions
|
674 |
-
* @param object $post
|
675 |
* @return array
|
676 |
*/
|
677 |
-
function media_row_actions( $actions, $post ) {
|
678 |
return $this->get_admin()->media_row_actions( $actions, $post );
|
679 |
}
|
680 |
|
681 |
-
|
682 |
/**
|
|
|
683 |
*
|
|
|
684 |
*
|
685 |
-
* @param unknown $current_state
|
686 |
* @return bool
|
687 |
*/
|
688 |
-
function cdn_is_running( $current_state ) {
|
689 |
$admin = $this->get_admin();
|
690 |
return $admin->is_running();
|
691 |
}
|
@@ -693,24 +694,24 @@ class Cdn_Plugin {
|
|
693 |
/**
|
694 |
* Change canonical header
|
695 |
*/
|
696 |
-
function change_canonical_header() {
|
697 |
$admin = $this->get_admin();
|
698 |
$admin->change_canonical_header();
|
699 |
}
|
700 |
|
701 |
/**
|
702 |
-
* Adjusts attachment urls to cdn. This is for those who rely on
|
703 |
-
*
|
|
|
704 |
*
|
705 |
-
* @
|
706 |
-
* @return array
|
707 |
*/
|
708 |
public function wp_prepare_attachment_for_js( $response ) {
|
709 |
-
$response['url']
|
710 |
$response['link'] = $this->wp_prepare_attachment_for_js_url( $response['link'] );
|
711 |
|
712 |
-
if ( !empty( $response['sizes'] ) ) {
|
713 |
-
foreach( $response['sizes'] as $size => &$data ) {
|
714 |
$data['url'] = $this->wp_prepare_attachment_for_js_url( $data['url'] );
|
715 |
}
|
716 |
}
|
@@ -719,62 +720,38 @@ class Cdn_Plugin {
|
|
719 |
}
|
720 |
|
721 |
/**
|
722 |
-
* An attachment's local url to modify into a cdn url
|
723 |
*
|
724 |
-
* @param
|
725 |
-
*
|
|
|
726 |
*/
|
727 |
private function wp_prepare_attachment_for_js_url( $url ) {
|
728 |
$url = trim( $url );
|
729 |
-
if ( !empty( $url ) ) {
|
730 |
-
$parsed = parse_url( $url );
|
731 |
-
$uri = ( isset( $parsed['path'] ) ? $parsed['path'] : '/' ) .
|
732 |
-
( isset( $parsed['query'] ) ? '?' . $parsed['query'] : '' );
|
733 |
-
|
734 |
-
$wp_upload_dir = wp_upload_dir();
|
735 |
-
$upload_base_url = $wp_upload_dir['baseurl'];
|
736 |
-
|
737 |
-
if ( substr($url, 0, strlen( $upload_base_url ) ) == $upload_base_url ) {
|
738 |
-
$common = Dispatcher::component( 'Cdn_Core' );
|
739 |
-
$new_url = $common->url_to_cdn_url( $url, $uri );
|
740 |
-
if ( !is_null( $new_url ) ) {
|
741 |
-
$url = $new_url;
|
742 |
-
}
|
743 |
-
}
|
744 |
-
}
|
745 |
-
|
746 |
-
return $url;
|
747 |
-
}
|
748 |
-
|
749 |
-
/**
|
750 |
-
* Adjusts attachment image src to cdn. This is for those who rely on
|
751 |
-
* wp_get_attachment_image_src()
|
752 |
-
*
|
753 |
-
* @param array $image Image object
|
754 |
-
* @return array
|
755 |
-
*/
|
756 |
-
function wp_get_attachment_image_src( $image ) {
|
757 |
-
$url = empty( $image[0] ) ? null : trim( $image[0] );
|
758 |
-
|
759 |
if ( ! empty( $url ) ) {
|
760 |
-
$parsed
|
761 |
-
$uri
|
|
|
|
|
762 |
$wp_upload_dir = wp_upload_dir();
|
763 |
$upload_base_url = $wp_upload_dir['baseurl'];
|
|
|
764 |
if ( substr( $url, 0, strlen( $upload_base_url ) ) === $upload_base_url ) {
|
765 |
$common = Dispatcher::component( 'Cdn_Core' );
|
766 |
$new_url = $common->url_to_cdn_url( $url, $uri );
|
767 |
if ( ! is_null( $new_url ) ) {
|
768 |
-
$
|
769 |
}
|
770 |
}
|
771 |
}
|
772 |
|
773 |
-
return $
|
774 |
}
|
775 |
|
776 |
/**
|
777 |
* Mutate http/2 header links
|
|
|
|
|
778 |
*/
|
779 |
public function w3tc_minify_http2_preload_url( $data ) {
|
780 |
$url = $data['result_link'];
|
@@ -784,60 +761,73 @@ class Cdn_Plugin {
|
|
784 |
return $data;
|
785 |
}
|
786 |
|
787 |
-
$parsed =
|
788 |
-
$uri
|
789 |
-
|
790 |
|
791 |
-
$common
|
792 |
$new_url = $common->url_to_cdn_url( $url, $uri );
|
793 |
if ( is_null( $new_url ) ) {
|
794 |
return $data;
|
795 |
}
|
796 |
|
797 |
$data['result_link'] = $new_url;
|
798 |
-
|
|
|
799 |
$data['browsercache_processed'] = '*';
|
800 |
|
801 |
return $data;
|
802 |
}
|
803 |
|
|
|
|
|
|
|
|
|
|
|
804 |
public function w3tc_admin_bar_menu( $menu_items ) {
|
805 |
$cdn_engine = $this->_config->get_string( 'cdn.engine' );
|
806 |
|
807 |
if ( Cdn_Util::can_purge_all( $cdn_engine ) ) {
|
808 |
$menu_items['20710.cdn'] = array(
|
809 |
-
'id'
|
810 |
'parent' => 'w3tc_flush',
|
811 |
-
'title'
|
812 |
-
'href'
|
813 |
-
'admin.php?page=w3tc_cdn&w3tc_flush_cdn' ),
|
814 |
-
'w3tc' )
|
815 |
);
|
816 |
}
|
817 |
|
818 |
if ( Cdn_Util::can_purge( $cdn_engine ) ) {
|
819 |
$menu_items['20790.cdn'] = array(
|
820 |
-
'id'
|
821 |
'parent' => 'w3tc_flush',
|
822 |
-
'title'
|
823 |
-
'href'
|
824 |
-
'meta'
|
825 |
);
|
826 |
}
|
827 |
|
828 |
return $menu_items;
|
829 |
}
|
830 |
|
|
|
|
|
|
|
|
|
|
|
831 |
public function w3tc_footer_comment( $strings ) {
|
832 |
$common = Dispatcher::component( 'Cdn_Core' );
|
833 |
-
$cdn
|
834 |
-
$via
|
835 |
|
836 |
$strings[] = sprintf(
|
837 |
-
|
|
|
|
|
|
|
|
|
838 |
( $via ? $via : 'N/A' ),
|
839 |
-
( empty( $this->cdn_reject_reason ) ? '' :
|
840 |
-
|
841 |
|
842 |
if ( $this->_debug ) {
|
843 |
$strings[] = '{w3tc_cdn_debug_info}';
|
@@ -846,35 +836,68 @@ class Cdn_Plugin {
|
|
846 |
return $strings;
|
847 |
}
|
848 |
|
849 |
-
|
850 |
-
|
|
|
|
|
|
|
|
|
851 |
public function w3tc_footer_comment_after( $buffer, $replaced_urls ) {
|
852 |
$strings = array();
|
853 |
|
854 |
-
if ( is_array( $replaced_urls ) &&
|
855 |
-
|
856 |
-
$strings[] = "Replaced URLs for CDN:";
|
857 |
|
858 |
foreach ( $replaced_urls as $old_url => $new_url ) {
|
859 |
-
$strings[] = sprintf(
|
|
|
860 |
Util_Content::escape_comment( $old_url ),
|
861 |
-
Util_Content::escape_comment( $new_url )
|
|
|
862 |
}
|
863 |
|
864 |
$strings[] = '';
|
865 |
}
|
866 |
|
867 |
-
$buffer = str_replace( '{w3tc_cdn_debug_info}',
|
868 |
-
|
869 |
return $buffer;
|
870 |
}
|
871 |
}
|
872 |
|
873 |
-
|
874 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
875 |
private $_regexps = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
876 |
private $_placeholders = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
877 |
private $_config;
|
|
|
|
|
|
|
|
|
|
|
|
|
878 |
private $_replaced_urls = array();
|
879 |
|
880 |
/**
|
@@ -884,21 +907,35 @@ class _Cdn_Plugin_ContentFilter {
|
|
884 |
*/
|
885 |
private static $_upload_scheduled = false;
|
886 |
|
887 |
-
|
|
|
|
|
|
|
888 |
$this->_config = Dispatcher::config();
|
889 |
}
|
890 |
|
891 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
892 |
$this->fill_regexps();
|
893 |
|
894 |
$srcset_pattern = '~srcset\s*=\s*[\"\'](.*?)[\"\']~';
|
895 |
-
$buffer
|
896 |
-
$srcset_pattern,
|
|
|
|
|
897 |
);
|
898 |
|
899 |
foreach ( $this->_regexps as $regexp ) {
|
900 |
$buffer = preg_replace_callback(
|
901 |
-
$regexp,
|
|
|
|
|
902 |
);
|
903 |
}
|
904 |
|
@@ -912,14 +949,12 @@ class _Cdn_Plugin_ContentFilter {
|
|
912 |
$processor = array( $this, '_minify_auto_pushcdn_link_replace_callback' );
|
913 |
}
|
914 |
} else {
|
915 |
-
$minify_url_regexp = $this->minify_url_regexp(
|
916 |
-
|
917 |
-
|
918 |
-
$processor = array( $this, '_link_replace_callback' );
|
919 |
}
|
920 |
|
921 |
-
if ( !empty( $minify_url_regexp ) ) {
|
922 |
-
$regexp = '~(["\'(=])\s*' . $minify_url_regexp .'~U';
|
923 |
$buffer = preg_replace_callback( $regexp, $processor, $buffer );
|
924 |
}
|
925 |
}
|
@@ -930,15 +965,17 @@ class _Cdn_Plugin_ContentFilter {
|
|
930 |
}
|
931 |
|
932 |
/**
|
933 |
-
* Link replace callback
|
|
|
|
|
934 |
*
|
935 |
-
* @param array $matches
|
936 |
* @return string
|
937 |
*/
|
938 |
-
function _link_replace_callback( $matches ) {
|
939 |
list( $match, $quote, $url, , , , $path ) = $matches;
|
|
|
940 |
$path = ltrim( $path, '/' );
|
941 |
-
$r
|
942 |
if ( is_null( $r ) ) {
|
943 |
$r = $this->_link_replace_callback_ask_cdn( $match, $quote, $url, $path );
|
944 |
}
|
@@ -946,42 +983,61 @@ class _Cdn_Plugin_ContentFilter {
|
|
946 |
return $r;
|
947 |
}
|
948 |
|
949 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
950 |
list( $match, $srcset ) = $matches;
|
951 |
-
|
|
|
952 |
return $match;
|
953 |
-
|
954 |
|
955 |
-
$
|
|
|
|
|
956 |
$new_srcset_urls = array();
|
957 |
|
958 |
foreach ( $srcset_urls as $set ) {
|
959 |
-
|
960 |
-
preg_match( "~(?P<spaces>^\s*)(?P<url>\S+)(?P<rest>.*)~", $set, $parts );
|
961 |
if ( isset( $parts['url'] ) ) {
|
962 |
-
|
963 |
foreach ( $this->_regexps as $regexp ) {
|
964 |
-
$new_url = preg_replace_callback(
|
|
|
|
|
965 |
$this,
|
966 |
-
'_link_replace_callback'
|
967 |
-
),
|
|
|
|
|
968 |
|
969 |
-
if ( '"' . $parts['url'] . '">'
|
970 |
$parts['url'] = substr( $new_url, 1, -2 );
|
971 |
break;
|
972 |
}
|
973 |
}
|
974 |
-
$new_srcset_urls[] = $parts['spaces']
|
975 |
-
. $parts['rest'];
|
976 |
} else {
|
977 |
$new_srcset_urls[] = $set;
|
978 |
}
|
979 |
-
|
980 |
}
|
981 |
-
|
|
|
|
|
982 |
return 'srcset="' . $index . '"';
|
983 |
}
|
984 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
985 |
private function replace_placeholders( $buffer ) {
|
986 |
foreach ( $this->_placeholders as $srcset_id => $srcset_content ) {
|
987 |
$buffer = str_replace( $srcset_id, $srcset_content, $buffer );
|
@@ -992,20 +1048,27 @@ class _Cdn_Plugin_ContentFilter {
|
|
992 |
/**
|
993 |
* Gets regexp for minified files
|
994 |
*
|
|
|
|
|
995 |
* @return string
|
996 |
*/
|
997 |
private function minify_url_regexp( $filename_mask ) {
|
998 |
$minify_base_url = Util_Environment::filename_to_url(
|
999 |
Util_Environment::cache_blog_minify_dir()
|
1000 |
);
|
1001 |
-
$matches
|
1002 |
-
if ( !preg_match( '~((https?://)?([^/]+))(.+)~i', $minify_base_url, $matches ) ) {
|
1003 |
-
error_log(
|
|
|
|
|
|
|
|
|
|
|
1004 |
return '';
|
1005 |
}
|
1006 |
|
1007 |
$protocol_domain_regexp = Util_Environment::get_url_regexp( $matches[1] );
|
1008 |
-
$path_regexp
|
1009 |
|
1010 |
$regexp =
|
1011 |
'(' .
|
@@ -1016,49 +1079,51 @@ class _Cdn_Plugin_ContentFilter {
|
|
1016 |
}
|
1017 |
|
1018 |
/**
|
|
|
1019 |
*
|
|
|
|
|
|
|
|
|
1020 |
*
|
1021 |
-
* @param unknown $domain_url_regexp
|
1022 |
-
* @param unknown $baseurl
|
1023 |
-
* @param unknown $upload_info
|
1024 |
-
* @param unknown $regexps
|
1025 |
* @return array
|
1026 |
*/
|
1027 |
-
private function make_uploads_regexes( $domain_url_regexp, $baseurl,
|
1028 |
-
$upload_info, $regexps ) {
|
1029 |
if ( preg_match( '~' . $domain_url_regexp . '~i', $baseurl ) ) {
|
1030 |
$regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp . ')?('
|
1031 |
. Util_Environment::preg_quote( $upload_info['baseurlpath'] )
|
1032 |
. '([^"\')>]+)))~i';
|
1033 |
} else {
|
1034 |
-
$parsed
|
1035 |
-
$upload_url_domain_regexp = isset( $parsed['host'] )
|
1036 |
-
|
1037 |
-
|
1038 |
-
$baseurlpath
|
1039 |
-
if ( $baseurlpath )
|
1040 |
$regexps[] = '~(["\'])\s*((' . $upload_url_domain_regexp . ')?('
|
1041 |
. Util_Environment::preg_quote( $baseurlpath )
|
1042 |
. '([^"\'>]+)))~i';
|
1043 |
-
else
|
1044 |
$regexps[] = '~(["\'])\s*((' . $upload_url_domain_regexp
|
1045 |
. ')(([^"\'>]+)))~i';
|
|
|
1046 |
}
|
1047 |
return $regexps;
|
1048 |
}
|
1049 |
|
|
|
|
|
|
|
1050 |
private function fill_regexps() {
|
1051 |
$regexps = array();
|
1052 |
|
1053 |
-
$site_path
|
1054 |
$domain_url_regexp = Util_Environment::home_domain_root_url_regexp();
|
1055 |
|
1056 |
$site_domain_url_regexp = false;
|
1057 |
-
if ( $domain_url_regexp
|
1058 |
-
|
1059 |
-
|
1060 |
-
Util_Environment::url_to_host( site_url() )
|
1061 |
-
);
|
1062 |
|
1063 |
if ( $this->_config->get_boolean( 'cdn.uploads.enable' ) ) {
|
1064 |
$upload_info = Util_Http::upload_info();
|
@@ -1067,56 +1132,59 @@ class _Cdn_Plugin_ContentFilter {
|
|
1067 |
$baseurl = $upload_info['baseurl'];
|
1068 |
|
1069 |
if ( defined( 'DOMAIN_MAPPING' ) && DOMAIN_MAPPING ) {
|
1070 |
-
$parsed
|
1071 |
$baseurl = home_url() . $parsed['path'];
|
1072 |
}
|
1073 |
|
1074 |
$regexps = $this->make_uploads_regexes(
|
1075 |
-
$domain_url_regexp,
|
|
|
|
|
|
|
1076 |
);
|
1077 |
-
|
|
|
1078 |
$regexps = $this->make_uploads_regexes(
|
1079 |
-
$site_domain_url_regexp,
|
|
|
|
|
|
|
1080 |
);
|
|
|
1081 |
}
|
1082 |
}
|
1083 |
|
1084 |
if ( $this->_config->get_boolean( 'cdn.includes.enable' ) ) {
|
1085 |
$mask = $this->_config->get_string( 'cdn.includes.files' );
|
1086 |
-
if ( $mask
|
1087 |
-
$regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp .
|
1088 |
-
')?(' .
|
1089 |
Util_Environment::preg_quote( $site_path . WPINC ) .
|
1090 |
'/(' . Cdn_Util::get_regexp_by_mask( $mask ) . ')([^"\'() >]*)))~i';
|
1091 |
-
if ( $site_domain_url_regexp )
|
1092 |
-
$regexps[] = '~(["\'(=])\s*((' .
|
1093 |
-
$site_domain_url_regexp . ')?(' .
|
1094 |
Util_Environment::preg_quote( $site_path . WPINC ) .
|
1095 |
'/(' . Cdn_Util::get_regexp_by_mask( $mask ) .
|
1096 |
')([^"\'() >]*)))~i';
|
|
|
1097 |
}
|
1098 |
}
|
1099 |
|
1100 |
if ( $this->_config->get_boolean( 'cdn.theme.enable' ) ) {
|
1101 |
-
$theme_dir = preg_replace( '~'
|
1102 |
-
. $domain_url_regexp . '~i', '', get_theme_root_uri() );
|
1103 |
|
1104 |
$mask = $this->_config->get_string( 'cdn.theme.files' );
|
1105 |
|
1106 |
-
if ( $mask
|
1107 |
$regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp . ')?(' .
|
1108 |
Util_Environment::preg_quote( $theme_dir ) . '/(' .
|
1109 |
Cdn_Util::get_regexp_by_mask( $mask ) . ')([^"\'() >]*)))~i';
|
1110 |
if ( $site_domain_url_regexp ) {
|
1111 |
-
$theme_dir2 = preg_replace( '~' . $site_domain_url_regexp
|
1112 |
-
|
1113 |
-
$regexps[] = '~(["\'(=])\s*((' .
|
1114 |
-
$site_domain_url_regexp . ')?(' .
|
1115 |
Util_Environment::preg_quote( $theme_dir ) . '/(' .
|
1116 |
Cdn_Util::get_regexp_by_mask( $mask ) .
|
1117 |
')([^"\'() >]*)))~i';
|
1118 |
-
$regexps[]
|
1119 |
-
$site_domain_url_regexp . ')?(' .
|
1120 |
Util_Environment::preg_quote( $theme_dir2 ) .
|
1121 |
'/(' . Cdn_Util::get_regexp_by_mask( $mask ) .
|
1122 |
')([^"\'() >]*)))~i';
|
@@ -1130,25 +1198,24 @@ class _Cdn_Plugin_ContentFilter {
|
|
1130 |
$masks = array_map( array( '\W3TC\Util_Environment', 'parse_path' ), $masks );
|
1131 |
|
1132 |
if ( count( $masks ) ) {
|
1133 |
-
$custom_regexps_urls
|
1134 |
-
$custom_regexps_uris
|
1135 |
$custom_regexps_docroot_related = array();
|
1136 |
|
1137 |
foreach ( $masks as $mask ) {
|
1138 |
-
if ( !empty( $mask ) ) {
|
1139 |
if ( Util_Environment::is_url( $mask ) ) {
|
1140 |
$url_match = array();
|
1141 |
if ( preg_match( '~^((https?:)?//([^/]*))(.*)~', $mask, $url_match ) ) {
|
1142 |
$custom_regexps_urls[] = array(
|
1143 |
-
'domain_url' => Util_Environment::get_url_regexp(
|
1144 |
-
|
1145 |
-
'uri' => Cdn_Util::get_regexp_by_mask( $url_match[4] )
|
1146 |
);
|
1147 |
}
|
1148 |
-
} elseif ( substr( $mask, 0, 1 )
|
1149 |
$custom_regexps_uris[] = Cdn_Util::get_regexp_by_mask( $mask );
|
1150 |
} else {
|
1151 |
-
$file = Util_Environment::normalize_path( $mask ); // \ -> backspaces
|
1152 |
$file = str_replace( Util_Environment::site_root(), '', $file );
|
1153 |
$file = ltrim( $file, '/' );
|
1154 |
|
@@ -1169,14 +1236,14 @@ class _Cdn_Plugin_ContentFilter {
|
|
1169 |
}
|
1170 |
|
1171 |
if ( count( $custom_regexps_docroot_related ) > 0 ) {
|
1172 |
-
$regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp .
|
1173 |
-
|
1174 |
'(' . implode( '|', $custom_regexps_docroot_related ) . ')([^"\'() >]*)))~i';
|
1175 |
-
if ( $site_domain_url_regexp )
|
1176 |
-
$regexps[] = '~(["\'(=])\s*((' .
|
1177 |
-
$site_domain_url_regexp . ')?(' .
|
1178 |
Util_Environment::preg_quote( $site_path ) . '(' .
|
1179 |
implode( '|', $custom_regexps_docroot_related ) . ')([^"\'() >]*)))~i';
|
|
|
1180 |
}
|
1181 |
}
|
1182 |
}
|
@@ -1185,40 +1252,40 @@ class _Cdn_Plugin_ContentFilter {
|
|
1185 |
}
|
1186 |
|
1187 |
/**
|
1188 |
-
* Link replace callback, basic checks step
|
|
|
|
|
|
|
|
|
|
|
1189 |
*
|
1190 |
-
* @param string $match
|
1191 |
-
* @param string $quote
|
1192 |
-
* @param string $url
|
1193 |
-
* @param string $path
|
1194 |
* @return null|string
|
1195 |
*/
|
1196 |
-
function _link_replace_callback_checks( $match, $quote, $url, $path ) {
|
1197 |
global $wpdb;
|
|
|
1198 |
static $queue = null, $reject_files = null;
|
1199 |
|
1200 |
/**
|
1201 |
* Check if URL was already replaced
|
1202 |
*/
|
1203 |
-
if ( isset( $this->_replaced_urls[$url] ) ) {
|
1204 |
-
return $quote . $this->_replaced_urls[$url];
|
1205 |
}
|
1206 |
|
1207 |
/**
|
1208 |
* Check URL for rejected files
|
1209 |
*/
|
1210 |
-
if (
|
1211 |
$reject_files = $this->_config->get_array( 'cdn.reject.files' );
|
1212 |
}
|
1213 |
|
1214 |
foreach ( $reject_files as $reject_file ) {
|
1215 |
-
if ( $reject_file
|
1216 |
$reject_file = Cdn_Util::replace_folder_placeholders( $reject_file );
|
1217 |
-
|
1218 |
$reject_file = Util_Environment::normalize_file( $reject_file );
|
1219 |
|
1220 |
-
$reject_file_regexp = '~^('
|
1221 |
-
. Cdn_Util::get_regexp_by_mask( $reject_file ) . ')~i';
|
1222 |
|
1223 |
if ( preg_match( $reject_file_regexp, $path ) ) {
|
1224 |
return $match;
|
@@ -1226,40 +1293,45 @@ class _Cdn_Plugin_ContentFilter {
|
|
1226 |
}
|
1227 |
}
|
1228 |
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
|
|
|
|
1240 |
$queue = false;
|
1241 |
}
|
1242 |
}
|
|
|
1243 |
if ( $queue ) {
|
1244 |
return $match;
|
1245 |
}
|
|
|
1246 |
return null;
|
1247 |
}
|
1248 |
|
1249 |
/**
|
1250 |
* Link replace callback, url replacement using cdn engine
|
1251 |
*
|
1252 |
-
* @param string
|
1253 |
-
* @param string
|
1254 |
-
* @param string
|
1255 |
-
* @param string
|
|
|
1256 |
* @return null|string
|
1257 |
*/
|
1258 |
-
function _link_replace_callback_ask_cdn( $match, $quote, $url, $path ) {
|
1259 |
-
$common
|
1260 |
$new_url = $common->url_to_cdn_url( $url, $path );
|
1261 |
-
if ( !is_null( $new_url ) ) {
|
1262 |
-
$this->_replaced_urls[$url] = $new_url;
|
1263 |
return $quote . $new_url;
|
1264 |
}
|
1265 |
|
@@ -1267,31 +1339,30 @@ class _Cdn_Plugin_ContentFilter {
|
|
1267 |
}
|
1268 |
|
1269 |
/**
|
1270 |
-
* Link replace callback for urls from minify module using auto mode and in cdn of push type
|
|
|
|
|
1271 |
*
|
1272 |
-
* @param array $matches
|
1273 |
* @return string
|
1274 |
*/
|
1275 |
-
function _minify_auto_pushcdn_link_replace_callback( $matches ) {
|
1276 |
static $dispatcher = null;
|
1277 |
|
1278 |
list( $match, $quote, $url, , , , $path ) = $matches;
|
|
|
1279 |
$path = ltrim( $path, '/' );
|
1280 |
-
$r
|
1281 |
|
1282 |
-
|
1283 |
-
|
1284 |
-
*/
|
1285 |
-
if ( !Dispatcher::is_url_cdn_uploaded( $url ) ) {
|
1286 |
Dispatcher::component( 'Cdn_Core' )->queue_upload_url( $url );
|
1287 |
-
if ( !self::$_upload_scheduled ) {
|
1288 |
wp_schedule_single_event( time(), 'w3_cdn_cron_queue_process' );
|
1289 |
add_action( 'shutdown', 'wp_cron' );
|
1290 |
|
1291 |
self::$_upload_scheduled = true;
|
1292 |
}
|
1293 |
|
1294 |
-
|
1295 |
return $match;
|
1296 |
}
|
1297 |
|
@@ -1301,7 +1372,12 @@ class _Cdn_Plugin_ContentFilter {
|
|
1301 |
return $r;
|
1302 |
}
|
1303 |
|
1304 |
-
|
|
|
|
|
|
|
|
|
|
|
1305 |
return $this->_replaced_urls;
|
1306 |
}
|
1307 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* File: Cdn_Plugin.php
|
4 |
+
*
|
5 |
+
* @package W3TC
|
6 |
+
*/
|
7 |
+
|
8 |
namespace W3TC;
|
9 |
|
10 |
/**
|
11 |
+
* Class: Cdn_Plugin
|
12 |
+
*
|
13 |
+
* phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
|
14 |
+
* phpcs:disable PSR2.Methods.MethodDeclaration.Underscore
|
15 |
*/
|
16 |
class Cdn_Plugin {
|
|
|
17 |
/**
|
18 |
+
* Reject reason.
|
19 |
*
|
20 |
* @var string
|
21 |
*/
|
22 |
+
private $cdn_reject_reason = '';
|
23 |
|
24 |
/**
|
25 |
+
* Config.
|
26 |
+
*
|
27 |
+
* @var Config
|
28 |
*/
|
29 |
private $_config = null;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Debug flag.
|
33 |
+
*
|
34 |
+
* @var bool
|
35 |
+
*/
|
36 |
private $_debug = false;
|
37 |
|
38 |
+
/**
|
39 |
+
* Attachements action.
|
40 |
+
*
|
41 |
+
* @var array
|
42 |
+
*/
|
43 |
private $_attachments_action = array();
|
44 |
|
45 |
+
/**
|
46 |
+
* Constructor.
|
47 |
+
*/
|
48 |
+
public function __construct() {
|
49 |
$this->_config = Dispatcher::config();
|
50 |
+
$this->_debug = $this->_config->get_boolean( 'cdn.debug' );
|
51 |
}
|
52 |
|
53 |
/**
|
54 |
* Runs plugin
|
55 |
*/
|
56 |
+
public function run() {
|
57 |
$cdn_engine = $this->_config->get_string( 'cdn.engine' );
|
58 |
|
59 |
+
add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) ); // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected
|
60 |
+
add_filter( 'w3tc_footer_comment', array( $this, 'w3tc_footer_comment' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
+
if ( ! Cdn_Util::is_engine_mirror( $cdn_engine ) ) {
|
63 |
+
add_action( 'w3_cdn_cron_queue_process', array( $this, 'cron_queue_process' ) );
|
64 |
+
add_action( 'w3_cdn_cron_upload', array( $this, 'cron_upload' ) );
|
65 |
+
add_action( 'switch_theme', array( $this, 'switch_theme' ) );
|
|
|
|
|
|
|
|
|
|
|
66 |
|
67 |
+
add_filter( 'update_feedback', array( $this, 'update_feedback' ) );
|
68 |
}
|
69 |
|
70 |
+
$default_override = Cdn_Util::get_flush_manually_default_override( $cdn_engine );
|
71 |
+
$flush_on_actions = ! $this->_config->get_boolean( 'cdn.flush_manually', $default_override );
|
72 |
|
73 |
if ( $flush_on_actions ) {
|
74 |
+
add_action( 'delete_attachment', array( $this, 'delete_attachment' ) );
|
75 |
+
add_filter( 'wp_insert_attachment_data', array( $this, 'check_inserting_new_attachment' ), 10, 2 );
|
76 |
+
add_filter( 'update_attached_file', array( $this, 'update_attached_file' ) );
|
77 |
+
add_filter( 'wp_update_attachment_metadata', array( $this, 'update_attachment_metadata' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
}
|
79 |
|
80 |
+
add_filter( 'w3tc_preflush_cdn_all', array( $this, 'w3tc_preflush_cdn_all' ), 10, 2 );
|
81 |
+
add_filter( 'w3tc_admin_bar_menu', array( $this, 'w3tc_admin_bar_menu' ) );
|
|
|
|
|
|
|
82 |
|
83 |
if ( is_admin() ) {
|
84 |
+
add_action( 'w3tc_config_ui_save-w3tc_cdn', array( $this, 'change_canonical_header' ), 0, 0 );
|
|
|
85 |
add_filter( 'w3tc_module_is_running-cdn', array( $this, 'cdn_is_running' ) );
|
86 |
}
|
87 |
|
88 |
+
if ( ! is_admin() || $this->_config->get_boolean( 'cdn.admin.media_library' ) ) {
|
89 |
+
add_filter( 'wp_prepare_attachment_for_js', array( $this, 'wp_prepare_attachment_for_js' ), 0 );
|
|
|
|
|
|
|
|
|
90 |
}
|
91 |
|
92 |
+
// Start rewrite engine.
|
|
|
|
|
93 |
if ( $this->can_cdn() ) {
|
94 |
Util_Bus::add_ob_callback( 'cdn', array( $this, 'ob_callback' ) );
|
95 |
}
|
96 |
|
97 |
if ( is_admin() && Cdn_Util::can_purge( $cdn_engine ) ) {
|
98 |
+
add_filter( 'media_row_actions', array( $this, 'media_row_actions' ), 0, 2 );
|
|
|
|
|
|
|
99 |
}
|
100 |
|
101 |
+
add_filter( 'w3tc_minify_http2_preload_url', array( $this, 'w3tc_minify_http2_preload_url' ), 3000 );
|
|
|
102 |
}
|
103 |
|
104 |
/**
|
106 |
*
|
107 |
* @return Cdn_Core_Admin
|
108 |
*/
|
109 |
+
public function get_admin() {
|
110 |
return Dispatcher::component( 'Cdn_Core_Admin' );
|
111 |
}
|
112 |
|
113 |
/**
|
114 |
* Cron queue process event
|
115 |
*/
|
116 |
+
public function cron_queue_process() {
|
117 |
$queue_limit = $this->_config->get_integer( 'cdn.queue.limit' );
|
118 |
return $this->get_admin()->queue_process( $queue_limit );
|
119 |
}
|
121 |
/**
|
122 |
* Cron upload event
|
123 |
*/
|
124 |
+
public function cron_upload() {
|
125 |
$files = $this->get_files();
|
126 |
|
127 |
+
$upload = array();
|
128 |
$results = array();
|
129 |
|
130 |
$common = Dispatcher::component( 'Cdn_Core' );
|
131 |
|
132 |
foreach ( $files as $file ) {
|
133 |
+
$local_path = $common->docroot_filename_to_absolute_path( $file );
|
134 |
$remote_path = $common->uri_to_cdn_uri( $common->docroot_filename_to_uri( $file ) );
|
135 |
+
$upload[] = $common->build_file_descriptor( $local_path, $remote_path );
|
136 |
}
|
137 |
|
138 |
$common->upload( $upload, true, $results );
|
139 |
}
|
140 |
|
141 |
+
/**
|
142 |
+
* Check attachement insert
|
143 |
+
*
|
144 |
+
* @param array $data Attachement processed data.
|
145 |
+
* @param array $postarr Attachement un-processed data.
|
146 |
+
*
|
147 |
+
* @return array
|
148 |
+
*/
|
149 |
+
public function check_inserting_new_attachment( $data, $postarr ) {
|
150 |
$this->_attachments_action[ $postarr['file'] ] = empty( $postarr['ID'] ) ? 'insert' : 'update';
|
151 |
|
152 |
return $data;
|
153 |
}
|
154 |
|
155 |
+
/**
|
156 |
+
* Preflush CDN.
|
157 |
+
*
|
158 |
+
* @param bool $do_flush Flush flag.
|
159 |
+
* @param array $extras Extras.
|
160 |
+
*
|
161 |
+
* @return bool
|
162 |
+
*/
|
163 |
public function w3tc_preflush_cdn_all( $do_flush, $extras = array() ) {
|
164 |
+
$default_override = Cdn_Util::get_flush_manually_default_override( $this->_config->get_string( 'cdn.engine' ) );
|
165 |
+
if ( $this->_config->get_boolean( 'cdn.flush_manually', $default_override ) ) {
|
166 |
+
if ( ! isset( $extras['ui_action'] ) ) {
|
167 |
$do_flush = false;
|
168 |
}
|
169 |
}
|
176 |
*
|
177 |
* Upload _wp_attached_file
|
178 |
*
|
179 |
+
* @param string $attached_file Attchement file path.
|
180 |
+
*
|
181 |
* @return string
|
182 |
*/
|
183 |
+
public function update_attached_file( $attached_file ) {
|
184 |
$common = Dispatcher::component( 'Cdn_Core' );
|
185 |
+
$files = $common->get_files_for_upload( $attached_file );
|
186 |
+
$files = apply_filters( 'w3tc_cdn_update_attachment', $files );
|
187 |
|
188 |
$results = array();
|
189 |
|
190 |
$cdn_engine = $this->_config->get_string( 'cdn.engine' );
|
191 |
if ( Cdn_Util::is_engine_mirror( $cdn_engine ) ) {
|
192 |
+
if ( ! array_key_exists( $attached_file, $this->_attachments_action ) || 'update' === $this->_attachments_action[ $attached_file ] ) {
|
193 |
$common->purge( $files, $results );
|
194 |
}
|
195 |
} else {
|
204 |
*
|
205 |
* Delete _wp_attached_file, _wp_attachment_metadata, _wp_attachment_backup_sizes
|
206 |
*
|
207 |
+
* @param integer $attachment_id Attchement ID.
|
208 |
*/
|
209 |
+
public function delete_attachment( $attachment_id ) {
|
210 |
$common = Dispatcher::component( 'Cdn_Core' );
|
211 |
+
$files = $common->get_attachment_files( $attachment_id );
|
212 |
+
$files = apply_filters( 'w3tc_cdn_delete_attachment', $files );
|
213 |
|
214 |
$results = array();
|
215 |
|
226 |
*
|
227 |
* Upload _wp_attachment_metadata
|
228 |
*
|
229 |
+
* @param array $metadata Metadata.
|
230 |
+
*
|
231 |
* @return array
|
232 |
*/
|
233 |
+
public function update_attachment_metadata( $metadata ) {
|
234 |
$common = Dispatcher::component( 'Cdn_Core' );
|
235 |
+
$files = $common->get_metadata_files( $metadata );
|
236 |
+
$files = apply_filters( 'w3tc_cdn_update_attachment_metadata', $files );
|
237 |
|
238 |
$results = array();
|
239 |
|
240 |
$cdn_engine = $this->_config->get_string( 'cdn.engine' );
|
241 |
if ( Cdn_Util::is_engine_mirror( $cdn_engine ) ) {
|
242 |
+
if ( $this->_config->get_boolean( 'cdn.uploads.enable' ) ) {
|
243 |
$common->purge( $files, $results );
|
244 |
}
|
245 |
} else {
|
252 |
/**
|
253 |
* Cron schedules filter
|
254 |
*
|
255 |
+
* @param array $schedules Schedules.
|
256 |
+
*
|
257 |
* @return array
|
258 |
*/
|
259 |
+
public function cron_schedules( $schedules ) {
|
260 |
$c = $this->_config;
|
261 |
|
262 |
+
if ( $c->get_boolean( 'cdn.enabled' ) && ! Cdn_Util::is_engine_mirror( $c->get_string( 'cdn.engine' ) ) ) {
|
|
|
263 |
$queue_interval = $c->get_integer( 'cdn.queue.interval' );
|
264 |
+
|
265 |
$schedules['w3_cdn_cron_queue_process'] = array(
|
266 |
+
'interval' => $queue_interval,
|
267 |
+
'display' => sprintf(
|
268 |
+
// translators: 1 queue interval value.
|
269 |
+
__(
|
270 |
+
'[W3TC] CDN queue process (every %1$d seconds)',
|
271 |
+
'w3-total-cache'
|
272 |
+
),
|
273 |
+
$queue_interval
|
274 |
+
),
|
275 |
+
);
|
276 |
}
|
277 |
|
278 |
if ( $c->get_boolean( 'cdn.enabled' ) &&
|
279 |
$c->get_boolean( 'cdn.autoupload.enabled' ) &&
|
280 |
+
! Cdn_Util::is_engine_mirror( $c->get_string( 'cdn.engine' ) ) ) {
|
281 |
$autoupload_interval = $c->get_integer( 'cdn.autoupload.interval' );
|
282 |
+
|
283 |
$schedules['w3_cdn_cron_upload'] = array(
|
284 |
+
'interval' => $autoupload_interval,
|
285 |
+
'display' => sprintf(
|
286 |
+
// translators: 1 queue interval value.
|
287 |
+
__(
|
288 |
+
'[W3TC] CDN auto upload (every %1$d seconds)',
|
289 |
+
'w3-total-cache'
|
290 |
+
),
|
291 |
+
$autoupload_interval
|
292 |
+
),
|
293 |
+
);
|
294 |
}
|
295 |
|
296 |
return $schedules;
|
297 |
}
|
298 |
|
299 |
/**
|
300 |
+
* Switch theme action.
|
301 |
*/
|
302 |
+
public function switch_theme() {
|
303 |
$state = Dispatcher::config_state();
|
304 |
$state->set( 'cdn.show_note_theme_changed', true );
|
305 |
$state->save();
|
306 |
}
|
307 |
|
308 |
/**
|
309 |
+
* WP Upgrade action hack.
|
310 |
*
|
311 |
+
* @param string $message Message.
|
312 |
*/
|
313 |
+
public function update_feedback( $message ) {
|
314 |
+
if ( 'Upgrading database' === $message ) {
|
315 |
$state = Dispatcher::config_state();
|
316 |
$state->set( 'cdn.show_note_wp_upgraded', true );
|
317 |
$state->save();
|
319 |
}
|
320 |
|
321 |
/**
|
322 |
+
* OB Callback.
|
323 |
+
*
|
324 |
+
* @param string $buffer Buffer.
|
325 |
*
|
|
|
326 |
* @return string
|
327 |
*/
|
328 |
+
public function ob_callback( $buffer ) {
|
329 |
+
if ( '' !== $buffer && Util_Content::is_html_xml( $buffer ) ) {
|
330 |
if ( $this->can_cdn2( $buffer ) ) {
|
331 |
$srcset_helper = new _Cdn_Plugin_ContentFilter();
|
332 |
+
$buffer = $srcset_helper->replace_all_links( $buffer );
|
333 |
|
334 |
if ( $this->_debug ) {
|
335 |
$replaced_urls = $srcset_helper->get_replaced_urls();
|
336 |
+
$buffer = $this->w3tc_footer_comment_after( $buffer, $replaced_urls );
|
|
|
337 |
}
|
338 |
}
|
339 |
}
|
342 |
}
|
343 |
|
344 |
/**
|
345 |
+
* Returns array of files to upload.
|
346 |
*
|
347 |
* @return array
|
348 |
*/
|
349 |
+
public function get_files() {
|
350 |
$files = array();
|
351 |
|
352 |
if ( $this->_config->get_boolean( 'cdn.includes.enable' ) ) {
|
373 |
*
|
374 |
* @return array
|
375 |
*/
|
376 |
+
public function get_files_includes() {
|
377 |
$includes_root = Util_Environment::normalize_path( ABSPATH . WPINC );
|
378 |
+
$doc_root = Util_Environment::normalize_path( Util_Environment::document_root() );
|
379 |
$includes_path = ltrim( str_replace( $doc_root, '', $includes_root ), '/' );
|
380 |
|
381 |
$files = Cdn_Util::search_files(
|
382 |
+
$includes_root,
|
383 |
+
$includes_path,
|
384 |
+
$this->_config->get_string( 'cdn.includes.files' )
|
385 |
);
|
386 |
|
387 |
return $files;
|
392 |
*
|
393 |
* @return array
|
394 |
*/
|
395 |
+
public function get_files_theme() {
|
396 |
+
// If mobile or referrer support enabled we should upload whole themes directory.
|
397 |
+
if ( $this->_config->get_boolean( 'mobile.enabled' ) || $this->_config->get_boolean( 'referrer.enabled' ) ) {
|
|
|
|
|
|
|
|
|
398 |
$themes_root = get_theme_root();
|
399 |
} else {
|
400 |
$themes_root = get_stylesheet_directory();
|
401 |
}
|
402 |
|
403 |
$themes_root = Util_Environment::normalize_path( $themes_root );
|
404 |
+
$themes_path = ltrim( str_replace( Util_Environment::normalize_path( Util_Environment::document_root() ), '', $themes_root ), '/' );
|
405 |
+
$files = Cdn_Util::search_files(
|
406 |
+
$themes_root,
|
407 |
+
$themes_path,
|
408 |
+
$this->_config->get_string( 'cdn.theme.files' )
|
409 |
);
|
410 |
|
411 |
return $files;
|
412 |
}
|
413 |
|
414 |
/**
|
415 |
+
* Exports min files to CDN.
|
416 |
*
|
417 |
* @return array
|
418 |
*/
|
419 |
+
public function get_files_minify() {
|
420 |
$files = array();
|
421 |
|
422 |
if ( $this->_config->get_boolean( 'minify.rewrite' ) &&
|
423 |
Util_Rule::can_check_rules() &&
|
424 |
+
(
|
425 |
+
! $this->_config->get_boolean( 'minify.auto' ) ||
|
426 |
+
Cdn_Util::is_engine_mirror( $this->_config->get_string( 'cdn.engine' ) )
|
427 |
+
) ) {
|
428 |
|
429 |
$minify = Dispatcher::component( 'Minify_Plugin' );
|
430 |
|
431 |
+
$document_root = Util_Environment::normalize_path( Util_Environment::document_root() );
|
432 |
+
$minify_root = Util_Environment::normalize_path( Util_Environment::cache_blog_dir( 'minify' ) );
|
433 |
+
$minify_path = ltrim( str_replace( $document_root, '', $minify_root ), '/' );
|
434 |
+
|
|
|
435 |
$urls = $minify->get_urls();
|
436 |
|
437 |
+
// In WPMU + network admin (this code used for minify manual only)
|
438 |
// common minify files are stored under context of main blog (i.e. 1)
|
439 |
+
// but have urls of 0 blog, so download has to be used.
|
440 |
+
if ( 'file' === $this->_config->get_string( 'minify.engine' ) && ! ( Util_Environment::is_wpmu() && is_network_admin() ) ) {
|
|
|
|
|
441 |
foreach ( $urls as $url ) {
|
442 |
Util_Http::get( $url );
|
443 |
}
|
444 |
|
445 |
+
$files = Cdn_Util::search_files(
|
446 |
+
$minify_root,
|
447 |
+
$minify_path,
|
448 |
+
'*.css;*.js'
|
449 |
+
);
|
450 |
} else {
|
451 |
foreach ( $urls as $url ) {
|
452 |
$file = Util_Environment::normalize_file_minify( $url );
|
453 |
|
454 |
+
if ( ! Util_Environment::is_url( $file ) ) {
|
455 |
$file = $document_root . '/' . $file;
|
456 |
$file = ltrim( str_replace( $minify_root, '', $file ), '/' );
|
457 |
|
477 |
*
|
478 |
* @return array
|
479 |
*/
|
480 |
+
public function get_files_custom() {
|
481 |
+
$files = array();
|
482 |
+
$document_root = Util_Environment::normalize_path( Util_Environment::document_root() );
|
483 |
+
$custom_files = $this->_config->get_array( 'cdn.custom.files' );
|
484 |
+
$custom_files = array_map( array( '\W3TC\Util_Environment', 'parse_path' ), $custom_files );
|
485 |
+
$site_root = Util_Environment::normalize_path( Util_Environment::site_root() );
|
486 |
+
$path = Util_Environment::site_url_uri();
|
|
|
487 |
$site_root_dir = str_replace( $document_root, '', $site_root );
|
488 |
if ( strstr( WP_CONTENT_DIR, Util_Environment::site_root() ) === false ) {
|
489 |
$site_root = Util_Environment::normalize_path( Util_Environment::document_root() );
|
490 |
+
$path = '';
|
491 |
}
|
492 |
|
493 |
$content_path = trim( str_replace( WP_CONTENT_DIR, '', $site_root ), '/\\' );
|
494 |
|
495 |
foreach ( $custom_files as $custom_file ) {
|
496 |
+
if ( '' !== $custom_file ) {
|
497 |
$custom_file = Cdn_Util::replace_folder_placeholders( $custom_file );
|
498 |
$custom_file = Util_Environment::normalize_file( $custom_file );
|
499 |
|
500 |
+
$dir = trim( dirname( $custom_file ), '/\\' );
|
501 |
+
$rel_path = $dir;
|
|
|
|
|
|
|
502 |
|
503 |
+
if ( strpos( $dir, '<currentblog>' ) !== false ) {
|
504 |
+
$dir = str_replace( '<currentblog>', 'blogs.dir/' . Util_Environment::blog_id(), $dir );
|
505 |
+
$rel_path = $dir;
|
|
|
|
|
506 |
}
|
507 |
|
508 |
+
if ( '.' === $dir ) {
|
509 |
+
$dir = '';
|
510 |
+
$rel_path = $dir;
|
511 |
}
|
512 |
+
|
513 |
+
$mask = basename( $custom_file );
|
514 |
$files = array_merge(
|
515 |
+
$files,
|
516 |
+
Cdn_Util::search_files(
|
517 |
+
$document_root . '/' . $dir,
|
518 |
+
$rel_path,
|
519 |
+
$mask
|
520 |
+
)
|
521 |
);
|
522 |
}
|
523 |
}
|
530 |
*
|
531 |
* @return boolean
|
532 |
*/
|
533 |
+
public function can_cdn() {
|
534 |
+
// Skip if admin.
|
|
|
|
|
535 |
if ( defined( 'WP_ADMIN' ) ) {
|
536 |
+
$this->cdn_reject_reason = esc_html__( 'wp-admin', 'w3-total-cache' );
|
537 |
|
538 |
return false;
|
539 |
}
|
540 |
|
541 |
+
// Check for WPMU's and WP's 3.0 short init.
|
|
|
|
|
542 |
if ( defined( 'SHORTINIT' ) && SHORTINIT ) {
|
543 |
+
$this->cdn_reject_reason = esc_html__( 'Short init', 'w3-total-cache' );
|
544 |
|
545 |
return false;
|
546 |
}
|
547 |
|
548 |
+
// Check User agent.
|
549 |
+
if ( ! $this->check_ua() ) {
|
550 |
+
$this->cdn_reject_reason = esc_html__( 'user agent is rejected', 'w3-total-cache' );
|
|
|
|
|
551 |
|
552 |
return false;
|
553 |
}
|
554 |
|
555 |
+
// Check request URI.
|
556 |
+
if ( ! $this->_check_request_uri() ) {
|
557 |
+
$this->cdn_reject_reason = esc_html__( 'request URI is rejected', 'w3-total-cache' );
|
|
|
|
|
558 |
|
559 |
return false;
|
560 |
}
|
561 |
|
562 |
+
// Do not replace urls if SSL and SSL support is do not replace.
|
|
|
|
|
563 |
if ( Util_Environment::is_https() && $this->_config->get_boolean( 'cdn.reject.ssl' ) ) {
|
564 |
+
$this->cdn_reject_reason = esc_html__( 'SSL is rejected', 'w3-total-cache' );
|
565 |
|
566 |
return false;
|
567 |
}
|
572 |
/**
|
573 |
* Returns true if we can do CDN logic
|
574 |
*
|
575 |
+
* @param unknown $buffer Buffer.
|
576 |
+
*
|
577 |
* @return string
|
578 |
*/
|
579 |
+
public function can_cdn2( $buffer ) {
|
580 |
+
// Check for DONOTCDN constant.
|
|
|
|
|
581 |
if ( defined( 'DONOTCDN' ) && DONOTCDN ) {
|
582 |
+
$this->cdn_reject_reason = esc_html__( 'DONOTCDN constant is defined', 'w3-total-cache' );
|
583 |
|
584 |
return false;
|
585 |
}
|
586 |
|
587 |
+
// Check logged users roles.
|
588 |
+
if ( $this->_config->get_boolean( 'cdn.reject.logged_roles' ) && ! $this->_check_logged_in_role_allowed() ) {
|
589 |
+
$this->cdn_reject_reason = esc_html__( 'logged in role is rejected', 'w3-total-cache' );
|
|
|
|
|
|
|
|
|
590 |
|
591 |
return false;
|
592 |
}
|
595 |
}
|
596 |
|
597 |
/**
|
598 |
+
* Checks User Agent.
|
599 |
*
|
600 |
* @return boolean
|
601 |
*/
|
602 |
+
public function check_ua() {
|
603 |
+
$uas = array_merge(
|
604 |
+
$this->_config->get_array( 'cdn.reject.ua' ),
|
605 |
+
array( W3TC_POWERED_BY )
|
606 |
+
);
|
607 |
|
608 |
foreach ( $uas as $ua ) {
|
609 |
+
if ( ! empty( $ua ) ) {
|
610 |
if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && stristr( sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ), $ua ) !== false ) {
|
611 |
return false;
|
612 |
}
|
617 |
}
|
618 |
|
619 |
/**
|
620 |
+
* Checks request URI.
|
621 |
*
|
622 |
* @return boolean
|
623 |
*/
|
624 |
+
public function _check_request_uri() {
|
625 |
$reject_uri = $this->_config->get_array( 'cdn.reject.uri' );
|
626 |
$reject_uri = array_map( array( '\W3TC\Util_Environment', 'parse_path' ), $reject_uri );
|
627 |
|
629 |
$expr = trim( $expr );
|
630 |
$expr = str_replace( '~', '\~', $expr );
|
631 |
|
632 |
+
if ( '' !== $expr && preg_match( '~' . $expr . '~i', isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' ) ) {
|
633 |
return false;
|
634 |
}
|
635 |
}
|
636 |
|
637 |
+
if ( Util_Request::get_string( 'wp_customize' ) ) {
|
|
|
638 |
return false;
|
639 |
+
}
|
640 |
|
641 |
return true;
|
642 |
}
|
648 |
private function _check_logged_in_role_allowed() {
|
649 |
$current_user = wp_get_current_user();
|
650 |
|
651 |
+
if ( ! is_user_logged_in() ) {
|
652 |
return true;
|
653 |
+
}
|
654 |
|
655 |
$roles = $this->_config->get_array( 'cdn.reject.roles' );
|
656 |
|
657 |
+
if ( empty( $roles ) || empty( $current_user->roles ) || ! is_array( $current_user->roles ) ) {
|
|
|
658 |
return true;
|
659 |
+
}
|
660 |
|
661 |
foreach ( $current_user->roles as $role ) {
|
662 |
+
if ( in_array( $role, $roles, true ) ) {
|
663 |
return false;
|
664 |
+
}
|
665 |
}
|
666 |
|
667 |
return true;
|
668 |
}
|
669 |
|
670 |
/**
|
671 |
+
* Media row actions filter.
|
672 |
+
*
|
673 |
+
* @param array $actions Actions.
|
674 |
+
* @param object $post Post.
|
675 |
*
|
|
|
|
|
676 |
* @return array
|
677 |
*/
|
678 |
+
public function media_row_actions( $actions, $post ) {
|
679 |
return $this->get_admin()->media_row_actions( $actions, $post );
|
680 |
}
|
681 |
|
|
|
682 |
/**
|
683 |
+
* Get CDN running status.
|
684 |
*
|
685 |
+
* @param unknown $current_state Current state.
|
686 |
*
|
|
|
687 |
* @return bool
|
688 |
*/
|
689 |
+
public function cdn_is_running( $current_state ) {
|
690 |
$admin = $this->get_admin();
|
691 |
return $admin->is_running();
|
692 |
}
|
694 |
/**
|
695 |
* Change canonical header
|
696 |
*/
|
697 |
+
public function change_canonical_header() {
|
698 |
$admin = $this->get_admin();
|
699 |
$admin->change_canonical_header();
|
700 |
}
|
701 |
|
702 |
/**
|
703 |
+
* Adjusts attachment urls to cdn. This is for those who rely on wp_prepare_attachment_for_js().
|
704 |
+
*
|
705 |
+
* @param array $response Mixed collection of data about the attachment object.
|
706 |
*
|
707 |
+
* @return array
|
|
|
708 |
*/
|
709 |
public function wp_prepare_attachment_for_js( $response ) {
|
710 |
+
$response['url'] = $this->wp_prepare_attachment_for_js_url( $response['url'] );
|
711 |
$response['link'] = $this->wp_prepare_attachment_for_js_url( $response['link'] );
|
712 |
|
713 |
+
if ( ! empty( $response['sizes'] ) ) {
|
714 |
+
foreach ( $response['sizes'] as $size => &$data ) {
|
715 |
$data['url'] = $this->wp_prepare_attachment_for_js_url( $data['url'] );
|
716 |
}
|
717 |
}
|
720 |
}
|
721 |
|
722 |
/**
|
723 |
+
* An attachment's local url to modify into a cdn url.
|
724 |
*
|
725 |
+
* @param string $url the local url to modify.
|
726 |
+
*
|
727 |
+
* @return string
|
728 |
*/
|
729 |
private function wp_prepare_attachment_for_js_url( $url ) {
|
730 |
$url = trim( $url );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
731 |
if ( ! empty( $url ) ) {
|
732 |
+
$parsed = wp_parse_url( $url );
|
733 |
+
$uri = ( isset( $parsed['path'] ) ? $parsed['path'] : '/' ) .
|
734 |
+
( isset( $parsed['query'] ) ? '?' . $parsed['query'] : '' );
|
735 |
+
|
736 |
$wp_upload_dir = wp_upload_dir();
|
737 |
$upload_base_url = $wp_upload_dir['baseurl'];
|
738 |
+
|
739 |
if ( substr( $url, 0, strlen( $upload_base_url ) ) === $upload_base_url ) {
|
740 |
$common = Dispatcher::component( 'Cdn_Core' );
|
741 |
$new_url = $common->url_to_cdn_url( $url, $uri );
|
742 |
if ( ! is_null( $new_url ) ) {
|
743 |
+
$url = $new_url;
|
744 |
}
|
745 |
}
|
746 |
}
|
747 |
|
748 |
+
return $url;
|
749 |
}
|
750 |
|
751 |
/**
|
752 |
* Mutate http/2 header links
|
753 |
+
*
|
754 |
+
* @param array $data Data.
|
755 |
*/
|
756 |
public function w3tc_minify_http2_preload_url( $data ) {
|
757 |
$url = $data['result_link'];
|
761 |
return $data;
|
762 |
}
|
763 |
|
764 |
+
$parsed = wp_parse_url( $url );
|
765 |
+
$uri = ( isset( $parsed['path'] ) ? $parsed['path'] : '/' ) .
|
766 |
+
( isset( $parsed['query'] ) ? '?' . $parsed['query'] : '' );
|
767 |
|
768 |
+
$common = Dispatcher::component( 'Cdn_Core' );
|
769 |
$new_url = $common->url_to_cdn_url( $url, $uri );
|
770 |
if ( is_null( $new_url ) ) {
|
771 |
return $data;
|
772 |
}
|
773 |
|
774 |
$data['result_link'] = $new_url;
|
775 |
+
|
776 |
+
// url_to_cdn_url processed by browsercache internally.
|
777 |
$data['browsercache_processed'] = '*';
|
778 |
|
779 |
return $data;
|
780 |
}
|
781 |
|
782 |
+
/**
|
783 |
+
* Get admin bar menu items.
|
784 |
+
*
|
785 |
+
* @param array $menu_items Menu items.
|
786 |
+
*/
|
787 |
public function w3tc_admin_bar_menu( $menu_items ) {
|
788 |
$cdn_engine = $this->_config->get_string( 'cdn.engine' );
|
789 |
|
790 |
if ( Cdn_Util::can_purge_all( $cdn_engine ) ) {
|
791 |
$menu_items['20710.cdn'] = array(
|
792 |
+
'id' => 'w3tc_cdn_flush_all',
|
793 |
'parent' => 'w3tc_flush',
|
794 |
+
'title' => __( 'CDN: All', 'w3-total-cache' ),
|
795 |
+
'href' => wp_nonce_url( admin_url( 'admin.php?page=w3tc_cdn&w3tc_flush_cdn' ), 'w3tc' ),
|
|
|
|
|
796 |
);
|
797 |
}
|
798 |
|
799 |
if ( Cdn_Util::can_purge( $cdn_engine ) ) {
|
800 |
$menu_items['20790.cdn'] = array(
|
801 |
+
'id' => 'w3tc_cdn_flush',
|
802 |
'parent' => 'w3tc_flush',
|
803 |
+
'title' => __( 'CDN: Manual Purge', 'w3-total-cache' ),
|
804 |
+
'href' => wp_nonce_url( admin_url( 'admin.php?page=w3tc_cdn&w3tc_cdn_purge' ), 'w3tc' ),
|
805 |
+
'meta' => array( 'onclick' => 'w3tc_popupadmin_bar(this.href); return false' ),
|
806 |
);
|
807 |
}
|
808 |
|
809 |
return $menu_items;
|
810 |
}
|
811 |
|
812 |
+
/**
|
813 |
+
* Add CDN mark to footer.
|
814 |
+
*
|
815 |
+
* @param array $strings Footer strings.
|
816 |
+
*/
|
817 |
public function w3tc_footer_comment( $strings ) {
|
818 |
$common = Dispatcher::component( 'Cdn_Core' );
|
819 |
+
$cdn = $common->get_cdn();
|
820 |
+
$via = $cdn->get_via();
|
821 |
|
822 |
$strings[] = sprintf(
|
823 |
+
// translators: 1 CDN engine name, 2 rejection reason.
|
824 |
+
__(
|
825 |
+
'Content Delivery Network via %1$s%2$s',
|
826 |
+
'w3-total-cache'
|
827 |
+
),
|
828 |
( $via ? $via : 'N/A' ),
|
829 |
+
( empty( $this->cdn_reject_reason ) ? '' : sprintf( ' (%s)', $this->cdn_reject_reason ) )
|
830 |
+
);
|
831 |
|
832 |
if ( $this->_debug ) {
|
833 |
$strings[] = '{w3tc_cdn_debug_info}';
|
836 |
return $strings;
|
837 |
}
|
838 |
|
839 |
+
/**
|
840 |
+
* Add after footer CDN mark.
|
841 |
+
*
|
842 |
+
* @param string $buffer Buffer.
|
843 |
+
* @param array $replaced_urls Replaced URLs.
|
844 |
+
*/
|
845 |
public function w3tc_footer_comment_after( $buffer, $replaced_urls ) {
|
846 |
$strings = array();
|
847 |
|
848 |
+
if ( is_array( $replaced_urls ) && count( $replaced_urls ) ) {
|
849 |
+
$strings[] = __( 'Replaced URLs for CDN:', 'w3-total-cache' );
|
|
|
850 |
|
851 |
foreach ( $replaced_urls as $old_url => $new_url ) {
|
852 |
+
$strings[] = sprintf(
|
853 |
+
'%1$s => %2$s',
|
854 |
Util_Content::escape_comment( $old_url ),
|
855 |
+
Util_Content::escape_comment( $new_url )
|
856 |
+
);
|
857 |
}
|
858 |
|
859 |
$strings[] = '';
|
860 |
}
|
861 |
|
862 |
+
$buffer = str_replace( '{w3tc_cdn_debug_info}', implode( "\n", $strings ), $buffer );
|
863 |
+
|
864 |
return $buffer;
|
865 |
}
|
866 |
}
|
867 |
|
868 |
+
/**
|
869 |
+
* Class: _Cdn_Plugin_ContentFilter
|
870 |
+
*
|
871 |
+
* phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
|
872 |
+
* phpcs:disable PSR2.Methods.MethodDeclaration.Underscore
|
873 |
+
*/
|
874 |
+
class _Cdn_Plugin_ContentFilter { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace, PEAR.NamingConventions.ValidClassName.StartWithCapital, Generic.Files.OneObjectStructurePerFile.MultipleFound
|
875 |
+
/**
|
876 |
+
* Regular expressions.
|
877 |
+
*
|
878 |
+
* @var array
|
879 |
+
*/
|
880 |
private $_regexps = array();
|
881 |
+
|
882 |
+
/**
|
883 |
+
* Placeholders.
|
884 |
+
*
|
885 |
+
* @var array
|
886 |
+
*/
|
887 |
private $_placeholders = array();
|
888 |
+
|
889 |
+
/**
|
890 |
+
* Config.
|
891 |
+
*
|
892 |
+
* @var Config
|
893 |
+
*/
|
894 |
private $_config;
|
895 |
+
|
896 |
+
/**
|
897 |
+
* Replaced URLs.
|
898 |
+
*
|
899 |
+
* @var array
|
900 |
+
*/
|
901 |
private $_replaced_urls = array();
|
902 |
|
903 |
/**
|
907 |
*/
|
908 |
private static $_upload_scheduled = false;
|
909 |
|
910 |
+
/**
|
911 |
+
* Constructor.
|
912 |
+
*/
|
913 |
+
public function __construct() {
|
914 |
$this->_config = Dispatcher::config();
|
915 |
}
|
916 |
|
917 |
+
/**
|
918 |
+
* Replace all links.
|
919 |
+
*
|
920 |
+
* @param string $buffer Buffer.
|
921 |
+
*
|
922 |
+
* @return string
|
923 |
+
*/
|
924 |
+
public function replace_all_links( $buffer ) {
|
925 |
$this->fill_regexps();
|
926 |
|
927 |
$srcset_pattern = '~srcset\s*=\s*[\"\'](.*?)[\"\']~';
|
928 |
+
$buffer = preg_replace_callback(
|
929 |
+
$srcset_pattern,
|
930 |
+
array( $this, '_srcset_replace_callback' ),
|
931 |
+
$buffer
|
932 |
);
|
933 |
|
934 |
foreach ( $this->_regexps as $regexp ) {
|
935 |
$buffer = preg_replace_callback(
|
936 |
+
$regexp,
|
937 |
+
array( $this, '_link_replace_callback' ),
|
938 |
+
$buffer
|
939 |
);
|
940 |
}
|
941 |
|
949 |
$processor = array( $this, '_minify_auto_pushcdn_link_replace_callback' );
|
950 |
}
|
951 |
} else {
|
952 |
+
$minify_url_regexp = $this->minify_url_regexp( '/[a-z0-9]+\..+\.include(-(footer|body))?(-nb)?\.[a-f0-9]+\.(css|js)' );
|
953 |
+
$processor = array( $this, '_link_replace_callback' );
|
|
|
|
|
954 |
}
|
955 |
|
956 |
+
if ( ! empty( $minify_url_regexp ) ) {
|
957 |
+
$regexp = '~(["\'(=])\s*' . $minify_url_regexp . '~U';
|
958 |
$buffer = preg_replace_callback( $regexp, $processor, $buffer );
|
959 |
}
|
960 |
}
|
965 |
}
|
966 |
|
967 |
/**
|
968 |
+
* Link replace callback.
|
969 |
+
*
|
970 |
+
* @param array $matches Matches.
|
971 |
*
|
|
|
972 |
* @return string
|
973 |
*/
|
974 |
+
public function _link_replace_callback( $matches ) {
|
975 |
list( $match, $quote, $url, , , , $path ) = $matches;
|
976 |
+
|
977 |
$path = ltrim( $path, '/' );
|
978 |
+
$r = $this->_link_replace_callback_checks( $match, $quote, $url, $path );
|
979 |
if ( is_null( $r ) ) {
|
980 |
$r = $this->_link_replace_callback_ask_cdn( $match, $quote, $url, $path );
|
981 |
}
|
983 |
return $r;
|
984 |
}
|
985 |
|
986 |
+
/**
|
987 |
+
* Srcset replace callback.
|
988 |
+
*
|
989 |
+
* @param array $matches Matches.
|
990 |
+
*
|
991 |
+
* @return string
|
992 |
+
*/
|
993 |
+
public function _srcset_replace_callback( $matches ) {
|
994 |
list( $match, $srcset ) = $matches;
|
995 |
+
|
996 |
+
if ( empty( $this->_regexps ) ) {
|
997 |
return $match;
|
998 |
+
}
|
999 |
|
1000 |
+
$index = '%srcset-' . count( $this->_placeholders ) . '%';
|
1001 |
+
|
1002 |
+
$srcset_urls = explode( ',', $srcset );
|
1003 |
$new_srcset_urls = array();
|
1004 |
|
1005 |
foreach ( $srcset_urls as $set ) {
|
1006 |
+
preg_match( '~(?P<spaces>^\s*)(?P<url>\S+)(?P<rest>.*)~', $set, $parts );
|
|
|
1007 |
if ( isset( $parts['url'] ) ) {
|
|
|
1008 |
foreach ( $this->_regexps as $regexp ) {
|
1009 |
+
$new_url = preg_replace_callback(
|
1010 |
+
$regexp,
|
1011 |
+
array(
|
1012 |
$this,
|
1013 |
+
'_link_replace_callback',
|
1014 |
+
),
|
1015 |
+
'"' . $parts['url'] . '">'
|
1016 |
+
);
|
1017 |
|
1018 |
+
if ( '"' . $parts['url'] . '">' !== $new_url ) {
|
1019 |
$parts['url'] = substr( $new_url, 1, -2 );
|
1020 |
break;
|
1021 |
}
|
1022 |
}
|
1023 |
+
$new_srcset_urls[] = $parts['spaces'] . $parts['url'] . $parts['rest'];
|
|
|
1024 |
} else {
|
1025 |
$new_srcset_urls[] = $set;
|
1026 |
}
|
|
|
1027 |
}
|
1028 |
+
|
1029 |
+
$this->_placeholders[ $index ] = implode( ',', $new_srcset_urls );
|
1030 |
+
|
1031 |
return 'srcset="' . $index . '"';
|
1032 |
}
|
1033 |
|
1034 |
+
/**
|
1035 |
+
* Replace placeholders.
|
1036 |
+
*
|
1037 |
+
* @param string $buffer Buffer.
|
1038 |
+
*
|
1039 |
+
* @return string
|
1040 |
+
*/
|
1041 |
private function replace_placeholders( $buffer ) {
|
1042 |
foreach ( $this->_placeholders as $srcset_id => $srcset_content ) {
|
1043 |
$buffer = str_replace( $srcset_id, $srcset_content, $buffer );
|
1048 |
/**
|
1049 |
* Gets regexp for minified files
|
1050 |
*
|
1051 |
+
* @param string $filename_mask Filename mask.
|
1052 |
+
*
|
1053 |
* @return string
|
1054 |
*/
|
1055 |
private function minify_url_regexp( $filename_mask ) {
|
1056 |
$minify_base_url = Util_Environment::filename_to_url(
|
1057 |
Util_Environment::cache_blog_minify_dir()
|
1058 |
);
|
1059 |
+
$matches = null;
|
1060 |
+
if ( ! preg_match( '~((https?://)?([^/]+))(.+)~i', $minify_base_url, $matches ) ) {
|
1061 |
+
error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
|
1062 |
+
__(
|
1063 |
+
'Cant find minification base url, make sure minification folder sits inside WP_CONTENT_DIR and DOCUMENT_ROOT is set correctly',
|
1064 |
+
'w3-total-cache'
|
1065 |
+
)
|
1066 |
+
);
|
1067 |
return '';
|
1068 |
}
|
1069 |
|
1070 |
$protocol_domain_regexp = Util_Environment::get_url_regexp( $matches[1] );
|
1071 |
+
$path_regexp = Util_Environment::preg_quote( $matches[4] );
|
1072 |
|
1073 |
$regexp =
|
1074 |
'(' .
|
1079 |
}
|
1080 |
|
1081 |
/**
|
1082 |
+
* Uploads regex.
|
1083 |
*
|
1084 |
+
* @param unknown $domain_url_regexp Domain URL regular expression.
|
1085 |
+
* @param unknown $baseurl Base URL.
|
1086 |
+
* @param unknown $upload_info Upload info.
|
1087 |
+
* @param unknown $regexps Regular expressions.
|
1088 |
*
|
|
|
|
|
|
|
|
|
1089 |
* @return array
|
1090 |
*/
|
1091 |
+
private function make_uploads_regexes( $domain_url_regexp, $baseurl, $upload_info, $regexps ) {
|
|
|
1092 |
if ( preg_match( '~' . $domain_url_regexp . '~i', $baseurl ) ) {
|
1093 |
$regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp . ')?('
|
1094 |
. Util_Environment::preg_quote( $upload_info['baseurlpath'] )
|
1095 |
. '([^"\')>]+)))~i';
|
1096 |
} else {
|
1097 |
+
$parsed = @wp_parse_url( $baseurl ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
|
1098 |
+
$upload_url_domain_regexp = isset( $parsed['host'] ) ?
|
1099 |
+
Util_Environment::get_url_regexp( $parsed['scheme'] . '://' . $parsed['host'] ) :
|
1100 |
+
$domain_url_regexp;
|
1101 |
+
$baseurlpath = isset( $parsed['path'] ) ? rtrim( $parsed['path'], '/' ) : '';
|
1102 |
+
if ( $baseurlpath ) {
|
1103 |
$regexps[] = '~(["\'])\s*((' . $upload_url_domain_regexp . ')?('
|
1104 |
. Util_Environment::preg_quote( $baseurlpath )
|
1105 |
. '([^"\'>]+)))~i';
|
1106 |
+
} else {
|
1107 |
$regexps[] = '~(["\'])\s*((' . $upload_url_domain_regexp
|
1108 |
. ')(([^"\'>]+)))~i';
|
1109 |
+
}
|
1110 |
}
|
1111 |
return $regexps;
|
1112 |
}
|
1113 |
|
1114 |
+
/**
|
1115 |
+
* Fill regular expressions.
|
1116 |
+
*/
|
1117 |
private function fill_regexps() {
|
1118 |
$regexps = array();
|
1119 |
|
1120 |
+
$site_path = Util_Environment::site_url_uri();
|
1121 |
$domain_url_regexp = Util_Environment::home_domain_root_url_regexp();
|
1122 |
|
1123 |
$site_domain_url_regexp = false;
|
1124 |
+
if ( Util_Environment::get_url_regexp( Util_Environment::url_to_host( site_url() ) ) !== $domain_url_regexp ) {
|
1125 |
+
$site_domain_url_regexp = Util_Environment::get_url_regexp( Util_Environment::url_to_host( site_url() ) );
|
1126 |
+
}
|
|
|
|
|
1127 |
|
1128 |
if ( $this->_config->get_boolean( 'cdn.uploads.enable' ) ) {
|
1129 |
$upload_info = Util_Http::upload_info();
|
1132 |
$baseurl = $upload_info['baseurl'];
|
1133 |
|
1134 |
if ( defined( 'DOMAIN_MAPPING' ) && DOMAIN_MAPPING ) {
|
1135 |
+
$parsed = @wp_parse_url( $upload_info['baseurl'] ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
|
1136 |
$baseurl = home_url() . $parsed['path'];
|
1137 |
}
|
1138 |
|
1139 |
$regexps = $this->make_uploads_regexes(
|
1140 |
+
$domain_url_regexp,
|
1141 |
+
$baseurl,
|
1142 |
+
$upload_info,
|
1143 |
+
$regexps
|
1144 |
);
|
1145 |
+
|
1146 |
+
if ( $site_domain_url_regexp ) {
|
1147 |
$regexps = $this->make_uploads_regexes(
|
1148 |
+
$site_domain_url_regexp,
|
1149 |
+
$baseurl,
|
1150 |
+
$upload_info,
|
1151 |
+
$regexps
|
1152 |
);
|
1153 |
+
}
|
1154 |
}
|
1155 |
}
|
1156 |
|
1157 |
if ( $this->_config->get_boolean( 'cdn.includes.enable' ) ) {
|
1158 |
$mask = $this->_config->get_string( 'cdn.includes.files' );
|
1159 |
+
if ( '' !== $mask ) {
|
1160 |
+
$regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp . ')?(' .
|
|
|
1161 |
Util_Environment::preg_quote( $site_path . WPINC ) .
|
1162 |
'/(' . Cdn_Util::get_regexp_by_mask( $mask ) . ')([^"\'() >]*)))~i';
|
1163 |
+
if ( $site_domain_url_regexp ) {
|
1164 |
+
$regexps[] = '~(["\'(=])\s*((' . $site_domain_url_regexp . ')?(' .
|
|
|
1165 |
Util_Environment::preg_quote( $site_path . WPINC ) .
|
1166 |
'/(' . Cdn_Util::get_regexp_by_mask( $mask ) .
|
1167 |
')([^"\'() >]*)))~i';
|
1168 |
+
}
|
1169 |
}
|
1170 |
}
|
1171 |
|
1172 |
if ( $this->_config->get_boolean( 'cdn.theme.enable' ) ) {
|
1173 |
+
$theme_dir = preg_replace( '~' . $domain_url_regexp . '~i', '', get_theme_root_uri() );
|
|
|
1174 |
|
1175 |
$mask = $this->_config->get_string( 'cdn.theme.files' );
|
1176 |
|
1177 |
+
if ( '' !== $mask ) {
|
1178 |
$regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp . ')?(' .
|
1179 |
Util_Environment::preg_quote( $theme_dir ) . '/(' .
|
1180 |
Cdn_Util::get_regexp_by_mask( $mask ) . ')([^"\'() >]*)))~i';
|
1181 |
if ( $site_domain_url_regexp ) {
|
1182 |
+
$theme_dir2 = preg_replace( '~' . $site_domain_url_regexp . '~i', '', get_theme_root_uri() );
|
1183 |
+
$regexps[] = '~(["\'(=])\s*((' . $site_domain_url_regexp . ')?(' .
|
|
|
|
|
1184 |
Util_Environment::preg_quote( $theme_dir ) . '/(' .
|
1185 |
Cdn_Util::get_regexp_by_mask( $mask ) .
|
1186 |
')([^"\'() >]*)))~i';
|
1187 |
+
$regexps[] = '~(["\'(=])\s*((' . $site_domain_url_regexp . ')?(' .
|
|
|
1188 |
Util_Environment::preg_quote( $theme_dir2 ) .
|
1189 |
'/(' . Cdn_Util::get_regexp_by_mask( $mask ) .
|
1190 |
')([^"\'() >]*)))~i';
|
1198 |
$masks = array_map( array( '\W3TC\Util_Environment', 'parse_path' ), $masks );
|
1199 |
|
1200 |
if ( count( $masks ) ) {
|
1201 |
+
$custom_regexps_urls = array();
|
1202 |
+
$custom_regexps_uris = array();
|
1203 |
$custom_regexps_docroot_related = array();
|
1204 |
|
1205 |
foreach ( $masks as $mask ) {
|
1206 |
+
if ( ! empty( $mask ) ) {
|
1207 |
if ( Util_Environment::is_url( $mask ) ) {
|
1208 |
$url_match = array();
|
1209 |
if ( preg_match( '~^((https?:)?//([^/]*))(.*)~', $mask, $url_match ) ) {
|
1210 |
$custom_regexps_urls[] = array(
|
1211 |
+
'domain_url' => Util_Environment::get_url_regexp( $url_match[1] ),
|
1212 |
+
'uri' => Cdn_Util::get_regexp_by_mask( $url_match[4] ),
|
|
|
1213 |
);
|
1214 |
}
|
1215 |
+
} elseif ( '/' === substr( $mask, 0, 1 ) ) { // uri.
|
1216 |
$custom_regexps_uris[] = Cdn_Util::get_regexp_by_mask( $mask );
|
1217 |
} else {
|
1218 |
+
$file = Util_Environment::normalize_path( $mask ); // \ -> backspaces.
|
1219 |
$file = str_replace( Util_Environment::site_root(), '', $file );
|
1220 |
$file = ltrim( $file, '/' );
|
1221 |
|
1236 |
}
|
1237 |
|
1238 |
if ( count( $custom_regexps_docroot_related ) > 0 ) {
|
1239 |
+
$regexps[] = '~(["\'(=])\s*((' . $domain_url_regexp . ')?(' .
|
1240 |
+
Util_Environment::preg_quote( $site_path ) .
|
1241 |
'(' . implode( '|', $custom_regexps_docroot_related ) . ')([^"\'() >]*)))~i';
|
1242 |
+
if ( $site_domain_url_regexp ) {
|
1243 |
+
$regexps[] = '~(["\'(=])\s*((' . $site_domain_url_regexp . ')?(' .
|
|
|
1244 |
Util_Environment::preg_quote( $site_path ) . '(' .
|
1245 |
implode( '|', $custom_regexps_docroot_related ) . ')([^"\'() >]*)))~i';
|
1246 |
+
}
|
1247 |
}
|
1248 |
}
|
1249 |
}
|
1252 |
}
|
1253 |
|
1254 |
/**
|
1255 |
+
* Link replace callback, basic checks step.
|
1256 |
+
*
|
1257 |
+
* @param string $match Match.
|
1258 |
+
* @param string $quote Quote.
|
1259 |
+
* @param string $url URL.
|
1260 |
+
* @param string $path Path.
|
1261 |
*
|
|
|
|
|
|
|
|
|
1262 |
* @return null|string
|
1263 |
*/
|
1264 |
+
public function _link_replace_callback_checks( $match, $quote, $url, $path ) {
|
1265 |
global $wpdb;
|
1266 |
+
|
1267 |
static $queue = null, $reject_files = null;
|
1268 |
|
1269 |
/**
|
1270 |
* Check if URL was already replaced
|
1271 |
*/
|
1272 |
+
if ( isset( $this->_replaced_urls[ $url ] ) ) {
|
1273 |
+
return $quote . $this->_replaced_urls[ $url ];
|
1274 |
}
|
1275 |
|
1276 |
/**
|
1277 |
* Check URL for rejected files
|
1278 |
*/
|
1279 |
+
if ( null === $reject_files ) {
|
1280 |
$reject_files = $this->_config->get_array( 'cdn.reject.files' );
|
1281 |
}
|
1282 |
|
1283 |
foreach ( $reject_files as $reject_file ) {
|
1284 |
+
if ( '' !== $reject_file ) {
|
1285 |
$reject_file = Cdn_Util::replace_folder_placeholders( $reject_file );
|
|
|
1286 |
$reject_file = Util_Environment::normalize_file( $reject_file );
|
1287 |
|
1288 |
+
$reject_file_regexp = '~^(' . Cdn_Util::get_regexp_by_mask( $reject_file ) . ')~i';
|
|
|
1289 |
|
1290 |
if ( preg_match( $reject_file_regexp, $path ) ) {
|
1291 |
return $match;
|
1293 |
}
|
1294 |
}
|
1295 |
|
1296 |
+
// Don't replace URL for files that are in the CDN queue.
|
1297 |
+
if ( null === $queue ) {
|
1298 |
+
if ( ! Cdn_Util::is_engine_mirror( $this->_config->get_string( 'cdn.engine' ) ) ) {
|
1299 |
+
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
1300 |
+
$queue = $wpdb->get_var(
|
1301 |
+
$wpdb->prepare(
|
1302 |
+
// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder
|
1303 |
+
'SELECT `remote_path` FROM `%1$s` WHERE `remote_path` = \'%2$s\'',
|
1304 |
+
$wpdb->base_prefix . W3TC_CDN_TABLE_QUEUE,
|
1305 |
+
$path
|
1306 |
+
)
|
1307 |
+
);
|
1308 |
+
} else {
|
1309 |
$queue = false;
|
1310 |
}
|
1311 |
}
|
1312 |
+
|
1313 |
if ( $queue ) {
|
1314 |
return $match;
|
1315 |
}
|
1316 |
+
|
1317 |
return null;
|
1318 |
}
|
1319 |
|
1320 |
/**
|
1321 |
* Link replace callback, url replacement using cdn engine
|
1322 |
*
|
1323 |
+
* @param string $match Matc.
|
1324 |
+
* @param string $quote Quote.
|
1325 |
+
* @param string $url URL.
|
1326 |
+
* @param string $path Path.
|
1327 |
+
*
|
1328 |
* @return null|string
|
1329 |
*/
|
1330 |
+
public function _link_replace_callback_ask_cdn( $match, $quote, $url, $path ) {
|
1331 |
+
$common = Dispatcher::component( 'Cdn_Core' );
|
1332 |
$new_url = $common->url_to_cdn_url( $url, $path );
|
1333 |
+
if ( ! is_null( $new_url ) ) {
|
1334 |
+
$this->_replaced_urls[ $url ] = $new_url;
|
1335 |
return $quote . $new_url;
|
1336 |
}
|
1337 |
|
1339 |
}
|
1340 |
|
1341 |
/**
|
1342 |
+
* Link replace callback for urls from minify module using auto mode and in cdn of push type.
|
1343 |
+
*
|
1344 |
+
* @param array $matches Matches.
|
1345 |
*
|
|
|
1346 |
* @return string
|
1347 |
*/
|
1348 |
+
public function _minify_auto_pushcdn_link_replace_callback( $matches ) {
|
1349 |
static $dispatcher = null;
|
1350 |
|
1351 |
list( $match, $quote, $url, , , , $path ) = $matches;
|
1352 |
+
|
1353 |
$path = ltrim( $path, '/' );
|
1354 |
+
$r = $this->_link_replace_callback_checks( $match, $quote, $url, $path );
|
1355 |
|
1356 |
+
// Check if we can replace that URL (for auto mode it should be uploaded).
|
1357 |
+
if ( ! Dispatcher::is_url_cdn_uploaded( $url ) ) {
|
|
|
|
|
1358 |
Dispatcher::component( 'Cdn_Core' )->queue_upload_url( $url );
|
1359 |
+
if ( ! self::$_upload_scheduled ) {
|
1360 |
wp_schedule_single_event( time(), 'w3_cdn_cron_queue_process' );
|
1361 |
add_action( 'shutdown', 'wp_cron' );
|
1362 |
|
1363 |
self::$_upload_scheduled = true;
|
1364 |
}
|
1365 |
|
|
|
1366 |
return $match;
|
1367 |
}
|
1368 |
|
1372 |
return $r;
|
1373 |
}
|
1374 |
|
1375 |
+
/**
|
1376 |
+
* Get replaced URLs.
|
1377 |
+
*
|
1378 |
+
* @return array
|
1379 |
+
*/
|
1380 |
+
public function get_replaced_urls() {
|
1381 |
return $this->_replaced_urls;
|
1382 |
}
|
1383 |
}
|
Cdn_Util.php
CHANGED
@@ -1,15 +1,27 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
namespace W3TC;
|
3 |
|
|
|
|
|
|
|
4 |
class Cdn_Util {
|
5 |
/**
|
6 |
* Check whether $engine is correct CDN engine
|
7 |
*
|
8 |
-
* @param string
|
9 |
-
*
|
|
|
10 |
*/
|
11 |
-
static
|
12 |
-
return in_array(
|
|
|
|
|
13 |
'akamai',
|
14 |
'att',
|
15 |
'azure',
|
@@ -29,34 +41,61 @@ class Cdn_Util {
|
|
29 |
's3_compatible',
|
30 |
'stackpath',
|
31 |
'stackpath2',
|
32 |
-
)
|
|
|
|
|
33 |
}
|
34 |
|
35 |
/**
|
36 |
* Returns true if CDN engine is mirror
|
37 |
*
|
38 |
-
* @param string
|
|
|
39 |
* @return bool
|
40 |
*/
|
41 |
-
static
|
42 |
-
return in_array(
|
43 |
-
|
44 |
-
|
45 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
}
|
47 |
|
48 |
-
|
49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
|
52 |
/**
|
53 |
-
* Returns true if CDN has purge all support
|
|
|
|
|
54 |
*
|
55 |
-
* @param unknown $engine
|
56 |
* @return bool
|
57 |
*/
|
58 |
-
static
|
59 |
-
return in_array(
|
|
|
|
|
60 |
'att',
|
61 |
'cf2',
|
62 |
'cotendo',
|
@@ -66,17 +105,22 @@ class Cdn_Util {
|
|
66 |
'maxcdn',
|
67 |
'stackpath',
|
68 |
'stackpath2',
|
69 |
-
)
|
|
|
|
|
70 |
}
|
71 |
|
72 |
/**
|
73 |
-
* Returns true if CDN engine is supporting purge
|
|
|
|
|
74 |
*
|
75 |
-
* @param string $engine
|
76 |
* @return bool
|
77 |
*/
|
78 |
-
static
|
79 |
-
return in_array(
|
|
|
|
|
80 |
'akamai',
|
81 |
'att',
|
82 |
'azure',
|
@@ -93,102 +137,132 @@ class Cdn_Util {
|
|
93 |
's3_compatible',
|
94 |
'stackpath',
|
95 |
'stackpath2',
|
96 |
-
)
|
|
|
|
|
97 |
}
|
98 |
|
99 |
/**
|
100 |
* Returns true if CDN supports realtime purge. That is purging on post changes, comments etc.
|
101 |
*
|
102 |
-
* @param unknown $engine
|
|
|
103 |
* @return bool
|
104 |
*/
|
105 |
-
static
|
106 |
-
return !in_array( $engine, array( 'cf2' ) );
|
107 |
}
|
108 |
|
109 |
/**
|
110 |
-
* Search files
|
|
|
|
|
|
|
|
|
|
|
111 |
*
|
112 |
-
* @param string $search_dir
|
113 |
-
* @param string $base_dir
|
114 |
-
* @param string $mask
|
115 |
-
* @param boolean $recursive
|
116 |
* @return array
|
117 |
*/
|
118 |
-
static function search_files( $search_dir, $base_dir, $mask = '*.*', $recursive = true ) {
|
119 |
static $stack = array();
|
120 |
-
|
|
|
121 |
$ignore = array(
|
122 |
'.svn',
|
123 |
'.git',
|
124 |
'.DS_Store',
|
125 |
'CVS',
|
126 |
'Thumbs.db',
|
127 |
-
'desktop.ini'
|
128 |
);
|
129 |
|
130 |
-
$dir = @opendir( $search_dir );
|
131 |
|
132 |
if ( $dir ) {
|
|
|
133 |
while ( ( $entry = @readdir( $dir ) ) !== false ) {
|
134 |
-
if (
|
135 |
$path = $search_dir . '/' . $entry;
|
136 |
|
137 |
-
if ( @is_dir( $path ) && $recursive ) {
|
138 |
array_push( $stack, $entry );
|
139 |
-
$files = array_merge(
|
140 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
array_pop( $stack );
|
142 |
} else {
|
143 |
$regexp = '~^(' . self::get_regexp_by_mask( $mask ) . ')$~i';
|
144 |
|
145 |
if ( preg_match( $regexp, $entry ) ) {
|
146 |
-
$tmp
|
147 |
-
$
|
|
|
148 |
$files[] = $tmp . $entry;
|
149 |
}
|
150 |
}
|
151 |
}
|
152 |
}
|
153 |
|
154 |
-
@closedir( $dir );
|
155 |
}
|
156 |
|
157 |
return $files;
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
-
* Returns regexp by mask
|
|
|
|
|
162 |
*
|
163 |
-
* @param string $mask
|
164 |
* @return string
|
165 |
*/
|
166 |
-
static function get_regexp_by_mask( $mask ) {
|
167 |
$mask = trim( $mask );
|
168 |
$mask = Util_Environment::preg_quote( $mask );
|
169 |
|
170 |
-
$mask = str_replace(
|
|
|
171 |
'\*',
|
172 |
'\?',
|
173 |
-
';'
|
174 |
-
),
|
|
|
175 |
'@ASTERISK@',
|
176 |
'@QUESTION@',
|
177 |
-
'|'
|
178 |
-
),
|
|
|
|
|
179 |
|
180 |
-
$regexp = str_replace(
|
|
|
181 |
'@ASTERISK@',
|
182 |
-
'@QUESTION@'
|
183 |
-
),
|
|
|
184 |
'[^\\?\\*:\\|\'"<>]*',
|
185 |
-
'[^\\?\\*:\\|\'"<>]'
|
186 |
-
),
|
|
|
|
|
187 |
|
188 |
return $regexp;
|
189 |
}
|
190 |
|
191 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
static $content_dir, $plugin_dir, $upload_dir;
|
193 |
if ( empty( $content_dir ) ) {
|
194 |
$content_dir = str_replace( Util_Environment::document_root(), '', WP_CONTENT_DIR );
|
@@ -212,17 +286,25 @@ class Cdn_Util {
|
|
212 |
return $file;
|
213 |
}
|
214 |
|
215 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
216 |
static $content_uri, $plugins_uri, $uploads_uri;
|
217 |
if ( empty( $content_uri ) ) {
|
218 |
$content_uri = Util_Environment::url_to_uri( content_url() );
|
219 |
$plugins_uri = Util_Environment::url_to_uri( plugins_url() );
|
220 |
|
221 |
$upload_dir = Util_Environment::wp_upload_dir();
|
222 |
-
if ( isset( $upload_dir['baseurl'] ) )
|
223 |
$uploads_uri = Util_Environment::url_to_uri( $upload_dir['baseurl'] );
|
224 |
-
else
|
225 |
$uploads_uri = '';
|
|
|
226 |
}
|
227 |
$file = str_replace( '{wp_content_dir}', $content_uri, $file );
|
228 |
$file = str_replace( '{plugins_dir}', $plugins_uri, $file );
|
@@ -230,4 +312,18 @@ class Cdn_Util {
|
|
230 |
|
231 |
return $file;
|
232 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* File: Cdn_Util.php
|
4 |
+
*
|
5 |
+
* @package W3TC
|
6 |
+
*/
|
7 |
+
|
8 |
namespace W3TC;
|
9 |
|
10 |
+
/**
|
11 |
+
* Class: Cdn_Util
|
12 |
+
*/
|
13 |
class Cdn_Util {
|
14 |
/**
|
15 |
* Check whether $engine is correct CDN engine
|
16 |
*
|
17 |
+
* @param string $engine CDN engine.
|
18 |
+
*
|
19 |
+
* @return bool
|
20 |
*/
|
21 |
+
public static function is_engine( $engine ) {
|
22 |
+
return in_array(
|
23 |
+
$engine,
|
24 |
+
array(
|
25 |
'akamai',
|
26 |
'att',
|
27 |
'azure',
|
41 |
's3_compatible',
|
42 |
'stackpath',
|
43 |
'stackpath2',
|
44 |
+
),
|
45 |
+
true
|
46 |
+
);
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
* Returns true if CDN engine is mirror
|
51 |
*
|
52 |
+
* @param string $engine CDN engine.
|
53 |
+
*
|
54 |
* @return bool
|
55 |
*/
|
56 |
+
public static function is_engine_mirror( $engine ) {
|
57 |
+
return in_array(
|
58 |
+
$engine,
|
59 |
+
array(
|
60 |
+
'mirror',
|
61 |
+
'maxcdn',
|
62 |
+
'cotendo',
|
63 |
+
'cf2',
|
64 |
+
'akamai',
|
65 |
+
'edgecast',
|
66 |
+
'att',
|
67 |
+
'highwinds',
|
68 |
+
'limelight',
|
69 |
+
'rackspace_cdn',
|
70 |
+
'stackpath',
|
71 |
+
'stackpath2',
|
72 |
+
),
|
73 |
+
true
|
74 |
+
);
|
75 |
}
|
76 |
|
77 |
+
/**
|
78 |
+
* Returns true if CDN engine is mirror.
|
79 |
+
*
|
80 |
+
* @param string $engine CDN engine.
|
81 |
+
*
|
82 |
+
* @return bool
|
83 |
+
*/
|
84 |
+
public static function is_engine_push( $engine ) {
|
85 |
+
return ! self::is_engine_mirror( $engine );
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
+
* Returns true if CDN has purge all support.
|
90 |
+
*
|
91 |
+
* @param unknown $engine CDN engine.
|
92 |
*
|
|
|
93 |
* @return bool
|
94 |
*/
|
95 |
+
public static function can_purge_all( $engine ) {
|
96 |
+
return in_array(
|
97 |
+
$engine,
|
98 |
+
array(
|
99 |
'att',
|
100 |
'cf2',
|
101 |
'cotendo',
|
105 |
'maxcdn',
|
106 |
'stackpath',
|
107 |
'stackpath2',
|
108 |
+
),
|
109 |
+
true
|
110 |
+
);
|
111 |
}
|
112 |
|
113 |
/**
|
114 |
+
* Returns true if CDN engine is supporting purge.
|
115 |
+
*
|
116 |
+
* @param string $engine CDN engine.
|
117 |
*
|
|
|
118 |
* @return bool
|
119 |
*/
|
120 |
+
public static function can_purge( $engine ) {
|
121 |
+
return in_array(
|
122 |
+
$engine,
|
123 |
+
array(
|
124 |
'akamai',
|
125 |
'att',
|
126 |
'azure',
|
137 |
's3_compatible',
|
138 |
'stackpath',
|
139 |
'stackpath2',
|
140 |
+
),
|
141 |
+
true
|
142 |
+
);
|
143 |
}
|
144 |
|
145 |
/**
|
146 |
* Returns true if CDN supports realtime purge. That is purging on post changes, comments etc.
|
147 |
*
|
148 |
+
* @param unknown $engine CDN engine.
|
149 |
+
*
|
150 |
* @return bool
|
151 |
*/
|
152 |
+
public static function supports_realtime_purge( $engine ) {
|
153 |
+
return ! in_array( $engine, array( 'cf2' ), true );
|
154 |
}
|
155 |
|
156 |
/**
|
157 |
+
* Search files.
|
158 |
+
*
|
159 |
+
* @param string $search_dir Search path.
|
160 |
+
* @param string $base_dir Base path.
|
161 |
+
* @param string $mask Mask value.
|
162 |
+
* @param boolean $recursive Recursive flag.
|
163 |
*
|
|
|
|
|
|
|
|
|
164 |
* @return array
|
165 |
*/
|
166 |
+
public static function search_files( $search_dir, $base_dir, $mask = '*.*', $recursive = true ) {
|
167 |
static $stack = array();
|
168 |
+
|
169 |
+
$files = array();
|
170 |
$ignore = array(
|
171 |
'.svn',
|
172 |
'.git',
|
173 |
'.DS_Store',
|
174 |
'CVS',
|
175 |
'Thumbs.db',
|
176 |
+
'desktop.ini',
|
177 |
);
|
178 |
|
179 |
+
$dir = @opendir( $search_dir ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
|
180 |
|
181 |
if ( $dir ) {
|
182 |
+
// phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition, WordPress.PHP.NoSilencedErrors.Discouraged
|
183 |
while ( ( $entry = @readdir( $dir ) ) !== false ) {
|
184 |
+
if ( '.' !== $entry && '..' !== $entry && ! in_array( $entry, $ignore, true ) ) {
|
185 |
$path = $search_dir . '/' . $entry;
|
186 |
|
187 |
+
if ( @is_dir( $path ) && $recursive ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
|
188 |
array_push( $stack, $entry );
|
189 |
+
$files = array_merge(
|
190 |
+
$files,
|
191 |
+
self::search_files(
|
192 |
+
$path,
|
193 |
+
$base_dir,
|
194 |
+
$mask,
|
195 |
+
$recursive
|
196 |
+
)
|
197 |
+
);
|
198 |
array_pop( $stack );
|
199 |
} else {
|
200 |
$regexp = '~^(' . self::get_regexp_by_mask( $mask ) . ')$~i';
|
201 |
|
202 |
if ( preg_match( $regexp, $entry ) ) {
|
203 |
+
$tmp = '' !== $base_dir ? $base_dir . '/' : '';
|
204 |
+
$p = implode( '/', $stack );
|
205 |
+
$tmp .= '' !== $p ? $p . '/' : '';
|
206 |
$files[] = $tmp . $entry;
|
207 |
}
|
208 |
}
|
209 |
}
|
210 |
}
|
211 |
|
212 |
+
@closedir( $dir ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
|
213 |
}
|
214 |
|
215 |
return $files;
|
216 |
}
|
217 |
|
218 |
/**
|
219 |
+
* Returns regexp by mask.
|
220 |
+
*
|
221 |
+
* @param string $mask Mask pattern.
|
222 |
*
|
|
|
223 |
* @return string
|
224 |
*/
|
225 |
+
public static function get_regexp_by_mask( $mask ) {
|
226 |
$mask = trim( $mask );
|
227 |
$mask = Util_Environment::preg_quote( $mask );
|
228 |
|
229 |
+
$mask = str_replace(
|
230 |
+
array(
|
231 |
'\*',
|
232 |
'\?',
|
233 |
+
';',
|
234 |
+
),
|
235 |
+
array(
|
236 |
'@ASTERISK@',
|
237 |
'@QUESTION@',
|
238 |
+
'|',
|
239 |
+
),
|
240 |
+
$mask
|
241 |
+
);
|
242 |
|
243 |
+
$regexp = str_replace(
|
244 |
+
array(
|
245 |
'@ASTERISK@',
|
246 |
+
'@QUESTION@',
|
247 |
+
),
|
248 |
+
array(
|
249 |
'[^\\?\\*:\\|\'"<>]*',
|
250 |
+
'[^\\?\\*:\\|\'"<>]',
|
251 |
+
),
|
252 |
+
$mask
|
253 |
+
);
|
254 |
|
255 |
return $regexp;
|
256 |
}
|
257 |
|
258 |
+
/**
|
259 |
+
* Replaces folder placeholders.
|
260 |
+
*
|
261 |
+
* @param string $file Replacement value.
|
262 |
+
*
|
263 |
+
* @return string
|
264 |
+
*/
|
265 |
+
public static function replace_folder_placeholders( $file ) {
|
266 |
static $content_dir, $plugin_dir, $upload_dir;
|
267 |
if ( empty( $content_dir ) ) {
|
268 |
$content_dir = str_replace( Util_Environment::document_root(), '', WP_CONTENT_DIR );
|
286 |
return $file;
|
287 |
}
|
288 |
|
289 |
+
/**
|
290 |
+
* Replaces folder placeholders URI.
|
291 |
+
*
|
292 |
+
* @param string $file Replacement value.
|
293 |
+
*
|
294 |
+
* @return string
|
295 |
+
*/
|
296 |
+
public static function replace_folder_placeholders_to_uri( $file ) {
|
297 |
static $content_uri, $plugins_uri, $uploads_uri;
|
298 |
if ( empty( $content_uri ) ) {
|
299 |
$content_uri = Util_Environment::url_to_uri( content_url() );
|
300 |
$plugins_uri = Util_Environment::url_to_uri( plugins_url() );
|
301 |
|
302 |
$upload_dir = Util_Environment::wp_upload_dir();
|
303 |
+
if ( isset( $upload_dir['baseurl'] ) ) {
|
304 |
$uploads_uri = Util_Environment::url_to_uri( $upload_dir['baseurl'] );
|
305 |
+
} else {
|
306 |
$uploads_uri = '';
|
307 |
+
}
|
308 |
}
|
309 |
$file = str_replace( '{wp_content_dir}', $content_uri, $file );
|
310 |
$file = str_replace( '{plugins_dir}', $plugins_uri, $file );
|
312 |
|
313 |
return $file;
|
314 |
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Get the override default value for cdn.flush_manually to prevent excessive invalidation charges for S3 CF and CF2.
|
318 |
+
*
|
319 |
+
* @since 2.2.6
|
320 |
+
*
|
321 |
+
* @param string $cdn_engine CDN engine value.
|
322 |
+
*
|
323 |
+
* @return boolean default value override;
|
324 |
+
*/
|
325 |
+
public static function get_flush_manually_default_override( $cdn_engine = null ) {
|
326 |
+
$override_targets = array( 's3', 'cf', 'cf2' );
|
327 |
+
return in_array( $cdn_engine, $override_targets, true );
|
328 |
+
}
|
329 |
}
|
Cdnfsd_CacheFlush.php
CHANGED
@@ -1,128 +1,137 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
/**
|
5 |
-
*
|
6 |
*/
|
7 |
class Cdnfsd_CacheFlush {
|
8 |
/**
|
9 |
-
* Array of urls to flush
|
10 |
*
|
11 |
* @var array
|
12 |
*/
|
13 |
private $queued_urls = array();
|
14 |
-
private $flush_all_requested = false;
|
15 |
-
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
/**
|
19 |
-
* Purges everything from CDNs that supports it
|
|
|
|
|
|
|
|
|
20 |
*/
|
21 |
-
static
|
22 |
-
if ( isset( $extras['only'] ) && $extras['only']
|
23 |
return;
|
|
|
24 |
|
25 |
-
$config
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
29 |
return true;
|
30 |
}
|
31 |
}
|
32 |
|
33 |
-
$o
|
34 |
-
|
35 |
$o->flush_all_requested = true;
|
|
|
36 |
return true;
|
37 |
}
|
38 |
|
39 |
-
|
40 |
-
|
41 |
/**
|
42 |
* Purges cdn's post cache
|
43 |
*
|
44 |
-
* @param integer $post_id
|
45 |
-
* @
|
|
|
|
|
46 |
*/
|
47 |
-
static
|
48 |
-
if (
|
49 |
$post_id = Util_Environment::detect_post_id();
|
50 |
}
|
51 |
|
52 |
-
if (
|
53 |
return false;
|
|
|
54 |
|
55 |
-
$config
|
56 |
-
|
57 |
-
|
58 |
-
|
|
|
|
|
59 |
return true;
|
60 |
}
|
61 |
}
|
62 |
|
63 |
-
global $wp_rewrite;
|
64 |
if ( empty( $wp_rewrite ) ) {
|
65 |
-
error_log('Post was modified before wp_rewrite initialization. Cant flush cache.');
|
66 |
return false;
|
67 |
}
|
68 |
|
69 |
$full_urls = array();
|
70 |
-
$post
|
71 |
-
$terms
|
72 |
|
73 |
-
$feeds
|
74 |
$limit_post_pages = $config->get_integer( 'pgcache.purge.postpages_limit' );
|
75 |
|
76 |
if ( $config->get_boolean( 'pgcache.purge.terms' ) || $config->get_boolean( 'varnish.pgcache.feed.terms' ) ) {
|
77 |
$taxonomies = get_post_taxonomies( $post_id );
|
78 |
-
$terms
|
79 |
}
|
80 |
|
81 |
switch ( true ) {
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
}
|
89 |
|
90 |
$front_page = get_option( 'show_on_front' );
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
if ( ( $config->get_boolean( 'pgcache.purge.home' ) && $front_page == 'posts' )||
|
96 |
$config->get_boolean( 'pgcache.purge.front_page' ) ) {
|
97 |
-
$full_urls = array_merge( $full_urls,
|
98 |
-
Util_PageUrls::get_frontpage_urls( $limit_post_pages ) );
|
99 |
}
|
100 |
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
if ( $config->get_boolean( 'pgcache.purge.home' ) && $front_page != 'posts' ) {
|
105 |
-
$full_urls = array_merge( $full_urls,
|
106 |
-
Util_PageUrls::get_postpage_urls( $limit_post_pages ) );
|
107 |
}
|
108 |
|
109 |
-
|
110 |
-
* Post URL
|
111 |
-
*/
|
112 |
if ( $config->get_boolean( 'pgcache.purge.post' ) ) {
|
113 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_post_urls( $post_id ) );
|
114 |
}
|
115 |
|
116 |
-
|
117 |
-
* Post comments URLs
|
118 |
-
*/
|
119 |
if ( $config->get_boolean( 'pgcache.purge.comments' ) && function_exists( 'get_comments_pagenum_link' ) ) {
|
120 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_post_comments_urls( $post_id ) );
|
121 |
}
|
122 |
|
123 |
-
|
124 |
-
* Post author URLs
|
125 |
-
*/
|
126 |
if ( $config->get_boolean( 'pgcache.purge.author' ) && $post ) {
|
127 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_post_author_urls( $post->post_author, $limit_post_pages ) );
|
128 |
}
|
@@ -148,86 +157,92 @@ class Cdnfsd_CacheFlush {
|
|
148 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_monthly_archive_urls( $post, $limit_post_pages ) );
|
149 |
}
|
150 |
|
151 |
-
|
152 |
-
* Yearly archive URLs
|
153 |
-
*/
|
154 |
if ( $config->get_boolean( 'pgcache.purge.archive.yearly' ) && $post ) {
|
155 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_yearly_archive_urls( $post, $limit_post_pages ) );
|
156 |
}
|
157 |
|
158 |
-
|
159 |
-
* Feed URLs
|
160 |
-
*/
|
161 |
if ( $config->get_boolean( 'pgcache.purge.feed.blog' ) ) {
|
162 |
-
$full_urls = array_merge( $full_urls,
|
163 |
-
Util_PageUrls::get_feed_urls( $feeds ) );
|
164 |
}
|
165 |
|
|
|
166 |
if ( $config->get_boolean( 'pgcache.purge.feed.comments' ) ) {
|
167 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_feed_comments_urls( $post_id, $feeds ) );
|
168 |
}
|
169 |
|
|
|
170 |
if ( $config->get_boolean( 'pgcache.purge.feed.author' ) && $post ) {
|
171 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_feed_author_urls( $post->post_author, $feeds ) );
|
172 |
}
|
173 |
|
|
|
174 |
if ( $config->get_boolean( 'pgcache.purge.feed.terms' ) ) {
|
175 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_feed_terms_urls( $terms, $feeds ) );
|
176 |
}
|
177 |
|
178 |
-
|
179 |
-
* Purge selected pages
|
180 |
-
*/
|
181 |
if ( $config->get_array( 'pgcache.purge.pages' ) ) {
|
182 |
-
$pages
|
183 |
-
$full_urls = array_merge( $full_urls,
|
184 |
-
Util_PageUrls::get_pages_urls( $pages ) );
|
185 |
}
|
186 |
|
187 |
-
|
188 |
-
* Queue flush
|
189 |
-
*/
|
190 |
if ( count( $full_urls ) ) {
|
191 |
$o = Dispatcher::component( 'Cdnfsd_CacheFlush' );
|
192 |
|
193 |
-
foreach ( $full_urls as $url )
|
194 |
-
$o->queued_urls[$url] = '*';
|
|
|
195 |
}
|
196 |
|
197 |
return true;
|
198 |
}
|
199 |
|
200 |
/**
|
201 |
-
* Purge a single url
|
|
|
|
|
|
|
202 |
*
|
203 |
-
* @
|
204 |
*/
|
205 |
-
static
|
206 |
-
$config
|
207 |
-
|
208 |
-
|
209 |
-
|
|
|
|
|
210 |
return true;
|
211 |
}
|
212 |
}
|
213 |
|
214 |
-
$o
|
215 |
-
$o->queued_urls[$url] = '*';
|
216 |
|
217 |
return true;
|
218 |
}
|
219 |
|
220 |
/**
|
221 |
* Clears global and repeated urls
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
*/
|
223 |
-
static
|
224 |
$o = Dispatcher::component( 'Cdnfsd_CacheFlush' );
|
225 |
|
226 |
-
//
|
227 |
-
$c
|
228 |
$engine = $c->get_string( 'cdnfsd.engine' );
|
229 |
-
if ( empty( $engine ) )
|
230 |
return $actions_made;
|
|
|
231 |
|
232 |
if ( $o->flush_all_requested ) {
|
233 |
$core = Dispatcher::component( 'Cdnfsd_Core' );
|
@@ -235,19 +250,19 @@ class Cdnfsd_CacheFlush {
|
|
235 |
try {
|
236 |
$engine = $core->get_engine();
|
237 |
|
238 |
-
if ( !is_null( $engine ) ) {
|
239 |
$engine->flush_all();
|
240 |
$actions_made[] = array( 'module' => 'cdn' );
|
241 |
}
|
242 |
} catch ( \Exception $ex ) {
|
243 |
$actions_made[] = array(
|
244 |
'module' => 'cdn',
|
245 |
-
'error'
|
246 |
);
|
247 |
}
|
248 |
|
249 |
$o->flush_all_requested = false;
|
250 |
-
$o->queued_urls
|
251 |
} else {
|
252 |
$count = count( $o->queued_urls );
|
253 |
if ( $count > 0 ) {
|
@@ -258,14 +273,14 @@ class Cdnfsd_CacheFlush {
|
|
258 |
try {
|
259 |
$engine = $core->get_engine();
|
260 |
|
261 |
-
if ( !is_null( $engine ) ) {
|
262 |
$engine->flush_urls( $urls );
|
263 |
$actions_made[] = array( 'module' => 'cdn' );
|
264 |
}
|
265 |
} catch ( \Exception $ex ) {
|
266 |
$actions_made[] = array(
|
267 |
'module' => 'cdn',
|
268 |
-
'error'
|
269 |
);
|
270 |
}
|
271 |
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* File: Cdnfsd_CacheFlush.php
|
4 |
+
*
|
5 |
+
* @package W3TC
|
6 |
+
*/
|
7 |
+
|
8 |
namespace W3TC;
|
9 |
|
10 |
/**
|
11 |
+
* Class: Cdnfsd_CacheFlush
|
12 |
*/
|
13 |
class Cdnfsd_CacheFlush {
|
14 |
/**
|
15 |
+
* Array of urls to flush.
|
16 |
*
|
17 |
* @var array
|
18 |
*/
|
19 |
private $queued_urls = array();
|
|
|
|
|
20 |
|
21 |
+
/**
|
22 |
+
* Flush all requests flag.
|
23 |
+
*
|
24 |
+
* @var bool
|
25 |
+
*/
|
26 |
+
private $flush_all_requested = false;
|
27 |
|
28 |
/**
|
29 |
+
* Purges everything from CDNs that supports it.
|
30 |
+
*
|
31 |
+
* @param array $extras Extras to purge.
|
32 |
+
*
|
33 |
+
* @return bool
|
34 |
*/
|
35 |
+
public static function w3tc_flush_all( $extras = null ) {
|
36 |
+
if ( isset( $extras['only'] ) && 'cdn' !== $extras['only'] ) {
|
37 |
return;
|
38 |
+
}
|
39 |
|
40 |
+
$config = Dispatcher::config();
|
41 |
+
$common = Dispatcher::component( 'Cdn_Core' );
|
42 |
+
$default_override = Cdn_Util::get_flush_manually_default_override();
|
43 |
+
if ( $config->get_boolean( 'cdn.flush_manually', $default_override ) ) {
|
44 |
+
// in this mode flush only on purge button clicks.
|
45 |
+
if ( ! isset( $extras['ui_action'] ) ) {
|
46 |
return true;
|
47 |
}
|
48 |
}
|
49 |
|
50 |
+
$o = Dispatcher::component( 'Cdnfsd_CacheFlush' );
|
|
|
51 |
$o->flush_all_requested = true;
|
52 |
+
|
53 |
return true;
|
54 |
}
|
55 |
|
|
|
|
|
56 |
/**
|
57 |
* Purges cdn's post cache
|
58 |
*
|
59 |
+
* @param integer $post_id Post ID.
|
60 |
+
* @param array $extras Extras.
|
61 |
+
*
|
62 |
+
* @return bool
|
63 |
*/
|
64 |
+
public static function w3tc_flush_post( $post_id, $extras = null ) {
|
65 |
+
if ( ! $post_id ) {
|
66 |
$post_id = Util_Environment::detect_post_id();
|
67 |
}
|
68 |
|
69 |
+
if ( ! $post_id ) {
|
70 |
return false;
|
71 |
+
}
|
72 |
|
73 |
+
$config = Dispatcher::config();
|
74 |
+
$common = Dispatcher::component( 'Cdn_Core' );
|
75 |
+
$default_override = Cdn_Util::get_flush_manually_default_override();
|
76 |
+
if ( $config->get_boolean( 'cdn.flush_manually', $default_override ) ) {
|
77 |
+
// in this mode flush only on purge button clicks.
|
78 |
+
if ( ! isset( $extras['ui_action'] ) ) {
|
79 |
return true;
|
80 |
}
|
81 |
}
|
82 |
|
83 |
+
global $wp_rewrite; // required by many Util_PageUrls methods.
|
84 |
if ( empty( $wp_rewrite ) ) {
|
85 |
+
error_log( __( 'Post was modified before wp_rewrite initialization. Cant flush cache.', 'w3-total-cache' ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
|
86 |
return false;
|
87 |
}
|
88 |
|
89 |
$full_urls = array();
|
90 |
+
$post = null;
|
91 |
+
$terms = array();
|
92 |
|
93 |
+
$feeds = $config->get_array( 'pgcache.purge.feed.types' );
|
94 |
$limit_post_pages = $config->get_integer( 'pgcache.purge.postpages_limit' );
|
95 |
|
96 |
if ( $config->get_boolean( 'pgcache.purge.terms' ) || $config->get_boolean( 'varnish.pgcache.feed.terms' ) ) {
|
97 |
$taxonomies = get_post_taxonomies( $post_id );
|
98 |
+
$terms = wp_get_post_terms( $post_id, $taxonomies );
|
99 |
}
|
100 |
|
101 |
switch ( true ) {
|
102 |
+
case $config->get_boolean( 'pgcache.purge.author' ):
|
103 |
+
case $config->get_boolean( 'pgcache.purge.archive.daily' ):
|
104 |
+
case $config->get_boolean( 'pgcache.purge.archive.monthly' ):
|
105 |
+
case $config->get_boolean( 'pgcache.purge.archive.yearly' ):
|
106 |
+
case $config->get_boolean( 'pgcache.purge.feed.author' ):
|
107 |
+
$post = get_post( $post_id );
|
108 |
}
|
109 |
|
110 |
$front_page = get_option( 'show_on_front' );
|
111 |
|
112 |
+
// Home (Frontpage) URL.
|
113 |
+
if ( ( $config->get_boolean( 'pgcache.purge.home' ) &&
|
114 |
+
'posts' === $front_page ) ||
|
|
|
115 |
$config->get_boolean( 'pgcache.purge.front_page' ) ) {
|
116 |
+
$full_urls = array_merge( $full_urls, Util_PageUrls::get_frontpage_urls( $limit_post_pages ) );
|
|
|
117 |
}
|
118 |
|
119 |
+
// Home (Post page) URL.
|
120 |
+
if ( $config->get_boolean( 'pgcache.purge.home' ) && 'posts' !== $front_page ) {
|
121 |
+
$full_urls = array_merge( $full_urls, Util_PageUrls::get_postpage_urls( $limit_post_pages ) );
|
|
|
|
|
|
|
122 |
}
|
123 |
|
124 |
+
// Post URL.
|
|
|
|
|
125 |
if ( $config->get_boolean( 'pgcache.purge.post' ) ) {
|
126 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_post_urls( $post_id ) );
|
127 |
}
|
128 |
|
129 |
+
// Post comments URLs.
|
|
|
|
|
130 |
if ( $config->get_boolean( 'pgcache.purge.comments' ) && function_exists( 'get_comments_pagenum_link' ) ) {
|
131 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_post_comments_urls( $post_id ) );
|
132 |
}
|
133 |
|
134 |
+
// Post author URLs.
|
|
|
|
|
135 |
if ( $config->get_boolean( 'pgcache.purge.author' ) && $post ) {
|
136 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_post_author_urls( $post->post_author, $limit_post_pages ) );
|
137 |
}
|
157 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_monthly_archive_urls( $post, $limit_post_pages ) );
|
158 |
}
|
159 |
|
160 |
+
// Yearly archive URLs.
|
|
|
|
|
161 |
if ( $config->get_boolean( 'pgcache.purge.archive.yearly' ) && $post ) {
|
162 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_yearly_archive_urls( $post, $limit_post_pages ) );
|
163 |
}
|
164 |
|
165 |
+
// Feed blog URLs.
|
|
|
|
|
166 |
if ( $config->get_boolean( 'pgcache.purge.feed.blog' ) ) {
|
167 |
+
$full_urls = array_merge( $full_urls, Util_PageUrls::get_feed_urls( $feeds ) );
|
|
|
168 |
}
|
169 |
|
170 |
+
// Feed comments URLs.
|
171 |
if ( $config->get_boolean( 'pgcache.purge.feed.comments' ) ) {
|
172 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_feed_comments_urls( $post_id, $feeds ) );
|
173 |
}
|
174 |
|
175 |
+
// Feed autor URLs.
|
176 |
if ( $config->get_boolean( 'pgcache.purge.feed.author' ) && $post ) {
|
177 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_feed_author_urls( $post->post_author, $feeds ) );
|
178 |
}
|
179 |
|
180 |
+
// Feed terms URLs.
|
181 |
if ( $config->get_boolean( 'pgcache.purge.feed.terms' ) ) {
|
182 |
$full_urls = array_merge( $full_urls, Util_PageUrls::get_feed_terms_urls( $terms, $feeds ) );
|
183 |
}
|
184 |
|
185 |
+
// Purge selected pages.
|
|
|
|
|
186 |
if ( $config->get_array( 'pgcache.purge.pages' ) ) {
|
187 |
+
$pages = $config->get_array( 'pgcache.purge.pages' );
|
188 |
+
$full_urls = array_merge( $full_urls, Util_PageUrls::get_pages_urls( $pages ) );
|
|
|
189 |
}
|
190 |
|
191 |
+
// Queue flush.
|
|
|
|
|
192 |
if ( count( $full_urls ) ) {
|
193 |
$o = Dispatcher::component( 'Cdnfsd_CacheFlush' );
|
194 |
|
195 |
+
foreach ( $full_urls as $url ) {
|
196 |
+
$o->queued_urls[ $url ] = '*';
|
197 |
+
}
|
198 |
}
|
199 |
|
200 |
return true;
|
201 |
}
|
202 |
|
203 |
/**
|
204 |
+
* Purge a single url.
|
205 |
+
*
|
206 |
+
* @param unknown $url URL to purge.
|
207 |
+
* @param array $extras Extras.
|
208 |
*
|
209 |
+
* @return bool
|
210 |
*/
|
211 |
+
public static function w3tc_flush_url( $url, $extras = null ) {
|
212 |
+
$config = Dispatcher::config();
|
213 |
+
$common = Dispatcher::component( 'Cdn_Core' );
|
214 |
+
$default_override = Cdn_Util::get_flush_manually_default_override();
|
215 |
+
if ( $config->get_boolean( 'cdn.flush_manually', $default_override ) ) {
|
216 |
+
// in this mode flush only on purge button clicks.
|
217 |
+
if ( ! isset( $extras['ui_action'] ) ) {
|
218 |
return true;
|
219 |
}
|
220 |
}
|
221 |
|
222 |
+
$o = Dispatcher::component( 'Cdnfsd_CacheFlush' );
|
223 |
+
$o->queued_urls[ $url ] = '*';
|
224 |
|
225 |
return true;
|
226 |
}
|
227 |
|
228 |
/**
|
229 |
* Clears global and repeated urls
|
230 |
+
*
|
231 |
+
* @param array $actions_made Actions made.
|
232 |
+
*
|
233 |
+
* @throws \Exception Exception.
|
234 |
+
*
|
235 |
+
* @return array
|
236 |
*/
|
237 |
+
public static function w3tc_flush_execute_delayed_operations( $actions_made ) {
|
238 |
$o = Dispatcher::component( 'Cdnfsd_CacheFlush' );
|
239 |
|
240 |
+
// Protection from incorrect w3tc upgrade operation when engine gets empty.
|
241 |
+
$c = Dispatcher::config();
|
242 |
$engine = $c->get_string( 'cdnfsd.engine' );
|
243 |
+
if ( empty( $engine ) ) {
|
244 |
return $actions_made;
|
245 |
+
}
|
246 |
|
247 |
if ( $o->flush_all_requested ) {
|
248 |
$core = Dispatcher::component( 'Cdnfsd_Core' );
|
250 |
try {
|
251 |
$engine = $core->get_engine();
|
252 |
|
253 |
+
if ( ! is_null( $engine ) ) {
|
254 |
$engine->flush_all();
|
255 |
$actions_made[] = array( 'module' => 'cdn' );
|
256 |
}
|
257 |
} catch ( \Exception $ex ) {
|
258 |
$actions_made[] = array(
|
259 |
'module' => 'cdn',
|
260 |
+
'error' => $ex->getMessage(),
|
261 |
);
|
262 |
}
|
263 |
|
264 |
$o->flush_all_requested = false;
|
265 |
+
$o->queued_urls = array();
|
266 |
} else {
|
267 |
$count = count( $o->queued_urls );
|
268 |
if ( $count > 0 ) {
|
273 |
try {
|
274 |
$engine = $core->get_engine();
|
275 |
|
276 |
+
if ( ! is_null( $engine ) ) {
|
277 |
$engine->flush_urls( $urls );
|
278 |
$actions_made[] = array( 'module' => 'cdn' );
|
279 |
}
|
280 |
} catch ( \Exception $ex ) {
|
281 |
$actions_made[] = array(
|
282 |
'module' => 'cdn',
|
283 |
+
'error' => $ex->getMessage(),
|
284 |
);
|
285 |
}
|
286 |
|
DbCache_WpdbInjection_QueryCaching.php
CHANGED
@@ -3,14 +3,15 @@
|
|
3 |
* File: DbCache_WpdbInjection_QueryCaching.php
|
4 |
*
|
5 |
* @package W3TC
|
6 |
-
*
|
7 |
-
* phpcs:disable WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize, PSR2.Methods.MethodDeclaration.Underscore, PSR2.Classes.PropertyDeclaration.Underscore
|
8 |
*/
|
9 |
|
10 |
namespace W3TC;
|
11 |
|
12 |
/**
|
13 |
* Class: DbCache_WpdbInjection_QueryCaching
|
|
|
|
|
|
|
14 |
*/
|
15 |
class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
16 |
/**
|
@@ -43,6 +44,8 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
43 |
|
44 |
/**
|
45 |
* Config.
|
|
|
|
|
46 |
*/
|
47 |
public $_config = null;
|
48 |
|
@@ -62,7 +65,6 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
62 |
|
63 |
/**
|
64 |
* Request-global cache reject reason.
|
65 |
-
* null until filled.
|
66 |
*
|
67 |
* @var string
|
68 |
*/
|
@@ -70,20 +72,48 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
70 |
|
71 |
/**
|
72 |
* Request-global check reject scope.
|
73 |
-
* false until set.
|
74 |
*
|
75 |
* @var bool
|
76 |
*/
|
77 |
private $cache_reject_request_wide = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
private $debug = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
private $reject_logged = false;
|
80 |
-
|
81 |
-
|
|
|
|
|
|
|
|
|
82 |
private $log_filehandle = false;
|
83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
/**
|
85 |
* Result of check if caching is possible at the level of current http request.
|
86 |
-
* null until filled.
|
87 |
*
|
88 |
* @var bool
|
89 |
*/
|
@@ -125,15 +155,15 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
125 |
$caching = $this->_can_cache( $query, $reject_reason );
|
126 |
if ( preg_match( '~^\s*start transaction\b~is', $query ) ) {
|
127 |
$this->cache_reject_reason = 'transaction';
|
128 |
-
$reject_reason
|
129 |
-
$caching
|
130 |
}
|
131 |
|
132 |
if ( preg_match( '~^\s*insert\b|^\s*delete\b|^\s*update\b|^\s*replace\b|^\s*commit\b|^\s*truncate\b|^\s*drop\b|^\s*create\b~is', $query ) ) {
|
133 |
$this->cache_reject_reason = 'modification query';
|
134 |
-
$reject_reason
|
135 |
-
$caching
|
136 |
-
$flush_after_query
|
137 |
}
|
138 |
|
139 |
if ( $this->use_filters && function_exists( 'apply_filters' ) ) {
|
@@ -219,16 +249,16 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
219 |
gmdate( 'r' ),
|
220 |
strtr(
|
221 |
isset( $_SERVER['REQUEST_URI'] ) ?
|
222 |
-
|
223 |
"<>\r\n",
|
224 |
'.. '
|
225 |
),
|
226 |
-
strtr( $query, "<>\r\n", '.. ' ), //
|
227 |
-
(int) ( $time_total * 1000000 ), //
|
228 |
-
$reject_reason, //
|
229 |
-
$is_cache_hit, //
|
230 |
-
( $data ? strlen( serialize( $data ) ) : 0 ), //
|
231 |
-
strtr( $group, "<>\r\n", '.. ' ), //
|
232 |
)
|
233 |
);
|
234 |
}
|
@@ -270,6 +300,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
270 |
* @param string $table Table.
|
271 |
* @param array $data Data.
|
272 |
* @param array|string $format Format.
|
|
|
273 |
* @return int|false
|
274 |
*/
|
275 |
public function insert( $table, $data, $format = null ) {
|
@@ -282,6 +313,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
282 |
* @param string $table Table.
|
283 |
* @param array $data Data.
|
284 |
* @param array|string $format Format.
|
|
|
285 |
* @return int|false
|
286 |
*/
|
287 |
public function replace( $table, $data, $format = null ) {
|
@@ -302,6 +334,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
302 |
* @param array $where Where.
|
303 |
* @param array|string $format Format.
|
304 |
* @param array|string $where_format Format where.
|
|
|
305 |
* @return int|false
|
306 |
*/
|
307 |
public function update( $table, $data, $where, $format = null, $where_format = null ) {
|
@@ -316,6 +349,8 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
316 |
* @param string $table Table.
|
317 |
* @param array $where Where.
|
318 |
* @param array|string $where_format Format where.
|
|
|
|
|
319 |
*/
|
320 |
public function delete( $table, $where, $where_format = null ) {
|
321 |
$group = $this->_get_group( $table );
|
@@ -327,6 +362,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
327 |
* Flushes cache.
|
328 |
*
|
329 |
* @param array $extras Extra arguments.
|
|
|
330 |
* @return bool
|
331 |
*/
|
332 |
public function flush_cache( $extras = array() ) {
|
@@ -340,6 +376,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
340 |
*
|
341 |
* @param string $group Group.
|
342 |
* @param array $extras Extra arguments.
|
|
|
343 |
* @return bool
|
344 |
*/
|
345 |
private function _flush_cache_for_sql_group( $group, $extras = array() ) {
|
@@ -349,7 +386,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
349 |
$filename = Util_Debug::log(
|
350 |
'dbcache',
|
351 |
'flushing based on sqlquery group ' . $group .
|
352 |
-
' with extras ' .
|
353 |
);
|
354 |
}
|
355 |
if ( $this->_config->get_boolean( 'dbcache.debug_purge' ) ) {
|
@@ -397,7 +434,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
397 |
'aws_autodiscovery' => $this->_config->get_boolean( 'dbcache.memcached.aws_autodiscovery' ),
|
398 |
'username' => $this->_config->get_string( 'dbcache.memcached.username' ),
|
399 |
'password' => $this->_config->get_string( 'dbcache.memcached.password' ),
|
400 |
-
'binary_protocol' => $this->_config->get_boolean( 'dbcache.memcached.binary_protocol' )
|
401 |
);
|
402 |
break;
|
403 |
|
@@ -410,7 +447,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
410 |
'retry_interval' => $this->_config->get_integer( 'dbcache.redis.retry_interval' ),
|
411 |
'read_timeout' => $this->_config->get_integer( 'dbcache.redis.read_timeout' ),
|
412 |
'dbid' => $this->_config->get_integer( 'dbcache.redis.dbid' ),
|
413 |
-
'password' => $this->_config->get_string( 'dbcache.redis.password' )
|
414 |
);
|
415 |
break;
|
416 |
|
@@ -419,7 +456,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
419 |
'use_wp_hash' => true,
|
420 |
'section' => 'db',
|
421 |
'locking' => $this->_config->get_boolean( 'dbcache.file.locking' ),
|
422 |
-
'flush_timelimit' => $this->_config->get_integer( 'timelimit.cache_flush' )
|
423 |
);
|
424 |
break;
|
425 |
|
@@ -441,6 +478,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
441 |
*
|
442 |
* @param string $sql SQL query.
|
443 |
* @param string $cache_reject_reason Cache reject reason.
|
|
|
444 |
* @return boolean
|
445 |
*/
|
446 |
public function _can_cache( $sql, &$cache_reject_reason ) {
|
@@ -471,7 +509,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
471 |
foreach ( $this->reject_constants as $name ) {
|
472 |
if ( defined( $name ) && constant( $name ) ) {
|
473 |
$this->cache_reject_reason = $name . ' constant defined';
|
474 |
-
$cache_reject_reason
|
475 |
|
476 |
return false;
|
477 |
}
|
@@ -516,7 +554,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
516 |
*/
|
517 |
if ( $this->reject_logged && ! $this->_check_logged_in() ) {
|
518 |
$this->cache_reject_reason = 'user.logged_in';
|
519 |
-
$cache_reject_reason
|
520 |
|
521 |
return false;
|
522 |
}
|
@@ -562,6 +600,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
562 |
* Check SQL
|
563 |
*
|
564 |
* @param string $sql SQL query.
|
|
|
565 |
* @return bool
|
566 |
*/
|
567 |
public function _check_sql( $sql ) {
|
@@ -597,7 +636,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
597 |
);
|
598 |
|
599 |
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ?
|
600 |
-
|
601 |
|
602 |
foreach ( $auto_reject_uri as $uri ) {
|
603 |
if ( strstr( $request_uri, $uri ) !== false ) {
|
@@ -665,6 +704,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
665 |
* @access private
|
666 |
*
|
667 |
* @param string $sql SQL query.
|
|
|
668 |
* @return string
|
669 |
*/
|
670 |
private function _get_group( $sql ) {
|
@@ -679,7 +719,14 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
679 |
|
680 |
if ( $this->contains_only_tables( $tables, array( 'options' => '*' ) ) ) {
|
681 |
$group = 'options';
|
682 |
-
} elseif (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
683 |
$group = 'comments';
|
684 |
} elseif ( count( $tables ) <= 1 ) {
|
685 |
$group = 'singletables'; // Request with single table affected.
|
@@ -700,7 +747,8 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
700 |
* @accress private
|
701 |
*
|
702 |
* @param array $tables Tables.
|
703 |
-
*
|
|
|
704 |
*/
|
705 |
private function contains_only_tables( $tables, $allowed ) {
|
706 |
if ( empty( $tables ) ) {
|
@@ -708,7 +756,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
708 |
}
|
709 |
|
710 |
foreach ( $tables as $t ) {
|
711 |
-
if ( !isset( $allowed[ $t ] ) ) {
|
712 |
return false;
|
713 |
}
|
714 |
}
|
@@ -722,6 +770,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
722 |
* @access private
|
723 |
*
|
724 |
* @param string $group Group.
|
|
|
725 |
* @param array $extras Extra arguments.
|
726 |
*/
|
727 |
private function _get_flush_groups( $group, $extras = array() ) {
|
@@ -770,7 +819,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
770 |
}
|
771 |
|
772 |
$request_wide_string = $this->cache_reject_request_wide ?
|
773 |
-
( function_exists( '__' ) ? __( 'Request-wide', 'w3-total-cache' )
|
774 |
|
775 |
return $request_wide_string . $this->_get_reject_reason_message( $this->cache_reject_reason );
|
776 |
}
|
@@ -779,6 +828,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
779 |
* Get reject reason message.
|
780 |
*
|
781 |
* @param string $key Key.
|
|
|
782 |
* @return string|void
|
783 |
*/
|
784 |
private function _get_reject_reason_message( $key ) {
|
@@ -820,6 +870,7 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
820 |
* Footer comment.
|
821 |
*
|
822 |
* @param array $strings Strings.
|
|
|
823 |
* @return array
|
824 |
*/
|
825 |
public function w3tc_footer_comment( $strings ) {
|
@@ -847,10 +898,10 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
847 |
|
848 |
if ( $this->debug ) {
|
849 |
$strings[] = '';
|
850 |
-
$strings[] = 'Db cache debug info:';
|
851 |
-
$strings[] = sprintf( '%1$s%2$d', str_pad( 'Total queries: ', 20 ), $this->query_total );
|
852 |
-
$strings[] = sprintf( '%1$s%2$d', str_pad( 'Cached queries: ', 20 ), $this->query_hits );
|
853 |
-
$strings[] = sprintf( '%1$s%2$.4f', str_pad( 'Total query time: ', 20 ), $this->time_total );
|
854 |
}
|
855 |
|
856 |
if ( $this->log_filehandle ) {
|
@@ -864,13 +915,14 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
864 |
* Usage statistics of request.
|
865 |
*
|
866 |
* @param object $storage Storage object.
|
|
|
867 |
* @return void
|
868 |
*/
|
869 |
public function w3tc_usage_statistics_of_request( $storage ) {
|
870 |
$storage->counter_add( 'dbcache_calls_total', $this->query_total );
|
871 |
$storage->counter_add( 'dbcache_calls_hits', $this->query_hits );
|
872 |
$storage->counter_add( 'dbcache_flushes', $this->cache_flushes );
|
873 |
-
$time_ms = (int)( $this->time_total * 1000 );
|
874 |
$storage->counter_add( 'dbcache_time_ms', $time_ms );
|
875 |
}
|
876 |
|
@@ -880,11 +932,12 @@ class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
|
880 |
* @access private
|
881 |
*
|
882 |
* @param string $line Line to add.
|
|
|
883 |
* @return void
|
884 |
*/
|
885 |
private function log_query( $line ) {
|
886 |
if ( ! $this->log_filehandle ) {
|
887 |
-
$filename
|
888 |
$this->log_filehandle = fopen( $filename, 'a' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen
|
889 |
}
|
890 |
|
3 |
* File: DbCache_WpdbInjection_QueryCaching.php
|
4 |
*
|
5 |
* @package W3TC
|
|
|
|
|
6 |
*/
|
7 |
|
8 |
namespace W3TC;
|
9 |
|
10 |
/**
|
11 |
* Class: DbCache_WpdbInjection_QueryCaching
|
12 |
+
*
|
13 |
+
* phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
|
14 |
+
* phpcs:disable PSR2.Methods.MethodDeclaration.Underscore
|
15 |
*/
|
16 |
class DbCache_WpdbInjection_QueryCaching extends DbCache_WpdbInjection {
|
17 |
/**
|
44 |
|
45 |
/**
|
46 |
* Config.
|
47 |
+
*
|
48 |
+
* @var Config
|
49 |
*/
|
50 |
public $_config = null;
|
51 |
|
65 |
|
66 |
/**
|
67 |
* Request-global cache reject reason.
|
|
|
68 |
*
|
69 |
* @var string
|
70 |
*/
|
72 |
|
73 |
/**
|
74 |
* Request-global check reject scope.
|
|
|
75 |
*
|
76 |
* @var bool
|
77 |
*/
|
78 |
private $cache_reject_request_wide = false;
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Debug flag.
|
82 |
+
*
|
83 |
+
* @var bool
|
84 |
+
*/
|
85 |
private $debug = false;
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Reject log flag.
|
89 |
+
*
|
90 |
+
* @var bool
|
91 |
+
*/
|
92 |
private $reject_logged = false;
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Log filehandle flag.
|
96 |
+
*
|
97 |
+
* @var bool
|
98 |
+
*/
|
99 |
private $log_filehandle = false;
|
100 |
|
101 |
+
/**
|
102 |
+
* Reject constants flag.
|
103 |
+
*
|
104 |
+
* @var bool
|
105 |
+
*/
|
106 |
+
private $reject_constants = false;
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Use filters flag.
|
110 |
+
*
|
111 |
+
* @var bool
|
112 |
+
*/
|
113 |
+
private $use_filters = false;
|
114 |
+
|
115 |
/**
|
116 |
* Result of check if caching is possible at the level of current http request.
|
|
|
117 |
*
|
118 |
* @var bool
|
119 |
*/
|
155 |
$caching = $this->_can_cache( $query, $reject_reason );
|
156 |
if ( preg_match( '~^\s*start transaction\b~is', $query ) ) {
|
157 |
$this->cache_reject_reason = 'transaction';
|
158 |
+
$reject_reason = $this->cache_reject_reason;
|
159 |
+
$caching = false;
|
160 |
}
|
161 |
|
162 |
if ( preg_match( '~^\s*insert\b|^\s*delete\b|^\s*update\b|^\s*replace\b|^\s*commit\b|^\s*truncate\b|^\s*drop\b|^\s*create\b~is', $query ) ) {
|
163 |
$this->cache_reject_reason = 'modification query';
|
164 |
+
$reject_reason = $this->cache_reject_reason;
|
165 |
+
$caching = false;
|
166 |
+
$flush_after_query = true;
|
167 |
}
|
168 |
|
169 |
if ( $this->use_filters && function_exists( 'apply_filters' ) ) {
|
249 |
gmdate( 'r' ),
|
250 |
strtr(
|
251 |
isset( $_SERVER['REQUEST_URI'] ) ?
|
252 |
+
filter_var( stripslashes( $_SERVER['REQUEST_URI'] ), FILTER_SANITIZE_URL ) : '', // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
253 |
"<>\r\n",
|
254 |
'.. '
|
255 |
),
|
256 |
+
strtr( $query, "<>\r\n", '.. ' ), // query.
|
257 |
+
(int) ( $time_total * 1000000 ), // time_total in seconds.
|
258 |
+
$reject_reason, // reason.
|
259 |
+
$is_cache_hit, // cached.
|
260 |
+
( $data ? strlen( serialize( $data ) ) : 0 ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize -- data size
|
261 |
+
strtr( $group, "<>\r\n", '.. ' ), // group.
|
262 |
)
|
263 |
);
|
264 |
}
|
300 |
* @param string $table Table.
|
301 |
* @param array $data Data.
|
302 |
* @param array|string $format Format.
|
303 |
+
*
|
304 |
* @return int|false
|
305 |
*/
|
306 |
public function insert( $table, $data, $format = null ) {
|
313 |
* @param string $table Table.
|
314 |
* @param array $data Data.
|
315 |
* @param array|string $format Format.
|
316 |
+
*
|
317 |
* @return int|false
|
318 |
*/
|
319 |
public function replace( $table, $data, $format = null ) {
|
334 |
* @param array $where Where.
|
335 |
* @param array|string $format Format.
|
336 |
* @param array|string $where_format Format where.
|
337 |
+
*
|
338 |
* @return int|false
|
339 |
*/
|
340 |
public function update( $table, $data, $where, $format = null, $where_format = null ) {
|
349 |
* @param string $table Table.
|
350 |
* @param array $where Where.
|
351 |
* @param array|string $where_format Format where.
|
352 |
+
*
|
353 |
+
* @return int|false
|
354 |
*/
|
355 |
public function delete( $table, $where, $where_format = null ) {
|
356 |
$group = $this->_get_group( $table );
|
362 |
* Flushes cache.
|
363 |
*
|
364 |
* @param array $extras Extra arguments.
|
365 |
+
*
|
366 |
* @return bool
|
367 |
*/
|
368 |
public function flush_cache( $extras = array() ) {
|
376 |
*
|
377 |
* @param string $group Group.
|
378 |
* @param array $extras Extra arguments.
|
379 |
+
*
|
380 |
* @return bool
|
381 |
*/
|
382 |
private function _flush_cache_for_sql_group( $group, $extras = array() ) {
|
386 |
$filename = Util_Debug::log(
|
387 |
'dbcache',
|
388 |
'flushing based on sqlquery group ' . $group .
|
389 |
+
' with extras ' . wp_json_encode( $extras )
|
390 |
);
|
391 |
}
|
392 |
if ( $this->_config->get_boolean( 'dbcache.debug_purge' ) ) {
|
434 |
'aws_autodiscovery' => $this->_config->get_boolean( 'dbcache.memcached.aws_autodiscovery' ),
|
435 |
'username' => $this->_config->get_string( 'dbcache.memcached.username' ),
|
436 |
'password' => $this->_config->get_string( 'dbcache.memcached.password' ),
|
437 |
+
'binary_protocol' => $this->_config->get_boolean( 'dbcache.memcached.binary_protocol' ),
|
438 |
);
|
439 |
break;
|
440 |
|
447 |
'retry_interval' => $this->_config->get_integer( 'dbcache.redis.retry_interval' ),
|
448 |
'read_timeout' => $this->_config->get_integer( 'dbcache.redis.read_timeout' ),
|
449 |
'dbid' => $this->_config->get_integer( 'dbcache.redis.dbid' ),
|
450 |
+
'password' => $this->_config->get_string( 'dbcache.redis.password' ),
|
451 |
);
|
452 |
break;
|
453 |
|
456 |
'use_wp_hash' => true,
|
457 |
'section' => 'db',
|
458 |
'locking' => $this->_config->get_boolean( 'dbcache.file.locking' ),
|
459 |
+
'flush_timelimit' => $this->_config->get_integer( 'timelimit.cache_flush' ),
|
460 |
);
|
461 |
break;
|
462 |
|
478 |
*
|
479 |
* @param string $sql SQL query.
|
480 |
* @param string $cache_reject_reason Cache reject reason.
|
481 |
+
*
|
482 |
* @return boolean
|
483 |
*/
|
484 |
public function _can_cache( $sql, &$cache_reject_reason ) {
|
509 |
foreach ( $this->reject_constants as $name ) {
|
510 |
if ( defined( $name ) && constant( $name ) ) {
|
511 |
$this->cache_reject_reason = $name . ' constant defined';
|
512 |
+
$cache_reject_reason = $this->cache_reject_reason;
|
513 |
|
514 |
return false;
|
515 |
}
|
554 |
*/
|
555 |
if ( $this->reject_logged && ! $this->_check_logged_in() ) {
|
556 |
$this->cache_reject_reason = 'user.logged_in';
|
557 |
+
$cache_reject_reason = $this->cache_reject_reason;
|
558 |
|
559 |
return false;
|
560 |
}
|
600 |
* Check SQL
|
601 |
*
|
602 |
* @param string $sql SQL query.
|
603 |
+
*
|
604 |
* @return bool
|
605 |
*/
|
606 |
public function _check_sql( $sql ) {
|
636 |
);
|
637 |
|
638 |
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ?
|
639 |
+
filter_var( stripslashes( $_SERVER['REQUEST_URI'] ), FILTER_SANITIZE_URL ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
640 |
|
641 |
foreach ( $auto_reject_uri as $uri ) {
|
642 |
if ( strstr( $request_uri, $uri ) !== false ) {
|
704 |
* @access private
|
705 |
*
|
706 |
* @param string $sql SQL query.
|
707 |
+
*
|
708 |
* @return string
|
709 |
*/
|
710 |
private function _get_group( $sql ) {
|
719 |
|
720 |
if ( $this->contains_only_tables( $tables, array( 'options' => '*' ) ) ) {
|
721 |
$group = 'options';
|
722 |
+
} elseif (
|
723 |
+
$this->contains_only_tables(
|
724 |
+
$tables,
|
725 |
+
array(
|
726 |
+
'comments' => '*',
|
727 |
+
'commentsmeta' => '*',
|
728 |
+
)
|
729 |
+
) ) {
|
730 |
$group = 'comments';
|
731 |
} elseif ( count( $tables ) <= 1 ) {
|
732 |
$group = 'singletables'; // Request with single table affected.
|
747 |
* @accress private
|
748 |
*
|
749 |
* @param array $tables Tables.
|
750 |
+
*
|
751 |
+
* @param array $allowed Allowed.
|
752 |
*/
|
753 |
private function contains_only_tables( $tables, $allowed ) {
|
754 |
if ( empty( $tables ) ) {
|
756 |
}
|
757 |
|
758 |
foreach ( $tables as $t ) {
|
759 |
+
if ( ! isset( $allowed[ $t ] ) ) {
|
760 |
return false;
|
761 |
}
|
762 |
}
|
770 |
* @access private
|
771 |
*
|
772 |
* @param string $group Group.
|
773 |
+
*
|
774 |
* @param array $extras Extra arguments.
|
775 |
*/
|
776 |
private function _get_flush_groups( $group, $extras = array() ) {
|
819 |
}
|
820 |
|
821 |
$request_wide_string = $this->cache_reject_request_wide ?
|
822 |
+
( function_exists( '__' ) ? __( 'Request-wide ', 'w3-total-cache' ) : 'Request ' ) : '';
|
823 |
|
824 |
return $request_wide_string . $this->_get_reject_reason_message( $this->cache_reject_reason );
|
825 |
}
|
828 |
* Get reject reason message.
|
829 |
*
|
830 |
* @param string $key Key.
|
831 |
+
*
|
832 |
* @return string|void
|
833 |
*/
|
834 |
private function _get_reject_reason_message( $key ) {
|
870 |
* Footer comment.
|
871 |
*
|
872 |
* @param array $strings Strings.
|
873 |
+
*
|
874 |
* @return array
|
875 |
*/
|
876 |
public function w3tc_footer_comment( $strings ) {
|
898 |
|
899 |
if ( $this->debug ) {
|
900 |
$strings[] = '';
|
901 |
+
$strings[] = __( 'Db cache debug info:', 'w3-total-cache' );
|
902 |
+
$strings[] = sprintf( '%1$s%2$d', str_pad( __( 'Total queries: ', 'w3-total-cache' ), 20 ), $this->query_total );
|
903 |
+
$strings[] = sprintf( '%1$s%2$d', str_pad( __( 'Cached queries: ', 'w3-total-cache' ), 20 ), $this->query_hits );
|
904 |
+
$strings[] = sprintf( '%1$s%2$.4f', str_pad( __( 'Total query time: ', 'w3-total-cache' ), 20 ), $this->time_total );
|
905 |
}
|
906 |
|
907 |
if ( $this->log_filehandle ) {
|
915 |
* Usage statistics of request.
|
916 |
*
|
917 |
* @param object $storage Storage object.
|
918 |
+
*
|
919 |
* @return void
|
920 |
*/
|
921 |
public function w3tc_usage_statistics_of_request( $storage ) {
|
922 |
$storage->counter_add( 'dbcache_calls_total', $this->query_total );
|
923 |
$storage->counter_add( 'dbcache_calls_hits', $this->query_hits );
|
924 |
$storage->counter_add( 'dbcache_flushes', $this->cache_flushes );
|
925 |
+
$time_ms = (int) ( $this->time_total * 1000 );
|
926 |
$storage->counter_add( 'dbcache_time_ms', $time_ms );
|
927 |
}
|
928 |
|
932 |
* @access private
|
933 |
*
|
934 |
* @param string $line Line to add.
|
935 |
+
*
|
936 |
* @return void
|
937 |
*/
|
938 |
private function log_query( $line ) {
|
939 |
if ( ! $this->log_filehandle ) {
|
940 |
+
$filename = Util_Debug::log_filename( 'dbcache-queries' );
|
941 |
$this->log_filehandle = fopen( $filename, 'a' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen
|
942 |
}
|
943 |
|
Generic_Plugin_Admin.php
CHANGED
@@ -1,8 +1,17 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
/**
|
5 |
-
*
|
|
|
|
|
|
|
6 |
*/
|
7 |
class Generic_Plugin_Admin {
|
8 |
/**
|
@@ -14,97 +23,64 @@ class Generic_Plugin_Admin {
|
|
14 |
|
15 |
/**
|
16 |
* Config
|
|
|
|
|
17 |
*/
|
18 |
private $_config = null;
|
19 |
|
|
|
|
|
|
|
|
|
|
|
20 |
private $is_w3tc_page;
|
21 |
-
// filled with message data (see Util_Admin::redirect*)
|
22 |
-
// if w3tc_message is passed
|
23 |
-
private $w3tc_message = null;
|
24 |
-
|
25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
|
|
|
|
|
|
|
28 |
$this->_config = Dispatcher::config();
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
* Runs plugin
|
33 |
*/
|
34 |
-
function run() {
|
35 |
$this->is_w3tc_page = Util_Admin::is_w3tc_admin_page();
|
36 |
|
37 |
-
add_action( 'admin_init', array(
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
add_action( '
|
45 |
-
|
46 |
-
|
47 |
-
add_action( '
|
48 |
-
'\W3TC\Generic_WidgetBoldGrid',
|
49 |
-
'admin_init_w3tc_dashboard' ) );
|
50 |
-
|
51 |
-
add_action( 'admin_enqueue_scripts', array(
|
52 |
-
$this,
|
53 |
-
'admin_enqueue_scripts'
|
54 |
-
) );
|
55 |
-
add_action( 'admin_print_styles-toplevel_page_w3tc_dashboard', array(
|
56 |
-
'\W3TC\Generic_Page_Dashboard',
|
57 |
-
'admin_print_styles_w3tc_dashboard'
|
58 |
-
) );
|
59 |
-
add_action( 'wp_ajax_w3tc_ajax', array(
|
60 |
-
$this,
|
61 |
-
'wp_ajax_w3tc_ajax'
|
62 |
-
) );
|
63 |
-
add_action( 'wp_ajax_w3tc_monitoring_score', array(
|
64 |
-
$this,
|
65 |
-
'wp_ajax_w3tc_monitoring_score'
|
66 |
-
) );
|
67 |
-
|
68 |
-
add_action( 'admin_head', array(
|
69 |
-
$this,
|
70 |
-
'admin_head'
|
71 |
-
) );
|
72 |
|
73 |
if ( is_network_admin() ) {
|
74 |
-
add_action( 'network_admin_menu', array(
|
75 |
-
|
76 |
-
'network_admin_menu'
|
77 |
-
) );
|
78 |
-
add_filter( 'network_admin_plugin_action_links_' . W3TC_FILE, array(
|
79 |
-
$this,
|
80 |
-
'plugin_action_links'
|
81 |
-
) );
|
82 |
} else {
|
83 |
-
add_action( 'admin_menu', array(
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
) );
|
91 |
-
}
|
92 |
-
|
93 |
-
add_filter( 'favorite_actions', array(
|
94 |
-
$this,
|
95 |
-
'favorite_actions'
|
96 |
-
) );
|
97 |
-
|
98 |
-
add_action( 'in_plugin_update_message-' . W3TC_FILE, array(
|
99 |
-
$this,
|
100 |
-
'in_plugin_update_message'
|
101 |
-
) );
|
102 |
|
103 |
if ( $this->_config->get_boolean( 'pgcache.enabled' ) || $this->_config->get_boolean( 'minify.enabled' ) ) {
|
104 |
-
add_filter( 'pre_update_option_active_plugins', array(
|
105 |
-
$this,
|
106 |
-
'pre_update_option_active_plugins'
|
107 |
-
) );
|
108 |
}
|
109 |
|
110 |
$config_labels = new Generic_ConfigLabels();
|
@@ -114,27 +90,21 @@ class Generic_Plugin_Admin {
|
|
114 |
add_filter( 'w3tc_notes', array( $admin_notes, 'w3tc_notes' ) );
|
115 |
add_filter( 'w3tc_errors', array( $admin_notes, 'w3tc_errors' ), 1000 );
|
116 |
|
117 |
-
add_action( 'w3tc_ajax_faq', array(
|
118 |
-
$this,
|
119 |
-
'w3tc_ajax_faq'
|
120 |
-
) );
|
121 |
|
122 |
-
//
|
123 |
$message_id = Util_Request::get_string( 'w3tc_message' );
|
124 |
if ( $message_id ) {
|
125 |
$v = get_transient( 'w3tc_message' );
|
126 |
|
127 |
-
if ( isset( $v[$message_id] ) ) {
|
128 |
-
$this->w3tc_message = $v[$message_id];
|
129 |
delete_transient( 'w3tc_message' );
|
130 |
}
|
131 |
}
|
132 |
|
133 |
-
//
|
134 |
-
add_action( 'admin_print_scripts-performance_page_w3tc_support', array(
|
135 |
-
'\W3TC\Support_Page',
|
136 |
-
'admin_print_scripts_w3tc_support'
|
137 |
-
) );
|
138 |
}
|
139 |
|
140 |
/**
|
@@ -142,14 +112,14 @@ class Generic_Plugin_Admin {
|
|
142 |
*
|
143 |
* @return void
|
144 |
*/
|
145 |
-
function load() {
|
146 |
$this->add_help_tabs();
|
147 |
$this->_page = Util_Admin::get_current_page();
|
148 |
|
149 |
-
//
|
150 |
$action = false;
|
151 |
-
foreach ( $_REQUEST as $key => $value ) {
|
152 |
-
if ( substr( $key, 0, 5 )
|
153 |
$action = $key;
|
154 |
break;
|
155 |
}
|
@@ -158,31 +128,39 @@ class Generic_Plugin_Admin {
|
|
158 |
$executor = new Root_AdminActions();
|
159 |
|
160 |
if ( $action && $executor->exists( $action ) ) {
|
161 |
-
if ( !wp_verify_nonce( Util_Request::get_string( '_wpnonce' ), 'w3tc' ) )
|
162 |
wp_nonce_ays( 'w3tc' );
|
|
|
163 |
|
164 |
try {
|
165 |
$executor->execute( $action );
|
166 |
} catch ( \Exception $e ) {
|
167 |
$key = 'admin_action_failed_' . $action;
|
168 |
-
Util_Admin::redirect_with_custom_messages( array(),
|
169 |
-
array( $key => $e->getMessage() ) );
|
170 |
}
|
171 |
|
172 |
exit();
|
173 |
}
|
174 |
}
|
175 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
public function wp_ajax_w3tc_ajax() {
|
177 |
-
if ( !wp_verify_nonce( Util_Request::get_string( '_wpnonce' ), 'w3tc' ) )
|
178 |
wp_nonce_ays( 'w3tc' );
|
|
|
179 |
|
180 |
try {
|
181 |
$base_capability = apply_filters( 'w3tc_ajax_base_capability_', 'manage_options' );
|
182 |
-
$capability
|
183 |
-
|
184 |
-
if ( !empty( $capability ) && !current_user_can( $capability ) )
|
185 |
throw new \Exception( 'no permissions' );
|
|
|
186 |
|
187 |
do_action( 'w3tc_ajax' );
|
188 |
do_action( 'w3tc_ajax_' . Util_Request::get_string( 'w3tc_action' ) );
|
@@ -193,16 +171,24 @@ class Generic_Plugin_Admin {
|
|
193 |
exit();
|
194 |
}
|
195 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
public function wp_ajax_w3tc_monitoring_score() {
|
197 |
-
if (
|
198 |
exit();
|
|
|
199 |
|
200 |
$score = '';
|
201 |
|
202 |
$modules = Dispatcher::component( 'ModuleStatus' );
|
203 |
-
$score
|
204 |
|
205 |
-
header(
|
206 |
echo 'document.getElementById("w3tc_monitoring_score") && ( document.getElementById("w3tc_monitoring_score").innerHTML = "' .
|
207 |
esc_html( strtr( $score, '"', '.' ) ) . '" );';
|
208 |
|
@@ -214,9 +200,9 @@ class Generic_Plugin_Admin {
|
|
214 |
*
|
215 |
* @return void
|
216 |
*/
|
217 |
-
function admin_init() {
|
218 |
-
//
|
219 |
-
if ( Util_Request::get_string( 'action' )
|
220 |
Util_Activation::deactivate_plugin();
|
221 |
}
|
222 |
|
@@ -234,11 +220,11 @@ class Generic_Plugin_Admin {
|
|
234 |
wp_register_style( 'w3tc-lightbox', plugins_url( 'pub/css/lightbox.css', W3TC_FILE ), array(), W3TC_VERSION );
|
235 |
wp_register_style( 'w3tc-widget', plugins_url( 'pub/css/widget.css', W3TC_FILE ), array(), W3TC_VERSION );
|
236 |
|
237 |
-
wp_register_script( 'w3tc-metadata', plugins_url( 'pub/js/metadata.js', W3TC_FILE ), array(), W3TC_VERSION );
|
238 |
-
wp_register_script( 'w3tc-options', plugins_url( 'pub/js/options.js', W3TC_FILE ), array(), W3TC_VERSION );
|
239 |
-
wp_register_script( 'w3tc-lightbox', plugins_url( 'pub/js/lightbox.js', W3TC_FILE ), array(), W3TC_VERSION );
|
240 |
-
wp_register_script( 'w3tc-widget', plugins_url( 'pub/js/widget.js', W3TC_FILE ), array(), W3TC_VERSION );
|
241 |
-
wp_register_script( 'w3tc-jquery-masonry', plugins_url( 'pub/js/jquery.masonry.min.js', W3TC_FILE ), array( 'jquery' ), W3TC_VERSION );
|
242 |
|
243 |
// New feature count for the Feature Showcase.
|
244 |
wp_register_script( 'w3tc-feature-counter', plugins_url( 'pub/js/feature-counter.js', W3TC_FILE ), array(), W3TC_VERSION, true );
|
@@ -254,21 +240,26 @@ class Generic_Plugin_Admin {
|
|
254 |
wp_enqueue_script( 'w3tc-feature-counter' );
|
255 |
|
256 |
// Messages.
|
257 |
-
if ( !is_null( $this->w3tc_message ) &&
|
258 |
-
|
259 |
-
is_array( $this->w3tc_message['actions'] ) ) {
|
260 |
-
foreach ( $this->w3tc_message['actions'] as $action )
|
261 |
do_action( 'w3tc_message_action_' . $action );
|
|
|
262 |
}
|
263 |
-
|
|
|
264 |
$w3tc_message_action_val = Util_Request::get_string( 'w3tc_message_action' );
|
265 |
if ( ! empty( $w3tc_message_action_val ) ) {
|
266 |
do_action( 'w3tc_message_action_' . $w3tc_message_action_val );
|
267 |
}
|
268 |
}
|
269 |
|
270 |
-
|
271 |
-
|
|
|
|
|
|
|
|
|
|
|
272 |
$page = Util_Request::get_string( 'page', null );
|
273 |
|
274 |
if ( ( ! is_multisite() || is_super_admin() ) && false !== strpos( $page, 'w3tc' ) && 'w3tc_setup_guide' !== $page && ! get_site_option( 'w3tc_setupguide_completed' ) ) {
|
@@ -276,121 +267,125 @@ class Generic_Plugin_Admin {
|
|
276 |
$state_master = Dispatcher::config_state_master();
|
277 |
|
278 |
if ( ! $config->get_boolean( 'pgcache.enabled' ) && $state_master->get_integer( 'common.install' ) > strtotime( 'NOW - 1 WEEK' ) ) {
|
279 |
-
|
280 |
}
|
281 |
}
|
282 |
|
283 |
if ( 'w3tc_dashboard' === $page ) {
|
284 |
-
?>
|
285 |
<script type="text/javascript">
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
</script>
|
292 |
<?php
|
293 |
}
|
294 |
|
295 |
if ( $this->_config->get_boolean( 'common.track_usage' ) && $this->is_w3tc_page ) {
|
|
|
296 |
$current_user = wp_get_current_user();
|
297 |
-
$page
|
298 |
-
if (
|
299 |
$page = 'extensions/' . Util_Request::get_string( 'extension' );
|
|
|
300 |
|
301 |
-
if ( defined( 'W3TC_DEBUG' ) && W3TC_DEBUG )
|
302 |
$profile = 'UA-2264433-7';
|
303 |
-
else
|
304 |
$profile = 'UA-2264433-8';
|
|
|
305 |
|
306 |
$state = Dispatcher::config_state();
|
307 |
-
?>
|
308 |
-
<script type="text/javascript">
|
309 |
-
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
310 |
-
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
311 |
-
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
312 |
-
})(window,document,'script','https://api.w3-edge.com/v1/analytics','w3tc_ga');
|
313 |
-
|
314 |
-
if (window.w3tc_ga) {
|
315 |
-
w3tc_ga('create', '<?php echo esc_html( $profile ); ?>', 'auto');
|
316 |
-
w3tc_ga('set', {
|
317 |
-
'dimension1': 'w3-total-cache',
|
318 |
-
'dimension2': '<?php echo esc_html( W3TC_VERSION ); ?>',
|
319 |
-
'dimension3': '<?php global $wp_version; echo esc_html( $wp_version ); ?>',
|
320 |
-
'dimension4': 'php<?php echo esc_html( phpversion() ); ?>',
|
321 |
-
'dimension5': '<?php echo esc_attr( isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '' ); ?>',
|
322 |
-
'dimension6': 'mysql<?php global $wpdb; echo esc_attr( $wpdb->db_version() ); ?>',
|
323 |
-
'dimension7': '<?php echo esc_url( Util_Environment::home_url_host() ); ?>',
|
324 |
-
'dimension9': '<?php echo esc_attr( $state->get_string( 'common.install_version' ) ); ?>',
|
325 |
-
'dimension10': '<?php echo esc_attr( Util_Environment::w3tc_edition( $this->_config ) ); ?>',
|
326 |
-
'dimension11': '<?php echo esc_attr( Util_Widget::list_widgets() ); ?>',
|
327 |
-
|
328 |
-
'page': '<?php echo esc_attr( $page ); ?>'
|
329 |
-
});
|
330 |
-
|
331 |
-
w3tc_ga('send', 'pageview');
|
332 |
-
}
|
333 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
334 |
</script>
|
335 |
<?php
|
336 |
}
|
337 |
|
338 |
-
?>
|
339 |
<style type="text/css" media="screen">
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
</style>
|
346 |
<script>
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
</script>
|
353 |
<?php
|
354 |
}
|
355 |
|
356 |
-
|
357 |
-
|
|
|
|
|
358 |
$this->_admin_menu( 'manage_network_options' );
|
359 |
}
|
360 |
|
361 |
-
|
|
|
|
|
|
|
362 |
$this->_admin_menu( 'manage_options' );
|
363 |
}
|
364 |
|
365 |
/**
|
366 |
* Admin menu
|
367 |
*
|
|
|
|
|
368 |
* @return void
|
369 |
*/
|
370 |
private function _admin_menu( $base_capability ) {
|
371 |
-
$base_capability = apply_filters( 'w3tc_capability_menu',
|
372 |
-
$base_capability );
|
373 |
|
374 |
if ( current_user_can( $base_capability ) ) {
|
375 |
-
$menus
|
376 |
$submenu_pages = $menus->generate( $base_capability );
|
377 |
|
378 |
/**
|
379 |
* Only admin can modify W3TC settings
|
380 |
*/
|
381 |
foreach ( $submenu_pages as $submenu_page ) {
|
382 |
-
add_action( 'load-' . $submenu_page,
|
383 |
-
|
384 |
-
|
385 |
-
add_action( 'admin_print_styles-' . $submenu_page,
|
386 |
-
array( $this, 'admin_print_styles' ) );
|
387 |
-
|
388 |
-
add_action( 'admin_print_scripts-' . $submenu_page,
|
389 |
-
array( $this, 'admin_print_scripts' ) );
|
390 |
}
|
391 |
|
392 |
global $pagenow;
|
393 |
-
if (
|
394 |
add_action( 'admin_print_scripts', array( $this, 'load_plugins_page_js' ) );
|
395 |
add_action( 'admin_print_styles', array( $this, 'print_plugins_page_css' ) );
|
396 |
}
|
@@ -400,17 +395,10 @@ class Generic_Plugin_Admin {
|
|
400 |
! empty( Util_Request::get_string( 'w3tc_note' ) ) ||
|
401 |
! empty( Util_Request::get_string( 'w3tc_error' ) ) ||
|
402 |
! empty( Util_Request::get_string( 'w3tc_message' ) ) ) {
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
add_action( '
|
407 |
-
$this,
|
408 |
-
'admin_notices'
|
409 |
-
) );
|
410 |
-
add_action( 'network_admin_notices', array(
|
411 |
-
$this,
|
412 |
-
'admin_notices'
|
413 |
-
) );
|
414 |
}
|
415 |
}
|
416 |
}
|
@@ -420,7 +408,7 @@ class Generic_Plugin_Admin {
|
|
420 |
*
|
421 |
* @return void
|
422 |
*/
|
423 |
-
function admin_print_styles() {
|
424 |
wp_enqueue_style( 'w3tc-options' );
|
425 |
wp_enqueue_style( 'w3tc-lightbox' );
|
426 |
}
|
@@ -428,7 +416,7 @@ class Generic_Plugin_Admin {
|
|
428 |
/**
|
429 |
* Print scripts.
|
430 |
*/
|
431 |
-
function admin_print_scripts() {
|
432 |
wp_enqueue_script( 'w3tc-metadata' );
|
433 |
wp_enqueue_script( 'w3tc-options' );
|
434 |
wp_enqueue_script( 'w3tc-lightbox' );
|
@@ -446,18 +434,23 @@ class Generic_Plugin_Admin {
|
|
446 |
array(
|
447 |
'cdnEnabled' => $this->_config->get_boolean( 'cdn.enabled' ),
|
448 |
'cdnEngine' => $this->_config->get_string( 'cdn.engine' ),
|
449 |
-
'cdnFlushManually' => $this->_config->get_boolean(
|
|
|
|
|
|
|
450 |
'cfWarning' => wp_kses(
|
451 |
sprintf(
|
452 |
-
// translators: 1: HTML
|
|
|
453 |
__(
|
454 |
-
'Please see %
|
455 |
'w3-total-cache'
|
456 |
),
|
457 |
-
'<br />',
|
458 |
'<a target="_blank" href="https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html#PayingForInvalidation">',
|
459 |
-
'</a
|
460 |
-
'<
|
|
|
|
|
461 |
),
|
462 |
array(
|
463 |
'a' => array(
|
@@ -472,36 +465,46 @@ class Generic_Plugin_Admin {
|
|
472 |
}
|
473 |
|
474 |
switch ( $this->_page ) {
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
|
|
490 |
}
|
491 |
-
|
|
|
492 |
wp_enqueue_script( 'jquery-ui-dialog' );
|
493 |
-
|
|
|
|
|
494 |
wp_enqueue_script( 'w3tc-jquery-masonry' );
|
|
|
495 |
}
|
496 |
|
497 |
-
|
498 |
-
|
|
|
|
|
499 |
wp_enqueue_script( 'w3tc-options' );
|
500 |
}
|
501 |
|
502 |
-
|
503 |
-
|
504 |
-
|
|
|
|
|
|
|
505 |
.w3tc-missing-files ul {
|
506 |
margin-left: 20px;
|
507 |
list-style-type: disc;
|
@@ -524,37 +527,39 @@ class Generic_Plugin_Admin {
|
|
524 |
width: 170px;
|
525 |
display: inline-block;
|
526 |
}
|
527 |
-
|
|
|
528 |
}
|
529 |
|
530 |
/**
|
531 |
-
* Contextual help list filter
|
532 |
-
*
|
533 |
-
* @param string $list
|
534 |
-
* @return string
|
535 |
*/
|
536 |
-
function add_help_tabs() {
|
537 |
-
$screen
|
538 |
$sections = Generic_Faq::sections();
|
539 |
-
$n
|
540 |
|
541 |
foreach ( $sections as $section => $data ) {
|
542 |
-
$content = '<div class="w3tchelp_content" data-section="' .
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
'id'
|
547 |
-
'title'
|
548 |
-
'content' => $content
|
549 |
-
)
|
|
|
550 |
$n++;
|
551 |
}
|
552 |
}
|
553 |
|
|
|
|
|
|
|
554 |
public function w3tc_ajax_faq() {
|
555 |
$section = Util_Request::get_string( 'section' );
|
556 |
|
557 |
-
$entries
|
558 |
$response = array();
|
559 |
|
560 |
ob_start();
|
@@ -562,26 +567,21 @@ class Generic_Plugin_Admin {
|
|
562 |
$content = ob_get_contents();
|
563 |
ob_end_clean();
|
564 |
|
565 |
-
echo
|
566 |
}
|
567 |
|
568 |
-
|
569 |
-
|
570 |
/**
|
571 |
* Plugin action links filter
|
572 |
*
|
573 |
-
* @param array
|
|
|
574 |
* @return array
|
575 |
*/
|
576 |
-
function plugin_action_links( $links ) {
|
577 |
-
array_unshift( $links,
|
578 |
-
|
579 |
-
array_unshift( $links,
|
580 |
-
'<a class="edit" style="color: red" href="admin.php?page=w3tc_support">Premium Support</a>' );
|
581 |
-
|
582 |
|
583 |
-
if ( !is_writable( WP_CONTENT_DIR ) ||
|
584 |
-
!is_writable( Util_Rule::get_browsercache_rules_cache_path() ) ) {
|
585 |
$delete_link = '<a href="' .
|
586 |
wp_nonce_url( admin_url( 'plugins.php?action=w3tc_deactivate_plugin' ), 'w3tc' ) .
|
587 |
'">Uninstall</a>';
|
@@ -592,15 +592,16 @@ class Generic_Plugin_Admin {
|
|
592 |
}
|
593 |
|
594 |
/**
|
595 |
-
*
|
|
|
|
|
596 |
*
|
597 |
-
* @param array $actions
|
598 |
* @return array
|
599 |
*/
|
600 |
-
function favorite_actions( $actions ) {
|
601 |
-
$actions[wp_nonce_url( admin_url( 'admin.php?page=w3tc_dashboard&w3tc_flush_all' ), 'w3tc' )] = array(
|
602 |
__( 'Empty Caches', 'w3-total-cache' ),
|
603 |
-
apply_filters( 'w3tc_capability_favorite_action_flush_all', 'manage_options' )
|
604 |
);
|
605 |
|
606 |
return $actions;
|
@@ -609,13 +610,14 @@ class Generic_Plugin_Admin {
|
|
609 |
/**
|
610 |
* Active plugins pre update option filter
|
611 |
*
|
612 |
-
* @param string
|
|
|
613 |
* @return string
|
614 |
*/
|
615 |
-
function pre_update_option_active_plugins( $new_value ) {
|
616 |
$old_value = (array) get_option( 'active_plugins' );
|
617 |
|
618 |
-
if ( $new_value !== $old_value && in_array( W3TC_FILE, (array) $new_value ) && in_array( W3TC_FILE, (array) $old_value ) ) {
|
619 |
$state_note = Dispatcher::config_state_note();
|
620 |
$state_note->set( 'common.show_note.plugins_updated', true );
|
621 |
}
|
@@ -628,18 +630,20 @@ class Generic_Plugin_Admin {
|
|
628 |
*
|
629 |
* @return void
|
630 |
*/
|
631 |
-
function in_plugin_update_message() {
|
632 |
$response = Util_Http::get( W3TC_README_URL );
|
633 |
|
634 |
-
if ( is_wp_error( $response ) || $response['response']['code']
|
635 |
return;
|
|
|
636 |
|
637 |
$matches = null;
|
638 |
-
$regexp
|
639 |
|
640 |
$body = $response['body'];
|
641 |
-
if ( !preg_match( $regexp, $body, $matches ) )
|
642 |
return;
|
|
|
643 |
|
644 |
$changelog = (array) preg_split( '~[\r\n]+~', trim( $matches[1] ) );
|
645 |
|
@@ -648,12 +652,12 @@ class Generic_Plugin_Admin {
|
|
648 |
|
649 |
foreach ( $changelog as $index => $line ) {
|
650 |
if ( preg_match( '~^\s*\*\s*~', $line ) ) {
|
651 |
-
if (
|
652 |
echo '<ul style="list-style: disc; margin-left: 20px;margin-top:0;">';
|
653 |
$ul = true;
|
654 |
}
|
655 |
$line = preg_replace( '~^\s*\*\s*~', '', htmlspecialchars( $line ) );
|
656 |
-
echo '<li style="width: 50%; margin: 0; float: left; ' . ( $index % 2
|
657 |
} else {
|
658 |
if ( $ul ) {
|
659 |
echo '</ul><div style="clear: left;"></div>';
|
@@ -662,8 +666,9 @@ class Generic_Plugin_Admin {
|
|
662 |
}
|
663 |
}
|
664 |
|
665 |
-
if ( $ul )
|
666 |
echo '</ul><div style="clear: left;"></div>';
|
|
|
667 |
|
668 |
echo '</div>';
|
669 |
}
|
@@ -673,103 +678,183 @@ class Generic_Plugin_Admin {
|
|
673 |
*
|
674 |
* @return void
|
675 |
*/
|
676 |
-
function admin_notices() {
|
677 |
$cookie_domain = Util_Admin::get_cookie_domain();
|
678 |
|
679 |
$error_messages = array(
|
680 |
-
'fancy_permalinks_disabled_pgcache'
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
'
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
'
|
697 |
-
'
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
705 |
);
|
706 |
|
707 |
$note_messages = array(
|
708 |
-
'config_save'
|
709 |
-
'flush_all'
|
710 |
-
'flush_memcached'
|
711 |
-
'flush_opcode'
|
712 |
-
'flush_file'
|
713 |
-
'flush_pgcache'
|
714 |
-
'flush_dbcache'
|
715 |
-
'flush_objectcache'
|
716 |
-
'flush_fragmentcache'
|
717 |
-
'flush_minify'
|
718 |
-
'flush_browser_cache'
|
719 |
-
'flush_varnish'
|
720 |
-
'flush_cdn'
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
727 |
'cdn_purge_attachment' => __( 'Attachment successfully purged.', 'w3-total-cache' ),
|
728 |
-
'pgcache_purge_post'
|
729 |
-
'new_relic_save'
|
730 |
-
'add_in_removed'
|
731 |
-
'enabled_edge'
|
732 |
-
'disabled_edge'
|
733 |
-
'pull_zone'
|
734 |
);
|
735 |
|
736 |
-
$errors
|
737 |
-
$notes
|
738 |
$environment_error_present = false;
|
739 |
|
740 |
$error = Util_Request::get_string( 'w3tc_error' );
|
741 |
-
if ( isset( $error_messages[$error] ) )
|
742 |
-
$errors[$error] = $error_messages[$error];
|
|
|
743 |
|
744 |
$note = Util_Request::get_string( 'w3tc_note' );
|
745 |
-
if ( isset( $note_messages[$note] ) )
|
746 |
-
$notes[$note] = $note_messages[$note];
|
|
|
747 |
|
748 |
// print errors happened during last request execution,
|
749 |
// when we decided to redirect with error message instead of
|
750 |
-
// printing it directly (to avoid reexecution on refresh)
|
751 |
-
if ( !is_null( $this->w3tc_message ) ) {
|
752 |
$v = $this->w3tc_message;
|
753 |
if ( isset( $v['errors'] ) && is_array( $v['errors'] ) ) {
|
754 |
foreach ( $v['errors'] as $error ) {
|
755 |
-
if ( isset( $error_messages[$error] ) )
|
756 |
-
$errors[] = $error_messages[$error];
|
757 |
-
else
|
758 |
$errors[] = $error;
|
|
|
759 |
}
|
760 |
}
|
761 |
if ( isset( $v['notes'] ) && is_array( $v['notes'] ) ) {
|
762 |
foreach ( $v['notes'] as $note ) {
|
763 |
-
if ( isset( $note_messages[$note] ) )
|
764 |
-
$notes[] = $note_messages[$note];
|
765 |
-
else
|
766 |
$notes[] = $note;
|
|
|
767 |
}
|
768 |
}
|
769 |
}
|
770 |
|
771 |
/*
|
772 |
-
* Filesystem environment fix, if needed
|
773 |
*/
|
774 |
try {
|
775 |
$environment = Dispatcher::component( 'Root_Environment' );
|
@@ -783,7 +868,7 @@ class Generic_Plugin_Admin {
|
|
783 |
$n = 1;
|
784 |
|
785 |
foreach ( $r['before_errors'] as $e ) {
|
786 |
-
$errors['generic_env_' . $n] = $e;
|
787 |
$n++;
|
788 |
}
|
789 |
|
@@ -792,45 +877,37 @@ class Generic_Plugin_Admin {
|
|
792 |
'background: white; ' .
|
793 |
'margin: 10px 30px 10px 30px; ' .
|
794 |
'padding: 10px; display: none';
|
|
|
795 |
$ftp_style = 'border: 1px solid black; background: white; ' .
|
796 |
'margin: 10px 30px 10px 30px; ' .
|
797 |
'padding: 10px; display: none';
|
798 |
-
|
799 |
-
|
800 |
-
$ftp_form = str_replace( '<form ', '<form name="w3tc_ftp_form" ',
|
801 |
-
$ftp_form );
|
802 |
$ftp_form = str_replace( '<fieldset>', '', $ftp_form );
|
803 |
$ftp_form = str_replace( '</fieldset>', '', $ftp_form );
|
804 |
-
$ftp_form = str_replace( 'id="upgrade" class="button"',
|
805 |
-
'id="upgrade" class="button w3tc-button-save"', $ftp_form );
|
806 |
|
807 |
-
$error = '<strong>W3 Total Cache Error
|
808 |
-
'Files and directories could not be automatically ' .
|
809 |
-
'created to complete the installation. ' .
|
810 |
'<table>' .
|
811 |
'<tr>' .
|
812 |
-
|
813 |
-
|
814 |
-
Util_Ui::button( 'View required changes', '',
|
815 |
-
'w3tc-show-required-changes' ) .
|
816 |
-
'</td>' .
|
817 |
'</tr>' .
|
818 |
'<tr>' .
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
'</
|
825 |
-
'</
|
826 |
-
|
827 |
-
'<div class="w3tc-
|
828 |
-
$changes_style . '">' . $r['required_changes'] . '</div>' .
|
829 |
-
'<div class="w3tc-ftp-form" style="' . $ftp_style . '">' .
|
830 |
-
$ftp_form . '</div>';
|
831 |
|
832 |
$environment_error_present = true;
|
833 |
-
$errors['generic_ftp']
|
834 |
}
|
835 |
|
836 |
foreach ( $r['later_errors'] as $e ) {
|
@@ -873,7 +950,7 @@ class Generic_Plugin_Admin {
|
|
873 |
printf(
|
874 |
'<div class="error w3tc_error" id="%1$s"><p>%2$s</p></div>',
|
875 |
esc_attr( $key ),
|
876 |
-
$error // phpcs:ignore
|
877 |
);
|
878 |
}
|
879 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* File: Generic_Plugin_Admin.php
|
4 |
+
*
|
5 |
+
* @package W3TC
|
6 |
+
*/
|
7 |
+
|
8 |
namespace W3TC;
|
9 |
|
10 |
/**
|
11 |
+
* Class Generic_Plugin_Admin
|
12 |
+
*
|
13 |
+
* phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
|
14 |
+
* phpcs:disable PSR2.Methods.MethodDeclaration.Underscore
|
15 |
*/
|
16 |
class Generic_Plugin_Admin {
|
17 |
/**
|
23 |
|
24 |
/**
|
25 |
* Config
|
26 |
+
*
|
27 |
+
* @var Config
|
28 |
*/
|
29 |
private $_config = null;
|
30 |
|
31 |
+
/**
|
32 |
+
* Config
|
33 |
+
*
|
34 |
+
* @var bool
|
35 |
+
*/
|
36 |
private $is_w3tc_page;
|
|
|
|
|
|
|
|
|
37 |
|
38 |
+
/**
|
39 |
+
* Message data (see Util_Admin::redirect*).
|
40 |
+
*
|
41 |
+
* @var array
|
42 |
+
*/
|
43 |
+
private $w3tc_message = null;
|
44 |
|
45 |
+
/**
|
46 |
+
* Constructor.
|
47 |
+
*/
|
48 |
+
public function __construct() {
|
49 |
$this->_config = Dispatcher::config();
|
50 |
}
|
51 |
|
52 |
/**
|
53 |
* Runs plugin
|
54 |
*/
|
55 |
+
public function run() {
|
56 |
$this->is_w3tc_page = Util_Admin::is_w3tc_admin_page();
|
57 |
|
58 |
+
add_action( 'admin_init', array( $this, 'admin_init' ) );
|
59 |
+
add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Generic_WidgetServices', 'admin_init_w3tc_dashboard' ) );
|
60 |
+
add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Generic_WidgetCommunity', 'admin_init_w3tc_dashboard' ) );
|
61 |
+
add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Generic_WidgetBoldGrid', 'admin_init_w3tc_dashboard' ) );
|
62 |
+
|
63 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
64 |
+
add_action( 'admin_print_styles-toplevel_page_w3tc_dashboard', array( '\W3TC\Generic_Page_Dashboard', 'admin_print_styles_w3tc_dashboard' ) );
|
65 |
+
add_action( 'wp_ajax_w3tc_ajax', array( $this, 'wp_ajax_w3tc_ajax' ) );
|
66 |
+
add_action( 'wp_ajax_w3tc_monitoring_score', array( $this, 'wp_ajax_w3tc_monitoring_score' ) );
|
67 |
+
|
68 |
+
add_action( 'admin_head', array( $this, 'admin_head' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
if ( is_network_admin() ) {
|
71 |
+
add_action( 'network_admin_menu', array( $this, 'network_admin_menu' ) );
|
72 |
+
add_filter( 'network_admin_plugin_action_links_' . W3TC_FILE, array( $this, 'plugin_action_links' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
} else {
|
74 |
+
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
|
75 |
+
add_filter( 'plugin_action_links_' . W3TC_FILE, array( $this, 'plugin_action_links' ) );
|
76 |
+
}
|
77 |
+
|
78 |
+
add_filter( 'favorite_actions', array( $this, 'favorite_actions' ) );
|
79 |
+
|
80 |
+
add_action( 'in_plugin_update_message-' . W3TC_FILE, array( $this, 'in_plugin_update_message' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
|
82 |
if ( $this->_config->get_boolean( 'pgcache.enabled' ) || $this->_config->get_boolean( 'minify.enabled' ) ) {
|
83 |
+
add_filter( 'pre_update_option_active_plugins', array( $this, 'pre_update_option_active_plugins' ) );
|
|
|
|
|
|
|
84 |
}
|
85 |
|
86 |
$config_labels = new Generic_ConfigLabels();
|
90 |
add_filter( 'w3tc_notes', array( $admin_notes, 'w3tc_notes' ) );
|
91 |
add_filter( 'w3tc_errors', array( $admin_notes, 'w3tc_errors' ), 1000 );
|
92 |
|
93 |
+
add_action( 'w3tc_ajax_faq', array( $this, 'w3tc_ajax_faq' ) );
|
|
|
|
|
|
|
94 |
|
95 |
+
// Load w3tc_message.
|
96 |
$message_id = Util_Request::get_string( 'w3tc_message' );
|
97 |
if ( $message_id ) {
|
98 |
$v = get_transient( 'w3tc_message' );
|
99 |
|
100 |
+
if ( isset( $v[ $message_id ] ) ) {
|
101 |
+
$this->w3tc_message = $v[ $message_id ];
|
102 |
delete_transient( 'w3tc_message' );
|
103 |
}
|
104 |
}
|
105 |
|
106 |
+
// Should be in Support_PluginAdmin, but saving loading file by being here.
|
107 |
+
add_action( 'admin_print_scripts-performance_page_w3tc_support', array( '\W3TC\Support_Page', 'admin_print_scripts_w3tc_support' ) );
|
|
|
|
|
|
|
108 |
}
|
109 |
|
110 |
/**
|
112 |
*
|
113 |
* @return void
|
114 |
*/
|
115 |
+
public function load() {
|
116 |
$this->add_help_tabs();
|
117 |
$this->_page = Util_Admin::get_current_page();
|
118 |
|
119 |
+
// Run plugin action.
|
120 |
$action = false;
|
121 |
+
foreach ( $_REQUEST as $key => $value ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
122 |
+
if ( 'w3tc_' === substr( $key, 0, 5 ) ) {
|
123 |
$action = $key;
|
124 |
break;
|
125 |
}
|
128 |
$executor = new Root_AdminActions();
|
129 |
|
130 |
if ( $action && $executor->exists( $action ) ) {
|
131 |
+
if ( ! wp_verify_nonce( Util_Request::get_string( '_wpnonce' ), 'w3tc' ) ) {
|
132 |
wp_nonce_ays( 'w3tc' );
|
133 |
+
}
|
134 |
|
135 |
try {
|
136 |
$executor->execute( $action );
|
137 |
} catch ( \Exception $e ) {
|
138 |
$key = 'admin_action_failed_' . $action;
|
139 |
+
Util_Admin::redirect_with_custom_messages( array(), array( $key => $e->getMessage() ) );
|
|
|
140 |
}
|
141 |
|
142 |
exit();
|
143 |
}
|
144 |
}
|
145 |
|
146 |
+
/**
|
147 |
+
* Load action
|
148 |
+
*
|
149 |
+
* @throws \Exception Exception.
|
150 |
+
*
|
151 |
+
* @return void
|
152 |
+
*/
|
153 |
public function wp_ajax_w3tc_ajax() {
|
154 |
+
if ( ! wp_verify_nonce( Util_Request::get_string( '_wpnonce' ), 'w3tc' ) ) {
|
155 |
wp_nonce_ays( 'w3tc' );
|
156 |
+
}
|
157 |
|
158 |
try {
|
159 |
$base_capability = apply_filters( 'w3tc_ajax_base_capability_', 'manage_options' );
|
160 |
+
$capability = apply_filters( 'w3tc_ajax_capability_' . Util_Request::get_string( 'w3tc_action' ), $base_capability );
|
161 |
+
if ( ! empty( $capability ) && ! current_user_can( $capability ) ) {
|
|
|
162 |
throw new \Exception( 'no permissions' );
|
163 |
+
}
|
164 |
|
165 |
do_action( 'w3tc_ajax' );
|
166 |
do_action( 'w3tc_ajax_' . Util_Request::get_string( 'w3tc_action' ) );
|
171 |
exit();
|
172 |
}
|
173 |
|
174 |
+
/**
|
175 |
+
* Load action
|
176 |
+
*
|
177 |
+
* @throws Exception Exception.
|
178 |
+
*
|
179 |
+
* @return void
|
180 |
+
*/
|
181 |
public function wp_ajax_w3tc_monitoring_score() {
|
182 |
+
if ( ! $this->_config->get_boolean( 'widget.pagespeed.show_in_admin_bar' ) ) {
|
183 |
exit();
|
184 |
+
}
|
185 |
|
186 |
$score = '';
|
187 |
|
188 |
$modules = Dispatcher::component( 'ModuleStatus' );
|
189 |
+
$score = apply_filters( 'w3tc_monitoring_score', $score );
|
190 |
|
191 |
+
header( 'Content-Type: application/x-javascript; charset=UTF-8' );
|
192 |
echo 'document.getElementById("w3tc_monitoring_score") && ( document.getElementById("w3tc_monitoring_score").innerHTML = "' .
|
193 |
esc_html( strtr( $score, '"', '.' ) ) . '" );';
|
194 |
|
200 |
*
|
201 |
* @return void
|
202 |
*/
|
203 |
+
public function admin_init() {
|
204 |
+
// Special handling for deactivation link, it's plugins.php file.
|
205 |
+
if ( 'w3tc_deactivate_plugin' === Util_Request::get_string( 'action' ) ) {
|
206 |
Util_Activation::deactivate_plugin();
|
207 |
}
|
208 |
|
220 |
wp_register_style( 'w3tc-lightbox', plugins_url( 'pub/css/lightbox.css', W3TC_FILE ), array(), W3TC_VERSION );
|
221 |
wp_register_style( 'w3tc-widget', plugins_url( 'pub/css/widget.css', W3TC_FILE ), array(), W3TC_VERSION );
|
222 |
|
223 |
+
wp_register_script( 'w3tc-metadata', plugins_url( 'pub/js/metadata.js', W3TC_FILE ), array(), W3TC_VERSION, false );
|
224 |
+
wp_register_script( 'w3tc-options', plugins_url( 'pub/js/options.js', W3TC_FILE ), array(), W3TC_VERSION, false );
|
225 |
+
wp_register_script( 'w3tc-lightbox', plugins_url( 'pub/js/lightbox.js', W3TC_FILE ), array(), W3TC_VERSION, false );
|
226 |
+
wp_register_script( 'w3tc-widget', plugins_url( 'pub/js/widget.js', W3TC_FILE ), array(), W3TC_VERSION, false );
|
227 |
+
wp_register_script( 'w3tc-jquery-masonry', plugins_url( 'pub/js/jquery.masonry.min.js', W3TC_FILE ), array( 'jquery' ), W3TC_VERSION, false );
|
228 |
|
229 |
// New feature count for the Feature Showcase.
|
230 |
wp_register_script( 'w3tc-feature-counter', plugins_url( 'pub/js/feature-counter.js', W3TC_FILE ), array(), W3TC_VERSION, true );
|
240 |
wp_enqueue_script( 'w3tc-feature-counter' );
|
241 |
|
242 |
// Messages.
|
243 |
+
if ( ! is_null( $this->w3tc_message ) && isset( $this->w3tc_message['actions'] ) && is_array( $this->w3tc_message['actions'] ) ) {
|
244 |
+
foreach ( $this->w3tc_message['actions'] as $action ) {
|
|
|
|
|
245 |
do_action( 'w3tc_message_action_' . $action );
|
246 |
+
}
|
247 |
}
|
248 |
+
|
249 |
+
// For testing.
|
250 |
$w3tc_message_action_val = Util_Request::get_string( 'w3tc_message_action' );
|
251 |
if ( ! empty( $w3tc_message_action_val ) ) {
|
252 |
do_action( 'w3tc_message_action_' . $w3tc_message_action_val );
|
253 |
}
|
254 |
}
|
255 |
|
256 |
+
/**
|
257 |
+
* Define icon styles for the custom post type.
|
258 |
+
*/
|
259 |
+
public function admin_head() {
|
260 |
+
global $wp_version;
|
261 |
+
global $wpdb;
|
262 |
+
|
263 |
$page = Util_Request::get_string( 'page', null );
|
264 |
|
265 |
if ( ( ! is_multisite() || is_super_admin() ) && false !== strpos( $page, 'w3tc' ) && 'w3tc_setup_guide' !== $page && ! get_site_option( 'w3tc_setupguide_completed' ) ) {
|
267 |
$state_master = Dispatcher::config_state_master();
|
268 |
|
269 |
if ( ! $config->get_boolean( 'pgcache.enabled' ) && $state_master->get_integer( 'common.install' ) > strtotime( 'NOW - 1 WEEK' ) ) {
|
270 |
+
wp_safe_redirect( esc_url( network_admin_url( 'admin.php?page=w3tc_setup_guide' ) ) );
|
271 |
}
|
272 |
}
|
273 |
|
274 |
if ( 'w3tc_dashboard' === $page ) {
|
275 |
+
?>
|
276 |
<script type="text/javascript">
|
277 |
+
jQuery( function() {
|
278 |
+
jQuery('#normal-sortables').masonry( {
|
279 |
+
itemSelector: '.postbox'
|
280 |
+
} );
|
281 |
+
} );
|
282 |
</script>
|
283 |
<?php
|
284 |
}
|
285 |
|
286 |
if ( $this->_config->get_boolean( 'common.track_usage' ) && $this->is_w3tc_page ) {
|
287 |
+
|
288 |
$current_user = wp_get_current_user();
|
289 |
+
$page = Util_Request::get_string( 'page' );
|
290 |
+
if ( 'w3tc_extensions' === $page ) {
|
291 |
$page = 'extensions/' . Util_Request::get_string( 'extension' );
|
292 |
+
}
|
293 |
|
294 |
+
if ( defined( 'W3TC_DEBUG' ) && W3TC_DEBUG ) {
|
295 |
$profile = 'UA-2264433-7';
|
296 |
+
} else {
|
297 |
$profile = 'UA-2264433-8';
|
298 |
+
}
|
299 |
|
300 |
$state = Dispatcher::config_state();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
|
302 |
+
?>
|
303 |
+
<script type="text/javascript">
|
304 |
+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
305 |
+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
306 |
+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
307 |
+
})(window,document,'script','https://api.w3-edge.com/v1/analytics','w3tc_ga');
|
308 |
+
|
309 |
+
if (window.w3tc_ga) {
|
310 |
+
w3tc_ga('create', '<?php echo esc_html( $profile ); ?>', 'auto');
|
311 |
+
w3tc_ga('set', {
|
312 |
+
'dimension1': 'w3-total-cache',
|
313 |
+
'dimension2': '<?php echo esc_html( W3TC_VERSION ); ?>',
|
314 |
+
'dimension3': '<?php echo esc_html( $wp_version ); ?>',
|
315 |
+
'dimension4': 'php<?php echo esc_html( phpversion() ); ?>',
|
316 |
+
'dimension5': '<?php echo esc_attr( isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '' ); ?>',
|
317 |
+
'dimension6': 'mysql<?php echo esc_attr( $wpdb->db_version() ); ?>',
|
318 |
+
'dimension7': '<?php echo esc_url( Util_Environment::home_url_host() ); ?>',
|
319 |
+
'dimension9': '<?php echo esc_attr( $state->get_string( 'common.install_version' ) ); ?>',
|
320 |
+
'dimension10': '<?php echo esc_attr( Util_Environment::w3tc_edition( $this->_config ) ); ?>',
|
321 |
+
'dimension11': '<?php echo esc_attr( Util_Widget::list_widgets() ); ?>',
|
322 |
+
|
323 |
+
'page': '<?php echo esc_attr( $page ); ?>'
|
324 |
+
});
|
325 |
+
|
326 |
+
w3tc_ga('send', 'pageview');
|
327 |
+
}
|
328 |
</script>
|
329 |
<?php
|
330 |
}
|
331 |
|
332 |
+
?>
|
333 |
<style type="text/css" media="screen">
|
334 |
+
li.toplevel_page_w3tc_dashboard .wp-menu-image:before{
|
335 |
+
content:'\0041';
|
336 |
+
top: 2px;
|
337 |
+
font-family: 'w3tc';
|
338 |
+
}
|
339 |
</style>
|
340 |
<script>
|
341 |
+
jQuery(document).ready( function($) {
|
342 |
+
$('#toplevel_page_w3tc_dashboard ul li').find('a[href*="w3tc_faq"]')
|
343 |
+
.prop('target','_blank')
|
344 |
+
.prop('href', <?php echo wp_json_encode( W3TC_FAQ_URL ); ?>);
|
345 |
+
} );
|
346 |
</script>
|
347 |
<?php
|
348 |
}
|
349 |
|
350 |
+
/**
|
351 |
+
* Render network admin menu.
|
352 |
+
*/
|
353 |
+
public function network_admin_menu() {
|
354 |
$this->_admin_menu( 'manage_network_options' );
|
355 |
}
|
356 |
|
357 |
+
/**
|
358 |
+
* Render admin menu.
|
359 |
+
*/
|
360 |
+
public function admin_menu() {
|
361 |
$this->_admin_menu( 'manage_options' );
|
362 |
}
|
363 |
|
364 |
/**
|
365 |
* Admin menu
|
366 |
*
|
367 |
+
* @param string $base_capability Base compatibility.
|
368 |
+
*
|
369 |
* @return void
|
370 |
*/
|
371 |
private function _admin_menu( $base_capability ) {
|
372 |
+
$base_capability = apply_filters( 'w3tc_capability_menu', $base_capability );
|
|
|
373 |
|
374 |
if ( current_user_can( $base_capability ) ) {
|
375 |
+
$menus = Dispatcher::component( 'Root_AdminMenu' );
|
376 |
$submenu_pages = $menus->generate( $base_capability );
|
377 |
|
378 |
/**
|
379 |
* Only admin can modify W3TC settings
|
380 |
*/
|
381 |
foreach ( $submenu_pages as $submenu_page ) {
|
382 |
+
add_action( 'load-' . $submenu_page, array( $this, 'load' ) );
|
383 |
+
add_action( 'admin_print_styles-' . $submenu_page, array( $this, 'admin_print_styles' ) );
|
384 |
+
add_action( 'admin_print_scripts-' . $submenu_page, array( $this, 'admin_print_scripts' ) );
|
|
|
|
|
|
|
|
|
|
|
385 |
}
|
386 |
|
387 |
global $pagenow;
|
388 |
+
if ( 'plugins.php' === $pagenow ) {
|
389 |
add_action( 'admin_print_scripts', array( $this, 'load_plugins_page_js' ) );
|
390 |
add_action( 'admin_print_styles', array( $this, 'print_plugins_page_css' ) );
|
391 |
}
|
395 |
! empty( Util_Request::get_string( 'w3tc_note' ) ) ||
|
396 |
! empty( Util_Request::get_string( 'w3tc_error' ) ) ||
|
397 |
! empty( Util_Request::get_string( 'w3tc_message' ) ) ) {
|
398 |
+
|
399 |
+
// Only admin can see W3TC notices and errors.
|
400 |
+
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
401 |
+
add_action( 'network_admin_notices', array( $this, 'admin_notices' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
402 |
}
|
403 |
}
|
404 |
}
|
408 |
*
|
409 |
* @return void
|
410 |
*/
|
411 |
+
public function admin_print_styles() {
|
412 |
wp_enqueue_style( 'w3tc-options' );
|
413 |
wp_enqueue_style( 'w3tc-lightbox' );
|
414 |
}
|
416 |
/**
|
417 |
* Print scripts.
|
418 |
*/
|
419 |
+
public function admin_print_scripts() {
|
420 |
wp_enqueue_script( 'w3tc-metadata' );
|
421 |
wp_enqueue_script( 'w3tc-options' );
|
422 |
wp_enqueue_script( 'w3tc-lightbox' );
|
434 |
array(
|
435 |
'cdnEnabled' => $this->_config->get_boolean( 'cdn.enabled' ),
|
436 |
'cdnEngine' => $this->_config->get_string( 'cdn.engine' ),
|
437 |
+
'cdnFlushManually' => $this->_config->get_boolean(
|
438 |
+
'cdn.flush_manually',
|
439 |
+
Cdn_Util::get_flush_manually_default_override( $this->_config->get_string( 'cdn.engine' ) )
|
440 |
+
),
|
441 |
'cfWarning' => wp_kses(
|
442 |
sprintf(
|
443 |
+
// translators: 1: HTML opening a tag to docs.aws.amazon.com for invalidation payments, 2: HTML closing a tag followed by HTML line break tag,
|
444 |
+
// translators: 4: HTML line break tag, 5: HTML opening a tag to purge CDN manually, 6: HTML closing a tag.
|
445 |
__(
|
446 |
+
'Please see %1$sAmazon\'s CloudFront documentation -- Paying for file invalidation%2$sThe first 1,000 invalidation paths that you submit per month are free; you pay for each invalidation path over 1,000 in a month.%3$sYou can disable automatic purging by enabling %4$sOnly purge CDN manually%5$s.',
|
447 |
'w3-total-cache'
|
448 |
),
|
|
|
449 |
'<a target="_blank" href="https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html#PayingForInvalidation">',
|
450 |
+
'</a>.<br/>',
|
451 |
+
'<br/>',
|
452 |
+
'<a href="' . esc_url( admin_url( 'admin.php?page=w3tc_cdn#advanced' ) ) . '">',
|
453 |
+
'</a>'
|
454 |
),
|
455 |
array(
|
456 |
'a' => array(
|
465 |
}
|
466 |
|
467 |
switch ( $this->_page ) {
|
468 |
+
case 'w3tc_minify':
|
469 |
+
case 'w3tc_cachegroups':
|
470 |
+
wp_enqueue_script(
|
471 |
+
'w3tc_cachegroups',
|
472 |
+
plugins_url( 'CacheGroups_Plugin_Admin_View.js', W3TC_FILE ),
|
473 |
+
array(
|
474 |
+
'jquery',
|
475 |
+
'jquery-ui-sortable',
|
476 |
+
),
|
477 |
+
W3TC_VERSION,
|
478 |
+
true
|
479 |
+
);
|
480 |
+
// No break.
|
481 |
+
case 'w3tc_cdn':
|
482 |
+
wp_enqueue_script( 'jquery-ui-sortable' );
|
483 |
+
break;
|
484 |
}
|
485 |
+
|
486 |
+
if ( 'w3tc_cdn' === $this->_page ) {
|
487 |
wp_enqueue_script( 'jquery-ui-dialog' );
|
488 |
+
}
|
489 |
+
|
490 |
+
if ( 'w3tc_dashboard' === $this->_page ) {
|
491 |
wp_enqueue_script( 'w3tc-jquery-masonry' );
|
492 |
+
}
|
493 |
}
|
494 |
|
495 |
+
/**
|
496 |
+
* Load plugins page JS.
|
497 |
+
*/
|
498 |
+
public function load_plugins_page_js() {
|
499 |
wp_enqueue_script( 'w3tc-options' );
|
500 |
}
|
501 |
|
502 |
+
/**
|
503 |
+
* Load plugins page CSS.
|
504 |
+
*/
|
505 |
+
public function print_plugins_page_css() {
|
506 |
+
?>
|
507 |
+
<style type=\"text/css\">
|
508 |
.w3tc-missing-files ul {
|
509 |
margin-left: 20px;
|
510 |
list-style-type: disc;
|
527 |
width: 170px;
|
528 |
display: inline-block;
|
529 |
}
|
530 |
+
</style>
|
531 |
+
<?php
|
532 |
}
|
533 |
|
534 |
/**
|
535 |
+
* Contextual help list filter.
|
|
|
|
|
|
|
536 |
*/
|
537 |
+
public function add_help_tabs() {
|
538 |
+
$screen = get_current_screen();
|
539 |
$sections = Generic_Faq::sections();
|
540 |
+
$n = 0;
|
541 |
|
542 |
foreach ( $sections as $section => $data ) {
|
543 |
+
$content = '<div class="w3tchelp_content" data-section="' . $section . '"></div>';
|
544 |
+
|
545 |
+
$screen->add_help_tab(
|
546 |
+
array(
|
547 |
+
'id' => 'w3tc_faq_' . $n,
|
548 |
+
'title' => $section,
|
549 |
+
'content' => $content,
|
550 |
+
)
|
551 |
+
);
|
552 |
$n++;
|
553 |
}
|
554 |
}
|
555 |
|
556 |
+
/**
|
557 |
+
* FAQ ajax handler.
|
558 |
+
*/
|
559 |
public function w3tc_ajax_faq() {
|
560 |
$section = Util_Request::get_string( 'section' );
|
561 |
|
562 |
+
$entries = Generic_Faq::parse( $section );
|
563 |
$response = array();
|
564 |
|
565 |
ob_start();
|
567 |
$content = ob_get_contents();
|
568 |
ob_end_clean();
|
569 |
|
570 |
+
echo wp_json_encode( array( 'content' => $content ) );
|
571 |
}
|
572 |
|
|
|
|
|
573 |
/**
|
574 |
* Plugin action links filter
|
575 |
*
|
576 |
+
* @param array $links Links array.
|
577 |
+
*
|
578 |
* @return array
|
579 |
*/
|
580 |
+
public function plugin_action_links( $links ) {
|
581 |
+
array_unshift( $links, '<a class="edit" href="admin.php?page=w3tc_general">' . esc_html__( 'Settings', 'w3-total-cache' ) . '</a>' );
|
582 |
+
array_unshift( $links, '<a class="edit" style="color: red" href="admin.php?page=w3tc_support">' . esc_html__( 'Premium Support', 'w3-total-cache' ) . '</a>' );
|
|
|
|
|
|
|
583 |
|
584 |
+
if ( ! is_writable( WP_CONTENT_DIR ) || ! is_writable( Util_Rule::get_browsercache_rules_cache_path() ) ) {
|
|
|
585 |
$delete_link = '<a href="' .
|
586 |
wp_nonce_url( admin_url( 'plugins.php?action=w3tc_deactivate_plugin' ), 'w3tc' ) .
|
587 |
'">Uninstall</a>';
|
592 |
}
|
593 |
|
594 |
/**
|
595 |
+
* Favorite actions filter.
|
596 |
+
*
|
597 |
+
* @param array $actions Actions.
|
598 |
*
|
|
|
599 |
* @return array
|
600 |
*/
|
601 |
+
public function favorite_actions( $actions ) {
|
602 |
+
$actions[ wp_nonce_url( admin_url( 'admin.php?page=w3tc_dashboard&w3tc_flush_all' ), 'w3tc' ) ] = array(
|
603 |
__( 'Empty Caches', 'w3-total-cache' ),
|
604 |
+
apply_filters( 'w3tc_capability_favorite_action_flush_all', 'manage_options' ),
|
605 |
);
|
606 |
|
607 |
return $actions;
|
610 |
/**
|
611 |
* Active plugins pre update option filter
|
612 |
*
|
613 |
+
* @param string $new_value New value.
|
614 |
+
*
|
615 |
* @return string
|
616 |
*/
|
617 |
+
public function pre_update_option_active_plugins( $new_value ) {
|
618 |
$old_value = (array) get_option( 'active_plugins' );
|
619 |
|
620 |
+
if ( $new_value !== $old_value && in_array( W3TC_FILE, (array) $new_value, true ) && in_array( W3TC_FILE, (array) $old_value, true ) ) {
|
621 |
$state_note = Dispatcher::config_state_note();
|
622 |
$state_note->set( 'common.show_note.plugins_updated', true );
|
623 |
}
|
630 |
*
|
631 |
* @return void
|
632 |
*/
|
633 |
+
public function in_plugin_update_message() {
|
634 |
$response = Util_Http::get( W3TC_README_URL );
|
635 |
|
636 |
+
if ( is_wp_error( $response ) || 200 !== $response['response']['code'] ) {
|
637 |
return;
|
638 |
+
}
|
639 |
|
640 |
$matches = null;
|
641 |
+
$regexp = '~==\s*Changelog\s*==\s*=\s*[0-9.]+\s*=(.*)(=\s*' . preg_quote( W3TC_VERSION, '~' ) . '\s*=|$)~Uis';
|
642 |
|
643 |
$body = $response['body'];
|
644 |
+
if ( ! preg_match( $regexp, $body, $matches ) ) {
|
645 |
return;
|
646 |
+
}
|
647 |
|
648 |
$changelog = (array) preg_split( '~[\r\n]+~', trim( $matches[1] ) );
|
649 |
|
652 |
|
653 |
foreach ( $changelog as $index => $line ) {
|
654 |
if ( preg_match( '~^\s*\*\s*~', $line ) ) {
|
655 |
+
if ( ! $ul ) {
|
656 |
echo '<ul style="list-style: disc; margin-left: 20px;margin-top:0;">';
|
657 |
$ul = true;
|
658 |
}
|
659 |
$line = preg_replace( '~^\s*\*\s*~', '', htmlspecialchars( $line ) );
|
660 |
+
echo '<li style="width: 50%; margin: 0; float: left; ' . ( 0 === $index % 2 ? 'clear: left;' : '' ) . '">' . esc_html( $line ) . '</li>';
|
661 |
} else {
|
662 |
if ( $ul ) {
|
663 |
echo '</ul><div style="clear: left;"></div>';
|
666 |
}
|
667 |
}
|
668 |
|
669 |
+
if ( $ul ) {
|
670 |
echo '</ul><div style="clear: left;"></div>';
|
671 |
+
}
|
672 |
|
673 |
echo '</div>';
|
674 |
}
|
678 |
*
|
679 |
* @return void
|
680 |
*/
|
681 |
+
public function admin_notices() {
|
682 |
$cookie_domain = Util_Admin::get_cookie_domain();
|
683 |
|
684 |
$error_messages = array(
|
685 |
+
'fancy_permalinks_disabled_pgcache' => sprintf(
|
686 |
+
// translators: 1 enable button link.
|
687 |
+
__(
|
688 |
+
'Fancy permalinks are disabled. Please %1$s it first, then re-attempt to enabling enhanced disk mode.',
|
689 |
+
'w3-total-cache'
|
690 |
+
),
|
691 |
+
Util_Ui::button_link( 'enable', 'options-permalink.php' )
|
692 |
+
),
|
693 |
+
'fancy_permalinks_disabled_browsercache' => sprintf(
|
694 |
+
// translators: 1 enable button link.
|
695 |
+
__(
|
696 |
+
'Fancy permalinks are disabled. Please %1$s it first, then re-attempt to enabling the \'Do not process 404 errors for static objects with WordPress\'.',
|
697 |
+
'w3-total-cache'
|
698 |
+
),
|
699 |
+
Util_Ui::button_link( 'enable', 'options-permalink.php' )
|
700 |
+
),
|
701 |
+
'support_request_type' => __( 'Please select request type.', 'w3-total-cache' ),
|
702 |
+
'support_request_url' => sprintf(
|
703 |
+
// translators: 1 HTML acronym URL (uniform resource locator).
|
704 |
+
__(
|
705 |
+
'Please enter the address of the site in the site %1$s field.',
|
706 |
+
'w3-total-cache'
|
707 |
+
),
|
708 |
+
'<acronym title="' . esc_attr__( 'Uniform Resource Locator', 'w3-total-cache' ) . '">' . esc_html__( 'URL', 'w3-total-cache' ) . '</acronym>'
|
709 |
+
),
|
710 |
+
'support_request_name' => __( 'Please enter your name in the Name field', 'w3-total-cache' ),
|
711 |
+
'support_request_email' => __( 'Please enter valid email address in the E-Mail field.', 'w3-total-cache' ),
|
712 |
+
'support_request_phone' => __( 'Please enter your phone in the phone field.', 'w3-total-cache' ),
|
713 |
+
'support_request_subject' => __( 'Please enter subject in the subject field.', 'w3-total-cache' ),
|
714 |
+
'support_request_description' => __( 'Please describe the issue in the issue description field.', 'w3-total-cache' ),
|
715 |
+
'support_request_wp_login' => __( 'Please enter an administrator login. Create a temporary one just for this support case if needed.', 'w3-total-cache' ),
|
716 |
+
'support_request_wp_password' => __( 'Please enter WP Admin password, be sure it\'s spelled correctly.', 'w3-total-cache' ),
|
717 |
+
'support_request_ftp_host' => sprintf(
|
718 |
+
// translators: 1 HTML acronym SSH (secure shell), 2 HTML acronym FTP (file transfer protocol).
|
719 |
+
__(
|
720 |
+
'Please enter %1$s or %2$s host for the site.',
|
721 |
+
'w3-total-cache'
|
722 |
+
),
|
723 |
+
'<acronym title="' . esc_attr__( 'Secure Shell', 'w3-total-cache' ) . '">' . esc_html__( 'SSH', 'w3-total-cache' ) . '</acronym>',
|
724 |
+
'<acronym title="' . esc_attr__( 'File Transfer Protocol', 'w3-total-cache' ) . '">' . esc_html__( 'FTP', 'w3-total-cache' ) . '</acronym>'
|
725 |
+
),
|
726 |
+
'support_request_ftp_login' => sprintf(
|
727 |
+
// translators: 1 HTML acronym SSH (secure shell), 2 HTML acronym FTP (file transfer protocol).
|
728 |
+
__(
|
729 |
+
'Please enter %1$s or %2$s login for the server. Create a temporary one just for this support case if needed.',
|
730 |
+
'w3-total-cache'
|
731 |
+
),
|
732 |
+
'<acronym title="' . esc_attr__( 'Secure Shell', 'w3-total-cache' ) . '">' . esc_html__( 'SSH', 'w3-total-cache' ) . '</acronym>',
|
733 |
+
'<acronym title="' . esc_attr__( 'File Transfer Protocol', 'w3-total-cache' ) . '">' . esc_html__( 'FTP', 'w3-total-cache' ) . '</acronym>'
|
734 |
+
),
|
735 |
+
'support_request_ftp_password' => sprintf(
|
736 |
+
// translators: 1 HTML acronym SSH (secure shell), 2 HTML acronym FTP (file transfer protocol).
|
737 |
+
__(
|
738 |
+
'Please enter %1$s or %2$s password for the %2$s account.',
|
739 |
+
'w3-total-cache'
|
740 |
+
),
|
741 |
+
'<acronym title="' . esc_attr__( 'Secure Shell', 'w3-total-cache' ) . '">' . esc_html__( 'SSH', 'w3-total-cache' ) . '</acronym>',
|
742 |
+
'<acronym title="' . esc_attr__( 'File Transfer Protocol', 'w3-total-cache' ) . '">' . esc_html__( 'FTP', 'w3-total-cache' ) . '</acronym>'
|
743 |
+
),
|
744 |
+
'support_request' => __( 'Unable to send the support request.', 'w3-total-cache' ),
|
745 |
+
'config_import_no_file' => __( 'Please select config file.', 'w3-total-cache' ),
|
746 |
+
'config_import_upload' => __( 'Unable to upload config file.', 'w3-total-cache' ),
|
747 |
+
'config_import_import' => __( 'Configuration file could not be imported.', 'w3-total-cache' ),
|
748 |
+
'config_reset' => sprintf(
|
749 |
+
// translators: 1 W3TC config director path.
|
750 |
+
__(
|
751 |
+
'Default settings could not be restored. Please run %1$s to make the configuration file write-able, then try again.',
|
752 |
+
'w3-total-cache'
|
753 |
+
),
|
754 |
+
'<strong>chmod 777 ' . W3TC_CONFIG_DIR . '</strong>'
|
755 |
+
),
|
756 |
+
'cdn_purge_attachment' => __( 'Unable to purge attachment.', 'w3-total-cache' ),
|
757 |
+
'pgcache_purge_post' => __( 'Unable to purge post.', 'w3-total-cache' ),
|
758 |
+
'enable_cookie_domain' => sprintf(
|
759 |
+
// translators: 1 absolute path to wp-config.php, 2 cookie domain definition, 3 require once wp-setting.php definition.
|
760 |
+
__(
|
761 |
+
'%1$s could not be written, please edit config and add: %2$s before %3$s.',
|
762 |
+
'w3-total-cache'
|
763 |
+
),
|
764 |
+
'<strong>' . ABSPATH . 'wp-config.php</strong>',
|
765 |
+
'<br /><strong style="color:#f00;">define(\'COOKIE_DOMAIN\', \'' . addslashes( $cookie_domain ) . '\');</strong>',
|
766 |
+
'<strong style="color:#f00;">require_once(ABSPATH . \'wp-settings.php\');</strong>'
|
767 |
+
),
|
768 |
+
'disable_cookie_domain' => sprintf(
|
769 |
+
// translators: 1 absolute path to wp-config.php, 2 cooke domain definition, 3 require once wp-setting.php definition.
|
770 |
+
__(
|
771 |
+
'%1$s could not be written, please edit config and add:%2$s before %3$s.',
|
772 |
+
'w3-total-cache'
|
773 |
+
),
|
774 |
+
'<strong>' . ABSPATH . 'wp-config.php</strong>',
|
775 |
+
'<br /><strong style="color:#f00;">define(\'COOKIE_DOMAIN\', false);</strong>',
|
776 |
+
'<strong style="color:#f00;">require_once(ABSPATH . \'wp-settings.php\');</strong>'
|
777 |
+
),
|
778 |
+
'pull_zone' => __( 'Pull Zone could not be automatically created.', 'w3-total-cache' ),
|
779 |
);
|
780 |
|
781 |
$note_messages = array(
|
782 |
+
'config_save' => __( 'Plugin configuration successfully updated.', 'w3-total-cache' ),
|
783 |
+
'flush_all' => __( 'All caches successfully emptied.', 'w3-total-cache' ),
|
784 |
+
'flush_memcached' => __( 'Memcached cache(s) successfully emptied.', 'w3-total-cache' ),
|
785 |
+
'flush_opcode' => __( 'Opcode cache(s) successfully emptied.', 'w3-total-cache' ),
|
786 |
+
'flush_file' => __( 'Disk cache(s) successfully emptied.', 'w3-total-cache' ),
|
787 |
+
'flush_pgcache' => __( 'Page cache successfully emptied.', 'w3-total-cache' ),
|
788 |
+
'flush_dbcache' => __( 'Database cache successfully emptied.', 'w3-total-cache' ),
|
789 |
+
'flush_objectcache' => __( 'Object cache successfully emptied.', 'w3-total-cache' ),
|
790 |
+
'flush_fragmentcache' => __( 'Fragment cache successfully emptied.', 'w3-total-cache' ),
|
791 |
+
'flush_minify' => __( 'Minify cache successfully emptied.', 'w3-total-cache' ),
|
792 |
+
'flush_browser_cache' => __( 'Media Query string has been successfully updated.', 'w3-total-cache' ),
|
793 |
+
'flush_varnish' => __( 'Varnish servers successfully purged.', 'w3-total-cache' ),
|
794 |
+
'flush_cdn' => sprintf(
|
795 |
+
// translators: 1 HTML acronym for CDN (content delivery network).
|
796 |
+
__(
|
797 |
+
'%1$s was successfully purged.',
|
798 |
+
'w3-total-cache'
|
799 |
+
),
|
800 |
+
'<acronym title="' . esc_attr__( 'Content Delivery Network', 'w3-total-cache' ) . '">' . esc_html__( 'CDN', 'w3-total-cache' ) . '</acronym>'
|
801 |
+
),
|
802 |
+
'support_request' => __( 'The support request has been successfully sent.', 'w3-total-cache' ),
|
803 |
+
'config_import' => __( 'Settings successfully imported.', 'w3-total-cache' ),
|
804 |
+
'config_reset' => __( 'Settings successfully restored.', 'w3-total-cache' ),
|
805 |
+
'preview_enable' => __( 'Preview mode was successfully enabled', 'w3-total-cache' ),
|
806 |
+
'preview_disable' => __( 'Preview mode was successfully disabled', 'w3-total-cache' ),
|
807 |
+
'preview_deploy' => __( 'Preview settings successfully deployed. Preview mode remains enabled until it\'s disabled. Continue testing new settings or disable preview mode if done.', 'w3-total-cache' ),
|
808 |
'cdn_purge_attachment' => __( 'Attachment successfully purged.', 'w3-total-cache' ),
|
809 |
+
'pgcache_purge_post' => __( 'Post successfully purged.', 'w3-total-cache' ),
|
810 |
+
'new_relic_save' => __( 'New relic settings have been updated.', 'w3-total-cache' ),
|
811 |
+
'add_in_removed' => __( 'The add-in has been removed.', 'w3-total-cache' ),
|
812 |
+
'enabled_edge' => __( 'Edge mode has been enabled.', 'w3-total-cache' ),
|
813 |
+
'disabled_edge' => __( 'Edge mode has been disabled.', 'w3-total-cache' ),
|
814 |
+
'pull_zone' => __( 'Pull Zone was automatically created.', 'w3-total-cache' ),
|
815 |
);
|
816 |
|
817 |
+
$errors = array();
|
818 |
+
$notes = array();
|
819 |
$environment_error_present = false;
|
820 |
|
821 |
$error = Util_Request::get_string( 'w3tc_error' );
|
822 |
+
if ( isset( $error_messages[ $error ] ) ) {
|
823 |
+
$errors[ $error ] = $error_messages[ $error ];
|
824 |
+
}
|
825 |
|
826 |
$note = Util_Request::get_string( 'w3tc_note' );
|
827 |
+
if ( isset( $note_messages[ $note ] ) ) {
|
828 |
+
$notes[ $note ] = $note_messages[ $note ];
|
829 |
+
}
|
830 |
|
831 |
// print errors happened during last request execution,
|
832 |
// when we decided to redirect with error message instead of
|
833 |
+
// printing it directly (to avoid reexecution on refresh).
|
834 |
+
if ( ! is_null( $this->w3tc_message ) ) {
|
835 |
$v = $this->w3tc_message;
|
836 |
if ( isset( $v['errors'] ) && is_array( $v['errors'] ) ) {
|
837 |
foreach ( $v['errors'] as $error ) {
|
838 |
+
if ( isset( $error_messages[ $error ] ) ) {
|
839 |
+
$errors[] = $error_messages[ $error ];
|
840 |
+
} else {
|
841 |
$errors[] = $error;
|
842 |
+
}
|
843 |
}
|
844 |
}
|
845 |
if ( isset( $v['notes'] ) && is_array( $v['notes'] ) ) {
|
846 |
foreach ( $v['notes'] as $note ) {
|
847 |
+
if ( isset( $note_messages[ $note ] ) ) {
|
848 |
+
$notes[] = $note_messages[ $note ];
|
849 |
+
} else {
|
850 |
$notes[] = $note;
|
851 |
+
}
|
852 |
}
|
853 |
}
|
854 |
}
|
855 |
|
856 |
/*
|
857 |
+
* Filesystem environment fix, if needed.
|
858 |
*/
|
859 |
try {
|
860 |
$environment = Dispatcher::component( 'Root_Environment' );
|
868 |
$n = 1;
|
869 |
|
870 |
foreach ( $r['before_errors'] as $e ) {
|
871 |
+
$errors[ 'generic_env_' . $n ] = $e;
|
872 |
$n++;
|
873 |
}
|
874 |
|
877 |
'background: white; ' .
|
878 |
'margin: 10px 30px 10px 30px; ' .
|
879 |
'padding: 10px; display: none';
|
880 |
+
|
881 |
$ftp_style = 'border: 1px solid black; background: white; ' .
|
882 |
'margin: 10px 30px 10px 30px; ' .
|
883 |
'padding: 10px; display: none';
|
884 |
+
|
885 |
+
$ftp_form = str_replace( 'class="wrap"', '', $exs->credentials_form() );
|
886 |
+
$ftp_form = str_replace( '<form ', '<form name="w3tc_ftp_form" ', $ftp_form );
|
|
|
887 |
$ftp_form = str_replace( '<fieldset>', '', $ftp_form );
|
888 |
$ftp_form = str_replace( '</fieldset>', '', $ftp_form );
|
889 |
+
$ftp_form = str_replace( 'id="upgrade" class="button"', 'id="upgrade" class="button w3tc-button-save"', $ftp_form );
|
|
|
890 |
|
891 |
+
$error = '<strong>' . esc_html__( 'W3 Total Cache Error:', 'w3-total-cache' ) . '</strong> ' .
|
892 |
+
esc_html__( 'Files and directories could not be automatically created to complete the installation.', 'w3-total-cache' ) .
|
|
|
893 |
'<table>' .
|
894 |
'<tr>' .
|
895 |
+
'<td>' . esc_html__( 'Please execute commands manually', 'w3-total-cache' ) . '</td>' .
|
896 |
+
'<td>' . Util_Ui::button( __( 'View required changes', 'w3-total-cache' ), '', 'w3tc-show-required-changes' ) . '</td>' .
|
|
|
|
|
|
|
897 |
'</tr>' .
|
898 |
'<tr>' .
|
899 |
+
'<td>' . esc_html__( 'or use FTP form to allow ', 'w3-total-cache' ) .
|
900 |
+
'<strong>' . esc_html__( 'W3 Total Cache', 'w3-total-cache' ) . '</strong>' .
|
901 |
+
esc_html__( 'make it automatically.', 'w3-total-cache' ) .
|
902 |
+
'</td>' .
|
903 |
+
'<td>' . Util_Ui::button( 'Update via FTP', '', 'w3tc-show-ftp-form' ) . '</td>' .
|
904 |
+
'</tr>' .
|
905 |
+
'</table>' .
|
906 |
+
'<div class="w3tc-required-changes" style="' . $changes_style . '">' . $r['required_changes'] . '</div>' .
|
907 |
+
'<div class="w3tc-ftp-form" style="' . $ftp_style . '">' . $ftp_form . '</div>';
|
|
|
|
|
|
|
908 |
|
909 |
$environment_error_present = true;
|
910 |
+
$errors['generic_ftp'] = $error;
|
911 |
}
|
912 |
|
913 |
foreach ( $r['later_errors'] as $e ) {
|
950 |
printf(
|
951 |
'<div class="error w3tc_error" id="%1$s"><p>%2$s</p></div>',
|
952 |
esc_attr( $key ),
|
953 |
+
$error // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
954 |
);
|
955 |
}
|
956 |
}
|
Root_Loader.php
CHANGED
@@ -1,6 +1,17 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
namespace W3TC;
|
3 |
|
|
|
|
|
|
|
|
|
|
|
4 |
class Root_Loader {
|
5 |
/**
|
6 |
* Enabled Plugins that has been run
|
@@ -8,6 +19,7 @@ class Root_Loader {
|
|
8 |
* @var W3_Plugin[]
|
9 |
*/
|
10 |
private $_loaded_plugins = array();
|
|
|
11 |
/**
|
12 |
* Enabled extensions that has been run
|
13 |
*
|
@@ -15,32 +27,54 @@ class Root_Loader {
|
|
15 |
*/
|
16 |
private $_loaded_extensions = array();
|
17 |
|
18 |
-
|
|
|
|
|
|
|
19 |
$c = Dispatcher::config();
|
20 |
|
21 |
-
$plugins
|
22 |
$plugins[] = new Generic_Plugin();
|
23 |
|
24 |
-
if ( $c->get_boolean( 'dbcache.enabled' ) )
|
25 |
$plugins[] = new DbCache_Plugin();
|
26 |
-
|
|
|
|
|
27 |
$plugins[] = new ObjectCache_Plugin();
|
28 |
-
|
|
|
|
|
29 |
$plugins[] = new PgCache_Plugin();
|
30 |
-
|
|
|
|
|
31 |
$plugins[] = new Cdn_Plugin();
|
32 |
-
|
|
|
|
|
33 |
$plugins[] = new Cdnfsd_Plugin();
|
34 |
-
|
|
|
|
|
35 |
$plugins[] = new UserExperience_LazyLoad_Plugin();
|
36 |
-
|
|
|
|
|
37 |
$plugins[] = new BrowserCache_Plugin();
|
38 |
-
|
|
|
|
|
39 |
$plugins[] = new Minify_Plugin();
|
40 |
-
|
|
|
|
|
41 |
$plugins[] = new Varnish_Plugin();
|
42 |
-
|
|
|
|
|
43 |
$plugins[] = new UsageStatistics_Plugin();
|
|
|
44 |
|
45 |
if ( is_admin() ) {
|
46 |
$plugins[] = new Generic_Plugin_Admin();
|
@@ -57,20 +91,22 @@ class Root_Loader {
|
|
57 |
|
58 |
$plugins[] = new Cdn_Plugin_Admin();
|
59 |
$plugins[] = new Cdnfsd_Plugin_Admin();
|
|
|
60 |
$cdn_engine = $c->get_string( 'cdn.engine' );
|
61 |
-
if (
|
62 |
$plugins[] = new Cdn_Plugin_WidgetMaxCdn();
|
63 |
}
|
64 |
|
65 |
-
if ( $c->get_boolean( 'widget.pagespeed.enabled' ) )
|
66 |
$plugins[] = new PageSpeed_Plugin_Widget();
|
|
|
67 |
|
68 |
$plugins[] = new Generic_Plugin_AdminCompatibility();
|
69 |
$plugins[] = new Licensing_Plugin_Admin();
|
70 |
|
71 |
-
if ( $c->get_boolean( 'pgcache.enabled' ) ||
|
72 |
-
$c->get_boolean( 'varnish.enabled' ) )
|
73 |
$plugins[] = new Generic_Plugin_AdminRowActions();
|
|
|
74 |
|
75 |
$plugins[] = new Extensions_Plugin_Admin();
|
76 |
$plugins[] = new Generic_Plugin_AdminNotifications();
|
@@ -85,21 +121,21 @@ class Root_Loader {
|
|
85 |
|
86 |
$this->_loaded_plugins = $plugins;
|
87 |
|
88 |
-
register_activation_hook(
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
|
93 |
-
register_deactivation_hook(
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
}
|
98 |
|
99 |
/**
|
100 |
* Run plugins
|
101 |
*/
|
102 |
-
function run() {
|
103 |
foreach ( $this->_loaded_plugins as $plugin ) {
|
104 |
$plugin->run();
|
105 |
}
|
@@ -114,6 +150,8 @@ class Root_Loader {
|
|
114 |
|
115 |
/**
|
116 |
* Activation action hook
|
|
|
|
|
117 |
*/
|
118 |
public function activate( $network_wide ) {
|
119 |
Root_AdminActivation::activate( $network_wide );
|
@@ -129,19 +167,18 @@ class Root_Loader {
|
|
129 |
/**
|
130 |
* Loads extensions stored in config
|
131 |
*/
|
132 |
-
function run_extensions() {
|
133 |
-
$c
|
134 |
$extensions = $c->get_array( 'extensions.active' );
|
135 |
|
136 |
$frontend = $c->get_array( 'extensions.active_frontend' );
|
137 |
foreach ( $frontend as $extension => $nothing ) {
|
138 |
-
if ( isset( $extensions[$extension] ) ) {
|
139 |
-
$path
|
140 |
-
$filename = W3TC_EXTENSION_DIR . '/' .
|
141 |
-
str_replace( '..', '', trim( $path, '/' ) );
|
142 |
|
143 |
if ( file_exists( $filename ) ) {
|
144 |
-
include_once
|
145 |
}
|
146 |
}
|
147 |
}
|
@@ -152,7 +189,7 @@ class Root_Loader {
|
|
152 |
str_replace( '..', '', trim( $path, '/' ) );
|
153 |
|
154 |
if ( file_exists( $filename ) ) {
|
155 |
-
include_once
|
156 |
}
|
157 |
}
|
158 |
}
|
@@ -170,51 +207,66 @@ class Root_Loader {
|
|
170 |
if ( 'never' === $visibility || ( 'extension' === $visibility && ! isset( $extensions['imageservice'] ) ) ) {
|
171 |
add_action(
|
172 |
'pre_get_posts',
|
173 |
-
|
174 |
-
if ( ! is_admin() || ! $query->is_main_query() ) {
|
175 |
-
return;
|
176 |
-
}
|
177 |
-
|
178 |
-
$screen = get_current_screen();
|
179 |
-
|
180 |
-
if ( ! $screen || 'upload' !== $screen->id || 'attachment' !== $screen->post_type ) {
|
181 |
-
return;
|
182 |
-
}
|
183 |
-
|
184 |
-
$query->set(
|
185 |
-
'meta_query',
|
186 |
-
array(
|
187 |
-
array(
|
188 |
-
'key' => 'w3tc_imageservice_file',
|
189 |
-
'compare' => 'NOT EXISTS',
|
190 |
-
),
|
191 |
-
)
|
192 |
-
);
|
193 |
-
|
194 |
-
return;
|
195 |
-
}
|
196 |
);
|
197 |
|
198 |
add_filter(
|
199 |
'ajax_query_attachments_args',
|
200 |
-
|
201 |
-
if ( ! is_admin() ) {
|
202 |
-
return;
|
203 |
-
}
|
204 |
-
|
205 |
-
// Modify the query.
|
206 |
-
$args['meta_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
207 |
-
array(
|
208 |
-
'key' => 'w3tc_imageservice_file',
|
209 |
-
'compare' => 'NOT EXISTS',
|
210 |
-
),
|
211 |
-
);
|
212 |
-
|
213 |
-
return $args;
|
214 |
-
}
|
215 |
);
|
216 |
}
|
217 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
}
|
219 |
|
220 |
global $w3tc_root;
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* File: Root_Loader.php
|
4 |
+
*
|
5 |
+
* @package W3TC
|
6 |
+
*/
|
7 |
+
|
8 |
namespace W3TC;
|
9 |
|
10 |
+
/**
|
11 |
+
* Class: Root_Loader
|
12 |
+
*
|
13 |
+
* phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
|
14 |
+
*/
|
15 |
class Root_Loader {
|
16 |
/**
|
17 |
* Enabled Plugins that has been run
|
19 |
* @var W3_Plugin[]
|
20 |
*/
|
21 |
private $_loaded_plugins = array();
|
22 |
+
|
23 |
/**
|
24 |
* Enabled extensions that has been run
|
25 |
*
|
27 |
*/
|
28 |
private $_loaded_extensions = array();
|
29 |
|
30 |
+
/**
|
31 |
+
* Constructor.
|
32 |
+
*/
|
33 |
+
public function __construct() {
|
34 |
$c = Dispatcher::config();
|
35 |
|
36 |
+
$plugins = array();
|
37 |
$plugins[] = new Generic_Plugin();
|
38 |
|
39 |
+
if ( $c->get_boolean( 'dbcache.enabled' ) ) {
|
40 |
$plugins[] = new DbCache_Plugin();
|
41 |
+
}
|
42 |
+
|
43 |
+
if ( $c->get_boolean( 'objectcache.enabled' ) ) {
|
44 |
$plugins[] = new ObjectCache_Plugin();
|
45 |
+
}
|
46 |
+
|
47 |
+
if ( $c->get_boolean( 'pgcache.enabled' ) ) {
|
48 |
$plugins[] = new PgCache_Plugin();
|
49 |
+
}
|
50 |
+
|
51 |
+
if ( $c->get_boolean( 'cdn.enabled' ) ) {
|
52 |
$plugins[] = new Cdn_Plugin();
|
53 |
+
}
|
54 |
+
|
55 |
+
if ( $c->get_boolean( 'cdnfsd.enabled' ) ) {
|
56 |
$plugins[] = new Cdnfsd_Plugin();
|
57 |
+
}
|
58 |
+
|
59 |
+
if ( $c->get_boolean( 'lazyload.enabled' ) ) {
|
60 |
$plugins[] = new UserExperience_LazyLoad_Plugin();
|
61 |
+
}
|
62 |
+
|
63 |
+
if ( $c->get_boolean( 'browsercache.enabled' ) ) {
|
64 |
$plugins[] = new BrowserCache_Plugin();
|
65 |
+
}
|
66 |
+
|
67 |
+
if ( $c->get_boolean( 'minify.enabled' ) ) {
|
68 |
$plugins[] = new Minify_Plugin();
|
69 |
+
}
|
70 |
+
|
71 |
+
if ( $c->get_boolean( 'varnish.enabled' ) ) {
|
72 |
$plugins[] = new Varnish_Plugin();
|
73 |
+
}
|
74 |
+
|
75 |
+
if ( $c->get_boolean( 'stats.enabled' ) ) {
|
76 |
$plugins[] = new UsageStatistics_Plugin();
|
77 |
+
}
|
78 |
|
79 |
if ( is_admin() ) {
|
80 |
$plugins[] = new Generic_Plugin_Admin();
|
91 |
|
92 |
$plugins[] = new Cdn_Plugin_Admin();
|
93 |
$plugins[] = new Cdnfsd_Plugin_Admin();
|
94 |
+
|
95 |
$cdn_engine = $c->get_string( 'cdn.engine' );
|
96 |
+
if ( 'maxcdn' === $cdn_engine ) {
|
97 |
$plugins[] = new Cdn_Plugin_WidgetMaxCdn();
|
98 |
}
|
99 |
|
100 |
+
if ( $c->get_boolean( 'widget.pagespeed.enabled' ) ) {
|
101 |
$plugins[] = new PageSpeed_Plugin_Widget();
|
102 |
+
}
|
103 |
|
104 |
$plugins[] = new Generic_Plugin_AdminCompatibility();
|
105 |
$plugins[] = new Licensing_Plugin_Admin();
|
106 |
|
107 |
+
if ( $c->get_boolean( 'pgcache.enabled' ) || $c->get_boolean( 'varnish.enabled' ) ) {
|
|
|
108 |
$plugins[] = new Generic_Plugin_AdminRowActions();
|
109 |
+
}
|
110 |
|
111 |
$plugins[] = new Extensions_Plugin_Admin();
|
112 |
$plugins[] = new Generic_Plugin_AdminNotifications();
|
121 |
|
122 |
$this->_loaded_plugins = $plugins;
|
123 |
|
124 |
+
register_activation_hook(
|
125 |
+
W3TC_FILE,
|
126 |
+
array( $this, 'activate' )
|
127 |
+
);
|
128 |
|
129 |
+
register_deactivation_hook(
|
130 |
+
W3TC_FILE,
|
131 |
+
array( $this, 'deactivate' )
|
132 |
+
);
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
* Run plugins
|
137 |
*/
|
138 |
+
public function run() {
|
139 |
foreach ( $this->_loaded_plugins as $plugin ) {
|
140 |
$plugin->run();
|
141 |
}
|
150 |
|
151 |
/**
|
152 |
* Activation action hook
|
153 |
+
*
|
154 |
+
* @param bool $network_wide Network wide flag.
|
155 |
*/
|
156 |
public function activate( $network_wide ) {
|
157 |
Root_AdminActivation::activate( $network_wide );
|
167 |
/**
|
168 |
* Loads extensions stored in config
|
169 |
*/
|
170 |
+
public function run_extensions() {
|
171 |
+
$c = Dispatcher::config();
|
172 |
$extensions = $c->get_array( 'extensions.active' );
|
173 |
|
174 |
$frontend = $c->get_array( 'extensions.active_frontend' );
|
175 |
foreach ( $frontend as $extension => $nothing ) {
|
176 |
+
if ( isset( $extensions[ $extension ] ) ) {
|
177 |
+
$path = $extensions[ $extension ];
|
178 |
+
$filename = W3TC_EXTENSION_DIR . '/' . str_replace( '..', '', trim( $path, '/' ) );
|
|
|
179 |
|
180 |
if ( file_exists( $filename ) ) {
|
181 |
+
include_once $filename;
|
182 |
}
|
183 |
}
|
184 |
}
|
189 |
str_replace( '..', '', trim( $path, '/' ) );
|
190 |
|
191 |
if ( file_exists( $filename ) ) {
|
192 |
+
include_once $filename;
|
193 |
}
|
194 |
}
|
195 |
}
|
207 |
if ( 'never' === $visibility || ( 'extension' === $visibility && ! isset( $extensions['imageservice'] ) ) ) {
|
208 |
add_action(
|
209 |
'pre_get_posts',
|
210 |
+
array( $this, 'w3tc_modify_query_obj' )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
);
|
212 |
|
213 |
add_filter(
|
214 |
'ajax_query_attachments_args',
|
215 |
+
array( $this, 'w3tc_filter_ajax_args' )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
216 |
);
|
217 |
}
|
218 |
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Modify query object to hide Image Service converted images.
|
222 |
+
*
|
223 |
+
* @param object $query WP_Query object.
|
224 |
+
*
|
225 |
+
* @return void
|
226 |
+
*/
|
227 |
+
public function w3tc_modify_query_obj( $query ) {
|
228 |
+
if ( ! is_admin() || ! $query->is_main_query() ) {
|
229 |
+
return;
|
230 |
+
}
|
231 |
+
|
232 |
+
$screen = get_current_screen();
|
233 |
+
|
234 |
+
if ( ! $screen || 'upload' !== $screen->id || 'attachment' !== $screen->post_type ) {
|
235 |
+
return;
|
236 |
+
}
|
237 |
+
|
238 |
+
$query->set(
|
239 |
+
'meta_query',
|
240 |
+
array(
|
241 |
+
array(
|
242 |
+
'key' => 'w3tc_imageservice_file',
|
243 |
+
'compare' => 'NOT EXISTS',
|
244 |
+
),
|
245 |
+
)
|
246 |
+
);
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Filter AJAX query arguments for attachements to hide Image Service converted images.
|
251 |
+
*
|
252 |
+
* @param string $args arguments.
|
253 |
+
*
|
254 |
+
* @return void
|
255 |
+
*/
|
256 |
+
public function w3tc_filter_ajax_args( $args ) {
|
257 |
+
if ( ! is_admin() ) {
|
258 |
+
return;
|
259 |
+
}
|
260 |
+
|
261 |
+
$args['meta_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
262 |
+
array(
|
263 |
+
'key' => 'w3tc_imageservice_file',
|
264 |
+
'compare' => 'NOT EXISTS',
|
265 |
+
),
|
266 |
+
);
|
267 |
+
|
268 |
+
return $args;
|
269 |
+
}
|
270 |
}
|
271 |
|
272 |
global $w3tc_root;
|
inc/options/cdn.php
CHANGED
@@ -1,4 +1,10 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( ! defined( 'W3TC' ) ) {
|
@@ -377,8 +383,8 @@ $upload_blogfiles_enabled = $cdn_mirror || ! is_network_admin() || ! Util_Enviro
|
|
377 |
|
378 |
<tr>
|
379 |
<th colspan="2">
|
380 |
-
<?php $this->checkbox( 'cdn.flush_manually' ); ?>
|
381 |
<?php
|
|
|
382 |
echo wp_kses(
|
383 |
sprintf(
|
384 |
// translators: 1 opening HTML acronym tag, 2 closing HTML acronym tag.
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* File: cdn.php
|
4 |
+
*
|
5 |
+
* @package W3TC
|
6 |
+
*/
|
7 |
+
|
8 |
namespace W3TC;
|
9 |
|
10 |
if ( ! defined( 'W3TC' ) ) {
|
383 |
|
384 |
<tr>
|
385 |
<th colspan="2">
|
|
|
386 |
<?php
|
387 |
+
$this->checkbox( 'cdn.flush_manually' );
|
388 |
echo wp_kses(
|
389 |
sprintf(
|
390 |
// translators: 1 opening HTML acronym tag, 2 closing HTML acronym tag.
|
inc/options/cdn/s3.php
CHANGED
@@ -1,4 +1,10 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
namespace W3TC;
|
3 |
|
4 |
if ( ! defined( 'W3TC' ) ) {
|
@@ -135,9 +141,9 @@ if ( ! defined( 'W3TC' ) ) {
|
|
135 |
<?php
|
136 |
$cdn_s3_bucket = $this->_config->get_string( 'cdn.s3.bucket' );
|
137 |
if ( '' !== $cdn_s3_bucket ) {
|
138 |
-
echo esc_html( $cdn_s3_bucket ) . '.s3.amazonaws.com';
|
139 |
} else {
|
140 |
-
echo '<bucket>.s3.amazonaws.com';
|
141 |
}
|
142 |
|
143 |
esc_html_e( 'or CNAME:', 'w3-total-cache' );
|
@@ -175,9 +181,9 @@ if ( ! defined( 'W3TC' ) ) {
|
|
175 |
</td>
|
176 |
</tr>
|
177 |
<tr>
|
178 |
-
<th><label for="cdn_s3_public_objects"><?php
|
179 |
<td>
|
180 |
-
<select id="cdn_s3_public_objects" name="cdn__s3__public_objects" <?php Util_Ui::sealing_disabled( 'cdn.' ) ?> >
|
181 |
<option value="enabled"<?php selected( $this->_config->get_string( 'cdn.s3.public_objects' ), 'enabled' ); ?>><?php esc_html_e( 'Enabled (apply the \'public-read\' ACL)', 'w3-total-cache' ); ?></option>
|
182 |
<option value="disabled"<?php selected( $this->_config->get_string( 'cdn.s3.public_objects' ), 'disabled' ); ?>><?php esc_html_e( 'Disabled (don\'t apply an ACL)', 'w3-total-cache' ); ?></option>
|
183 |
</select>
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* File: s3.php
|
4 |
+
*
|
5 |
+
* @package W3TC
|
6 |
+
*/
|
7 |
+
|
8 |
namespace W3TC;
|
9 |
|
10 |
if ( ! defined( 'W3TC' ) ) {
|
141 |
<?php
|
142 |
$cdn_s3_bucket = $this->_config->get_string( 'cdn.s3.bucket' );
|
143 |
if ( '' !== $cdn_s3_bucket ) {
|
144 |
+
echo esc_html( $cdn_s3_bucket ) . '.s3.amazonaws.com ';
|
145 |
} else {
|
146 |
+
echo '<bucket>.s3.amazonaws.com ';
|
147 |
}
|
148 |
|
149 |
esc_html_e( 'or CNAME:', 'w3-total-cache' );
|
181 |
</td>
|
182 |
</tr>
|
183 |
<tr>
|
184 |
+
<th><label for="cdn_s3_public_objects"><?php esc_html_e( 'Set objects to publicly accessible on upload:', 'w3-total-cache' ); ?></label></th>
|
185 |
<td>
|
186 |
+
<select id="cdn_s3_public_objects" name="cdn__s3__public_objects" <?php Util_Ui::sealing_disabled( 'cdn.' ); ?> >
|
187 |
<option value="enabled"<?php selected( $this->_config->get_string( 'cdn.s3.public_objects' ), 'enabled' ); ?>><?php esc_html_e( 'Enabled (apply the \'public-read\' ACL)', 'w3-total-cache' ); ?></option>
|
188 |
<option value="disabled"<?php selected( $this->_config->get_string( 'cdn.s3.public_objects' ), 'disabled' ); ?>><?php esc_html_e( 'Disabled (don\'t apply an ACL)', 'w3-total-cache' ); ?></option>
|
189 |
</select>
|
pub/js/options.js
CHANGED
@@ -321,6 +321,11 @@ function w3tc_csp_reference() {
|
|
321 |
}
|
322 |
|
323 |
function cdn_cf_check() {
|
|
|
|
|
|
|
|
|
|
|
324 |
var cdnEnabled = jQuery( '#cdn__enabled' ).is( ':checked' ),
|
325 |
cdnEngine = jQuery( '#cdn__engine' ).find( ':selected' ).val(),
|
326 |
cdnFlushManually = jQuery( '[name="cdn__flush_manually"]' ).is( ':checked' );
|
321 |
}
|
322 |
|
323 |
function cdn_cf_check() {
|
324 |
+
// Prevents JS error for non W3TC pages.
|
325 |
+
if ( typeof w3tcData === 'undefined' ) {
|
326 |
+
return;
|
327 |
+
}
|
328 |
+
|
329 |
var cdnEnabled = jQuery( '#cdn__enabled' ).is( ':checked' ),
|
330 |
cdnEngine = jQuery( '#cdn__engine' ).find( ':selected' ).val(),
|
331 |
cdnFlushManually = jQuery( '[name="cdn__flush_manually"]' ).is( ':checked' );
|
readme.txt
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
=== Plugin Name ===
|
2 |
Contributors: boldgrid, fredericktownes, maxicusc, gidomanders, bwmarkle, harryjackson1221, joemoto, vmarko, jacobd91
|
3 |
Tags: seo, cache, CDN, pagespeed, caching, performance, compression, optimize, cloudflare, nginx, apache, varnish, redis, aws, amazon web services, s3, cloudfront, azure
|
4 |
-
Requires at least: 3
|
5 |
Tested up to: 6.0
|
6 |
-
Stable tag: 2.2.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -285,6 +285,18 @@ Please reach out to all of these people and support their projects if you're so
|
|
285 |
|
286 |
== Changelog ==
|
287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
= 2.2.4 =
|
289 |
* Fix: Extensions URL in settings
|
290 |
* Fix: Redis undefined array key warnings
|
1 |
=== Plugin Name ===
|
2 |
Contributors: boldgrid, fredericktownes, maxicusc, gidomanders, bwmarkle, harryjackson1221, joemoto, vmarko, jacobd91
|
3 |
Tags: seo, cache, CDN, pagespeed, caching, performance, compression, optimize, cloudflare, nginx, apache, varnish, redis, aws, amazon web services, s3, cloudfront, azure
|
4 |
+
Requires at least: 5.3
|
5 |
Tested up to: 6.0
|
6 |
+
Stable tag: 2.2.6
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
285 |
|
286 |
== Changelog ==
|
287 |
|
288 |
+
= 2.2.6 =
|
289 |
+
* Fix: Error clearing all cache when using Cloudfront full CDN in Pro
|
290 |
+
|
291 |
+
= 2.2.5 =
|
292 |
+
* Fix: Revert WooCommerce Variation Image Gallery plugin CDN filter
|
293 |
+
* Fix: DB cache syntax error in PHP 5.6
|
294 |
+
* Fix: Added missing space to S3 CDN bucket label
|
295 |
+
* Fix: JS error for CloudFront CDN related check on non-W3TC pages
|
296 |
+
* Fix: Page cache unpack warning for empty/malformed files
|
297 |
+
* Enhancement: Image Service pre_get_posts anonymous action now hooked (w3tc_modify_query_obj)
|
298 |
+
* Enhancement: Image Service ajax_query_attachments_args anonymous action now hooked (w3tc_filter_ajax_args)
|
299 |
+
|
300 |
= 2.2.4 =
|
301 |
* Fix: Extensions URL in settings
|
302 |
* Fix: Redis undefined array key warnings
|
w3-total-cache-api.php
CHANGED
@@ -12,7 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
12 |
}
|
13 |
|
14 |
define( 'W3TC', true );
|
15 |
-
define( 'W3TC_VERSION', '2.2.
|
16 |
define( 'W3TC_POWERED_BY', 'W3 Total Cache' );
|
17 |
define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' );
|
18 |
define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' );
|
12 |
}
|
13 |
|
14 |
define( 'W3TC', true );
|
15 |
+
define( 'W3TC_VERSION', '2.2.6' );
|
16 |
define( 'W3TC_POWERED_BY', 'W3 Total Cache' );
|
17 |
define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' );
|
18 |
define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' );
|
w3-total-cache.php
CHANGED
@@ -3,8 +3,8 @@
|
|
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.2.
|
7 |
-
* Requires at least: 3
|
8 |
* Requires PHP: 5.6
|
9 |
* Author: BoldGrid
|
10 |
* Author URI: https://www.boldgrid.com/
|
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.2.6
|
7 |
+
* Requires at least: 5.3
|
8 |
* Requires PHP: 5.6
|
9 |
* Author: BoldGrid
|
10 |
* Author URI: https://www.boldgrid.com/
|