W3 Total Cache - Version 0.8.5

Version Description

  • Added "enhanced" disk caching mode for page cache, a 160% performance improvement over basic mode
  • Added disk caching as an option for Database Cache
  • Added CDN support for Amazon S3 and CloudFront
  • Added mobile user agent rejection and redirect fields to page cache for handling mobile user agents
  • Added Submit Bug Report tab
  • Added support for detection of custom templates for minify groups
  • Added separate controls expiration time field for minify and page cache settings
  • Added PHP4 Support Notification to handle fatal errors on activation
  • Improved database caching by 45%
  • Improved handling of cache-control HTML headers
  • Improved handing of 3rd Party CSS file minification
  • Improved media library import reliability
  • Improved handling of DOCUMENT_ROOT on some servers
  • Improved garbage collection routine
  • Improved handling of <pre> and <textarea> minification
  • Improved handling of regular expressions in custom file list in CDN settings
  • Improved handling of media library attachments in RSS feeds
  • Improved handing of subdomains for CDN settings
  • Improved various notifications and error messages
  • Improved optional .htaccess directives (located in /ini/_htaccess)
  • Fixed bug with JS minifcation saving group settings
  • Fixed bug with false positives for duplicate CSS or JS in minify settings
  • Fixed bug causing settings to be lost on upgrade
  • Fixed bug with attachment URI when CDN mode enabled
  • Fixed small bug with FTP upload when CDN Method is Mirror (Origin Pull)
  • Fixed bug with the URI for wlwmanfiest.xml when CDN enabled
  • Fixed bug with handling of HTTPS objects according to options
  • Fixed bug with emptying disk cache under various obscure permutations
  • Fixed bug with handling of obscure open_basedir restrictions
  • Fixed various bugs with emptying cache under various obscure permutations
  • Fixed bug with installations deeper than document root
Download this release

Release Info

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

Code changes from version 0.8 to 0.8.5

Files changed (91) hide show
  1. inc/css/lightbox.css +29 -0
  2. inc/css/options.css +64 -43
  3. inc/css/popup.css +117 -91
  4. inc/define.php +552 -75
  5. inc/images/loader.gif +0 -0
  6. inc/js/lightbox.js +247 -0
  7. inc/js/options.js +165 -10
  8. inc/js/popup.js +102 -203
  9. inc/lightbox/support_us.phtml +25 -0
  10. inc/lightbox/tweet.phtml +26 -0
  11. inc/options/about.phtml +5 -1
  12. inc/options/cdn.phtml +42 -69
  13. inc/options/cdn/cf.phtml +33 -0
  14. inc/options/cdn/ftp.phtml +43 -0
  15. inc/options/cdn/mirror.phtml +9 -0
  16. inc/options/cdn/s3.phtml +36 -0
  17. inc/options/common/header.phtml +34 -23
  18. inc/options/dbcache.phtml +35 -7
  19. inc/options/faq.phtml +83 -26
  20. inc/options/general.phtml +56 -42
  21. inc/options/install.phtml +21 -19
  22. inc/options/minify.phtml +55 -50
  23. inc/options/pgcache.phtml +74 -22
  24. inc/options/support.phtml +86 -0
  25. inc/options/support_email.phtml +21 -0
  26. inc/popup/cdn_export_file.phtml +5 -1
  27. inc/popup/cdn_export_library.phtml +5 -1
  28. inc/popup/cdn_import_library.phtml +5 -1
  29. inc/popup/cdn_queue.phtml +7 -3
  30. inc/popup/cdn_rename_domain.phtml +8 -1
  31. ini/_htaccess +87 -28
  32. ini/apc.ini +2 -5
  33. ini/memcache.ini +2 -2
  34. ini/memcached.conf +0 -7
  35. lib/Minify/HTTP/ConditionalGet.php +1 -1
  36. lib/Minify/Minify.php +34 -11
  37. lib/Minify/Minify/Build.php +1 -1
  38. lib/Minify/Minify/CSS.php +3 -3
  39. lib/Minify/Minify/CSS/UriRewriter.php +30 -8
  40. lib/Minify/Minify/Cache/File.php +1 -1
  41. lib/Minify/Minify/Controller/Base.php +2 -2
  42. lib/Minify/Minify/Controller/Files.php +1 -1
  43. lib/Minify/Minify/Controller/Groups.php +1 -1
  44. lib/Minify/Minify/Controller/MinApp.php +1 -1
  45. lib/Minify/Minify/Controller/Page.php +3 -3
  46. lib/Minify/Minify/Controller/Version1.php +1 -1
  47. lib/Minify/Minify/HTML.php +33 -1
  48. lib/Minify/Minify/Lines.php +10 -3
  49. lib/Minify/Minify/Packer.php +1 -1
  50. lib/Minify/Minify/Source.php +1 -0
  51. lib/S3.php +1335 -0
  52. lib/W3/Cache.php +10 -1
  53. lib/W3/Cache/Base.php +11 -11
  54. lib/W3/Cache/File.php +35 -10
  55. lib/W3/Cache/File/Manager.php +16 -12
  56. lib/W3/Cache/File/Minify/Manager.php +41 -0
  57. lib/W3/Cache/File/PgCache.php +113 -0
  58. lib/W3/Cache/File/PgCache/Manager.php +41 -0
  59. lib/W3/Cache/Memcached/Base.php +5 -5
  60. lib/W3/Cache/Memcached/Client.php +4 -4
  61. lib/W3/Cache/Memcached/memcached-client.php +0 -977
  62. lib/W3/Cdn.php +13 -4
  63. lib/W3/Cdn/Base.php +48 -6
  64. lib/W3/Cdn/Cf.php +100 -2
  65. lib/W3/Cdn/Ftp.php +31 -17
  66. lib/W3/Cdn/Mirror.php +64 -0
  67. lib/W3/Cdn/S3.php +242 -1
  68. lib/W3/Config.php +398 -50
  69. lib/W3/Db.php +55 -60
  70. lib/W3/Minify.php +60 -60
  71. lib/W3/PgCache.php +471 -395
  72. lib/W3/Plugin.php +18 -15
  73. lib/W3/Plugin/Cdn.php +259 -334
  74. lib/W3/Plugin/DbCache.php +155 -4
  75. lib/W3/Plugin/Minify.php +336 -134
  76. lib/W3/Plugin/PgCache.php +501 -24
  77. lib/W3/Plugin/TotalCache.php +1879 -466
  78. lib/W3/Request.php +1 -1
  79. lib/memcached-client.php +977 -0
  80. readme.txt +51 -15
  81. tools/apc.php +0 -1362
  82. tools/memcache.php +0 -880
  83. tools/phpinfo.php +0 -2
  84. w3-total-cache-config-default.php +0 -157
  85. w3-total-cache-config-example.php +249 -0
  86. w3-total-cache.php +8 -3
  87. wp-content/advanced-cache.php +2 -2
  88. wp-content/db.php +2 -2
  89. wp-content/w3tc/_htaccess +0 -10
  90. wp-content/w3tc/index.html +0 -0
  91. wp-content/w3tc/{minify.php → min/index.php} +3 -3
inc/css/lightbox.css ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #overlay {
2
+ background:#666;
3
+ }
4
+
5
+ .lightbox {
6
+ background:#f9f9f9;
7
+ padding:10px 20px;
8
+ border:1px solid #bbb;
9
+ border-radius:11px;
10
+ -webkit-border-radius:11px;
11
+ -moz-border-radius:11px;
12
+ }
13
+
14
+ .lightbox-close {
15
+ cursor:hand;
16
+ cursor:pointer;
17
+ text-decoration:underline;
18
+ float:right;
19
+ }
20
+
21
+ .lightbox-loader {
22
+ background-image:url(../images/loader.gif);
23
+ background-position:center center;
24
+ background-repeat:no-repeat;
25
+ }
26
+
27
+ .lightbox th {
28
+ width:80px;
29
+ }
inc/css/options.css CHANGED
@@ -1,88 +1,109 @@
1
  #icon-w3tc-logo {
2
- background:url(../images/logo.png) no-repeat;
3
- float:left;
4
- height: 36px;
5
- width:36px
6
  }
 
7
  .w3tc-options-menu-selected {
8
- font-weight:bold
9
  }
 
10
  .w3tc-enabled {
11
- color: #090;
12
- font-weight:bold
13
  }
 
14
  .w3tc-disabled {
15
- color: #f00;
16
- font-weight:bold
17
  }
 
18
  .w3tc-empty {
19
- font-weight: bold;
20
- font-style:italic
21
  }
 
22
  .w3tc-success {
23
- background:#bfb
24
  }
 
25
  .w3tc-error {
26
- background:#f99
27
  }
 
28
  .w3tc-status {
29
- padding:5px
30
  }
 
31
  #w3tc acronym {
32
- border-bottom:1px dotted #666
33
  }
 
34
  #w3tc ul {
35
- list-style-type:disc;
36
- list-style-position:inside
37
  }
 
38
  #w3tc blockquote {
39
- font-style:italic;
40
- width:700px
41
  }
 
42
  #w3tc blockquote cite {
43
- font-style:normal
44
  }
 
45
  #w3tc h5 {
46
- margin:0
47
  }
 
48
  #w3tc hr {
49
- clear:both;
50
- margin-top:10px
51
  }
 
52
  #w3tc ul {
53
- list-style-position:inside
54
  }
55
- #w3tc #toc a, #qa a {
56
- text-decoration:none
 
57
  }
58
- #w3tc #toc a:hover, #qa a:hover {
59
- text-decoration:underline
 
60
  }
 
61
  #w3tc #toc ul {
62
- margin:0;
63
- padding:0
64
  }
 
65
  #w3tc #toc li {
66
- margin:0;
67
- padding:0
68
  }
 
69
  #w3tc #toc li.col {
70
- float:left;
71
- list-style:none;
72
- margin:0 30px 0 0;
73
- width:30%
74
  }
 
75
  #w3tc #toc li.col ul {
76
- margin-left:20px
77
  }
 
78
  #w3tc #toc li.col ul li {
79
- list-style:disc
80
  }
 
81
  #w3tc #qa {
82
- clear:both;
83
- padding:10px;
84
- width:760px
85
  }
86
- #w3tc #about, #w3tc #install {
87
- width: 760px;
 
88
  }
1
  #icon-w3tc-logo {
2
+ background:url(../images/logo.png) no-repeat;
3
+ float:left;
4
+ height:36px;
5
+ width:36px
6
  }
7
+
8
  .w3tc-options-menu-selected {
9
+ font-weight:700
10
  }
11
+
12
  .w3tc-enabled {
13
+ color:#090;
14
+ font-weight:700
15
  }
16
+
17
  .w3tc-disabled {
18
+ color:#f00;
19
+ font-weight:700
20
  }
21
+
22
  .w3tc-empty {
23
+ font-weight:700;
24
+ font-style:italic
25
  }
26
+
27
  .w3tc-success {
28
+ background:#bfb
29
  }
30
+
31
  .w3tc-error {
32
+ background:#f99
33
  }
34
+
35
  .w3tc-status {
36
+ padding:5px
37
  }
38
+
39
  #w3tc acronym {
40
+ border-bottom:1px dotted #666
41
  }
42
+
43
  #w3tc ul {
44
+ list-style-type:disc;
45
+ list-style-position:inside
46
  }
47
+
48
  #w3tc blockquote {
49
+ font-style:italic;
 
50
  }
51
+
52
  #w3tc blockquote cite {
53
+ font-style:400
54
  }
55
+
56
  #w3tc h5 {
57
+ margin:0
58
  }
59
+
60
  #w3tc hr {
61
+ clear:both;
62
+ margin-top:10px
63
  }
64
+
65
  #w3tc ul {
66
+ list-style-position:inside
67
  }
68
+
69
+ #w3tc #toc a,#qa a {
70
+ text-decoration:none
71
  }
72
+
73
+ #w3tc #toc a:hover,#qa a:hover {
74
+ text-decoration:underline
75
  }
76
+
77
  #w3tc #toc ul {
78
+ margin:0;
79
+ padding:0
80
  }
81
+
82
  #w3tc #toc li {
83
+ margin:0;
84
+ padding:0
85
  }
86
+
87
  #w3tc #toc li.col {
88
+ float:left;
89
+ list-style:none;
90
+ margin:0 30px 0 0;
91
+ width:30%
92
  }
93
+
94
  #w3tc #toc li.col ul {
95
+ margin-left:20px
96
  }
97
+
98
  #w3tc #toc li.col ul li {
99
+ list-style:disc
100
  }
101
+
102
  #w3tc #qa {
103
+ clear:both;
104
+ padding:10px;
 
105
  }
106
+
107
+ #w3tc #qa,#w3tc #about,#w3tc #install {
108
+ width:760px;
109
  }
inc/css/popup.css CHANGED
@@ -1,149 +1,175 @@
1
  * {
2
- margin: 0;
3
- padding: 0;
4
- color: #464646;
5
  }
 
6
  html,body {
7
- height: 100%;
8
  }
 
9
  body {
10
- line-height: 1;
11
- background: #f9f9f9;
12
  }
 
13
  body,td,textarea,input,select {
14
- font-family: "Lucida Grande", Verdana, Arial;
15
- font-size: 13px;
16
  }
 
17
  p {
18
- margin: 1em 0;
19
  }
 
20
  h1 {
21
- font-family: Georgia, "Times New Roman", "Bitstream Charter";
22
- font-size: 24px;
23
- font-style: italic;
24
- font-weight: normal;
25
- line-height: 35px;
26
- margin-bottom: 0.8em 0;
27
- text-shadow: 0 1px 0 #fff;
28
- }
 
29
  a {
30
- color: #21759B;
31
  }
 
32
  a:hover {
33
- color: #D54E21;
34
  }
 
35
  #content {
36
- padding: 40px 50px;
37
  }
 
38
  .clear {
39
- clear: both;
40
  }
 
41
  .button,input[type="button"],input[type="submit"] {
42
- font-size: 11px;
43
- line-height: 16px;
44
- background: #F2F2F2 url(/wp-admin/images/white-grad.png) repeat-x scroll
45
- left top;
46
- border: 1px solid #bbb;
47
- color: #464646;
48
- text-shadow: 0 1px 0 #fff;
49
- cursor: pointer;
50
- padding: 2px 8px;
51
- -moz-background-clip: border;
52
- -moz-background-inline-policy: continuous;
53
- -moz-background-origin: padding;
54
- -moz-border-radius: 11px;
55
- -moz-box-sizing: content-box;
56
- }
57
  .button:hover,input[type="button"]:hover,input[type="submit"]:hover {
58
- border-color: #666;
59
- color: #000;
60
  }
 
61
  .button:active,input[type="button"]:active,input[type="submit"]:active {
62
- background: #F2F2F2 url(/wp-admin/images/white-grad-active.png) repeat-x
63
- scroll left top;
64
  }
 
65
  .progress {
66
- background: #fff;
67
- border: 1px solid #464646;
68
- padding: 1px;
69
- margin: 1em 0;
70
- position: relative;
71
  }
 
72
  .progress-value {
73
- position: absolute;
74
- line-height: 30px;
75
- font-size: 16px;
76
- font-weight: bold;
77
- color: #000;
78
- text-align: center;
79
- width: 100%;
80
- }
 
81
  .progress-bar {
82
- float: left;
83
- width: 0;
84
- height: 30px;
85
- background: #fc2;
86
  }
 
87
  .log {
88
- border: 1px solid #464646;
89
- height: 279px;
90
- overflow: auto;
91
  }
 
92
  .log div {
93
- padding: 3px;
94
- border-bottom: 1px solid #464646;
95
  }
 
96
  .log-success {
97
- background: #bfb;
98
  }
 
99
  .log-error {
100
- background: #f99;
101
  }
 
102
  .empty {
103
- font-weight: bold;
104
- font-style: italic;
105
  }
 
106
  .table {
107
- width: 100%;
108
- border-collapse: collapse;
109
  }
 
110
  .table td,th {
111
- border: 1px solid #ccc;
112
- padding: 3px 2px;
113
  }
 
114
  .table th {
115
- background: #eee;
116
  }
 
117
  .queue td {
118
- font-size: 10px;
119
  }
 
120
  .updated,.error {
121
- -moz-border-radius-bottomleft: 3px;
122
- -moz-border-radius-bottomright: 3px;
123
- -moz-border-radius-topleft: 3px;
124
- -moz-border-radius-topright: 3px;
125
- border-style: solid;
126
- border-width: 1px;
127
- padding: 0 0.6em;
128
- margin: 0.5em 0;
129
- }
 
130
  .updated {
131
- background: #FFFFE0;
132
- border-color: #E6DB55;
133
  }
 
134
  .error {
135
- background-color: #FFEBE8;
136
- border-color: #CC0000;
137
  }
 
138
  .updated p,.error p {
139
- line-height: 1;
140
- margin: 0.5em 0;
141
- padding: 2px;
142
  }
 
143
  .tab-selected {
144
- font-weight: bold;
145
  }
 
146
  .rules {
147
- width: 100%;
148
- font-size: 9px;
149
  }
1
  * {
2
+ margin:0;
3
+ padding:0;
4
+ color:#464646;
5
  }
6
+
7
  html,body {
8
+ height:100%;
9
  }
10
+
11
  body {
12
+ line-height:1;
13
+ background:#f9f9f9;
14
  }
15
+
16
  body,td,textarea,input,select {
17
+ font-family:"Lucida Grande", Verdana, Arial;
18
+ font-size:13px;
19
  }
20
+
21
  p {
22
+ margin:1em 0;
23
  }
24
+
25
  h1 {
26
+ font-family:Georgia, "Times New Roman", "Bitstream Charter";
27
+ font-size:24px;
28
+ font-style:italic;
29
+ font-weight:400;
30
+ line-height:35px;
31
+ margin-bottom:0.8em 0;
32
+ text-shadow:0 1px 0 #fff;
33
+ }
34
+
35
  a {
36
+ color:#21759B;
37
  }
38
+
39
  a:hover {
40
+ color:#D54E21;
41
  }
42
+
43
  #content {
44
+ padding:40px 50px;
45
  }
46
+
47
  .clear {
48
+ clear:both;
49
  }
50
+
51
  .button,input[type="button"],input[type="submit"] {
52
+ font-size:11px;
53
+ line-height:16px;
54
+ background:#f2f2f2 url(/wp-admin/images/white-grad.png) repeat-x scroll left top;
55
+ border:1px solid #bbb;
56
+ color:#464646;
57
+ text-shadow:0 1px 0 #fff;
58
+ cursor:pointer;
59
+ padding:2px 8px;
60
+ border-radius:11px;
61
+ -webkit-border-radius:11px;
62
+ -moz-border-radius:11px;
63
+ }
64
+
 
 
65
  .button:hover,input[type="button"]:hover,input[type="submit"]:hover {
66
+ border-color:#666;
67
+ color:#000;
68
  }
69
+
70
  .button:active,input[type="button"]:active,input[type="submit"]:active {
71
+ background:#F2F2F2 url(/wp-admin/images/white-grad-active.png) repeat-x scroll left top;
 
72
  }
73
+
74
  .progress {
75
+ background:#fff;
76
+ border:1px solid #464646;
77
+ padding:1px;
78
+ margin:1em 0;
79
+ position:relative;
80
  }
81
+
82
  .progress-value {
83
+ position:absolute;
84
+ line-height:30px;
85
+ font-size:16px;
86
+ font-weight:700;
87
+ color:#000;
88
+ text-align:center;
89
+ width:100%;
90
+ }
91
+
92
  .progress-bar {
93
+ float:left;
94
+ width:0;
95
+ height:30px;
96
+ background:#fc2;
97
  }
98
+
99
  .log {
100
+ border:1px solid #464646;
101
+ height:279px;
102
+ overflow:auto;
103
  }
104
+
105
  .log div {
106
+ padding:3px;
107
+ border-bottom:1px solid #464646;
108
  }
109
+
110
  .log-success {
111
+ background:#bfb;
112
  }
113
+
114
  .log-error {
115
+ background:#f99;
116
  }
117
+
118
  .empty {
119
+ font-weight:700;
120
+ font-style:italic;
121
  }
122
+
123
  .table {
124
+ width:100%;
125
+ border-collapse:collapse;
126
  }
127
+
128
  .table td,th {
129
+ border:1px solid #ccc;
130
+ padding:3px 2px;
131
  }
132
+
133
  .table th {
134
+ background:#eee;
135
  }
136
+
137
  .queue td {
138
+ font-size:10px;
139
  }
140
+
141
  .updated,.error {
142
+ -moz-border-radius-bottomleft:3px;
143
+ -moz-border-radius-bottomright:3px;
144
+ -moz-border-radius-topleft:3px;
145
+ -moz-border-radius-topright:3px;
146
+ border-style:solid;
147
+ border-width:1px;
148
+ padding:0 0.6em;
149
+ margin:0.5em 0;
150
+ }
151
+
152
  .updated {
153
+ background:#ffffe0;
154
+ border-color:#e6db55;
155
  }
156
+
157
  .error {
158
+ background-color:#ffebe8;
159
+ border-color:#cc0000;
160
  }
161
+
162
  .updated p,.error p {
163
+ line-height:1;
164
+ margin:0.5em 0;
165
+ padding:2px;
166
  }
167
+
168
  .tab-selected {
169
+ font-weight:700;
170
  }
171
+
172
  .rules {
173
+ width:100%;
174
+ font-size:9px;
175
  }
inc/define.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- define('W3TC_VERSION', '0.8');
4
  define('W3TC_POWERED_BY', 'W3 Total Cache/' . W3TC_VERSION);
5
  define('W3TC_LINK_URL', 'http://www.w3-edge.com/wordpress-plugins/');
6
  define('W3TC_LINK_NAME', 'WordPress Plugins');
@@ -10,10 +10,12 @@ if (! defined('W3TC_DIR')) {
10
  }
11
 
12
  define('W3TC_FILE', 'w3-total-cache/w3-total-cache.php');
13
- define('W3TC_LIB_W3_DIR', W3TC_DIR . '/lib/W3');
14
- define('W3TC_LIB_MINIFY_DIR', W3TC_DIR . '/lib/Minify/');
 
 
15
  define('W3TC_INSTALL_DIR', W3TC_DIR . '/wp-content');
16
- define('W3TC_INSTALL_MINIFY_DIR', W3TC_INSTALL_DIR . '/w3tc');
17
 
18
  if (! defined('WP_CONTENT_DIR')) {
19
  define('WP_CONTENT_DIR', realpath(W3TC_DIR . '/../..'));
@@ -23,18 +25,34 @@ define('WP_CONTENT_DIR_NAME', basename(WP_CONTENT_DIR));
23
 
24
  define('W3TC_CONTENT_DIR_NAME', WP_CONTENT_DIR_NAME . '/w3tc');
25
  define('W3TC_CONTENT_DIR', ABSPATH . W3TC_CONTENT_DIR_NAME);
26
- define('W3TC_CACHE_FILE_DIR', W3TC_CONTENT_DIR . '/cache');
27
- define('W3TC_CACHE_MINIFY_DIR', W3TC_CONTENT_DIR . '/minify');
 
 
 
28
  define('W3TC_LOG_DIR', W3TC_CONTENT_DIR . '/log');
 
29
 
30
- define('W3TC_CONFIG_NAME', 'w3-total-cache-config');
31
- define('W3TC_CONFIG_PATH', WP_CONTENT_DIR . '/' . W3TC_CONFIG_NAME . (($w3_blog_id = w3_get_blog_id()) != '' ? '-' . $w3_blog_id : '') . '.php');
32
- define('W3TC_CONFIG_DEFAULT_PATH', W3TC_DIR . '/w3-total-cache-config-default.php');
 
33
 
34
  define('W3TC_CDN_COMMAND_UPLOAD', 1);
35
  define('W3TC_CDN_COMMAND_DELETE', 2);
36
  define('W3TC_CDN_TABLE_QUEUE', 'w3tc_cdn_queue');
37
 
 
 
 
 
 
 
 
 
 
 
 
38
  /**
39
  * W3 writable error
40
  *
@@ -44,7 +62,11 @@ define('W3TC_CDN_TABLE_QUEUE', 'w3tc_cdn_queue');
44
  */
45
  function w3_writable_error($path, $die = true)
46
  {
47
- $error = sprintf('<strong>%s</strong> could not be created, please run following command:<br /><strong style="color: #f00;">chmod 777 %s</strong><br />then re-activate plugin.', $path, dirname($path));
 
 
 
 
48
 
49
  if ($die) {
50
  die($error);
@@ -127,11 +149,14 @@ function w3_mkdir($path, $mask = 0755, $curr_path = '')
127
  $path = preg_replace('~[\\\/]+~', '/', $path);
128
  $path = trim($path, '/');
129
  $dirs = explode('/', $path);
 
130
  foreach ($dirs as $dir) {
131
  if (empty($dir)) {
132
  return false;
133
  }
 
134
  $curr_path .= ($curr_path == '' ? '' : '/') . $dir;
 
135
  if (! is_dir($curr_path)) {
136
  if (@mkdir($curr_path, $mask)) {
137
  @chmod($curr_path, $mask);
@@ -140,48 +165,52 @@ function w3_mkdir($path, $mask = 0755, $curr_path = '')
140
  }
141
  }
142
  }
 
143
  return true;
144
  }
145
 
146
  /**
147
  * Recursive remove dir
148
  *
149
- * @param $path
150
- * @return boolean
 
151
  */
152
- function w3_rmdir($path, $empty = false)
153
  {
154
  $dir = @opendir($path);
 
155
  if ($dir) {
156
- while (($entry = readdir($dir))) {
157
- if ($entry != '.' && $entry != '..') {
158
- $full_path = $path . '/' . $entry;
 
159
  if (is_dir($full_path)) {
160
- $result = @w3_rmdir($full_path);
161
  } else {
162
- $result = @unlink($full_path);
163
- }
164
- if (! $result) {
165
- @closedir($dir);
166
- return false;
167
  }
168
  }
169
  }
 
170
  @closedir($dir);
171
- return ($empty ? true : @rmdir($path));
 
 
 
172
  }
173
- return false;
174
  }
175
 
176
  /**
177
  * Recursive empty dir
178
  *
179
- * @param $path
180
- * @return boolean
 
181
  */
182
- function w3_emptydir($path)
183
  {
184
- return w3_rmdir($path, true);
185
  }
186
 
187
  /**
@@ -300,34 +329,79 @@ function w3_get_site_url()
300
 
301
  if ($site_url === null) {
302
  $site_url = get_option('siteurl');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  }
304
 
305
  return $site_url;
306
  }
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  /**
309
  * Get domain URL
 
310
  * @return string
311
  */
312
  function w3_get_domain_url()
313
  {
314
- $siteurl = w3_get_site_url();
315
- $parse_url = @parse_url($siteurl);
316
 
317
- if ($parse_url && isset($parse_url['scheme'])) {
318
  $scheme = $parse_url['scheme'];
319
- if (isset($parse_url['host'])) {
320
- $host = $parse_url['host'];
321
- $port = (isset($parse_url['port']) ? ':' . $parse_url['port'] : '');
322
- return sprintf('%s://%s%s', $scheme, $host, $port);
323
- }
324
  }
325
 
326
  return false;
327
  }
328
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329
  /**
330
  * Returns blog path
 
331
  * @return string
332
  */
333
  function w3_get_site_path()
@@ -335,12 +409,11 @@ function w3_get_site_path()
335
  static $site_path = null;
336
 
337
  if ($site_path === null) {
338
-
339
  $site_url = w3_get_site_url();
340
  $domain_url = w3_get_domain_url();
341
 
342
  $site_path = str_replace($domain_url, '', $site_url);
343
- $site_path = trim($site_path, '/');
344
 
345
  if ($site_path != '') {
346
  $site_path .= '/';
@@ -362,7 +435,11 @@ function w3_upload_info()
362
  if ($upload_info === null) {
363
  $upload_info = @wp_upload_dir();
364
 
365
- if (! empty($upload_info['error'])) {
 
 
 
 
366
  $upload_info = false;
367
  }
368
  }
@@ -375,42 +452,65 @@ function w3_upload_info()
375
  *
376
  * @param string $url
377
  * @param string $params
 
378
  */
379
- function w3_redirect($url = '', $params = '')
380
  {
381
- $url = (! empty($url) ? $url : (! empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $_SERVER['REQUEST_URI']));
382
 
383
- if (($parse_url = @parse_url($url))) {
384
- $url = $parse_url['scheme'] . '://' . (! empty($parse_url['user']) ? $parse_url['user'] . (! empty($parse_url['pass']) ? ':' . $parse_url['pass'] : '') . '@' : '') . $parse_url['host'] . (! empty($parse_url['port']) ? ':' . $parse_url['port'] : '') . $parse_url['path'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
  } else {
386
  $parse_url = array();
387
  }
388
 
389
- $old_params = array();
390
- if (! empty($parse_url['query'])) {
391
- parse_str($parse_url['query'], $old_params);
392
- }
393
-
394
- $new_params = array();
395
- if (! empty($params)) {
396
- parse_str($params, $new_params);
397
- }
398
-
399
- $merged_params = array_merge($old_params, $new_params);
400
-
401
- if (! empty($merged_params)) {
402
- $count = count($merged_params);
403
- $query_string = '';
404
 
405
- foreach ($merged_params as $param => $value) {
406
  $count--;
407
- $query_string .= urlencode($param) . (! empty($value) ? '=' . urlencode($value) : '') . ($count ? '&' : '');
408
  }
409
 
410
- $url .= (strpos($url, '?') === false ? '?' : '&') . $query_string;
411
  }
412
 
413
- $url .= (! empty($parse_url['fragment']) ? '#' . $parse_url['fragment'] : '');
 
 
414
 
415
  @header('Location: ' . $url);
416
  exit();
@@ -418,6 +518,7 @@ function w3_redirect($url = '', $params = '')
418
 
419
  /**
420
  * Returns caching engine name
 
421
  * @param $engine
422
  * @return string
423
  */
@@ -436,6 +537,10 @@ function w3_get_engine_name($engine)
436
  $engine_name = 'disk';
437
  break;
438
 
 
 
 
 
439
  default:
440
  $engine_name = 'N/A';
441
  break;
@@ -446,6 +551,7 @@ function w3_get_engine_name($engine)
446
 
447
  /**
448
  * Converts value to boolean
 
449
  * @param mixed $value
450
  * @return boolean
451
  */
@@ -477,47 +583,418 @@ function w3_to_boolean($value)
477
  }
478
 
479
  /**
480
- * Download url via GET
481
- * @param $url
 
 
 
 
482
  * @return string
483
  */
484
- function w3_url_get($url)
485
  {
486
- if (w3_to_boolean(ini_get('allow_url_fopen'))) {
487
- ini_set('user_agent', W3TC_POWERED_BY);
488
- return @file_get_contents($url);
489
- } elseif (function_exists('curl_init')) {
490
  $ch = curl_init();
 
491
  curl_setopt($ch, CURLOPT_URL, $url);
492
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
493
  curl_setopt($ch, CURLOPT_USERAGENT, W3TC_POWERED_BY);
 
 
 
 
 
 
 
 
 
 
494
  $contents = curl_exec($ch);
 
495
  curl_close($ch);
 
496
  return $contents;
497
  } else {
498
  $parse_url = @parse_url($url);
499
- if (isset($parse_url['host'])) {
 
500
  $host = $parse_url['host'];
501
- $port = (isset($parse_url['port']) ? (int) $parse_url['path'] : 80);
502
- $path = (isset($parse_url['path']) ? trim($parse_url['path']) : '/');
503
- $query = (isset($parse_url['query']) ? trim($parse_url['query']) : '');
504
  $request_uri = $path . ($query != '' ? '?' . $query : '');
505
- $request = sprintf("GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\nUser-Agent: %s\r\n\r\n", $request_uri, $host, W3TC_POWERED_BY);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  if (($fp = @fsockopen($host, $port))) {
507
  $response = '';
508
  @fputs($fp, $request);
 
509
  while (! @feof($fp)) {
510
  $response .= @fgets($fp, 4096);
511
  }
 
512
  @fclose($fp);
 
513
  list (, $contents) = explode("\r\n\r\n", $response, 2);
 
514
  return $contents;
515
  }
516
  }
517
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  }
519
 
520
  /**
521
  * Send powered by header
522
  */
523
- @header('X-Powered-By: ' . W3TC_POWERED_BY);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ define('W3TC_VERSION', '0.8.5');
4
  define('W3TC_POWERED_BY', 'W3 Total Cache/' . W3TC_VERSION);
5
  define('W3TC_LINK_URL', 'http://www.w3-edge.com/wordpress-plugins/');
6
  define('W3TC_LINK_NAME', 'WordPress Plugins');
10
  }
11
 
12
  define('W3TC_FILE', 'w3-total-cache/w3-total-cache.php');
13
+ define('W3TC_LIB_DIR', W3TC_DIR . '/lib');
14
+ define('W3TC_LIB_W3_DIR', W3TC_LIB_DIR . '/W3');
15
+ define('W3TC_LIB_MINIFY_DIR', W3TC_LIB_DIR . '/Minify');
16
+ define('W3TC_PLUGINS_DIR', W3TC_DIR . '/plugins');
17
  define('W3TC_INSTALL_DIR', W3TC_DIR . '/wp-content');
18
+ define('W3TC_INSTALL_MINIFY_DIR', W3TC_INSTALL_DIR . '/w3tc/min');
19
 
20
  if (! defined('WP_CONTENT_DIR')) {
21
  define('WP_CONTENT_DIR', realpath(W3TC_DIR . '/../..'));
25
 
26
  define('W3TC_CONTENT_DIR_NAME', WP_CONTENT_DIR_NAME . '/w3tc');
27
  define('W3TC_CONTENT_DIR', ABSPATH . W3TC_CONTENT_DIR_NAME);
28
+ define('W3TC_CONTENT_MINIFY_DIR_NAME', WP_CONTENT_DIR_NAME . '/w3tc/min');
29
+ define('W3TC_CONTENT_MINIFY_DIR', ABSPATH . W3TC_CONTENT_DIR_NAME . '/min');
30
+ define('W3TC_CACHE_FILE_DBCACHE_DIR', W3TC_CONTENT_DIR . '/dbcache');
31
+ define('W3TC_CACHE_FILE_PGCACHE_DIR', W3TC_CONTENT_DIR . '/pgcache');
32
+ define('W3TC_CACHE_FILE_MINIFY_DIR', W3TC_CONTENT_DIR . '/min');
33
  define('W3TC_LOG_DIR', W3TC_CONTENT_DIR . '/log');
34
+ define('W3TC_TMP_DIR', W3TC_CONTENT_DIR . '/tmp');
35
 
36
+ define('W3TC_CONFIG_PATH', WP_CONTENT_DIR . '/w3-total-cache-config' . (($w3_blog_id = w3_get_blog_id()) != '' ? '-' . $w3_blog_id : '') . '.php');
37
+ define('W3TC_CONFIG_EXAMPLE_PATH', W3TC_DIR . '/w3-total-cache-config-example.php');
38
+
39
+ define('W3TC_MINIFY_LOG_FILE', W3TC_LOG_DIR . '/minify.log');
40
 
41
  define('W3TC_CDN_COMMAND_UPLOAD', 1);
42
  define('W3TC_CDN_COMMAND_DELETE', 2);
43
  define('W3TC_CDN_TABLE_QUEUE', 'w3tc_cdn_queue');
44
 
45
+ define('W3TC_PHP5', PHP_VERSION >= 5);
46
+ define('W3TC_WIN', (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'));
47
+
48
+ define('W3TC_EMAIL', 'w3tc@w3-edge.com');
49
+ define('W3TC_FEED_URL', 'http://feeds.feedburner.com/W3TOTALCACHE');
50
+ define('W3TC_FEED_ITEMS', 3);
51
+ define('W3TC_README_URL', 'http://plugins.trac.wordpress.org/browser/w3-total-cache/trunk/readme.txt?format=txt');
52
+
53
+ define('W3TC_TWITTER_STATUS', 'I just optimized my #wordpress blog\'s performance using the W3 Total Cache #plugin by @w3edge. Check it out! http://j.mp/A69xX');
54
+ define('W3TC_SUPPORT_US_TIMEOUT', 2592000);
55
+
56
  /**
57
  * W3 writable error
58
  *
62
  */
63
  function w3_writable_error($path, $die = true)
64
  {
65
+ if (w3_check_open_basedir($path)) {
66
+ $error = sprintf('<strong>%s</strong> could not be created, please run following command:<br /><strong style="color: #f00;">chmod 777 %s</strong><br />then re-activate plugin.', $path, dirname($path));
67
+ } else {
68
+ $error = sprintf('<strong>%s</strong> could not be created, <strong>open_basedir</strong> restriction in effect, please check your php.ini settings:<br /><strong style="color: #f00;">open_basedir = "%s"</strong></br />then re-activate plugin.', $path, ini_get('open_basedir'));
69
+ }
70
 
71
  if ($die) {
72
  die($error);
149
  $path = preg_replace('~[\\\/]+~', '/', $path);
150
  $path = trim($path, '/');
151
  $dirs = explode('/', $path);
152
+
153
  foreach ($dirs as $dir) {
154
  if (empty($dir)) {
155
  return false;
156
  }
157
+
158
  $curr_path .= ($curr_path == '' ? '' : '/') . $dir;
159
+
160
  if (! is_dir($curr_path)) {
161
  if (@mkdir($curr_path, $mask)) {
162
  @chmod($curr_path, $mask);
165
  }
166
  }
167
  }
168
+
169
  return true;
170
  }
171
 
172
  /**
173
  * Recursive remove dir
174
  *
175
+ * @param string $path
176
+ * @param array $exclude
177
+ * @return void
178
  */
179
+ function w3_rmdir($path, $exclude = array(), $remove = true)
180
  {
181
  $dir = @opendir($path);
182
+
183
  if ($dir) {
184
+ while (($entry = @readdir($dir))) {
185
+ $full_path = $path . '/' . $entry;
186
+
187
+ if ($entry != '.' && $entry != '..' && ! in_array($full_path, $exclude)) {
188
  if (is_dir($full_path)) {
189
+ w3_rmdir($full_path, $exclude);
190
  } else {
191
+ @unlink($full_path);
 
 
 
 
192
  }
193
  }
194
  }
195
+
196
  @closedir($dir);
197
+
198
+ if ($remove) {
199
+ @rmdir($path);
200
+ }
201
  }
 
202
  }
203
 
204
  /**
205
  * Recursive empty dir
206
  *
207
+ * @param string $path
208
+ * @param array $exclude
209
+ * @return void
210
  */
211
+ function w3_emptydir($path, $exclude = array())
212
  {
213
+ w3_rmdir($path, $exclude, false);
214
  }
215
 
216
  /**
329
 
330
  if ($site_url === null) {
331
  $site_url = get_option('siteurl');
332
+ $site_url = rtrim($site_url, '/') . '/';
333
+ }
334
+
335
+ return $site_url;
336
+ }
337
+
338
+ /**
339
+ * Returns SSL site url
340
+ *
341
+ * @return string
342
+ */
343
+ function w3_get_site_url_ssl()
344
+ {
345
+ $site_url = w3_get_site_url();
346
+
347
+ if (w3_is_https()) {
348
+ $site_url = str_replace('http:', 'https:', $site_url);
349
  }
350
 
351
  return $site_url;
352
  }
353
 
354
+ /**
355
+ * Returns site url regexp
356
+ *
357
+ * @return string
358
+ */
359
+ function w3_get_site_url_regexp()
360
+ {
361
+ $site_url = w3_get_site_url();
362
+ $domain = preg_replace('~https?://~i', '', $site_url);
363
+ $regexp = 'https?://' . w3_preg_quote($domain);
364
+ return $regexp;
365
+ }
366
+
367
  /**
368
  * Get domain URL
369
+ *
370
  * @return string
371
  */
372
  function w3_get_domain_url()
373
  {
374
+ $site_url = w3_get_site_url();
375
+ $parse_url = @parse_url($site_url);
376
 
377
+ if ($parse_url && isset($parse_url['scheme']) && isset($parse_url['host'])) {
378
  $scheme = $parse_url['scheme'];
379
+ $host = $parse_url['host'];
380
+ $port = (isset($parse_url['port']) && $parse_url['port'] != 80 ? ':' . (int) $parse_url['port'] : '');
381
+ $domain_url = sprintf('%s://%s%s/', $scheme, $host, $port);
382
+
383
+ return $domain_url;
384
  }
385
 
386
  return false;
387
  }
388
 
389
+ /**
390
+ * Returns domain url regexp
391
+ *
392
+ * @return string
393
+ */
394
+ function w3_get_domain_url_regexp()
395
+ {
396
+ $domain_url = w3_get_domain_url();
397
+ $domain = preg_replace('~https?://~i', '', $domain_url);
398
+ $regexp = 'https?://' . w3_preg_quote($domain);
399
+ return $regexp;
400
+ }
401
+
402
  /**
403
  * Returns blog path
404
+ *
405
  * @return string
406
  */
407
  function w3_get_site_path()
409
  static $site_path = null;
410
 
411
  if ($site_path === null) {
 
412
  $site_url = w3_get_site_url();
413
  $domain_url = w3_get_domain_url();
414
 
415
  $site_path = str_replace($domain_url, '', $site_url);
416
+ $site_path = rtrim($site_path, '/');
417
 
418
  if ($site_path != '') {
419
  $site_path .= '/';
435
  if ($upload_info === null) {
436
  $upload_info = @wp_upload_dir();
437
 
438
+ if (empty($upload_info['error'])) {
439
+ $site_url = w3_get_site_url();
440
+ $upload_info['upload_url'] = ltrim(str_replace($site_url, '', $upload_info['baseurl']), '/');
441
+ $upload_info['upload_dir'] = ltrim(str_replace(ABSPATH, '', $upload_info['basedir']), '/\\');
442
+ } else {
443
  $upload_info = false;
444
  }
445
  }
452
  *
453
  * @param string $url
454
  * @param string $params
455
+ * @return string
456
  */
457
+ function w3_redirect($url = '', $params = array())
458
  {
459
+ $fragment = '';
460
 
461
+ if ($url != '' && ($parse_url = @parse_url($url))) {
462
+ $url = '';
463
+
464
+ if (! empty($parse_url['scheme'])) {
465
+ $url .= $parse_url['scheme'] . '://';
466
+ }
467
+
468
+ if (! empty($parse_url['user'])) {
469
+ $url .= $parse_url['user'];
470
+
471
+ if (! empty($parse_url['pass'])) {
472
+ $url .= ':' . $parse_url['pass'];
473
+ }
474
+ }
475
+
476
+ if (! empty($parse_url['host'])) {
477
+ $url .= $parse_url['host'];
478
+ }
479
+
480
+ if (! empty($parse_url['port']) && $parse_url['port'] != 80) {
481
+ $url .= ':' . (int) $parse_url['port'];
482
+ }
483
+
484
+ $url .= (! empty($parse_url['path']) ? $parse_url['path'] : '/');
485
+
486
+ if (! empty($parse_url['query'])) {
487
+ $old_params = array();
488
+ parse_str($parse_url['query'], $old_params);
489
+
490
+ $params = array_merge($old_params, $params);
491
+ }
492
+
493
+ if (! empty($parse_url['fragment'])) {
494
+ $fragment = '#' . $parse_url['fragment'];
495
+ }
496
  } else {
497
  $parse_url = array();
498
  }
499
 
500
+ if (($count = count($params))) {
501
+ $query = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
502
 
503
+ foreach ($params as $param => $value) {
504
  $count--;
505
+ $query .= urlencode($param) . (! empty($value) ? '=' . urlencode($value) : '') . ($count ? '&' : '');
506
  }
507
 
508
+ $url .= (strpos($url, '?') === false ? '?' : '&') . $query;
509
  }
510
 
511
+ if ($fragment != '') {
512
+ $url .= $fragment;
513
+ }
514
 
515
  @header('Location: ' . $url);
516
  exit();
518
 
519
  /**
520
  * Returns caching engine name
521
+ *
522
  * @param $engine
523
  * @return string
524
  */
537
  $engine_name = 'disk';
538
  break;
539
 
540
+ case 'file_pgcache':
541
+ $engine_name = 'disk (enchanced)';
542
+ break;
543
+
544
  default:
545
  $engine_name = 'N/A';
546
  break;
551
 
552
  /**
553
  * Converts value to boolean
554
+ *
555
  * @param mixed $value
556
  * @return boolean
557
  */
583
  }
584
 
585
  /**
586
+ * Request URL
587
+ *
588
+ * @param string $method
589
+ * @param string $url
590
+ * @param string $data
591
+ * @param string $auth
592
  * @return string
593
  */
594
+ function w3_url_request($method, $url, $data = '', $auth = '')
595
  {
596
+ $method = strtoupper($method);
597
+
598
+ if (function_exists('curl_init')) {
 
599
  $ch = curl_init();
600
+
601
  curl_setopt($ch, CURLOPT_URL, $url);
602
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
603
  curl_setopt($ch, CURLOPT_USERAGENT, W3TC_POWERED_BY);
604
+
605
+ if ($method == 'POST') {
606
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
607
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
608
+ }
609
+
610
+ if (! empty($auth)) {
611
+ curl_setopt($ch, CURLOPT_USERPWD, $auth);
612
+ }
613
+
614
  $contents = curl_exec($ch);
615
+
616
  curl_close($ch);
617
+
618
  return $contents;
619
  } else {
620
  $parse_url = @parse_url($url);
621
+
622
+ if ($parse_url && isset($parse_url['host'])) {
623
  $host = $parse_url['host'];
624
+ $port = (isset($parse_url['port']) ? (int) $parse_url['port'] : 80);
625
+ $path = (! empty($parse_url['path']) ? $parse_url['path'] : '/');
626
+ $query = (isset($parse_url['query']) ? $parse_url['query'] : '');
627
  $request_uri = $path . ($query != '' ? '?' . $query : '');
628
+
629
+ $headers = array(
630
+ sprintf('%s %s HTTP/1.1', $method, $request_uri),
631
+ sprintf('Host: %s', $host),
632
+ sprintf('User-Agent: %s', W3TC_POWERED_BY),
633
+ 'Connection: close'
634
+ );
635
+
636
+ if (! empty($data)) {
637
+ $headers[] = sprintf('Content-Length: %d', strlen($data));
638
+ }
639
+
640
+ if (! empty($auth)) {
641
+ $headers[] = sprintf('Authorization: Basic %s', base64_encode($auth));
642
+ }
643
+
644
+ $request = implode("\r\n", $headers) . "\r\n\r\n" . $data;
645
+
646
  if (($fp = @fsockopen($host, $port))) {
647
  $response = '';
648
  @fputs($fp, $request);
649
+
650
  while (! @feof($fp)) {
651
  $response .= @fgets($fp, 4096);
652
  }
653
+
654
  @fclose($fp);
655
+
656
  list (, $contents) = explode("\r\n\r\n", $response, 2);
657
+
658
  return $contents;
659
  }
660
  }
661
  }
662
+
663
+ }
664
+
665
+ /**
666
+ * Download url via GET
667
+ *
668
+ * @param $url
669
+ * @return string
670
+ */
671
+ function w3_url_get($url)
672
+ {
673
+ return w3_url_request('GET', $url);
674
+ }
675
+
676
+ /**
677
+ * Send POST request to URL
678
+ *
679
+ * @param string $url
680
+ * @param string $data
681
+ * @param string $auth
682
+ * @return string
683
+ */
684
+ function w3_url_post($url, $data = '', $auth = '')
685
+ {
686
+ return w3_url_request('POST', $url, $data, $auth);
687
+ }
688
+
689
+ /**
690
+ * Loads plugins
691
+ *
692
+ * @return void
693
+ */
694
+ function w3_load_plugins()
695
+ {
696
+ $dir = @opendir(W3TC_PLUGINS_DIR);
697
+
698
+ if ($dir) {
699
+ while (($entry = @readdir($dir))) {
700
+ if (strrchr($entry, '.') === '.php') {
701
+ require_once W3TC_PLUGINS_DIR . '/' . $entry;
702
+ }
703
+ }
704
+ @closedir($dir);
705
+ }
706
+ }
707
+
708
+ /**
709
+ * Returns true if current connection is secure
710
+ *
711
+ * @return boolean
712
+ */
713
+ function w3_is_https()
714
+ {
715
+ switch (true) {
716
+ case (isset($_SERVER['HTTPS']) && w3_to_boolean($_SERVER['HTTPS'])):
717
+ case (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] == 443):
718
+ return true;
719
+ }
720
+
721
+ return false;
722
+ }
723
+
724
+ /**
725
+ * Returns realpath of given path
726
+ *
727
+ * @param string $path
728
+ */
729
+ function w3_realpath($path)
730
+ {
731
+ $path = preg_replace('~[/\\\]+~', '/', $path);
732
+ $parts = explode('/', $path);
733
+ $absolutes = array();
734
+
735
+ foreach ($parts as $part) {
736
+ if ('.' == $part) {
737
+ continue;
738
+ }
739
+ if ('..' == $part) {
740
+ array_pop($absolutes);
741
+ } else {
742
+ $absolutes[] = $part;
743
+ }
744
+ }
745
+
746
+ return implode('/', $absolutes);
747
+ }
748
+
749
+ /**
750
+ * Returns open basedirs
751
+ *
752
+ * @return array
753
+ */
754
+ function w3_get_open_basedirs()
755
+ {
756
+ $open_basedir_ini = ini_get('open_basedir');
757
+ $open_basedirs = (W3TC_WIN ? preg_split('~[;,]~', $open_basedir_ini) : explode(':', $open_basedir_ini));
758
+ $result = array();
759
+
760
+ foreach ($open_basedirs as $open_basedir) {
761
+ $open_basedir = trim($open_basedir);
762
+ if ($open_basedir != '') {
763
+ $result[] = w3_realpath($open_basedir);
764
+ }
765
+ }
766
+
767
+ return $result;
768
+ }
769
+
770
+ /**
771
+ * Checks if path is restricted by open_basedir
772
+ *
773
+ * @param string $path
774
+ * @return boolean
775
+ */
776
+ function w3_check_open_basedir($path)
777
+ {
778
+ $path = w3_realpath($path);
779
+ $open_basedirs = w3_get_open_basedirs();
780
+
781
+ if (! count($open_basedirs)) {
782
+ return true;
783
+ }
784
+
785
+ foreach ($open_basedirs as $open_basedir) {
786
+ if (strstr($path, $open_basedir) !== false) {
787
+ return true;
788
+ }
789
+ }
790
+
791
+ return false;
792
+ }
793
+
794
+ /**
795
+ * Returns PHP info
796
+ *
797
+ * @return array
798
+ */
799
+ function w3_phpinfo()
800
+ {
801
+ ob_start();
802
+ phpinfo();
803
+ $phpinfo = ob_get_clean();
804
+
805
+ $phpinfo = preg_replace(array(
806
+ '#^.*<body>(.*)</body>.*$#ms',
807
+ '#<h2>PHP License</h2>.*$#ms',
808
+ '#<h1>Configuration</h1>#',
809
+ "#\r?\n#",
810
+ "#</(h1|h2|h3|tr)>#",
811
+ '# +<#',
812
+ "#[ \t]+#",
813
+ '#&nbsp;#',
814
+ '# +#',
815
+ '# class=".*?"#',
816
+ '%&#039;%',
817
+ '#<tr>(?:.*?)" src="(?:.*?)=(.*?)" alt="PHP Logo" /></a>' . '<h1>PHP Version (.*?)</h1>(?:\n+?)</td></tr>#',
818
+ '#<h1><a href="(?:.*?)\?=(.*?)">PHP Credits</a></h1>#',
819
+ '#<tr>(?:.*?)" src="(?:.*?)=(.*?)"(?:.*?)Zend Engine (.*?),(?:.*?)</tr>#',
820
+ "# +#",
821
+ '#<tr>#',
822
+ '#</tr>#'
823
+ ), array(
824
+ '$1',
825
+ '',
826
+ '',
827
+ '',
828
+ '</$1>' . "\n",
829
+ '<',
830
+ ' ',
831
+ ' ',
832
+ ' ',
833
+ '',
834
+ ' ',
835
+ '<h2>PHP Configuration</h2>' . "\n" . '<tr><td>PHP Version</td><td>$2</td></tr>' . "\n" . '<tr><td>PHP Egg</td><td>$1</td></tr>',
836
+ '<tr><td>PHP Credits Egg</td><td>$1</td></tr>',
837
+ '<tr><td>Zend Engine</td><td>$2</td></tr>' . "\n" . '<tr><td>Zend Egg</td><td>$1</td></tr>',
838
+ ' ',
839
+ '%S%',
840
+ '%E%'
841
+ ), $phpinfo);
842
+
843
+ $sections = explode('<h2>', strip_tags($phpinfo, '<h2><th><td>'));
844
+
845
+ $pi = array();
846
+
847
+ foreach ($sections as $section) {
848
+ $n = substr($section, 0, strpos($section, '</h2>'));
849
+ $askapache = null;
850
+ if (preg_match_all('#%S%(?:<td>(.*?)</td>)?(?:<td>(.*?)</td>)?(?:<td>(.*?)</td>)?%E%#', $section, $askapache, PREG_SET_ORDER)) {
851
+ foreach ($askapache as $m) {
852
+ $pi[$n][$m[1]] = (! isset($m[3]) || $m[2] == $m[3]) ? $m[2] : array_slice($m, 2);
853
+ }
854
+ }
855
+ }
856
+
857
+ return $pi;
858
+ }
859
+
860
+ /**
861
+ * Returns file mime type
862
+ *
863
+ * @param string $file
864
+ * @return string
865
+ */
866
+ function w3_get_mime_type($file)
867
+ {
868
+ $mime_types = array(
869
+ 'jpg|jpeg|jpe' => 'image/jpeg',
870
+ 'gif' => 'image/gif',
871
+ 'png' => 'image/png',
872
+ 'bmp' => 'image/bmp',
873
+ 'tif|tiff' => 'image/tiff',
874
+ 'ico' => 'image/x-icon',
875
+ 'asf|asx|wax|wmv|wmx' => 'video/asf',
876
+ 'avi' => 'video/avi',
877
+ 'divx' => 'video/divx',
878
+ 'mov|qt' => 'video/quicktime',
879
+ 'mpeg|mpg|mpe' => 'video/mpeg',
880
+ 'txt|c|cc|h' => 'text/plain',
881
+ 'svg' => 'image/svg+xml',
882
+ 'rtx' => 'text/richtext',
883
+ 'css' => 'text/css',
884
+ 'xsl|xsd|xml' => 'text/xml',
885
+ 'htm|html' => 'text/html',
886
+ 'mp3|m4a' => 'audio/mpeg',
887
+ 'mp4|m4v' => 'video/mp4',
888
+ 'ra|ram' => 'audio/x-realaudio',
889
+ 'wav' => 'audio/wav',
890
+ 'ogg' => 'audio/ogg',
891
+ 'mid|midi' => 'audio/midi',
892
+ 'wma' => 'audio/wma',
893
+ 'rtf' => 'application/rtf',
894
+ 'js' => 'application/x-javascript',
895
+ 'pdf' => 'application/pdf',
896
+ 'doc|docx' => 'application/msword',
897
+ 'pot|pps|ppt|pptx' => 'application/vnd.ms-powerpoint',
898
+ 'wri' => 'application/vnd.ms-write',
899
+ 'xla|xls|xlsx|xlt|xlw' => 'application/vnd.ms-excel',
900
+ 'mdb' => 'application/vnd.ms-access',
901
+ 'mpp' => 'application/vnd.ms-project',
902
+ 'swf' => 'application/x-shockwave-flash',
903
+ 'class' => 'application/java',
904
+ 'tar' => 'application/x-tar',
905
+ 'zip' => 'application/zip',
906
+ 'gz|gzip' => 'application/x-gzip',
907
+ 'exe' => 'application/x-msdownload',
908
+ 'odt' => 'application/vnd.oasis.opendocument.text',
909
+ 'odp' => 'application/vnd.oasis.opendocument.presentation',
910
+ 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
911
+ 'odg' => 'application/vnd.oasis.opendocument.graphics',
912
+ 'odc' => 'application/vnd.oasis.opendocument.chart',
913
+ 'odb' => 'application/vnd.oasis.opendocument.database',
914
+ 'odf' => 'application/vnd.oasis.opendocument.formula'
915
+ );
916
+
917
+ $file_ext = strrchr($file, '.');
918
+
919
+ if ($file_ext) {
920
+ $file_ext = ltrim($file_ext, '.');
921
+ foreach ($mime_types as $extension => $mime_type) {
922
+ $exts = explode('|', $extension);
923
+ foreach ($exts as $ext) {
924
+ if ($file_ext == $ext) {
925
+ return $mime_type;
926
+ }
927
+ }
928
+ }
929
+ }
930
+
931
+ return false;
932
+ }
933
+
934
+ /**
935
+ * Send twitter update status request
936
+ *
937
+ * @param string $username
938
+ * @param string $password
939
+ * @param string $status
940
+ * @param string $error
941
+ * @return string
942
+ */
943
+ function w3_twitter_status_update($username, $password, $status, &$error)
944
+ {
945
+ $data = sprintf('status=%s', urlencode($status));
946
+ $auth = sprintf('%s:%s', $username, $password);
947
+
948
+ $xml = w3_url_post('http://twitter.com/statuses/update.xml', $data, $auth);
949
+
950
+ if ($xml) {
951
+ $matches = null;
952
+
953
+ if (preg_match('~<id>(\d+)</id>~', $xml, $matches)) {
954
+ return $matches[1];
955
+ } elseif (preg_match('~<error>([^<]+)</error>~', $xml, $matches)) {
956
+ $error = $matches[1];
957
+ } else {
958
+ $error = 'Unknown error.';
959
+ }
960
+ } else {
961
+ $error = 'Unable to send request.';
962
+ }
963
+
964
+ return false;
965
+ }
966
+
967
+ /**
968
+ * Quotes regular expression string
969
+ *
970
+ * @param string $regexp
971
+ * @return string
972
+ */
973
+ function w3_preg_quote($string, $delimiter = null)
974
+ {
975
+ $string = preg_quote($string, $delimiter);
976
+ $string = strtr($string, array(
977
+ ' ' => '\ '
978
+ ));
979
+
980
+ return $string;
981
  }
982
 
983
  /**
984
  * Send powered by header
985
  */
986
+ function w3_send_x_powered_by()
987
+ {
988
+ switch (true) {
989
+ case defined('DOING_AJAX'):
990
+ case defined('DOING_CRON'):
991
+ case defined('APP_REQUEST'):
992
+ case defined('XMLRPC_REQUEST'):
993
+ case defined('WP_ADMIN'):
994
+ return;
995
+ }
996
+
997
+ @header('X-Powered-By: ' . W3TC_POWERED_BY);
998
+ }
999
+
1000
+ w3_send_x_powered_by();
inc/images/loader.gif ADDED
Binary file
inc/js/lightbox.js ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var Lightbox = {
2
+ window: jQuery(window),
3
+ container: null,
4
+ options: null,
5
+
6
+ create: function() {
7
+ var me = this;
8
+
9
+ this.container = jQuery('<div class="lightbox lightbox-loading"><div class="lightbox-close">Close window</div><div class="lightbox-content"></div></div>').css( {
10
+ top: 0,
11
+ left: 0,
12
+ width: 0,
13
+ height: 0,
14
+ position: 'absolute',
15
+ 'z-index': 9991,
16
+ display: 'none'
17
+ });
18
+
19
+ jQuery('#w3tc').append(this.container);
20
+
21
+ this.window.resize(function() {
22
+ me.resize();
23
+ });
24
+
25
+ this.window.scroll(function() {
26
+ me.resize();
27
+ });
28
+
29
+ this.container.find('.lightbox-close').click(function() {
30
+ me.close();
31
+ });
32
+ },
33
+
34
+ open: function(options) {
35
+ var me = this;
36
+
37
+ this.options = jQuery.extend( {
38
+ width: 400,
39
+ height: 300,
40
+ offsetTop: 100,
41
+ content: null,
42
+ url: null,
43
+ callback: null
44
+ }, options);
45
+
46
+ if (!this.container) {
47
+ this.create();
48
+ }
49
+
50
+ this.container.css( {
51
+ width: this.options.width,
52
+ height: this.options.height
53
+ });
54
+
55
+ if (this.options.content) {
56
+ this.content(options.content);
57
+ } else if (this.options.url) {
58
+ this.load(this.options.url, this.options.callback);
59
+ }
60
+
61
+ Overlay.show(this);
62
+
63
+ this.resize();
64
+ this.container.show();
65
+ currentLightbox = this;
66
+ },
67
+
68
+ close: function() {
69
+ this.container.hide();
70
+ Overlay.hide();
71
+ currentLightbox = null;
72
+ },
73
+
74
+ resize: function() {
75
+ this.container.css( {
76
+ top: this.window.scrollTop() + this.options.offsetTop,
77
+ left: this.window.scrollLeft() + this.window.width() / 2 - this.container.width() / 2
78
+ });
79
+ },
80
+
81
+ load: function(url, callback) {
82
+ this.content('');
83
+ this.loading(true);
84
+ var me = this;
85
+ jQuery.get(url, {}, function(content) {
86
+ me.loading(false);
87
+ me.content(content);
88
+ if (callback) {
89
+ callback.call(this, me);
90
+ }
91
+ });
92
+ },
93
+
94
+ content: function(content) {
95
+ return this.container.find('.lightbox-content').html(content);
96
+ },
97
+
98
+ width: function(width) {
99
+ if (width === undefined) {
100
+ return this.container.width();
101
+ } else {
102
+ return this.container.css( {
103
+ width: width,
104
+ left: this.window.scrollLeft() + this.window.width() / 2 - width / 2
105
+ });
106
+ }
107
+ },
108
+
109
+ height: function(height) {
110
+ if (height === undefined) {
111
+ return this.container.height();
112
+ } else {
113
+ return this.container.css( {
114
+ height: height,
115
+ top: this.window.scrollTop() + this.options.offsetTop
116
+ });
117
+ }
118
+ },
119
+
120
+ loading: function(loading) {
121
+ return (loading === undefined ? this.container.hasClass('lightbox-loader') : (loading ? this.container.addClass('lightbox-loader') : this.container.removeClass('lightbox-loader')));
122
+ }
123
+ };
124
+
125
+ var Overlay = {
126
+ window: jQuery(window),
127
+ container: null,
128
+
129
+ create: function() {
130
+ var me = this;
131
+
132
+ this.container = jQuery('<div id="overlay" />').css( {
133
+ top: 0,
134
+ left: 0,
135
+ width: 0,
136
+ height: 0,
137
+ position: 'absolute',
138
+ 'z-index': 9990,
139
+ display: 'none',
140
+ opacity: 0.6
141
+ });
142
+
143
+ jQuery('#w3tc').append(this.container);
144
+
145
+ this.window.resize(function() {
146
+ me.resize();
147
+ });
148
+
149
+ this.window.scroll(function() {
150
+ me.resize();
151
+ });
152
+ },
153
+
154
+ show: function() {
155
+ if (!this.container) {
156
+ this.create();
157
+ }
158
+
159
+ this.resize();
160
+ this.container.show();
161
+ },
162
+
163
+ hide: function() {
164
+ this.container.hide();
165
+ },
166
+
167
+ resize: function() {
168
+ this.container.css( {
169
+ top: this.window.scrollTop(),
170
+ left: this.window.scrollLeft(),
171
+ width: this.window.width(),
172
+ height: this.window.height()
173
+ });
174
+ }
175
+ };
176
+
177
+ function w3tc_lightbox_support_us() {
178
+ Lightbox.open( {
179
+ width: 500,
180
+ height: 200,
181
+ url: 'options-general.php?page=w3-total-cache/w3-total-cache.php&w3tc_action=support_us',
182
+ callback: function(lightbox) {
183
+ jQuery('.link-tweet', lightbox.container).click(function(event) {
184
+ lightbox.close();
185
+ w3tc_lightbox_tweet();
186
+ return false;
187
+ });
188
+
189
+ jQuery('form').submit(function() {
190
+ if (jQuery('select :selected', this).val() == '') {
191
+ alert('Please select link location!');
192
+ return false;
193
+ }
194
+ });
195
+ }
196
+ });
197
+
198
+ }
199
+
200
+ function w3tc_lightbox_tweet() {
201
+ Lightbox.open( {
202
+ width: 550,
203
+ height: 340,
204
+ url: 'options-general.php?page=w3-total-cache/w3-total-cache.php&w3tc_action=tweet',
205
+ callback: function(lightbox) {
206
+ jQuery('form', lightbox.container).submit(function() {
207
+ var me = this, username = jQuery('#tweet_username').val(), password = jQuery('#tweet_password').val();
208
+
209
+ if (username == '') {
210
+ alert('Please enter your twitter.com username.');
211
+ return false;
212
+ }
213
+
214
+ if (password == '') {
215
+ alert('Please enter your twitter.com password.');
216
+ return false;
217
+ }
218
+
219
+ jQuery('input', this).attr('disabled', 'disabled');
220
+
221
+ jQuery.post('options-general.php?page=w3-total-cache/w3-total-cache.php', {
222
+ w3tc_action: 'twitter_status_update',
223
+ username: username,
224
+ password: password
225
+ }, function(data) {
226
+ jQuery('input', me).attr('disabled', '');
227
+
228
+ if (data.result) {
229
+ lightbox.close();
230
+ alert('Nice! Thanks for telling your friends about us!');
231
+ } else {
232
+ alert('Uh oh, seems that that #failed. Please try again.');
233
+ }
234
+ }, 'json');
235
+
236
+ return false;
237
+ });
238
+ }
239
+ });
240
+ }
241
+
242
+ jQuery(function($) {
243
+ $('.link-tweet').click(function() {
244
+ w3tc_lightbox_tweet();
245
+ return false;
246
+ });
247
+ });
inc/js/options.js CHANGED
@@ -28,7 +28,7 @@ function input_enable(input, enabled) {
28
 
29
  function js_file_location_change() {
30
  jQuery('.js_file_location').change(function() {
31
- jQuery(this).parent().find(':text').attr('name', 'js_files[' + jQuery('#js_groups').val() + '][' + jQuery(this).val() + ']');
32
  });
33
  }
34
 
@@ -105,29 +105,29 @@ function file_validate() {
105
  });
106
 
107
  if (jQuery('#js_enabled:checked').size()) {
108
- if (invalid_js.length && !confirm('These files have invalid JS file extension:\r\n\r\n' + invalid_js.join('\r\n') + '\r\n\r\nAre you confident this files contain valid JS code?')) {
109
  return false;
110
  }
111
 
112
  if (query_js.length) {
113
- alert('These JS files contain query string in the name:\r\n\r\n' + query_js.join('\r\n'));
114
  return false;
115
  }
116
  }
117
 
118
  if (jQuery('#css_enabled:checked').size()) {
119
- if (invalid_css.length && !confirm('These files have invalid CSS file extension:\r\n\r\n' + invalid_css.join('\r\n') + '\r\n\r\nAre you confident this files contain valid CSS code?')) {
120
  return false;
121
  }
122
 
123
  if (query_css.length) {
124
- alert('These CSS files contain query string in the name:\r\n\r\n' + query_css.join('\r\n'));
125
  return false;
126
  }
127
  }
128
 
129
  if (duplicate) {
130
- alert('Duplicate files have been found in your minify settings, please check your settings again.');
131
  return false;
132
  }
133
 
@@ -320,10 +320,10 @@ jQuery(function($) {
320
  $('#test_ftp').click(function() {
321
  var status = $('#test_ftp_status');
322
  status.removeClass('w3tc-error');
 
323
  status.addClass('w3tc-process');
324
  status.html('Testing...');
325
- $.post('options-general.php', {
326
- page: 'w3-total-cache/w3-total-cache.php',
327
  w3tc_action: 'cdn_test_ftp',
328
  host: $('#cdn_ftp_host').val(),
329
  user: $('#cdn_ftp_user').val(),
@@ -335,13 +335,85 @@ jQuery(function($) {
335
  }, 'json');
336
  });
337
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  $('#test_memcached').click(function() {
339
  var status = $('#test_memcached_status');
340
  status.removeClass('w3tc-error');
 
341
  status.addClass('w3tc-process');
342
  status.html('Testing...');
343
- $.post('options-general.php', {
344
- page: 'w3-total-cache/w3-total-cache.php',
345
  w3tc_action: 'test_memcached',
346
  servers: $('#memcached_servers').val()
347
  }, function(data) {
@@ -349,4 +421,87 @@ jQuery(function($) {
349
  status.html(data.error);
350
  }, 'json');
351
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  });
28
 
29
  function js_file_location_change() {
30
  jQuery('.js_file_location').change(function() {
31
+ jQuery(this).parent().find(':text').attr('name', 'js_files[' + jQuery('#js_groups').val() + '][' + jQuery(this).val() + '][]');
32
  });
33
  }
34
 
105
  });
106
 
107
  if (jQuery('#js_enabled:checked').size()) {
108
+ if (invalid_js.length && !confirm('The following files have invalid JS file extension:\r\n\r\n' + invalid_js.join('\r\n') + '\r\n\r\nAre you confident these files contain valid JS code?')) {
109
  return false;
110
  }
111
 
112
  if (query_js.length) {
113
+ alert('We recommend using the entire URI for files with query string (GET) variables. You entered:\r\n\r\n' + query_js.join('\r\n'));
114
  return false;
115
  }
116
  }
117
 
118
  if (jQuery('#css_enabled:checked').size()) {
119
+ if (invalid_css.length && !confirm('The following files have invalid CSS file extension:\r\n\r\n' + invalid_css.join('\r\n') + '\r\n\r\nAre you confident these files contain valid CSS code?')) {
120
  return false;
121
  }
122
 
123
  if (query_css.length) {
124
+ alert('We recommend using the entire URI for files with query string (GET) variables. You entered:\r\n\r\n' + query_css.join('\r\n'));
125
  return false;
126
  }
127
  }
128
 
129
  if (duplicate) {
130
+ alert('Duplicate files have been found in your minify settings, please check your settings and re-save.');
131
  return false;
132
  }
133
 
320
  $('#test_ftp').click(function() {
321
  var status = $('#test_ftp_status');
322
  status.removeClass('w3tc-error');
323
+ status.removeClass('w3tc-success');
324
  status.addClass('w3tc-process');
325
  status.html('Testing...');
326
+ $.post('options-general.php?page=w3-total-cache/w3-total-cache.php', {
 
327
  w3tc_action: 'cdn_test_ftp',
328
  host: $('#cdn_ftp_host').val(),
329
  user: $('#cdn_ftp_user').val(),
335
  }, 'json');
336
  });
337
 
338
+ $('#test_s3').click(function() {
339
+ var status = $('#test_s3_status');
340
+ status.removeClass('w3tc-error');
341
+ status.removeClass('w3tc-success');
342
+ status.addClass('w3tc-process');
343
+ status.html('Testing...');
344
+ $.post('options-general.php?page=w3-total-cache/w3-total-cache.php', {
345
+ w3tc_action: 'cdn_test_s3',
346
+ key: $('#cdn_s3_key').val(),
347
+ secret: $('#cdn_s3_secret').val(),
348
+ bucket: $('#cdn_s3_bucket').val()
349
+ }, function(data) {
350
+ status.addClass(data.result ? 'w3tc-success' : 'w3tc-error');
351
+ status.html(data.error);
352
+ }, 'json');
353
+ });
354
+
355
+ $('#test_cf').click(function() {
356
+ var status = $('#test_cf_status');
357
+ status.removeClass('w3tc-error');
358
+ status.removeClass('w3tc-success');
359
+ status.addClass('w3tc-process');
360
+ status.html('Testing...');
361
+ $.post('options-general.php?page=w3-total-cache/w3-total-cache.php', {
362
+ w3tc_action: 'cdn_test_cf',
363
+ key: $('#cdn_cf_key').val(),
364
+ secret: $('#cdn_cf_secret').val(),
365
+ bucket: $('#cdn_cf_bucket').val(),
366
+ id: $('#cdn_cf_id').val(),
367
+ cname: $('#cdn_cf_cname').val()
368
+ }, function(data) {
369
+ status.addClass(data.result ? 'w3tc-success' : 'w3tc-error');
370
+ status.html(data.error);
371
+ }, 'json');
372
+ });
373
+
374
+ $('#create_bucket_s3').click(function() {
375
+ var status = $('#create_bucket_s3_status');
376
+ status.removeClass('w3tc-error');
377
+ status.removeClass('w3tc-success');
378
+ status.addClass('w3tc-process');
379
+ status.html('Creating bucket...');
380
+ $.post('options-general.php?page=w3-total-cache/w3-total-cache.php', {
381
+ w3tc_action: 'cdn_create_bucket',
382
+ type: 's3',
383
+ key: $('#cdn_s3_key').val(),
384
+ secret: $('#cdn_s3_secret').val(),
385
+ bucket: $('#cdn_s3_bucket').val()
386
+ }, function(data) {
387
+ status.addClass(data.result ? 'w3tc-success' : 'w3tc-error');
388
+ status.html(data.error);
389
+ }, 'json');
390
+ });
391
+
392
+ $('#create_bucket_cf').click(function() {
393
+ var status = $('#create_bucket_cf_status');
394
+ status.removeClass('w3tc-error');
395
+ status.removeClass('w3tc-success');
396
+ status.addClass('w3tc-process');
397
+ status.html('Creating bucket...');
398
+ $.post('options-general.php?page=w3-total-cache/w3-total-cache.php', {
399
+ w3tc_action: 'cdn_create_bucket',
400
+ type: 'cf',
401
+ key: $('#cdn_cf_key').val(),
402
+ secret: $('#cdn_cf_secret').val(),
403
+ bucket: $('#cdn_cf_bucket').val()
404
+ }, function(data) {
405
+ status.addClass(data.result ? 'w3tc-success' : 'w3tc-error');
406
+ status.html(data.error);
407
+ }, 'json');
408
+ });
409
+
410
  $('#test_memcached').click(function() {
411
  var status = $('#test_memcached_status');
412
  status.removeClass('w3tc-error');
413
+ status.removeClass('w3tc-success');
414
  status.addClass('w3tc-process');
415
  status.html('Testing...');
416
+ $.post('options-general.php?page=w3-total-cache/w3-total-cache.php', {
 
417
  w3tc_action: 'test_memcached',
418
  servers: $('#memcached_servers').val()
419
  }, function(data) {
421
  status.html(data.error);
422
  }, 'json');
423
  });
424
+
425
+ $('#support_more_files').click(function() {
426
+ $(this).before('<input type="file" name="files[]" /><br />');
427
+ });
428
+
429
+ $('#support_form').submit(function() {
430
+ var url = $('#support_url');
431
+ var name = $('#support_name');
432
+ var email = $('#support_email');
433
+ var request_type = $('#support_request_type');
434
+ var description = $('#support_description');
435
+ var wp_login = $('#support_wp_login');
436
+ var wp_password = $('#support_wp_password');
437
+ var ftp_host = $('#support_ftp_host');
438
+ var ftp_login = $('#support_ftp_login');
439
+ var ftp_password = $('#support_ftp_password');
440
+
441
+ if (url.val() == '') {
442
+ alert('Please enter the address of your blog in the Blog URL field.');
443
+ url.focus();
444
+ return false;
445
+ }
446
+
447
+ if (name.val() == '') {
448
+ alert('Please enter your name in the Name field.');
449
+ name.focus();
450
+ return false;
451
+ }
452
+
453
+ if (!/^[a-z0-9_\-\.]+@[a-z0-9-\.]+\.[a-z]{2,5}$/.test(email.val().toLowerCase())) {
454
+ alert('Please enter valid email address in the E-Mail field.');
455
+ email.focus();
456
+ return false;
457
+ }
458
+
459
+ if (request_type.val() == '') {
460
+ alert('Please select request type.');
461
+ request_type.focus();
462
+ return false;
463
+ }
464
+
465
+ if (description.val() == '') {
466
+ alert('Please describe the issue in the issue description field.');
467
+ description.focus();
468
+ return false;
469
+ }
470
+
471
+ if (wp_login.val() != '' || wp_password.val() != '') {
472
+ if (wp_login.val() == '') {
473
+ alert('Please enter an administrator login. Remember you can create a temporary one just for this support case.');
474
+ wp_login.focus();
475
+ return false;
476
+ }
477
+
478
+ if (wp_password.val() == '') {
479
+ alert('Please enter WP Admin password, be sure it\'s spelled correctly.');
480
+ wp_password.focus();
481
+ return false;
482
+ }
483
+ }
484
+
485
+ if (ftp_host.val() != '' || ftp_login.val() != '' || ftp_password.val() != '') {
486
+ if (ftp_host.val() == '') {
487
+ alert('Please enter SSH or FTP host for your site.');
488
+ ftp_host.focus();
489
+ return false;
490
+ }
491
+
492
+ if (ftp_login.val() == '') {
493
+ alert('Please enter SSH or FTP login for your server. Remember you can create a temporary one just for this support case.');
494
+ ftp_login.focus();
495
+ return false;
496
+ }
497
+
498
+ if (ftp_password.val() == '') {
499
+ alert('Please enter SSH or FTP password for your FTP account.');
500
+ ftp_password.focus();
501
+ return false;
502
+ }
503
+ }
504
+
505
+ return true;
506
+ });
507
  });
inc/js/popup.js CHANGED
@@ -1,5 +1,4 @@
1
- function seconds_to_string(seconds)
2
- {
3
  var string = '', days = 0, hours = 0, minutes = 0;
4
  days = Math.floor(seconds / 86400);
5
  if (days) {
@@ -24,8 +23,7 @@ function seconds_to_string(seconds)
24
  return string;
25
  }
26
 
27
- var Cdn_Export_File =
28
- {
29
  paused: 0,
30
  limit: 25,
31
  offset: 0,
@@ -35,50 +33,41 @@ var Cdn_Export_File =
35
  seconds_elapsed: 0,
36
  timer: null,
37
 
38
- set_progress: function(percent)
39
- {
40
  jQuery('#cdn_export_file_progress .progress-bar').width(percent + '%');
41
  jQuery('#cdn_export_file_progress .progress-value').html(percent + '%');
42
  },
43
 
44
- set_status: function(status)
45
- {
46
  jQuery('#cdn_export_file_status').html(status);
47
  },
48
 
49
- set_processed: function(processed)
50
- {
51
  jQuery('#cdn_export_file_processed').html(processed);
52
  },
53
 
54
- set_button_text: function(text)
55
- {
56
  jQuery('#cdn_export_file_start').val(text);
57
  },
58
 
59
- set_last_response: function()
60
- {
61
  var date = new Date();
62
  jQuery('#cdn_export_file_last_response').html(date.toLocaleTimeString() + ' ' + date.toLocaleDateString());
63
  },
64
 
65
- set_elapsed: function(text)
66
- {
67
  jQuery('#cdn_export_file_elapsed').html(text);
68
  },
69
 
70
- add_log: function(path, result, error)
71
- {
72
  jQuery('#cdn_export_file_log').prepend('<div class="log-' + (result == 1 ? 'success' : 'error') + '">' + path + ' <strong>' + error + '</strong></div>');
73
  },
74
 
75
- clear_log: function()
76
- {
77
  jQuery('#cdn_export_library_log').val('');
78
  },
79
 
80
- process: function()
81
- {
82
  if (this.paused) {
83
  return;
84
  }
@@ -91,24 +80,19 @@ var Cdn_Export_File =
91
 
92
  var me = this;
93
  if (this.upload_files.length) {
94
- jQuery.ajax(
95
- {
96
  type: 'POST',
97
- url: 'options-general.php',
98
- data:
99
- {
100
- page: 'w3-total-cache/w3-total-cache.php',
101
  w3tc_action: 'cdn_export_process',
102
  'files[]': this.upload_files
103
  },
104
  dataType: 'json',
105
- success: function(data)
106
- {
107
  me.set_last_response();
108
  me.process_callback(data);
109
  },
110
- error: function()
111
- {
112
  me.set_last_response();
113
  me.retry(me.retry_seconds);
114
  }
@@ -116,16 +100,14 @@ var Cdn_Export_File =
116
  }
117
  },
118
 
119
- retry: function(seconds)
120
- {
121
  if (this.paused) {
122
  return;
123
  }
124
  this.set_status('request failed (retry in ' + seconds + 's)');
125
  if (seconds) {
126
  var me = this;
127
- setTimeout(function()
128
- {
129
  me.retry(--seconds);
130
  }, 1000);
131
  } else {
@@ -134,8 +116,7 @@ var Cdn_Export_File =
134
  }
135
  },
136
 
137
- process_callback: function(data)
138
- {
139
  var failed = false;
140
  for ( var i = 0; i < data.results.length; i++) {
141
  this.add_log(data.results[i].remote_path, data.results[i].result, data.results[i].error);
@@ -166,14 +147,12 @@ var Cdn_Export_File =
166
  }
167
  },
168
 
169
- timer_callback: function()
170
- {
171
  this.seconds_elapsed++;
172
  this.set_elapsed(seconds_to_string(this.seconds_elapsed));
173
  },
174
 
175
- init: function(files, cdn_url)
176
- {
177
  if (files === undefined) {
178
  files = [];
179
  }
@@ -181,8 +160,7 @@ var Cdn_Export_File =
181
  this.files = files;
182
 
183
  var me = this;
184
- jQuery('#cdn_export_file_start').click(function()
185
- {
186
  if (this.value == 'Pause') {
187
  me.paused = 1;
188
  me.set_button_text('Resume');
@@ -198,8 +176,7 @@ var Cdn_Export_File =
198
  me.paused = 0;
199
  me.set_button_text('Pause');
200
  me.set_status('processing');
201
- me.timer = setInterval(function()
202
- {
203
  me.timer_callback();
204
  }, 1000);
205
  }
@@ -209,8 +186,7 @@ var Cdn_Export_File =
209
  }
210
  };
211
 
212
- var Cdn_Export_Library =
213
- {
214
  paused: 0,
215
  limit: 25,
216
  offset: 0,
@@ -218,95 +194,78 @@ var Cdn_Export_Library =
218
  seconds_elapsed: 0,
219
  timer: null,
220
 
221
- set_progress: function(percent)
222
- {
223
  jQuery('#cdn_export_library_progress .progress-bar').width(percent + '%');
224
  jQuery('#cdn_export_library_progress .progress-value').html(percent + '%');
225
  },
226
 
227
- set_status: function(status)
228
- {
229
  jQuery('#cdn_export_library_status').html(status);
230
  },
231
 
232
- set_processed: function(processed)
233
- {
234
  jQuery('#cdn_export_library_processed').html(processed);
235
  },
236
 
237
- set_total: function(total)
238
- {
239
  jQuery('#cdn_export_library_total').html(total);
240
  },
241
 
242
- set_button_text: function(text)
243
- {
244
  jQuery('#cdn_export_library_start').val(text);
245
  },
246
 
247
- set_last_response: function()
248
- {
249
  var date = new Date();
250
  jQuery('#cdn_export_library_last_response').html(date.toLocaleTimeString() + ' ' + date.toLocaleDateString());
251
  },
252
 
253
- set_elapsed: function(text)
254
- {
255
  jQuery('#cdn_export_library_elapsed').html(text);
256
  },
257
 
258
- add_log: function(path, result, error)
259
- {
260
  jQuery('#cdn_export_library_log').prepend('<div class="log-' + (result == 1 ? 'success' : 'error') + '">' + path + ' <strong>' + error + '</strong></div>');
261
  },
262
 
263
- clear_log: function()
264
- {
265
  jQuery('#cdn_export_library_log').html('');
266
  },
267
 
268
- process: function()
269
- {
270
  if (this.paused) {
271
  return;
272
  }
273
 
274
  var me = this;
275
- jQuery.ajax(
276
- {
277
  type: 'POST',
278
- url: 'options-general.php',
279
- data:
280
- {
281
- page: 'w3-total-cache/w3-total-cache.php',
282
  w3tc_action: 'cdn_export_library_process',
283
  limit: this.limit,
284
  offset: this.offset
285
  },
286
  dataType: 'json',
287
- success: function(data)
288
- {
289
  me.set_last_response();
290
  me.process_callback(data);
291
  },
292
- error: function()
293
- {
294
  me.set_last_response();
295
  me.retry(me.retry_seconds);
296
  }
297
  });
298
  },
299
 
300
- retry: function(seconds)
301
- {
302
  if (this.paused) {
303
  return;
304
  }
305
  this.set_status('request failed (retry in ' + seconds + 's)');
306
  if (seconds) {
307
  var me = this;
308
- setTimeout(function()
309
- {
310
  me.retry(--seconds);
311
  }, 1000);
312
  } else {
@@ -315,8 +274,7 @@ var Cdn_Export_Library =
315
  }
316
  },
317
 
318
- process_callback: function(data, status)
319
- {
320
  this.offset += data.count;
321
 
322
  this.set_total(data.total);
@@ -349,17 +307,14 @@ var Cdn_Export_Library =
349
  }
350
  },
351
 
352
- timer_callback: function()
353
- {
354
  this.seconds_elapsed++;
355
  this.set_elapsed(seconds_to_string(this.seconds_elapsed));
356
  },
357
 
358
- init: function()
359
- {
360
  var me = this;
361
- jQuery('#cdn_export_library_start').click(function()
362
- {
363
  if (this.value == 'Pause') {
364
  me.paused = 1;
365
  me.set_status('paused');
@@ -375,8 +330,7 @@ var Cdn_Export_Library =
375
  me.paused = 0;
376
  me.set_status('processing');
377
  me.set_button_text('Pause');
378
- me.timer = setInterval(function()
379
- {
380
  me.timer_callback();
381
  }, 1000);
382
  }
@@ -386,8 +340,7 @@ var Cdn_Export_Library =
386
  }
387
  };
388
 
389
- var Cdn_Import_Library =
390
- {
391
  paused: 0,
392
  limit: 5,
393
  offset: 0,
@@ -396,65 +349,53 @@ var Cdn_Import_Library =
396
  seconds_elapsed: 0,
397
  timer: null,
398
 
399
- set_progress: function(percent)
400
- {
401
  jQuery('#cdn_import_library_progress .progress-bar').width(percent + '%');
402
  jQuery('#cdn_import_library_progress .progress-value').html(percent + '%');
403
  },
404
 
405
- set_status: function(status)
406
- {
407
  jQuery('#cdn_import_library_status').html(status);
408
  },
409
 
410
- set_processed: function(processed)
411
- {
412
  jQuery('#cdn_import_library_processed').html(processed);
413
  },
414
 
415
- set_total: function(total)
416
- {
417
  jQuery('#cdn_import_library_total').html(total);
418
  },
419
 
420
- set_button_text: function(text)
421
- {
422
  jQuery('#cdn_import_library_start').val(text);
423
  },
424
 
425
- set_last_response: function()
426
- {
427
  var date = new Date();
428
  jQuery('#cdn_import_library_last_response').html(date.toLocaleTimeString() + ' ' + date.toLocaleDateString());
429
  },
430
 
431
- set_elapsed: function(text)
432
- {
433
  jQuery('#cdn_import_library_elapsed').html(text);
434
  },
435
 
436
- is_redirect_permanent: function()
437
- {
438
  return (jQuery('#cdn_import_library_redirect_permanent:checked').size() > 0);
439
  },
440
 
441
- is_redirect_cdn: function()
442
- {
443
  return (jQuery('#cdn_import_library_redirect_cdn:checked').size() > 0);
444
  },
445
 
446
- add_log: function(path, result, error)
447
- {
448
  jQuery('#cdn_import_library_log').prepend('<div class="log-' + (result == 1 ? 'success' : 'error') + '">' + path + ' <strong>' + error + '</strong></div>');
449
  },
450
 
451
- clear_log: function()
452
- {
453
  jQuery('#cdn_import_library_log').html('');
454
  },
455
 
456
- add_rule: function(src, dst)
457
- {
458
  if (/^https?:\/\//.test(src)) {
459
  return;
460
  }
@@ -473,53 +414,44 @@ var Cdn_Import_Library =
473
  rules.val(rules.val() + 'Redirect ' + (this.is_redirect_permanent() ? '302 ' : '') + src + ' ' + dst + '\r\n');
474
  },
475
 
476
- clear_rules: function()
477
- {
478
  jQuery('#cdn_import_library_rules').val('');
479
  },
480
 
481
- process: function()
482
- {
483
  if (this.paused) {
484
  return;
485
  }
486
 
487
  var me = this;
488
- jQuery.ajax(
489
- {
490
  type: 'POST',
491
- url: 'options-general.php',
492
- data:
493
- {
494
- page: 'w3-total-cache/w3-total-cache.php',
495
  w3tc_action: 'cdn_import_library_process',
496
  limit: this.limit,
497
  offset: this.offset
498
  },
499
  dataType: 'json',
500
- success: function(data)
501
- {
502
  me.set_last_response();
503
  me.process_callback(data);
504
  },
505
- error: function()
506
- {
507
  me.set_last_response();
508
  me.retry(me.retry_seconds);
509
  }
510
  });
511
  },
512
 
513
- retry: function(seconds)
514
- {
515
  if (this.paused) {
516
  return;
517
  }
518
  this.set_status('request failed (retry in ' + seconds + 's)');
519
  if (seconds) {
520
  var me = this;
521
- setTimeout(function()
522
- {
523
  me.retry(--seconds);
524
  }, 1000);
525
  } else {
@@ -528,8 +460,7 @@ var Cdn_Import_Library =
528
  }
529
  },
530
 
531
- process_callback: function(data)
532
- {
533
  this.offset += data.count;
534
 
535
  this.set_total(data.total);
@@ -564,18 +495,15 @@ var Cdn_Import_Library =
564
  }
565
  },
566
 
567
- timer_callback: function()
568
- {
569
  this.seconds_elapsed++;
570
  this.set_elapsed(seconds_to_string(this.seconds_elapsed));
571
  },
572
 
573
- init: function(cdn_host)
574
- {
575
  var me = this;
576
  this.cdn_host = cdn_host;
577
- jQuery('#cdn_import_library_start').click(function()
578
- {
579
  if (this.value == 'Pause') {
580
  me.paused = 1;
581
  me.set_button_text('Resume');
@@ -592,8 +520,7 @@ var Cdn_Import_Library =
592
  me.paused = 0;
593
  me.set_button_text('Pause');
594
  me.set_status('processing');
595
- me.timer = setInterval(function()
596
- {
597
  me.timer_callback();
598
  }, 1000);
599
  }
@@ -603,8 +530,7 @@ var Cdn_Import_Library =
603
  }
604
  };
605
 
606
- var Cdn_Rename_Domain =
607
- {
608
  paused: 0,
609
  limit: 25,
610
  offset: 0,
@@ -612,101 +538,83 @@ var Cdn_Rename_Domain =
612
  seconds_elapsed: 0,
613
  timer: null,
614
 
615
- set_progress: function(percent)
616
- {
617
  jQuery('#cdn_rename_domain_progress .progress-bar').width(percent + '%');
618
  jQuery('#cdn_rename_domain_progress .progress-value').html(percent + '%');
619
  },
620
 
621
- set_status: function(status)
622
- {
623
  jQuery('cdn_rename_domain_status').html(status);
624
  },
625
 
626
- set_processed: function(processed)
627
- {
628
  jQuery('#cdn_rename_domain_processed').html(processed);
629
  },
630
 
631
- set_total: function(total)
632
- {
633
  jQuery('#cdn_rename_domain_total').html(total);
634
  },
635
 
636
- set_button_text: function(text)
637
- {
638
  jQuery('#cdn_rename_domain_start').val(text);
639
  },
640
 
641
- set_last_response: function()
642
- {
643
  var date = new Date();
644
  jQuery('#cdn_rename_domain_last_response').html(date.toLocaleTimeString() + ' ' + date.toLocaleDateString());
645
  },
646
 
647
- set_elapsed: function(text)
648
- {
649
  jQuery('#cdn_rename_domain_elapsed').html(text);
650
  },
651
 
652
- add_log: function(path, result, error)
653
- {
654
  jQuery('#cdn_rename_domain_log').prepend('<div class="log-' + (result == 1 ? 'success' : 'error') + '">' + path + ' <strong>' + error + '</strong></div>');
655
  },
656
 
657
- clear_log: function()
658
- {
659
  jQuery('#cdn_rename_domain_log').html('');
660
  },
661
 
662
- get_domain_names: function()
663
- {
664
  return jQuery('#cdn_rename_domain_names').val();
665
  },
666
 
667
- process: function()
668
- {
669
  if (this.paused) {
670
  return;
671
  }
672
 
673
  var me = this;
674
- jQuery.ajax(
675
- {
676
  type: 'POST',
677
- url: 'options-general.php',
678
- data:
679
- {
680
- page: 'w3-total-cache/w3-total-cache.php',
681
  w3tc_action: 'cdn_rename_domain_process',
682
  names: this.get_domain_names(),
683
  limit: this.limit,
684
  offset: this.offset
685
  },
686
  dataType: 'json',
687
- success: function(data)
688
- {
689
  me.set_last_response();
690
  me.process_callback(data);
691
  },
692
- error: function()
693
- {
694
  me.set_last_response();
695
  me.retry(me.retry_seconds);
696
  }
697
  });
698
  },
699
 
700
- retry: function(seconds)
701
- {
702
  if (this.paused) {
703
  return;
704
  }
705
  this.set_status('request failed (retry in ' + seconds + 's)');
706
  if (seconds) {
707
  var me = this;
708
- setTimeout(function()
709
- {
710
  me.retry(--seconds);
711
  }, 1000);
712
  } else {
@@ -715,8 +623,7 @@ var Cdn_Rename_Domain =
715
  }
716
  },
717
 
718
- process_callback: function(data)
719
- {
720
  this.offset += data.count;
721
 
722
  this.set_total(data.total);
@@ -749,18 +656,15 @@ var Cdn_Rename_Domain =
749
  }
750
  },
751
 
752
- timer_callback: function()
753
- {
754
  this.seconds_elapsed++;
755
  this.set_elapsed(seconds_to_string(this.seconds_elapsed));
756
  },
757
 
758
- init: function(cdn_host)
759
- {
760
  var me = this;
761
  this.cdn_host = cdn_host;
762
- jQuery('#cdn_rename_domain_start').click(function()
763
- {
764
  if (this.value == 'Pause') {
765
  me.paused = 1;
766
  me.set_button_text('Resume');
@@ -780,8 +684,7 @@ var Cdn_Rename_Domain =
780
  me.paused = 0;
781
  me.set_button_text('Pause');
782
  me.set_status('processing');
783
- me.timer = setInterval(function()
784
- {
785
  me.timer_callback();
786
  }, 1000);
787
  }
@@ -791,23 +694,19 @@ var Cdn_Rename_Domain =
791
  }
792
  };
793
 
794
- jQuery(function($)
795
- {
796
- $('.tab').click(function()
797
- {
798
  $('.tab').removeClass('tab-selected');
799
  $('.tab-content').hide();
800
  $(this).addClass('tab-selected');
801
  $(this.rel).show();
802
  });
803
 
804
- $('.cdn_queue_delete').click(function()
805
- {
806
- return confirm('Are you sure you want to delete this file from the queue?');
807
  });
808
 
809
- $('.cdn_queue_empty').click(function()
810
- {
811
  return confirm('Are you sure you want to empty the queue?');
812
  });
813
  });
1
+ function seconds_to_string(seconds) {
 
2
  var string = '', days = 0, hours = 0, minutes = 0;
3
  days = Math.floor(seconds / 86400);
4
  if (days) {
23
  return string;
24
  }
25
 
26
+ var Cdn_Export_File = {
 
27
  paused: 0,
28
  limit: 25,
29
  offset: 0,
33
  seconds_elapsed: 0,
34
  timer: null,
35
 
36
+ set_progress: function(percent) {
 
37
  jQuery('#cdn_export_file_progress .progress-bar').width(percent + '%');
38
  jQuery('#cdn_export_file_progress .progress-value').html(percent + '%');
39
  },
40
 
41
+ set_status: function(status) {
 
42
  jQuery('#cdn_export_file_status').html(status);
43
  },
44
 
45
+ set_processed: function(processed) {
 
46
  jQuery('#cdn_export_file_processed').html(processed);
47
  },
48
 
49
+ set_button_text: function(text) {
 
50
  jQuery('#cdn_export_file_start').val(text);
51
  },
52
 
53
+ set_last_response: function() {
 
54
  var date = new Date();
55
  jQuery('#cdn_export_file_last_response').html(date.toLocaleTimeString() + ' ' + date.toLocaleDateString());
56
  },
57
 
58
+ set_elapsed: function(text) {
 
59
  jQuery('#cdn_export_file_elapsed').html(text);
60
  },
61
 
62
+ add_log: function(path, result, error) {
 
63
  jQuery('#cdn_export_file_log').prepend('<div class="log-' + (result == 1 ? 'success' : 'error') + '">' + path + ' <strong>' + error + '</strong></div>');
64
  },
65
 
66
+ clear_log: function() {
 
67
  jQuery('#cdn_export_library_log').val('');
68
  },
69
 
70
+ process: function() {
 
71
  if (this.paused) {
72
  return;
73
  }
80
 
81
  var me = this;
82
  if (this.upload_files.length) {
83
+ jQuery.ajax( {
 
84
  type: 'POST',
85
+ url: 'options-general.php?page=w3-total-cache/w3-total-cache.php',
86
+ data: {
 
 
87
  w3tc_action: 'cdn_export_process',
88
  'files[]': this.upload_files
89
  },
90
  dataType: 'json',
91
+ success: function(data) {
 
92
  me.set_last_response();
93
  me.process_callback(data);
94
  },
95
+ error: function() {
 
96
  me.set_last_response();
97
  me.retry(me.retry_seconds);
98
  }
100
  }
101
  },
102
 
103
+ retry: function(seconds) {
 
104
  if (this.paused) {
105
  return;
106
  }
107
  this.set_status('request failed (retry in ' + seconds + 's)');
108
  if (seconds) {
109
  var me = this;
110
+ setTimeout(function() {
 
111
  me.retry(--seconds);
112
  }, 1000);
113
  } else {
116
  }
117
  },
118
 
119
+ process_callback: function(data) {
 
120
  var failed = false;
121
  for ( var i = 0; i < data.results.length; i++) {
122
  this.add_log(data.results[i].remote_path, data.results[i].result, data.results[i].error);
147
  }
148
  },
149
 
150
+ timer_callback: function() {
 
151
  this.seconds_elapsed++;
152
  this.set_elapsed(seconds_to_string(this.seconds_elapsed));
153
  },
154
 
155
+ init: function(files, cdn_url) {
 
156
  if (files === undefined) {
157
  files = [];
158
  }
160
  this.files = files;
161
 
162
  var me = this;
163
+ jQuery('#cdn_export_file_start').click(function() {
 
164
  if (this.value == 'Pause') {
165
  me.paused = 1;
166
  me.set_button_text('Resume');
176
  me.paused = 0;
177
  me.set_button_text('Pause');
178
  me.set_status('processing');
179
+ me.timer = setInterval(function() {
 
180
  me.timer_callback();
181
  }, 1000);
182
  }
186
  }
187
  };
188
 
189
+ var Cdn_Export_Library = {
 
190
  paused: 0,
191
  limit: 25,
192
  offset: 0,
194
  seconds_elapsed: 0,
195
  timer: null,
196
 
197
+ set_progress: function(percent) {
 
198
  jQuery('#cdn_export_library_progress .progress-bar').width(percent + '%');
199
  jQuery('#cdn_export_library_progress .progress-value').html(percent + '%');
200
  },
201
 
202
+ set_status: function(status) {
 
203
  jQuery('#cdn_export_library_status').html(status);
204
  },
205
 
206
+ set_processed: function(processed) {
 
207
  jQuery('#cdn_export_library_processed').html(processed);
208
  },
209
 
210
+ set_total: function(total) {
 
211
  jQuery('#cdn_export_library_total').html(total);
212
  },
213
 
214
+ set_button_text: function(text) {
 
215
  jQuery('#cdn_export_library_start').val(text);
216
  },
217
 
218
+ set_last_response: function() {
 
219
  var date = new Date();
220
  jQuery('#cdn_export_library_last_response').html(date.toLocaleTimeString() + ' ' + date.toLocaleDateString());
221
  },
222
 
223
+ set_elapsed: function(text) {
 
224
  jQuery('#cdn_export_library_elapsed').html(text);
225
  },
226
 
227
+ add_log: function(path, result, error) {
 
228
  jQuery('#cdn_export_library_log').prepend('<div class="log-' + (result == 1 ? 'success' : 'error') + '">' + path + ' <strong>' + error + '</strong></div>');
229
  },
230
 
231
+ clear_log: function() {
 
232
  jQuery('#cdn_export_library_log').html('');
233
  },
234
 
235
+ process: function() {
 
236
  if (this.paused) {
237
  return;
238
  }
239
 
240
  var me = this;
241
+ jQuery.ajax( {
 
242
  type: 'POST',
243
+ url: 'options-general.php?page=w3-total-cache/w3-total-cache.php',
244
+ data: {
 
 
245
  w3tc_action: 'cdn_export_library_process',
246
  limit: this.limit,
247
  offset: this.offset
248
  },
249
  dataType: 'json',
250
+ success: function(data) {
 
251
  me.set_last_response();
252
  me.process_callback(data);
253
  },
254
+ error: function() {
 
255
  me.set_last_response();
256
  me.retry(me.retry_seconds);
257
  }
258
  });
259
  },
260
 
261
+ retry: function(seconds) {
 
262
  if (this.paused) {
263
  return;
264
  }
265
  this.set_status('request failed (retry in ' + seconds + 's)');
266
  if (seconds) {
267
  var me = this;
268
+ setTimeout(function() {
 
269
  me.retry(--seconds);
270
  }, 1000);
271
  } else {
274
  }
275
  },
276
 
277
+ process_callback: function(data, status) {
 
278
  this.offset += data.count;
279
 
280
  this.set_total(data.total);
307
  }
308
  },
309
 
310
+ timer_callback: function() {
 
311
  this.seconds_elapsed++;
312
  this.set_elapsed(seconds_to_string(this.seconds_elapsed));
313
  },
314
 
315
+ init: function() {
 
316
  var me = this;
317
+ jQuery('#cdn_export_library_start').click(function() {
 
318
  if (this.value == 'Pause') {
319
  me.paused = 1;
320
  me.set_status('paused');
330
  me.paused = 0;
331
  me.set_status('processing');
332
  me.set_button_text('Pause');
333
+ me.timer = setInterval(function() {
 
334
  me.timer_callback();
335
  }, 1000);
336
  }
340
  }
341
  };
342
 
343
+ var Cdn_Import_Library = {
 
344
  paused: 0,
345
  limit: 5,
346
  offset: 0,
349
  seconds_elapsed: 0,
350
  timer: null,
351
 
352
+ set_progress: function(percent) {
 
353
  jQuery('#cdn_import_library_progress .progress-bar').width(percent + '%');
354
  jQuery('#cdn_import_library_progress .progress-value').html(percent + '%');
355
  },
356
 
357
+ set_status: function(status) {
 
358
  jQuery('#cdn_import_library_status').html(status);
359
  },
360
 
361
+ set_processed: function(processed) {
 
362
  jQuery('#cdn_import_library_processed').html(processed);
363
  },
364
 
365
+ set_total: function(total) {
 
366
  jQuery('#cdn_import_library_total').html(total);
367
  },
368
 
369
+ set_button_text: function(text) {
 
370
  jQuery('#cdn_import_library_start').val(text);
371
  },
372
 
373
+ set_last_response: function() {
 
374
  var date = new Date();
375
  jQuery('#cdn_import_library_last_response').html(date.toLocaleTimeString() + ' ' + date.toLocaleDateString());
376
  },
377
 
378
+ set_elapsed: function(text) {
 
379
  jQuery('#cdn_import_library_elapsed').html(text);
380
  },
381
 
382
+ is_redirect_permanent: function() {
 
383
  return (jQuery('#cdn_import_library_redirect_permanent:checked').size() > 0);
384
  },
385
 
386
+ is_redirect_cdn: function() {
 
387
  return (jQuery('#cdn_import_library_redirect_cdn:checked').size() > 0);
388
  },
389
 
390
+ add_log: function(path, result, error) {
 
391
  jQuery('#cdn_import_library_log').prepend('<div class="log-' + (result == 1 ? 'success' : 'error') + '">' + path + ' <strong>' + error + '</strong></div>');
392
  },
393
 
394
+ clear_log: function() {
 
395
  jQuery('#cdn_import_library_log').html('');
396
  },
397
 
398
+ add_rule: function(src, dst) {
 
399
  if (/^https?:\/\//.test(src)) {
400
  return;
401
  }
414
  rules.val(rules.val() + 'Redirect ' + (this.is_redirect_permanent() ? '302 ' : '') + src + ' ' + dst + '\r\n');
415
  },
416
 
417
+ clear_rules: function() {
 
418
  jQuery('#cdn_import_library_rules').val('');
419
  },
420
 
421
+ process: function() {
 
422
  if (this.paused) {
423
  return;
424
  }
425
 
426
  var me = this;
427
+ jQuery.ajax( {
 
428
  type: 'POST',
429
+ url: 'options-general.php?page=w3-total-cache/w3-total-cache.php',
430
+ data: {
 
 
431
  w3tc_action: 'cdn_import_library_process',
432
  limit: this.limit,
433
  offset: this.offset
434
  },
435
  dataType: 'json',
436
+ success: function(data) {
 
437
  me.set_last_response();
438
  me.process_callback(data);
439
  },
440
+ error: function() {
 
441
  me.set_last_response();
442
  me.retry(me.retry_seconds);
443
  }
444
  });
445
  },
446
 
447
+ retry: function(seconds) {
 
448
  if (this.paused) {
449
  return;
450
  }
451
  this.set_status('request failed (retry in ' + seconds + 's)');
452
  if (seconds) {
453
  var me = this;
454
+ setTimeout(function() {
 
455
  me.retry(--seconds);
456
  }, 1000);
457
  } else {
460
  }
461
  },
462
 
463
+ process_callback: function(data) {
 
464
  this.offset += data.count;
465
 
466
  this.set_total(data.total);
495
  }
496
  },
497
 
498
+ timer_callback: function() {
 
499
  this.seconds_elapsed++;
500
  this.set_elapsed(seconds_to_string(this.seconds_elapsed));
501
  },
502
 
503
+ init: function(cdn_host) {
 
504
  var me = this;
505
  this.cdn_host = cdn_host;
506
+ jQuery('#cdn_import_library_start').click(function() {
 
507
  if (this.value == 'Pause') {
508
  me.paused = 1;
509
  me.set_button_text('Resume');
520
  me.paused = 0;
521
  me.set_button_text('Pause');
522
  me.set_status('processing');
523
+ me.timer = setInterval(function() {
 
524
  me.timer_callback();
525
  }, 1000);
526
  }
530
  }
531
  };
532
 
533
+ var Cdn_Rename_Domain = {
 
534
  paused: 0,
535
  limit: 25,
536
  offset: 0,
538
  seconds_elapsed: 0,
539
  timer: null,
540
 
541
+ set_progress: function(percent) {
 
542
  jQuery('#cdn_rename_domain_progress .progress-bar').width(percent + '%');
543
  jQuery('#cdn_rename_domain_progress .progress-value').html(percent + '%');
544
  },
545
 
546
+ set_status: function(status) {
 
547
  jQuery('cdn_rename_domain_status').html(status);
548
  },
549
 
550
+ set_processed: function(processed) {
 
551
  jQuery('#cdn_rename_domain_processed').html(processed);
552
  },
553
 
554
+ set_total: function(total) {
 
555
  jQuery('#cdn_rename_domain_total').html(total);
556
  },
557
 
558
+ set_button_text: function(text) {
 
559
  jQuery('#cdn_rename_domain_start').val(text);
560
  },
561
 
562
+ set_last_response: function() {
 
563
  var date = new Date();
564
  jQuery('#cdn_rename_domain_last_response').html(date.toLocaleTimeString() + ' ' + date.toLocaleDateString());
565
  },
566
 
567
+ set_elapsed: function(text) {
 
568
  jQuery('#cdn_rename_domain_elapsed').html(text);
569
  },
570
 
571
+ add_log: function(path, result, error) {
 
572
  jQuery('#cdn_rename_domain_log').prepend('<div class="log-' + (result == 1 ? 'success' : 'error') + '">' + path + ' <strong>' + error + '</strong></div>');
573
  },
574
 
575
+ clear_log: function() {
 
576
  jQuery('#cdn_rename_domain_log').html('');
577
  },
578
 
579
+ get_domain_names: function() {
 
580
  return jQuery('#cdn_rename_domain_names').val();
581
  },
582
 
583
+ process: function() {
 
584
  if (this.paused) {
585
  return;
586
  }
587
 
588
  var me = this;
589
+ jQuery.ajax( {
 
590
  type: 'POST',
591
+ url: 'options-general.php?page=w3-total-cache/w3-total-cache.php',
592
+ data: {
 
 
593
  w3tc_action: 'cdn_rename_domain_process',
594
  names: this.get_domain_names(),
595
  limit: this.limit,
596
  offset: this.offset
597
  },
598
  dataType: 'json',
599
+ success: function(data) {
 
600
  me.set_last_response();
601
  me.process_callback(data);
602
  },
603
+ error: function() {
 
604
  me.set_last_response();
605
  me.retry(me.retry_seconds);
606
  }
607
  });
608
  },
609
 
610
+ retry: function(seconds) {
 
611
  if (this.paused) {
612
  return;
613
  }
614
  this.set_status('request failed (retry in ' + seconds + 's)');
615
  if (seconds) {
616
  var me = this;
617
+ setTimeout(function() {
 
618
  me.retry(--seconds);
619
  }, 1000);
620
  } else {
623
  }
624
  },
625
 
626
+ process_callback: function(data) {
 
627
  this.offset += data.count;
628
 
629
  this.set_total(data.total);
656
  }
657
  },
658
 
659
+ timer_callback: function() {
 
660
  this.seconds_elapsed++;
661
  this.set_elapsed(seconds_to_string(this.seconds_elapsed));
662
  },
663
 
664
+ init: function(cdn_host) {
 
665
  var me = this;
666
  this.cdn_host = cdn_host;
667
+ jQuery('#cdn_rename_domain_start').click(function() {
 
668
  if (this.value == 'Pause') {
669
  me.paused = 1;
670
  me.set_button_text('Resume');
684
  me.paused = 0;
685
  me.set_button_text('Pause');
686
  me.set_status('processing');
687
+ me.timer = setInterval(function() {
 
688
  me.timer_callback();
689
  }, 1000);
690
  }
694
  }
695
  };
696
 
697
+ jQuery(function($) {
698
+ $('.tab').click(function() {
 
 
699
  $('.tab').removeClass('tab-selected');
700
  $('.tab-content').hide();
701
  $(this).addClass('tab-selected');
702
  $(this.rel).show();
703
  });
704
 
705
+ $('.cdn_queue_delete').click(function() {
706
+ return confirm('Are you sure you want to remove this file from the queue?');
 
707
  });
708
 
709
+ $('.cdn_queue_empty').click(function() {
 
710
  return confirm('Are you sure you want to empty the queue?');
711
  });
712
  });
inc/lightbox/support_us.phtml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <h3>Support Us</h3>
2
+
3
+ <p>We noticed you've been using W3 Total cache for at least 30 days, would you like to help us improve WordPress?</p>
4
+
5
+ <form action="options-general.php?page=<?php echo W3TC_FILE; ?>&amp;tab=<?php echo $this->_tab; ?>&amp;save_support_us" method="post">
6
+ <p>
7
+ <label>
8
+ Link to us:
9
+ <select name="support" class="select-support-type">
10
+ <option value="">select one</option>
11
+ <?php foreach ($supports as $support_id => $support_name): ?>
12
+ <option value="<?php echo $support_id; ?>"><?php echo htmlspecialchars($support_name); ?></option>
13
+ <?php endforeach; ?>
14
+ </select>
15
+ </label> (easy) or tell your friends with a <a href="#" class="link-tweet">tweet</a> (easiest).
16
+ </p>
17
+
18
+ <div style="text-align:center;">
19
+ <h3>THANK YOU!</h3>
20
+ <p>
21
+ <input type="submit" class="button-primary" value="Save and close"> or
22
+ <?php echo $this->button_hide_note('Don\'t show this message again', 'support_us'); ?>
23
+ </p>
24
+ </div>
25
+ </form>
inc/lightbox/tweet.phtml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <h3>Tweet</h3>
2
+
3
+ <p>Enter your username (email), password and click "Tweet!" to support us!</p>
4
+
5
+ <p>This is the message that will be tweeted:</p>
6
+
7
+ <blockquote>I just optimized my #wordpress blog's performance using the W3 Total Cache #plugin by @<a href="http://twitter.com/w3edge" target="_blank">w3edge</a>. Check it out! <a href="http://j.mp/A69xX" target="_blank">http://j.mp/A69xX</a></blockquote>
8
+
9
+ <form action="">
10
+ <table class="form-table">
11
+ <tr>
12
+ <th><label for="tweet_username">Username:</label></th>
13
+ <td><input id="tweet_username" type="text" size="30" /></td>
14
+ </tr>
15
+ <tr>
16
+ <th><label for="tweet_password">Password:</label></th>
17
+ <td><input id="tweet_password" type="password" size="30" /></td>
18
+ </tr>
19
+ </table>
20
+
21
+ <p class="submit">
22
+ <input type="submit" name="Submit" class="button-primary" value="Tweet!" />
23
+ </p>
24
+ </form>
25
+
26
+ <p><em>Your password is not saved. Your tweet is submitted directly to twitter.com via their <acronym title="Application Programming Interface">API</acronym>.</em></p>
inc/options/about.phtml CHANGED
@@ -1,3 +1,5 @@
 
 
1
  <div id="about">
2
  <h3>About</h3>
3
 
@@ -35,4 +37,6 @@
35
  <li><a href="http://t3.dotgnu.info/" target="_blank">Gopal Vijayaraghavan</a></li>
36
  </ul>
37
  <p>Please reach out to all of these people and support their projects if you're so inclined.</p>
38
- </div>
 
 
1
+ <?php include W3TC_DIR . '/inc/options/common/header.phtml'; ?>
2
+
3
  <div id="about">
4
  <h3>About</h3>
5
 
37
  <li><a href="http://t3.dotgnu.info/" target="_blank">Gopal Vijayaraghavan</a></li>
38
  </ul>
39
  <p>Please reach out to all of these people and support their projects if you're so inclined.</p>
40
+ </div>
41
+
42
+ <?php include W3TC_DIR . '/inc/options/common/footer.phtml'; ?>
inc/options/cdn.phtml CHANGED
@@ -1,9 +1,8 @@
1
- <?php
2
- $cdn_mirror = ($config->get_string('cdn.engine') == 'mirror');
3
- ?>
4
  <h3><acronym title="Content Delivery Network">CDN</acronym> Settings</h3>
5
 
6
- <p><acronym title="Content Delivery Network">CDN</acronym> support is currently <span class="w3tc-<?php if ($config->get_boolean('cdn.enabled')): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>.</p>
7
 
8
  <?php if ($cdn_mirror): ?>
9
  <p>
@@ -13,71 +12,36 @@ $cdn_mirror = ($config->get_string('cdn.engine') == 'mirror');
13
  <p>
14
  You can <input id="cdn_export_library" class="button" type="button" value="export media library to CDN" />,
15
  use the <input id="cdn_rename_domain" class="button" type="button" value="domain rename tool" />,
16
- <input id="cdn_import_library" class="button" type="button" value="import post files to the Media Library & CDN" /> or
17
- <input id="cdn_queue" class="button" type="button" value="view unsuccessful FTP transfers" /> now.
18
  </p>
19
  <?php endif; ?>
20
 
21
- <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $tab; ?>" method="post">
22
- <?php if (! $cdn_mirror): ?>
23
- <div id="cdn_ftp" class="w3tc-tab-content">
24
- <table class="form-table">
25
- <tr>
26
- <th><label for="cdn_ftp_host"><acronym title="File Transfer Protocol">FTP</acronym> Hostname:</label></th>
27
- <td>
28
- <input id="cdn_ftp_host" type="text" name="cdn.ftp.host" value="<?php echo htmlspecialchars($config->get_string('cdn.ftp.host')); ?>" size="30" />
29
- </td>
30
- </tr>
31
- <tr>
32
- <th><label for="cdn_ftp_user"><acronym title="File Transfer Protocol">FTP</acronym> Username:</label></th>
33
- <td>
34
- <input id="cdn_ftp_user" type="text" name="cdn.ftp.user" value="<?php echo htmlspecialchars($config->get_string('cdn.ftp.user')); ?>" size="30" />
35
- </td>
36
- </tr>
37
- <tr>
38
- <th><label for="cdn_ftp_pass"><acronym title="File Transfer Protocol">FTP</acronym> Password:</label></th>
39
- <td>
40
- <input id="cdn_ftp_pass" type="text" name="cdn.ftp.pass" value="<?php echo htmlspecialchars($config->get_string('cdn.ftp.pass')); ?>" size="30" />
41
- </td>
42
- </tr>
43
- <tr>
44
- <th><label for="cdn_ftp_path"><acronym title="File Transfer Protocol">FTP</acronym> Path:</label></th>
45
- <td>
46
- <input id="cdn_ftp_path" type="text" name="cdn.ftp.path" value="<?php echo htmlspecialchars($config->get_string('cdn.ftp.path')); ?>" size="30" />
47
- </td>
48
- </tr>
49
- <tr>
50
- <th colspan="2">
51
- <input type="hidden" name="cdn.ftp.pasv" value="0" />
52
- <label><input type="checkbox" name="cdn.ftp.pasv" value="1"<?php checked($config->get_boolean('cdn.ftp.pasv'), true); ?> /> Use Passive <acronym title="File Transfer Protocol">FTP</acronym> Mode</label>
53
- </th>
54
- </tr>
55
- </table>
56
- <p>
57
- <input id="test_ftp" class="button" type="button" value="Test FTP server" /> <span id="test_ftp_status" class="w3tc-status w3tc-process"></span>
58
- </p>
59
- </div>
60
- <?php endif; ?>
61
  <table class="form-table">
62
- <tr>
63
- <th style="width: 300px;"><label for="cdn_domain">Replace domain in <acronym title="Uniform Resource Locator">URL</acronym> with:</label></th>
64
- <td>
65
- <input id="cdn_domain" type="text" name="cdn.domain" value="<?php echo htmlspecialchars($config->get_string('cdn.domain')); ?>" size="40" />
66
- </td>
67
- </tr>
68
  <?php if (! $cdn_mirror): ?>
69
  <tr>
70
  <th><label for="cdn_limit_queue">Re-transfer cycle limit:</label></th>
71
  <td>
72
- <input id="cdn_limit_queue" type="text" name="cdn.limit.queue" value="<?php echo htmlspecialchars($config->get_integer('cdn.limit.queue')); ?>" size="10" /><br />
73
- <span class="description">Number of files processed per cycle.</span>
74
  </td>
75
  </tr>
76
  <?php endif; ?>
77
  <tr>
78
  <th<?php if ($cdn_mirror): ?> colspan="2"<?php endif; ?>>
79
  <input type="hidden" name="cdn.includes.enable" value="0" />
80
- <label><input type="checkbox" name="cdn.includes.enable" value="1"<?php checked($config->get_boolean('cdn.includes.enable'), true); ?> /> Host wp-includes/ files</label>
81
  </th>
82
  <?php if (! $cdn_mirror): ?>
83
  <td>
@@ -88,7 +52,7 @@ $cdn_mirror = ($config->get_string('cdn.engine') == 'mirror');
88
  <tr>
89
  <th<?php if ($cdn_mirror): ?> colspan="2"<?php endif; ?>>
90
  <input type="hidden" name="cdn.theme.enable" value="0" />
91
- <label><input type="checkbox" name="cdn.theme.enable" value="1"<?php checked($config->get_boolean('cdn.theme.enable'), true); ?> /> Host active theme files</label>
92
  </th>
93
  <?php if (! $cdn_mirror): ?>
94
  <td>
@@ -99,18 +63,18 @@ $cdn_mirror = ($config->get_string('cdn.engine') == 'mirror');
99
  <tr>
100
  <th<?php if ($cdn_mirror): ?> colspan="2"<?php endif; ?>>
101
  <input type="hidden" name="cdn.minify.enable" value="0" />
102
- <label><input type="checkbox" name="cdn.minify.enable" value="1"<?php checked($config->get_boolean('cdn.minify.enable'), true); ?> /> Host minified <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> files</label>
103
  </th>
104
  <?php if (! $cdn_mirror): ?>
105
  <td>
106
- <input class="button cdn_export" type="button" name="minify" value="Upload minify files" />
107
  </td>
108
  <?php endif; ?>
109
  </tr>
110
  <tr>
111
  <th<?php if ($cdn_mirror): ?> colspan="2"<?php endif; ?>>
112
  <input type="hidden" name="cdn.custom.enable" value="0" />
113
- <label><input type="checkbox" name="cdn.custom.enable" value="1"<?php checked($config->get_boolean('cdn.custom.enable'), true); ?> /> Host custom files</label>
114
  </th>
115
  <?php if (! $cdn_mirror): ?>
116
  <td>
@@ -119,38 +83,45 @@ $cdn_mirror = ($config->get_string('cdn.engine') == 'mirror');
119
  <?php endif; ?>
120
  </tr>
121
  <tr>
122
- <th><label for="cdn_includes_files">Search wp-includes/ directory for files:</label></th>
123
  <td>
124
- <input id="cdn_includes_files" type="text" name="cdn.includes.files" value="<?php echo htmlspecialchars($config->get_string('cdn.includes.files')); ?>" size="40" />
 
125
  </td>
126
  </tr>
127
  <tr>
128
- <th><label for="cdn_theme_files">Search current theme directory for files:</label></th>
129
  <td>
130
- <input id="cdn_theme_files" type="text" name="cdn.theme.files" value="<?php echo htmlspecialchars($config->get_string('cdn.theme.files')); ?>" size="40" />
 
131
  </td>
132
  </tr>
133
  <tr>
134
  <th valign="top"><label for="cdn_custom_files">Custom file list:</label></th>
135
  <td>
136
- <textarea id="cdn_custom_files" name="cdn.custom.files" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $config->get_array('cdn.custom.files'))); ?></textarea>
 
137
  </td>
138
  </tr>
139
  <tr>
140
- <th valign="top"><label for="cdn_reject_ua">Rejected User Agents:</label></th>
141
- <td><textarea id="cdn_reject_ua" name="cdn.reject.ua" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $config->get_array('cdn.reject.ua'))); ?></textarea></td>
 
 
 
142
  </tr>
143
  <?php if (! $cdn_mirror): ?>
144
  <tr>
145
  <th colspan="2">
146
  <input type="hidden" name="cdn.import.external" value="0" />
147
- <label><input type="checkbox" name="cdn.import.external" value="1"<?php checked($config->get_boolean('cdn.import.external'), true); ?> /> Import external media library attachments</label>
148
  </th>
149
  </tr>
150
  <tr>
151
- <th><label for="cdn_import_files">Import files:</label></th>
152
  <td>
153
- <input id="cdn_import_files" type="text" name="cdn.import.files" value="<?php echo htmlspecialchars($config->get_string('cdn.import.files')); ?>" size="40" />
 
154
  </td>
155
  </tr>
156
  <?php endif; ?>
@@ -160,3 +131,5 @@ $cdn_mirror = ($config->get_string('cdn.engine') == 'mirror');
160
  <input type="submit" name="Submit" class="button-primary" value="Save changes" />
161
  </p>
162
  </form>
 
 
1
+ <?php include W3TC_DIR . '/inc/options/common/header.phtml'; ?>
2
+
 
3
  <h3><acronym title="Content Delivery Network">CDN</acronym> Settings</h3>
4
 
5
+ <p><acronym title="Content Delivery Network">CDN</acronym> support is currently <span class="w3tc-<?php if ($cdn_enabled): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>.</p>
6
 
7
  <?php if ($cdn_mirror): ?>
8
  <p>
12
  <p>
13
  You can <input id="cdn_export_library" class="button" type="button" value="export media library to CDN" />,
14
  use the <input id="cdn_rename_domain" class="button" type="button" value="domain rename tool" />,
15
+ <input id="cdn_import_library" class="button" type="button" value="import attachments into the Media Library &amp; CDN" /> or
16
+ <input id="cdn_queue" class="button" type="button" value="view unsuccessful file transfers" /> now.
17
  </p>
18
  <?php endif; ?>
19
 
20
+ <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $this->_tab; ?>" method="post">
21
+ <?php
22
+ switch ($cdn_engine) {
23
+ case 'mirror':
24
+ case 'ftp':
25
+ case 's3':
26
+ case 'cf':
27
+ include W3TC_DIR . '/inc/options/cdn/' . $cdn_engine . '.phtml';
28
+ break;
29
+ }
30
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  <table class="form-table">
 
 
 
 
 
 
32
  <?php if (! $cdn_mirror): ?>
33
  <tr>
34
  <th><label for="cdn_limit_queue">Re-transfer cycle limit:</label></th>
35
  <td>
36
+ <input id="cdn_limit_queue" type="text" name="cdn.limit.queue" value="<?php echo htmlspecialchars($this->_config->get_integer('cdn.limit.queue')); ?>" size="10" /><br />
37
+ <span class="description">Number of files processed per upload attempt.</span>
38
  </td>
39
  </tr>
40
  <?php endif; ?>
41
  <tr>
42
  <th<?php if ($cdn_mirror): ?> colspan="2"<?php endif; ?>>
43
  <input type="hidden" name="cdn.includes.enable" value="0" />
44
+ <label><input type="checkbox" name="cdn.includes.enable" value="1"<?php checked($this->_config->get_boolean('cdn.includes.enable'), true); ?> /> Host wp-includes/ files</label>
45
  </th>
46
  <?php if (! $cdn_mirror): ?>
47
  <td>
52
  <tr>
53
  <th<?php if ($cdn_mirror): ?> colspan="2"<?php endif; ?>>
54
  <input type="hidden" name="cdn.theme.enable" value="0" />
55
+ <label><input type="checkbox" name="cdn.theme.enable" value="1"<?php checked($this->_config->get_boolean('cdn.theme.enable'), true); ?> /> Host active theme files</label>
56
  </th>
57
  <?php if (! $cdn_mirror): ?>
58
  <td>
63
  <tr>
64
  <th<?php if ($cdn_mirror): ?> colspan="2"<?php endif; ?>>
65
  <input type="hidden" name="cdn.minify.enable" value="0" />
66
+ <label><input type="checkbox" name="cdn.minify.enable" value="1"<?php if (! W3TC_PHP5): ?> disabled="disabled"<?php endif; ?><?php checked($this->_config->get_boolean('cdn.minify.enable'), true); ?> /> Host minified <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> files</label>
67
  </th>
68
  <?php if (! $cdn_mirror): ?>
69
  <td>
70
+ <input class="button cdn_export" type="button" name="minify" value="Upload minify files"<?php if (! W3TC_PHP5): ?> disabled="disabled"<?php endif; ?> />
71
  </td>
72
  <?php endif; ?>
73
  </tr>
74
  <tr>
75
  <th<?php if ($cdn_mirror): ?> colspan="2"<?php endif; ?>>
76
  <input type="hidden" name="cdn.custom.enable" value="0" />
77
+ <label><input type="checkbox" name="cdn.custom.enable" value="1"<?php checked($this->_config->get_boolean('cdn.custom.enable'), true); ?> /> Host custom files</label>
78
  </th>
79
  <?php if (! $cdn_mirror): ?>
80
  <td>
83
  <?php endif; ?>
84
  </tr>
85
  <tr>
86
+ <th style="width: 300px;"><label for="cdn_includes_files">wp-includes/ file types to upload:</label></th>
87
  <td>
88
+ <input id="cdn_includes_files" type="text" name="cdn.includes.files" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.includes.files')); ?>" size="40" /><br />
89
+ <span class="description">Specify the file types within the WordPress core to host with the <acronym title="Content Delivery Network">CDN</acronym>.</span>
90
  </td>
91
  </tr>
92
  <tr>
93
+ <th><label for="cdn_theme_files">Theme file types to upload:</label></th>
94
  <td>
95
+ <input id="cdn_theme_files" type="text" name="cdn.theme.files" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.theme.files')); ?>" size="40" /><br />
96
+ <span class="description">Specify the file types in the active theme to host with the <acronym title="Content Delivery Network">CDN</acronym>.</span>
97
  </td>
98
  </tr>
99
  <tr>
100
  <th valign="top"><label for="cdn_custom_files">Custom file list:</label></th>
101
  <td>
102
+ <textarea id="cdn_custom_files" name="cdn.custom.files" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $this->_config->get_array('cdn.custom.files'))); ?></textarea><br />
103
+ <span class="description">Specify any files outside of theme or other common directories to host with the <acronym title="Content Delivery Network">CDN</acronym>.</span>
104
  </td>
105
  </tr>
106
  <tr>
107
+ <th valign="top"><label for="cdn_reject_ua">Rejected user agents:</label></th>
108
+ <td>
109
+ <textarea id="cdn_reject_ua" name="cdn.reject.ua" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $this->_config->get_array('cdn.reject.ua'))); ?></textarea><br />
110
+ <span class="description">Specify user agents that should not access files hosted with the <acronym title="Content Delivery Network">CDN</acronym>.</span>
111
+ </td>
112
  </tr>
113
  <?php if (! $cdn_mirror): ?>
114
  <tr>
115
  <th colspan="2">
116
  <input type="hidden" name="cdn.import.external" value="0" />
117
+ <label><input type="checkbox" name="cdn.import.external" value="1"<?php checked($this->_config->get_boolean('cdn.import.external'), true); ?> /> Import external media library attachments</label>
118
  </th>
119
  </tr>
120
  <tr>
121
+ <th><label for="cdn_import_files">File types to import:</label></th>
122
  <td>
123
+ <input id="cdn_import_files" type="text" name="cdn.import.files" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.import.files')); ?>" size="40" /><br />
124
+ <span class="description">Automatically import files hosted with 3rd parties of these types (if used in your posts / pages) to your media library.</span>
125
  </td>
126
  </tr>
127
  <?php endif; ?>
131
  <input type="submit" name="Submit" class="button-primary" value="Save changes" />
132
  </p>
133
  </form>
134
+
135
+ <?php include W3TC_DIR . '/inc/options/common/footer.phtml'; ?>
inc/options/cdn/cf.phtml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table class="form-table">
2
+ <tr>
3
+ <th style="width:300px;"><label for="cdn_cf_key">Access key:</label></th>
4
+ <td>
5
+ <input id="cdn_cf_key" type="text" name="cdn.cf.key" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.cf.key')); ?>" size="30" />
6
+ </td>
7
+ </tr>
8
+ <tr>
9
+ <th><label for="cdn_cf_secret">Secret key:</label></th>
10
+ <td>
11
+ <input id="cdn_cf_secret" type="text" name="cdn.cf.secret" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.cf.secret')); ?>" size="60" />
12
+ </td>
13
+ </tr>
14
+ <tr>
15
+ <th><label for="cdn_cf_bucket">Bucket:</label></th>
16
+ <td>
17
+ <input id="cdn_cf_bucket" type="text" name="cdn.cf.bucket" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.cf.bucket')); ?>" size="30" />
18
+ <input id="create_bucket_cf" class="button" type="button" value="Create bucket" />
19
+ <span id="create_bucket_cf_status" class="w3tc-status w3tc-process"></span>
20
+ </td>
21
+ </tr>
22
+ <tr>
23
+ <th><label for="cdn_cf_id">Replace default hostname with:</label></th>
24
+ <td>
25
+ <input id="cdn_cf_id" type="text" name="cdn.cf.id" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.cf.id')); ?>" size="18" style="text-align:right;" />.cloudfront.net or <label for="cdn_cf_cname">CNAME:</label> <input id="cdn_cf_cname" type="text" name="cdn.cf.cname" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.cf.cname')); ?>" size="30" /><br />
26
+ <span class="description">If you have already added a <a href="http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/index.html?CNAMEs.html" target="_blank">CNAME</a> to your <acronym title="Domain Name System">DNS</acronym> Zone, enter it here.</span>
27
+ </td>
28
+ </tr>
29
+ </table>
30
+ <p>
31
+ <input id="test_cf" class="button" type="button" value="Test CloudFront upload" />
32
+ <span id="test_cf_status" class="w3tc-status w3tc-process"></span>
33
+ </p>
inc/options/cdn/ftp.phtml ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table class="form-table">
2
+ <tr>
3
+ <th style="width:300px;"><label for="cdn_ftp_host"><acronym title="File Transfer Protocol">FTP</acronym> hostname:</label></th>
4
+ <td>
5
+ <input id="cdn_ftp_host" type="text" name="cdn.ftp.host" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.ftp.host')); ?>" size="30" />
6
+ </td>
7
+ </tr>
8
+ <tr>
9
+ <th><label for="cdn_ftp_user"><acronym title="File Transfer Protocol">FTP</acronym> username:</label></th>
10
+ <td>
11
+ <input id="cdn_ftp_user" type="text" name="cdn.ftp.user" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.ftp.user')); ?>" size="30" />
12
+ </td>
13
+ </tr>
14
+ <tr>
15
+ <th><label for="cdn_ftp_pass"><acronym title="File Transfer Protocol">FTP</acronym> password:</label></th>
16
+ <td>
17
+ <input id="cdn_ftp_pass" type="text" name="cdn.ftp.pass" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.ftp.pass')); ?>" size="30" />
18
+ </td>
19
+ </tr>
20
+ <tr>
21
+ <th><label for="cdn_ftp_path"><acronym title="File Transfer Protocol">FTP</acronym> path:</label></th>
22
+ <td>
23
+ <input id="cdn_ftp_path" type="text" name="cdn.ftp.path" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.ftp.path')); ?>" size="30" /><br />
24
+ <span class="description">Specify the directory where files must be uploaded to be accessible in a web browser.</span>
25
+ </td>
26
+ </tr>
27
+ <tr>
28
+ <th colspan="2">
29
+ <input type="hidden" name="cdn.ftp.pasv" value="0" />
30
+ <label><input type="checkbox" name="cdn.ftp.pasv" value="1"<?php checked($this->_config->get_boolean('cdn.ftp.pasv'), true); ?> /> Use passive <acronym title="File Transfer Protocol">FTP</acronym> mode</label>
31
+ </th>
32
+ </tr>
33
+ <tr>
34
+ <th><label for="cdn_ftp_domain">Replace default hostname with:</label></th>
35
+ <td>
36
+ <input id="cdn_ftp_domain" type="text" name="cdn.ftp.domain" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.ftp.domain')); ?>" size="30" /><br />
37
+ <span class="description">Enter the hostname of your FTP server configured above, this value will replace your blog's hostname in the <acronym title="Hypertext Markup Language">HTML</acronym>.</span>
38
+ </td>
39
+ </tr>
40
+ </table>
41
+ <p>
42
+ <input id="test_ftp" class="button" type="button" value="Test FTP server" /> <span id="test_ftp_status" class="w3tc-status w3tc-process"></span>
43
+ </p>
inc/options/cdn/mirror.phtml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <table class="form-table">
2
+ <tr>
3
+ <th style="width:300px;"><label for="cdn_mirror_domain">Replace default hostname with:</label></th>
4
+ <td>
5
+ <input id="cdn_mirror_domain" type="text" name="cdn.mirror.domain" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.mirror.domain')); ?>" size="30" /><br />
6
+ <span class="description">Enter the hostname provided by your <acronym>CDN</acronym> provider, this value will replace your blog's hostname in the <acronym title="Hypertext Markup Language">HTML</acronym>.</span>
7
+ </td>
8
+ </tr>
9
+ </table>
inc/options/cdn/s3.phtml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table class="form-table">
2
+ <tr>
3
+ <th style="width:300px;"><label for="cdn_s3_key">Access key:</label></th>
4
+ <td>
5
+ <input id="cdn_s3_key" type="text" name="cdn.s3.key" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.s3.key')); ?>" size="30" />
6
+ </td>
7
+ </tr>
8
+ <tr>
9
+ <th><label for="cdn_s3_secret">Secret key:</label></th>
10
+ <td>
11
+ <input id="cdn_s3_secret" type="text" name="cdn.s3.secret" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.s3.secret')); ?>" size="60" />
12
+ </td>
13
+ </tr>
14
+ <tr>
15
+ <th><label for="cdn_s3_bucket">Bucket:</label></th>
16
+ <td>
17
+ <input id="cdn_s3_bucket" type="text" name="cdn.s3.bucket" value="<?php echo htmlspecialchars($this->_config->get_string('cdn.s3.bucket')); ?>" size="30" />
18
+ <input id="create_bucket_s3" class="button" type="button" value="Create bucket" />
19
+ <span id="create_bucket_s3_status" class="w3tc-status w3tc-process"></span>
20
+ </td>
21
+ </tr>
22
+ <tr>
23
+ <th>Replace default hostname with:</th>
24
+ <td>
25
+ <?php if (($cdn_s3_bucket = $this->_config->get_string('cdn.s3.bucket')) != ''): ?>
26
+ <?php echo htmlspecialchars($cdn_s3_bucket); ?>.s3.amazonaws.com
27
+ <?php else: ?>
28
+ &lt;bucket&gt;.s3.amazonaws.com
29
+ <?php endif; ?>
30
+ </td>
31
+ </tr>
32
+ </table>
33
+ <p>
34
+ <input id="test_s3" class="button" type="button" value="Test S3 upload" />
35
+ <span id="test_s3_status" class="w3tc-status w3tc-process"></span>
36
+ </p>
inc/options/common/header.phtml CHANGED
@@ -1,31 +1,42 @@
 
 
 
 
 
 
 
 
 
 
1
  <div class="wrap" id="w3tc">
2
  <?php screen_icon('w3tc-logo'); ?>
3
 
4
  <h2>W3 Total Cache</h2>
5
 
6
- <?php if (count($notes)): ?>
7
- <?php foreach ($notes as $note): ?>
8
- <div id="message" class="updated fade">
9
- <p><?php echo $note; ?></p>
10
- </div>
11
- <?php endforeach; ?>
12
- <?php endif; ?>
13
-
14
- <?php if (count($errors)): ?>
15
- <?php foreach ($errors as $error): ?>
16
- <div id="message" class="error">
17
- <p><?php echo $error; ?></p>
18
- </div>
19
- <?php endforeach; ?>
20
- <?php endif; ?>
21
 
 
 
 
 
 
 
22
  <p id="w3tc-options-menu">
23
- <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=general"<?php if ($tab == 'general'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>General Settings</a> |
24
- <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=pgcache"<?php if ($tab == 'pgcache'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>Page Cache Settings</a> |
25
- <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=minify"<?php if ($tab == 'minify'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>Minify Settings</a> |
26
- <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=dbcache"<?php if ($tab == 'dbcache'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>Database Cache Settings</a> |
27
- <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=cdn"<?php if ($tab == 'cdn'): ?> class="w3tc-options-menu-selected"<?php endif; ?>><acronym title="Content Delivery Network">CDN</acronym> Settings</a> |
28
- <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=faq"<?php if ($tab == 'faq'): ?> class="w3tc-options-menu-selected"<?php endif; ?>><acronym title="Frequently Asked Questions">FAQ</acronym></a> |
29
- <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=install"<?php if ($tab == 'install'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>Installation</a> |
30
- <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=about"<?php if ($tab == 'about'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>About</a>
 
 
 
 
 
31
  </p>
1
+ <?php if ($this->_support_reminder): ?>
2
+ <script type="text/javascript">
3
+ /*<![CDATA[*/
4
+ jQuery(function($) {
5
+ w3tc_lightbox_support_us();
6
+ });
7
+ /*]]>*/
8
+ </script>
9
+ <?php endif; ?>
10
+
11
  <div class="wrap" id="w3tc">
12
  <?php screen_icon('w3tc-logo'); ?>
13
 
14
  <h2>W3 Total Cache</h2>
15
 
16
+ <?php foreach ($this->_errors as $error): ?>
17
+ <div id="message" class="error">
18
+ <p><?php echo $error; ?></p>
19
+ </div>
20
+ <?php endforeach; ?>
 
 
 
 
 
 
 
 
 
 
21
 
22
+ <?php foreach ($this->_notes as $note): ?>
23
+ <div id="message" class="updated fade">
24
+ <p><?php echo $note; ?></p>
25
+ </div>
26
+ <?php endforeach; ?>
27
+
28
  <p id="w3tc-options-menu">
29
+ <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=general"<?php if ($this->_tab == 'general'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>General Settings</a> |
30
+ <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=pgcache"<?php if ($this->_tab == 'pgcache'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>Page Cache Settings</a> |
31
+ <?php if (W3TC_PHP5): ?>
32
+ <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=minify"<?php if ($this->_tab == 'minify'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>Minify Settings</a> |
33
+ <?php else: ?>
34
+ Minify Settings |
35
+ <?php endif; ?>
36
+ <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=dbcache"<?php if ($this->_tab == 'dbcache'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>Database Cache Settings</a> |
37
+ <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=cdn"<?php if ($this->_tab == 'cdn'): ?> class="w3tc-options-menu-selected"<?php endif; ?>><acronym title="Content Delivery Network">CDN</acronym> Settings</a> |
38
+ <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=faq"<?php if ($this->_tab == 'faq'): ?> class="w3tc-options-menu-selected"<?php endif; ?>><acronym title="Frequently Asked Questions">FAQ</acronym></a> |
39
+ <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=support"<?php if ($this->_tab == 'support'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>Support</a> |
40
+ <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=install"<?php if ($this->_tab == 'install'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>Installation</a> |
41
+ <a href="?page=<?php echo W3TC_FILE; ?>&amp;tab=about"<?php if ($this->_tab == 'about'): ?> class="w3tc-options-menu-selected"<?php endif; ?>>About</a>
42
  </p>
inc/options/dbcache.phtml CHANGED
@@ -1,3 +1,5 @@
 
 
1
  <h3>Database Caching Settings</h3>
2
 
3
  <form action="options-general.php">
@@ -5,24 +7,48 @@
5
  Database caching is currently <span class="w3tc-<?php if ($dbcache_enabled): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>.
6
  <input type="submit" name="flush_dbcache" value="Empty cache"<?php if (! $dbcache_enabled): ?> disabled="disabled"<?php endif; ?> class="button" />
7
  <input type="hidden" name="page" value="<?php echo W3TC_FILE; ?>" />
8
- <input type="hidden" name="tab" value="<?php echo $tab; ?>" />
9
  </p>
10
  </form>
11
 
12
- <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $tab; ?>" method="post">
13
  <table class="form-table">
 
14
  <tr>
15
- <th style="width: 250px;"><label for="memcached_servers">Memcached Hostname:Port / IP:Port:</label></th>
16
  <td>
17
- <input id="memcached_servers" type="text" name="dbcache.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $config->get_array('dbcache.memcached.servers'))); ?>" size="100"<?php if (! $dbcache_memcached): ?> disabled="disabled"<?php endif; ?> />
18
- <input id="test_memcached" class="button" type="button" value="Test"<?php if (! $dbcache_memcached): ?> disabled="disabled"<?php endif; ?> />
19
  <span id="test_memcached_status" class="w3tc-status w3tc-process"></span>
20
  <br /><span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
21
  </td>
22
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  <tr>
24
- <th><label for="dbcache_lifetime">Maximum lifetime of cache objects:</label></th>
25
- <td><input id="dbcache_lifetime" type="text" name="dbcache.lifetime" value="<?php echo $config->get_integer('dbcache.lifetime'); ?>" size="8" /> seconds</td>
 
 
 
 
 
 
 
 
 
 
26
  </tr>
27
  </table>
28
 
@@ -30,3 +56,5 @@
30
  <input type="submit" name="Submit" class="button-primary" value="Save changes" />
31
  </p>
32
  </form>
 
 
1
+ <?php include W3TC_DIR . '/inc/options/common/header.phtml'; ?>
2
+
3
  <h3>Database Caching Settings</h3>
4
 
5
  <form action="options-general.php">
7
  Database caching is currently <span class="w3tc-<?php if ($dbcache_enabled): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>.
8
  <input type="submit" name="flush_dbcache" value="Empty cache"<?php if (! $dbcache_enabled): ?> disabled="disabled"<?php endif; ?> class="button" />
9
  <input type="hidden" name="page" value="<?php echo W3TC_FILE; ?>" />
10
+ <input type="hidden" name="tab" value="<?php echo $this->_tab; ?>" />
11
  </p>
12
  </form>
13
 
14
+ <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $this->_tab; ?>" method="post">
15
  <table class="form-table">
16
+ <?php if ($this->_config->get_string('dbcache.engine') == 'memcached'): ?>
17
  <tr>
18
+ <th><label for="memcached_servers">Memcached hostname:port / <acronym title="Internet Protocol">IP</acronym>:port:</label></th>
19
  <td>
20
+ <input id="memcached_servers" type="text" name="dbcache.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $this->_config->get_array('dbcache.memcached.servers'))); ?>" size="100" />
21
+ <input id="test_memcached" class="button" type="button" value="Test" />
22
  <span id="test_memcached_status" class="w3tc-status w3tc-process"></span>
23
  <br /><span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
24
  </td>
25
  </tr>
26
+ <?php endif; ?>
27
+ <tr>
28
+ <th style="width: 250px;"><label for="dbcache_lifetime">Maximum lifetime of cache objects:</label></th>
29
+ <td><input id="dbcache_lifetime" type="text" name="dbcache.lifetime" value="<?php echo $this->_config->get_integer('dbcache.lifetime'); ?>" size="8" /> seconds
30
+ <br /><span class="description">Determines the natural expiration time of unchanged cache items. The higher the value, the larger the cache.</span>
31
+ </td>
32
+ </tr>
33
+ <tr>
34
+ <th><label for="dbcache_file_gc">Garbage collection interval:</label></th>
35
+ <td><input id="dbcache_file_gc" type="text" name="dbcache.file.gc" value="<?php echo $this->_config->get_integer('dbcache.file.gc'); ?>" size="8" /> seconds
36
+ <br /><span class="description">If caching to disk, specify how frequently expired cache data is removed. For busy sites, a lower value is best.</span>
37
+ </td>
38
+ </tr>
39
  <tr>
40
+ <th colspan="2">
41
+ <input type="hidden" name="dbcache.reject.logged" value="0" />
42
+ <label><input type="checkbox" name="dbcache.reject.logged" value="1"<?php checked($this->_config->get_boolean('dbcache.reject.logged'), true); ?> /> Don't cache queries for logged in users</label>
43
+ <br /><span class="description">Enabling this option is recommended to allow default WordPress behavior.</span>
44
+ </th>
45
+ </tr>
46
+ <tr>
47
+ <th valign="top"><label for="dbcache_reject_sql">Ignored query stems:</label></th>
48
+ <td>
49
+ <textarea id="dbcache_reject_sql" name="dbcache.reject.sql" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $this->_config->get_array('dbcache.reject.sql'))); ?></textarea><br />
50
+ <span class="description">Do not cache queries that contain these input contents. The entered prefix (set in wp-config.php) will be replaced with current database prefix (default: wp_).</span>
51
+ </td>
52
  </tr>
53
  </table>
54
 
56
  <input type="submit" name="Submit" class="button-primary" value="Save changes" />
57
  </p>
58
  </form>
59
+
60
+ <?php include W3TC_DIR . '/inc/options/common/footer.phtml'; ?>
inc/options/faq.phtml CHANGED
@@ -1,3 +1,5 @@
 
 
1
  <h3><acronym title="Frequently Asked Questions">FAQ</acronym></h3>
2
 
3
  <h4>Table of Contents</h4>
@@ -53,9 +55,11 @@
53
  <li class="col">
54
  <h5>USAGE:</h5>
55
  <ul>
56
- <li><a href="#q42">So how do I find the <acronym title="JavaScript">JS</acronym> and <acronym title="Cascading Style Sheet">CSS</acronym> to optimize them with this plugin?</a></li>
57
  <li><a href="#q43">I've used the plugin to optimize all my theme's <acronym title="JavaScript">JS</acronym> and plugins <acronym title="JavaScript">JS</acronym>, but there are some function calls, where do those go?</a></li>
58
  <li><a href="#q44">Can I use scripts that generate <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> with this plugin?</a></li>
 
 
59
  <li><a href="#q45">In the past, I always had to modify my theme to run dynamic code. Don't I need to do that again for this plugin?</a></li>
60
  <li><a href="#q46">How fast will the cache be updated?</a></li>
61
  <li><a href="#q47">How do I make some specific pages stay dynamic?</a></li>
@@ -83,13 +87,18 @@
83
  <li><a href="#q69">Won't various 3rd parties who's <acronym title="JavaScript">JS</acronym> I download and cache be concerned?</a></li>
84
  <li><a href="#q70">Google already minified and <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compressed jQuery (and other libraries ) for me, why can't I just use their bandwidth and embed other code after it?</a></li>
85
  <li><a href="#q71">I wanted to use a different version jQuery with my theme, how do I replace WordPress' jQuery with Google's minified version using your plugin?</a></li>
86
- <li><a href="#q72">What about the wp-includes files, can those be served from the <acronym title="Content Delivery Network">CDN</acronym>?</a></li>
87
  <li><a href="#q73">What if I don't want to work with a <acronym title="Content Delivery Network">CDN</acronym> right now, is there any other use for this feature?</a></li>
88
  <li><a href="#q74">Are minified files uploaded to my <acronym title="Content Delivery Network">CDN</acronym> provider?</a></li>
89
  <li><a href="#q75">Who do you recommend as a <acronym title="Content Delivery Network">CDN</acronym> provider?</a></li>
90
  <li><a href="#q76">Hang on, don't I need to modify my <acronym title="Cascading Style Sheet">CSS</acronym> files so they'll work on the <acronym title="Content Delivery Network">CDN</acronym>?</a></li>
91
  <li><a href="#q77">I don't have time to deal with this, but I know I need it. Will you help me?</a></li>
92
  <li><a href="#q92">What about query string variables on <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym>, do they matter?</a></li>
 
 
 
 
 
93
  </ul>
94
  </li>
95
  <li class="col">
@@ -167,7 +176,7 @@
167
  First let me point out that in many cases we suggest putting all the <acronym title="JavaScript">JS</acronym> that's not required for interactivity with your site at the bottom of the document. Anything <acronym title="JavaScript">JS</acronym> that makes the site work as intended we suggested embedding in the &lt;head&gt;. Depending on your specific situation, having the majority of your <acronym title="JavaScript">JS</acronym> at the bottom of the document will mean that your visitors won't have to download things they don't want to begin interacting with your site or reading it's content. Quite often the additional <acronym title="Hypertext Transfer Protocol">HTTP</acronym> transaction is worthwhile.</p>
168
  <p align="right"><a href="#toc">back to top</a></p>
169
  <p id="q10"><strong>What's an Etag and why do I need one?</strong><br />
170
- Etags were created to add more reliability to client side caching my providing a simple method for a browser to verify that a file had not changed since last it was downloaded. Using them enables your server to return 304 or "not modified" responses instead of other responses which are much much slower. The result is a visitor viewing multiple pages of your site would have that "instant loading" experience that we all definitely enjoy. Don't worry we don't use inodes to create our Etags so this solution is reliable for multi server hosting solutions.</p>
171
  <p align="right"><a href="#toc">back to top</a></p>
172
  <p id="q11"><strong>So let me get this straight; you're telling me this plugin is designed to improve performance of any WordPress blog?</strong><br />
173
  Precisely, that is unless you don't write any posts in your blog nor have any readers. If you're someone that's always into the latest web development technique or plugin, now you can "have it all" without making your readers suffer.</p>
@@ -175,9 +184,17 @@
175
  <p id="q12"><strong>This is too good to be true, how can I test the results?</strong><br />
176
  You will be able to see it instantly on each page load, but for tangible metrics, consider the following tools:</p>
177
  <ul>
178
- <li><a href="http://www.mozilla.com/firefox/" target="_blank">Firefox</a> + <a href="http://getfirebug.com/" target="_blank">Firebug</a> + <a href="http://developer.yahoo.com/yslow/" target="_blank">Yahoo! YSlow</a></li>
179
- <li><a href="http://www.gomez.com/instant-test-pro/" target="_blank">Gomez Instant Test Pro</a></li>
 
 
 
 
 
180
  <li><a href="http://www.webpagetest.org/test" target="_blank">WebPagetest</a></li>
 
 
 
181
  <li><a href="http://www.port80software.com/tools/compresscheck.asp" target="_blank">Port80 Compression Check</a> (requires <acronym title="Microsoft Internet Explorer">MSIE</acronym>6 support to be enabled)</li>
182
  <li><a href="http://www.gidnetwork.com/tools/gzip-test.php" target="_blank">A simple online web page compression / deflate / <acronym title="GNU zip">gzip</acronym> test tool</a></li>
183
  <li><a href="http://www.websiteoptimization.com/services/analyze/" target="_blank">Web Page Analyzer</a></li>
@@ -190,7 +207,7 @@
190
  Not sure, we'll get to that soon.</p>
191
  <p align="right"><a href="#toc">back to top</a></p>
192
  <p id="q15"><strong>Which WordPress versions are supported?</strong><br />
193
- To use all features in the suite, a minimum of version 2.5 is required. Earlier versions will benefit from our Media Library Importer to get them back on the upgrade path and into a <acronym title="Content Delivery Network">CDN</acronym> of their choosing.</p>
194
  <p align="right"><a href="#toc">back to top</a></p>
195
  <p id="q16"><strong>I understand the database caching and the page caching, but what's minify all about?</strong><br />
196
  We'll just quote the fine folks at yahoo on this one:</p>
@@ -201,7 +218,7 @@
201
  <cite><a href="http://developer.yahoo.com/performance/rules.html#minify" target="_blank">developer.yahoo.com</a></cite> </blockquote>
202
  <p align="right"><a href="#toc">back to top</a></p>
203
  <p id="q17"><strong>What do you use to minify?</strong><br />
204
- We use: <a href="http://code.google.com/p/minify/" target="_blank">minify</a> but may support various engines in the future. Based on <a href="http://ejohn.org/" target="_blank">John Resig's</a> suggestion we're currently looking at <a href="http://yuilibrary.com/projects/yuicompressor/wiki" target="_blank"><acronym title="Yahoo! User Interface">YUI</acronym> Compressor</a> also.</p>
205
  <p align="right"><a href="#toc">back to top</a></p>
206
  <p id="q18"><strong>What's the point of downloading and caching 3rd party files (e.g. <acronym title="JavaScript">JS</acronym>)?</strong><br />
207
  With the various hosted 3rd party applications available (from web site statistics to social media sharing widgets), the problems we've noticed are: additional <acronym title="Hypertext Transfer Protocol">HTTP</acronym> transactions, <acronym title="Domain Name System">DNS</acronym> lookups and latencies from busy servers that we can't control and often un-minified files with no <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression all add up to a very slow page load and poor user experience. With your own copy of external files, updated as frequently as you wish, none of these problems exist.</p>
@@ -294,7 +311,7 @@
294
  </ul>
295
  <p>Please reach out to all of these people and support their projects if you're so inclined.</p>
296
  <p align="right"><a href="#toc">back to top</a></p>
297
- <p id="q42"><strong>So how do I find the <acronym title="JavaScript">JS</acronym> and <acronym title="Cascading Style Sheet">CSS</acronym> to optimize them with this plugin?</strong><br />
298
  View your page source in your browser and search for any &lt;style&gt;, &lt;link&gt; or &lt;script&gt; tags that contain external <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> files and one by one add them to the minify settings page. Do not include any <acronym title="Cascading Style Sheet">CSS</acronym> in conditional statements (unless you know what you are doing) like:</p>
299
  <p>&lt;!--[if lte IE 8]&gt;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/wp-content/themes/default/lte.css&quot; media=&quot;screen,projection&quot; /&gt;&lt;![endif]--&gt;</p>
300
  <p>The plugin will concatenate, minify, <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compress and check for updates to these files automatically from now on. If you have any <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> that are inline consider making them external files so that you can use them with minify.</p>
@@ -305,8 +322,18 @@
305
  <p id="q44"><strong>Can I use scripts that generate <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> with this plugin?</strong><br />
306
  Yes you can, but since there are numerous ways to do so, so be sure to test your results carefully. Having said that we do encourage it as it will mean that less processing has to be done to deliver your pages.</p>
307
  <p align="right"><a href="#toc">back to top</a></p>
 
 
 
 
 
 
 
 
 
 
308
  <p id="q45"><strong>In the past, I always had to modify my theme to run dynamic code. Don't I need to do that again for this plugin?</strong><br />
309
- Absolutely not. This plugin doesn't require you to do anything differently to develop or maintain your blog. You'll want to remove any special calls you had in place for your old plugins, although they will be ignored by our plugin in any case.</p>
310
  <p align="right"><a href="#toc">back to top</a></p>
311
  <p id="q46"><strong>How fast will the cache be updated?</strong><br />
312
  Items expire from the cache at a rate that you specify. As far as how fast changes appear to your visitors, they appear instantly in most cases and if you're an administrator who's logged in they will always be immediately visible.</p>
@@ -318,7 +345,7 @@
318
  On the contrary, as with any other action a user can perform on a site, faster performance will encourage more of it. The cache is so quickly rebuilt in memory that it's no trouble to show visitors the most current version of a post that's experiencing Digg, Slashdot, Drudge Report, Yahoo Buzz or Twitter effect.</p>
319
  <p align="right"><a href="#toc">back to top</a></p>
320
  <p id="q49"><strong>What if I accidentally specify an incorrect path to a <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> file?</strong><br />
321
- Unfortunately a 400 bad request error may be generated. So use the "Check <acronym title="Uniform Resource Indicator">URL</acronym>" button to make sure that you have entered the correct <acronym title="Uniform Resource Indicator">URL</acronym> or path to the file.</p>
322
  <p align="right"><a href="#toc">back to top</a></p>
323
  <p id="q50"><strong>Does the plugin automatically remove duplicate <acronym title="JavaScript">JS</acronym>?</strong><br />
324
  No. If you include a script in the minfy settings twice or it already exists in your theme we do not automatically remove the extra code. That's tricky business and it's better for us to just let you make the decisions conscientiously.</p>
@@ -341,8 +368,8 @@ No, you can drag and drop them into the desired order on the minify settings pag
341
  <p align="right"><a href="#toc">back to top</a></p>
342
  <p id="q56"><strong>I'm not a hardcore developer, can you explain to me how this // and / stuff works and how I should specify the paths for <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym> files?</strong><br />
343
  You mean on the minify settings page right? Ok, it's simple:<br />
344
- // tells the plugin to search for the file with the provided path from the document root, e.g.: //wp-includes/JS/jquery/jquery.<acronym title="JavaScript">JS</acronym><br />
345
- / tells the plugin to search for the file with the provided path from the server root, e.g. /wp-includes/JS/jquery/jquery.<acronym title="JavaScript">JS</acronym></p>
346
  <p>In most cases providing an absolute path is sufficient and most reliable. You can of course use relative paths, but we discourage it unless you really know what you are doing.</p>
347
  <p align="right"><a href="#toc">back to top</a></p>
348
  <p id="q57"><strong>What about Etags?</strong><br />
@@ -355,13 +382,12 @@ No, you can drag and drop them into the desired order on the minify settings pag
355
  Right now we do not show the statistics in <acronym title="WordPress">WP</acronym> Admin, but soon we will provide graphs of: Page Cache Memory Use, Page Cache Hits/Misses, <acronym title="Database">DB</acronym> Cache Memory Use, <acronym title="Database">DB</acronym> Hits/Misses, Average Page Compression Savings, Average <acronym title="Cascading Style Sheet">CSS</acronym> Compression Savings, Average <acronym title="JavaScript">JS</acronym> Compression Savings, Average Requests per Second, and Average Page Execution Time.</p>
356
  <p align="right"><a href="#toc">back to top</a></p>
357
  <p id="q60"><strong>How can I tell if it's working? Aren't there any statistics at all?</strong><br />
358
- Well yes actually there are. If you're logged in as an administrator they will be appended to the bottom of the source code. Keep in mind that there's a bit of work to show the stats so effort to produce the pages for the visitors is a bit less.</p>
359
- <p align="right"><a href="#toc">back to top</a></p>
360
  <p id="q61"><strong>I'm an advanced theme developer and I want to have different combinations of <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> files on different types of pages in my theme; how is this done?</strong><br />
361
- Great question, we understand the use case all too well. Right now you cannot create different groups of <acronym title="JavaScript">JS</acronym> and <acronym title="Cascading Style Sheet">CSS</acronym> files for your home, page, post, archive or 404 etc. This feature is coming soon; it did not make the first cut.</p>
362
  <p align="right"><a href="#toc">back to top</a></p>
363
  <p id="q62"><strong>Which features can I use if I haven't yet installed <acronym title="Alternative PHP Cache">APC</acronym> or memcached?</strong><br />
364
- Memory caching will not be possible. However you will be able to use both the page cache and minify in "disk" mode, as well <acronym title="Content Delivery Network">CDN</acronym> functionality without issue. Remember that W3 Total Cache is not compatible with other caching plugins, so you'll want to install <acronym title="Alternative PHP Cache">APC</acronym> and/or memcached as soon as possible.</p>
365
  <p align="right"><a href="#toc">back to top</a></p>
366
  <p id="q63"><strong>How can I host my favicon with my <acronym title="Content Delivery Network">CDN</acronym>?</strong><br />
367
  If the file exists in your document root (i.e. http://domain.com/favicon.ico), the plugin can take care of that for you using custom upload options. If the file is in your theme directory you can also have the plugin uploaded from there.</p>
@@ -399,7 +425,7 @@ No, you can drag and drop them into the desired order on the minify settings pag
399
  Currently you cannot, replacement is not yet supported.</p>
400
  <p align="right"><a href="#toc">back to top</a></p>
401
  <p id="q72"><strong>What about the wp-includes files, can those be served from the <acronym title="Content Delivery Network">CDN</acronym>?</strong><br />
402
- Yes, you can specify which file types you would like served from your <acronym title="Content Delivery Network">CDN</acronym> and they will be uploaded and always downloaded from that location. This includes the smiles, manfest.xml et al. By default we take care of them all.</p>
403
  <p align="right"><a href="#toc">back to top</a></p>
404
  <p id="q73"><strong>What if I don't want to work with a <acronym title="Content Delivery Network">CDN</acronym> right now, is there any other use for this feature?</strong><br />
405
  Yes! You can take advantage of the <a href="http://www.mozilla.org/projects/netlib/http/pipelining-faq.html">pipelining</a> support in some browsers by creating a sub-domain for the static content for your site. So you could create static.domain.com on your server (and update your <acronym title="Domain Name System">DNS</acronym> zone) and then specify the <acronym title="File Transfer Protocol">FTP</acronym> details for it in the plugin configuration panel and you're done. If you disable the scripting options on your server you'll find that your server will actually respond slightly faster from that sub-domain because it's just sending files and not processing them.</p>
@@ -410,13 +436,16 @@ No, you can drag and drop them into the desired order on the minify settings pag
410
  <p id="q75"><strong>Who do you recommend as a <acronym title="Content Delivery Network">CDN</acronym> provider?</strong><br />
411
  That depends on how you use your blog and where most of your readers read your blog (regionally). Here's a short list:</p>
412
  <ul>
413
- <li><a href="http://www.netdna.com/" target="_blank">NetDNA</a></li>
414
- <li><a href="http://www.simplecdn.com/" target="_blank">Simple<acronym title="Content Delivery Network">CDN</acronym></a></li>
 
415
  <li><a href="http://aws.amazon.com/s3/" target="_blank">Amazon S3</a> / <a href="http://aws.amazon.com/cloudfront/" target="_blank">Cloudfront</a></li>
 
416
  <li><a href="http://www.edgecast.com/" target="_blank">EdgeCast</a></li>
417
- <li><a href="http://www.voxel.net/products-services/voxcast-cdn" target="_blank">Voxel</a></li>
418
- <li><a href="http://www.limelightnetworks.com/" target="_blank">Limelight Networks</a></li>
419
  <li><a href="http://www.akamai.com/" target="_blank">Akamai</a></li>
 
 
 
420
  </ul>
421
  <p align="right"><a href="#toc">back to top</a></p>
422
  <p id="q76"><strong>Hang on, don't I need to modify my <acronym title="Cascading Style Sheet">CSS</acronym> files so they'll work on the <acronym title="Content Delivery Network">CDN</acronym>?</strong><br />
@@ -428,6 +457,28 @@ No, you can drag and drop them into the desired order on the minify settings pag
428
  <p id="q92"><strong>What about query string variables on <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym>, do they matter?</strong><br />
429
  This is definitely a special case. Files like "http://domain.com/wp-content/themes/default/js/script.js?ver=20090102" etc need to be specified with the full <acronym title="Uniform Resource Locator">URL</acronym>. This is an exception to the general rule of specifying a local path to file like: "wp-content/themes/default/js/script.js", which should also work fine. Be sure to click the "Verify <acronym title="Uniform Resource Indicator">URL</acronym>" button to be sure that everything is ok before saving changes.</p>
430
  <p align="right"><a href="#toc">back to top</a></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  <p id="q78"><strong>Which web servers do you support?</strong><br />
432
  We are aware of no incompatibilities with <a href="http://httpd.apache.org/" target="_blank">apache</a> 1.3+, <a href="http://www.iis.net/" target="_blank">IIS</a> 5+ or <a href="http://litespeedtech.com/products/webserver/overview/" target="_blank">litespeed</a> 4.0.2+. If there's a web server you feel we should be actively testing (e.g. <a href="http://www.lighttpd.net/" target="_blank">lighttpd</a>), we're <a href="mailto:wordpressexperts@w3-edge.com">interested in hearing</a>.</p>
433
  <p align="right"><a href="#toc">back to top</a></p>
@@ -436,15 +487,19 @@ No, you can drag and drop them into the desired order on the minify settings pag
436
  <p>If you're larger organization or a web hosting company, consider looking into solutions that exist like <a href="http://www.gear6.com/">Gear6</a> which could be useful now that you have a plugin that makes management memcached pain free.</p>
437
  <p align="right"><a href="#toc">back to top</a></p>
438
  <p id="q80"><strong>Is this plugin compatible with varnish or squid?</strong><br />
439
- Yes, it is compatible with <a href="http://varnish.projects.linpro.no/" target="_blank">varnish</a> and <a href="http://www.squid-cache.org/" target="_blank">squid</a>, however (with regard to dynamic content) we have yet to find a practical case where either can provide more scale for an individual server than apache 2+ if properly configured.</p>
440
  <p align="right"><a href="#toc">back to top</a></p>
441
  <p id="q81"><strong>My server is state of the art with 15,000 RPM RAID, why do I need to cache anything in memory?</strong><br />
442
  Even if your server was using an array of solid state disks (SSD), your server's <acronym title="Random Access Memory">RAM</acronym> is still going to be faster and introduce less overhead to access than even the fastest solid state drives on a PCIe bus. If you didn't invest in solid state disks for your server, then even worse off - at least an order of magnitude speed difference in read operations in <acronym title="Random Access Memory">RAM</acronym> versus HDD. For write operations delta the latency differences is even more pronounced. <acronym title="Random Access Memory">RAM</acronym> is the winner hands down. We won't even discuss the blocking and arbitration issues that happen with disk arrays under certain circumstances.</p>
443
  <p align="right"><a href="#toc">back to top</a></p>
444
  <p id="q82"><strong>Why would I choose <acronym title="Alternative PHP Cache">APC</acronym> over memcached or vice versa?</strong><br />
445
  There's no straight answer for this one. Since WordPress is a PHP-based application, we encourage everyone to install <acronym title="Alternative PHP Cache">APC</acronym> and subsequently realize a minimum of 10x performance gain. It will obviously make our plugin faster as well, so again please check out the installation instructions if you do not already use <acronym title="Alternative PHP Cache">APC</acronym>. Once installed, you can select <acronym title="Alternative PHP Cache">APC</acronym> as your caching engine in our plugin and get back to blogging.</p>
446
- <p><acronym title="Alternative PHP Cache">APC</acronym>'s only weakness is that if you frequently restart your web server (e.g. apache) especially during high traffic periods, you will lose your cache and your site will slow down as it rebuilds the cache (which happens very quickly). However if you use memcached you would not lose your cache if your web server is restarted. It would appear that using <acronym title="Alternative PHP Cache">APC</acronym> for all cases is best, but your mileage may vary. So depending on what software you install and how you manage your server, you can choose the options to fit your needs.</p>
447
- <p>If you need help with the install on your dedicated or virtual dedicated linux-based server ask us!</p>
 
 
 
 
448
  <p align="right"><a href="#toc">back to top</a></p>
449
  <p id="q83"><strong>I already use <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression on my server, why does it matter if I minify my code?</strong><br />
450
  Let's say you had a file of 10240 bytes, which becomes 2048 bytes when compressed, savings of ~80% (typical for <acronym title="Cascading Style Sheet">CSS</acronym> files). That same file will now have an <strong>additional</strong> ~3x-10x transfer speed improvement when minified. That's a big return from a small operation. The larger your files, the more significant the proportional performance gains.</p>
@@ -461,7 +516,7 @@ No, you can drag and drop them into the desired order on the minify settings pag
461
  <p>For those that don't want or have time to learn anything new to get started, sample configuration files are included with the plugin containing inline comments for you.</p>
462
  <p align="right"><a href="#toc">back to top</a></p>
463
  <p id="q85"><strong>What version of <acronym title="Hypertext Preprocessor">PHP</acronym> do I need for this thing?</strong><br />
464
- Version 4.3 is supported, version 5 preferred (it's much much faster especially with <acronym title="Alternative PHP Cache">APC</acronym>).</p>
465
  <p align="right"><a href="#toc">back to top</a></p>
466
  <p id="q86"><strong>What version of mySQL is needed?</strong><br />
467
  If your WordPress installation is works, you're all set.</p>
@@ -476,10 +531,12 @@ No, you can drag and drop them into the desired order on the minify settings pag
476
  Yes, built from the ground up with scale and current hosting paradigms in mind.</p>
477
  <p align="right"><a href="#toc">back to top</a></p>
478
  <p id="q90"><strong>I'm a web hosting provider and I heard about this plugin from my clients, is this plugin safe for a shared hosting environment?<br />
479
- </strong>Not yet. The next release has ~30 more features and one of them is the remedy to data security concerns for a shared (virtual) hosting environment.</p>
480
  <p align="right"><a href="#toc">back to top</a></p>
481
  <p id="q91"><strong>What is the intended impact of this plugin on the web hosting landscape?</strong><br />
482
  We feel that shared or virtual hosting providers will begin offering secure containers (similar to what <a href="http://mediatemple.net/" target="_blank">mediatemple.net</a> does for mySQL and Ruby etc) for <acronym title="Alternative PHP Cache">APC</acronym> and memcached. Whoever brings this offering to market first will lower the bar for more web sites/applications (and startups) to build better performing applications with greater ease. The same hosting provider would also possess a new value added service, thereby realizing a competitive advantage in a highly competitive marketplace. Not to mention be able to increase the density of domains per server (or cluster) without shortchanging customers.</p>
483
  <p>One day hopefully this plugin will contribute to making web servers greener and reduce the ecological footprint of the web by reducing the computational effort required to deliver high performance rich user experiences.</p>
484
  <p align="right"><a href="#toc">back to top</a></p>
485
  </div>
 
 
1
+ <?php include W3TC_DIR . '/inc/options/common/header.phtml'; ?>
2
+
3
  <h3><acronym title="Frequently Asked Questions">FAQ</acronym></h3>
4
 
5
  <h4>Table of Contents</h4>
55
  <li class="col">
56
  <h5>USAGE:</h5>
57
  <ul>
58
+ <li><a href="#q42">How do I find the <acronym title="JavaScript">JS</acronym> and <acronym title="Cascading Style Sheet">CSS</acronym> to optimize (minify) them with this plugin?</a></li>
59
  <li><a href="#q43">I've used the plugin to optimize all my theme's <acronym title="JavaScript">JS</acronym> and plugins <acronym title="JavaScript">JS</acronym>, but there are some function calls, where do those go?</a></li>
60
  <li><a href="#q44">Can I use scripts that generate <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> with this plugin?</a></li>
61
+ <li><a href="#q93">How do I configure Amazon Simple Storage Service (Amazon <acronym title="Simple Storage Service">S3</acronym>) or Amazon CloudFront as my <acronym title="Content Delivery Network">CDN</acronym>?</a></li>
62
+ <li><a href="#q94">How do I use an Origin Pull (Mirror) <acronym title="Content Delivery Network">CDN</acronym>?</a></li>
63
  <li><a href="#q45">In the past, I always had to modify my theme to run dynamic code. Don't I need to do that again for this plugin?</a></li>
64
  <li><a href="#q46">How fast will the cache be updated?</a></li>
65
  <li><a href="#q47">How do I make some specific pages stay dynamic?</a></li>
87
  <li><a href="#q69">Won't various 3rd parties who's <acronym title="JavaScript">JS</acronym> I download and cache be concerned?</a></li>
88
  <li><a href="#q70">Google already minified and <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compressed jQuery (and other libraries ) for me, why can't I just use their bandwidth and embed other code after it?</a></li>
89
  <li><a href="#q71">I wanted to use a different version jQuery with my theme, how do I replace WordPress' jQuery with Google's minified version using your plugin?</a></li>
90
+ <li><a href="#q72">What about the files, can those be served from the <acronym title="Content Delivery Network">CDN</acronym>?</a></li>
91
  <li><a href="#q73">What if I don't want to work with a <acronym title="Content Delivery Network">CDN</acronym> right now, is there any other use for this feature?</a></li>
92
  <li><a href="#q74">Are minified files uploaded to my <acronym title="Content Delivery Network">CDN</acronym> provider?</a></li>
93
  <li><a href="#q75">Who do you recommend as a <acronym title="Content Delivery Network">CDN</acronym> provider?</a></li>
94
  <li><a href="#q76">Hang on, don't I need to modify my <acronym title="Cascading Style Sheet">CSS</acronym> files so they'll work on the <acronym title="Content Delivery Network">CDN</acronym>?</a></li>
95
  <li><a href="#q77">I don't have time to deal with this, but I know I need it. Will you help me?</a></li>
96
  <li><a href="#q92">What about query string variables on <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym>, do they matter?</a></li>
97
+ <li><a href="#q95">Is this plugin comptatible with GD Star Rating?</li>
98
+ <li><a href="#q96">How do I cache only the home page?</a></li>
99
+ <li><a href="#q97">I see garbage characters instead of the normal web site, what's going on here?</a></li>
100
+ <li><a href="#q98">What is the purpose of the "Media Library Import" tool and how do I use it?</a></li>
101
+ <li><a href="#q99">I'm getting blank pages or 500 error codes when trying to upgrade on WordPress MU</a></li>
102
  </ul>
103
  </li>
104
  <li class="col">
176
  First let me point out that in many cases we suggest putting all the <acronym title="JavaScript">JS</acronym> that's not required for interactivity with your site at the bottom of the document. Anything <acronym title="JavaScript">JS</acronym> that makes the site work as intended we suggested embedding in the &lt;head&gt;. Depending on your specific situation, having the majority of your <acronym title="JavaScript">JS</acronym> at the bottom of the document will mean that your visitors won't have to download things they don't want to begin interacting with your site or reading it's content. Quite often the additional <acronym title="Hypertext Transfer Protocol">HTTP</acronym> transaction is worthwhile.</p>
177
  <p align="right"><a href="#toc">back to top</a></p>
178
  <p id="q10"><strong>What's an Etag and why do I need one?</strong><br />
179
+ Entity tags were created to add more reliability to client side caching my providing a simple method for a browser to verify that a file had not changed since last it was downloaded. Using them helps enables your server return 304 or "not modified" responses instead of a 200 "ok" response which are much much slower (because the file is sent). The result is a visitor viewing multiple pages of your site would have that "instant loading" experience that we all definitely enjoy. Don't worry we don't use inodes to create our Etags so this solution is reliable for multi server hosting solutions.</p>
180
  <p align="right"><a href="#toc">back to top</a></p>
181
  <p id="q11"><strong>So let me get this straight; you're telling me this plugin is designed to improve performance of any WordPress blog?</strong><br />
182
  Precisely, that is unless you don't write any posts in your blog nor have any readers. If you're someone that's always into the latest web development technique or plugin, now you can "have it all" without making your readers suffer.</p>
184
  <p id="q12"><strong>This is too good to be true, how can I test the results?</strong><br />
185
  You will be able to see it instantly on each page load, but for tangible metrics, consider the following tools:</p>
186
  <ul>
187
+ <li><a href="http://www.mozilla.com/firefox/" target="_blank">Mozilla Firefox</a> + <a href="http://getfirebug.com/" target="_blank">Firebug</a> + <a href="http://developer.yahoo.com/yslow/" target="_blank">Yahoo! YSlow</a></li>
188
+ <li><a href="http://www.mozilla.com/firefox/" target="_blank">Mozilla Firefox</a> + <a href="http://getfirebug.com/" target="_blank">Firebug</a> + <a href="http://code.google.com/speed/page-speed/" target="_blank">Google Page Speed</a></li>
189
+ <li><a href="http://www.mozilla.com/firefox/" target="_blank">Mozilla Firefox</a> + <a href="http://getfirebug.com/" target="_blank">Firebug</a> + <a href="http://stevesouders.com/hammerhead/" target="_blank">Hammerhead</a></li>
190
+ <li><a href="http://www.google.com/chrome" target="_blank">Google Chrome</a> + <a href="http://code.google.com/webtoolkit/speedtracer/" target="_blank">Google Speed Tracer</a></li>
191
+ </ul>
192
+ <ul>
193
+ <li><a href="http://tools.pingdom.com/" target="_blank">Pingdom</a></li>
194
  <li><a href="http://www.webpagetest.org/test" target="_blank">WebPagetest</a></li>
195
+ <li><a href="http://www.gomez.com/instant-test-pro/" target="_blank">Gomez Instant Test Pro</a></li>
196
+ </ul>
197
+ <ul>
198
  <li><a href="http://www.port80software.com/tools/compresscheck.asp" target="_blank">Port80 Compression Check</a> (requires <acronym title="Microsoft Internet Explorer">MSIE</acronym>6 support to be enabled)</li>
199
  <li><a href="http://www.gidnetwork.com/tools/gzip-test.php" target="_blank">A simple online web page compression / deflate / <acronym title="GNU zip">gzip</acronym> test tool</a></li>
200
  <li><a href="http://www.websiteoptimization.com/services/analyze/" target="_blank">Web Page Analyzer</a></li>
207
  Not sure, we'll get to that soon.</p>
208
  <p align="right"><a href="#toc">back to top</a></p>
209
  <p id="q15"><strong>Which WordPress versions are supported?</strong><br />
210
+ To use all features in the suite, a minimum version of 2.5 is required. Earlier versions will benefit from our Media Library Importer to get them back on the upgrade path and into a <acronym title="Content Delivery Network">CDN</acronym> of their choosing.</p>
211
  <p align="right"><a href="#toc">back to top</a></p>
212
  <p id="q16"><strong>I understand the database caching and the page caching, but what's minify all about?</strong><br />
213
  We'll just quote the fine folks at yahoo on this one:</p>
218
  <cite><a href="http://developer.yahoo.com/performance/rules.html#minify" target="_blank">developer.yahoo.com</a></cite> </blockquote>
219
  <p align="right"><a href="#toc">back to top</a></p>
220
  <p id="q17"><strong>What do you use to minify?</strong><br />
221
+ We use: <a href="http://code.google.com/p/minify/" target="_blank">minify</a> but may support various engines in the future. Based on <a href="http://ejohn.org/" target="_blank">John Resig's</a> suggestion we're currently looking at <a href="http://yuilibrary.com/projects/yuicompressor/wiki" target="_blank"><acronym title="Yahoo! User Interface">YUI</acronym> Compressor</a> and <a href="http://code.google.com/closure/compiler/" target="_blank">Google Closure Compiler</a> (for JavaScript) also.</p>
222
  <p align="right"><a href="#toc">back to top</a></p>
223
  <p id="q18"><strong>What's the point of downloading and caching 3rd party files (e.g. <acronym title="JavaScript">JS</acronym>)?</strong><br />
224
  With the various hosted 3rd party applications available (from web site statistics to social media sharing widgets), the problems we've noticed are: additional <acronym title="Hypertext Transfer Protocol">HTTP</acronym> transactions, <acronym title="Domain Name System">DNS</acronym> lookups and latencies from busy servers that we can't control and often un-minified files with no <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression all add up to a very slow page load and poor user experience. With your own copy of external files, updated as frequently as you wish, none of these problems exist.</p>
311
  </ul>
312
  <p>Please reach out to all of these people and support their projects if you're so inclined.</p>
313
  <p align="right"><a href="#toc">back to top</a></p>
314
+ <p id="q42"><strong>How do I find the <acronym title="JavaScript">JS</acronym> and <acronym title="Cascading Style Sheet">CSS</acronym> to optimize (minify) them with this plugin?</strong><br />
315
  View your page source in your browser and search for any &lt;style&gt;, &lt;link&gt; or &lt;script&gt; tags that contain external <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> files and one by one add them to the minify settings page. Do not include any <acronym title="Cascading Style Sheet">CSS</acronym> in conditional statements (unless you know what you are doing) like:</p>
316
  <p>&lt;!--[if lte IE 8]&gt;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/wp-content/themes/default/lte.css&quot; media=&quot;screen,projection&quot; /&gt;&lt;![endif]--&gt;</p>
317
  <p>The plugin will concatenate, minify, <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compress and check for updates to these files automatically from now on. If you have any <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> that are inline consider making them external files so that you can use them with minify.</p>
322
  <p id="q44"><strong>Can I use scripts that generate <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> with this plugin?</strong><br />
323
  Yes you can, but since there are numerous ways to do so, so be sure to test your results carefully. Having said that we do encourage it as it will mean that less processing has to be done to deliver your pages.</p>
324
  <p align="right"><a href="#toc">back to top</a></p>
325
+ <p id="q93"><strong>How do I configure Amazon Simple Storage Service (Amazon <acronym title="Simple Storage Service">S3</acronym>) or Amazon CloudFront as my <acronym title="Content Delivery Network">CDN</acronym>?</strong><br />
326
+ First <a href="http://aws.amazon.com/" target="_blank">create an <acronym title="Simple Storage Service">S3</acronym> account</a>. Next, you need to obtain your "Access key" and "Secret key" from the "Access Credentials" section of the "<a href="http://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key" target="_blank">Security Credentials</a>" page of "My Account." Make sure the status is "active." Next, make sure that "Amazon Simple Storage Service (Amazon <acronym title="Simple Storage Service">S3</acronym>)" is the selected type of <acronym title="Content Delivery Network">CDN</acronym> on the General Settings tab (if not change the setting and save the changes). Now on the <acronym title="Content Delivery Network">CDN</acronym> Settings tab enter your "Access key," "Secret key" and create a bucket. Click the "Test <acronym title="Simple Storage Service">S3</acronym> Upload" button and make sure that the test is successful, if not check your settings and try again. </p>
327
+ <p>Save your settings. Make sure that you export your media library, upload your wp-includes (WordPress core files) theme files, and custom files if you wish to host each of those with <acronym title="Amazon Web Services">AWS</acronym>. Unless you wish to use CloudFront, you're almost done, skip to the next paragraph if you're using CloudFront. Just go to the General Settings tab and click the checkbox and save the settings to enable <acronym title="Content Delivery Network">CDN</acronym> functionality and empty the cache for the changes to take effect.</p>
328
+ <p>To use CloudFront, perform all of the steps above, except select the "Amazon CloudFront" <acronym title="Content Delivery Network">CDN</acronym> type in the <acronym title="Content Delivery Network">CDN</acronym> section of the General Settings tab. Proceed to the <a href="https://console.aws.amazon.com/cloudfront/" target="_blank"><acronym title="Amazon Web Services">AWS</acronym> Management Console</a> and create a new distribution: select the <acronym title="Simple Storage Service">S3</acronym> Bucket you created earlier as the "Origin," enter a <a href="http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/index.html?CNAMEs.html" target="_blank">CNAME</a> if you wish to add one to your <acronym title="Domain Name System">DNS</acronym> Zone. Make sure that "Distribution Status" is enabled and "State" is deployed. Now on <acronym title="Content Delivery Network">CDN</acronym> Settings tab of the plugin, copy the subdomain found in the <acronym title="Amazon Web Services">AWS</acronym> Management Console and enter the CNAME used for the distribution in the "CNAME" field.</p>
329
+ <p>Now go to the General Settings tab and click the checkbox and save the settings to enable <acronym title="Content Delivery Network">CDN</acronym> functionality and empty the cache for the changes to take effect.</p>
330
+ <p align="right"><a href="#toc">back to top</a></p>
331
+ <p id="q94"><strong>How do I use an Origin Pull (Mirror) <acronym title="Content Delivery Network">CDN</acronym>?</strong><br />
332
+ Login to your <acronym title="Content Delivery Network">CDN</acronym> providers control panel or account management area. Following any set up steps they provide, create a new "pull zone" or "bucket" for your site's domain name. If there's a set up wizard or any troubleshooting tips your provider offers, be sure to review them. In the <acronym title="Content Delivery Network">CDN</acronym> Settings tab of the plugin, enter the hostname your <acronym title="Content Delivery Network">CDN</acronym> provider provided in the "replace default hostname with" field. You should always do a quick check by opening a test file from the <acronym title="Content Delivery Network">CDN</acronym> hostname, e.g. http://cdn.domain.com/favicon.ico. Troubleshoot with yoru <acronym title="Content Delivery Network">CDN</acronym> provider until this test is successful.</p>
333
+ <p>Now go to the General Settings tab and click the checkbox and save the settings to enable <acronym title="Content Delivery Network">CDN</acronym> functionality and empty the cache for the changes to take effect.</p>
334
+ <p align="right"><a href="#toc">back to top</a></p>
335
  <p id="q45"><strong>In the past, I always had to modify my theme to run dynamic code. Don't I need to do that again for this plugin?</strong><br />
336
+ For now no; there are some special cases that we will address with an upcoming release for highly dynamic sites.</p>
337
  <p align="right"><a href="#toc">back to top</a></p>
338
  <p id="q46"><strong>How fast will the cache be updated?</strong><br />
339
  Items expire from the cache at a rate that you specify. As far as how fast changes appear to your visitors, they appear instantly in most cases and if you're an administrator who's logged in they will always be immediately visible.</p>
345
  On the contrary, as with any other action a user can perform on a site, faster performance will encourage more of it. The cache is so quickly rebuilt in memory that it's no trouble to show visitors the most current version of a post that's experiencing Digg, Slashdot, Drudge Report, Yahoo Buzz or Twitter effect.</p>
346
  <p align="right"><a href="#toc">back to top</a></p>
347
  <p id="q49"><strong>What if I accidentally specify an incorrect path to a <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> file?</strong><br />
348
+ Unfortunately a 400 bad request error may be generated. So use the "Check <acronym title="Uniform Resource Indicator">URI</acronym>" button to make sure that you have entered the correct <acronym title="Uniform Resource Indicator">URL</acronym> or path to the file.</p>
349
  <p align="right"><a href="#toc">back to top</a></p>
350
  <p id="q50"><strong>Does the plugin automatically remove duplicate <acronym title="JavaScript">JS</acronym>?</strong><br />
351
  No. If you include a script in the minfy settings twice or it already exists in your theme we do not automatically remove the extra code. That's tricky business and it's better for us to just let you make the decisions conscientiously.</p>
368
  <p align="right"><a href="#toc">back to top</a></p>
369
  <p id="q56"><strong>I'm not a hardcore developer, can you explain to me how this // and / stuff works and how I should specify the paths for <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym> files?</strong><br />
370
  You mean on the minify settings page right? Ok, it's simple:<br />
371
+ // tells the plugin to search for the file with the provided path from the document root, e.g.: ///JS/jquery/jquery.<acronym title="JavaScript">JS</acronym><br />
372
+ / tells the plugin to search for the file with the provided path from the server root, e.g. //JS/jquery/jquery.<acronym title="JavaScript">JS</acronym></p>
373
  <p>In most cases providing an absolute path is sufficient and most reliable. You can of course use relative paths, but we discourage it unless you really know what you are doing.</p>
374
  <p align="right"><a href="#toc">back to top</a></p>
375
  <p id="q57"><strong>What about Etags?</strong><br />
382
  Right now we do not show the statistics in <acronym title="WordPress">WP</acronym> Admin, but soon we will provide graphs of: Page Cache Memory Use, Page Cache Hits/Misses, <acronym title="Database">DB</acronym> Cache Memory Use, <acronym title="Database">DB</acronym> Hits/Misses, Average Page Compression Savings, Average <acronym title="Cascading Style Sheet">CSS</acronym> Compression Savings, Average <acronym title="JavaScript">JS</acronym> Compression Savings, Average Requests per Second, and Average Page Execution Time.</p>
383
  <p align="right"><a href="#toc">back to top</a></p>
384
  <p id="q60"><strong>How can I tell if it's working? Aren't there any statistics at all?</strong><br />
385
+ Well yes actually there are, simply enable debug mode on the general settings tab to have details appended to the bottom of your <acronym title="Hypertext Markup Language">HTML</acronym> source. Remember that when enabled all visitors to your blog can see these statistics if they view source. Using debug mode does slow the performance of your site so use sparingly.</p>
 
386
  <p id="q61"><strong>I'm an advanced theme developer and I want to have different combinations of <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> files on different types of pages in my theme; how is this done?</strong><br />
387
+ On the minify settings tab, use the drop-down selection menu to define the <acronym title="Cascading Style Sheet">CSS</acronym> or <acronym title="JavaScript">JS</acronym> files that appear on all pages using the "Default" group first. Then specify unie files for the other pages.</p>
388
  <p align="right"><a href="#toc">back to top</a></p>
389
  <p id="q62"><strong>Which features can I use if I haven't yet installed <acronym title="Alternative PHP Cache">APC</acronym> or memcached?</strong><br />
390
+ Memory caching will not be possible. However you will be able to use both the page cache and minify in "disk" mode, as well <acronym title="Content Delivery Network">CDN</acronym> functionality without issue.</p>
391
  <p align="right"><a href="#toc">back to top</a></p>
392
  <p id="q63"><strong>How can I host my favicon with my <acronym title="Content Delivery Network">CDN</acronym>?</strong><br />
393
  If the file exists in your document root (i.e. http://domain.com/favicon.ico), the plugin can take care of that for you using custom upload options. If the file is in your theme directory you can also have the plugin uploaded from there.</p>
425
  Currently you cannot, replacement is not yet supported.</p>
426
  <p align="right"><a href="#toc">back to top</a></p>
427
  <p id="q72"><strong>What about the wp-includes files, can those be served from the <acronym title="Content Delivery Network">CDN</acronym>?</strong><br />
428
+ Yes, you can specify which file types you would like served by <acronym title="Content Delivery Network">CDN</acronym> and they will be uploaded and always downloaded from that location. This includes the smilies, JavaScript files et al. By default we take care of them all.</p>
429
  <p align="right"><a href="#toc">back to top</a></p>
430
  <p id="q73"><strong>What if I don't want to work with a <acronym title="Content Delivery Network">CDN</acronym> right now, is there any other use for this feature?</strong><br />
431
  Yes! You can take advantage of the <a href="http://www.mozilla.org/projects/netlib/http/pipelining-faq.html">pipelining</a> support in some browsers by creating a sub-domain for the static content for your site. So you could create static.domain.com on your server (and update your <acronym title="Domain Name System">DNS</acronym> zone) and then specify the <acronym title="File Transfer Protocol">FTP</acronym> details for it in the plugin configuration panel and you're done. If you disable the scripting options on your server you'll find that your server will actually respond slightly faster from that sub-domain because it's just sending files and not processing them.</p>
436
  <p id="q75"><strong>Who do you recommend as a <acronym title="Content Delivery Network">CDN</acronym> provider?</strong><br />
437
  That depends on how you use your blog and where most of your readers read your blog (regionally). Here's a short list:</p>
438
  <ul>
439
+ <li><a href="http://www.maxcdn.com/" target="_blank">MaxCDN</a></li>
440
+ <li><a href="http://www.cotendo.com/" target="_blank">Cotendo</a></li>
441
+ <li><a href="https://vps.net/cdn-signup" target="_blank">VPS NET</a></li>
442
  <li><a href="http://aws.amazon.com/s3/" target="_blank">Amazon S3</a> / <a href="http://aws.amazon.com/cloudfront/" target="_blank">Cloudfront</a></li>
443
+ <li><a href="http://www.netdna.com/" target="_blank">NetDNA</a></li>
444
  <li><a href="http://www.edgecast.com/" target="_blank">EdgeCast</a></li>
 
 
445
  <li><a href="http://www.akamai.com/" target="_blank">Akamai</a></li>
446
+ <li><a href="http://www.limelightnetworks.com/" target="_blank">Limelight Networks</a></li>
447
+ <li><a href="http://www.simplecdn.com/" target="_blank">Simple<acronym title="Content Delivery Network">CDN</acronym></a></li>
448
+ <li><a href="http://www.voxel.net/products-services/voxcast-cdn" target="_blank">Voxel</a></li>
449
  </ul>
450
  <p align="right"><a href="#toc">back to top</a></p>
451
  <p id="q76"><strong>Hang on, don't I need to modify my <acronym title="Cascading Style Sheet">CSS</acronym> files so they'll work on the <acronym title="Content Delivery Network">CDN</acronym>?</strong><br />
457
  <p id="q92"><strong>What about query string variables on <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym>, do they matter?</strong><br />
458
  This is definitely a special case. Files like "http://domain.com/wp-content/themes/default/js/script.js?ver=20090102" etc need to be specified with the full <acronym title="Uniform Resource Locator">URL</acronym>. This is an exception to the general rule of specifying a local path to file like: "wp-content/themes/default/js/script.js", which should also work fine. Be sure to click the "Verify <acronym title="Uniform Resource Indicator">URL</acronym>" button to be sure that everything is ok before saving changes.</p>
459
  <p align="right"><a href="#toc">back to top</a></p>
460
+ <p id="q95"><strong>Is this plugin comptatible with GD Star Rating?</strong><br />
461
+ Yes. Follow these steps:</p>
462
+ <ol>
463
+ <li>Enable dynamic loading of ratings by checking GD Star Rating -> Settings -> Features "Cache support option"</li>
464
+ <li>If Database cache enabled in W3 Total Cache add "wp_gdsr" to "Ignored query stems" option on the Database Cache settings tab, otherwise ratings will not updated after voting</li>
465
+ <li>Empty all caches</li>
466
+ </ol>
467
+ <p align="right"><a href="#toc">back to top</a></p>
468
+ <p id="q96"><strong>How do I cache only the home page?</strong><br />
469
+ Add "/.+" (without the quotes) to page cache "Never cache the following pages" option on the page cache settings tab.</p>
470
+ <p align="right"><a href="#toc">back to top</a></p>
471
+ <p id="q97"><strong>I see garbage characters instead of the normal web site, what's going on here?</strong><br />
472
+ If a theme or it's files use the call php_flush() or function flush() that will interfere with the plugins normal operation; making the plugin send cached files before essential operations have finished. The flush() call is no longer necessary and should be removed.</p>
473
+ <p align="right"><a href="#toc">back to top</a></p>
474
+ <p id="q98"><strong>What is the purpose of the "Media Library Import" tool and how do I use it?</strong><br />
475
+ The media library import tool is for old or "messy" WordPress installations that have attachments (images etc in posts or pages) scattered about the web server or "hot linked" to 3rd party sites instead of properly using the media library.</p>
476
+ <p>The tool will scan your posts and pages for the cases above and copy them to your media library, update your posts to use the link addresses and produce a .htaccess file containing the list of of permanent redirects, so search engines can find the files in their new location.</p>
477
+ <p>You should backup your database before performing this operation.</p>
478
+ <p align="right"><a href="#toc">back to top</a></p>
479
+ <p id="q99"><strong>I'm getting blank pages or 500 error codes when trying to upgrade on WordPress MU</strong><br />
480
+ First, make sure the plugin is not active (disabled) site-wide. Then make sure it's deactivated site-wide. Now you should be able to successful upgrade without breaking your site.</p>
481
+ <p align="right"><a href="#toc">back to top</a></p>
482
  <p id="q78"><strong>Which web servers do you support?</strong><br />
483
  We are aware of no incompatibilities with <a href="http://httpd.apache.org/" target="_blank">apache</a> 1.3+, <a href="http://www.iis.net/" target="_blank">IIS</a> 5+ or <a href="http://litespeedtech.com/products/webserver/overview/" target="_blank">litespeed</a> 4.0.2+. If there's a web server you feel we should be actively testing (e.g. <a href="http://www.lighttpd.net/" target="_blank">lighttpd</a>), we're <a href="mailto:wordpressexperts@w3-edge.com">interested in hearing</a>.</p>
484
  <p align="right"><a href="#toc">back to top</a></p>
487
  <p>If you're larger organization or a web hosting company, consider looking into solutions that exist like <a href="http://www.gear6.com/">Gear6</a> which could be useful now that you have a plugin that makes management memcached pain free.</p>
488
  <p align="right"><a href="#toc">back to top</a></p>
489
  <p id="q80"><strong>Is this plugin compatible with varnish or squid?</strong><br />
490
+ Yes, it is compatible with <a href="http://varnish.projects.linpro.no/" target="_blank">varnish</a>.</p>
491
  <p align="right"><a href="#toc">back to top</a></p>
492
  <p id="q81"><strong>My server is state of the art with 15,000 RPM RAID, why do I need to cache anything in memory?</strong><br />
493
  Even if your server was using an array of solid state disks (SSD), your server's <acronym title="Random Access Memory">RAM</acronym> is still going to be faster and introduce less overhead to access than even the fastest solid state drives on a PCIe bus. If you didn't invest in solid state disks for your server, then even worse off - at least an order of magnitude speed difference in read operations in <acronym title="Random Access Memory">RAM</acronym> versus HDD. For write operations delta the latency differences is even more pronounced. <acronym title="Random Access Memory">RAM</acronym> is the winner hands down. We won't even discuss the blocking and arbitration issues that happen with disk arrays under certain circumstances.</p>
494
  <p align="right"><a href="#toc">back to top</a></p>
495
  <p id="q82"><strong>Why would I choose <acronym title="Alternative PHP Cache">APC</acronym> over memcached or vice versa?</strong><br />
496
  There's no straight answer for this one. Since WordPress is a PHP-based application, we encourage everyone to install <acronym title="Alternative PHP Cache">APC</acronym> and subsequently realize a minimum of 10x performance gain. It will obviously make our plugin faster as well, so again please check out the installation instructions if you do not already use <acronym title="Alternative PHP Cache">APC</acronym>. Once installed, you can select <acronym title="Alternative PHP Cache">APC</acronym> as your caching engine in our plugin and get back to blogging.</p>
497
+ <p><acronym title="Alternative PHP Cache">APC</acronym> does have a couple weaknesses:</p>
498
+ <ul>
499
+ <li>If you frequently restart your web server (e.g. apache) especially during high traffic periods, you will lose your cache and your site will slow down as it rebuilds the cache (which happens very quickly). However if you use memcached you would not lose your cache if your web server is restarted.</li>
500
+ <li>More importantly, <acronym title="Alternative PHP Cache">APC</acronym> is best suited for single server environments; an <acronym title="Alternative PHP Cache">APC</acronym> cache is only accessible on the local server, it cannot be shared with other servers in a multi-server (cluster) environment.</li>
501
+ </ul>
502
+ <p>It would appear that using <acronym title="Alternative PHP Cache">APC</acronym> for all cases is best, but your mileage may vary. So depending on what software you install and how you manage your server, you can choose the options to fit your needs. If you need help with the install on your dedicated or virtual dedicated linux-based server ask us!</p>
503
  <p align="right"><a href="#toc">back to top</a></p>
504
  <p id="q83"><strong>I already use <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression on my server, why does it matter if I minify my code?</strong><br />
505
  Let's say you had a file of 10240 bytes, which becomes 2048 bytes when compressed, savings of ~80% (typical for <acronym title="Cascading Style Sheet">CSS</acronym> files). That same file will now have an <strong>additional</strong> ~3x-10x transfer speed improvement when minified. That's a big return from a small operation. The larger your files, the more significant the proportional performance gains.</p>
516
  <p>For those that don't want or have time to learn anything new to get started, sample configuration files are included with the plugin containing inline comments for you.</p>
517
  <p align="right"><a href="#toc">back to top</a></p>
518
  <p id="q85"><strong>What version of <acronym title="Hypertext Preprocessor">PHP</acronym> do I need for this thing?</strong><br />
519
+ Version 4.3 is supported for some modules, however version 5 preferred (it's much much faster especially with <acronym title="Alternative PHP Cache">APC</acronym>). It is likely version 3.0 of WordPress will no longer support <acronym title="Hypertext Preprocessor">PHP</acronym> 4.3.</p>
520
  <p align="right"><a href="#toc">back to top</a></p>
521
  <p id="q86"><strong>What version of mySQL is needed?</strong><br />
522
  If your WordPress installation is works, you're all set.</p>
531
  Yes, built from the ground up with scale and current hosting paradigms in mind.</p>
532
  <p align="right"><a href="#toc">back to top</a></p>
533
  <p id="q90"><strong>I'm a web hosting provider and I heard about this plugin from my clients, is this plugin safe for a shared hosting environment?<br />
534
+ </strong>Yes.</p>
535
  <p align="right"><a href="#toc">back to top</a></p>
536
  <p id="q91"><strong>What is the intended impact of this plugin on the web hosting landscape?</strong><br />
537
  We feel that shared or virtual hosting providers will begin offering secure containers (similar to what <a href="http://mediatemple.net/" target="_blank">mediatemple.net</a> does for mySQL and Ruby etc) for <acronym title="Alternative PHP Cache">APC</acronym> and memcached. Whoever brings this offering to market first will lower the bar for more web sites/applications (and startups) to build better performing applications with greater ease. The same hosting provider would also possess a new value added service, thereby realizing a competitive advantage in a highly competitive marketplace. Not to mention be able to increase the density of domains per server (or cluster) without shortchanging customers.</p>
538
  <p>One day hopefully this plugin will contribute to making web servers greener and reduce the ecological footprint of the web by reducing the computational effort required to deliver high performance rich user experiences.</p>
539
  <p align="right"><a href="#toc">back to top</a></p>
540
  </div>
541
+
542
+ <?php include W3TC_DIR . '/inc/options/common/footer.phtml'; ?>
inc/options/general.phtml CHANGED
@@ -1,73 +1,66 @@
1
- <?php
2
 
3
- $support_type = $config->get_string('common.support.type');
4
-
5
- $memcache_engine = class_exists('Memcache') ? '(Memcache)' : '';
6
-
7
- $support_types = array('footer' => 'Page footer');
8
- $link_categories = get_terms('link_category', array('hide_empty' => 0));
9
-
10
- foreach ($link_categories as $link_category) {
11
- $support_types['link_category_' . $link_category->term_id] = $link_category->name;
12
- }
13
-
14
- ?>
15
  <h3>General Settings</h3>
16
 
17
- <p>The plugin is currently <span class="w3tc-<?php if ($enabled): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>. Changing any of the following settings will clear all caches. If an option is disabled it means that either your current installation is not compatible or installation is required.</p>
18
 
19
  <p><label><input id="enabled" type="checkbox" name="enabled" value="1"<?php checked($enabled, true); ?> /> Deselect this option to disable all caching functionality.</label></p>
20
 
21
  <form action="options-general.php">
22
  <p>You can
23
  <input type="hidden" name="page" value="<?php echo W3TC_FILE; ?>" />
24
- <input type="hidden" name="tab" value="<?php echo $tab; ?>" />
25
  <input class="button" type="submit" name="flush_all" value="empty all caches" /> at once or
26
  <input class="button" type="submit" name="flush_memcached" value="empty only the memcached cache"<?php if (! $can_empty_memcache): ?> disabled="disabled"<?php endif; ?> /> or
27
- <input class="button" type="submit" name="flush_apc" value="empty only the APC cache"<?php if (! $can_empty_apc): ?> disabled="disabled"<?php endif; ?> /> or
28
  <input class="button" type="submit" name="flush_file" value="empty only the disk cache"<?php if (! $can_empty_file): ?> disabled="disabled"<?php endif; ?> />.
29
  </p>
30
  </form>
31
 
32
  <p>Enable page caching to decrease the response time of your blog.</p>
33
 
34
- <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $tab; ?>" method="post">
35
  <table class="form-table">
36
  <tr>
37
  <th valign="top">Page Caching:</th>
38
  <td>
39
  <input type="hidden" name="pgcache.enabled" value="0" />
40
  <label><input class="enabled" type="checkbox" name="pgcache.enabled" value="1"<?php checked($pgcache_enabled, true); ?> />&nbsp;<strong>Enable</strong></label><br />
41
- <span class="description">Caching pages will reduce the response time of and increase the concurrency potential (scale) of your web server.</span>
42
  </td>
43
  </tr>
44
  <tr>
45
  <th valign="top">Page Caching Method:</th>
46
  <td>
47
- <label><input type="radio" name="pgcache.engine" value="file"<?php checked($config->get_string('pgcache.engine'), 'file'); ?> /> Disk</label><br />
48
- <label><input type="radio" name="pgcache.engine" value="memcached"<?php checked($config->get_string('pgcache.engine'), 'memcached'); ?> /> Memcached <?php echo $memcache_engine; ?></label><br />
49
- <label><input type="radio" name="pgcache.engine" value="apc"<?php checked($config->get_string('pgcache.engine'), 'apc'); ?><?php if (! $check_apc): ?> disabled="disabled"<?php endif; ?> /> <acronym title="Alternative PHP Cache">APC</acronym></label><br />
 
 
 
50
  </td>
51
  </tr>
52
  </table>
53
 
54
- <p>Enable minify to concatenate, remove white space / comments and compress (<acronym title="GNU zip">gzip</acronym> / deflate) your (theme's / plugin's / external) <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> files.</p>
55
 
56
  <table class="form-table">
57
  <tr>
58
  <th valign="top">Minify:</th>
59
  <td>
60
  <input type="hidden" name="minify.enabled" value="0" />
61
- <label><input class="enabled" type="checkbox" name="minify.enabled" value="1"<?php checked($minify_enabled, true); ?> />&nbsp;<strong>Enable</strong></label><br />
62
- <span class="description">Minification can decrease file size of <acronym title="Hypertext Markup Language">HTML</acronym>, <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> respectively by ~10% on average.</span>
63
  </td>
64
  </tr>
65
  <tr>
66
  <th valign="top">Minify Caching Method:</th>
67
  <td>
68
- <label><input type="radio" name="minify.engine" value="file"<?php checked($config->get_string('minify.engine'), 'file'); ?> /> Disk</label><br />
69
- <label><input type="radio" name="minify.engine" value="memcached"<?php checked($config->get_string('minify.engine'), 'memcached'); ?> /> Memcached <?php echo $memcache_engine; ?></label><br />
70
- <label><input type="radio" name="minify.engine" value="apc"<?php checked($config->get_string('minify.engine'), 'apc'); ?><?php if (! $check_apc): ?> disabled="disabled"<?php endif; ?> /> <acronym title="Alternative PHP Cache">APC</acronym></label><br />
 
 
71
  </td>
72
  </tr>
73
  </table>
@@ -86,13 +79,16 @@ foreach ($link_categories as $link_category) {
86
  <tr>
87
  <th valign="top">Database Caching Method:</th>
88
  <td>
89
- <label><input type="radio" name="dbcache.engine" value="memcached"<?php checked($config->get_string('dbcache.engine'), 'memcached'); ?> /> Memcached <?php echo $memcache_engine; ?></label><br />
90
- <label><input type="radio" name="dbcache.engine" value="apc"<?php checked($config->get_string('dbcache.engine'), 'apc'); ?><?php if (! $check_apc): ?> disabled="disabled"<?php endif; ?> /> <acronym title="Alternative PHP Cache">APC</acronym></label><br />
 
 
 
91
  </td>
92
  </tr>
93
  </table>
94
 
95
- <p>Host your wp-includes/ (images and scripts only), media library, theme images / <acronym title="Cascading Style Sheets">CSS</acronym> / <acronym title="JavaScript">JS</acronym> with your <acronym title="Content Delivery Network">CDN</acronym> provider.</p>
96
 
97
  <table class="form-table">
98
  <tr>
@@ -105,14 +101,18 @@ foreach ($link_categories as $link_category) {
105
  <tr>
106
  <th><acronym title="Content Delivery Network">CDN</acronym> Type:</th>
107
  <td>
108
- <label><input type="radio" name="cdn.engine" value="ftp"<?php checked($config->get_string('cdn.engine'), 'ftp'); ?> /> <acronym title="File Transfer Protocol">FTP</acronym></label><br />
109
- <label><input type="radio" name="cdn.engine" value="mirror"<?php checked($config->get_string('cdn.engine'), 'mirror'); ?> /> Mirror (Origin Pull)</label><br />
110
- <span class="description">Select the <acronym title="Content Delivery Network">CDN</acronym> type you wish to use.</span>
 
 
 
 
111
  </td>
112
  </tr>
113
  </table>
114
 
115
- <p>View detailed data on the operations being performed using debug mode. Performance in this mode will not be optimal nor private, use sparingly.</p>
116
 
117
  <table class="form-table">
118
  <tr>
@@ -123,21 +123,35 @@ foreach ($link_categories as $link_category) {
123
  </td>
124
  </tr>
125
  </table>
126
-
127
  <h3>Support Us</h3>
128
 
129
- <p>If this plugin has saved you money, made your server more stable and/or improved user experience for the readers of your blog, support us with a link!</p>
130
- <p><input type="hidden" name="common.support.enabled" value="0" /><label><input type="checkbox" name="common.support.enabled"<?php checked($config->get_boolean('common.support.enabled'), true); ?> /> Yes, I'd love to support you guys, please add the link to my site's</label>
131
- <select name="common.support.type">
132
- <?php foreach ($support_types as $support_type_id => $support_type_name): ?>
133
- <option value="<?php echo $support_type_id; ?>"<?php selected($support_type, $support_type_id); ?>><?php echo htmlspecialchars($support_type_name); ?></option>
134
- <?php endforeach; ?>
135
- </select>.
 
 
 
 
136
  </p>
 
137
  <p>If you want to place the link manually here is the code:</p>
138
  <p><textarea cols="100" rows="3">Performance Optimization &lt;a href=&quot;http://www.w3-edge.com/wordpress-plugins/&quot; rel=&quot;external&quot;&gt;WordPress Plugins&lt;/a&gt; by W3 EDGE</textarea></p>
 
 
 
 
 
 
 
139
 
140
  <p class="submit">
141
  <input type="submit" name="Submit" class="button-primary" value="Save changes" />
142
  </p>
143
  </form>
 
 
1
+ <?php include W3TC_DIR . '/inc/options/common/header.phtml'; ?>
2
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  <h3>General Settings</h3>
4
 
5
+ <p>The plugin is currently <span class="w3tc-<?php if ($enabled): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>. If an option is disabled it means that either your current installation is not compatible or installation is required.</p>
6
 
7
  <p><label><input id="enabled" type="checkbox" name="enabled" value="1"<?php checked($enabled, true); ?> /> Deselect this option to disable all caching functionality.</label></p>
8
 
9
  <form action="options-general.php">
10
  <p>You can
11
  <input type="hidden" name="page" value="<?php echo W3TC_FILE; ?>" />
12
+ <input type="hidden" name="tab" value="<?php echo $this->_tab; ?>" />
13
  <input class="button" type="submit" name="flush_all" value="empty all caches" /> at once or
14
  <input class="button" type="submit" name="flush_memcached" value="empty only the memcached cache"<?php if (! $can_empty_memcache): ?> disabled="disabled"<?php endif; ?> /> or
15
+ <input class="button" type="submit" name="flush_apc" value="empty only the opcode cache"<?php if (! $can_empty_apc): ?> disabled="disabled"<?php endif; ?> /> or
16
  <input class="button" type="submit" name="flush_file" value="empty only the disk cache"<?php if (! $can_empty_file): ?> disabled="disabled"<?php endif; ?> />.
17
  </p>
18
  </form>
19
 
20
  <p>Enable page caching to decrease the response time of your blog.</p>
21
 
22
+ <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $this->_tab; ?>" method="post">
23
  <table class="form-table">
24
  <tr>
25
  <th valign="top">Page Caching:</th>
26
  <td>
27
  <input type="hidden" name="pgcache.enabled" value="0" />
28
  <label><input class="enabled" type="checkbox" name="pgcache.enabled" value="1"<?php checked($pgcache_enabled, true); ?> />&nbsp;<strong>Enable</strong></label><br />
29
+ <span class="description">Caching pages will reduce the response time of your site and increase the concurrency (scale) of your web server.</span>
30
  </td>
31
  </tr>
32
  <tr>
33
  <th valign="top">Page Caching Method:</th>
34
  <td>
35
+ <select name="pgcache.engine">
36
+ <option value="file_pgcache"<?php selected($this->_config->get_string('pgcache.engine'), 'file_pgcache'); ?>>Disk (enhanced)</option>
37
+ <option value="file"<?php selected($this->_config->get_string('pgcache.engine'), 'file'); ?>>Disk (basic)</option>
38
+ <option value="memcached"<?php selected($this->_config->get_string('pgcache.engine'), 'memcached'); ?>>Memcached<?php echo $memcache_engine; ?></option>
39
+ <option value="apc"<?php selected($this->_config->get_string('pgcache.engine'), 'apc'); ?><?php if (! $check_apc): ?> disabled="disabled"<?php endif; ?>>Alternative PHP Cache (APC)</option>
40
+ </select>
41
  </td>
42
  </tr>
43
  </table>
44
 
45
+ <p>Enable minify to combine, remove white space / comments and compress (<acronym title="GNU zip">gzip</acronym> / deflate) your (theme's / plugin's / external) <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> files.</p>
46
 
47
  <table class="form-table">
48
  <tr>
49
  <th valign="top">Minify:</th>
50
  <td>
51
  <input type="hidden" name="minify.enabled" value="0" />
52
+ <label><input class="enabled" type="checkbox" name="minify.enabled" value="1"<?php checked($minify_enabled, true); ?><?php if (! W3TC_PHP5): ?> disabled="disabled"<?php endif; ?> />&nbsp;<strong>Enable</strong></label><br />
53
+ <span class="description">Minification can decrease file size of <acronym title="Hypertext Markup Language">HTML</acronym>, <acronym title="Cascading Style Sheets">CSS</acronym>, <acronym title="JavaScript">JS</acronym> and feeds respectively by ~10% on average.</span>
54
  </td>
55
  </tr>
56
  <tr>
57
  <th valign="top">Minify Caching Method:</th>
58
  <td>
59
+ <select name="minify.engine"<?php if (! W3TC_PHP5): ?> disabled="disabled"<?php endif; ?>>
60
+ <option value="file"<?php selected($this->_config->get_string('minify.engine'), 'file'); ?>>Disk</option>
61
+ <option value="memcached"<?php selected($this->_config->get_string('minify.engine'), 'memcached'); ?>>Memcached<?php echo $memcache_engine; ?></option>
62
+ <option value="apc"<?php selected($this->_config->get_string('minify.engine'), 'apc'); ?><?php if (! $check_apc): ?> disabled="disabled"<?php endif; ?>>Alternative PHP Cache (APC)</option>
63
+ </select>
64
  </td>
65
  </tr>
66
  </table>
79
  <tr>
80
  <th valign="top">Database Caching Method:</th>
81
  <td>
82
+ <select name="dbcache.engine">
83
+ <option value="file"<?php selected($this->_config->get_string('dbcache.engine'), 'file'); ?>>Disk</option>
84
+ <option value="memcached"<?php selected($this->_config->get_string('dbcache.engine'), 'memcached'); ?>>Memcached<?php echo $memcache_engine; ?></option>
85
+ <option value="apc"<?php selected($this->_config->get_string('dbcache.engine'), 'apc'); ?><?php if (! $check_apc): ?> disabled="disabled"<?php endif; ?>>Alternative PHP Cache (APC)</option>
86
+ </select>
87
  </td>
88
  </tr>
89
  </table>
90
 
91
+ <p>Host your wp-includes/ (WordPress' core files), media library, theme images / <acronym title="Cascading Style Sheets">CSS</acronym> / <acronym title="JavaScript">JS</acronym> with your <acronym title="Content Delivery Network">CDN</acronym> provider.</p>
92
 
93
  <table class="form-table">
94
  <tr>
101
  <tr>
102
  <th><acronym title="Content Delivery Network">CDN</acronym> Type:</th>
103
  <td>
104
+ <select name="cdn.engine">
105
+ <option value="mirror"<?php selected($this->_config->get_string('cdn.engine'), 'mirror'); ?>>Origin Pull (Mirror)</option>
106
+ <option value="cf"<?php selected($this->_config->get_string('cdn.engine'), 'cf'); ?><?php if (! W3TC_PHP5 || ! $check_curl): ?> disabled="disabled"<?php endif; ?>>Amazon CloudFront</option>
107
+ <option value="s3"<?php selected($this->_config->get_string('cdn.engine'), 's3'); ?><?php if (! W3TC_PHP5 || ! $check_curl): ?> disabled="disabled"<?php endif; ?>>Amazon Simple Storage Service (Amazon S3)</option>
108
+ <option value="ftp"<?php selected($this->_config->get_string('cdn.engine'), 'ftp'); ?>>Self-hosted (File Transfer Protocol)</option>
109
+ </select><br />
110
+ <span class="description">Select the <acronym title="Content Delivery Network">CDN</acronym> type you wish to use.</span>
111
  </td>
112
  </tr>
113
  </table>
114
 
115
+ <p>Use debug mode to view detailed data about the enabled caching types. Performance in this mode will not be optimal nor private, use sparingly.</p>
116
 
117
  <table class="form-table">
118
  <tr>
123
  </td>
124
  </tr>
125
  </table>
126
+
127
  <h3>Support Us</h3>
128
 
129
+ <p>We're working to make WordPress better. Please support us!</p>
130
+
131
+ <p>
132
+ <label>Link to us:
133
+ <select name="common.support">
134
+ <option value="">select one</option>
135
+ <?php foreach ($supports as $support_id => $support_name): ?>
136
+ <option value="<?php echo $support_id; ?>"<?php selected($support, $support_id); ?>><?php echo htmlspecialchars($support_name); ?></option>
137
+ <?php endforeach; ?>
138
+ </select>
139
+ </label> (easy) or tell your friends with a <a href="#" class="link-tweet">tweet</a> (easiest).
140
  </p>
141
+
142
  <p>If you want to place the link manually here is the code:</p>
143
  <p><textarea cols="100" rows="3">Performance Optimization &lt;a href=&quot;http://www.w3-edge.com/wordpress-plugins/&quot; rel=&quot;external&quot;&gt;WordPress Plugins&lt;/a&gt; by W3 EDGE</textarea></p>
144
+
145
+ <h3>Miscellaneous Settings</h3>
146
+
147
+ <p>
148
+ <input type="hidden" name="common.widget.latest" value="0" />
149
+ <label><input type="checkbox" name="common.widget.latest" value="1"<?php checked($this->_config->get_boolean('common.widget.latest'), true); ?> /> Enable dashboard widget</label><br />
150
+ </p>
151
 
152
  <p class="submit">
153
  <input type="submit" name="Submit" class="button-primary" value="Save changes" />
154
  </p>
155
  </form>
156
+
157
+ <?php include W3TC_DIR . '/inc/options/common/footer.phtml'; ?>
inc/options/install.phtml CHANGED
@@ -1,16 +1,18 @@
 
 
1
  <div id="install">
2
  <h3>Installation</h3>
3
 
4
  <ol>
5
  <li>Disable and remove any other caching plugin you may be using &mdash; most plugins have uninstall procedures you can follow. Make sure wp-content/ has 777 permissions before proceeding, e.g.: # chmod 777 /var/www/vhosts/domain.com/httpdocs/wp-content/</li>
6
  <li>Ensure that wp-config.php contains the statement below; if you previously used a caching plugin, this statement is likely to exist already: define('WP_CACHE', true);</li>
7
- <li>Locate and activate the plugin on the <a href="/wp-admin/plugins.php">Plugins</a> page, then click the Settings link to proceed to the <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=general">General Settings</a> tab. Set the permisions of wp-content back to 755, e.g.: `# chmod 755 /var/www/vhosts/domain.com/httpdocs/wp-content/.</li>
8
  <li>Select your caching preferences for page, database and minify. If memcached is used this will require you to confirm or modify the default settings and add any additional memcached servers you wish to use. To utilize <a href="#APC"><acronym title="Alternative PHP Cache">APC</acronym></a> and <a href="#memcached">memcached</a> + <a href="#memcache">memcache</a> installation guides have been provided under the Installation tab. For those in shared hosting environments, contact your provider to see if either of these are supported.</li>
9
- <li>If you already have a content delivery network provider, proceed to the <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=cdn"><acronym title="Content Delivery Network">CDN</acronym> Settings</a> tab and populate the fields and set your preferences. If you're not running a version of WordPress with the Media Library feature, use the Media Library Import Tool to migrate your post images etc to appropriate locations. If you do not have a <acronym title="Content Delivery Network">CDN</acronym> provider, you can still improve your site's performance using this feature. Create and use a subdomain on your own server; e.g. static.domain.com and configure options on the <acronym title="Content Delivery Network">CDN</acronym> tab accordingly.</li>
10
- <li>On the <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=minify">Minify Settings</a> tab all of the recommended settings are preset. Specify any <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym> files in the respective sections, view your site's <acronym title="Hypertext Markup Language">HTML</acronym> source and search for .<acronym title="Cascading Style Sheet">css</acronym> and .<acronym title="JavaScript">js</acronym> files. In the case of <acronym title="JavaScript">JS</acronym> files you can specify the type and location of the embedding using the drop down menu.</li>
11
  <li>You're done! Get back to blogging!</li>
12
  </ol>
13
- Check out the <acronym title="Frequently Asked Questions">FAQ</acronym> for more details on <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=faq">usage</a>.
14
  <hr />
15
  <p><strong>Server Preparation:</strong><br />
16
  <em>Time required: ~1 minute</em></p>
@@ -49,18 +51,19 @@
49
  # ldconfig -v</li>
50
  <li>Now find the <a href="http://www.danga.com/memcached/download.bml" target="_blank">latest stable memcached</a>, download and extract:<br />
51
  # cd /usr/local/src<br />
52
- # wget <a href="http://memcached.googlecode.com/files/memcached-1.4.0.tar.gz" target="_blank">http://memcached.googlecode.com/files/memcached-1.4.0.tar.gz</a><br />
53
- # gunzip -c memcached-1.4.0.tar.gz | tar xf -<br />
54
- # cd memcached-1.4.0</li>
55
  <li>Let's compile:<br />
56
  # ./configure &amp;&amp; make &amp;&amp; make install</li>
57
  <li>Make sure memcached is starts automatically on server boot:<br />
58
- # touch /etc/rc.d/init.d/memcached<br />
59
- # echo '#!/bin/sh -e' >> /etc/rc.d/init.d/memcached<br />
60
- # echo '/usr/local/bin/memcached -d -m 128 -p 11211 -u nobody -l localhost' >> /etc/rc.d/init.d/memcached<br />
61
- # chmod u+x /etc/rc.d/init.d/memcached</li>
 
62
  <li>And finally, let's start memcached:<br />
63
- # /etc/rc.d/init.d/memcached</li>
64
  </ol>
65
  <p>For windows users we recommend checking the following sites for more installation tips:</p>
66
  <ul>
@@ -92,14 +95,11 @@
92
  # php -r 'phpinfo();' | grep 'memcache'</li>
93
  </ol>
94
  <hr />
95
- <p id="APC"><strong><acronym title="Alternative PHP Cache">APC</acronym> Installation via Yum or <acronym title="PHP Extension Community Library">PECL</acronym>: </strong><br />
96
  <em>Time required: 1 minute</em></p>
97
  <ol>
98
  <li>Install <acronym title="Alternative PHP Cache">APC</acronym> using the <acronym title="PHP Extension Community Library">PECL</acronym> command:<br />
99
- # pecl install apc<br />
100
- <br />
101
- or using yum:<br />
102
- # yum install php-pecl-apc</li>
103
  <li>Make sure the module is loaded:<br />
104
  # echo "extension=apc.so" &gt; /etc/php.d/apc.ini<br />
105
  <br />
@@ -142,9 +142,11 @@
142
  <p><strong>Note(s):</strong></p>
143
  <ul>
144
  <li>The provided instructions are for CentOS, however we can provide others based on <a href="mailto:wordpressexperts@w3-edge.com">your requests</a>.</li>
145
- <li>In the case where the "Rewrite <acronym>URL</acronym> Structure" (in <a href="/wp-admin/options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=minify">Minify Settings</a> tab) is desired, and apache is not used, the file located in wp-content/plugins/w3-total-cache/wp-content/w3tc/.htaccess contains directives that must be created for the directory: wp-content/w3tc/.</li>
146
  <li>Restarting the web server will empty your <acronym title="Alternative PHP Cache">APC</acronym> cache, which means it will have to be rebuilt over time and your site's performance will suffer during this period. Still, <acronym title="Alternative PHP Cache">APC</acronym> should be installed in any case to maximize WordPress performance.</li>
147
  <li>Consider using memcached for objects that must persist across web server restarts or that you wish to share amongst your pool of servers (or cluster), e.g.: database objects or page cache.</li>
148
  <li>Some yum or mirrors may not have the necessary packages, in such cases you may have to do a manual installation.</li>
149
  </ul>
150
- </div>
 
 
1
+ <?php include W3TC_DIR . '/inc/options/common/header.phtml'; ?>
2
+
3
  <div id="install">
4
  <h3>Installation</h3>
5
 
6
  <ol>
7
  <li>Disable and remove any other caching plugin you may be using &mdash; most plugins have uninstall procedures you can follow. Make sure wp-content/ has 777 permissions before proceeding, e.g.: # chmod 777 /var/www/vhosts/domain.com/httpdocs/wp-content/</li>
8
  <li>Ensure that wp-config.php contains the statement below; if you previously used a caching plugin, this statement is likely to exist already: define('WP_CACHE', true);</li>
9
+ <li>Locate and activate the plugin on the Plugins page, then click the Settings link to proceed to the <a href="options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=general">General Settings</a> tab. Set the permisions of wp-content back to 755, e.g.: `# chmod 755 /var/www/vhosts/domain.com/httpdocs/wp-content/.</li>
10
  <li>Select your caching preferences for page, database and minify. If memcached is used this will require you to confirm or modify the default settings and add any additional memcached servers you wish to use. To utilize <a href="#APC"><acronym title="Alternative PHP Cache">APC</acronym></a> and <a href="#memcached">memcached</a> + <a href="#memcache">memcache</a> installation guides have been provided under the Installation tab. For those in shared hosting environments, contact your provider to see if either of these are supported.</li>
11
+ <li>If you already have a content delivery network provider, proceed to the <a href="options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=cdn"><acronym title="Content Delivery Network">CDN</acronym> Settings</a> tab and populate the fields and set your preferences. If you're not running a version of WordPress with the Media Library feature, use the Media Library Import Tool to migrate your post images etc to appropriate locations. If you do not have a <acronym title="Content Delivery Network">CDN</acronym> provider, you can still improve your site's performance using this feature. Create and use a subdomain on your own server; e.g. static.domain.com and configure options on the <acronym title="Content Delivery Network">CDN</acronym> tab accordingly.</li>
12
+ <li>On the <a href="options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=minify">Minify Settings</a> tab all of the recommended settings are preset. Specify any <acronym title="Cascading Style Sheet">CSS</acronym> and <acronym title="JavaScript">JS</acronym> files in the respective sections, view your site's <acronym title="Hypertext Markup Language">HTML</acronym> source and search for .<acronym title="Cascading Style Sheet">css</acronym> and .<acronym title="JavaScript">js</acronym> files. In the case of <acronym title="JavaScript">JS</acronym> files you can specify the type and location of the embedding using the drop down menu.</li>
13
  <li>You're done! Get back to blogging!</li>
14
  </ol>
15
+ Check out the <acronym title="Frequently Asked Questions">FAQ</acronym> for more details on <a href="options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=faq">usage</a>.
16
  <hr />
17
  <p><strong>Server Preparation:</strong><br />
18
  <em>Time required: ~1 minute</em></p>
51
  # ldconfig -v</li>
52
  <li>Now find the <a href="http://www.danga.com/memcached/download.bml" target="_blank">latest stable memcached</a>, download and extract:<br />
53
  # cd /usr/local/src<br />
54
+ # wget <a href="http://memcached.googlecode.com/files/memcached-1.4.3.tar.gz" target="_blank">http://memcached.googlecode.com/files/memcached-1.4.3.tar.gz</a><br />
55
+ # gunzip -c memcached-1.4.3.tar.gz | tar xf -<br />
56
+ # cd memcached-1.4.3</li>
57
  <li>Let's compile:<br />
58
  # ./configure &amp;&amp; make &amp;&amp; make install</li>
59
  <li>Make sure memcached is starts automatically on server boot:<br />
60
+ # touch /etc/init.d/memcached<br />
61
+ # echo '#!/bin/sh -e' >> /etc/init.d/memcached<br />
62
+ # echo '/usr/local/bin/memcached -d -m 128 -p 11211 -u nobody -l localhost' >> /etc/init.d/memcached<br />
63
+ # chmod u+x /etc/init.d/memcached<br />
64
+ # echo '/etc/init.d/memcached' >> /etc/rc.local</li>
65
  <li>And finally, let's start memcached:<br />
66
+ # /etc/init.d/memcached</li>
67
  </ol>
68
  <p>For windows users we recommend checking the following sites for more installation tips:</p>
69
  <ul>
95
  # php -r 'phpinfo();' | grep 'memcache'</li>
96
  </ol>
97
  <hr />
98
+ <p id="APC"><strong><acronym title="Alternative PHP Cache">APC</acronym> Installation via <acronym title="PHP Extension Community Library">PECL</acronym>: </strong><br />
99
  <em>Time required: 1 minute</em></p>
100
  <ol>
101
  <li>Install <acronym title="Alternative PHP Cache">APC</acronym> using the <acronym title="PHP Extension Community Library">PECL</acronym> command:<br />
102
+ # pecl install apc</li>
 
 
 
103
  <li>Make sure the module is loaded:<br />
104
  # echo "extension=apc.so" &gt; /etc/php.d/apc.ini<br />
105
  <br />
142
  <p><strong>Note(s):</strong></p>
143
  <ul>
144
  <li>The provided instructions are for CentOS, however we can provide others based on <a href="mailto:wordpressexperts@w3-edge.com">your requests</a>.</li>
145
+ <li>In the case where the "Rewrite <acronym>URL</acronym> Structure" (in <a href="options-general.php?page=w3-total-cache/w3-total-cache.php&amp;tab=minify">Minify Settings</a> tab) is desired, and apache is not used, the file located in wp-content/plugins/w3-total-cache/wp-content/w3tc/.htaccess contains directives that must be created for the directory: wp-content/w3tc/.</li>
146
  <li>Restarting the web server will empty your <acronym title="Alternative PHP Cache">APC</acronym> cache, which means it will have to be rebuilt over time and your site's performance will suffer during this period. Still, <acronym title="Alternative PHP Cache">APC</acronym> should be installed in any case to maximize WordPress performance.</li>
147
  <li>Consider using memcached for objects that must persist across web server restarts or that you wish to share amongst your pool of servers (or cluster), e.g.: database objects or page cache.</li>
148
  <li>Some yum or mirrors may not have the necessary packages, in such cases you may have to do a manual installation.</li>
149
  </ul>
150
+ </div>
151
+
152
+ <?php include W3TC_DIR . '/inc/options/common/footer.phtml'; ?>
inc/options/minify.phtml CHANGED
@@ -1,24 +1,5 @@
1
- <?php
2
 
3
- $groups = array(
4
- '404' => '404',
5
- 'archive' => 'Archive',
6
- 'attachment' => 'Attachment',
7
- 'author' => 'Author',
8
- 'category' => 'Category',
9
- 'date' => 'Date',
10
- 'default' => 'Default',
11
- 'home' => 'Home',
12
- 'page' => 'Page',
13
- 'search' => 'Search',
14
- 'single' => 'Single',
15
- 'tag' => 'Tag',
16
- );
17
-
18
- $js_groups = $config->get_array('minify.js.groups');
19
- $css_groups = $config->get_array('minify.css.groups');
20
-
21
- ?>
22
  <h3>Minify Settings</h3>
23
 
24
  <form action="options-general.php">
@@ -26,96 +7,118 @@ $css_groups = $config->get_array('minify.css.groups');
26
  Minify is currently <span class="w3tc-<?php if ($minify_enabled): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>.
27
  <input type="submit" name="flush_minify" value="Empty cache"<?php if (! $minify_enabled): ?> disabled="disabled"<?php endif; ?> class="button" />
28
  <input type="hidden" name="page" value="<?php echo W3TC_FILE; ?>" />
29
- <input type="hidden" name="tab" value="<?php echo $tab; ?>" />
30
  </p>
31
  </form>
32
 
33
- <form id="minify_form" action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $tab; ?>" method="post">
34
  <table class="form-table">
 
35
  <tr>
36
- <th style="width: 250px;"><label for="memcached_servers">Memcached Hostname:Port / IP:Port:</label></th>
37
  <td>
38
- <input id="memcached_servers" type="text" name="minify.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $config->get_array('minify.memcached.servers'))); ?>" size="100"<?php if (! $minify_memcached): ?> disabled="disabled"<?php endif; ?> />
39
- <input id="test_memcached" class="button" type="button" value="Test"<?php if (! $minify_memcached): ?> disabled="disabled"<?php endif; ?> />
40
  <span id="test_memcached_status" class="w3tc-status w3tc-process"></span>
41
  <br /><span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
42
  </td>
43
  </tr>
 
44
  <tr>
45
  <th colspan="2">
46
  <input type="hidden" name="minify.compress" value="0" />
47
- <label><input type="checkbox" name="minify.compress" value="1"<?php checked($config->get_boolean('minify.compress'), true); ?> /> <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression (<acronym title="GNU zip">gzip</acronym> / deflate)</label><br />
48
- <span class="description">Reduce file size by utomatically detecting the user agent's supported compression method of any.</span>
49
  </th>
50
  </tr>
51
  <tr>
52
  <th colspan="2">
53
  <input type="hidden" name="minify.compress.ie6" value="0" />
54
- <label><input type="checkbox" name="minify.compress.ie6" value="1"<?php checked($config->get_boolean('minify.compress.ie6'), true); ?> /> <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression for <acronym title="Microsoft Internet Explorer">MSIE</acronym>6</label><br />
55
  <span class="description">Workaround for <acronym title="Microsoft Internet Explorer">MSIE</acronym>6 <acronym title="Service Pack">SP</acronym>2 compression bug.</span>
56
  </th>
57
  </tr>
58
  <tr>
59
  <th colspan="2">
60
  <input type="hidden" name="minify.rewrite" value="0" />
61
- <label><input type="checkbox" name="minify.rewrite" value="1"<?php checked($config->get_boolean('minify.rewrite'), true); ?> /> Rewrite <acronym title="Uniform Resource Locator">URL</acronym> Structure</label><br />
62
- <span class="description">If disabled, <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> embeddings will use of GET variables, enabling this option is recommended unless you really want to avoid the redirects.</span>
63
  </th>
64
  </tr>
65
  <tr>
66
  <th colspan="2">
67
  <input type="hidden" name="minify.upload" value="0" />
68
- <label><input type="checkbox" name="minify.upload" value="1"<?php checked($config->get_boolean('minify.upload'), true); ?> /> Automatically upload modified files</label>
 
69
  </th>
70
  </tr>
 
 
 
 
 
 
71
  <tr>
72
  <th><label for="minify_lifetime">Update external files every:</label></th>
73
- <td><input id="minify_lifetime" type="text" name="minify.lifetime" value="<?php echo $config->get_integer('minify.lifetime'); ?>" size="8" /> seconds<br />
74
  <span class="description">Specify the interval between download and update of external files in the minify cache. Hint: 6 hours is 21600 seconds. 12 hours is 43200 seconds. 24 hours is 86400 seconds.</span></td>
75
  </tr>
76
  <tr>
77
- <th valign="top"><acronym title="Hypertext Markup Language">HTML</acronym> Settings:</th>
 
 
 
 
 
 
78
  <td>
79
  <input type="hidden" name="minify.html.enable" value="0" />
80
  <input type="hidden" name="minify.html.reject.admin" value="0" />
81
  <input type="hidden" name="minify.html.inline.css" value="0" />
82
  <input type="hidden" name="minify.html.inline.js" value="0" />
83
  <input type="hidden" name="minify.html.strip.crlf" value="0" />
84
- <label><input id="html_enabled" type="checkbox" name="minify.html.enable" value="1"<?php checked($config->get_boolean('minify.html.enable'), true); ?> /> Minify</label><br />
85
- <label><input class="html_enabled" type="checkbox" name="minify.html.reject.admin" value="1"<?php checked($config->get_boolean('minify.html.reject.admin'), true); ?> /> Don't Minify <acronym title="Hypertext Markup Language">HTML</acronym> for logged in administrators</label><br />
86
- <label><input class="html_enabled" type="checkbox" name="minify.html.inline.css" value="1"<?php checked($config->get_boolean('minify.html.inline.css'), true); ?> /> Inline CSS Minification</label><br />
87
- <label><input class="html_enabled" type="checkbox" name="minify.html.inline.js" value="1"<?php checked($config->get_boolean('minify.html.inline.js'), true); ?> /> Inline JS Minification</label><br />
88
- <label><input class="html_enabled" type="checkbox" name="minify.html.strip.crlf" value="1"<?php checked($config->get_boolean('minify.html.strip.crlf'), true); ?> /> Line break removal</label><br />
89
  </td>
90
  </tr>
91
  <tr>
92
- <th valign="top"><acronym title="JavaScript">JS</acronym> Minify Settings:</th>
93
  <td>
94
  <input type="hidden" name="minify.js.enable" value="0" />
95
  <input type="hidden" name="minify.js.combine.header" value="0" />
96
  <input type="hidden" name="minify.js.combine.footer" value="0" />
97
  <input type="hidden" name="minify.js.strip.comments" value="0" />
98
  <input type="hidden" name="minify.js.strip.crlf" value="0" />
99
- <label><input id="js_enabled" type="checkbox" name="minify.js.enable" value="1"<?php checked($config->get_boolean('minify.js.enable'), true); ?> /> Minify</label><br />
100
- <label><input class="js_enabled" type="checkbox" name="minify.js.combine.header" value="1"<?php checked($config->get_boolean('minify.js.combine.header'), true); ?> /> Only combine (Head)</label><br />
101
- <label><input class="js_enabled" type="checkbox" name="minify.js.combine.footer" value="1"<?php checked($config->get_boolean('minify.js.combine.footer'), true); ?> /> Only combine (Footer)</label><br />
102
- <label><input class="js_enabled" type="checkbox" name="minify.js.strip.comments" value="1"<?php checked($config->get_boolean('minify.js.strip.comments'), true); ?> /> Comment removal</label><br />
103
- <label><input class="js_enabled" type="checkbox" name="minify.js.strip.crlf" value="1"<?php checked($config->get_boolean('minify.js.strip.crlf'), true); ?> /> Line break removal</label><br />
104
  </td>
105
  </tr>
106
  <tr>
107
- <th valign="top"><acronym title="Cascading Style Sheets">CSS</acronym> Minify Settings:</th>
108
  <td>
109
  <input type="hidden" name="minify.css.enable" value="0" />
110
  <input type="hidden" name="minify.css.strip.comments" value="0" />
111
  <input type="hidden" name="minify.css.strip.crlf" value="0" />
112
- <label><input id="css_enabled" type="checkbox" name="minify.css.enable" value="1"<?php checked($config->get_boolean('minify.css.enable'), true); ?> /> Minify</label><br />
113
- <label><input class="css_enabled" type="checkbox" name="minify.css.strip.comments" value="1"<?php checked($config->get_boolean('minify.css.strip.comments'), true); ?> /> Comment removal</label><br />
114
- <label><input class="css_enabled" type="checkbox" name="minify.css.strip.crlf" value="1"<?php checked($config->get_boolean('minify.css.strip.crlf'), true); ?> /> Line break removal</label><br />
115
  </td>
116
  </tr>
117
  <tr>
118
- <th valign="top"><acronym title="JavaScript">JS</acronym> File Management:</th>
 
 
 
 
 
 
 
119
  <td>
120
  <p>
121
  <label>
@@ -143,7 +146,7 @@ $css_groups = $config->get_array('minify.css.groups');
143
  </td>
144
  </tr>
145
  <tr>
146
- <th valign="top"><acronym title="Cascading Style Sheets">CSS</acronym> File Management:</th>
147
  <td>
148
  <p>
149
  <label>
@@ -176,3 +179,5 @@ $css_groups = $config->get_array('minify.css.groups');
176
  <input type="submit" name="Submit" class="button-primary" value="Save changes" />
177
  </p>
178
  </form>
 
 
1
+ <?php include W3TC_DIR . '/inc/options/common/header.phtml'; ?>
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  <h3>Minify Settings</h3>
4
 
5
  <form action="options-general.php">
7
  Minify is currently <span class="w3tc-<?php if ($minify_enabled): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>.
8
  <input type="submit" name="flush_minify" value="Empty cache"<?php if (! $minify_enabled): ?> disabled="disabled"<?php endif; ?> class="button" />
9
  <input type="hidden" name="page" value="<?php echo W3TC_FILE; ?>" />
10
+ <input type="hidden" name="tab" value="<?php echo $this->_tab; ?>" />
11
  </p>
12
  </form>
13
 
14
+ <form id="minify_form" action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $this->_tab; ?>" method="post">
15
  <table class="form-table">
16
+ <?php if ($this->_config->get_string('minify.engine') == 'memcached'): ?>
17
  <tr>
18
+ <th><label for="memcached_servers">Memcached hostname:port / <acronym title="Internet Protocol">IP</acronym>:port:</label></th>
19
  <td>
20
+ <input id="memcached_servers" type="text" name="minify.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $this->_config->get_array('minify.memcached.servers'))); ?>" size="100" />
21
+ <input id="test_memcached" class="button" type="button" value="Test" />
22
  <span id="test_memcached_status" class="w3tc-status w3tc-process"></span>
23
  <br /><span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
24
  </td>
25
  </tr>
26
+ <?php endif; ?>
27
  <tr>
28
  <th colspan="2">
29
  <input type="hidden" name="minify.compress" value="0" />
30
+ <label><input type="checkbox" name="minify.compress" value="1"<?php checked($this->_config->get_boolean('minify.compress'), true); ?> /> <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression (<acronym title="GNU zip">gzip</acronym>)</label><br />
31
+ <span class="description">Use <acronym>HTTP</acronym> compression to automatically reduce the load time of <acronym>CSS</acronym> and <acronym>JS</acronym> files in browsers that support it.</span>
32
  </th>
33
  </tr>
34
  <tr>
35
  <th colspan="2">
36
  <input type="hidden" name="minify.compress.ie6" value="0" />
37
+ <label><input type="checkbox" name="minify.compress.ie6" value="1"<?php checked($this->_config->get_boolean('minify.compress.ie6'), true); ?> /> <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression for <acronym title="Microsoft Internet Explorer">MSIE</acronym>6</label><br />
38
  <span class="description">Workaround for <acronym title="Microsoft Internet Explorer">MSIE</acronym>6 <acronym title="Service Pack">SP</acronym>2 compression bug.</span>
39
  </th>
40
  </tr>
41
  <tr>
42
  <th colspan="2">
43
  <input type="hidden" name="minify.rewrite" value="0" />
44
+ <label><input type="checkbox" name="minify.rewrite" value="1"<?php checked($this->_config->get_boolean('minify.rewrite'), true); ?> /> Rewrite <acronym title="Uniform Resource Locator">URL</acronym> structure</label><br />
45
+ <span class="description">If disabled, <acronym title="Cascading Style Sheets">CSS</acronym> and <acronym title="JavaScript">JS</acronym> embeddings will use GET variables instead of "fancy links."</span>
46
  </th>
47
  </tr>
48
  <tr>
49
  <th colspan="2">
50
  <input type="hidden" name="minify.upload" value="0" />
51
+ <label><input type="checkbox" name="minify.upload" value="1"<?php checked($this->_config->get_boolean('minify.upload'), true); ?> /> Automatically upload modified files</label><br />
52
+ <span class="description">If CDN is enabled (and not using the origin pull method), your minified files will be automatically uploaded.</span>
53
  </th>
54
  </tr>
55
+ <tr>
56
+ <th style="width: 250px;"><label for="minify_maxage">Maximum lifetime of cache objects:</label></th>
57
+ <td><input id="minify_maxage" type="text" name="minify.maxage" value="<?php echo $this->_config->get_integer('minify.maxage'); ?>" size="8" /> seconds
58
+ <br /><span class="description">Determines the natural expiration time of unchanged cache items. The higher the value, the larger the cache.</span>
59
+ </td>
60
+ </tr>
61
  <tr>
62
  <th><label for="minify_lifetime">Update external files every:</label></th>
63
+ <td><input id="minify_lifetime" type="text" name="minify.lifetime" value="<?php echo $this->_config->get_integer('minify.lifetime'); ?>" size="8" /> seconds<br />
64
  <span class="description">Specify the interval between download and update of external files in the minify cache. Hint: 6 hours is 21600 seconds. 12 hours is 43200 seconds. 24 hours is 86400 seconds.</span></td>
65
  </tr>
66
  <tr>
67
+ <th><label for="minify_file_gc">Garbage collection interval:</label></th>
68
+ <td><input id="minify_file_gc" type="text" name="minify.file.gc" value="<?php echo $this->_config->get_integer('minify.file.gc'); ?>" size="8"<?php if ($this->_config->get_string('minify.engine') != 'file' && $this->_config->get_string('minify.engine') != 'file'): ?> disabled="disabled"<?php endif; ?> /> seconds
69
+ <br /><span class="description">If caching to disk, specify how frequently expired cache data is removed. For busy sites, a lower value is best.</span>
70
+ </td>
71
+ </tr>
72
+ <tr>
73
+ <th valign="top"><acronym title="Hypertext Markup Language">HTML</acronym> settings:</th>
74
  <td>
75
  <input type="hidden" name="minify.html.enable" value="0" />
76
  <input type="hidden" name="minify.html.reject.admin" value="0" />
77
  <input type="hidden" name="minify.html.inline.css" value="0" />
78
  <input type="hidden" name="minify.html.inline.js" value="0" />
79
  <input type="hidden" name="minify.html.strip.crlf" value="0" />
80
+ <label><input id="html_enabled" type="checkbox" name="minify.html.enable" value="1"<?php checked($this->_config->get_boolean('minify.html.enable'), true); ?> /> Minify</label><br />
81
+ <label><input class="html_enabled" type="checkbox" name="minify.html.reject.admin" value="1"<?php checked($this->_config->get_boolean('minify.html.reject.admin'), true); ?> /> Don't Minify <acronym title="Hypertext Markup Language">HTML</acronym> for logged in administrators</label><br />
82
+ <label><input class="html_enabled" type="checkbox" name="minify.html.inline.css" value="1"<?php checked($this->_config->get_boolean('minify.html.inline.css'), true); ?> /> Inline <acronym title="Cascading Style Sheets">CSS</acronym> Minification</label><br />
83
+ <label><input class="html_enabled" type="checkbox" name="minify.html.inline.js" value="1"<?php checked($this->_config->get_boolean('minify.html.inline.js'), true); ?> /> Inline <acronym title="JavaScript">JS</acronym> Minification</label><br />
84
+ <label><input class="html_enabled" type="checkbox" name="minify.html.strip.crlf" value="1"<?php checked($this->_config->get_boolean('minify.html.strip.crlf'), true); ?> /> Line break removal</label><br />
85
  </td>
86
  </tr>
87
  <tr>
88
+ <th valign="top"><acronym title="JavaScript">JS</acronym> minify settings:</th>
89
  <td>
90
  <input type="hidden" name="minify.js.enable" value="0" />
91
  <input type="hidden" name="minify.js.combine.header" value="0" />
92
  <input type="hidden" name="minify.js.combine.footer" value="0" />
93
  <input type="hidden" name="minify.js.strip.comments" value="0" />
94
  <input type="hidden" name="minify.js.strip.crlf" value="0" />
95
+ <label><input id="js_enabled" type="checkbox" name="minify.js.enable" value="1"<?php checked($this->_config->get_boolean('minify.js.enable'), true); ?> /> Minify</label><br />
96
+ <label><input class="js_enabled" type="checkbox" name="minify.js.combine.header" value="1"<?php checked($this->_config->get_boolean('minify.js.combine.header'), true); ?> /> Only combine (Head)</label><br />
97
+ <label><input class="js_enabled" type="checkbox" name="minify.js.combine.footer" value="1"<?php checked($this->_config->get_boolean('minify.js.combine.footer'), true); ?> /> Only combine (Footer)</label><br />
98
+ <label><input class="js_enabled" type="checkbox" name="minify.js.strip.comments" value="1"<?php checked($this->_config->get_boolean('minify.js.strip.comments'), true); ?> /> Comment removal</label><br />
99
+ <label><input class="js_enabled" type="checkbox" name="minify.js.strip.crlf" value="1"<?php checked($this->_config->get_boolean('minify.js.strip.crlf'), true); ?> /> Line break removal</label><br />
100
  </td>
101
  </tr>
102
  <tr>
103
+ <th valign="top"><acronym title="Cascading Style Sheets">CSS</acronym> minify settings:</th>
104
  <td>
105
  <input type="hidden" name="minify.css.enable" value="0" />
106
  <input type="hidden" name="minify.css.strip.comments" value="0" />
107
  <input type="hidden" name="minify.css.strip.crlf" value="0" />
108
+ <label><input id="css_enabled" type="checkbox" name="minify.css.enable" value="1"<?php checked($this->_config->get_boolean('minify.css.enable'), true); ?> /> Minify</label><br />
109
+ <label><input class="css_enabled" type="checkbox" name="minify.css.strip.comments" value="1"<?php checked($this->_config->get_boolean('minify.css.strip.comments'), true); ?> /> Comment removal</label><br />
110
+ <label><input class="css_enabled" type="checkbox" name="minify.css.strip.crlf" value="1"<?php checked($this->_config->get_boolean('minify.css.strip.crlf'), true); ?> /> Line break removal</label><br />
111
  </td>
112
  </tr>
113
  <tr>
114
+ <th valign="top"><label for="minify_reject_ua">Rejected user agents:</label></th>
115
+ <td>
116
+ <textarea id="minify_reject_ua" name="minify.reject.ua" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $this->_config->get_array('minify.reject.ua'))); ?></textarea><br />
117
+ <span class="description">Specify user agents that will never receive minified content.</span>
118
+ </td>
119
+ </tr>
120
+ <tr>
121
+ <th valign="top"><acronym title="JavaScript">JS</acronym> file management:</th>
122
  <td>
123
  <p>
124
  <label>
146
  </td>
147
  </tr>
148
  <tr>
149
+ <th valign="top"><acronym title="Cascading Style Sheets">CSS</acronym> file management:</th>
150
  <td>
151
  <p>
152
  <label>
179
  <input type="submit" name="Submit" class="button-primary" value="Save changes" />
180
  </p>
181
  </form>
182
+
183
+ <?php include W3TC_DIR . '/inc/options/common/footer.phtml'; ?>
inc/options/pgcache.phtml CHANGED
@@ -1,79 +1,129 @@
1
- <h3>Page Cache Settings</h3>
2
 
 
3
 
4
  <form action="options-general.php">
5
  <p>
6
  Page Caching is currently <span class="w3tc-<?php if ($pgcache_enabled): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>.
7
  <input type="submit" name="flush_pgcache" value="Empty cache"<?php if (! $pgcache_enabled): ?> disabled="disabled"<?php endif; ?> class="button" />
8
  <input type="hidden" name="page" value="<?php echo W3TC_FILE; ?>" />
9
- <input type="hidden" name="tab" value="<?php echo $tab; ?>" />
10
  </p>
11
  </form>
12
 
13
- <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $tab; ?>" method="post">
14
  <table class="form-table">
 
15
  <tr>
16
- <th style="width: 250px;"><label for="memcached_servers">Memcached Hostname:Port / IP:Port:</label></th>
17
  <td>
18
- <input id="memcached_servers" type="text" name="pgcache.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $config->get_array('pgcache.memcached.servers'))); ?>" size="100"<?php if (! $pgcache_memcached): ?> disabled="disabled"<?php endif; ?> />
19
- <input id="test_memcached" class="button" type="button" value="Test"<?php if (! $pgcache_memcached): ?> disabled="disabled"<?php endif; ?> />
20
  <span id="test_memcached_status" class="w3tc-status w3tc-process"></span>
21
  <br /><span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
22
  </td>
23
  </tr>
 
24
  <tr>
25
- <th><label for="pgcache_lifetime">Maximum lifetime of cache objects:</label></th>
26
- <td><input id="pgcache_lifetime" type="text" name="pgcache.lifetime" value="<?php echo $config->get_integer('pgcache.lifetime'); ?>" size="8" /> seconds</td>
 
 
27
  </tr>
28
  <tr>
29
- <th colspan="2">
30
- <input type="hidden" name="pgcache.reject.logged" value="0" />
31
- <label><input type="checkbox" name="pgcache.reject.logged" value="1"<?php checked($config->get_boolean('pgcache.reject.logged'), true); ?> /> Don't cache pages for logged in users</label>
32
- </th>
 
 
 
 
 
 
 
 
 
 
 
 
33
  </tr>
34
  <tr>
35
  <th colspan="2">
36
- <input type="hidden" name="pgcache.compress" value="0" />
37
- <label><input type="checkbox" name="pgcache.compress" value="1"<?php checked($config->get_boolean('pgcache.compress'), true); ?> /> <acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression (<acronym title="GNU zip">gzip</acronym> / deflate)</label>
 
38
  </th>
39
  </tr>
40
  <tr>
41
  <th colspan="2">
42
  <input type="hidden" name="pgcache.cache.home" value="0" />
43
- <label><input type="checkbox" name="pgcache.cache.home" value="1"<?php checked($config->get_boolean('pgcache.cache.home'), true); ?> /> Cache the home page</label>
 
44
  </th>
45
  </tr>
46
  <tr>
47
  <th colspan="2">
48
  <input type="hidden" name="pgcache.cache.feed" value="0" />
49
- <label><input type="checkbox" name="pgcache.cache.feed" value="1"<?php checked($config->get_boolean('pgcache.cache.feed'), true); ?> /> Cache <acronym title="Really Simple Syndication">RSS</acronym> feeds (site, post, post comments)</label>
 
50
  </th>
51
  </tr>
52
  <tr>
53
  <th colspan="2">
54
  <input type="hidden" name="pgcache.cache.query" value="0" />
55
- <label><input type="checkbox" name="pgcache.cache.query" value="1"<?php checked($config->get_boolean('pgcache.cache.query'), true); ?> /> Cache <acronym title="Uniform Resource Identifier">URI</acronym>s with query string variables</label>
 
56
  </th>
57
  </tr>
58
  <tr>
59
  <th valign="top"><label for="pgcache_reject_ua">Rejected User Agents:</label></th>
60
- <td><textarea id="pgcache_reject_ua" name="pgcache.reject.ua" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $config->get_array('pgcache.reject.ua'))); ?></textarea></td>
 
 
 
61
  </tr>
62
  <tr>
63
  <th valign="top"><label for="pgcache_reject_cookie">Rejected Cookies:</label></th>
64
- <td><textarea id="pgcache_reject_cookie" name="pgcache.reject.cookie" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $config->get_array('pgcache.reject.cookie'))); ?></textarea></td>
 
 
 
65
  </tr>
66
  <tr>
67
  <th valign="top"><label for="pgcache_reject_uri">Never cache the following pages:</label></th>
68
- <td><textarea id="pgcache_reject_uri" name="pgcache.reject.uri" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $config->get_array('pgcache.reject.uri'))); ?></textarea></td>
 
 
 
69
  </tr>
70
  <tr>
71
  <th valign="top"><label for="pgcache_accept_files">Caching exception list:</label></th>
72
- <td><textarea id="pgcache_accept_files" name="pgcache.accept.files" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $config->get_array('pgcache.accept.files'))); ?></textarea></td>
 
 
 
73
  </tr>
74
  <tr>
75
  <th valign="top"><label for="pgcache_cache_headers">Specify page headers:</label></th>
76
- <td><textarea id="pgcache_cache_headers" name="pgcache.cache.headers" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $config->get_array('pgcache.cache.headers'))); ?></textarea></td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  </tr>
78
  </table>
79
 
@@ -81,3 +131,5 @@
81
  <input type="submit" name="Submit" class="button-primary" value="Save changes" />
82
  </p>
83
  </form>
 
 
1
+ <?php include W3TC_DIR . '/inc/options/common/header.phtml'; ?>
2
 
3
+ <h3>Page Cache Settings</h3>
4
 
5
  <form action="options-general.php">
6
  <p>
7
  Page Caching is currently <span class="w3tc-<?php if ($pgcache_enabled): ?>enabled">enabled<?php else: ?>disabled">disabled<?php endif; ?></span>.
8
  <input type="submit" name="flush_pgcache" value="Empty cache"<?php if (! $pgcache_enabled): ?> disabled="disabled"<?php endif; ?> class="button" />
9
  <input type="hidden" name="page" value="<?php echo W3TC_FILE; ?>" />
10
+ <input type="hidden" name="tab" value="<?php echo $this->_tab; ?>" />
11
  </p>
12
  </form>
13
 
14
+ <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $this->_tab; ?>" method="post">
15
  <table class="form-table">
16
+ <?php if ($this->_config->get_string('pgcache.engine') == 'memcached'): ?>
17
  <tr>
18
+ <th><label for="memcached_servers">Memcached hostname:port / <acronym title="Internet Protocol">IP</acronym>:port:</label></th>
19
  <td>
20
+ <input id="memcached_servers" type="text" name="pgcache.memcached.servers" value="<?php echo htmlspecialchars(implode(',', $this->_config->get_array('pgcache.memcached.servers'))); ?>" size="100" />
21
+ <input id="test_memcached" class="button" type="button" value="Test" />
22
  <span id="test_memcached_status" class="w3tc-status w3tc-process"></span>
23
  <br /><span class="description">Multiple servers may be used and seperated by a comma; e.g. 192.168.1.100:11211, domain.com:22122</span>
24
  </td>
25
  </tr>
26
+ <?php endif; ?>
27
  <tr>
28
+ <th style="width: 250px;"><label for="pgcache_lifetime">Maximum lifetime of cache objects:</label></th>
29
+ <td><input id="pgcache_lifetime" type="text" name="pgcache.lifetime" value="<?php echo $this->_config->get_integer('pgcache.lifetime'); ?>" size="8" /> seconds
30
+ <br /><span class="description">Determines the natural expiration time of unchanged cache items. The higher the value, the larger the cache.</span>
31
+ </td>
32
  </tr>
33
  <tr>
34
+ <th><label for="pgcache_file_gc">Garbage collection interval:</label></th>
35
+ <td><input id="pgcache_file_gc" type="text" name="pgcache.file.gc" value="<?php echo $this->_config->get_integer('pgcache.file.gc'); ?>" size="8"<?php if ($this->_config->get_string('pgcache.engine') != 'file' && $this->_config->get_string('pgcache.engine') != 'file_pgcache'): ?> disabled="disabled"<?php endif; ?> /> seconds
36
+ <br /><span class="description">If caching to disk, specify how frequently expired cache data is removed. For busy sites, a lower value is best.</span>
37
+ </td>
38
+ </tr>
39
+ <tr>
40
+ <th><label for="pgcache_compression"><acronym title="Hypertext Transfer Protocol">HTTP</acronym> compression:</label></th>
41
+ <td>
42
+ <select name="pgcache.compression">
43
+ <option value="">None (not recommended)</option>
44
+ <option value="gzip"<?php selected($this->_config->get_string('pgcache.compression'), 'gzip'); ?><?php if (! $pgcache_gzip): ?> disabled="disabled"<?php endif; ?>>gzip (good)</option>
45
+ <option value="deflate"<?php selected($this->_config->get_string('pgcache.compression'), 'deflate'); ?><?php if (! $pgcache_deflate): ?> disabled="disabled"<?php endif; ?>>deflate (not recommended)</option>
46
+ <option value="gzip,deflate"<?php selected($this->_config->get_string('pgcache.compression'), 'gzip,deflate'); ?><?php if (! $pgcache_gzip || ! $pgcache_deflate): ?> disabled="disabled"<?php endif; ?>>gzip and deflate (best)</option>
47
+ </select><br />
48
+ <span class="description">Use <acronym>HTTP</acronym> compression to automatically reduce the load time of HTML documents in browsers that support it.</span>
49
+ </td>
50
  </tr>
51
  <tr>
52
  <th colspan="2">
53
+ <input type="hidden" name="pgcache.reject.logged" value="0" />
54
+ <label><input type="checkbox" name="pgcache.reject.logged" value="1"<?php checked($this->_config->get_boolean('pgcache.reject.logged'), true); ?> /> Don't cache pages for logged in users</label><br />
55
+ <span class="description">Users that have signed in to WordPress (e.g. administrators) will never view cached pages if enabled.</span>
56
  </th>
57
  </tr>
58
  <tr>
59
  <th colspan="2">
60
  <input type="hidden" name="pgcache.cache.home" value="0" />
61
+ <label><input type="checkbox" name="pgcache.cache.home" value="1"<?php checked($this->_config->get_boolean('pgcache.cache.home'), true); ?> /> Cache the home page</label><br />
62
+ <span class="description">For many blogs this is your most visited page, it is recommended that you cache it.</span>
63
  </th>
64
  </tr>
65
  <tr>
66
  <th colspan="2">
67
  <input type="hidden" name="pgcache.cache.feed" value="0" />
68
+ <label><input type="checkbox" name="pgcache.cache.feed" value="1"<?php checked($this->_config->get_boolean('pgcache.cache.feed'), true); ?> /> Cache <acronym title="Really Simple Syndication">RSS</acronym> / Atom feeds (site, post, post comments)</label><br />
69
+ <span class="description">Even if using a feed proxy service (like <a href="http://en.wikipedia.org/wiki/FeedBurner" target="_blank">FeedBurner</a>), enabling this option is recommended.</span>
70
  </th>
71
  </tr>
72
  <tr>
73
  <th colspan="2">
74
  <input type="hidden" name="pgcache.cache.query" value="0" />
75
+ <label><input type="checkbox" name="pgcache.cache.query" value="1"<?php checked($this->_config->get_boolean('pgcache.cache.query'), true); ?><?php if ($this->_config->get_string('pgcache.engine') == 'file_pgcache'): ?> disabled="disabled"<?php endif; ?> /> Cache <acronym title="Uniform Resource Identifier">URI</acronym>s with query string variables</label><br />
76
+ <span class="description">Search result (and similar) pages will be cached if enabled.</span>
77
  </th>
78
  </tr>
79
  <tr>
80
  <th valign="top"><label for="pgcache_reject_ua">Rejected User Agents:</label></th>
81
+ <td>
82
+ <textarea id="pgcache_reject_ua" name="pgcache.reject.ua" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $this->_config->get_array('pgcache.reject.ua'))); ?></textarea><br />
83
+ <span class="description">Never send cached pages to these user agents.</span>
84
+ </td>
85
  </tr>
86
  <tr>
87
  <th valign="top"><label for="pgcache_reject_cookie">Rejected Cookies:</label></th>
88
+ <td>
89
+ <textarea id="pgcache_reject_cookie" name="pgcache.reject.cookie" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $this->_config->get_array('pgcache.reject.cookie'))); ?></textarea><br />
90
+ <span class="description">Never cache pages that use the specified cookies.</span>
91
+ </td>
92
  </tr>
93
  <tr>
94
  <th valign="top"><label for="pgcache_reject_uri">Never cache the following pages:</label></th>
95
+ <td>
96
+ <textarea id="pgcache_reject_uri" name="pgcache.reject.uri" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $this->_config->get_array('pgcache.reject.uri'))); ?></textarea><br />
97
+ <span class="description">Always ignore the specified pages / directories.</span>
98
+ </td>
99
  </tr>
100
  <tr>
101
  <th valign="top"><label for="pgcache_accept_files">Caching exception list:</label></th>
102
+ <td>
103
+ <textarea id="pgcache_accept_files" name="pgcache.accept.files" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $this->_config->get_array('pgcache.accept.files'))); ?></textarea><br />
104
+ <span class="description">Cache the specified pages / directories even if listed in the "never cache the following pages" field.</span>
105
+ </td>
106
  </tr>
107
  <tr>
108
  <th valign="top"><label for="pgcache_cache_headers">Specify page headers:</label></th>
109
+ <td>
110
+ <textarea id="pgcache_cache_headers" name="pgcache.cache.headers" cols="30" rows="5"<?php if (! W3TC_PHP5 || $this->_config->get_string('pgcache.engine') == 'file_pgcache'): ?> disabled="disabled"<?php endif; ?>><?php echo htmlspecialchars(implode("\r\n", $this->_config->get_array('pgcache.cache.headers'))); ?></textarea><br />
111
+ <span class="description">Specify additional page headers to cache.</span>
112
+ </td>
113
+ </tr>
114
+ <tr>
115
+ <th valign="top"><label for="pgcache_mobile_agents">Mobile user agents:</label></th>
116
+ <td>
117
+ <textarea id="pgcache_mobile_agents" name="pgcache.mobile.agents" cols="30" rows="5"><?php echo htmlspecialchars(implode("\r\n", $this->_config->get_array('pgcache.mobile.agents'))); ?></textarea><br />
118
+ <span class="description">Specify which mobile devices to detect.</span>
119
+ </td>
120
+ </tr>
121
+ <tr>
122
+ <th><label for="pgcache_mobile_redirect">Redirect mobile users to:</label></th>
123
+ <td>
124
+ <input id="pgcache_mobile_redirect" type="text" name="pgcache.mobile.redirect" value="<?php echo htmlspecialchars($this->_config->get_string('pgcache.mobile.redirect')); ?>" size="100" />
125
+ <br /><span class="description">If you have a mobile version of your site hosted on another domain, enter the domain name above. The user agents specified in the "Mobile user agents" box will be directed to this domain.</span>
126
+ </td>
127
  </tr>
128
  </table>
129
 
131
  <input type="submit" name="Submit" class="button-primary" value="Save changes" />
132
  </p>
133
  </form>
134
+
135
+ <?php include W3TC_DIR . '/inc/options/common/footer.phtml'; ?>
inc/options/support.phtml ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php include W3TC_DIR . '/inc/options/common/header.phtml'; ?>
2
+
3
+ <h3>Support</h3>
4
+
5
+ <form action="options-general.php?page=<?php echo urldecode(W3TC_FILE); ?>&amp;tab=<?php echo $this->_tab; ?>" method="post" enctype="multipart/form-data" id="support_form">
6
+ <table class="form-table">
7
+ <tr>
8
+ <th colspan="2">Request professional services or notify us of any bugs you have identified:</th>
9
+ </tr>
10
+ <tr>
11
+ <th valign="top"><label for="support_request_type">Request type:</label></th>
12
+ <td><select id="support_request_type" name="request_type">
13
+ <option value="">-- Choose Type --</option>
14
+ <?php foreach ($request_types as $_request_type): ?>
15
+ <option value="<?php echo $_request_type; ?>"<?php selected($_request_type, $request_type); ?>><?php echo $_request_type; ?></option>
16
+ <?php endforeach; ?>
17
+ </select></td>
18
+ </tr>
19
+ <tr>
20
+ <th><label for="support_url">Blog <acronym title="Uniform Resource Locator">URL</acronym>:</label></th>
21
+ <td><input id="support_url" type="text" name="url" value="<?php echo htmlspecialchars($url); ?>" size="80" /></td>
22
+ </tr>
23
+ <tr>
24
+ <th><label for="support_name">Name:</label></th>
25
+ <td><input id="support_name" type="text" name="name" value="<?php echo htmlspecialchars($name); ?>" size="80" /></td>
26
+ </tr>
27
+ <tr>
28
+ <th><label for="support_email">E-Mail:</label></th>
29
+ <td><input id="support_email" type="text" name="email" value="<?php echo htmlspecialchars($email); ?>" size="80" /></td>
30
+ </tr>
31
+ <tr>
32
+ <th valign="top"><label for="support_description">Issue description:</label></th>
33
+ <td><textarea id="support_description" name="description" cols="80" rows="8"><?php echo htmlspecialchars($description); ?></textarea></td>
34
+ </tr>
35
+ <tr>
36
+ <th><label for="support_template">Attach template:</label></th>
37
+ <td><select id="support_template" name="templates[]" multiple="multiple" size="10" style="height: auto;">
38
+ <?php foreach ($template_files as $template_file): ?>
39
+ <option value="<?php echo htmlspecialchars($template_file); ?>"<?php if (in_array($template_file, $templates)): ?> selected="selected"<?php endif; ?>><?php echo htmlspecialchars($template_file); ?></option>
40
+ <?php endforeach; ?>
41
+ </select></td>
42
+ </tr>
43
+ <tr>
44
+ <th><label for="support_file">Attach file:</label></th>
45
+ <td>
46
+ <input id="support_file" type="file" name="files[]" value="" /><br />
47
+ <a href="#" id="support_more_files">Attach more files</a>
48
+ </td>
49
+ </tr>
50
+ <tr>
51
+ <th><label for="support_wp_login">WP Admin login:</label></th>
52
+ <td><input id="support_wp_login" type="text" name="wp_login" value="<?php echo htmlspecialchars($wp_login); ?>" size="40" /></td>
53
+ </tr>
54
+ <tr>
55
+ <th><label for="support_wp_password">WP Admin password:</label></th>
56
+ <td><input id="support_wp_password" type="text" name="wp_password" value="<?php echo htmlspecialchars($wp_password); ?>" size="40" /></td>
57
+ </tr>
58
+ <tr>
59
+ <th><label for="support_ftp_host"><acronym title="Secure Shell">SSH</acronym> / <acronym title="File Transfer Protocol">FTP</acronym> host:</label></th>
60
+ <td><input id="support_ftp_host" type="text" name="ftp_host" value="<?php echo htmlspecialchars($ftp_host); ?>" size="40" /></td>
61
+ </tr>
62
+ <tr>
63
+ <th><label for="support_ftp_login"><acronym title="Secure Shell">SSH</acronym> / <acronym title="File Transfer Protocol">FTP</acronym> login:</label></th>
64
+ <td><input id="support_ftp_login" type="text" name="ftp_login" value="<?php echo htmlspecialchars($ftp_login); ?>" size="40" /></td>
65
+ </tr>
66
+ <tr>
67
+ <th><label for="support_ftp_password"><acronym title="Secure Shell">SSH</acronym> / <acronym title="File Transfer Protocol">FTP</acronym> password:</label></th>
68
+ <td><input id="support_ftp_password" type="text" name="ftp_password" value="<?php echo htmlspecialchars($ftp_password); ?>" size="40" /></td>
69
+ </tr>
70
+ <tr>
71
+ <th colspan="2">Notes:
72
+ <ul>
73
+ <li>All submitted data will not be saved and is used solely for the purposes your support request. You will not be added to a mailing list, solicited without your permission, nor will your site be administered after this support case is closed.</li>
74
+ <li>Instead of providing your primary administrative or <acronym title="Secure Shell">SSH</acronym> / <acronym title="File Transfer Protocol">FTP</acronym> accounts, create a new administrator account that can be disabled when the support case is closed.</li>
75
+ <li>Please add the domain w3-edge.com to your <a href="http://en.wikipedia.org/wiki/Whitelist" target="_blank">email whitelist</a> as soon as possible.</li>
76
+ </ul>
77
+ </th>
78
+ </tr>
79
+ </table>
80
+
81
+ <p class="submit">
82
+ <input type="submit" name="Submit" class="button-primary" value="Submit request" />
83
+ </p>
84
+ </form>
85
+
86
+ <?php include W3TC_DIR . '/inc/options/common/footer.phtml'; ?>
inc/options/support_email.phtml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head></head>
3
+ <body>
4
+ <p>
5
+ Date: <?php echo date('m/d/Y H:i:s'); ?><br />
6
+ Request type: <?php echo htmlspecialchars($request_type); ?><br />
7
+ URL: <a href="<?php echo htmlspecialchars($url); ?>"><?php echo htmlspecialchars($url); ?></a><br />
8
+ <?php if ($request_data_url): ?>
9
+ Request data: <a href="<?php echo htmlspecialchars($request_data_url); ?>"><?php echo htmlspecialchars($request_data_url); ?></a>
10
+ <?php endif; ?>
11
+ </p>
12
+ <p>
13
+ <?php echo nl2br(htmlspecialchars($description)); ?>
14
+ </p>
15
+ <hr />
16
+ <font size="-1" color="#cccccc">
17
+ E-mail sent from IP: <?php echo htmlspecialchars($_SERVER['REMOTE_ADDR']); ?><br />
18
+ User Agent: <?php echo htmlspecialchars($_SERVER['HTTP_USER_AGENT']); ?>
19
+ </font>
20
+ </body>
21
+ </html>
inc/popup/cdn_export_file.phtml CHANGED
@@ -1,3 +1,5 @@
 
 
1
  <script type="text/javascript">
2
  var files = [
3
  <?php $files_count = count($files); foreach ($files as $index => $file): ?>
@@ -44,4 +46,6 @@ jQuery(function() {
44
  <div class="clear"></div>
45
  </div>
46
 
47
- <div id="cdn_export_file_log" class="log"></div>
 
 
1
+ <?php include W3TC_DIR . '/inc/popup/common/header.phtml'; ?>
2
+
3
  <script type="text/javascript">
4
  var files = [
5
  <?php $files_count = count($files); foreach ($files as $index => $file): ?>
46
  <div class="clear"></div>
47
  </div>
48
 
49
+ <div id="cdn_export_file_log" class="log"></div>
50
+
51
+ <?php include W3TC_DIR . '/inc/popup/common/footer.phtml'; ?>
inc/popup/cdn_export_library.phtml CHANGED
@@ -1,3 +1,5 @@
 
 
1
  <script type="text/javascript">
2
  /*<![CDATA[*/
3
  jQuery(function() {
@@ -39,4 +41,6 @@ jQuery(function() {
39
  <div class="clear"></div>
40
  </div>
41
 
42
- <div id="cdn_export_library_log" class="log"></div>
 
 
1
+ <?php include W3TC_DIR . '/inc/popup/common/header.phtml'; ?>
2
+
3
  <script type="text/javascript">
4
  /*<![CDATA[*/
5
  jQuery(function() {
41
  <div class="clear"></div>
42
  </div>
43
 
44
+ <div id="cdn_export_library_log" class="log"></div>
45
+
46
+ <?php include W3TC_DIR . '/inc/popup/common/footer.phtml'; ?>
inc/popup/cdn_import_library.phtml CHANGED
@@ -1,3 +1,5 @@
 
 
1
  <script type="text/javascript">
2
  /*<![CDATA[*/
3
  var cdn_host = '<?php echo $cdn_host; ?>';
@@ -59,4 +61,6 @@ jQuery(function() {
59
 
60
  <p>
61
  <textarea rows="10" cols="90" id="cdn_import_library_rules" class="rules"></textarea>
62
- </p>
 
 
1
+ <?php include W3TC_DIR . '/inc/popup/common/header.phtml'; ?>
2
+
3
  <script type="text/javascript">
4
  /*<![CDATA[*/
5
  var cdn_host = '<?php echo $cdn_host; ?>';
61
 
62
  <p>
63
  <textarea rows="10" cols="90" id="cdn_import_library_rules" class="rules"></textarea>
64
+ </p>
65
+
66
+ <?php include W3TC_DIR . '/inc/popup/common/footer.phtml'; ?>
inc/popup/cdn_queue.phtml CHANGED
@@ -1,9 +1,11 @@
 
 
1
  <p id="w3tc-options-menu">
2
  <a href="#cdn_queue_upload" rel="#cdn_queue_upload" class="tab<?php if ($cdn_queue_tab == 'upload'): ?> tab-selected<?php endif; ?>">Upload queue</a> |
3
  <a href="#cdn_queue_delete" rel="#cdn_queue_delete" class="tab<?php if ($cdn_queue_tab == 'delete'): ?> tab-selected<?php endif; ?>">Delete queue</a>
4
  </p>
5
 
6
- <div id="cdn_queue_upload" class="tab-content"<?php if ($cdn_queue_tab != 'upload'): ?> style="display: none;"<?php endif; ?>>
7
  <?php if (! empty($queue[W3TC_CDN_COMMAND_UPLOAD])): ?>
8
  <table class="table queue">
9
  <tr>
@@ -33,7 +35,7 @@
33
  <?php endif; ?>
34
  </div>
35
 
36
- <div id="cdn_queue_delete" class="tab-content"<?php if ($cdn_queue_tab != 'delete'): ?> style="display: none;"<?php endif; ?>>
37
  <?php if (! empty($queue[W3TC_CDN_COMMAND_DELETE])): ?>
38
  <table class="table queue">
39
  <tr>
@@ -61,4 +63,6 @@
61
  <?php else: ?>
62
  <p class="empty">Delete queue is empty</p>
63
  <?php endif; ?>
64
- </div>
 
 
1
+ <?php include W3TC_DIR . '/inc/popup/common/header.phtml'; ?>
2
+
3
  <p id="w3tc-options-menu">
4
  <a href="#cdn_queue_upload" rel="#cdn_queue_upload" class="tab<?php if ($cdn_queue_tab == 'upload'): ?> tab-selected<?php endif; ?>">Upload queue</a> |
5
  <a href="#cdn_queue_delete" rel="#cdn_queue_delete" class="tab<?php if ($cdn_queue_tab == 'delete'): ?> tab-selected<?php endif; ?>">Delete queue</a>
6
  </p>
7
 
8
+ <div id="cdn_queue_upload" class="tab-content"<?php if ($cdn_queue_tab != 'upload'): ?> style="display:none;"<?php endif; ?>>
9
  <?php if (! empty($queue[W3TC_CDN_COMMAND_UPLOAD])): ?>
10
  <table class="table queue">
11
  <tr>
35
  <?php endif; ?>
36
  </div>
37
 
38
+ <div id="cdn_queue_delete" class="tab-content"<?php if ($cdn_queue_tab != 'delete'): ?> style="display:none;"<?php endif; ?>>
39
  <?php if (! empty($queue[W3TC_CDN_COMMAND_DELETE])): ?>
40
  <table class="table queue">
41
  <tr>
63
  <?php else: ?>
64
  <p class="empty">Delete queue is empty</p>
65
  <?php endif; ?>
66
+ </div>
67
+
68
+ <?php include W3TC_DIR . '/inc/popup/common/footer.phtml'; ?>
inc/popup/cdn_rename_domain.phtml CHANGED
@@ -1,3 +1,5 @@
 
 
1
  <script type="text/javascript">
2
  /*<![CDATA[*/
3
  jQuery(function() {
@@ -29,7 +31,10 @@ jQuery(function() {
29
  </tr>
30
  <tr>
31
  <td>Domains to rename:</td>
32
- <td><textarea cols="30" rows="3" id="cdn_rename_domain_names"></textarea></td>
 
 
 
33
  </tr>
34
  </table>
35
 
@@ -44,3 +49,5 @@ jQuery(function() {
44
  </div>
45
 
46
  <div id="cdn_rename_domain_log" class="log"></div>
 
 
1
+ <?php include W3TC_DIR . '/inc/popup/common/header.phtml'; ?>
2
+
3
  <script type="text/javascript">
4
  /*<![CDATA[*/
5
  jQuery(function() {
31
  </tr>
32
  <tr>
33
  <td>Domains to rename:</td>
34
+ <td>
35
+ <textarea cols="30" rows="3" id="cdn_rename_domain_names"></textarea><br />
36
+ e.g.: domain.com
37
+ </td>
38
  </tr>
39
  </table>
40
 
49
  </div>
50
 
51
  <div id="cdn_rename_domain_log" class="log"></div>
52
+
53
+ <?php include W3TC_DIR . '/inc/popup/common/footer.phtml'; ?>
ini/_htaccess CHANGED
@@ -1,6 +1,29 @@
1
  # Append the contents of this file to this .htaccess to the one in your document root or configuration file to enable http
2
  # compression and client-side (browser) caching of files that W3 Total Cache does not handle. This file can also be used
3
- # for the self-hosted subdomain used in your CDN settings.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  # BEGIN HTTP Compression
6
  <IfModule mod_deflate.c>
@@ -15,13 +38,12 @@ BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
15
  # workaround to get the desired effect:
16
  BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
17
  # Don't compress media or scripts
18
- SetEnvIfNoCase Request_URI \
19
- \.(?:php|gif|jpe?g|png|swf|pdf|zip|tar|rar|mp3|mov|rm|ram|wav|wma|wmv|asf|avi|mpg|mpeg|tgz|qt|doc|xls|ppt)$ no-gzip$
20
  # Make sure proxies don't deliver the wrong content
21
  Header append Vary User-Agent env=!dont-vary
22
  # Fragment size to be compressed at one time by zlib
23
  #DeflateBufferSize 4096
24
- # Fragment size to be compressed at one time by zlib
25
  #DeflateCompressionLevel 9
26
  # How much memory should be used by zlib for compression
27
  #DeflateMemLevel 9
@@ -29,39 +51,76 @@ Header append Vary User-Agent env=!dont-vary
29
  #DeflateWindowSize 15
30
  # Enable HTTP Compression policy for all except .css, .js and .html documents
31
  SetOutputFilter DEFLATE
32
- AddOutputFilterByType DEFLATE text/plain text/xml application/xml text/xsd text/xsl application/wlwmanifest+xml image/x-icon
 
33
  </IfModule>
34
  # END HTTP Compression
35
 
36
- # BEGIN Headers
37
- # Browser caching policy for all except .css, .js and .html documents
38
  <IfModule mod_expires.c>
39
  ExpiresActive On
40
- ExpiresByType text/plain A31536000
41
- ExpiresByType text/xml A31536000
42
- ExpiresByType application/xml A31536000
43
- ExpiresByType text/xsd A31536000
44
- ExpiresByType text/xsl A31536000
45
- ExpiresByType application/wlwmanifest+xml A31536000
46
- ExpiresByType image/png A31536000
47
- ExpiresByType image/jpeg A31536000
48
- ExpiresByType image/jpg A31536000
49
- ExpiresByType image/pjpeg A31536000
50
- ExpiresByType image/gif A31536000
51
- ExpiresByType image/x-icon A31536000
 
 
 
 
 
 
 
52
  </IfModule>
53
 
 
54
  <IfModule mod_headers.c>
55
- <FilesMatch "\.(ico|xml|xsd|xsl|gif|jpe?g|png|swf|pdf|zip|tar|rar|mp3|mov|rm|ram|wav|wma|wmv|asf|avi|mpg|mpeg|tgz|qt|doc|xls|ppt)$">
56
- # Set header information for proxies
57
- Header append Vary User-Agent
58
- # Ensure client-side caching of objects
59
- Header set Cache-Control "max-age=31536000, public"
60
- </FilesMatch>
61
  </IfModule>
62
 
63
- # Enable Entity Tag
64
- <FilesMatch "\.(ico|xml|xsd|xsl|gif|jpe?g|png|swf|pdf|zip|tar|rar|mp3|mov|rm|ram|wav|wma|wmv|asf|avi|mpg|mpeg|tgz|qt|doc|xls|ppt)$">
65
  FileETag MTime Size
66
  </FilesMatch>
67
- # END Headers
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # Append the contents of this file to this .htaccess to the one in your document root or configuration file to enable http
2
  # compression and client-side (browser) caching of files that W3 Total Cache does not handle. This file can also be used
3
+ # for the self-hosted subdomain used in your CDN settings. Remove the optional directives section if necessary.
4
+
5
+ # BEGIN Define Mime Types (in case /etc/mime.types is poorly configured or incorrect)
6
+ <IfModule mod_mime.c>
7
+ AddType application/x-javascript .js
8
+ AddType application/x-shockwave-flash .swf
9
+ AddType image/bmp .bmp
10
+ AddType image/gif .gif
11
+ AddType image/jpeg .jpeg
12
+ AddType image/jpg .jpg
13
+ AddType image/png .png
14
+ AddType image/svg+xml .svg
15
+ AddType image/tif .tif
16
+ AddType image/tiff .tiff
17
+ AddType image/x-icon .ico
18
+ AddType text/css .css
19
+ AddType text/htm .htm
20
+ AddType text/html .html
21
+ AddType text/plain .txt
22
+ AddType text/xml .xml
23
+ AddType text/xsd .xsd
24
+ AddType text/xsl .xsl
25
+ </IfModule>
26
+ # END Define Mime Types
27
 
28
  # BEGIN HTTP Compression
29
  <IfModule mod_deflate.c>
38
  # workaround to get the desired effect:
39
  BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
40
  # Don't compress media or scripts
41
+ SetEnvIfNoCase Request_URI (?:bmp|gif|jpe?g|php|png|swf|tiff?)$ no-gzip dont-vary
 
42
  # Make sure proxies don't deliver the wrong content
43
  Header append Vary User-Agent env=!dont-vary
44
  # Fragment size to be compressed at one time by zlib
45
  #DeflateBufferSize 4096
46
+ # Amount of compression applied to output
47
  #DeflateCompressionLevel 9
48
  # How much memory should be used by zlib for compression
49
  #DeflateMemLevel 9
51
  #DeflateWindowSize 15
52
  # Enable HTTP Compression policy for all except .css, .js and .html documents
53
  SetOutputFilter DEFLATE
54
+ AddOutputFilterByType DEFLATE text/css text/plain text/html text/xml text/xsd text/xsl application/x-javascript \
55
+ \. application/wlwmanifest+xml image/svg+xml image/x-icon
56
  </IfModule>
57
  # END HTTP Compression
58
 
59
+ # BEGIN Headers: Ensure browser caching of objects for 3 days
60
+ # Set Expires header
61
  <IfModule mod_expires.c>
62
  ExpiresActive On
63
+ ExpiresByType application/x-javascript A259200
64
+ ExpiresByType application/x-shockwave-flash A259200
65
+ ExpiresByType application/wlwmanifest+xml A259200
66
+ ExpiresByType image/bmp A259200
67
+ ExpiresByType image/gif A259200
68
+ ExpiresByType image/jpeg A259200
69
+ ExpiresByType image/jpg A259200
70
+ ExpiresByType image/png A259200
71
+ ExpiresByType image/svg+xml A259200
72
+ ExpiresByType image/tif A259200
73
+ ExpiresByType image/tiff A259200
74
+ ExpiresByType image/x-icon A259200
75
+ ExpiresByType text/css A259200
76
+ ExpiresByType text/htm A259200
77
+ ExpiresByType text/html A259200
78
+ ExpiresByType text/plain A259200
79
+ ExpiresByType text/xml A259200
80
+ ExpiresByType text/xsd A259200
81
+ ExpiresByType text/xsl A259200
82
  </IfModule>
83
 
84
+ <FilesMatch "\.(bmp|ico|html?|tiff?|gif|jpe?g|png|svgz?|swf|txt|xsd|xsl|xml)$">
85
  <IfModule mod_headers.c>
86
+ # Set Pragma header
87
+ Header set Pragma "public"
88
+ # Set Cache-Control header
89
+ Header set Cache-Control "max-age=259200, public"
90
+ # For optimal performance remove cookies
91
+ #Header unset Set-Cookie
92
  </IfModule>
93
 
94
+ # Set Entity Tag header
 
95
  FileETag MTime Size
96
  </FilesMatch>
97
+ # END Headers: Ensure client-side caching of objects
98
+
99
+ # BEGIN Optional Directives (if using a non-default permalink setting)
100
+ <IfModule mod_rewrite.c>
101
+ RewriteEngine On
102
+ RewriteBase /
103
+
104
+ # BEGIN Do not allow WordPress to process static objects
105
+ RewriteCond %{REQUEST_FILENAME} !^.*\.bmp [NC]
106
+ RewriteCond %{REQUEST_FILENAME} !^.*\.css [NC]
107
+ RewriteCond %{REQUEST_FILENAME} !^.*\.gif [NC]
108
+ RewriteCond %{REQUEST_FILENAME} !^.*\.html? [NC]
109
+ RewriteCond %{REQUEST_FILENAME} !^.*\.js [NC]
110
+ RewriteCond %{REQUEST_FILENAME} !^.*\.jpe?g [NC]
111
+ RewriteCond %{REQUEST_FILENAME} !^.*\.png [NC]
112
+ RewriteCond %{REQUEST_FILENAME} !^.*\.svgz? [NC]
113
+ RewriteCond %{REQUEST_FILENAME} !^.*\.swf [NC]
114
+ RewriteCond %{REQUEST_FILENAME} !^.*\.tiff? [NC]
115
+ RewriteCond %{REQUEST_FILENAME} !^.*\.txt [NC]
116
+ RewriteCond %{REQUEST_FILENAME} !^.*\.xsd [NC]
117
+ RewriteCond %{REQUEST_FILENAME} !^.*\.xsl [NC]
118
+ RewriteCond %{REQUEST_FILENAME} !^.*\.xml [NC]
119
+ # END Do not allow WordPress to process static objects
120
+
121
+ # Default WordPress Directives
122
+ RewriteCond %{REQUEST_FILENAME} !-f
123
+ RewriteCond %{REQUEST_FILENAME} !-d
124
+ RewriteRule . /index.php [L]
125
+ </IfModule>
126
+ # END Optional Directives
ini/apc.ini CHANGED
@@ -1,8 +1,6 @@
1
- # /etc/php.d/apc.ini
2
 
3
- ; Enable apc extension module
4
  extension = apc.so
5
- ; Options for the apc module
6
  apc.enabled = 1
7
  apc.shm_segments = 1
8
  apc.optimization = 0
@@ -13,5 +11,4 @@ apc.num_files_hint = 1024
13
  apc.mmap_file_mask = /tmp/apc.XXXXXX
14
  apc.enable_cli = 1
15
  apc.cache_by_default = 1
16
- apc.apc.stat = 0
17
- apc.include_once_override = 1
1
+ ; /etc/php.d/apc.ini
2
 
 
3
  extension = apc.so
 
4
  apc.enabled = 1
5
  apc.shm_segments = 1
6
  apc.optimization = 0
11
  apc.mmap_file_mask = /tmp/apc.XXXXXX
12
  apc.enable_cli = 1
13
  apc.cache_by_default = 1
14
+ apc.apc.stat = 0
 
ini/memcache.ini CHANGED
@@ -1,6 +1,6 @@
1
- # /etc/php.d/memcache.ini
2
 
3
- extension=memcache.so
4
  memcache.allow_failover = 1
5
  memcache.redundancy = 1
6
  memcache.session_redundancy = 2
1
+ ; /etc/php.d/memcache.ini
2
 
3
+ extension = memcache.so
4
  memcache.allow_failover = 1
5
  memcache.redundancy = 1
6
  memcache.session_redundancy = 2
ini/memcached.conf DELETED
@@ -1,7 +0,0 @@
1
- # /etc/memcached.conf
2
-
3
- PORT="11211"
4
- USER="nobody"
5
- MAXCONN="1024"
6
- CACHESIZE="128"
7
- OPTIONS=""
 
 
 
 
 
 
 
lib/Minify/HTTP/ConditionalGet.php CHANGED
@@ -150,7 +150,7 @@ class HTTP_ConditionalGet {
150
  } elseif (isset($spec['contentHash'])) { // Use the hash as the ETag
151
  $this->_setEtag($spec['contentHash'] . $etagAppend, $scope);
152
  }
153
- $this->_headers['Cache-Control'] = "max-age={$maxAge}, {$scope}";
154
  // invalidate cache if disabled, otherwise check
155
  $this->cacheIsValid = (isset($spec['invalidate']) && $spec['invalidate'])
156
  ? false
150
  } elseif (isset($spec['contentHash'])) { // Use the hash as the ETag
151
  $this->_setEtag($spec['contentHash'] . $etagAppend, $scope);
152
  }
153
+ $this->_headers['Cache-Control'] = "max-age={$maxAge}, {$scope}, must-revalidate";
154
  // invalidate cache if disabled, otherwise check
155
  $this->cacheIsValid = (isset($spec['invalidate']) && $spec['invalidate'])
156
  ? false
lib/Minify/Minify.php CHANGED
@@ -7,7 +7,7 @@
7
  /**
8
  * Minify_Source
9
  */
10
- require_once 'Minify/Source.php';
11
 
12
  /**
13
  * Minify - Combines, minifies, and caches JavaScript and CSS files on demand.
@@ -59,6 +59,12 @@ class Minify {
59
  */
60
  public static $importWarning = "/* See http://code.google.com/p/minify/wiki/CommonProblems#@imports_can_appear_in_invalid_locations_in_combined_CSS_files */\n";
61
 
 
 
 
 
 
 
62
  /**
63
  * Specify a cache object (with identical interface as Minify_Cache_File) or
64
  * a path to use with Minify_Cache_File.
@@ -77,7 +83,7 @@ class Minify {
77
  public static function setCache($cache = '', $fileLocking = true)
78
  {
79
  if (is_string($cache)) {
80
- require_once 'Minify/Cache/File.php';
81
  self::$_cache = new Minify_Cache_File($cache, $fileLocking);
82
  } else {
83
  self::$_cache = $cache;
@@ -163,7 +169,7 @@ class Minify {
163
  // make $controller into object
164
  $class = 'Minify_Controller_' . $controller;
165
  if (! class_exists($class, false)) {
166
- require_once "Minify/Controller/"
167
  . str_replace('_', '/', $controller) . ".php";
168
  }
169
  $controller = new $class();
@@ -207,7 +213,7 @@ class Minify {
207
  $contentEncoding = self::$_options['encodeMethod'];
208
  } else {
209
  // sniff request header
210
- require_once 'HTTP/Encoder.php';
211
  // depending on what the client accepts, $contentEncoding may be
212
  // 'x-gzip' while our internal encodeMethod is 'gzip'. Calling
213
  // getAcceptedEncoding(false, false) leaves out compress and deflate as options.
@@ -218,7 +224,7 @@ class Minify {
218
  }
219
 
220
  // check client cache
221
- require_once 'HTTP/ConditionalGet.php';
222
  $cgOptions = array(
223
  'lastModifiedTime' => self::$_options['lastModifiedTime']
224
  ,'isPublic' => self::$_options['isPublic']
@@ -266,7 +272,7 @@ class Minify {
266
  // the goal is to use only the cache methods to sniff the length and
267
  // output the content, as they do not require ever loading the file into
268
  // memory.
269
- $cacheId = 'minify_' . self::_getCacheId();
270
  $fullCacheId = (self::$_options['encodeMethod'])
271
  ? $cacheId . '.gz'
272
  : $cacheId;
@@ -376,7 +382,7 @@ class Minify {
376
  if ($unsetPathInfo) {
377
  unset($_SERVER['PATH_INFO']);
378
  }
379
- require_once 'Minify/Logger.php';
380
  Minify_Logger::log("setDocRoot() set DOCUMENT_ROOT to \"{$_SERVER['DOCUMENT_ROOT']}\"");
381
  }
382
  }
@@ -408,8 +414,8 @@ class Minify {
408
  foreach ($sources as $source) {
409
  $source->minifier = array('Minify_Lines', 'minify');
410
  $id = $source->getId();
411
- $source->minifyOptions = array(
412
- 'id' => (is_file($id) ? basename($id) : $id)
413
  );
414
  }
415
  }
@@ -486,6 +492,23 @@ class Minify {
486
  return $content;
487
  }
488
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
489
  /**
490
  * Make a unique cache id for for this request.
491
  *
@@ -495,13 +518,13 @@ class Minify {
495
  */
496
  protected static function _getCacheId()
497
  {
498
- return md5(serialize(array(
499
  Minify_Source::getDigest(self::$_controller->sources)
500
  ,self::$_options['minifiers']
501
  ,self::$_options['minifierOptions']
502
  ,self::$_options['postprocessor']
503
  ,self::$_options['bubbleCssImports']
504
- )));
505
  }
506
 
507
  /**
7
  /**
8
  * Minify_Source
9
  */
10
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Source.php';
11
 
12
  /**
13
  * Minify - Combines, minifies, and caches JavaScript and CSS files on demand.
59
  */
60
  public static $importWarning = "/* See http://code.google.com/p/minify/wiki/CommonProblems#@imports_can_appear_in_invalid_locations_in_combined_CSS_files */\n";
61
 
62
+ /**
63
+ * Cache ID
64
+ * @var string
65
+ */
66
+ protected static $_cacheId = null;
67
+
68
  /**
69
  * Specify a cache object (with identical interface as Minify_Cache_File) or
70
  * a path to use with Minify_Cache_File.
83
  public static function setCache($cache = '', $fileLocking = true)
84
  {
85
  if (is_string($cache)) {
86
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/File.php';
87
  self::$_cache = new Minify_Cache_File($cache, $fileLocking);
88
  } else {
89
  self::$_cache = $cache;
169
  // make $controller into object
170
  $class = 'Minify_Controller_' . $controller;
171
  if (! class_exists($class, false)) {
172
+ require_once W3TC_LIB_MINIFY_DIR . "/Minify/Controller/"
173
  . str_replace('_', '/', $controller) . ".php";
174
  }
175
  $controller = new $class();
213
  $contentEncoding = self::$_options['encodeMethod'];
214
  } else {
215
  // sniff request header
216
+ require_once W3TC_LIB_MINIFY_DIR . '/HTTP/Encoder.php';
217
  // depending on what the client accepts, $contentEncoding may be
218
  // 'x-gzip' while our internal encodeMethod is 'gzip'. Calling
219
  // getAcceptedEncoding(false, false) leaves out compress and deflate as options.
224
  }
225
 
226
  // check client cache
227
+ require_once W3TC_LIB_MINIFY_DIR . '/HTTP/ConditionalGet.php';
228
  $cgOptions = array(
229
  'lastModifiedTime' => self::$_options['lastModifiedTime']
230
  ,'isPublic' => self::$_options['isPublic']
272
  // the goal is to use only the cache methods to sniff the length and
273
  // output the content, as they do not require ever loading the file into
274
  // memory.
275
+ $cacheId = self::_getCacheId();
276
  $fullCacheId = (self::$_options['encodeMethod'])
277
  ? $cacheId . '.gz'
278
  : $cacheId;
382
  if ($unsetPathInfo) {
383
  unset($_SERVER['PATH_INFO']);
384
  }
385
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Logger.php';
386
  Minify_Logger::log("setDocRoot() set DOCUMENT_ROOT to \"{$_SERVER['DOCUMENT_ROOT']}\"");
387
  }
388
  }
414
  foreach ($sources as $source) {
415
  $source->minifier = array('Minify_Lines', 'minify');
416
  $id = $source->getId();
417
+ $source->minifyOptions = array_merge((array) $source->minifyOptions, array(
418
+ 'id' => (is_file($id) ? basename($id) : $id))
419
  );
420
  }
421
  }
492
  return $content;
493
  }
494
 
495
+ /**
496
+ * Sets cache ID
497
+ * @param string $cacheId
498
+ */
499
+ public static function setCacheId($cacheId = null)
500
+ {
501
+ self::$_cacheId = $cacheId;
502
+ }
503
+
504
+ /**
505
+ * Returns cache ID
506
+ */
507
+ public static function getCacheId()
508
+ {
509
+ return self::$_cacheId;
510
+ }
511
+
512
  /**
513
  * Make a unique cache id for for this request.
514
  *
518
  */
519
  protected static function _getCacheId()
520
  {
521
+ return (self::$_cacheId ? self::$_cacheId : md5(serialize(array(
522
  Minify_Source::getDigest(self::$_controller->sources)
523
  ,self::$_options['minifiers']
524
  ,self::$_options['minifierOptions']
525
  ,self::$_options['postprocessor']
526
  ,self::$_options['bubbleCssImports']
527
+ ))));
528
  }
529
 
530
  /**
lib/Minify/Minify/Build.php CHANGED
@@ -4,7 +4,7 @@
4
  * @package Minify
5
  */
6
 
7
- require_once 'Minify/Source.php';
8
 
9
  /**
10
  * Maintain a single last modification time for a group of Minify sources to
4
  * @package Minify
5
  */
6
 
7
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Source.php';
8
 
9
  /**
10
  * Maintain a single last modification time for a group of Minify sources to
lib/Minify/Minify/CSS.php CHANGED
@@ -50,12 +50,12 @@ class Minify_CSS {
50
  */
51
  public static function minify($css, $options = array())
52
  {
53
- require_once 'Minify/CSS/Compressor.php';
54
  if (isset($options['preserveComments'])
55
  && !$options['preserveComments']) {
56
  $css = Minify_CSS_Compressor::process($css, $options);
57
  } else {
58
- require_once 'Minify/CommentPreserver.php';
59
  $css = Minify_CommentPreserver::process(
60
  $css
61
  ,array('Minify_CSS_Compressor', 'process')
@@ -65,7 +65,7 @@ class Minify_CSS {
65
  if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) {
66
  return $css;
67
  }
68
- require_once 'Minify/CSS/UriRewriter.php';
69
  if (isset($options['currentDir'])) {
70
  return Minify_CSS_UriRewriter::rewrite(
71
  $css
50
  */
51
  public static function minify($css, $options = array())
52
  {
53
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/CSS/Compressor.php';
54
  if (isset($options['preserveComments'])
55
  && !$options['preserveComments']) {
56
  $css = Minify_CSS_Compressor::process($css, $options);
57
  } else {
58
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/CommentPreserver.php';
59
  $css = Minify_CommentPreserver::process(
60
  $css
61
  ,array('Minify_CSS_Compressor', 'process')
65
  if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) {
66
  return $css;
67
  }
68
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/CSS/UriRewriter.php';
69
  if (isset($options['currentDir'])) {
70
  return Minify_CSS_UriRewriter::rewrite(
71
  $css
lib/Minify/Minify/CSS/UriRewriter.php CHANGED
@@ -158,15 +158,33 @@ class Minify_CSS_UriRewriter {
158
  : substr($m[1], 1, strlen($m[1]) - 2);
159
  }
160
  // analyze URI
161
- if ('/' !== $uri[0] // root-relative
162
- && false === strpos($uri, '//') // protocol (non-data)
163
- && 0 !== strpos($uri, 'data:') // data protocol
164
- ) {
165
- // URI is file-relative: rewrite depending on options
166
- $uri = (self::$_prependPath !== null)
167
- ? (self::$_prependPath . $uri)
168
- : self::rewriteRelative($uri, self::$_currentDir, self::$_docRoot, self::$_symlinks);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  }
 
170
  return $isImport
171
  ? "@import {$quoteChar}{$uri}{$quoteChar}"
172
  : "url({$quoteChar}{$uri}{$quoteChar})";
@@ -212,6 +230,10 @@ class Minify_CSS_UriRewriter {
212
  */
213
  public static function rewriteRelative($uri, $realCurrentDir, $realDocRoot, $symlinks = array())
214
  {
 
 
 
 
215
  // prepend path with current dir separator (OS-independent)
216
  $path = strtr($realCurrentDir, '/', DIRECTORY_SEPARATOR)
217
  . DIRECTORY_SEPARATOR . strtr($uri, '/', DIRECTORY_SEPARATOR);
158
  : substr($m[1], 1, strlen($m[1]) - 2);
159
  }
160
  // analyze URI
161
+ if (false === strpos($uri, '//') // protocol (non-data)
162
+ && 0 !== strpos($uri, 'data:')) // data protocol
163
+ {
164
+ if (self::$_prependPath !== null) {
165
+ if (w3_is_url(self::$_prependPath)) {
166
+ $parse_url = @parse_url(self::$_prependPath);
167
+
168
+ if ($parse_url && isset($parse_url['host'])) {
169
+ $scheme = $parse_url['scheme'];
170
+ $host = $parse_url['host'];
171
+ $port = (isset($parse_url['port']) && $parse_url['port'] != 80 ? ':' . (int) $parse_url['port'] : '');
172
+ $path = (! empty($parse_url['path']) ? $parse_url['path'] : '/');
173
+ $dir_css = preg_replace('~[^/]+$~', '', $path);
174
+ $dir_obj = preg_replace('~[^/]+$~', '', $uri);
175
+ $dir = ltrim((strpos($dir_obj, '/') === 0 ? w3_realpath($dir_obj) : w3_realpath($dir_css . $dir_obj)), '/');
176
+ $file = basename($uri);
177
+
178
+ $uri = sprintf('%s://%s%s/%s%s', $scheme, $host, $port, $dir, $file);
179
+ }
180
+ } else {
181
+ $uri = self::$_prependPath . $uri;
182
+ }
183
+ } else {
184
+ $uri = self::rewriteRelative($uri, self::$_currentDir, self::$_docRoot, self::$_symlinks);
185
+ }
186
  }
187
+
188
  return $isImport
189
  ? "@import {$quoteChar}{$uri}{$quoteChar}"
190
  : "url({$quoteChar}{$uri}{$quoteChar})";
230
  */
231
  public static function rewriteRelative($uri, $realCurrentDir, $realDocRoot, $symlinks = array())
232
  {
233
+ if ('/' === $uri[0]) { // root-relative
234
+ return $uri;
235
+ }
236
+
237
  // prepend path with current dir separator (OS-independent)
238
  $path = strtr($realCurrentDir, '/', DIRECTORY_SEPARATOR)
239
  . DIRECTORY_SEPARATOR . strtr($uri, '/', DIRECTORY_SEPARATOR);
lib/Minify/Minify/Cache/File.php CHANGED
@@ -9,7 +9,7 @@ class Minify_Cache_File {
9
  public function __construct($path = '', $fileLocking = false)
10
  {
11
  if (! $path) {
12
- require_once 'Solar/Dir.php';
13
  $path = rtrim(Solar_Dir::tmp(), DIRECTORY_SEPARATOR);
14
  }
15
  $this->_locking = $fileLocking;
9
  public function __construct($path = '', $fileLocking = false)
10
  {
11
  if (! $path) {
12
+ require_once W3TC_LIB_MINIFY_DIR . '/Solar/Dir.php';
13
  $path = rtrim(Solar_Dir::tmp(), DIRECTORY_SEPARATOR);
14
  }
15
  $this->_locking = $fileLocking;
lib/Minify/Minify/Controller/Base.php CHANGED
@@ -100,7 +100,7 @@ abstract class Minify_Controller_Base {
100
  && is_string($minifierCallback[0])
101
  && !class_exists($minifierCallback[0], false)) {
102
 
103
- require str_replace('_', '/', $minifierCallback[0]) . '.php';
104
  }
105
  }
106
 
@@ -196,7 +196,7 @@ abstract class Minify_Controller_Base {
196
  * @return null
197
  */
198
  protected function log($msg) {
199
- require_once 'Minify/Logger.php';
200
  Minify_Logger::log($msg);
201
  }
202
  }
100
  && is_string($minifierCallback[0])
101
  && !class_exists($minifierCallback[0], false)) {
102
 
103
+ require W3TC_LIB_MINIFY_DIR . '/' . str_replace('_', '/', $minifierCallback[0]) . '.php';
104
  }
105
  }
106
 
196
  * @return null
197
  */
198
  protected function log($msg) {
199
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Logger.php';
200
  Minify_Logger::log($msg);
201
  }
202
  }
lib/Minify/Minify/Controller/Files.php CHANGED
@@ -4,7 +4,7 @@
4
  * @package Minify
5
  */
6
 
7
- require_once 'Minify/Controller/Base.php';
8
 
9
  /**
10
  * Controller class for minifying a set of files
4
  * @package Minify
5
  */
6
 
7
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Controller/Base.php';
8
 
9
  /**
10
  * Controller class for minifying a set of files
lib/Minify/Minify/Controller/Groups.php CHANGED
@@ -4,7 +4,7 @@
4
  * @package Minify
5
  */
6
 
7
- require_once 'Minify/Controller/Base.php';
8
 
9
  /**
10
  * Controller class for serving predetermined groups of minimized sets, selected
4
  * @package Minify
5
  */
6
 
7
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Controller/Base.php';
8
 
9
  /**
10
  * Controller class for serving predetermined groups of minimized sets, selected
lib/Minify/Minify/Controller/MinApp.php CHANGED
@@ -4,7 +4,7 @@
4
  * @package Minify
5
  */
6
 
7
- require_once 'Minify/Controller/Base.php';
8
 
9
  /**
10
  * Controller class for requests to /min/index.php
4
  * @package Minify
5
  */
6
 
7
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Controller/Base.php';
8
 
9
  /**
10
  * Controller class for requests to /min/index.php
lib/Minify/Minify/Controller/Page.php CHANGED
@@ -4,7 +4,7 @@
4
  * @package Minify
5
  */
6
 
7
- require_once 'Minify/Controller/Base.php';
8
 
9
  /**
10
  * Controller class for serving a single HTML page
@@ -73,8 +73,8 @@ class Minify_Controller_Page extends Minify_Controller_Base {
73
  if ($this->_loadCssJsMinifiers) {
74
  // Minify will not call for these so we must manually load
75
  // them when Minify/HTML.php is called for.
76
- require_once 'Minify/CSS.php';
77
- require_once 'JSMin.php';
78
  }
79
  parent::loadMinifier($minifierCallback); // load Minify/HTML.php
80
  }
4
  * @package Minify
5
  */
6
 
7
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Controller/Base.php';
8
 
9
  /**
10
  * Controller class for serving a single HTML page
73
  if ($this->_loadCssJsMinifiers) {
74
  // Minify will not call for these so we must manually load
75
  // them when Minify/HTML.php is called for.
76
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/CSS.php';
77
+ require_once W3TC_LIB_MINIFY_DIR . '/JSMin.php';
78
  }
79
  parent::loadMinifier($minifierCallback); // load Minify/HTML.php
80
  }
lib/Minify/Minify/Controller/Version1.php CHANGED
@@ -4,7 +4,7 @@
4
  * @package Minify
5
  */
6
 
7
- require_once 'Minify/Controller/Base.php';
8
 
9
  /**
10
  * Controller class for emulating version 1 of minify.php
4
  * @package Minify
5
  */
6
 
7
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/Controller/Base.php';
8
 
9
  /**
10
  * Controller class for emulating version 1 of minify.php
lib/Minify/Minify/HTML.php CHANGED
@@ -72,9 +72,14 @@ class Minify_HTML {
72
  if (isset($options['jsMinifier'])) {
73
  $this->_jsMinifier = $options['jsMinifier'];
74
  }
 
 
 
 
 
 
75
  }
76
 
77
-
78
  /**
79
  * Minify the markeup given in the constructor
80
  *
@@ -138,6 +143,12 @@ class Minify_HTML {
138
  // use newlines before 1st attribute in open tags (to limit line lengths)
139
  $this->_html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/i', "$1\n$2", $this->_html);
140
 
 
 
 
 
 
 
141
  // fill placeholders
142
  $this->_html = str_replace(
143
  array_keys($this->_placeholders)
@@ -198,6 +209,16 @@ class Minify_HTML {
198
  : 'trim';
199
  $css = call_user_func($minifier, $css);
200
 
 
 
 
 
 
 
 
 
 
 
201
  return $this->_reservePlace($this->_needsCdata($css)
202
  ? "{$openStyle}/*<![CDATA[*/{$css}/*]]>*/</style>"
203
  : "{$openStyle}{$css}</style>"
@@ -225,6 +246,17 @@ class Minify_HTML {
225
  : 'trim';
226
  $js = call_user_func($minifier, $js);
227
 
 
 
 
 
 
 
 
 
 
 
 
228
  return $this->_reservePlace($this->_needsCdata($js)
229
  ? "{$ws1}{$openScript}/*<![CDATA[*/{$js}/*]]>*/</script>{$ws2}"
230
  : "{$ws1}{$openScript}{$js}</script>{$ws2}"
72
  if (isset($options['jsMinifier'])) {
73
  $this->_jsMinifier = $options['jsMinifier'];
74
  }
75
+
76
+ $this->_stripCrlf = (isset($options['stripCrlf']) ? (boolean) $options['stripCrlf'] : false) ;
77
+ $this->_cssStripCrlf = (isset($options['cssStripCrlf']) ? (boolean) $options['cssStripCrlf'] : false);
78
+ $this->_cssStripComments = (isset($options['cssStripComments']) ? (boolean) $options['cssStripComments'] : false);
79
+ $this->_jsStripCrlf = (isset($options['jsStripCrlf']) ? (boolean) $options['jsStripCrlf'] : false);
80
+ $this->_jsStripComments = (isset($options['jsStripComments']) ? (boolean) $options['jsStripComments'] : false);
81
  }
82
 
 
83
  /**
84
  * Minify the markeup given in the constructor
85
  *
143
  // use newlines before 1st attribute in open tags (to limit line lengths)
144
  $this->_html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/i', "$1\n$2", $this->_html);
145
 
146
+ if ($this->_stripCrlf) {
147
+ $this->_html = preg_replace("~[\r\n]+~", ' ', $this->_html);
148
+ } else {
149
+ $this->_html = preg_replace("~[\r\n]+~", "\n", $this->_html);
150
+ }
151
+
152
  // fill placeholders
153
  $this->_html = str_replace(
154
  array_keys($this->_placeholders)
209
  : 'trim';
210
  $css = call_user_func($minifier, $css);
211
 
212
+ if ($this->_cssStripComments) {
213
+ $css = preg_replace('~/\*.*\*/~Us', '', $css);
214
+ }
215
+
216
+ if ($this->_cssStripCrlf) {
217
+ $css = preg_replace("~[\r\n]+~", ' ', $css);
218
+ } else {
219
+ $css = preg_replace("~[\r\n]+~", "\n", $css);
220
+ }
221
+
222
  return $this->_reservePlace($this->_needsCdata($css)
223
  ? "{$openStyle}/*<![CDATA[*/{$css}/*]]>*/</style>"
224
  : "{$openStyle}{$css}</style>"
246
  : 'trim';
247
  $js = call_user_func($minifier, $js);
248
 
249
+ if ($this->_jsStripComments) {
250
+ $js = preg_replace('~^//.*$~m', '', $js);
251
+ $js = preg_replace('~/\*.*\*/~Us', '', $js);
252
+ }
253
+
254
+ if ($this->_jsStripCrlf) {
255
+ $js = preg_replace("~[\r\n]+~", '', $js);
256
+ } else {
257
+ $js = preg_replace("~[\r\n]+~", "\n", $js);
258
+ }
259
+
260
  return $this->_reservePlace($this->_needsCdata($js)
261
  ? "{$ws1}{$openScript}/*<![CDATA[*/{$js}/*]]>*/</script>{$ws2}"
262
  : "{$ws1}{$openScript}{$js}</script>{$ws2}"
lib/Minify/Minify/Lines.php CHANGED
@@ -59,7 +59,7 @@ class Minify_Lines {
59
 
60
  // check for desired URI rewriting
61
  if (isset($options['currentDir'])) {
62
- require_once 'Minify/CSS/UriRewriter.php';
63
  Minify_CSS_UriRewriter::$debugText = '';
64
  $content = Minify_CSS_UriRewriter::rewrite(
65
  $content
@@ -68,8 +68,15 @@ class Minify_Lines {
68
  ,isset($options['symlinks']) ? $options['symlinks'] : array()
69
  );
70
  $content = "/* Minify_CSS_UriRewriter::\$debugText\n\n"
71
- . Minify_CSS_UriRewriter::$debugText . "*/\n"
72
- . $content;
 
 
 
 
 
 
 
73
  }
74
 
75
  return $content;
59
 
60
  // check for desired URI rewriting
61
  if (isset($options['currentDir'])) {
62
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/CSS/UriRewriter.php';
63
  Minify_CSS_UriRewriter::$debugText = '';
64
  $content = Minify_CSS_UriRewriter::rewrite(
65
  $content
68
  ,isset($options['symlinks']) ? $options['symlinks'] : array()
69
  );
70
  $content = "/* Minify_CSS_UriRewriter::\$debugText\n\n"
71
+ . Minify_CSS_UriRewriter::$debugText . "*/\n"
72
+ . $content;
73
+ } elseif (isset($options['prependRelativePath'])) {
74
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/CSS/UriRewriter.php';
75
+ Minify_CSS_UriRewriter::$debugText = '';
76
+ $content = Minify_CSS_UriRewriter::prepend(
77
+ $content
78
+ ,$options['prependRelativePath']
79
+ );
80
  }
81
 
82
  return $content;
lib/Minify/Minify/Packer.php CHANGED
@@ -14,7 +14,7 @@
14
  * @package Minify
15
  */
16
 
17
- if (false === (@include 'class.JavaScriptPacker.php')) {
18
  trigger_error(
19
  'The script "class.JavaScriptPacker.php" is required. Please see: http:'
20
  .'//code.google.com/p/minify/source/browse/trunk/min/lib/Minify/Packer.php'
14
  * @package Minify
15
  */
16
 
17
+ if (false === (@include W3TC_LIB_MINIFY_DIR . '/class.JavaScriptPacker.php')) {
18
  trigger_error(
19
  'The script "class.JavaScriptPacker.php" is required. Please see: http:'
20
  .'//code.google.com/p/minify/source/browse/trunk/min/lib/Minify/Packer.php'
lib/Minify/Minify/Source.php CHANGED
@@ -72,6 +72,7 @@ class Minify_Source {
72
  }
73
  $this->filepath = $spec['filepath'];
74
  $this->_id = $spec['filepath'];
 
75
  $this->lastModified = filemtime($spec['filepath'])
76
  // offset for Windows uploaders with out of sync clocks
77
  + round(Minify::$uploaderHoursBehind * 3600);
72
  }
73
  $this->filepath = $spec['filepath'];
74
  $this->_id = $spec['filepath'];
75
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify.php';
76
  $this->lastModified = filemtime($spec['filepath'])
77
  // offset for Windows uploaders with out of sync clocks
78
  + round(Minify::$uploaderHoursBehind * 3600);
lib/S3.php ADDED
@@ -0,0 +1,1335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * $Id: S3.php 47 2009-07-20 01:25:40Z don.schonknecht $
4
+ *
5
+ * Copyright (c) 2008, Donovan Schönknecht. All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * - Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ * - Redistributions in binary form must reproduce the above copyright
13
+ * notice, this list of conditions and the following disclaimer in the
14
+ * documentation and/or other materials provided with the distribution.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ * POSSIBILITY OF SUCH DAMAGE.
27
+ *
28
+ * Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
29
+ */
30
+
31
+ /**
32
+ * Amazon S3 PHP class
33
+ *
34
+ * @link http://undesigned.org.za/2007/10/22/amazon-s3-php-class
35
+ * @version 0.4.0
36
+ */
37
+ class S3 {
38
+ // ACL flags
39
+ const ACL_PRIVATE = 'private';
40
+ const ACL_PUBLIC_READ = 'public-read';
41
+ const ACL_PUBLIC_READ_WRITE = 'public-read-write';
42
+ const ACL_AUTHENTICATED_READ = 'authenticated-read';
43
+
44
+ public static $useSSL = true;
45
+
46
+ private static $__accessKey; // AWS Access key
47
+ private static $__secretKey; // AWS Secret key
48
+
49
+
50
+ /**
51
+ * Constructor - if you're not using the class statically
52
+ *
53
+ * @param string $accessKey Access key
54
+ * @param string $secretKey Secret key
55
+ * @param boolean $useSSL Enable SSL
56
+ * @return void
57
+ */
58
+ public function __construct($accessKey = null, $secretKey = null, $useSSL = true) {
59
+ if ($accessKey !== null && $secretKey !== null)
60
+ self::setAuth($accessKey, $secretKey);
61
+ self::$useSSL = $useSSL;
62
+ }
63
+
64
+
65
+ /**
66
+ * Set AWS access key and secret key
67
+ *
68
+ * @param string $accessKey Access key
69
+ * @param string $secretKey Secret key
70
+ * @return void
71
+ */
72
+ public static function setAuth($accessKey, $secretKey) {
73
+ self::$__accessKey = $accessKey;
74
+ self::$__secretKey = $secretKey;
75
+ }
76
+
77
+
78
+ /**
79
+ * Get a list of buckets
80
+ *
81
+ * @param boolean $detailed Returns detailed bucket list when true
82
+ * @return array | false
83
+ */
84
+ public static function listBuckets($detailed = false) {
85
+ $rest = new S3Request('GET', '', '');
86
+ $rest = $rest->getResponse();
87
+ if ($rest->error === false && $rest->code !== 200)
88
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
89
+ if ($rest->error !== false) {
90
+ trigger_error(sprintf("S3::listBuckets(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING);
91
+ return false;
92
+ }
93
+ $results = array();
94
+ if (!isset($rest->body->Buckets)) return $results;
95
+
96
+ if ($detailed) {
97
+ if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
98
+ $results['owner'] = array(
99
+ 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID
100
+ );
101
+ $results['buckets'] = array();
102
+ foreach ($rest->body->Buckets->Bucket as $b)
103
+ $results['buckets'][] = array(
104
+ 'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate)
105
+ );
106
+ } else
107
+ foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name;
108
+
109
+ return $results;
110
+ }
111
+
112
+
113
+ /*
114
+ * Get contents for a bucket
115
+ *
116
+ * If maxKeys is null this method will loop through truncated result sets
117
+ *
118
+ * @param string $bucket Bucket name
119
+ * @param string $prefix Prefix
120
+ * @param string $marker Marker (last file listed)
121
+ * @param string $maxKeys Max keys (maximum number of keys to return)
122
+ * @param string $delimiter Delimiter
123
+ * @param boolean $returnCommonPrefixes Set to true to return CommonPrefixes
124
+ * @return array | false
125
+ */
126
+ public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null, $delimiter = null, $returnCommonPrefixes = false) {
127
+ $rest = new S3Request('GET', $bucket, '');
128
+ if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
129
+ if ($marker !== null && $marker !== '') $rest->setParameter('marker', $marker);
130
+ if ($maxKeys !== null && $maxKeys !== '') $rest->setParameter('max-keys', $maxKeys);
131
+ if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
132
+ $response = $rest->getResponse();
133
+ if ($response->error === false && $response->code !== 200)
134
+ $response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status');
135
+ if ($response->error !== false) {
136
+ trigger_error(sprintf("S3::getBucket(): [%s] %s", $response->error['code'], $response->error['message']), E_USER_WARNING);
137
+ return false;
138
+ }
139
+
140
+ $results = array();
141
+
142
+ $nextMarker = null;
143
+ if (isset($response->body, $response->body->Contents))
144
+ foreach ($response->body->Contents as $c) {
145
+ $results[(string)$c->Key] = array(
146
+ 'name' => (string)$c->Key,
147
+ 'time' => strtotime((string)$c->LastModified),
148
+ 'size' => (int)$c->Size,
149
+ 'hash' => substr((string)$c->ETag, 1, -1)
150
+ );
151
+ $nextMarker = (string)$c->Key;
152
+ }
153
+
154
+ if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
155
+ foreach ($response->body->CommonPrefixes as $c)
156
+ $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
157
+
158
+ if (isset($response->body, $response->body->IsTruncated) &&
159
+ (string)$response->body->IsTruncated == 'false') return $results;
160
+
161
+ if (isset($response->body, $response->body->NextMarker))
162
+ $nextMarker = (string)$response->body->NextMarker;
163
+
164
+ // Loop through truncated results if maxKeys isn't specified
165
+ if ($maxKeys == null && $nextMarker !== null && (string)$response->body->IsTruncated == 'true')
166
+ do {
167
+ $rest = new S3Request('GET', $bucket, '');
168
+ if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
169
+ $rest->setParameter('marker', $nextMarker);
170
+ if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
171
+
172
+ if (($response = $rest->getResponse(true)) == false || $response->code !== 200) break;
173
+
174
+ if (isset($response->body, $response->body->Contents))
175
+ foreach ($response->body->Contents as $c) {
176
+ $results[(string)$c->Key] = array(
177
+ 'name' => (string)$c->Key,
178
+ 'time' => strtotime((string)$c->LastModified),
179
+ 'size' => (int)$c->Size,
180
+ 'hash' => substr((string)$c->ETag, 1, -1)
181
+ );
182
+ $nextMarker = (string)$c->Key;
183
+ }
184
+
185
+ if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
186
+ foreach ($response->body->CommonPrefixes as $c)
187
+ $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
188
+
189
+ if (isset($response->body, $response->body->NextMarker))
190
+ $nextMarker = (string)$response->body->NextMarker;
191
+
192
+ } while ($response !== false && (string)$response->body->IsTruncated == 'true');
193
+
194
+ return $results;
195
+ }
196
+
197
+
198
+ /**
199
+ * Put a bucket
200
+ *
201
+ * @param string $bucket Bucket name
202
+ * @param constant $acl ACL flag
203
+ * @param string $location Set as "EU" to create buckets hosted in Europe
204
+ * @return boolean
205
+ */
206
+ public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = false) {
207
+ $rest = new S3Request('PUT', $bucket, '');
208
+ $rest->setAmzHeader('x-amz-acl', $acl);
209
+
210
+ if ($location !== false) {
211
+ $dom = new DOMDocument;
212
+ $createBucketConfiguration = $dom->createElement('CreateBucketConfiguration');
213
+ $locationConstraint = $dom->createElement('LocationConstraint', strtoupper($location));
214
+ $createBucketConfiguration->appendChild($locationConstraint);
215
+ $dom->appendChild($createBucketConfiguration);
216
+ $rest->data = $dom->saveXML();
217
+ $rest->size = strlen($rest->data);
218
+ $rest->setHeader('Content-Type', 'application/xml');
219
+ }
220
+ $rest = $rest->getResponse();
221
+
222
+ if ($rest->error === false && $rest->code !== 200)
223
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
224
+ if ($rest->error !== false) {
225
+ trigger_error(sprintf("S3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s",
226
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
227
+ return false;
228
+ }
229
+ return true;
230
+ }
231
+
232
+
233
+ /**
234
+ * Delete an empty bucket
235
+ *
236
+ * @param string $bucket Bucket name
237
+ * @return boolean
238
+ */
239
+ public static function deleteBucket($bucket) {
240
+ $rest = new S3Request('DELETE', $bucket);
241
+ $rest = $rest->getResponse();
242
+ if ($rest->error === false && $rest->code !== 204)
243
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
244
+ if ($rest->error !== false) {
245
+ trigger_error(sprintf("S3::deleteBucket({$bucket}): [%s] %s",
246
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
247
+ return false;
248
+ }
249
+ return true;
250
+ }
251
+
252
+
253
+ /**
254
+ * Create input info array for putObject()
255
+ *
256
+ * @param string $file Input file
257
+ * @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own)
258
+ * @return array | false
259
+ */
260
+ public static function inputFile($file, $md5sum = true) {
261
+ if (!file_exists($file) || !is_file($file) || !is_readable($file)) {
262
+ trigger_error('S3::inputFile(): Unable to open input file: '.$file, E_USER_WARNING);
263
+ return false;
264
+ }
265
+ return array('file' => $file, 'size' => filesize($file),
266
+ 'md5sum' => $md5sum !== false ? (is_string($md5sum) ? $md5sum :
267
+ base64_encode(md5_file($file, true))) : '');
268
+ }
269
+
270
+
271
+ /**
272
+ * Create input array info for putObject() with a resource
273
+ *
274
+ * @param string $resource Input resource to read from
275
+ * @param integer $bufferSize Input byte size
276
+ * @param string $md5sum MD5 hash to send (optional)
277
+ * @return array | false
278
+ */
279
+ public static function inputResource(&$resource, $bufferSize, $md5sum = '') {
280
+ if (!is_resource($resource) || $bufferSize < 0) {
281
+ trigger_error('S3::inputResource(): Invalid resource or buffer size', E_USER_WARNING);
282
+ return false;
283
+ }
284
+ $input = array('size' => $bufferSize, 'md5sum' => $md5sum);
285
+ $input['fp'] =& $resource;
286
+ return $input;
287
+ }
288
+
289
+
290
+ /**
291
+ * Put an object
292
+ *
293
+ * @param mixed $input Input data
294
+ * @param string $bucket Bucket name
295
+ * @param string $uri Object URI
296
+ * @param constant $acl ACL constant
297
+ * @param array $metaHeaders Array of x-amz-meta-* headers
298
+ * @param array $requestHeaders Array of request headers or content type as a string
299
+ * @return boolean
300
+ */
301
+ public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
302
+ if ($input === false) return false;
303
+ $rest = new S3Request('PUT', $bucket, $uri);
304
+
305
+ if (is_string($input)) $input = array(
306
+ 'data' => $input, 'size' => strlen($input),
307
+ 'md5sum' => base64_encode(md5($input, true))
308
+ );
309
+
310
+ // Data
311
+ if (isset($input['fp']))
312
+ $rest->fp =& $input['fp'];
313
+ elseif (isset($input['file']))
314
+ $rest->fp = @fopen($input['file'], 'rb');
315
+ elseif (isset($input['data']))
316
+ $rest->data = $input['data'];
317
+
318
+ // Content-Length (required)
319
+ if (isset($input['size']) && $input['size'] >= 0)
320
+ $rest->size = $input['size'];
321
+ else {
322
+ if (isset($input['file']))
323
+ $rest->size = filesize($input['file']);
324
+ elseif (isset($input['data']))
325
+ $rest->size = strlen($input['data']);
326
+ }
327
+
328
+ // Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
329
+ if (is_array($requestHeaders))
330
+ foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
331
+ elseif (is_string($requestHeaders)) // Support for legacy contentType parameter
332
+ $input['type'] = $requestHeaders;
333
+
334
+ // Content-Type
335
+ if (!isset($input['type'])) {
336
+ if (isset($requestHeaders['Content-Type']))
337
+ $input['type'] =& $requestHeaders['Content-Type'];
338
+ elseif (isset($input['file']))
339
+ $input['type'] = self::__getMimeType($input['file']);
340
+ else
341
+ $input['type'] = 'application/octet-stream';
342
+ }
343
+
344
+ // We need to post with Content-Length and Content-Type, MD5 is optional
345
+ if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false)) {
346
+ $rest->setHeader('Content-Type', $input['type']);
347
+ if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']);
348
+
349
+ $rest->setAmzHeader('x-amz-acl', $acl);
350
+ foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
351
+ $rest->getResponse();
352
+ } else
353
+ $rest->response->error = array('code' => 0, 'message' => 'Missing input parameters');
354
+
355
+ if ($rest->response->error === false && $rest->response->code !== 200)
356
+ $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
357
+ if ($rest->response->error !== false) {
358
+ trigger_error(sprintf("S3::putObject(): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
359
+ return false;
360
+ }
361
+ return true;
362
+ }
363
+
364
+
365
+ /**
366
+ * Put an object from a file (legacy function)
367
+ *
368
+ * @param string $file Input file path
369
+ * @param string $bucket Bucket name
370
+ * @param string $uri Object URI
371
+ * @param constant $acl ACL constant
372
+ * @param array $metaHeaders Array of x-amz-meta-* headers
373
+ * @param string $contentType Content type
374
+ * @return boolean
375
+ */
376
+ public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null) {
377
+ return self::putObject(self::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType);
378
+ }
379
+
380
+
381
+ /**
382
+ * Put an object from a string (legacy function)
383
+ *
384
+ * @param string $string Input data
385
+ * @param string $bucket Bucket name
386
+ * @param string $uri Object URI
387
+ * @param constant $acl ACL constant
388
+ * @param array $metaHeaders Array of x-amz-meta-* headers
389
+ * @param string $contentType Content type
390
+ * @return boolean
391
+ */
392
+ public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain') {
393
+ return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType);
394
+ }
395
+
396
+
397
+ /**
398
+ * Get an object
399
+ *
400
+ * @param string $bucket Bucket name
401
+ * @param string $uri Object URI
402
+ * @param mixed $saveTo Filename or resource to write to
403
+ * @return mixed
404
+ */
405
+ public static function getObject($bucket, $uri, $saveTo = false) {
406
+ $rest = new S3Request('GET', $bucket, $uri);
407
+ if ($saveTo !== false) {
408
+ if (is_resource($saveTo))
409
+ $rest->fp =& $saveTo;
410
+ else
411
+ if (($rest->fp = @fopen($saveTo, 'wb')) !== false)
412
+ $rest->file = realpath($saveTo);
413
+ else
414
+ $rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo);
415
+ }
416
+ if ($rest->response->error === false) $rest->getResponse();
417
+
418
+ if ($rest->response->error === false && $rest->response->code !== 200)
419
+ $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
420
+ if ($rest->response->error !== false) {
421
+ trigger_error(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s",
422
+ $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
423
+ return false;
424
+ }
425
+ return $rest->response;
426
+ }
427
+
428
+
429
+ /**
430
+ * Get object information
431
+ *
432
+ * @param string $bucket Bucket name
433
+ * @param string $uri Object URI
434
+ * @param boolean $returnInfo Return response information
435
+ * @return mixed | false
436
+ */
437
+ public static function getObjectInfo($bucket, $uri, $returnInfo = true) {
438
+ $rest = new S3Request('HEAD', $bucket, $uri);
439
+ $rest = $rest->getResponse();
440
+ if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404))
441
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
442
+ if ($rest->error !== false) {
443
+ trigger_error(sprintf("S3::getObjectInfo({$bucket}, {$uri}): [%s] %s",
444
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
445
+ return false;
446
+ }
447
+ return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false;
448
+ }
449
+
450
+
451
+ /**
452
+ * Copy an object
453
+ *
454
+ * @param string $bucket Source bucket name
455
+ * @param string $uri Source object URI
456
+ * @param string $bucket Destination bucket name
457
+ * @param string $uri Destination object URI
458
+ * @param constant $acl ACL constant
459
+ * @param array $metaHeaders Optional array of x-amz-meta-* headers
460
+ * @param array $requestHeaders Optional array of request headers (content type, disposition, etc.)
461
+ * @return mixed | false
462
+ */
463
+ public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
464
+ $rest = new S3Request('PUT', $bucket, $uri);
465
+ $rest->setHeader('Content-Length', 0);
466
+ foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
467
+ foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
468
+ $rest->setAmzHeader('x-amz-acl', $acl);
469
+ $rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, $srcUri));
470
+ if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0)
471
+ $rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE');
472
+ $rest = $rest->getResponse();
473
+ if ($rest->error === false && $rest->code !== 200)
474
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
475
+ if ($rest->error !== false) {
476
+ trigger_error(sprintf("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s",
477
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
478
+ return false;
479
+ }
480
+ return isset($rest->body->LastModified, $rest->body->ETag) ? array(
481
+ 'time' => strtotime((string)$rest->body->LastModified),
482
+ 'hash' => substr((string)$rest->body->ETag, 1, -1)
483
+ ) : false;
484
+ }
485
+
486
+
487
+ /**
488
+ * Set logging for a bucket
489
+ *
490
+ * @param string $bucket Bucket name
491
+ * @param string $targetBucket Target bucket (where logs are stored)
492
+ * @param string $targetPrefix Log prefix (e,g; domain.com-)
493
+ * @return boolean
494
+ */
495
+ public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = null) {
496
+ // The S3 log delivery group has to be added to the target bucket's ACP
497
+ if ($targetBucket !== null && ($acp = self::getAccessControlPolicy($targetBucket, '')) !== false) {
498
+ // Only add permissions to the target bucket when they do not exist
499
+ $aclWriteSet = false;
500
+ $aclReadSet = false;
501
+ foreach ($acp['acl'] as $acl)
502
+ if ($acl['type'] == 'Group' && $acl['uri'] == 'http://acs.amazonaws.com/groups/s3/LogDelivery') {
503
+ if ($acl['permission'] == 'WRITE') $aclWriteSet = true;
504
+ elseif ($acl['permission'] == 'READ_ACP') $aclReadSet = true;
505
+ }
506
+ if (!$aclWriteSet) $acp['acl'][] = array(
507
+ 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'WRITE'
508
+ );
509
+ if (!$aclReadSet) $acp['acl'][] = array(
510
+ 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'READ_ACP'
511
+ );
512
+ if (!$aclReadSet || !$aclWriteSet) self::setAccessControlPolicy($targetBucket, '', $acp);
513
+ }
514
+
515
+ $dom = new DOMDocument;
516
+ $bucketLoggingStatus = $dom->createElement('BucketLoggingStatus');
517
+ $bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/');
518
+ if ($targetBucket !== null) {
519
+ if ($targetPrefix == null) $targetPrefix = $bucket . '-';
520
+ $loggingEnabled = $dom->createElement('LoggingEnabled');
521
+ $loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket));
522
+ $loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix));
523
+ // TODO: Add TargetGrants?
524
+ $bucketLoggingStatus->appendChild($loggingEnabled);
525
+ }
526
+ $dom->appendChild($bucketLoggingStatus);
527
+
528
+ $rest = new S3Request('PUT', $bucket, '');
529
+ $rest->setParameter('logging', null);
530
+ $rest->data = $dom->saveXML();
531
+ $rest->size = strlen($rest->data);
532
+ $rest->setHeader('Content-Type', 'application/xml');
533
+ $rest = $rest->getResponse();
534
+ if ($rest->error === false && $rest->code !== 200)
535
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
536
+ if ($rest->error !== false) {
537
+ trigger_error(sprintf("S3::setBucketLogging({$bucket}, {$uri}): [%s] %s",
538
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
539
+ return false;
540
+ }
541
+ return true;
542
+ }
543
+
544
+
545
+ /**
546
+ * Get logging status for a bucket
547
+ *
548
+ * This will return false if logging is not enabled.
549
+ * Note: To enable logging, you also need to grant write access to the log group
550
+ *
551
+ * @param string $bucket Bucket name
552
+ * @return array | false
553
+ */
554
+ public static function getBucketLogging($bucket) {
555
+ $rest = new S3Request('GET', $bucket, '');
556
+ $rest->setParameter('logging', null);
557
+ $rest = $rest->getResponse();
558
+ if ($rest->error === false && $rest->code !== 200)
559
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
560
+ if ($rest->error !== false) {
561
+ trigger_error(sprintf("S3::getBucketLogging({$bucket}): [%s] %s",
562
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
563
+ return false;
564
+ }
565
+ if (!isset($rest->body->LoggingEnabled)) return false; // No logging
566
+ return array(
567
+ 'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket,
568
+ 'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix,
569
+ );
570
+ }
571
+
572
+
573
+ /**
574
+ * Disable bucket logging
575
+ *
576
+ * @param string $bucket Bucket name
577
+ * @return boolean
578
+ */
579
+ public static function disableBucketLogging($bucket) {
580
+ return self::setBucketLogging($bucket, null);
581
+ }
582
+
583
+
584
+ /**
585
+ * Get a bucket's location
586
+ *
587
+ * @param string $bucket Bucket name
588
+ * @return string | false
589
+ */
590
+ public static function getBucketLocation($bucket) {
591
+ $rest = new S3Request('GET', $bucket, '');
592
+ $rest->setParameter('location', null);
593
+ $rest = $rest->getResponse();
594
+ if ($rest->error === false && $rest->code !== 200)
595
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
596
+ if ($rest->error !== false) {
597
+ trigger_error(sprintf("S3::getBucketLocation({$bucket}): [%s] %s",
598
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
599
+ return false;
600
+ }
601
+ return (isset($rest->body[0]) && (string)$rest->body[0] !== '') ? (string)$rest->body[0] : 'US';
602
+ }
603
+
604
+
605
+ /**
606
+ * Set object or bucket Access Control Policy
607
+ *
608
+ * @param string $bucket Bucket name
609
+ * @param string $uri Object URI
610
+ * @param array $acp Access Control Policy Data (same as the data returned from getAccessControlPolicy)
611
+ * @return boolean
612
+ */
613
+ public static function setAccessControlPolicy($bucket, $uri = '', $acp = array()) {
614
+ $dom = new DOMDocument;
615
+ $dom->formatOutput = true;
616
+ $accessControlPolicy = $dom->createElement('AccessControlPolicy');
617
+ $accessControlList = $dom->createElement('AccessControlList');
618
+
619
+ // It seems the owner has to be passed along too
620
+ $owner = $dom->createElement('Owner');
621
+ $owner->appendChild($dom->createElement('ID', $acp['owner']['id']));
622
+ $owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name']));
623
+ $accessControlPolicy->appendChild($owner);
624
+
625
+ foreach ($acp['acl'] as $g) {
626
+ $grant = $dom->createElement('Grant');
627
+ $grantee = $dom->createElement('Grantee');
628
+ $grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
629
+ if (isset($g['id'])) { // CanonicalUser (DisplayName is omitted)
630
+ $grantee->setAttribute('xsi:type', 'CanonicalUser');
631
+ $grantee->appendChild($dom->createElement('ID', $g['id']));
632
+ } elseif (isset($g['email'])) { // AmazonCustomerByEmail
633
+ $grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail');
634
+ $grantee->appendChild($dom->createElement('EmailAddress', $g['email']));
635
+ } elseif ($g['type'] == 'Group') { // Group
636
+ $grantee->setAttribute('xsi:type', 'Group');
637
+ $grantee->appendChild($dom->createElement('URI', $g['uri']));
638
+ }
639
+ $grant->appendChild($grantee);
640
+ $grant->appendChild($dom->createElement('Permission', $g['permission']));
641
+ $accessControlList->appendChild($grant);
642
+ }
643
+
644
+ $accessControlPolicy->appendChild($accessControlList);
645
+ $dom->appendChild($accessControlPolicy);
646
+
647
+ $rest = new S3Request('PUT', $bucket, $uri);
648
+ $rest->setParameter('acl', null);
649
+ $rest->data = $dom->saveXML();
650
+ $rest->size = strlen($rest->data);
651
+ $rest->setHeader('Content-Type', 'application/xml');
652
+ $rest = $rest->getResponse();
653
+ if ($rest->error === false && $rest->code !== 200)
654
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
655
+ if ($rest->error !== false) {
656
+ trigger_error(sprintf("S3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
657
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
658
+ return false;
659
+ }
660
+ return true;
661
+ }
662
+
663
+
664
+ /**
665
+ * Get object or bucket Access Control Policy
666
+ *
667
+ * @param string $bucket Bucket name
668
+ * @param string $uri Object URI
669
+ * @return mixed | false
670
+ */
671
+ public static function getAccessControlPolicy($bucket, $uri = '') {
672
+ $rest = new S3Request('GET', $bucket, $uri);
673
+ $rest->setParameter('acl', null);
674
+ $rest = $rest->getResponse();
675
+ if ($rest->error === false && $rest->code !== 200)
676
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
677
+ if ($rest->error !== false) {
678
+ trigger_error(sprintf("S3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
679
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
680
+ return false;
681
+ }
682
+
683
+ $acp = array();
684
+ if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) {
685
+ $acp['owner'] = array(
686
+ 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName
687
+ );
688
+ }
689
+ if (isset($rest->body->AccessControlList)) {
690
+ $acp['acl'] = array();
691
+ foreach ($rest->body->AccessControlList->Grant as $grant) {
692
+ foreach ($grant->Grantee as $grantee) {
693
+ if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser
694
+ $acp['acl'][] = array(
695
+ 'type' => 'CanonicalUser',
696
+ 'id' => (string)$grantee->ID,
697
+ 'name' => (string)$grantee->DisplayName,
698
+ 'permission' => (string)$grant->Permission
699
+ );
700
+ elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail
701
+ $acp['acl'][] = array(
702
+ 'type' => 'AmazonCustomerByEmail',
703
+ 'email' => (string)$grantee->EmailAddress,
704
+ 'permission' => (string)$grant->Permission
705
+ );
706
+ elseif (isset($grantee->URI)) // Group
707
+ $acp['acl'][] = array(
708
+ 'type' => 'Group',
709
+ 'uri' => (string)$grantee->URI,
710
+ 'permission' => (string)$grant->Permission
711
+ );
712
+ else continue;
713
+ }
714
+ }
715
+ }
716
+ return $acp;
717
+ }
718
+
719
+
720
+ /**
721
+ * Delete an object
722
+ *
723
+ * @param string $bucket Bucket name
724
+ * @param string $uri Object URI
725
+ * @return boolean
726
+ */
727
+ public static function deleteObject($bucket, $uri) {
728
+ $rest = new S3Request('DELETE', $bucket, $uri);
729
+ $rest = $rest->getResponse();
730
+ if ($rest->error === false && $rest->code !== 204)
731
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
732
+ if ($rest->error !== false) {
733
+ trigger_error(sprintf("S3::deleteObject(): [%s] %s",
734
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
735
+ return false;
736
+ }
737
+ return true;
738
+ }
739
+
740
+
741
+ /**
742
+ * Get a query string authenticated URL
743
+ *
744
+ * @param string $bucket Bucket name
745
+ * @param string $uri Object URI
746
+ * @param integer $lifetime Lifetime in seconds
747
+ * @param boolean $hostBucket Use the bucket name as the hostname
748
+ * @param boolean $https Use HTTPS ($hostBucket should be false for SSL verification)
749
+ * @return string
750
+ */
751
+ public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false) {
752
+ $expires = time() + $lifetime;
753
+ $uri = str_replace('%2F', '/', rawurlencode($uri)); // URI should be encoded (thanks Sean O'Dea)
754
+ return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s',
755
+ $hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires,
756
+ urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}")));
757
+ }
758
+
759
+ /**
760
+ * Get upload POST parameters for form uploads
761
+ *
762
+ * @param string $bucket Bucket name
763
+ * @param string $uriPrefix Object URI prefix
764
+ * @param constant $acl ACL constant
765
+ * @param integer $lifetime Lifetime in seconds
766
+ * @param integer $maxFileSize Maximum filesize in bytes (default 5MB)
767
+ * @param string $successRedirect Redirect URL or 200 / 201 status code
768
+ * @param array $amzHeaders Array of x-amz-meta-* headers
769
+ * @param array $headers Array of request headers or content type as a string
770
+ * @param boolean $flashVars Includes additional "Filename" variable posted by Flash
771
+ * @return object
772
+ */
773
+ public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600, $maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false) {
774
+ // Create policy object
775
+ $policy = new stdClass;
776
+ $policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime));
777
+ $policy->conditions = array();
778
+ $obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj);
779
+ $obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj);
780
+
781
+ $obj = new stdClass; // 200 for non-redirect uploads
782
+ if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
783
+ $obj->success_action_status = (string)$successRedirect;
784
+ else // URL
785
+ $obj->success_action_redirect = $successRedirect;
786
+ array_push($policy->conditions, $obj);
787
+
788
+ array_push($policy->conditions, array('starts-with', '$key', $uriPrefix));
789
+ if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', ''));
790
+ foreach (array_keys($headers) as $headerKey)
791
+ array_push($policy->conditions, array('starts-with', '$'.$headerKey, ''));
792
+ foreach ($amzHeaders as $headerKey => $headerVal) {
793
+ $obj = new stdClass; $obj->{$headerKey} = (string)$headerVal; array_push($policy->conditions, $obj);
794
+ }
795
+ array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
796
+ $policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
797
+
798
+ // Create parameters
799
+ $params = new stdClass;
800
+ $params->AWSAccessKeyId = self::$__accessKey;
801
+ $params->key = $uriPrefix.'${filename}';
802
+ $params->acl = $acl;
803
+ $params->policy = $policy; unset($policy);
804
+ $params->signature = self::__getHash($params->policy);
805
+ if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
806
+ $params->success_action_status = (string)$successRedirect;
807
+ else
808
+ $params->success_action_redirect = $successRedirect;
809
+ foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
810
+ foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
811
+ return $params;
812
+ }
813
+
814
+ /**
815
+ * Create a CloudFront distribution
816
+ *
817
+ * @param string $bucket Bucket name
818
+ * @param boolean $enabled Enabled (true/false)
819
+ * @param array $cnames Array containing CNAME aliases
820
+ * @param string $comment Use the bucket name as the hostname
821
+ * @return array | false
822
+ */
823
+ public static function createDistribution($bucket, $enabled = true, $cnames = array(), $comment = '') {
824
+ self::$useSSL = true; // CloudFront requires SSL
825
+ $rest = new S3Request('POST', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
826
+ $rest->data = self::__getCloudFrontDistributionConfigXML($bucket.'.s3.amazonaws.com', $enabled, $comment, (string)microtime(true), $cnames);
827
+ $rest->size = strlen($rest->data);
828
+ $rest->setHeader('Content-Type', 'application/xml');
829
+ $rest = self::__getCloudFrontResponse($rest);
830
+
831
+ if ($rest->error === false && $rest->code !== 201)
832
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
833
+ if ($rest->error !== false) {
834
+ trigger_error(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", '$comment'): [%s] %s",
835
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
836
+ return false;
837
+ } elseif ($rest->body instanceof SimpleXMLElement)
838
+ return self::__parseCloudFrontDistributionConfig($rest->body);
839
+ return false;
840
+ }
841
+
842
+
843
+ /**
844
+ * Get CloudFront distribution info
845
+ *
846
+ * @param string $distributionId Distribution ID from listDistributions()
847
+ * @return array | false
848
+ */
849
+ public static function getDistribution($distributionId) {
850
+ self::$useSSL = true; // CloudFront requires SSL
851
+ $rest = new S3Request('GET', '', '2008-06-30/distribution/'.$distributionId, 'cloudfront.amazonaws.com');
852
+ $rest = self::__getCloudFrontResponse($rest);
853
+
854
+ if ($rest->error === false && $rest->code !== 200)
855
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
856
+ if ($rest->error !== false) {
857
+ trigger_error(sprintf("S3::getDistribution($distributionId): [%s] %s",
858
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
859
+ return false;
860
+ } elseif ($rest->body instanceof SimpleXMLElement) {
861
+ $dist = self::__parseCloudFrontDistributionConfig($rest->body);
862
+ $dist['hash'] = $rest->headers['hash'];
863
+ return $dist;
864
+ }
865
+ return false;
866
+ }
867
+
868
+
869
+ /**
870
+ * Update a CloudFront distribution
871
+ *
872
+ * @param array $dist Distribution array info identical to output of getDistribution()
873
+ * @return array | false
874
+ */
875
+ public static function updateDistribution($dist) {
876
+ self::$useSSL = true; // CloudFront requires SSL
877
+ $rest = new S3Request('PUT', '', '2008-06-30/distribution/'.$dist['id'].'/config', 'cloudfront.amazonaws.com');
878
+ $rest->data = self::__getCloudFrontDistributionConfigXML($dist['origin'], $dist['enabled'], $dist['comment'], $dist['callerReference'], $dist['cnames']);
879
+ $rest->size = strlen($rest->data);
880
+ $rest->setHeader('If-Match', $dist['hash']);
881
+ $rest = self::__getCloudFrontResponse($rest);
882
+
883
+ if ($rest->error === false && $rest->code !== 200)
884
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
885
+ if ($rest->error !== false) {
886
+ trigger_error(sprintf("S3::updateDistribution({$dist['id']}, ".(int)$enabled.", '$comment'): [%s] %s",
887
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
888
+ return false;
889
+ } else {
890
+ $dist = self::__parseCloudFrontDistributionConfig($rest->body);
891
+ $dist['hash'] = $rest->headers['hash'];
892
+ return $dist;
893
+ }
894
+ return false;
895
+ }
896
+
897
+
898
+ /**
899
+ * Delete a CloudFront distribution
900
+ *
901
+ * @param array $dist Distribution array info identical to output of getDistribution()
902
+ * @return boolean
903
+ */
904
+ public static function deleteDistribution($dist) {
905
+ self::$useSSL = true; // CloudFront requires SSL
906
+ $rest = new S3Request('DELETE', '', '2008-06-30/distribution/'.$dist['id'], 'cloudfront.amazonaws.com');
907
+ $rest->setHeader('If-Match', $dist['hash']);
908
+ $rest = self::__getCloudFrontResponse($rest);
909
+
910
+ if ($rest->error === false && $rest->code !== 204)
911
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
912
+ if ($rest->error !== false) {
913
+ trigger_error(sprintf("S3::deleteDistribution({$dist['id']}): [%s] %s",
914
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
915
+ return false;
916
+ }
917
+ return true;
918
+ }
919
+
920
+
921
+ /**
922
+ * Get a list of CloudFront distributions
923
+ *
924
+ * @return array
925
+ */
926
+ public static function listDistributions() {
927
+ self::$useSSL = true; // CloudFront requires SSL
928
+ $rest = new S3Request('GET', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
929
+ $rest = self::__getCloudFrontResponse($rest);
930
+
931
+ if ($rest->error === false && $rest->code !== 200)
932
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
933
+ if ($rest->error !== false) {
934
+ trigger_error(sprintf("S3::listDistributions(): [%s] %s",
935
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
936
+ return false;
937
+ } elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary)) {
938
+ $list = array();
939
+ if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated)) {
940
+ //$info['marker'] = (string)$rest->body->Marker;
941
+ //$info['maxItems'] = (int)$rest->body->MaxItems;
942
+ //$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false;
943
+ }
944
+ foreach ($rest->body->DistributionSummary as $summary) {
945
+ $list[(string)$summary->Id] = self::__parseCloudFrontDistributionConfig($summary);
946
+ }
947
+ return $list;
948
+ }
949
+ return array();
950
+ }
951
+
952
+
953
+ /**
954
+ * Get a DistributionConfig DOMDocument
955
+ *
956
+ * @internal Used to create XML in createDistribution() and updateDistribution()
957
+ * @param string $bucket Origin bucket
958
+ * @param boolean $enabled Enabled (true/false)
959
+ * @param string $comment Comment to append
960
+ * @param string $callerReference Caller reference
961
+ * @param array $cnames Array of CNAME aliases
962
+ * @return string
963
+ */
964
+ private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, $comment, $callerReference = '0', $cnames = array()) {
965
+ $dom = new DOMDocument('1.0', 'UTF-8');
966
+ $dom->formatOutput = true;
967
+ $distributionConfig = $dom->createElement('DistributionConfig');
968
+ $distributionConfig->setAttribute('xmlns', 'http://cloudfront.amazonaws.com/doc/2008-06-30/');
969
+ $distributionConfig->appendChild($dom->createElement('Origin', $bucket));
970
+ $distributionConfig->appendChild($dom->createElement('CallerReference', $callerReference));
971
+ foreach ($cnames as $cname)
972
+ $distributionConfig->appendChild($dom->createElement('CNAME', $cname));
973
+ if ($comment !== '') $distributionConfig->appendChild($dom->createElement('Comment', $comment));
974
+ $distributionConfig->appendChild($dom->createElement('Enabled', $enabled ? 'true' : 'false'));
975
+ $dom->appendChild($distributionConfig);
976
+ return $dom->saveXML();
977
+ }
978
+
979
+
980
+ /**
981
+ * Parse a CloudFront distribution config
982
+ *
983
+ * @internal Used to parse the CloudFront DistributionConfig node to an array
984
+ * @param object &$node DOMNode
985
+ * @return array
986
+ */
987
+ private static function __parseCloudFrontDistributionConfig(&$node) {
988
+ $dist = array();
989
+ if (isset($node->Id, $node->Status, $node->LastModifiedTime, $node->DomainName)) {
990
+ $dist['id'] = (string)$node->Id;
991
+ $dist['status'] = (string)$node->Status;
992
+ $dist['time'] = strtotime((string)$node->LastModifiedTime);
993
+ $dist['domain'] = (string)$node->DomainName;
994
+ }
995
+ if (isset($node->CallerReference))
996
+ $dist['callerReference'] = (string)$node->CallerReference;
997
+ if (isset($node->Comment))
998
+ $dist['comment'] = (string)$node->Comment;
999
+ if (isset($node->Enabled, $node->Origin)) {
1000
+ $dist['origin'] = (string)$node->Origin;
1001
+ $dist['enabled'] = (string)$node->Enabled == 'true' ? true : false;
1002
+ } elseif (isset($node->DistributionConfig)) {
1003
+ $dist = array_merge($dist, self::__parseCloudFrontDistributionConfig($node->DistributionConfig));
1004
+ }
1005
+ if (isset($node->CNAME)) {
1006
+ $dist['cnames'] = array();
1007
+ foreach ($node->CNAME as $cname) $dist['cnames'][(string)$cname] = (string)$cname;
1008
+ }
1009
+ return $dist;
1010
+ }
1011
+
1012
+
1013
+ /**
1014
+ * Grab CloudFront response
1015
+ *
1016
+ * @internal Used to parse the CloudFront S3Request::getResponse() output
1017
+ * @param object &$rest S3Request instance
1018
+ * @return object
1019
+ */
1020
+ private static function __getCloudFrontResponse(&$rest) {
1021
+ $rest->getResponse();
1022
+ if ($rest->response->error === false && isset($rest->response->body) &&
1023
+ is_string($rest->response->body) && substr($rest->response->body, 0, 5) == '<?xml') {
1024
+ $rest->response->body = simplexml_load_string($rest->response->body);
1025
+ // Grab CloudFront errors
1026
+ if (isset($rest->response->body->Error, $rest->response->body->Error->Code,
1027
+ $rest->response->body->Error->Message)) {
1028
+ $rest->response->error = array(
1029
+ 'code' => (string)$rest->response->body->Error->Code,
1030
+ 'message' => (string)$rest->response->body->Error->Message
1031
+ );
1032
+ unset($rest->response->body);
1033
+ }
1034
+ }
1035
+ return $rest->response;
1036
+ }
1037
+
1038
+
1039
+ /**
1040
+ * Get MIME type for file
1041
+ *
1042
+ * @internal Used to get mime types
1043
+ * @param string &$file File path
1044
+ * @return string
1045
+ */
1046
+ public static function __getMimeType(&$file) {
1047
+ $type = w3_get_mime_type($file);
1048
+
1049
+ if (! $type && function_exists('mime_content_type')) {
1050
+ $type = trim(mime_content_type($file));
1051
+ }
1052
+
1053
+ return (! empty($type) ? $type : 'application/octet-stream');
1054
+ }
1055
+
1056
+
1057
+ /**
1058
+ * Generate the auth string: "AWS AccessKey:Signature"
1059
+ *
1060
+ * @internal Used by S3Request::getResponse()
1061
+ * @param string $string String to sign
1062
+ * @return string
1063
+ */
1064
+ public static function __getSignature($string) {
1065
+ return 'AWS '.self::$__accessKey.':'.self::__getHash($string);
1066
+ }
1067
+
1068
+
1069
+ /**
1070
+ * Creates a HMAC-SHA1 hash
1071
+ *
1072
+ * This uses the hash extension if loaded
1073
+ *
1074
+ * @internal Used by __getSignature()
1075
+ * @param string $string String to sign
1076
+ * @return string
1077
+ */
1078
+ private static function __getHash($string) {
1079
+ return base64_encode(extension_loaded('hash') ?
1080
+ hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1(
1081
+ (str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
1082
+ pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^
1083
+ (str_repeat(chr(0x36), 64))) . $string)))));
1084
+ }
1085
+
1086
+ }
1087
+
1088
+ final class S3Request {
1089
+ private $verb, $bucket, $uri, $resource = '', $parameters = array(),
1090
+ $amzHeaders = array(), $headers = array(
1091
+ 'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => ''
1092
+ );
1093
+ public $fp = false, $size = 0, $data = false, $response;
1094
+
1095
+
1096
+ /**
1097
+ * Constructor
1098
+ *
1099
+ * @param string $verb Verb
1100
+ * @param string $bucket Bucket name
1101
+ * @param string $uri Object URI
1102
+ * @return mixed
1103
+ */
1104
+ function __construct($verb, $bucket = '', $uri = '', $defaultHost = 's3.amazonaws.com') {
1105
+ $this->verb = $verb;
1106
+ $this->bucket = strtolower($bucket);
1107
+ $this->uri = $uri !== '' ? '/'.str_replace('%2F', '/', rawurlencode($uri)) : '/';
1108
+
1109
+ if ($this->bucket !== '') {
1110
+ $this->headers['Host'] = $this->bucket.'.'.$defaultHost;
1111
+ $this->resource = '/'.$this->bucket.$this->uri;
1112
+ } else {
1113
+ $this->headers['Host'] = $defaultHost;
1114
+ //$this->resource = strlen($this->uri) > 1 ? '/'.$this->bucket.$this->uri : $this->uri;
1115
+ $this->resource = $this->uri;
1116
+ }
1117
+ $this->headers['Date'] = gmdate('D, d M Y H:i:s T');
1118
+
1119
+ $this->response = new STDClass;
1120
+ $this->response->error = false;
1121
+ }
1122
+
1123
+
1124
+ /**
1125
+ * Set request parameter
1126
+ *
1127
+ * @param string $key Key
1128
+ * @param string $value Value
1129
+ * @return void
1130
+ */
1131
+ public function setParameter($key, $value) {
1132
+ $this->parameters[$key] = $value;
1133
+ }
1134
+
1135
+
1136
+ /**
1137
+ * Set request header
1138
+ *
1139
+ * @param string $key Key
1140
+ * @param string $value Value
1141
+ * @return void
1142
+ */
1143
+ public function setHeader($key, $value) {
1144
+ $this->headers[$key] = $value;
1145
+ }
1146
+
1147
+
1148
+ /**
1149
+ * Set x-amz-meta-* header
1150
+ *
1151
+ * @param string $key Key
1152
+ * @param string $value Value
1153
+ * @return void
1154
+ */
1155
+ public function setAmzHeader($key, $value) {
1156
+ $this->amzHeaders[$key] = $value;
1157
+ }
1158
+
1159
+
1160
+ /**
1161
+ * Get the S3 response
1162
+ *
1163
+ * @return object | false
1164
+ */
1165
+ public function getResponse() {
1166
+ $query = '';
1167
+ if (sizeof($this->parameters) > 0) {
1168
+ $query = substr($this->uri, -1) !== '?' ? '?' : '&';
1169
+ foreach ($this->parameters as $var => $value)
1170
+ if ($value == null || $value == '') $query .= $var.'&';
1171
+ // Parameters should be encoded (thanks Sean O'Dea)
1172
+ else $query .= $var.'='.rawurlencode($value).'&';
1173
+ $query = substr($query, 0, -1);
1174
+ $this->uri .= $query;
1175
+
1176
+ if (array_key_exists('acl', $this->parameters) ||
1177
+ array_key_exists('location', $this->parameters) ||
1178
+ array_key_exists('torrent', $this->parameters) ||
1179
+ array_key_exists('logging', $this->parameters))
1180
+ $this->resource .= $query;
1181
+ }
1182
+ $url = ((S3::$useSSL && extension_loaded('openssl')) ?
1183
+ 'https://':'http://').$this->headers['Host'].$this->uri;
1184
+ //var_dump($this->bucket, $this->uri, $this->resource, $url);
1185
+
1186
+ // Basic setup
1187
+ $curl = curl_init();
1188
+ curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
1189
+
1190
+ if (S3::$useSSL) {
1191
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
1192
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
1193
+ }
1194
+
1195
+ curl_setopt($curl, CURLOPT_URL, $url);
1196
+
1197
+ // Headers
1198
+ $headers = array(); $amz = array();
1199
+ foreach ($this->amzHeaders as $header => $value)
1200
+ if (strlen($value) > 0) $headers[] = $header.': '.$value;
1201
+ foreach ($this->headers as $header => $value)
1202
+ if (strlen($value) > 0) $headers[] = $header.': '.$value;
1203
+
1204
+ // Collect AMZ headers for signature
1205
+ foreach ($this->amzHeaders as $header => $value)
1206
+ if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value;
1207
+
1208
+ // AMZ headers must be sorted
1209
+ if (sizeof($amz) > 0) {
1210
+ sort($amz);
1211
+ $amz = "\n".implode("\n", $amz);
1212
+ } else $amz = '';
1213
+
1214
+ // Authorization string (CloudFront stringToSign should only contain a date)
1215
+ $headers[] = 'Authorization: ' . S3::__getSignature(
1216
+ $this->headers['Host'] == 'cloudfront.amazonaws.com' ? $this->headers['Date'] :
1217
+ $this->verb."\n".$this->headers['Content-MD5']."\n".
1218
+ $this->headers['Content-Type']."\n".$this->headers['Date'].$amz."\n".$this->resource
1219
+ );
1220
+
1221
+ curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
1222
+ curl_setopt($curl, CURLOPT_HEADER, false);
1223
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
1224
+ curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
1225
+ curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
1226
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
1227
+
1228
+ // Request types
1229
+ switch ($this->verb) {
1230
+ case 'GET': break;
1231
+ case 'PUT': case 'POST': // POST only used for CloudFront
1232
+ if ($this->fp !== false) {
1233
+ curl_setopt($curl, CURLOPT_PUT, true);
1234
+ curl_setopt($curl, CURLOPT_INFILE, $this->fp);
1235
+ if ($this->size >= 0)
1236
+ curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
1237
+ } elseif ($this->data !== false) {
1238
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1239
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
1240
+ if ($this->size >= 0)
1241
+ curl_setopt($curl, CURLOPT_BUFFERSIZE, $this->size);
1242
+ } else
1243
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1244
+ break;
1245
+ case 'HEAD':
1246
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
1247
+ curl_setopt($curl, CURLOPT_NOBODY, true);
1248
+ break;
1249
+ case 'DELETE':
1250
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
1251
+ break;
1252
+ default: break;
1253
+ }
1254
+
1255
+ // Execute, grab errors
1256
+ if (curl_exec($curl))
1257
+ $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
1258
+ else
1259
+ $this->response->error = array(
1260
+ 'code' => curl_errno($curl),
1261
+ 'message' => curl_error($curl),
1262
+ 'resource' => $this->resource
1263
+ );
1264
+
1265
+ @curl_close($curl);
1266
+
1267
+ // Parse body into XML
1268
+ if ($this->response->error === false && isset($this->response->headers['type']) &&
1269
+ $this->response->headers['type'] == 'application/xml' && isset($this->response->body)) {
1270
+ $this->response->body = simplexml_load_string($this->response->body);
1271
+
1272
+ // Grab S3 errors
1273
+ if (!in_array($this->response->code, array(200, 204)) &&
1274
+ isset($this->response->body->Code, $this->response->body->Message)) {
1275
+ $this->response->error = array(
1276
+ 'code' => (string)$this->response->body->Code,
1277
+ 'message' => (string)$this->response->body->Message
1278
+ );
1279
+ if (isset($this->response->body->Resource))
1280
+ $this->response->error['resource'] = (string)$this->response->body->Resource;
1281
+ unset($this->response->body);
1282
+ }
1283
+ }
1284
+
1285
+ // Clean up file resources
1286
+ if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp);
1287
+
1288
+ return $this->response;
1289
+ }
1290
+
1291
+
1292
+ /**
1293
+ * CURL write callback
1294
+ *
1295
+ * @param resource &$curl CURL resource
1296
+ * @param string &$data Data
1297
+ * @return integer
1298
+ */
1299
+ private function __responseWriteCallback(&$curl, &$data) {
1300
+ if ($this->response->code == 200 && $this->fp !== false)
1301
+ return fwrite($this->fp, $data);
1302
+ else
1303
+ $this->response->body .= $data;
1304
+ return strlen($data);
1305
+ }
1306
+
1307
+
1308
+ /**
1309
+ * CURL header callback
1310
+ *
1311
+ * @param resource &$curl CURL resource
1312
+ * @param string &$data Data
1313
+ * @return integer
1314
+ */
1315
+ private function __responseHeaderCallback(&$curl, &$data) {
1316
+ if (($strlen = strlen($data)) <= 2) return $strlen;
1317
+ if (substr($data, 0, 4) == 'HTTP')
1318
+ $this->response->code = (int)substr($data, 9, 3);
1319
+ else {
1320
+ list($header, $value) = explode(': ', trim($data), 2);
1321
+ if ($header == 'Last-Modified')
1322
+ $this->response->headers['time'] = strtotime($value);
1323
+ elseif ($header == 'Content-Length')
1324
+ $this->response->headers['size'] = (int)$value;
1325
+ elseif ($header == 'Content-Type')
1326
+ $this->response->headers['type'] = $value;
1327
+ elseif ($header == 'ETag')
1328
+ $this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
1329
+ elseif (preg_match('/^x-amz-meta-.*$/', $header))
1330
+ $this->response->headers[$header] = is_numeric($value) ? (int)$value : $value;
1331
+ }
1332
+ return $strlen;
1333
+ }
1334
+
1335
+ }
lib/W3/Cache.php CHANGED
@@ -19,6 +19,10 @@ if (! defined('W3_CACHE_FILE')) {
19
  define('W3_CACHE_FILE', 'file');
20
  }
21
 
 
 
 
 
22
  /**
23
  * Class W3_Cache
24
  */
@@ -41,7 +45,7 @@ class W3_Cache
41
  switch ($engine) {
42
  case W3_CACHE_MEMCACHED:
43
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
44
- $instances[$instance_key] = W3_Cache_Memcached::instance($config['engine'], $config);
45
  break;
46
 
47
  case W3_CACHE_APC:
@@ -54,6 +58,11 @@ class W3_Cache
54
  $instances[$instance_key] = & new W3_Cache_File($config);
55
  break;
56
 
 
 
 
 
 
57
  default:
58
  trigger_error('Incorrect cache engine', E_USER_WARNING);
59
  require_once W3TC_LIB_W3_DIR . '/Cache/Base.php';
19
  define('W3_CACHE_FILE', 'file');
20
  }
21
 
22
+ if (! defined('W3_CACHE_FILE_PGCACHE')) {
23
+ define('W3_CACHE_FILE_PGCACHE', 'file_pgcache');
24
+ }
25
+
26
  /**
27
  * Class W3_Cache
28
  */
45
  switch ($engine) {
46
  case W3_CACHE_MEMCACHED:
47
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
48
+ $instances[$instance_key] = & W3_Cache_Memcached::instance($config['engine'], $config);
49
  break;
50
 
51
  case W3_CACHE_APC:
58
  $instances[$instance_key] = & new W3_Cache_File($config);
59
  break;
60
 
61
+ case W3_CACHE_FILE_PGCACHE:
62
+ require_once W3TC_LIB_W3_DIR . '/Cache/File/PgCache.php';
63
+ $instances[$instance_key] = & new W3_Cache_File_PgCache($config);
64
+ break;
65
+
66
  default:
67
  trigger_error('Incorrect cache engine', E_USER_WARNING);
68
  require_once W3TC_LIB_W3_DIR . '/Cache/Base.php';
lib/W3/Cache/Base.php CHANGED
@@ -12,7 +12,7 @@ class W3_Cache_Base
12
  /**
13
  * Adds data
14
  *
15
- * @abstract
16
  * @param string $key
17
  * @param mixed $data
18
  * @param integer $expire
@@ -22,11 +22,11 @@ class W3_Cache_Base
22
  {
23
  return false;
24
  }
25
-
26
  /**
27
  * Sets data
28
  *
29
- * @abstract
30
  * @param string $key
31
  * @param mixed $data
32
  * @param integer $expire
@@ -36,11 +36,11 @@ class W3_Cache_Base
36
  {
37
  return false;
38
  }
39
-
40
  /**
41
  * Returns data
42
  *
43
- * @abstract
44
  * @param string $key
45
  * @return mixed
46
  */
@@ -59,11 +59,11 @@ class W3_Cache_Base
59
  {
60
  return $this->get($key);
61
  }
62
-
63
  /**
64
  * Replaces data
65
  *
66
- * @abstract
67
  * @param string $key
68
  * @param mixed $data
69
  * @param integer $expire
@@ -73,11 +73,11 @@ class W3_Cache_Base
73
  {
74
  return false;
75
  }
76
-
77
  /**
78
  * Deletes data
79
  *
80
- * @abstract
81
  * @param string $key
82
  * @return boolean
83
  */
@@ -85,11 +85,11 @@ class W3_Cache_Base
85
  {
86
  return false;
87
  }
88
-
89
  /**
90
  * Flushes all data
91
  *
92
- * @abstract
93
  * @return boolean
94
  */
95
  function flush()
12
  /**
13
  * Adds data
14
  *
15
+ * @abstract
16
  * @param string $key
17
  * @param mixed $data
18
  * @param integer $expire
22
  {
23
  return false;
24
  }
25
+
26
  /**
27
  * Sets data
28
  *
29
+ * @abstract
30
  * @param string $key
31
  * @param mixed $data
32
  * @param integer $expire
36
  {
37
  return false;
38
  }
39
+
40
  /**
41
  * Returns data
42
  *
43
+ * @abstract
44
  * @param string $key
45
  * @return mixed
46
  */
59
  {
60
  return $this->get($key);
61
  }
62
+
63
  /**
64
  * Replaces data
65
  *
66
+ * @abstract
67
  * @param string $key
68
  * @param mixed $data
69
  * @param integer $expire
73
  {
74
  return false;
75
  }
76
+
77
  /**
78
  * Deletes data
79
  *
80
+ * @abstract
81
  * @param string $key
82
  * @return boolean
83
  */
85
  {
86
  return false;
87
  }
88
+
89
  /**
90
  * Flushes all data
91
  *
92
+ * @abstract
93
  * @return boolean
94
  */
95
  function flush()
lib/W3/Cache/File.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
 
3
  if (! defined('W3_CACHE_FILE_EXPIRE_MAX')) {
4
- define('W3_CACHE_FILE_EXPIRE_MAX', 864000);
5
  }
6
 
7
  /**
8
- * APC class
9
  */
10
  require_once W3TC_LIB_W3_DIR . '/Cache/Base.php';
11
 
@@ -69,9 +69,13 @@ class W3_Cache_File extends W3_Cache_Base
69
  */
70
  function set($key, $var, $expire = 0)
71
  {
72
- $path = $this->_get_path($key);
73
- $dir = dirname(str_replace($this->_cache_dir, '', $path));
74
- if ((is_dir($dir) || w3_mkdir($dir, 0755, $this->_cache_dir))) {
 
 
 
 
75
  $fp = @fopen($path, 'wb');
76
  if ($fp) {
77
  @fputs($fp, pack('L', $expire));
@@ -80,6 +84,7 @@ class W3_Cache_File extends W3_Cache_Base
80
  return true;
81
  }
82
  }
 
83
  return false;
84
  }
85
 
@@ -91,9 +96,9 @@ class W3_Cache_File extends W3_Cache_Base
91
  */
92
  function get($key)
93
  {
94
- $pwd = getcwd();
95
  $var = false;
96
- $path = $this->_get_path($key);
 
97
  if (is_readable($path)) {
98
  $ftime = @filemtime($path);
99
  if ($ftime) {
@@ -144,10 +149,12 @@ class W3_Cache_File extends W3_Cache_Base
144
  */
145
  function delete($key)
146
  {
147
- $path = $this->_get_path($key);
 
148
  if (file_exists($path)) {
149
  return @unlink($path);
150
  }
 
151
  return false;
152
  }
153
 
@@ -158,7 +165,25 @@ class W3_Cache_File extends W3_Cache_Base
158
  */
159
  function flush()
160
  {
161
- return w3_emptydir($this->_cache_dir);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  }
163
 
164
  /**
@@ -170,7 +195,7 @@ class W3_Cache_File extends W3_Cache_Base
170
  function _get_path($key)
171
  {
172
  $hash = md5($key);
173
- $path = sprintf('%s/%s/%s/%s', $this->_cache_dir, substr($hash, 0, 2), substr($hash, 2, 2), $hash);
174
 
175
  return $path;
176
  }
1
  <?php
2
 
3
  if (! defined('W3_CACHE_FILE_EXPIRE_MAX')) {
4
+ define('W3_CACHE_FILE_EXPIRE_MAX', 2592000);
5
  }
6
 
7
  /**
8
+ * File class
9
  */
10
  require_once W3TC_LIB_W3_DIR . '/Cache/Base.php';
11
 
69
  */
70
  function set($key, $var, $expire = 0)
71
  {
72
+ $sub_path = $this->_get_path($key);
73
+ $path = $this->_cache_dir . '/' . $sub_path;
74
+
75
+ $sub_dir = dirname($sub_path);
76
+ $dir = dirname($path);
77
+
78
+ if ((is_dir($dir) || w3_mkdir($sub_dir, 0755, $this->_cache_dir))) {
79
  $fp = @fopen($path, 'wb');
80
  if ($fp) {
81
  @fputs($fp, pack('L', $expire));
84
  return true;
85
  }
86
  }
87
+
88
  return false;
89
  }
90
 
96
  */
97
  function get($key)
98
  {
 
99
  $var = false;
100
+ $path = $this->_cache_dir . '/' . $this->_get_path($key);
101
+
102
  if (is_readable($path)) {
103
  $ftime = @filemtime($path);
104
  if ($ftime) {
149
  */
150
  function delete($key)
151
  {
152
+ $path = $this->_cache_dir . '/' . $this->_get_path($key);
153
+
154
  if (file_exists($path)) {
155
  return @unlink($path);
156
  }
157
+
158
  return false;
159
  }
160
 
165
  */
166
  function flush()
167
  {
168
+ w3_emptydir($this->_cache_dir);
169
+
170
+ return true;
171
+ }
172
+
173
+ /**
174
+ * Returns modification time of cache file
175
+ *
176
+ * @param integer $key
177
+ */
178
+ function mtime($key)
179
+ {
180
+ $path = $this->_cache_dir . '/' . $this->_get_path($key);
181
+
182
+ if (file_exists($path)) {
183
+ return @filemtime($path);
184
+ }
185
+
186
+ return false;
187
  }
188
 
189
  /**
195
  function _get_path($key)
196
  {
197
  $hash = md5($key);
198
+ $path = sprintf('%s/%s/%s', substr($hash, 0, 2), substr($hash, 2, 2), $hash);
199
 
200
  return $path;
201
  }
lib/W3/Cache/File/Manager.php CHANGED
@@ -18,45 +18,47 @@ class W3_Cache_File_Manager
18
 
19
  function clean()
20
  {
21
- return $this->_clean($this->_cache_dir, true);
22
  }
23
 
24
- function _clean($path, $empty = false)
25
  {
26
  $dir = @opendir($path);
 
27
  if ($dir) {
28
  while (($entry = @readdir($dir))) {
29
  if ($entry != '.' && $entry != '..') {
30
  $full_path = $path . '/' . $entry;
 
31
  if (is_dir($full_path)) {
32
- $result = $this->_clean($full_path);
33
  } elseif (! $this->is_valid($full_path)) {
34
- $result = @unlink($full_path);
35
- }
36
- if (! $result) {
37
- @closedir($dir);
38
- return false;
39
  }
40
  }
41
  }
 
42
  @closedir($dir);
43
- if (! $empty) {
 
44
  @rmdir($path);
45
  }
46
- return true;
47
  }
48
- return false;
49
  }
50
 
51
  function is_valid($file)
52
  {
53
  $valid = false;
54
- if (is_readable($file)) {
 
55
  $ftime = @filemtime($file);
 
56
  if ($ftime) {
57
  $fp = @fopen($file, 'rb');
 
58
  if ($fp) {
59
  $expires = @fread($fp, 4);
 
60
  if ($expires !== false) {
61
  list (, $expire) = @unpack('L', $expires);
62
  $expire = ($expire && $expire <= W3_CACHE_FILE_EXPIRE_MAX ? $expire : W3_CACHE_FILE_EXPIRE_MAX);
@@ -64,10 +66,12 @@ class W3_Cache_File_Manager
64
  $valid = true;
65
  }
66
  }
 
67
  @fclose($fp);
68
  }
69
  }
70
  }
 
71
  return $valid;
72
  }
73
  }
18
 
19
  function clean()
20
  {
21
+ $this->_clean($this->_cache_dir, false);
22
  }
23
 
24
+ function _clean($path, $remove = true)
25
  {
26
  $dir = @opendir($path);
27
+
28
  if ($dir) {
29
  while (($entry = @readdir($dir))) {
30
  if ($entry != '.' && $entry != '..') {
31
  $full_path = $path . '/' . $entry;
32
+
33
  if (is_dir($full_path)) {
34
+ $this->_clean($full_path);
35
  } elseif (! $this->is_valid($full_path)) {
36
+ @unlink($full_path);
 
 
 
 
37
  }
38
  }
39
  }
40
+
41
  @closedir($dir);
42
+
43
+ if ($remove) {
44
  @rmdir($path);
45
  }
 
46
  }
 
47
  }
48
 
49
  function is_valid($file)
50
  {
51
  $valid = false;
52
+
53
+ if (file_exists($file)) {
54
  $ftime = @filemtime($file);
55
+
56
  if ($ftime) {
57
  $fp = @fopen($file, 'rb');
58
+
59
  if ($fp) {
60
  $expires = @fread($fp, 4);
61
+
62
  if ($expires !== false) {
63
  list (, $expire) = @unpack('L', $expires);
64
  $expire = ($expire && $expire <= W3_CACHE_FILE_EXPIRE_MAX ? $expire : W3_CACHE_FILE_EXPIRE_MAX);
66
  $valid = true;
67
  }
68
  }
69
+
70
  @fclose($fp);
71
  }
72
  }
73
  }
74
+
75
  return $valid;
76
  }
77
  }
lib/W3/Cache/File/Minify/Manager.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once W3TC_LIB_W3_DIR . '/Cache/File/Manager.php';
4
+
5
+ class W3_Cache_File_Minify_Manager extends W3_Cache_File_Manager
6
+ {
7
+ var $_expire = 0;
8
+
9
+ function __construct($config = array())
10
+ {
11
+ parent::__construct($config);
12
+
13
+ $this->_expire = (isset($config['expire']) ? (int) $config['expire'] : 0);
14
+
15
+ if (! $this->_expire || $this->_expire > W3_CACHE_FILE_EXPIRE_MAX) {
16
+ $this->_expire = W3_CACHE_FILE_EXPIRE_MAX;
17
+ }
18
+ }
19
+
20
+ function W3_Cache_File_Minify_Manager($config = array())
21
+ {
22
+ $this->__construct($config);
23
+ }
24
+
25
+ function is_valid($file)
26
+ {
27
+ if ($file == $this->_cache_dir . '/.htaccess' || $file == $this->_cache_dir . '/index.php') {
28
+ return true;
29
+ }
30
+
31
+ if (file_exists($file)) {
32
+ $ftime = @filemtime($file);
33
+
34
+ if ($ftime && $ftime > (time() - $this->_expire)) {
35
+ return true;
36
+ }
37
+ }
38
+
39
+ return false;
40
+ }
41
+ }
lib/W3/Cache/File/PgCache.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * File cache for Page cache
5
+ */
6
+ require_once W3TC_LIB_W3_DIR . '/Cache/File.php';
7
+
8
+ /**
9
+ * Class W3_Cache_File_PgCache
10
+ */
11
+ class W3_Cache_File_PgCache extends W3_Cache_File
12
+ {
13
+ var $_expire = 0;
14
+
15
+ function __construct($config = array())
16
+ {
17
+ parent::__construct($config);
18
+
19
+ $this->_expire = (isset($config['expire']) ? (int) $config['expire'] : 0);
20
+
21
+ if (! $this->_expire || $this->_expire > W3_CACHE_FILE_EXPIRE_MAX) {
22
+ $this->_expire = W3_CACHE_FILE_EXPIRE_MAX;
23
+ }
24
+ }
25
+
26
+ function W3_Cache_File_PgCache($config = array())
27
+ {
28
+ $this->__construct($config);
29
+ }
30
+
31
+ /**
32
+ * Sets data
33
+ *
34
+ * @param string $key
35
+ * @param string $var
36
+ * @return boolean
37
+ */
38
+ function set($key, $var)
39
+ {
40
+ $sub_path = $this->_get_path($key);
41
+ $path = $this->_cache_dir . '/' . $sub_path;
42
+
43
+ $sub_dir = dirname($sub_path);
44
+ $dir = dirname($path);
45
+
46
+ if ((is_dir($dir) || w3_mkdir($sub_dir, 0755, $this->_cache_dir))) {
47
+ $fp = @fopen($path, 'w');
48
+ if ($fp) {
49
+ @fputs($fp, $var);
50
+ @fclose($fp);
51
+
52
+ return true;
53
+ }
54
+ }
55
+
56
+ return false;
57
+ }
58
+
59
+ /**
60
+ * Returns data
61
+ *
62
+ * @param string $key
63
+ * @return string
64
+ */
65
+ function get($key)
66
+ {
67
+ $var = false;
68
+ $path = $this->_cache_dir . '/' . $this->_get_path($key);
69
+
70
+ if (is_readable($path)) {
71
+ $ftime = @filemtime($path);
72
+
73
+ if ($ftime && $ftime > (time() - $this->_expire)) {
74
+ $fp = @fopen($path, 'r');
75
+
76
+ if ($fp) {
77
+ $var = '';
78
+ while (! @feof($fp)) {
79
+ $var .= @fread($fp, 4096);
80
+ }
81
+ @fclose($fp);
82
+ }
83
+ }
84
+ }
85
+
86
+ return $var;
87
+ }
88
+
89
+ /**
90
+ * Flushes all data
91
+ *
92
+ * @return boolean
93
+ */
94
+ function flush()
95
+ {
96
+ w3_emptydir($this->_cache_dir, array(
97
+ $this->_cache_dir . '/.htaccess'
98
+ ));
99
+
100
+ return true;
101
+ }
102
+
103
+ /**
104
+ * Returns cache file path by key
105
+ *
106
+ * @param string $key
107
+ * @return string
108
+ */
109
+ function _get_path($key)
110
+ {
111
+ return $key;
112
+ }
113
+ }
lib/W3/Cache/File/PgCache/Manager.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once W3TC_LIB_W3_DIR . '/Cache/File/Manager.php';
4
+
5
+ class W3_Cache_File_PgCache_Manager extends W3_Cache_File_Manager
6
+ {
7
+ var $_expire = 0;
8
+
9
+ function __construct($config = array())
10
+ {
11
+ parent::__construct($config);
12
+
13
+ $this->_expire = (isset($config['expire']) ? (int) $config['expire'] : 0);
14
+
15
+ if (! $this->_expire || $this->_expire > W3_CACHE_FILE_EXPIRE_MAX) {
16
+ $this->_expire = W3_CACHE_FILE_EXPIRE_MAX;
17
+ }
18
+ }
19
+
20
+ function W3_Cache_File_PgCache_Manager($config = array())
21
+ {
22
+ $this->__construct($config);
23
+ }
24
+
25
+ function is_valid($file)
26
+ {
27
+ if ($file == $this->_cache_dir . '/.htaccess') {
28
+ return true;
29
+ }
30
+
31
+ if (file_exists($file)) {
32
+ $ftime = @filemtime($file);
33
+
34
+ if ($ftime && $ftime > (time() - $this->_expire)) {
35
+ return true;
36
+ }
37
+ }
38
+
39
+ return false;
40
+ }
41
+ }
lib/W3/Cache/Memcached/Base.php CHANGED
@@ -8,7 +8,7 @@ require_once W3TC_LIB_W3_DIR . '/Cache/Base.php';
8
  /**
9
  * Class W3_Cache_Memcached_Base
10
  */
11
- class W3_Cache_Memcached_Base extends W3_Cache_Base
12
  {
13
  /**
14
  * Server config
@@ -37,22 +37,22 @@ class W3_Cache_Memcached_Base extends W3_Cache_Base
37
  {
38
  $this->__construct($config);
39
  }
40
-
41
  /**
42
  * Inits the engine
43
  *
44
- * @abstract
45
  * @return boolean
46
  */
47
  function connect()
48
  {
49
  return false;
50
  }
51
-
52
  /**
53
  * Disconnects from the memcached server
54
  *
55
- * @abstract
56
  * @return bool
57
  */
58
  function disconnect()
8
  /**
9
  * Class W3_Cache_Memcached_Base
10
  */
11
+ class W3_Cache_Memcached_Base extends W3_Cache_Base
12
  {
13
  /**
14
  * Server config
37
  {
38
  $this->__construct($config);
39
  }
40
+
41
  /**
42
  * Inits the engine
43
  *
44
+ * @abstract
45
  * @return boolean
46
  */
47
  function connect()
48
  {
49
  return false;
50
  }
51
+
52
  /**
53
  * Disconnects from the memcached server
54
  *
55
+ * @abstract
56
  * @return bool
57
  */
58
  function disconnect()
lib/W3/Cache/Memcached/Client.php CHANGED
@@ -4,7 +4,7 @@
4
  * PHP memcached client
5
  */
6
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached/Base.php';
7
- require_once W3TC_LIB_W3_DIR . '/Cache/Memcached/memcached-client.php';
8
 
9
  /**
10
  * Class W3_Cache_Memcached_Client
@@ -38,7 +38,7 @@ class W3_Cache_Memcached_Client extends W3_Cache_Memcached_Base
38
 
39
  $this->_memcached = & new memcached_client(array(
40
  'servers' => $servers,
41
- 'persistant' => isset($this->config['persistant']) ? (boolean) $this->config['persistant'] : false,
42
  'debug' => false,
43
  'compress_threshold' => (! empty($this->config['compress_threshold']) ? (integer) $this->config['compress_threshold'] : 0)
44
  ));
@@ -48,7 +48,7 @@ class W3_Cache_Memcached_Client extends W3_Cache_Memcached_Base
48
 
49
  /**
50
  * Disconnects from servers
51
- *
52
  * @return boolean
53
  */
54
  function disconnect()
@@ -145,7 +145,7 @@ class W3_Cache_Memcached_Client extends W3_Cache_Memcached_Base
145
  /**
146
  * Fluhes all data
147
  *
148
- * @todo
149
  * @return boolean
150
  */
151
  function flush()
4
  * PHP memcached client
5
  */
6
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached/Base.php';
7
+ require_once W3TC_LIB_DIR . '/memcached-client.php';
8
 
9
  /**
10
  * Class W3_Cache_Memcached_Client
38
 
39
  $this->_memcached = & new memcached_client(array(
40
  'servers' => $servers,
41
+ 'persistant' => false,
42
  'debug' => false,
43
  'compress_threshold' => (! empty($this->config['compress_threshold']) ? (integer) $this->config['compress_threshold'] : 0)
44
  ));
48
 
49
  /**
50
  * Disconnects from servers
51
+ *
52
  * @return boolean
53
  */
54
  function disconnect()
145
  /**
146
  * Fluhes all data
147
  *
148
+ * @todo
149
  * @return boolean
150
  */
151
  function flush()
lib/W3/Cache/Memcached/memcached-client.php DELETED
@@ -1,977 +0,0 @@
1
- <?php
2
- //
3
- // +---------------------------------------------------------------------------+
4
- // | memcached client, PHP |
5
- // +---------------------------------------------------------------------------+
6
- // | Copyright (c) 2003 Ryan T. Dean <rtdean@cytherianage.net> |
7
- // | All rights reserved. |
8
- // | |
9
- // | Redistribution and use in source and binary forms, with or without |
10
- // | modification, are permitted provided that the following conditions |
11
- // | are met: |
12
- // | |
13
- // | 1. Redistributions of source code must retain the above copyright |
14
- // | notice, this list of conditions and the following disclaimer. |
15
- // | 2. Redistributions in binary form must reproduce the above copyright |
16
- // | notice, this list of conditions and the following disclaimer in the |
17
- // | documentation and/or other materials provided with the distribution. |
18
- // | |
19
- // | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
20
- // | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
21
- // | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
22
- // | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
23
- // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
24
- // | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25
- // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26
- // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27
- // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
28
- // | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29
- // +---------------------------------------------------------------------------+
30
- // | Author: Ryan T. Dean <rtdean@cytherianage.net> |
31
- // | Heavily influenced by the Perl memcached client by Brad Fitzpatrick. |
32
- // | Permission granted by Brad Fitzpatrick for relicense of ported Perl |
33
- // | client logic under 2-clause BSD license. |
34
- // +---------------------------------------------------------------------------+
35
- //
36
- // $TCAnet$
37
- //
38
-
39
- /**
40
- * This is the PHP client for memcached - a distributed memory cache daemon.
41
- * More information is available at http://www.danga.com/memcached/
42
- *
43
- * Usage example:
44
- *
45
- * require_once 'memcached.php';
46
- *
47
- * $mc = new memcached(array(
48
- * 'servers' => array('127.0.0.1:10000',
49
- * array('192.0.0.1:10010', 2),
50
- * '127.0.0.1:10020'),
51
- * 'debug' => false,
52
- * 'compress_threshold' => 10240,
53
- * 'persistant' => true));
54
- *
55
- * $mc->add('key', array('some', 'array'));
56
- * $mc->replace('key', 'some random string');
57
- * $val = $mc->get('key');
58
- *
59
- * @author Ryan T. Dean <rtdean@cytherianage.net>
60
- * @package memcached-client
61
- * @version 0.1.2
62
- */
63
-
64
- // {{{ requirements
65
- // }}}
66
-
67
- // {{{ constants
68
- // {{{ flags
69
-
70
- /**
71
- * Flag: indicates data is serialized
72
- */
73
- if (! defined("MEMCACHE_SERIALIZED")) {
74
- define("MEMCACHE_SERIALIZED", 1<<0);
75
- }
76
-
77
- /**
78
- * Flag: indicates data is compressed
79
- */
80
- if (! defined("MEMCACHE_COMPRESSED")) {
81
- define("MEMCACHE_COMPRESSED", 1<<1);
82
- }
83
-
84
- // }}}
85
-
86
- /**
87
- * Minimum savings to store data compressed
88
- */
89
- if (! defined("COMPRESSION_SAVINGS")) {
90
- define("COMPRESSION_SAVINGS", 0.20);
91
- }
92
-
93
- // }}}
94
-
95
- // {{{ class memcached
96
- /**
97
- * memcached client class implemented using (p)fsockopen()
98
- *
99
- * @author Ryan T. Dean <rtdean@cytherianage.net>
100
- * @package memcached-client
101
- */
102
- class memcached_client
103
- {
104
- // {{{ properties
105
- // {{{ public
106
-
107
- /**
108
- * Command statistics
109
- *
110
- * @var array
111
- * @access public
112
- */
113
- var $stats;
114
-
115
- // }}}
116
- // {{{ private
117
-
118
- /**
119
- * Cached Sockets that are connected
120
- *
121
- * @var array
122
- * @access private
123
- */
124
- var $_cache_sock;
125
-
126
- /**
127
- * Current debug status; 0 - none to 9 - profiling
128
- *
129
- * @var boolean
130
- * @access private
131
- */
132
- var $_debug;
133
-
134
- /**
135
- * Dead hosts, assoc array, 'host'=>'unixtime when ok to check again'
136
- *
137
- * @var array
138
- * @access private
139
- */
140
- var $_host_dead;
141
-
142
- /**
143
- * Is compression available?
144
- *
145
- * @var boolean
146
- * @access private
147
- */
148
- var $_have_zlib;
149
-
150
- /**
151
- * Do we want to use compression?
152
- *
153
- * @var boolean
154
- * @access private
155
- */
156
- var $_compress_enable;
157
-
158
- /**
159
- * At how many bytes should we compress?
160
- *
161
- * @var interger
162
- * @access private
163
- */
164
- var $_compress_threshold;
165
-
166
- /**
167
- * Are we using persistant links?
168
- *
169
- * @var boolean
170
- * @access private
171
- */
172
- var $_persistant;
173
-
174
- /**
175
- * If only using one server; contains ip:port to connect to
176
- *
177
- * @var string
178
- * @access private
179
- */
180
- var $_single_sock;
181
-
182
- /**
183
- * Array containing ip:port or array(ip:port, weight)
184
- *
185
- * @var array
186
- * @access private
187
- */
188
- var $_servers;
189
-
190
- /**
191
- * Our bit buckets
192
- *
193
- * @var array
194
- * @access private
195
- */
196
- var $_buckets;
197
-
198
- /**
199
- * Total # of bit buckets we have
200
- *
201
- * @var interger
202
- * @access private
203
- */
204
- var $_bucketcount;
205
-
206
- /**
207
- * # of total servers we have
208
- *
209
- * @var interger
210
- * @access private
211
- */
212
- var $_active;
213
-
214
- // }}}
215
- // }}}
216
- // {{{ methods
217
- // {{{ public functions
218
- // {{{ memcached()
219
-
220
- /**
221
- * Memcache initializer
222
- *
223
- * @param array $args Associative array of settings
224
- *
225
- * @return mixed
226
- * @access public
227
- */
228
- function memcached_client ($args)
229
- {
230
- $this->set_servers($args['servers']);
231
- $this->_debug = $args['debug'];
232
- $this->stats = array();
233
- $this->_compress_threshold = $args['compress_threshold'];
234
- $this->_persistant = isset($args['persistant']) ? $args['persistant'] : false;
235
- $this->_compress_enable = true;
236
- $this->_have_zlib = function_exists("gzcompress");
237
-
238
- $this->_cache_sock = array();
239
- $this->_host_dead = array();
240
- }
241
-
242
- // }}}
243
- // {{{ add()
244
-
245
- /**
246
- * Adds a key/value to the memcache server if one isn't already set with
247
- * that key
248
- *
249
- * @param string $key Key to set with data
250
- * @param mixed $val Value to store
251
- * @param interger $exp (optional) Time to expire data at
252
- *
253
- * @return boolean
254
- * @access public
255
- */
256
- function add ($key, $val, $exp = 0)
257
- {
258
- return $this->_set('add', $key, $val, $exp);
259
- }
260
-
261
- // }}}
262
- // {{{ decr()
263
-
264
- /**
265
- * Decriment a value stored on the memcache server
266
- *
267
- * @param string $key Key to decriment
268
- * @param interger $amt (optional) Amount to decriment
269
- *
270
- * @return mixed FALSE on failure, value on success
271
- * @access public
272
- */
273
- function decr ($key, $amt=1)
274
- {
275
- return $this->_incrdecr('decr', $key, $amt);
276
- }
277
-
278
- // }}}
279
- // {{{ delete()
280
-
281
- /**
282
- * Deletes a key from the server, optionally after $time
283
- *
284
- * @param string $key Key to delete
285
- * @param interger $time (optional) How long to wait before deleting
286
- *
287
- * @return boolean TRUE on success, FALSE on failure
288
- * @access public
289
- */
290
- function delete ($key, $time = 0)
291
- {
292
- if (!$this->_active)
293
- return false;
294
-
295
- $sock = $this->get_sock($key);
296
- if (!is_resource($sock))
297
- return false;
298
-
299
- $key = is_array($key) ? $key[1] : $key;
300
-
301
- $this->stats['delete']++;
302
- $cmd = "delete $key $time\r\n";
303
- if(!fwrite($sock, $cmd, strlen($cmd)))
304
- {
305
- $this->_dead_sock($sock);
306
- return false;
307
- }
308
- $res = trim(fgets($sock));
309
-
310
- if ($this->_debug)
311
- printf("MemCache: delete %s (%s)\n", $key, $res);
312
-
313
- if ($res == "DELETED")
314
- return true;
315
- return false;
316
- }
317
-
318
- // }}}
319
- // {{{ disconnect_all()
320
-
321
- /**
322
- * Disconnects all connected sockets
323
- *
324
- * @access public
325
- */
326
- function disconnect_all ()
327
- {
328
- foreach ($this->_cache_sock as $sock)
329
- fclose($sock);
330
-
331
- $this->_cache_sock = array();
332
- }
333
-
334
- // }}}
335
- // {{{ enable_compress()
336
-
337
- /**
338
- * Enable / Disable compression
339
- *
340
- * @param boolean $enable TRUE to enable, FALSE to disable
341
- *
342
- * @access public
343
- */
344
- function enable_compress ($enable)
345
- {
346
- $this->_compress_enable = $enable;
347
- }
348
-
349
- // }}}
350
- // {{{ forget_dead_hosts()
351
-
352
- /**
353
- * Forget about all of the dead hosts
354
- *
355
- * @access public
356
- */
357
- function forget_dead_hosts ()
358
- {
359
- $this->_host_dead = array();
360
- }
361
-
362
- // }}}
363
- // {{{ get()
364
-
365
- /**
366
- * Retrieves the value associated with the key from the memcache server
367
- *
368
- * @param string $key Key to retrieve
369
- *
370
- * @return mixed
371
- * @access public
372
- */
373
- function get ($key)
374
- {
375
- if (!$this->_active)
376
- return false;
377
-
378
- $sock = $this->get_sock($key);
379
-
380
- if (!is_resource($sock))
381
- return false;
382
-
383
- $this->stats['get']++;
384
-
385
- $cmd = "get $key\r\n";
386
- if (!fwrite($sock, $cmd, strlen($cmd)))
387
- {
388
- $this->_dead_sock($sock);
389
- return false;
390
- }
391
-
392
- $val = array();
393
- $this->_load_items($sock, $val);
394
-
395
- if ($this->_debug)
396
- foreach ($val as $k => $v)
397
- printf("MemCache: sock %s got %s => %s\r\n", $sock, $k, $v);
398
-
399
- return $val[$key];
400
- }
401
-
402
- // }}}
403
- // {{{ get_multi()
404
-
405
- /**
406
- * Get multiple keys from the server(s)
407
- *
408
- * @param array $keys Keys to retrieve
409
- *
410
- * @return array
411
- * @access public
412
- */
413
- function get_multi ($keys)
414
- {
415
- if (!$this->_active)
416
- return false;
417
-
418
- $this->stats['get_multi']++;
419
-
420
- foreach ($keys as $key)
421
- {
422
- $sock = $this->get_sock($key);
423
- if (!is_resource($sock)) continue;
424
- $key = is_array($key) ? $key[1] : $key;
425
- if (!isset($sock_keys[$sock]))
426
- {
427
- $sock_keys[$sock] = array();
428
- $socks[] = $sock;
429
- }
430
- $sock_keys[$sock][] = $key;
431
- }
432
-
433
- // Send out the requests
434
- foreach ($socks as $sock)
435
- {
436
- $cmd = "get";
437
- foreach ($sock_keys[$sock] as $key)
438
- {
439
- $cmd .= " ". $key;
440
- }
441
- $cmd .= "\r\n";
442
-
443
- if (fwrite($sock, $cmd, strlen($cmd)))
444
- {
445
- $gather[] = $sock;
446
- } else
447
- {
448
- $this->_dead_sock($sock);
449
- }
450
- }
451
-
452
- // Parse responses
453
- $val = array();
454
- foreach ($gather as $sock)
455
- {
456
- $this->_load_items($sock, $val);
457
- }
458
-
459
- if ($this->_debug)
460
- foreach ($val as $k => $v)
461
- printf("MemCache: got %s => %s\r\n", $k, $v);
462
-
463
- return $val;
464
- }
465
-
466
- // }}}
467
- // {{{ incr()
468
-
469
- /**
470
- * Increments $key (optionally) by $amt
471
- *
472
- * @param string $key Key to increment
473
- * @param interger $amt (optional) amount to increment
474
- *
475
- * @return interger New key value?
476
- * @access public
477
- */
478
- function incr ($key, $amt=1)
479
- {
480
- return $this->_incrdecr('incr', $key, $amt);
481
- }
482
-
483
- // }}}
484
- // {{{ replace()
485
-
486
- /**
487
- * Overwrites an existing value for key; only works if key is already set
488
- *
489
- * @param string $key Key to set value as
490
- * @param mixed $value Value to store
491
- * @param interger $exp (optional) Experiation time
492
- *
493
- * @return boolean
494
- * @access public
495
- */
496
- function replace ($key, $value, $exp=0)
497
- {
498
- return $this->_set('replace', $key, $value, $exp);
499
- }
500
-
501
- // }}}
502
- // {{{ run_command()
503
-
504
- /**
505
- * Passes through $cmd to the memcache server connected by $sock; returns
506
- * output as an array (null array if no output)
507
- *
508
- * NOTE: due to a possible bug in how PHP reads while using fgets(), each
509
- * line may not be terminated by a \r\n. More specifically, my testing
510
- * has shown that, on FreeBSD at least, each line is terminated only
511
- * with a \n. This is with the PHP flag auto_detect_line_endings set
512
- * to falase (the default).
513
- *
514
- * @param resource $sock Socket to send command on
515
- * @param string $cmd Command to run
516
- *
517
- * @return array Output array
518
- * @access public
519
- */
520
- function run_command ($sock, $cmd)
521
- {
522
- if (!is_resource($sock))
523
- return array();
524
-
525
- if (!fwrite($sock, $cmd, strlen($cmd)))
526
- return array();
527
-
528
- while (true)
529
- {
530
- $res = fgets($sock);
531
- $ret[] = $res;
532
- if (preg_match('/^END/', $res))
533
- break;
534
- if (strlen($res) == 0)
535
- break;
536
- }
537
- return $ret;
538
- }
539
-
540
- // }}}
541
- // {{{ set()
542
-
543
- /**
544
- * Unconditionally sets a key to a given value in the memcache. Returns true
545
- * if set successfully.
546
- *
547
- * @param string $key Key to set value as
548
- * @param mixed $value Value to set
549
- * @param interger $exp (optional) Experiation time
550
- *
551
- * @return boolean TRUE on success
552
- * @access public
553
- */
554
- function set ($key, $value, $exp=0)
555
- {
556
- return $this->_set('set', $key, $value, $exp);
557
- }
558
-
559
- // }}}
560
- // {{{ set_compress_threshold()
561
-
562
- /**
563
- * Sets the compression threshold
564
- *
565
- * @param interger $thresh Threshold to compress if larger than
566
- *
567
- * @access public
568
- */
569
- function set_compress_threshold ($thresh)
570
- {
571
- $this->_compress_threshold = $thresh;
572
- }
573
-
574
- // }}}
575
- // {{{ set_debug()
576
-
577
- /**
578
- * Sets the debug flag
579
- *
580
- * @param boolean $dbg TRUE for debugging, FALSE otherwise
581
- *
582
- * @access public
583
- *
584
- * @see memcahced::memcached
585
- */
586
- function set_debug ($dbg)
587
- {
588
- $this->_debug = $dbg;
589
- }
590
-
591
- // }}}
592
- // {{{ set_servers()
593
-
594
- /**
595
- * Sets the server list to distribute key gets and puts between
596
- *
597
- * @param array $list Array of servers to connect to
598
- *
599
- * @access public
600
- *
601
- * @see memcached::memcached()
602
- */
603
- function set_servers ($list)
604
- {
605
- $this->_servers = $list;
606
- $this->_active = count($list);
607
- $this->_buckets = null;
608
- $this->_bucketcount = 0;
609
-
610
- $this->_single_sock = null;
611
- if ($this->_active == 1)
612
- $this->_single_sock = $this->_servers[0];
613
- }
614
-
615
- // }}}
616
- // }}}
617
- // {{{ private methods
618
- // {{{ _close_sock()
619
-
620
- /**
621
- * Close the specified socket
622
- *
623
- * @param string $sock Socket to close
624
- *
625
- * @access private
626
- */
627
- function _close_sock ($sock)
628
- {
629
- $host = array_search($sock, $this->_cache_sock);
630
- fclose($this->_cache_sock[$host]);
631
- unset($this->_cache_sock[$host]);
632
- }
633
-
634
- // }}}
635
- // {{{ _connect_sock()
636
-
637
- /**
638
- * Connects $sock to $host, timing out after $timeout
639
- *
640
- * @param interger $sock Socket to connect
641
- * @param string $host Host:IP to connect to
642
- * @param float $timeout (optional) Timeout value, defaults to 0.25s
643
- *
644
- * @return boolean
645
- * @access private
646
- */
647
- function _connect_sock (&$sock, $host, $timeout = 0.25)
648
- {
649
- list ($ip, $port) = explode(":", $host);
650
- if ($this->_persistant == 1)
651
- {
652
- $sock = @pfsockopen($ip, $port, $errno, $errstr, $timeout);
653
- } else
654
- {
655
- $sock = @fsockopen($ip, $port, $errno, $errstr, $timeout);
656
- }
657
-
658
- if (!$sock)
659
- return false;
660
- return true;
661
- }
662
-
663
- // }}}
664
- // {{{ _dead_sock()
665
-
666
- /**
667
- * Marks a host as dead until 30-40 seconds in the future
668
- *
669
- * @param string $sock Socket to mark as dead
670
- *
671
- * @access private
672
- */
673
- function _dead_sock ($sock)
674
- {
675
- $host = array_search($sock, $this->_cache_sock);
676
- list ($ip, $port) = explode(":", $host);
677
- $this->_host_dead[$ip] = time() + 30 + intval(rand(0, 10));
678
- $this->_host_dead[$host] = $this->_host_dead[$ip];
679
- unset($this->_cache_sock[$host]);
680
- }
681
-
682
- // }}}
683
- // {{{ get_sock()
684
-
685
- /**
686
- * get_sock
687
- *
688
- * @param string $key Key to retrieve value for;
689
- *
690
- * @return mixed resource on success, false on failure
691
- * @access private
692
- */
693
- function get_sock ($key)
694
- {
695
- if (!$this->_active)
696
- return false;
697
-
698
- if ($this->_single_sock !== null)
699
- return $this->sock_to_host($this->_single_sock);
700
-
701
- $hv = is_array($key) ? intval($key[0]) : $this->_hashfunc($key);
702
-
703
- if ($this->_buckets === null)
704
- {
705
- foreach ($this->_servers as $v)
706
- {
707
- if (is_array($v))
708
- {
709
- for ($i=0; $i<$v[1]; $i++)
710
- $bu[] = $v[0];
711
- } else
712
- {
713
- $bu[] = $v;
714
- }
715
- }
716
- $this->_buckets = $bu;
717
- $this->_bucketcount = count($bu);
718
- }
719
-
720
- $realkey = is_array($key) ? $key[1] : $key;
721
- for ($tries = 0; $tries<20; $tries++)
722
- {
723
- $host = $this->_buckets[$hv % $this->_bucketcount];
724
- $sock = $this->sock_to_host($host);
725
- if (is_resource($sock))
726
- return $sock;
727
- $hv += $this->_hashfunc($tries . $realkey);
728
- }
729
-
730
- return false;
731
- }
732
-
733
- // }}}
734
- // {{{ _hashfunc()
735
-
736
- /**
737
- * Creates a hash interger based on the $key
738
- *
739
- * @param string $key Key to hash
740
- *
741
- * @return interger Hash value
742
- * @access private
743
- */
744
- function _hashfunc ($key)
745
- {
746
- $hash = 0;
747
- for ($i=0; $i<strlen($key); $i++)
748
- {
749
- $hash = $hash*33 + ord($key[$i]);
750
- }
751
-
752
- return $hash;
753
- }
754
-
755
- // }}}
756
- // {{{ _incrdecr()
757
-
758
- /**
759
- * Perform increment/decriment on $key
760
- *
761
- * @param string $cmd Command to perform
762
- * @param string $key Key to perform it on
763
- * @param interger $amt Amount to adjust
764
- *
765
- * @return interger New value of $key
766
- * @access private
767
- */
768
- function _incrdecr ($cmd, $key, $amt=1)
769
- {
770
- if (!$this->_active)
771
- return null;
772
-
773
- $sock = $this->get_sock($key);
774
- if (!is_resource($sock))
775
- return null;
776
-
777
- $key = is_array($key) ? $key[1] : $key;
778
- $this->stats[$cmd]++;
779
- if (!fwrite($sock, "$cmd $key $amt\r\n"))
780
- return $this->_dead_sock($sock);
781
-
782
- stream_set_timeout($sock, 1, 0);
783
- $line = fgets($sock);
784
- if (!preg_match('/^(\d+)/', $line, $match))
785
- return null;
786
- return $match[1];
787
- }
788
-
789
- // }}}
790
- // {{{ _load_items()
791
-
792
- /**
793
- * Load items into $ret from $sock
794
- *
795
- * @param resource $sock Socket to read from
796
- * @param array $ret Returned values
797
- *
798
- * @access private
799
- */
800
- function _load_items ($sock, &$ret)
801
- {
802
- while (1)
803
- {
804
- $decl = fgets($sock);
805
- if ($decl == "END\r\n")
806
- {
807
- return true;
808
- } elseif (preg_match('/^VALUE (\S+) (\d+) (\d+)\r\n$/', $decl, $match))
809
- {
810
- list($rkey, $flags, $len) = array($match[1], $match[2], $match[3]);
811
- $bneed = $len+2;
812
- $offset = 0;
813
-
814
- while ($bneed > 0)
815
- {
816
- $data = fread($sock, $bneed);
817
- $n = strlen($data);
818
- if ($n == 0)
819
- break;
820
- $offset += $n;
821
- $bneed -= $n;
822
- $ret[$rkey] .= $data;
823
- }
824
-
825
- if ($offset != $len+2)
826
- {
827
- // Something is borked!
828
- if ($this->_debug)
829
- printf("Something is borked! key %s expecting %d got %d length\n", $rkey, $len+2, $offset);
830
-
831
- unset($ret[$rkey]);
832
- $this->_close_sock($sock);
833
- return false;
834
- }
835
-
836
- //$ret[$rkey] = rtrim($ret[$rkey]); buggy
837
- $ret[$rkey] = substr($ret[$rkey], 0, -2);
838
-
839
- if ($this->_have_zlib && $flags & MEMCACHE_COMPRESSED) {
840
- $ret[$rkey] = gzuncompress($ret[$rkey]);
841
- }
842
-
843
- if ($flags & MEMCACHE_SERIALIZED)
844
- $ret[$rkey] = unserialize($ret[$rkey]);
845
-
846
- } else
847
- {
848
- print("Error parsing memcached response\n");
849
- return 0;
850
- }
851
- }
852
- }
853
-
854
- // }}}
855
- // {{{ _set()
856
-
857
- /**
858
- * Performs the requested storage operation to the memcache server
859
- *
860
- * @param string $cmd Command to perform
861
- * @param string $key Key to act on
862
- * @param mixed $val What we need to store
863
- * @param interger $exp When it should expire
864
- *
865
- * @return boolean
866
- * @access private
867
- */
868
- function _set ($cmd, $key, $val, $exp)
869
- {
870
- if (!$this->_active)
871
- return false;
872
-
873
- $sock = $this->get_sock($key);
874
- if (!is_resource($sock))
875
- return false;
876
-
877
- $this->stats[$cmd]++;
878
-
879
- $flags = 0;
880
-
881
- if (!is_scalar($val))
882
- {
883
- $val = serialize($val);
884
- $flags |= MEMCACHE_SERIALIZED;
885
- if ($this->_debug)
886
- printf("client: serializing data as it is not scalar\n");
887
- }
888
-
889
- $len = strlen($val);
890
-
891
- if ($this->_have_zlib && $this->_compress_enable &&
892
- $this->_compress_threshold && $len >= $this->_compress_threshold)
893
- {
894
- $c_val = gzcompress($val, 9);
895
- $c_len = strlen($c_val);
896
-
897
- if ($c_len < $len*(1 - COMPRESS_SAVINGS))
898
- {
899
- if ($this->_debug)
900
- printf("client: compressing data; was %d bytes is now %d bytes\n", $len, $c_len);
901
- $val = $c_val;
902
- $len = $c_len;
903
- $flags |= MEMCACHE_COMPRESSED;
904
- }
905
- }
906
- if (!fwrite($sock, "$cmd $key $flags $exp $len\r\n$val\r\n"))
907
- return $this->_dead_sock($sock);
908
-
909
- $line = trim(fgets($sock));
910
-
911
- if ($this->_debug)
912
- {
913
- if ($flags & MEMCACHE_COMPRESSED)
914
- $val = 'compressed data';
915
- printf("MemCache: %s %s => %s (%s)\n", $cmd, $key, $val, $line);
916
- }
917
- if ($line == "STORED")
918
- return true;
919
- return false;
920
- }
921
-
922
- // }}}
923
- // {{{ sock_to_host()
924
-
925
- /**
926
- * Returns the socket for the host
927
- *
928
- * @param string $host Host:IP to get socket for
929
- *
930
- * @return mixed IO Stream or false
931
- * @access private
932
- */
933
- function sock_to_host ($host)
934
- {
935
- if (isset($this->_cache_sock[$host]))
936
- return $this->_cache_sock[$host];
937
-
938
- $now = time();
939
- list ($ip, $port) = explode (":", $host);
940
- if (isset($this->_host_dead[$host]) && $this->_host_dead[$host] > $now ||
941
- isset($this->_host_dead[$ip]) && $this->_host_dead[$ip] > $now)
942
- return null;
943
-
944
- if (!$this->_connect_sock($sock, $host))
945
- return $this->_dead_sock($host);
946
-
947
- // Do not buffer writes
948
- stream_set_write_buffer($sock, 0);
949
-
950
- $this->_cache_sock[$host] = $sock;
951
-
952
- return $this->_cache_sock[$host];
953
- }
954
-
955
- // }}}
956
- // {{{ flush_all()
957
-
958
- /**
959
- * Flushes all memcached data
960
- *
961
- * @return boolean
962
- * @access public
963
- */
964
- function flush_all()
965
- {
966
- foreach ($this->_cache_sock as $sock) {
967
- $this->run_command($sock, "flush_all\r\n");
968
- }
969
- }
970
-
971
- // }}}
972
- // }}}
973
- // }}}
974
- }
975
-
976
- // }}}
977
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/W3/Cdn.php CHANGED
@@ -16,6 +16,10 @@ if (! defined('W3_CDN_S3')) {
16
  define('W3_CDN_S3', 's3');
17
  }
18
 
 
 
 
 
19
  /**
20
  * Class W3_Cdn
21
  */
@@ -35,22 +39,27 @@ class W3_Cdn
35
  $instance_key = sprintf('%s_%s', $engine, md5(serialize($config)));
36
 
37
  if (! isset($instances[$instance_key])) {
38
- switch ($engine) {
39
- case W3_CDN_FTP:
40
  require_once W3TC_LIB_W3_DIR . '/Cdn/Ftp.php';
41
  $instances[$instance_key] = & new W3_Cdn_Ftp($config);
42
  break;
43
 
44
- case W3_CDN_CF:
45
  require_once W3TC_LIB_W3_DIR . '/Cdn/Cf.php';
46
  $instances[$instance_key] = & new W3_Cdn_Cf($config);
47
  break;
48
 
49
- case W3_CDN_S3:
50
  require_once W3TC_LIB_W3_DIR . '/Cdn/S3.php';
51
  $instances[$instance_key] = & new W3_Cdn_S3($config);
52
  break;
53
 
 
 
 
 
 
54
  default:
55
  trigger_error('Incorrect CDN engine', E_USER_WARNING);
56
  require_once W3TC_LIB_W3_DIR . '/Cdn/Base.php';
16
  define('W3_CDN_S3', 's3');
17
  }
18
 
19
+ if (! defined('W3_CDN_MIRROR')) {
20
+ define('W3_CDN_MIRROR', 'mirror');
21
+ }
22
+
23
  /**
24
  * Class W3_Cdn
25
  */
39
  $instance_key = sprintf('%s_%s', $engine, md5(serialize($config)));
40
 
41
  if (! isset($instances[$instance_key])) {
42
+ switch (true) {
43
+ case ($engine == W3_CDN_FTP):
44
  require_once W3TC_LIB_W3_DIR . '/Cdn/Ftp.php';
45
  $instances[$instance_key] = & new W3_Cdn_Ftp($config);
46
  break;
47
 
48
+ case (W3TC_PHP5 && $engine == W3_CDN_CF):
49
  require_once W3TC_LIB_W3_DIR . '/Cdn/Cf.php';
50
  $instances[$instance_key] = & new W3_Cdn_Cf($config);
51
  break;
52
 
53
+ case (W3TC_PHP5 && $engine == W3_CDN_S3):
54
  require_once W3TC_LIB_W3_DIR . '/Cdn/S3.php';
55
  $instances[$instance_key] = & new W3_Cdn_S3($config);
56
  break;
57
 
58
+ case ($engine == W3_CDN_MIRROR):
59
+ require_once W3TC_LIB_W3_DIR . '/Cdn/Mirror.php';
60
+ $instances[$instance_key] = & new W3_Cdn_Mirror($config);
61
+ break;
62
+
63
  default:
64
  trigger_error('Incorrect CDN engine', E_USER_WARNING);
65
  require_once W3TC_LIB_W3_DIR . '/Cdn/Base.php';
lib/W3/Cdn/Base.php CHANGED
@@ -30,6 +30,7 @@ class W3_Cdn_Base
30
 
31
  /**
32
  * PHP5 Constructor
 
33
  * @param array $config
34
  */
35
  function __construct($config)
@@ -39,6 +40,7 @@ class W3_Cdn_Base
39
 
40
  /**
41
  * PHP4 Constructor
 
42
  * @param array $config
43
  */
44
  function W3_Cdn_Base($config)
@@ -51,11 +53,11 @@ class W3_Cdn_Base
51
  *
52
  * @param array $files
53
  * @param array $results
54
- * @return integer
55
  */
56
  function upload($files, &$results)
57
  {
58
- $results = $this->get_results($files, W3_CDN_RESULT_HALT, 'Not implemented');
59
  return false;
60
  }
61
 
@@ -64,22 +66,62 @@ class W3_Cdn_Base
64
  *
65
  * @param array $files
66
  * @param array $results
67
- * @return integer
68
  */
69
  function delete($files, &$results)
70
  {
71
- $results = $this->get_results($files, W3_CDN_RESULT_HALT, 'Not implemented');
72
  return false;
73
  }
74
 
75
  /**
76
  * Test CDN server
77
  *
 
78
  * @return boolean
79
  */
80
- function test(&$error = null)
 
 
 
 
 
 
 
 
 
 
 
81
  {
82
- $error = 'Not implemented';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  return false;
84
  }
85
 
30
 
31
  /**
32
  * PHP5 Constructor
33
+ *
34
  * @param array $config
35
  */
36
  function __construct($config)
40
 
41
  /**
42
  * PHP4 Constructor
43
+ *
44
  * @param array $config
45
  */
46
  function W3_Cdn_Base($config)
53
  *
54
  * @param array $files
55
  * @param array $results
56
+ * @return boolean
57
  */
58
  function upload($files, &$results)
59
  {
60
+ $results = $this->get_results($files, W3_CDN_RESULT_HALT, 'Not implemented.');
61
  return false;
62
  }
63
 
66
  *
67
  * @param array $files
68
  * @param array $results
69
+ * @return boolean
70
  */
71
  function delete($files, &$results)
72
  {
73
+ $results = $this->get_results($files, W3_CDN_RESULT_HALT, 'Not implemented.');
74
  return false;
75
  }
76
 
77
  /**
78
  * Test CDN server
79
  *
80
+ * @param string $error
81
  * @return boolean
82
  */
83
+ function test(&$error)
84
+ {
85
+ $error = 'Not implemented.';
86
+ return false;
87
+ }
88
+
89
+ /**
90
+ * Returns CDN domain
91
+ *
92
+ * @return string
93
+ */
94
+ function get_domain()
95
  {
96
+ return false;
97
+ }
98
+
99
+ /**
100
+ * Returns via string
101
+ *
102
+ * @return string
103
+ */
104
+ function get_via()
105
+ {
106
+ return $this->get_domain();
107
+ }
108
+
109
+ /**
110
+ * Formats object URL
111
+ *
112
+ * @param string $path
113
+ * @return string
114
+ */
115
+ function format_url($path)
116
+ {
117
+ $domain = $this->get_domain();
118
+
119
+ if ($domain) {
120
+ $url = sprintf('%s://%s%s', (w3_is_https() ? 'https' : 'http'), $domain, $path);
121
+
122
+ return $url;
123
+ }
124
+
125
  return false;
126
  }
127
 
lib/W3/Cdn/Cf.php CHANGED
@@ -1,7 +1,105 @@
1
  <?php
2
 
3
- require_once W3TC_LIB_W3_DIR . '/Cdn/Base.php';
4
 
5
- class W3_Cdn_Cf extends W3_Cdn_Base
6
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  }
1
  <?php
2
 
3
+ require_once W3TC_LIB_W3_DIR . '/Cdn/S3.php';
4
 
5
+ class W3_Cdn_Cf extends W3_Cdn_S3
6
  {
7
+ /**
8
+ * Returns CDN domain
9
+ *
10
+ * @return string
11
+ */
12
+ function get_domain()
13
+ {
14
+ if (! empty($this->_config['cname'])) {
15
+ return $this->_config['cname'];
16
+ } elseif (! empty($this->_config['id'])) {
17
+ $domain = sprintf('%s.cloudfront.net', $this->_config['id']);
18
+
19
+ return $domain;
20
+ }
21
+
22
+ return false;
23
+ }
24
+ /**
25
+ * Tests CF
26
+ *
27
+ * @param string $error
28
+ * @return boolean
29
+ */
30
+ function test(&$error)
31
+ {
32
+ /**
33
+ * Test S3 first
34
+ */
35
+ if (! parent::test($error)) {
36
+ return false;
37
+ }
38
+
39
+ /**
40
+ * Search active CF distribution
41
+ */
42
+ $dists = @$this->_s3->listDistributions();
43
+
44
+ if (! $dists) {
45
+ $error = 'Unable to list distributions.';
46
+
47
+ return false;
48
+ }
49
+
50
+ $search = sprintf('%s.s3.amazonaws.com', $this->_config['bucket']);
51
+ $dist = false;
52
+
53
+ if ($dists) {
54
+ foreach ((array) $dists as $_dist) {
55
+ if (isset($_dist['origin']) && $_dist['origin'] == $search) {
56
+ $dist = $_dist;
57
+ break;
58
+ }
59
+ }
60
+ }
61
+
62
+ if (! $dist) {
63
+ $error = sprintf('Distribution for bucket "%s" not found.', $this->_config['bucket']);
64
+
65
+ return false;
66
+ }
67
+
68
+ if (! $dist['enabled']) {
69
+ $error = sprintf('Distribution for bucket "%s" is disabled.', $this->_config['bucket']);
70
+
71
+ return false;
72
+ }
73
+
74
+ if ($this->_config['cname'] != '') {
75
+ $cnames = (isset($dist['cnames']) ? (array) $dist['cnames'] : array());
76
+
77
+ if (! in_array($this->_config['cname'], $cnames)) {
78
+ $error = sprintf('Domain name %s is not in distribution CNAME list.', $this->_config['cname']);
79
+
80
+ return false;
81
+ }
82
+
83
+ } elseif ($this->_config['id'] != '') {
84
+ $domain = $this->get_domain();
85
+
86
+ if ($domain != $dist['domain']) {
87
+ $error = sprintf('Distribution domain name mismatch (%s != %s).', $domain, $dist['domain']);
88
+
89
+ return false;
90
+ }
91
+ }
92
+
93
+ return true;
94
+ }
95
+
96
+ /**
97
+ * Returns via string
98
+ *
99
+ * @return string
100
+ */
101
+ function get_via()
102
+ {
103
+ return sprintf('Amazon Web Services: CloudFront: %s', $this->get_domain());
104
+ }
105
  }
lib/W3/Cdn/Ftp.php CHANGED
@@ -27,10 +27,10 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
27
  * @param string $error
28
  * @return boolean
29
  */
30
- function _connect(&$error = null)
31
  {
32
  if (empty($this->_config['host'])) {
33
- $error = 'Empty host';
34
  return false;
35
  }
36
 
@@ -41,27 +41,27 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
41
  $this->_ftp = @ftp_connect($this->_config['host'], $this->_config['port'], W3_CDN_FTP_CONNECT_TIMEOUT);
42
 
43
  if (! $this->_ftp) {
44
- $error = sprintf('Unable to connect to %s:%d', $this->_config['host'], $this->_config['port']);
45
  return false;
46
  }
47
 
48
  if (! @ftp_login($this->_ftp, $this->_config['user'], $this->_config['pass'])) {
49
  $this->_disconnect();
50
- $error = 'Incorrect login or password';
51
 
52
  return false;
53
  }
54
 
55
  if (isset($this->_config['pasv']) && ! @ftp_pasv($this->_ftp, $this->_config['pasv'])) {
56
  $this->_disconnect();
57
- $error = 'Unable to change mode to passive';
58
 
59
  return false;
60
  }
61
 
62
  if (! empty($this->_config['path']) && ! @ftp_chdir($this->_ftp, $this->_config['path'])) {
63
  $this->_disconnect();
64
- $error = 'Unable to change directory';
65
 
66
  return false;
67
  }
@@ -82,7 +82,7 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
82
  *
83
  * @param array $files
84
  * @param array $results
85
- * @return integer
86
  */
87
  function upload($files, &$results)
88
  {
@@ -136,7 +136,7 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
136
  $results[] = $this->get_result($local_path, $remote_path, ($result ? W3_CDN_RESULT_OK : W3_CDN_RESULT_ERROR), ($result ? 'OK' : 'Unable to upload file'));
137
 
138
  if ($result) {
139
- $count ++;
140
  @ftp_chmod($this->_ftp, 0644, $remote_file);
141
  }
142
  }
@@ -151,7 +151,7 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
151
  *
152
  * @param array $files
153
  * @param array $results
154
- * @return integer
155
  */
156
  function delete($files, &$results)
157
  {
@@ -168,7 +168,7 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
168
  $results[] = $this->get_result($local_path, $remote_path, ($result ? W3_CDN_RESULT_OK : W3_CDN_RESULT_ERROR), ($result ? 'OK' : 'Unable to delete file'));
169
 
170
  if ($result) {
171
- $count ++;
172
  }
173
 
174
  while (true) {
@@ -186,11 +186,11 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
186
 
187
  /**
188
  * Tests FTP server
189
- *
190
  * @param string $error
191
  * @return boolean
192
  */
193
- function test(&$error = null)
194
  {
195
  $rand = md5(time());
196
  $upload_info = w3_upload_info();
@@ -202,17 +202,17 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
202
  @fputs($fp, $rand);
203
  @fclose($fp);
204
  } else {
205
- $error = sprintf('Unable to create file: %s', $tmp_path);
206
  return false;
207
  }
208
-
209
  if (! $this->_connect($error)) {
210
  return false;
211
  }
212
 
213
  if (! @ftp_mkdir($this->_ftp, $tmp_dir)) {
214
  $this->_disconnect();
215
- $error = sprintf('Unable to make directory: %s', $tmp_dir);
216
  return false;
217
  } else {
218
  @ftp_chmod($this->_ftp, 0755, $tmp_dir);
@@ -220,7 +220,7 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
220
 
221
  if (! @ftp_chdir($this->_ftp, $tmp_dir)) {
222
  $this->_disconnect();
223
- $error = sprintf('Unable to change directory to: %d', $tmp_dir);
224
  return false;
225
  }
226
 
@@ -229,7 +229,7 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
229
  @ftp_rmdir($this->_ftp, $tmp_dir);
230
  @unlink($tmp_path);
231
  $this->_disconnect();
232
- $error = sprintf('Unable to upload file: %s', $tmp_path);
233
  return false;
234
  }
235
 
@@ -241,4 +241,18 @@ class W3_Cdn_Ftp extends W3_Cdn_Base
241
 
242
  return true;
243
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  }
27
  * @param string $error
28
  * @return boolean
29
  */
30
+ function _connect(&$error)
31
  {
32
  if (empty($this->_config['host'])) {
33
+ $error = 'Empty host.';
34
  return false;
35
  }
36
 
41
  $this->_ftp = @ftp_connect($this->_config['host'], $this->_config['port'], W3_CDN_FTP_CONNECT_TIMEOUT);
42
 
43
  if (! $this->_ftp) {
44
+ $error = sprintf('Unable to connect to %s:%d.', $this->_config['host'], $this->_config['port']);
45
  return false;
46
  }
47
 
48
  if (! @ftp_login($this->_ftp, $this->_config['user'], $this->_config['pass'])) {
49
  $this->_disconnect();
50
+ $error = 'Incorrect login or password.';
51
 
52
  return false;
53
  }
54
 
55
  if (isset($this->_config['pasv']) && ! @ftp_pasv($this->_ftp, $this->_config['pasv'])) {
56
  $this->_disconnect();
57
+ $error = 'Unable to change mode to passive.';
58
 
59
  return false;
60
  }
61
 
62
  if (! empty($this->_config['path']) && ! @ftp_chdir($this->_ftp, $this->_config['path'])) {
63
  $this->_disconnect();
64
+ $error = sprintf('Unable to change directory to: %s.', $this->_config['path']);
65
 
66
  return false;
67
  }
82
  *
83
  * @param array $files
84
  * @param array $results
85
+ * @return boolean
86
  */
87
  function upload($files, &$results)
88
  {
136
  $results[] = $this->get_result($local_path, $remote_path, ($result ? W3_CDN_RESULT_OK : W3_CDN_RESULT_ERROR), ($result ? 'OK' : 'Unable to upload file'));
137
 
138
  if ($result) {
139
+ $count++;
140
  @ftp_chmod($this->_ftp, 0644, $remote_file);
141
  }
142
  }
151
  *
152
  * @param array $files
153
  * @param array $results
154
+ * @return boolean
155
  */
156
  function delete($files, &$results)
157
  {
168
  $results[] = $this->get_result($local_path, $remote_path, ($result ? W3_CDN_RESULT_OK : W3_CDN_RESULT_ERROR), ($result ? 'OK' : 'Unable to delete file'));
169
 
170
  if ($result) {
171
+ $count++;
172
  }
173
 
174
  while (true) {
186
 
187
  /**
188
  * Tests FTP server
189
+ *
190
  * @param string $error
191
  * @return boolean
192
  */
193
+ function test(&$error)
194
  {
195
  $rand = md5(time());
196
  $upload_info = w3_upload_info();
202
  @fputs($fp, $rand);
203
  @fclose($fp);
204
  } else {
205
+ $error = sprintf('Unable to create file: %s.', $tmp_path);
206
  return false;
207
  }
208
+
209
  if (! $this->_connect($error)) {
210
  return false;
211
  }
212
 
213
  if (! @ftp_mkdir($this->_ftp, $tmp_dir)) {
214
  $this->_disconnect();
215
+ $error = sprintf('Unable to make directory: %s.', $tmp_dir);
216
  return false;
217
  } else {
218
  @ftp_chmod($this->_ftp, 0755, $tmp_dir);
220
 
221
  if (! @ftp_chdir($this->_ftp, $tmp_dir)) {
222
  $this->_disconnect();
223
+ $error = sprintf('Unable to change directory to: %s.', $tmp_dir);
224
  return false;
225
  }
226
 
229
  @ftp_rmdir($this->_ftp, $tmp_dir);
230
  @unlink($tmp_path);
231
  $this->_disconnect();
232
+ $error = sprintf('Unable to upload file: %s.', $tmp_path);
233
  return false;
234
  }
235
 
241
 
242
  return true;
243
  }
244
+
245
+ /**
246
+ * Returns CDN domain
247
+ *
248
+ * @return string
249
+ */
250
+ function get_domain()
251
+ {
252
+ if (! empty($this->_config['domain'])) {
253
+ return $this->_config['domain'];
254
+ }
255
+
256
+ return false;
257
+ }
258
  }
lib/W3/Cdn/Mirror.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * W3 CDN Mirror Class
5
+ */
6
+ require_once W3TC_LIB_W3_DIR . '/Cdn/Base.php';
7
+
8
+ /**
9
+ * Class W3_Cdn_Mirror
10
+ */
11
+ class W3_Cdn_Mirror extends W3_Cdn_Base
12
+ {
13
+ /**
14
+ * Uploads files to FTP
15
+ *
16
+ * @param array $files
17
+ * @param array $results
18
+ * @return boolean
19
+ */
20
+ function upload($files, &$results)
21
+ {
22
+ $results = $this->get_results($files, W3_CDN_RESULT_OK, 'OK');
23
+
24
+ return count($files);
25
+ }
26
+
27
+ /**
28
+ * Deletes files from FTP
29
+ *
30
+ * @param array $files
31
+ * @param array $results
32
+ * @return boolean
33
+ */
34
+ function delete($files, &$results)
35
+ {
36
+ $results = $this->get_results($files, W3_CDN_RESULT_OK, 'OK');
37
+
38
+ return count($files);
39
+ }
40
+
41
+ /**
42
+ * Tests FTP server
43
+ *
44
+ * @param string $error
45
+ * @return boolean
46
+ */
47
+ function test(&$error)
48
+ {
49
+ return true;
50
+ }
51
+
52
+ /**
53
+ * Returns CDN domain
54
+ * @return string
55
+ */
56
+ function get_domain()
57
+ {
58
+ if (! empty($this->_config['domain'])) {
59
+ return $this->_config['domain'];
60
+ }
61
+
62
+ return false;
63
+ }
64
+ }
lib/W3/Cdn/S3.php CHANGED
@@ -1,7 +1,248 @@
1
  <?php
2
 
3
  require_once W3TC_LIB_W3_DIR . '/Cdn/Base.php';
 
4
 
5
- class W3_Cdn_S3 extends W3_Cdn_Base
6
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  }
1
  <?php
2
 
3
  require_once W3TC_LIB_W3_DIR . '/Cdn/Base.php';
4
+ require_once W3TC_LIB_DIR . '/S3.php';
5
 
6
+ class W3_Cdn_S3 extends W3_Cdn_Base
7
  {
8
+ /**
9
+ * S3 object
10
+ *
11
+ * @var S3
12
+ */
13
+ var $_s3 = null;
14
+
15
+ /**
16
+ * Inits S3 object
17
+ *
18
+ * @param string $error
19
+ * @return boolean
20
+ */
21
+ function _init(&$error)
22
+ {
23
+ if (empty($this->_config['key'])) {
24
+ $error = 'Empty access key';
25
+
26
+ return false;
27
+ }
28
+
29
+ if (empty($this->_config['secret'])) {
30
+ $error = 'Empty secret key';
31
+
32
+ return false;
33
+ }
34
+
35
+ if (empty($this->_config['bucket'])) {
36
+ $error = 'Empty bucket';
37
+
38
+ return false;
39
+ }
40
+
41
+ $this->_s3 = & new S3($this->_config['key'], $this->_config['secret'], false);
42
+
43
+ return true;
44
+ }
45
+
46
+ /**
47
+ * Uploads files to FTP
48
+ *
49
+ * @param array $files
50
+ * @param array $results
51
+ * @return boolean
52
+ */
53
+ function upload($files, &$results)
54
+ {
55
+ $count = 0;
56
+ $error = null;
57
+
58
+ if (! $this->_init($error)) {
59
+ $results = $this->get_results($files, W3_CDN_RESULT_HALT, $error);
60
+ return false;
61
+ }
62
+
63
+ foreach ($files as $local_path => $remote_path) {
64
+ if (! file_exists($local_path)) {
65
+ $results[] = $this->get_result($local_path, $remote_path, W3_CDN_RESULT_ERROR, 'Source file not found');
66
+ continue;
67
+ }
68
+
69
+ $info = @$this->_s3->getObjectInfo($this->_config['bucket'], $remote_path);
70
+
71
+ if ($info && isset($info['size']) && $info['size'] == filesize($local_path)) {
72
+ $results[] = $this->get_result($local_path, $remote_path, W3_CDN_RESULT_ERROR, 'Object already exists');
73
+ continue;
74
+ }
75
+
76
+ $result = @$this->_s3->putObjectFile($local_path, $this->_config['bucket'], $remote_path, S3::ACL_PUBLIC_READ);
77
+ $results[] = $this->get_result($local_path, $remote_path, ($result ? W3_CDN_RESULT_OK : W3_CDN_RESULT_ERROR), ($result ? 'OK' : 'Unable to put object'));
78
+
79
+ if ($result) {
80
+ $count++;
81
+ }
82
+ }
83
+
84
+ return $count;
85
+ }
86
+
87
+ /**
88
+ * Deletes files from FTP
89
+ *
90
+ * @param array $files
91
+ * @param array $results
92
+ * @return boolean
93
+ */
94
+ function delete($files, &$results)
95
+ {
96
+ $error = null;
97
+ $count = 0;
98
+
99
+ if (! $this->_init($error)) {
100
+ $results = $this->get_results($files, W3_CDN_RESULT_HALT, $error);
101
+ return false;
102
+ }
103
+
104
+ foreach ($files as $local_path => $remote_path) {
105
+ $result = @$this->_s3->deleteObject($this->_config['bucket'], $remote_path);
106
+ $results[] = $this->get_result($local_path, $remote_path, ($result ? W3_CDN_RESULT_OK : W3_CDN_RESULT_ERROR), ($result ? 'OK' : 'Unable to delete object'));
107
+
108
+ if ($result) {
109
+ $count++;
110
+ }
111
+ }
112
+
113
+ return $count;
114
+ }
115
+
116
+ /**
117
+ * Tests S3
118
+ *
119
+ * @param string $error
120
+ * @return boolean
121
+ */
122
+ function test(&$error)
123
+ {
124
+ $string = 'test_s3_' . md5(time());
125
+
126
+ if (! $this->_init($error)) {
127
+ return false;
128
+ }
129
+
130
+ $domain = $this->get_domain();
131
+
132
+ if (! $domain) {
133
+ $error = 'Empty domain.';
134
+
135
+ return false;
136
+ }
137
+
138
+ if (gethostbyname($domain) == $domain) {
139
+ $error = sprintf('Unable to resolve domain: %s.', $domain);
140
+
141
+ return false;
142
+ }
143
+
144
+ $buckets = @$this->_s3->listBuckets();
145
+
146
+ if (! $buckets) {
147
+ $error = 'Unable to list buckets (check your credentials).';
148
+
149
+ return false;
150
+ }
151
+
152
+ if (! in_array($this->_config['bucket'], (array) $buckets)) {
153
+ $error = sprintf('Bucket doesn\'t exist: %s', $this->_config['bucket']);
154
+
155
+ return false;
156
+ }
157
+
158
+ if (! @$this->_s3->putObjectString($string, $this->_config['bucket'], $string, S3::ACL_PUBLIC_READ)) {
159
+ $error = 'Unable to put object.';
160
+
161
+ return false;
162
+ }
163
+
164
+ if (! ($object = @$this->_s3->getObject($this->_config['bucket'], $string))) {
165
+ $error = 'Unable to get object.';
166
+
167
+ return false;
168
+ }
169
+
170
+ if ($object->body != $string) {
171
+ @$this->_s3->deleteObject($this->_config['bucket'], $string);
172
+ $error = 'Objects are not equal.';
173
+
174
+ return false;
175
+ }
176
+
177
+ if (! @$this->_s3->deleteObject($this->_config['bucket'], $string)) {
178
+ $error = 'Unable to delete object.';
179
+
180
+ return false;
181
+ }
182
+
183
+ return true;
184
+ }
185
+
186
+ /**
187
+ * Returns CDN domain
188
+ *
189
+ * @return string
190
+ */
191
+ function get_domain()
192
+ {
193
+ if (! empty($this->_config['bucket'])) {
194
+ $domain = sprintf('%s.s3.amazonaws.com', $this->_config['bucket']);
195
+
196
+ return $domain;
197
+ }
198
+
199
+ return false;
200
+ }
201
+
202
+ /**
203
+ * Returns via string
204
+ *
205
+ * @return string
206
+ */
207
+ function get_via()
208
+ {
209
+ $domain = $this->get_domain();
210
+
211
+ return sprintf('Amazon Web Services: S3: %s', ($domain ? $domain : 'N/A'));
212
+ }
213
+
214
+ /**
215
+ * Creates bucket
216
+ *
217
+ * @param string $error
218
+ * @return boolean
219
+ */
220
+ function create_bucket(&$error)
221
+ {
222
+ if (! $this->_init($error)) {
223
+ return false;
224
+ }
225
+
226
+ $buckets = @$this->_s3->listBuckets();
227
+
228
+ if (! $buckets) {
229
+ $error = 'Unable to list buckets (check your credentials).';
230
+
231
+ return false;
232
+ }
233
+
234
+ if (in_array($this->_config['bucket'], (array) $buckets)) {
235
+ $error = sprintf('Bucket already exists: %s.', $this->_config['bucket']);
236
+
237
+ return false;
238
+ }
239
+
240
+ if (! @$this->_s3->putBucket($this->_config['bucket'], S3::ACL_PUBLIC_READ)) {
241
+ $error = sprintf('Unable to create bucket: %s.', $this->_config['bucket']);
242
+
243
+ return false;
244
+ }
245
+
246
+ return true;
247
+ }
248
  }
lib/W3/Config.php CHANGED
@@ -30,9 +30,10 @@ class W3_Config
30
  'dbcache.enabled' => 'boolean',
31
  'dbcache.debug' => 'boolean',
32
  'dbcache.engine' => 'string',
 
33
  'dbcache.memcached.engine' => 'string',
34
  'dbcache.memcached.servers' => 'array',
35
- 'dbcache.reject.admin' => 'boolean',
36
  'dbcache.reject.uri' => 'array',
37
  'dbcache.reject.cookie' => 'array',
38
  'dbcache.reject.sql' => 'array',
@@ -41,10 +42,11 @@ class W3_Config
41
  'pgcache.enabled' => 'boolean',
42
  'pgcache.debug' => 'boolean',
43
  'pgcache.engine' => 'string',
 
44
  'pgcache.memcached.engine' => 'string',
45
  'pgcache.memcached.servers' => 'array',
46
  'pgcache.lifetime' => 'integer',
47
- 'pgcache.compress' => 'boolean',
48
  'pgcache.cache.query' => 'boolean',
49
  'pgcache.cache.home' => 'boolean',
50
  'pgcache.cache.feed' => 'boolean',
@@ -56,22 +58,23 @@ class W3_Config
56
  'pgcache.reject.uri' => 'array',
57
  'pgcache.reject.ua' => 'array',
58
  'pgcache.reject.cookie' => 'array',
59
- 'pgcache.mobile.check' => 'boolean',
60
- 'pgcache.mobile.whitelist' => 'array',
61
- 'pgcache.mobile.browsers' => 'array',
62
 
63
  'minify.enabled' => 'boolean',
64
  'minify.debug' => 'boolean',
65
  'minify.engine' => 'string',
 
 
66
  'minify.memcached.engine' => 'string',
67
  'minify.memcached.servers' => 'array',
68
  'minify.rewrite' => 'boolean',
69
- 'minify.locking' => 'string',
70
  'minify.fixtime' => 'integer',
71
  'minify.compress' => 'boolean',
72
  'minify.compress.ie6' => 'boolean',
73
  'minify.options' => 'array',
74
  'minify.symlinks' => 'array',
 
75
  'minify.lifetime' => 'integer',
76
  'minify.upload' => 'boolean',
77
  'minify.html.enable' => 'boolean',
@@ -95,7 +98,6 @@ class W3_Config
95
  'cdn.enabled' => 'boolean',
96
  'cdn.debug' => 'boolean',
97
  'cdn.engine' => 'string',
98
- 'cdn.domain' => 'string',
99
  'cdn.includes.enable' => 'boolean',
100
  'cdn.includes.files' => 'string',
101
  'cdn.theme.enable' => 'boolean',
@@ -106,23 +108,321 @@ class W3_Config
106
  'cdn.import.external' => 'boolean',
107
  'cdn.import.files' => 'string',
108
  'cdn.limit.queue' => 'integer',
 
109
  'cdn.ftp.host' => 'string',
110
  'cdn.ftp.user' => 'string',
111
  'cdn.ftp.pass' => 'string',
112
  'cdn.ftp.path' => 'string',
113
  'cdn.ftp.pasv' => 'boolean',
 
 
 
 
 
 
 
 
 
114
  'cdn.reject.ua' => 'array',
115
  'cdn.reject.uri' => 'array',
116
 
117
- 'common.support.enabled' => 'boolean',
118
- 'common.support.type' => 'string',
 
 
119
 
120
  'notes.defaults' => 'boolean',
121
  'notes.wp_content_perms' => 'boolean',
122
  'notes.cdn_first_time' => 'boolean',
123
- 'notes.no_memcached_nor_apc' => 'boolean'
 
 
 
 
 
 
 
 
 
 
 
 
124
  );
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  /**
127
  * Returns config value
128
  *
@@ -132,11 +432,68 @@ class W3_Config
132
  */
133
  function get($key, $default = null)
134
  {
135
- if (isset($this->_keys[$key]) && array_key_exists($key, $this->_config)) {
136
- return $this->_config[$key];
 
 
 
 
 
 
137
  }
138
 
139
- return $default;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  }
141
 
142
  /**
@@ -198,7 +555,7 @@ class W3_Config
198
  */
199
  function set($key, $value)
200
  {
201
- if (isset($this->_keys[$key])) {
202
  $type = $this->_keys[$key];
203
  settype($value, $type);
204
  $this->_config[$key] = $value;
@@ -224,7 +581,7 @@ class W3_Config
224
  function read($file)
225
  {
226
  if (file_exists($file) && is_readable($file)) {
227
- $config = include $file;
228
 
229
  if (! is_array($config)) {
230
  return false;
@@ -289,22 +646,24 @@ class W3_Config
289
  */
290
  function write($file)
291
  {
292
- @$fp = fopen($file, 'w');
293
- if (! $fp) {
294
- return false;
295
- }
296
-
297
- @fputs($fp, "<?php\r\n\r\nreturn array(\r\n");
298
 
299
- $this->_tabs = 1;
300
- foreach ($this->_config as $key => $value) {
301
- $this->_write($fp, $key, $value);
 
 
 
 
 
 
 
 
 
 
302
  }
303
 
304
- @fputs($fp, ");");
305
- @fclose($fp);
306
-
307
- return true;
308
  }
309
 
310
  /**
@@ -361,7 +720,7 @@ class W3_Config
361
 
362
  /**
363
  * Loads config
364
- *
365
  * @return boolean
366
  */
367
  function load()
@@ -370,18 +729,18 @@ class W3_Config
370
  }
371
 
372
  /**
373
- * Loads default config
374
- *
375
- * @return boolean
376
  */
377
- function load_default()
378
  {
379
- return $this->read(W3TC_CONFIG_DEFAULT_PATH);
 
 
380
  }
381
 
382
  /**
383
  * Saves config
384
- *
385
  * @return boolean
386
  */
387
  function save()
@@ -397,24 +756,13 @@ class W3_Config
397
  */
398
  function &instance($check_config = true)
399
  {
400
- static $instance = null;
401
 
402
- if ($instance === null) {
403
  $class = __CLASS__;
404
- $instance = & new $class();
405
-
406
- if (! $instance->load_default()) {
407
- debug_print_backtrace();
408
-
409
- die(sprintf('<strong>W3 Total Cache Error:</strong> Unable to read default config file <strong>%s</strong> or it is broken. Please re-install plugin.', W3TC_CONFIG_DEFAULT_PATH));
410
- }
411
-
412
- if (! $instance->load() && $check_config) {
413
- debug_print_backtrace();
414
- die(sprintf('<strong>W3 Total Cache Error:</strong> Unable to read config file or it is broken. Please create <strong>%s</strong> from <strong>%s</strong>.', W3TC_CONFIG_PATH, W3TC_CONFIG_DEFAULT_PATH));
415
- }
416
  }
417
 
418
- return $instance;
419
  }
420
  }
30
  'dbcache.enabled' => 'boolean',
31
  'dbcache.debug' => 'boolean',
32
  'dbcache.engine' => 'string',
33
+ 'dbcache.file.gc' => 'integer',
34
  'dbcache.memcached.engine' => 'string',
35
  'dbcache.memcached.servers' => 'array',
36
+ 'dbcache.reject.logged' => 'boolean',
37
  'dbcache.reject.uri' => 'array',
38
  'dbcache.reject.cookie' => 'array',
39
  'dbcache.reject.sql' => 'array',
42
  'pgcache.enabled' => 'boolean',
43
  'pgcache.debug' => 'boolean',
44
  'pgcache.engine' => 'string',
45
+ 'pgcache.file.gc' => 'integer',
46
  'pgcache.memcached.engine' => 'string',
47
  'pgcache.memcached.servers' => 'array',
48
  'pgcache.lifetime' => 'integer',
49
+ 'pgcache.compression' => 'string',
50
  'pgcache.cache.query' => 'boolean',
51
  'pgcache.cache.home' => 'boolean',
52
  'pgcache.cache.feed' => 'boolean',
58
  'pgcache.reject.uri' => 'array',
59
  'pgcache.reject.ua' => 'array',
60
  'pgcache.reject.cookie' => 'array',
61
+ 'pgcache.mobile.redirect' => 'string',
62
+ 'pgcache.mobile.agents' => 'array',
 
63
 
64
  'minify.enabled' => 'boolean',
65
  'minify.debug' => 'boolean',
66
  'minify.engine' => 'string',
67
+ 'minify.file.locking' => 'boolean',
68
+ 'minify.file.gc' => 'integer',
69
  'minify.memcached.engine' => 'string',
70
  'minify.memcached.servers' => 'array',
71
  'minify.rewrite' => 'boolean',
 
72
  'minify.fixtime' => 'integer',
73
  'minify.compress' => 'boolean',
74
  'minify.compress.ie6' => 'boolean',
75
  'minify.options' => 'array',
76
  'minify.symlinks' => 'array',
77
+ 'minify.maxage' => 'integer',
78
  'minify.lifetime' => 'integer',
79
  'minify.upload' => 'boolean',
80
  'minify.html.enable' => 'boolean',
98
  'cdn.enabled' => 'boolean',
99
  'cdn.debug' => 'boolean',
100
  'cdn.engine' => 'string',
 
101
  'cdn.includes.enable' => 'boolean',
102
  'cdn.includes.files' => 'string',
103
  'cdn.theme.enable' => 'boolean',
108
  'cdn.import.external' => 'boolean',
109
  'cdn.import.files' => 'string',
110
  'cdn.limit.queue' => 'integer',
111
+ 'cdn.mirror.domain' => 'string',
112
  'cdn.ftp.host' => 'string',
113
  'cdn.ftp.user' => 'string',
114
  'cdn.ftp.pass' => 'string',
115
  'cdn.ftp.path' => 'string',
116
  'cdn.ftp.pasv' => 'boolean',
117
+ 'cdn.ftp.domain' => 'string',
118
+ 'cdn.s3.key' => 'string',
119
+ 'cdn.s3.secret' => 'string',
120
+ 'cdn.s3.bucket' => 'string',
121
+ 'cdn.cf.key' => 'string',
122
+ 'cdn.cf.secret' => 'string',
123
+ 'cdn.cf.bucket' => 'string',
124
+ 'cdn.cf.id' => 'string',
125
+ 'cdn.cf.cname' => 'string',
126
  'cdn.reject.ua' => 'array',
127
  'cdn.reject.uri' => 'array',
128
 
129
+ 'common.support' => 'string',
130
+ 'common.install' => 'integer',
131
+ 'common.tweeted' => 'integer',
132
+ 'common.widget.latest' => 'boolean',
133
 
134
  'notes.defaults' => 'boolean',
135
  'notes.wp_content_perms' => 'boolean',
136
  'notes.cdn_first_time' => 'boolean',
137
+ 'notes.no_memcached_nor_apc' => 'boolean',
138
+ 'notes.php_is_old' => 'boolean',
139
+ 'notes.theme_changed' => 'boolean',
140
+ 'notes.wp_upgraded' => 'boolean',
141
+ 'notes.plugins_updated' => 'boolean',
142
+ 'notes.cdn_upload' => 'boolean',
143
+ 'notes.need_empty_pgcache' => 'boolean',
144
+ 'notes.need_empty_minify' => 'boolean',
145
+ 'notes.pgcache_rules_core' => 'boolean',
146
+ 'notes.pgcache_rules_cache' => 'boolean',
147
+ 'notes.minify_rules' => 'boolean',
148
+ 'notes.support_us' => 'boolean',
149
+ 'notes.no_curl' => 'boolean'
150
  );
151
 
152
+ var $_defaults = array(
153
+ 'dbcache.enabled' => true,
154
+ 'dbcache.debug' => false,
155
+ 'dbcache.engine' => 'file',
156
+ 'dbcache.file.gc' => 3600,
157
+ 'dbcache.memcached.engine' => 'auto',
158
+ 'dbcache.memcached.servers' => array(
159
+ 'localhost:11211'
160
+ ),
161
+ 'dbcache.reject.logged' => true,
162
+ 'dbcache.reject.uri' => array(),
163
+ 'dbcache.reject.cookie' => array(),
164
+ 'dbcache.reject.sql' => array(),
165
+ 'dbcache.lifetime' => 180,
166
+
167
+ 'pgcache.enabled' => true,
168
+ 'pgcache.debug' => false,
169
+ 'pgcache.engine' => 'file',
170
+ 'pgcache.file.gc' => 3600,
171
+ 'pgcache.memcached.engine' => 'auto',
172
+ 'pgcache.memcached.servers' => array(
173
+ 'localhost:11211'
174
+ ),
175
+ 'pgcache.lifetime' => 3600,
176
+ 'pgcache.compression' => 'gzip',
177
+ 'pgcache.cache.query' => true,
178
+ 'pgcache.cache.home' => true,
179
+ 'pgcache.cache.feed' => true,
180
+ 'pgcache.cache.404' => false,
181
+ 'pgcache.cache.flush' => false,
182
+ 'pgcache.cache.headers' => array(
183
+ 'Last-Modified',
184
+ 'Content-Type',
185
+ 'X-Pingback'
186
+ ),
187
+ 'pgcache.accept.files' => array(
188
+ 'wp-comments-popup.php',
189
+ 'wp-links-opml.php',
190
+ 'wp-locations.php'
191
+ ),
192
+ 'pgcache.reject.logged' => true,
193
+ 'pgcache.reject.uri' => array(
194
+ 'wp-.*\.php',
195
+ 'index\.php'
196
+ ),
197
+ 'pgcache.reject.ua' => array(
198
+ 'bot',
199
+ 'ia_archive',
200
+ 'slurp',
201
+ 'crawl',
202
+ 'spider'
203
+ ),
204
+ 'pgcache.reject.cookie' => array(),
205
+ 'pgcache.mobile.redirect' => '',
206
+ 'pgcache.mobile.agents' => array(
207
+ 'Android',
208
+ '2.0 MMP',
209
+ '240x320',
210
+ 'AvantGo',
211
+ 'BlackBerry',
212
+ 'Blazer',
213
+ 'Cellphone',
214
+ 'Danger',
215
+ 'DoCoMo',
216
+ 'Elaine/3.0',
217
+ 'EudoraWeb',
218
+ 'hiptop',
219
+ 'IEMobile',
220
+ 'iPhone',
221
+ 'iPod',
222
+ 'KYOCERA/WX310K',
223
+ 'LG/U990',
224
+ 'MIDP-2.0',
225
+ 'MMEF20',
226
+ 'MOT-V',
227
+ 'NetFront',
228
+ 'Newt',
229
+ 'Nintendo Wii',
230
+ 'Nitro',
231
+ 'Nokia',
232
+ 'Opera Mini',
233
+ 'Palm',
234
+ 'Playstation Portable',
235
+ 'portalmmm',
236
+ 'Proxinet',
237
+ 'ProxiNet',
238
+ 'SHARP-TQ-GX10',
239
+ 'Small',
240
+ 'SonyEricsson',
241
+ 'Symbian OS',
242
+ 'SymbianOS',
243
+ 'TS21i-10',
244
+ 'UP.Browser',
245
+ 'UP.Link',
246
+ 'Windows CE',
247
+ 'WinWAP',
248
+ 'Ericsson',
249
+ 'htc',
250
+ 'Huawei',
251
+ 'MobilePhone',
252
+ 'Motorola',
253
+ 'nokia',
254
+ 'Novarra',
255
+ 'O2',
256
+ 'Samsung',
257
+ 'Sanyo',
258
+ 'Smartphone',
259
+ 'Symbian',
260
+ 'Toshiba',
261
+ 'Treo',
262
+ 'vodafone',
263
+ 'Xda',
264
+ 'Alcatel',
265
+ 'Amoi',
266
+ 'ASUS',
267
+ 'Audiovox',
268
+ 'AU-MIC',
269
+ 'BenQ',
270
+ 'Bird',
271
+ 'CDM',
272
+ 'dopod',
273
+ 'Fly',
274
+ 'Haier',
275
+ 'HP.iPAQ',
276
+ 'i-mobile',
277
+ 'KDDI',
278
+ 'KONKA',
279
+ 'KWC',
280
+ 'Lenovo',
281
+ 'LG',
282
+ 'NEWGEN',
283
+ 'Panasonic',
284
+ 'PANTECH',
285
+ 'PG',
286
+ 'Philips',
287
+ 'PPC',
288
+ 'PT',
289
+ 'Qtek',
290
+ 'Sagem',
291
+ 'SCH',
292
+ 'SEC',
293
+ 'Sendo',
294
+ 'SGH',
295
+ 'Sharp',
296
+ 'SIE',
297
+ 'SoftBank',
298
+ 'SPH',
299
+ 'UTS',
300
+ 'Vertu',
301
+ 'Opera.Mobi',
302
+ 'Windows.CE',
303
+ 'ZTE'
304
+ ),
305
+
306
+ 'minify.enabled' => true,
307
+ 'minify.debug' => false,
308
+ 'minify.engine' => 'file',
309
+ 'minify.file.locking' => true,
310
+ 'minify.file.gc' => 86400,
311
+ 'minify.memcached.engine' => 'auto',
312
+ 'minify.memcached.servers' => array(
313
+ 'localhost:11211'
314
+ ),
315
+ 'minify.rewrite' => true,
316
+ 'minify.fixtime' => 0,
317
+ 'minify.compress' => true,
318
+ 'minify.compress.ie6' => true,
319
+ 'minify.options' => array(
320
+ 'bubbleCssImports' => false,
321
+ 'minApp' => array(
322
+ 'groupsOnly' => false,
323
+ 'maxFiles' => 20
324
+ )
325
+ ),
326
+ 'minify.symlinks' => array(),
327
+ 'minify.maxage' => 86400,
328
+ 'minify.lifetime' => 86400,
329
+ 'minify.upload' => true,
330
+ 'minify.html.enable' => true,
331
+ 'minify.html.reject.admin' => true,
332
+ 'minify.html.inline.css' => false,
333
+ 'minify.html.inline.js' => false,
334
+ 'minify.html.strip.crlf' => false,
335
+ 'minify.css.enable' => true,
336
+ 'minify.css.strip.comments' => false,
337
+ 'minify.css.strip.crlf' => false,
338
+ 'minify.css.groups' => array(),
339
+ 'minify.js.enable' => true,
340
+ 'minify.js.combine.header' => false,
341
+ 'minify.js.combine.footer' => false,
342
+ 'minify.js.strip.comments' => false,
343
+ 'minify.js.strip.crlf' => false,
344
+ 'minify.js.groups' => array(),
345
+ 'minify.reject.ua' => array(),
346
+ 'minify.reject.uri' => array(),
347
+
348
+ 'cdn.enabled' => false,
349
+ 'cdn.debug' => false,
350
+ 'cdn.engine' => 'ftp',
351
+ 'cdn.includes.enable' => true,
352
+ 'cdn.includes.files' => '*.css;*.js;*.gif;*.png;*.jpg',
353
+ 'cdn.theme.enable' => true,
354
+ 'cdn.theme.files' => '*.css;*.js;*.gif;*.png;*.jpg;*.ico',
355
+ 'cdn.minify.enable' => true,
356
+ 'cdn.custom.enable' => true,
357
+ 'cdn.custom.files' => array(
358
+ 'favicon.ico'
359
+ ),
360
+ 'cdn.import.external' => false,
361
+ 'cdn.import.files' => '*.jpg;*.png;*.gif;*.avi;*.wmv;*.mpg;*.wav;*.mp3;*.txt;*.rtf;*.doc;*.xls;*.rar;*.zip;*.tar;*.gz;*.exe',
362
+ 'cdn.limit.queue' => 25,
363
+ 'cdn.mirror.domain' => '',
364
+ 'cdn.ftp.host' => '',
365
+ 'cdn.ftp.user' => '',
366
+ 'cdn.ftp.pass' => '',
367
+ 'cdn.ftp.path' => '',
368
+ 'cdn.ftp.pasv' => false,
369
+ 'cdn.ftp.domain' => '',
370
+ 'cdn.s3.key' => '',
371
+ 'cdn.s3.secret' => '',
372
+ 'cdn.s3.bucket' => '',
373
+ 'cdn.cf.key' => '',
374
+ 'cdn.cf.secret' => '',
375
+ 'cdn.cf.bucket' => '',
376
+ 'cdn.cf.id' => '',
377
+ 'cdn.cf.cname' => '',
378
+ 'cdn.reject.ua' => array(),
379
+ 'cdn.reject.uri' => array(),
380
+
381
+ 'common.support' => '',
382
+ 'common.install' => 0,
383
+ 'common.tweeted' => 0,
384
+ 'common.widget.latest' => true,
385
+
386
+ 'notes.defaults' => true,
387
+ 'notes.wp_content_perms' => true,
388
+ 'notes.cdn_first_time' => true,
389
+ 'notes.no_memcached_nor_apc' => true,
390
+ 'notes.php_is_old' => true,
391
+ 'notes.theme_changed' => false,
392
+ 'notes.wp_upgraded' => false,
393
+ 'notes.plugins_updated' => false,
394
+ 'notes.cdn_upload' => false,
395
+ 'notes.need_empty_pgcache' => false,
396
+ 'notes.need_empty_minify' => false,
397
+ 'notes.pgcache_rules_core' => true,
398
+ 'notes.pgcache_rules_cache' => true,
399
+ 'notes.minify_rules' => true,
400
+ 'notes.support_us' => true,
401
+ 'notes.no_curl' => true
402
+ );
403
+
404
+ /**
405
+ * PHP5 Constructor
406
+ * @param boolean $check_config
407
+ */
408
+ function __construct($check_config = true)
409
+ {
410
+ $this->load_defaults();
411
+
412
+ if (! $this->load() && $check_config) {
413
+ die(sprintf('<strong>W3 Total Cache Error:</strong> Unable to read config file or it is broken. Please create <strong>%s</strong> from <strong>%s</strong>.', W3TC_CONFIG_PATH, W3TC_CONFIG_EXAMPLE_PATH));
414
+ }
415
+ }
416
+
417
+ /**
418
+ * PHP4 Constructor
419
+ * @param booleab $check_config
420
+ */
421
+ function W3_Config($check_config = true)
422
+ {
423
+ $this->__construct($check_config);
424
+ }
425
+
426
  /**
427
  * Returns config value
428
  *
432
  */
433
  function get($key, $default = null)
434
  {
435
+ if (array_key_exists($key, $this->_keys) && array_key_exists($key, $this->_config)) {
436
+ $value = $this->_config[$key];
437
+ } else {
438
+ if ($default === null && array_key_exists($key, $this->_defaults)) {
439
+ $value = $this->_defaults[$key];
440
+ } else {
441
+ $value = $default;
442
+ }
443
  }
444
 
445
+ switch ($key) {
446
+ /**
447
+ * Disable compression if compression functions don't exist
448
+ */
449
+ case 'pgcache.compression':
450
+ if ((stristr($value, 'gzip') && ! function_exists('gzencode')) || (stristr($value, 'deflate') && ! function_exists('gzdeflate'))) {
451
+ return '';
452
+ }
453
+ break;
454
+
455
+ /**
456
+ * Don't support additional headers caching when PHP5 is not installed
457
+ */
458
+ case 'pgcache.cache.headers':
459
+ if (! W3TC_PHP5) {
460
+ return array();
461
+ }
462
+ break;
463
+
464
+ /**
465
+ * Disabled some page cache options when enchanced mode enabled
466
+ */
467
+ case 'pgcache.cache.query':
468
+ if ($this->get_boolean('pgcache.enabled') && $this->get_string('pgcache.engine') == 'file_pgcache') {
469
+ return false;
470
+ }
471
+ break;
472
+
473
+ case 'pgcache.cache.headers':
474
+ if ($this->get_boolean('pgcache.enabled') && $this->get_string('pgcache.engine') == 'file_pgcache') {
475
+ return array();
476
+ }
477
+ break;
478
+
479
+ /**
480
+ * Disabled minify when PHP5 is not installed
481
+ */
482
+ case 'minify.enabled':
483
+ case 'cdn.minify.enable':
484
+ if (! W3TC_PHP5) {
485
+ return false;
486
+ }
487
+ break;
488
+
489
+ case 'cdn.engine':
490
+ if (($value == 's3' || $value == 'cf') && (! W3TC_PHP5 || ! function_exists('curl_init'))) {
491
+ return 'mirror';
492
+ }
493
+ break;
494
+ }
495
+
496
+ return $value;
497
  }
498
 
499
  /**
555
  */
556
  function set($key, $value)
557
  {
558
+ if (array_key_exists($key, $this->_keys)) {
559
  $type = $this->_keys[$key];
560
  settype($value, $type);
561
  $this->_config[$key] = $value;
581
  function read($file)
582
  {
583
  if (file_exists($file) && is_readable($file)) {
584
+ $config = @include $file;
585
 
586
  if (! is_array($config)) {
587
  return false;
646
  */
647
  function write($file)
648
  {
649
+ $fp = @fopen($file, 'w');
 
 
 
 
 
650
 
651
+ if ($fp) {
652
+ @fputs($fp, "<?php\r\n\r\nreturn array(\r\n");
653
+
654
+ $this->_tabs = 1;
655
+
656
+ foreach ($this->_config as $key => $value) {
657
+ $this->_write($fp, $key, $value);
658
+ }
659
+
660
+ @fputs($fp, ");");
661
+ @fclose($fp);
662
+
663
+ return true;
664
  }
665
 
666
+ return false;
 
 
 
667
  }
668
 
669
  /**
720
 
721
  /**
722
  * Loads config
723
+ *
724
  * @return boolean
725
  */
726
  function load()
729
  }
730
 
731
  /**
732
+ * Loads config dfefaults
 
 
733
  */
734
+ function load_defaults()
735
  {
736
+ foreach ($this->_defaults as $key => $value) {
737
+ $this->set($key, $value);
738
+ }
739
  }
740
 
741
  /**
742
  * Saves config
743
+ *
744
  * @return boolean
745
  */
746
  function save()
756
  */
757
  function &instance($check_config = true)
758
  {
759
+ static $instances = array();
760
 
761
+ if (! isset($instances[0])) {
762
  $class = __CLASS__;
763
+ $instances[0] = & new $class($check_config);
 
 
 
 
 
 
 
 
 
 
 
764
  }
765
 
766
+ return $instances[0];
767
  }
768
  }
lib/W3/Db.php CHANGED
@@ -3,15 +3,8 @@
3
  /**
4
  * W3 Database object
5
  */
6
-
7
- /**
8
- * @global w3db $wpdb
9
- */
10
  $wpdb = false;
11
 
12
- /**
13
- * Require default WordPress database object
14
- */
15
  require_once ABSPATH . 'wp-includes/wp-db.php';
16
 
17
  /**
@@ -79,8 +72,8 @@ class W3_Db extends wpdb
79
  function __construct($dbuser, $dbpassword, $dbname, $dbhost)
80
  {
81
  require_once W3TC_LIB_W3_DIR . '/Config.php';
82
- $this->_config = W3_Config::instance();
83
- $this->_lifetime = $this->_config->get_integer('dbcache.lifetime', 180);
84
 
85
  parent::__construct($dbuser, $dbpassword, $dbname, $dbhost);
86
  }
@@ -112,20 +105,20 @@ class W3_Db extends wpdb
112
 
113
  ++ $this->query_total;
114
 
115
- // filter the query, if filters are available
116
- // NOTE: some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
117
  if (function_exists('apply_filters')) {
118
  $query = apply_filters('query', $query);
119
  }
120
 
121
- // initialise return
122
  $return_val = 0;
123
  $this->flush();
124
 
125
- // Log how the function was called
126
  $this->func_call = "\$db->query(\"$query\")";
127
 
128
- // Keep track of the last query for debug..
129
  $this->last_query = $query;
130
 
131
  $reason = '';
@@ -138,7 +131,7 @@ class W3_Db extends wpdb
138
  $cache_key = $this->_get_cache_key($query);
139
 
140
  $this->timer_start();
141
- $cache = $this->_get_cache();
142
  $data = $cache->get($cache_key);
143
  $time_total = $this->timer_stop();
144
  }
@@ -162,7 +155,7 @@ class W3_Db extends wpdb
162
  ++ $this->num_queries;
163
  ++ $this->query_misses;
164
 
165
- // Perform the query via std mysql_query function..
166
  $this->timer_start();
167
  $this->result = @mysql_query($query, $this->dbh);
168
  $time_total = $this->timer_stop();
@@ -175,21 +168,21 @@ class W3_Db extends wpdb
175
  );
176
  }
177
 
178
- // If there is an error then take note of it..
179
  if (($this->last_error = mysql_error($this->dbh))) {
180
  $this->print_error();
181
  return false;
182
  }
183
 
184
- if (preg_match("/^\\s*(insert|delete|update|replace|alter) /i", $query)) {
185
  $this->rows_affected = mysql_affected_rows($this->dbh);
186
- // Take note of the insert_id
187
  if (preg_match("/^\\s*(insert|replace) /i", $query)) {
188
  $this->insert_id = mysql_insert_id($this->dbh);
189
  }
190
- // Return number of rows affected
191
  $return_val = $this->rows_affected;
192
- } else {
193
  $i = 0;
194
  while ($i < @mysql_num_fields($this->result)) {
195
  $this->col_info[$i] = @mysql_fetch_field($this->result);
@@ -204,10 +197,10 @@ class W3_Db extends wpdb
204
 
205
  @mysql_free_result($this->result);
206
 
207
- // Log number of rows the query returned
208
  $this->num_rows = $num_rows;
209
 
210
- // Return number of rows selected
211
  $return_val = $this->num_rows;
212
 
213
  if ($caching) {
@@ -222,7 +215,7 @@ class W3_Db extends wpdb
222
  'num_rows' => $this->num_rows
223
  );
224
 
225
- $cache = $this->_get_cache();
226
  $cache->set($cache_key, $data, $this->_lifetime);
227
  }
228
  }
@@ -255,7 +248,7 @@ class W3_Db extends wpdb
255
  * Skip if disabled
256
  */
257
  if (! $this->_config->get_boolean('dbcache.enabled')) {
258
- $cache_reject_reason = 'Caching is disabled';
259
  return false;
260
  }
261
 
@@ -263,7 +256,7 @@ class W3_Db extends wpdb
263
  * Skip if doint AJAX
264
  */
265
  if (defined('DOING_AJAX')) {
266
- $cache_reject_reason = 'Doing AJAX';
267
  return false;
268
  }
269
 
@@ -271,7 +264,7 @@ class W3_Db extends wpdb
271
  * Skip if doing cron
272
  */
273
  if (defined('DOING_CRON')) {
274
- $cache_reject_reason = 'Doing cron';
275
  return false;
276
  }
277
 
@@ -279,7 +272,7 @@ class W3_Db extends wpdb
279
  * Skip if APP request
280
  */
281
  if (defined('APP_REQUEST')) {
282
- $cache_reject_reason = 'APP request';
283
  return false;
284
  }
285
 
@@ -295,7 +288,7 @@ class W3_Db extends wpdb
295
  * Skip if admin
296
  */
297
  if (defined('WP_ADMIN')) {
298
- $cache_reject_reason = 'Admin';
299
  return false;
300
  }
301
 
@@ -303,7 +296,7 @@ class W3_Db extends wpdb
303
  * Skip if SQL is rejected
304
  */
305
  if (! $this->_check_sql($sql)) {
306
- $cache_reject_reason = 'SQL rejected';
307
  return false;
308
  }
309
 
@@ -311,7 +304,7 @@ class W3_Db extends wpdb
311
  * Skip if request URI is rejected
312
  */
313
  if (! $this->_check_request_uri()) {
314
- $cache_reject_reason = 'URI rejected';
315
  return false;
316
  }
317
 
@@ -319,15 +312,15 @@ class W3_Db extends wpdb
319
  * Skip if cookie is rejected
320
  */
321
  if (! $this->_check_cookies()) {
322
- $cache_reject_reason = 'Cookie rejected';
323
  return false;
324
  }
325
 
326
  /**
327
  * Skip if user is logged in
328
  */
329
- if (! $this->_check_logged_in()) {
330
- $cache_reject_reason = 'User is logged in';
331
  return false;
332
  }
333
 
@@ -341,7 +334,7 @@ class W3_Db extends wpdb
341
  */
342
  function flush_cache()
343
  {
344
- $cache = $this->_get_cache();
345
 
346
  return $cache->flush();
347
  }
@@ -353,19 +346,19 @@ class W3_Db extends wpdb
353
  */
354
  function &instance()
355
  {
356
- static $instance = null;
357
 
358
- if ($instance === null) {
359
  $class = __CLASS__;
360
- $instance = & new $class(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
361
  }
362
 
363
- return $instance;
364
  }
365
 
366
  /**
367
  * Returns debug info
368
- *
369
  * @return string
370
  */
371
  function get_debug_info()
@@ -396,15 +389,15 @@ class W3_Db extends wpdb
396
  */
397
  function &_get_cache()
398
  {
399
- static $cache = null;
400
 
401
- if ($cache === null) {
402
- $engine = $this->_config->get_string('dbcache.engine', 'memcached');
403
 
404
  switch ($engine) {
405
  case 'memcached':
406
  $engineConfig = array(
407
- 'engine' => $this->_config->get_string('dbcache.memcached.engine', 'auto'),
408
  'servers' => $this->_config->get_array('dbcache.memcached.servers'),
409
  'persistant' => true
410
  );
@@ -412,7 +405,7 @@ class W3_Db extends wpdb
412
 
413
  case 'file':
414
  $engineConfig = array(
415
- 'cache_dir' => W3TC_CACHE_FILE_DIR
416
  );
417
  break;
418
 
@@ -421,10 +414,10 @@ class W3_Db extends wpdb
421
  }
422
 
423
  require_once W3TC_LIB_W3_DIR . '/Cache.php';
424
- $cache = & W3_Cache::instance($engine, $engineConfig);
425
  }
426
 
427
- return $cache;
428
  }
429
 
430
  /**
@@ -436,19 +429,20 @@ class W3_Db extends wpdb
436
  function _check_sql($sql)
437
  {
438
  $auto_reject_strings = array(
439
- 'insert',
440
- 'delete',
441
- 'update',
442
- 'replace',
443
- 'alter',
444
- 'set names',
445
- 'found_rows',
446
- $this->prefix . 'posts',
447
- $this->prefix . 'postmeta',
448
- $this->prefix . 'comments'
 
449
  );
450
 
451
- if (preg_match('@(' . implode('|', $auto_reject_strings) . ')@i', $sql)) {
452
  return false;
453
  }
454
 
@@ -456,6 +450,7 @@ class W3_Db extends wpdb
456
 
457
  foreach ($reject_sql as $expr) {
458
  $expr = trim($expr);
 
459
  if ($expr != '' && preg_match('@' . $expr . '@i', $sql)) {
460
  return false;
461
  }
@@ -495,7 +490,7 @@ class W3_Db extends wpdb
495
  }
496
 
497
  /**
498
- * Checks WordPress cookies
499
  *
500
  * @return boolean
501
  */
@@ -523,7 +518,7 @@ class W3_Db extends wpdb
523
 
524
  /**
525
  * Check if user is logged in
526
- *
527
  * @return boolean
528
  */
529
  function _check_logged_in()
3
  /**
4
  * W3 Database object
5
  */
 
 
 
 
6
  $wpdb = false;
7
 
 
 
 
8
  require_once ABSPATH . 'wp-includes/wp-db.php';
9
 
10
  /**
72
  function __construct($dbuser, $dbpassword, $dbname, $dbhost)
73
  {
74
  require_once W3TC_LIB_W3_DIR . '/Config.php';
75
+ $this->_config = & W3_Config::instance();
76
+ $this->_lifetime = $this->_config->get_integer('dbcache.lifetime');
77
 
78
  parent::__construct($dbuser, $dbpassword, $dbname, $dbhost);
79
  }
105
 
106
  ++ $this->query_total;
107
 
108
+ // Filter the query, if filters are available
109
+ // NOTE: Some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
110
  if (function_exists('apply_filters')) {
111
  $query = apply_filters('query', $query);
112
  }
113
 
114
+ // Initialise return
115
  $return_val = 0;
116
  $this->flush();
117
 
118
+ // Log how the function was called
119
  $this->func_call = "\$db->query(\"$query\")";
120
 
121
+ // Keep track of the last query for debug..
122
  $this->last_query = $query;
123
 
124
  $reason = '';
131
  $cache_key = $this->_get_cache_key($query);
132
 
133
  $this->timer_start();
134
+ $cache = & $this->_get_cache();
135
  $data = $cache->get($cache_key);
136
  $time_total = $this->timer_stop();
137
  }
155
  ++ $this->num_queries;
156
  ++ $this->query_misses;
157
 
158
+ // Perform the query via std mysql_query function..
159
  $this->timer_start();
160
  $this->result = @mysql_query($query, $this->dbh);
161
  $time_total = $this->timer_stop();
168
  );
169
  }
170
 
171
+ // If there is an error then take note of it..
172
  if (($this->last_error = mysql_error($this->dbh))) {
173
  $this->print_error();
174
  return false;
175
  }
176
 
177
+ if (preg_match("/^\\s*(insert|delete|update|replace|alter)\\s+/si", $query)) {
178
  $this->rows_affected = mysql_affected_rows($this->dbh);
179
+ // Take note of the insert_id
180
  if (preg_match("/^\\s*(insert|replace) /i", $query)) {
181
  $this->insert_id = mysql_insert_id($this->dbh);
182
  }
183
+ // Return number of rows affected
184
  $return_val = $this->rows_affected;
185
+ } elseif (is_resource($this->result)) {
186
  $i = 0;
187
  while ($i < @mysql_num_fields($this->result)) {
188
  $this->col_info[$i] = @mysql_fetch_field($this->result);
197
 
198
  @mysql_free_result($this->result);
199
 
200
+ // Log number of rows the query returned
201
  $this->num_rows = $num_rows;
202
 
203
+ // Return number of rows selected
204
  $return_val = $this->num_rows;
205
 
206
  if ($caching) {
215
  'num_rows' => $this->num_rows
216
  );
217
 
218
+ $cache = & $this->_get_cache();
219
  $cache->set($cache_key, $data, $this->_lifetime);
220
  }
221
  }
248
  * Skip if disabled
249
  */
250
  if (! $this->_config->get_boolean('dbcache.enabled')) {
251
+ $cache_reject_reason = 'database caching is disabled';
252
  return false;
253
  }
254
 
256
  * Skip if doint AJAX
257
  */
258
  if (defined('DOING_AJAX')) {
259
+ $cache_reject_reason = 'doing AJAX';
260
  return false;
261
  }
262
 
264
  * Skip if doing cron
265
  */
266
  if (defined('DOING_CRON')) {
267
+ $cache_reject_reason = 'doing cron';
268
  return false;
269
  }
270
 
272
  * Skip if APP request
273
  */
274
  if (defined('APP_REQUEST')) {
275
+ $cache_reject_reason = 'application request';
276
  return false;
277
  }
278
 
288
  * Skip if admin
289
  */
290
  if (defined('WP_ADMIN')) {
291
+ $cache_reject_reason = 'wp-admin';
292
  return false;
293
  }
294
 
296
  * Skip if SQL is rejected
297
  */
298
  if (! $this->_check_sql($sql)) {
299
+ $cache_reject_reason = 'query is rejected';
300
  return false;
301
  }
302
 
304
  * Skip if request URI is rejected
305
  */
306
  if (! $this->_check_request_uri()) {
307
+ $cache_reject_reason = 'request URI is rejected';
308
  return false;
309
  }
310
 
312
  * Skip if cookie is rejected
313
  */
314
  if (! $this->_check_cookies()) {
315
+ $cache_reject_reason = 'cookie is rejected';
316
  return false;
317
  }
318
 
319
  /**
320
  * Skip if user is logged in
321
  */
322
+ if ($this->_config->get_boolean('dbcache.reject.logged') && ! $this->_check_logged_in()) {
323
+ $cache_reject_reason = 'user is logged in';
324
  return false;
325
  }
326
 
334
  */
335
  function flush_cache()
336
  {
337
+ $cache = & $this->_get_cache();
338
 
339
  return $cache->flush();
340
  }
346
  */
347
  function &instance()
348
  {
349
+ static $instances = array();
350
 
351
+ if (! isset($instances[0])) {
352
  $class = __CLASS__;
353
+ $instances[0] = & new $class(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
354
  }
355
 
356
+ return $instances[0];
357
  }
358
 
359
  /**
360
  * Returns debug info
361
+ *
362
  * @return string
363
  */
364
  function get_debug_info()
389
  */
390
  function &_get_cache()
391
  {
392
+ static $cache = array();
393
 
394
+ if (! isset($cache[0])) {
395
+ $engine = $this->_config->get_string('dbcache.engine');
396
 
397
  switch ($engine) {
398
  case 'memcached':
399
  $engineConfig = array(
400
+ 'engine' => $this->_config->get_string('dbcache.memcached.engine'),
401
  'servers' => $this->_config->get_array('dbcache.memcached.servers'),
402
  'persistant' => true
403
  );
405
 
406
  case 'file':
407
  $engineConfig = array(
408
+ 'cache_dir' => W3TC_CACHE_FILE_DBCACHE_DIR
409
  );
410
  break;
411
 
414
  }
415
 
416
  require_once W3TC_LIB_W3_DIR . '/Cache.php';
417
+ $cache[0] = & W3_Cache::instance($engine, $engineConfig);
418
  }
419
 
420
+ return $cache[0];
421
  }
422
 
423
  /**
429
  function _check_sql($sql)
430
  {
431
  $auto_reject_strings = array(
432
+ '^\s*insert',
433
+ '^\s*delete',
434
+ '^\s*update',
435
+ '^\s*replace',
436
+ '^\s*create',
437
+ '^\s*alter',
438
+ '^\s*show',
439
+ '^\s*set',
440
+ 'sql_calc_found_rows',
441
+ 'found_rows\(\)',
442
+ 'w3tc_request_data'
443
  );
444
 
445
+ if (preg_match('@' . implode('|', $auto_reject_strings) . '@is', $sql)) {
446
  return false;
447
  }
448
 
450
 
451
  foreach ($reject_sql as $expr) {
452
  $expr = trim($expr);
453
+ $expr = str_replace('{prefix}', $this->prefix, $expr);
454
  if ($expr != '' && preg_match('@' . $expr . '@i', $sql)) {
455
  return false;
456
  }
490
  }
491
 
492
  /**
493
+ * Checks for WordPress cookies
494
  *
495
  * @return boolean
496
  */
518
 
519
  /**
520
  * Check if user is logged in
521
+ *
522
  * @return boolean
523
  */
524
  function _check_logged_in()
lib/W3/Minify.php CHANGED
@@ -11,7 +11,7 @@ class W3_Minify
11
  {
12
  /**
13
  * Config
14
- *
15
  * @var W3_Config
16
  */
17
  var $_config = null;
@@ -29,8 +29,7 @@ class W3_Minify
29
  function __construct()
30
  {
31
  require_once W3TC_LIB_W3_DIR . '/Config.php';
32
- $this->_config = W3_Config::instance();
33
- set_include_path(get_include_path() . PATH_SEPARATOR . W3TC_LIB_MINIFY_DIR);
34
  }
35
 
36
  /**
@@ -50,13 +49,14 @@ class W3_Minify
50
  require_once W3TC_LIB_MINIFY_DIR . '/Minify.php';
51
  require_once W3TC_LIB_MINIFY_DIR . '/HTTP/Encoder.php';
52
 
53
- HTTP_Encoder::$encodeToIe6 = $this->_config->get_boolean('minify.comprss.ie6', true);
54
 
55
  Minify::$uploaderHoursBehind = $this->_config->get_integer('minify.fixtime');
56
  Minify::setCache($this->_get_cache());
57
 
58
  $serve_options = $this->_config->get_array('minify.options');
59
- $serve_options['encodeOutput'] = $this->_config->get_boolean('minify.compress', true);
 
60
  $serve_options['postprocessor'] = array(
61
  &$this,
62
  'postprocessor'
@@ -72,7 +72,7 @@ class W3_Minify
72
  $serve_options['minifierOptions']['text/css']['symlinks'][$link] = realpath($target);
73
  }
74
 
75
- if ($this->_config->get_boolean('minify.debug') && isset($_REQUEST['debug'])) {
76
  $serve_options['debug'] = true;
77
  }
78
 
@@ -97,9 +97,24 @@ class W3_Minify
97
  'minify_stub'
98
  );
99
  }
 
 
 
 
 
 
 
 
 
100
  }
101
 
102
- Minify::serve('MinApp', $serve_options);
 
 
 
 
 
 
103
  } else {
104
  die('This file cannot be accessed directly');
105
  }
@@ -141,7 +156,7 @@ class W3_Minify
141
  break;
142
  }
143
 
144
- return $content;
145
  }
146
 
147
  /**
@@ -151,17 +166,21 @@ class W3_Minify
151
  {
152
  static $cache_path = null;
153
 
154
- $cache = $this->_get_cache();
155
 
156
  if (is_a($cache, 'Minify_Cache_Memcache') && is_a($this->_memcached, 'W3_Cache_Memcached_Base')) {
157
  return $this->_memcached->flush();
158
  } elseif (is_a($cache, 'Minify_Cache_APC') && function_exists('apc_clear_cache')) {
159
  return apc_clear_cache('user');
160
  } elseif (is_a($cache, 'Minify_Cache_File')) {
161
- if (! is_dir(W3TC_CACHE_MINIFY_DIR)) {
162
- $this->log(sprintf('Cache directory %s does not exists', W3TC_CACHE_MINIFY_DIR));
163
  }
164
- return w3_emptydir(W3TC_CACHE_MINIFY_DIR);
 
 
 
 
165
  }
166
 
167
  return false;
@@ -174,14 +193,14 @@ class W3_Minify
174
  */
175
  function &instance()
176
  {
177
- static $instance = null;
178
 
179
- if ($instance === null) {
180
  $class = __CLASS__;
181
- $instance = & new $class();
182
  }
183
 
184
- return $instance;
185
  }
186
 
187
  /**
@@ -202,10 +221,9 @@ class W3_Minify
202
  */
203
  function log($object, $label = null)
204
  {
205
- $file = W3TC_LOG_DIR . '/minify.log';
206
  $data = sprintf("[%s] [%s] %s\n", date('r'), $_SERVER['REQUEST_URI'], $object);
207
 
208
- $fp = @fopen($file, 'a');
209
  if ($fp) {
210
  @fputs($fp, $data);
211
  @fclose($fp);
@@ -256,6 +274,10 @@ class W3_Minify
256
  $result[$location][$file] = $precached_file;
257
  }
258
  } else {
 
 
 
 
259
  $result[$location][$file] = '//' . $file;
260
  }
261
  }
@@ -274,22 +296,21 @@ class W3_Minify
274
  */
275
  function _precache_file($url, $type)
276
  {
277
- $lifetime = $this->_config->get_integer('minify.lifetime', 3600);
278
- $file_path = sprintf('%s/minify_%s.%s', W3TC_CACHE_MINIFY_DIR, md5($url), $type);
279
  $file_exists = file_exists($file_path);
280
- $base_url = $this->_get_base_url($url);
281
 
282
  if (file_exists($file_path) && @filemtime($file_path) >= (time() - $lifetime)) {
283
- return $this->_get_minify_source($file_path, $base_url);
284
  }
285
 
286
- if (is_dir(W3TC_CACHE_MINIFY_DIR)) {
287
  if (($file_data = w3_url_get($url))) {
288
  if (($fp = @fopen($file_path, 'w'))) {
289
  @fputs($fp, $file_data);
290
  @fclose($fp);
291
 
292
- return $this->_get_minify_source($file_path, $base_url);
293
  } else {
294
  $this->log(sprintf('Unable to open file %s for writing', $file_path));
295
  }
@@ -297,51 +318,30 @@ class W3_Minify
297
  $this->log(sprintf('Unable to download URL: %s', $url));
298
  }
299
  } else {
300
- $this->log(sprintf('Cache directory %s is not exists', W3TC_CACHE_MINIFY_DIR));
301
  }
302
 
303
- return ($file_exists ? $this->_get_minify_source($file_path, $base_url) : false);
304
  }
305
 
306
  /**
307
  * Returns minify source
308
  * @param $file_path
309
- * @param $base_url
310
  * @return Minify_Source
311
  */
312
- function _get_minify_source($file_path, $base_url)
313
  {
314
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Source.php';
315
 
316
  return new Minify_Source(array(
317
  'filepath' => $file_path,
318
  'minifyOptions' => array(
319
- 'prependRelativePath' => $base_url
320
  )
321
  ));
322
  }
323
 
324
- /**
325
- * Returns base URL
326
- * @param $url
327
- * @return string
328
- */
329
- function _get_base_url($url)
330
- {
331
- $parse_url = @parse_url($url);
332
- if ($parse_url && isset($parse_url['scheme'])) {
333
- $scheme = $parse_url['scheme'];
334
- if (isset($parse_url['host'])) {
335
- $host = $parse_url['host'];
336
- $port = (isset($parse_url['port']) && $parse_url['port'] != 80 ? ':' . $parse_url['port'] : '');
337
- $path = (isset($parse_url['path']) ? preg_replace('~[^/]+$~', '', $parse_url['path']) : '/');
338
-
339
- return sprintf('%s://%s%s%s', $scheme, $host, $port, $path);
340
- }
341
- }
342
- return false;
343
- }
344
-
345
  /**
346
  * Returns minify cache object
347
  *
@@ -349,35 +349,35 @@ class W3_Minify
349
  */
350
  function &_get_cache()
351
  {
352
- static $cache = null;
353
 
354
- if ($cache === null) {
355
- switch ($this->_config->get_string('minify.engine', 'memcached')) {
356
  case 'memcached':
357
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
358
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/Memcache.php';
359
- $this->_memcached = & W3_Cache_Memcached::instance($this->_config->get_string('minify.memcached.engine', 'auto'), array(
360
  'servers' => $this->_config->get_array('minify.memcached.servers'),
361
  'persistant' => true
362
  ));
363
- $cache = & new Minify_Cache_Memcache($this->_memcached);
364
  break;
365
 
366
  case 'apc':
367
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/APC.php';
368
- $cache = & new Minify_Cache_APC();
369
  break;
370
 
371
  default:
372
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/File.php';
373
- if (! is_dir(W3TC_CACHE_MINIFY_DIR)) {
374
- $this->log(sprintf('Cache directory %s does not exists', W3TC_CACHE_MINIFY_DIR));
375
  }
376
- $cache = & new Minify_Cache_File(W3TC_CACHE_MINIFY_DIR, $this->_config->get_boolean('minify.locking'));
377
  break;
378
  }
379
  }
380
 
381
- return $cache;
382
  }
383
  }
11
  {
12
  /**
13
  * Config
14
+ *
15
  * @var W3_Config
16
  */
17
  var $_config = null;
29
  function __construct()
30
  {
31
  require_once W3TC_LIB_W3_DIR . '/Config.php';
32
+ $this->_config = & W3_Config::instance();
 
33
  }
34
 
35
  /**
49
  require_once W3TC_LIB_MINIFY_DIR . '/Minify.php';
50
  require_once W3TC_LIB_MINIFY_DIR . '/HTTP/Encoder.php';
51
 
52
+ HTTP_Encoder::$encodeToIe6 = $this->_config->get_boolean('minify.comprss.ie6');
53
 
54
  Minify::$uploaderHoursBehind = $this->_config->get_integer('minify.fixtime');
55
  Minify::setCache($this->_get_cache());
56
 
57
  $serve_options = $this->_config->get_array('minify.options');
58
+ $serve_options['maxAge'] = $this->_config->get_integer('minify.maxage');
59
+ $serve_options['encodeOutput'] = $this->_config->get_boolean('minify.compress');
60
  $serve_options['postprocessor'] = array(
61
  &$this,
62
  'postprocessor'
72
  $serve_options['minifierOptions']['text/css']['symlinks'][$link] = realpath($target);
73
  }
74
 
75
+ if ($this->_config->get_boolean('minify.debug')) {
76
  $serve_options['debug'] = true;
77
  }
78
 
97
  'minify_stub'
98
  );
99
  }
100
+
101
+ /**
102
+ * Setup user-friendly cache ID for disk cache
103
+ */
104
+ if ($this->_config->get_string('minify.engine') == 'file') {
105
+ $cacheId = sprintf('%s.%s.%s', $_GET['gg'], $_GET['g'], $_GET['t']);
106
+
107
+ Minify::setCacheId($cacheId);
108
+ }
109
  }
110
 
111
+ @header('Pragma: public');
112
+
113
+ try {
114
+ Minify::serve('MinApp', $serve_options);
115
+ } catch (Exception $exception) {
116
+ printf('<strong>W3 Total Cache Error:</strong> Minify error: %s', $exception->getMessage());
117
+ }
118
  } else {
119
  die('This file cannot be accessed directly');
120
  }
156
  break;
157
  }
158
 
159
+ return trim($content);
160
  }
161
 
162
  /**
166
  {
167
  static $cache_path = null;
168
 
169
+ $cache = & $this->_get_cache();
170
 
171
  if (is_a($cache, 'Minify_Cache_Memcache') && is_a($this->_memcached, 'W3_Cache_Memcached_Base')) {
172
  return $this->_memcached->flush();
173
  } elseif (is_a($cache, 'Minify_Cache_APC') && function_exists('apc_clear_cache')) {
174
  return apc_clear_cache('user');
175
  } elseif (is_a($cache, 'Minify_Cache_File')) {
176
+ if (! is_dir(W3TC_CACHE_FILE_MINIFY_DIR)) {
177
+ $this->log(sprintf('Cache directory %s does not exists', W3TC_CACHE_FILE_MINIFY_DIR));
178
  }
179
+
180
+ return w3_emptydir(W3TC_CACHE_FILE_MINIFY_DIR, array(
181
+ W3TC_CACHE_FILE_MINIFY_DIR . '/index.php',
182
+ W3TC_CACHE_FILE_MINIFY_DIR . '/.htaccess'
183
+ ));
184
  }
185
 
186
  return false;
193
  */
194
  function &instance()
195
  {
196
+ static $instances = array();
197
 
198
+ if (! isset($instances[0])) {
199
  $class = __CLASS__;
200
+ $instances[0] = & new $class();
201
  }
202
 
203
+ return $instances[0];
204
  }
205
 
206
  /**
221
  */
222
  function log($object, $label = null)
223
  {
 
224
  $data = sprintf("[%s] [%s] %s\n", date('r'), $_SERVER['REQUEST_URI'], $object);
225
 
226
+ $fp = @fopen(W3TC_MINIFY_LOG_FILE, 'a');
227
  if ($fp) {
228
  @fputs($fp, $data);
229
  @fclose($fp);
274
  $result[$location][$file] = $precached_file;
275
  }
276
  } else {
277
+ if (w3_get_blog_id()) {
278
+ // for WPMU we have to remove blog path
279
+ $file = str_replace(w3_get_site_path(), '', $file);
280
+ }
281
  $result[$location][$file] = '//' . $file;
282
  }
283
  }
296
  */
297
  function _precache_file($url, $type)
298
  {
299
+ $lifetime = $this->_config->get_integer('minify.lifetime');
300
+ $file_path = sprintf('%s/minify_%s.%s', W3TC_CACHE_FILE_MINIFY_DIR, md5($url), $type);
301
  $file_exists = file_exists($file_path);
 
302
 
303
  if (file_exists($file_path) && @filemtime($file_path) >= (time() - $lifetime)) {
304
+ return $this->_get_minify_source($file_path, $url);
305
  }
306
 
307
+ if (is_dir(W3TC_CACHE_FILE_MINIFY_DIR)) {
308
  if (($file_data = w3_url_get($url))) {
309
  if (($fp = @fopen($file_path, 'w'))) {
310
  @fputs($fp, $file_data);
311
  @fclose($fp);
312
 
313
+ return $this->_get_minify_source($file_path, $url);
314
  } else {
315
  $this->log(sprintf('Unable to open file %s for writing', $file_path));
316
  }
318
  $this->log(sprintf('Unable to download URL: %s', $url));
319
  }
320
  } else {
321
+ $this->log(sprintf('The cache directory %s does not exist', W3TC_CACHE_FILE_MINIFY_DIR));
322
  }
323
 
324
+ return ($file_exists ? $this->_get_minify_source($file_path, $url) : false);
325
  }
326
 
327
  /**
328
  * Returns minify source
329
  * @param $file_path
330
+ * @param $url
331
  * @return Minify_Source
332
  */
333
+ function _get_minify_source($file_path, $url)
334
  {
335
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Source.php';
336
 
337
  return new Minify_Source(array(
338
  'filepath' => $file_path,
339
  'minifyOptions' => array(
340
+ 'prependRelativePath' => $url
341
  )
342
  ));
343
  }
344
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  /**
346
  * Returns minify cache object
347
  *
349
  */
350
  function &_get_cache()
351
  {
352
+ static $cache = array();
353
 
354
+ if (! isset($cache[0])) {
355
+ switch ($this->_config->get_string('minify.engine')) {
356
  case 'memcached':
357
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
358
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/Memcache.php';
359
+ $this->_memcached = & W3_Cache_Memcached::instance($this->_config->get_string('minify.memcached.engine'), array(
360
  'servers' => $this->_config->get_array('minify.memcached.servers'),
361
  'persistant' => true
362
  ));
363
+ $cache[0] = & new Minify_Cache_Memcache($this->_memcached);
364
  break;
365
 
366
  case 'apc':
367
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/APC.php';
368
+ $cache[0] = & new Minify_Cache_APC();
369
  break;
370
 
371
  default:
372
  require_once W3TC_LIB_MINIFY_DIR . '/Minify/Cache/File.php';
373
+ if (! is_dir(W3TC_CACHE_FILE_MINIFY_DIR)) {
374
+ $this->log(sprintf('Cache directory %s does not exist', W3TC_CACHE_FILE_MINIFY_DIR));
375
  }
376
+ $cache[0] = & new Minify_Cache_File(W3TC_CACHE_FILE_MINIFY_DIR, $this->_config->get_boolean('minify.file.locking'));
377
  break;
378
  }
379
  }
380
 
381
+ return $cache[0];
382
  }
383
  }
lib/W3/PgCache.php CHANGED
@@ -24,38 +24,38 @@ class W3_PgCache
24
  var $_caching = false;
25
 
26
  /**
27
- * Compression availability flag
28
  *
29
- * @var boolean
30
  */
31
- var $_compression = false;
32
 
33
  /**
34
- * Page key
35
- *
36
- * @var string
37
  */
38
- var $_page_key = '';
39
 
40
  /**
41
- * Time start
42
- *
43
- * @var double
44
  */
45
- var $_time_start = 0;
46
 
47
  /**
48
- * Lifetime
49
- * @var integer
 
50
  */
51
- var $_lifetime = 0;
52
 
53
  /**
54
  * Cache reject reason
55
  *
56
  * @var string
57
  */
58
- var $_cache_reject_reason = '';
59
 
60
  /**
61
  * PHP5 Constructor
@@ -63,9 +63,11 @@ class W3_PgCache
63
  function __construct()
64
  {
65
  require_once W3TC_LIB_W3_DIR . '/Config.php';
66
- $this->_config = W3_Config::instance();
67
- $this->_lifetime = $this->_config->get_integer('pgcache.lifetime', 3600);
68
- $this->_compression = ($this->_config->get_boolean('pgcache.compress', true) ? $this->_get_compression() : false);
 
 
69
  }
70
 
71
  /**
@@ -81,57 +83,99 @@ class W3_PgCache
81
  */
82
  function process()
83
  {
84
- if ($this->_config->get_boolean('pgcache.debug')) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  $this->_time_start = w3_microtime();
86
  }
87
 
88
  $this->_caching = $this->_can_cache();
89
- $this->_page_key = $this->_get_page_key($this->_compression);
 
 
90
 
91
  if ($this->_caching) {
92
  /**
93
  * Check if page is cached
94
  */
95
- $cache = $this->_get_cache();
 
96
 
97
- if (is_array(($data = $cache->get($this->_page_key)))) {
98
- @header('Pragma: public');
99
-
100
- /**
101
- * Handle 404 error
102
- */
103
- if ($data['404']) {
104
- @header('HTTP/1.1 404 Not Found');
105
  } else {
106
- @$this->_conditional_get($data['time'], md5($data['content']));
 
 
 
107
  }
108
 
109
  /**
110
- * Send cached headers
111
  */
112
- foreach ((array) $data['headers'] as $header_name => $header_value) {
113
- @header($header_name . ': ' . $header_value);
 
 
114
  }
115
 
116
  /**
117
- * Append debug info to content if debug mode is enabled
118
  */
119
- if ($this->_config->get_boolean('pgcache.debug')) {
120
- $time_total = w3_microtime() - $this->_time_start;
121
- $debug_info = $this->_get_debug_info(true, '', true, $time_total);
122
- $this->_append_content($data, "\r\n\r\n" . $debug_info);
 
 
 
 
 
 
 
 
 
123
  }
124
 
125
  /**
126
- * Send content
127
  */
128
- echo $data['content'];
 
 
129
  exit();
130
  }
131
  }
132
 
133
  /**
134
- * Start ob
135
  */
136
  ob_start(array(
137
  &$this,
@@ -147,164 +191,112 @@ class W3_PgCache
147
  */
148
  function ob_callback($buffer)
149
  {
150
- if (! w3_is_xml($buffer)) {
151
- return $buffer;
152
- }
153
-
154
- if (! $this->_can_cache2()) {
155
- $this->_send_compression_headers($this->_compression);
156
-
157
- if ($this->_config->get_boolean('pgcache.debug')) {
158
- $time_total = w3_microtime() - $this->_time_start;
159
- $debug_info = $this->_get_debug_info(false, $this->_cache_reject_reason, false, $time_total);
160
- $buffer .= "\r\n\r\n" . $debug_info;
161
- }
162
-
163
- switch ($this->_compression) {
164
- case 'gzip':
165
- return gzencode($buffer);
166
 
167
- case 'deflate':
168
- return gzdeflate($buffer);
169
- }
170
-
171
- return $buffer;
172
- }
173
-
174
- /**
175
- * Create data object
176
- */
177
- $data_array = array();
178
- $page_keys = array();
179
-
180
- $cache = $this->_get_cache();
181
- $time = time();
182
- $is_404 = is_404();
183
-
184
- $compressions = array(
185
- false,
186
- 'gzip',
187
- 'deflate'
188
- );
189
-
190
- foreach ($compressions as $compression) {
191
- $data = array(
192
- 'time' => $time,
193
- '404' => $is_404
194
- );
195
-
196
- /**
197
- * Set content to cache
198
- */
199
- if ($compression == 'gzip') {
200
- $data['content'] = gzencode($buffer);
201
- } elseif ($compression == 'deflate') {
202
- $data['content'] = gzdeflate($buffer);
203
- } else {
204
- $data['content'] = $buffer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  }
206
-
207
- $data_array[$compression] = $data;
208
- }
209
-
210
- /**
211
- * We must compression headers first before ::_get_data_headers() call
212
- */
213
- @$this->_conditional_get($time, md5($data_array[$this->_compression]['content']));
214
- $this->_send_compression_headers($this->_compression);
215
- @header('Pragma: public');
216
-
217
- foreach ($data_array as $compression => $data) {
218
- /**
219
- * Set headers to cache
220
- */
221
- $data['headers'] = $this->_get_data_headers($compression);
222
- $data_array[$compression] = $data;
223
-
224
- /**
225
- * Cache data
226
- */
227
- $page_key = $this->_get_page_key($compression);
228
- $cache->set($page_key, $data, $this->_lifetime);
229
- $page_keys[] = $page_key;
230
- }
231
-
232
- /**
233
- * Try to detect post id
234
- */
235
- $post_id = $this->_detect_post_id();
236
-
237
- /**
238
- * If there is post id, store link to cached page
239
- */
240
- if ($post_id) {
241
- $map = $this->get_map($post_id);
242
- $map += $page_keys;
243
- $this->set_map($post_id, $map);
244
  }
245
 
246
- /**
247
- * Store links to home page
248
- */
249
- if ($_SERVER['REQUEST_URI'] == '/') {
250
- $map = $this->get_map('home');
251
- $map += $page_keys;
252
- $this->set_map('home', $map);
253
- }
254
-
255
- /**
256
- * Append debug info if debug mode is enabled
257
- */
258
- if ($this->_config->get_boolean('pgcache.debug')) {
259
- $time_total = w3_microtime() - $this->_time_start;
260
- $debug_info = $this->_get_debug_info(true, '', false, $time_total);
261
- $this->_append_content($data_array[$this->_compression], "\r\n\r\n" . $debug_info);
262
- }
263
-
264
- return $data_array[$this->_compression]['content'];
265
- }
266
-
267
- /**
268
- * Returns map associated to namespace
269
- *
270
- * @param string $namespace
271
- * @return array
272
- */
273
- function get_map($namespace)
274
- {
275
- $map_key = $this->_get_map_key($namespace);
276
- $cache = $this->_get_cache();
277
-
278
- if (is_array(($map = $cache->get($map_key)))) {
279
- return $map;
280
- }
281
-
282
- return array();
283
- }
284
-
285
- /**
286
- * Sets map
287
- *
288
- * @param string $namespace
289
- * @param array $map
290
- * @return boolean
291
- */
292
- function set_map($namespace, $map)
293
- {
294
- $map_key = $this->_get_map_key($namespace);
295
- $cache = $this->_get_cache();
296
-
297
- return $cache->set($map_key, $map, $this->_lifetime);
298
  }
299
 
300
  /**
301
- * Flushes all cache
302
  *
303
  * @return boolean
304
  */
305
  function flush()
306
  {
307
- $cache = $this->_get_cache();
308
 
309
  return $cache->flush();
310
  }
@@ -322,49 +314,42 @@ class W3_PgCache
322
  }
323
 
324
  if ($post_id) {
325
- $cache = $this->_get_cache();
326
 
327
- /**
328
- * Flush post page
329
- */
330
- foreach ((array) $this->get_map($post_id) as $page_key) {
331
- $cache->delete($page_key);
332
- }
 
 
333
 
334
- /**
335
- * Flush home page
336
- */
337
- foreach ((array) $this->get_map('home') as $page_key) {
338
  $cache->delete($page_key);
339
  }
340
-
341
- /**
342
- * Flush map cache
343
- */
344
- $this->set_map($post_id, array());
345
- $this->set_map('home', array());
346
-
347
- return true;
348
  }
349
 
350
  return false;
351
  }
352
 
353
  /**
354
- * Returns onject instance
355
  *
356
  * @return W3_PgCache
357
  */
358
  function &instance()
359
  {
360
- static $instance = null;
361
 
362
- if ($instance === null) {
363
  $class = __CLASS__;
364
- $instance = & new $class();
365
  }
366
 
367
- return $instance;
368
  }
369
 
370
  /**
@@ -377,48 +362,8 @@ class W3_PgCache
377
  /**
378
  * Skip if disabled
379
  */
380
- if (! $this->_config->get_boolean('pgcache.enabled', true)) {
381
- $this->_cache_reject_reason = 'Caching is disabled';
382
- return false;
383
- }
384
-
385
- /**
386
- * Skip if doing AJAX
387
- */
388
- if (defined('DOING_AJAX')) {
389
- $this->_cache_reject_reason = 'Doing AJAX';
390
- return false;
391
- }
392
-
393
- /**
394
- * Skip if doing cron
395
- */
396
- if (defined('DOING_CRON')) {
397
- $this->_cache_reject_reason = 'Doing cron';
398
- return false;
399
- }
400
-
401
- /**
402
- * Skip if APP request
403
- */
404
- if (defined('APP_REQUEST')) {
405
- $this->_cache_reject_reason = 'APP request';
406
- return false;
407
- }
408
-
409
- /**
410
- * Skip if XMLRPC request
411
- */
412
- if (defined('XMLRPC_REQUEST')) {
413
- $this->_cache_reject_reason = 'XMLRPC request';
414
- return false;
415
- }
416
-
417
- /**
418
- * Skip if admin
419
- */
420
- if (defined('WP_ADMIN')) {
421
- $this->_cache_reject_reason = 'Admin';
422
  return false;
423
  }
424
 
@@ -426,7 +371,7 @@ class W3_PgCache
426
  * Skip if posting
427
  */
428
  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
429
- $this->_cache_reject_reason = 'Request method is POST';
430
  return false;
431
  }
432
 
@@ -434,15 +379,15 @@ class W3_PgCache
434
  * Skip if session defined
435
  */
436
  if (defined('SID') && SID != '') {
437
- $this->_cache_reject_reason = 'Session is started';
438
  return false;
439
  }
440
 
441
  /**
442
  * Skip if there is query in the request uri
443
  */
444
- if (! $this->_config->get_boolean('pgcache.cache.query', true) && strstr($_SERVER['REQUEST_URI'], '?') !== false) {
445
- $this->_cache_reject_reason = 'Request URI contains query';
446
  return false;
447
  }
448
 
@@ -450,7 +395,7 @@ class W3_PgCache
450
  * Check request URI
451
  */
452
  if (! in_array($_SERVER['PHP_SELF'], $this->_config->get_array('pgcache.accept.files')) && ! $this->_check_request_uri()) {
453
- $this->_cache_reject_reason = 'Request URI rejected';
454
  return false;
455
  }
456
 
@@ -458,7 +403,7 @@ class W3_PgCache
458
  * Check User Agent
459
  */
460
  if (! $this->_check_ua()) {
461
- $this->_cache_reject_reason = 'User Agent rejected';
462
  return false;
463
  }
464
 
@@ -466,15 +411,15 @@ class W3_PgCache
466
  * Check WordPress cookies
467
  */
468
  if (! $this->_check_cookies()) {
469
- $this->_cache_reject_reason = 'Cookie rejected';
470
  return false;
471
  }
472
 
473
  /**
474
  * Skip if user is logged in
475
  */
476
- if ($this->_config->get_boolean('pgcache.reject.logged', true) && ! $this->_check_logged_in()) {
477
- $this->_cache_reject_reason = 'User is logged in';
478
 
479
  return false;
480
  }
@@ -500,8 +445,8 @@ class W3_PgCache
500
  /**
501
  * Don't cache 404 pages
502
  */
503
- if (! $this->_config->get_boolean('pgcache.cache.404', true) && is_404()) {
504
- $this->_cache_reject_reason = 'Page is 404';
505
 
506
  return false;
507
  }
@@ -509,8 +454,8 @@ class W3_PgCache
509
  /**
510
  * Don't cache homepage
511
  */
512
- if (! $this->_config->get_boolean('pgcache.cache.home', true) && is_home()) {
513
- $this->_cache_reject_reason = 'Page is home';
514
 
515
  return false;
516
  }
@@ -518,8 +463,8 @@ class W3_PgCache
518
  /**
519
  * Don't cache feed
520
  */
521
- if (! $this->_config->get_boolean('pgcache.cache.feed', true) && is_feed()) {
522
- $this->_cache_reject_reason = 'Page is feed';
523
 
524
  return false;
525
  }
@@ -534,15 +479,15 @@ class W3_PgCache
534
  */
535
  function &_get_cache()
536
  {
537
- static $cache = null;
538
 
539
- if ($cache === null) {
540
- $engine = $this->_config->get_string('pgcache.engine', 'file');
541
 
542
  switch ($engine) {
543
  case 'memcached':
544
  $engineConfig = array(
545
- 'engine' => $this->_config->get_string('pgcache.memcached.engine', 'auto'),
546
  'servers' => $this->_config->get_array('pgcache.memcached.servers'),
547
  'persistant' => true
548
  );
@@ -550,7 +495,14 @@ class W3_PgCache
550
 
551
  case 'file':
552
  $engineConfig = array(
553
- 'cache_dir' => W3TC_CACHE_FILE_DIR
 
 
 
 
 
 
 
554
  );
555
  break;
556
 
@@ -559,10 +511,10 @@ class W3_PgCache
559
  }
560
 
561
  require_once W3TC_LIB_W3_DIR . '/Cache.php';
562
- $cache = & W3_Cache::instance($engine, $engineConfig);
563
  }
564
 
565
- return $cache;
566
  }
567
 
568
  /**
@@ -620,7 +572,7 @@ class W3_PgCache
620
  if ($cookie_name == 'wordpress_test_cookie') {
621
  continue;
622
  }
623
- if (preg_match('/^wp-postpass|^comment_author/', $cookie_name)) {
624
  return false;
625
  }
626
  }
@@ -638,7 +590,7 @@ class W3_PgCache
638
 
639
  /**
640
  * Check if user is logged in
641
- *
642
  * @return boolean
643
  */
644
  function _check_logged_in()
@@ -662,17 +614,42 @@ class W3_PgCache
662
  */
663
  function _get_compression()
664
  {
665
- if (ini_get('zlib.output_compression')) {
666
- return false;
 
 
 
 
 
 
667
  }
668
 
669
- if (strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) {
670
- return 'gzip';
671
- } elseif (strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !== false) {
672
- return 'deflate';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
673
  }
674
 
675
- return false;
676
  }
677
 
678
  /**
@@ -685,33 +662,30 @@ class W3_PgCache
685
  $headers = array();
686
 
687
  if (function_exists('headers_list')) {
688
- foreach (headers_list() as $header) {
689
- list ($header_name, $header_value) = explode(': ', $header, 2);
690
- $headers[$header_name] = $header_value;
 
 
 
691
  }
692
- } elseif (function_exists('apache_response_headers')) {
693
- flush();
694
- $headers = apache_response_headers();
695
  }
696
 
697
- ksort($headers);
698
- reset($headers);
699
-
700
  return $headers;
701
  }
702
 
703
  /**
704
  * Returns array of data headers
705
  *
706
- * @param string $compression
707
  * @return array
708
  */
709
- function _get_data_headers($compression)
710
  {
711
  $data_headers = array();
712
  $cache_headers = $this->_config->get_array('pgcache.cache.headers');
 
713
 
714
- foreach ($this->_get_response_headers() as $header_name => $header_value) {
715
  foreach ($cache_headers as $cache_header_name) {
716
  if (strcasecmp($header_name, $cache_header_name) == 0) {
717
  $data_headers[$header_name] = $header_value;
@@ -719,87 +693,53 @@ class W3_PgCache
719
  }
720
  }
721
 
722
- if ($compression !== false) {
723
- $data_headers['Content-Encoding'] = $compression;
724
- $data_headers['Vary'] = 'Accept-Encoding, Cookie';
725
- } else {
726
- $data_headers['Vary'] = 'Cookie';
727
- }
728
-
729
- if (isset($data_headers['Last-Modified'])) {
730
- $data_headers['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT';
731
- }
732
-
733
  return $data_headers;
734
  }
735
 
736
  /**
737
- * Returns mobile type
738
  *
 
 
739
  * @return string
740
  */
741
- function _get_mobile_type()
742
  {
743
- if (isset($_SERVER['HTTP_USER_AGENT'])) {
744
- foreach ($this->_config->get_array('pgcache.mobile.whitelist') as $browser) {
745
- if (strstr($_SERVER['HTTP_USER_AGENT'], trim($browser)) !== false) {
746
- return '';
747
- }
 
 
 
748
  }
749
 
750
- foreach ($this->_config->get_array('pgcache.mobile.browsers') as $browser) {
751
- if (strstr($_SERVER["HTTP_USER_AGENT"], trim($browser)) !== false) {
752
- return strtolower($browser);
753
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
754
  }
755
  }
756
 
757
- return '';
758
- }
759
-
760
- /**
761
- * Returns page key
762
- *
763
- * @param string $compression
764
- * @return string
765
- */
766
- function _get_page_key($compression = false)
767
- {
768
- $blog_id = w3_get_blog_id();
769
-
770
- if (empty($blog_id)) {
771
- $blog_id = $_SERVER['HTTP_HOST'];
772
- }
773
-
774
- $key = sprintf('w3tc_%s_page_%s', md5($blog_id), md5($_SERVER['REQUEST_URI']));
775
-
776
- if ($this->_config->get_boolean('pgcache.mobile.check') && ($mobile_type = $this->_get_mobile_type()) != '') {
777
- $key .= '_' . $mobile_type;
778
- }
779
-
780
- if (! empty($compression)) {
781
- $key .= '_' . $compression;
782
- }
783
-
784
- return $key;
785
- }
786
-
787
- /**
788
- * Returns map key
789
- *
790
- * @param string $namespace
791
- * @return string
792
- */
793
- function _get_map_key($namespace)
794
- {
795
- $blog_id = w3_get_blog_id();
796
-
797
- if (empty($blog_id)) {
798
- $blog_id = $_SERVER['HTTP_HOST'];
799
- }
800
-
801
- $key = sprintf('w3tc_%s_map_%s', md5($blog_id), $namespace);
802
-
803
  return $key;
804
  }
805
 
@@ -828,17 +768,18 @@ class W3_PgCache
828
  /**
829
  * Returns debug info
830
  *
 
831
  * @param boolean $cache
832
  * @param string $reason
833
  * @param boolean $status
834
  * @param double $time
835
  * @return string
836
  */
837
- function _get_debug_info($cache, $reason, $status, $time)
838
  {
839
  $debug_info = "<!-- W3 Total Cache: Page cache debug info:\r\n";
840
  $debug_info .= sprintf("%s%s\r\n", str_pad('Engine: ', 20), w3_get_engine_name($this->_config->get_string('pgcache.engine')));
841
- $debug_info .= sprintf("%s%s\r\n", str_pad('Key: ', 20), $this->_page_key);
842
  $debug_info .= sprintf("%s%s\r\n", str_pad('Caching: ', 20), ($cache ? 'enabled' : 'disabled'));
843
  if (! $cache) {
844
  $debug_info .= sprintf("%s%s\r\n", str_pad('Reject reason: ', 20), $reason);
@@ -849,7 +790,7 @@ class W3_PgCache
849
  $headers = $this->_get_response_headers();
850
 
851
  if (count($headers)) {
852
- $debug_info .= "Headers info:\r\n";
853
 
854
  foreach ($headers as $header_name => $header_value) {
855
  $debug_info .= sprintf("%s%s\r\n", str_pad($header_name . ': ', 20), $header_value);
@@ -866,60 +807,195 @@ class W3_PgCache
866
  *
867
  * @param array $data
868
  * @param string $content
 
 
869
  */
870
- function _append_content(&$data, $content)
871
  {
872
- switch ($this->_compression) {
873
  case false:
874
- $data['content'] .= $content;
875
  break;
876
 
877
  case 'gzip':
878
- $data['content'] = (function_exists('gzdecode') ? gzdecode($data['content']) : w3_gzdecode($data['content']));
879
- $data['content'] .= $content;
880
- $data['content'] = gzencode($data['content']);
881
  break;
882
 
883
  case 'deflate':
884
- $data['content'] = gzinflate($data['content']);
885
- $data['content'] .= $content;
886
- $data['content'] = gzdeflate($data['content']);
887
  break;
888
  }
889
  }
890
 
891
  /**
892
- * Sends compression headers
893
- *
894
- * @param string $compression
 
895
  */
896
- function _send_compression_headers($compression)
897
  {
898
- if ($compression !== false) {
899
- @header('Content-Encoding: ' . $compression);
900
- @header('Vary: Accept-Encoding, Cookie');
 
 
 
 
901
  }
 
 
902
  }
903
 
904
  /**
905
- * Conditional get
906
- * @param $time
907
- * @param $etag
908
- * @return void
 
 
 
909
  */
910
- function _conditional_get($time, $etag)
911
  {
912
- require_once W3TC_LIB_MINIFY_DIR . 'HTTP/ConditionalGet.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
913
 
914
- $cg_options = array(
915
- 'maxAge' => $this->_lifetime,
916
- 'contentHash' => $etag
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
917
  );
918
 
919
- if ($this->_compression) {
920
- $cg_options['encoding'] = $this->_compression;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
921
  }
922
 
923
- HTTP_ConditionalGet::check($time, true, $cg_options);
 
 
 
 
 
 
 
 
 
 
924
  }
925
  }
24
  var $_caching = false;
25
 
26
  /**
27
+ * Time start
28
  *
29
+ * @var double
30
  */
31
+ var $_time_start = 0;
32
 
33
  /**
34
+ * Lifetime
35
+ * @var integer
 
36
  */
37
+ var $_lifetime = 0;
38
 
39
  /**
40
+ * Enchanced mode flag
41
+ *
42
+ * @var boolean
43
  */
44
+ var $_enchanced_mode = false;
45
 
46
  /**
47
+ * Debug flag
48
+ *
49
+ * @var boolean
50
  */
51
+ var $_debug = false;
52
 
53
  /**
54
  * Cache reject reason
55
  *
56
  * @var string
57
  */
58
+ var $cache_reject_reason = '';
59
 
60
  /**
61
  * PHP5 Constructor
63
  function __construct()
64
  {
65
  require_once W3TC_LIB_W3_DIR . '/Config.php';
66
+
67
+ $this->_config = & W3_Config::instance();
68
+ $this->_debug = $this->_config->get_boolean('pgcache.debug');
69
+ $this->_lifetime = $this->_config->get_integer('pgcache.lifetime');
70
+ $this->_enchanced_mode = ($this->_config->get_string('pgcache.engine') == 'file_pgcache');
71
  }
72
 
73
  /**
83
  */
84
  function process()
85
  {
86
+ /**
87
+ * Skip caching for some pages
88
+ */
89
+ switch (true) {
90
+ case defined('DOING_AJAX'):
91
+ case defined('DOING_CRON'):
92
+ case defined('APP_REQUEST'):
93
+ case defined('XMLRPC_REQUEST'):
94
+ case defined('WP_ADMIN'):
95
+ return;
96
+ }
97
+
98
+ /**
99
+ * Handle mobile redirects
100
+ */
101
+ $mobile_redirect = $this->_config->get_string('pgcache.mobile.redirect');
102
+
103
+ if ($mobile_redirect != '' && $this->_is_mobile()) {
104
+ w3_redirect($mobile_redirect);
105
+ exit();
106
+ }
107
+
108
+ /**
109
+ * Do page cache logic
110
+ */
111
+ if ($this->_debug) {
112
  $this->_time_start = w3_microtime();
113
  }
114
 
115
  $this->_caching = $this->_can_cache();
116
+
117
+ $compression = $this->_get_compression();
118
+ $page_key = $this->_get_page_key($_SERVER['REQUEST_URI'], $compression);
119
 
120
  if ($this->_caching) {
121
  /**
122
  * Check if page is cached
123
  */
124
+ $cache = & $this->_get_cache();
125
+ $data = $cache->get($page_key);
126
 
127
+ if ($data !== false) {
128
+ if ($this->_enchanced_mode) {
129
+ $is_404 = false;
130
+ $headers = array();
131
+ $time = $cache->mtime($page_key);
132
+ $content = $data;
 
 
133
  } else {
134
+ $is_404 = $data['404'];
135
+ $headers = $data['headers'];
136
+ $time = $data['time'];
137
+ $content = $data['content'];
138
  }
139
 
140
  /**
141
+ * Append debug info
142
  */
143
+ if ($this->_debug) {
144
+ $time_total = w3_microtime() - $this->_time_start;
145
+ $debug_info = $this->_get_debug_info($page_key, true, '', true, $time_total);
146
+ $this->_append_content($content, "\r\n\r\n" . $debug_info, $compression);
147
  }
148
 
149
  /**
150
+ * Calculate content etag and length
151
  */
152
+ $etag = md5($content);
153
+ $content_length = strlen($content);
154
+
155
+ if ($is_404) {
156
+ /**
157
+ * Send 404 header
158
+ */
159
+ $this->_send_headers_404();
160
+ } else {
161
+ /**
162
+ * Send 304 header if content is not modified
163
+ */
164
+ $this->_send_headers_304($time, $etag);
165
  }
166
 
167
  /**
168
+ * Send headers
169
  */
170
+ $this->_send_headers($time, $etag, $content_length, $compression, $headers);
171
+
172
+ echo $content;
173
  exit();
174
  }
175
  }
176
 
177
  /**
178
+ * Start output buffering
179
  */
180
  ob_start(array(
181
  &$this,
191
  */
192
  function ob_callback($buffer)
193
  {
194
+ if ($buffer != '') {
195
+ if ($this->_can_cache2() && w3_is_xml($buffer)) {
196
+ $compression = $this->_get_compression();
197
+ $compressions = $this->_get_compressions();
 
 
 
 
 
 
 
 
 
 
 
 
198
 
199
+ if ($this->_enchanced_mode) {
200
+ $is_404 = false;
201
+ $headers = array();
202
+ } else {
203
+ $is_404 = (function_exists('is_404') ? is_404() : false);
204
+ $headers = $this->_get_cached_headers();
205
+ }
206
+
207
+ $time = time();
208
+ $cache = & $this->_get_cache();
209
+
210
+ foreach ($compressions as $_compression) {
211
+ $_page_key = $this->_get_page_key($_SERVER['REQUEST_URI'], $_compression);
212
+
213
+ /**
214
+ * Encode content
215
+ */
216
+ switch ($_compression) {
217
+ case false:
218
+ $_content = $buffer;
219
+ break;
220
+
221
+ case 'gzip':
222
+ $_content = gzencode($buffer);
223
+ break;
224
+
225
+ case 'deflate':
226
+ $_content = gzdeflate($buffer);
227
+ break;
228
+ }
229
+
230
+ /**
231
+ * Store cache data
232
+ */
233
+ if ($this->_enchanced_mode) {
234
+ $cache->set($_page_key, $_content);
235
+ } else {
236
+ $_data = array(
237
+ '404' => $is_404,
238
+ 'headers' => $headers,
239
+ 'time' => $time,
240
+ 'content' => $_content
241
+ );
242
+
243
+ $cache->set($_page_key, $_data, $this->_lifetime);
244
+ }
245
+
246
+ if ($compression == $_compression) {
247
+ $page_key = $_page_key;
248
+ $buffer = $_content;
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Append debug info
254
+ */
255
+ if ($this->_debug) {
256
+ $time_total = w3_microtime() - $this->_time_start;
257
+ $debug_info = $this->_get_debug_info($page_key, true, '', false, $time_total);
258
+ $this->_append_content($buffer, "\r\n\r\n" . $debug_info, $compression);
259
+ }
260
+
261
+ /**
262
+ * Calculate content etag and content length
263
+ */
264
+ $etag = md5($buffer);
265
+ $content_length = strlen($buffer);
266
+
267
+ if (! $is_404) {
268
+ /**
269
+ * Send 304 header if content is not modified
270
+ */
271
+ $this->_send_headers_304($time, $etag);
272
+ }
273
+
274
+ /**
275
+ * Send headers
276
+ */
277
+ $this->_send_headers($time, $etag, $content_length, $compression);
278
+ } elseif ($this->_debug) {
279
+ /**
280
+ * Append debug info
281
+ */
282
+ $page_key = $this->_get_page_key($_SERVER['REQUEST_URI'], false);
283
+ $time_total = w3_microtime() - $this->_time_start;
284
+ $debug_info = $this->_get_debug_info($page_key, false, $this->cache_reject_reason, false, $time_total);
285
+ $this->_append_content($buffer, "\r\n\r\n" . $debug_info, false);
286
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  }
288
 
289
+ return $buffer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
  }
291
 
292
  /**
293
+ * Flushes all caches
294
  *
295
  * @return boolean
296
  */
297
  function flush()
298
  {
299
+ $cache = & $this->_get_cache();
300
 
301
  return $cache->flush();
302
  }
314
  }
315
 
316
  if ($post_id) {
317
+ $home = get_option('home');
318
 
319
+ $page_keys = array(
320
+ $this->_get_page_key(str_replace($home, '', post_permalink($post_id)), false),
321
+ $this->_get_page_key(str_replace($home, '', post_permalink($post_id)), 'gzip'),
322
+ $this->_get_page_key(str_replace($home, '', post_permalink($post_id)), 'deflate'),
323
+ $this->_get_page_key('/', false),
324
+ $this->_get_page_key('/', 'gzip'),
325
+ $this->_get_page_key('/', 'deflate')
326
+ );
327
 
328
+ $cache = & $this->_get_cache();
329
+
330
+ foreach ($page_keys as $page_key) {
 
331
  $cache->delete($page_key);
332
  }
 
 
 
 
 
 
 
 
333
  }
334
 
335
  return false;
336
  }
337
 
338
  /**
339
+ * Returns object instance
340
  *
341
  * @return W3_PgCache
342
  */
343
  function &instance()
344
  {
345
+ static $instances = array();
346
 
347
+ if (! isset($instances[0])) {
348
  $class = __CLASS__;
349
+ $instances[0] = & new $class();
350
  }
351
 
352
+ return $instances[0];
353
  }
354
 
355
  /**
362
  /**
363
  * Skip if disabled
364
  */
365
+ if (! $this->_config->get_boolean('pgcache.enabled')) {
366
+ $this->cache_reject_reason = 'page caching is disabled';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  return false;
368
  }
369
 
371
  * Skip if posting
372
  */
373
  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
374
+ $this->cache_reject_reason = 'request method is POST';
375
  return false;
376
  }
377
 
379
  * Skip if session defined
380
  */
381
  if (defined('SID') && SID != '') {
382
+ $this->cache_reject_reason = 'session is started';
383
  return false;
384
  }
385
 
386
  /**
387
  * Skip if there is query in the request uri
388
  */
389
+ if (! $this->_config->get_boolean('pgcache.cache.query') && strstr($_SERVER['REQUEST_URI'], '?') !== false) {
390
+ $this->cache_reject_reason = 'request URI contains query';
391
  return false;
392
  }
393
 
395
  * Check request URI
396
  */
397
  if (! in_array($_SERVER['PHP_SELF'], $this->_config->get_array('pgcache.accept.files')) && ! $this->_check_request_uri()) {
398
+ $this->cache_reject_reason = 'request URI is rejected';
399
  return false;
400
  }
401
 
403
  * Check User Agent
404
  */
405
  if (! $this->_check_ua()) {
406
+ $this->cache_reject_reason = 'user agent is rejected';
407
  return false;
408
  }
409
 
411
  * Check WordPress cookies
412
  */
413
  if (! $this->_check_cookies()) {
414
+ $this->cache_reject_reason = 'cookie is rejected';
415
  return false;
416
  }
417
 
418
  /**
419
  * Skip if user is logged in
420
  */
421
+ if ($this->_config->get_boolean('pgcache.reject.logged') && ! $this->_check_logged_in()) {
422
+ $this->cache_reject_reason = 'user is logged in';
423
 
424
  return false;
425
  }
445
  /**
446
  * Don't cache 404 pages
447
  */
448
+ if (! $this->_config->get_boolean('pgcache.cache.404') && function_exists('is_404') && is_404()) {
449
+ $this->cache_reject_reason = 'page is 404';
450
 
451
  return false;
452
  }
454
  /**
455
  * Don't cache homepage
456
  */
457
+ if (! $this->_config->get_boolean('pgcache.cache.home') && function_exists('is_home') && is_home()) {
458
+ $this->cache_reject_reason = 'page is home';
459
 
460
  return false;
461
  }
463
  /**
464
  * Don't cache feed
465
  */
466
+ if (! $this->_config->get_boolean('pgcache.cache.feed') && function_exists('is_feed') && is_feed()) {
467
+ $this->cache_reject_reason = 'page is feed';
468
 
469
  return false;
470
  }
479
  */
480
  function &_get_cache()
481
  {
482
+ static $cache = array();
483
 
484
+ if (! isset($cache[0])) {
485
+ $engine = $this->_config->get_string('pgcache.engine');
486
 
487
  switch ($engine) {
488
  case 'memcached':
489
  $engineConfig = array(
490
+ 'engine' => $this->_config->get_string('pgcache.memcached.engine'),
491
  'servers' => $this->_config->get_array('pgcache.memcached.servers'),
492
  'persistant' => true
493
  );
495
 
496
  case 'file':
497
  $engineConfig = array(
498
+ 'cache_dir' => W3TC_CACHE_FILE_PGCACHE_DIR
499
+ );
500
+ break;
501
+
502
+ case 'file_pgcache':
503
+ $engineConfig = array(
504
+ 'cache_dir' => W3TC_CACHE_FILE_PGCACHE_DIR,
505
+ 'expire' => $this->_lifetime
506
  );
507
  break;
508
 
511
  }
512
 
513
  require_once W3TC_LIB_W3_DIR . '/Cache.php';
514
+ $cache[0] = & W3_Cache::instance($engine, $engineConfig);
515
  }
516
 
517
+ return $cache[0];
518
  }
519
 
520
  /**
572
  if ($cookie_name == 'wordpress_test_cookie') {
573
  continue;
574
  }
575
+ if (preg_match('/^(wp-postpass|comment_author)/', $cookie_name)) {
576
  return false;
577
  }
578
  }
590
 
591
  /**
592
  * Check if user is logged in
593
+ *
594
  * @return boolean
595
  */
596
  function _check_logged_in()
614
  */
615
  function _get_compression()
616
  {
617
+ if (! w3_to_boolean(ini_get('zlib.output_compression')) && ! headers_sent()) {
618
+ $compressions = $this->_get_compressions();
619
+
620
+ foreach ($compressions as $compression) {
621
+ if (stristr($_SERVER['HTTP_ACCEPT_ENCODING'], $compression) !== false) {
622
+ return $compression;
623
+ }
624
+ }
625
  }
626
 
627
+ return false;
628
+ }
629
+
630
+ /**
631
+ * Returns array of supported compressions
632
+ *
633
+ * @return array
634
+ */
635
+ function _get_compressions()
636
+ {
637
+ $compression = $this->_config->get_string('pgcache.compression');
638
+ $compressions = array(
639
+ false
640
+ );
641
+
642
+ if ($compression != '') {
643
+ if (stristr($compression, 'gzip') !== false && function_exists('gzencode')) {
644
+ $compressions[] = 'gzip';
645
+ }
646
+
647
+ if (stristr($compression, 'deflate') !== false && function_exists('gzdeflate')) {
648
+ $compressions[] = 'deflate';
649
+ }
650
  }
651
 
652
+ return $compressions;
653
  }
654
 
655
  /**
662
  $headers = array();
663
 
664
  if (function_exists('headers_list')) {
665
+ $headers_list = headers_list();
666
+ if ($headers_list) {
667
+ foreach ($headers_list as $header) {
668
+ list ($header_name, $header_value) = explode(': ', $header, 2);
669
+ $headers[$header_name] = $header_value;
670
+ }
671
  }
 
 
 
672
  }
673
 
 
 
 
674
  return $headers;
675
  }
676
 
677
  /**
678
  * Returns array of data headers
679
  *
 
680
  * @return array
681
  */
682
+ function _get_cached_headers()
683
  {
684
  $data_headers = array();
685
  $cache_headers = $this->_config->get_array('pgcache.cache.headers');
686
+ $response_headers = $this->_get_response_headers();
687
 
688
+ foreach ($response_headers as $header_name => $header_value) {
689
  foreach ($cache_headers as $cache_header_name) {
690
  if (strcasecmp($header_name, $cache_header_name) == 0) {
691
  $data_headers[$header_name] = $header_value;
693
  }
694
  }
695
 
 
 
 
 
 
 
 
 
 
 
 
696
  return $data_headers;
697
  }
698
 
699
  /**
700
+ * Returns page key
701
  *
702
+ * @param string $request_uri
703
+ * @param string $compression
704
  * @return string
705
  */
706
+ function _get_page_key($request_uri, $compression)
707
  {
708
+ if ($this->_config->get_string('pgcache.engine') == 'file_pgcache') {
709
+ $request_uri = preg_replace('~\?.*$~', '', $request_uri);
710
+ $request_uri = str_replace('/index.php', '/', $request_uri);
711
+ $request_uri = preg_replace('~[/\\\]+~', '/', $request_uri);
712
+ $request_uri = w3_realpath($request_uri);
713
+
714
+ if (empty($request_uri)) {
715
+ $request_uri = '/';
716
  }
717
 
718
+ if (substr($request_uri, - 1) == '/') {
719
+ $request_uri .= 'index.html';
720
+ }
721
+
722
+ $request_uri = ltrim($request_uri, '/');
723
+
724
+ $key = sprintf('%s/%s', $_SERVER['HTTP_HOST'], $request_uri);
725
+
726
+ if (! empty($compression)) {
727
+ $key .= '.' . $compression;
728
+ }
729
+ } else {
730
+ $blog_id = w3_get_blog_id();
731
+
732
+ if (empty($blog_id)) {
733
+ $blog_id = $_SERVER['HTTP_HOST'];
734
+ }
735
+
736
+ $key = sprintf('w3tc_%s_page_%s', md5($blog_id), md5($request_uri));
737
+
738
+ if (! empty($compression)) {
739
+ $key .= '_' . $compression;
740
  }
741
  }
742
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
743
  return $key;
744
  }
745
 
768
  /**
769
  * Returns debug info
770
  *
771
+ * @param string $page_key
772
  * @param boolean $cache
773
  * @param string $reason
774
  * @param boolean $status
775
  * @param double $time
776
  * @return string
777
  */
778
+ function _get_debug_info($page_key, $cache, $reason, $status, $time)
779
  {
780
  $debug_info = "<!-- W3 Total Cache: Page cache debug info:\r\n";
781
  $debug_info .= sprintf("%s%s\r\n", str_pad('Engine: ', 20), w3_get_engine_name($this->_config->get_string('pgcache.engine')));
782
+ $debug_info .= sprintf("%s%s\r\n", str_pad('Key: ', 20), $page_key);
783
  $debug_info .= sprintf("%s%s\r\n", str_pad('Caching: ', 20), ($cache ? 'enabled' : 'disabled'));
784
  if (! $cache) {
785
  $debug_info .= sprintf("%s%s\r\n", str_pad('Reject reason: ', 20), $reason);
790
  $headers = $this->_get_response_headers();
791
 
792
  if (count($headers)) {
793
+ $debug_info .= "Header info:\r\n";
794
 
795
  foreach ($headers as $header_name => $header_value) {
796
  $debug_info .= sprintf("%s%s\r\n", str_pad($header_name . ': ', 20), $header_value);
807
  *
808
  * @param array $data
809
  * @param string $content
810
+ * @param string $compression
811
+ * @return string
812
  */
813
+ function _append_content(&$data, $content, $compression)
814
  {
815
+ switch ($compression) {
816
  case false:
817
+ $data .= $content;
818
  break;
819
 
820
  case 'gzip':
821
+ $data = (function_exists('gzdecode') ? gzdecode($data) : w3_gzdecode($data));
822
+ $data .= $content;
823
+ $data = gzencode($data);
824
  break;
825
 
826
  case 'deflate':
827
+ $data = gzinflate($data);
828
+ $data .= $content;
829
+ $data = gzdeflate($data);
830
  break;
831
  }
832
  }
833
 
834
  /**
835
+ * Sends headers
836
+ *
837
+ * @param array $headers
838
+ * @return boolean
839
  */
840
+ function _headers($headers)
841
  {
842
+ if (! headers_sent()) {
843
+ foreach ($headers as $name => $value) {
844
+ $header = ($name == 'Status' ? $value : $name . ': ' . $value);
845
+ @header($header);
846
+ }
847
+
848
+ return true;
849
  }
850
+
851
+ return false;
852
  }
853
 
854
  /**
855
+ * Sends headers
856
+ * @param string $etag
857
+ * @param integer $time
858
+ * @param integer $content_length
859
+ * @param string $compression
860
+ * @param array $custom_headers
861
+ * @return boolean
862
  */
863
+ function _send_headers($time, $etag, $content_length, $compression, $custom_headers = array())
864
  {
865
+ $curr_time = time();
866
+ $expires = $time + $this->_lifetime;
867
+ $max_age = ($expires > $curr_time ? $expires - $curr_time : 0);
868
+
869
+ $headers = array(
870
+ 'Pragma' => 'public',
871
+ 'Expires' => $this->_gmdate($expires),
872
+ 'Last-Modified' => $this->_gmdate($time),
873
+ 'Cache-Control' => 'max-age=' . $max_age . ', public, must-revalidate'
874
+ );
875
+
876
+ $headers = array_merge($headers, $custom_headers);
877
+
878
+ $headers = array_merge($headers, array(
879
+ 'Vary' => 'Cookie',
880
+ 'Etag' => $etag,
881
+ 'Content-Length' => $content_length
882
+ ));
883
+
884
+ if ($compression) {
885
+ $headers = array_merge($headers, array(
886
+ 'Vary' => 'Accept-Encoding, Cookie',
887
+ 'Content-Encoding' => $compression
888
+ ));
889
+ }
890
 
891
+ return $this->_headers($headers);
892
+ }
893
+
894
+ /**
895
+ * Sends 304 header if content is not modified
896
+ *
897
+ * @param integer $time
898
+ * @param string $etag
899
+ * @return boolean
900
+ */
901
+ function _send_headers_304($time, $etag)
902
+ {
903
+ if ($this->_check_modified_since($time) || $this->_check_match($etag)) {
904
+ $headers = array(
905
+ 'Status' => 'HTTP/1.1 304 Not Modified',
906
+ 'Etag' => $etag,
907
+ 'Last-Modified' => $this->_gmdate($time)
908
+ );
909
+
910
+ if ($this->_headers($headers)) {
911
+ exit();
912
+ }
913
+ }
914
+ }
915
+
916
+ /**
917
+ * Sends 404 header
918
+ *
919
+ * @return boolean
920
+ */
921
+ function _send_headers_404()
922
+ {
923
+ $headers = array(
924
+ 'Status' => 'HTTP/1.1 404 Not Found'
925
  );
926
 
927
+ return $this->_headers($headers);
928
+ }
929
+
930
+ /**
931
+ * Checks if User Agent is mobile
932
+ *
933
+ * @return boolean
934
+ */
935
+ function _is_mobile()
936
+ {
937
+ $mobile_agents = $this->_config->get_array('pgcache.mobile.agents');
938
+
939
+ foreach ($mobile_agents as $mobile_agent) {
940
+ if (stristr($_SERVER['HTTP_USER_AGENT'], $mobile_agent) !== false) {
941
+ return true;
942
+ }
943
+ }
944
+
945
+ return false;
946
+ }
947
+
948
+ /**
949
+ * Check if content was modified by time
950
+ * @param integer $time
951
+ * @return boolean
952
+ */
953
+ function _check_modified_since($time)
954
+ {
955
+ if (! empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
956
+ $if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
957
+
958
+ // IE has tacked on extra data to this header, strip it
959
+ if (($semicolon = strrpos($if_modified_since, ';')) !== false) {
960
+ $if_modified_since = substr($if_modified_since, 0, $semicolon);
961
+ }
962
+
963
+ return ($time == strtotime($if_modified_since));
964
+ }
965
+
966
+ return false;
967
+ }
968
+
969
+ /**
970
+ * Check if content was modified by etag
971
+ * @param string $etag
972
+ * @return boolean
973
+ */
974
+ function _check_match($etag)
975
+ {
976
+ if (! empty($_SERVER['HTTP_IF_NONE_MATCH'])) {
977
+ $if_none_match = (get_magic_quotes_gpc() ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : $_SERVER['HTTP_IF_NONE_MATCH']);
978
+ $client_etags = explode(',', $if_none_match);
979
+
980
+ foreach ($client_etags as $client_etag) {
981
+ $client_etag = trim($client_etag);
982
+
983
+ if ($etag == $client_etag) {
984
+ return true;
985
+ }
986
+ }
987
  }
988
 
989
+ return false;
990
+ }
991
+
992
+ /**
993
+ * Returns GMT date
994
+ * @param integer $time
995
+ * @return string
996
+ */
997
+ function _gmdate($time)
998
+ {
999
+ return gmdate('D, d M Y H:i:s \G\M\T', $time);
1000
  }
1001
  }
lib/W3/Plugin.php CHANGED
@@ -22,7 +22,7 @@ class W3_Plugin
22
  function __construct()
23
  {
24
  require_once W3TC_LIB_W3_DIR . '/Config.php';
25
- $this->_config = W3_Config::instance(false);
26
  }
27
 
28
  /**
@@ -49,14 +49,14 @@ class W3_Plugin
49
  */
50
  function &instance()
51
  {
52
- static $instance = null;
53
 
54
- if ($instance === null) {
55
  $class = __CLASS__;
56
- $instance = & new $class();
57
  }
58
 
59
- return $instance;
60
  }
61
 
62
  /**
@@ -66,23 +66,26 @@ class W3_Plugin
66
  */
67
  function locked()
68
  {
 
69
  static $locked = null;
70
 
71
  if ($locked === null) {
72
  $locked = false;
73
- $config = basename(W3TC_CONFIG_PATH);
74
- $config_dir = dirname(W3TC_CONFIG_PATH);
75
 
76
- $dir = @opendir($config_dir);
77
-
78
- if ($dir) {
79
- while (($entry = @readdir($dir))) {
80
- if (strpos($entry, W3TC_CONFIG_NAME) === 0 && $entry !== $config) {
81
- $locked = true;
82
- break;
 
 
 
 
 
83
  }
84
  }
85
- @closedir($dir);
86
  }
87
  }
88
 
22
  function __construct()
23
  {
24
  require_once W3TC_LIB_W3_DIR . '/Config.php';
25
+ $this->_config = & W3_Config::instance(false);
26
  }
27
 
28
  /**
49
  */
50
  function &instance()
51
  {
52
+ static $instances = array();
53
 
54
+ if (! isset($instances[0])) {
55
  $class = __CLASS__;
56
+ $instances[0] = & new $class();
57
  }
58
 
59
+ return $instances[0];
60
  }
61
 
62
  /**
66
  */
67
  function locked()
68
  {
69
+ global $blog_id;
70
  static $locked = null;
71
 
72
  if ($locked === null) {
73
  $locked = false;
 
 
74
 
75
+ // check only for WP MU
76
+ if ($blog_id && function_exists('get_blog_option')) {
77
+ $blogs = get_blog_list();
78
+
79
+ foreach ($blogs as $blog) {
80
+ if ($blog['blog_id'] != $blog_id) {
81
+ $active_plugins = get_blog_option($blog['blog_id'], 'active_plugins');
82
+
83
+ if (in_array(W3TC_FILE, $active_plugins)) {
84
+ $locked = true;
85
+ break;
86
+ }
87
  }
88
  }
 
89
  }
90
  }
91
 
lib/W3/Plugin/Cdn.php CHANGED
@@ -17,6 +17,13 @@ class W3_Plugin_Cdn extends W3_Plugin
17
  */
18
  var $replaced_urls = array();
19
 
 
 
 
 
 
 
 
20
  /**
21
  * Run plugin
22
  */
@@ -38,25 +45,22 @@ class W3_Plugin_Cdn extends W3_Plugin
38
  ));
39
 
40
  if ($this->_config->get_boolean('cdn.enabled')) {
41
- add_action('delete_attachment', array(
42
- &$this,
43
- 'delete_attachment'
44
- ));
45
-
46
- add_filter('wp_generate_attachment_metadata', array(
47
- &$this,
48
- 'generate_attachment_metadata'
49
- ));
50
-
51
- add_filter('the_content', array(
52
- &$this,
53
- 'the_content'
54
- ));
55
-
56
- add_action('w3_cdn_cron_queue_process', array(
57
- &$this,
58
- 'cron_queue_process'
59
- ));
60
 
61
  if ($this->can_cdn()) {
62
  ob_start(array(
@@ -74,14 +78,14 @@ class W3_Plugin_Cdn extends W3_Plugin
74
  */
75
  function &instance()
76
  {
77
- static $instance = null;
78
 
79
- if ($instance === null) {
80
  $class = __CLASS__;
81
- $instance = & new $class();
82
  }
83
 
84
- return $instance;
85
  }
86
 
87
  /**
@@ -96,7 +100,9 @@ class W3_Plugin_Cdn extends W3_Plugin
96
  if (! $upload_info) {
97
  $upload_path = get_option('upload_path');
98
  $upload_path = trim($upload_path);
 
99
  if (empty($upload_path)) {
 
100
  $upload_path = WP_CONTENT_DIR . '/uploads';
101
  }
102
 
@@ -107,17 +113,17 @@ class W3_Plugin_Cdn extends W3_Plugin
107
 
108
  $wpdb->query($sql);
109
 
110
- $sql = sprintf("CREATE TABLE `%s%s` (
111
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
112
- `local_path` varchar(255) NOT NULL DEFAULT '',
113
- `remote_path` varchar(255) NOT NULL DEFAULT '',
114
  `command` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '1 - Upload, 2 - Delete',
115
- `last_error` varchar(255) NOT NULL DEFAULT '',
116
  `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
117
  PRIMARY KEY (`id`),
118
  UNIQUE KEY `path` (`local_path`, `remote_path`),
119
  KEY `date` (`date`)
120
- ) DEFAULT CHARSET=latin1", $wpdb->prefix, W3TC_CDN_TABLE_QUEUE);
121
 
122
  $wpdb->query($sql);
123
 
@@ -125,7 +131,7 @@ class W3_Plugin_Cdn extends W3_Plugin
125
  die(sprintf('Unable to create table <strong>%s%s</strong>: %s', $wpdb->prefix, W3TC_CDN_TABLE_QUEUE, $wpdb->last_error));
126
  }
127
 
128
- wp_schedule_event(time(), 'every_15_min', 'w3_cdn_cron_queue_process');
129
  }
130
 
131
  /**
@@ -135,18 +141,42 @@ class W3_Plugin_Cdn extends W3_Plugin
135
  {
136
  global $wpdb;
137
 
138
- wp_clear_scheduled_hook('w3_cdn_cron_queue_process');
139
 
140
  $sql = sprintf('DROP TABLE IF EXISTS `%s%s`', $wpdb->prefix, W3TC_CDN_TABLE_QUEUE);
141
  $wpdb->query($sql);
142
  }
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  /**
145
  * Cron queue process event
146
  */
147
  function cron_queue_process()
148
  {
149
- $limit_queue = $this->_config->get_integer('cdn.limit.queue', 25);
150
  $this->queue_process($limit_queue);
151
  }
152
 
@@ -158,7 +188,11 @@ class W3_Plugin_Cdn extends W3_Plugin
158
  function delete_attachment($attachment_id)
159
  {
160
  $files = $this->get_attachment_files($attachment_id);
161
- $this->delete($files, true);
 
 
 
 
162
  }
163
 
164
  /**
@@ -170,33 +204,13 @@ class W3_Plugin_Cdn extends W3_Plugin
170
  function generate_attachment_metadata($metadata)
171
  {
172
  $files = $this->get_metadata_files($metadata);
 
173
 
174
- $this->upload($files, true);
175
-
176
- return $metadata;
177
- }
178
-
179
- /**
180
- * Content filter
181
- *
182
- * @param string $content
183
- * @return string
184
- */
185
- function the_content($content)
186
- {
187
- $siteurl = w3_get_site_url();
188
- $upload_url = $this->get_upload_url();
189
 
190
- if ($upload_url) {
191
- $regexp = '~(["\'])((' . preg_quote($siteurl) . ')?/?(' . preg_quote($upload_url) . '[^"\'>]+))~';
192
-
193
- $content = preg_replace_callback($regexp, array(
194
- &$this,
195
- 'link_replace_callback'
196
- ), $content);
197
- }
198
 
199
- return $content;
200
  }
201
 
202
  /**
@@ -245,53 +259,56 @@ class W3_Plugin_Cdn extends W3_Plugin
245
  */
246
  function ob_callback($buffer)
247
  {
248
- if (! w3_is_xml($buffer)) {
249
- return $buffer;
250
- }
251
-
252
- $siteurl = w3_get_site_url();
253
- $regexps = array();
254
-
255
- if ($this->_config->get_boolean('cdn.includes.enable', true)) {
256
- $mask = $this->_config->get_string('cdn.includes.files');
257
- if (! empty($mask)) {
258
- $regexps[] = '~(["\'])((' . preg_quote($siteurl) . ')?/?(' . preg_quote(WPINC) . '/(' . $this->get_regexp_by_mask($mask) . ')))~';
259
  }
260
- }
261
-
262
- if ($this->_config->get_boolean('cdn.theme.enable', true)) {
263
- $theme_dir = ltrim(str_replace($siteurl, '', get_stylesheet_directory_uri()), '/');
264
- $mask = $this->_config->get_string('cdn.theme.files');
265
- if (! empty($mask)) {
266
- $regexps[] = '~(["\'])((' . preg_quote($siteurl) . ')?/?(' . preg_quote($theme_dir) . '/(' . $this->get_regexp_by_mask($mask) . ')))~';
267
  }
268
- }
269
-
270
- if ($this->_config->get_boolean('cdn.minify.enable', true)) {
271
- $regexps[] = '~(["\'])((' . preg_quote($siteurl) . ')?/?(' . preg_quote(W3TC_CONTENT_DIR_NAME) . '/[a-z0-9-_]+\.include(-footer)?(-nb)?\.(css|js)))~';
272
- }
273
-
274
- if ($this->_config->get_boolean('cdn.custom.enable', true)) {
275
- $files = $this->_config->get_array('cdn.custom.files');
276
- if (! empty($files)) {
277
- $files_quoted = array();
278
- foreach ($files as $file) {
279
- $file = ltrim(str_replace($siteurl, '', $file), '/');
280
- $files_quoted[] = preg_quote($file);
281
  }
282
- $regexps[] = '~(["\'])((' . preg_quote($siteurl) . ')?/?(' . implode('|', $files_quoted) . '))~';
283
  }
284
- }
285
-
286
- foreach ($regexps as $regexp) {
287
- $buffer = preg_replace_callback($regexp, array(
288
- &$this,
289
- 'link_replace_callback'
290
- ), $buffer);
291
- }
292
-
293
- if ($this->_config->get_boolean('cdn.debug')) {
294
- $buffer .= "\r\n\r\n" . $this->get_debug_info();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  }
296
 
297
  return $buffer;
@@ -307,22 +324,20 @@ class W3_Plugin_Cdn extends W3_Plugin
307
  {
308
  $files = array();
309
 
310
- $site_path = w3_get_site_path();
311
- $upload_dir = $this->get_upload_dir();
312
- $upload_url = $this->get_upload_url();
313
 
314
- if ($upload_dir && $upload_url) {
315
  if (isset($metadata['file'])) {
316
  $file = $this->normalize_attachment_file($metadata['file']);
317
- $local_file = $site_path . $upload_dir . '/' . $file;
318
- $remote_file = $site_path . $upload_url . '/' . $file;
319
  $files[$local_file] = $remote_file;
320
  if (isset($metadata['sizes'])) {
321
  $file_dir = dirname($file);
322
  foreach ((array) $metadata['sizes'] as $size) {
323
  if (isset($size['file'])) {
324
- $local_file = $site_path . $upload_dir . '/' . $file_dir . '/' . $size['file'];
325
- $remote_file = $site_path . $upload_url . '/' . $file_dir . '/' . $size['file'];
326
  $files[$local_file] = $remote_file;
327
  }
328
  }
@@ -442,7 +457,7 @@ class W3_Plugin_Cdn extends W3_Plugin
442
  $commands = $this->queue_get($limit);
443
 
444
  if (count($commands)) {
445
- $cdn = $this->get_cdn();
446
  foreach ($commands as $command => $queue) {
447
  $files = array();
448
  $results = array();
@@ -480,9 +495,9 @@ class W3_Plugin_Cdn extends W3_Plugin
480
  * @param array $files
481
  * @param boolean $queue_failed
482
  * @param array $results
483
- * @return boolean|array
484
  */
485
- function upload($files, $queue_failed = false, &$results = array())
486
  {
487
  $upload = array();
488
 
@@ -492,7 +507,7 @@ class W3_Plugin_Cdn extends W3_Plugin
492
  $upload[$local_path] = $remote_path;
493
  }
494
 
495
- $cdn = $this->get_cdn();
496
  if (! $cdn->upload($upload, $results)) {
497
  if ($queue_failed) {
498
  foreach ($results as $result) {
@@ -514,9 +529,9 @@ class W3_Plugin_Cdn extends W3_Plugin
514
  * @param array $files
515
  * @param boolean $queue_failed
516
  * @param array $results
517
- * @return boolean|array
518
  */
519
- function delete($files, $queue_failed = false, &$results = array())
520
  {
521
  $delete = array();
522
 
@@ -526,7 +541,7 @@ class W3_Plugin_Cdn extends W3_Plugin
526
  $delete[$local_path] = $remote_path;
527
  }
528
 
529
- $cdn = $this->get_cdn();
530
  if (! $cdn->delete($delete, $results)) {
531
  if ($queue_failed) {
532
  foreach ($results as $result) {
@@ -544,7 +559,7 @@ class W3_Plugin_Cdn extends W3_Plugin
544
 
545
  /**
546
  * Export library to CDN
547
- *
548
  * @param integer $limit
549
  * @param integer $offset
550
  * @param integer $count
@@ -552,19 +567,16 @@ class W3_Plugin_Cdn extends W3_Plugin
552
  * @param array $results
553
  * @return boolean
554
  */
555
- function export_library($limit = null, $offset = null, &$count = null, &$total = null, &$results = array())
556
  {
557
  global $wpdb;
558
 
559
  $count = 0;
560
  $total = 0;
561
- $results = array();
562
 
563
- $site_path = w3_get_site_path();
564
- $upload_dir = $this->get_upload_dir();
565
- $upload_url = $this->get_upload_url();
566
 
567
- if ($upload_dir && $upload_url) {
568
  $sql = sprintf('SELECT
569
  pm.meta_value AS file,
570
  pm2.meta_value AS metadata
@@ -604,8 +616,8 @@ class W3_Plugin_Cdn extends W3_Plugin
604
  $files = array_merge($files, $this->get_metadata_files($metadata));
605
  } elseif (! empty($post->file)) {
606
  $file = $this->normalize_attachment_file($post->file);
607
- $local_file = $site_path . $upload_dir . '/' . $file;
608
- $remote_file = $site_path . $upload_url . '/' . $file;
609
  $files[$local_file] = $remote_file;
610
  }
611
  }
@@ -627,7 +639,7 @@ class W3_Plugin_Cdn extends W3_Plugin
627
  * @param array $results
628
  * @return boolean
629
  */
630
- function import_library($limit = null, $offset = null, &$count = null, &$total = null, &$results = array())
631
  {
632
  global $wpdb;
633
 
@@ -635,11 +647,11 @@ class W3_Plugin_Cdn extends W3_Plugin
635
  $total = 0;
636
  $results = array();
637
 
638
- $siteurl = w3_get_site_url();
639
- $upload_dir = $this->get_upload_dir();
640
- $upload_url = $this->get_upload_url();
641
 
642
- if ($upload_dir && $upload_url) {
643
  $sql = sprintf('SELECT
644
  ID,
645
  post_content,
@@ -648,7 +660,7 @@ class W3_Plugin_Cdn extends W3_Plugin
648
  %sposts
649
  WHERE
650
  post_status = "publish"
651
- AND post_type = "post"
652
  AND (post_content LIKE "%%src=%%"
653
  OR post_content LIKE "%%href=%%")
654
  ', $wpdb->prefix);
@@ -675,41 +687,44 @@ class W3_Plugin_Cdn extends W3_Plugin
675
 
676
  if (preg_match_all('~(href|src)=[\'"]?([^\'"<>\s]+)[\'"]?~', $post_content, $matches, PREG_SET_ORDER)) {
677
  foreach ($matches as $match) {
678
- $src = $match[2];
679
 
680
  if (preg_match('~(' . $regexp . ')$~', $src)) {
681
- $file = ltrim(str_replace($siteurl, '', $src), '\\/');
682
- $file_dir = date('Y/m', strtotime($post->post_date));
683
- $file_base = basename($file);
684
- $dst = sprintf('%s/%s/%s', $upload_dir, $file_dir, $file_base);
685
  $dst_dir = dirname($dst);
686
  $dst_path = ABSPATH . $dst;
687
- $dst_url = sprintf('%s/%s/%s/%s', $siteurl, $upload_url, $file_dir, $file_base);
688
  $result = false;
689
  $error = '';
690
  $download_result = null;
691
 
692
  w3_mkdir($dst_dir, 0755, ABSPATH);
693
 
 
694
  if (! file_exists($dst_path)) {
695
- if (w3_is_url($file)) {
 
696
  if ($import_external) {
697
- $download_result = $this->download($file, $dst_path);
698
  } else {
699
  $error = 'External file import is disabled';
700
  }
701
- } elseif (strstr($src, $upload_url) === false) {
702
- $file_path = ABSPATH . $file;
703
- $download_result = @copy($file_path, $dst_path);
 
 
704
  } else {
705
  $error = 'Source file already exists';
706
  }
707
 
708
  if ($download_result !== null) {
709
  if ($download_result) {
710
- $title = $file_base;
711
- $guid = $upload_url . '/' . $title;
712
- $mime_type = $this->get_mime_type($file_base);
713
 
714
  $GLOBALS['wp_rewrite'] = & new WP_Rewrite();
715
 
@@ -761,15 +776,16 @@ class W3_Plugin_Cdn extends W3_Plugin
761
 
762
  /**
763
  * Rename domain
764
- * @param $names
765
- * @param $limit
766
- * @param $offset
767
- * @param $count
768
- * @param $total
769
- * @param $results
 
770
  * @return void
771
  */
772
- function rename_domain($names, $limit = null, $offset = null, &$count = null, &$total = null, &$results = array())
773
  {
774
  global $wpdb;
775
 
@@ -777,14 +793,14 @@ class W3_Plugin_Cdn extends W3_Plugin
777
  $total = 0;
778
  $results = array();
779
 
780
- $siteurl = w3_get_site_url();
781
- $upload_url = $this->get_upload_url();
782
 
783
  foreach ($names as $index => $name) {
784
  $names[$index] = str_ireplace('www.', '', $name);
785
  }
786
 
787
- if ($upload_url) {
788
  $sql = sprintf('SELECT
789
  ID,
790
  post_content,
@@ -793,7 +809,7 @@ class W3_Plugin_Cdn extends W3_Plugin
793
  %sposts
794
  WHERE
795
  post_status = "publish"
796
- AND post_type = "post"
797
  AND (post_content LIKE "%%src=%%"
798
  OR post_content LIKE "%%href=%%")
799
  ', $wpdb->prefix);
@@ -811,17 +827,17 @@ class W3_Plugin_Cdn extends W3_Plugin
811
  if ($posts) {
812
  $count = count($posts);
813
  $total = $this->get_rename_posts_count();
814
- $names_quoted = array_map('preg_quote', $names);
815
 
816
  foreach ($posts as $post) {
817
  $matches = null;
818
  $post_content = $post->post_content;
819
- $regexp = '~(href|src)=[\'"]?(https?://(www\.)?(' . implode('|', $names_quoted) . ')/' . preg_quote($upload_url) . '([^\'"<>\s]+))[\'"]~';
820
 
821
  if (preg_match_all($regexp, $post_content, $matches, PREG_SET_ORDER)) {
822
  foreach ($matches as $match) {
823
  $old_url = $match[2];
824
- $new_url = sprintf('%s/%s%s', $siteurl, $upload_url, $match[5]);
825
  $post_content = str_replace($old_url, $new_url, $post_content);
826
 
827
  $results[] = array(
@@ -880,7 +896,7 @@ class W3_Plugin_Cdn extends W3_Plugin
880
  %sposts
881
  WHERE
882
  post_status = "publish"
883
- AND post_type = "post"
884
  AND (post_content LIKE "%%src=%%"
885
  OR post_content LIKE "%%href=%%")
886
  ', $wpdb->prefix);
@@ -903,7 +919,7 @@ class W3_Plugin_Cdn extends W3_Plugin
903
  */
904
  function get_files_includes()
905
  {
906
- $files = $this->search_files(ABSPATH . WPINC, w3_get_site_path() . WPINC, $this->_config->get_string('cdn.includes.files'));
907
 
908
  return $files;
909
  }
@@ -913,8 +929,8 @@ class W3_Plugin_Cdn extends W3_Plugin
913
  */
914
  function get_files_theme()
915
  {
916
- $theme_dir = ltrim(str_replace(ABSPATH, '', get_stylesheet_directory()), '/');
917
- $files = $this->search_files(get_stylesheet_directory(), w3_get_site_path() . $theme_dir, $this->_config->get_string('cdn.theme.files'));
918
 
919
  return $files;
920
  }
@@ -924,17 +940,18 @@ class W3_Plugin_Cdn extends W3_Plugin
924
  */
925
  function get_files_minify()
926
  {
927
- require_once W3TC_LIB_W3_DIR . '/Plugin/Minify.php';
928
- $minify = W3_Plugin_Minify::instance();
929
- $urls = $minify->get_urls();
930
-
931
  $files = array();
932
- $site_path = w3_get_site_path();
933
 
934
- foreach ($urls as $url) {
935
- $file = basename($url);
936
- if ($this->download($url, W3TC_CONTENT_DIR . '/' . $file)) {
937
- $files[] = $site_path . W3TC_CONTENT_DIR_NAME . '/' . $file;
 
 
 
 
 
 
938
  }
939
  }
940
 
@@ -946,7 +963,21 @@ class W3_Plugin_Cdn extends W3_Plugin
946
  */
947
  function get_files_custom()
948
  {
949
- $files = $this->_config->get_array('cdn.custom.files');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
950
 
951
  return $files;
952
  }
@@ -978,9 +1009,7 @@ class W3_Plugin_Cdn extends W3_Plugin
978
  */
979
  function format_local_path($file)
980
  {
981
- $site_path = w3_get_site_path();
982
- $abspath = ($site_path ? substr(ABSPATH, 0, - strlen($site_path)) : ABSPATH);
983
- return $abspath . $file;
984
  }
985
 
986
  /**
@@ -991,7 +1020,7 @@ class W3_Plugin_Cdn extends W3_Plugin
991
  */
992
  function format_remote_path($file)
993
  {
994
- return $file;
995
  }
996
 
997
  /**
@@ -1003,7 +1032,7 @@ class W3_Plugin_Cdn extends W3_Plugin
1003
  function link_replace_callback($matches)
1004
  {
1005
  global $wpdb;
1006
- static $queue = null, $domain = null;
1007
 
1008
  if (in_array($matches[2], $this->replaced_urls)) {
1009
  return $matches[0];
@@ -1018,17 +1047,18 @@ class W3_Plugin_Cdn extends W3_Plugin
1018
  return $matches[0];
1019
  }
1020
 
1021
- if ($domain === null) {
1022
- $domain = $this->_config->get_string('cdn.domain');
1023
- }
 
1024
 
1025
- if (empty($domain)) {
1026
  return $matches[0];
1027
  }
1028
 
1029
  $this->replaced_urls[] = $matches[2];
1030
 
1031
- $replacement = sprintf('%shttp://%s/%s%s', $matches[1], $domain, w3_get_site_path(), $matches[4]);
1032
 
1033
  return $replacement;
1034
  }
@@ -1059,7 +1089,7 @@ class W3_Plugin_Cdn extends W3_Plugin
1059
  } else {
1060
  $regexp = '~^' . $this->get_regexp_by_mask($mask) . '$~i';
1061
  if (preg_match($regexp, $entry)) {
1062
- $files[] = $base_dir . '/' . (($p = implode('/', $stack)) != '' ? $p . '/' : '') . $entry;
1063
  }
1064
  }
1065
  }
@@ -1090,127 +1120,11 @@ class W3_Plugin_Cdn extends W3_Plugin
1090
  '[',
1091
  ']',
1092
  '|'
1093
- ), preg_quote($mask));
1094
 
1095
  return $regexp;
1096
  }
1097
 
1098
- /**
1099
- * Returns file mime type
1100
- *
1101
- * @param string $file
1102
- * @return string
1103
- */
1104
- function get_mime_type($file)
1105
- {
1106
- $mime_types = array(
1107
- 'jpg|jpeg|jpe' => 'image/jpeg',
1108
- 'gif' => 'image/gif',
1109
- 'png' => 'image/png',
1110
- 'bmp' => 'image/bmp',
1111
- 'tif|tiff' => 'image/tiff',
1112
- 'ico' => 'image/x-icon',
1113
- 'asf|asx|wax|wmv|wmx' => 'video/asf',
1114
- 'avi' => 'video/avi',
1115
- 'divx' => 'video/divx',
1116
- 'mov|qt' => 'video/quicktime',
1117
- 'mpeg|mpg|mpe' => 'video/mpeg',
1118
- 'txt|c|cc|h' => 'text/plain',
1119
- 'rtx' => 'text/richtext',
1120
- 'css' => 'text/css',
1121
- 'htm|html' => 'text/html',
1122
- 'mp3|m4a' => 'audio/mpeg',
1123
- 'mp4|m4v' => 'video/mp4',
1124
- 'ra|ram' => 'audio/x-realaudio',
1125
- 'wav' => 'audio/wav',
1126
- 'ogg' => 'audio/ogg',
1127
- 'mid|midi' => 'audio/midi',
1128
- 'wma' => 'audio/wma',
1129
- 'rtf' => 'application/rtf',
1130
- 'js' => 'application/javascript',
1131
- 'pdf' => 'application/pdf',
1132
- 'doc|docx' => 'application/msword',
1133
- 'pot|pps|ppt|pptx' => 'application/vnd.ms-powerpoint',
1134
- 'wri' => 'application/vnd.ms-write',
1135
- 'xla|xls|xlsx|xlt|xlw' => 'application/vnd.ms-excel',
1136
- 'mdb' => 'application/vnd.ms-access',
1137
- 'mpp' => 'application/vnd.ms-project',
1138
- 'swf' => 'application/x-shockwave-flash',
1139
- 'class' => 'application/java',
1140
- 'tar' => 'application/x-tar',
1141
- 'zip' => 'application/zip',
1142
- 'gz|gzip' => 'application/x-gzip',
1143
- 'exe' => 'application/x-msdownload',
1144
- // openoffice formats
1145
- 'odt' => 'application/vnd.oasis.opendocument.text',
1146
- 'odp' => 'application/vnd.oasis.opendocument.presentation',
1147
- 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
1148
- 'odg' => 'application/vnd.oasis.opendocument.graphics',
1149
- 'odc' => 'application/vnd.oasis.opendocument.chart',
1150
- 'odb' => 'application/vnd.oasis.opendocument.database',
1151
- 'odf' => 'application/vnd.oasis.opendocument.formula'
1152
- );
1153
-
1154
- $file_ext = strrchr($file, '.');
1155
-
1156
- if ($file_ext) {
1157
- $file_ext = ltrim($file_ext, '.');
1158
- foreach ($mime_types as $extension => $mime_type) {
1159
- $exts = explode('|', $extension);
1160
- foreach ($exts as $ext) {
1161
- if ($file_ext == $ext) {
1162
- return $mime_type;
1163
- }
1164
- }
1165
- }
1166
- }
1167
-
1168
- return false;
1169
- }
1170
-
1171
- /**
1172
- * Returns upload dir
1173
- *
1174
- * @return string
1175
- */
1176
- function get_upload_dir()
1177
- {
1178
- static $upload_dir = null;
1179
-
1180
- if ($upload_dir === null) {
1181
- $upload_info = w3_upload_info();
1182
- if ($upload_info) {
1183
- $upload_dir = ltrim(str_replace(ABSPATH, '', $upload_info['basedir']), '\\/');
1184
- } else {
1185
- $upload_dir = false;
1186
- }
1187
- }
1188
-
1189
- return $upload_dir;
1190
- }
1191
-
1192
- /**
1193
- * Returns upload dir
1194
- *
1195
- * @return string
1196
- */
1197
- function get_upload_url()
1198
- {
1199
- static $upload_dir = null;
1200
-
1201
- if ($upload_dir === null) {
1202
- $upload_info = w3_upload_info();
1203
- if ($upload_info) {
1204
- $siteurl = w3_get_site_url();
1205
- $upload_dir = ltrim(str_replace($siteurl, '', $upload_info['baseurl']), '\\/');
1206
- } else {
1207
- $upload_dir = false;
1208
- }
1209
- }
1210
-
1211
- return $upload_dir;
1212
- }
1213
-
1214
  /**
1215
  * Normalizes attachment file
1216
  *
@@ -1221,7 +1135,12 @@ class W3_Plugin_Cdn extends W3_Plugin
1221
  {
1222
  $upload_info = w3_upload_info();
1223
  if ($upload_info) {
1224
- $file = ltrim(str_replace($upload_info['basedir'], '', $file), '\\/');
 
 
 
 
 
1225
  }
1226
 
1227
  return $file;
@@ -1234,34 +1153,60 @@ class W3_Plugin_Cdn extends W3_Plugin
1234
  */
1235
  function &get_cdn()
1236
  {
1237
- static $cdn = null;
1238
 
1239
- if ($cdn === null) {
1240
  $engine = $this->_config->get_string('cdn.engine');
1241
  $engine_config = array();
1242
 
1243
  switch ($engine) {
 
 
 
 
 
 
1244
  case 'ftp':
1245
  $engine_config = array(
1246
  'host' => $this->_config->get_string('cdn.ftp.host'),
1247
  'user' => $this->_config->get_string('cdn.ftp.user'),
1248
  'pass' => $this->_config->get_string('cdn.ftp.pass'),
1249
  'path' => $this->_config->get_string('cdn.ftp.path'),
1250
- 'pasv' => $this->_config->get_boolean('cdb.ftp.pasv')
 
1251
  );
1252
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1253
  }
1254
 
1255
  require_once W3TC_LIB_W3_DIR . '/Cdn.php';
1256
- $cdn = W3_Cdn::instance($engine, $engine_config);
1257
  }
1258
 
1259
- return $cdn;
1260
  }
1261
 
1262
  /**
1263
  * Returns debug info
1264
- *
1265
  * @return string
1266
  */
1267
  function get_debug_info()
@@ -1292,6 +1237,8 @@ class W3_Plugin_Cdn extends W3_Plugin
1292
  * Skip if CDN is disabled
1293
  */
1294
  if (! $this->_config->get_boolean('cdn.enabled')) {
 
 
1295
  return false;
1296
  }
1297
 
@@ -1299,34 +1246,8 @@ class W3_Plugin_Cdn extends W3_Plugin
1299
  * Skip if admin
1300
  */
1301
  if (defined('WP_ADMIN')) {
1302
- return false;
1303
- }
1304
-
1305
- /**
1306
- * Skip if doint AJAX
1307
- */
1308
- if (defined('DOING_AJAX')) {
1309
- return false;
1310
- }
1311
-
1312
- /**
1313
- * Skip if doing cron
1314
- */
1315
- if (defined('DOING_CRON')) {
1316
- return false;
1317
- }
1318
-
1319
- /**
1320
- * Skip if APP request
1321
- */
1322
- if (defined('APP_REQUEST')) {
1323
- return false;
1324
- }
1325
-
1326
- /**
1327
- * Skip if XMLRPC request
1328
- */
1329
- if (defined('XMLRPC_REQUEST')) {
1330
  return false;
1331
  }
1332
 
@@ -1334,6 +1255,8 @@ class W3_Plugin_Cdn extends W3_Plugin
1334
  * Check User agent
1335
  */
1336
  if (! $this->check_ua()) {
 
 
1337
  return false;
1338
  }
1339
 
@@ -1341,6 +1264,8 @@ class W3_Plugin_Cdn extends W3_Plugin
1341
  * Check request URI
1342
  */
1343
  if (! $this->check_request_uri()) {
 
 
1344
  return false;
1345
  }
1346
 
17
  */
18
  var $replaced_urls = array();
19
 
20
+ /**
21
+ * CDN reject reason
22
+ *
23
+ * @var string
24
+ */
25
+ var $cdn_reject_reason = '';
26
+
27
  /**
28
  * Run plugin
29
  */
45
  ));
46
 
47
  if ($this->_config->get_boolean('cdn.enabled')) {
48
+ if ($this->_config->get_string('cdn.engine') != 'mirror') {
49
+ add_action('delete_attachment', array(
50
+ &$this,
51
+ 'delete_attachment'
52
+ ));
53
+
54
+ add_filter('wp_generate_attachment_metadata', array(
55
+ &$this,
56
+ 'generate_attachment_metadata'
57
+ ));
58
+
59
+ add_action('w3_cdn_cron_queue_process', array(
60
+ &$this,
61
+ 'cron_queue_process'
62
+ ));
63
+ }
 
 
 
64
 
65
  if ($this->can_cdn()) {
66
  ob_start(array(
78
  */
79
  function &instance()
80
  {
81
+ static $instances = array();
82
 
83
+ if (! isset($instances[0])) {
84
  $class = __CLASS__;
85
+ $instances[0] = & new $class();
86
  }
87
 
88
+ return $instances[0];
89
  }
90
 
91
  /**
100
  if (! $upload_info) {
101
  $upload_path = get_option('upload_path');
102
  $upload_path = trim($upload_path);
103
+
104
  if (empty($upload_path)) {
105
+ echo 'Your store uploads folder is not available. Default WordPress directories will be created: <strong>wp-content/uploads/</strong>.<br />';
106
  $upload_path = WP_CONTENT_DIR . '/uploads';
107
  }
108
 
113
 
114
  $wpdb->query($sql);
115
 
116
+ $sql = sprintf("CREATE TABLE IF NOT EXISTS `%s%s` (
117
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
118
+ `local_path` varchar(150) NOT NULL DEFAULT '',
119
+ `remote_path` varchar(150) NOT NULL DEFAULT '',
120
  `command` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '1 - Upload, 2 - Delete',
121
+ `last_error` varchar(150) NOT NULL DEFAULT '',
122
  `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
123
  PRIMARY KEY (`id`),
124
  UNIQUE KEY `path` (`local_path`, `remote_path`),
125
  KEY `date` (`date`)
126
+ ) /*!40100 CHARACTER SET latin1 */", $wpdb->prefix, W3TC_CDN_TABLE_QUEUE);
127
 
128
  $wpdb->query($sql);
129
 
131
  die(sprintf('Unable to create table <strong>%s%s</strong>: %s', $wpdb->prefix, W3TC_CDN_TABLE_QUEUE, $wpdb->last_error));
132
  }
133
 
134
+ $this->schedule();
135
  }
136
 
137
  /**
141
  {
142
  global $wpdb;
143
 
144
+ $this->unschedule();
145
 
146
  $sql = sprintf('DROP TABLE IF EXISTS `%s%s`', $wpdb->prefix, W3TC_CDN_TABLE_QUEUE);
147
  $wpdb->query($sql);
148
  }
149
 
150
+ /**
151
+ * Schedules cron events
152
+ */
153
+ function schedule()
154
+ {
155
+ if ($this->_config->get_boolean('cdn.enabled') && $this->_config->get_string('cdn.engine') != 'mirror') {
156
+ if (! wp_next_scheduled('w3_cdn_cron_queue_process')) {
157
+ wp_schedule_event(time(), 'every_15_min', 'w3_cdn_cron_queue_process');
158
+ }
159
+ } else {
160
+ $this->unschedule();
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Unschedules cron events
166
+ */
167
+ function unschedule()
168
+ {
169
+ if (wp_next_scheduled('w3_cdn_cron_queue_process')) {
170
+ wp_clear_scheduled_hook('w3_cdn_cron_queue_process');
171
+ }
172
+ }
173
+
174
  /**
175
  * Cron queue process event
176
  */
177
  function cron_queue_process()
178
  {
179
+ $limit_queue = $this->_config->get_integer('cdn.limit.queue');
180
  $this->queue_process($limit_queue);
181
  }
182
 
188
  function delete_attachment($attachment_id)
189
  {
190
  $files = $this->get_attachment_files($attachment_id);
191
+ $files = apply_filters('w3tc_cdn_delete_attachment_files', $files);
192
+
193
+ $results = array();
194
+
195
+ $this->delete($files, true, $results);
196
  }
197
 
198
  /**
204
  function generate_attachment_metadata($metadata)
205
  {
206
  $files = $this->get_metadata_files($metadata);
207
+ $files = apply_filters('w3tc_cdn_upload_attachment_files', $files);
208
 
209
+ $results = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
 
211
+ $this->upload($files, true, $results);
 
 
 
 
 
 
 
212
 
213
+ return $metadata;
214
  }
215
 
216
  /**
259
  */
260
  function ob_callback($buffer)
261
  {
262
+ if ($buffer != '' && w3_is_xml($buffer)) {
263
+ $site_url_regexp = w3_get_site_url_regexp();
264
+ $upload_info = w3_upload_info();
265
+ $regexps = array();
266
+
267
+ if ($upload_info) {
268
+ $regexps[] = '~(["\'])((' . $site_url_regexp . ')?/?(' . w3_preg_quote($upload_info['upload_url']) . '[^"\'>]+))~';
 
 
 
 
269
  }
270
+
271
+ if ($this->_config->get_boolean('cdn.includes.enable')) {
272
+ $mask = $this->_config->get_string('cdn.includes.files');
273
+ if (! empty($mask)) {
274
+ $regexps[] = '~(["\'])((' . $site_url_regexp . ')?/?(' . w3_preg_quote(WPINC) . '/(' . $this->get_regexp_by_mask($mask) . ')))~';
275
+ }
 
276
  }
277
+
278
+ if ($this->_config->get_boolean('cdn.theme.enable')) {
279
+ $theme_dir = preg_replace('~' . $site_url_regexp . '~i', '', get_stylesheet_directory_uri());
280
+ $mask = $this->_config->get_string('cdn.theme.files');
281
+ if (! empty($mask)) {
282
+ $regexps[] = '~(["\'])((' . $site_url_regexp . ')?/?(' . w3_preg_quote($theme_dir) . '/(' . $this->get_regexp_by_mask($mask) . ')))~';
 
 
 
 
 
 
 
283
  }
 
284
  }
285
+
286
+ if ($this->_config->get_boolean('cdn.minify.enable')) {
287
+ $regexps[] = '~(["\'])((' . $site_url_regexp . ')?/?(' . w3_preg_quote(W3TC_CONTENT_MINIFY_DIR_NAME) . '/[a-z0-9-_]+\.include(-footer)?(-nb)?\.(css|js)))~';
288
+ }
289
+
290
+ if ($this->_config->get_boolean('cdn.custom.enable')) {
291
+ $masks = $this->_config->get_array('cdn.custom.files');
292
+ if (! empty($masks)) {
293
+ $mask_regexps = array();
294
+ foreach ($masks as $mask) {
295
+ $mask = ltrim(preg_replace('~' . $site_url_regexp . '~i', '', $mask), '/\\');
296
+ $mask_regexps[] = $this->get_regexp_by_mask($mask);
297
+ }
298
+ $regexps[] = '~(["\'])((' . $site_url_regexp . ')?/?(' . implode('|', $mask_regexps) . '))~';
299
+ }
300
+ }
301
+
302
+ foreach ($regexps as $regexp) {
303
+ $buffer = preg_replace_callback($regexp, array(
304
+ &$this,
305
+ 'link_replace_callback'
306
+ ), $buffer);
307
+ }
308
+
309
+ if ($this->_config->get_boolean('cdn.debug')) {
310
+ $buffer .= "\r\n\r\n" . $this->get_debug_info();
311
+ }
312
  }
313
 
314
  return $buffer;
324
  {
325
  $files = array();
326
 
327
+ $upload_info = w3_upload_info();
 
 
328
 
329
+ if ($upload_info) {
330
  if (isset($metadata['file'])) {
331
  $file = $this->normalize_attachment_file($metadata['file']);
332
+ $local_file = $upload_info['upload_dir'] . '/' . $file;
333
+ $remote_file = $upload_info['upload_url'] . '/' . $file;
334
  $files[$local_file] = $remote_file;
335
  if (isset($metadata['sizes'])) {
336
  $file_dir = dirname($file);
337
  foreach ((array) $metadata['sizes'] as $size) {
338
  if (isset($size['file'])) {
339
+ $local_file = $upload_info['upload_dir'] . '/' . $file_dir . '/' . $size['file'];
340
+ $remote_file = $upload_info['upload_url'] . '/' . $file_dir . '/' . $size['file'];
341
  $files[$local_file] = $remote_file;
342
  }
343
  }
457
  $commands = $this->queue_get($limit);
458
 
459
  if (count($commands)) {
460
+ $cdn = & $this->get_cdn();
461
  foreach ($commands as $command => $queue) {
462
  $files = array();
463
  $results = array();
495
  * @param array $files
496
  * @param boolean $queue_failed
497
  * @param array $results
498
+ * @return boolean
499
  */
500
+ function upload($files, $queue_failed, &$results)
501
  {
502
  $upload = array();
503
 
507
  $upload[$local_path] = $remote_path;
508
  }
509
 
510
+ $cdn = & $this->get_cdn();
511
  if (! $cdn->upload($upload, $results)) {
512
  if ($queue_failed) {
513
  foreach ($results as $result) {
529
  * @param array $files
530
  * @param boolean $queue_failed
531
  * @param array $results
532
+ * @return boolean
533
  */
534
+ function delete($files, $queue_failed, &$results)
535
  {
536
  $delete = array();
537
 
541
  $delete[$local_path] = $remote_path;
542
  }
543
 
544
+ $cdn = & $this->get_cdn();
545
  if (! $cdn->delete($delete, $results)) {
546
  if ($queue_failed) {
547
  foreach ($results as $result) {
559
 
560
  /**
561
  * Export library to CDN
562
+ *
563
  * @param integer $limit
564
  * @param integer $offset
565
  * @param integer $count
567
  * @param array $results
568
  * @return boolean
569
  */
570
+ function export_library($limit, $offset, &$count, &$total, &$results)
571
  {
572
  global $wpdb;
573
 
574
  $count = 0;
575
  $total = 0;
 
576
 
577
+ $upload_info = w3_upload_info();
 
 
578
 
579
+ if ($upload_info) {
580
  $sql = sprintf('SELECT
581
  pm.meta_value AS file,
582
  pm2.meta_value AS metadata
616
  $files = array_merge($files, $this->get_metadata_files($metadata));
617
  } elseif (! empty($post->file)) {
618
  $file = $this->normalize_attachment_file($post->file);
619
+ $local_file = $upload_info['upload_dir'] . '/' . $file;
620
+ $remote_file = $upload_info['upload_url'] . '/' . $file;
621
  $files[$local_file] = $remote_file;
622
  }
623
  }
639
  * @param array $results
640
  * @return boolean
641
  */
642
+ function import_library($limit, $offset, &$count, &$total, &$results)
643
  {
644
  global $wpdb;
645
 
647
  $total = 0;
648
  $results = array();
649
 
650
+ $site_url = w3_get_site_url();
651
+ $site_url_regexp = w3_get_site_url_regexp();
652
+ $upload_info = w3_upload_info();
653
 
654
+ if ($upload_info) {
655
  $sql = sprintf('SELECT
656
  ID,
657
  post_content,
660
  %sposts
661
  WHERE
662
  post_status = "publish"
663
+ AND (post_type = "post" OR post_type = "page")
664
  AND (post_content LIKE "%%src=%%"
665
  OR post_content LIKE "%%href=%%")
666
  ', $wpdb->prefix);
687
 
688
  if (preg_match_all('~(href|src)=[\'"]?([^\'"<>\s]+)[\'"]?~', $post_content, $matches, PREG_SET_ORDER)) {
689
  foreach ($matches as $match) {
690
+ $src = ltrim(preg_replace('~' . $site_url_regexp . '~i', '', $match[2]), '/\\');
691
 
692
  if (preg_match('~(' . $regexp . ')$~', $src)) {
693
+ $src_dir = date('Y/m', strtotime($post->post_date));
694
+ $src_base = basename($src);
695
+ $dst = sprintf('%s/%s/%s', $upload_info['upload_dir'], $src_dir, $src_base);
 
696
  $dst_dir = dirname($dst);
697
  $dst_path = ABSPATH . $dst;
698
+ $dst_url = sprintf('%s%s/%s/%s', $site_url, $upload_info['upload_url'], $src_dir, $src_base);
699
  $result = false;
700
  $error = '';
701
  $download_result = null;
702
 
703
  w3_mkdir($dst_dir, 0755, ABSPATH);
704
 
705
+ // file already exists
706
  if (! file_exists($dst_path)) {
707
+ // source is external URL
708
+ if (w3_is_url($src)) {
709
  if ($import_external) {
710
+ $download_result = $this->download($src, $dst_path);
711
  } else {
712
  $error = 'External file import is disabled';
713
  }
714
+ // source is local file not in wp-content/uploads dir
715
+ } elseif (strstr($src, $upload_info['upload_dir']) === false) {
716
+ $src_path = ABSPATH . $src;
717
+ $download_result = @copy($src_path, $dst_path);
718
+ // file is already in wp-content/uploads dir
719
  } else {
720
  $error = 'Source file already exists';
721
  }
722
 
723
  if ($download_result !== null) {
724
  if ($download_result) {
725
+ $title = $src_base;
726
+ $guid = $upload_info['upload_url'] . '/' . $title;
727
+ $mime_type = w3_get_mime_type($src_base);
728
 
729
  $GLOBALS['wp_rewrite'] = & new WP_Rewrite();
730
 
776
 
777
  /**
778
  * Rename domain
779
+ *
780
+ * @param array $names
781
+ * @param integer $limit
782
+ * @param integer $offset
783
+ * @param integer $count
784
+ * @param integer $total
785
+ * @param integer $results
786
  * @return void
787
  */
788
+ function rename_domain($names, $limit, $offset, &$count, &$total, &$results)
789
  {
790
  global $wpdb;
791
 
793
  $total = 0;
794
  $results = array();
795
 
796
+ $site_url = w3_get_site_url();
797
+ $upload_info = w3_upload_info();
798
 
799
  foreach ($names as $index => $name) {
800
  $names[$index] = str_ireplace('www.', '', $name);
801
  }
802
 
803
+ if ($upload_info) {
804
  $sql = sprintf('SELECT
805
  ID,
806
  post_content,
809
  %sposts
810
  WHERE
811
  post_status = "publish"
812
+ AND (post_type = "post" OR post_type = "page")
813
  AND (post_content LIKE "%%src=%%"
814
  OR post_content LIKE "%%href=%%")
815
  ', $wpdb->prefix);
827
  if ($posts) {
828
  $count = count($posts);
829
  $total = $this->get_rename_posts_count();
830
+ $names_quoted = array_map('w3_preg_quote', $names);
831
 
832
  foreach ($posts as $post) {
833
  $matches = null;
834
  $post_content = $post->post_content;
835
+ $regexp = '~(href|src)=[\'"]?(https?://(www\.)?(' . implode('|', $names_quoted) . ')/' . w3_preg_quote($upload_info['upload_url']) . '([^\'"<>\s]+))[\'"]~';
836
 
837
  if (preg_match_all($regexp, $post_content, $matches, PREG_SET_ORDER)) {
838
  foreach ($matches as $match) {
839
  $old_url = $match[2];
840
+ $new_url = sprintf('%s%s%s', $site_url, $upload_info['upload_url'], $match[5]);
841
  $post_content = str_replace($old_url, $new_url, $post_content);
842
 
843
  $results[] = array(
896
  %sposts
897
  WHERE
898
  post_status = "publish"
899
+ AND (post_type = "post" OR post_type = "page")
900
  AND (post_content LIKE "%%src=%%"
901
  OR post_content LIKE "%%href=%%")
902
  ', $wpdb->prefix);
919
  */
920
  function get_files_includes()
921
  {
922
+ $files = $this->search_files(ABSPATH . WPINC, WPINC, $this->_config->get_string('cdn.includes.files'));
923
 
924
  return $files;
925
  }
929
  */
930
  function get_files_theme()
931
  {
932
+ $theme_dir = ltrim(str_replace(ABSPATH, '', get_stylesheet_directory()), '/\\');
933
+ $files = $this->search_files(get_stylesheet_directory(), $theme_dir, $this->_config->get_string('cdn.theme.files'));
934
 
935
  return $files;
936
  }
940
  */
941
  function get_files_minify()
942
  {
 
 
 
 
943
  $files = array();
 
944
 
945
+ if (W3TC_PHP5) {
946
+ require_once W3TC_LIB_W3_DIR . '/Plugin/Minify.php';
947
+ $minify = & W3_Plugin_Minify::instance();
948
+ $urls = $minify->get_urls();
949
+
950
+ foreach ($urls as $url) {
951
+ $file = basename($url);
952
+ if ($this->download($url, W3TC_CONTENT_MINIFY_DIR . '/' . $file)) {
953
+ $files[] = W3TC_CONTENT_MINIFY_DIR_NAME . '/' . $file;
954
+ }
955
  }
956
  }
957
 
963
  */
964
  function get_files_custom()
965
  {
966
+ $site_url_regexp = w3_get_site_url_regexp();
967
+ $custom_files = $this->_config->get_array('cdn.custom.files');
968
+ $files = array();
969
+
970
+ foreach ($custom_files as $custom_file) {
971
+ if (! empty($custom_file)) {
972
+ $custom_file = ltrim(preg_replace('~' . $site_url_regexp . '~i', '', $custom_file), '/\\');
973
+ $dir = trim(dirname($custom_file), '/\\');
974
+ if ($dir == '.') {
975
+ $dir = '';
976
+ }
977
+ $mask = basename($custom_file);
978
+ $files = array_merge($files, $this->search_files(ABSPATH . $dir, $dir, $mask));
979
+ }
980
+ }
981
 
982
  return $files;
983
  }
1009
  */
1010
  function format_local_path($file)
1011
  {
1012
+ return ABSPATH . $file;
 
 
1013
  }
1014
 
1015
  /**
1020
  */
1021
  function format_remote_path($file)
1022
  {
1023
+ return w3_get_site_path() . $file;
1024
  }
1025
 
1026
  /**
1032
  function link_replace_callback($matches)
1033
  {
1034
  global $wpdb;
1035
+ static $queue = null;
1036
 
1037
  if (in_array($matches[2], $this->replaced_urls)) {
1038
  return $matches[0];
1047
  return $matches[0];
1048
  }
1049
 
1050
+ $path = '/' . w3_get_site_path() . $matches[4];
1051
+
1052
+ $cdn = & $this->get_cdn();
1053
+ $url = $cdn->format_url($path);
1054
 
1055
+ if (! $url) {
1056
  return $matches[0];
1057
  }
1058
 
1059
  $this->replaced_urls[] = $matches[2];
1060
 
1061
+ $replacement = sprintf('%s%s', $matches[1], $url);
1062
 
1063
  return $replacement;
1064
  }
1089
  } else {
1090
  $regexp = '~^' . $this->get_regexp_by_mask($mask) . '$~i';
1091
  if (preg_match($regexp, $entry)) {
1092
+ $files[] = ($base_dir != '' ? $base_dir . '/' : '') . (($p = implode('/', $stack)) != '' ? $p . '/' : '') . $entry;
1093
  }
1094
  }
1095
  }
1120
  '[',
1121
  ']',
1122
  '|'
1123
+ ), w3_preg_quote($mask));
1124
 
1125
  return $regexp;
1126
  }
1127
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1128
  /**
1129
  * Normalizes attachment file
1130
  *
1135
  {
1136
  $upload_info = w3_upload_info();
1137
  if ($upload_info) {
1138
+ $file = ltrim(str_replace($upload_info['basedir'], '', $file), '/\\');
1139
+ $matches = null;
1140
+
1141
+ if (preg_match('~(\d{4}/\d{2}/)?[^/]+$~', $file, $matches)) {
1142
+ $file = $matches[0];
1143
+ }
1144
  }
1145
 
1146
  return $file;
1153
  */
1154
  function &get_cdn()
1155
  {
1156
+ static $cdn = array();
1157
 
1158
+ if (! isset($cdn[0])) {
1159
  $engine = $this->_config->get_string('cdn.engine');
1160
  $engine_config = array();
1161
 
1162
  switch ($engine) {
1163
+ case 'mirror':
1164
+ $engine_config = array(
1165
+ 'domain' => $this->_config->get_string('cdn.mirror.domain')
1166
+ );
1167
+ break;
1168
+
1169
  case 'ftp':
1170
  $engine_config = array(
1171
  'host' => $this->_config->get_string('cdn.ftp.host'),
1172
  'user' => $this->_config->get_string('cdn.ftp.user'),
1173
  'pass' => $this->_config->get_string('cdn.ftp.pass'),
1174
  'path' => $this->_config->get_string('cdn.ftp.path'),
1175
+ 'pasv' => $this->_config->get_boolean('cdb.ftp.pasv'),
1176
+ 'domain' => $this->_config->get_string('cdn.ftp.domain')
1177
  );
1178
  break;
1179
+
1180
+ case 's3':
1181
+ $engine_config = array(
1182
+ 'key' => $this->_config->get_string('cdn.s3.key'),
1183
+ 'secret' => $this->_config->get_string('cdn.s3.secret'),
1184
+ 'bucket' => $this->_config->get_string('cdn.s3.bucket')
1185
+ );
1186
+ break;
1187
+
1188
+ case 'cf':
1189
+ $engine_config = array(
1190
+ 'key' => $this->_config->get_string('cdn.cf.key'),
1191
+ 'secret' => $this->_config->get_string('cdn.cf.secret'),
1192
+ 'bucket' => $this->_config->get_string('cdn.cf.bucket'),
1193
+ 'id' => $this->_config->get_string('cdn.cf.id'),
1194
+ 'cname' => $this->_config->get_string('cdn.cf.cname')
1195
+ );
1196
+ break;
1197
+
1198
  }
1199
 
1200
  require_once W3TC_LIB_W3_DIR . '/Cdn.php';
1201
+ $cdn[0] = & W3_Cdn::instance($engine, $engine_config);
1202
  }
1203
 
1204
+ return $cdn[0];
1205
  }
1206
 
1207
  /**
1208
  * Returns debug info
1209
+ *
1210
  * @return string
1211
  */
1212
  function get_debug_info()
1237
  * Skip if CDN is disabled
1238
  */
1239
  if (! $this->_config->get_boolean('cdn.enabled')) {
1240
+ $this->cdn_reject_reason = 'CDN is disabled';
1241
+
1242
  return false;
1243
  }
1244
 
1246
  * Skip if admin
1247
  */
1248
  if (defined('WP_ADMIN')) {
1249
+ $this->cdn_reject_reason = 'wp-admin';
1250
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1251
  return false;
1252
  }
1253
 
1255
  * Check User agent
1256
  */
1257
  if (! $this->check_ua()) {
1258
+ $this->cdn_reject_reason = 'user agent is rejected';
1259
+
1260
  return false;
1261
  }
1262
 
1264
  * Check request URI
1265
  */
1266
  if (! $this->check_request_uri()) {
1267
+ $this->cdn_reject_reason = 'request URI is rejected';
1268
+
1269
  return false;
1270
  }
1271
 
lib/W3/Plugin/DbCache.php CHANGED
@@ -24,6 +24,80 @@ class W3_Plugin_DbCache extends W3_Plugin
24
  &$this,
25
  'deactivate'
26
  ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  }
28
 
29
  /**
@@ -33,14 +107,14 @@ class W3_Plugin_DbCache extends W3_Plugin
33
  */
34
  function &instance()
35
  {
36
- static $instance = null;
37
 
38
- if ($instance === null) {
39
  $class = __CLASS__;
40
- $instance = & new $class();
41
  }
42
 
43
- return $instance;
44
  }
45
 
46
  /**
@@ -57,6 +131,8 @@ class W3_Plugin_DbCache extends W3_Plugin
57
  w3_writable_error($file_db);
58
  }
59
  }
 
 
60
  }
61
 
62
  /**
@@ -64,8 +140,83 @@ class W3_Plugin_DbCache extends W3_Plugin
64
  */
65
  function deactivate()
66
  {
 
 
67
  if (! $this->locked()) {
68
  @unlink(WP_CONTENT_DIR . '/db.php');
69
  }
70
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  }
24
  &$this,
25
  'deactivate'
26
  ));
27
+
28
+ add_filter('cron_schedules', array(
29
+ &$this,
30
+ 'cron_schedules'
31
+ ));
32
+
33
+ if ($this->_config->get_boolean('dbcache.enabled')) {
34
+ if ($this->_config->get_string('dbcache.engine') == 'file') {
35
+ add_action('w3_dbcache_cleanup', array(
36
+ &$this,
37
+ 'cleanup'
38
+ ));
39
+ }
40
+
41
+ add_action('publish_phone', array(
42
+ &$this,
43
+ 'on_change'
44
+ ), 0);
45
+
46
+ add_action('publish_post', array(
47
+ &$this,
48
+ 'on_change'
49
+ ), 0);
50
+
51
+ add_action('edit_post', array(
52
+ &$this,
53
+ 'on_change'
54
+ ), 0);
55
+
56
+ add_action('delete_post', array(
57
+ &$this,
58
+ 'on_change'
59
+ ), 0);
60
+
61
+ add_action('comment_post', array(
62
+ &$this,
63
+ 'on_change'
64
+ ), 0);
65
+
66
+ add_action('edit_comment', array(
67
+ &$this,
68
+ 'on_change'
69
+ ), 0);
70
+
71
+ add_action('delete_comment', array(
72
+ &$this,
73
+ 'on_change'
74
+ ), 0);
75
+
76
+ add_action('wp_set_comment_status', array(
77
+ &$this,
78
+ 'on_change'
79
+ ), 0);
80
+
81
+ add_action('trackback_post', array(
82
+ &$this,
83
+ 'on_change'
84
+ ), 0);
85
+
86
+ add_action('pingback_post', array(
87
+ &$this,
88
+ 'on_change'
89
+ ), 0);
90
+
91
+ add_action('switch_theme', array(
92
+ &$this,
93
+ 'on_change'
94
+ ), 0);
95
+
96
+ add_action('edit_user_profile_update', array(
97
+ &$this,
98
+ 'on_change'
99
+ ), 0);
100
+ }
101
  }
102
 
103
  /**
107
  */
108
  function &instance()
109
  {
110
+ static $instances = array();
111
 
112
+ if (! isset($instances[0])) {
113
  $class = __CLASS__;
114
+ $instances[0] = & new $class();
115
  }
116
 
117
+ return $instances[0];
118
  }
119
 
120
  /**
131
  w3_writable_error($file_db);
132
  }
133
  }
134
+
135
+ $this->schedule();
136
  }
137
 
138
  /**
140
  */
141
  function deactivate()
142
  {
143
+ $this->unschedule();
144
+
145
  if (! $this->locked()) {
146
  @unlink(WP_CONTENT_DIR . '/db.php');
147
  }
148
  }
149
+
150
+ /**
151
+ * Schedules events
152
+ */
153
+ function schedule()
154
+ {
155
+ if ($this->_config->get_boolean('dbcache.enabled') && $this->_config->get_string('dbcache.engine') == 'file') {
156
+ if (! wp_next_scheduled('w3_dbcache_cleanup')) {
157
+ wp_schedule_event(time(), 'w3_dbcache_cleanup', 'w3_dbcache_cleanup');
158
+ }
159
+ } else {
160
+ $this->unschedule();
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Unschedules events
166
+ */
167
+ function unschedule()
168
+ {
169
+ if (wp_next_scheduled('w3_dbcache_cleanup')) {
170
+ wp_clear_scheduled_hook('w3_dbcache_cleanup');
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Does disk cache cleanup
176
+ *
177
+ * @return void
178
+ */
179
+ function cleanup()
180
+ {
181
+ require_once W3TC_LIB_W3_DIR . '/Cache/File/Manager.php';
182
+
183
+ $w3_cache_file_manager = & new W3_Cache_File_Manager(array(
184
+ 'cache_dir' => W3TC_CACHE_FILE_DBCACHE_DIR
185
+ ));
186
+
187
+ $w3_cache_file_manager->clean();
188
+ }
189
+
190
+ /**
191
+ * Cron schedules filter
192
+ *
193
+ * @paran array $schedules
194
+ * @return array
195
+ */
196
+ function cron_schedules($schedules)
197
+ {
198
+ $gc = $this->_config->get_integer('dbcache.file.gc');
199
+
200
+ return array_merge($schedules, array(
201
+ 'w3_dbcache_cleanup' => array(
202
+ 'interval' => $gc,
203
+ 'display' => sprintf('Every %d seconds', $gc)
204
+ )
205
+ ));
206
+ }
207
+
208
+ /**
209
+ * Change action
210
+ */
211
+ function on_change()
212
+ {
213
+ static $flushed = false;
214
+
215
+ if (! $flushed) {
216
+ require_once W3TC_LIB_W3_DIR . '/Db.php';
217
+
218
+ $w3_db = & W3_Db::instance();
219
+ $w3_db->flush_cache();
220
+ }
221
+ }
222
  }
lib/W3/Plugin/Minify.php CHANGED
@@ -10,6 +10,13 @@ require_once W3TC_LIB_W3_DIR . '/Plugin.php';
10
  */
11
  class W3_Plugin_Minify extends W3_Plugin
12
  {
 
 
 
 
 
 
 
13
  /**
14
  * Runs plugin
15
  */
@@ -25,6 +32,18 @@ class W3_Plugin_Minify extends W3_Plugin
25
  'deactivate'
26
  ));
27
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  if ($this->can_minify()) {
29
  ob_start(array(
30
  &$this,
@@ -45,14 +64,14 @@ class W3_Plugin_Minify extends W3_Plugin
45
  */
46
  function &instance()
47
  {
48
- static $instance = null;
49
 
50
- if ($instance === null) {
51
  $class = __CLASS__;
52
- $instance = & new $class();
53
  }
54
 
55
- return $instance;
56
  }
57
 
58
  /**
@@ -69,30 +88,20 @@ class W3_Plugin_Minify extends W3_Plugin
69
  }
70
  }
71
 
72
- $file_htaccess = W3TC_CONTENT_DIR . '/.htaccess';
73
 
74
- if (@copy(W3TC_INSTALL_MINIFY_DIR . '/_htaccess', $file_htaccess)) {
75
- @chmod($file_htaccess, 0644);
76
- } else {
77
- w3_writable_error($file_htaccess);
78
- }
79
-
80
- $file_index = W3TC_CONTENT_DIR . '/index.html';
81
-
82
- if (@copy(W3TC_INSTALL_MINIFY_DIR . '/index.html', $file_index)) {
83
  @chmod($file_index, 0644);
84
  } else {
85
  w3_writable_error($file_index);
86
  }
87
 
88
- $file_minify = W3TC_CONTENT_DIR . '/minify.php';
89
-
90
- if (@copy(W3TC_INSTALL_MINIFY_DIR . '/minify.php', $file_minify)) {
91
- @chmod($file_minify, 0644);
92
- } else {
93
- w3_writable_error($file_minify);
94
  }
95
  }
 
 
96
  }
97
 
98
  /**
@@ -100,42 +109,102 @@ class W3_Plugin_Minify extends W3_Plugin
100
  */
101
  function deactivate()
102
  {
 
 
103
  if (! $this->locked()) {
104
- @unlink(W3TC_CONTENT_DIR . '/.htaccess');
105
- @unlink(W3TC_CONTENT_DIR . '/index.php');
 
106
  }
107
  }
108
 
109
  /**
110
- * OB callback
111
- *
112
- * @param string $buffer
113
- * @return string
114
  */
115
- function ob_callback($buffer)
116
  {
117
- if (! w3_is_xml($buffer)) {
118
- return $buffer;
119
- }
120
-
121
- $head_prepend = '';
122
-
123
- if ($this->_config->get_boolean('minify.css.enable', true)) {
124
- $head_prepend .= $this->get_styles('include');
125
  }
126
-
127
- if ($this->_config->get_boolean('minify.js.enable', true)) {
128
- $head_prepend .= $this->get_scripts('include') . $this->get_scripts('include-nb');
 
 
 
 
 
 
129
  }
 
 
 
 
 
 
 
 
 
 
130
 
131
- if (! empty($head_prepend)) {
132
- $buffer = preg_replace('~<head[^>]*>~Ui', '\\0' . $head_prepend, $buffer);
133
- }
 
134
 
135
- $buffer = $this->clean($buffer);
 
 
 
 
 
 
 
 
 
 
 
136
 
137
- if ($this->_config->get_boolean('minify.debug')) {
138
- $buffer .= "\r\n\r\n" . $this->get_debug_info();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
  return $buffer;
@@ -146,30 +215,30 @@ class W3_Plugin_Minify extends W3_Plugin
146
  */
147
  function footer()
148
  {
149
- if ($this->_config->get_boolean('minify.js.enable', true)) {
150
  echo $this->get_scripts('include-footer') . $this->get_scripts('include-footer-nb');
151
  }
152
  }
153
 
154
  /**
155
  * Cleans content
156
- *
157
  * @param string $content
158
  * @return string
159
  */
160
  function clean($content)
161
  {
162
  if (! is_feed()) {
163
- if ($this->_config->get_boolean('minify.css.enable', true)) {
164
  $content = $this->clean_styles($content);
165
  }
166
 
167
- if ($this->_config->get_boolean('minify.js.enable', true)) {
168
  $content = $this->clean_scripts($content);
169
  }
170
  }
171
 
172
- if ($this->_config->get_boolean('minify.html.enable', true) && ! ($this->_config->get_boolean('minify.html.reject.admin', true) && current_user_can('manage_options'))) {
173
  $content = $this->minify_html($content);
174
  }
175
 
@@ -180,7 +249,7 @@ class W3_Plugin_Minify extends W3_Plugin
180
 
181
  /**
182
  * Cleans styles
183
- *
184
  * @param string $content
185
  * @return string
186
  */
@@ -189,17 +258,19 @@ class W3_Plugin_Minify extends W3_Plugin
189
  $regexps = array();
190
 
191
  $groups = $this->_config->get_array('minify.css.groups');
192
- $siteurl = w3_get_domain_url();
193
 
194
  foreach ($groups as $group => $locations) {
195
  foreach ((array) $locations as $location => $config) {
196
  if (! empty($config['files'])) {
197
  foreach ((array) $config['files'] as $file) {
198
- if (w3_is_url($file) && strstr($file, $siteurl) === false) {
199
- $regexps[] = preg_quote($file);
 
200
  } else {
201
- $file = ltrim(str_replace($siteurl, '', $file), '/');
202
- $regexps[] = '(' . preg_quote($siteurl) . ')?/?' . preg_quote($file);
 
203
  }
204
  }
205
  }
@@ -225,17 +296,19 @@ class W3_Plugin_Minify extends W3_Plugin
225
  $regexps = array();
226
 
227
  $groups = $this->_config->get_array('minify.js.groups');
228
- $siteurl = w3_get_domain_url();
229
 
230
  foreach ($groups as $group => $locations) {
231
  foreach ((array) $locations as $location => $config) {
232
  if (! empty($config['files'])) {
233
  foreach ((array) $config['files'] as $file) {
234
- if (w3_is_url($file) && strstr($file, $siteurl) === false) {
235
- $regexps[] = preg_quote($file);
 
236
  } else {
237
- $file = ltrim(str_replace($siteurl, '', $file), '/');
238
- $regexps[] = '(' . preg_quote($siteurl) . ')?/?' . preg_quote($file);
 
239
  }
240
  }
241
  }
@@ -257,24 +330,27 @@ class W3_Plugin_Minify extends W3_Plugin
257
  */
258
  function minify_html($content)
259
  {
260
- set_include_path(get_include_path() . PATH_SEPARATOR . W3TC_LIB_MINIFY_DIR);
261
-
262
- require_once 'Minify/HTML.php';
263
- require_once 'Minify/CSS.php';
264
- require_once 'JSMin.php';
265
 
266
  $options = array(
267
- 'xhtml' => true
 
 
 
 
 
268
  );
269
 
270
- if ($this->_config->get_boolean('minify.html.inline.css', false)) {
271
  $options['cssMinifier'] = array(
272
  'Minify_CSS',
273
  'minify'
274
  );
275
  }
276
 
277
- if ($this->_config->get_boolean('minify.html.inline.js', false)) {
278
  $options['jsMinifier'] = array(
279
  'JSMin',
280
  'minify'
@@ -287,17 +363,12 @@ class W3_Plugin_Minify extends W3_Plugin
287
  return sprintf('<strong>W3 Total Cache Error:</strong> Minify error: %s', $exception->getMessage());
288
  }
289
 
290
- if ($this->_config->get_boolean('minify.html.strip.crlf')) {
291
- $content = preg_replace("~[\r\n]+~", ' ', $content);
292
- } else {
293
- $content = preg_replace("~[\r\n]+~", "\n", $content);
294
- }
295
-
296
  return $content;
297
  }
298
 
299
  /**
300
  * Returns current group
 
301
  * @return string
302
  */
303
  function get_group()
@@ -306,48 +377,21 @@ class W3_Plugin_Minify extends W3_Plugin
306
 
307
  if ($group === null) {
308
  switch (true) {
309
- case is_date():
310
- $group = 'date';
311
- break;
312
-
313
- case is_category():
314
- $group = 'category';
315
- break;
316
-
317
- case is_tag():
318
- $group = 'tag';
319
- break;
320
-
321
- case is_author():
322
- $group = 'author';
323
- break;
324
-
325
- case is_home():
326
- $group = 'home';
327
- break;
328
-
329
- case is_page():
330
- $group = 'page';
331
- break;
332
-
333
- case is_search():
334
- $group = 'search';
335
- break;
336
-
337
- case is_404():
338
- $group = '404';
339
- break;
340
-
341
- case is_attachment():
342
- $group = 'attachment';
343
- break;
344
-
345
- case is_archive():
346
- $group = 'archive';
347
- break;
348
-
349
- case is_single():
350
- $group = 'single';
351
  break;
352
 
353
  default:
@@ -361,7 +405,7 @@ class W3_Plugin_Minify extends W3_Plugin
361
 
362
  /**
363
  * Returns style link
364
- *
365
  * @param string $url
366
  * @param string $import
367
  */
@@ -401,7 +445,8 @@ class W3_Plugin_Minify extends W3_Plugin
401
  }
402
 
403
  /**
404
- * returns style link for styles group
 
405
  * @param string $location
406
  * @param string $group
407
  */
@@ -427,6 +472,7 @@ class W3_Plugin_Minify extends W3_Plugin
427
 
428
  /**
429
  * Returns script linkg for scripts group
 
430
  * @param string $location
431
  * @param string $group
432
  */
@@ -482,13 +528,13 @@ class W3_Plugin_Minify extends W3_Plugin
482
  */
483
  function format_url($group, $location, $type)
484
  {
485
- $siteurl = w3_get_site_url();
486
 
487
- if ($this->_config->get_boolean('minify.rewrite', true)) {
488
- return sprintf('%s/%s/%s.%s.%s', $siteurl, W3TC_CONTENT_DIR_NAME, $group, $location, $type);
489
  }
490
 
491
- return sprintf('%s/%s/minify.php?gg=%s&g=%s&t=%s', $siteurl, W3TC_CONTENT_DIR_NAME, $group, $location, $type);
492
  }
493
 
494
  /**
@@ -517,8 +563,8 @@ class W3_Plugin_Minify extends W3_Plugin
517
  }
518
  }
519
 
520
- $siteurl = w3_get_site_url();
521
- $url = sprintf('%s/%s/minify.php?f=%s', $siteurl, W3TC_CONTENT_DIR_NAME, implode(',', $files));
522
 
523
  if ($base) {
524
  $url .= sprintf('&b=%s', $base);
@@ -529,6 +575,7 @@ class W3_Plugin_Minify extends W3_Plugin
529
 
530
  /**
531
  * Returns array of minify URLs
 
532
  * @return array
533
  */
534
  function get_urls()
@@ -569,7 +616,7 @@ class W3_Plugin_Minify extends W3_Plugin
569
  $debug_info .= sprintf("%s%s\r\n", str_pad('Group: ', 20), $group);
570
 
571
  require_once W3TC_LIB_W3_DIR . '/Minify.php';
572
- $w3_minify = W3_Minify::instance();
573
 
574
  $css_groups = $w3_minify->get_groups($group, 'css');
575
 
@@ -579,10 +626,12 @@ class W3_Plugin_Minify extends W3_Plugin
579
 
580
  foreach ($css_groups as $css_group => $css_files) {
581
  foreach ($css_files as $css_file => $css_file_path) {
582
- if (w3_is_url($css_file)) {
 
583
  $css_file_info = sprintf('%s (%s)', $css_file, $css_file_path);
584
  } else {
585
- $css_file_path = $css_file_info = ABSPATH . ltrim($css_file, '\\/');
 
586
  }
587
 
588
  $debug_info .= sprintf("%s | %s | % s | %s\r\n", str_pad($css_group, 15, ' ', STR_PAD_BOTH), str_pad(date('Y-m-d H:i:s', filemtime($css_file_path)), 19, ' ', STR_PAD_BOTH), str_pad(filesize($css_file_path), 12, ' ', STR_PAD_LEFT), $css_file_info);
@@ -598,10 +647,11 @@ class W3_Plugin_Minify extends W3_Plugin
598
 
599
  foreach ($js_groups as $js_group => $js_files) {
600
  foreach ($js_files as $js_file => $js_file_path) {
601
- if (w3_is_url($js_file)) {
 
602
  $js_file_info = sprintf('%s (%s)', $js_file, $js_file_path);
603
  } else {
604
- $js_file_path = $js_file_info = ABSPATH . ltrim($js_file, '\\/');
605
  }
606
 
607
  $debug_info .= sprintf("%s | %s | % s | %s\r\n", str_pad($js_group, 15, ' ', STR_PAD_BOTH), str_pad(date('Y-m-d H:i:s', filemtime($js_file_path)), 19, ' ', STR_PAD_BOTH), str_pad(filesize($js_file_path), 12, ' ', STR_PAD_LEFT), $js_file_info);
@@ -616,6 +666,7 @@ class W3_Plugin_Minify extends W3_Plugin
616
 
617
  /**
618
  * Check if we can do minify logic
 
619
  * @return boolean
620
  */
621
  function can_minify()
@@ -623,7 +674,9 @@ class W3_Plugin_Minify extends W3_Plugin
623
  /**
624
  * Skip if Minify is disabled
625
  */
626
- if (! $this->_config->get_boolean('minify.enabled', true)) {
 
 
627
  return false;
628
  }
629
 
@@ -631,6 +684,8 @@ class W3_Plugin_Minify extends W3_Plugin
631
  * Skip if Admin
632
  */
633
  if (defined('WP_ADMIN')) {
 
 
634
  return false;
635
  }
636
 
@@ -638,6 +693,8 @@ class W3_Plugin_Minify extends W3_Plugin
638
  * Skip if doint AJAX
639
  */
640
  if (defined('DOING_AJAX')) {
 
 
641
  return false;
642
  }
643
 
@@ -645,6 +702,8 @@ class W3_Plugin_Minify extends W3_Plugin
645
  * Skip if doing cron
646
  */
647
  if (defined('DOING_CRON')) {
 
 
648
  return false;
649
  }
650
 
@@ -652,6 +711,8 @@ class W3_Plugin_Minify extends W3_Plugin
652
  * Skip if APP request
653
  */
654
  if (defined('APP_REQUEST')) {
 
 
655
  return false;
656
  }
657
 
@@ -659,6 +720,8 @@ class W3_Plugin_Minify extends W3_Plugin
659
  * Skip if XMLRPC request
660
  */
661
  if (defined('XMLRPC_REQUEST')) {
 
 
662
  return false;
663
  }
664
 
@@ -666,6 +729,8 @@ class W3_Plugin_Minify extends W3_Plugin
666
  * Check User agent
667
  */
668
  if (! $this->check_ua()) {
 
 
669
  return false;
670
  }
671
 
@@ -673,6 +738,8 @@ class W3_Plugin_Minify extends W3_Plugin
673
  * Check request URI
674
  */
675
  if (! $this->check_request_uri()) {
 
 
676
  return false;
677
  }
678
 
@@ -722,27 +789,162 @@ class W3_Plugin_Minify extends W3_Plugin
722
 
723
  return true;
724
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
725
  }
726
 
727
  /**
728
  * Prints script link for scripts group
 
729
  * @param string $location
730
  * @param string $group
731
  */
732
  function w3tc_scripts($location, $group = null)
733
  {
734
- $w3_plugin_minify = W3_Plugin_Minify::instance();
735
  echo $w3_plugin_minify->get_scripts($location, $group);
736
  }
737
 
738
  /**
739
  * Prints style link for styles group
 
740
  * @param string $location
741
  * @param string $group
742
  */
743
  function w3tc_styles($location, $group = null)
744
  {
745
- $w3_plugin_minify = W3_Plugin_Minify::instance();
746
  echo $w3_plugin_minify->get_styles($location, $group);
747
  }
748
 
@@ -754,7 +956,7 @@ function w3tc_styles($location, $group = null)
754
  */
755
  function w3tc_custom_script($files, $blocking = true)
756
  {
757
- $w3_plugin_minify = W3_Plugin_Minify::instance();
758
  echo $w3_plugin_minify->get_custom_script($files, $blocking);
759
  }
760
 
@@ -766,6 +968,6 @@ function w3tc_custom_script($files, $blocking = true)
766
  */
767
  function w3tc_custom_style($files, $import = false)
768
  {
769
- $w3_plugin_minify = W3_Plugin_Minify::instance();
770
  echo $w3_plugin_minify->get_custom_style($files, $import);
771
  }
10
  */
11
  class W3_Plugin_Minify extends W3_Plugin
12
  {
13
+ /**
14
+ * Minify reject reason
15
+ *
16
+ * @var string
17
+ */
18
+ var $minify_reject_reason = '';
19
+
20
  /**
21
  * Runs plugin
22
  */
32
  'deactivate'
33
  ));
34
 
35
+ add_filter('cron_schedules', array(
36
+ &$this,
37
+ 'cron_schedules'
38
+ ));
39
+
40
+ if ($this->_config->get_boolean('minify.enabled') && $this->_config->get_string('minify.engine') == 'file') {
41
+ add_action('w3_minify_cleanup', array(
42
+ &$this,
43
+ 'cleanup'
44
+ ));
45
+ }
46
+
47
  if ($this->can_minify()) {
48
  ob_start(array(
49
  &$this,
64
  */
65
  function &instance()
66
  {
67
+ static $instances = array();
68
 
69
+ if (! isset($instances[0])) {
70
  $class = __CLASS__;
71
+ $instances[0] = & new $class();
72
  }
73
 
74
+ return $instances[0];
75
  }
76
 
77
  /**
88
  }
89
  }
90
 
91
+ $file_index = W3TC_CONTENT_MINIFY_DIR . '/index.php';
92
 
93
+ if (@copy(W3TC_INSTALL_MINIFY_DIR . '/index.php', $file_index)) {
 
 
 
 
 
 
 
 
94
  @chmod($file_index, 0644);
95
  } else {
96
  w3_writable_error($file_index);
97
  }
98
 
99
+ if ($this->_config->get_boolean('minify.rewrite') && ! $this->write_rules()) {
100
+ w3_writable_error(W3TC_CONTENT_MINIFY_DIR . '/.htaccess');
 
 
 
 
101
  }
102
  }
103
+
104
+ $this->schedule();
105
  }
106
 
107
  /**
109
  */
110
  function deactivate()
111
  {
112
+ $this->unschedule();
113
+
114
  if (! $this->locked()) {
115
+ @unlink(W3TC_CONTENT_MINIFY_DIR . '/index.php');
116
+
117
+ $this->remove_rules();
118
  }
119
  }
120
 
121
  /**
122
+ * Schedules events
 
 
 
123
  */
124
+ function schedule()
125
  {
126
+ if ($this->_config->get_boolean('minify.enabled') && $this->_config->get_string('minify.engine') == 'file') {
127
+ if (! wp_next_scheduled('w3_minify_cleanup')) {
128
+ wp_schedule_event(time(), 'w3_minify_cleanup', 'w3_minify_cleanup');
129
+ }
130
+ } else {
131
+ $this->unschedule();
 
 
132
  }
133
+ }
134
+
135
+ /**
136
+ * Unschedules events
137
+ */
138
+ function unschedule()
139
+ {
140
+ if (wp_next_scheduled('w3_minify_cleanup')) {
141
+ wp_clear_scheduled_hook('w3_minify_cleanup');
142
  }
143
+ }
144
+
145
+ /**
146
+ * Does disk cache cleanup
147
+ *
148
+ * @return void
149
+ */
150
+ function cleanup()
151
+ {
152
+ require_once W3TC_LIB_W3_DIR . '/Cache/File/Minify/Manager.php';
153
 
154
+ $w3_cache_file_minify_manager = & new W3_Cache_File_Minify_Manager(array(
155
+ 'cache_dir' => W3TC_CACHE_FILE_MINIFY_DIR,
156
+ 'expire' => $this->_config->get_integer('minify.lifetime')
157
+ ));
158
 
159
+ $w3_cache_file_minify_manager->clean();
160
+ }
161
+
162
+ /**
163
+ * Cron schedules filter
164
+ *
165
+ * @paran array $schedules
166
+ * @return array
167
+ */
168
+ function cron_schedules($schedules)
169
+ {
170
+ $gc = $this->_config->get_integer('minify.file.gc');
171
 
172
+ return array_merge($schedules, array(
173
+ 'w3_minify_cleanup' => array(
174
+ 'interval' => $gc,
175
+ 'display' => sprintf('Every %d seconds', $gc)
176
+ )
177
+ ));
178
+ }
179
+
180
+ /**
181
+ * OB callback
182
+ *
183
+ * @param string $buffer
184
+ * @return string
185
+ */
186
+ function ob_callback($buffer)
187
+ {
188
+ if ($buffer != '' && w3_is_xml($buffer)) {
189
+ $head_prepend = '';
190
+
191
+ if ($this->_config->get_boolean('minify.css.enable')) {
192
+ $head_prepend .= $this->get_styles('include');
193
+ }
194
+
195
+ if ($this->_config->get_boolean('minify.js.enable')) {
196
+ $head_prepend .= $this->get_scripts('include') . $this->get_scripts('include-nb');
197
+ }
198
+
199
+ if (! empty($head_prepend)) {
200
+ $buffer = preg_replace('~<head(\s+[^<>]+)*>~Ui', '\\0' . $head_prepend, $buffer, 1);
201
+ }
202
+
203
+ $buffer = $this->clean($buffer);
204
+
205
+ if ($this->_config->get_boolean('minify.debug')) {
206
+ $buffer .= "\r\n\r\n" . $this->get_debug_info();
207
+ }
208
  }
209
 
210
  return $buffer;
215
  */
216
  function footer()
217
  {
218
+ if ($this->_config->get_boolean('minify.js.enable')) {
219
  echo $this->get_scripts('include-footer') . $this->get_scripts('include-footer-nb');
220
  }
221
  }
222
 
223
  /**
224
  * Cleans content
225
+ *
226
  * @param string $content
227
  * @return string
228
  */
229
  function clean($content)
230
  {
231
  if (! is_feed()) {
232
+ if ($this->_config->get_boolean('minify.css.enable')) {
233
  $content = $this->clean_styles($content);
234
  }
235
 
236
+ if ($this->_config->get_boolean('minify.js.enable')) {
237
  $content = $this->clean_scripts($content);
238
  }
239
  }
240
 
241
+ if ($this->_config->get_boolean('minify.html.enable') && ! ($this->_config->get_boolean('minify.html.reject.admin') && current_user_can('manage_options'))) {
242
  $content = $this->minify_html($content);
243
  }
244
 
249
 
250
  /**
251
  * Cleans styles
252
+ *
253
  * @param string $content
254
  * @return string
255
  */
258
  $regexps = array();
259
 
260
  $groups = $this->_config->get_array('minify.css.groups');
261
+ $domain_url_regexp = w3_get_domain_url_regexp();
262
 
263
  foreach ($groups as $group => $locations) {
264
  foreach ((array) $locations as $location => $config) {
265
  if (! empty($config['files'])) {
266
  foreach ((array) $config['files'] as $file) {
267
+ if (w3_is_url($file) && ! preg_match('~' . $domain_url_regexp . '~i', $file)) {
268
+ // external CSS files
269
+ $regexps[] = w3_preg_quote($file);
270
  } else {
271
+ // local CSS files
272
+ $file = ltrim(preg_replace('~' . $domain_url_regexp . '~i', '', $file), '/\\');
273
+ $regexps[] = '(' . $domain_url_regexp . ')?/?' . w3_preg_quote($file);
274
  }
275
  }
276
  }
296
  $regexps = array();
297
 
298
  $groups = $this->_config->get_array('minify.js.groups');
299
+ $domain_url_regexp = w3_get_domain_url_regexp();
300
 
301
  foreach ($groups as $group => $locations) {
302
  foreach ((array) $locations as $location => $config) {
303
  if (! empty($config['files'])) {
304
  foreach ((array) $config['files'] as $file) {
305
+ if (w3_is_url($file) && ! preg_match('~' . $domain_url_regexp . '~i', $file)) {
306
+ // external JS files
307
+ $regexps[] = w3_preg_quote($file);
308
  } else {
309
+ // local JS files
310
+ $file = ltrim(preg_replace('~' . $domain_url_regexp . '~i', '', $file), '/\\');
311
+ $regexps[] = '(' . $domain_url_regexp . ')?/?' . w3_preg_quote($file);
312
  }
313
  }
314
  }
330
  */
331
  function minify_html($content)
332
  {
333
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/HTML.php';
334
+ require_once W3TC_LIB_MINIFY_DIR . '/Minify/CSS.php';
335
+ require_once W3TC_LIB_MINIFY_DIR . '/JSMin.php';
 
 
336
 
337
  $options = array(
338
+ 'xhtml' => true,
339
+ 'stripCrlf' => $this->_config->get_boolean('minify.html.strip.crlf'),
340
+ 'cssStripCrlf' => $this->_config->get_boolean('minify.css.strip.crlf'),
341
+ 'cssStripComments' => $this->_config->get_boolean('minify.css.strip.comments'),
342
+ 'jsStripCrlf' => $this->_config->get_boolean('minify.js.strip.crlf'),
343
+ 'jsStripComments' => $this->_config->get_boolean('minify.js.strip.comments')
344
  );
345
 
346
+ if ($this->_config->get_boolean('minify.html.inline.css')) {
347
  $options['cssMinifier'] = array(
348
  'Minify_CSS',
349
  'minify'
350
  );
351
  }
352
 
353
+ if ($this->_config->get_boolean('minify.html.inline.js')) {
354
  $options['jsMinifier'] = array(
355
  'JSMin',
356
  'minify'
363
  return sprintf('<strong>W3 Total Cache Error:</strong> Minify error: %s', $exception->getMessage());
364
  }
365
 
 
 
 
 
 
 
366
  return $content;
367
  }
368
 
369
  /**
370
  * Returns current group
371
+ *
372
  * @return string
373
  */
374
  function get_group()
377
 
378
  if ($group === null) {
379
  switch (true) {
380
+ case (is_404() && ($template = get_404_template())):
381
+ case (is_search() && ($template = get_search_template())):
382
+ case (is_tax() && ($template = get_taxonomy_template())):
383
+ case (is_home() && ($template = get_home_template())):
384
+ case (is_attachment() && ($template = get_attachment_template())):
385
+ case (is_single() && ($template = get_single_template())):
386
+ case (is_page() && ($template = get_page_template())):
387
+ case (is_category() && ($template = get_category_template())):
388
+ case (is_tag() && ($template = get_tag_template())):
389
+ case (is_author() && ($template = get_author_template())):
390
+ case (is_date() && ($template = get_date_template())):
391
+ case (is_archive() && ($template = get_archive_template())):
392
+ case (is_comments_popup() && ($template = get_comments_popup_template())):
393
+ case (is_paged() && ($template = get_paged_template())):
394
+ $group = basename($template, '.php');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
  break;
396
 
397
  default:
405
 
406
  /**
407
  * Returns style link
408
+ *
409
  * @param string $url
410
  * @param string $import
411
  */
445
  }
446
 
447
  /**
448
+ * Returns style link for styles group
449
+ *
450
  * @param string $location
451
  * @param string $group
452
  */
472
 
473
  /**
474
  * Returns script linkg for scripts group
475
+ *
476
  * @param string $location
477
  * @param string $group
478
  */
528
  */
529
  function format_url($group, $location, $type)
530
  {
531
+ $site_url_ssl = w3_get_site_url_ssl();
532
 
533
+ if ($this->_config->get_boolean('minify.rewrite')) {
534
+ return sprintf('%s%s/%s.%s.%s', $site_url_ssl, W3TC_CONTENT_MINIFY_DIR_NAME, $group, $location, $type);
535
  }
536
 
537
+ return sprintf('%s%s/index.php?gg=%s&g=%s&t=%s', $site_url_ssl, W3TC_CONTENT_MINIFY_DIR_NAME, $group, $location, $type);
538
  }
539
 
540
  /**
563
  }
564
  }
565
 
566
+ $site_url_ssl = w3_get_site_url_ssl();
567
+ $url = sprintf('%s%s/minify.php?f=%s', $site_url_ssl, W3TC_CONTENT_DIR_NAME, implode(',', $files));
568
 
569
  if ($base) {
570
  $url .= sprintf('&b=%s', $base);
575
 
576
  /**
577
  * Returns array of minify URLs
578
+ *
579
  * @return array
580
  */
581
  function get_urls()
616
  $debug_info .= sprintf("%s%s\r\n", str_pad('Group: ', 20), $group);
617
 
618
  require_once W3TC_LIB_W3_DIR . '/Minify.php';
619
+ $w3_minify = & W3_Minify::instance();
620
 
621
  $css_groups = $w3_minify->get_groups($group, 'css');
622
 
626
 
627
  foreach ($css_groups as $css_group => $css_files) {
628
  foreach ($css_files as $css_file => $css_file_path) {
629
+ if (is_a($css_file_path, 'Minify_Source')) {
630
+ $css_file_path = $css_file_path->filepath;
631
  $css_file_info = sprintf('%s (%s)', $css_file, $css_file_path);
632
  } else {
633
+ $css_file_info = $css_file;
634
+ $css_file_path = ABSPATH . ltrim($css_file_path, '/\\');
635
  }
636
 
637
  $debug_info .= sprintf("%s | %s | % s | %s\r\n", str_pad($css_group, 15, ' ', STR_PAD_BOTH), str_pad(date('Y-m-d H:i:s', filemtime($css_file_path)), 19, ' ', STR_PAD_BOTH), str_pad(filesize($css_file_path), 12, ' ', STR_PAD_LEFT), $css_file_info);
647
 
648
  foreach ($js_groups as $js_group => $js_files) {
649
  foreach ($js_files as $js_file => $js_file_path) {
650
+ if (is_a($js_file_path, 'Minify_Source')) {
651
+ $js_file_path = $js_file_path->filepath;
652
  $js_file_info = sprintf('%s (%s)', $js_file, $js_file_path);
653
  } else {
654
+ $js_file_path = $js_file_info = ABSPATH . ltrim($js_file, '/\\');
655
  }
656
 
657
  $debug_info .= sprintf("%s | %s | % s | %s\r\n", str_pad($js_group, 15, ' ', STR_PAD_BOTH), str_pad(date('Y-m-d H:i:s', filemtime($js_file_path)), 19, ' ', STR_PAD_BOTH), str_pad(filesize($js_file_path), 12, ' ', STR_PAD_LEFT), $js_file_info);
666
 
667
  /**
668
  * Check if we can do minify logic
669
+ *
670
  * @return boolean
671
  */
672
  function can_minify()
674
  /**
675
  * Skip if Minify is disabled
676
  */
677
+ if (! $this->_config->get_boolean('minify.enabled')) {
678
+ $this->minify_reject_reason = 'minify is disabled';
679
+
680
  return false;
681
  }
682
 
684
  * Skip if Admin
685
  */
686
  if (defined('WP_ADMIN')) {
687
+ $this->minify_reject_reason = 'wp-admin';
688
+
689
  return false;
690
  }
691
 
693
  * Skip if doint AJAX
694
  */
695
  if (defined('DOING_AJAX')) {
696
+ $this->minify_reject_reason = 'doing AJAX';
697
+
698
  return false;
699
  }
700
 
702
  * Skip if doing cron
703
  */
704
  if (defined('DOING_CRON')) {
705
+ $this->minify_reject_reason = 'doing cron';
706
+
707
  return false;
708
  }
709
 
711
  * Skip if APP request
712
  */
713
  if (defined('APP_REQUEST')) {
714
+ $this->minify_reject_reason = 'application request';
715
+
716
  return false;
717
  }
718
 
720
  * Skip if XMLRPC request
721
  */
722
  if (defined('XMLRPC_REQUEST')) {
723
+ $this->minify_reject_reason = 'XMLRPC request';
724
+
725
  return false;
726
  }
727
 
729
  * Check User agent
730
  */
731
  if (! $this->check_ua()) {
732
+ $this->minify_reject_reason = 'user agent is rejected';
733
+
734
  return false;
735
  }
736
 
738
  * Check request URI
739
  */
740
  if (! $this->check_request_uri()) {
741
+ $this->minify_reject_reason = 'request URI is rejected';
742
+
743
  return false;
744
  }
745
 
789
 
790
  return true;
791
  }
792
+
793
+ /**
794
+ * Generates rules
795
+ *
796
+ * @return string
797
+ */
798
+ function generate_rules()
799
+ {
800
+ $rules = '';
801
+ $rules .= "# BEGIN W3TC Minify\n";
802
+
803
+ if ($this->_config->get_string('minify.engine') == 'file') {
804
+ if ($this->_config->get_boolean('minify.compress')) {
805
+ $rules .= "<IfModule mod_mime.c>\n";
806
+ $rules .= " AddEncoding gzip .gz\n";
807
+ $rules .= " <Files *.css.gz>\n";
808
+ $rules .= " ForceType text/css\n";
809
+ $rules .= " </Files>\n";
810
+ $rules .= " <Files *.js.gz>\n";
811
+ $rules .= " ForceType application/x-javascript\n";
812
+ $rules .= " </Files>\n";
813
+ $rules .= "</IfModule>\n";
814
+
815
+ $rules .= "<IfModule mod_deflate.c>\n";
816
+ $rules .= " SetEnvIfNoCase Request_URI \\.gz$ no-gzip\n";
817
+ $rules .= "</IfModule>\n";
818
+ }
819
+
820
+ $rules .= "<IfModule mod_expires.c>\n";
821
+ $rules .= " ExpiresActive On\n";
822
+ $rules .= " ExpiresByType text/css M" . $this->_config->get_integer('minify.lifetime') . "\n";
823
+ $rules .= " ExpiresByType application/x-javascript M" . $this->_config->get_integer('minify.lifetime') . "\n";
824
+ $rules .= "</IfModule>\n";
825
+
826
+ $rules .= "<IfModule mod_headers.c>\n";
827
+ $rules .= " Header set Pragma public\n";
828
+ $rules .= " Header set X-Powered-By \"" . W3TC_POWERED_BY . "\"\n";
829
+ $rules .= " Header set Vary \"Accept-Encoding\"\n";
830
+ $rules .= " Header append Cache-Control \"public, must-revalidate\"\n";
831
+ $rules .= "</IfModule>\n";
832
+ }
833
+
834
+ $rules .= "<IfModule mod_rewrite.c>\n";
835
+
836
+ $rules .= " RewriteEngine On\n";
837
+
838
+ if ($this->_config->get_string('minify.engine') == 'file') {
839
+ if ($this->_config->get_boolean('minify.compress')) {
840
+ $rules .= " SetEnvIfNoCase Accept-Encoding gzip APPEND_EXT=.gz\n";
841
+ }
842
+
843
+ $rules .= " RewriteCond %{REQUEST_FILENAME}%{ENV:APPEND_EXT} -f\n";
844
+ $rules .= " RewriteRule (.*) $1%{ENV:APPEND_EXT} [L]\n";
845
+ }
846
+
847
+ $rules .= " RewriteRule ^([a-z0-9-_]+)\\.(include(-footer)?(-nb)?)\\.(css|js)$ index.php?gg=$1&g=$2&t=$5 [L]\n";
848
+
849
+ $rules .= "</IfModule>\n";
850
+
851
+ $rules .= "# END W3TC Minify\n\n";
852
+
853
+ return $rules;
854
+ }
855
+
856
+ /**
857
+ * Writes rules to file cache .htaccess
858
+ *
859
+ * @return boolean
860
+ */
861
+ function write_rules()
862
+ {
863
+ $path = W3TC_CONTENT_MINIFY_DIR . '/.htaccess';
864
+
865
+ if (file_exists($path)) {
866
+ if (($data = @file_get_contents($path)) !== false) {
867
+ $data = $this->erase_rules($data);
868
+ } else {
869
+ return false;
870
+ }
871
+ } else {
872
+ $data = '';
873
+ }
874
+
875
+ $data = trim($this->generate_rules() . $data);
876
+
877
+ if (($fp = @fopen($path, 'w'))) {
878
+ @fputs($fp, $data);
879
+ @fclose($fp);
880
+
881
+ return true;
882
+ }
883
+
884
+ return false;
885
+ }
886
+
887
+ /**
888
+ * Erases W3TC rules from config
889
+ *
890
+ * @param string $data
891
+ * @return string
892
+ */
893
+ function erase_rules($data)
894
+ {
895
+ $data = preg_replace('~# BEGIN W3TC Minify.*# END W3TC Minify~s', '', $data);
896
+ $data = trim($data);
897
+
898
+ return $data;
899
+ }
900
+
901
+ /**
902
+ * Removes W3TC rules from file cache dir
903
+ *
904
+ * @return boolean
905
+ */
906
+ function remove_rules()
907
+ {
908
+ $path = W3TC_CONTENT_MINIFY_DIR . '/.htaccess';
909
+
910
+ return @unlink($path);
911
+ }
912
+
913
+ /**
914
+ * Checks rules
915
+ *
916
+ * @return boolean
917
+ */
918
+ function check_rules()
919
+ {
920
+ $path = W3TC_CACHE_FILE_MINIFY_DIR . '/.htaccess';
921
+ $search = trim($this->generate_rules());
922
+
923
+ return (($data = @file_get_contents($path)) && strstr($data, $search) !== false);
924
+ }
925
  }
926
 
927
  /**
928
  * Prints script link for scripts group
929
+ *
930
  * @param string $location
931
  * @param string $group
932
  */
933
  function w3tc_scripts($location, $group = null)
934
  {
935
+ $w3_plugin_minify = & W3_Plugin_Minify::instance();
936
  echo $w3_plugin_minify->get_scripts($location, $group);
937
  }
938
 
939
  /**
940
  * Prints style link for styles group
941
+ *
942
  * @param string $location
943
  * @param string $group
944
  */
945
  function w3tc_styles($location, $group = null)
946
  {
947
+ $w3_plugin_minify = & W3_Plugin_Minify::instance();
948
  echo $w3_plugin_minify->get_styles($location, $group);
949
  }
950
 
956
  */
957
  function w3tc_custom_script($files, $blocking = true)
958
  {
959
+ $w3_plugin_minify = & W3_Plugin_Minify::instance();
960
  echo $w3_plugin_minify->get_custom_script($files, $blocking);
961
  }
962
 
968
  */
969
  function w3tc_custom_style($files, $import = false)
970
  {
971
+ $w3_plugin_minify = & W3_Plugin_Minify::instance();
972
  echo $w3_plugin_minify->get_custom_style($files, $import);
973
  }
lib/W3/Plugin/PgCache.php CHANGED
@@ -25,66 +25,78 @@ class W3_Plugin_PgCache extends W3_Plugin
25
  'deactivate'
26
  ));
27
 
28
- if ($this->_config->get_boolean('pgcache.enabled', true)) {
 
 
 
 
 
 
 
 
 
 
 
 
29
  add_action('publish_phone', array(
30
  &$this,
31
  'on_post_edit'
32
- ));
33
 
34
  add_action('publish_post', array(
35
  &$this,
36
  'on_post_edit'
37
- ));
38
 
39
  add_action('edit_post', array(
40
  &$this,
41
  'on_post_change'
42
- ));
43
 
44
  add_action('delete_post', array(
45
  &$this,
46
  'on_post_edit'
47
- ));
48
 
49
  add_action('comment_post', array(
50
  &$this,
51
  'on_comment_change'
52
- ));
53
 
54
  add_action('edit_comment', array(
55
  &$this,
56
  'on_comment_change'
57
- ));
58
 
59
  add_action('delete_comment', array(
60
  &$this,
61
  'on_comment_change'
62
- ));
63
 
64
  add_action('wp_set_comment_status', array(
65
  &$this,
66
  'on_comment_status'
67
- ), 1, 2);
68
 
69
  add_action('trackback_post', array(
70
  &$this,
71
  'on_comment_change'
72
- ));
73
 
74
  add_action('pingback_post', array(
75
  &$this,
76
  'on_comment_change'
77
- ));
78
 
79
  add_action('switch_theme', array(
80
  &$this,
81
  'on_change'
82
- ));
83
 
84
  add_action('edit_user_profile_update', array(
85
  &$this,
86
  'on_change'
87
- ));
88
  }
89
  }
90
 
@@ -95,14 +107,14 @@ class W3_Plugin_PgCache extends W3_Plugin
95
  */
96
  function &instance()
97
  {
98
- static $instance = null;
99
 
100
- if ($instance === null) {
101
  $class = __CLASS__;
102
- $instance = & new $class();
103
  }
104
 
105
- return $instance;
106
  }
107
 
108
  /**
@@ -110,17 +122,39 @@ class W3_Plugin_PgCache extends W3_Plugin
110
  */
111
  function activate()
112
  {
113
- if (! $this->update_wp_config()) {
114
- die('<strong>' . ABSPATH . 'wp-config.php</strong> could not be written, please edit config and add:<br /><strong style="color:#f00;">define(\'WP_CACHE\', true);</strong> before <strong style="color:#f00;">require_once(ABSPATH . \'wp-settings.php\');</strong><br />then re-activate plugin.');
115
- }
116
-
117
  if (! $this->locked()) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  if (@copy(W3TC_INSTALL_DIR . '/advanced-cache.php', WP_CONTENT_DIR . '/advanced-cache.php')) {
119
  @chmod(WP_CONTENT_DIR . '/advanced-cache.php', 0644);
120
  } else {
121
  w3_writable_error(WP_CONTENT_DIR . '/advanced-cache.php');
122
  }
123
  }
 
 
124
  }
125
 
126
  /**
@@ -128,11 +162,40 @@ class W3_Plugin_PgCache extends W3_Plugin
128
  */
129
  function deactivate()
130
  {
 
 
131
  if (! $this->locked()) {
 
 
 
132
  @unlink(WP_CONTENT_DIR . '/advanced-cache.php');
133
  }
134
  }
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  /**
137
  * Updates WP config
138
  *
@@ -164,6 +227,57 @@ class W3_Plugin_PgCache extends W3_Plugin
164
  return true;
165
  }
166
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  /**
168
  * Post edit action
169
  *
@@ -190,7 +304,7 @@ class W3_Plugin_PgCache extends W3_Plugin
190
  if (! in_array($post_id, $flushed_posts)) {
191
  require_once W3TC_LIB_W3_DIR . '/PgCache.php';
192
 
193
- $w3_pgcache = W3_PgCache::instance();
194
  $w3_pgcache->flush_post($post_id);
195
 
196
  $flushed_posts[] = $post_id;
@@ -228,7 +342,7 @@ class W3_Plugin_PgCache extends W3_Plugin
228
  }
229
 
230
  /**
231
- * Cange action
232
  */
233
  function on_change()
234
  {
@@ -237,8 +351,371 @@ class W3_Plugin_PgCache extends W3_Plugin
237
  if (! $flushed) {
238
  require_once W3TC_LIB_W3_DIR . '/PgCache.php';
239
 
240
- $w3_pgcache = W3_PgCache::instance();
241
  $w3_pgcache->flush();
242
  }
243
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  }
25
  'deactivate'
26
  ));
27
 
28
+ add_filter('cron_schedules', array(
29
+ &$this,
30
+ 'cron_schedules'
31
+ ));
32
+
33
+ if ($this->_config->get_boolean('pgcache.enabled')) {
34
+ if ($this->_config->get_string('pgcache.engine') == 'file' || $this->_config->get_string('pgcache.engine') == 'file_pgcache') {
35
+ add_action('w3_pgcache_cleanup', array(
36
+ &$this,
37
+ 'cleanup'
38
+ ));
39
+ }
40
+
41
  add_action('publish_phone', array(
42
  &$this,
43
  'on_post_edit'
44
+ ), 0);
45
 
46
  add_action('publish_post', array(
47
  &$this,
48
  'on_post_edit'
49
+ ), 0);
50
 
51
  add_action('edit_post', array(
52
  &$this,
53
  'on_post_change'
54
+ ), 0);
55
 
56
  add_action('delete_post', array(
57
  &$this,
58
  'on_post_edit'
59
+ ), 0);
60
 
61
  add_action('comment_post', array(
62
  &$this,
63
  'on_comment_change'
64
+ ), 0);
65
 
66
  add_action('edit_comment', array(
67
  &$this,
68
  'on_comment_change'
69
+ ), 0);
70
 
71
  add_action('delete_comment', array(
72
  &$this,
73
  'on_comment_change'
74
+ ), 0);
75
 
76
  add_action('wp_set_comment_status', array(
77
  &$this,
78
  'on_comment_status'
79
+ ), 0, 2);
80
 
81
  add_action('trackback_post', array(
82
  &$this,
83
  'on_comment_change'
84
+ ), 0);
85
 
86
  add_action('pingback_post', array(
87
  &$this,
88
  'on_comment_change'
89
+ ), 0);
90
 
91
  add_action('switch_theme', array(
92
  &$this,
93
  'on_change'
94
+ ), 0);
95
 
96
  add_action('edit_user_profile_update', array(
97
  &$this,
98
  'on_change'
99
+ ), 0);
100
  }
101
  }
102
 
107
  */
108
  function &instance()
109
  {
110
+ static $instances = array();
111
 
112
+ if (! isset($instances[0])) {
113
  $class = __CLASS__;
114
+ $instances[0] = & new $class();
115
  }
116
 
117
+ return $instances[0];
118
  }
119
 
120
  /**
122
  */
123
  function activate()
124
  {
 
 
 
 
125
  if (! $this->locked()) {
126
+ if (! $this->update_wp_config()) {
127
+ die('<strong>' . ABSPATH . 'wp-config.php</strong> could not be written, please edit config and add:<br /><strong style="color:#f00;">define(\'WP_CACHE\', true);</strong> before <strong style="color:#f00;">require_once(ABSPATH . \'wp-settings.php\');</strong><br />then re-activate plugin.');
128
+ }
129
+
130
+ if ($this->_config->get_boolean('pgcache.enabled') && $this->_config->get_string('pgcache.engine') == 'file_pgcache') {
131
+ /**
132
+ * Disable enchanged mode if permalink structure is disabled
133
+ */
134
+ $permalink_structure = get_option('permalink_structure');
135
+
136
+ if ($permalink_structure == '') {
137
+ $this->_config->set('pgcache.engine', 'file');
138
+ $this->_config->save();
139
+ } else {
140
+ if (! $this->write_rules_core()) {
141
+ w3_writable_error(ABSPATH . '.htaccess');
142
+ }
143
+
144
+ if (! $this->write_rules_cache()) {
145
+ w3_writable_error(W3TC_CACHE_FILE_PGCACHE_DIR . '/.htaccess');
146
+ }
147
+ }
148
+ }
149
+
150
  if (@copy(W3TC_INSTALL_DIR . '/advanced-cache.php', WP_CONTENT_DIR . '/advanced-cache.php')) {
151
  @chmod(WP_CONTENT_DIR . '/advanced-cache.php', 0644);
152
  } else {
153
  w3_writable_error(WP_CONTENT_DIR . '/advanced-cache.php');
154
  }
155
  }
156
+
157
+ $this->schedule();
158
  }
159
 
160
  /**
162
  */
163
  function deactivate()
164
  {
165
+ $this->unschedule();
166
+
167
  if (! $this->locked()) {
168
+ $this->remove_rules_cache();
169
+ $this->remove_rules_core();
170
+
171
  @unlink(WP_CONTENT_DIR . '/advanced-cache.php');
172
  }
173
  }
174
 
175
+ /**
176
+ * Schedules events
177
+ */
178
+ function schedule()
179
+ {
180
+ if ($this->_config->get_boolean('pgcache.enabled') && ($this->_config->get_string('pgcache.engine') == 'file' || $this->_config->get_string('pgcache.engine') == 'file_pgcache')) {
181
+ if (! wp_next_scheduled('w3_pgcache_cleanup')) {
182
+ wp_schedule_event(time(), 'w3_pgcache_cleanup', 'w3_pgcache_cleanup');
183
+ }
184
+ } else {
185
+ $this->unschedule();
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Unschedules events
191
+ */
192
+ function unschedule()
193
+ {
194
+ if (wp_next_scheduled('w3_pgcache_cleanup')) {
195
+ wp_clear_scheduled_hook('w3_pgcache_cleanup');
196
+ }
197
+ }
198
+
199
  /**
200
  * Updates WP config
201
  *
227
  return true;
228
  }
229
 
230
+ /**
231
+ * Does disk cache cleanup
232
+ *
233
+ * @return void
234
+ */
235
+ function cleanup()
236
+ {
237
+ $engine = $this->_config->get_string('pgcache.engine');
238
+
239
+ switch ($engine) {
240
+ case 'file':
241
+ require_once W3TC_LIB_W3_DIR . '/Cache/File/Manager.php';
242
+
243
+ $w3_cache_file_manager = & new W3_Cache_File_Manager(array(
244
+ 'cache_dir' => W3TC_CACHE_FILE_PGCACHE_DIR
245
+ ));
246
+
247
+ $w3_cache_file_manager->clean();
248
+ break;
249
+
250
+ case 'file_pgcache':
251
+ require_once W3TC_LIB_W3_DIR . '/Cache/File/PgCache/Manager.php';
252
+
253
+ $w3_cache_file_pgcache_manager = & new W3_Cache_File_PgCache_Manager(array(
254
+ 'cache_dir' => W3TC_CACHE_FILE_PGCACHE_DIR,
255
+ 'expire' => $this->_config->get_integer('pgcache.lifetime')
256
+ ));
257
+
258
+ $w3_cache_file_pgcache_manager->clean();
259
+ break;
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Cron schedules filter
265
+ *
266
+ * @paran array $schedules
267
+ * @return array
268
+ */
269
+ function cron_schedules($schedules)
270
+ {
271
+ $gc = $this->_config->get_integer('pgcache.file.gc');
272
+
273
+ return array_merge($schedules, array(
274
+ 'w3_pgcache_cleanup' => array(
275
+ 'interval' => $gc,
276
+ 'display' => sprintf('Every %d seconds', $gc)
277
+ )
278
+ ));
279
+ }
280
+
281
  /**
282
  * Post edit action
283
  *
304
  if (! in_array($post_id, $flushed_posts)) {
305
  require_once W3TC_LIB_W3_DIR . '/PgCache.php';
306
 
307
+ $w3_pgcache = & W3_PgCache::instance();
308
  $w3_pgcache->flush_post($post_id);
309
 
310
  $flushed_posts[] = $post_id;
342
  }
343
 
344
  /**
345
+ * Change action
346
  */
347
  function on_change()
348
  {
351
  if (! $flushed) {
352
  require_once W3TC_LIB_W3_DIR . '/PgCache.php';
353
 
354
+ $w3_pgcache = & W3_PgCache::instance();
355
  $w3_pgcache->flush();
356
  }
357
  }
358
+
359
+ /**
360
+ * Generates rules for WP dir
361
+ *
362
+ * @return string
363
+ */
364
+ function generate_rules_core()
365
+ {
366
+ /**
367
+ * Auto reject cookies
368
+ */
369
+ $reject_cookies = array(
370
+ 'comment_author',
371
+ 'wp-postpass'
372
+ );
373
+
374
+ /**
375
+ * Auto reject URIs
376
+ */
377
+ $reject_uris = array(
378
+ '\/wp-admin\/',
379
+ '\/xmlrpc.php',
380
+ '\/wp-(app|cron|login|register).php'
381
+ );
382
+
383
+ /**
384
+ * Reject cache for logged in users
385
+ */
386
+ if ($this->_config->get_boolean('pgcache.reject.logged')) {
387
+ $reject_cookies = array_merge($reject_cookies, array(
388
+ 'wordpress_[a-f0-9]+',
389
+ 'wordpress_logged_in'
390
+ ));
391
+ }
392
+
393
+ /**
394
+ * Reject cache for home page
395
+ */
396
+ if (! $this->_config->get_boolean('pgcache.cache.home')) {
397
+ $reject_uris[] = '^(\/|\/index.php)$';
398
+ }
399
+
400
+ /**
401
+ * Reject cache for feeds
402
+ */
403
+ if (! $this->_config->get_boolean('pgcache.cache.feed')) {
404
+ $reject_uris[] = 'feed';
405
+ }
406
+
407
+ /**
408
+ * Custom config
409
+ */
410
+ $reject_cookies += $this->_config->get_array('pgcache.reject.cookie');
411
+ $reject_uris += $this->_config->get_array('pgcache.reject.uri');
412
+ $reject_user_agents = $this->_config->get_array('pgcache.reject.ua');
413
+ $accept_files = $this->_config->get_array('pgcache.accept.files');
414
+
415
+ /**
416
+ * Generate directives
417
+ */
418
+ $rules = '';
419
+ $rules .= "# BEGIN W3 Total Cache\n";
420
+
421
+ $rules .= "<IfModule mod_rewrite.c>\n";
422
+
423
+ $compression = $this->_config->get_string('pgcache.compression');
424
+
425
+ if ($compression != '') {
426
+ $compressions = array();
427
+
428
+ if (stristr($compression, 'gzip') !== false) {
429
+ $compressions[] = 'gzip';
430
+ }
431
+
432
+ if (stristr($compression, 'deflate') !== false) {
433
+ $compressions[] = 'deflate';
434
+ }
435
+
436
+ if (count($compressions)) {
437
+ $rules .= " SetEnvIfNoCase Accept-Encoding (" . implode('|', $compressions) . ") APPEND_EXT=.$1\n";
438
+ }
439
+ }
440
+
441
+ $rules .= " RewriteEngine On\n";
442
+
443
+ $mobile_redirect = $this->_config->get_string('pgcache.mobile.redirect');
444
+
445
+ if ($mobile_redirect != '') {
446
+ $mobile_agents = $this->_config->get_array('pgcache.mobile.agents');
447
+
448
+ $rules .= " RewriteCond %{HTTP_USER_AGENT} " . implode('|', array_map('w3_preg_quote', $mobile_agents)) . " [NC]\n";
449
+ $rules .= " RewriteRule .* " . $mobile_redirect . " [R,L]\n";
450
+ }
451
+
452
+ $rules .= " RewriteCond %{REQUEST_URI} !" . implode('|', $reject_uris);
453
+
454
+ if (count($accept_files)) {
455
+ $rules .= " [OR]\n RewriteCond %{REQUEST_URI} " . implode('|', array_map('w3_preg_quote', $accept_files)) . " [NC]\n";
456
+ } else {
457
+ $rules .= "\n";
458
+ }
459
+
460
+ $rules .= " RewriteCond %{REQUEST_METHOD} !=POST\n";
461
+ $rules .= " RewriteCond %{QUERY_STRING} =\"\"\n";
462
+ $rules .= " RewriteCond %{HTTP_COOKIE} !" . implode('|', array_map('w3_preg_quote', $reject_cookies)) . " [NC]\n";
463
+
464
+ if (count($reject_user_agents)) {
465
+ $rules .= " RewriteCond %{HTTP_USER_AGENT} !" . implode('|', array_map('w3_preg_quote', $reject_user_agents)) . " [NC]\n";
466
+ }
467
+
468
+ $rules .= " RewriteCond " . str_replace('\\', '/', W3TC_CACHE_FILE_PGCACHE_DIR) . "/%{HTTP_HOST}/$1/index.html%{ENV:APPEND_EXT} -f\n";
469
+ $rules .= " RewriteRule ^(.*) " . str_replace(ABSPATH, '', W3TC_CACHE_FILE_PGCACHE_DIR) . "/%{HTTP_HOST}/$1/index.html%{ENV:APPEND_EXT} [L]\n";
470
+ $rules .= "</IfModule>\n";
471
+
472
+ $rules .= "# END W3 Total Cache\n\n";
473
+
474
+ if (! function_exists('is_site_admin') && ! $this->check_rules_wp()) {
475
+ $rules .= "# BEGIN WordPress\n";
476
+ $rules .= "<IfModule mod_rewrite.c>\n";
477
+ $rules .= " RewriteEngine On\n";
478
+ $rules .= " RewriteCond %{REQUEST_FILENAME} !-f\n";
479
+ $rules .= " RewriteCond %{REQUEST_FILENAME} !-d\n";
480
+ $rules .= " RewriteRule .* index.php [L]\n";
481
+ $rules .= "</IfModule>\n";
482
+ $rules .= "# END WordPress\n\n";
483
+ }
484
+
485
+ return $rules;
486
+ }
487
+
488
+ /**
489
+ * Generates directives for file cache dir
490
+ *
491
+ * @return string
492
+ */
493
+ function generate_rules_cache()
494
+ {
495
+ $charset = get_option('blog_charset');
496
+
497
+ $rules = '';
498
+ $rules .= "# BEGIN W3 Total Cache\n";
499
+ $rules .= "AddDefaultCharset " . ($charset ? $charset : 'UTF-8') . "\n";
500
+
501
+ $compression = $this->_config->get_string('pgcache.compression');
502
+
503
+ if ($compression != '') {
504
+ $compressions = array();
505
+
506
+ if (stristr($compression, 'gzip') !== false) {
507
+ $compressions[] = 'gzip';
508
+ }
509
+
510
+ if (stristr($compression, 'deflate') !== false) {
511
+ $compressions[] = 'deflate';
512
+ }
513
+
514
+ if (count($compressions)) {
515
+ $rules .= "<IfModule mod_mime.c>\n";
516
+
517
+ foreach ($compressions as $_compression) {
518
+ $rules .= " AddType text/html ." . $_compression . "\n";
519
+ $rules .= " AddEncoding " . $_compression . " .$_compression\n";
520
+ }
521
+
522
+ $rules .= "</IfModule>\n";
523
+
524
+ $rules .= "<IfModule mod_deflate.c>\n";
525
+ $rules .= " SetEnvIfNoCase Request_URI \\.(" . implode('|', $compressions) . ")$ no-gzip\n";
526
+ $rules .= "</IfModule>\n";
527
+ }
528
+ }
529
+
530
+ $rules .= "<IfModule mod_expires.c>\n";
531
+ $rules .= " ExpiresActive On\n";
532
+ $rules .= " ExpiresByType text/html M" . $this->_config->get_integer('pgcache.lifetime') . "\n";
533
+ $rules .= "</IfModule>\n";
534
+
535
+ $rules .= "<IfModule mod_headers.c>\n";
536
+ $rules .= " Header set X-Pingback \"" . get_bloginfo('pingback_url') . "\"\n";
537
+ $rules .= " Header set X-Powered-By \"" . W3TC_POWERED_BY . "\"\n";
538
+
539
+ if ($compression != '') {
540
+ $rules .= " Header set Vary \"Accept-Encoding, Cookie\"\n";
541
+ } else {
542
+ $rules .= " Header set Vary \"Cookie\"\n";
543
+ }
544
+
545
+ $rules .= " Header set Pragma public\n";
546
+ $rules .= " Header append Cache-Control \"public, must-revalidate\"\n";
547
+ $rules .= "</IfModule>\n";
548
+
549
+ $rules .= "# END W3 Total Cache\n\n";
550
+
551
+ return $rules;
552
+ }
553
+
554
+ /**
555
+ * Writes directives to WP .htaccess
556
+ *
557
+ * @return boolean
558
+ */
559
+ function write_rules_core()
560
+ {
561
+ $path = ABSPATH . '.htaccess';
562
+
563
+ if (file_exists($path)) {
564
+ if (($data = @file_get_contents($path)) !== false) {
565
+ $data = $this->erase_rules_w3tc($data);
566
+ $data = $this->erase_rules_wpsc($data);
567
+ } else {
568
+ return false;
569
+ }
570
+ } else {
571
+ $data = '';
572
+ }
573
+
574
+ $data = trim($this->generate_rules_core() . $data);
575
+
576
+ if (($fp = @fopen($path, 'w'))) {
577
+ @fputs($fp, $data);
578
+ @fclose($fp);
579
+
580
+ return true;
581
+ }
582
+
583
+ return false;
584
+ }
585
+
586
+ /**
587
+ * Writes directives to file cache .htaccess
588
+ *
589
+ * @return boolean
590
+ */
591
+ function write_rules_cache()
592
+ {
593
+ $path = W3TC_CACHE_FILE_PGCACHE_DIR . '/.htaccess';
594
+
595
+ if (file_exists($path)) {
596
+ if (($data = @file_get_contents($path)) !== false) {
597
+ $data = $this->erase_rules_w3tc($data);
598
+ } else {
599
+ return false;
600
+ }
601
+ } else {
602
+ $data = '';
603
+ }
604
+
605
+ $data = trim($this->generate_rules_cache() . $data);
606
+
607
+ if (($fp = @fopen($path, 'w'))) {
608
+ @fputs($fp, $data);
609
+ @fclose($fp);
610
+
611
+ return true;
612
+ }
613
+
614
+ return false;
615
+ }
616
+
617
+ /**
618
+ * Erases W3TC directives from config
619
+ *
620
+ * @param string $data
621
+ * @return string
622
+ */
623
+ function erase_rules_w3tc($data)
624
+ {
625
+ $data = preg_replace('~# BEGIN W3 Total Cache.*# END W3 Total Cache~s', '', $data);
626
+ $data = trim($data);
627
+
628
+ return $data;
629
+ }
630
+
631
+ /**
632
+ * Erases WP Super Cache rules directives config
633
+ *
634
+ * @param string $data
635
+ * @return string
636
+ */
637
+ function erase_rules_wpsc($data)
638
+ {
639
+ $data = preg_replace('~# BEGIN WPSuperCache.*# END WPSuperCache~s', '', $data);
640
+ $data = trim($data);
641
+
642
+ return $data;
643
+ }
644
+
645
+ /**
646
+ * Removes W3TC directives from WP .htaccess
647
+ *
648
+ * @return boolean
649
+ */
650
+ function remove_rules_core()
651
+ {
652
+ $path = ABSPATH . '.htaccess';
653
+
654
+ if (file_exists($path)) {
655
+ if (($data = @file_get_contents($path)) !== false) {
656
+ $data = $this->erase_rules_w3tc($data);
657
+
658
+ if (($fp = @fopen($path, 'w'))) {
659
+ @fputs($fp, $data);
660
+ @fclose($fp);
661
+
662
+ return true;
663
+ }
664
+ }
665
+ } else {
666
+ return true;
667
+ }
668
+
669
+ return false;
670
+ }
671
+
672
+ /**
673
+ * Removes W3TC directives from file cache dir
674
+ *
675
+ * @return boolean
676
+ */
677
+ function remove_rules_cache()
678
+ {
679
+ $path = W3TC_CACHE_FILE_PGCACHE_DIR . '/.htaccess';
680
+
681
+ return @unlink($path);
682
+ }
683
+
684
+ /**
685
+ * Checks core directives
686
+ *
687
+ * @return boolean
688
+ */
689
+ function check_rules_core()
690
+ {
691
+ $path = ABSPATH . '.htaccess';
692
+ $search = trim($this->generate_rules_core());
693
+
694
+ return (($data = @file_get_contents($path)) && strstr($data, $search) !== false && $this->check_rules_wp());
695
+ }
696
+
697
+ /**
698
+ * Checks cache directives
699
+ *
700
+ * @return boolean
701
+ */
702
+ function check_rules_cache()
703
+ {
704
+ $path = W3TC_CACHE_FILE_PGCACHE_DIR . '/.htaccess';
705
+ $search = trim($this->generate_rules_cache());
706
+
707
+ return (($data = @file_get_contents($path)) && strstr($data, $search) !== false);
708
+ }
709
+
710
+ /**
711
+ * Checks WP directives
712
+ *
713
+ * @return boolean
714
+ */
715
+ function check_rules_wp()
716
+ {
717
+ $path = ABSPATH . '/.htaccess';
718
+
719
+ return (($data = @file_get_contents($path)) && preg_match('~# BEGIN WordPress.*# END WordPress~s', $data));
720
+ }
721
  }
lib/W3/Plugin/TotalCache.php CHANGED
@@ -11,11 +11,34 @@ require_once W3TC_LIB_W3_DIR . '/Plugin.php';
11
  class W3_Plugin_TotalCache extends W3_Plugin
12
  {
13
  /**
14
- * Plugin action
15
- *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  * @var string
17
  */
18
- var $_action = '';
19
 
20
  /**
21
  * Runs plugin
@@ -52,24 +75,46 @@ class W3_Plugin_TotalCache extends W3_Plugin
52
  'admin_notices'
53
  ));
54
 
55
- if ($this->_config->get_boolean('pgcache.enabled', true) && $this->_config->get_string('pgcache.engine', 'memcached') == 'file') {
56
- add_action('w3_cache_file_cleanup', array(
 
 
 
 
 
 
 
 
 
 
57
  &$this,
58
- 'cache_file_cleanup'
59
  ));
60
  }
61
 
62
- if ($this->_config->get_boolean('common.support.enabled', true) && $this->_config->get_string('common.support.type', 'footer') == 'footer') {
63
- add_action('wp_footer', array(
64
  &$this,
65
- 'footer'
 
 
 
 
 
 
 
 
 
 
 
 
66
  ));
67
  }
68
 
69
- if (is_admin()) {
70
- add_action('init', array(
71
  &$this,
72
- 'init'
73
  ));
74
  }
75
 
@@ -84,29 +129,31 @@ class W3_Plugin_TotalCache extends W3_Plugin
84
  * Run DbCache plugin
85
  */
86
  require_once W3TC_DIR . '/lib/W3/Plugin/DbCache.php';
87
- $w3_plugin_dbcache = W3_Plugin_DbCache::instance();
88
  $w3_plugin_dbcache->run();
89
 
90
  /**
91
  * Run PgCache plugin
92
  */
93
  require_once W3TC_DIR . '/lib/W3/Plugin/PgCache.php';
94
- $w3_plugin_pgcache = W3_Plugin_PgCache::instance();
95
  $w3_plugin_pgcache->run();
96
 
97
  /**
98
  * Run CDN plugin
99
  */
100
  require_once W3TC_DIR . '/lib/W3/Plugin/Cdn.php';
101
- $w3_plugin_cdn = W3_Plugin_Cdn::instance();
102
  $w3_plugin_cdn->run();
103
 
104
  /**
105
  * Run Minify plugin
106
  */
107
- require_once W3TC_DIR . '/lib/W3/Plugin/Minify.php';
108
- $w3_plugin_minify = W3_Plugin_Minify::instance();
109
- $w3_plugin_minify->run();
 
 
110
  }
111
 
112
  /**
@@ -116,14 +163,14 @@ class W3_Plugin_TotalCache extends W3_Plugin
116
  */
117
  function &instance()
118
  {
119
- static $instance = null;
120
 
121
- if ($instance === null) {
122
  $class = __CLASS__;
123
- $instance = & new $class();
124
  }
125
 
126
- return $instance;
127
  }
128
 
129
  /**
@@ -140,19 +187,27 @@ class W3_Plugin_TotalCache extends W3_Plugin
140
  }
141
  }
142
 
143
- if (! is_dir(W3TC_CACHE_FILE_DIR)) {
144
- if (@mkdir(W3TC_CACHE_FILE_DIR, 0755)) {
145
- @chmod(W3TC_CACHE_FILE_DIR, 0755);
 
 
 
 
 
 
 
 
146
  } else {
147
- w3_writable_error(W3TC_CACHE_FILE_DIR);
148
  }
149
  }
150
 
151
- if (! is_dir(W3TC_CACHE_MINIFY_DIR)) {
152
- if (@mkdir(W3TC_CACHE_MINIFY_DIR, 0755)) {
153
- @chmod(W3TC_CACHE_MINIFY_DIR, 0755);
154
  } else {
155
- w3_writable_error(W3TC_CACHE_MINIFY_DIR);
156
  }
157
  }
158
 
@@ -163,17 +218,28 @@ class W3_Plugin_TotalCache extends W3_Plugin
163
  w3_writable_error(W3TC_LOG_DIR);
164
  }
165
  }
 
 
 
 
 
 
 
 
166
  }
167
 
168
- if (! file_exists(W3TC_CONFIG_PATH)) {
169
- if (@copy(W3TC_CONFIG_DEFAULT_PATH, W3TC_CONFIG_PATH)) {
170
- @chmod(W3TC_CONFIG_PATH, 0644);
171
- } else {
172
- w3_writable_error(W3TC_CONFIG_PATH);
173
- }
174
  }
175
 
176
- wp_schedule_event(time(), 'twicedaily', 'w3_cache_file_cleanup');
 
 
 
177
  }
178
 
179
  /**
@@ -181,324 +247,96 @@ class W3_Plugin_TotalCache extends W3_Plugin
181
  */
182
  function deactivate()
183
  {
184
- wp_clear_scheduled_hook('w3_cache_file_cleanup');
185
 
186
- @unlink(W3TC_CONFIG_PATH);
187
 
188
  if (! $this->locked()) {
189
  w3_rmdir(W3TC_LOG_DIR);
190
- w3_rmdir(W3TC_CACHE_MINIFY_DIR);
191
- w3_rmdir(W3TC_CACHE_FILE_DIR);
 
192
  w3_rmdir(W3TC_CONTENT_DIR);
193
  }
194
  }
195
 
196
  /**
197
- * Init Action
198
  */
199
  function init()
200
  {
201
- wp_enqueue_style('w3tc-options', WP_PLUGIN_URL . '/w3-total-cache/inc/css/options.css');
202
- wp_enqueue_script('w3tc-options', WP_PLUGIN_URL . '/w3-total-cache/inc/js/options.js');
203
-
204
- /**
205
- * Run plugin action
206
- */
207
- if (isset($_REQUEST['w3tc_action']) && current_user_can('manage_options')) {
208
- $action = trim($_REQUEST['w3tc_action']);
209
-
210
- if (method_exists($this, $action)) {
211
- call_user_func(array(
212
- &$this,
213
- $action
214
- ));
215
- die();
216
- }
217
- }
218
- }
219
-
220
- /**
221
- * Admin menu
222
- */
223
- function admin_menu()
224
- {
225
- add_options_page('W3 Total Cache', 'W3 Total Cache', 'manage_options', W3TC_FILE, array(
226
- &$this,
227
- 'options'
228
- ));
229
- }
230
-
231
- /**
232
- * Plugin action links filter
233
- *
234
- * @return array
235
- */
236
- function plugin_action_links($links)
237
- {
238
- array_unshift($links, '<a class="edit" href="options-general.php?page=' . W3TC_FILE . '">Settings</a>');
239
-
240
- return $links;
241
- }
242
-
243
- /**
244
- * favorite_actions filter
245
- */
246
- function favorite_actions($actions)
247
- {
248
- $actions['options-general.php?page=' . W3TC_FILE . '&amp;flush_all'] = array(
249
- 'Empty Caches',
250
- 'manage_options'
251
- );
252
-
253
- return $actions;
254
- }
255
-
256
- /**
257
- * Admin notices action
258
- */
259
- function admin_notices()
260
- {
261
- require_once W3TC_LIB_W3_DIR . '/Request.php';
262
- $notice = W3_Request::get_string('w3tc_notice');
263
- $error = W3_Request::get_string('w3tc_error');
264
-
265
- if (! empty($notice)) {
266
- echo sprintf('<div id="message" class="updated fade"><p>%s</p></div>', $notice);
267
- }
268
-
269
- if (! empty($error)) {
270
- echo sprintf('<div id="message" class="error"><p>%s</p></div>', $error);
271
- }
272
- }
273
-
274
- /**
275
- * Does disk cache cleanup
276
- * @return void
277
- */
278
- function cache_file_cleanup()
279
- {
280
- require_once W3TC_LIB_W3_DIR . '/Cache/File/Manager.php';
281
-
282
- $w3_cache_file_manager = & new W3_Cache_File_Manager(array(
283
- 'cache_dir' => W3TC_CACHE_FILE_DIR
284
- ));
285
-
286
- $w3_cache_file_manager->clean();
287
- }
288
-
289
- /**
290
- * Footer plugin action
291
- */
292
- function footer()
293
- {
294
- echo '<div style="text-align: center;">Performance Optimization <a href="http://www.w3-edge.com/wordpress-plugins/" rel="external">WordPress Plugins</a> by W3 EDGE</div>';
295
  }
296
 
297
  /**
298
- * Options page
299
  */
300
- function options()
301
  {
302
  require_once W3TC_LIB_W3_DIR . '/Request.php';
303
 
304
- $config = & $this->_config;
305
- $errors = array();
306
- $notes = array();
307
-
308
- $tab = W3_Request::get_string('tab');
309
-
310
- switch ($tab) {
311
- case 'general':
312
- case 'pgcache':
313
- case 'dbcache':
314
- case 'minify':
315
- case 'cdn':
316
- case 'install':
317
- case 'faq':
318
- case 'about':
319
  break;
320
 
321
  default:
322
- $tab = 'general';
323
- }
324
-
325
- /**
326
- * Save config
327
- */
328
- if ($_SERVER['REQUEST_METHOD'] == 'POST') {
329
- $config->read_request();
330
-
331
- /**
332
- * General tab
333
- */
334
- if ($tab == 'general') {
335
- $debug = W3_Request::get_boolean('debug');
336
-
337
- $config->set('dbcache.debug', $debug);
338
- $config->set('pgcache.debug', $debug);
339
- $config->set('minify.debug', $debug);
340
- $config->set('cdn.debug', $debug);
341
- }
342
-
343
- /**
344
- * Minify tab
345
- */
346
- if ($tab == 'minify') {
347
- $js_files = W3_Request::get_array('js_files');
348
- $css_files = W3_Request::get_array('css_files');
349
-
350
- $js_groups = array();
351
- $css_groups = array();
352
-
353
- foreach ($js_files as $group => $locations) {
354
- foreach ((array) $locations as $location => $files) {
355
- switch ($location) {
356
- case 'include':
357
- $js_groups[$group][$location]['blocking'] = true;
358
- break;
359
- case 'include-nb':
360
- $js_groups[$group][$location]['blocking'] = false;
361
- break;
362
- case 'include-footer':
363
- $js_groups[$group][$location]['blocking'] = true;
364
- break;
365
- case 'include-footer-nb':
366
- $js_groups[$group][$location]['blocking'] = false;
367
- break;
368
- }
369
- foreach ((array) $files as $file) {
370
- if (! empty($file)) {
371
- $js_groups[$group][$location]['files'][] = $file;
372
- }
373
- }
374
- }
375
- }
376
-
377
- foreach ($css_files as $group => $locations) {
378
- foreach ((array) $locations as $location => $files) {
379
- foreach ((array) $files as $file) {
380
- if (! empty($file)) {
381
- $css_groups[$group][$location]['files'][] = $file;
382
- }
383
- }
384
- }
385
- }
386
-
387
- $config->set('minify.js.groups', $js_groups);
388
- $config->set('minify.css.groups', $css_groups);
389
- }
390
-
391
- /**
392
- * Save config
393
- */
394
- if ($config->save()) {
395
- $this->link_delete();
396
-
397
- if ($config->get_boolean('common.support.enabled', true) && ($link_category_id = $this->link_get_category_id($config->get_string('common.support.type', 'footer')))) {
398
- $this->link_insert($link_category_id);
399
- }
400
-
401
- if ($tab == 'minify' && $config->get_boolean('minify.upload') && $config->get_boolean('cdn.enabled') && $config->get_string('cdn.engine') != 'mirror') {
402
- $this->cdn_upload_minify();
403
- }
404
-
405
- if (headers_sent()) {
406
- $notes[] = 'Plugin configuration updated successfully.';
407
- } else {
408
- w3_redirect('', 'w3tc_notice=Plugin configuration updated successfully.');
409
- }
410
- } else {
411
- if (headers_sent()) {
412
- $errors[] = 'Unable to save plugin configuration: config file is not writeable.';
413
- } else {
414
- w3_redirect('', 'w3tc_error=Unable to save plugin configuration: config file is not writeable.');
415
- }
416
- }
417
  }
418
 
419
- $pgcache_enabled = $config->get_boolean('pgcache.enabled');
420
- $dbcache_enabled = $config->get_boolean('dbcache.enabled');
421
- $minify_enabled = $config->get_boolean('minify.enabled');
422
- $cdn_enabled = $config->get_boolean('cdn.enabled');
423
-
424
- $enabled = ($pgcache_enabled || $dbcache_enabled || $minify_enabled || $cdn_enabled);
425
- $debug = ($config->get_boolean('dbcache.debug') || $config->get_boolean('pgcache.debug') || $config->get_boolean('minify.debug') || $config->get_boolean('cdn.debug'));
426
-
427
- $check_memcache = $this->check_memcache();
428
- $check_apc = $this->check_apc();
429
-
430
- $pgcache_memcached = ($config->get_string('pgcache.engine') == 'memcached');
431
- $dbcache_memcached = ($config->get_string('dbcache.engine') == 'memcached');
432
- $minify_memcached = ($config->get_string('minify.engine') == 'memcached');
433
-
434
- $can_empty_memcache = ($pgcache_memcached || $dbcache_memcached || $minify_memcached);
435
- $can_empty_apc = ($config->get_string('dbcache.engine') == 'apc' || $config->get_string('pgcache.engine') == 'apc' || $config->get_string('minify.engine') == 'apc');
436
- $can_empty_file = ($config->get_string('pgcache.engine') == 'file' || $config->get_string('minify.engine') == 'file');
437
-
438
  /**
439
  * Flush all caches
440
  */
441
  if (isset($_REQUEST['flush_all'])) {
442
- if ($can_empty_memcache) {
443
- $this->flush_memcached();
444
- }
445
- if ($can_empty_apc) {
446
- $this->flush_apc();
447
- }
448
- if ($can_empty_file) {
449
- $this->flush_file();
450
- }
451
 
452
- if (headers_sent()) {
453
- $notes[] = 'All caches emptied successfully.';
454
- } else {
455
- w3_redirect('', 'w3tc_notice=All caches emptied successfully.');
456
- }
457
  }
458
 
459
  /**
460
  * Flush memcached cache
461
  */
462
  if (isset($_REQUEST['flush_memcached'])) {
463
- if ($can_empty_memcache) {
464
- $this->flush_memcached();
465
- }
466
 
467
- if (headers_sent()) {
468
- $notes[] = 'Memcached cache emptied successfully.';
469
- } else {
470
- w3_redirect('', 'w3tc_notice=Memcached cache emptied successfully.');
471
- }
472
  }
473
 
474
  /**
475
  * Flush APC cache
476
  */
477
  if (isset($_REQUEST['flush_apc'])) {
478
- if ($can_empty_apc) {
479
- $this->flush_apc();
480
- }
481
 
482
- if (headers_sent()) {
483
- $notes[] = 'APC cache emptied successfully.';
484
- } else {
485
- w3_redirect('', 'w3tc_notice=APC cache emptied successfully.');
486
- }
487
  }
488
 
489
  /**
490
- * Flish disk cache
491
  */
492
  if (isset($_REQUEST['flush_file'])) {
493
- if ($can_empty_file) {
494
- $this->flush_file();
495
- }
496
 
497
- if (headers_sent()) {
498
- $notes[] = 'Disk cache emptied successfully.';
499
- } else {
500
- w3_redirect('', 'w3tc_notice=Disk cache emptied successfully.');
501
- }
502
  }
503
 
504
  /**
@@ -507,11 +345,17 @@ class W3_Plugin_TotalCache extends W3_Plugin
507
  if (isset($_REQUEST['flush_pgcache'])) {
508
  $this->flush_pgcache();
509
 
510
- if (headers_sent()) {
511
- $notes[] = 'Page cache emptied successfully.';
512
- } else {
513
- w3_redirect('', 'w3tc_notice=Page cache emptied successfully.');
 
 
514
  }
 
 
 
 
515
  }
516
 
517
  /**
@@ -520,11 +364,9 @@ class W3_Plugin_TotalCache extends W3_Plugin
520
  if (isset($_REQUEST['flush_dbcache'])) {
521
  $this->flush_dbcache();
522
 
523
- if (headers_sent()) {
524
- $notes[] = 'Database cache emptied successfully.';
525
- } else {
526
- w3_redirect('', 'w3tc_notice=Database cache emptied successfully.');
527
- }
528
  }
529
 
530
  /**
@@ -533,11 +375,17 @@ class W3_Plugin_TotalCache extends W3_Plugin
533
  if (isset($_REQUEST['flush_minify'])) {
534
  $this->flush_minify();
535
 
536
- if (headers_sent()) {
537
- $notes[] = 'Minify cache emptied successfully.';
538
- } else {
539
- w3_redirect('', 'w3tc_notice=Minify cache emptied successfully.');
 
 
540
  }
 
 
 
 
541
  }
542
 
543
  /**
@@ -545,89 +393,1348 @@ class W3_Plugin_TotalCache extends W3_Plugin
545
  */
546
  if (isset($_REQUEST['hide_note'])) {
547
  $setting = sprintf('notes.%s', W3_Request::get_string('hide_note'));
548
- $config->set($setting, false);
549
- $config->save();
550
 
551
- if (! headers_sent()) {
552
- w3_redirect();
 
 
 
 
553
  }
 
 
554
  }
555
 
556
  /**
557
- * Do some checks
558
  */
559
- if ($config->get_boolean('notes.defaults')) {
560
- $notes[] = 'The plugin is in quick setup mode, our recommended defaults are set. Simply satisfy all warnings and enable the plugin to get started or customize all of the settings you wish. <a href="options-general.php?page=' . W3TC_FILE . '&hide_note=defaults">Hide this message</a>';
 
 
 
 
 
 
 
 
 
 
 
561
  }
562
 
563
- /**
564
- * Check wp-content permissions
565
- */
566
- if ($config->get_boolean('notes.wp_content_perms')) {
567
- $wp_content_stat = stat(WP_CONTENT_DIR);
568
- $wp_content_mode = ($wp_content_stat['mode'] & 0777);
569
- if ($wp_content_mode != 0755) {
570
- $notes[] = '<strong>' . WP_CONTENT_DIR . '</strong> is <strong>writeable</strong>! You should change the permissions and make it more restrictive. Use your ftp client, or the following command to fix things: <strong>chmod 755 ' . WP_CONTENT_DIR . '</strong>. <a href="options-general.php?page=' . W3TC_FILE . '&hide_note=wp_content_perms">Hide this message</a>';
 
 
 
 
571
  }
572
  }
573
 
574
  /**
575
- * CDN checks
576
  */
577
- if ($tab == 'cdn') {
578
- if ($config->get('notes.cdn_first_time')) {
579
- $notes[] = 'It appears this is the first time you are using CDN feature. Unless you wish to first import attachments in your posts that are not already in the media library, please start a <strong>"manual export to <acronym title="Content Delivery Network">CDN</acronym>"</strong> and only enable this module after pending attachments have been successfully uploaded. <a href="options-general.php?page=' . W3TC_FILE . '&hide_note=cdn_first_time">Hide this message</a>';
580
- }
581
 
582
- if ($cdn_enabled && $config->get('cdn.domain') == '') {
583
- $errors[] = 'The <strong>"Replace domain in URL with"</strong> field must be populated. Enter the hostname of your <acronym title="Content Delivery Network">CDN</acronym> provider. <em>This is the hostname you would enter into your address bar in order to view objects in your browser.</em>';
 
 
 
 
 
 
584
  }
585
  }
586
 
587
  /**
588
- * Check for memcached & APC
589
  */
590
- if (! $check_memcache && ! $check_apc && $config->get_boolean('notes.no_memcached_nor_apc')) {
591
- $notes[] = '<strong>Memcached</strong> nor <strong>APC</strong> appear to be installed correctly. <a href="options-general.php?page=' . W3TC_FILE . '&hide_note=no_memcached_nor_apc">Hide this message</a>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
592
  }
593
 
594
  /**
595
- * Check for PgCache availability
596
  */
597
- if ($pgcache_enabled) {
598
- if (! $this->check_advanced_cache()) {
599
- $errors[] = '<strong>Page caching</strong> is not available. <strong>advanced-cache.php</strong> is not installed. Either the <strong>' . WP_CONTENT_DIR . '</strong> directory is not write-able or you have another caching plugin installed.';
600
- } elseif (! defined('WP_CACHE')) {
601
- $errors[] = '<strong>Page caching</strong> is not available. <strong>WP_CACHE</strong> constant is not defined in wp-config.php.';
602
- } elseif ($pgcache_memcached && ! $this->is_memcache_available($config->get_array('pgcache.memcached.servers'))) {
603
- $errors[] = sprintf('<strong>Page caching</strong> is not available. Memcached server <strong>%s</strong> is not running or is non-responsive.', implode(', ', $config->get_array('pgcache.memcached.servers')));
 
 
604
  }
605
  }
606
 
607
- /**
608
- * Check for DbCache availability
609
- */
610
- if ($dbcache_enabled) {
611
- if (! $this->check_db()) {
612
- $errors[] = '<strong>Database caching</strong> is not available. <strong>db.php</strong> is not installed. Either the <strong>' . WP_CONTENT_DIR . '</strong> directory is not write-able or you have another caching plugin installed.';
613
- } elseif ($dbcache_memcached && ! $this->is_memcache_available($config->get_array('dbcache.memcached.servers'))) {
614
- $errors[] = sprintf('<strong>Database caching</strong> is not available. Memcached server <strong>%s</strong> is not running or is non-responsive.', implode(', ', $config->get_array('dbcache.memcached.servers')));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
616
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
617
 
618
- /**
619
- * Check for minify availability
620
- */
621
- if ($minify_enabled && $minify_memcached && ! $this->is_memcache_available($config->get_array('minify.memcached.servers'))) {
622
- $errors[] = sprintf('<strong>Minify</strong> is not available. Memcached server <strong>%s</strong> is not running or is non-responsive.', implode(', ', $config->get_array('minify.memcached.servers')));
623
- }
 
 
 
 
 
 
 
624
 
625
- /**
626
- * Show page
627
- */
628
- include W3TC_DIR . '/inc/options/common/header.phtml';
629
- include W3TC_DIR . '/inc/options/' . $tab . '.phtml';
630
- include W3TC_DIR . '/inc/options/common/footer.phtml';
 
 
 
 
 
 
 
 
 
 
 
 
631
  }
632
 
633
  /**
@@ -658,7 +1765,7 @@ class W3_Plugin_TotalCache extends W3_Plugin
658
  $cdn_queue_id = W3_Request::get_integer('cdn_queue_id');
659
  if (! empty($cdn_queue_id)) {
660
  $w3_plugin_cdn->queue_delete($cdn_queue_id);
661
- $notes[] = 'File successfully deleted from the queue';
662
  }
663
  break;
664
 
@@ -666,17 +1773,15 @@ class W3_Plugin_TotalCache extends W3_Plugin
666
  $cdn_queue_type = W3_Request::get_integer('cdn_queue_type');
667
  if (! empty($cdn_queue_type)) {
668
  $w3_plugin_cdn->queue_empty($cdn_queue_type);
669
- $notes[] = 'Queue successfully emptied';
670
  }
671
  break;
672
  }
673
 
674
  $queue = $w3_plugin_cdn->queue_get();
675
- $title = 'Unsuccessfull transfers queue';
676
 
677
- include W3TC_DIR . '/inc/popup/common/header.phtml';
678
  include W3TC_DIR . '/inc/popup/cdn_queue.phtml';
679
- include W3TC_DIR . '/inc/popup/common/footer.phtml';
680
  }
681
 
682
  /**
@@ -691,9 +1796,7 @@ class W3_Plugin_TotalCache extends W3_Plugin
691
  $total = $w3_plugin_cdn->get_attachments_count();
692
  $title = 'Media library export';
693
 
694
- include W3TC_DIR . '/inc/popup/common/header.phtml';
695
  include W3TC_DIR . '/inc/popup/cdn_export_library.phtml';
696
- include W3TC_DIR . '/inc/popup/common/footer.phtml';
697
  }
698
 
699
  /**
@@ -739,15 +1842,14 @@ class W3_Plugin_TotalCache extends W3_Plugin
739
  require_once W3TC_LIB_W3_DIR . '/Plugin/Cdn.php';
740
 
741
  $w3_plugin_cdn = & W3_Plugin_Cdn::instance();
 
742
 
743
  $total = $w3_plugin_cdn->get_import_posts_count();
744
- $cdn_host = $this->_config->get_string('cdn.domain');
745
 
746
  $title = 'Media library import';
747
 
748
- include W3TC_DIR . '/inc/popup/common/header.phtml';
749
  include W3TC_DIR . '/inc/popup/cdn_import_library.phtml';
750
- include W3TC_DIR . '/inc/popup/common/footer.phtml';
751
  }
752
 
753
  /**
@@ -798,9 +1900,7 @@ class W3_Plugin_TotalCache extends W3_Plugin
798
 
799
  $title = 'Domain rename tool';
800
 
801
- include W3TC_DIR . '/inc/popup/common/header.phtml';
802
  include W3TC_DIR . '/inc/popup/cdn_rename_domain.phtml';
803
- include W3TC_DIR . '/inc/popup/common/footer.phtml';
804
  }
805
 
806
  /**
@@ -874,9 +1974,7 @@ class W3_Plugin_TotalCache extends W3_Plugin
874
  break;
875
  }
876
 
877
- include W3TC_DIR . '/inc/popup/common/header.phtml';
878
  include W3TC_DIR . '/inc/popup/cdn_export_file.phtml';
879
- include W3TC_DIR . '/inc/popup/common/footer.phtml';
880
  }
881
 
882
  /**
@@ -899,7 +1997,7 @@ class W3_Plugin_TotalCache extends W3_Plugin
899
  $upload[$file] = $file;
900
  }
901
 
902
- @$w3_plugin_cdn->upload($upload, false, $results);
903
 
904
  echo "{results: [\r\n";
905
 
@@ -922,15 +2020,16 @@ class W3_Plugin_TotalCache extends W3_Plugin
922
  {
923
  require_once W3TC_LIB_W3_DIR . '/Plugin/Cdn.php';
924
 
925
- $w3_plugin_cdn = W3_Plugin_Cdn::instance();
926
  $files = $w3_plugin_cdn->get_files_minify();
927
  $upload = array();
 
928
 
929
  foreach ($files as $file) {
930
  $upload[$file] = $file;
931
  }
932
 
933
- return @$w3_plugin_cdn->upload($upload);
934
  }
935
 
936
  /**
@@ -968,6 +2067,118 @@ class W3_Plugin_TotalCache extends W3_Plugin
968
  echo sprintf('{result: %d, error: "%s"}', $result, addslashes($error));
969
  }
970
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
971
  /**
972
  * Check if memcache is available
973
  *
@@ -983,7 +2194,7 @@ class W3_Plugin_TotalCache extends W3_Plugin
983
  if (! isset($results[$key])) {
984
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
985
 
986
- $memcached = W3_Cache_Memcached::instance(W3_CACHE_MEMCACHED_AUTO, array(
987
  'servers' => $servers,
988
  'persistant' => false
989
  ));
@@ -1004,7 +2215,7 @@ class W3_Plugin_TotalCache extends W3_Plugin
1004
  {
1005
  require_once W3TC_LIB_W3_DIR . '/Request.php';
1006
 
1007
- $servers = W3_Request::get_string('servers');
1008
 
1009
  if ($this->is_memcache_available($servers)) {
1010
  $result = true;
@@ -1018,37 +2229,24 @@ class W3_Plugin_TotalCache extends W3_Plugin
1018
  }
1019
 
1020
  /**
1021
- * Returns link category ID
1022
- *
1023
- * @param string $support_type
1024
- * @return integer
1025
  */
1026
- function link_get_category_id($support_type)
1027
  {
 
1028
  $matches = null;
1029
 
1030
- if (preg_match('~^link_category_(\d+)$~', $support_type, $matches)) {
1031
- return $matches[1];
 
 
 
 
 
 
 
 
1032
  }
1033
-
1034
- return false;
1035
- }
1036
-
1037
- /**
1038
- * Insert plugin link into Blogroll
1039
- *
1040
- * @param integer $link_category_id
1041
- */
1042
- function link_insert($link_category_id)
1043
- {
1044
- require_once ABSPATH . 'wp-admin/includes/bookmark.php';
1045
- wp_insert_link(array(
1046
- 'link_url' => W3TC_LINK_URL,
1047
- 'link_name' => W3TC_LINK_NAME,
1048
- 'link_category' => array(
1049
- $link_category_id
1050
- )
1051
- ));
1052
  }
1053
 
1054
  /**
@@ -1058,6 +2256,7 @@ class W3_Plugin_TotalCache extends W3_Plugin
1058
  {
1059
  $bookmarks = get_bookmarks();
1060
  $link_id = 0;
 
1061
  foreach ($bookmarks as $bookmark) {
1062
  if ($bookmark->link_url == W3TC_LINK_URL) {
1063
  $link_id = $bookmark->link_id;
@@ -1071,6 +2270,15 @@ class W3_Plugin_TotalCache extends W3_Plugin
1071
  }
1072
  }
1073
 
 
 
 
 
 
 
 
 
 
1074
  /**
1075
  * Flush specified cache
1076
  *
@@ -1078,21 +2286,38 @@ class W3_Plugin_TotalCache extends W3_Plugin
1078
  */
1079
  function flush($type)
1080
  {
1081
- if ($this->_config->get_string('pgcache.engine') == $type) {
 
 
 
 
 
 
 
 
1082
  $this->flush_pgcache();
1083
  }
1084
 
1085
- if ($this->_config->get_string('dbcache.engine') == $type) {
1086
  $this->flush_dbcache();
1087
  }
1088
 
1089
- if ($this->_config->get_string('minify.engine') == $type) {
 
 
 
 
 
 
 
 
1090
  $this->flush_minify();
1091
  }
1092
  }
1093
 
1094
  /**
1095
  * Flush memcached cache
 
1096
  * @return void
1097
  */
1098
  function flush_memcached()
@@ -1111,11 +2336,13 @@ class W3_Plugin_TotalCache extends W3_Plugin
1111
 
1112
  /**
1113
  * Flush file cache
 
1114
  * @return void
1115
  */
1116
  function flush_file()
1117
  {
1118
  $this->flush('file');
 
1119
  }
1120
 
1121
  /**
@@ -1124,7 +2351,7 @@ class W3_Plugin_TotalCache extends W3_Plugin
1124
  function flush_pgcache()
1125
  {
1126
  require_once W3TC_DIR . '/lib/W3/PgCache.php';
1127
- $w3_pgcache = W3_PgCache::instance();
1128
  $w3_pgcache->flush();
1129
  }
1130
 
@@ -1134,7 +2361,7 @@ class W3_Plugin_TotalCache extends W3_Plugin
1134
  function flush_dbcache()
1135
  {
1136
  require_once W3TC_DIR . '/lib/W3/Db.php';
1137
- $w3_db = W3_Db::instance();
1138
  $w3_db->flush_cache();
1139
  }
1140
 
@@ -1143,14 +2370,16 @@ class W3_Plugin_TotalCache extends W3_Plugin
1143
  */
1144
  function flush_minify()
1145
  {
1146
- require_once W3TC_DIR . '/lib/W3/Minify.php';
1147
- $w3_minify = W3_Minify::instance();
1148
- $w3_minify->flush();
 
 
1149
  }
1150
 
1151
  /**
1152
  * Checks if advanced-cache.php exists
1153
- *
1154
  * @return boolean
1155
  */
1156
  function check_advanced_cache()
@@ -1188,6 +2417,16 @@ class W3_Plugin_TotalCache extends W3_Plugin
1188
  return function_exists('apc_store');
1189
  }
1190
 
 
 
 
 
 
 
 
 
 
 
1191
  /**
1192
  * Output buffering callback
1193
  *
@@ -1198,50 +2437,54 @@ class W3_Plugin_TotalCache extends W3_Plugin
1198
  {
1199
  global $wpdb;
1200
 
1201
- if (! w3_is_xml($buffer)) {
1202
- return $buffer;
1203
- }
1204
-
1205
- $host = gethostbyaddr($_SERVER['SERVER_ADDR']);
1206
- $date = date('Y-m-d H:i:s');
1207
-
1208
- if ($this->_config->get_boolean('common.support.enabled')) {
1209
- $buffer .= sprintf("\r\n<!-- Served from: %s @ %s by W3 Total Cache -->", $host, $date);
1210
- } else {
1211
- $buffer .= <<<DATA
1212
- <!--
1213
- This site's performance optimized by W3 Total Cache:
1214
-
1215
- W3 Total Cache improves the user experience of your blog by caching
1216
- frequent operations, reducing the weight of various files and providing
1217
- transparent content delivery network integration.
1218
-
1219
- Learn more about our WordPress Plugins: http://www.w3-edge.com/wordpress-plugins/
1220
- DATA;
1221
-
1222
- $buffer .= "\r\n\r\n";
1223
-
1224
- if ($this->_config->get_boolean('minify.enabled', true)) {
1225
- $buffer .= sprintf("Minified using %s\r\n", w3_get_engine_name($this->_config->get_string('minify.engine')));
1226
- }
1227
-
1228
- if ($this->_config->get_boolean('pgcache.enabled', true)) {
1229
- $buffer .= sprintf("Page Caching using %s\r\n", w3_get_engine_name($this->_config->get_string('pgcache.engine')));
1230
- }
1231
 
1232
- if ($this->_config->get_boolean('dbcache.enabled', true) && is_a($wpdb, 'W3_Db')) {
1233
- $buffer .= sprintf("Database Caching %d/%d queries in %.3f seconds using %s\r\n", $wpdb->query_hits, $wpdb->query_total, $wpdb->time_total, w3_get_engine_name($this->_config->get_string('dbcache.engine')));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1234
  }
1235
 
1236
- if ($this->_config->get_boolean('cdn.enabled', true)) {
1237
- $buffer .= sprintf("Content Delivery Network via %s\r\n", $this->_config->get_string('cdn.domain', 'N/A'));
1238
  }
1239
-
1240
- $buffer .= sprintf("\r\nServed from: %s @ %s -->", $host, $date);
1241
- }
1242
-
1243
- if ($this->_config->get_boolean('dbcache.enabled', true) && $this->_config->get_boolean('dbcache.debug') && is_a($wpdb, 'W3_Db')) {
1244
- $buffer .= "\r\n\r\n" . $wpdb->get_debug_info();
1245
  }
1246
 
1247
  return $buffer;
@@ -1318,4 +2561,174 @@ DATA;
1318
 
1319
  return true;
1320
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1321
  }
11
  class W3_Plugin_TotalCache extends W3_Plugin
12
  {
13
  /**
14
+ * Page tab
15
+ * @var string
16
+ */
17
+ var $_tab = '';
18
+
19
+ /**
20
+ * Notes
21
+ * @var array
22
+ */
23
+ var $_notes = array();
24
+
25
+ /**
26
+ * Errors
27
+ * @var array
28
+ */
29
+ var $_errors = array();
30
+
31
+ /**
32
+ * Show support reminder flag
33
+ * @var boolean
34
+ */
35
+ var $_support_reminder = false;
36
+
37
+ /**
38
+ * Used in PHPMailer init function
39
  * @var string
40
  */
41
+ var $_phpmailer_sender = '';
42
 
43
  /**
44
  * Runs plugin
75
  'admin_notices'
76
  ));
77
 
78
+ add_action('init', array(
79
+ &$this,
80
+ 'init'
81
+ ));
82
+
83
+ add_action('in_plugin_update_message-' . W3TC_FILE, array(
84
+ &$this,
85
+ 'in_plugin_update_message'
86
+ ));
87
+
88
+ if ($this->_config->get_boolean('common.widget.latest')) {
89
+ add_action('wp_dashboard_setup', array(
90
  &$this,
91
+ 'wp_dashboard_setup'
92
  ));
93
  }
94
 
95
+ if ($this->_config->get_boolean('cdn.enabled')) {
96
+ add_action('switch_theme', array(
97
  &$this,
98
+ 'switch_theme'
99
+ ));
100
+
101
+ add_filter('update_feedback', array(
102
+ &$this,
103
+ 'update_feedback'
104
+ ));
105
+ }
106
+
107
+ if ($this->_config->get_boolean('pgcache.enabled') || $this->_config->get_boolean('minify.enabled')) {
108
+ add_filter('pre_update_option_active_plugins', array(
109
+ &$this,
110
+ 'pre_update_option_active_plugins'
111
  ));
112
  }
113
 
114
+ if ($this->_config->get_string('common.support') == 'footer') {
115
+ add_action('wp_footer', array(
116
  &$this,
117
+ 'footer'
118
  ));
119
  }
120
 
129
  * Run DbCache plugin
130
  */
131
  require_once W3TC_DIR . '/lib/W3/Plugin/DbCache.php';
132
+ $w3_plugin_dbcache = & W3_Plugin_DbCache::instance();
133
  $w3_plugin_dbcache->run();
134
 
135
  /**
136
  * Run PgCache plugin
137
  */
138
  require_once W3TC_DIR . '/lib/W3/Plugin/PgCache.php';
139
+ $w3_plugin_pgcache = & W3_Plugin_PgCache::instance();
140
  $w3_plugin_pgcache->run();
141
 
142
  /**
143
  * Run CDN plugin
144
  */
145
  require_once W3TC_DIR . '/lib/W3/Plugin/Cdn.php';
146
+ $w3_plugin_cdn = & W3_Plugin_Cdn::instance();
147
  $w3_plugin_cdn->run();
148
 
149
  /**
150
  * Run Minify plugin
151
  */
152
+ if (W3TC_PHP5) {
153
+ require_once W3TC_DIR . '/lib/W3/Plugin/Minify.php';
154
+ $w3_plugin_minify = & W3_Plugin_Minify::instance();
155
+ $w3_plugin_minify->run();
156
+ }
157
  }
158
 
159
  /**
163
  */
164
  function &instance()
165
  {
166
+ static $instances = array();
167
 
168
+ if (! isset($instances[0])) {
169
  $class = __CLASS__;
170
+ $instances[0] = & new $class();
171
  }
172
 
173
+ return $instances[0];
174
  }
175
 
176
  /**
187
  }
188
  }
189
 
190
+ if (! is_dir(W3TC_CACHE_FILE_DBCACHE_DIR)) {
191
+ if (@mkdir(W3TC_CACHE_FILE_DBCACHE_DIR, 0755)) {
192
+ @chmod(W3TC_CACHE_FILE_DBCACHE_DIR, 0755);
193
+ } else {
194
+ w3_writable_error(W3TC_CACHE_FILE_DBCACHE_DIR);
195
+ }
196
+ }
197
+
198
+ if (! is_dir(W3TC_CACHE_FILE_PGCACHE_DIR)) {
199
+ if (@mkdir(W3TC_CACHE_FILE_PGCACHE_DIR, 0755)) {
200
+ @chmod(W3TC_CACHE_FILE_PGCACHE_DIR, 0755);
201
  } else {
202
+ w3_writable_error(W3TC_CACHE_FILE_PGCACHE_DIR);
203
  }
204
  }
205
 
206
+ if (! is_dir(W3TC_CACHE_FILE_MINIFY_DIR)) {
207
+ if (@mkdir(W3TC_CACHE_FILE_MINIFY_DIR, 0755)) {
208
+ @chmod(W3TC_CACHE_FILE_MINIFY_DIR, 0755);
209
  } else {
210
+ w3_writable_error(W3TC_CACHE_FILE_MINIFY_DIR);
211
  }
212
  }
213
 
218
  w3_writable_error(W3TC_LOG_DIR);
219
  }
220
  }
221
+
222
+ if (! is_dir(W3TC_TMP_DIR)) {
223
+ if (@mkdir(W3TC_TMP_DIR, 0755)) {
224
+ @chmod(W3TC_TMP_DIR, 0755);
225
+ } else {
226
+ w3_writable_error(W3TC_TMP_DIR);
227
+ }
228
+ }
229
  }
230
 
231
+ if (! $this->_config->get_integer('common.install')) {
232
+ $this->_config->set('common.install', time());
233
+ }
234
+
235
+ if (! file_exists(W3TC_CONFIG_PATH) && ! $this->_config->save()) {
236
+ w3_writable_error(W3TC_CONFIG_PATH);
237
  }
238
 
239
+ delete_option('w3tc_request_data');
240
+ add_option('w3tc_request_data', '', null, 'no');
241
+
242
+ $this->link_update();
243
  }
244
 
245
  /**
247
  */
248
  function deactivate()
249
  {
250
+ $this->link_delete();
251
 
252
+ delete_option('w3tc_request_data');
253
 
254
  if (! $this->locked()) {
255
  w3_rmdir(W3TC_LOG_DIR);
256
+ w3_rmdir(W3TC_CACHE_FILE_MINIFY_DIR);
257
+ w3_rmdir(W3TC_CACHE_FILE_PGCACHE_DIR);
258
+ w3_rmdir(W3TC_CACHE_FILE_DBCACHE_DIR);
259
  w3_rmdir(W3TC_CONTENT_DIR);
260
  }
261
  }
262
 
263
  /**
264
+ * Init action
265
  */
266
  function init()
267
  {
268
+ $this->check_request();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  }
270
 
271
  /**
272
+ * Load action
273
  */
274
+ function load()
275
  {
276
  require_once W3TC_LIB_W3_DIR . '/Request.php';
277
 
278
+ $this->_tab = W3_Request::get_string('tab');
279
+
280
+ switch (true) {
281
+ case ($this->_tab == 'general'):
282
+ case ($this->_tab == 'pgcache'):
283
+ case ($this->_tab == 'dbcache'):
284
+ case ($this->_tab == 'minify' && W3TC_PHP5):
285
+ case ($this->_tab == 'cdn'):
286
+ case ($this->_tab == 'install'):
287
+ case ($this->_tab == 'faq'):
288
+ case ($this->_tab == 'about'):
289
+ case ($this->_tab == 'support'):
 
 
 
290
  break;
291
 
292
  default:
293
+ $this->_tab = 'general';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  }
295
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  /**
297
  * Flush all caches
298
  */
299
  if (isset($_REQUEST['flush_all'])) {
300
+ $this->flush_memcached();
301
+ $this->flush_apc();
302
+ $this->flush_file();
 
 
 
 
 
 
303
 
304
+ $this->redirect(array(
305
+ 'note' => 'flush_all'
306
+ ), true);
 
 
307
  }
308
 
309
  /**
310
  * Flush memcached cache
311
  */
312
  if (isset($_REQUEST['flush_memcached'])) {
313
+ $this->flush_memcached();
 
 
314
 
315
+ $this->redirect(array(
316
+ 'note' => 'flush_memcached'
317
+ ), true);
 
 
318
  }
319
 
320
  /**
321
  * Flush APC cache
322
  */
323
  if (isset($_REQUEST['flush_apc'])) {
324
+ $this->flush_apc();
 
 
325
 
326
+ $this->redirect(array(
327
+ 'note' => 'flush_apc'
328
+ ), true);
 
 
329
  }
330
 
331
  /**
332
+ * Flush disk cache
333
  */
334
  if (isset($_REQUEST['flush_file'])) {
335
+ $this->flush_file();
 
 
336
 
337
+ $this->redirect(array(
338
+ 'note' => 'flush_file'
339
+ ), true);
 
 
340
  }
341
 
342
  /**
345
  if (isset($_REQUEST['flush_pgcache'])) {
346
  $this->flush_pgcache();
347
 
348
+ $this->_config->set('notes.need_empty_pgcache', false);
349
+
350
+ if (! $this->_config->save()) {
351
+ $this->redirect(array(
352
+ 'error' => 'config_save'
353
+ ), true);
354
  }
355
+
356
+ $this->redirect(array(
357
+ 'note' => 'flush_pgcache'
358
+ ), true);
359
  }
360
 
361
  /**
364
  if (isset($_REQUEST['flush_dbcache'])) {
365
  $this->flush_dbcache();
366
 
367
+ $this->redirect(array(
368
+ 'note' => 'flush_dbcache'
369
+ ), true);
 
 
370
  }
371
 
372
  /**
375
  if (isset($_REQUEST['flush_minify'])) {
376
  $this->flush_minify();
377
 
378
+ $this->_config->set('notes.need_empty_minify', false);
379
+
380
+ if (! $this->_config->save()) {
381
+ $this->redirect(array(
382
+ 'error' => 'config_save'
383
+ ), true);
384
  }
385
+
386
+ $this->redirect(array(
387
+ 'note' => 'flush_minify'
388
+ ), true);
389
  }
390
 
391
  /**
393
  */
394
  if (isset($_REQUEST['hide_note'])) {
395
  $setting = sprintf('notes.%s', W3_Request::get_string('hide_note'));
 
 
396
 
397
+ $this->_config->set($setting, false);
398
+
399
+ if (! $this->_config->save()) {
400
+ $this->redirect(array(
401
+ 'error' => 'config_save'
402
+ ), true);
403
  }
404
+
405
+ $this->redirect(array(), true);
406
  }
407
 
408
  /**
409
+ * Write page cache rules
410
  */
411
+ if (isset($_REQUEST['pgcache_write_rules_core'])) {
412
+ require_once W3TC_LIB_W3_DIR . '/Plugin/PgCache.php';
413
+ $w3_plugin_pgcache = & W3_Plugin_PgCache::instance();
414
+
415
+ if ($w3_plugin_pgcache->write_rules_core()) {
416
+ $this->redirect(array(
417
+ 'note' => 'pgcache_write_rules_core'
418
+ ));
419
+ } else {
420
+ $this->redirect(array(
421
+ 'error' => 'pgcache_write_rules_core'
422
+ ));
423
+ }
424
  }
425
 
426
+ if (isset($_REQUEST['pgcache_write_rules_cache'])) {
427
+ require_once W3TC_LIB_W3_DIR . '/Plugin/PgCache.php';
428
+ $w3_plugin_pgcache = & W3_Plugin_PgCache::instance();
429
+
430
+ if ($w3_plugin_pgcache->write_rules_cache()) {
431
+ $this->redirect(array(
432
+ 'note' => 'pgcache_write_rules_cache'
433
+ ));
434
+ } else {
435
+ $this->redirect(array(
436
+ 'error' => 'pgcache_write_rules_cache'
437
+ ));
438
  }
439
  }
440
 
441
  /**
442
+ * Write minify rules
443
  */
444
+ if (W3TC_PHP5 && isset($_REQUEST['minify_write_rules'])) {
445
+ require_once W3TC_LIB_W3_DIR . '/Plugin/Minify.php';
446
+ $w3_plugin_minify = & W3_Plugin_Minify::instance();
 
447
 
448
+ if ($w3_plugin_minify->write_rules()) {
449
+ $this->redirect(array(
450
+ 'note' => 'minify_write_rules'
451
+ ));
452
+ } else {
453
+ $this->redirect(array(
454
+ 'error' => 'minify_write_rules'
455
+ ));
456
  }
457
  }
458
 
459
  /**
460
+ * Save support us options
461
  */
462
+ if (isset($_REQUEST['save_support_us'])) {
463
+ $support = W3_Request::get_string('support');
464
+
465
+ $this->_config->set('common.support', $support);
466
+
467
+ if (! $this->_config->save()) {
468
+ $this->redirect(array(
469
+ 'error' => 'config_save'
470
+ ));
471
+ }
472
+
473
+ $this->link_update();
474
+
475
+ $this->redirect(array(
476
+ 'note' => 'config_save'
477
+ ));
478
  }
479
 
480
  /**
481
+ * Run plugin action
482
  */
483
+ if (isset($_REQUEST['w3tc_action']) && current_user_can('manage_options')) {
484
+ $action = trim($_REQUEST['w3tc_action']);
485
+
486
+ if (method_exists($this, $action)) {
487
+ call_user_func(array(
488
+ &$this,
489
+ $action
490
+ ));
491
+ exit();
492
  }
493
  }
494
 
495
+ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
496
+ if ($this->_tab == 'support') {
497
+ $this->support_request();
498
+ } else {
499
+ $this->options_save();
500
+ }
501
+ exit();
502
+ }
503
+
504
+ $this->_support_reminder = ($this->_config->get_boolean('notes.support_us') && $this->_config->get_integer('common.install') < (time() - W3TC_SUPPORT_US_TIMEOUT) && ! $this->is_supported());
505
+
506
+ wp_enqueue_style('w3tc-options', WP_PLUGIN_URL . '/w3-total-cache/inc/css/options.css');
507
+ wp_enqueue_style('w3tc-lightbox', WP_PLUGIN_URL . '/w3-total-cache/inc/css/lightbox.css');
508
+ wp_enqueue_script('w3tc-options', WP_PLUGIN_URL . '/w3-total-cache/inc/js/options.js');
509
+ wp_enqueue_script('w3tc-lightbox', WP_PLUGIN_URL . '/w3-total-cache/inc/js/lightbox.js');
510
+ }
511
+
512
+ /**
513
+ * Dashboard setup action
514
+ */
515
+ function wp_dashboard_setup()
516
+ {
517
+ wp_add_dashboard_widget('w3_latest', 'The Latest from W3 EDGE', array(
518
+ &$this,
519
+ 'widget_latest'
520
+ ));
521
+ }
522
+
523
+ /**
524
+ * Prints lates widget contents
525
+ */
526
+ function widget_latest()
527
+ {
528
+ global $wp_version;
529
+
530
+ if ($wp_version >= 2.8) {
531
+ include_once (ABSPATH . WPINC . '/feed.php');
532
+ $feed = fetch_feed(W3TC_FEED_URL);
533
+ $items = $feed->get_items(0, W3TC_FEED_ITEMS);
534
+
535
+ foreach ($items as $item) {
536
+ echo sprintf('<h4><a href="%s">%s</a></h4><p>%s</p>', $item->get_link(), $item->get_title(), $item->get_description());
537
+ }
538
+ } else {
539
+ include_once (ABSPATH . WPINC . '/rss.php');
540
+ $rss = fetch_rss(W3TC_FEED_URL);
541
+ $items = array_slice($rss->items, 0, W3TC_FEED_ITEMS);
542
+
543
+ foreach ($items as $item) {
544
+ echo sprintf('<h4><a href="%s">%s</a></h4><p>%s</p>', $item['link'], $item['title'], $item['description']);
545
+ }
546
+ }
547
+
548
+ }
549
+
550
+ /**
551
+ * Admin menu
552
+ */
553
+ function admin_menu()
554
+ {
555
+ $page = add_options_page('W3 Total Cache', 'W3 Total Cache', 'manage_options', W3TC_FILE, array(
556
+ &$this,
557
+ 'options'
558
+ ));
559
+
560
+ add_action('load-' . $page, array(
561
+ &$this,
562
+ 'load'
563
+ ));
564
+ }
565
+
566
+ /**
567
+ * Plugin action links filter
568
+ *
569
+ * @return array
570
+ */
571
+ function plugin_action_links($links)
572
+ {
573
+ array_unshift($links, '<a class="edit" href="options-general.php?page=' . W3TC_FILE . '">Settings</a>');
574
+
575
+ return $links;
576
+ }
577
+
578
+ /**
579
+ * favorite_actions filter
580
+ */
581
+ function favorite_actions($actions)
582
+ {
583
+ $actions['options-general.php?page=' . W3TC_FILE . '&amp;flush_all'] = array(
584
+ 'Empty Caches',
585
+ 'manage_options'
586
+ );
587
+
588
+ return $actions;
589
+ }
590
+
591
+ /**
592
+ * Check request and handle w3tc_request_data requests
593
+ */
594
+ function check_request()
595
+ {
596
+ $pos = strpos($_SERVER['REQUEST_URI'], '/w3tc_request_data/');
597
+
598
+ if ($pos !== false) {
599
+ $hash = substr($_SERVER['REQUEST_URI'], $pos + 19, 32);
600
+
601
+ if (strlen($hash) == 32) {
602
+ $request_data = (array) get_option('w3tc_request_data');
603
+
604
+ if (isset($request_data[$hash])) {
605
+ echo '<pre>';
606
+ foreach ($request_data[$hash] as $key => $value) {
607
+ printf("%s: %s\n", $key, $value);
608
+ }
609
+ echo '</pre>';
610
+
611
+ unset($request_data[$hash]);
612
+ update_option('w3tc_request_data', $request_data);
613
+ } else {
614
+ echo 'Hash is expired or invalid';
615
+ }
616
+
617
+ exit();
618
+ }
619
+ }
620
+ }
621
+
622
+ /**
623
+ * Admin notices action
624
+ */
625
+ function admin_notices()
626
+ {
627
+ $error_messages = array(
628
+ 'config_save' => sprintf('The settings could not be saved because the config file is not write-able. Please run <strong>chmod 777 %s</strong> to resolve this issue.', file_exists(W3TC_CONFIG_PATH) ? W3TC_CONFIG_PATH : WP_CONTENT_DIR),
629
+ 'fancy_permalinks_disabled' => sprintf('Fancy permalinks are disabled. Please %s it first, then re-attempt to enabling the enhanced disk mode.', $this->button_link('enable', 'options-permalink.php')),
630
+ 'pgcache_write_rules_core' => sprintf('Either your .htaccess file does not exist or cannot be modified (%s.htaccess). Please run <strong>chmod 777 %s.htaccess</strong> to resolve this issue.', ABSPATH, ABSPATH),
631
+ 'pgcache_write_rules_cache' => sprintf('The page cache rules (%s/.htaccess) could not be modified. Please run <strong>chmod 777 %s/.htaccess</strong> to resolve this issue.', W3TC_CACHE_FILE_PGCACHE_DIR, W3TC_CACHE_FILE_PGCACHE_DIR),
632
+ 'minify_write_rules' => sprintf('The minify cache rules (%s/.htaccess) could not be modified. Please run <strong>chmod 777 %s/.htaccess</strong> to resolve this issue.', W3TC_CACHE_FILE_MINIFY_DIR, W3TC_CACHE_FILE_MINIFY_DIR),
633
+ 'support_request_url' => 'Please enter the address of your blog in the Blog <acronym title="Uniform Resource Locator">URL</acronym> field.',
634
+ 'support_request_name' => 'Please enter your name in the Name field',
635
+ 'support_request_email' => 'Please enter valid email address in the E-Mail field.',
636
+ 'support_request_type' => 'Please select request type.',
637
+ 'support_request_description' => 'Please describe the issue in the issue description field.',
638
+ 'support_request_wp_login' => 'Please enter an administrator login. Remember you can create a temporary one just for this support case.',
639
+ 'support_request_wp_password' => 'Please enter WP Admin password, be sure it\'s spelled correctly.',
640
+ 'support_request_ftp_host' => 'Please enter <acronym title="Secure Shell">SSH</acronym> or <acronym title="File Transfer Protocol">FTP</acronym> host for your site.',
641
+ 'support_request_ftp_login' => 'Please enter <acronym title="Secure Shell">SSH</acronym> or <acronym title="File Transfer Protocol">FTP</acronym> login for your server. Remember you can create a temporary one just for this support case.',
642
+ 'support_request_ftp_password' => 'Please enter <acronym title="Secure Shell">SSH</acronym> or <acronym title="File Transfer Protocol">FTP</acronym> password for your <acronym title="File Transfer Protocol">FTP</acronym> account.',
643
+ 'support_request' => 'Unable to send your support request.'
644
+ );
645
+
646
+ $note_messages = array(
647
+ 'config_save' => 'Plugin configuration successfully updated.',
648
+ 'flush_all' => 'All caches successfully emptied.',
649
+ 'flush_memcached' => 'Memcached cache(s) successfully emptied.',
650
+ 'flush_apc' => 'Opcode (APC) cache successfully emptied.',
651
+ 'flush_file' => 'Disk cache successfully emptied.',
652
+ 'flush_pgcache' => 'Page cache successfull emptied.',
653
+ 'flush_dbcache' => 'Database cache successfully emptied.',
654
+ 'flush_minify' => 'Minify cache successfully emptied.',
655
+ 'pgcache_write_rules_core' => 'Page cache rewrite rules have been successfully written.',
656
+ 'pgcache_write_rules_cache' => 'Page cache rewrite rules have been successfully written.',
657
+ 'minify_write_rules' => 'Minify rewrite rules have been successfully written.',
658
+ 'support_request' => 'Your support request has been successfully sent.'
659
+ );
660
+
661
+ $errors = array();
662
+ $notes = array();
663
+
664
+ require_once W3TC_LIB_W3_DIR . '/Request.php';
665
+
666
+ $error = W3_Request::get_string('error');
667
+ $note = W3_Request::get_string('note');
668
+
669
+ /**
670
+ * Handle messages from reqeust
671
+ */
672
+ if (isset($error_messages[$error])) {
673
+ $errors[] = $error_messages[$error];
674
+ }
675
+
676
+ if (isset($note_messages[$note])) {
677
+ $notes[] = $note_messages[$note];
678
+ }
679
+
680
+ /**
681
+ * Do checks and show messages
682
+ */
683
+ if ($this->_config->get_boolean('cdn.enabled')) {
684
+ if ($this->_config->get_boolean('notes.theme_changed')) {
685
+ $notes[] = sprintf('Your active theme has changed, please %s now to ensure proper operation. %s', $this->button_popup('upload active theme files', 'cdn_export', 'cdn_export_type=theme'), $this->button_hide_note('Hide this message', 'theme_changed'));
686
+ }
687
+
688
+ if ($this->_config->get_boolean('notes.wp_upgraded')) {
689
+ $notes[] = sprintf('Have you upgraded WordPress? Please %s files now to ensure proper operation. %s', $this->button_popup('upload wp-includes', 'cdn_export', 'cdn_export_type=includes'), $this->button_hide_note('Hide this message', 'wp_upgraded'));
690
+ }
691
+
692
+ if ($this->_config->get_boolean('notes.cdn_upload') && $this->_config->get_string('cdn.engine') != 'mirror') {
693
+ $cdn_upload_buttons = array();
694
+
695
+ if ($this->_config->get_boolean('cdn.includes.enable')) {
696
+ $cdn_upload_buttons[] = $this->button_popup('wp-includes', 'cdn_export', 'cdn_export_type=includes');
697
+ }
698
+ if ($this->_config->get_boolean('cdn.theme.enable')) {
699
+ $cdn_upload_buttons[] = $this->button_popup('theme files', 'cdn_export', 'cdn_export_type=theme');
700
+ }
701
+ if ($this->_config->get_boolean('cdn.minify.enable')) {
702
+ $cdn_upload_buttons[] = $this->button_popup('minify files', 'cdn_export', 'cdn_export_type=minify');
703
+ }
704
+ if ($this->_config->get_boolean('cdn.custom.enable')) {
705
+ $cdn_upload_buttons[] = $this->button_popup('custom files', 'cdn_export', 'cdn_export_type=custom');
706
+ }
707
+
708
+ $notes[] = sprintf('Make sure to %s and upload your %s, files to the CDN to ensure proper operation. %s', $this->button_popup('export your media library', 'cdn_export_library'), implode(', ', $cdn_upload_buttons), $this->button_hide_note('Hide this message', 'cdn_upload'));
709
+ }
710
+ }
711
+
712
+ if ($this->_config->get_boolean('notes.plugins_updated')) {
713
+ $texts = array();
714
+
715
+ if ($this->_config->get_boolean('pgcache.enabled')) {
716
+ $texts[] = $this->button_link('empty the page cache', sprintf('options-general.php?page=%s&tab=%s&flush_pgcache', W3TC_FILE, $this->_tab));
717
+ }
718
+
719
+ if ($this->_config->get_boolean('minify.enabled')) {
720
+ $texts[] = sprintf('check your %s to maintain the desired user experience', $this->button_link('minify settings', sprintf('options-general.php?page=%s&tab=minify', W3TC_FILE)));
721
+ }
722
+
723
+ if (count($texts)) {
724
+ $notes[] = sprintf('One or more plugins have been activated or deactivated, please %s. %s', implode(' and ', $texts), $this->button_hide_note('Hide this message', 'plugins_updated'));
725
+ }
726
+ }
727
+
728
+ if ($this->_config->get_boolean('pgcache.enabled') && $this->_config->get('notes.need_empty_pgcache')) {
729
+ $notes[] = sprintf('The setting change(s) made either invalidate your cached data or modify the behavior of your site. %s now to provide a consistent user experience.', $this->button_link('Empty the page cache', sprintf('options-general.php?page=%s&tab=%s&flush_pgcache', W3TC_FILE, $this->_tab)));
730
+
731
+ }
732
+
733
+ if ($this->_config->get_boolean('minify.enabled') && $this->_config->get('notes.need_empty_minify')) {
734
+ $notes[] = sprintf('The setting change(s) made either invalidate your cached data or modify the behavior of your site. %s now to provide a consistent user experience.', $this->button_link('Empty the minify cache', sprintf('options-general.php?page=%s&tab=%s&flush_minify', W3TC_FILE, $this->_tab)));
735
+ }
736
+
737
+ /**
738
+ * Show messages
739
+ */
740
+ foreach ($errors as $error) {
741
+ echo sprintf('<div id="message" class="error"><p>%s</p></div>', $error);
742
+ }
743
+
744
+ foreach ($notes as $note) {
745
+ echo sprintf('<div id="message" class="updated fade"><p>%s</p></div>', $note);
746
+ }
747
+ }
748
+
749
+ /**
750
+ * Switch theme action
751
+ */
752
+ function switch_theme()
753
+ {
754
+ $this->_config->set('notes.theme_changed', true);
755
+ $this->_config->save();
756
+ }
757
+
758
+ /**
759
+ * WP Upgrade action hack
760
+ *
761
+ * @param string $message
762
+ */
763
+ function update_feedback($message)
764
+ {
765
+ if ($message == __('Upgrading database')) {
766
+ $this->_config->set('notes.wp_upgraded', true);
767
+ $this->_config->save();
768
+ }
769
+ }
770
+
771
+ /**
772
+ * Active plugins pre update option filter
773
+ */
774
+ function pre_update_option_active_plugins($new_value)
775
+ {
776
+ $old_value = (array) get_option('active_plugins');
777
+
778
+ if ($new_value !== $old_value && in_array(W3TC_FILE, (array) $new_value) && in_array(W3TC_FILE, (array) $old_value)) {
779
+ $this->_config->set('notes.plugins_updated', true);
780
+ $this->_config->save();
781
+ }
782
+
783
+ return $new_value;
784
+ }
785
+
786
+ /**
787
+ * Show plugin changes
788
+ */
789
+ function in_plugin_update_message()
790
+ {
791
+ $data = w3_url_get(W3TC_README_URL);
792
+
793
+ if ($data) {
794
+ $matches = null;
795
+ if (preg_match('~==\s*Changelog\s*==\s*=\s*[0-9.]+\s*=(.*)(=\s*[0-9.]+\s*=|$)~Uis', $data, $matches)) {
796
+ $changelog = (array) preg_split('~[\r\n]+~', trim($matches[1]));
797
+
798
+ echo '<div style="color: #f00;">Take a minute to update, here\'s why:</div><div style="font-weight: normal;">';
799
+ $ul = false;
800
+
801
+ foreach ($changelog as $index => $line) {
802
+ if (preg_match('~^\s*\*\s*~', $line)) {
803
+ if (! $ul) {
804
+ echo '<ul style="list-style: disc; margin-left: 20px;">';
805
+ $ul = true;
806
+ }
807
+ $line = preg_replace('~^\s*\*\s*~', '', htmlspecialchars($line));
808
+ echo '<li style="width: 50%; margin: 0; float: left; ' . ($index % 2 == 0 ? 'clear: left;' : '') . '">' . $line . '</li>';
809
+ } else {
810
+ if ($ul) {
811
+ echo '</ul><div style="clear: left;"></div>';
812
+ $ul = false;
813
+ }
814
+ echo '<p style="margin: 5px 0;">' . htmlspecialchars($line) . '</p>';
815
+ }
816
+ }
817
+
818
+ if ($ul) {
819
+ echo '</ul><div style="clear: left;"></div>';
820
+ }
821
+
822
+ echo '</div>';
823
+ }
824
+ }
825
+ }
826
+
827
+ /**
828
+ * Footer plugin action
829
+ */
830
+ function footer()
831
+ {
832
+ echo '<div style="text-align: center;">Performance Optimization <a href="http://www.w3-edge.com/wordpress-plugins/" rel="external">WordPress Plugins</a> by W3 EDGE</div>';
833
+ }
834
+
835
+ /**
836
+ * Options page
837
+ */
838
+ function options()
839
+ {
840
+ /**
841
+ * Check for Page Cache availability
842
+ */
843
+ if ($this->_config->get_boolean('pgcache.enabled')) {
844
+ if (! $this->check_advanced_cache()) {
845
+ $this->_errors[] = sprintf('Page caching is not available: advanced-cache.php is not installed. Either the <strong>%s</strong> directory is not write-able or you have another caching plugin installed. This error message will automatically disappear once the change is successfully made.', WP_CONTENT_DIR);
846
+ } elseif (! defined('WP_CACHE')) {
847
+ $this->_errors[] = sprintf('Page caching is not available: please add: <strong>define(\'WP_CACHE\', true);</strong> to <strong>%swp-config.php</strong>. This error message will automatically disappear once the change is successfully made.', ABSPATH);
848
+ } else {
849
+ switch ($this->_config->get_string('pgcache.engine')) {
850
+ case 'file_pgcache':
851
+ require_once W3TC_LIB_W3_DIR . '/Plugin/PgCache.php';
852
+ $w3_plugin_pgcache = & W3_Plugin_PgCache::instance();
853
+
854
+ if ($this->_config->get_boolean('notes.pgcache_rules_core') && ! $w3_plugin_pgcache->check_rules_core()) {
855
+ if (function_exists('is_site_admin')) {
856
+ $this->_errors[] = sprintf('Enhanced mode page cache is not operational. Your .htaccess rules could not be modified. Please verify <strong>%s.htaccess</strong> has the following rules: <pre>%s</pre> %s', ABSPATH, htmlspecialchars($w3_plugin_pgcache->generate_rules_core()), $this->button_hide_note('Hide this message', 'pgcache_rules_core'));
857
+ } else {
858
+ $this->_errors[] = sprintf('You\'ve selected disk caching with enhanced mode however the .htaccess file is not properly configured. Please run <strong>chmod 777 %s.htaccess</strong>, then %s. To manually modify your server configuration for enhanced mode append the following code: <pre>%s</pre> and %s.', ABSPATH, $this->button_link('try again', sprintf('options-general.php?page=%s&tab=%s&pgcache_write_rules_core', W3TC_FILE, $this->_tab)), htmlspecialchars($w3_plugin_pgcache->generate_rules_core()), $this->button_hide_note('hide this message', 'pgcache_rules_core'));
859
+ }
860
+ }
861
+
862
+ if ($this->_config->get_boolean('notes.pgcache_rules_cache') && ! $w3_plugin_pgcache->check_rules_cache()) {
863
+ if (function_exists('is_site_admin')) {
864
+ $this->_errors[] = sprintf('Enhanced mode page cache is not operational. Your .htaccess rules could not be modified. Please verify <strong>%s/.htaccess</strong> has the following rules: <pre>%s</pre> %s', W3TC_CACHE_FILE_PGCACHE_DIR, htmlspecialchars($w3_plugin_pgcache->generate_rules_cache()), $this->button_hide_note('Hide this message', 'pgcache_rules_cache'));
865
+ } else {
866
+ $this->_errors[] = sprintf('You\'ve selected disk caching with enhanced mode however the .htaccess file is not properly configured. Please run <strong>chmod 777 %s/.htaccess</strong>, then %s. To manually modify your server configuration for enhanced mode append the following code: <pre>%s</pre> and %s.', W3TC_CACHE_FILE_PGCACHE_DIR, $this->button_link('try again', sprintf('options-general.php?page=%s&tab=%s&pgcache_write_rules_cache', W3TC_FILE, $this->_tab)), htmlspecialchars($w3_plugin_pgcache->generate_rules_cache()), $this->button_hide_note('hide this message', 'pgcache_rules_cache'));
867
+ }
868
+ }
869
+ break;
870
+
871
+ case 'memcached':
872
+ $pgcache_memcached_servers = $this->_config->get_array('pgcache.memcached.servers');
873
+
874
+ if (! $this->is_memcache_available($pgcache_memcached_servers)) {
875
+ $this->_errors[] = sprintf('Page caching is not working properly. Memcached server(s): <strong>%s</strong> may not running or not responding. This error message will automatically disappear once the issue is resolved.', implode(', ', $pgcache_memcached_servers));
876
+ }
877
+ break;
878
+ }
879
+ }
880
+ }
881
+
882
+ /**
883
+ * Check for minify availability
884
+ */
885
+ if ($this->_config->get_boolean('minify.enabled')) {
886
+ switch ($this->_config->get_string('minify.engine')) {
887
+ case 'file':
888
+ if (W3TC_PHP5) {
889
+ require_once W3TC_LIB_W3_DIR . '/Plugin/Minify.php';
890
+ $w3_plugin_minify = & W3_Plugin_Minify::instance();
891
+
892
+ if ($this->_config->get_boolean('notes.minify_rules') && ! $w3_plugin_minify->check_rules()) {
893
+ if (function_exists('is_site_admin')) {
894
+ $this->_errors[] = sprintf('Minify is not operational. Your .htaccess rules could not be modified. Please verify <strong>%s/.htaccess</strong> has the following rules: <pre>%s</pre> %s', W3TC_CACHE_FILE_MINIFY_DIR, htmlspecialchars($w3_plugin_minify->generate_rules()), $this->button_hide_note('Hide this message', 'minify_rules'));
895
+ } else {
896
+ $this->_errors[] = sprintf('The "Rewrite URL Structure" feature, requires rewrite rules be present. Please run <strong>chmod 777 %s/.htaccess</strong>, then %s. To manually modify your server configuration for minify append the following code: <pre>%s</pre> and %s.', W3TC_CACHE_FILE_MINIFY_DIR, $this->button_link('try again', sprintf('options-general.php?page=%s&tab=%s&minify_write_rules', W3TC_FILE, $this->_tab)), htmlspecialchars($w3_plugin_minify->generate_rules()), $this->button_hide_note('hide this message', 'minify_rules'));
897
+ }
898
+ }
899
+ }
900
+ break;
901
+
902
+ case 'memcached':
903
+ $minify_memcached_servers = $this->_config->get_array('minify.memcached.servers');
904
+
905
+ if (! $this->is_memcache_available($minify_memcached_servers)) {
906
+ $this->_errors[] = sprintf('Minify is not working properly. Memcached server(s): <strong>%s</strong>may not running or not responding. This error message will automatically disappear once the issue is resolved.', implode(', ', $minify_memcached_servers));
907
+ }
908
+ break;
909
+ }
910
+ }
911
+
912
+ /**
913
+ * Check for DbCache availability
914
+ */
915
+ if ($this->_config->get_boolean('dbcache.enabled')) {
916
+ if (! $this->check_db()) {
917
+ $this->_errors[] = sprintf('Database caching is not available: db.php is not installed. Either the <strong>%s</strong> directory is not write-able or you have another caching plugin installed. This error message will automatically disappear once the change is successfully made.', WP_CONTENT_DIR);
918
+ } elseif ($this->_config->get_string('pgcache.engine') == 'memcached') {
919
+ $dbcache_memcached_servers = $this->_config->get_array('dbcache.memcached.servers');
920
+
921
+ if (! $this->is_memcache_available($dbcache_memcached_servers)) {
922
+ $this->_errors[] = sprintf('Database caching is not working properly. Memcached server(s): <strong>%s</strong> may not running or not responding. This error message will automatically disappear once the issue is successfully resolved.', implode(', ', $dbcache_memcached_servers));
923
+ }
924
+ }
925
+ }
926
+
927
+ /**
928
+ * Check PHP version
929
+ */
930
+ if (! W3TC_PHP5 && $this->_config->get_boolean('notes.php_is_old')) {
931
+ $this->_notes[] = sprintf('Unfortunately, <strong>PHP5</strong> is required for full functionality of this plugin; incompatible features are automatically disabled. Please upgrade if possible. %s', $this->button_hide_note('Hide this message', 'php_is_old'));
932
+ }
933
+
934
+ if ($this->_config->get_boolean('notes.no_curl') && $this->_config->get_boolean('cdn.enabled') && ! $this->check_curl()) {
935
+ $this->_notes[] = sprintf('The <strong>CURL PHP</strong> extension is not available. Please install it to enable S3 or CloudFront functionality. %s', $this->button_hide_note('Hide this message', 'no_curl'));
936
+ }
937
+
938
+ /**
939
+ * Show message when defaults are set
940
+ */
941
+ if ($this->_config->get_boolean('notes.defaults')) {
942
+ $this->_notes[] = sprintf('The plugin is in quick setup mode, most recommended defaults are set. Satisfy any warnings customizing any settings. %s', $this->button_hide_note('Hide this message', 'defaults'));
943
+ }
944
+
945
+ /**
946
+ * Check wp-content permissions
947
+ */
948
+ if (! W3TC_WIN && $this->_config->get_boolean('notes.wp_content_perms')) {
949
+ $wp_content_stat = stat(WP_CONTENT_DIR);
950
+ $wp_content_mode = ($wp_content_stat['mode'] & 0777);
951
+
952
+ if ($wp_content_mode != 0755) {
953
+ $this->_notes[] = sprintf('<strong>%s</strong> is write-able. If you\'ve finished installing the plugin, change the permissions back to the default: <strong>chmod 755 %s</strong>. %s', WP_CONTENT_DIR, WP_CONTENT_DIR, $this->button_hide_note('Hide this message', 'wp_content_perms'));
954
+ }
955
+ }
956
+
957
+ /**
958
+ * Check for memcached & APC
959
+ */
960
+ if ($this->_config->get_boolean('notes.no_memcached_nor_apc') && ! $this->check_memcache() && ! $this->check_apc()) {
961
+ $this->_notes[] = sprintf('<strong>Memcached</strong> nor an <strong>opcode cache (APC)</strong> appear to be installed correctly. %s', $this->button_hide_note('Hide this message', 'no_memcached_nor_apc'));
962
+ }
963
+
964
+ /**
965
+ * Show tab
966
+ */
967
+ switch ($this->_tab) {
968
+ case 'general':
969
+ $this->options_general();
970
+ break;
971
+
972
+ case 'pgcache':
973
+ $this->options_pgcache();
974
+ break;
975
+
976
+ case 'dbcache':
977
+ $this->options_dbcache();
978
+ break;
979
+
980
+ case 'minify':
981
+ $this->options_minify();
982
+ break;
983
+
984
+ case 'cdn':
985
+ $this->options_cdn();
986
+ break;
987
+
988
+ case 'faq':
989
+ $this->options_faq();
990
+ break;
991
+
992
+ case 'support':
993
+ $this->options_support();
994
+ break;
995
+
996
+ case 'install':
997
+ $this->options_install();
998
+ break;
999
+
1000
+ case 'about':
1001
+ $this->options_about();
1002
+ break;
1003
+ }
1004
+ }
1005
+
1006
+ /**
1007
+ * General tab
1008
+ */
1009
+ function options_general()
1010
+ {
1011
+ $pgcache_enabled = $this->_config->get_boolean('pgcache.enabled');
1012
+ $dbcache_enabled = $this->_config->get_boolean('dbcache.enabled');
1013
+ $minify_enabled = $this->_config->get_boolean('minify.enabled');
1014
+ $cdn_enabled = $this->_config->get_boolean('cdn.enabled');
1015
+
1016
+ $enabled = ($pgcache_enabled || $dbcache_enabled || $minify_enabled || $cdn_enabled);
1017
+
1018
+ $check_apc = $this->check_apc();
1019
+ $check_curl = $this->check_curl();
1020
+
1021
+ $pgcache_engine = $this->_config->get_string('pgcache.engine');
1022
+ $dbcache_engine = $this->_config->get_string('dbcache.engine');
1023
+ $minify_engine = $this->_config->get_string('minify.engine');
1024
+
1025
+ $can_empty_memcache = ($pgcache_engine == 'memcached' || $dbcache_engine == 'memcached' || $minify_engine == 'memcached');
1026
+ $can_empty_apc = $check_apc && ($pgcache_engine == 'apc' || $dbcache_engine == 'apc' || $minify_engine == 'apc');
1027
+ $can_empty_file = ($pgcache_engine == 'file' || $pgcache_engine == 'file_pgcache' || $dbcache_engine == 'file' || $minify_engine == 'file');
1028
+
1029
+ $memcache_engine = class_exists('Memcache') ? ' (via Memcache)' : '';
1030
+
1031
+ $debug = ($this->_config->get_boolean('dbcache.debug') || $this->_config->get_boolean('pgcache.debug') || $this->_config->get_boolean('minify.debug') || $this->_config->get_boolean('cdn.debug'));
1032
+
1033
+ $support = $this->_config->get_string('common.support');
1034
+ $supports = $this->get_supports();
1035
+
1036
+ include W3TC_DIR . '/inc/options/general.phtml';
1037
+ }
1038
+
1039
+ /**
1040
+ * Page cache tab
1041
+ */
1042
+ function options_pgcache()
1043
+ {
1044
+ $pgcache_enabled = $this->_config->get_boolean('pgcache.enabled');
1045
+ $pgcache_gzip = function_exists('gzencode');
1046
+ $pgcache_deflate = function_exists('gzdeflate');
1047
+
1048
+ include W3TC_DIR . '/inc/options/pgcache.phtml';
1049
+ }
1050
+
1051
+ /**
1052
+ * Minify tab
1053
+ */
1054
+ function options_minify()
1055
+ {
1056
+ $minify_enabled = $this->_config->get_boolean('minify.enabled');
1057
+
1058
+ $groups = $this->minify_get_groups();
1059
+
1060
+ $js_groups = $this->_config->get_array('minify.js.groups');
1061
+ $css_groups = $this->_config->get_array('minify.css.groups');
1062
+
1063
+ include W3TC_DIR . '/inc/options/minify.phtml';
1064
+ }
1065
+
1066
+ /**
1067
+ * Database cache tab
1068
+ */
1069
+ function options_dbcache()
1070
+ {
1071
+ $dbcache_enabled = $this->_config->get_boolean('dbcache.enabled');
1072
+
1073
+ include W3TC_DIR . '/inc/options/dbcache.phtml';
1074
+ }
1075
+
1076
+ /**
1077
+ * CDN tab
1078
+ */
1079
+ function options_cdn()
1080
+ {
1081
+ $cdn_enabled = $this->_config->get_boolean('cdn.enabled');
1082
+ $cdn_engine = $this->_config->get_string('cdn.engine');
1083
+ $cdn_mirror = ($cdn_engine == 'mirror');
1084
+
1085
+ if ($this->_config->get_boolean('notes.cdn_first_time')) {
1086
+ $this->_notes[] = sprintf('It appears this is the first time you are using CDN feature. Unless you wish to first import attachments in your posts that are not already in the media library, please start a <strong>"manual export to <acronym title="Content Delivery Network">CDN</acronym>"</strong> and only enable this module after pending attachments have been successfully uploaded. %s', $this->button_hide_note('Hide this message', 'cdn_first_time'));
1087
+ }
1088
+
1089
+ if ($cdn_enabled) {
1090
+ switch (true) {
1091
+ case ($cdn_engine == 'mirror' && $this->_config->get_string('cdn.mirror.domain') == ''):
1092
+ $this->_errors[] = 'The <strong>"Replace default hostname with"</strong> field must be populated.';
1093
+ break;
1094
+
1095
+ case ($cdn_engine == 'ftp' && $this->_config->get_string('cdn.ftp.domain') == ''):
1096
+ $this->_errors[] = 'The <strong>"Replace default hostname with"</strong> field must be populated. Enter the hostname of your <acronym title="Content Delivery Network">CDN</acronym> provider. <em>This is the hostname you would enter into your address bar in order to view objects in your browser.</em>';
1097
+ break;
1098
+
1099
+ case ($cdn_engine == 's3' && ($this->_config->get_string('cdn.s3.key') == '' || $this->_config->get_string('cdn.s3.bucket') == '' || $this->_config->get_string('cdn.s3.bucket') == '')):
1100
+ $this->_errors[] = 'The <strong>"Access key", "Secret key" and "Bucket"</strong> fields must be populated.';
1101
+ break;
1102
+
1103
+ case ($cdn_engine == 'cf' && ($this->_config->get_string('cdn.cf.key') == '' || $this->_config->get_string('cdn.cf.secret') == '' || $this->_config->get_string('cdn.cf.bucket') == '' || ($this->_config->get_string('cdn.cf.id') == '' && $this->_config->get_string('cdn.cf.cname') == ''))):
1104
+ $this->_errors[] = 'The <strong>"Access key", "Secret key", "Bucket" and "Replace default hostname with"</strong> fields must be populated.';
1105
+ break;
1106
+ }
1107
+ }
1108
+
1109
+ include W3TC_DIR . '/inc/options/cdn.phtml';
1110
+ }
1111
+
1112
+ /**
1113
+ * FAQ tab
1114
+ */
1115
+ function options_faq()
1116
+ {
1117
+ include W3TC_DIR . '/inc/options/faq.phtml';
1118
+ }
1119
+
1120
+ /**
1121
+ * Support tab
1122
+ */
1123
+ function options_support()
1124
+ {
1125
+ $theme = get_theme(get_current_theme());
1126
+ $template_files = (isset($theme['Template Files']) ? (array) $theme['Template Files'] : array());
1127
+
1128
+ $request_types = array(
1129
+ 'Bug Submission',
1130
+ 'Plugin (add-on) Request'
1131
+ );
1132
+
1133
+ require_once W3TC_LIB_W3_DIR . '/Request.php';
1134
+
1135
+ $user = get_user_by('login', 'admin');
1136
+
1137
+ $url = W3_Request::get_string('url', w3_get_domain_url());
1138
+ $name = W3_Request::get_string('name', ($user ? $user->display_name : ''));
1139
+ $email = W3_Request::get_string('email', ($user ? $user->user_email : ''));
1140
+ $request_type = W3_Request::get_string('request_type');
1141
+ $description = W3_Request::get_string('description');
1142
+ $templates = W3_Request::get_array('templates');
1143
+ $wp_login = W3_Request::get_string('wp_login');
1144
+ $wp_password = W3_Request::get_string('wp_password');
1145
+ $ftp_host = W3_Request::get_string('ftp_host');
1146
+ $ftp_login = W3_Request::get_string('ftp_login');
1147
+ $ftp_password = W3_Request::get_string('ftp_password');
1148
+
1149
+ include W3TC_DIR . '/inc/options/support.phtml';
1150
+ }
1151
+
1152
+ /**
1153
+ * Install tab
1154
+ */
1155
+ function options_install()
1156
+ {
1157
+ include W3TC_DIR . '/inc/options/install.phtml';
1158
+ }
1159
+
1160
+ /**
1161
+ * About tab
1162
+ */
1163
+ function options_about()
1164
+ {
1165
+ include W3TC_DIR . '/inc/options/about.phtml';
1166
+ }
1167
+
1168
+ /**
1169
+ * Options save action
1170
+ */
1171
+ function options_save()
1172
+ {
1173
+ require_once W3TC_LIB_W3_DIR . '/Request.php';
1174
+
1175
+ /**
1176
+ * Read config
1177
+ */
1178
+ $config = & new W3_Config();
1179
+ $config->read_request();
1180
+
1181
+ /**
1182
+ * General tab
1183
+ */
1184
+ if ($this->_tab == 'general') {
1185
+ $debug = W3_Request::get_boolean('debug');
1186
+
1187
+ $config->set('dbcache.debug', $debug);
1188
+ $config->set('pgcache.debug', $debug);
1189
+ $config->set('minify.debug', $debug);
1190
+ $config->set('cdn.debug', $debug);
1191
+
1192
+ /**
1193
+ * Page cache tab
1194
+ */
1195
+ if ($config->get_boolean('pgcache.enabled') && $config->get_string('pgcache.engine') == 'file_pgcache' && get_option('permalink_structure') == '') {
1196
+ $this->redirect(array(
1197
+ 'error' => 'fancy_permalinks_disabled'
1198
+ ));
1199
+ }
1200
+
1201
+ /**
1202
+ * Show notification when CDN enabled
1203
+ */
1204
+ if ($this->_config->get_boolean('cdn.enabled') == false && $config->get_boolean('cdn.enabled') == true && $config->get_string('cdn.engine') != 'mirror') {
1205
+ $config->set('notes.cdn_upload', true);
1206
+ }
1207
+ }
1208
+
1209
+ /**
1210
+ * Minify tab
1211
+ */
1212
+
1213
+ if ($this->_tab == 'minify') {
1214
+ $groups = $this->minify_get_groups();
1215
+ $js_files = W3_Request::get_array('js_files');
1216
+ $css_files = W3_Request::get_array('css_files');
1217
+
1218
+ $js_groups = array();
1219
+ $css_groups = array();
1220
+
1221
+ foreach ($js_files as $group => $locations) {
1222
+ if (! array_key_exists($group, $groups)) {
1223
+ continue;
1224
+ }
1225
+
1226
+ foreach ((array) $locations as $location => $files) {
1227
+ switch ($location) {
1228
+ case 'include':
1229
+ $js_groups[$group][$location]['blocking'] = true;
1230
+ break;
1231
+ case 'include-nb':
1232
+ $js_groups[$group][$location]['blocking'] = false;
1233
+ break;
1234
+ case 'include-footer':
1235
+ $js_groups[$group][$location]['blocking'] = true;
1236
+ break;
1237
+ case 'include-footer-nb':
1238
+ $js_groups[$group][$location]['blocking'] = false;
1239
+ break;
1240
+ }
1241
+ foreach ((array) $files as $file) {
1242
+ if (! empty($file)) {
1243
+ $js_groups[$group][$location]['files'][] = ltrim($file, '/\\');
1244
+ }
1245
+ }
1246
+ }
1247
+ }
1248
+
1249
+ foreach ($css_files as $group => $locations) {
1250
+ if (! array_key_exists($group, $groups)) {
1251
+ continue;
1252
+ }
1253
+
1254
+ foreach ((array) $locations as $location => $files) {
1255
+ foreach ((array) $files as $file) {
1256
+ if (! empty($file)) {
1257
+ $css_groups[$group][$location]['files'][] = ltrim($file, '/\\');
1258
+ }
1259
+ }
1260
+ }
1261
+ }
1262
+
1263
+ $config->set('minify.js.groups', $js_groups);
1264
+ $config->set('minify.css.groups', $css_groups);
1265
+ }
1266
+
1267
+ /**
1268
+ * Handle settings change that require pgcache and minify empty
1269
+ */
1270
+ $pgcache_dependencies = array(
1271
+ 'dbcache.debug',
1272
+ 'pgcache.debug',
1273
+ 'pgcache.compression',
1274
+ 'minify.enabled',
1275
+ 'minify.debug',
1276
+ 'minify.rewrite',
1277
+ 'minify.options',
1278
+ 'minify.html.enable',
1279
+ 'minify.html.reject.admin',
1280
+ 'minify.html.inline.css',
1281
+ 'minify.html.inline.js',
1282
+ 'minify.html.strip.crlf',
1283
+ 'minify.css.enable',
1284
+ 'minify.css.groups',
1285
+ 'minify.js.enable',
1286
+ 'minify.js.groups',
1287
+ 'cdn.enabled',
1288
+ 'cdn.debug',
1289
+ 'cdn.engine',
1290
+ 'cdn.includes.enable',
1291
+ 'cdn.includes.files',
1292
+ 'cdn.theme.enable',
1293
+ 'cdn.theme.files',
1294
+ 'cdn.minify.enable',
1295
+ 'cdn.custom.enable',
1296
+ 'cdn.custom.files',
1297
+ 'cdn.ftp.domain',
1298
+ 'cdn.s3.bucket',
1299
+ 'cdn.cf.id',
1300
+ 'cdn.cf.cname',
1301
+ 'common.support'
1302
+ );
1303
+
1304
+ $minify_dependencies = array(
1305
+ 'minify.debug',
1306
+ 'minify.css.strip.comments',
1307
+ 'minify.css.strip.crlf',
1308
+ 'minify.css.groups',
1309
+ 'minify.js.combine.header',
1310
+ 'minify.js.combine.footer',
1311
+ 'minify.js.strip.comments',
1312
+ 'minify.js.strip.crlf',
1313
+ 'minify.js.groups'
1314
+ );
1315
+
1316
+ $old_pgcache_dependencies_values = array();
1317
+ $new_pgcache_dependencies_values = array();
1318
+
1319
+ $old_minify_dependencies_values = array();
1320
+ $new_minify_dependencies_values = array();
1321
+
1322
+ foreach ($pgcache_dependencies as $pgcache_dependency) {
1323
+ $old_pgcache_dependencies_values[] = $this->_config->get($pgcache_dependency);
1324
+ $new_pgcache_dependencies_values[] = $config->get($pgcache_dependency);
1325
+ }
1326
+
1327
+ foreach ($minify_dependencies as $minify_dependency) {
1328
+ $old_minify_dependencies_values[] = $this->_config->get($minify_dependency);
1329
+ $new_minify_dependencies_values[] = $config->get($minify_dependency);
1330
+ }
1331
+
1332
+ if ($this->_config->get_boolean('pgcache.enabled') && serialize($old_pgcache_dependencies_values) != serialize($new_pgcache_dependencies_values)) {
1333
+ $config->set('notes.need_empty_pgcache', true);
1334
+ }
1335
+
1336
+ if ($this->_config->get_boolean('minify.enabled') && serialize($old_minify_dependencies_values) != serialize($new_minify_dependencies_values)) {
1337
+ $config->set('notes.need_empty_minify', true);
1338
+ }
1339
+
1340
+ /**
1341
+ * Save config
1342
+ */
1343
+ if ($config->save()) {
1344
+ require_once W3TC_LIB_W3_DIR . '/Plugin/PgCache.php';
1345
+ require_once W3TC_LIB_W3_DIR . '/Plugin/DbCache.php';
1346
+ require_once W3TC_LIB_W3_DIR . '/Plugin/Cdn.php';
1347
+
1348
+ $w3_plugin_pgcache = & W3_Plugin_PgCache::instance();
1349
+ $w3_plugin_dbcache = & W3_Plugin_DbCache::instance();
1350
+ $w3_plugin_cdn = & W3_Plugin_Cdn::instance();
1351
+
1352
+ if (W3TC_PHP5) {
1353
+ require_once W3TC_LIB_W3_DIR . '/Plugin/Minify.php';
1354
+ $w3_plugin_minify = & W3_Plugin_Minify::instance();
1355
  }
1356
+
1357
+ /**
1358
+ * Empty caches on engine change or cache enable/disable
1359
+ */
1360
+ if ($this->_config->get_string('pgcache.engine') != $config->get_string('pgcache.engine') || $this->_config->get_string('pgcache.enabled') != $config->get_string('pgcache.enabled')) {
1361
+ $this->flush_pgcache();
1362
+ }
1363
+
1364
+ if ($this->_config->get_string('dbcache.engine') != $config->get_string('dbcache.engine') || $this->_config->get_string('dbcache.enabled') != $config->get_string('dbcache.enabled')) {
1365
+ $this->flush_dbcache();
1366
+ }
1367
+
1368
+ if ($this->_config->get_string('minify.engine') != $config->get_string('minify.engine') || $this->_config->get_string('minify.enabled') != $config->get_string('minify.enabled')) {
1369
+ $this->flush_minify();
1370
+ }
1371
+
1372
+ /**
1373
+ * Unschedule events if changed file gc interval
1374
+ */
1375
+ if ($this->_config->get_boolean('pgcache.file.gc') != $config->get_boolean('pgcache.file.gc')) {
1376
+ $w3_plugin_pgcache->unschedule();
1377
+ }
1378
+
1379
+ if ($this->_config->get_boolean('dbcache.file.gc') != $config->get_boolean('dbcache.file.gc')) {
1380
+ $w3_plugin_dbcache->unschedule();
1381
+ }
1382
+
1383
+ if (W3TC_PHP5 && $this->_config->get_boolean('minify.file.gc') != $config->get_boolean('minify.file.gc')) {
1384
+ $w3_plugin_minify->unschedule();
1385
+ }
1386
+
1387
+ $this->_config->load();
1388
+
1389
+ /**
1390
+ * Schedule events
1391
+ */
1392
+ $w3_plugin_pgcache->schedule();
1393
+ $w3_plugin_dbcache->schedule();
1394
+ $w3_plugin_cdn->schedule();
1395
+
1396
+ if (W3TC_PHP5) {
1397
+ $w3_plugin_minify->schedule();
1398
+ }
1399
+
1400
+ /**
1401
+ * Update support us option
1402
+ */
1403
+ $this->link_update();
1404
+
1405
+ /**
1406
+ * Auto upload minify files to CDN
1407
+ */
1408
+ if ($this->_tab == 'minify' && $this->_config->get_boolean('minify.upload') && $this->_config->get_boolean('cdn.enabled') && $this->_config->get_string('cdn.engine') != 'mirror') {
1409
+ $this->cdn_upload_minify();
1410
+ }
1411
+
1412
+ /**
1413
+ * Only for WP not WPMU
1414
+ */
1415
+ if (! function_exists('is_site_admin')) {
1416
+ /**
1417
+ * Write page cache rewrite rules
1418
+ */
1419
+ if ($this->_tab == 'general' || $this->_tab == 'pgcache') {
1420
+ if ($this->_config->get_boolean('pgcache.enabled') && $this->_config->get_string('pgcache.engine') == 'file_pgcache') {
1421
+ $w3_plugin_pgcache->write_rules_core();
1422
+ $w3_plugin_pgcache->write_rules_cache();
1423
+ } else {
1424
+ $w3_plugin_pgcache->remove_rules_core();
1425
+ $w3_plugin_pgcache->remove_rules_cache();
1426
+ }
1427
+ }
1428
+
1429
+ /**
1430
+ * Write minify rewrite rules
1431
+ */
1432
+ if (W3TC_PHP5 && ($this->_tab == 'general' || $this->_tab == 'minify')) {
1433
+ if ($this->_config->get_boolean('minify.enabled') && $this->_config->get_boolean('minify.rewrite')) {
1434
+ $w3_plugin_minify->write_rules();
1435
+ } else {
1436
+ require_once W3TC_DIR . '/lib/W3/Plugin/Minify.php';
1437
+ $w3_plugin_minify->remove_rules();
1438
+ }
1439
+ }
1440
+ }
1441
+
1442
+ $this->redirect(array(
1443
+ 'note' => 'config_save'
1444
+ ));
1445
+ } else {
1446
+ $this->redirect(array(
1447
+ 'error' => 'config_save'
1448
+ ));
1449
+ }
1450
+ }
1451
+
1452
+ /**
1453
+ * Send support request
1454
+ */
1455
+ function support_request()
1456
+ {
1457
+ require_once W3TC_LIB_W3_DIR . '/Request.php';
1458
+
1459
+ $url = W3_Request::get_string('url');
1460
+ $name = W3_Request::get_string('name');
1461
+ $email = W3_Request::get_string('email');
1462
+ $request_type = W3_Request::get_string('request_type');
1463
+ $description = W3_Request::get_string('description');
1464
+ $templates = W3_Request::get_array('templates');
1465
+ $attachments = array();
1466
+ $wp_login = W3_Request::get_string('wp_login');
1467
+ $wp_password = W3_Request::get_string('wp_password');
1468
+ $ftp_host = W3_Request::get_string('ftp_host');
1469
+ $ftp_login = W3_Request::get_string('ftp_login');
1470
+ $ftp_password = W3_Request::get_string('ftp_password');
1471
+
1472
+ $params = array(
1473
+ 'url' => $url,
1474
+ 'name' => $name,
1475
+ 'email' => $email,
1476
+ 'request_type' => $request_type,
1477
+ 'description' => $description,
1478
+ 'wp_login' => $wp_login,
1479
+ 'wp_password' => $wp_password,
1480
+ 'ftp_host' => $ftp_host,
1481
+ 'ftp_login' => $ftp_login,
1482
+ 'ftp_password' => $ftp_password
1483
+ );
1484
+
1485
+ foreach ($templates as $template_index => $template) {
1486
+ $template_key = sprintf('templates[%d]', $template_index);
1487
+ $params[$template_key] = $template;
1488
+ }
1489
+
1490
+ if ($url == '') {
1491
+ $this->redirect(array_merge($params, array(
1492
+ 'error' => 'support_request_url'
1493
+ )));
1494
+ }
1495
+
1496
+ if ($name == '') {
1497
+ $this->redirect(array_merge($params, array(
1498
+ 'error' => 'support_request_name'
1499
+ )));
1500
+ }
1501
+
1502
+ if (! preg_match('~^[a-z0-9_\-\.]+@[a-z0-9-\.]+\.[a-z]{2,5}$~', $email)) {
1503
+ $this->redirect(array_merge($params, array(
1504
+ 'error' => 'support_request_email'
1505
+ )));
1506
+ }
1507
+
1508
+ if ($request_type == '') {
1509
+ $this->redirect(array_merge($params, array(
1510
+ 'error' => 'support_request_type'
1511
+ )));
1512
+ }
1513
+
1514
+ if ($description == '') {
1515
+ $this->redirect(array_merge($params, array(
1516
+ 'error' => 'support_request_description'
1517
+ )));
1518
+ }
1519
+
1520
+ if ($wp_login != '' || $wp_password != '') {
1521
+ if ($wp_login == '') {
1522
+ $this->redirect(array_merge($params, array(
1523
+ 'error' => 'support_request_wp_login'
1524
+ )));
1525
+ }
1526
+
1527
+ if ($wp_password == '') {
1528
+ $this->redirect(array_merge($params, array(
1529
+ 'error' => 'support_request_wp_password'
1530
+ )));
1531
+ }
1532
+ }
1533
+
1534
+ if ($ftp_host != '' || $ftp_login != '' || $ftp_password != '') {
1535
+ if ($ftp_host == '') {
1536
+ $this->redirect(array_merge($params, array(
1537
+ 'error' => 'support_request_ftp_host'
1538
+ )));
1539
+ }
1540
+
1541
+ if ($ftp_login == '') {
1542
+ $this->redirect(array_merge($params, array(
1543
+ 'error' => 'support_request_ftp_login'
1544
+ )));
1545
+ }
1546
+
1547
+ if ($ftp_password == '') {
1548
+ $this->redirect(array_merge($params, array(
1549
+ 'error' => 'support_request_ftp_password'
1550
+ )));
1551
+ }
1552
+ }
1553
+
1554
+ /**
1555
+ * Add attachments
1556
+ */
1557
+ foreach ($templates as $template) {
1558
+ if (! empty($template)) {
1559
+ $attachments[] = WP_CONTENT_DIR . $template;
1560
+ }
1561
+ }
1562
+
1563
+ if (! empty($_FILES['files'])) {
1564
+ $files = (array) $_FILES['files'];
1565
+ for ($i = 0, $l = count($files); $i < $l; $i++) {
1566
+ if (isset($files['tmp_name'][$i]) && isset($files['name'][$i]) && isset($files['error'][$i]) && $files['error'][$i] == UPLOAD_ERR_OK) {
1567
+ $path = W3TC_TMP_DIR . '/' . $files['name'][$i];
1568
+ if (@move_uploaded_file($files['tmp_name'][$i], $path)) {
1569
+ $attachments[] = $path;
1570
+ }
1571
+ }
1572
+ }
1573
+ }
1574
+
1575
+ /**
1576
+ * Attach server info
1577
+ */
1578
+ $server_info = print_r($this->get_server_info(), true);
1579
+ $server_info = str_replace("\n", "\r\n", $server_info);
1580
+ $path = W3TC_TMP_DIR . '/server_info.txt';
1581
+
1582
+ if (($fp = @fopen($path, 'w'))) {
1583
+ @fputs($fp, $server_info);
1584
+ @fclose($fp);
1585
+
1586
+ $attachments[] = $path;
1587
+ }
1588
+
1589
+ /**
1590
+ * Attach minify log
1591
+ */
1592
+ if (file_exists(W3TC_MINIFY_LOG_FILE)) {
1593
+ $attachments[] = W3TC_MINIFY_LOG_FILE;
1594
+ }
1595
+
1596
+ $data = array();
1597
+
1598
+ if (! empty($wp_login) && ! empty($wp_password)) {
1599
+ $data['WP Admin login'] = $wp_login;
1600
+ $data['WP Admin password'] = $wp_password;
1601
+ }
1602
+
1603
+ if (! empty($ftp_host) && ! empty($ftp_login) && ! empty($ftp_password)) {
1604
+ $data['SSH / FTP host'] = $ftp_host;
1605
+ $data['SSH / FTP login'] = $ftp_login;
1606
+ $data['SSH / FTP password'] = $ftp_password;
1607
+ }
1608
+
1609
+ /**
1610
+ * Store request data for future access
1611
+ */
1612
+ if (count($data)) {
1613
+ $hash = md5(microtime());
1614
+ $request_data = get_option('w3tc_request_data', array());
1615
+ $request_data[$hash] = $data;
1616
+
1617
+ update_option('w3tc_request_data', $request_data);
1618
+
1619
+ $request_data_url = sprintf('%sw3tc_request_data/%s', w3_get_site_url(), $hash);
1620
+ } else {
1621
+ $request_data_url = null;
1622
+ }
1623
+
1624
+ /**
1625
+ * Get body contents
1626
+ */
1627
+ ob_start();
1628
+ include W3TC_DIR . '/inc/options/support_email.phtml';
1629
+ $body = ob_get_contents();
1630
+ ob_end_clean();
1631
+
1632
+ /**
1633
+ * Send email
1634
+ */
1635
+ $subject = sprintf('W3TC Support Request: %s', $request_type);
1636
+
1637
+ $headers = array(
1638
+ sprintf('From: "%s" <%s>', addslashes($name), $email),
1639
+ sprintf('Reply-To: "%s" <%s>', addslashes($name), $email),
1640
+ 'Content-Type: text/html; charset=UTF-8'
1641
+ );
1642
+
1643
+ $this->_phpmailer_sender = $email;
1644
+
1645
+ add_action('phpmailer_init', array(
1646
+ &$this,
1647
+ 'phpmailer_init'
1648
+ ));
1649
+
1650
+ $result = @wp_mail(W3TC_EMAIL, $subject, $body, implode("\n", $headers), $attachments);
1651
+
1652
+ /**
1653
+ * Remove temporary files
1654
+ */
1655
+ foreach ($attachments as $attachment) {
1656
+ if (strstr($attachment, W3TC_TMP_DIR) !== false) {
1657
+ @unlink($attachment);
1658
+ }
1659
+ }
1660
+
1661
+ if ($result) {
1662
+ $this->redirect(array(
1663
+ 'note' => 'support_request'
1664
+ ));
1665
+ } else {
1666
+ $this->redirect(array_merge($params, array(
1667
+ 'error' => 'support_request'
1668
+ )));
1669
  }
1670
+ }
1671
+
1672
+ /**
1673
+ * PHPMailer init function
1674
+ *
1675
+ * @param PHPMailer $phpmailer
1676
+ * @return void
1677
+ */
1678
+ function phpmailer_init(&$phpmailer)
1679
+ {
1680
+ $phpmailer->Sender = $this->_phpmailer_sender;
1681
+ }
1682
+
1683
+ /**
1684
+ * Returns button html
1685
+ *
1686
+ * @param string $text
1687
+ * @param string $onclick
1688
+ * @return string
1689
+ */
1690
+ function button($text, $onclick = '')
1691
+ {
1692
+ return sprintf('<input type="button" class="button" value="%s" onclick="%s" />', htmlspecialchars($text), htmlspecialchars($onclick));
1693
+ }
1694
+
1695
+ /**
1696
+ * Returns button link html
1697
+ *
1698
+ * @param string $text
1699
+ * @param string $url
1700
+ * @return string
1701
+ */
1702
+ function button_link($text, $url)
1703
+ {
1704
+ $onclick = sprintf('document.location.href = \'%s\';', addslashes($url));
1705
 
1706
+ return $this->button($text, $onclick);
1707
+ }
1708
+
1709
+ /**
1710
+ * Returns hide note button html
1711
+ *
1712
+ * @param string $text
1713
+ * @param string $note
1714
+ * @return string
1715
+ */
1716
+ function button_hide_note($text, $note)
1717
+ {
1718
+ $url = sprintf('options-general.php?page=%s&tab=%s&hide_note=%s', W3TC_FILE, $this->_tab, $note);
1719
 
1720
+ return $this->button_link($text, $url);
1721
+ }
1722
+
1723
+ /**
1724
+ * Returns popup button html
1725
+ *
1726
+ * @param string $text
1727
+ * @param string $w3tc_action
1728
+ * @param string $params
1729
+ * @param integer $width
1730
+ * @param integer $height
1731
+ * @return string
1732
+ */
1733
+ function button_popup($text, $w3tc_action, $params = '', $width = 800, $height = 600)
1734
+ {
1735
+ $onclick = sprintf('window.open(\'options-general.php?page=%s&w3tc_action=%s%s\', \'%s\', \'width=%d,height=%d,status=no,toolbar=no,menubar=no,scrollbars=yes\');', W3TC_FILE, $w3tc_action, ($params != '' ? '&' . $params : ''), $w3tc_action, $width, $height);
1736
+
1737
+ return $this->button($text, $onclick);
1738
  }
1739
 
1740
  /**
1765
  $cdn_queue_id = W3_Request::get_integer('cdn_queue_id');
1766
  if (! empty($cdn_queue_id)) {
1767
  $w3_plugin_cdn->queue_delete($cdn_queue_id);
1768
+ $notes[] = 'File successfully deleted from the queue.';
1769
  }
1770
  break;
1771
 
1773
  $cdn_queue_type = W3_Request::get_integer('cdn_queue_type');
1774
  if (! empty($cdn_queue_type)) {
1775
  $w3_plugin_cdn->queue_empty($cdn_queue_type);
1776
+ $notes[] = 'Queue successfully emptied.';
1777
  }
1778
  break;
1779
  }
1780
 
1781
  $queue = $w3_plugin_cdn->queue_get();
1782
+ $title = 'Unsuccessfull transfers queue.';
1783
 
 
1784
  include W3TC_DIR . '/inc/popup/cdn_queue.phtml';
 
1785
  }
1786
 
1787
  /**
1796
  $total = $w3_plugin_cdn->get_attachments_count();
1797
  $title = 'Media library export';
1798
 
 
1799
  include W3TC_DIR . '/inc/popup/cdn_export_library.phtml';
 
1800
  }
1801
 
1802
  /**
1842
  require_once W3TC_LIB_W3_DIR . '/Plugin/Cdn.php';
1843
 
1844
  $w3_plugin_cdn = & W3_Plugin_Cdn::instance();
1845
+ $cdn = & $w3_plugin_cdn->get_cdn();
1846
 
1847
  $total = $w3_plugin_cdn->get_import_posts_count();
1848
+ $cdn_host = $cdn->get_domain();
1849
 
1850
  $title = 'Media library import';
1851
 
 
1852
  include W3TC_DIR . '/inc/popup/cdn_import_library.phtml';
 
1853
  }
1854
 
1855
  /**
1900
 
1901
  $title = 'Domain rename tool';
1902
 
 
1903
  include W3TC_DIR . '/inc/popup/cdn_rename_domain.phtml';
 
1904
  }
1905
 
1906
  /**
1974
  break;
1975
  }
1976
 
 
1977
  include W3TC_DIR . '/inc/popup/cdn_export_file.phtml';
 
1978
  }
1979
 
1980
  /**
1997
  $upload[$file] = $file;
1998
  }
1999
 
2000
+ $w3_plugin_cdn->upload($upload, false, $results);
2001
 
2002
  echo "{results: [\r\n";
2003
 
2020
  {
2021
  require_once W3TC_LIB_W3_DIR . '/Plugin/Cdn.php';
2022
 
2023
+ $w3_plugin_cdn = & W3_Plugin_Cdn::instance();
2024
  $files = $w3_plugin_cdn->get_files_minify();
2025
  $upload = array();
2026
+ $results = array();
2027
 
2028
  foreach ($files as $file) {
2029
  $upload[$file] = $file;
2030
  }
2031
 
2032
+ return $w3_plugin_cdn->upload($upload, false, $results);
2033
  }
2034
 
2035
  /**
2067
  echo sprintf('{result: %d, error: "%s"}', $result, addslashes($error));
2068
  }
2069
 
2070
+ /**
2071
+ * CDN Test S3
2072
+ */
2073
+ function cdn_test_s3()
2074
+ {
2075
+ require_once W3TC_LIB_W3_DIR . '/Request.php';
2076
+ require_once W3TC_LIB_W3_DIR . '/Cdn.php';
2077
+
2078
+ $key = W3_Request::get_string('key');
2079
+ $secret = W3_Request::get_string('secret');
2080
+ $bucket = W3_Request::get_string('bucket');
2081
+
2082
+ $w3_cdn_s3 = & W3_Cdn::instance('s3', array(
2083
+ 'key' => $key,
2084
+ 'secret' => $secret,
2085
+ 'bucket' => $bucket
2086
+ ));
2087
+
2088
+ $error = null;
2089
+
2090
+ if ($w3_cdn_s3->test($error)) {
2091
+ $result = true;
2092
+ $error = 'Test passed';
2093
+ } else {
2094
+ $result = false;
2095
+ $error = sprintf('Test failed. Error: %s', $error);
2096
+ }
2097
+
2098
+ echo sprintf('{result: %d, error: "%s"}', $result, addslashes($error));
2099
+ }
2100
+
2101
+ /**
2102
+ * CDN Test CloudFront
2103
+ */
2104
+ function cdn_test_cf()
2105
+ {
2106
+ require_once W3TC_LIB_W3_DIR . '/Request.php';
2107
+ require_once W3TC_LIB_W3_DIR . '/Cdn.php';
2108
+
2109
+ $key = W3_Request::get_string('key');
2110
+ $secret = W3_Request::get_string('secret');
2111
+ $bucket = W3_Request::get_string('bucket');
2112
+ $id = W3_Request::get_string('id');
2113
+ $cname = W3_Request::get_string('cname');
2114
+
2115
+ $w3_cdn_s3 = & W3_Cdn::instance('cf', array(
2116
+ 'key' => $key,
2117
+ 'secret' => $secret,
2118
+ 'bucket' => $bucket,
2119
+ 'id' => $id,
2120
+ 'cname' => $cname
2121
+ ));
2122
+
2123
+ $error = null;
2124
+
2125
+ if ($w3_cdn_s3->test($error)) {
2126
+ $result = true;
2127
+ $error = 'Test passed';
2128
+ } else {
2129
+ $result = false;
2130
+ $error = sprintf('Test failed. Error: %s', $error);
2131
+ }
2132
+
2133
+ echo sprintf('{result: %d, error: "%s"}', $result, addslashes($error));
2134
+ }
2135
+
2136
+ /**
2137
+ * Create bucket action
2138
+ */
2139
+ function cdn_create_bucket()
2140
+ {
2141
+ require_once W3TC_LIB_W3_DIR . '/Request.php';
2142
+ require_once W3TC_LIB_W3_DIR . '/Cdn.php';
2143
+
2144
+ $type = W3_Request::get_string('type');
2145
+ $key = W3_Request::get_string('key');
2146
+ $secret = W3_Request::get_string('secret');
2147
+ $bucket = W3_Request::get_string('bucket');
2148
+
2149
+ switch ($type) {
2150
+ case 's3':
2151
+ case 'cf':
2152
+ $result = true;
2153
+ break;
2154
+
2155
+ default:
2156
+ $result = false;
2157
+ $error = 'Incorrect type.';
2158
+ break;
2159
+ }
2160
+
2161
+ if ($result) {
2162
+ $w3_cdn_s3 = & W3_Cdn::instance($type, array(
2163
+ 'key' => $key,
2164
+ 'secret' => $secret,
2165
+ 'bucket' => $bucket
2166
+ ));
2167
+
2168
+ $error = null;
2169
+
2170
+ if ($w3_cdn_s3->create_bucket($error)) {
2171
+ $result = true;
2172
+ $error = 'Bucket has been successfully created.';
2173
+ } else {
2174
+ $result = false;
2175
+ $error = sprintf('Error: %s', $error);
2176
+ }
2177
+
2178
+ echo sprintf('{result: %d, error: "%s"}', $result, addslashes($error));
2179
+ }
2180
+ }
2181
+
2182
  /**
2183
  * Check if memcache is available
2184
  *
2194
  if (! isset($results[$key])) {
2195
  require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
2196
 
2197
+ $memcached = & W3_Cache_Memcached::instance(W3_CACHE_MEMCACHED_AUTO, array(
2198
  'servers' => $servers,
2199
  'persistant' => false
2200
  ));
2215
  {
2216
  require_once W3TC_LIB_W3_DIR . '/Request.php';
2217
 
2218
+ $servers = W3_Request::get_array('servers');
2219
 
2220
  if ($this->is_memcache_available($servers)) {
2221
  $result = true;
2229
  }
2230
 
2231
  /**
2232
+ * Insert plugin link into Blogroll
 
 
 
2233
  */
2234
+ function link_insert()
2235
  {
2236
+ $support = $this->_config->get_string('common.support');
2237
  $matches = null;
2238
 
2239
+ if ($support != '' && preg_match('~^link_category_(\d+)$~', $support, $matches)) {
2240
+ require_once ABSPATH . 'wp-admin/includes/bookmark.php';
2241
+
2242
+ wp_insert_link(array(
2243
+ 'link_url' => W3TC_LINK_URL,
2244
+ 'link_name' => W3TC_LINK_NAME,
2245
+ 'link_category' => array(
2246
+ (int) $matches[1]
2247
+ )
2248
+ ));
2249
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2250
  }
2251
 
2252
  /**
2256
  {
2257
  $bookmarks = get_bookmarks();
2258
  $link_id = 0;
2259
+
2260
  foreach ($bookmarks as $bookmark) {
2261
  if ($bookmark->link_url == W3TC_LINK_URL) {
2262
  $link_id = $bookmark->link_id;
2270
  }
2271
  }
2272
 
2273
+ /**
2274
+ * Updates link
2275
+ */
2276
+ function link_update()
2277
+ {
2278
+ $this->link_delete();
2279
+ $this->link_insert();
2280
+ }
2281
+
2282
  /**
2283
  * Flush specified cache
2284
  *
2286
  */
2287
  function flush($type)
2288
  {
2289
+ if ($this->_config->get_string('pgcache.engine') == $type && $this->_config->get_boolean('pgcache.enabled')) {
2290
+ $this->_config->set('notes.need_empty_pgcache', false);
2291
+
2292
+ if (! $this->_config->save()) {
2293
+ $this->redirect(array(
2294
+ 'error' => 'config_save'
2295
+ ));
2296
+ }
2297
+
2298
  $this->flush_pgcache();
2299
  }
2300
 
2301
+ if ($this->_config->get_string('dbcache.engine') == $type && $this->_config->get_boolean('dbcache.enabled')) {
2302
  $this->flush_dbcache();
2303
  }
2304
 
2305
+ if ($this->_config->get_string('minify.engine') == $type && $this->_config->get_boolean('minify.enabled')) {
2306
+ $this->_config->set('notes.need_empty_minify', false);
2307
+
2308
+ if (! $this->_config->save()) {
2309
+ $this->redirect(array(
2310
+ 'error' => 'config_save'
2311
+ ));
2312
+ }
2313
+
2314
  $this->flush_minify();
2315
  }
2316
  }
2317
 
2318
  /**
2319
  * Flush memcached cache
2320
+ *
2321
  * @return void
2322
  */
2323
  function flush_memcached()
2336
 
2337
  /**
2338
  * Flush file cache
2339
+ *
2340
  * @return void
2341
  */
2342
  function flush_file()
2343
  {
2344
  $this->flush('file');
2345
+ $this->flush('file_pgcache');
2346
  }
2347
 
2348
  /**
2351
  function flush_pgcache()
2352
  {
2353
  require_once W3TC_DIR . '/lib/W3/PgCache.php';
2354
+ $w3_pgcache = & W3_PgCache::instance();
2355
  $w3_pgcache->flush();
2356
  }
2357
 
2361
  function flush_dbcache()
2362
  {
2363
  require_once W3TC_DIR . '/lib/W3/Db.php';
2364
+ $w3_db = & W3_Db::instance();
2365
  $w3_db->flush_cache();
2366
  }
2367
 
2370
  */
2371
  function flush_minify()
2372
  {
2373
+ if (W3TC_PHP5) {
2374
+ require_once W3TC_DIR . '/lib/W3/Minify.php';
2375
+ $w3_minify = & W3_Minify::instance();
2376
+ $w3_minify->flush();
2377
+ }
2378
  }
2379
 
2380
  /**
2381
  * Checks if advanced-cache.php exists
2382
+ *
2383
  * @return boolean
2384
  */
2385
  function check_advanced_cache()
2417
  return function_exists('apc_store');
2418
  }
2419
 
2420
+ /**
2421
+ * Checks CURL availability
2422
+ *
2423
+ * @return boolean
2424
+ */
2425
+ function check_curl()
2426
+ {
2427
+ return function_exists('curl_init');
2428
+ }
2429
+
2430
  /**
2431
  * Output buffering callback
2432
  *
2437
  {
2438
  global $wpdb;
2439
 
2440
+ if ($buffer != '' && w3_is_xml($buffer)) {
2441
+ $host = gethostbyaddr($_SERVER['SERVER_ADDR']);
2442
+ $date = date('Y-m-d H:i:s');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2443
 
2444
+ if ($this->is_supported()) {
2445
+ $buffer .= sprintf("\r\n<!-- Served from: %s @ %s by W3 Total Cache -->", $host, $date);
2446
+ } else {
2447
+ $buffer .= "\r\n<!-- This site's performance optimized by W3 Total Cache. Dramatically improve the speed and reliability of your blog!\r\n\r\nLearn more about our WordPress Plugins: http://www.w3-edge.com/wordpress-plugins/\r\n\r\n";
2448
+
2449
+ if ($this->_config->get_boolean('minify.enabled')) {
2450
+ require_once W3TC_LIB_W3_DIR . '/Plugin/Minify.php';
2451
+ $w3_plugin_minify = & W3_Plugin_Minify::instance();
2452
+
2453
+ $buffer .= sprintf("Minified using %s%s\r\n", w3_get_engine_name($this->_config->get_string('minify.engine')), ($w3_plugin_minify->minify_reject_reason != '' ? sprintf(' (%s)', $w3_plugin_minify->minify_reject_reason) : ''));
2454
+ }
2455
+
2456
+ if ($this->_config->get_boolean('pgcache.enabled')) {
2457
+ require_once W3TC_LIB_W3_DIR . '/PgCache.php';
2458
+ $w3_pgcache = & W3_PgCache::instance();
2459
+
2460
+ $buffer .= sprintf("Page Caching using %s%s\r\n", w3_get_engine_name($this->_config->get_string('pgcache.engine')), ($w3_pgcache->cache_reject_reason != '' ? sprintf(' (%s)', $w3_pgcache->cache_reject_reason) : ''));
2461
+ }
2462
+
2463
+ if ($this->_config->get_boolean('dbcache.enabled') && is_a($wpdb, 'W3_Db')) {
2464
+ $append = (is_user_logged_in() ? ' (user is logged in)' : '');
2465
+
2466
+ if ($wpdb->query_hits) {
2467
+ $buffer .= sprintf("Database Caching %d/%d queries in %.3f seconds using %s%s\r\n", $wpdb->query_hits, $wpdb->query_total, $wpdb->time_total, w3_get_engine_name($this->_config->get_string('dbcache.engine')), $append);
2468
+ } else {
2469
+ $buffer .= sprintf("Database Caching using %s%s\r\n", w3_get_engine_name($this->_config->get_string('dbcache.engine')), $append);
2470
+ }
2471
+ }
2472
+
2473
+ if ($this->_config->get_boolean('cdn.enabled')) {
2474
+ require_once W3TC_LIB_W3_DIR . '/Plugin/Cdn.php';
2475
+ $w3_plugin_cdn = & W3_Plugin_Cdn::instance();
2476
+ $cdn = & $w3_plugin_cdn->get_cdn();
2477
+ $via = $cdn->get_via();
2478
+
2479
+ $buffer .= sprintf("Content Delivery Network via %s%s\r\n", ($via ? $via : 'N/A'), ($w3_plugin_cdn->cdn_reject_reason != '' ? sprintf(' (%s)', $w3_plugin_cdn->cdn_reject_reason) : ''));
2480
+ }
2481
+
2482
+ $buffer .= sprintf("\r\nServed from: %s @ %s -->", $host, $date);
2483
  }
2484
 
2485
+ if ($this->_config->get_boolean('dbcache.enabled') && $this->_config->get_boolean('dbcache.debug') && is_a($wpdb, 'W3_Db')) {
2486
+ $buffer .= "\r\n\r\n" . $wpdb->get_debug_info();
2487
  }
 
 
 
 
 
 
2488
  }
2489
 
2490
  return $buffer;
2561
 
2562
  return true;
2563
  }
2564
+
2565
+ /**
2566
+ * Returns server info
2567
+ */
2568
+ function get_server_info()
2569
+ {
2570
+ global $wp_version, $wp_db_version, $wpdb;
2571
+
2572
+ $wordpress_plugins = get_plugins();
2573
+ $wordpress_plugins_active = array();
2574
+
2575
+ foreach ($wordpress_plugins as $wordpress_plugin_file => $wordpress_plugin) {
2576
+ if (is_plugin_active($wordpress_plugin_file)) {
2577
+ $wordpress_plugins_active[$wordpress_plugin_file] = $wordpress_plugin;
2578
+ }
2579
+ }
2580
+
2581
+ $w3tc_config = (array) @include W3TC_CONFIG_PATH;
2582
+ $mysql_version = (array) $wpdb->get_var('SELECT VERSION()');
2583
+ $mysql_variables_result = (array) $wpdb->get_results('SHOW VARIABLES', ARRAY_N);
2584
+ $mysql_variables = array();
2585
+
2586
+ foreach ($mysql_variables_result as $mysql_variables_row) {
2587
+ $mysql_variables[$mysql_variables_row[0]] = $mysql_variables_row[1];
2588
+ }
2589
+
2590
+ return array(
2591
+ 'wp' => array(
2592
+ 'version' => $wp_version,
2593
+ 'db_version' => $wp_db_version,
2594
+ 'url' => w3_get_domain_url(),
2595
+ 'path' => ABSPATH,
2596
+ 'email' => get_option('admin_email'),
2597
+ 'upload_info' => (array) w3_upload_info(),
2598
+ 'theme' => get_theme(get_current_theme()),
2599
+ 'plugins' => $wordpress_plugins_active,
2600
+ 'wp_cache' => (defined('WP_CACHE') ? 'true' : 'false')
2601
+ ),
2602
+ 'w3tc' => array(
2603
+ 'version' => W3TC_VERSION,
2604
+ 'config' => $w3tc_config
2605
+ ),
2606
+ 'php' => w3_phpinfo(),
2607
+ 'mysql' => array(
2608
+ 'version' => $mysql_version,
2609
+ 'variables' => $mysql_variables
2610
+ )
2611
+ );
2612
+ }
2613
+
2614
+ /**
2615
+ * Support Us action
2616
+ */
2617
+ function support_us()
2618
+ {
2619
+ $supports = $this->get_supports();
2620
+
2621
+ include W3TC_DIR . '/inc/lightbox/support_us.phtml';
2622
+ }
2623
+
2624
+ /**
2625
+ * Tweet action
2626
+ */
2627
+ function tweet()
2628
+ {
2629
+ include W3TC_DIR . '/inc/lightbox/tweet.phtml';
2630
+ }
2631
+
2632
+ /**
2633
+ * Update twitter status
2634
+ */
2635
+ function twitter_status_update()
2636
+ {
2637
+ require_once W3TC_LIB_W3_DIR . '/Request.php';
2638
+
2639
+ $username = W3_Request::get_string('username');
2640
+ $password = W3_Request::get_string('password');
2641
+
2642
+ $error = 'OK';
2643
+
2644
+ if (w3_twitter_status_update($username, $password, W3TC_TWITTER_STATUS, $error)) {
2645
+ $this->_config->set('common.tweeted', time());
2646
+
2647
+ if ($this->_config->save()) {
2648
+ $result = true;
2649
+ } else {
2650
+ $error = 'Unable to save config.';
2651
+ $result = false;
2652
+ }
2653
+ } else {
2654
+ $result = false;
2655
+ }
2656
+
2657
+ echo sprintf('{result: %d, error: "%s"}', $result, addslashes($error));
2658
+ }
2659
+
2660
+ /**
2661
+ * Returns list of support types
2662
+ * @return array
2663
+ */
2664
+ function get_supports()
2665
+ {
2666
+ $supports = array(
2667
+ 'footer' => 'page footer'
2668
+ );
2669
+
2670
+ $link_categories = get_terms('link_category', array(
2671
+ 'hide_empty' => 0
2672
+ ));
2673
+
2674
+ foreach ($link_categories as $link_category) {
2675
+ $supports['link_category_' . $link_category->term_id] = strtolower($link_category->name);
2676
+ }
2677
+
2678
+ return $supports;
2679
+ }
2680
+
2681
+ /**
2682
+ * Returns true if is supported
2683
+ * @return boolean
2684
+ */
2685
+ function is_supported()
2686
+ {
2687
+ return ($this->_config->get_string('common.support') != '' || $this->_config->get_string('common.tweeted'));
2688
+ }
2689
+
2690
+ /**
2691
+ * Returns minify groups
2692
+ * @return array
2693
+ */
2694
+ function minify_get_groups()
2695
+ {
2696
+ $groups = array(
2697
+ 'default' => 'Default'
2698
+ );
2699
+
2700
+ $current_theme = get_current_theme();
2701
+
2702
+ if ($current_theme) {
2703
+ $theme = get_theme($current_theme);
2704
+ if ($theme && isset($theme['Template Files'])) {
2705
+ foreach ((array) $theme['Template Files'] as $template_file) {
2706
+ $group = basename($template_file, '.php');
2707
+ $groups[$group] = ucfirst($group);
2708
+ }
2709
+ }
2710
+ }
2711
+
2712
+ return $groups;
2713
+ }
2714
+
2715
+ /**
2716
+ * Redirect function
2717
+ *
2718
+ * @param boolean $check_referer
2719
+ */
2720
+ function redirect($params = array(), $check_referer = false)
2721
+ {
2722
+ if ($check_referer && ! empty($_SERVER['HTTP_REFERER'])) {
2723
+ $url = $_SERVER['HTTP_REFERER'];
2724
+ } else {
2725
+ $url = 'options-general.php';
2726
+ $params = array_merge(array(
2727
+ 'page' => W3TC_FILE,
2728
+ 'tab' => $this->_tab
2729
+ ), $params);
2730
+ }
2731
+
2732
+ w3_redirect($url, $params);
2733
+ }
2734
  }
lib/W3/Request.php CHANGED
@@ -39,7 +39,7 @@ class W3_Request
39
  * @param boolean $trim
40
  * @return string
41
  */
42
- function get_string($key, $default = 0, $trim = true)
43
  {
44
  $value = (string) W3_Request::get($key, $default);
45
 
39
  * @param boolean $trim
40
  * @return string
41
  */
42
+ function get_string($key, $default = '', $trim = true)
43
  {
44
  $value = (string) W3_Request::get($key, $default);
45
 
lib/memcached-client.php ADDED
@@ -0,0 +1,977 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //
3
+ // +---------------------------------------------------------------------------+
4
+ // | memcached client, PHP |
5
+ // +---------------------------------------------------------------------------+
6
+ // | Copyright (c) 2003 Ryan T. Dean <rtdean@cytherianage.net> |
7
+ // | All rights reserved. |
8
+ // | |
9
+ // | Redistribution and use in source and binary forms, with or without |
10
+ // | modification, are permitted provided that the following conditions |
11
+ // | are met: |
12
+ // | |
13
+ // | 1. Redistributions of source code must retain the above copyright |
14
+ // | notice, this list of conditions and the following disclaimer. |
15
+ // | 2. Redistributions in binary form must reproduce the above copyright |
16
+ // | notice, this list of conditions and the following disclaimer in the |
17
+ // | documentation and/or other materials provided with the distribution. |
18
+ // | |
19
+ // | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
20
+ // | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
21
+ // | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
22
+ // | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
23
+ // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
24
+ // | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25
+ // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26
+ // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27
+ // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
28
+ // | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29
+ // +---------------------------------------------------------------------------+
30
+ // | Author: Ryan T. Dean <rtdean@cytherianage.net> |
31
+ // | Heavily influenced by the Perl memcached client by Brad Fitzpatrick. |
32
+ // | Permission granted by Brad Fitzpatrick for relicense of ported Perl |
33
+ // | client logic under 2-clause BSD license. |
34
+ // +---------------------------------------------------------------------------+
35
+ //
36
+ // $TCAnet$
37
+ //
38
+
39
+ /**
40
+ * This is the PHP client for memcached - a distributed memory cache daemon.
41
+ * More information is available at http://www.danga.com/memcached/
42
+ *
43
+ * Usage example:
44
+ *
45
+ * require_once 'memcached.php';
46
+ *
47
+ * $mc = new memcached(array(
48
+ * 'servers' => array('127.0.0.1:10000',
49
+ * array('192.0.0.1:10010', 2),
50
+ * '127.0.0.1:10020'),
51
+ * 'debug' => false,
52
+ * 'compress_threshold' => 10240,
53
+ * 'persistant' => true));
54
+ *
55
+ * $mc->add('key', array('some', 'array'));
56
+ * $mc->replace('key', 'some random string');
57
+ * $val = $mc->get('key');
58
+ *
59
+ * @author Ryan T. Dean <rtdean@cytherianage.net>
60
+ * @package memcached-client
61
+ * @version 0.1.2
62
+ */
63
+
64
+ // {{{ requirements
65
+ // }}}
66
+
67
+ // {{{ constants
68
+ // {{{ flags
69
+
70
+ /**
71
+ * Flag: indicates data is serialized
72
+ */
73
+ if (! defined("MEMCACHE_SERIALIZED")) {
74
+ define("MEMCACHE_SERIALIZED", 1<<0);
75
+ }
76
+
77
+ /**
78
+ * Flag: indicates data is compressed
79
+ */
80
+ if (! defined("MEMCACHE_COMPRESSED")) {
81
+ define("MEMCACHE_COMPRESSED", 1<<1);
82
+ }
83
+
84
+ // }}}
85
+
86
+ /**
87
+ * Minimum savings to store data compressed
88
+ */
89
+ if (! defined("COMPRESSION_SAVINGS")) {
90
+ define("COMPRESSION_SAVINGS", 0.20);
91
+ }
92
+
93
+ // }}}
94
+
95
+ // {{{ class memcached
96
+ /**
97
+ * memcached client class implemented using (p)fsockopen()
98
+ *
99
+ * @author Ryan T. Dean <rtdean@cytherianage.net>
100
+ * @package memcached-client
101
+ */
102
+ class memcached_client
103
+ {
104
+ // {{{ properties
105
+ // {{{ public
106
+
107
+ /**
108
+ * Command statistics
109
+ *
110
+ * @var array
111
+ * @access public
112
+ */
113
+ var $stats;
114
+
115
+ // }}}
116
+ // {{{ private
117
+
118
+ /**
119
+ * Cached Sockets that are connected
120
+ *
121
+ * @var array
122
+ * @access private
123
+ */
124
+ var $_cache_sock;
125
+
126
+ /**
127
+ * Current debug status; 0 - none to 9 - profiling
128
+ *
129
+ * @var boolean
130
+ * @access private
131
+ */
132
+ var $_debug;
133
+
134
+ /**
135
+ * Dead hosts, assoc array, 'host'=>'unixtime when ok to check again'
136
+ *
137
+ * @var array
138
+ * @access private
139
+ */
140
+ var $_host_dead;
141
+
142
+ /**
143
+ * Is compression available?
144
+ *
145
+ * @var boolean
146
+ * @access private
147
+ */
148
+ var $_have_zlib;
149
+
150
+ /**
151
+ * Do we want to use compression?
152
+ *
153
+ * @var boolean
154
+ * @access private
155
+ */
156
+ var $_compress_enable;
157
+
158
+ /**
159
+ * At how many bytes should we compress?
160
+ *
161
+ * @var interger
162
+ * @access private
163
+ */
164
+ var $_compress_threshold;
165
+
166
+ /**
167
+ * Are we using persistant links?
168
+ *
169
+ * @var boolean
170
+ * @access private
171
+ */
172
+ var $_persistant;
173
+
174
+ /**
175
+ * If only using one server; contains ip:port to connect to
176
+ *
177
+ * @var string
178
+ * @access private
179
+ */
180
+ var $_single_sock;
181
+
182
+ /**
183
+ * Array containing ip:port or array(ip:port, weight)
184
+ *
185
+ * @var array
186
+ * @access private
187
+ */
188
+ var $_servers;
189
+
190
+ /**
191
+ * Our bit buckets
192
+ *
193
+ * @var array
194
+ * @access private
195
+ */
196
+ var $_buckets;
197
+
198
+ /**
199
+ * Total # of bit buckets we have
200
+ *
201
+ * @var interger
202
+ * @access private
203
+ */
204
+ var $_bucketcount;
205
+
206
+ /**
207
+ * # of total servers we have
208
+ *
209
+ * @var interger
210
+ * @access private
211
+ */
212
+ var $_active;
213
+
214
+ // }}}
215
+ // }}}
216
+ // {{{ methods
217
+ // {{{ public functions
218
+ // {{{ memcached()
219
+
220
+ /**
221
+ * Memcache initializer
222
+ *
223
+ * @param array $args Associative array of settings
224
+ *
225
+ * @return mixed
226
+ * @access public
227
+ */
228
+ function memcached_client ($args)
229
+ {
230
+ $this->set_servers($args['servers']);
231
+ $this->_debug = $args['debug'];
232
+ $this->stats = array();
233
+ $this->_compress_threshold = $args['compress_threshold'];
234
+ $this->_persistant = isset($args['persistant']) ? $args['persistant'] : false;
235
+ $this->_compress_enable = true;
236
+ $this->_have_zlib = function_exists("gzcompress");
237
+
238
+ $this->_cache_sock = array();
239
+ $this->_host_dead = array();
240
+ }
241
+
242
+ // }}}
243
+ // {{{ add()
244
+
245
+ /**
246
+ * Adds a key/value to the memcache server if one isn't already set with
247
+ * that key
248
+ *
249
+ * @param string $key Key to set with data
250
+ * @param mixed $val Value to store
251
+ * @param interger $exp (optional) Time to expire data at
252
+ *
253
+ * @return boolean
254
+ * @access public
255
+ */
256
+ function add ($key, $val, $exp = 0)
257
+ {
258
+ return $this->_set('add', $key, $val, $exp);
259
+ }
260
+
261
+ // }}}
262
+ // {{{ decr()
263
+
264
+ /**
265
+ * Decriment a value stored on the memcache server
266
+ *
267
+ * @param string $key Key to decriment
268
+ * @param interger $amt (optional) Amount to decriment
269
+ *
270
+ * @return mixed FALSE on failure, value on success
271
+ * @access public
272
+ */
273
+ function decr ($key, $amt=1)
274
+ {
275
+ return $this->_incrdecr('decr', $key, $amt);
276
+ }
277
+
278
+ // }}}
279
+ // {{{ delete()
280
+
281
+ /**
282
+ * Deletes a key from the server, optionally after $time
283
+ *
284
+ * @param string $key Key to delete
285
+ * @param interger $time (optional) How long to wait before deleting
286
+ *
287
+ * @return boolean TRUE on success, FALSE on failure
288
+ * @access public
289
+ */
290
+ function delete ($key, $time = 0)
291
+ {
292
+ if (!$this->_active)
293
+ return false;
294
+
295
+ $sock = $this->get_sock($key);
296
+ if (!is_resource($sock))
297
+ return false;
298
+
299
+ $key = is_array($key) ? $key[1] : $key;
300
+
301
+ $this->stats['delete']++;
302
+ $cmd = "delete $key $time\r\n";
303
+ if(!fwrite($sock, $cmd, strlen($cmd)))
304
+ {
305
+ $this->_dead_sock($sock);
306
+ return false;
307
+ }
308
+ $res = trim(fgets($sock));
309
+
310
+ if ($this->_debug)
311
+ printf("MemCache: delete %s (%s)\n", $key, $res);
312
+
313
+ if ($res == "DELETED")
314
+ return true;
315
+ return false;
316
+ }
317
+
318
+ // }}}
319
+ // {{{ disconnect_all()
320
+
321
+ /**
322
+ * Disconnects all connected sockets
323
+ *
324
+ * @access public
325
+ */
326
+ function disconnect_all ()
327
+ {
328
+ foreach ($this->_cache_sock as $sock)
329
+ fclose($sock);
330
+
331
+ $this->_cache_sock = array();
332
+ }
333
+
334
+ // }}}
335
+ // {{{ enable_compress()
336
+
337
+ /**
338
+ * Enable / Disable compression
339
+ *
340
+ * @param boolean $enable TRUE to enable, FALSE to disable
341
+ *
342
+ * @access public
343
+ */
344
+ function enable_compress ($enable)
345
+ {
346
+ $this->_compress_enable = $enable;
347
+ }
348
+
349
+ // }}}
350
+ // {{{ forget_dead_hosts()
351
+
352
+ /**
353
+ * Forget about all of the dead hosts
354
+ *
355
+ * @access public
356
+ */
357
+ function forget_dead_hosts ()
358
+ {
359
+ $this->_host_dead = array();
360
+ }
361
+
362
+ // }}}
363
+ // {{{ get()
364
+
365
+ /**
366
+ * Retrieves the value associated with the key from the memcache server
367
+ *
368
+ * @param string $key Key to retrieve
369
+ *
370
+ * @return mixed
371
+ * @access public
372
+ */
373
+ function get ($key)
374
+ {
375
+ if (!$this->_active)
376
+ return false;
377
+
378
+ $sock = $this->get_sock($key);
379
+
380
+ if (!is_resource($sock))
381
+ return false;
382
+
383
+ $this->stats['get']++;
384
+
385
+ $cmd = "get $key\r\n";
386
+ if (!fwrite($sock, $cmd, strlen($cmd)))
387
+ {
388
+ $this->_dead_sock($sock);
389
+ return false;
390
+ }
391
+
392
+ $val = array();
393
+ $this->_load_items($sock, $val);
394
+
395
+ if ($this->_debug)
396
+ foreach ($val as $k => $v)
397
+ printf("MemCache: sock %s got %s => %s\r\n", $sock, $k, $v);
398
+
399
+ return $val[$key];
400
+ }
401
+
402
+ // }}}
403
+ // {{{ get_multi()
404
+
405
+ /**
406
+ * Get multiple keys from the server(s)
407
+ *
408
+ * @param array $keys Keys to retrieve
409
+ *
410
+ * @return array
411
+ * @access public
412
+ */
413
+ function get_multi ($keys)
414
+ {
415
+ if (!$this->_active)
416
+ return false;
417
+
418
+ $this->stats['get_multi']++;
419
+
420
+ foreach ($keys as $key)
421
+ {
422
+ $sock = $this->get_sock($key);
423
+ if (!is_resource($sock)) continue;
424
+ $key = is_array($key) ? $key[1] : $key;
425
+ if (!isset($sock_keys[$sock]))
426
+ {
427
+ $sock_keys[$sock] = array();
428
+ $socks[] = $sock;
429
+ }
430
+ $sock_keys[$sock][] = $key;
431
+ }
432
+
433
+ // Send out the requests
434
+ foreach ($socks as $sock)
435
+ {
436
+ $cmd = "get";
437
+ foreach ($sock_keys[$sock] as $key)
438
+ {
439
+ $cmd .= " ". $key;
440
+ }
441
+ $cmd .= "\r\n";
442
+
443
+ if (fwrite($sock, $cmd, strlen($cmd)))
444
+ {
445
+ $gather[] = $sock;
446
+ } else
447
+ {
448
+ $this->_dead_sock($sock);
449
+ }
450
+ }
451
+
452
+ // Parse responses
453
+ $val = array();
454
+ foreach ($gather as $sock)
455
+ {
456
+ $this->_load_items($sock, $val);
457
+ }
458
+
459
+ if ($this->_debug)
460
+ foreach ($val as $k => $v)
461
+ printf("MemCache: got %s => %s\r\n", $k, $v);
462
+
463
+ return $val;
464
+ }
465
+
466
+ // }}}
467
+ // {{{ incr()
468
+
469
+ /**
470
+ * Increments $key (optionally) by $amt
471
+ *
472
+ * @param string $key Key to increment
473
+ * @param interger $amt (optional) amount to increment
474
+ *
475
+ * @return interger New key value?
476
+ * @access public
477
+ */
478
+ function incr ($key, $amt=1)
479
+ {
480
+ return $this->_incrdecr('incr', $key, $amt);
481
+ }
482
+
483
+ // }}}
484
+ // {{{ replace()
485
+
486
+ /**
487
+ * Overwrites an existing value for key; only works if key is already set
488
+ *
489
+ * @param string $key Key to set value as
490
+ * @param mixed $value Value to store
491
+ * @param interger $exp (optional) Experiation time
492
+ *
493
+ * @return boolean
494
+ * @access public
495
+ */
496
+ function replace ($key, $value, $exp=0)
497
+ {
498
+ return $this->_set('replace', $key, $value, $exp);
499
+ }
500
+
501
+ // }}}
502
+ // {{{ run_command()
503
+
504
+ /**
505
+ * Passes through $cmd to the memcache server connected by $sock; returns
506
+ * output as an array (null array if no output)
507
+ *
508
+ * NOTE: due to a possible bug in how PHP reads while using fgets(), each
509
+ * line may not be terminated by a \r\n. More specifically, my testing
510
+ * has shown that, on FreeBSD at least, each line is terminated only
511
+ * with a \n. This is with the PHP flag auto_detect_line_endings set
512
+ * to falase (the default).
513
+ *
514
+ * @param resource $sock Socket to send command on
515
+ * @param string $cmd Command to run
516
+ *
517
+ * @return array Output array
518
+ * @access public
519
+ */
520
+ function run_command ($sock, $cmd)
521
+ {
522
+ if (!is_resource($sock))
523
+ return array();
524
+
525
+ if (!fwrite($sock, $cmd, strlen($cmd)))
526
+ return array();
527
+
528
+ while (true)
529
+ {
530
+ $res = fgets($sock);
531
+ $ret[] = $res;
532
+ if (preg_match('/^END/', $res))
533
+ break;
534
+ if (strlen($res) == 0)
535
+ break;
536
+ }
537
+ return $ret;
538
+ }
539
+
540
+ // }}}
541
+ // {{{ set()
542
+
543
+ /**
544
+ * Unconditionally sets a key to a given value in the memcache. Returns true
545
+ * if set successfully.
546
+ *
547
+ * @param string $key Key to set value as
548
+ * @param mixed $value Value to set
549
+ * @param interger $exp (optional) Experiation time
550
+ *
551
+ * @return boolean TRUE on success
552
+ * @access public
553
+ */
554
+ function set ($key, $value, $exp=0)
555
+ {
556
+ return $this->_set('set', $key, $value, $exp);
557
+ }
558
+
559
+ // }}}
560
+ // {{{ set_compress_threshold()
561
+
562
+ /**
563
+ * Sets the compression threshold
564
+ *
565
+ * @param interger $thresh Threshold to compress if larger than
566
+ *
567
+ * @access public
568
+ */
569
+ function set_compress_threshold ($thresh)
570
+ {
571
+ $this->_compress_threshold = $thresh;
572
+ }
573
+
574
+ // }}}
575
+ // {{{ set_debug()
576
+
577
+ /**
578
+ * Sets the debug flag
579
+ *
580
+ * @param boolean $dbg TRUE for debugging, FALSE otherwise
581
+ *
582
+ * @access public
583
+ *
584
+ * @see memcahced::memcached
585
+ */
586
+ function set_debug ($dbg)
587
+ {
588
+ $this->_debug = $dbg;
589
+ }
590
+
591
+ // }}}
592
+ // {{{ set_servers()
593
+
594
+ /**
595
+ * Sets the server list to distribute key gets and puts between
596
+ *
597
+ * @param array $list Array of servers to connect to
598
+ *
599
+ * @access public
600
+ *
601
+ * @see memcached::memcached()
602
+ */
603
+ function set_servers ($list)
604
+ {
605
+ $this->_servers = $list;
606
+ $this->_active = count($list);
607
+ $this->_buckets = null;
608
+ $this->_bucketcount = 0;
609
+
610
+ $this->_single_sock = null;
611
+ if ($this->_active == 1)
612
+ $this->_single_sock = $this->_servers[0];
613
+ }
614
+
615
+ // }}}
616
+ // }}}
617
+ // {{{ private methods
618
+ // {{{ _close_sock()
619
+
620
+ /**
621
+ * Close the specified socket
622
+ *
623
+ * @param string $sock Socket to close
624
+ *
625
+ * @access private
626
+ */
627
+ function _close_sock ($sock)
628
+ {
629
+ $host = array_search($sock, $this->_cache_sock);
630
+ fclose($this->_cache_sock[$host]);
631
+ unset($this->_cache_sock[$host]);
632
+ }
633
+
634
+ // }}}
635
+ // {{{ _connect_sock()
636
+
637
+ /**
638
+ * Connects $sock to $host, timing out after $timeout
639
+ *
640
+ * @param interger $sock Socket to connect
641
+ * @param string $host Host:IP to connect to
642
+ * @param float $timeout (optional) Timeout value, defaults to 0.25s
643
+ *
644
+ * @return boolean
645
+ * @access private
646
+ */
647
+ function _connect_sock (&$sock, $host, $timeout = 0.25)
648
+ {
649
+ list ($ip, $port) = explode(":", $host);
650
+ if ($this->_persistant == 1)
651
+ {
652
+ $sock = @pfsockopen($ip, $port, $errno, $errstr, $timeout);
653
+ } else
654
+ {
655
+ $sock = @fsockopen($ip, $port, $errno, $errstr, $timeout);
656
+ }
657
+
658
+ if (!$sock)
659
+ return false;
660
+ return true;
661
+ }
662
+
663
+ // }}}
664
+ // {{{ _dead_sock()
665
+
666
+ /**
667
+ * Marks a host as dead until 30-40 seconds in the future
668
+ *
669
+ * @param string $sock Socket to mark as dead
670
+ *
671
+ * @access private
672
+ */
673
+ function _dead_sock ($sock)
674
+ {
675
+ $host = array_search($sock, $this->_cache_sock);
676
+ list ($ip, $port) = explode(":", $host);
677
+ $this->_host_dead[$ip] = time() + 30 + intval(rand(0, 10));
678
+ $this->_host_dead[$host] = $this->_host_dead[$ip];
679
+ unset($this->_cache_sock[$host]);
680
+ }
681
+
682
+ // }}}
683
+ // {{{ get_sock()
684
+
685
+ /**
686
+ * get_sock
687
+ *
688
+ * @param string $key Key to retrieve value for;
689
+ *
690
+ * @return mixed resource on success, false on failure
691
+ * @access private
692
+ */
693
+ function get_sock ($key)
694
+ {
695
+ if (!$this->_active)
696
+ return false;
697
+
698
+ if ($this->_single_sock !== null)
699
+ return $this->sock_to_host($this->_single_sock);
700
+
701
+ $hv = is_array($key) ? intval($key[0]) : $this->_hashfunc($key);
702
+
703
+ if ($this->_buckets === null)
704
+ {
705
+ foreach ($this->_servers as $v)
706
+ {
707
+ if (is_array($v))
708
+ {
709
+ for ($i=0; $i<$v[1]; $i++)
710
+ $bu[] = $v[0];
711
+ } else
712
+ {
713
+ $bu[] = $v;
714
+ }
715
+ }
716
+ $this->_buckets = $bu;
717
+ $this->_bucketcount = count($bu);
718
+ }
719
+
720
+ $realkey = is_array($key) ? $key[1] : $key;
721
+ for ($tries = 0; $tries<20; $tries++)
722
+ {
723
+ $host = $this->_buckets[$hv % $this->_bucketcount];
724
+ $sock = $this->sock_to_host($host);
725
+ if (is_resource($sock))
726
+ return $sock;
727
+ $hv += $this->_hashfunc($tries . $realkey);
728
+ }
729
+
730
+ return false;
731
+ }
732
+
733
+ // }}}
734
+ // {{{ _hashfunc()
735
+
736
+ /**
737
+ * Creates a hash interger based on the $key
738
+ *
739
+ * @param string $key Key to hash
740
+ *
741
+ * @return interger Hash value
742
+ * @access private
743
+ */
744
+ function _hashfunc ($key)
745
+ {
746
+ $hash = 0;
747
+ for ($i=0; $i<strlen($key); $i++)
748
+ {
749
+ $hash = $hash*33 + ord($key[$i]);
750
+ }
751
+
752
+ return $hash;
753
+ }
754
+
755
+ // }}}
756
+ // {{{ _incrdecr()
757
+
758
+ /**
759
+ * Perform increment/decriment on $key
760
+ *
761
+ * @param string $cmd Command to perform
762
+ * @param string $key Key to perform it on
763
+ * @param interger $amt Amount to adjust
764
+ *
765
+ * @return interger New value of $key
766
+ * @access private
767
+ */
768
+ function _incrdecr ($cmd, $key, $amt=1)
769
+ {
770
+ if (!$this->_active)
771
+ return null;
772
+
773
+ $sock = $this->get_sock($key);
774
+ if (!is_resource($sock))
775
+ return null;
776
+
777
+ $key = is_array($key) ? $key[1] : $key;
778
+ $this->stats[$cmd]++;
779
+ if (!fwrite($sock, "$cmd $key $amt\r\n"))
780
+ return $this->_dead_sock($sock);
781
+
782
+ stream_set_timeout($sock, 1, 0);
783
+ $line = fgets($sock);
784
+ if (!preg_match('/^(\d+)/', $line, $match))
785
+ return null;
786
+ return $match[1];
787
+ }
788
+
789
+ // }}}
790
+ // {{{ _load_items()
791
+
792
+ /**
793
+ * Load items into $ret from $sock
794
+ *
795
+ * @param resource $sock Socket to read from
796
+ * @param array $ret Returned values
797
+ *
798
+ * @access private
799
+ */
800
+ function _load_items ($sock, &$ret)
801
+ {
802
+ while (1)
803
+ {
804
+ $decl = fgets($sock);
805
+ if ($decl == "END\r\n")
806
+ {
807
+ return true;
808
+ } elseif (preg_match('/^VALUE (\S+) (\d+) (\d+)\r\n$/', $decl, $match))
809
+ {
810
+ list($rkey, $flags, $len) = array($match[1], $match[2], $match[3]);
811
+ $bneed = $len+2;
812
+ $offset = 0;
813
+
814
+ while ($bneed > 0)
815
+ {
816
+ $data = fread($sock, $bneed);
817
+ $n = strlen($data);
818
+ if ($n == 0)
819
+ break;
820
+ $offset += $n;
821
+ $bneed -= $n;
822
+ $ret[$rkey] .= $data;
823
+ }
824
+
825
+ if ($offset != $len+2)
826
+ {
827
+ // Something is borked!
828
+ if ($this->_debug)
829
+ printf("Something is borked! key %s expecting %d got %d length\n", $rkey, $len+2, $offset);
830
+
831
+ unset($ret[$rkey]);
832
+ $this->_close_sock($sock);
833
+ return false;
834
+ }
835
+
836
+ //$ret[$rkey] = rtrim($ret[$rkey]); buggy
837
+ $ret[$rkey] = substr($ret[$rkey], 0, -2);
838
+
839
+ if ($this->_have_zlib && $flags & MEMCACHE_COMPRESSED) {
840
+ $ret[$rkey] = gzuncompress($ret[$rkey]);
841
+ }
842
+
843
+ if ($flags & MEMCACHE_SERIALIZED)
844
+ $ret[$rkey] = unserialize($ret[$rkey]);
845
+
846
+ } else
847
+ {
848
+ print("Error parsing memcached response\n");
849
+ return 0;
850
+ }
851
+ }
852
+ }
853
+
854
+ // }}}
855
+ // {{{ _set()
856
+
857
+ /**
858
+ * Performs the requested storage operation to the memcache server
859
+ *
860
+ * @param string $cmd Command to perform
861
+ * @param string $key Key to act on
862
+ * @param mixed $val What we need to store
863
+ * @param interger $exp When it should expire
864
+ *
865
+ * @return boolean
866
+ * @access private
867
+ */
868
+ function _set ($cmd, $key, $val, $exp)
869
+ {
870
+ if (!$this->_active)
871
+ return false;
872
+
873
+ $sock = $this->get_sock($key);
874
+ if (!is_resource($sock))
875
+ return false;
876
+
877
+ $this->stats[$cmd]++;
878
+
879
+ $flags = 0;
880
+
881
+ if (!is_scalar($val))
882
+ {
883
+ $val = serialize($val);
884
+ $flags |= MEMCACHE_SERIALIZED;
885
+ if ($this->_debug)
886
+ printf("client: serializing data as it is not scalar\n");
887
+ }
888
+
889
+ $len = strlen($val);
890
+
891
+ if ($this->_have_zlib && $this->_compress_enable &&
892
+ $this->_compress_threshold && $len >= $this->_compress_threshold)
893
+ {
894
+ $c_val = gzcompress($val, 9);
895
+ $c_len = strlen($c_val);
896
+
897
+ if ($c_len < $len*(1 - COMPRESS_SAVINGS))
898
+ {
899
+ if ($this->_debug)
900
+ printf("client: compressing data; was %d bytes is now %d bytes\n", $len, $c_len);
901
+ $val = $c_val;
902
+ $len = $c_len;
903
+ $flags |= MEMCACHE_COMPRESSED;
904
+ }
905
+ }
906
+ if (!fwrite($sock, "$cmd $key $flags $exp $len\r\n$val\r\n"))
907
+ return $this->_dead_sock($sock);
908
+
909
+ $line = trim(fgets($sock));
910
+
911
+ if ($this->_debug)
912
+ {
913
+ if ($flags & MEMCACHE_COMPRESSED)
914
+ $val = 'compressed data';
915
+ printf("MemCache: %s %s => %s (%s)\n", $cmd, $key, $val, $line);
916
+ }
917
+ if ($line == "STORED")
918
+ return true;
919
+ return false;
920
+ }
921
+
922
+ // }}}
923
+ // {{{ sock_to_host()
924
+
925
+ /**
926
+ * Returns the socket for the host
927
+ *
928
+ * @param string $host Host:IP to get socket for
929
+ *
930
+ * @return mixed IO Stream or false
931
+ * @access private
932
+ */
933
+ function sock_to_host ($host)
934
+ {
935
+ if (isset($this->_cache_sock[$host]))
936
+ return $this->_cache_sock[$host];
937
+
938
+ $now = time();
939
+ list ($ip, $port) = explode (":", $host);
940
+ if (isset($this->_host_dead[$host]) && $this->_host_dead[$host] > $now ||
941
+ isset($this->_host_dead[$ip]) && $this->_host_dead[$ip] > $now)
942
+ return null;
943
+
944
+ if (!$this->_connect_sock($sock, $host))
945
+ return $this->_dead_sock($host);
946
+
947
+ // Do not buffer writes
948
+ stream_set_write_buffer($sock, 0);
949
+
950
+ $this->_cache_sock[$host] = $sock;
951
+
952
+ return $this->_cache_sock[$host];
953
+ }
954
+
955
+ // }}}
956
+ // {{{ flush_all()
957
+
958
+ /**
959
+ * Flushes all memcached data
960
+ *
961
+ * @return boolean
962
+ * @access public
963
+ */
964
+ function flush_all()
965
+ {
966
+ foreach ($this->_cache_sock as $sock) {
967
+ $this->run_command($sock, "flush_all\r\n");
968
+ }
969
+ }
970
+
971
+ // }}}
972
+ // }}}
973
+ // }}}
974
+ }
975
+
976
+ // }}}
977
+ ?>
readme.txt CHANGED
@@ -1,19 +1,20 @@
1
  === Plugin Name ===
2
  Contributors: fredericktownes
3
- Tags: user experience, cache, caching, page cache, css cache, js cache, db cache, disk cache, disk caching, database cache, http compression, gzip, deflate, minify, CDN, content delivery network, media library, wp cache, wp super cache, w3 total cache, performance, speed, multiple hosts, CSS, merge, combine, unobtrusive javascript, compress, optimize, optimizer, JavaScript, JS, cascading style sheet, plugin, yslow
4
  Requires at least: 2.5
5
- Tested up to: 2.8.4
6
- Stable tag: 0.8
7
 
8
  Dramatically improve the user experience of your blog. Add page caching, database caching, minify and content delivery network functionality and more to WordPress.
9
 
10
  == Description ==
11
 
12
- Trusted by many popular blogs like: mashable.com, pearsonified.com, webdesignerdepot.com, freelanceswitch.com, briansolis.com, css3.info, tutsplus.com, yoast.com, noupe.com and others &mdash; W3 Total Cache improves the user experience of your blog by improving your server performance, caching every aspect of your site, reducing the download time of your theme and providing transparent content delivery network (CDN) integration.
13
 
14
  Benefits:
15
 
16
- * At least 10x improvement in site performance (Grade A in YSlow, when fully configured)
 
17
  * "Instant" second page views (browser caching after first page view)
18
  * Reduced page load time: increased visitor time on site (visitors view more pages)
19
  * Optimized progressive render (pages appear to load instantly)
@@ -51,6 +52,8 @@ Speed is among the most significant success factors web sites face. In fact, you
51
 
52
  A thousandth of a second is not a long time, yet the impact is quite significant. Even if you're not a large company (or just hope to become one), a loss is still a loss. However, there is a solution to this problem, take advantage.
53
 
 
 
54
  = Why is W3 Total Cache better than other cache plugins? =
55
 
56
  Most of the popular cache plugins available do a great job and serve their purpose very well. Our plugin remedies numerous performance reducing aspects of any web site going far beyond merely reducing CPU usage (load) and bandwidth consumption for HTML pages alone. Equally important, the plugin requires no theme modifications, modifications to your .htaccess (mod_rewrite rules) or programming compromises to reap the benefits. Setup is easy.
@@ -69,7 +72,7 @@ You're right, [Matt did say that](http://ma.tt/2008/03/wordpress-is-open-source/
69
 
70
  = Which WordPress versions are supported? =
71
 
72
- To use all features in the suite, a minimum of version 2.5 is required. Earlier versions will benefit from our Media Library Importer to get them back on the upgrade path and into a CDN of their choosing.
73
 
74
  = Will the plugin interfere with other plugins or widgets? =
75
 
@@ -89,17 +92,18 @@ On the contrary, as with any other action a user can perform on a site, faster p
89
 
90
  = Who do you recommend as a CDN (Content Delivery Network) provider? =
91
 
92
- That depends on how you use your blog and where most of your readers read your blog (regionally). Here's a short list:</p>
93
 
94
- * [NetDNA](http://www.netdna.com/)
 
95
  * [VPS NET](https://vps.net/cdn-signup)
96
- * [SimpleCDN](http://www.simplecdn.com/)
97
- * [Amazon S3](http://aws.amazon.com/s3/)
98
- * [Amazon Cloudfront](http://aws.amazon.com/cloudfront/)
99
  * [EdgeCast](http://www.edgecast.com/)
100
- * [Voxel](http://www.voxel.net/products-services/voxcast-cdn)
101
- * [Limelight Networks](http://www.limelightnetworks.com/)
102
  * [Akamai](http://www.akamai.com/)
 
 
 
103
 
104
  = Why would I want to cache my feeds? =
105
 
@@ -113,7 +117,6 @@ Technically no, a CDN is a high performance cache that stores static assets (you
113
 
114
  Yes, indirectly - if you have a lot of bloggers working with you, you will find that it feels like you have a server dedicated only to WP Admin once this plugin is enabled; the result, increased productivity.
115
 
116
-
117
  = Which web servers do you support? =
118
 
119
  We are aware of no incompatibilities with [apache](http://httpd.apache.org/) 1.3+, [IIS](http://www.iis.net/) 5+ or [litespeed](http://litespeedtech.com/products/webserver/overview/) 4.0.2+. If there's a web server you feel we should be actively testing (e.g. [lighttpd](http://www.lighttpd.net/)), we're [interested in hearing](mailto:wordpressexperts@w3-edge.com).
@@ -136,13 +139,46 @@ Install the plugin to read the full FAQ.
136
  1. Unzip and upload the plugin to your plugins directory (wp-content/plugins/), when done wp-content/plugins/w3-total-cache/ should exist.
137
  1. Ensure that wp-config.php contains the statement below; if you previously used a caching plugin, this statement is likely to exist already: `define('WP_CACHE', true);`
138
  1. Locate and activate the plugin on the plugins page, then click the Settings link to proceed to the General Settings tab. Set the permissions of wp-content back to 755, e.g.: `# chmod 755 /var/www/vhosts/domain.com/httpdocs/wp-content/`
139
- 1. Select your caching preferences for page, database and minify. If memcached is used this will require you to confirm or modify the default settings and add any additional memcached servers you wish to use. To utilize APC and memcached + memcache installation guides have been provided under the Installation tab. For those in shared hosting environments, contact your provider to see if either of these is supported.
140
  1. If you already have a content delivery network provider, proceed to the CDN Settings tab and populate the fields and set your preferences. If you're not running a version of WordPress with the Media Library feature, use the Media Library Import Tool to migrate your post images etc to appropriate locations. If you do not have a CDN provider, you can still improve your site's performance using this feature. Create and use a subdomain on your own server; e.g. static.domain.com and configure options on the CDN tab accordingly.
141
  1. On the Minify Settings tab all of the recommended settings are preset. Specify any CSS and JS files in the respective sections, view your site's HTML source and search for .css and .js files. In the case of JS files you can specify the type and location of the embedding using the drop down menu.
142
  1. You're done! Get back to blogging!
143
 
144
  == Changelog ==
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  = 0.8 =
147
  * Added disk as method for page caching
148
  * Added support for mirror (origin pull) content delivery networks
1
  === Plugin Name ===
2
  Contributors: fredericktownes
3
+ Tags: user experience, cache, caching, page cache, css cache, js cache, db cache, disk cache, disk caching, database cache, http compression, gzip, deflate, minify, CDN, content delivery network, media library, performance, speed, multiple hosts, CSS, merge, combine, unobtrusive javascript, compress, optimize, optimizer, JavaScript, JS, cascading style sheet, plugin, yslow, YUI, google, google rank, google page speed, S3, CloudFront, AWS, Amazon Web Services, batcache, wp cache, wp super cache, w3 total cache
4
  Requires at least: 2.5
5
+ Tested up to: 2.9
6
+ Stable tag: 0.8.5
7
 
8
  Dramatically improve the user experience of your blog. Add page caching, database caching, minify and content delivery network functionality and more to WordPress.
9
 
10
  == Description ==
11
 
12
+ The fastest and most complete WordPress performance optimization plugin. Trusted by many popular blogs like: mashable.com, pearsonified.com, noupe.com, webdesignerdepot.com, freelanceswitch.com, briansolis.com, tutsplus.com, yoast.com, css3.info and others &mdash; W3 Total Cache improves the user experience of your blog by improving your server performance, caching every aspect of your site, reducing the download time of your theme and providing transparent content delivery network (CDN) integration.
13
 
14
  Benefits:
15
 
16
+ * At least 10x improvement in site performance (when fully configured: Grade A in [YSlow](http://developer.yahoo.com/yslow/) or significant [Google Page Speed](http://code.google.com/speed/page-speed/) Improvements)
17
+ * Improves "[site performance](http://googlewebmastercentral.blogspot.com/2009/12/your-sites-performance-in-webmaster.html)" which [may affect your blog's rank](http://searchengineland.com/site-speed-googles-next-ranking-factor-29793) google.com
18
  * "Instant" second page views (browser caching after first page view)
19
  * Reduced page load time: increased visitor time on site (visitors view more pages)
20
  * Optimized progressive render (pages appear to load instantly)
52
 
53
  A thousandth of a second is not a long time, yet the impact is quite significant. Even if you're not a large company (or just hope to become one), a loss is still a loss. However, there is a solution to this problem, take advantage.
54
 
55
+ In the near future search engines themselves will weigh the performance of web sites as factors in their ranking algorithms. Search engine's have the goal of providing users with the best user experience, so speed is definitely a factor.
56
+
57
  = Why is W3 Total Cache better than other cache plugins? =
58
 
59
  Most of the popular cache plugins available do a great job and serve their purpose very well. Our plugin remedies numerous performance reducing aspects of any web site going far beyond merely reducing CPU usage (load) and bandwidth consumption for HTML pages alone. Equally important, the plugin requires no theme modifications, modifications to your .htaccess (mod_rewrite rules) or programming compromises to reap the benefits. Setup is easy.
72
 
73
  = Which WordPress versions are supported? =
74
 
75
+ To use all features in the suite, a minimum of version WordPress 2.5 with PHP 5 is required. Earlier versions will benefit from our Media Library Importer to get them back on the upgrade path and into a CDN of their choosing.
76
 
77
  = Will the plugin interfere with other plugins or widgets? =
78
 
92
 
93
  = Who do you recommend as a CDN (Content Delivery Network) provider? =
94
 
95
+ That depends on how you use your blog and where most of your readers read your blog (regionally). Here's a short list:
96
 
97
+ * [MaxCDN](http://www.maxcdn.com/)
98
+ * [Cotendo](http://www.cotendo.com/)
99
  * [VPS NET](https://vps.net/cdn-signup)
100
+ * [Amazon S3](http://aws.amazon.com/s3/) &amp; [Amazon Cloudfront](http://aws.amazon.com/cloudfront/)
101
+ * [NetDNA](http://www.netdna.com/)
 
102
  * [EdgeCast](http://www.edgecast.com/)
 
 
103
  * [Akamai](http://www.akamai.com/)
104
+ * [Limelight Networks](http://www.limelightnetworks.com/)
105
+ * [SimpleCDN](http://www.simplecdn.com/)
106
+ * [Voxel](http://www.voxel.net/products-services/voxcast-cdn)
107
 
108
  = Why would I want to cache my feeds? =
109
 
117
 
118
  Yes, indirectly - if you have a lot of bloggers working with you, you will find that it feels like you have a server dedicated only to WP Admin once this plugin is enabled; the result, increased productivity.
119
 
 
120
  = Which web servers do you support? =
121
 
122
  We are aware of no incompatibilities with [apache](http://httpd.apache.org/) 1.3+, [IIS](http://www.iis.net/) 5+ or [litespeed](http://litespeedtech.com/products/webserver/overview/) 4.0.2+. If there's a web server you feel we should be actively testing (e.g. [lighttpd](http://www.lighttpd.net/)), we're [interested in hearing](mailto:wordpressexperts@w3-edge.com).
139
  1. Unzip and upload the plugin to your plugins directory (wp-content/plugins/), when done wp-content/plugins/w3-total-cache/ should exist.
140
  1. Ensure that wp-config.php contains the statement below; if you previously used a caching plugin, this statement is likely to exist already: `define('WP_CACHE', true);`
141
  1. Locate and activate the plugin on the plugins page, then click the Settings link to proceed to the General Settings tab. Set the permissions of wp-content back to 755, e.g.: `# chmod 755 /var/www/vhosts/domain.com/httpdocs/wp-content/`
142
+ 1. Select your caching preferences for page, database and minify. If memcached is used this will require you to confirm or modify the default settings and add any additional memcached servers you wish to use. To (optionally) utilize APC / memcached + memcache installation guides have been provided under the Installation tab. For those in shared hosting environments, contact your provider to see if either of these is supported.
143
  1. If you already have a content delivery network provider, proceed to the CDN Settings tab and populate the fields and set your preferences. If you're not running a version of WordPress with the Media Library feature, use the Media Library Import Tool to migrate your post images etc to appropriate locations. If you do not have a CDN provider, you can still improve your site's performance using this feature. Create and use a subdomain on your own server; e.g. static.domain.com and configure options on the CDN tab accordingly.
144
  1. On the Minify Settings tab all of the recommended settings are preset. Specify any CSS and JS files in the respective sections, view your site's HTML source and search for .css and .js files. In the case of JS files you can specify the type and location of the embedding using the drop down menu.
145
  1. You're done! Get back to blogging!
146
 
147
  == Changelog ==
148
 
149
+ = 0.8.5 =
150
+ * Added "enhanced" disk caching mode for page cache, a 160% performance improvement over basic mode
151
+ * Added disk caching as an option for Database Cache
152
+ * Added CDN support for Amazon S3 and CloudFront
153
+ * Added mobile user agent rejection and redirect fields to page cache for handling mobile user agents
154
+ * Added Submit Bug Report tab
155
+ * Added support for detection of custom templates for minify groups
156
+ * Added separate controls expiration time field for minify and page cache settings
157
+ * Added PHP4 Support Notification to handle fatal errors on activation
158
+ * Improved database caching by 45%
159
+ * Improved handling of cache-control HTML headers
160
+ * Improved handing of 3rd Party CSS file minification
161
+ * Improved media library import reliability
162
+ * Improved handling of `DOCUMENT_ROOT` on some servers
163
+ * Improved garbage collection routine
164
+ * Improved handling of `<pre>` and `<textarea>` minification
165
+ * Improved handling of regular expressions in custom file list in CDN settings
166
+ * Improved handling of media library attachments in RSS feeds
167
+ * Improved handing of subdomains for CDN settings
168
+ * Improved various notifications and error messages
169
+ * Improved optional .htaccess directives (located in /ini/_htaccess)
170
+ * Fixed bug with JS minifcation saving group settings
171
+ * Fixed bug with false positives for duplicate CSS or JS in minify settings
172
+ * Fixed bug causing settings to be lost on upgrade
173
+ * Fixed bug with attachment URI when CDN mode enabled
174
+ * Fixed small bug with FTP upload when CDN Method is Mirror (Origin Pull)
175
+ * Fixed bug with the URI for wlwmanfiest.xml when CDN enabled
176
+ * Fixed bug with handling of HTTPS objects according to options
177
+ * Fixed bug with emptying disk cache under various obscure permutations
178
+ * Fixed bug with handling of obscure open_basedir restrictions
179
+ * Fixed various bugs with emptying cache under various obscure permutations
180
+ * Fixed bug with installations deeper than document root
181
+
182
  = 0.8 =
183
  * Added disk as method for page caching
184
  * Added support for mirror (origin pull) content delivery networks
tools/apc.php DELETED
@@ -1,1362 +0,0 @@
1
- <?php
2
- /*
3
- +----------------------------------------------------------------------+
4
- | APC |
5
- +----------------------------------------------------------------------+
6
- | Copyright (c) 2006-2008 The PHP Group |
7
- +----------------------------------------------------------------------+
8
- | This source file is subject to version 3.01 of the PHP license, |
9
- | that is bundled with this package in the file LICENSE, and is |
10
- | available through the world-wide-web at the following url: |
11
- | http://www.php.net/license/3_01.txt |
12
- | If you did not receive a copy of the PHP license and are unable to |
13
- | obtain it through the world-wide-web, please send a note to |
14
- | license@php.net so we can mail you a copy immediately. |
15
- +----------------------------------------------------------------------+
16
- | Authors: Ralf Becker <beckerr@php.net> |
17
- | Rasmus Lerdorf <rasmus@php.net> |
18
- | Ilia Alshanetsky <ilia@prohost.org> |
19
- +----------------------------------------------------------------------+
20
-
21
- All other licensing and usage conditions are those of the PHP Group.
22
-
23
- */
24
-
25
- $VERSION='$Id: apc.php 271315 2008-12-16 07:15:07Z shire $';
26
-
27
- ////////// READ OPTIONAL CONFIGURATION FILE ////////////
28
- if (file_exists("apc.conf.php")) include("apc.conf.php");
29
- ////////////////////////////////////////////////////////
30
-
31
- ////////// BEGIN OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////
32
-
33
- defaults('USE_AUTHENTICATION',1); // Use (internal) authentication - best choice if
34
- // no other authentication is available
35
- // If set to 0:
36
- // There will be no further authentication. You
37
- // will have to handle this by yourself!
38
- // If set to 1:
39
- // You need to change ADMIN_PASSWORD to make
40
- // this work!
41
- defaults('ADMIN_USERNAME','admin'); // Admin Username
42
- defaults('ADMIN_PASSWORD','totalcache'); // Admin Password - CHANGE THIS TO ENABLE!!!
43
-
44
- // (beckerr) I'm using a clear text password here, because I've no good idea how to let
45
- // users generate a md5 or crypt password in a easy way to fill it in above
46
-
47
- //defaults('DATE_FORMAT', "d.m.Y H:i:s"); // German
48
- defaults('DATE_FORMAT', 'Y/m/d H:i:s'); // US
49
-
50
- defaults('GRAPH_SIZE',200); // Image size
51
-
52
- //defaults('PROXY', 'tcp://127.0.0.1:8080');
53
-
54
- ////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
55
-
56
-
57
- // "define if not defined"
58
- function defaults($d,$v) {
59
- if (!defined($d)) define($d,$v); // or just @define(...)
60
- }
61
-
62
- // rewrite $PHP_SELF to block XSS attacks
63
- //
64
- $PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],''), ENT_QUOTES, 'UTF-8') : '';
65
- $time = time();
66
- $host = php_uname('n');
67
- if($host) { $host = '('.$host.')'; }
68
- if ($_SERVER['SERVER_ADDR']) {
69
- $host .= ' ('.$_SERVER['SERVER_ADDR'].')';
70
- }
71
-
72
- // operation constants
73
- define('OB_HOST_STATS',1);
74
- define('OB_SYS_CACHE',2);
75
- define('OB_USER_CACHE',3);
76
- define('OB_SYS_CACHE_DIR',4);
77
- define('OB_VERSION_CHECK',9);
78
-
79
- // check validity of input variables
80
- $vardom=array(
81
- 'OB' => '/^\d+$/', // operational mode switch
82
- 'CC' => '/^[01]$/', // clear cache requested
83
- 'DU' => '/^.*$/', // Delete User Key
84
- 'SH' => '/^[a-z0-9]+$/', // shared object description
85
-
86
- 'IMG' => '/^[123]$/', // image to generate
87
- 'LO' => '/^1$/', // login requested
88
-
89
- 'COUNT' => '/^\d+$/', // number of line displayed in list
90
- 'SCOPE' => '/^[AD]$/', // list view scope
91
- 'SORT1' => '/^[AHSMCDTZ]$/', // first sort key
92
- 'SORT2' => '/^[DA]$/', // second sort key
93
- 'AGGR' => '/^\d+$/', // aggregation by dir level
94
- 'SEARCH' => '~^[a-zA-Z0-1/_.-]*$~' // aggregation by dir level
95
- );
96
-
97
- // default cache mode
98
- $cache_mode='opcode';
99
-
100
- // cache scope
101
- $scope_list=array(
102
- 'A' => 'cache_list',
103
- 'D' => 'deleted_list'
104
- );
105
-
106
- // handle POST and GET requests
107
- if (empty($_REQUEST)) {
108
- if (!empty($_GET) && !empty($_POST)) {
109
- $_REQUEST = array_merge($_GET, $_POST);
110
- } else if (!empty($_GET)) {
111
- $_REQUEST = $_GET;
112
- } else if (!empty($_POST)) {
113
- $_REQUEST = $_POST;
114
- } else {
115
- $_REQUEST = array();
116
- }
117
- }
118
-
119
- // check parameter syntax
120
- foreach($vardom as $var => $dom) {
121
- if (!isset($_REQUEST[$var])) {
122
- $MYREQUEST[$var]=NULL;
123
- } else if (!is_array($_REQUEST[$var]) && preg_match($dom.'D',$_REQUEST[$var])) {
124
- $MYREQUEST[$var]=$_REQUEST[$var];
125
- } else {
126
- $MYREQUEST[$var]=$_REQUEST[$var]=NULL;
127
- }
128
- }
129
-
130
- // check parameter sematics
131
- if (empty($MYREQUEST['SCOPE'])) $MYREQUEST['SCOPE']="A";
132
- if (empty($MYREQUEST['SORT1'])) $MYREQUEST['SORT1']="H";
133
- if (empty($MYREQUEST['SORT2'])) $MYREQUEST['SORT2']="D";
134
- if (empty($MYREQUEST['OB'])) $MYREQUEST['OB']=OB_HOST_STATS;
135
- if (!isset($MYREQUEST['COUNT'])) $MYREQUEST['COUNT']=20;
136
- if (!isset($scope_list[$MYREQUEST['SCOPE']])) $MYREQUEST['SCOPE']='A';
137
-
138
- $MY_SELF=
139
- "$PHP_SELF".
140
- "?SCOPE=".$MYREQUEST['SCOPE'].
141
- "&SORT1=".$MYREQUEST['SORT1'].
142
- "&SORT2=".$MYREQUEST['SORT2'].
143
- "&COUNT=".$MYREQUEST['COUNT'];
144
- $MY_SELF_WO_SORT=
145
- "$PHP_SELF".
146
- "?SCOPE=".$MYREQUEST['SCOPE'].
147
- "&COUNT=".$MYREQUEST['COUNT'];
148
-
149
- // authentication needed?
150
- //
151
- if (!USE_AUTHENTICATION) {
152
- $AUTHENTICATED=1;
153
- } else {
154
- $AUTHENTICATED=0;
155
- if (ADMIN_PASSWORD!='password' && ($MYREQUEST['LO'] == 1 || isset($_SERVER['PHP_AUTH_USER']))) {
156
-
157
- if (!isset($_SERVER['PHP_AUTH_USER']) ||
158
- !isset($_SERVER['PHP_AUTH_PW']) ||
159
- $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||
160
- $_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
161
- Header("WWW-Authenticate: Basic realm=\"APC Login\"");
162
- Header("HTTP/1.0 401 Unauthorized");
163
-
164
- echo <<<EOB
165
- <html><body>
166
- <h1>Rejected!</h1>
167
- <big>Wrong Username or Password!</big><br/>&nbsp;<br/>&nbsp;
168
- <big><a href='$PHP_SELF?OB={$MYREQUEST['OB']}'>Continue...</a></big>
169
- </body></html>
170
- EOB;
171
- exit;
172
-
173
- } else {
174
- $AUTHENTICATED=1;
175
- }
176
- }
177
- }
178
-
179
- // select cache mode
180
- if ($AUTHENTICATED && $MYREQUEST['OB'] == OB_USER_CACHE) {
181
- $cache_mode='user';
182
- }
183
- // clear cache
184
- if ($AUTHENTICATED && isset($MYREQUEST['CC']) && $MYREQUEST['CC']) {
185
- apc_clear_cache($cache_mode);
186
- }
187
-
188
- if ($AUTHENTICATED && !empty($MYREQUEST['DU'])) {
189
- apc_delete($MYREQUEST['DU']);
190
- }
191
-
192
- if(!function_exists('apc_cache_info') || !($cache=@apc_cache_info($cache_mode))) {
193
- echo "No cache info available. APC does not appear to be running.";
194
- exit;
195
- }
196
-
197
- $cache_user = apc_cache_info('user', 1);
198
- $mem=apc_sma_info();
199
- if(!$cache['num_hits']) { $cache['num_hits']=1; $time++; } // Avoid division by 0 errors on a cache clear
200
-
201
- // don't cache this page
202
- //
203
- header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
204
- header("Cache-Control: post-check=0, pre-check=0", false);
205
- header("Pragma: no-cache"); // HTTP/1.0
206
-
207
- function duration($ts) {
208
- global $time;
209
- $years = (int)((($time - $ts)/(7*86400))/52.177457);
210
- $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400));
211
- $weeks = (int)(($rem)/(7*86400));
212
- $days = (int)(($rem)/86400) - $weeks*7;
213
- $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24;
214
- $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60;
215
- $str = '';
216
- if($years==1) $str .= "$years year, ";
217
- if($years>1) $str .= "$years years, ";
218
- if($weeks==1) $str .= "$weeks week, ";
219
- if($weeks>1) $str .= "$weeks weeks, ";
220
- if($days==1) $str .= "$days day,";
221
- if($days>1) $str .= "$days days,";
222
- if($hours == 1) $str .= " $hours hour and";
223
- if($hours>1) $str .= " $hours hours and";
224
- if($mins == 1) $str .= " 1 minute";
225
- else $str .= " $mins minutes";
226
- return $str;
227
- }
228
-
229
- // create graphics
230
- //
231
- function graphics_avail() {
232
- return extension_loaded('gd');
233
- }
234
- if (isset($MYREQUEST['IMG']))
235
- {
236
- if (!graphics_avail()) {
237
- exit(0);
238
- }
239
-
240
- function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) {
241
- $r=$diameter/2;
242
- $w=deg2rad((360+$start+($end-$start)/2)%360);
243
-
244
-
245
- if (function_exists("imagefilledarc")) {
246
- // exists only if GD 2.0.1 is avaliable
247
- imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
248
- imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
249
- imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED);
250
- } else {
251
- imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
252
- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
253
- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
254
- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
255
- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
256
- imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2);
257
- }
258
- if ($text) {
259
- if ($placeindex>0) {
260
- imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
261
- imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
262
-
263
- } else {
264
- imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
265
- }
266
- }
267
- }
268
-
269
- function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$text,$placeindex=0) {
270
- $r=$diameter/2;
271
- $w=deg2rad((360+$start+($end-$start)/2)%360);
272
-
273
- if ($placeindex>0) {
274
- imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
275
- imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
276
-
277
- } else {
278
- imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
279
- }
280
- }
281
-
282
- function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') {
283
- global $col_black;
284
- $x1=$x+$w-1;
285
- $y1=$y+$h-1;
286
-
287
- imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black);
288
- if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
289
- else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
290
- imagerectangle($im, $x, $y1, $x1, $y, $color1);
291
- if ($text) {
292
- if ($placeindex>0) {
293
-
294
- if ($placeindex<16)
295
- {
296
- $px=5;
297
- $py=$placeindex*12+6;
298
- imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2);
299
- imageline($im,$x,$y+$h/2,$px+90,$py,$color2);
300
- imagestring($im,2,$px,$py-6,$text,$color1);
301
-
302
- } else {
303
- if ($placeindex<31) {
304
- $px=$x+40*2;
305
- $py=($placeindex-15)*12+6;
306
- } else {
307
- $px=$x+40*2+100*intval(($placeindex-15)/15);
308
- $py=($placeindex%15)*12+6;
309
- }
310
- imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2);
311
- imageline($im,$x+$w,$y+$h/2,$px,$py,$color2);
312
- imagestring($im,2,$px+2,$py-6,$text,$color1);
313
- }
314
- } else {
315
- imagestring($im,4,$x+5,$y1-16,$text,$color1);
316
- }
317
- }
318
- }
319
-
320
-
321
- $size = GRAPH_SIZE; // image size
322
- if ($MYREQUEST['IMG']==3)
323
- $image = imagecreate(2*$size+150, $size+10);
324
- else
325
- $image = imagecreate($size+50, $size+10);
326
-
327
- $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
328
- $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30);
329
- $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
330
- $col_black = imagecolorallocate($image, 0, 0, 0);
331
- imagecolortransparent($image,$col_white);
332
-
333
- switch ($MYREQUEST['IMG']) {
334
-
335
- case 1:
336
- $s=$mem['num_seg']*$mem['seg_size'];
337
- $a=$mem['avail_mem'];
338
- $x=$y=$size/2;
339
- $fuzz = 0.000001;
340
-
341
- // This block of code creates the pie chart. It is a lot more complex than you
342
- // would expect because we try to visualize any memory fragmentation as well.
343
- $angle_from = 0;
344
- $string_placement=array();
345
- for($i=0; $i<$mem['num_seg']; $i++) {
346
- $ptr = 0;
347
- $free = $mem['block_lists'][$i];
348
- uasort($free, 'block_sort');
349
- foreach($free as $block) {
350
- if($block['offset']!=$ptr) { // Used block
351
- $angle_to = $angle_from+($block['offset']-$ptr)/$s;
352
- if(($angle_to+$fuzz)>1) $angle_to = 1;
353
- if( ($angle_to*360) - ($angle_from*360) >= 1) {
354
- fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
355
- if (($angle_to-$angle_from)>0.05) {
356
- array_push($string_placement, array($angle_from,$angle_to));
357
- }
358
- }
359
- $angle_from = $angle_to;
360
- }
361
- $angle_to = $angle_from+($block['size'])/$s;
362
- if(($angle_to+$fuzz)>1) $angle_to = 1;
363
- if( ($angle_to*360) - ($angle_from*360) >= 1) {
364
- fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_green);
365
- if (($angle_to-$angle_from)>0.05) {
366
- array_push($string_placement, array($angle_from,$angle_to));
367
- }
368
- }
369
- $angle_from = $angle_to;
370
- $ptr = $block['offset']+$block['size'];
371
- }
372
- if ($ptr < $mem['seg_size']) { // memory at the end
373
- $angle_to = $angle_from + ($mem['seg_size'] - $ptr)/$s;
374
- if(($angle_to+$fuzz)>1) $angle_to = 1;
375
- fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
376
- if (($angle_to-$angle_from)>0.05) {
377
- array_push($string_placement, array($angle_from,$angle_to));
378
- }
379
- }
380
- }
381
- foreach ($string_placement as $angle) {
382
- text_arc($image,$x,$y,$size,$angle[0]*360,$angle[1]*360,$col_black,bsize($s*($angle[1]-$angle[0])));
383
- }
384
- break;
385
-
386
- case 2:
387
- $s=$cache['num_hits']+$cache['num_misses'];
388
- $a=$cache['num_hits'];
389
-
390
- fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
391
- fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
392
- break;
393
-
394
- case 3:
395
- $s=$mem['num_seg']*$mem['seg_size'];
396
- $a=$mem['avail_mem'];
397
- $x=130;
398
- $y=1;
399
- $j=1;
400
-
401
- // This block of code creates the bar chart. It is a lot more complex than you
402
- // would expect because we try to visualize any memory fragmentation as well.
403
- for($i=0; $i<$mem['num_seg']; $i++) {
404
- $ptr = 0;
405
- $free = $mem['block_lists'][$i];
406
- uasort($free, 'block_sort');
407
- foreach($free as $block) {
408
- if($block['offset']!=$ptr) { // Used block
409
- $h=(GRAPH_SIZE-5)*($block['offset']-$ptr)/$s;
410
- if ($h>0) {
411
- $j++;
412
- if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($block['offset']-$ptr),$j);
413
- else fill_box($image,$x,$y,50,$h,$col_black,$col_red);
414
- }
415
- $y+=$h;
416
- }
417
- $h=(GRAPH_SIZE-5)*($block['size'])/$s;
418
- if ($h>0) {
419
- $j++;
420
- if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_green,bsize($block['size']),$j);
421
- else fill_box($image,$x,$y,50,$h,$col_black,$col_green);
422
- }
423
- $y+=$h;
424
- $ptr = $block['offset']+$block['size'];
425
- }
426
- if ($ptr < $mem['seg_size']) { // memory at the end
427
- $h = (GRAPH_SIZE-5) * ($mem['seg_size'] - $ptr) / $s;
428
- if ($h > 0) {
429
- fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($mem['seg_size']-$ptr),$j++);
430
- }
431
- }
432
- }
433
- break;
434
- case 4:
435
- $s=$cache['num_hits']+$cache['num_misses'];
436
- $a=$cache['num_hits'];
437
-
438
- fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
439
- fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
440
- break;
441
-
442
- }
443
- header("Content-type: image/png");
444
- imagepng($image);
445
- exit;
446
- }
447
-
448
- // pretty printer for byte values
449
- //
450
- function bsize($s) {
451
- foreach (array('','K','M','G') as $i => $k) {
452
- if ($s < 1024) break;
453
- $s/=1024;
454
- }
455
- return sprintf("%5.1f %sBytes",$s,$k);
456
- }
457
-
458
- // sortable table header in "scripts for this host" view
459
- function sortheader($key,$name,$extra='') {
460
- global $MYREQUEST, $MY_SELF_WO_SORT;
461
-
462
- if ($MYREQUEST['SORT1']==$key) {
463
- $MYREQUEST['SORT2'] = $MYREQUEST['SORT2']=='A' ? 'D' : 'A';
464
- }
465
- return "<a class=sortable href=\"$MY_SELF_WO_SORT$extra&SORT1=$key&SORT2=".$MYREQUEST['SORT2']."\">$name</a>";
466
-
467
- }
468
-
469
- // create menu entry
470
- function menu_entry($ob,$title) {
471
- global $MYREQUEST,$MY_SELF;
472
- if ($MYREQUEST['OB']!=$ob) {
473
- return "<li><a href=\"$MY_SELF&OB=$ob\">$title</a></li>";
474
- } else if (empty($MYREQUEST['SH'])) {
475
- return "<li><span class=active>$title</span></li>";
476
- } else {
477
- return "<li><a class=\"child_active\" href=\"$MY_SELF&OB=$ob\">$title</a></li>";
478
- }
479
- }
480
-
481
- function put_login_link($s="Login")
482
- {
483
- global $MY_SELF,$MYREQUEST,$AUTHENTICATED;
484
- // needs ADMIN_PASSWORD to be changed!
485
- //
486
- if (!USE_AUTHENTICATION) {
487
- return;
488
- } else if (ADMIN_PASSWORD=='password')
489
- {
490
- print <<<EOB
491
- <a href="#" onClick="javascript:alert('You need to set a password at the top of apc.php before this will work!');return false";>$s</a>
492
- EOB;
493
- } else if ($AUTHENTICATED) {
494
- print <<<EOB
495
- '{$_SERVER['PHP_AUTH_USER']}'&nbsp;logged&nbsp;in!
496
- EOB;
497
- } else{
498
- print <<<EOB
499
- <a href="$MY_SELF&LO=1&OB={$MYREQUEST['OB']}">$s</a>
500
- EOB;
501
- }
502
- }
503
-
504
- function block_sort($array1, $array2)
505
- {
506
- if ($array1['offset'] > $array2['offset']) {
507
- return 1;
508
- } else {
509
- return -1;
510
- }
511
- }
512
-
513
-
514
- ?>
515
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
516
- <html>
517
- <head><title>APC INFO <?php echo $host ?></title>
518
- <style><!--
519
- body { background:white; font-size:100.01%; margin:0; padding:0; }
520
- body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; }
521
- * html body {font-size:0.8em}
522
- * html p {font-size:0.8em}
523
- * html td {font-size:0.8em}
524
- * html th {font-size:0.8em}
525
- * html input {font-size:0.8em}
526
- * html submit {font-size:0.8em}
527
- td { vertical-align:top }
528
- a { color:black; font-weight:none; text-decoration:none; }
529
- a:hover { text-decoration:underline; }
530
- div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; }
531
-
532
-
533
- div.head div.login {
534
- position:absolute;
535
- right: 1em;
536
- top: 1.2em;
537
- color:white;
538
- width:6em;
539
- }
540
- div.head div.login a {
541
- position:absolute;
542
- right: 0em;
543
- background:rgb(119,123,180);
544
- border:solid rgb(102,102,153) 2px;
545
- color:white;
546
- font-weight:bold;
547
- padding:0.1em 0.5em 0.1em 0.5em;
548
- text-decoration:none;
549
- }
550
- div.head div.login a:hover {
551
- background:rgb(193,193,244);
552
- }
553
-
554
- h1.apc { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
555
- * html h1.apc { margin-bottom:-7px; }
556
- h1.apc a:hover { text-decoration:none; color:rgb(90,90,90); }
557
- h1.apc div.logo span.logo {
558
- background:rgb(119,123,180);
559
- color:black;
560
- border-right: solid black 1px;
561
- border-bottom: solid black 1px;
562
- font-style:italic;
563
- font-size:1em;
564
- padding-left:1.2em;
565
- padding-right:1.2em;
566
- text-align:right;
567
- }
568
- h1.apc div.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
569
- h1.apc div.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
570
- h1.apc div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
571
- hr.apc {
572
- background:white;
573
- border-bottom:solid rgb(102,102,153) 1px;
574
- border-style:none;
575
- border-top:solid rgb(102,102,153) 10px;
576
- height:12px;
577
- margin:0;
578
- margin-top:1px;
579
- padding:0;
580
- }
581
-
582
- ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;}
583
- ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%}
584
- ol.menu a {
585
- background:rgb(153,153,204);
586
- border:solid rgb(102,102,153) 2px;
587
- color:white;
588
- font-weight:bold;
589
- margin-right:0em;
590
- padding:0.1em 0.5em 0.1em 0.5em;
591
- text-decoration:none;
592
- margin-left: 5px;
593
- }
594
- ol.menu a.child_active {
595
- background:rgb(153,153,204);
596
- border:solid rgb(102,102,153) 2px;
597
- color:white;
598
- font-weight:bold;
599
- margin-right:0em;
600
- padding:0.1em 0.5em 0.1em 0.5em;
601
- text-decoration:none;
602
- border-left: solid black 5px;
603
- margin-left: 0px;
604
- }
605
- ol.menu span.active {
606
- background:rgb(153,153,204);
607
- border:solid rgb(102,102,153) 2px;
608
- color:black;
609
- font-weight:bold;
610
- margin-right:0em;
611
- padding:0.1em 0.5em 0.1em 0.5em;
612
- text-decoration:none;
613
- border-left: solid black 5px;
614
- }
615
- ol.menu span.inactive {
616
- background:rgb(193,193,244);
617
- border:solid rgb(182,182,233) 2px;
618
- color:white;
619
- font-weight:bold;
620
- margin-right:0em;
621
- padding:0.1em 0.5em 0.1em 0.5em;
622
- text-decoration:none;
623
- margin-left: 5px;
624
- }
625
- ol.menu a:hover {
626
- background:rgb(193,193,244);
627
- text-decoration:none;
628
- }
629
-
630
-
631
- div.info {
632
- background:rgb(204,204,204);
633
- border:solid rgb(204,204,204) 1px;
634
- margin-bottom:1em;
635
- }
636
- div.info h2 {
637
- background:rgb(204,204,204);
638
- color:black;
639
- font-size:1em;
640
- margin:0;
641
- padding:0.1em 1em 0.1em 1em;
642
- }
643
- div.info table {
644
- border:solid rgb(204,204,204) 1px;
645
- border-spacing:0;
646
- width:100%;
647
- }
648
- div.info table th {
649
- background:rgb(204,204,204);
650
- color:white;
651
- margin:0;
652
- padding:0.1em 1em 0.1em 1em;
653
- }
654
- div.info table th a.sortable { color:black; }
655
- div.info table tr.tr-0 { background:rgb(238,238,238); }
656
- div.info table tr.tr-1 { background:rgb(221,221,221); }
657
- div.info table td { padding:0.3em 1em 0.3em 1em; }
658
- div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; }
659
- div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; }
660
- div.info table td h3 {
661
- color:black;
662
- font-size:1.1em;
663
- margin-left:-0.3em;
664
- }
665
-
666
- div.graph { margin-bottom:1em }
667
- div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; }
668
- div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; }
669
- div.graph table td.td-0 { background:rgb(238,238,238); }
670
- div.graph table td.td-1 { background:rgb(221,221,221); }
671
- div.graph table td { padding:0.2em 1em 0.4em 1em; }
672
-
673
- div.div1,div.div2 { margin-bottom:1em; width:35em; }
674
- div.div3 { position:absolute; left:40em; top:1em; width:580px; }
675
- //div.div3 { position:absolute; left:37em; top:1em; right:1em; }
676
-
677
- div.sorting { margin:1.5em 0em 1.5em 2em }
678
- .center { text-align:center }
679
- .aright { position:absolute;right:1em }
680
- .right { text-align:right }
681
- .ok { color:rgb(0,200,0); font-weight:bold}
682
- .failed { color:rgb(200,0,0); font-weight:bold}
683
-
684
- span.box {
685
- border: black solid 1px;
686
- border-right:solid black 2px;
687
- border-bottom:solid black 2px;
688
- padding:0 0.5em 0 0.5em;
689
- margin-right:1em;
690
- }
691
- span.green { background:#60F060; padding:0 0.5em 0 0.5em}
692
- span.red { background:#D06030; padding:0 0.5em 0 0.5em }
693
-
694
- div.authneeded {
695
- background:rgb(238,238,238);
696
- border:solid rgb(204,204,204) 1px;
697
- color:rgb(200,0,0);
698
- font-size:1.2em;
699
- font-weight:bold;
700
- padding:2em;
701
- text-align:center;
702
- }
703
-
704
- input {
705
- background:rgb(153,153,204);
706
- border:solid rgb(102,102,153) 2px;
707
- color:white;
708
- font-weight:bold;
709
- margin-right:1em;
710
- padding:0.1em 0.5em 0.1em 0.5em;
711
- }
712
- //-->
713
- </style>
714
- </head>
715
- <body>
716
- <div class="head">
717
- <h1 class="apc">
718
- <div class="logo"><span class="logo"><a href="http://pecl.php.net/package/APC">APC</a></span></div>
719
- <div class="nameinfo">Opcode Cache</div>
720
- </h1>
721
- <div class="login">
722
- <?php put_login_link(); ?>
723
- </div>
724
- <hr class="apc">
725
- </div>
726
- <?php
727
-
728
-
729
- // Display main Menu
730
- echo <<<EOB
731
- <ol class=menu>
732
- <li><a href="$MY_SELF&OB={$MYREQUEST['OB']}&SH={$MYREQUEST['SH']}">Refresh Data</a></li>
733
- EOB;
734
- echo
735
- menu_entry(1,'View Host Stats'),
736
- menu_entry(2,'System Cache Entries');
737
- if ($AUTHENTICATED) {
738
- echo menu_entry(4,'Per-Directory Entries');
739
- }
740
- echo
741
- menu_entry(3,'User Cache Entries'),
742
- menu_entry(9,'Version Check');
743
-
744
- if ($AUTHENTICATED) {
745
- echo <<<EOB
746
- <li><a class="aright" href="$MY_SELF&CC=1&OB={$MYREQUEST['OB']}" onClick="javascipt:return confirm('Are you sure?');">Clear $cache_mode Cache</a></li>
747
- EOB;
748
- }
749
- echo <<<EOB
750
- </ol>
751
- EOB;
752
-
753
-
754
- // CONTENT
755
- echo <<<EOB
756
- <div class=content>
757
- EOB;
758
-
759
- // MAIN SWITCH STATEMENT
760
-
761
- switch ($MYREQUEST['OB']) {
762
-
763
-
764
-
765
-
766
-
767
- // -----------------------------------------------
768
- // Host Stats
769
- // -----------------------------------------------
770
- case OB_HOST_STATS:
771
- $mem_size = $mem['num_seg']*$mem['seg_size'];
772
- $mem_avail= $mem['avail_mem'];
773
- $mem_used = $mem_size-$mem_avail;
774
- $seg_size = bsize($mem['seg_size']);
775
- $req_rate = sprintf("%.2f",($cache['num_hits']+$cache['num_misses'])/($time-$cache['start_time']));
776
- $hit_rate = sprintf("%.2f",($cache['num_hits'])/($time-$cache['start_time']));
777
- $miss_rate = sprintf("%.2f",($cache['num_misses'])/($time-$cache['start_time']));
778
- $insert_rate = sprintf("%.2f",($cache['num_inserts'])/($time-$cache['start_time']));
779
- $req_rate_user = sprintf("%.2f",($cache_user['num_hits']+$cache_user['num_misses'])/($time-$cache_user['start_time']));
780
- $hit_rate_user = sprintf("%.2f",($cache_user['num_hits'])/($time-$cache_user['start_time']));
781
- $miss_rate_user = sprintf("%.2f",($cache_user['num_misses'])/($time-$cache_user['start_time']));
782
- $insert_rate_user = sprintf("%.2f",($cache_user['num_inserts'])/($time-$cache_user['start_time']));
783
- $apcversion = phpversion('apc');
784
- $phpversion = phpversion();
785
- $number_files = $cache['num_entries'];
786
- $size_files = bsize($cache['mem_size']);
787
- $number_vars = $cache_user['num_entries'];
788
- $size_vars = bsize($cache_user['mem_size']);
789
- $i=0;
790
- echo <<< EOB
791
- <div class="info div1"><h2>General Cache Information</h2>
792
- <table cellspacing=0><tbody>
793
- <tr class=tr-0><td class=td-0>APC Version</td><td>$apcversion</td></tr>
794
- <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
795
- EOB;
796
-
797
- if(!empty($_SERVER['SERVER_NAME']))
798
- echo "<tr class=tr-0><td class=td-0>APC Host</td><td>{$_SERVER['SERVER_NAME']} $host</td></tr>\n";
799
- if(!empty($_SERVER['SERVER_SOFTWARE']))
800
- echo "<tr class=tr-1><td class=td-0>Server Software</td><td>{$_SERVER['SERVER_SOFTWARE']}</td></tr>\n";
801
-
802
- echo <<<EOB
803
- <tr class=tr-0><td class=td-0>Shared Memory</td><td>{$mem['num_seg']} Segment(s) with $seg_size
804
- <br/> ({$cache['memory_type']} memory, {$cache['locking_type']} locking)
805
- </td></tr>
806
- EOB;
807
- echo '<tr class=tr-1><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$cache['start_time']),'</td></tr>';
808
- echo '<tr class=tr-0><td class=td-0>Uptime</td><td>',duration($cache['start_time']),'</td></tr>';
809
- echo '<tr class=tr-1><td class=td-0>File Upload Support</td><td>',$cache['file_upload_progress'],'</td></tr>';
810
- echo <<<EOB
811
- </tbody></table>
812
- </div>
813
-
814
- <div class="info div1"><h2>File Cache Information</h2>
815
- <table cellspacing=0><tbody>
816
- <tr class=tr-0><td class=td-0>Cached Files</td><td>$number_files ($size_files)</td></tr>
817
- <tr class=tr-1><td class=td-0>Hits</td><td>{$cache['num_hits']}</td></tr>
818
- <tr class=tr-0><td class=td-0>Misses</td><td>{$cache['num_misses']}</td></tr>
819
- <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate cache requests/second</td></tr>
820
- <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate cache requests/second</td></tr>
821
- <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate cache requests/second</td></tr>
822
- <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate cache requests/second</td></tr>
823
- <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache['expunges']}</td></tr>
824
- </tbody></table>
825
- </div>
826
-
827
- <div class="info div1"><h2>User Cache Information</h2>
828
- <table cellspacing=0><tbody>
829
- <tr class=tr-0><td class=td-0>Cached Variables</td><td>$number_vars ($size_vars)</td></tr>
830
- <tr class=tr-1><td class=td-0>Hits</td><td>{$cache_user['num_hits']}</td></tr>
831
- <tr class=tr-0><td class=td-0>Misses</td><td>{$cache_user['num_misses']}</td></tr>
832
- <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate_user cache requests/second</td></tr>
833
- <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate_user cache requests/second</td></tr>
834
- <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate_user cache requests/second</td></tr>
835
- <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate_user cache requests/second</td></tr>
836
- <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache_user['expunges']}</td></tr>
837
-
838
- </tbody></table>
839
- </div>
840
-
841
- <div class="info div2"><h2>Runtime Settings</h2><table cellspacing=0><tbody>
842
- EOB;
843
-
844
- $j = 0;
845
- foreach (ini_get_all('apc') as $k => $v) {
846
- echo "<tr class=tr-$j><td class=td-0>",$k,"</td><td>",str_replace(',',',<br />',$v['local_value']),"</td></tr>\n";
847
- $j = 1 - $j;
848
- }
849
-
850
- if($mem['num_seg']>1 || $mem['num_seg']==1 && count($mem['block_lists'][0])>1)
851
- $mem_note = "Memory Usage<br /><font size=-2>(multiple slices indicate fragments)</font>";
852
- else
853
- $mem_note = "Memory Usage";
854
-
855
- echo <<< EOB
856
- </tbody></table>
857
- </div>
858
-
859
- <div class="graph div3"><h2>Host Status Diagrams</h2>
860
- <table cellspacing=0><tbody>
861
- EOB;
862
- $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10);
863
- echo <<<EOB
864
- <tr>
865
- <td class=td-0>$mem_note</td>
866
- <td class=td-1>Hits &amp; Misses</td>
867
- </tr>
868
- EOB;
869
-
870
- echo
871
- graphics_avail() ?
872
- '<tr>'.
873
- "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF?IMG=1&$time\"></td>".
874
- "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF?IMG=2&$time\"></td></tr>\n"
875
- : "",
876
- '<tr>',
877
- '<td class=td-0><span class="green box">&nbsp;</span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n",
878
- '<td class=td-1><span class="green box">&nbsp;</span>Hits: ',$cache['num_hits'].sprintf(" (%.1f%%)",$cache['num_hits']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n",
879
- '</tr>',
880
- '<tr>',
881
- '<td class=td-0><span class="red box">&nbsp;</span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n",
882
- '<td class=td-1><span class="red box">&nbsp;</span>Misses: ',$cache['num_misses'].sprintf(" (%.1f%%)",$cache['num_misses']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n";
883
- echo <<< EOB
884
- </tr>
885
- </tbody></table>
886
-
887
- <br/>
888
- <h2>Detailed Memory Usage and Fragmentation</h2>
889
- <table cellspacing=0><tbody>
890
- <tr>
891
- <td class=td-0 colspan=2><br/>
892
- EOB;
893
-
894
- // Fragementation: (freeseg - 1) / total_seg
895
- $nseg = $freeseg = $fragsize = $freetotal = 0;
896
- for($i=0; $i<$mem['num_seg']; $i++) {
897
- $ptr = 0;
898
- foreach($mem['block_lists'][$i] as $block) {
899
- if ($block['offset'] != $ptr) {
900
- ++$nseg;
901
- }
902
- $ptr = $block['offset'] + $block['size'];
903
- /* Only consider blocks <5M for the fragmentation % */
904
- if($block['size']<(5*1024*1024)) $fragsize+=$block['size'];
905
- $freetotal+=$block['size'];
906
- }
907
- $freeseg += count($mem['block_lists'][$i]);
908
- }
909
-
910
- if ($freeseg > 1) {
911
- $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize/$freetotal)*100,bsize($fragsize),bsize($freetotal),$freeseg);
912
- } else {
913
- $frag = "0%";
914
- }
915
-
916
- if (graphics_avail()) {
917
- $size='width='.(2*GRAPH_SIZE+150).' height='.(GRAPH_SIZE+10);
918
- echo <<<EOB
919
- <img alt="" $size src="$PHP_SELF?IMG=3&$time">
920
- EOB;
921
- }
922
- echo <<<EOB
923
- </br>Fragmentation: $frag
924
- </td>
925
- </tr>
926
- EOB;
927
- if(isset($mem['adist'])) {
928
- foreach($mem['adist'] as $i=>$v) {
929
- $cur = pow(2,$i); $nxt = pow(2,$i+1)-1;
930
- if($i==0) $range = "1";
931
- else $range = "$cur - $nxt";
932
- echo "<tr><th align=right>$range</th><td align=right>$v</td></tr>\n";
933
- }
934
- }
935
- echo <<<EOB
936
- </tbody></table>
937
- </div>
938
- EOB;
939
-
940
- break;
941
-
942
-
943
- // -----------------------------------------------
944
- // User Cache Entries
945
- // -----------------------------------------------
946
- case OB_USER_CACHE:
947
- if (!$AUTHENTICATED) {
948
- echo '<div class="error">You need to login to see the user values here!<br/>&nbsp;<br/>';
949
- put_login_link("Login now!");
950
- echo '</div>';
951
- break;
952
- }
953
- $fieldname='info';
954
- $fieldheading='User Entry Label';
955
- $fieldkey='info';
956
-
957
- // -----------------------------------------------
958
- // System Cache Entries
959
- // -----------------------------------------------
960
- case OB_SYS_CACHE:
961
- if (!isset($fieldname))
962
- {
963
- $fieldname='filename';
964
- $fieldheading='Script Filename';
965
- if(ini_get("apc.stat")) $fieldkey='inode';
966
- else $fieldkey='filename';
967
- }
968
- if (!empty($MYREQUEST['SH']))
969
- {
970
- echo <<< EOB
971
- <div class="info"><table cellspacing=0><tbody>
972
- <tr><th>Attribute</th><th>Value</th></tr>
973
- EOB;
974
-
975
- $m=0;
976
- foreach($scope_list as $j => $list) {
977
- foreach($cache[$list] as $i => $entry) {
978
- if (md5($entry[$fieldkey])!=$MYREQUEST['SH']) continue;
979
- foreach($entry as $k => $value) {
980
- if (!$AUTHENTICATED) {
981
- // hide all path entries if not logged in
982
- $value=preg_replace('/^.*(\\/|\\\\)/','<i>&lt;hidden&gt;</i>/',$value);
983
- }
984
-
985
- if ($k == "num_hits") {
986
- $value=sprintf("%s (%.2f%%)",$value,$value*100/$cache['num_hits']);
987
- }
988
- if ($k == 'deletion_time') {
989
- if(!$entry['deletion_time']) $value = "None";
990
- }
991
- echo
992
- "<tr class=tr-$m>",
993
- "<td class=td-0>",ucwords(preg_replace("/_/"," ",$k)),"</td>",
994
- "<td class=td-last>",(preg_match("/time/",$k) && $value!='None') ? date(DATE_FORMAT,$value) : $value,"</td>",
995
- "</tr>";
996
- $m=1-$m;
997
- }
998
- if($fieldkey=='info') {
999
- echo "<tr class=tr-$m><td class=td-0>Stored Value</td><td class=td-last><pre>";
1000
- $output = var_export(apc_fetch($entry[$fieldkey]),true);
1001
- echo htmlspecialchars($output);
1002
- echo "</pre></td></tr>\n";
1003
- }
1004
- break;
1005
- }
1006
- }
1007
-
1008
- echo <<<EOB
1009
- </tbody></table>
1010
- </div>
1011
- EOB;
1012
- break;
1013
- }
1014
-
1015
- $cols=6;
1016
- echo <<<EOB
1017
- <div class=sorting><form>Scope:
1018
- <input type=hidden name=OB value={$MYREQUEST['OB']}>
1019
- <select name=SCOPE>
1020
- EOB;
1021
- echo
1022
- "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
1023
- "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
1024
- "</select>",
1025
- ", Sorting:<select name=SORT1>",
1026
- "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Hits</option>",
1027
- "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Size</option>",
1028
- "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">$fieldheading</option>",
1029
- "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Last accessed</option>",
1030
- "<option value=M",$MYREQUEST['SORT1']=='M' ? " selected":"",">Last modified</option>",
1031
- "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Created at</option>",
1032
- "<option value=D",$MYREQUEST['SORT1']=='D' ? " selected":"",">Deleted at</option>";
1033
- if($fieldname=='info') echo
1034
- "<option value=D",$MYREQUEST['SORT1']=='T' ? " selected":"",">Timeout</option>";
1035
- echo
1036
- '</select>',
1037
- '<select name=SORT2>',
1038
- '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
1039
- '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
1040
- '</select>',
1041
- '<select name=COUNT onChange="form.submit()">',
1042
- '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
1043
- '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
1044
- '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
1045
- '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
1046
- '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
1047
- '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
1048
- '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
1049
- '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
1050
- '</select>',
1051
- '&nbsp; Search: <input name=SEARCH value="',$MYREQUEST['SEARCH'],'" type=text size=25/>',
1052
- '&nbsp;<input type=submit value="GO!">',
1053
- '</form></div>';
1054
-
1055
- if (isset($MYREQUEST['SEARCH'])) {
1056
- // Don't use preg_quote because we want the user to be able to specify a
1057
- // regular expression subpattern.
1058
- $MYREQUEST['SEARCH'] = '/'.str_replace('/', '\\/', $MYREQUEST['SEARCH']).'/i';
1059
- if (preg_match($MYREQUEST['SEARCH'], 'test') === false) {
1060
- echo '<div class="error">Error: enter a valid regular expression as a search query.</div>';
1061
- break;
1062
- }
1063
- }
1064
-
1065
- echo
1066
- '<div class="info"><table cellspacing=0><tbody>',
1067
- '<tr>',
1068
- '<th>',sortheader('S',$fieldheading, "&OB=".$MYREQUEST['OB']),'</th>',
1069
- '<th>',sortheader('H','Hits', "&OB=".$MYREQUEST['OB']),'</th>',
1070
- '<th>',sortheader('Z','Size', "&OB=".$MYREQUEST['OB']),'</th>',
1071
- '<th>',sortheader('A','Last accessed',"&OB=".$MYREQUEST['OB']),'</th>',
1072
- '<th>',sortheader('M','Last modified',"&OB=".$MYREQUEST['OB']),'</th>',
1073
- '<th>',sortheader('C','Created at', "&OB=".$MYREQUEST['OB']),'</th>';
1074
-
1075
- if($fieldname=='info') {
1076
- $cols+=2;
1077
- echo '<th>',sortheader('T','Timeout',"&OB=".$MYREQUEST['OB']),'</th>';
1078
- }
1079
- echo '<th>',sortheader('D','Deleted at',"&OB=".$MYREQUEST['OB']),'</th></tr>';
1080
-
1081
- // builds list with alpha numeric sortable keys
1082
- //
1083
- $list = array();
1084
- foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $i => $entry) {
1085
- switch($MYREQUEST['SORT1']) {
1086
- case 'A': $k=sprintf('%015d-',$entry['access_time']); break;
1087
- case 'H': $k=sprintf('%015d-',$entry['num_hits']); break;
1088
- case 'Z': $k=sprintf('%015d-',$entry['mem_size']); break;
1089
- case 'M': $k=sprintf('%015d-',$entry['mtime']); break;
1090
- case 'C': $k=sprintf('%015d-',$entry['creation_time']); break;
1091
- case 'T': $k=sprintf('%015d-',$entry['ttl']); break;
1092
- case 'D': $k=sprintf('%015d-',$entry['deletion_time']); break;
1093
- case 'S': $k=''; break;
1094
- }
1095
- if (!$AUTHENTICATED) {
1096
- // hide all path entries if not logged in
1097
- $list[$k.$entry[$fieldname]]=preg_replace('/^.*(\\/|\\\\)/','*hidden*/',$entry);
1098
- } else {
1099
- $list[$k.$entry[$fieldname]]=$entry;
1100
- }
1101
- }
1102
-
1103
- if ($list) {
1104
-
1105
- // sort list
1106
- //
1107
- switch ($MYREQUEST['SORT2']) {
1108
- case "A": krsort($list); break;
1109
- case "D": ksort($list); break;
1110
- }
1111
-
1112
- // output list
1113
- $i=0;
1114
- foreach($list as $k => $entry) {
1115
- if(!$MYREQUEST['SEARCH'] || preg_match($MYREQUEST['SEARCH'], $entry[$fieldname]) != 0) {
1116
- $field_value = htmlentities(strip_tags($entry[$fieldname],''), ENT_QUOTES, 'UTF-8');
1117
- echo
1118
- '<tr class=tr-',$i%2,'>',
1119
- "<td class=td-0><a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&SH=",md5($entry[$fieldkey]),"\">",$field_value,'</a></td>',
1120
- '<td class="td-n center">',$entry['num_hits'],'</td>',
1121
- '<td class="td-n right">',$entry['mem_size'],'</td>',
1122
- '<td class="td-n center">',date(DATE_FORMAT,$entry['access_time']),'</td>',
1123
- '<td class="td-n center">',date(DATE_FORMAT,$entry['mtime']),'</td>',
1124
- '<td class="td-n center">',date(DATE_FORMAT,$entry['creation_time']),'</td>';
1125
-
1126
- if($fieldname=='info') {
1127
- if($entry['ttl'])
1128
- echo '<td class="td-n center">'.$entry['ttl'].' seconds</td>';
1129
- else
1130
- echo '<td class="td-n center">None</td>';
1131
- }
1132
- if ($entry['deletion_time']) {
1133
-
1134
- echo '<td class="td-last center">', date(DATE_FORMAT,$entry['deletion_time']), '</td>';
1135
- } else if ($MYREQUEST['OB'] == OB_USER_CACHE) {
1136
-
1137
- echo '<td class="td-last center">';
1138
- echo '[<a href="', $MY_SELF, '&OB=', $MYREQUEST['OB'], '&DU=', urlencode($entry[$fieldkey]), '">Delete Now</a>]';
1139
- echo '</td>';
1140
- } else {
1141
- echo '<td class="td-last center"> &nbsp; </td>';
1142
- }
1143
- echo '</tr>';
1144
- $i++;
1145
- if ($i == $MYREQUEST['COUNT'])
1146
- break;
1147
- }
1148
- }
1149
-
1150
- } else {
1151
- echo '<tr class=tr-0><td class="center" colspan=',$cols,'><i>No data</i></td></tr>';
1152
- }
1153
- echo <<< EOB
1154
- </tbody></table>
1155
- EOB;
1156
-
1157
- if ($list && $i < count($list)) {
1158
- echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
1159
- }
1160
-
1161
- echo <<< EOB
1162
- </div>
1163
- EOB;
1164
- break;
1165
-
1166
-
1167
- // -----------------------------------------------
1168
- // Per-Directory System Cache Entries
1169
- // -----------------------------------------------
1170
- case OB_SYS_CACHE_DIR:
1171
- if (!$AUTHENTICATED) {
1172
- break;
1173
- }
1174
-
1175
- echo <<<EOB
1176
- <div class=sorting><form>Scope:
1177
- <input type=hidden name=OB value={$MYREQUEST['OB']}>
1178
- <select name=SCOPE>
1179
- EOB;
1180
- echo
1181
- "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
1182
- "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
1183
- "</select>",
1184
- ", Sorting:<select name=SORT1>",
1185
- "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Total Hits</option>",
1186
- "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Total Size</option>",
1187
- "<option value=T",$MYREQUEST['SORT1']=='T' ? " selected":"",">Number of Files</option>",
1188
- "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">Directory Name</option>",
1189
- "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Avg. Size</option>",
1190
- "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Avg. Hits</option>",
1191
- '</select>',
1192
- '<select name=SORT2>',
1193
- '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
1194
- '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
1195
- '</select>',
1196
- '<select name=COUNT onChange="form.submit()">',
1197
- '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
1198
- '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
1199
- '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
1200
- '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
1201
- '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
1202
- '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
1203
- '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
1204
- '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
1205
- '</select>',
1206
- ", Group By Dir Level:<select name=AGGR>",
1207
- "<option value='' selected>None</option>";
1208
- for ($i = 1; $i < 10; $i++)
1209
- echo "<option value=$i",$MYREQUEST['AGGR']==$i ? " selected":"",">$i</option>";
1210
- echo '</select>',
1211
- '&nbsp;<input type=submit value="GO!">',
1212
- '</form></div>',
1213
-
1214
- '<div class="info"><table cellspacing=0><tbody>',
1215
- '<tr>',
1216
- '<th>',sortheader('S','Directory Name', "&OB=".$MYREQUEST['OB']),'</th>',
1217
- '<th>',sortheader('T','Number of Files',"&OB=".$MYREQUEST['OB']),'</th>',
1218
- '<th>',sortheader('H','Total Hits', "&OB=".$MYREQUEST['OB']),'</th>',
1219
- '<th>',sortheader('Z','Total Size', "&OB=".$MYREQUEST['OB']),'</th>',
1220
- '<th>',sortheader('C','Avg. Hits', "&OB=".$MYREQUEST['OB']),'</th>',
1221
- '<th>',sortheader('A','Avg. Size', "&OB=".$MYREQUEST['OB']),'</th>',
1222
- '</tr>';
1223
-
1224
- // builds list with alpha numeric sortable keys
1225
- //
1226
- $tmp = $list = array();
1227
- foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $entry) {
1228
- $n = dirname($entry['filename']);
1229
- if ($MYREQUEST['AGGR'] > 0) {
1230
- $n = preg_replace("!^(/?(?:[^/\\\\]+[/\\\\]){".($MYREQUEST['AGGR']-1)."}[^/\\\\]*).*!", "$1", $n);
1231
- }
1232
- if (!isset($tmp[$n])) {
1233
- $tmp[$n] = array('hits'=>0,'size'=>0,'ents'=>0);
1234
- }
1235
- $tmp[$n]['hits'] += $entry['num_hits'];
1236
- $tmp[$n]['size'] += $entry['mem_size'];
1237
- ++$tmp[$n]['ents'];
1238
- }
1239
-
1240
- foreach ($tmp as $k => $v) {
1241
- switch($MYREQUEST['SORT1']) {
1242
- case 'A': $kn=sprintf('%015d-',$v['size'] / $v['ents']);break;
1243
- case 'T': $kn=sprintf('%015d-',$v['ents']); break;
1244
- case 'H': $kn=sprintf('%015d-',$v['hits']); break;
1245
- case 'Z': $kn=sprintf('%015d-',$v['size']); break;
1246
- case 'C': $kn=sprintf('%015d-',$v['hits'] / $v['ents']);break;
1247
- case 'S': $kn = $k; break;
1248
- }
1249
- $list[$kn.$k] = array($k, $v['ents'], $v['hits'], $v['size']);
1250
- }
1251
-
1252
- if ($list) {
1253
-
1254
- // sort list
1255
- //
1256
- switch ($MYREQUEST['SORT2']) {
1257
- case "A": krsort($list); break;
1258
- case "D": ksort($list); break;
1259
- }
1260
-
1261
- // output list
1262
- $i = 0;
1263
- foreach($list as $entry) {
1264
- echo
1265
- '<tr class=tr-',$i%2,'>',
1266
- "<td class=td-0>",$entry[0],'</a></td>',
1267
- '<td class="td-n center">',$entry[1],'</td>',
1268
- '<td class="td-n center">',$entry[2],'</td>',
1269
- '<td class="td-n center">',$entry[3],'</td>',
1270
- '<td class="td-n center">',round($entry[2] / $entry[1]),'</td>',
1271
- '<td class="td-n center">',round($entry[3] / $entry[1]),'</td>',
1272
- '</tr>';
1273
-
1274
- if (++$i == $MYREQUEST['COUNT']) break;
1275
- }
1276
-
1277
- } else {
1278
- echo '<tr class=tr-0><td class="center" colspan=6><i>No data</i></td></tr>';
1279
- }
1280
- echo <<< EOB
1281
- </tbody></table>
1282
- EOB;
1283
-
1284
- if ($list && $i < count($list)) {
1285
- echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
1286
- }
1287
-
1288
- echo <<< EOB
1289
- </div>
1290
- EOB;
1291
- break;
1292
-
1293
- // -----------------------------------------------
1294
- // Version check
1295
- // -----------------------------------------------
1296
- case OB_VERSION_CHECK:
1297
- echo <<<EOB
1298
- <div class="info"><h2>APC Version Information</h2>
1299
- <table cellspacing=0><tbody>
1300
- <tr>
1301
- <th></th>
1302
- </tr>
1303
- EOB;
1304
- if (defined('PROXY')) {
1305
- $ctxt = stream_context_create( array( 'http' => array( 'proxy' => PROXY, 'request_fulluri' => True ) ) );
1306
- $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss", False, $ctxt);
1307
- } else {
1308
- $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss");
1309
- }
1310
- if (!$rss) {
1311
- echo '<tr class="td-last center"><td>Unable to fetch version information.</td></tr>';
1312
- } else {
1313
- $apcversion = phpversion('apc');
1314
-
1315
- preg_match('!<title>APC ([0-9.]+)</title>!', $rss, $match);
1316
- echo '<tr class="tr-0 center"><td>';
1317
- if (version_compare($apcversion, $match[1], '>=')) {
1318
- echo '<div class="ok">You are running the latest version of APC ('.$apcversion.')</div>';
1319
- $i = 3;
1320
- } else {
1321
- echo '<div class="failed">You are running an older version of APC ('.$apcversion.'),
1322
- newer version '.$match[1].' is available at <a href="http://pecl.php.net/package/APC/'.$match[1].'">
1323
- http://pecl.php.net/package/APC/'.$match[1].'</a>
1324
- </div>';
1325
- $i = -1;
1326
- }
1327
- echo '</td></tr>';
1328
- echo '<tr class="tr-0"><td><h3>Change Log:</h3><br/>';
1329
-
1330
- preg_match_all('!<(title|description)>([^<]+)</\\1>!', $rss, $match);
1331
- next($match[2]); next($match[2]);
1332
-
1333
- while (list(,$v) = each($match[2])) {
1334
- list(,$ver) = explode(' ', $v, 2);
1335
- if ($i < 0 && version_compare($apcversion, $ver, '>=')) {
1336
- break;
1337
- } else if (!$i--) {
1338
- break;
1339
- }
1340
- echo "<b><a href=\"http://pecl.php.net/package/APC/$ver\">".htmlspecialchars($v)."</a></b><br><blockquote>";
1341
- echo nl2br(htmlspecialchars(current($match[2])))."</blockquote>";
1342
- next($match[2]);
1343
- }
1344
- echo '</td></tr>';
1345
- }
1346
- echo <<< EOB
1347
- </tbody></table>
1348
- </div>
1349
- EOB;
1350
- break;
1351
-
1352
- }
1353
-
1354
- echo <<< EOB
1355
- </div>
1356
- EOB;
1357
-
1358
- ?>
1359
-
1360
- <!-- <?php echo "\nBased on APCGUI By R.Becker\n$VERSION\n"?> -->
1361
- </body>
1362
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tools/memcache.php DELETED
@@ -1,880 +0,0 @@
1
- <?php
2
- /*
3
- +----------------------------------------------------------------------+
4
- | PHP Version 5 |
5
- +----------------------------------------------------------------------+
6
- | Copyright (c) 1997-2004 The PHP Group |
7
- +----------------------------------------------------------------------+
8
- | This source file is subject to version 3.0 of the PHP license, |
9
- | that is bundled with this package in the file LICENSE, and is |
10
- | available through the world-wide-web at the following url: |
11
- | http://www.php.net/license/3_0.txt. |
12
- | If you did not receive a copy of the PHP license and are unable to |
13
- | obtain it through the world-wide-web, please send a note to |
14
- | license@php.net so we can mail you a copy immediately. |
15
- +----------------------------------------------------------------------+
16
- | Author: Harun Yayli <harunyayli at gmail.com> |
17
- +----------------------------------------------------------------------+
18
- */
19
-
20
- $VERSION='$Id: memcache.php,v 1.2 2008/09/11 19:21:06 mikl Exp $';
21
-
22
- define('ADMIN_USERNAME','admin'); // Admin Username
23
- define('ADMIN_PASSWORD','totalcache'); // Admin Password
24
- define('DATE_FORMAT','Y/m/d H:i:s');
25
- define('GRAPH_SIZE',200);
26
- define('MAX_ITEM_DUMP',50);
27
-
28
- $MEMCACHE_SERVERS[] = 'localhost:11211'; // add more as an array
29
-
30
-
31
- ////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
32
-
33
- ///////////////// Password protect ////////////////////////////////////////////////////////////////
34
- if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) ||
35
- $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
36
- Header("WWW-Authenticate: Basic realm=\"Memcache Login\"");
37
- Header("HTTP/1.0 401 Unauthorized");
38
-
39
- echo <<<EOB
40
- <html><body>
41
- <h1>Rejected!</h1>
42
- <big>Wrong Username or Password!</big>
43
- </body></html>
44
- EOB;
45
- exit;
46
- }
47
-
48
- ///////////MEMCACHE FUNCTIONS /////////////////////////////////////////////////////////////////////
49
-
50
- function sendMemcacheCommands($command){
51
- global $MEMCACHE_SERVERS;
52
- $result = array();
53
-
54
- foreach($MEMCACHE_SERVERS as $server){
55
- $strs = explode(':',$server);
56
- $host = $strs[0];
57
- $port = $strs[1];
58
- $result[$server] = sendMemcacheCommand($host,$port,$command);
59
- }
60
- return $result;
61
- }
62
- function sendMemcacheCommand($server,$port,$command){
63
-
64
- $s = @fsockopen($server,$port);
65
- if (!$s){
66
- die("Cant connect to:".$server.':'.$port);
67
- }
68
-
69
- fwrite($s, $command."\r\n");
70
-
71
- $buf='';
72
- while ((!feof($s))) {
73
- $buf .= fgets($s, 256);
74
- if (strpos($buf,"END\r\n")!==false){ // stat says end
75
- break;
76
- }
77
- if (strpos($buf,"DELETED\r\n")!==false || strpos($buf,"NOT_FOUND\r\n")!==false){ // delete says these
78
- break;
79
- }
80
- if (strpos($buf,"OK\r\n")!==false){ // flush_all says ok
81
- break;
82
- }
83
- }
84
- fclose($s);
85
- return parseMemcacheResults($buf);
86
- }
87
- function parseMemcacheResults($str){
88
-
89
- $res = array();
90
- $lines = explode("\r\n",$str);
91
- $cnt = count($lines);
92
- for($i=0; $i< $cnt; $i++){
93
- $line = $lines[$i];
94
- $l = explode(' ',$line,3);
95
- if (count($l)==3){
96
- $res[$l[0]][$l[1]]=$l[2];
97
- if ($l[0]=='VALUE'){ // next line is the value
98
- $res[$l[0]][$l[1]] = array();
99
- list ($flag,$size)=explode(' ',$l[2]);
100
- $res[$l[0]][$l[1]]['stat']=array('flag'=>$flag,'size'=>$size);
101
- $res[$l[0]][$l[1]]['value']=$lines[++$i];
102
- }
103
- }elseif($line=='DELETED' || $line=='NOT_FOUND' || $line=='OK'){
104
- return $line;
105
- }
106
- }
107
- return $res;
108
-
109
- }
110
-
111
- function dumpCacheSlab($server,$slabId,$limit){
112
- list($host,$port) = explode(':',$server);
113
- $resp = sendMemcacheCommand($host,$port,'stats cachedump '.$slabId.' '.$limit);
114
-
115
- return $resp;
116
-
117
- }
118
-
119
- function flushServer($server){
120
- list($host,$port) = explode(':',$server);
121
- $resp = sendMemcacheCommand($host,$port,'flush_all');
122
- return $resp;
123
- }
124
- function getCacheItems(){
125
- $items = sendMemcacheCommands('stats items');
126
- $serverItems = array();
127
- $totalItems = array();
128
- foreach ($items as $server=>$itemlist){
129
- $serverItems[$server] = array();
130
- $totalItems[$server]=0;
131
- if (!isset($itemlist['STAT'])){
132
- continue;
133
- }
134
-
135
- $iteminfo = $itemlist['STAT'];
136
-
137
- foreach($iteminfo as $keyinfo=>$value){
138
- if (preg_match('/items\:(\d+?)\:(.+?)$/',$keyinfo,$matches)){
139
- $serverItems[$server][$matches[1]][$matches[2]] = $value;
140
- if ($matches[2]=='number'){
141
- $totalItems[$server] +=$value;
142
- }
143
- }
144
- }
145
- }
146
- return array('items'=>$serverItems,'counts'=>$totalItems);
147
- }
148
- function getMemcacheStats($total=true){
149
- $resp = sendMemcacheCommands('stats');
150
- if ($total){
151
- $res = array();
152
- foreach($resp as $server=>$r){
153
- foreach($r['STAT'] as $key=>$row){
154
- if (!isset($res[$key])){
155
- $res[$key]=null;
156
- }
157
- switch ($key){
158
- case 'pid':
159
- $res['pid'][$server]=$row;
160
- break;
161
- case 'uptime':
162
- $res['uptime'][$server]=$row;
163
- break;
164
- case 'time':
165
- $res['time'][$server]=$row;
166
- break;
167
- case 'version':
168
- $res['version'][$server]=$row;
169
- break;
170
- case 'pointer_size':
171
- $res['pointer_size'][$server]=$row;
172
- break;
173
- case 'rusage_user':
174
- $res['rusage_user'][$server]=$row;
175
- break;
176
- case 'rusage_system':
177
- $res['rusage_system'][$server]=$row;
178
- break;
179
- case 'curr_items':
180
- $res['curr_items']+=$row;
181
- break;
182
- case 'total_items':
183
- $res['total_items']+=$row;
184
- break;
185
- case 'bytes':
186
- $res['bytes']+=$row;
187
- break;
188
- case 'curr_connections':
189
- $res['curr_connections']+=$row;
190
- break;
191
- case 'total_connections':
192
- $res['total_connections']+=$row;
193
- break;
194
- case 'connection_structures':
195
- $res['connection_structures']+=$row;
196
- break;
197
- case 'cmd_get':
198
- $res['cmd_get']+=$row;
199
- break;
200
- case 'cmd_set':
201
- $res['cmd_set']+=$row;
202
- break;
203
- case 'get_hits':
204
- $res['get_hits']+=$row;
205
- break;
206
- case 'get_misses':
207
- $res['get_misses']+=$row;
208
- break;
209
- case 'evictions':
210
- $res['evictions']+=$row;
211
- break;
212
- case 'bytes_read':
213
- $res['bytes_read']+=$row;
214
- break;
215
- case 'bytes_written':
216
- $res['bytes_written']+=$row;
217
- break;
218
- case 'limit_maxbytes':
219
- $res['limit_maxbytes']+=$row;
220
- break;
221
- case 'threads':
222
- $res['rusage_system'][$server]=$row;
223
- break;
224
- }
225
- }
226
- }
227
- return $res;
228
- }
229
- return $resp;
230
- }
231
-
232
- //////////////////////////////////////////////////////
233
-
234
- //
235
- // don't cache this page
236
- //
237
- header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
238
- header("Cache-Control: post-check=0, pre-check=0", false);
239
- header("Pragma: no-cache"); // HTTP/1.0
240
-
241
- function duration($ts) {
242
- global $time;
243
- $years = (int)((($time - $ts)/(7*86400))/52.177457);
244
- $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400));
245
- $weeks = (int)(($rem)/(7*86400));
246
- $days = (int)(($rem)/86400) - $weeks*7;
247
- $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24;
248
- $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60;
249
- $str = '';
250
- if($years==1) $str .= "$years year, ";
251
- if($years>1) $str .= "$years years, ";
252
- if($weeks==1) $str .= "$weeks week, ";
253
- if($weeks>1) $str .= "$weeks weeks, ";
254
- if($days==1) $str .= "$days day,";
255
- if($days>1) $str .= "$days days,";
256
- if($hours == 1) $str .= " $hours hour and";
257
- if($hours>1) $str .= " $hours hours and";
258
- if($mins == 1) $str .= " 1 minute";
259
- else $str .= " $mins minutes";
260
- return $str;
261
- }
262
-
263
- // create graphics
264
- //
265
- function graphics_avail() {
266
- return extension_loaded('gd');
267
- }
268
-
269
- function bsize($s) {
270
- foreach (array('','K','M','G') as $i => $k) {
271
- if ($s < 1024) break;
272
- $s/=1024;
273
- }
274
- return sprintf("%5.1f %sBytes",$s,$k);
275
- }
276
-
277
- // create menu entry
278
- function menu_entry($ob,$title) {
279
- global $PHP_SELF;
280
- if ($ob==$_GET['op']){
281
- return "<li><a class=\"child_active\" href=\"$PHP_SELF&op=$ob\">$title</a></li>";
282
- }
283
- return "<li><a class=\"active\" href=\"$PHP_SELF&op=$ob\">$title</a></li>";
284
- }
285
-
286
- function getHeader(){
287
- $header = <<<EOB
288
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
289
- <html>
290
- <head><title>MEMCACHE INFO</title>
291
- <style type="text/css"><!--
292
- body { background:white; font-size:100.01%; margin:0; padding:0; }
293
- body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; }
294
- * html body {font-size:0.8em}
295
- * html p {font-size:0.8em}
296
- * html td {font-size:0.8em}
297
- * html th {font-size:0.8em}
298
- * html input {font-size:0.8em}
299
- * html submit {font-size:0.8em}
300
- td { vertical-align:top }
301
- a { color:black; font-weight:none; text-decoration:none; }
302
- a:hover { text-decoration:underline; }
303
- div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; }
304
-
305
- h1.memcache { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
306
- * html h1.memcache { margin-bottom:-7px; }
307
- h1.memcache a:hover { text-decoration:none; color:rgb(90,90,90); }
308
- h1.memcache span.logo {
309
- background:rgb(119,123,180);
310
- color:black;
311
- border-right: solid black 1px;
312
- border-bottom: solid black 1px;
313
- font-style:italic;
314
- font-size:1em;
315
- padding-left:1.2em;
316
- padding-right:1.2em;
317
- text-align:right;
318
- display:block;
319
- width:130px;
320
- }
321
- h1.memcache span.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
322
- h1.memcache span.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
323
- h1.memcache div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
324
- hr.memcache {
325
- background:white;
326
- border-bottom:solid rgb(102,102,153) 1px;
327
- border-style:none;
328
- border-top:solid rgb(102,102,153) 10px;
329
- height:12px;
330
- margin:0;
331
- margin-top:1px;
332
- padding:0;
333
- }
334
-
335
- ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;}
336
- ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%}
337
- ol.menu a {
338
- background:rgb(153,153,204);
339
- border:solid rgb(102,102,153) 2px;
340
- color:white;
341
- font-weight:bold;
342
- margin-right:0em;
343
- padding:0.1em 0.5em 0.1em 0.5em;
344
- text-decoration:none;
345
- margin-left: 5px;
346
- }
347
- ol.menu a.child_active {
348
- background:rgb(153,153,204);
349
- border:solid rgb(102,102,153) 2px;
350
- color:white;
351
- font-weight:bold;
352
- margin-right:0em;
353
- padding:0.1em 0.5em 0.1em 0.5em;
354
- text-decoration:none;
355
- border-left: solid black 5px;
356
- margin-left: 0px;
357
- }
358
- ol.menu span.active {
359
- background:rgb(153,153,204);
360
- border:solid rgb(102,102,153) 2px;
361
- color:black;
362
- font-weight:bold;
363
- margin-right:0em;
364
- padding:0.1em 0.5em 0.1em 0.5em;
365
- text-decoration:none;
366
- border-left: solid black 5px;
367
- }
368
- ol.menu span.inactive {
369
- background:rgb(193,193,244);
370
- border:solid rgb(182,182,233) 2px;
371
- color:white;
372
- font-weight:bold;
373
- margin-right:0em;
374
- padding:0.1em 0.5em 0.1em 0.5em;
375
- text-decoration:none;
376
- margin-left: 5px;
377
- }
378
- ol.menu a:hover {
379
- background:rgb(193,193,244);
380
- text-decoration:none;
381
- }
382
-
383
-
384
- div.info {
385
- background:rgb(204,204,204);
386
- border:solid rgb(204,204,204) 1px;
387
- margin-bottom:1em;
388
- }
389
- div.info h2 {
390
- background:rgb(204,204,204);
391
- color:black;
392
- font-size:1em;
393
- margin:0;
394
- padding:0.1em 1em 0.1em 1em;
395
- }
396
- div.info table {
397
- border:solid rgb(204,204,204) 1px;
398
- border-spacing:0;
399
- width:100%;
400
- }
401
- div.info table th {
402
- background:rgb(204,204,204);
403
- color:white;
404
- margin:0;
405
- padding:0.1em 1em 0.1em 1em;
406
- }
407
- div.info table th a.sortable { color:black; }
408
- div.info table tr.tr-0 { background:rgb(238,238,238); }
409
- div.info table tr.tr-1 { background:rgb(221,221,221); }
410
- div.info table td { padding:0.3em 1em 0.3em 1em; }
411
- div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; }
412
- div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; }
413
- div.info table td h3 {
414
- color:black;
415
- font-size:1.1em;
416
- margin-left:-0.3em;
417
- }
418
- .td-0 a , .td-n a, .tr-0 a , tr-1 a {
419
- text-decoration:underline;
420
- }
421
- div.graph { margin-bottom:1em }
422
- div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; }
423
- div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; }
424
- div.graph table td.td-0 { background:rgb(238,238,238); }
425
- div.graph table td.td-1 { background:rgb(221,221,221); }
426
- div.graph table td { padding:0.2em 1em 0.4em 1em; }
427
-
428
- div.div1,div.div2 { margin-bottom:1em; width:35em; }
429
- div.div3 { position:absolute; left:40em; top:1em; width:580px; }
430
- //div.div3 { position:absolute; left:37em; top:1em; right:1em; }
431
-
432
- div.sorting { margin:1.5em 0em 1.5em 2em }
433
- .center { text-align:center }
434
- .aright { position:absolute;right:1em }
435
- .right { text-align:right }
436
- .ok { color:rgb(0,200,0); font-weight:bold}
437
- .failed { color:rgb(200,0,0); font-weight:bold}
438
-
439
- span.box {
440
- border: black solid 1px;
441
- border-right:solid black 2px;
442
- border-bottom:solid black 2px;
443
- padding:0 0.5em 0 0.5em;
444
- margin-right:1em;
445
- }
446
- span.green { background:#60F060; padding:0 0.5em 0 0.5em}
447
- span.red { background:#D06030; padding:0 0.5em 0 0.5em }
448
-
449
- div.authneeded {
450
- background:rgb(238,238,238);
451
- border:solid rgb(204,204,204) 1px;
452
- color:rgb(200,0,0);
453
- font-size:1.2em;
454
- font-weight:bold;
455
- padding:2em;
456
- text-align:center;
457
- }
458
-
459
- input {
460
- background:rgb(153,153,204);
461
- border:solid rgb(102,102,153) 2px;
462
- color:white;
463
- font-weight:bold;
464
- margin-right:1em;
465
- padding:0.1em 0.5em 0.1em 0.5em;
466
- }
467
- //-->
468
- </style>
469
- </head>
470
- <body>
471
- <div class="head">
472
- <h1 class="memcache">
473
- <span class="logo"><a href="http://pecl.php.net/package/memcache">memcache</a></span>
474
- <span class="nameinfo">memcache.php by <a href="http://livebookmark.net">Harun Yayli</a></span>
475
- </h1>
476
- <hr class="memcache">
477
- </div>
478
- <div class=content>
479
- EOB;
480
-
481
- return $header;
482
- }
483
- function getFooter(){
484
- global $VERSION;
485
- $footer = '</div><!-- Based on apc.php '.$VERSION.'--></body>
486
- </html>
487
- ';
488
-
489
- return $footer;
490
-
491
- }
492
- function getMenu(){
493
- global $PHP_SELF;
494
- echo "<ol class=menu>";
495
- if ($_GET['op']!=4){
496
- echo <<<EOB
497
- <li><a href="$PHP_SELF&op={$_GET['op']}">Refresh Data</a></li>
498
- EOB;
499
- }
500
- else {
501
- echo <<<EOB
502
- <li><a href="$PHP_SELF&op=2}">Back</a></li>
503
- EOB;
504
- }
505
- echo
506
- menu_entry(1,'View Host Stats'),
507
- menu_entry(2,'Variables');
508
-
509
- echo <<<EOB
510
- </ol>
511
- <br/>
512
- EOB;
513
- }
514
-
515
- // TODO, AUTH
516
-
517
- $_GET['op'] = !isset($_GET['op'])? '1':$_GET['op'];
518
- $PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],'')) : '';
519
-
520
- $PHP_SELF=$PHP_SELF.'?';
521
- $time = time();
522
- // sanitize _GET
523
-
524
- foreach($_GET as $key=>$g){
525
- $_GET[$key]=htmlentities($g);
526
- }
527
-
528
-
529
- // singleout
530
- // when singleout is set, it only gives details for that server.
531
- if (isset($_GET['singleout']) && $_GET['singleout']>=0 && $_GET['singleout'] <count($MEMCACHE_SERVERS)){
532
- $MEMCACHE_SERVERS = array($MEMCACHE_SERVERS[$_GET['singleout']]);
533
- }
534
-
535
- // display images
536
- if (isset($_GET['IMG'])){
537
- $memcacheStats = getMemcacheStats();
538
- $memcacheStatsSingle = getMemcacheStats(false);
539
-
540
- if (!graphics_avail()) {
541
- exit(0);
542
- }
543
-
544
- function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') {
545
- global $col_black;
546
- $x1=$x+$w-1;
547
- $y1=$y+$h-1;
548
-
549
- imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black);
550
- if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
551
- else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
552
- imagerectangle($im, $x, $y1, $x1, $y, $color1);
553
- if ($text) {
554
- if ($placeindex>0) {
555
-
556
- if ($placeindex<16)
557
- {
558
- $px=5;
559
- $py=$placeindex*12+6;
560
- imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2);
561
- imageline($im,$x,$y+$h/2,$px+90,$py,$color2);
562
- imagestring($im,2,$px,$py-6,$text,$color1);
563
-
564
- } else {
565
- if ($placeindex<31) {
566
- $px=$x+40*2;
567
- $py=($placeindex-15)*12+6;
568
- } else {
569
- $px=$x+40*2+100*intval(($placeindex-15)/15);
570
- $py=($placeindex%15)*12+6;
571
- }
572
- imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2);
573
- imageline($im,$x+$w,$y+$h/2,$px,$py,$color2);
574
- imagestring($im,2,$px+2,$py-6,$text,$color1);
575
- }
576
- } else {
577
- imagestring($im,4,$x+5,$y1-16,$text,$color1);
578
- }
579
- }
580
- }
581
-
582
-
583
- function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) {
584
- $r=$diameter/2;
585
- $w=deg2rad((360+$start+($end-$start)/2)%360);
586
-
587
-
588
- if (function_exists("imagefilledarc")) {
589
- // exists only if GD 2.0.1 is avaliable
590
- imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
591
- imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
592
- imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED);
593
- } else {
594
- imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
595
- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
596
- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
597
- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
598
- imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
599
- imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2);
600
- }
601
- if ($text) {
602
- if ($placeindex>0) {
603
- imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
604
- imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
605
-
606
- } else {
607
- imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
608
- }
609
- }
610
- }
611
- $size = GRAPH_SIZE; // image size
612
- $image = imagecreate($size+50, $size+10);
613
-
614
- $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
615
- $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30);
616
- $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
617
- $col_black = imagecolorallocate($image, 0, 0, 0);
618
-
619
- imagecolortransparent($image,$col_white);
620
-
621
- switch ($_GET['IMG']){
622
- case 1: // pie chart
623
- $tsize=$memcacheStats['limit_maxbytes'];
624
- $avail=$tsize-$memcacheStats['bytes'];
625
- $x=$y=$size/2;
626
- $angle_from = 0;
627
- $fuzz = 0.000001;
628
-
629
- foreach($memcacheStatsSingle as $serv=>$mcs) {
630
- $free = $mcs['STAT']['limit_maxbytes']-$mcs['STAT']['bytes'];
631
- $used = $mcs['STAT']['bytes'];
632
-
633
-
634
- if ($free>0){
635
- // draw free
636
- $angle_to = ($free*360)/$tsize;
637
- $perc =sprintf("%.2f%%", ($free *100) / $tsize) ;
638
-
639
- fill_arc($image,$x,$y,$size,$angle_from,$angle_from + $angle_to ,$col_black,$col_green,$perc);
640
- $angle_from = $angle_from + $angle_to ;
641
- }
642
- if ($used>0){
643
- // draw used
644
- $angle_to = ($used*360)/$tsize;
645
- $perc =sprintf("%.2f%%", ($used *100) / $tsize) ;
646
- fill_arc($image,$x,$y,$size,$angle_from,$angle_from + $angle_to ,$col_black,$col_red, '('.$perc.')' );
647
- $angle_from = $angle_from+ $angle_to ;
648
- }
649
- }
650
-
651
- break;
652
-
653
- case 2: // hit miss
654
-
655
- $hits = ($memcacheStats['get_hits']==0) ? 1:$memcacheStats['get_hits'];
656
- $misses = ($memcacheStats['get_misses']==0) ? 1:$memcacheStats['get_misses'];
657
- $total = $hits + $misses ;
658
-
659
- fill_box($image, 30,$size,50,-$hits*($size-21)/$total,$col_black,$col_green,sprintf("%.1f%%",$hits*100/$total));
660
- fill_box($image,130,$size,50,-max(4,($total-$hits)*($size-21)/$total),$col_black,$col_red,sprintf("%.1f%%",$misses*100/$total));
661
- break;
662
-
663
- }
664
- header("Content-type: image/png");
665
- imagepng($image);
666
- exit;
667
- }
668
-
669
- echo getHeader();
670
- echo getMenu();
671
-
672
- switch ($_GET['op']) {
673
-
674
- case 1: // host stats
675
- $phpversion = phpversion();
676
- $memcacheStats = getMemcacheStats();
677
- $memcacheStatsSingle = getMemcacheStats(false);
678
-
679
- $mem_size = $memcacheStats['limit_maxbytes'];
680
- $mem_used = $memcacheStats['bytes'];
681
- $mem_avail= $mem_size-$mem_used;
682
- $startTime = time()-array_sum($memcacheStats['uptime']);
683
-
684
- $curr_items = $memcacheStats['curr_items'];
685
- $total_items = $memcacheStats['total_items'];
686
- $hits = ($memcacheStats['get_hits']==0) ? 1:$memcacheStats['get_hits'];
687
- $misses = ($memcacheStats['get_misses']==0) ? 1:$memcacheStats['get_misses'];
688
- $sets = $memcacheStats['cmd_set'];
689
-
690
- $req_rate = sprintf("%.2f",($hits+$misses)/($time-$startTime));
691
- $hit_rate = sprintf("%.2f",($hits)/($time-$startTime));
692
- $miss_rate = sprintf("%.2f",($misses)/($time-$startTime));
693
- $set_rate = sprintf("%.2f",($sets)/($time-$startTime));
694
-
695
- echo <<< EOB
696
- <div class="info div1"><h2>General Cache Information</h2>
697
- <table cellspacing=0><tbody>
698
- <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
699
- EOB;
700
- echo "<tr class=tr-0><td class=td-0>Memcached Host". ((count($MEMCACHE_SERVERS)>1) ? 's':'')."</td><td>";
701
- $i=0;
702
- if (!isset($_GET['singleout']) && count($MEMCACHE_SERVERS)>1){
703
- foreach($MEMCACHE_SERVERS as $server){
704
- echo ($i+1).'. <a href="'.$PHP_SELF.'&singleout='.$i++.'">'.$server.'</a><br/>';
705
- }
706
- }
707
- else{
708
- echo '1.'.$MEMCACHE_SERVERS[0];
709
- }
710
- if (isset($_GET['singleout'])){
711
- echo '<a href="'.$PHP_SELF.'">(all servers)</a><br/>';
712
- }
713
- echo "</td></tr>\n";
714
- echo "<tr class=tr-1><td class=td-0>Total Memcache Cache</td><td>".bsize($memcacheStats['limit_maxbytes'])."</td></tr>\n";
715
-
716
- echo <<<EOB
717
- </tbody></table>
718
- </div>
719
-
720
- <div class="info div1"><h2>Memcache Server Information</h2>
721
- EOB;
722
- foreach($MEMCACHE_SERVERS as $server){
723
- echo '<table cellspacing=0><tbody>';
724
- echo '<tr class=tr-1><td class=td-1>'.$server.'</td><td><a href="'.$PHP_SELF.'&server='.array_search($server,$MEMCACHE_SERVERS).'&op=6">[<b>Flush this server</b>]</a></td></tr>';
725
- echo '<tr class=tr-0><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$memcacheStatsSingle[$server]['STAT']['time']-$memcacheStatsSingle[$server]['STAT']['uptime']),'</td></tr>';
726
- echo '<tr class=tr-1><td class=td-0>Uptime</td><td>',duration($memcacheStatsSingle[$server]['STAT']['time']-$memcacheStatsSingle[$server]['STAT']['uptime']),'</td></tr>';
727
- echo '<tr class=tr-0><td class=td-0>Memcached Server Version</td><td>'.$memcacheStatsSingle[$server]['STAT']['version'].'</td></tr>';
728
- echo '<tr class=tr-1><td class=td-0>Used Cache Size</td><td>',bsize($memcacheStatsSingle[$server]['STAT']['bytes']),'</td></tr>';
729
- echo '<tr class=tr-0><td class=td-0>Total Cache Size</td><td>',bsize($memcacheStatsSingle[$server]['STAT']['limit_maxbytes']),'</td></tr>';
730
- echo '</tbody></table>';
731
- }
732
- echo <<<EOB
733
-
734
- </div>
735
- <div class="graph div3"><h2>Host Status Diagrams</h2>
736
- <table cellspacing=0><tbody>
737
- EOB;
738
-
739
- $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10);
740
- echo <<<EOB
741
- <tr>
742
- <td class=td-0>Cache Usage</td>
743
- <td class=td-1>Hits &amp; Misses</td>
744
- </tr>
745
- EOB;
746
-
747
- echo
748
- graphics_avail() ?
749
- '<tr>'.
750
- "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF&IMG=1&".(isset($_GET['singleout'])? 'singleout='.$_GET['singleout'].'&':'')."$time\"></td>".
751
- "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF&IMG=2&".(isset($_GET['singleout'])? 'singleout='.$_GET['singleout'].'&':'')."$time\"></td></tr>\n"
752
- : "",
753
- '<tr>',
754
- '<td class=td-0><span class="green box">&nbsp;</span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n",
755
- '<td class=td-1><span class="green box">&nbsp;</span>Hits: ',$hits.sprintf(" (%.1f%%)",$hits*100/($hits+$misses)),"</td>\n",
756
- '</tr>',
757
- '<tr>',
758
- '<td class=td-0><span class="red box">&nbsp;</span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n",
759
- '<td class=td-1><span class="red box">&nbsp;</span>Misses: ',$misses.sprintf(" (%.1f%%)",$misses*100/($hits+$misses)),"</td>\n";
760
- echo <<< EOB
761
- </tr>
762
- </tbody></table>
763
- <br/>
764
- <div class="info"><h2>Cache Information</h2>
765
- <table cellspacing=0><tbody>
766
- <tr class=tr-0><td class=td-0>Current Items(total)</td><td>$curr_items ($total_items)</td></tr>
767
- <tr class=tr-1><td class=td-0>Hits</td><td>{$hits}</td></tr>
768
- <tr class=tr-0><td class=td-0>Misses</td><td>{$misses}</td></tr>
769
- <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate cache requests/second</td></tr>
770
- <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate cache requests/second</td></tr>
771
- <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate cache requests/second</td></tr>
772
- <tr class=tr-0><td class=td-0>Set Rate</td><td>$set_rate cache requests/second</td></tr>
773
- </tbody></table>
774
- </div>
775
-
776
- EOB;
777
-
778
- break;
779
-
780
- case 2: // variables
781
-
782
- $m=0;
783
- $cacheItems= getCacheItems();
784
- $items = $cacheItems['items'];
785
- $totals = $cacheItems['counts'];
786
- $maxDump = MAX_ITEM_DUMP;
787
- foreach($items as $server => $entries) {
788
-
789
- echo <<< EOB
790
-
791
- <div class="info"><table cellspacing=0><tbody>
792
- <tr><th colspan="2">$server</th></tr>
793
- <tr><th>Slab Id</th><th>Info</th></tr>
794
- EOB;
795
-
796
- foreach($entries as $slabId => $slab) {
797
- $dumpUrl = $PHP_SELF.'&op=2&server='.(array_search($server,$MEMCACHE_SERVERS)).'&dumpslab='.$slabId;
798
- echo
799
- "<tr class=tr-$m>",
800
- "<td class=td-0><center>",'<a href="',$dumpUrl,'">',$slabId,'</a>',"</center></td>",
801
- "<td class=td-last><b>Item count:</b> ",$slab['number'],'<br/><b>Age:</b>',duration($time-$slab['age']),'<br/> <b>Evicted:</b>',((isset($slab['evicted']) && $slab['evicted']==1)? 'Yes':'No');
802
- if ((isset($_GET['dumpslab']) && $_GET['dumpslab']==$slabId) && (isset($_GET['server']) && $_GET['server']==array_search($server,$MEMCACHE_SERVERS))){
803
- echo "<br/><b>Items: item</b><br/>";
804
- $items = dumpCacheSlab($server,$slabId,$slab['number']);
805
- // maybe someone likes to do a pagination here :)
806
- $i=1;
807
- foreach($items['ITEM'] as $itemKey=>$itemInfo){
808
- $itemInfo = trim($itemInfo,'[ ]');
809
-
810
-
811
- echo '<a href="',$PHP_SELF,'&op=4&server=',(array_search($server,$MEMCACHE_SERVERS)),'&key=',base64_encode($itemKey).'">',$itemKey,'</a>';
812
- if ($i++ % 10 == 0) {
813
- echo '<br/>';
814
- }
815
- elseif ($i!=$slab['number']+1){
816
- echo ',';
817
- }
818
- }
819
- }
820
-
821
- echo "</td></tr>";
822
- $m=1-$m;
823
- }
824
- echo <<<EOB
825
- </tbody></table>
826
- </div><hr/>
827
- EOB;
828
- }
829
- break;
830
-
831
- break;
832
-
833
- case 4: //item dump
834
- if (!isset($_GET['key']) || !isset($_GET['server'])){
835
- echo "No key set!";
836
- break;
837
- }
838
- // I'm not doing anything to check the validity of the key string.
839
- // probably an exploit can be written to delete all the files in key=base64_encode("\n\r delete all").
840
- // somebody has to do a fix to this.
841
- $theKey = htmlentities(base64_decode($_GET['key']));
842
-
843
- $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
844
- list($h,$p) = explode(':',$theserver);
845
- $r = sendMemcacheCommand($h,$p,'get '.$theKey);
846
- echo <<<EOB
847
- <div class="info"><table cellspacing=0><tbody>
848
- <tr><th>Server<th>Key</th><th>Value</th><th>Delete</th></tr>
849
- EOB;
850
- echo "<tr><td class=td-0>",$theserver,"</td><td class=td-0>",$theKey,
851
- " <br/>flag:",$r['VALUE'][$theKey]['stat']['flag'],
852
- " <br/>Size:",bsize($r['VALUE'][$theKey]['stat']['size']),
853
- "</td><td>",chunk_split($r['VALUE'][$theKey]['value'],40),"</td>",
854
- '<td><a href="',$PHP_SELF,'&op=5&server=',(int)$_GET['server'],'&key=',base64_encode($theKey),"\">Delete</a></td>","</tr>";
855
- echo <<<EOB
856
- </tbody></table>
857
- </div><hr/>
858
- EOB;
859
- break;
860
- case 5: // item delete
861
- if (!isset($_GET['key']) || !isset($_GET['server'])){
862
- echo "No key set!";
863
- break;
864
- }
865
- $theKey = htmlentities(base64_decode($_GET['key']));
866
- $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
867
- list($h,$p) = explode(':',$theserver);
868
- $r = sendMemcacheCommand($h,$p,'delete '.$theKey);
869
- echo 'Deleting '.$theKey.':'.$r;
870
- break;
871
-
872
- case 6: // flush server
873
- $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
874
- $r = flushServer($theserver);
875
- echo 'Flush '.$theserver.":".$r;
876
- break;
877
- }
878
- echo getFooter();
879
-
880
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tools/phpinfo.php DELETED
@@ -1,2 +0,0 @@
1
- <?php
2
- phpinfo();
 
 
w3-total-cache-config-default.php DELETED
@@ -1,157 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * W3 Total Cache default configuration
5
- */
6
- return array(
7
- /**
8
- * DbCache configuration
9
- */
10
- 'dbcache.enabled' => true,
11
- 'dbcache.debug' => false,
12
- 'dbcache.engine' => 'memcached',
13
- 'dbcache.memcached.engine' => 'auto',
14
- 'dbcache.memcached.servers' => array(
15
- 'localhost:11211'
16
- ),
17
- 'dbcache.reject.admin' => false,
18
- 'dbcache.reject.uri' => array(),
19
- 'dbcache.reject.cookie' => array(),
20
- 'dbcache.reject.sql' => array(),
21
- 'dbcache.lifetime' => 180,
22
-
23
- /**
24
- * PgCache configuration
25
- */
26
- 'pgcache.enabled' => true,
27
- 'pgcache.debug' => false,
28
- 'pgcache.engine' => 'file',
29
- 'pgcache.memcached.engine' => 'auto',
30
- 'pgcache.memcached.servers' => array(
31
- 'localhost:11211'
32
- ),
33
- 'pgcache.lifetime' => 3600,
34
- 'pgcache.compress' => true,
35
- 'pgcache.cache.query' => true,
36
- 'pgcache.cache.home' => true,
37
- 'pgcache.cache.feed' => true,
38
- 'pgcache.cache.404' => true,
39
- 'pgcache.cache.flush' => false,
40
- 'pgcache.cache.headers' => array(
41
- 'Last-Modified',
42
- 'Content-Type',
43
- 'X-Pingback'
44
- ),
45
- 'pgcache.accept.files' => array(
46
- 'wp-comments-popup.php',
47
- 'wp-links-opml.php',
48
- 'wp-locations.php'
49
- ),
50
- 'pgcache.reject.logged' => true,
51
- 'pgcache.reject.uri' => array(
52
- 'wp-.*\.php',
53
- 'index\.php'
54
- ),
55
- 'pgcache.reject.ua' => array(
56
- 'bot',
57
- 'ia_archive',
58
- 'slurp',
59
- 'crawl',
60
- 'spider'
61
- ),
62
- 'pgcache.reject.cookie' => array(),
63
- 'pgcache.mobile.check' => false,
64
- 'pgcache.mobile.whitelist' => array(),
65
- 'pgcache.mobile.browsers' => array(),
66
-
67
- /**
68
- * Minify configuration
69
- */
70
- 'minify.enabled' => true,
71
- 'minify.debug' => false,
72
- 'minify.engine' => 'file',
73
- 'minify.memcached.engine' => 'auto',
74
- 'minify.memcached.servers' => array(
75
- 'localhost:11211'
76
- ),
77
- 'minify.rewrite' => true,
78
- 'minify.locking' => true,
79
- 'minify.fixtime' => 0,
80
- 'minify.symlinks' => array(),
81
- 'minify.compress' => true,
82
- 'minify.compress.ie6' => true,
83
- 'minify.options' => array(
84
- 'bubbleCssImports' => false,
85
- 'maxAge' => 1800,
86
- 'minApp' => array(
87
- 'groupsOnly' => false,
88
- 'maxFiles' => 20
89
- )
90
- ),
91
- 'minify.lifetime' => 3600,
92
- 'minify.upload' => true,
93
- 'minify.html.enable' => true,
94
- 'minify.html.reject.admin' => true,
95
- 'minify.html.inline.css' => false,
96
- 'minify.html.inline.js' => false,
97
- 'minify.html.strip.crlf' => false,
98
- 'minify.css.enable' => true,
99
- 'minify.css.strip.comments' => false,
100
- 'minify.css.strip.crlf' => false,
101
- 'minify.css.groups' => array(),
102
- 'minify.js.enable' => true,
103
- 'minify.js.combine.header' => false,
104
- 'minify.js.combine.footer' => false,
105
- 'minify.js.strip.comments' => false,
106
- 'minify.js.strip.crlf' => false,
107
- 'minify.js.groups' => array(),
108
- 'minify.reject.ua' => array(),
109
- 'minify.reject.uri' => array(),
110
-
111
- /**
112
- * CDN configuration
113
- */
114
- 'cdn.enabled' => false,
115
- 'cdn.debug' => false,
116
- 'cdn.engine' => 'ftp',
117
- 'cdn.domain' => '',
118
- 'cdn.includes.enable' => true,
119
- 'cdn.includes.files' => '*.css;*.js;*.gif;*.png;*.jpg;*.xml',
120
- 'cdn.theme.enable' => true,
121
- 'cdn.theme.files' => '*.css;*.js;*.gif;*.png;*.jpg;*.ico',
122
- 'cdn.minify.enable' => true,
123
- 'cdn.custom.enable' => true,
124
- 'cdn.custom.files' => array(
125
- 'favicon.ico'
126
- ),
127
- 'cdn.import.external' => false,
128
- 'cdn.import.files' => '*.jpg;*.png;*.gif;*.avi;*.wmv;*.mpg;*.wav;*.mp3;*.txt;*.rtf;*.doc;*.xls;*.rar;*.zip;*.tar;*.gz;*.exe',
129
- 'cdn.limit.queue' => 25,
130
- 'cdn.ftp.host' => '',
131
- 'cdn.ftp.user' => '',
132
- 'cdn.ftp.pass' => '',
133
- 'cdn.ftp.path' => '',
134
- 'cdn.ftp.pasv' => false,
135
- 'cdn.reject.ua' => array(
136
- 'bot',
137
- 'ia_archive',
138
- 'slurp',
139
- 'crawl',
140
- 'spider'
141
- ),
142
- 'cdn.reject.uri' => array(),
143
-
144
- /**
145
- * Common configuration
146
- */
147
- 'common.support.enabled' => true,
148
- 'common.support.type' => 'footer',
149
-
150
- /**
151
- * Notes configuration
152
- */
153
- 'notes.defaults' => true,
154
- 'notes.wp_content_perms' => true,
155
- 'notes.cdn_first_time' => true,
156
- 'notes.no_memcached_nor_apc' => true
157
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
w3-total-cache-config-example.php ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ return array(
4
+ 'dbcache.enabled' => true,
5
+ 'dbcache.debug' => false,
6
+ 'dbcache.engine' => 'file',
7
+ 'dbcache.file.gc' => 3600,
8
+ 'dbcache.memcached.engine' => 'auto',
9
+ 'dbcache.memcached.servers' => array(
10
+ 'localhost:11211'
11
+ ),
12
+ 'dbcache.reject.logged' => true,
13
+ 'dbcache.reject.uri' => array(),
14
+ 'dbcache.reject.cookie' => array(),
15
+ 'dbcache.reject.sql' => array(),
16
+ 'dbcache.lifetime' => 180,
17
+ 'pgcache.enabled' => true,
18
+ 'pgcache.debug' => false,
19
+ 'pgcache.engine' => 'file',
20
+ 'pgcache.file.gc' => 3600,
21
+ 'pgcache.memcached.engine' => 'auto',
22
+ 'pgcache.memcached.servers' => array(
23
+ 'localhost:11211'
24
+ ),
25
+ 'pgcache.lifetime' => 3600,
26
+ 'pgcache.compression' => 'gzip',
27
+ 'pgcache.cache.query' => true,
28
+ 'pgcache.cache.home' => true,
29
+ 'pgcache.cache.feed' => true,
30
+ 'pgcache.cache.404' => false,
31
+ 'pgcache.cache.flush' => false,
32
+ 'pgcache.cache.headers' => array(
33
+ 'Last-Modified',
34
+ 'Content-Type',
35
+ 'X-Pingback'
36
+ ),
37
+ 'pgcache.accept.files' => array(
38
+ 'wp-comments-popup.php',
39
+ 'wp-links-opml.php',
40
+ 'wp-locations.php'
41
+ ),
42
+ 'pgcache.reject.logged' => true,
43
+ 'pgcache.reject.uri' => array(
44
+ 'wp-.*\.php',
45
+ 'index\.php'
46
+ ),
47
+ 'pgcache.reject.ua' => array(
48
+ 'bot',
49
+ 'ia_archive',
50
+ 'slurp',
51
+ 'crawl',
52
+ 'spider'
53
+ ),
54
+ 'pgcache.reject.cookie' => array(),
55
+ 'pgcache.mobile.redirect' => '',
56
+ 'pgcache.mobile.agents' => array(
57
+ 'Android',
58
+ '2.0 MMP',
59
+ '240x320',
60
+ 'AvantGo',
61
+ 'BlackBerry',
62
+ 'Blazer',
63
+ 'Cellphone',
64
+ 'Danger',
65
+ 'DoCoMo',
66
+ 'Elaine/3.0',
67
+ 'EudoraWeb',
68
+ 'hiptop',
69
+ 'IEMobile',
70
+ 'iPhone',
71
+ 'iPod',
72
+ 'KYOCERA/WX310K',
73
+ 'LG/U990',
74
+ 'MIDP-2.0',
75
+ 'MMEF20',
76
+ 'MOT-V',
77
+ 'NetFront',
78
+ 'Newt',
79
+ 'Nintendo Wii',
80
+ 'Nitro',
81
+ 'Nokia',
82
+ 'Opera Mini',
83
+ 'Palm',
84
+ 'Playstation Portable',
85
+ 'portalmmm',
86
+ 'Proxinet',
87
+ 'ProxiNet',
88
+ 'SHARP-TQ-GX10',
89
+ 'Small',
90
+ 'SonyEricsson',
91
+ 'Symbian OS',
92
+ 'SymbianOS',
93
+ 'TS21i-10',
94
+ 'UP.Browser',
95
+ 'UP.Link',
96
+ 'Windows CE',
97
+ 'WinWAP',
98
+ 'Ericsson',
99
+ 'htc',
100
+ 'Huawei',
101
+ 'MobilePhone',
102
+ 'Motorola',
103
+ 'nokia',
104
+ 'Novarra',
105
+ 'O2',
106
+ 'Samsung',
107
+ 'Sanyo',
108
+ 'Smartphone',
109
+ 'Symbian',
110
+ 'Toshiba',
111
+ 'Treo',
112
+ 'vodafone',
113
+ 'Xda',
114
+ 'Alcatel',
115
+ 'Amoi',
116
+ 'ASUS',
117
+ 'Audiovox',
118
+ 'AU-MIC',
119
+ 'BenQ',
120
+ 'Bird',
121
+ 'CDM',
122
+ 'dopod',
123
+ 'Fly',
124
+ 'Haier',
125
+ 'HP.iPAQ',
126
+ 'i-mobile',
127
+ 'KDDI',
128
+ 'KONKA',
129
+ 'KWC',
130
+ 'Lenovo',
131
+ 'LG',
132
+ 'NEWGEN',
133
+ 'Panasonic',
134
+ 'PANTECH',
135
+ 'PG',
136
+ 'Philips',
137
+ 'PPC',
138
+ 'PT',
139
+ 'Qtek',
140
+ 'Sagem',
141
+ 'SCH',
142
+ 'SEC',
143
+ 'Sendo',
144
+ 'SGH',
145
+ 'Sharp',
146
+ 'SIE',
147
+ 'SoftBank',
148
+ 'SPH',
149
+ 'UTS',
150
+ 'Vertu',
151
+ 'Opera.Mobi',
152
+ 'Windows.CE',
153
+ 'ZTE'
154
+ ),
155
+
156
+ 'minify.enabled' => true,
157
+ 'minify.debug' => false,
158
+ 'minify.engine' => 'file',
159
+ 'minify.file.locking' => true,
160
+ 'minify.file.gc' => 86400,
161
+ 'minify.memcached.engine' => 'auto',
162
+ 'minify.memcached.servers' => array(
163
+ 'localhost:11211'
164
+ ),
165
+ 'minify.rewrite' => true,
166
+ 'minify.fixtime' => 0,
167
+ 'minify.compress' => true,
168
+ 'minify.compress.ie6' => true,
169
+ 'minify.options' => array(
170
+ 'bubbleCssImports' => false,
171
+ 'minApp' => array(
172
+ 'groupsOnly' => false,
173
+ 'maxFiles' => 20
174
+ )
175
+ ),
176
+ 'minify.symlinks' => array(),
177
+ 'minify.maxage' => 86400,
178
+ 'minify.lifetime' => 86400,
179
+ 'minify.upload' => true,
180
+ 'minify.html.enable' => true,
181
+ 'minify.html.reject.admin' => true,
182
+ 'minify.html.inline.css' => false,
183
+ 'minify.html.inline.js' => false,
184
+ 'minify.html.strip.crlf' => false,
185
+ 'minify.css.enable' => true,
186
+ 'minify.css.strip.comments' => false,
187
+ 'minify.css.strip.crlf' => false,
188
+ 'minify.css.groups' => array(),
189
+ 'minify.js.enable' => true,
190
+ 'minify.js.combine.header' => false,
191
+ 'minify.js.combine.footer' => false,
192
+ 'minify.js.strip.comments' => false,
193
+ 'minify.js.strip.crlf' => false,
194
+ 'minify.js.groups' => array(),
195
+ 'minify.reject.ua' => array(),
196
+ 'minify.reject.uri' => array(),
197
+ 'cdn.enabled' => false,
198
+ 'cdn.debug' => false,
199
+ 'cdn.engine' => 'ftp',
200
+ 'cdn.includes.enable' => true,
201
+ 'cdn.includes.files' => '*.css;*.js;*.gif;*.png;*.jpg',
202
+ 'cdn.theme.enable' => true,
203
+ 'cdn.theme.files' => '*.css;*.js;*.gif;*.png;*.jpg;*.ico',
204
+ 'cdn.minify.enable' => true,
205
+ 'cdn.custom.enable' => true,
206
+ 'cdn.custom.files' => array(
207
+ 'favicon.ico'
208
+ ),
209
+ 'cdn.import.external' => false,
210
+ 'cdn.import.files' => '*.jpg;*.png;*.gif;*.avi;*.wmv;*.mpg;*.wav;*.mp3;*.txt;*.rtf;*.doc;*.xls;*.rar;*.zip;*.tar;*.gz;*.exe',
211
+ 'cdn.limit.queue' => 25,
212
+ 'cdn.mirror.domain' => '',
213
+ 'cdn.ftp.host' => '',
214
+ 'cdn.ftp.user' => '',
215
+ 'cdn.ftp.pass' => '',
216
+ 'cdn.ftp.path' => '',
217
+ 'cdn.ftp.pasv' => false,
218
+ 'cdn.ftp.domain' => '',
219
+ 'cdn.s3.key' => '',
220
+ 'cdn.s3.secret' => '',
221
+ 'cdn.s3.bucket' => '',
222
+ 'cdn.cf.key' => '',
223
+ 'cdn.cf.secret' => '',
224
+ 'cdn.cf.bucket' => '',
225
+ 'cdn.cf.id' => '',
226
+ 'cdn.cf.cname' => '',
227
+ 'cdn.reject.ua' => array(),
228
+ 'cdn.reject.uri' => array(),
229
+ 'common.support' => '',
230
+ 'common.install' => 0,
231
+ 'common.tweeted' => 0,
232
+ 'common.widget.latest' => true,
233
+ 'notes.defaults' => true,
234
+ 'notes.wp_content_perms' => true,
235
+ 'notes.cdn_first_time' => true,
236
+ 'notes.no_memcached_nor_apc' => true,
237
+ 'notes.php_is_old' => true,
238
+ 'notes.theme_changed' => false,
239
+ 'notes.wp_upgraded' => false,
240
+ 'notes.plugins_updated' => false,
241
+ 'notes.cdn_upload' => false,
242
+ 'notes.need_empty_pgcache' => false,
243
+ 'notes.need_empty_minify' => false,
244
+ 'notes.pgcache_rules_core' => true,
245
+ 'notes.pgcache_rules_cache' => true,
246
+ 'notes.minify_rules' => true,
247
+ 'notes.support_us' => true,
248
+ 'notes.no_curl' => true
249
+ );
w3-total-cache.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
  /*
3
  Plugin Name: W3 Total Cache
4
- Description: Dramatically improve the user experience of your blog. Add transparent page caching, database caching, minify and content delivery network (CDN) functionality and more to WordPress.
5
- Version: 0.8
6
  Plugin URI: http://www.w3-edge.com/wordpress-plugins/w3-total-cache/
7
  Author: Frederick Townes
8
  Author URI: http://www.linkedin.com/in/w3edge
@@ -35,9 +35,14 @@ Author URI: http://www.linkedin.com/in/w3edge
35
  */
36
  require_once dirname(__FILE__) . '/inc/define.php';
37
 
 
 
 
 
 
38
  /**
39
  * Run plugin
40
  */
41
  require_once W3TC_DIR . '/lib/W3/Plugin/TotalCache.php';
42
- $w3_plugin_totalcache = W3_Plugin_TotalCache::instance();
43
  $w3_plugin_totalcache->run();
1
  <?php
2
  /*
3
  Plugin Name: W3 Total Cache
4
+ Description: The fastest and most complete WordPress performance plugin. Dramatically improve the user experience of your blog by adding: page caching, database caching, minify, content delivery network (CDN) functionality and more...
5
+ Version: 0.8.5
6
  Plugin URI: http://www.w3-edge.com/wordpress-plugins/w3-total-cache/
7
  Author: Frederick Townes
8
  Author URI: http://www.linkedin.com/in/w3edge
35
  */
36
  require_once dirname(__FILE__) . '/inc/define.php';
37
 
38
+ /**
39
+ * Load plugins
40
+ */
41
+ w3_load_plugins();
42
+
43
  /**
44
  * Run plugin
45
  */
46
  require_once W3TC_DIR . '/lib/W3/Plugin/TotalCache.php';
47
+ $w3_plugin_totalcache = & W3_Plugin_TotalCache::instance();
48
  $w3_plugin_totalcache->run();
wp-content/advanced-cache.php CHANGED
@@ -8,7 +8,7 @@ if (! defined('W3TC_DIR')) {
8
  }
9
 
10
  if (! is_dir(W3TC_DIR) || ! file_exists(W3TC_DIR . '/inc/define.php')) {
11
- die(sprintf('<strong>W3 Total Cache Error:</strong> plugin seems to be broken. Please re-install plugin or remove <strong>%s</strong>.', __FILE__));
12
  }
13
 
14
  require_once W3TC_DIR . '/inc/define.php';
@@ -16,6 +16,6 @@ require_once W3TC_DIR . '/inc/define.php';
16
  if (file_exists(W3TC_CONFIG_PATH)) {
17
  require_once W3TC_DIR . '/lib/W3/PgCache.php';
18
 
19
- $w3_pgcache = W3_PgCache::instance();
20
  $w3_pgcache->process();
21
  }
8
  }
9
 
10
  if (! is_dir(W3TC_DIR) || ! file_exists(W3TC_DIR . '/inc/define.php')) {
11
+ die(sprintf('<strong>W3 Total Cache Error:</strong> some files appear to be missing or out of place. Please re-install plugin or remove <strong>%s</strong>.', __FILE__));
12
  }
13
 
14
  require_once W3TC_DIR . '/inc/define.php';
16
  if (file_exists(W3TC_CONFIG_PATH)) {
17
  require_once W3TC_DIR . '/lib/W3/PgCache.php';
18
 
19
+ $w3_pgcache = & W3_PgCache::instance();
20
  $w3_pgcache->process();
21
  }
wp-content/db.php CHANGED
@@ -8,7 +8,7 @@ if (! defined('W3TC_DIR')) {
8
  }
9
 
10
  if (! is_dir(W3TC_DIR) || ! file_exists(W3TC_DIR . '/inc/define.php')) {
11
- die(sprintf('<strong>W3 Total Cache Error:</strong> plugin seems to be broken. Please re-install plugin or remove <strong>%s</strong>.', __FILE__));
12
  }
13
 
14
  require_once W3TC_DIR . '/inc/define.php';
@@ -16,7 +16,7 @@ require_once W3TC_DIR . '/inc/define.php';
16
  if (file_exists(W3TC_CONFIG_PATH)) {
17
  require_once W3TC_DIR . '/lib/W3/Db.php';
18
 
19
- $wpdb = W3_Db::instance();
20
  } else {
21
  require_once ABSPATH . WPINC . '/wp-db.php';
22
  }
8
  }
9
 
10
  if (! is_dir(W3TC_DIR) || ! file_exists(W3TC_DIR . '/inc/define.php')) {
11
+ die(sprintf('<strong>W3 Total Cache Error:</strong> some files appear to be missing or out of place. Please re-install plugin or remove <strong>%s</strong>.', __FILE__));
12
  }
13
 
14
  require_once W3TC_DIR . '/inc/define.php';
16
  if (file_exists(W3TC_CONFIG_PATH)) {
17
  require_once W3TC_DIR . '/lib/W3/Db.php';
18
 
19
+ $GLOBALS['wpdb'] = & W3_Db::instance();
20
  } else {
21
  require_once ABSPATH . WPINC . '/wp-db.php';
22
  }
wp-content/w3tc/_htaccess DELETED
@@ -1,10 +0,0 @@
1
- # BEGIN W3 Minify module rewrite rules
2
- <IfModule mod_rewrite.c>
3
- RewriteEngine On
4
- RewriteRule ^([a-z0-9-_]+)\.(include(-footer)?(-nb)?)\.(css|js)$ minify.php?gg=$1&g=$2&t=$5
5
- </IfModule>
6
- # END W3 Minify module rewrite rules
7
-
8
- # BEGIN Prevent directory listing
9
- Options -Indexes
10
- # END Prevent directory listing
 
 
 
 
 
 
 
 
 
 
wp-content/w3tc/index.html DELETED
File without changes
wp-content/w3tc/{minify.php → min/index.php} RENAMED
@@ -4,7 +4,7 @@
4
  * W3 Total Cache Minify module
5
  */
6
  if (! defined('ABSPATH')) {
7
- require_once dirname(__FILE__) . '/../../wp-load.php';
8
  }
9
 
10
  if (! defined('W3TC_DIR')) {
@@ -12,7 +12,7 @@ if (! defined('W3TC_DIR')) {
12
  }
13
 
14
  if (! is_dir(W3TC_DIR) || ! file_exists(W3TC_DIR . '/inc/define.php')) {
15
- die(sprintf('<strong>W3 Total Cache Error:</strong> plugin seems to be broken. Please re-install plugin or remove <strong>%s</strong>.', dirname(__FILE__)));
16
  }
17
 
18
  require_once W3TC_DIR . '/inc/define.php';
@@ -20,6 +20,6 @@ require_once W3TC_DIR . '/inc/define.php';
20
  if (file_exists(W3TC_CONFIG_PATH)) {
21
  require_once W3TC_DIR . '/lib/W3/Minify.php';
22
 
23
- $w3_minify = W3_Minify::instance();
24
  $w3_minify->process();
25
  }
4
  * W3 Total Cache Minify module
5
  */
6
  if (! defined('ABSPATH')) {
7
+ require_once dirname(__FILE__) . '/../../../wp-load.php';
8
  }
9
 
10
  if (! defined('W3TC_DIR')) {
12
  }
13
 
14
  if (! is_dir(W3TC_DIR) || ! file_exists(W3TC_DIR . '/inc/define.php')) {
15
+ die(sprintf('<strong>W3 Total Cache Error:</strong> some files appear to be missing or out of place. Please re-install plugin or remove <strong>%s</strong>.', dirname(__FILE__)));
16
  }
17
 
18
  require_once W3TC_DIR . '/inc/define.php';
20
  if (file_exists(W3TC_CONFIG_PATH)) {
21
  require_once W3TC_DIR . '/lib/W3/Minify.php';
22
 
23
+ $w3_minify = & W3_Minify::instance();
24
  $w3_minify->process();
25
  }