W3 Total Cache - Version 0.9.7.2

Version Description

  • Fixed fatal error during media file upload with CDN module active
  • Fixed removal of empty values, JSON encoded string in attribute, trailing quote at end of tag, and the handling of anchors in HTML minify
  • Fixed undefined index warning
  • Fixed fatal error when purging CDN using full site delivery
Download this release

Release Info

Developer fredericktownes
Plugin Icon 128x128 W3 Total Cache
Version 0.9.7.2
Comparing to
See all releases

Code changes from version 0.9.7.1 to 0.9.7.2

Cdn_Plugin.php CHANGED
@@ -72,7 +72,7 @@ class Cdn_Plugin {
72
  array( $this, 'delete_attachment' ) );
73
 
74
  add_filter( 'wp_insert_attachment_data',
75
- array( $this, 'check_inserting_new_attachment' ) );
76
 
77
  add_filter( 'update_attached_file',
78
  array( $this, 'update_attached_file' ) );
72
  array( $this, 'delete_attachment' ) );
73
 
74
  add_filter( 'wp_insert_attachment_data',
75
+ array( $this, 'check_inserting_new_attachment' ), 10, 2 );
76
 
77
  add_filter( 'update_attached_file',
78
  array( $this, 'update_attached_file' ) );
Cdnfsd_CacheFlush.php CHANGED
@@ -197,6 +197,7 @@ class Cdnfsd_CacheFlush {
197
  * @param unknown $url
198
  */
199
  static public function w3tc_flush_url( $url, $extras = null ) {
 
200
  if ( $config->get_boolean( 'cdn.flush_manually' ) ) {
201
  // in this mode flush only on purge button clicks
202
  if ( !isset( $extras['ui_action'] ) ) {
197
  * @param unknown $url
198
  */
199
  static public function w3tc_flush_url( $url, $extras = null ) {
200
+ $config = Dispatcher::config();
201
  if ( $config->get_boolean( 'cdn.flush_manually' ) ) {
202
  // in this mode flush only on purge button clicks
203
  if ( !isset( $extras['ui_action'] ) ) {
lib/Minify/Minify/HTML.php CHANGED
@@ -17,166 +17,166 @@
17
  * @author Stephen Clay <steve@mrclay.org>
18
  */
19
  class Minify_HTML {
20
- /**
21
- * @var boolean
22
- */
23
- protected $_jsCleanComments = true;
24
-
25
- /**
26
- * "Minify" an HTML page
27
- *
28
- * @param string $html
29
- *
30
- * @param array $options
31
- *
32
- * 'cssMinifier' : (optional) callback function to process content of STYLE
33
- * elements.
34
- *
35
- * 'jsMinifier' : (optional) callback function to process content of SCRIPT
36
- * elements. Note: the type attribute is ignored.
37
- *
38
- * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
39
- * unset, minify will sniff for an XHTML doctype.
40
- *
41
- * @return string
42
- */
43
- public static function minify($html, $options = array()) {
44
- $min = new self($html, $options);
45
- return $min->process();
46
- }
47
-
48
-
49
- /**
50
- * Create a minifier object
51
- *
52
- * @param string $html
53
- *
54
- * @param array $options
55
- *
56
- * 'cssMinifier' : (optional) callback function to process content of STYLE
57
- * elements.
58
- *
59
- * 'jsMinifier' : (optional) callback function to process content of SCRIPT
60
- * elements. Note: the type attribute is ignored.
61
- *
62
- * 'jsCleanComments' : (optional) whether to remove HTML comments beginning and end of script block
63
- *
64
- * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
65
- * unset, minify will sniff for an XHTML doctype.
66
- *
67
- * @return null
68
- */
69
- public function __construct($html, $options = array())
70
- {
71
- $this->_html = str_replace("\r\n", "\n", trim($html));
72
- if (isset($options['xhtml'])) {
73
- $this->_isXhtml = (bool)$options['xhtml'];
74
- }
75
- if (isset($options['cssMinifier'])) {
76
- $this->_cssMinifier = $options['cssMinifier'];
77
- }
78
- if (isset($options['jsMinifier'])) {
79
- $this->_jsMinifier = $options['jsMinifier'];
80
- }
81
-
82
- $this->_stripCrlf = (isset($options['stripCrlf']) ? (boolean) $options['stripCrlf'] : false) ;
83
- $this->_ignoredComments = (isset($options['ignoredComments']) ? (array) $options['ignoredComments'] : array());
84
- }
85
-
86
-
87
- /**
88
- * Minify the markeup given in the constructor
89
- *
90
- * @return string
91
- */
92
- public function process()
93
- {
94
- if ($this->_isXhtml === null) {
95
- $this->_isXhtml = (false !== strpos($this->_html, '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML'));
96
- }
97
-
98
- $this->_replacementHash = 'MINIFYHTML' . md5($_SERVER['REQUEST_TIME']);
99
- $this->_placeholders = array();
100
-
101
- // replace dynamic tags
102
- $this->_html = preg_replace_callback(
103
- '~(<!--\s*m(func|clude)(.*)-->\s*<!--\s*/m(func|clude)\s*-->)~is'
104
- ,array($this, '_removeComment')
105
- ,$this->_html);
106
-
107
- // replace SCRIPTs (and minify) with placeholders
108
- $this->_html = preg_replace_callback(
109
- '/(\\s*)<script(\\b[^>]*?>)([\\s\\S]*?)<\\/script>(\\s*)/i'
110
- ,array($this, '_removeScriptCB')
111
- ,$this->_html);
112
-
113
- // replace STYLEs (and minify) with placeholders
114
- $this->_html = preg_replace_callback(
115
- '/\\s*<style(\\b[^>]*>)([\\s\\S]*?)<\\/style>\\s*/i'
116
- ,array($this, '_removeStyleCB')
117
- ,$this->_html);
118
-
119
- // remove HTML comments (not containing IE conditional comments).
120
- $this->_html = preg_replace_callback(
121
- '/<!--([\\s\\S]*?)-->/'
122
- ,array($this, '_commentCB')
123
- ,$this->_html);
124
-
125
- // replace PREs with placeholders
126
- $this->_html = preg_replace_callback('/\\s*<pre(\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/i'
127
- ,array($this, '_removePreCB')
128
- ,$this->_html);
129
-
130
- // replace TEXTAREAs with placeholders
131
- $this->_html = preg_replace_callback(
132
- '/\\s*<textarea(\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/i'
133
- ,array($this, '_removeTextareaCB')
134
- ,$this->_html);
135
-
136
- // trim each line.
137
- // @todo take into account attribute values that span multiple lines.
138
- $this->_html = preg_replace('/^\\s+|\\s+$/m', '', $this->_html);
139
-
140
- // remove ws around block/undisplayed elements
141
- $this->_html = preg_replace('/\\s+(<\\/?(?:area|base(?:font)?|blockquote|body'
142
- .'|caption|center|col(?:group)?|dd|dir|div|dl|dt|fieldset|form'
143
- .'|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta'
144
- .'|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h||r|foot|itle)'
145
- .'|ul)\\b[^>]*>)/i', '$1', $this->_html);
146
-
147
- // remove ws outside of all elements
148
- $this->_html = preg_replace(
149
- '/(^|>)\\s+\\b([^<]+)\\b\\s+?(<|$)/'
150
- ,'$1 $2 $3'
151
- ,$this->_html);
152
-
153
- // remove ws before end of all empty elements
154
  $this->_html = preg_replace(
155
  '/\\s*\\/>/'
156
  ,'/>'
157
  ,$this->_html);
158
 
159
- // use newlines before 1st attribute in open tags (to limit line lengths)
160
- $this->_html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/i', "$1\n$2", $this->_html);
161
-
162
- if ($this->_stripCrlf) {
163
- $this->_html = preg_replace("~[\r\n]+~", ' ', $this->_html);
164
- } else {
165
- $this->_html = preg_replace("~[\r\n]+~", "\n", $this->_html);
166
- }
167
-
168
- // fill placeholders
169
- $this->_html = str_replace(
170
- array_keys($this->_placeholders)
171
- ,array_values($this->_placeholders)
172
- ,$this->_html
173
- );
174
- // issue 229: multi-pass to catch scripts that didn't get replaced in textareas
175
- $this->_html = str_replace(
176
- array_keys($this->_placeholders)
177
- ,array_values($this->_placeholders)
178
- ,$this->_html
179
- );
180
 
181
  // remove trailing slash from void elements
182
  $this->_html = preg_replace(
@@ -199,153 +199,156 @@ class Minify_HTML {
199
  ,array($this, '_removeAttributeQuotes')
200
  ,$this->_html);
201
 
202
- return $this->_html;
203
- }
204
-
205
- protected function _commentCB($m)
206
- {
207
- return (0 === strpos($m[1], '[') || false !== strpos($m[1], '<![') || $this->_ignoredComment($m[1]))
208
- ? $m[0]
209
- : '';
210
- }
211
-
212
- protected function _ignoredComment($comment)
213
- {
214
- foreach ($this->_ignoredComments as $ignoredComment) {
215
- if (!empty($ignoredComment) && stristr($comment, $ignoredComment) !== false) {
216
- return true;
217
- }
218
- }
219
-
220
- return false;
221
- }
222
-
223
- protected function _reservePlace($content)
224
- {
225
- $placeholder = '%' . $this->_replacementHash . count($this->_placeholders) . '%';
226
- $this->_placeholders[$placeholder] = $content;
227
- return $placeholder;
228
- }
229
-
230
- protected $_isXhtml = null;
231
- protected $_replacementHash = null;
232
- protected $_placeholders = array();
233
- protected $_cssMinifier = null;
234
- protected $_jsMinifier = null;
235
- protected $_stripCrlf = null;
236
- protected $_ignoredComments = null;
237
-
238
- protected function _removePreCB($m)
239
- {
240
- return $this->_reservePlace("<pre{$m[1]}");
241
- }
242
-
243
- protected function _removeTextareaCB($m)
244
- {
245
- return $this->_reservePlace("<textarea{$m[1]}");
246
- }
247
-
248
- protected function _removeStyleCB($m)
249
- {
250
- $openStyle = "<style{$m[1]}";
251
- $css = $m[2];
252
- // remove HTML comments
253
- $css = preg_replace('/(?:^\\s*<!--|-->\\s*$)/', '', $css);
254
-
255
- // remove CDATA section markers
256
- $css = $this->_removeCdata($css);
257
-
258
- // minify
259
- $minifier = $this->_cssMinifier
260
- ? $this->_cssMinifier
261
- : 'trim';
262
- $css = call_user_func($minifier, $css);
263
-
264
- return $this->_reservePlace($this->_needsCdata($css)
265
- ? "{$openStyle}/*<![CDATA[*/{$css}/*]]>*/</style>"
266
- : "{$openStyle}{$css}</style>"
267
- );
268
- }
269
-
270
- protected function _removeScriptCB($m)
271
- {
272
- $openScript = "<script{$m[2]}";
273
- $js = $m[3];
274
-
275
- $script_tag = "<script{$m[2]}>{$js}</script>";
276
-
277
- $type = '';
278
- if (preg_match('#type="([^"]+)"#i', $m[2], $matches)) {
279
- $type = strtolower($matches[1]);
280
- }
281
-
282
- // whitespace surrounding? preserve at least one space
283
- $ws1 = ($m[1] === '') ? '' : ' ';
284
- $ws2 = ($m[4] === '') ? '' : ' ';
285
-
286
- // remove HTML comments (and ending "//" if present)
287
- if ($this->_jsCleanComments) {
288
- $js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js);
289
- }
290
-
291
- // minify
292
- $minifier = $this->_jsMinifier
293
- ? $this->_jsMinifier
294
- : 'trim';
295
-
296
- if (in_array($type, array('text/template', 'text/x-handlebars-template'))) {
297
- $minifier = '';
298
- }
299
-
300
- $minifier = apply_filters('w3tc_minify_html_script_minifier', $minifier, $type, $script_tag);
301
-
302
- if (empty($minifier)) {
303
- $needsCdata = false;
304
- } else {
305
- // remove CDATA section markers
306
- $js_old = $js;
307
- $js = $this->_removeCdata($js);
308
- $needsCdata = ( $js_old != $js );
309
-
310
- $js = call_user_func($minifier, $js);
311
- }
312
-
313
- return $this->_reservePlace($needsCdata && $this->_needsCdata($js)
314
- ? "{$ws1}{$openScript}/*<![CDATA[*/{$js}/*]]>*/</script>{$ws2}"
315
- : "{$ws1}{$openScript}{$js}</script>{$ws2}"
316
- );
317
- }
318
-
319
- protected function _removeCdata($str)
320
- {
321
- if (false !== strpos($str, '<![CDATA[')) {
322
- $str = str_replace('//<![CDATA[', '', $str);
323
-
324
- $str = preg_replace('~/\*\s*<!\[CDATA\[\s*\*/~', '', $str);
325
- $str = str_replace('<![CDATA[', '', $str);
326
-
327
- $str = str_replace('//]]>', '', $str);
328
- $str = preg_replace('~/\*\s*\]\]>\s*\*/~', '', $str);
329
- $str = str_replace(']]>', '', $str);
330
- }
331
-
332
- return $str;
333
- }
334
-
335
- protected function _removeComment($m)
336
- {
337
- return $this->_reservePlace($m[1]);
338
- }
339
-
340
- protected function _needsCdata($str)
341
- {
342
- return ($this->_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str));
343
- }
344
-
345
- protected function _removeAttributeQuotes($m) {
346
- $m[2] = preg_replace('/([a-z0-9]=)[\'"]([^\'"\\s=]+)[\'"](?!\\/)/i', '$1$2', $m[2]);
347
- $m[2] = preg_replace('/([a-z0-9]=)[\'"]([^\'"\\s=]+)[\'"]\\//i', '$1$2 /', $m[2]);
348
- $m[2] = preg_replace('/([a-z0-9])=[\'"][\'"]/i', '$1', $m[2]);
 
 
 
349
  return $m[1] . $m[2];
350
  }
351
  }
17
  * @author Stephen Clay <steve@mrclay.org>
18
  */
19
  class Minify_HTML {
20
+ /**
21
+ * @var boolean
22
+ */
23
+ protected $_jsCleanComments = true;
24
+
25
+ /**
26
+ * "Minify" an HTML page
27
+ *
28
+ * @param string $html
29
+ *
30
+ * @param array $options
31
+ *
32
+ * 'cssMinifier' : (optional) callback function to process content of STYLE
33
+ * elements.
34
+ *
35
+ * 'jsMinifier' : (optional) callback function to process content of SCRIPT
36
+ * elements. Note: the type attribute is ignored.
37
+ *
38
+ * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
39
+ * unset, minify will sniff for an XHTML doctype.
40
+ *
41
+ * @return string
42
+ */
43
+ public static function minify($html, $options = array()) {
44
+ $min = new self($html, $options);
45
+ return $min->process();
46
+ }
47
+
48
+
49
+ /**
50
+ * Create a minifier object
51
+ *
52
+ * @param string $html
53
+ *
54
+ * @param array $options
55
+ *
56
+ * 'cssMinifier' : (optional) callback function to process content of STYLE
57
+ * elements.
58
+ *
59
+ * 'jsMinifier' : (optional) callback function to process content of SCRIPT
60
+ * elements. Note: the type attribute is ignored.
61
+ *
62
+ * 'jsCleanComments' : (optional) whether to remove HTML comments beginning and end of script block
63
+ *
64
+ * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
65
+ * unset, minify will sniff for an XHTML doctype.
66
+ *
67
+ * @return null
68
+ */
69
+ public function __construct($html, $options = array())
70
+ {
71
+ $this->_html = str_replace("\r\n", "\n", trim($html));
72
+ if (isset($options['xhtml'])) {
73
+ $this->_isXhtml = (bool)$options['xhtml'];
74
+ }
75
+ if (isset($options['cssMinifier'])) {
76
+ $this->_cssMinifier = $options['cssMinifier'];
77
+ }
78
+ if (isset($options['jsMinifier'])) {
79
+ $this->_jsMinifier = $options['jsMinifier'];
80
+ }
81
+
82
+ $this->_stripCrlf = (isset($options['stripCrlf']) ? (boolean) $options['stripCrlf'] : false) ;
83
+ $this->_ignoredComments = (isset($options['ignoredComments']) ? (array) $options['ignoredComments'] : array());
84
+ }
85
+
86
+
87
+ /**
88
+ * Minify the markeup given in the constructor
89
+ *
90
+ * @return string
91
+ */
92
+ public function process()
93
+ {
94
+ if ($this->_isXhtml === null) {
95
+ $this->_isXhtml = (false !== strpos($this->_html, '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML'));
96
+ }
97
+
98
+ $this->_replacementHash = 'MINIFYHTML' . md5($_SERVER['REQUEST_TIME']);
99
+ $this->_placeholders = array();
100
+
101
+ // replace dynamic tags
102
+ $this->_html = preg_replace_callback(
103
+ '~(<!--\s*m(func|clude)(.*)-->\s*<!--\s*/m(func|clude)\s*-->)~is'
104
+ ,array($this, '_removeComment')
105
+ ,$this->_html);
106
+
107
+ // replace SCRIPTs (and minify) with placeholders
108
+ $this->_html = preg_replace_callback(
109
+ '/(\\s*)<script(\\b[^>]*?>)([\\s\\S]*?)<\\/script>(\\s*)/i'
110
+ ,array($this, '_removeScriptCB')
111
+ ,$this->_html);
112
+
113
+ // replace STYLEs (and minify) with placeholders
114
+ $this->_html = preg_replace_callback(
115
+ '/\\s*<style(\\b[^>]*>)([\\s\\S]*?)<\\/style>\\s*/i'
116
+ ,array($this, '_removeStyleCB')
117
+ ,$this->_html);
118
+
119
+ // remove HTML comments (not containing IE conditional comments).
120
+ $this->_html = preg_replace_callback(
121
+ '/<!--([\\s\\S]*?)-->/'
122
+ ,array($this, '_commentCB')
123
+ ,$this->_html);
124
+
125
+ // replace PREs with placeholders
126
+ $this->_html = preg_replace_callback('/\\s*<pre(\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/i'
127
+ ,array($this, '_removePreCB')
128
+ ,$this->_html);
129
+
130
+ // replace TEXTAREAs with placeholders
131
+ $this->_html = preg_replace_callback(
132
+ '/\\s*<textarea(\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/i'
133
+ ,array($this, '_removeTextareaCB')
134
+ ,$this->_html);
135
+
136
+ // trim each line.
137
+ // @todo take into account attribute values that span multiple lines.
138
+ $this->_html = preg_replace('/^\\s+|\\s+$/m', '', $this->_html);
139
+
140
+ // remove ws around block/undisplayed elements
141
+ $this->_html = preg_replace('/\\s+(<\\/?(?:area|base(?:font)?|blockquote|body'
142
+ .'|caption|center|col(?:group)?|dd|dir|div|dl|dt|fieldset|form'
143
+ .'|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta'
144
+ .'|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h||r|foot|itle)'
145
+ .'|ul)\\b[^>]*>)/i', '$1', $this->_html);
146
+
147
+ // remove ws outside of all elements
148
+ $this->_html = preg_replace(
149
+ '/(^|>)\\s+\\b([^<]+)\\b\\s+?(<|$)/'
150
+ ,'$1 $2 $3'
151
+ ,$this->_html);
152
+
153
+ // remove ws before end of all empty elements
154
  $this->_html = preg_replace(
155
  '/\\s*\\/>/'
156
  ,'/>'
157
  ,$this->_html);
158
 
159
+ // use newlines before 1st attribute in open tags (to limit line lengths)
160
+ $this->_html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/i', "$1\n$2", $this->_html);
161
+
162
+ if ($this->_stripCrlf) {
163
+ $this->_html = preg_replace("~[\r\n]+~", ' ', $this->_html);
164
+ } else {
165
+ $this->_html = preg_replace("~[\r\n]+~", "\n", $this->_html);
166
+ }
167
+
168
+ // fill placeholders
169
+ $this->_html = str_replace(
170
+ array_keys($this->_placeholders)
171
+ ,array_values($this->_placeholders)
172
+ ,$this->_html
173
+ );
174
+ // issue 229: multi-pass to catch scripts that didn't get replaced in textareas
175
+ $this->_html = str_replace(
176
+ array_keys($this->_placeholders)
177
+ ,array_values($this->_placeholders)
178
+ ,$this->_html
179
+ );
180
 
181
  // remove trailing slash from void elements
182
  $this->_html = preg_replace(
199
  ,array($this, '_removeAttributeQuotes')
200
  ,$this->_html);
201
 
202
+ return $this->_html;
203
+ }
204
+
205
+ protected function _commentCB($m)
206
+ {
207
+ return (0 === strpos($m[1], '[') || false !== strpos($m[1], '<![') || $this->_ignoredComment($m[1]))
208
+ ? $m[0]
209
+ : '';
210
+ }
211
+
212
+ protected function _ignoredComment($comment)
213
+ {
214
+ foreach ($this->_ignoredComments as $ignoredComment) {
215
+ if (!empty($ignoredComment) && stristr($comment, $ignoredComment) !== false) {
216
+ return true;
217
+ }
218
+ }
219
+
220
+ return false;
221
+ }
222
+
223
+ protected function _reservePlace($content)
224
+ {
225
+ $placeholder = '%' . $this->_replacementHash . count($this->_placeholders) . '%';
226
+ $this->_placeholders[$placeholder] = $content;
227
+ return $placeholder;
228
+ }
229
+
230
+ protected $_isXhtml = null;
231
+ protected $_replacementHash = null;
232
+ protected $_placeholders = array();
233
+ protected $_cssMinifier = null;
234
+ protected $_jsMinifier = null;
235
+ protected $_stripCrlf = null;
236
+ protected $_ignoredComments = null;
237
+
238
+ protected function _removePreCB($m)
239
+ {
240
+ return $this->_reservePlace("<pre{$m[1]}");
241
+ }
242
+
243
+ protected function _removeTextareaCB($m)
244
+ {
245
+ return $this->_reservePlace("<textarea{$m[1]}");
246
+ }
247
+
248
+ protected function _removeStyleCB($m)
249
+ {
250
+ $openStyle = "<style{$m[1]}";
251
+ $css = $m[2];
252
+ // remove HTML comments
253
+ $css = preg_replace('/(?:^\\s*<!--|-->\\s*$)/', '', $css);
254
+
255
+ // remove CDATA section markers
256
+ $css = $this->_removeCdata($css);
257
+
258
+ // minify
259
+ $minifier = $this->_cssMinifier
260
+ ? $this->_cssMinifier
261
+ : 'trim';
262
+ $css = call_user_func($minifier, $css);
263
+
264
+ return $this->_reservePlace($this->_needsCdata($css)
265
+ ? "{$openStyle}/*<![CDATA[*/{$css}/*]]>*/</style>"
266
+ : "{$openStyle}{$css}</style>"
267
+ );
268
+ }
269
+
270
+ protected function _removeScriptCB($m)
271
+ {
272
+ $openScript = "<script{$m[2]}";
273
+ $js = $m[3];
274
+
275
+ $script_tag = "<script{$m[2]}>{$js}</script>";
276
+
277
+ $type = '';
278
+ if (preg_match('#type="([^"]+)"#i', $m[2], $matches)) {
279
+ $type = strtolower($matches[1]);
280
+ }
281
+
282
+ // whitespace surrounding? preserve at least one space
283
+ $ws1 = ($m[1] === '') ? '' : ' ';
284
+ $ws2 = ($m[4] === '') ? '' : ' ';
285
+
286
+ // remove HTML comments (and ending "//" if present)
287
+ if ($this->_jsCleanComments) {
288
+ $js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js);
289
+ }
290
+
291
+ // minify
292
+ $minifier = $this->_jsMinifier
293
+ ? $this->_jsMinifier
294
+ : 'trim';
295
+
296
+ if (in_array($type, array('text/template', 'text/x-handlebars-template'))) {
297
+ $minifier = '';
298
+ }
299
+
300
+ $minifier = apply_filters('w3tc_minify_html_script_minifier', $minifier, $type, $script_tag);
301
+
302
+ if (empty($minifier)) {
303
+ $needsCdata = false;
304
+ } else {
305
+ // remove CDATA section markers
306
+ $js_old = $js;
307
+ $js = $this->_removeCdata($js);
308
+ $needsCdata = ( $js_old != $js );
309
+
310
+ $js = call_user_func($minifier, $js);
311
+ }
312
+
313
+ return $this->_reservePlace($needsCdata && $this->_needsCdata($js)
314
+ ? "{$ws1}{$openScript}/*<![CDATA[*/{$js}/*]]>*/</script>{$ws2}"
315
+ : "{$ws1}{$openScript}{$js}</script>{$ws2}"
316
+ );
317
+ }
318
+
319
+ protected function _removeCdata($str)
320
+ {
321
+ if (false !== strpos($str, '<![CDATA[')) {
322
+ $str = str_replace('//<![CDATA[', '', $str);
323
+
324
+ $str = preg_replace('~/\*\s*<!\[CDATA\[\s*\*/~', '', $str);
325
+ $str = str_replace('<![CDATA[', '', $str);
326
+
327
+ $str = str_replace('//]]>', '', $str);
328
+ $str = preg_replace('~/\*\s*\]\]>\s*\*/~', '', $str);
329
+ $str = str_replace(']]>', '', $str);
330
+ }
331
+
332
+ return $str;
333
+ }
334
+
335
+ protected function _removeComment($m)
336
+ {
337
+ return $this->_reservePlace($m[1]);
338
+ }
339
+
340
+ protected function _needsCdata($str)
341
+ {
342
+ return ($this->_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str));
343
+ }
344
+
345
+ protected function _removeAttributeQuotes($m) {
346
+ $m[2] = preg_replace( '/([a-z0-9]=)\'([^"\'\\s=]+)\'(\\s(?!\\/)|>)/i', '$1$2$3', $m[2] );
347
+ $m[2] = preg_replace( '/([a-z0-9]=)"([^"\'\\s=]+)"(\\s(?!\\/)|>)/i', '$1$2$3', $m[2] );
348
+ $m[2] = preg_replace( '/([a-z0-9]=)\'([^\'\\s=]+)\'\\//i', '$1$2 /', $m[2] );
349
+ $m[2] = preg_replace( '/([a-z0-9]=)"([^"\\s=]+)"\\//i', '$1$2 /', $m[2] );
350
+ $m[2] = preg_replace( '/([a-z0-9])=\'\'/i', '$1', $m[2] );
351
+ $m[2] = preg_replace( '/([a-z0-9])=""/i', '$1', $m[2] );
352
  return $m[1] . $m[2];
353
  }
354
  }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: fredericktownes
3
  Tags: seo, cache, caching, compression, maxcdn, nginx, varnish, redis, new relic, aws, amazon web services, s3, cloudfront, rackspace, cloudflare, azure, apache
4
  Requires at least: 3.2
5
  Tested up to: 5.0.3
6
- Stable tag: 0.9.7.1
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -270,6 +270,12 @@ Please reach out to all of these people and support their projects if you're so
270
 
271
  == Changelog ==
272
 
 
 
 
 
 
 
273
  = 0.9.7.1 =
274
  * Fixed undefined variable notice
275
  * Fixed "No such file or directory" warning
3
  Tags: seo, cache, caching, compression, maxcdn, nginx, varnish, redis, new relic, aws, amazon web services, s3, cloudfront, rackspace, cloudflare, azure, apache
4
  Requires at least: 3.2
5
  Tested up to: 5.0.3
6
+ Stable tag: 0.9.7.2
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
270
 
271
  == Changelog ==
272
 
273
+ = 0.9.7.2 =
274
+ * Fixed fatal error during media file upload with CDN module active
275
+ * Fixed removal of empty values, JSON encoded string in attribute, trailing quote at end of tag, and the handling of anchors in HTML minify
276
+ * Fixed undefined index warning
277
+ * Fixed fatal error when purging CDN using full site delivery
278
+
279
  = 0.9.7.1 =
280
  * Fixed undefined variable notice
281
  * Fixed "No such file or directory" warning
w3-total-cache-api.php CHANGED
@@ -5,7 +5,7 @@ if ( !defined( 'ABSPATH' ) ) {
5
  }
6
 
7
  define( 'W3TC', true );
8
- define( 'W3TC_VERSION', '0.9.7.1' );
9
  define( 'W3TC_POWERED_BY', 'W3 Total Cache' );
10
  define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' );
11
  define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' );
@@ -639,6 +639,10 @@ function w3tc_er( $key, $default_value ) {
639
  $v = get_site_option( 'w3tc_generic_widgetservices' );
640
  try {
641
  $v = json_decode( $v, true );
 
 
 
 
642
  $v = $v['content'];
643
  } catch ( \Exception $e ) {
644
  return $default_value;
5
  }
6
 
7
  define( 'W3TC', true );
8
+ define( 'W3TC_VERSION', '0.9.7.2' );
9
  define( 'W3TC_POWERED_BY', 'W3 Total Cache' );
10
  define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' );
11
  define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' );
639
  $v = get_site_option( 'w3tc_generic_widgetservices' );
640
  try {
641
  $v = json_decode( $v, true );
642
+ if ( !isset( $v['content'] ) ) {
643
+ return $default_value;
644
+ }
645
+
646
  $v = $v['content'];
647
  } catch ( \Exception $e ) {
648
  return $default_value;
w3-total-cache.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: W3 Total Cache
4
  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.
5
- Version: 0.9.7.1
6
  Plugin URI: https://www.w3-edge.com/wordpress-plugins/w3-total-cache/
7
  Author: Frederick Townes
8
  Author URI: http://www.linkedin.com/in/fredericktownes
2
  /*
3
  Plugin Name: W3 Total Cache
4
  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.
5
+ Version: 0.9.7.2
6
  Plugin URI: https://www.w3-edge.com/wordpress-plugins/w3-total-cache/
7
  Author: Frederick Townes
8
  Author URI: http://www.linkedin.com/in/fredericktownes