PageRenderTime 5820ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-content/plugins/w3-total-cache/lib/W3/Plugin/TotalCacheAdmin.php

https://bitbucket.org/broderboy/nycendurance-wordpress
PHP | 5766 lines | 3630 code | 933 blank | 1203 comment | 819 complexity | 095cd23987932df7138737a51680e544 MD5 | raw file
Possible License(s): AGPL-1.0, GPL-3.0, Apache-2.0, GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * W3 Total Cache Admin plugin
  4. */
  5. if (!defined('W3TC')) {
  6. die();
  7. }
  8. define('W3TC_PLUGIN_TOTALCACHE_REGEXP_COOKIEDOMAIN', '~define\s*\(\s*[\'"]COOKIE_DOMAIN[\'"]\s*,.*?\)~is');
  9. require_once W3TC_INC_DIR . '/functions/rule.php';
  10. require_once W3TC_INC_DIR . '/functions/http.php';
  11. require_once W3TC_LIB_W3_DIR . '/Plugin.php';
  12. /**
  13. * Class W3_Plugin_TotalCacheAdmin
  14. */
  15. class W3_Plugin_TotalCacheAdmin extends W3_Plugin {
  16. /**
  17. * Current page
  18. *
  19. * @var string
  20. */
  21. var $_page = 'w3tc_general';
  22. /**
  23. * Notes
  24. *
  25. * @var array
  26. */
  27. var $_notes = array();
  28. /**
  29. * Errors
  30. *
  31. * @var array
  32. */
  33. var $_errors = array();
  34. /**
  35. * Show support reminder flag
  36. *
  37. * @var boolean
  38. */
  39. var $_support_reminder = false;
  40. /**
  41. * Used in PHPMailer init function
  42. *
  43. * @var string
  44. */
  45. var $_phpmailer_sender = '';
  46. /**
  47. * Array of request types
  48. *
  49. * @var array
  50. */
  51. var $_request_types = array(
  52. 'bug_report' => 'Submit a Bug Report',
  53. 'new_feature' => 'Suggest a New Feature',
  54. 'email_support' => 'Less than 15 Minute Email Support Response (M-F 9AM - 5PM EDT): $75 USD',
  55. 'phone_support' => 'Less than 15 Minute Phone Support Response (M-F 9AM - 5PM EDT): $150 USD',
  56. 'plugin_config' => 'Professional Plugin Configuration: Starting @ $100 USD',
  57. 'theme_config' => 'Theme Performance Optimization & Plugin Configuration: Starting @ $150 USD',
  58. 'linux_config' => 'Linux Server Optimization & Plugin Configuration: Starting @ $200 USD'
  59. );
  60. /**
  61. * Array of request groups
  62. *
  63. * @var array
  64. */
  65. var $_request_groups = array(
  66. 'General Support' => array(
  67. 'bug_report',
  68. 'new_feature'
  69. ),
  70. 'Professional Services (per site pricing)' => array(
  71. 'email_support',
  72. 'phone_support',
  73. 'plugin_config',
  74. 'theme_config',
  75. 'linux_config'
  76. )
  77. );
  78. /**
  79. * Request price list
  80. *
  81. * @var array
  82. */
  83. var $_request_prices = array(
  84. 'email_support' => 75,
  85. 'phone_support' => 150,
  86. 'plugin_config' => 100,
  87. 'theme_config' => 150,
  88. 'linux_config' => 200
  89. );
  90. /**
  91. * Runs plugin
  92. *
  93. * @return void
  94. */
  95. function run() {
  96. register_activation_hook(W3TC_FILE, array(
  97. &$this,
  98. 'activate'
  99. ));
  100. register_deactivation_hook(W3TC_FILE, array(
  101. &$this,
  102. 'deactivate'
  103. ));
  104. add_action('admin_init', array(
  105. &$this,
  106. 'admin_init'
  107. ));
  108. add_action('admin_menu', array(
  109. &$this,
  110. 'admin_menu'
  111. ));
  112. add_filter('contextual_help_list', array(
  113. &$this,
  114. 'contextual_help_list'
  115. ));
  116. add_filter('plugin_action_links_' . W3TC_FILE, array(
  117. &$this,
  118. 'plugin_action_links'
  119. ));
  120. add_filter('favorite_actions', array(
  121. &$this,
  122. 'favorite_actions'
  123. ));
  124. add_action('in_plugin_update_message-' . W3TC_FILE, array(
  125. &$this,
  126. 'in_plugin_update_message'
  127. ));
  128. if ($this->_config->get_boolean('widget.latest.enabled') || $this->_config->get_boolean('widget.pagespeed.enabled')) {
  129. add_action('wp_dashboard_setup', array(
  130. &$this,
  131. 'wp_dashboard_setup'
  132. ));
  133. }
  134. if ($this->_config->get_boolean('pgcache.enabled') || $this->_config->get_boolean('minify.enabled')) {
  135. add_filter('pre_update_option_active_plugins', array(
  136. &$this,
  137. 'pre_update_option_active_plugins'
  138. ));
  139. }
  140. if ($this->_config->get_boolean('cdn.enabled') && w3_can_cdn_purge($this->_config->get_string('cdn.engine'))) {
  141. add_filter('media_row_actions', array(
  142. &$this,
  143. 'media_row_actions'
  144. ), 0, 2);
  145. }
  146. if ($this->_config->get_boolean('pgcache.enabled')) {
  147. add_filter('post_row_actions', array(
  148. &$this,
  149. 'post_row_actions'
  150. ), 0, 2);
  151. add_filter('page_row_actions', array(
  152. &$this,
  153. 'page_row_actions'
  154. ), 0, 2);
  155. }
  156. }
  157. /**
  158. * Activate plugin action
  159. *
  160. * @return void
  161. */
  162. function activate() {
  163. $this->link_update();
  164. }
  165. /**
  166. * Deactivate plugin action
  167. *
  168. * @return void
  169. */
  170. function deactivate() {
  171. $this->link_delete();
  172. }
  173. /**
  174. * Load action
  175. *
  176. * @return void
  177. */
  178. function load() {
  179. require_once W3TC_LIB_W3_DIR . '/Request.php';
  180. $this->_page = W3_Request::get_string('page');
  181. switch (true) {
  182. case ($this->_page == 'w3tc_general'):
  183. case ($this->_page == 'w3tc_pgcache'):
  184. case ($this->_page == 'w3tc_minify' && W3TC_PHP5):
  185. case ($this->_page == 'w3tc_dbcache'):
  186. case ($this->_page == 'w3tc_objectcache'):
  187. case ($this->_page == 'w3tc_browsercache'):
  188. case ($this->_page == 'w3tc_mobile'):
  189. case ($this->_page == 'w3tc_referrer'):
  190. case ($this->_page == 'w3tc_cdn'):
  191. case ($this->_page == 'w3tc_install'):
  192. case ($this->_page == 'w3tc_faq'):
  193. case ($this->_page == 'w3tc_about'):
  194. case ($this->_page == 'w3tc_support'):
  195. break;
  196. default:
  197. $this->_page = 'w3tc_general';
  198. }
  199. $this->_support_reminder = ($this->_config->get_boolean('notes.support_us') && $this->_config->get_integer('common.install') < (time() - W3TC_SUPPORT_US_TIMEOUT) && $this->_config->get_string('common.support') == '' && !$this->_config->get_boolean('common.tweeted'));
  200. /**
  201. * Run plugin action
  202. */
  203. $action = false;
  204. foreach ($_REQUEST as $key => $value) {
  205. if (strpos($key, 'w3tc_') === 0) {
  206. $action = 'action_' . substr($key, 5);
  207. break;
  208. }
  209. }
  210. if ($action && method_exists($this, $action)) {
  211. check_admin_referer('w3tc');
  212. call_user_func(array(
  213. &$this,
  214. $action
  215. ));
  216. exit();
  217. }
  218. }
  219. /**
  220. * Admin init
  221. *
  222. * @return void
  223. */
  224. function admin_init() {
  225. wp_register_style('w3tc-options', plugins_url('pub/css/options.css', W3TC_FILE));
  226. wp_register_style('w3tc-lightbox', plugins_url('pub/css/lightbox.css', W3TC_FILE));
  227. wp_register_style('w3tc-widget', plugins_url('pub/css/widget.css', W3TC_FILE));
  228. wp_register_script('w3tc-metadata', plugins_url('pub/js/metadata.js', W3TC_FILE));
  229. wp_register_script('w3tc-options', plugins_url('pub/js/options.js', W3TC_FILE));
  230. wp_register_script('w3tc-lightbox', plugins_url('pub/js/lightbox.js', W3TC_FILE));
  231. wp_register_script('w3tc-widget', plugins_url('pub/js/widget.js', W3TC_FILE));
  232. }
  233. /**
  234. * Admin menu
  235. *
  236. * @return void
  237. */
  238. function admin_menu() {
  239. $pages = array(
  240. 'w3tc_general' => array(
  241. 'General Settings',
  242. 'General Settings'
  243. ),
  244. 'w3tc_pgcache' => array(
  245. 'Page Cache',
  246. 'Page Cache'
  247. ),
  248. 'w3tc_minify' => array(
  249. 'Minify',
  250. 'Minify'
  251. ),
  252. 'w3tc_dbcache' => array(
  253. 'Database Cache',
  254. 'Database Cache'
  255. ),
  256. 'w3tc_objectcache' => array(
  257. 'Object Cache',
  258. 'Object Cache'
  259. ),
  260. 'w3tc_browsercache' => array(
  261. 'Browser Cache',
  262. 'Browser Cache'
  263. ),
  264. 'w3tc_mobile' => array(
  265. 'User Agent Groups',
  266. 'User Agent Groups'
  267. ),
  268. 'w3tc_referrer' => array(
  269. 'Referrer Groups',
  270. 'Referrer Groups'
  271. ),
  272. 'w3tc_cdn' => array(
  273. 'Content Delivery Network',
  274. '<acronym title="Content Delivery Network">CDN</acronym>'
  275. ),
  276. 'w3tc_faq' => array(
  277. 'FAQ',
  278. 'FAQ'
  279. ),
  280. 'w3tc_support' => array(
  281. 'Support',
  282. '<span style="color: red;">Support</span>'
  283. ),
  284. 'w3tc_install' => array(
  285. 'Install',
  286. 'Install'
  287. ),
  288. 'w3tc_about' => array(
  289. 'About',
  290. 'About'
  291. )
  292. );
  293. if (!W3TC_PHP5) {
  294. unset($pages['w3tc_minify']);
  295. }
  296. add_menu_page('Performance', 'Performance', 'manage_options', 'w3tc_general', '', plugins_url('w3-total-cache/pub/img/logo_small.png'));
  297. $submenu_pages = array();
  298. foreach ($pages as $slug => $titles) {
  299. $submenu_pages[] = add_submenu_page('w3tc_general', $titles[0] . ' | W3 Total Cache', $titles[1], 'manage_options', $slug, array(
  300. &$this,
  301. 'options'
  302. ));
  303. }
  304. if (current_user_can('manage_options')) {
  305. /**
  306. * Only admin can modify W3TC settings
  307. */
  308. foreach ($submenu_pages as $submenu_page) {
  309. add_action('load-' . $submenu_page, array(
  310. &$this,
  311. 'load'
  312. ));
  313. add_action('admin_print_styles-' . $submenu_page, array(
  314. &$this,
  315. 'admin_print_styles'
  316. ));
  317. add_action('admin_print_scripts-' . $submenu_page, array(
  318. &$this,
  319. 'admin_print_scripts'
  320. ));
  321. }
  322. /**
  323. * Only admin can see W3TC notices and errors
  324. */
  325. add_action('admin_notices', array(
  326. &$this,
  327. 'admin_notices'
  328. ));
  329. }
  330. }
  331. /**
  332. * Print styles
  333. *
  334. * @return void
  335. */
  336. function admin_print_styles() {
  337. wp_enqueue_style('w3tc-options');
  338. wp_enqueue_style('w3tc-lightbox');
  339. }
  340. /**
  341. * Print scripts
  342. *
  343. * @return void
  344. */
  345. function admin_print_scripts() {
  346. wp_enqueue_script('w3tc-metadata');
  347. wp_enqueue_script('w3tc-options');
  348. wp_enqueue_script('w3tc-lightbox');
  349. switch ($this->_page) {
  350. case 'w3tc_minify':
  351. case 'w3tc_mobile':
  352. case 'w3tc_referrer':
  353. case 'w3tc_cdn':
  354. wp_enqueue_script('jquery-ui-sortable');
  355. break;
  356. }
  357. }
  358. /**
  359. * Contextual help list filter
  360. *
  361. * @param string $list
  362. * @return string
  363. */
  364. function contextual_help_list($list) {
  365. $faq = $this->parse_faq();
  366. if (isset($faq['Usage'])) {
  367. $columns = array_chunk($faq['Usage'], ceil(count($faq['Usage']) / 3));
  368. ob_start();
  369. include W3TC_INC_DIR . '/options/common/help.php';
  370. $help = ob_get_contents();
  371. ob_end_clean();
  372. $hook = get_plugin_page_hookname($this->_page, 'w3tc_general');
  373. $list[$hook] = $help;
  374. }
  375. return $list;
  376. }
  377. /**
  378. * Plugin action links filter
  379. *
  380. * @param array $links
  381. * @return array
  382. */
  383. function plugin_action_links($links) {
  384. array_unshift($links, '<a class="edit" href="admin.php?page=w3tc_general">Settings</a>');
  385. return $links;
  386. }
  387. /**
  388. * favorite_actions filter
  389. *
  390. * @param array $actions
  391. * @return void
  392. */
  393. function favorite_actions($actions) {
  394. $actions[wp_nonce_url(admin_url('admin.php?page=w3tc_general&amp;w3tc_flush_all'), 'w3tc')] = array(
  395. 'Empty Caches',
  396. 'manage_options'
  397. );
  398. return $actions;
  399. }
  400. /**
  401. * Active plugins pre update option filter
  402. *
  403. * @param string $new_value
  404. * @return string
  405. */
  406. function pre_update_option_active_plugins($new_value) {
  407. $old_value = (array) get_option('active_plugins');
  408. if ($new_value !== $old_value && in_array(W3TC_FILE, (array) $new_value) && in_array(W3TC_FILE, (array) $old_value)) {
  409. $this->_config->set('notes.plugins_updated', true);
  410. $this->_config->save();
  411. }
  412. return $new_value;
  413. }
  414. /**
  415. * Show plugin changes
  416. *
  417. * @return void
  418. */
  419. function in_plugin_update_message() {
  420. $response = w3_http_get(W3TC_README_URL);
  421. if (!is_wp_error($response) && $response['response']['code'] == 200) {
  422. $matches = null;
  423. $regexp = '~==\s*Changelog\s*==\s*=\s*[0-9.]+\s*=(.*)(=\s*' . preg_quote(W3TC_VERSION) . '\s*=|$)~Uis';
  424. if (preg_match($regexp, $response['body'], $matches)) {
  425. $changelog = (array) preg_split('~[\r\n]+~', trim($matches[1]));
  426. echo '<div style="color: #f00;">Take a minute to update, here\'s why:</div><div style="font-weight: normal;">';
  427. $ul = false;
  428. foreach ($changelog as $index => $line) {
  429. if (preg_match('~^\s*\*\s*~', $line)) {
  430. if (!$ul) {
  431. echo '<ul style="list-style: disc; margin-left: 20px;">';
  432. $ul = true;
  433. }
  434. $line = preg_replace('~^\s*\*\s*~', '', htmlspecialchars($line));
  435. echo '<li style="width: 50%; margin: 0; float: left; ' . ($index % 2 == 0 ? 'clear: left;' : '') . '">' . $line . '</li>';
  436. } else {
  437. if ($ul) {
  438. echo '</ul><div style="clear: left;"></div>';
  439. $ul = false;
  440. }
  441. echo '<p style="margin: 5px 0;">' . htmlspecialchars($line) . '</p>';
  442. }
  443. }
  444. if ($ul) {
  445. echo '</ul><div style="clear: left;"></div>';
  446. }
  447. echo '</div>';
  448. }
  449. }
  450. }
  451. /**
  452. * media_row_actions filter
  453. *
  454. * @param array $actions
  455. * @param object $post
  456. * @return array
  457. */
  458. function media_row_actions($actions, $post) {
  459. $actions = array_merge($actions, array(
  460. 'cdn_purge' => sprintf('<a href="%s">Purge from CDN</a>', wp_nonce_url(sprintf('admin.php?page=w3tc_general&w3tc_cdn_purge_attachment&attachment_id=%d', $post->ID), 'w3tc'))
  461. ));
  462. return $actions;
  463. }
  464. /**
  465. * post_row_actions filter
  466. *
  467. * @param array $actions
  468. * @param object $post
  469. * @return array
  470. */
  471. function post_row_actions($actions, $post) {
  472. $actions = array_merge($actions, array(
  473. 'pgcache_purge' => sprintf('<a href="%s">Purge from Page Cache</a>', wp_nonce_url(sprintf('admin.php?page=w3tc_general&w3tc_pgcache_purge_post&post_id=%d', $post->ID), 'w3tc'))
  474. ));
  475. return $actions;
  476. }
  477. /**
  478. * page_row_actions filter
  479. *
  480. * @param array $actions
  481. * @param object $post
  482. * @return array
  483. */
  484. function page_row_actions($actions, $post) {
  485. $actions = array_merge($actions, array(
  486. 'pgcache_purge' => sprintf('<a href="%s">Purge from Page Cache</a>', wp_nonce_url(sprintf('admin.php?page=w3tc_general&w3tc_pgcache_purge_page&post_id=%d', $post->ID), 'w3tc'))
  487. ));
  488. return $actions;
  489. }
  490. /**
  491. * Dashboard setup action
  492. *
  493. * @return void
  494. */
  495. function wp_dashboard_setup() {
  496. wp_enqueue_style('w3tc-widget');
  497. wp_enqueue_script('w3tc-metadata');
  498. wp_enqueue_script('w3tc-widget');
  499. if ($this->_config->get_boolean('widget.latest.enabled')) {
  500. wp_add_dashboard_widget('w3tc_latest', 'The Latest from W3 EDGE', array(
  501. &$this,
  502. 'widget_latest'
  503. ), array(
  504. &$this,
  505. 'widget_latest_control'
  506. ));
  507. }
  508. if ($this->_config->get_boolean('widget.pagespeed.enabled')) {
  509. wp_add_dashboard_widget('w3tc_pagespeed', 'W3 Total Cache: Google Page Speed Report', array(
  510. &$this,
  511. 'widget_pagespeed'
  512. ), array(
  513. &$this,
  514. 'widget_pagespeed_control'
  515. ));
  516. }
  517. }
  518. /**
  519. * Admin notices action
  520. *
  521. * @return void
  522. */
  523. function admin_notices() {
  524. $config_path = (w3_is_preview_config() ? W3TC_CONFIG_PREVIEW_PATH : W3TC_CONFIG_PATH);
  525. $pgcache_rules_core_path = w3_get_pgcache_rules_core_path();
  526. $pgcache_rules_cache_path = w3_get_pgcache_rules_cache_path();
  527. $browsercache_rules_cache_path = w3_get_browsercache_rules_cache_path();
  528. $browsercache_rules_no404wp_path = w3_get_browsercache_rules_no404wp_path();
  529. $minify_rules_core_path = w3_get_minify_rules_core_path();
  530. $minify_rules_cache_path = w3_get_minify_rules_cache_path();
  531. $cookie_domain = $this->get_cookie_domain();
  532. $error_messages = array(
  533. 'config_save' => sprintf('The settings could not be saved because the configuration file is not write-able. Please run <strong>chmod 777 %s</strong> to resolve this issue.', (file_exists($config_path) ? $config_path : dirname($config_path))),
  534. 'fancy_permalinks_disabled_pgcache' => sprintf('Fancy permalinks are disabled. Please %s it first, then re-attempt to enabling enhanced disk mode.', $this->button_link('enable', 'options-permalink.php')),
  535. 'fancy_permalinks_disabled_browsercache' => sprintf('Fancy permalinks are disabled. Please %s it first, then re-attempt to enabling the \'Do not process 404 errors for static objects with WordPress\'.', $this->button_link('enable', 'options-permalink.php')),
  536. 'pgcache_write_rules_core' => sprintf('The page cache rules could not be modified. Please %srun <strong>chmod 777 %s</strong> to resolve this issue.', (file_exists($pgcache_rules_core_path) ? '' : sprintf('create an empty file in <strong>%s</strong> and ', $pgcache_rules_core_path)), $pgcache_rules_core_path),
  537. 'pgcache_write_rules_cache' => sprintf('The page cache rules could not be modified. Please run <strong>chmod 777 %s</strong> to resolve this issue.', (file_exists($pgcache_rules_cache_path) ? $pgcache_rules_cache_path : dirname($pgcache_rules_cache_path))),
  538. 'pgcache_remove_rules_legacy' => sprintf('The legacy page cache rules could not be removed. Please run <strong>chmod 777 %s</strong> to resolve this issue.', (file_exists($pgcache_rules_cache_path) ? $pgcache_rules_cache_path : dirname($pgcache_rules_cache_path))),
  539. 'pgcache_remove_rules_wpsc' => sprintf('The WP Super Cache rules could not be removed. Please run <strong>chmod 777 %s</strong> to resolve this issue.', (file_exists($pgcache_rules_cache_path) ? $pgcache_rules_cache_path : dirname($pgcache_rules_cache_path))),
  540. 'browsercache_write_rules_cache' => sprintf('The browser cache rules could not be modified. Please %srun <strong>chmod 777 %s</strong> to resolve this issue.', (file_exists($browsercache_rules_cache_path) ? '' : sprintf('create an empty file in <strong>%s</strong> and ', $browsercache_rules_cache_path)), $browsercache_rules_cache_path),
  541. 'browsercache_write_rules_no404wp' => sprintf('The browser cache rules could not be modified. Please %srun <strong>chmod 777 %s</strong> to resolve this issue.', (file_exists($browsercache_rules_no404wp_path) ? '' : sprintf('create an empty file in <strong>%s</strong> and ', $browsercache_rules_no404wp_path)), $browsercache_rules_no404wp_path),
  542. 'browsercache_write_rules_cdn' => sprintf('The browser cache rules for <acronym title="Content Delivery Network">CDN</acronym> could not be modified. Please check <acronym title="Content Delivery Network">CDN</acronym> settings.'),
  543. 'minify_write_rules_core' => sprintf('The minify rules could not be modified. Please run <strong>chmod 777 %s</strong> to resolve this issue.', (file_exists($minify_rules_core_path) ? $minify_rules_core_path : dirname($minify_rules_core_path))),
  544. 'minify_write_rules_cache' => sprintf('The minify rules could not be modified. Please run <strong>chmod 777 %s</strong> to resolve this issue.', (file_exists($minify_rules_cache_path) ? $minify_rules_cache_path : dirname($minify_rules_cache_path))),
  545. 'minify_remove_rules_legacy' => sprintf('The legacy minify rules could not be modified. Please run <strong>chmod 777 %s</strong> to resolve this issue.', (file_exists($minify_rules_cache_path) ? $minify_rules_cache_path : dirname($minify_rules_cache_path))),
  546. 'support_request_type' => 'Please select request type.',
  547. 'support_request_url' => 'Please enter the address of the site in the site <acronym title="Uniform Resource Locator">URL</acronym> field.',
  548. 'support_request_name' => 'Please enter your name in the Name field',
  549. 'support_request_email' => 'Please enter valid email address in the E-Mail field.',
  550. 'support_request_phone' => 'Please enter your phone in the phone field.',
  551. 'support_request_subject' => 'Please enter subject in the subject field.',
  552. 'support_request_description' => 'Please describe the issue in the issue description field.',
  553. 'support_request_wp_login' => 'Please enter an administrator login. Create a temporary one just for this support case if needed.',
  554. 'support_request_wp_password' => 'Please enter WP Admin password, be sure it\'s spelled correctly.',
  555. 'support_request_ftp_host' => 'Please enter <acronym title="Secure Shell">SSH</acronym> or <acronym title="File Transfer Protocol">FTP</acronym> host for the site.',
  556. 'support_request_ftp_login' => 'Please enter <acronym title="Secure Shell">SSH</acronym> or <acronym title="File Transfer Protocol">FTP</acronym> login for the server. Create a temporary one just for this support case if needed.',
  557. 'support_request_ftp_password' => 'Please enter <acronym title="Secure Shell">SSH</acronym> or <acronym title="File Transfer Protocol">FTP</acronym> password for the <acronym title="File Transfer Protocol">FTP</acronym> account.',
  558. 'support_request' => 'Unable to send the support request.',
  559. 'config_import_no_file' => 'Please select config file.',
  560. 'config_import_upload' => 'Unable to upload config file.',
  561. 'config_import_import' => 'Configuration file could not be imported.',
  562. 'config_reset' => sprintf('Default settings could not be restored. Please run <strong>chmod 777 %s</strong> to make the configuration file write-able, then try again.', (file_exists(W3TC_CONFIG_PREVIEW_PATH) ? W3TC_CONFIG_PREVIEW_PATH : W3TC_CONFIG_PREVIEW_PATH)),
  563. 'preview_enable' => sprintf('Preview mode could not be enabled. Please run <strong>chmod 777 %s</strong> to make the configuration file write-able, then try again.', (file_exists(W3TC_CONFIG_PREVIEW_PATH) ? W3TC_CONFIG_PREVIEW_PATH : dirname(W3TC_CONFIG_PREVIEW_PATH))),
  564. 'preview_disable' => sprintf('Preview mode could not be disabled. Please run <strong>chmod 777 %s</strong> to make the configuration file write-able, then try again.', (file_exists($config_path) ? $config_path : dirname($config_path))),
  565. 'preview_deploy' => sprintf('Preview settings could not be deployed. Please run <strong>chmod 777 %s</strong> to make the configuration file write-able, then try again.', (file_exists(W3TC_CONFIG_PATH) ? W3TC_CONFIG_PATH : dirname(W3TC_CONFIG_PATH))),
  566. 'cdn_purge_attachment' => 'Unable to purge attachment.',
  567. 'pgcache_purge_post' => 'Unable to purge post.',
  568. 'pgcache_purge_page' => 'Unable to purge page.',
  569. 'enable_cookie_domain' => sprintf('<strong>%swp-config.php</strong> could not be written, please edit config and add:<br /><strong style="color:#f00;">define(\'COOKIE_DOMAIN\', \'%s\');</strong> before <strong style="color:#f00;">require_once(ABSPATH . \'wp-settings.php\');</strong>.', ABSPATH, addslashes($cookie_domain)),
  570. 'disable_cookie_domain' => sprintf('<strong>%swp-config.php</strong> could not be written, please edit config and add:<br /><strong style="color:#f00;">define(\'COOKIE_DOMAIN\', false);</strong> before <strong style="color:#f00;">require_once(ABSPATH . \'wp-settings.php\');</strong>.', ABSPATH),
  571. 'cloudflare_api_request' => 'Unable to make CloudFlare API request.'
  572. );
  573. $note_messages = array(
  574. 'config_save' => 'Plugin configuration successfully updated.',
  575. 'flush_all' => 'All caches successfully emptied.',
  576. 'flush_memcached' => 'Memcached cache(s) successfully emptied.',
  577. 'flush_opcode' => 'Opcode cache(s) successfully emptied.',
  578. 'flush_file' => 'Disk cache(s) successfully emptied.',
  579. 'flush_pgcache' => 'Page cache successfully emptied.',
  580. 'flush_dbcache' => 'Database cache successfully emptied.',
  581. 'flush_objectcache' => 'Object cache successfully emptied.',
  582. 'flush_minify' => 'Minify cache successfully emptied.',
  583. 'pgcache_write_rules_core' => 'Page cache rewrite rules have been successfully written.',
  584. 'pgcache_write_rules_cache' => 'Page cache rewrite rules have been successfully written.',
  585. 'pgcache_remove_rules_legacy' => 'Legacy page cache configuration settings have been successfully removed.',
  586. 'pgcache_remove_rules_wpsc' => 'WP Super Cache configuration settings have been successfully removed.',
  587. 'browsercache_write_rules_cache' => 'Browser cache directives have been successfully written.',
  588. 'browsercache_write_rules_no404wp' => 'Browser cache directives have been successfully written.',
  589. 'minify_write_rules_core' => 'Minify rewrite rules have been successfully written.',
  590. 'minify_write_rules_cache' => 'Minify rewrite rules have been successfully written.',
  591. 'minify_remove_rules_legacy' => 'Legacy minify configuration settings have been successfuly removed.',
  592. 'support_request' => 'The support request has been successfully sent.',
  593. 'config_import' => 'Settings successfully imported.',
  594. 'config_reset' => 'Settings successfully restored.',
  595. 'preview_enable' => 'Preview mode was successfully enabled',
  596. 'preview_disable' => 'Preview mode was successfully disabled',
  597. 'preview_deploy' => 'Preview settings successfully deployed.',
  598. 'cdn_purge_attachment' => 'Attachment successfully purged.',
  599. 'pgcache_purge_post' => 'Post successfully purged.',
  600. 'pgcache_purge_page' => 'Page successfully purged.'
  601. );
  602. $errors = array();
  603. $notes = array();
  604. require_once W3TC_LIB_W3_DIR . '/Request.php';
  605. $error = W3_Request::get_string('w3tc_error');
  606. $note = W3_Request::get_string('w3tc_note');
  607. /**
  608. * Handle messages from reqeust
  609. */
  610. if (isset($error_messages[$error])) {
  611. $errors[] = $error_messages[$error];
  612. }
  613. if (isset($note_messages[$note])) {
  614. $notes[] = $note_messages[$note];
  615. }
  616. /**
  617. * Check config file
  618. */
  619. if (!w3_is_preview_config() && !file_exists(W3TC_CONFIG_PATH)) {
  620. $errors[] = sprintf('<strong>W3 Total Cache Error:</strong> Default settings are in use. The configuration file could not be read or doesn\'t exist. Please %s to create the file.', $this->button_link('save the settings', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_save_config', $this->_page), 'w3tc')));
  621. }
  622. /**
  623. * CDN notifications
  624. */
  625. if ($this->_config->get_boolean('cdn.enabled') && !w3_is_cdn_mirror($this->_config->get_string('cdn.engine'))) {
  626. /**
  627. * Show notification after theme change
  628. */
  629. if ($this->_config->get_boolean('notes.theme_changed')) {
  630. $notes[] = sprintf('The 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'));
  631. }
  632. /**
  633. * Show notification after WP upgrade
  634. */
  635. if ($this->_config->get_boolean('notes.wp_upgraded')) {
  636. $notes[] = sprintf('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'));
  637. }
  638. /**
  639. * Show notification after CDN enable
  640. */
  641. if ($this->_config->get_boolean('notes.cdn_upload') || $this->_config->get_boolean('notes.cdn_reupload')) {
  642. $cdn_upload_buttons = array();
  643. if ($this->_config->get_boolean('cdn.includes.enable')) {
  644. $cdn_upload_buttons[] = $this->button_popup('wp-includes', 'cdn_export', 'cdn_export_type=includes');
  645. }
  646. if ($this->_config->get_boolean('cdn.theme.enable')) {
  647. $cdn_upload_buttons[] = $this->button_popup('theme files', 'cdn_export', 'cdn_export_type=theme');
  648. }
  649. if ($this->_config->get_boolean('minify.enabled') && $this->_config->get_boolean('cdn.minify.enable')) {
  650. $cdn_upload_buttons[] = $this->button_popup('minify files', 'cdn_export', 'cdn_export_type=minify');
  651. }
  652. if ($this->_config->get_boolean('cdn.custom.enable')) {
  653. $cdn_upload_buttons[] = $this->button_popup('custom files', 'cdn_export', 'cdn_export_type=custom');
  654. }
  655. if ($this->_config->get_boolean('notes.cdn_upload')) {
  656. $notes[] = sprintf('Make sure to %s and upload the %s, files to the <acronym title="Content Delivery Network">CDN</acronym> to ensure proper operation. %s', $this->button_popup('export the media library', 'cdn_export_library'), implode(', ', $cdn_upload_buttons), $this->button_hide_note('Hide this message', 'cdn_upload'));
  657. }
  658. if ($this->_config->get_boolean('notes.cdn_reupload')) {
  659. $notes[] = sprintf('Settings that effect Browser Cache settings for files hosted by the CDN have been changed. To apply the new settings %s and %s. %s', $this->button_popup('export the media library', 'cdn_export_library'), implode(', ', $cdn_upload_buttons), $this->button_hide_note('Hide this message', 'cdn_reupload'));
  660. }
  661. }
  662. /**
  663. * Show notification if upload queue is not empty
  664. */
  665. if (!$this->is_queue_empty()) {
  666. $errors[] = sprintf('The %s has unresolved errors. Empty the queue to restore normal operation.', $this->button_popup('unsuccessful transfer queue', 'cdn_queue'));
  667. }
  668. }
  669. /**
  670. * Show notification after plugin activate/deactivate
  671. */
  672. if ($this->_config->get_boolean('notes.plugins_updated')) {
  673. $texts = array();
  674. if ($this->_config->get_boolean('pgcache.enabled')) {
  675. $texts[] = $this->button_link('empty the page cache', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_flush_pgcache', $this->_page), 'w3tc'));
  676. }
  677. if ($this->_config->get_boolean('minify.enabled')) {
  678. $texts[] = sprintf('check the %s to maintain the desired user experience', $this->button_hide_note('minify settings', 'plugins_updated', 'admin.php?page=w3tc_minify'));
  679. }
  680. if (count($texts)) {
  681. $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'));
  682. }
  683. }
  684. /**
  685. * Show notification when page cache needs to be emptied
  686. */
  687. if ($this->_config->get_boolean('pgcache.enabled') && $this->_config->get('notes.need_empty_pgcache') && !w3_is_preview_config()) {
  688. $notes[] = sprintf('The setting change(s) made either invalidate the cached data or modify the behavior of the site. %s now to provide a consistent user experience.', $this->button_link('Empty the page cache', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_flush_pgcache', $this->_page), 'w3tc')));
  689. }
  690. /**
  691. * Show notification when object cache needs to be emptied
  692. */
  693. if ($this->_config->get_boolean('objectcache.enabled') && $this->_config->get('notes.need_empty_objectcache') && !w3_is_preview_config()) {
  694. $notes[] = sprintf('The setting change(s) made either invalidate the cached data or modify the behavior of the site. %s now to provide a consistent user experience.', $this->button_link('Empty the object cache', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_flush_objectcache', $this->_page), 'w3tc')));
  695. }
  696. /**
  697. * Minify notifications
  698. */
  699. if ($this->_config->get_boolean('minify.enabled')) {
  700. /**
  701. * Minify error occured
  702. */
  703. if ($this->_config->get('notes.minify_error')) {
  704. $errors[] = sprintf('Recently an error occurred while creating the CSS / JS minify cache: %s. %s', $this->_config->get_string('minify.error.last'), $this->button_hide_note('Hide this message', 'minify_error'));
  705. }
  706. /**
  707. * Show notification when minify needs to be emptied
  708. */
  709. if ($this->_config->get('notes.need_empty_minify') && !w3_is_preview_config()) {
  710. $notes[] = sprintf('The setting change(s) made either invalidate the cached data or modify the behavior of the site. %s now to provide a consistent user experience.', $this->button_link('Empty the minify cache', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_flush_minify', $this->_page), 'w3tc')));
  711. }
  712. }
  713. /**
  714. * Show messages
  715. */
  716. foreach ($errors as $error) {
  717. echo sprintf('<div class="error"><p>%s</p></div>', $error);
  718. }
  719. foreach ($notes as $note) {
  720. echo sprintf('<div class="updated fade"><p>%s</p></div>', $note);
  721. }
  722. }
  723. /**
  724. * Options page
  725. *
  726. * @return void
  727. */
  728. function options() {
  729. /**
  730. * Check for page cache availability
  731. */
  732. if ($this->_config->get_boolean('pgcache.enabled')) {
  733. if (!$this->advanced_cache_installed()) {
  734. $this->_errors[] = sprintf('Page caching is not available: %s is not installed. Either the <strong>%s</strong> directory is not write-able or another caching plugin installed. This error message will automatically disappear once the change is successfully made.', W3TC_ADDIN_FILE_ADVANCED_CACHE, WP_CONTENT_DIR);
  735. } elseif (!$this->advanced_cache_check()) {
  736. $this->_errors[] = sprintf('Page caching is not available. The current add-in %s is either an incorrect file or an old version. De-activate the plugin, remove the file, then activate the plugin again.', W3TC_ADDIN_FILE_ADVANCED_CACHE);
  737. } elseif (!defined('WP_CACHE') || !WP_CACHE) {
  738. $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);
  739. } elseif ($this->_config->get_string('pgcache.engine') == 'file_generic' && $this->_config->get_boolean('config.check') && w3_can_check_rules()) {
  740. $w3_plugin_pgcache = & w3_instance('W3_Plugin_PgCacheAdmin');
  741. if ($w3_plugin_pgcache->check_rules_core()) {
  742. if (!$this->test_rewrite_pgcache()) {
  743. $this->_errors[] = 'It appears Page Cache <acronym title="Uniform Resource Locator">URL</acronym> rewriting is not working. If using apache, verify that the server configuration allows .htaccess or if using nginx verify all configuration files are included in the configuration.';
  744. }
  745. } elseif ($this->_config->get_boolean('notes.pgcache_rules_core')) {
  746. $this->_errors[] = sprintf('Disk enhanced page caching is not active. To enable it, add the following rules into the server configuration file (<strong>%s</strong>) of the site above the WordPress directives %s <textarea class="w3tc-rules" cols="120" rows="10" readonly="readonly">%s</textarea>. Or if permission allow this can be done automatically, by clicking here: %s. %s', w3_get_pgcache_rules_core_path(), $this->button('view code', '', 'w3tc-show-rules'), htmlspecialchars($w3_plugin_pgcache->generate_rules_core()), $this->button_link('auto-install', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_pgcache_write_rules_core', $this->_page), 'w3tc')), $this->button_hide_note('Hide this message', 'pgcache_rules_core'));
  747. }
  748. if ($this->_config->get_boolean('notes.pgcache_rules_legacy') && $w3_plugin_pgcache->check_rules_legacy()) {
  749. $this->_errors[] = sprintf('Legacy Page Cache rewrite rules have been found. To remove them manually, edit the configuration file (<strong>%s</strong>) and remove all lines between and including <strong>%s</strong> and <strong>%s</strong> markers inclusive. Or if permission allow this can be done automatically, by clicking here: %s. %s', w3_get_pgcache_rules_core_path(), W3TC_MARKER_BEGIN_PGCACHE_LEGACY, W3TC_MARKER_END_PGCACHE_LEGACY, $this->button_link('auto-remove', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_pgcache_remove_rules_legacy', $this->_page), 'w3tc')), $this->button_hide_note('Hide this message', 'pgcache_rules_legacy'));
  750. }
  751. if ($this->_config->get_boolean('notes.pgcache_rules_wpsc') && $w3_plugin_pgcache->check_rules_wpsc()) {
  752. $this->_errors[] = sprintf('WP Super Cache rewrite rules have been found. To remove them manually, edit the configuration file (<strong>%s</strong>) and remove all lines between and including <strong>%s</strong> and <strong>%s</strong> markers inclusive. Or if permission allow this can be done automatically, by clicking here: %s. %s', w3_get_pgcache_rules_core_path(), W3TC_MARKER_BEGIN_PGCACHE_WPSC, W3TC_MARKER_END_PGCACHE_WPSC, $this->button_link('auto-remove', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_pgcache_remove_rules_wpsc', $this->_page), 'w3tc')), $this->button_hide_note('Hide this message', 'pgcache_rules_wpsc'));
  753. }
  754. if ($this->_config->get_boolean('notes.pgcache_rules_cache') && !$w3_plugin_pgcache->check_rules_cache()) {
  755. $this->_errors[] = sprintf('Disk enhanced page caching is not active. To enable it, add the following rules into the server configuration file (<strong>%s</strong>) of the site %s <textarea class="w3tc-rules" cols="120" rows="10" readonly="readonly">%s</textarea>. This can be done automatically, by clicking here: %s. %s', w3_get_pgcache_rules_cache_path(), $this->button('view code', '', 'w3tc-show-rules'), htmlspecialchars($w3_plugin_pgcache->generate_rules_cache()), $this->button_link('auto-install', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_pgcache_write_rules_cache', $this->_page), 'w3tc')), $this->button_hide_note('Hide this message', 'pgcache_rules_cache'));
  756. }
  757. }
  758. }
  759. /**
  760. * Check for browser cache availability
  761. */
  762. if ($this->_config->get_boolean('browsercache.enabled') && $this->_config->get_boolean('config.check') && w3_can_check_rules()) {
  763. $w3_plugin_browsercache = & w3_instance('W3_Plugin_BrowserCacheAdmin');
  764. if ($this->_config->get_boolean('notes.browsercache_rules_cache') && !$w3_plugin_browsercache->check_rules_cache()) {
  765. $this->_errors[] = sprintf('Browser caching is not active. To enable it, add the following rules into the server configuration file (<strong>%s</strong>) of the site %s <textarea class="w3tc-rules" cols="120" rows="10" readonly="readonly">%s</textarea>. Or if permission allow this can be done automatically, by clicking here: %s. %s', w3_get_browsercache_rules_cache_path(), $this->button('view code', '', 'w3tc-show-rules'), htmlspecialchars($w3_plugin_browsercache->generate_rules_cache()), $this->button_link('auto-install', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_browsercache_write_rules_cache', $this->_page), 'w3tc')), $this->button_hide_note('Hide this message', 'browsercache_rules_cache'));
  766. }
  767. if ($this->_config->get_boolean('notes.browsercache_rules_no404wp') && $this->_config->get_boolean('browsercache.no404wp') && !$w3_plugin_browsercache->check_rules_no404wp()) {
  768. $this->_errors[] = sprintf('"Do not process 404 errors for static objects with WordPress" feature is not active. To enable it, add the following rules into the server configuration file (<strong>%s</strong>) of the site %s <textarea class="w3tc-rules" cols="120" rows="10" readonly="readonly">%s</textarea>. Or if permission allow this can be done automatically, by clicking here: %s. %s', w3_get_browsercache_rules_no404wp_path(), $this->button('view code', '', 'w3tc-show-rules'), htmlspecialchars($w3_plugin_browsercache->generate_rules_no404wp()), $this->button_link('auto-install', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_browsercache_write_rules_no404wp', $this->_page), 'w3tc')), $this->button_hide_note('Hide this message', 'browsercache_rules_no404wp'));
  769. }
  770. }
  771. /**
  772. * Check for minify availability
  773. */
  774. if ($this->_config->get_boolean('minify.enabled')) {
  775. if ($this->_config->get_boolean('minify.rewrite') && $this->_config->get_boolean('config.check') && w3_can_check_rules()) {
  776. $w3_plugin_minify = & w3_instance('W3_Plugin_MinifyAdmin');
  777. if ($w3_plugin_minify->check_rules_core()) {
  778. if (!$this->test_rewrite_minify()) {
  779. $this->_errors[] = 'It appears Minify <acronym title="Uniform Resource Locator">URL</acronym> rewriting is not working. If using apache, verify that the server configuration allows .htaccess or if using nginx verify all configuration files are included in the configuration.';
  780. }
  781. } elseif ($this->_config->get_boolean('notes.minify_rules_core')) {
  782. $this->_errors[] = sprintf('Minify is not active. To enable it, add the following rules into the server configuration file (<strong>%s</strong>) of the site %s <textarea class="w3tc-rules" cols="120" rows="10" readonly="readonly">%s</textarea>. This can be done automatically, by clicking here: %s. %s', w3_get_minify_rules_core_path(), $this->button('view code', '', 'w3tc-show-rules'), htmlspecialchars($w3_plugin_minify->generate_rules_core()), $this->button_link('auto-install', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_minify_write_rules_core', $this->_page), 'w3tc')), $this->button_hide_note('Hide this message', 'minify_rules_core'));
  783. }
  784. if ($this->_config->get_boolean('notes.minify_rules_legacy') && $w3_plugin_minify->check_rules_legacy()) {
  785. $this->_errors[] = sprintf('Legacy Minify rewrite rules have been found. To remove them manually, edit the configuration file (<strong>%s</strong>) and remove all lines between and including <strong>%s</strong> and <strong>%s</strong> markers inclusive. Or if permission allow this can be done automatically, by clicking here: %s. %s', w3_get_minify_rules_core_path(), W3TC_MARKER_BEGIN_MINIFY_LEGACY, W3TC_MARKER_END_MINIFY_LEGACY, $this->button_link('auto-remove', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_minify_remove_rules_legacy', $this->_page), 'w3tc')), $this->button_hide_note('Hide this message', 'minify_rules_legacy'));
  786. }
  787. if ($this->_config->get_string('minify.engine') == 'file' && $this->_config->get_boolean('notes.minify_rules_cache') && !$w3_plugin_minify->check_rules_cache()) {
  788. $this->_errors[] = sprintf('Minify is not active. To enable it, add the following rules into the server configuration file (<strong>%s</strong>) of the site %s <textarea class="w3tc-rules" cols="120" rows="10" readonly="readonly">%s</textarea>. This can be done automatically, by clicking here: %s. %s', w3_get_minify_rules_cache_path(), $this->button('view code', '', 'w3tc-show-rules'), htmlspecialchars($w3_plugin_minify->generate_rules_cache()), $this->button_link('auto-install', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_minify_write_rules_cache', $this->_page), 'w3tc')), $this->button_hide_note('Hide this message', 'minify_rules_cache'));
  789. }
  790. }
  791. /**
  792. * Minifiers availability error handling
  793. */
  794. $minifiers_errors = array();
  795. if ($this->_config->get_string('minify.js.engine') == 'yuijs') {
  796. $path_java = $this->_config->get_string('minify.yuijs.path.java');
  797. $path_jar = $this->_config->get_string('minify.yuijs.path.jar');
  798. if (!file_exists($path_java)) {
  799. $minifiers_errors[] = sprintf('YUI Compressor (JS): JAVA executable path was not found. The default minifier JSMin will be used instead.');
  800. } elseif (!file_exists($path_jar)) {
  801. $minifiers_errors[] = sprintf('YUI Compressor (JS): JAR file path was not found. The default minifier JSMin will be used instead.');
  802. }
  803. }
  804. if ($this->_config->get_string('minify.css.engine') == 'yuicss') {
  805. $path_java = $this->_config->get_string('minify.yuicss.path.java');
  806. $path_jar = $this->_config->get_string('minify.yuicss.path.jar');
  807. if (!file_exists($path_java)) {
  808. $minifiers_errors[] = sprintf('YUI Compressor (CSS): JAVA executable path was not found. The default CSS minifier will be used instead.');
  809. } elseif (!file_exists($path_jar)) {
  810. $minifiers_errors[] = sprintf('YUI Compressor (CSS): JAR file path was not found. The default CSS minifier will be used instead.');
  811. }
  812. }
  813. if ($this->_config->get_string('minify.js.engine') == 'ccjs') {
  814. $path_java = $this->_config->get_string('minify.ccjs.path.java');
  815. $path_jar = $this->_config->get_string('minify.ccjs.path.jar');
  816. if (!file_exists($path_java)) {
  817. $minifiers_errors[] = sprintf('Closure Compiler: JAVA executable path was not found. The default minifier JSMin will be used instead.');
  818. } elseif (!file_exists($path_jar)) {
  819. $minifiers_errors[] = sprintf('Closure Compiler: JAR file path was not found. The default minifier JSMin will be used instead.');
  820. }
  821. }
  822. if (count($minifiers_errors)) {
  823. $minify_error = 'The following minifiers cannot be found or are no longer working:</p><ul>';
  824. foreach ($minifiers_errors as $minifiers_error) {
  825. $minify_error .= '<li>' . $minifiers_error . '</li>';
  826. }
  827. $minify_error .= '</ul><p>This message will automatically disappear once the issue is resolved.';
  828. $this->_errors[] = $minify_error;
  829. }
  830. }
  831. /**
  832. * Check for database cache availability
  833. */
  834. if ($this->_config->get_boolean('dbcache.enabled')) {
  835. if (!$this->db_installed()) {
  836. $this->_errors[] = sprintf('Database caching is not available: %s is not installed. Either the <strong>%s</strong> directory is not write-able or another caching plugin is installed. This error message will automatically disappear once the change is successfully made.', W3TC_ADDIN_FILE_DB, WP_CONTENT_DIR);
  837. } elseif (!$this->db_check()) {
  838. $this->_errors[] = sprintf('Database caching is not available. The current add-in %s is either an incorrect file or an old version. De-activate the plugin, remove the file, then activate the plugin again.', W3TC_ADDIN_FILE_DB);
  839. }
  840. }
  841. /**
  842. * Check for object cache availability
  843. */
  844. if ($this->_config->get_boolean('objectcache.enabled')) {
  845. if (!$this->objectcache_installed()) {
  846. $this->_errors[] = sprintf('Object caching is not available: %s is not installed. Either the <strong>%s</strong> directory is not write-able or another caching plugin is installed. This error message will automatically disappear once the change is successfully made.', W3TC_ADDIN_FILE_OBJECT_CACHE, WP_CONTENT_DIR);
  847. } elseif (!$this->objectcache_check()) {
  848. $this->_errors[] = sprintf('Object caching is not available. The current add-in %s is either an incorrect file or an old version. De-activate the plugin, remove the file, then activate the plugin again.', W3TC_ADDIN_FILE_OBJECT_CACHE);
  849. }
  850. }
  851. /**
  852. * Check memcached
  853. */
  854. $memcaches_errors = array();
  855. if ($this->_config->get_boolean('pgcache.enabled') && $this->_config->get_string('pgcache.engine') == 'memcached') {
  856. $pgcache_memcached_servers = $this->_config->get_array('pgcache.memcached.servers');
  857. if (!$this->is_memcache_available($pgcache_memcached_servers)) {
  858. $this->_errors[] = sprintf('Page Cache: %s.', implode(', ', $pgcache_memcached_servers));
  859. }
  860. }
  861. if ($this->_config->get_boolean('minify.enabled') && $this->_config->get_string('minify.engine') == 'memcached') {
  862. $minify_memcached_servers = $this->_config->get_array('minify.memcached.servers');
  863. if (!$this->is_memcache_available($minify_memcached_servers)) {
  864. $memcaches_errors[] = sprintf('Minify: %s.', implode(', ', $minify_memcached_servers));
  865. }
  866. }
  867. if ($this->_config->get_boolean('dbcache.enabled') && $this->_config->get_string('dbcache.engine') == 'memcached') {
  868. $dbcache_memcached_servers = $this->_config->get_array('dbcache.memcached.servers');
  869. if (!$this->is_memcache_available($dbcache_memcached_servers)) {
  870. $memcaches_errors[] = sprintf('Database Cache: %s.', implode(', ', $dbcache_memcached_servers));
  871. }
  872. }
  873. if ($this->_config->get_boolean('objectcache.enabled') && $this->_config->get_string('objectcache.engine') == 'memcached') {
  874. $objectcache_memcached_servers = $this->_config->get_array('objectcache.memcached.servers');
  875. if (!$this->is_memcache_available($objectcache_memcached_servers)) {
  876. $memcaches_errors[] = sprintf('Object Cache: %s.', implode(', ', $objectcache_memcached_servers));
  877. }
  878. }
  879. if (count($memcaches_errors)) {
  880. $memcache_error = 'The following memcached servers are not responding or not running:</p><ul>';
  881. foreach ($memcaches_errors as $memcaches_error) {
  882. $memcache_error .= '<li>' . $memcaches_error . '</li>';
  883. }
  884. $memcache_error .= '</ul><p>This message will automatically disappear once the issue is resolved.';
  885. $this->_errors[] = $memcache_error;
  886. }
  887. /**
  888. * Check PHP version
  889. */
  890. if (!W3TC_PHP5 && $this->_config->get_boolean('notes.php_is_old')) {
  891. $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'));
  892. }
  893. /**
  894. * Check CURL extension
  895. */
  896. if ($this->_config->get_boolean('notes.no_curl') && $this->_config->get_boolean('cdn.enabled') && !function_exists('curl_init')) {
  897. $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'));
  898. }
  899. /**
  900. * Check Zlib extension
  901. */
  902. if ($this->_config->get_boolean('notes.no_zlib') && !function_exists('gzencode')) {
  903. $this->_notes[] = sprintf('Unfortunately the PHP installation is incomplete, the <strong>zlib module is missing</strong>. This is a core PHP module. Notify the server administrator. %s', $this->button_hide_note('Hide this message', 'no_zlib'));
  904. }
  905. /**
  906. * Check if Zlib output compression is enabled
  907. */
  908. if ($this->_config->get_boolean('notes.zlib_output_compression') && w3_zlib_output_compression()) {
  909. $this->_notes[] = sprintf('Either the PHP configuration, web server configuration or a script in the WordPress installation has <strong>zlib.output_compression</strong> enabled.<br />Please locate and disable this setting to ensure proper HTTP compression behavior. %s', $this->button_hide_note('Hide this message', 'zlib_output_compression'));
  910. }
  911. /**
  912. * Check wp-content permissions
  913. */
  914. if (!W3TC_WIN && $this->_config->get_boolean('notes.wp_content_perms')) {
  915. $wp_content_stat = stat(WP_CONTENT_DIR);
  916. $wp_content_mode = ($wp_content_stat['mode'] & 0777);
  917. if ($wp_content_mode != 0755) {
  918. $this->_notes[] = sprintf('<strong>%s</strong> is write-able. When 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'));
  919. }
  920. }
  921. /**
  922. * Check permalinks
  923. */
  924. if ($this->_config->get_boolean('notes.no_permalink_rules') && (($this->_config->get_boolean('pgcache.enabled') && $this->_config->get_string('pgcache.engine') == 'file_generic') || ($this->_config->get_boolean('browsercache.enabled') && $this->_config->get_boolean('browsercache.no404wp'))) && !w3_is_permalink_rules()) {
  925. $this->_errors[] = sprintf('The required directives for fancy permalinks could not be detected, please confirm they are available: <a href="http://codex.wordpress.org/Using_Permalinks#Creating_and_editing_.28.htaccess.29">Creating and editing</a> %s', $this->button_hide_note('Hide this message', 'no_permalink_rules'));
  926. }
  927. /**
  928. * CDN
  929. */
  930. if ($this->_config->get_boolean('cdn.enabled')) {
  931. /**
  932. * Check upload settings
  933. */
  934. $upload_info = w3_upload_info();
  935. if (!$upload_info) {
  936. $upload_path = get_option('upload_path');
  937. $upload_path = trim($upload_path);
  938. if (empty($upload_path)) {
  939. $upload_path = WP_CONTENT_DIR . '/uploads';
  940. $this->_errors[] = sprintf('The uploads directory is not available. Default WordPress directories will be created: <strong>%s</strong>.', $upload_path);
  941. }
  942. if (!w3_is_multisite()) {
  943. $this->_errors[] = sprintf('The uploads path found in the database (%s) is inconsistent with the actual path. Please manually adjust the upload path either in miscellaneous settings or if not using a custom path %s automatically to resolve the issue.', $upload_path, $this->button_link('update the path', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_update_upload_path', $this->_page), 'w3tc')));
  944. }
  945. }
  946. /**
  947. * Check CDN settings
  948. */
  949. $cdn_engine = $this->_config->get_string('cdn.engine');
  950. switch (true) {
  951. case ($cdn_engine == 'ftp' && !count($this->_config->get_array('cdn.ftp.domain'))):
  952. $this->_errors[] = 'Content Delivery Network Error: The <strong>"Replace default hostname with"</strong> field must be populated. Enter <acronym title="Content Delivery Network">CDN</acronym> provider hostname. <em>(This is the hostname used in order to view objects in a browser.)</em>';
  953. break;
  954. case ($cdn_engine == 's3' && ($this->_config->get_string('cdn.s3.key') == '' || $this->_config->get_string('cdn.s3.secret') == '' || $this->_config->get_string('cdn.s3.bucket') == '')):
  955. $this->_errors[] = 'Content Delivery Network Error: The <strong>"Access key", "Secret key" and "Bucket"</strong> fields must be populated.';
  956. break;
  957. 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') == '' && !count($this->_config->get_array('cdn.cf.cname'))))):
  958. $this->_errors[] = 'Content Delivery Network Error: The <strong>"Access key", "Secret key", "Bucket" and "Replace default hostname with"</strong> fields must be populated.';
  959. break;
  960. case ($cdn_engine == 'cf2' && ($this->_config->get_string('cdn.cf2.key') == '' || $this->_config->get_string('cdn.cf2.secret') == '' || ($this->_config->get_string('cdn.cf2.id') == '' && !count($this->_config->get_array('cdn.cf2.cname'))))):
  961. $this->_errors[] = 'Content Delivery Network Error: The <strong>"Access key", "Secret key" and "Replace default hostname with"</strong> fields must be populated.';
  962. break;
  963. case ($cdn_engine == 'rscf' && ($this->_config->get_string('cdn.rscf.user') == '' || $this->_config->get_string('cdn.rscf.key') == '' || $this->_config->get_string('cdn.rscf.container') == '' || !count($this->_config->get_array('cdn.rscf.cname')))):
  964. $this->_errors[] = 'Content Delivery Network Error: The <strong>"Username", "API key", "Container" and "Replace default hostname with"</strong> fields must be populated.';
  965. break;
  966. case ($cdn_engine == 'azure' && ($this->_config->get_string('cdn.azure.user') == '' || $this->_config->get_string('cdn.azure.key') == '' || $this->_config->get_string('cdn.azure.container') == '')):
  967. $this->_errors[] = 'Content Delivery Network Error: The <strong>"Account name", "Account key" and "Container"</strong> fields must be populated.';
  968. break;
  969. case ($cdn_engine == 'mirror' && !count($this->_config->get_array('cdn.mirror.domain'))):
  970. $this->_errors[] = 'Content Delivery Network Error: The <strong>"Replace default hostname with"</strong> field must be populated.';
  971. break;
  972. case ($cdn_engine == 'netdna' && !count($this->_config->get_array('cdn.netdna.domain'))):
  973. $this->_errors[] = 'Content Delivery Network Error: The <strong>"Replace default hostname with"</strong> field must be populated.';
  974. break;
  975. case ($cdn_engine == 'cotendo' && !count($this->_config->get_array('cdn.cotendo.domain'))):
  976. $this->_errors[] = 'Content Delivery Network Error: The <strong>"Replace default hostname with"</strong> field must be populated.';
  977. break;
  978. case ($cdn_engine == 'edgecast' && !count($this->_config->get_array('cdn.edgecast.domain'))):
  979. $this->_errors[] = 'Content Delivery Network Error: The <strong>"Replace default hostname with"</strong> field must be populated.';
  980. break;
  981. }
  982. }
  983. /**
  984. * Preview mode
  985. */
  986. if (w3_is_preview_config()) {
  987. $this->_notes[] = sprintf('Preview mode is active: Changed settings will not take effect until preview mode is %s or %s. %s any changed settings (without deploying), or make additional changes.', $this->button_link('deploy', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_preview_deploy', $this->_page), 'w3tc')), $this->button_link('disable', wp_nonce_url(sprintf('admin.php?page=%s&w3tc_preview_save&preview=0', $this->_page), 'w3tc')), $this->button_link('Preview', w3_get_home_url() . '/?w3tc_preview=1', true));
  988. }
  989. /**
  990. * Show tab
  991. */
  992. switch ($this->_page) {
  993. case 'w3tc_general':
  994. $this->options_general();
  995. break;
  996. case 'w3tc_pgcache':
  997. $this->options_pgcache();
  998. break;
  999. case 'w3tc_minify':
  1000. $this->options_minify();
  1001. break;
  1002. case 'w3tc_dbcache':
  1003. $this->options_dbcache();
  1004. break;
  1005. case 'w3tc_objectcache':
  1006. $this->options_objectcache();
  1007. break;
  1008. case 'w3tc_browsercache':
  1009. $this->options_browsercache();
  1010. break;
  1011. case 'w3tc_mobile':
  1012. $this->options_mobile();
  1013. break;
  1014. case 'w3tc_referrer':
  1015. $this->options_referrer();
  1016. break;
  1017. case 'w3tc_cdn':
  1018. $this->options_cdn();
  1019. break;
  1020. case 'w3tc_faq':
  1021. $this->options_faq();
  1022. break;
  1023. case 'w3tc_support':
  1024. $this->options_support();
  1025. break;
  1026. case 'w3tc_install':
  1027. $this->options_install();
  1028. break;
  1029. case 'w3tc_about':
  1030. $this->options_about();
  1031. break;
  1032. }
  1033. }
  1034. /**
  1035. * General tab
  1036. *
  1037. * @return void
  1038. */
  1039. function options_general() {
  1040. global $current_user;
  1041. $preview = w3_is_preview_config();
  1042. $pgcache_enabled = $this->_config->get_boolean('pgcache.enabled');
  1043. $dbcache_enabled = $this->_config->get_boolean('dbcache.enabled');
  1044. $objectcache_enabled = $this->_config->get_boolean('objectcache.enabled');
  1045. $browsercache_enabled = $this->_config->get_boolean('browsercache.enabled');
  1046. $minify_enabled = $this->_config->get_boolean('minify.enabled');
  1047. $cdn_enabled = $this->_config->get_boolean('cdn.enabled');
  1048. $cloudflare_enabled = $this->_config->get_boolean('cloudflare.enabled');
  1049. $varnish_enabled = $this->_config->get_boolean('varnish.enabled');
  1050. $enabled = ($pgcache_enabled || $minify_enabled || $dbcache_enabled || $objectcache_enabled || $browsercache_enabled || $cdn_enabled || $cloudflare_enabled || $varnish_enabled);
  1051. $enabled_checkbox = ($pgcache_enabled && $minify_enabled && $dbcache_enabled && $objectcache_enabled && $browsercache_enabled && $cdn_enabled && $cloudflare_enabled && $varnish_enabled);
  1052. $check_rules = w3_can_check_rules();
  1053. $check_apc = function_exists('apc_store');
  1054. $check_eaccelerator = function_exists('eaccelerator_put');
  1055. $check_xcache = function_exists('xcache_set');
  1056. $check_wincache = function_exists('wincache_ucache_set');
  1057. $check_curl = function_exists('curl_init');
  1058. $check_memcached = class_exists('Memcache');
  1059. $check_ftp = function_exists('ftp_connect');
  1060. $check_tidy = class_exists('tidy');
  1061. $pgcache_engine = $this->_config->get_string('pgcache.engine');
  1062. $dbcache_engine = $this->_config->get_string('dbcache.engine');
  1063. $objectcache_engine = $this->_config->get_string('objectcache.engine');
  1064. $minify_engine = $this->_config->get_string('minify.engine');
  1065. $opcode_engines = array(
  1066. 'apc',
  1067. 'eaccelerator',
  1068. 'xcache',
  1069. 'wincache'
  1070. );
  1071. $file_engines = array(
  1072. 'file',
  1073. 'file_generic'
  1074. );
  1075. $can_empty_memcache = ($pgcache_enabled && $pgcache_engine == 'memcached');
  1076. $can_empty_memcache = $can_empty_memcache || ($pgcache_enabled && $pgcache_engine == 'memcached');
  1077. $can_empty_memcache = $can_empty_memcache || ($dbcache_enabled && $dbcache_engine == 'memcached');
  1078. $can_empty_memcache = $can_empty_memcache || ($objectcache_enabled && $objectcache_engine == 'memcached');
  1079. $can_empty_memcache = $can_empty_memcache || ($minify_enabled && $minify_engine == 'memcached');
  1080. $can_empty_opcode = ($pgcache_enabled && in_array($pgcache_engine, $opcode_engines));
  1081. $can_empty_opcode = $can_empty_opcode || ($dbcache_enabled && in_array($dbcache_engine, $opcode_engines));
  1082. $can_empty_opcode = $can_empty_opcode || ($objectcache_enabled && in_array($objectcache_engine, $opcode_engines));
  1083. $can_empty_opcode = $can_empty_opcode || ($minify_enabled && in_array($minify_engine, $opcode_engines));
  1084. $can_empty_file = ($pgcache_enabled && in_array($pgcache_engine, $file_engines));
  1085. $can_empty_file = $can_empty_file || ($dbcache_enabled && in_array($dbcache_engine, $file_engines));
  1086. $can_empty_file = $can_empty_file || ($objectcache_enabled && in_array($objectcache_engine, $file_engines));
  1087. $can_empty_file = $can_empty_file || ($minify_enabled && in_array($minify_engine, $file_engines));
  1088. $cloudflare_signup_email = '';
  1089. $cloudflare_signup_user = '';
  1090. if (is_a($current_user, 'WP_User')) {
  1091. if ($current_user->user_email) {
  1092. $cloudflare_signup_email = $current_user->user_email;
  1093. }
  1094. if ($current_user->user_login && $current_user->user_login != 'admin') {
  1095. $cloudflare_signup_user = $current_user->user_login;
  1096. }
  1097. }
  1098. $cloudflare_seclvls = array(
  1099. 'high' => 'High',
  1100. 'med' => 'Medium',
  1101. 'low' => 'Low'
  1102. );
  1103. $cloudflare_devmodes = array(
  1104. 1 => 'On',
  1105. 0 => 'Off'
  1106. );
  1107. $cloudflare_seclvl = 'high';
  1108. $cloudflare_devmode_expire = 0;
  1109. $cloudflare_devmode = 0;
  1110. if ($cloudflare_enabled && $this->_config->get_string('cloudflare.email') && $this->_config->get_string('cloudflare.key')) {
  1111. $this->cloudflare_read($cloudflare_seclvl, $cloudflare_devmode_expire);
  1112. $cloudflare_devmode = ($cloudflare_devmode_expire ? 1 : 0);
  1113. }
  1114. $debug = ($this->_config->get_boolean('dbcache.debug') || $this->_config->get_boolean('objectcache.debug') || $this->_config->get_boolean('pgcache.debug') || $this->_config->get_boolean('minify.debug') || $this->_config->get_boolean('cdn.debug'));
  1115. $file_nfs = ($this->_config->get_boolean('pgcache.file.nfs') || $this->_config->get_boolean('minify.file.nfs'));
  1116. $file_locking = ($this->_config->get_boolean('dbcache.file.locking') || $this->_config->get_boolean('objectcache.file.locking') || $this->_config->get_boolean('pgcache.file.locking') || $this->_config->get_boolean('minify.file.locking'));
  1117. $support = $this->_config->get_string('common.support');
  1118. $supports = $this->get_supports();
  1119. include W3TC_INC_DIR . '/options/general.php';
  1120. }
  1121. /**
  1122. * Page cache tab
  1123. *
  1124. * @return void
  1125. */
  1126. function options_pgcache() {
  1127. global $wp_rewrite;
  1128. $feeds = $wp_rewrite->feeds;
  1129. $feed_key = array_search('feed', $feeds);
  1130. if ($feed_key !== false) {
  1131. unset($feeds[$feed_key]);
  1132. }
  1133. $default_feed = get_default_feed();
  1134. $pgcache_enabled = $this->_config->get_boolean('pgcache.enabled');
  1135. $permalink_structure = get_option('permalink_structure');
  1136. include W3TC_INC_DIR . '/options/pgcache.php';
  1137. }
  1138. /**
  1139. * Minify tab
  1140. *
  1141. * @return void
  1142. */
  1143. function options_minify() {
  1144. $minify_enabled = $this->_config->get_boolean('minify.enabled');
  1145. $themes = $this->get_themes();
  1146. $templates = array();
  1147. $current_theme = get_current_theme();
  1148. $current_theme_key = '';
  1149. foreach ($themes as $theme_key => $theme_name) {
  1150. if ($theme_name == $current_theme) {
  1151. $current_theme_key = $theme_key;
  1152. }
  1153. $templates[$theme_key] = $this->get_theme_templates($theme_name);
  1154. }
  1155. $css_imports_values = array(
  1156. '' => 'None',
  1157. 'bubble' => 'Bubble',
  1158. 'process' => 'Process',
  1159. );
  1160. $auto = $this->_config->get_boolean('minify.auto');
  1161. require_once W3TC_LIB_W3_DIR . '/Request.php';
  1162. $js_theme = W3_Request::get_string('js_theme', $current_theme_key);
  1163. $js_groups = $this->_config->get_array('minify.js.groups');
  1164. $css_theme = W3_Request::get_string('css_theme', $current_theme_key);
  1165. $css_groups = $this->_config->get_array('minify.css.groups');
  1166. $js_engine = $this->_config->get_string('minify.js.engine');
  1167. $css_engine = $this->_config->get_string('minify.css.engine');
  1168. $html_engine = $this->_config->get_string('minify.html.engine');
  1169. $css_imports = $this->_config->get_string('minify.css.imports');
  1170. include W3TC_INC_DIR . '/options/minify.php';
  1171. }
  1172. /**
  1173. * Database cache tab
  1174. *
  1175. * @return void
  1176. */
  1177. function options_dbcache() {
  1178. $dbcache_enabled = $this->_config->get_boolean('dbcache.enabled');
  1179. include W3TC_INC_DIR . '/options/dbcache.php';
  1180. }
  1181. /**
  1182. * Objects cache tab
  1183. *
  1184. * @return void
  1185. */
  1186. function options_objectcache() {
  1187. $objectcache_enabled = $this->_config->get_boolean('objectcache.enabled');
  1188. include W3TC_INC_DIR . '/options/objectcache.php';
  1189. }
  1190. /**
  1191. * Objects cache tab
  1192. *
  1193. * @return void
  1194. */
  1195. function options_browsercache() {
  1196. $browsercache_enabled = $this->_config->get_boolean('browsercache.enabled');
  1197. $browsercache_expires = ($this->_config->get_boolean('browsercache.cssjs.expires') && $this->_config->get_boolean('browsercache.html.expires') && $this->_config->get_boolean('browsercache.other.expires'));
  1198. $browsercache_cache_control = ($this->_config->get_boolean('browsercache.cssjs.cache.control') && $this->_config->get_boolean('browsercache.html.cache.control') && $this->_config->get_boolean('browsercache.other.cache.control'));
  1199. $browsercache_etag = ($this->_config->get_boolean('browsercache.cssjs.etag') && $this->_config->get_boolean('browsercache.html.etag') && $this->_config->get_boolean('browsercache.other.etag'));
  1200. $browsercache_w3tc = ($this->_config->get_boolean('browsercache.cssjs.w3tc') && $this->_config->get_boolean('browsercache.html.w3tc') && $this->_config->get_boolean('browsercache.other.w3tc'));
  1201. $browsercache_compression = ($this->_config->get_boolean('browsercache.cssjs.compression') && $this->_config->get_boolean('browsercache.html.compression') && $this->_config->get_boolean('browsercache.other.compression'));
  1202. $browsercache_replace = ($this->_config->get_boolean('browsercache.cssjs.replace') && $this->_config->get_boolean('browsercache.other.replace'));
  1203. include W3TC_INC_DIR . '/options/browsercache.php';
  1204. }
  1205. /**
  1206. * Mobile tab
  1207. *
  1208. * @return void
  1209. */
  1210. function options_mobile() {
  1211. $groups = $this->_config->get_array('mobile.rgroups');
  1212. $w3_mobile = & w3_instance('W3_Mobile');
  1213. $themes = $w3_mobile->get_themes();
  1214. include W3TC_INC_DIR . '/options/mobile.php';
  1215. }
  1216. /**
  1217. * Referrer tab
  1218. *
  1219. * @return void
  1220. */
  1221. function options_referrer() {
  1222. $groups = $this->_config->get_array('referrer.rgroups');
  1223. $w3_referrer = & w3_instance('W3_Referrer');
  1224. $themes = $w3_referrer->get_themes();
  1225. include W3TC_INC_DIR . '/options/referrer.php';
  1226. }
  1227. /**
  1228. * CDN tab
  1229. *
  1230. * @return void
  1231. */
  1232. function options_cdn() {
  1233. $cdn_enabled = $this->_config->get_boolean('cdn.enabled');
  1234. $cdn_engine = $this->_config->get_string('cdn.engine');
  1235. $cdn_mirror = w3_is_cdn_mirror($cdn_engine);
  1236. $minify_enabled = (W3TC_PHP5 && $this->_config->get_boolean('minify.enabled') && $this->_config->get_boolean('minify.rewrite') && (!$this->_config->get_boolean('minify.auto') || w3_is_cdn_mirror($this->_config->get_string('cdn.engine'))));
  1237. $cookie_domain = $this->get_cookie_domain();
  1238. $set_cookie_domain = $this->is_cookie_domain_enabled();
  1239. include W3TC_INC_DIR . '/options/cdn.php';
  1240. }
  1241. /**
  1242. * FAQ tab
  1243. *
  1244. * @return void
  1245. */
  1246. function options_faq() {
  1247. $faq = $this->parse_faq();
  1248. include W3TC_INC_DIR . '/options/faq.php';
  1249. }
  1250. /**
  1251. * Support tab
  1252. *
  1253. * @return void
  1254. */
  1255. function options_support() {
  1256. require_once W3TC_LIB_W3_DIR . '/Request.php';
  1257. $request_type = W3_Request::get_string('request_type');
  1258. $payment = W3_Request::get_boolean('payment');
  1259. include W3TC_INC_DIR . '/options/support.php';
  1260. }
  1261. /**
  1262. * Install tab
  1263. *
  1264. * @return void
  1265. */
  1266. function options_install() {
  1267. $rewrite_rules = array();
  1268. if (w3_can_check_rules()) {
  1269. if ($this->_config->get_boolean('minify.enabled') && $this->_config->get_string('minify.engine') == 'file') {
  1270. $w3_plugin_minify = & w3_instance('W3_Plugin_MinifyAdmin');
  1271. $minify_rules_cache_path = w3_get_minify_rules_cache_path();
  1272. if (!isset($rewrite_rules[$minify_rules_cache_path])) {
  1273. $rewrite_rules[$minify_rules_cache_path] = '';
  1274. }
  1275. $rewrite_rules[$minify_rules_cache_path] .= $w3_plugin_minify->generate_rules_cache();
  1276. }
  1277. if ($this->_config->get_boolean('pgcache.enabled')) {
  1278. $w3_plugin_pgcache = & w3_instance('W3_Plugin_PgCacheAdmin');
  1279. $pgcache_rules_cache_path = w3_get_pgcache_rules_cache_path();
  1280. if (!isset($rewrite_rules[$pgcache_rules_cache_path])) {
  1281. $rewrite_rules[$pgcache_rules_cache_path] = '';
  1282. }
  1283. $rewrite_rules[$pgcache_rules_cache_path] .= $w3_plugin_pgcache->generate_rules_cache();
  1284. }
  1285. if ($this->_config->get_boolean('browsercache.enabled')) {
  1286. $w3_plugin_browsercache = & w3_instance('W3_Plugin_BrowserCacheAdmin');
  1287. $browsercache_rules_cache_path = w3_get_browsercache_rules_cache_path();
  1288. if (!isset($rewrite_rules[$browsercache_rules_cache_path])) {
  1289. $rewrite_rules[$browsercache_rules_cache_path] = '';
  1290. }
  1291. $rewrite_rules[$browsercache_rules_cache_path] .= $w3_plugin_browsercache->generate_rules_cache();
  1292. }
  1293. if ($this->_config->get_boolean('minify.enabled')) {
  1294. $w3_plugin_minify = & w3_instance('W3_Plugin_MinifyAdmin');
  1295. $minify_rules_core_path = w3_get_minify_rules_core_path();
  1296. if (!isset($rewrite_rules[$minify_rules_core_path])) {
  1297. $rewrite_rules[$minify_rules_core_path] = '';
  1298. }
  1299. $rewrite_rules[$minify_rules_core_path] .= $w3_plugin_minify->generate_rules_core();
  1300. }
  1301. if ($this->_config->get_boolean('pgcache.enabled')) {
  1302. $w3_plugin_pgcache = & w3_instance('W3_Plugin_PgCacheAdmin');
  1303. $pgcache_rules_core_path = w3_get_pgcache_rules_core_path();
  1304. if (!isset($rewrite_rules[$pgcache_rules_core_path])) {
  1305. $rewrite_rules[$pgcache_rules_core_path] = '';
  1306. }
  1307. $rewrite_rules[$pgcache_rules_core_path] .= $w3_plugin_pgcache->generate_rules_core();
  1308. }
  1309. if ($this->_config->get_boolean('browsercache.enabled') && $this->_config->get_boolean('browsercache.no404wp')) {
  1310. $w3_plugin_browsercache = & w3_instance('W3_Plugin_BrowserCacheAdmin');
  1311. $browsercache_rules_no404wp_path = w3_get_browsercache_rules_no404wp_path();
  1312. if (!isset($rewrite_rules[$browsercache_rules_no404wp_path])) {
  1313. $rewrite_rules[$browsercache_rules_no404wp_path] = '';
  1314. }
  1315. $rewrite_rules[$browsercache_rules_no404wp_path] .= $w3_plugin_browsercache->generate_rules_no404wp();
  1316. }
  1317. if ($this->_config->get_boolean('browsercache.enabled') && $this->_config->get_boolean('cdn.enabled') && $this->_config->get_string('cdn.engine') == 'ftp') {
  1318. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnCommon');
  1319. $cdn = & $w3_plugin_cdn->get_cdn();
  1320. $domain = $cdn->get_domain();
  1321. if ($domain) {
  1322. $cdn_rules_path = sprintf('ftp://%s/%s', $domain, w3_get_cdn_rules_path());
  1323. if (!isset($rewrite_rules[$cdn_rules_path])) {
  1324. $rewrite_rules[$cdn_rules_path] = '';
  1325. }
  1326. $rewrite_rules[$cdn_rules_path] .= $w3_plugin_browsercache->generate_rules_cache();
  1327. }
  1328. }
  1329. ksort($rewrite_rules);
  1330. reset($rewrite_rules);
  1331. }
  1332. include W3TC_INC_DIR . '/options/install.php';
  1333. }
  1334. /**
  1335. * About tab
  1336. *
  1337. * @return void
  1338. */
  1339. function options_about() {
  1340. include W3TC_INC_DIR . '/options/about.php';
  1341. }
  1342. /**
  1343. * Returns key for transient cache of "widget latest"
  1344. *
  1345. * @return string
  1346. */
  1347. function _widget_latest_cache_key() {
  1348. return 'dash_' . md5('w3tc_latest');
  1349. }
  1350. /**
  1351. * Prints latest widget contents
  1352. *
  1353. * @return void
  1354. */
  1355. function widget_latest() {
  1356. if (false !== ($output = get_transient($this->_widget_latest_cache_key())))
  1357. echo $output;
  1358. else
  1359. include W3TC_INC_DIR . '/widget/latest.php';
  1360. }
  1361. /**
  1362. * Prints latest widget contents
  1363. *
  1364. * @return void
  1365. */
  1366. function action_widget_latest_ajax() {
  1367. // load content of feed
  1368. global $wp_version;
  1369. $items = array();
  1370. $items_count = $this->_config->get_integer('widget.latest.items');
  1371. if ($wp_version >= 2.8) {
  1372. include_once (ABSPATH . WPINC . '/feed.php');
  1373. $feed = fetch_feed(W3TC_FEED_URL);
  1374. if (!is_wp_error($feed)) {
  1375. $feed_items = $feed->get_items(0, $items_count);
  1376. foreach ($feed_items as $feed_item) {
  1377. $items[] = array(
  1378. 'link' => $feed_item->get_link(),
  1379. 'title' => $feed_item->get_title(),
  1380. 'description' => $feed_item->get_description()
  1381. );
  1382. }
  1383. }
  1384. } else {
  1385. include_once (ABSPATH . WPINC . '/rss.php');
  1386. $rss = fetch_rss(W3TC_FEED_URL);
  1387. if (is_object($rss)) {
  1388. $items = array_slice($rss->items, 0, $items_count);
  1389. }
  1390. }
  1391. ob_start();
  1392. include W3TC_INC_DIR . '/widget/latest_ajax.php';
  1393. // Default lifetime in cache of 12 hours (same as the feeds)
  1394. set_transient($this->_widget_latest_cache_key(), ob_get_flush(), 43200);
  1395. }
  1396. /**
  1397. * Latest widget control
  1398. *
  1399. * @param integer $widget_id
  1400. * @param array $form_inputs
  1401. * @return void
  1402. */
  1403. function widget_latest_control($widget_id, $form_inputs = array()) {
  1404. if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  1405. require_once W3TC_LIB_W3_DIR . '/Request.php';
  1406. $this->_config->set('widget.latest.items', W3_Request::get_integer('w3tc_widget_latest_items', 3));
  1407. $this->_config->save();
  1408. } else {
  1409. include W3TC_INC_DIR . '/widget/latest_control.php';
  1410. }
  1411. }
  1412. /**
  1413. * PageSpeed widget
  1414. *
  1415. * @return void
  1416. */
  1417. function widget_pagespeed() {
  1418. require_once W3TC_LIB_W3_DIR . '/PageSpeed.php';
  1419. require_once W3TC_LIB_W3_DIR . '/Request.php';
  1420. $key = $this->_config->get_string('widget.pagespeed.key');
  1421. $force = W3_Request::get_boolean('w3tc_widget_pagespeed_force');
  1422. $results = null;
  1423. if ($key) {
  1424. $w3_pagespeed = new W3_PageSpeed();
  1425. $results = $w3_pagespeed->analyze(w3_get_home_url(), $force);
  1426. }
  1427. include W3TC_INC_DIR . '/widget/pagespeed.php';
  1428. }
  1429. /**
  1430. * Latest widget control
  1431. *
  1432. * @param integer $widget_id
  1433. * @param array $form_inputs
  1434. * @return void
  1435. */
  1436. function widget_pagespeed_control($widget_id, $form_inputs = array()) {
  1437. if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  1438. require_once W3TC_LIB_W3_DIR . '/Request.php';
  1439. $this->_config->set('widget.pagespeed.key', W3_Request::get_string('w3tc_widget_pagespeed_key'));
  1440. $this->_config->save();
  1441. } else {
  1442. include W3TC_INC_DIR . '/widget/pagespeed_control.php';
  1443. }
  1444. }
  1445. /**
  1446. * Flush all caches action
  1447. *
  1448. * @return void
  1449. */
  1450. function action_flush_all() {
  1451. $this->flush_all();
  1452. $this->redirect(array(
  1453. 'w3tc_note' => 'flush_all'
  1454. ), true);
  1455. }
  1456. /**
  1457. * Flush memcache cache action
  1458. *
  1459. * @return void
  1460. */
  1461. function action_flush_memcached() {
  1462. $this->flush_memcached();
  1463. $this->redirect(array(
  1464. 'w3tc_note' => 'flush_memcached'
  1465. ), true);
  1466. }
  1467. /**
  1468. * Flush opcode caches action
  1469. *
  1470. * @return void
  1471. */
  1472. function action_flush_opcode() {
  1473. $this->flush_opcode();
  1474. $this->redirect(array(
  1475. 'w3tc_note' => 'flush_opcode'
  1476. ), true);
  1477. }
  1478. /**
  1479. * Flush file caches action
  1480. *
  1481. * @return void
  1482. */
  1483. function action_flush_file() {
  1484. $this->flush_file();
  1485. $this->redirect(array(
  1486. 'w3tc_note' => 'flush_file'
  1487. ), true);
  1488. }
  1489. /**
  1490. * Flush page cache action
  1491. *
  1492. * @return void
  1493. */
  1494. function action_flush_pgcache() {
  1495. $this->flush_pgcache();
  1496. $this->_config->set('notes.need_empty_pgcache', false);
  1497. $this->_config->set('notes.plugins_updated', false);
  1498. if (!$this->_config->save()) {
  1499. $this->redirect(array(
  1500. 'w3tc_error' => 'config_save'
  1501. ), true);
  1502. }
  1503. $this->redirect(array(
  1504. 'w3tc_note' => 'flush_pgcache'
  1505. ), true);
  1506. }
  1507. /**
  1508. * Flush database cache action
  1509. *
  1510. * @return void
  1511. */
  1512. function action_flush_dbcache() {
  1513. $this->flush_dbcache();
  1514. $this->redirect(array(
  1515. 'w3tc_note' => 'flush_dbcache'
  1516. ), true);
  1517. }
  1518. /**
  1519. * Flush object cache action
  1520. *
  1521. * @return void
  1522. */
  1523. function action_flush_objectcache() {
  1524. $this->flush_objectcache();
  1525. $this->_config->set('notes.need_empty_objectcache', false);
  1526. if (!$this->_config->save()) {
  1527. $this->redirect(array(
  1528. 'w3tc_error' => 'config_save'
  1529. ), true);
  1530. }
  1531. $this->redirect(array(
  1532. 'w3tc_note' => 'flush_objectcache'
  1533. ), true);
  1534. }
  1535. /**
  1536. * Flush minify action
  1537. *
  1538. * @return void
  1539. */
  1540. function action_flush_minify() {
  1541. $this->flush_minify();
  1542. $this->_config->set('notes.need_empty_minify', false);
  1543. if (!$this->_config->save()) {
  1544. $this->redirect(array(
  1545. 'w3tc_error' => 'config_save'
  1546. ), true);
  1547. }
  1548. $this->redirect(array(
  1549. 'w3tc_note' => 'flush_minify'
  1550. ), true);
  1551. }
  1552. /**
  1553. * Import config action
  1554. *
  1555. * @return void
  1556. */
  1557. function action_config_import() {
  1558. $error = '';
  1559. @$config = & new W3_Config();
  1560. if (!isset($_FILES['config_file']['error']) || $_FILES['config_file']['error'] == UPLOAD_ERR_NO_FILE) {
  1561. $error = 'config_import_no_file';
  1562. } elseif ($_FILES['config_file']['error'] != UPLOAD_ERR_OK) {
  1563. $error = 'config_import_upload';
  1564. } else {
  1565. ob_start();
  1566. $imported = $config->read($_FILES['config_file']['tmp_name']);
  1567. ob_end_clean();
  1568. if (!$imported) {
  1569. $error = 'config_import_import';
  1570. }
  1571. }
  1572. if ($error) {
  1573. $this->redirect(array(
  1574. 'w3tc_error' => $error
  1575. ), true);
  1576. }
  1577. if ($this->config_save($this->_config, $config)) {
  1578. $this->redirect(array(
  1579. 'w3tc_note' => 'config_import'
  1580. ), true);
  1581. } else {
  1582. $this->redirect(array(
  1583. 'w3tc_error' => 'config_save'
  1584. ), true);
  1585. }
  1586. }
  1587. /**
  1588. * Export config action
  1589. *
  1590. * @return void
  1591. */
  1592. function action_config_export() {
  1593. @header(sprintf('Content-Disposition: attachment; filename=%s', basename(W3TC_CONFIG_PATH)));
  1594. @readfile(W3TC_CONFIG_PATH);
  1595. die();
  1596. }
  1597. /**
  1598. * Reset config action
  1599. *
  1600. * @return void
  1601. */
  1602. function action_config_reset() {
  1603. @$config = & new W3_Config();
  1604. $config->load_defaults();
  1605. $config->set_defaults();
  1606. if ($this->config_save($this->_config, $config, true)) {
  1607. $this->redirect(array(
  1608. 'w3tc_note' => 'config_reset'
  1609. ), true);
  1610. } else {
  1611. $this->redirect(array(
  1612. 'w3tc_error' => 'config_reset'
  1613. ), true);
  1614. }
  1615. }
  1616. /**
  1617. * Save preview option
  1618. *
  1619. * @return void
  1620. */
  1621. function action_preview_save() {
  1622. require_once W3TC_LIB_W3_DIR . '/Request.php';
  1623. $preview = W3_Request::get_boolean('preview');
  1624. if ($preview) {
  1625. if ($this->_config->save(true)) {
  1626. $this->redirect(array(
  1627. 'w3tc_note' => 'preview_enable'
  1628. ));
  1629. } else {
  1630. $this->redirect(array(
  1631. 'w3tc_error' => 'preview_enable'
  1632. ));
  1633. }
  1634. } else {
  1635. @$config = & new W3_Config(false);
  1636. if (@unlink(W3TC_CONFIG_PREVIEW_PATH) && $this->config_save($this->_config, $config, false)) {
  1637. $this->redirect(array(
  1638. 'w3tc_note' => 'preview_disable'
  1639. ));
  1640. } else {
  1641. $this->redirect(array(
  1642. 'w3tc_error' => 'preview_disable'
  1643. ));
  1644. }
  1645. }
  1646. }
  1647. /**
  1648. * Deploy preview settings action
  1649. *
  1650. * @return void
  1651. */
  1652. function action_preview_deploy() {
  1653. if ($this->_config->save(false)) {
  1654. $this->flush_all();
  1655. $this->redirect(array(
  1656. 'w3tc_note' => 'preview_deploy'
  1657. ));
  1658. } else {
  1659. $this->redirect(array(
  1660. 'w3tc_error' => 'preview_deploy'
  1661. ));
  1662. }
  1663. }
  1664. /**
  1665. * Support select action
  1666. *
  1667. * @return void
  1668. */
  1669. function action_support_select() {
  1670. include W3TC_INC_DIR . '/options/support/select.php';
  1671. }
  1672. /**
  1673. * Support payment action
  1674. *
  1675. * @return void
  1676. */
  1677. function action_support_payment() {
  1678. require_once W3TC_LIB_W3_DIR . '/Request.php';
  1679. $request_type = W3_Request::get_string('request_type');
  1680. if (!isset($this->_request_types[$request_type])) {
  1681. $request_type = 'bug_report';
  1682. }
  1683. $request_id = date('YmdHi');
  1684. $return_url = admin_url('admin.php?page=w3tc_support&request_type=' . $request_type . '&payment=1&request_id=' . $request_id);
  1685. $cancel_url = admin_url('admin.php?page=w3tc_general');
  1686. include W3TC_INC_DIR . '/options/support/payment.php';
  1687. }
  1688. /**
  1689. * Support form action
  1690. *
  1691. * @return void
  1692. */
  1693. function action_support_form() {
  1694. global $current_user;
  1695. require_once W3TC_LIB_W3_DIR . '/Request.php';
  1696. $name = '';
  1697. $email = '';
  1698. $request_type = W3_Request::get_string('request_type');
  1699. if (!isset($this->_request_types[$request_type])) {
  1700. $request_type = 'bug_report';
  1701. }
  1702. if (is_a($current_user, 'WP_User')) {
  1703. if ($current_user->first_name) {
  1704. $name = $current_user->first_name;
  1705. }
  1706. if ($current_user->last_name) {
  1707. $name .= ($name != '' ? ' ' : '') . $current_user->last_name;
  1708. }
  1709. if ($name == 'admin') {
  1710. $name = '';
  1711. }
  1712. if ($current_user->user_email) {
  1713. $email = $current_user->user_email;
  1714. }
  1715. }
  1716. $theme = get_theme(get_current_theme());
  1717. $template_files = (isset($theme['Template Files']) ? (array) $theme['Template Files'] : array());
  1718. $ajax = W3_Request::get_boolean('ajax');
  1719. $request_id = W3_Request::get_string('request_id', date('YmdHi'));
  1720. $payment = W3_Request::get_boolean('payment');
  1721. $url = W3_Request::get_string('url', w3_get_domain_url());
  1722. $name = W3_Request::get_string('name', $name);
  1723. $email = W3_Request::get_string('email', $email);
  1724. $twitter = W3_Request::get_string('twitter');
  1725. $phone = W3_Request::get_string('phone');
  1726. $subject = W3_Request::get_string('subject');
  1727. $description = W3_Request::get_string('description');
  1728. $templates = W3_Request::get_array('templates');
  1729. $forum_url = W3_Request::get_string('forum_url');
  1730. $wp_login = W3_Request::get_string('wp_login');
  1731. $wp_password = W3_Request::get_string('wp_password');
  1732. $ftp_host = W3_Request::get_string('ftp_host');
  1733. $ftp_login = W3_Request::get_string('ftp_login');
  1734. $ftp_password = W3_Request::get_string('ftp_password');
  1735. include W3TC_INC_DIR . '/options/support/form.php';
  1736. }
  1737. /**
  1738. * Send support request action
  1739. *
  1740. * @return void
  1741. */
  1742. function action_support_request() {
  1743. require_once W3TC_LIB_W3_DIR . '/Request.php';
  1744. $request_type = W3_Request::get_string('request_type');
  1745. $payment = W3_Request::get_boolean('payment');
  1746. $request_id = W3_Request::get_string('request_id');
  1747. $url = W3_Request::get_string('url');
  1748. $name = W3_Request::get_string('name');
  1749. $email = W3_Request::get_string('email');
  1750. $twitter = W3_Request::get_string('twitter');
  1751. $phone = W3_Request::get_string('phone');
  1752. $subject = W3_Request::get_string('subject');
  1753. $description = W3_Request::get_string('description');
  1754. $templates = W3_Request::get_array('templates');
  1755. $forum_url = W3_Request::get_string('forum_url');
  1756. $wp_login = W3_Request::get_string('wp_login');
  1757. $wp_password = W3_Request::get_string('wp_password');
  1758. $ftp_host = W3_Request::get_string('ftp_host');
  1759. $ftp_login = W3_Request::get_string('ftp_login');
  1760. $ftp_password = W3_Request::get_string('ftp_password');
  1761. $params = array(
  1762. 'request_type' => $request_type,
  1763. 'payment' => $payment,
  1764. 'url' => $url,
  1765. 'name' => $name,
  1766. 'email' => $email,
  1767. 'twitter' => $twitter,
  1768. 'phone' => $phone,
  1769. 'subject' => $subject,
  1770. 'description' => $description,
  1771. 'forum_url' => $forum_url,
  1772. 'wp_login' => $wp_login,
  1773. 'wp_password' => $wp_password,
  1774. 'ftp_host' => $ftp_host,
  1775. 'ftp_login' => $ftp_login,
  1776. 'ftp_password' => $ftp_password
  1777. );
  1778. foreach ($templates as $template_index => $template) {
  1779. $template_key = sprintf('templates[%d]', $template_index);
  1780. $params[$template_key] = $template;
  1781. }
  1782. if (!isset($this->_request_types[$request_type])) {
  1783. $this->redirect(array_merge($params, array(
  1784. 'w3tc_error' => 'support_request_type'
  1785. )));
  1786. }
  1787. $required = array(
  1788. 'bug_report' => 'url,name,email,subject,description',
  1789. 'new_feature' => 'url,name,email,subject,description',
  1790. 'email_support' => 'url,name,email,subject,description',
  1791. 'phone_support' => 'url,name,email,subject,description,phone',
  1792. 'plugin_config' => 'url,name,email,subject,description,wp_login,wp_password',
  1793. 'theme_config' => 'url,name,email,subject,description,wp_login,wp_password,ftp_host,ftp_login,ftp_password',
  1794. 'linux_config' => 'url,name,email,subject,description,wp_login,wp_password,ftp_host,ftp_login,ftp_password'
  1795. );
  1796. if (strstr($required[$request_type], 'url') !== false && $url == '') {
  1797. $this->redirect(array_merge($params, array(
  1798. 'w3tc_error' => 'support_request_url'
  1799. )));
  1800. }
  1801. if (strstr($required[$request_type], 'name') !== false && $name == '') {
  1802. $this->redirect(array_merge($params, array(
  1803. 'w3tc_error' => 'support_request_name'
  1804. )));
  1805. }
  1806. if (strstr($required[$request_type], 'email') !== false && !preg_match('~^[a-z0-9_\-\.]+@[a-z0-9-\.]+\.[a-z]{2,5}$~', $email)) {
  1807. $this->redirect(array_merge($params, array(
  1808. 'w3tc_error' => 'support_request_email'
  1809. )));
  1810. }
  1811. if (strstr($required[$request_type], 'phone') !== false && !preg_match('~^[0-9\-\.\ \(\)\+]+$~', $phone)) {
  1812. $this->redirect(array_merge($params, array(
  1813. 'w3tc_error' => 'support_request_phone'
  1814. )));
  1815. }
  1816. if (strstr($required[$request_type], 'subject') !== false && $subject == '') {
  1817. $this->redirect(array_merge($params, array(
  1818. 'w3tc_error' => 'support_request_subject'
  1819. )));
  1820. }
  1821. if (strstr($required[$request_type], 'description') !== false && $description == '') {
  1822. $this->redirect(array_merge($params, array(
  1823. 'w3tc_error' => 'support_request_description'
  1824. )));
  1825. }
  1826. if (strstr($required[$request_type], 'wp_login') !== false && $wp_login == '') {
  1827. $this->redirect(array_merge($params, array(
  1828. 'w3tc_error' => 'support_request_wp_login'
  1829. )));
  1830. }
  1831. if (strstr($required[$request_type], 'wp_password') !== false && $wp_password == '') {
  1832. $this->redirect(array_merge($params, array(
  1833. 'w3tc_error' => 'support_request_wp_password'
  1834. )));
  1835. }
  1836. if (strstr($required[$request_type], 'ftp_host') !== false && $ftp_host == '') {
  1837. $this->redirect(array_merge($params, array(
  1838. 'w3tc_error' => 'support_request_ftp_host'
  1839. )));
  1840. }
  1841. if (strstr($required[$request_type], 'ftp_login') !== false && $ftp_login == '') {
  1842. $this->redirect(array_merge($params, array(
  1843. 'w3tc_error' => 'support_request_ftp_login'
  1844. )));
  1845. }
  1846. if (strstr($required[$request_type], 'ftp_password') !== false && $ftp_password == '') {
  1847. $this->redirect(array_merge($params, array(
  1848. 'w3tc_error' => 'support_request_ftp_password'
  1849. )));
  1850. }
  1851. /**
  1852. * Add attachments
  1853. */
  1854. $attachments = array();
  1855. $attach_files = array(
  1856. /**
  1857. * Attach WP config file
  1858. */
  1859. w3_get_wp_config_path(),
  1860. /**
  1861. * Attach config files
  1862. */
  1863. W3TC_CONFIG_PATH,
  1864. W3TC_CONFIG_PREVIEW_PATH,
  1865. W3TC_CONFIG_MASTER_PATH,
  1866. /**
  1867. * Attach minify file
  1868. */
  1869. W3TC_MINIFY_LOG_FILE,
  1870. /**
  1871. * Attach .htaccess files
  1872. */
  1873. w3_get_pgcache_rules_core_path(),
  1874. w3_get_pgcache_rules_cache_path(),
  1875. w3_get_browsercache_rules_cache_path(),
  1876. w3_get_browsercache_rules_no404wp_path(),
  1877. w3_get_minify_rules_core_path(),
  1878. w3_get_minify_rules_cache_path()
  1879. );
  1880. foreach ($attach_files as $attach_file) {
  1881. if ($attach_file && file_exists($attach_file) && !in_array($attach_file, $attachments)) {
  1882. $attachments[] = $attach_file;
  1883. }
  1884. }
  1885. /**
  1886. * Attach server info
  1887. */
  1888. $server_info = print_r($this->get_server_info(), true);
  1889. $server_info = str_replace("\n", "\r\n", $server_info);
  1890. $server_info_path = W3TC_TMP_DIR . '/server_info.txt';
  1891. if (@file_put_contents($server_info_path, $server_info)) {
  1892. $attachments[] = $server_info_path;
  1893. }
  1894. /**
  1895. * Attach phpinfo
  1896. */
  1897. ob_start();
  1898. phpinfo();
  1899. $php_info = ob_get_contents();
  1900. ob_end_clean();
  1901. $php_info_path = W3TC_TMP_DIR . '/php_info.html';
  1902. if (@file_put_contents($php_info_path, $php_info)) {
  1903. $attachments[] = $php_info_path;
  1904. }
  1905. /**
  1906. * Attach self-test
  1907. */
  1908. ob_start();
  1909. $this->action_self_test();
  1910. $self_test = ob_get_contents();
  1911. ob_end_clean();
  1912. $self_test_path = W3TC_TMP_DIR . '/self_test.html';
  1913. if (@file_put_contents($self_test_path, $self_test)) {
  1914. $attachments[] = $self_test_path;
  1915. }
  1916. /**
  1917. * Attach templates
  1918. */
  1919. foreach ($templates as $template) {
  1920. if (!empty($template)) {
  1921. $attachments[] = $template;
  1922. }
  1923. }
  1924. /**
  1925. * Attach other files
  1926. */
  1927. if (!empty($_FILES['files'])) {
  1928. $files = (array) $_FILES['files'];
  1929. for ($i = 0, $l = count($files); $i < $l; $i++) {
  1930. if (isset($files['tmp_name'][$i]) && isset($files['name'][$i]) && isset($files['error'][$i]) && $files['error'][$i] == UPLOAD_ERR_OK) {
  1931. $path = W3TC_TMP_DIR . '/' . $files['name'][$i];
  1932. if (@move_uploaded_file($files['tmp_name'][$i], $path)) {
  1933. $attachments[] = $path;
  1934. }
  1935. }
  1936. }
  1937. }
  1938. $data = array();
  1939. if (!empty($wp_login) && !empty($wp_password)) {
  1940. $data['WP Admin login'] = $wp_login;
  1941. $data['WP Admin password'] = $wp_password;
  1942. }
  1943. if (!empty($ftp_host) && !empty($ftp_login) && !empty($ftp_password)) {
  1944. $data['SSH / FTP host'] = $ftp_host;
  1945. $data['SSH / FTP login'] = $ftp_login;
  1946. $data['SSH / FTP password'] = $ftp_password;
  1947. }
  1948. /**
  1949. * Store request data for future access
  1950. */
  1951. if (count($data)) {
  1952. $hash = md5(microtime());
  1953. $request_data = get_option('w3tc_request_data', array());
  1954. $request_data[$hash] = $data;
  1955. update_option('w3tc_request_data', $request_data);
  1956. $request_data_url = sprintf('%s/w3tc_request_data/%s', w3_get_home_url(), $hash);
  1957. } else {
  1958. $request_data_url = null;
  1959. }
  1960. /**
  1961. * Get body contents
  1962. */
  1963. ob_start();
  1964. include W3TC_INC_DIR . '/email/support_request.php';
  1965. $body = ob_get_contents();
  1966. ob_end_clean();
  1967. /**
  1968. * Send email
  1969. */
  1970. $subject = sprintf('[W3TC %s] #%s: %s', $this->_request_types[$request_type], $request_id, $subject);
  1971. $headers = array(
  1972. sprintf('From: "%s" <%s>', addslashes($name), $email),
  1973. sprintf('Reply-To: "%s" <%s>', addslashes($name), $email),
  1974. 'Content-Type: text/html; charset=UTF-8'
  1975. );
  1976. $this->_phpmailer_sender = $email;
  1977. add_action('phpmailer_init', array(
  1978. &$this,
  1979. 'phpmailer_init'
  1980. ));
  1981. @set_time_limit($this->_config->get_integer('timelimit.email_send'));
  1982. $result = @wp_mail(W3TC_EMAIL, $subject, $body, implode("\n", $headers), $attachments);
  1983. /**
  1984. * Remove temporary files
  1985. */
  1986. foreach ($attachments as $attachment) {
  1987. if (strstr($attachment, W3TC_TMP_DIR) !== false) {
  1988. @unlink($attachment);
  1989. }
  1990. }
  1991. if ($result) {
  1992. $this->redirect(array(
  1993. 'tab' => 'general',
  1994. 'w3tc_note' => 'support_request'
  1995. ));
  1996. } else {
  1997. $this->redirect(array_merge($params, array(
  1998. 'request_type' => $request_type,
  1999. 'w3tc_error' => 'support_request'
  2000. )));
  2001. }
  2002. }
  2003. /**
  2004. * CDN queue action
  2005. *
  2006. * @return void
  2007. */
  2008. function action_cdn_queue() {
  2009. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2010. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnAdmin');
  2011. $cdn_queue_action = W3_Request::get_string('cdn_queue_action');
  2012. $cdn_queue_tab = W3_Request::get_string('cdn_queue_tab');
  2013. $notes = array();
  2014. switch ($cdn_queue_tab) {
  2015. case 'upload':
  2016. case 'delete':
  2017. case 'purge':
  2018. break;
  2019. default:
  2020. $cdn_queue_tab = 'upload';
  2021. }
  2022. switch ($cdn_queue_action) {
  2023. case 'delete':
  2024. $cdn_queue_id = W3_Request::get_integer('cdn_queue_id');
  2025. if (!empty($cdn_queue_id)) {
  2026. $w3_plugin_cdn->queue_delete($cdn_queue_id);
  2027. $notes[] = 'File successfully deleted from the queue.';
  2028. }
  2029. break;
  2030. case 'empty':
  2031. $cdn_queue_type = W3_Request::get_integer('cdn_queue_type');
  2032. if (!empty($cdn_queue_type)) {
  2033. $w3_plugin_cdn->queue_empty($cdn_queue_type);
  2034. $notes[] = 'Queue successfully emptied.';
  2035. }
  2036. break;
  2037. }
  2038. $nonce = wp_create_nonce('w3tc');
  2039. $queue = $w3_plugin_cdn->queue_get();
  2040. $title = 'Unsuccessful file transfer queue.';
  2041. include W3TC_INC_DIR . '/popup/cdn_queue.php';
  2042. }
  2043. /**
  2044. * CDN export library action
  2045. *
  2046. * @return void
  2047. */
  2048. function action_cdn_export_library() {
  2049. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnAdmin');
  2050. $total = $w3_plugin_cdn->get_attachments_count();
  2051. $title = 'Media Library export';
  2052. include W3TC_INC_DIR . '/popup/cdn_export_library.php';
  2053. }
  2054. /**
  2055. * CDN export library process
  2056. *
  2057. * @return void
  2058. */
  2059. function action_cdn_export_library_process() {
  2060. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2061. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnAdmin');
  2062. $limit = W3_Request::get_integer('limit');
  2063. $offset = W3_Request::get_integer('offset');
  2064. $count = null;
  2065. $total = null;
  2066. $results = array();
  2067. @$w3_plugin_cdn->export_library($limit, $offset, $count, $total, $results);
  2068. $response = array(
  2069. 'limit' => $limit,
  2070. 'offset' => $offset,
  2071. 'count' => $count,
  2072. 'total' => $total,
  2073. 'results' => $results
  2074. );
  2075. echo json_encode($response);
  2076. }
  2077. /**
  2078. * CDN import library action
  2079. *
  2080. * @return void
  2081. */
  2082. function action_cdn_import_library() {
  2083. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnAdmin');
  2084. $w3_plugin_cdncommon = & w3_instance('W3_Plugin_CdnCommon');
  2085. $cdn = & $w3_plugin_cdncommon->get_cdn();
  2086. $total = $w3_plugin_cdn->get_import_posts_count();
  2087. $cdn_host = $cdn->get_domain();
  2088. $title = 'Media Library import';
  2089. include W3TC_INC_DIR . '/popup/cdn_import_library.php';
  2090. }
  2091. /**
  2092. * CDN import library process
  2093. *
  2094. * @return void
  2095. */
  2096. function action_cdn_import_library_process() {
  2097. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2098. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnAdmin');
  2099. $limit = W3_Request::get_integer('limit');
  2100. $offset = W3_Request::get_integer('offset');
  2101. $count = null;
  2102. $total = null;
  2103. $results = array();
  2104. @$w3_plugin_cdn->import_library($limit, $offset, $count, $total, $results);
  2105. $response = array(
  2106. 'limit' => $limit,
  2107. 'offset' => $offset,
  2108. 'count' => $count,
  2109. 'total' => $total,
  2110. 'results' => $results
  2111. );
  2112. echo json_encode($response);
  2113. }
  2114. /**
  2115. * CDN rename domain action
  2116. *
  2117. * @return void
  2118. */
  2119. function action_cdn_rename_domain() {
  2120. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnAdmin');
  2121. $total = $w3_plugin_cdn->get_rename_posts_count();
  2122. $title = 'Modify attachment URLs';
  2123. include W3TC_INC_DIR . '/popup/cdn_rename_domain.php';
  2124. }
  2125. /**
  2126. * CDN rename domain process
  2127. *
  2128. * @return void
  2129. */
  2130. function action_cdn_rename_domain_process() {
  2131. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2132. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnAdmin');
  2133. $limit = W3_Request::get_integer('limit');
  2134. $offset = W3_Request::get_integer('offset');
  2135. $names = W3_Request::get_array('names');
  2136. $count = null;
  2137. $total = null;
  2138. $results = array();
  2139. @$w3_plugin_cdn->rename_domain($names, $limit, $offset, $count, $total, $results);
  2140. $response = array(
  2141. 'limit' => $limit,
  2142. 'offset' => $offset,
  2143. 'count' => $count,
  2144. 'total' => $total,
  2145. 'results' => $results
  2146. );
  2147. echo json_encode($response);
  2148. }
  2149. /**
  2150. * CDN export action
  2151. *
  2152. * @return void
  2153. */
  2154. function action_cdn_export() {
  2155. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2156. $w3_plugin_cdn = & w3_instance('W3_Plugin_Cdn');
  2157. $cdn_export_type = W3_Request::get_string('cdn_export_type', 'custom');
  2158. switch ($cdn_export_type) {
  2159. case 'includes':
  2160. $title = 'Includes files export';
  2161. $files = $w3_plugin_cdn->get_files_includes();
  2162. break;
  2163. case 'theme':
  2164. $title = 'Theme files export';
  2165. $files = $w3_plugin_cdn->get_files_theme();
  2166. break;
  2167. case 'minify':
  2168. $title = 'Minify files export';
  2169. $files = $w3_plugin_cdn->get_files_minify();
  2170. break;
  2171. default:
  2172. case 'custom':
  2173. $title = 'Custom files export';
  2174. $files = $w3_plugin_cdn->get_files_custom();
  2175. break;
  2176. }
  2177. include W3TC_INC_DIR . '/popup/cdn_export_file.php';
  2178. }
  2179. /**
  2180. * CDN export process
  2181. *
  2182. * @return void
  2183. */
  2184. function action_cdn_export_process() {
  2185. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2186. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnCommon');
  2187. $files = W3_Request::get_array('files');
  2188. $document_root = w3_get_document_root();
  2189. $upload = array();
  2190. $results = array();
  2191. foreach ($files as $remote_file) {
  2192. $local_file = $document_root . '/' . w3_translate_file($remote_file);
  2193. $upload[$local_file] = $remote_file;
  2194. }
  2195. $w3_plugin_cdn->upload($upload, false, $results);
  2196. $response = array(
  2197. 'results' => $results
  2198. );
  2199. echo json_encode($response);
  2200. }
  2201. /**
  2202. * CDN purge action
  2203. *
  2204. * @return void
  2205. */
  2206. function action_cdn_purge() {
  2207. $title = 'Content Delivery Network (CDN): Purge Tool';
  2208. $results = array();
  2209. include W3TC_INC_DIR . '/popup/cdn_purge.php';
  2210. }
  2211. /**
  2212. * CDN purge post action
  2213. *
  2214. * @return void
  2215. */
  2216. function action_cdn_purge_post() {
  2217. $title = 'Content Delivery Network (CDN): Purge Tool';
  2218. $results = array();
  2219. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2220. $files = W3_Request::get_array('files');
  2221. $document_root = w3_get_document_root();
  2222. $purge = array();
  2223. foreach ($files as $remote_file) {
  2224. $local_file = $document_root . '/' . w3_translate_file($remote_file);
  2225. $purge[$local_file] = $remote_file;
  2226. }
  2227. if (count($purge)) {
  2228. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnCommon');
  2229. $w3_plugin_cdn->purge($purge, false, $results);
  2230. } else {
  2231. $errors[] = 'Empty files list.';
  2232. }
  2233. include W3TC_INC_DIR . '/popup/cdn_purge.php';
  2234. }
  2235. /**
  2236. * CDN Purge Post
  2237. *
  2238. * @return void
  2239. */
  2240. function action_cdn_purge_attachment() {
  2241. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2242. $results = array();
  2243. $attachment_id = W3_Request::get_integer('attachment_id');
  2244. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnAdmin');
  2245. if ($w3_plugin_cdn->purge_attachment($attachment_id, $results)) {
  2246. $this->redirect(array(
  2247. 'w3tc_note' => 'cdn_purge_attachment'
  2248. ), true);
  2249. } else {
  2250. $this->redirect(array(
  2251. 'w3tc_error' => 'cdn_purge_attachment'
  2252. ), true);
  2253. }
  2254. }
  2255. /**
  2256. * CDN Test action
  2257. *
  2258. * @return void
  2259. */
  2260. function action_cdn_test() {
  2261. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2262. require_once W3TC_LIB_W3_DIR . '/Cdn.php';
  2263. $engine = W3_Request::get_string('engine');
  2264. $config = W3_Request::get_array('config');
  2265. $config = array_merge($config, array(
  2266. 'debug' => false
  2267. ));
  2268. if (w3_is_cdn_engine($engine)) {
  2269. $result = true;
  2270. } else {
  2271. $result = false;
  2272. $error = 'Incorrect engine.';
  2273. }
  2274. if ($result) {
  2275. @$w3_cdn = & W3_Cdn::instance($engine, $config);
  2276. $error = null;
  2277. @set_time_limit($this->_config->get_integer('timelimit.cdn_test'));
  2278. if ($w3_cdn->test($error)) {
  2279. $result = true;
  2280. $error = 'Test passed';
  2281. } else {
  2282. $result = false;
  2283. $error = sprintf('Error: %s', $error);
  2284. }
  2285. }
  2286. $response = array(
  2287. 'result' => $result,
  2288. 'error' => $error
  2289. );
  2290. echo json_encode($response);
  2291. }
  2292. /**
  2293. * Create container action
  2294. *
  2295. * @return void
  2296. */
  2297. function action_cdn_create_container() {
  2298. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2299. require_once W3TC_LIB_W3_DIR . '/Cdn.php';
  2300. $engine = W3_Request::get_string('engine');
  2301. $config = W3_Request::get_array('config');
  2302. $config = array_merge($config, array(
  2303. 'debug' => false
  2304. ));
  2305. $result = false;
  2306. $error = 'Incorrect type.';
  2307. $container_id = '';
  2308. switch ($engine) {
  2309. case 's3':
  2310. case 'cf':
  2311. case 'cf2':
  2312. case 'rscf':
  2313. case 'azure':
  2314. $result = true;
  2315. break;
  2316. }
  2317. if ($result) {
  2318. @$w3_cdn = & W3_Cdn::instance($engine, $config);
  2319. @set_time_limit($this->_config->get_integer('timelimit.cdn_container_create'));
  2320. if ($w3_cdn->create_container($container_id, $error)) {
  2321. $result = true;
  2322. $error = 'Created successfully.';
  2323. } else {
  2324. $result = false;
  2325. $error = sprintf('Error: %s', $error);
  2326. }
  2327. }
  2328. $response = array(
  2329. 'result' => $result,
  2330. 'error' => $error,
  2331. 'container_id' => $container_id
  2332. );
  2333. echo json_encode($response);
  2334. }
  2335. /**
  2336. * S3 bucket location lightbox
  2337. *
  2338. * @return void
  2339. */
  2340. function action_cdn_s3_bucket_location() {
  2341. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2342. $type = W3_Request::get_string('type', 's3');
  2343. $locations = array(
  2344. '' => 'US (Default)',
  2345. 'us-west-1' => 'US-West (Northern California)',
  2346. 'EU' => 'Europe',
  2347. 'ap-southeast-1' => 'AP-SouthEast (Singapore)',
  2348. );
  2349. include W3TC_INC_DIR . '/lightbox/cdn_s3_bucket_location.php';
  2350. }
  2351. /**
  2352. * Test memcached
  2353. *
  2354. * @return void
  2355. */
  2356. function action_test_memcached() {
  2357. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2358. $servers = W3_Request::get_array('servers');
  2359. if ($this->is_memcache_available($servers)) {
  2360. $result = true;
  2361. $error = 'Test passed.';
  2362. } else {
  2363. $result = false;
  2364. $error = 'Test failed.';
  2365. }
  2366. $response = array(
  2367. 'result' => $result,
  2368. 'error' => $error
  2369. );
  2370. echo json_encode($response);
  2371. }
  2372. /**
  2373. * Test minifier action
  2374. *
  2375. * @return void
  2376. */
  2377. function action_test_minifier() {
  2378. if (W3TC_PHP5) {
  2379. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2380. $engine = W3_Request::get_string('engine');
  2381. $path_java = W3_Request::get_string('path_java');
  2382. $path_jar = W3_Request::get_string('path_jar');
  2383. $result = false;
  2384. $error = '';
  2385. if (!$path_java) {
  2386. $error = 'Empty JAVA executable path.';
  2387. } elseif (!$path_jar) {
  2388. $error = 'Empty JAR file path.';
  2389. } else {
  2390. switch ($engine) {
  2391. case 'yuijs':
  2392. require_once W3TC_LIB_MINIFY_DIR . '/Minify/YUICompressor.php';
  2393. Minify_YUICompressor::setPathJava($path_java);
  2394. Minify_YUICompressor::setPathJar($path_jar);
  2395. $result = Minify_YUICompressor::testJs($error);
  2396. break;
  2397. case 'yuicss':
  2398. require_once W3TC_LIB_MINIFY_DIR . '/Minify/YUICompressor.php';
  2399. Minify_YUICompressor::setPathJava($path_java);
  2400. Minify_YUICompressor::setPathJar($path_jar);
  2401. $result = Minify_YUICompressor::testCss($error);
  2402. break;
  2403. case 'ccjs':
  2404. require_once W3TC_LIB_MINIFY_DIR . '/Minify/ClosureCompiler.php';
  2405. Minify_ClosureCompiler::setPathJava($path_java);
  2406. Minify_ClosureCompiler::setPathJar($path_jar);
  2407. $result = Minify_ClosureCompiler::test($error);
  2408. break;
  2409. default:
  2410. $error = 'Invalid engine.';
  2411. break;
  2412. }
  2413. }
  2414. $response = array(
  2415. 'result' => $result,
  2416. 'error' => $error
  2417. );
  2418. echo json_encode($response);
  2419. }
  2420. }
  2421. /**
  2422. * Hide note action
  2423. *
  2424. * @return void
  2425. */
  2426. function action_hide_note() {
  2427. $setting = sprintf('notes.%s', W3_Request::get_string('note'));
  2428. $this->_config->set($setting, false);
  2429. if (!$this->_config->save()) {
  2430. $this->redirect(array(
  2431. 'w3tc_error' => 'config_save'
  2432. ), true);
  2433. }
  2434. $this->redirect(array(), true);
  2435. }
  2436. /**
  2437. * Update upload path action
  2438. *
  2439. * @return void
  2440. */
  2441. function action_update_upload_path() {
  2442. update_option('upload_path', '');
  2443. $this->redirect();
  2444. }
  2445. /**
  2446. * Options save action
  2447. *
  2448. * @return void
  2449. */
  2450. function action_save_options() {
  2451. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2452. /**
  2453. * Redirect params
  2454. */
  2455. $params = array();
  2456. /**
  2457. * Read config
  2458. * We should use new instance of WP_Config object here
  2459. */
  2460. @$config = & new W3_Config();
  2461. $config->read_request();
  2462. /**
  2463. * General tab
  2464. */
  2465. if ($this->_page == 'w3tc_general') {
  2466. $file_nfs = W3_Request::get_boolean('file_nfs');
  2467. $file_locking = W3_Request::get_boolean('file_locking');
  2468. $config->set('pgcache.file.nfs', $file_nfs);
  2469. $config->set('minify.file.nfs', $file_nfs);
  2470. $config->set('dbcache.file.locking', $file_locking);
  2471. $config->set('objectcache.file.locking', $file_locking);
  2472. $config->set('pgcache.file.locking', $file_locking);
  2473. $config->set('minify.file.locking', $file_locking);
  2474. /**
  2475. * Check permalinks for page cache
  2476. */
  2477. if ($config->get_boolean('pgcache.enabled') && $config->get_string('pgcache.engine') == 'file_generic' && !get_option('permalink_structure')) {
  2478. $this->redirect(array(
  2479. 'w3tc_error' => 'fancy_permalinks_disabled_pgcache'
  2480. ));
  2481. }
  2482. }
  2483. /**
  2484. * Minify tab
  2485. */
  2486. if ($this->_page == 'w3tc_minify' && !$this->_config->get_boolean('minify.auto')) {
  2487. $js_groups = array();
  2488. $css_groups = array();
  2489. $js_files = W3_Request::get_array('js_files');
  2490. $css_files = W3_Request::get_array('css_files');
  2491. foreach ($js_files as $theme => $templates) {
  2492. foreach ($templates as $template => $locations) {
  2493. foreach ((array) $locations as $location => $files) {
  2494. switch ($location) {
  2495. case 'include':
  2496. $js_groups[$theme][$template][$location]['blocking'] = true;
  2497. break;
  2498. case 'include-nb':
  2499. $js_groups[$theme][$template][$location]['blocking'] = false;
  2500. break;
  2501. case 'include-body':
  2502. $js_groups[$theme][$template][$location]['blocking'] = true;
  2503. break;
  2504. case 'include-body-nb':
  2505. $js_groups[$theme][$template][$location]['blocking'] = false;
  2506. break;
  2507. case 'include-footer':
  2508. $js_groups[$theme][$template][$location]['blocking'] = true;
  2509. break;
  2510. case 'include-footer-nb':
  2511. $js_groups[$theme][$template][$location]['blocking'] = false;
  2512. break;
  2513. }
  2514. foreach ((array) $files as $file) {
  2515. if (!empty($file)) {
  2516. $js_groups[$theme][$template][$location]['files'][] = w3_normalize_file_minify($file);
  2517. }
  2518. }
  2519. }
  2520. }
  2521. }
  2522. foreach ($css_files as $theme => $templates) {
  2523. foreach ($templates as $template => $locations) {
  2524. foreach ((array) $locations as $location => $files) {
  2525. foreach ((array) $files as $file) {
  2526. if (!empty($file)) {
  2527. $css_groups[$theme][$template][$location]['files'][] = w3_normalize_file_minify($file);
  2528. }
  2529. }
  2530. }
  2531. }
  2532. }
  2533. $config->set('minify.js.groups', $js_groups);
  2534. $config->set('minify.css.groups', $css_groups);
  2535. $js_theme = W3_Request::get_string('js_theme');
  2536. $css_theme = W3_Request::get_string('css_theme');
  2537. $params = array_merge($params, array(
  2538. 'js_theme' => $js_theme,
  2539. 'css_theme' => $css_theme
  2540. ));
  2541. }
  2542. /**
  2543. * Browser Cache tab
  2544. */
  2545. if ($this->_page == 'w3tc_browsercache') {
  2546. if ($config->get_boolean('browsercache.enabled') && $config->get_boolean('browsercache.no404wp') && !get_option('permalink_structure')) {
  2547. $this->redirect(array(
  2548. 'w3tc_error' => 'fancy_permalinks_disabled_browsercache'
  2549. ));
  2550. }
  2551. }
  2552. /**
  2553. * Mobile tab
  2554. */
  2555. if ($this->_page == 'w3tc_mobile') {
  2556. $groups = W3_Request::get_array('mobile_groups');
  2557. $mobile_groups = array();
  2558. $cached_mobile_groups = array();
  2559. foreach ($groups as $group => $group_config) {
  2560. $group = strtolower($group);
  2561. $group = preg_replace('~[^0-9a-z_]+~', '_', $group);
  2562. $group = trim($group, '_');
  2563. if ($group) {
  2564. $theme = (isset($group_config['theme']) ? trim($group_config['theme']) : 'default');
  2565. $enabled = (isset($group_config['enabled']) ? (boolean) $group_config['enabled'] : true);
  2566. $redirect = (isset($group_config['redirect']) ? trim($group_config['redirect']) : '');
  2567. $agents = (isset($group_config['agents']) ? explode("\r\n", trim($group_config['agents'])) : array());
  2568. $mobile_groups[$group] = array(
  2569. 'theme' => $theme,
  2570. 'enabled' => $enabled,
  2571. 'redirect' => $redirect,
  2572. 'agents' => $agents
  2573. );
  2574. $cached_mobile_groups[$group] = $agents;
  2575. }
  2576. }
  2577. /**
  2578. * Allow plugins modify WPSC mobile groups
  2579. */
  2580. $cached_mobile_groups = apply_filters('cached_mobile_groups', $cached_mobile_groups);
  2581. /**
  2582. * Merge existent and delete removed groups
  2583. */
  2584. foreach ($mobile_groups as $group => $group_config) {
  2585. if (isset($cached_mobile_groups[$group])) {
  2586. $mobile_groups[$group]['agents'] = (array) $cached_mobile_groups[$group];
  2587. } else {
  2588. unset($mobile_groups[$group]);
  2589. }
  2590. }
  2591. /**
  2592. * Add new groups
  2593. */
  2594. foreach ($cached_mobile_groups as $group => $agents) {
  2595. if (!isset($mobile_groups[$group])) {
  2596. $mobile_groups[$group] = array(
  2597. 'theme' => '',
  2598. 'enabled' => true,
  2599. 'redirect' => '',
  2600. 'agents' => $agents
  2601. );
  2602. }
  2603. }
  2604. /**
  2605. * Allow plugins modify W3TC mobile groups
  2606. */
  2607. $mobile_groups = apply_filters('w3tc_mobile_groups', $mobile_groups);
  2608. /**
  2609. * Sanitize mobile groups
  2610. */
  2611. foreach ($mobile_groups as $group => $group_config) {
  2612. $mobile_groups[$group] = array_merge(array(
  2613. 'theme' => '',
  2614. 'enabled' => true,
  2615. 'redirect' => '',
  2616. 'agents' => array()
  2617. ), $group_config);
  2618. $mobile_groups[$group]['agents'] = array_unique($mobile_groups[$group]['agents']);
  2619. $mobile_groups[$group]['agents'] = array_map('strtolower', $mobile_groups[$group]['agents']);
  2620. sort($mobile_groups[$group]['agents']);
  2621. }
  2622. $config->set('mobile.rgroups', $mobile_groups);
  2623. }
  2624. /**
  2625. * Referrer tab
  2626. */
  2627. if ($this->_page == 'w3tc_referrer') {
  2628. $groups = W3_Request::get_array('referrer_groups');
  2629. $referrer_groups = array();
  2630. foreach ($groups as $group => $group_config) {
  2631. $group = strtolower($group);
  2632. $group = preg_replace('~[^0-9a-z_]+~', '_', $group);
  2633. $group = trim($group, '_');
  2634. if ($group) {
  2635. $theme = (isset($group_config['theme']) ? trim($group_config['theme']) : 'default');
  2636. $enabled = (isset($group_config['enabled']) ? (boolean) $group_config['enabled'] : true);
  2637. $redirect = (isset($group_config['redirect']) ? trim($group_config['redirect']) : '');
  2638. $referrers = (isset($group_config['referrers']) ? explode("\r\n", trim($group_config['referrers'])) : array());
  2639. $referrer_groups[$group] = array(
  2640. 'theme' => $theme,
  2641. 'enabled' => $enabled,
  2642. 'redirect' => $redirect,
  2643. 'referrers' => $referrers
  2644. );
  2645. }
  2646. }
  2647. /**
  2648. * Allow plugins modify W3TC referrer groups
  2649. */
  2650. $referrer_groups = apply_filters('w3tc_referrer_groups', $referrer_groups);
  2651. /**
  2652. * Sanitize mobile groups
  2653. */
  2654. foreach ($referrer_groups as $group => $group_config) {
  2655. $referrer_groups[$group] = array_merge(array(
  2656. 'theme' => '',
  2657. 'enabled' => true,
  2658. 'redirect' => '',
  2659. 'referrers' => array()
  2660. ), $group_config);
  2661. $referrer_groups[$group]['referrers'] = array_unique($referrer_groups[$group]['referrers']);
  2662. $referrer_groups[$group]['referrers'] = array_map('strtolower', $referrer_groups[$group]['referrers']);
  2663. sort($referrer_groups[$group]['referrers']);
  2664. }
  2665. $config->set('referrer.rgroups', $referrer_groups);
  2666. }
  2667. /**
  2668. * CDN tab
  2669. */
  2670. if ($this->_page == 'w3tc_cdn') {
  2671. $cdn_cnames = W3_Request::get_array('cdn_cnames');
  2672. $cdn_domains = array();
  2673. foreach ($cdn_cnames as $cdn_cname) {
  2674. $cdn_cname = trim($cdn_cname);
  2675. /**
  2676. * Auto expand wildcard domain to 10 subdomains
  2677. */
  2678. $matches = null;
  2679. if (preg_match('~^\*\.(.*)$~', $cdn_cname, $matches)) {
  2680. $cdn_domains = array();
  2681. for ($i = 1; $i <= 10; $i++) {
  2682. $cdn_domains[] = sprintf('cdn%d.%s', $i, $matches[1]);
  2683. }
  2684. break;
  2685. }
  2686. if ($cdn_cname) {
  2687. $cdn_domains[] = $cdn_cname;
  2688. }
  2689. }
  2690. switch ($this->_config->get_string('cdn.engine')) {
  2691. case 'ftp':
  2692. $config->set('cdn.ftp.domain', $cdn_domains);
  2693. break;
  2694. case 's3':
  2695. $config->set('cdn.s3.cname', $cdn_domains);
  2696. break;
  2697. case 'cf':
  2698. $config->set('cdn.cf.cname', $cdn_domains);
  2699. break;
  2700. case 'cf2':
  2701. $config->set('cdn.cf2.cname', $cdn_domains);
  2702. break;
  2703. case 'rscf':
  2704. $config->set('cdn.rscf.cname', $cdn_domains);
  2705. break;
  2706. case 'azure':
  2707. $config->set('cdn.azure.cname', $cdn_domains);
  2708. break;
  2709. case 'mirror':
  2710. $config->set('cdn.mirror.domain', $cdn_domains);
  2711. break;
  2712. case 'netdna':
  2713. $config->set('cdn.netdna.domain', $cdn_domains);
  2714. break;
  2715. case 'cotendo':
  2716. $config->set('cdn.cotendo.domain', $cdn_domains);
  2717. break;
  2718. case 'edgecast':
  2719. $config->set('cdn.edgecast.domain', $cdn_domains);
  2720. break;
  2721. }
  2722. }
  2723. if ($this->config_save($this->_config, $config)) {
  2724. switch ($this->_page) {
  2725. case 'w3tc_cdn':
  2726. /**
  2727. * Handle Set Cookie Domain
  2728. */
  2729. $set_cookie_domain_old = W3_Request::get_boolean('set_cookie_domain_old');
  2730. $set_cookie_domain_new = W3_Request::get_boolean('set_cookie_domain_new');
  2731. if ($set_cookie_domain_old != $set_cookie_domain_new) {
  2732. if ($set_cookie_domain_new) {
  2733. if (!$this->enable_cookie_domain()) {
  2734. $this->redirect(array_merge($params, array(
  2735. 'w3tc_error' => 'enable_cookie_domain'
  2736. )));
  2737. }
  2738. } else {
  2739. if (!$this->disable_cookie_domain()) {
  2740. $this->redirect(array_merge($params, array(
  2741. 'w3tc_error' => 'disable_cookie_domain'
  2742. )));
  2743. }
  2744. }
  2745. }
  2746. break;
  2747. case 'w3tc_general':
  2748. /**
  2749. * Handle CloudFlare changes
  2750. */
  2751. if ($this->_config->get_boolean('cloudflare.enabled')) {
  2752. $cloudflare_seclvl_old = W3_Request::get_string('cloudflare_seclvl_old');
  2753. $cloudflare_seclvl_new = W3_Request::get_string('cloudflare_seclvl_new');
  2754. $cloudflare_devmode_old = W3_Request::get_integer('cloudflare_devmode_old');
  2755. $cloudflare_devmode_new = W3_Request::get_integer('cloudflare_devmode_new');
  2756. if (($cloudflare_seclvl_old != $cloudflare_seclvl_new) || ($cloudflare_devmode_old != $cloudflare_devmode_new)) {
  2757. require_once W3TC_LIB_W3_DIR . '/CloudFlare.php';
  2758. @$w3_cloudflare =& new W3_CloudFlare(array(
  2759. 'email' => $this->_config->get_string('cloudflare.email'),
  2760. 'key' => $this->_config->get_string('cloudflare.key'),
  2761. 'zone' => $this->_config->get_string('cloudflare.zone')
  2762. ));
  2763. @set_time_limit($this->_config->get_integer('timelimit.cloudflare_api_request'));
  2764. $cloudflare_response = false;
  2765. if ($cloudflare_seclvl_old != $cloudflare_seclvl_new) {
  2766. $cloudflare_response = $w3_cloudflare->api_request('sec_lvl', $cloudflare_seclvl_new);
  2767. if (!$cloudflare_response || $cloudflare_response->result != 'success') {
  2768. $this->redirect(array_merge($params, array(
  2769. 'w3tc_error' => 'cloudflare_api_request'
  2770. )));
  2771. }
  2772. }
  2773. if ($cloudflare_devmode_old != $cloudflare_devmode_new) {
  2774. $cloudflare_response = $w3_cloudflare->api_request('devmode', $cloudflare_devmode_new);
  2775. if (!$cloudflare_response || $cloudflare_response->result != 'success') {
  2776. $this->redirect(array_merge($params, array(
  2777. 'w3tc_error' => 'cloudflare_api_request'
  2778. )));
  2779. }
  2780. }
  2781. }
  2782. }
  2783. break;
  2784. }
  2785. $this->redirect(array_merge($params, array(
  2786. 'w3tc_note' => 'config_save'
  2787. )));
  2788. } else {
  2789. $this->redirect(array_merge($params, array(
  2790. 'w3tc_error' => 'config_save'
  2791. )));
  2792. }
  2793. }
  2794. /**
  2795. * Save config action
  2796. *
  2797. * @return void
  2798. */
  2799. function action_save_config() {
  2800. if ($this->_config->save()) {
  2801. $this->redirect(array(
  2802. 'w3tc_note' => 'config_save'
  2803. ), true);
  2804. } else {
  2805. $this->redirect(array(
  2806. 'w3tc_error' => 'config_save'
  2807. ), true);
  2808. }
  2809. }
  2810. /**
  2811. * Save support us action
  2812. *
  2813. * @return void
  2814. */
  2815. function action_save_support_us() {
  2816. $support = W3_Request::get_string('support');
  2817. $tweeted = W3_Request::get_boolean('tweeted');
  2818. $this->_config->set('common.support', $support);
  2819. $this->_config->set('common.tweeted', $tweeted);
  2820. if (!$this->_config->save()) {
  2821. $this->redirect(array(
  2822. 'w3tc_error' => 'config_save'
  2823. ));
  2824. }
  2825. $this->link_update();
  2826. $this->redirect(array(
  2827. 'w3tc_note' => 'config_save'
  2828. ));
  2829. }
  2830. /**
  2831. * PgCache purge post
  2832. *
  2833. * @return void
  2834. */
  2835. function action_pgcache_purge_post() {
  2836. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2837. $post_id = W3_Request::get_integer('post_id');
  2838. $w3_pgcache = & w3_instance('W3_PgCacheFlush');
  2839. if ($w3_pgcache->flush_post($post_id)) {
  2840. $this->redirect(array(
  2841. 'w3tc_note' => 'pgcache_purge_post'
  2842. ), true);
  2843. } else {
  2844. $this->redirect(array(
  2845. 'w3tc_error' => 'pgcache_purge_post'
  2846. ), true);
  2847. }
  2848. }
  2849. /**
  2850. * PgCache purge page
  2851. *
  2852. * @return void
  2853. */
  2854. function action_pgcache_purge_page() {
  2855. require_once W3TC_LIB_W3_DIR . '/Request.php';
  2856. $post_id = W3_Request::get_integer('post_id');
  2857. $w3_pgcache = & w3_instance('W3_PgCacheFlush');
  2858. if ($w3_pgcache->flush_post($post_id)) {
  2859. $this->redirect(array(
  2860. 'w3tc_note' => 'pgcache_purge_page'
  2861. ), true);
  2862. } else {
  2863. $this->redirect(array(
  2864. 'w3tc_error' => 'pgcache_purge_page'
  2865. ), true);
  2866. }
  2867. }
  2868. /**
  2869. * Write page cache core rules action
  2870. *
  2871. * @return void
  2872. */
  2873. function action_pgcache_write_rules_core() {
  2874. $w3_plugin_pgcache = & w3_instance('W3_Plugin_PgCacheAdmin');
  2875. if ($w3_plugin_pgcache->write_rules_core()) {
  2876. $this->redirect(array(
  2877. 'w3tc_note' => 'pgcache_write_rules_core'
  2878. ));
  2879. } else {
  2880. $this->redirect(array(
  2881. 'w3tc_error' => 'pgcache_write_rules_core'
  2882. ));
  2883. }
  2884. }
  2885. /**
  2886. * Write page cache cache rules action
  2887. *
  2888. * @return void
  2889. */
  2890. function action_pgcache_write_rules_cache() {
  2891. $w3_plugin_pgcache = & w3_instance('W3_Plugin_PgCacheAdmin');
  2892. if ($w3_plugin_pgcache->write_rules_cache()) {
  2893. $this->redirect(array(
  2894. 'w3tc_note' => 'pgcache_write_rules_cache'
  2895. ));
  2896. } else {
  2897. $this->redirect(array(
  2898. 'w3tc_error' => 'pgcache_write_rules_cache'
  2899. ));
  2900. }
  2901. }
  2902. /**
  2903. * Remove page cache legacy rules action
  2904. *
  2905. * @return void
  2906. */
  2907. function action_pgcache_remove_rules_legacy() {
  2908. $w3_plugin_pgcache = & w3_instance('W3_Plugin_PgCacheAdmin');
  2909. if ($w3_plugin_pgcache->remove_rules_legacy()) {
  2910. $this->redirect(array(
  2911. 'w3tc_note' => 'pgcache_remove_rules_legacy'
  2912. ));
  2913. } else {
  2914. $this->redirect(array(
  2915. 'w3tc_error' => 'pgcache_remove_rules_legacy'
  2916. ));
  2917. }
  2918. }
  2919. /**
  2920. * Remove page cache WPSC rules action
  2921. *
  2922. * @return void
  2923. */
  2924. function action_pgcache_remove_rules_wpsc() {
  2925. $w3_plugin_pgcache = & w3_instance('W3_Plugin_PgCacheAdmin');
  2926. if ($w3_plugin_pgcache->remove_rules_wpsc()) {
  2927. $this->redirect(array(
  2928. 'w3tc_note' => 'pgcache_remove_rules_wpsc'
  2929. ));
  2930. } else {
  2931. $this->redirect(array(
  2932. 'w3tc_error' => 'pgcache_remove_rules_wpsc'
  2933. ));
  2934. }
  2935. }
  2936. /**
  2937. * Write browser cache cache action
  2938. *
  2939. * @return void
  2940. */
  2941. function action_browsercache_write_rules_cache() {
  2942. $w3_plugin_browsercache = & w3_instance('W3_Plugin_BrowserCacheAdmin');
  2943. if ($w3_plugin_browsercache->write_rules_cache()) {
  2944. $this->redirect(array(
  2945. 'w3tc_note' => 'browsercache_write_rules_cache'
  2946. ));
  2947. } else {
  2948. $this->redirect(array(
  2949. 'w3tc_error' => 'browsercache_write_rules_cache'
  2950. ));
  2951. }
  2952. }
  2953. /**
  2954. * Write browser cache no404wp rules action
  2955. *
  2956. * @return void
  2957. */
  2958. function action_browsercache_write_rules_no404wp() {
  2959. $w3_plugin_browsercache = & w3_instance('W3_Plugin_BrowserCacheAdmin');
  2960. if ($w3_plugin_browsercache->write_rules_no404wp()) {
  2961. $this->redirect(array(
  2962. 'w3tc_note' => 'browsercache_write_rules_no404wp'
  2963. ));
  2964. } else {
  2965. $this->redirect(array(
  2966. 'w3tc_error' => 'browsercache_write_rules_no404wp'
  2967. ));
  2968. }
  2969. }
  2970. /**
  2971. * Write minify core rules action
  2972. *
  2973. * @return void
  2974. */
  2975. function action_minify_write_rules_core() {
  2976. $w3_plugin_minify = & w3_instance('W3_Plugin_MinifyAdmin');
  2977. if ($w3_plugin_minify->write_rules_core()) {
  2978. $this->redirect(array(
  2979. 'w3tc_note' => 'minify_write_rules_core'
  2980. ));
  2981. } else {
  2982. $this->redirect(array(
  2983. 'w3tc_error' => 'minify_write_rules_core'
  2984. ));
  2985. }
  2986. }
  2987. /**
  2988. * Write minify cache rules action
  2989. *
  2990. * @return void
  2991. */
  2992. function action_minify_write_rules_cache() {
  2993. $w3_plugin_minify = & w3_instance('W3_Plugin_MinifyAdmin');
  2994. if ($w3_plugin_minify->write_rules_cache()) {
  2995. $this->redirect(array(
  2996. 'w3tc_note' => 'minify_write_rules_cache'
  2997. ));
  2998. } else {
  2999. $this->redirect(array(
  3000. 'w3tc_error' => 'minify_write_rules_cache'
  3001. ));
  3002. }
  3003. }
  3004. /**
  3005. * Remove minify legacy rules action
  3006. *
  3007. * @return void
  3008. */
  3009. function action_minify_remove_rules_legacy() {
  3010. $w3_plugin_minify = & w3_instance('W3_Plugin_MinifyAdmin');
  3011. if ($w3_plugin_minify->remove_rules_legacy()) {
  3012. $this->redirect(array(
  3013. 'w3tc_note' => 'minify_remove_rules_legacy'
  3014. ));
  3015. } else {
  3016. $this->redirect(array(
  3017. 'w3tc_error' => 'minify_remove_rules_legacy'
  3018. ));
  3019. }
  3020. }
  3021. /**
  3022. * Minify recommendations action
  3023. *
  3024. * @return void
  3025. */
  3026. function action_minify_recommendations() {
  3027. $themes = $this->get_themes();
  3028. $current_theme = get_current_theme();
  3029. $current_theme_key = array_search($current_theme, $themes);
  3030. require_once W3TC_LIB_W3_DIR . '/Request.php';
  3031. $theme_key = W3_Request::get_string('theme_key', $current_theme_key);
  3032. $theme_name = (isset($themes[$theme_key]) ? $themes[$theme_key] : $current_theme);
  3033. $templates = $this->get_theme_templates($theme_name);
  3034. $recommendations = $this->get_theme_recommendations($theme_name);
  3035. list ($js_groups, $css_groups) = $recommendations;
  3036. $minify_js_groups = $this->_config->get_array('minify.js.groups');
  3037. $minify_css_groups = $this->_config->get_array('minify.css.groups');
  3038. $checked_js = array();
  3039. $checked_css = array();
  3040. $locations_js = array();
  3041. if (isset($minify_js_groups[$theme_key])) {
  3042. foreach ((array) $minify_js_groups[$theme_key] as $template => $locations) {
  3043. foreach ((array) $locations as $location => $config) {
  3044. if (isset($config['files'])) {
  3045. foreach ((array) $config['files'] as $file) {
  3046. if (!isset($js_groups[$template]) || !in_array($file, $js_groups[$template])) {
  3047. $js_groups[$template][] = $file;
  3048. }
  3049. $checked_js[$template][$file] = true;
  3050. $locations_js[$template][$file] = $location;
  3051. }
  3052. }
  3053. }
  3054. }
  3055. }
  3056. if (isset($minify_css_groups[$theme_key])) {
  3057. foreach ((array) $minify_css_groups[$theme_key] as $template => $locations) {
  3058. foreach ((array) $locations as $location => $config) {
  3059. if (isset($config['files'])) {
  3060. foreach ((array) $config['files'] as $file) {
  3061. if (!isset($css_groups[$template]) || !in_array($file, $css_groups[$template])) {
  3062. $css_groups[$template][] = $file;
  3063. }
  3064. $checked_css[$template][$file] = true;
  3065. }
  3066. }
  3067. }
  3068. }
  3069. }
  3070. include W3TC_INC_DIR . '/lightbox/minify_recommendations.php';
  3071. }
  3072. /**
  3073. * Send CloudFlare API request
  3074. *
  3075. * @return void
  3076. */
  3077. function action_cloudflare_api_request() {
  3078. $result = false;
  3079. $response = null;
  3080. $actions = array(
  3081. 'devmode',
  3082. 'sec_lvl',
  3083. 'fpurge_ts'
  3084. );
  3085. require_once W3TC_LIB_W3_DIR . '/Request.php';
  3086. $email = W3_Request::get_string('email');
  3087. $key = W3_Request::get_string('key');
  3088. $zone = W3_Request::get_string('zone');
  3089. $action = W3_Request::get_string('action');
  3090. $value = W3_Request::get_string('value');
  3091. if (!$email) {
  3092. $error = 'Empty email.';
  3093. } elseif (!$key) {
  3094. $error = 'Empty key.';
  3095. } elseif (!$zone) {
  3096. $error = 'Empty zone.';
  3097. } elseif (!in_array($action, $actions)) {
  3098. $error = 'Invalid action.';
  3099. } else {
  3100. $config = array(
  3101. 'email' => $email,
  3102. 'key' => $key,
  3103. 'zone' => $zone
  3104. );
  3105. require_once W3TC_LIB_W3_DIR . '/CloudFlare.php';
  3106. @$w3_cloudflare =& new W3_CloudFlare($config);
  3107. @set_time_limit($this->_config->get_integer('timelimit.cloudflare_api_request'));
  3108. $response = $w3_cloudflare->api_request($action, $value);
  3109. if ($response) {
  3110. if ($response->result == 'success') {
  3111. $result = true;
  3112. $error = 'OK';
  3113. } else {
  3114. $error = $response->msg;
  3115. }
  3116. } else {
  3117. $error = 'Unable to make CloudFlare API request.';
  3118. }
  3119. }
  3120. $return = array(
  3121. 'result' => $result,
  3122. 'error' => $error,
  3123. 'response' => $response
  3124. );
  3125. echo json_encode($return);
  3126. }
  3127. /**
  3128. * Self test action
  3129. */
  3130. function action_self_test() {
  3131. include W3TC_INC_DIR . '/lightbox/self_test.php';
  3132. }
  3133. /**
  3134. * Support Us action
  3135. *
  3136. * @return void
  3137. */
  3138. function action_support_us() {
  3139. $supports = $this->get_supports();
  3140. include W3TC_INC_DIR . '/lightbox/support_us.php';
  3141. }
  3142. /**
  3143. * Page Speed results action
  3144. *
  3145. * @return void
  3146. */
  3147. function action_pagespeed_results() {
  3148. require_once W3TC_LIB_W3_DIR . '/Request.php';
  3149. require_once W3TC_LIB_W3_DIR . '/PageSpeed.php';
  3150. $force = W3_Request::get_boolean('force');
  3151. $title = 'Google Page Speed';
  3152. $w3_pagespeed = new W3_PageSpeed();
  3153. $results = $w3_pagespeed->analyze(w3_get_home_url(), $force);
  3154. if ($force) {
  3155. $this->redirect(array(
  3156. 'w3tc_pagespeed_results' => 1,
  3157. '_wpnonce' => wp_create_nonce('w3tc')
  3158. ));
  3159. }
  3160. include W3TC_INC_DIR . '/popup/pagespeed_results.php';
  3161. }
  3162. /**
  3163. * Save config action
  3164. *
  3165. * Do some actions on config keys update
  3166. * Used in several places such as:
  3167. *
  3168. * 1. common config save
  3169. * 2. import settings
  3170. * 3. enable/disable preview mode
  3171. *
  3172. * @param W3_Config $old_config
  3173. * @param W3_Config $new_config
  3174. * @param boolean $preview
  3175. * @return void
  3176. */
  3177. function config_save(&$old_config, &$new_config, $preview = null) {
  3178. $browsercache_dependencies = array();
  3179. if ($new_config->get_boolean('browsercache.enabled')) {
  3180. $browsercache_dependencies = array_merge($browsercache_dependencies, array(
  3181. 'browsercache.cssjs.replace',
  3182. 'browsercache.html.replace',
  3183. 'browsercache.other.replace'
  3184. ));
  3185. if ($new_config->get_boolean('browsercache.cssjs.replace')) {
  3186. $browsercache_dependencies = array_merge($browsercache_dependencies, array(
  3187. 'browsercache.cssjs.compression',
  3188. 'browsercache.cssjs.expires',
  3189. 'browsercache.cssjs.lifetime',
  3190. 'browsercache.cssjs.cache.control',
  3191. 'browsercache.cssjs.cache.policy',
  3192. 'browsercache.cssjs.etag',
  3193. 'browsercache.cssjs.w3tc'
  3194. ));
  3195. }
  3196. if ($new_config->get_boolean('browsercache.html.replace')) {
  3197. $browsercache_dependencies = array_merge($browsercache_dependencies, array(
  3198. 'browsercache.html.compression',
  3199. 'browsercache.html.expires',
  3200. 'browsercache.html.lifetime',
  3201. 'browsercache.html.cache.control',
  3202. 'browsercache.html.cache.policy',
  3203. 'browsercache.html.etag',
  3204. 'browsercache.html.w3tc'
  3205. ));
  3206. }
  3207. if ($new_config->get_boolean('browsercache.other.replace')) {
  3208. $browsercache_dependencies = array_merge($browsercache_dependencies, array(
  3209. 'browsercache.other.compression',
  3210. 'browsercache.other.expires',
  3211. 'browsercache.other.lifetime',
  3212. 'browsercache.other.cache.control',
  3213. 'browsercache.other.cache.policy',
  3214. 'browsercache.other.etag',
  3215. 'browsercache.other.w3tc'
  3216. ));
  3217. }
  3218. }
  3219. /**
  3220. * Show need empty page cache notification
  3221. */
  3222. if ($new_config->get_boolean('pgcache.enabled')) {
  3223. $pgcache_dependencies = array_merge($browsercache_dependencies, array(
  3224. 'pgcache.debug',
  3225. 'dbcache.enabled',
  3226. 'objectcache.enabled',
  3227. 'minify.enabled',
  3228. 'cdn.enabled',
  3229. 'mobile.enabled',
  3230. 'referrer.enabled'
  3231. ));
  3232. if ($new_config->get_boolean('dbcache.enabled')) {
  3233. $pgcache_dependencies = array_merge($pgcache_dependencies, array(
  3234. 'dbcache.debug'
  3235. ));
  3236. }
  3237. if ($new_config->get_boolean('objectcache.enabled')) {
  3238. $pgcache_dependencies = array_merge($pgcache_dependencies, array(
  3239. 'objectcache.debug'
  3240. ));
  3241. }
  3242. if ($new_config->get_boolean('minify.enabled')) {
  3243. $pgcache_dependencies = array_merge($pgcache_dependencies, array(
  3244. 'minify.auto',
  3245. 'minify.debug',
  3246. 'minify.rewrite',
  3247. 'minify.html.enable',
  3248. 'minify.html.engine',
  3249. 'minify.html.inline.css',
  3250. 'minify.html.inline.js',
  3251. 'minify.html.strip.crlf',
  3252. 'minify.html.comments.ignore',
  3253. 'minify.css.enable',
  3254. 'minify.css.engine',
  3255. 'minify.css.groups',
  3256. 'minify.js.enable',
  3257. 'minify.js.engine',
  3258. 'minify.js.groups',
  3259. 'minify.htmltidy.options.clean',
  3260. 'minify.htmltidy.options.hide-comments',
  3261. 'minify.htmltidy.options.wrap',
  3262. 'minify.reject.logged',
  3263. 'minify.reject.ua',
  3264. 'minify.reject.uri'
  3265. ));
  3266. }
  3267. if ($new_config->get_boolean('cdn.enabled')) {
  3268. $pgcache_dependencies = array_merge($pgcache_dependencies, array(
  3269. 'cdn.debug',
  3270. 'cdn.engine',
  3271. 'cdn.uploads.enable',
  3272. 'cdn.includes.enable',
  3273. 'cdn.includes.files',
  3274. 'cdn.theme.enable',
  3275. 'cdn.theme.files',
  3276. 'cdn.minify.enable',
  3277. 'cdn.custom.enable',
  3278. 'cdn.custom.files',
  3279. 'cdn.ftp.domain',
  3280. 'cdn.ftp.ssl',
  3281. 'cdn.s3.cname',
  3282. 'cdn.s3.ssl',
  3283. 'cdn.cf.cname',
  3284. 'cdn.cf.ssl',
  3285. 'cdn.cf2.cname',
  3286. 'cdn.cf2.ssl',
  3287. 'cdn.rscf.cname',
  3288. 'cdn.rscf.ssl',
  3289. 'cdn.azure.cname',
  3290. 'cdn.azure.ssl',
  3291. 'cdn.mirror.domain',
  3292. 'cdn.mirror.ssl',
  3293. 'cdn.netdna.domain',
  3294. 'cdn.netdna.ssl',
  3295. 'cdn.cotendo.domain',
  3296. 'cdn.cotendo.ssl',
  3297. 'cdn.edgecast.domain',
  3298. 'cdn.edgecast.ssl',
  3299. 'cdn.reject.admins',
  3300. 'cdn.reject.ua',
  3301. 'cdn.reject.uri',
  3302. 'cdn.reject.files'
  3303. ));
  3304. }
  3305. if ($new_config->get_boolean('mobile.enabled')) {
  3306. $pgcache_dependencies = array_merge($pgcache_dependencies, array(
  3307. 'mobile.rgroups'
  3308. ));
  3309. }
  3310. if ($new_config->get_boolean('referrer.enabled')) {
  3311. $pgcache_dependencies = array_merge($pgcache_dependencies, array(
  3312. 'referrer.rgroups'
  3313. ));
  3314. }
  3315. $old_pgcache_dependencies_values = array();
  3316. $new_pgcache_dependencies_values = array();
  3317. foreach ($pgcache_dependencies as $pgcache_dependency) {
  3318. $old_pgcache_dependencies_values[] = $old_config->get($pgcache_dependency);
  3319. $new_pgcache_dependencies_values[] = $new_config->get($pgcache_dependency);
  3320. }
  3321. if (serialize($old_pgcache_dependencies_values) != serialize($new_pgcache_dependencies_values)) {
  3322. $new_config->set('notes.need_empty_pgcache', true);
  3323. }
  3324. }
  3325. /**
  3326. * Show need empty minify notification
  3327. */
  3328. if ($new_config->get_boolean('minify.enabled') && (($new_config->get_boolean('minify.css.enable') && ($new_config->get_boolean('minify.auto') || count($new_config->get_array('minify.css.groups')))) || ($new_config->get_boolean('minify.js.enable') && ($new_config->get_boolean('minify.auto') || count($new_config->get_array('minify.js.groups')))))) {
  3329. $minify_dependencies = array_merge($browsercache_dependencies, array(
  3330. 'minify.auto',
  3331. 'minify.debug',
  3332. 'minify.options',
  3333. 'minify.symlinks',
  3334. 'minify.css.enable',
  3335. 'minify.js.enable',
  3336. 'cdn.enabled'
  3337. ));
  3338. if ($new_config->get_boolean('minify.css.enable') && ($new_config->get_boolean('minify.auto') || count($new_config->get_array('minify.css.groups')))) {
  3339. $minify_dependencies = array_merge($minify_dependencies, array(
  3340. 'minify.css.engine',
  3341. 'minify.css.combine',
  3342. 'minify.css.strip.comments',
  3343. 'minify.css.strip.crlf',
  3344. 'minify.css.imports',
  3345. 'minify.css.groups',
  3346. 'minify.yuicss.path.java',
  3347. 'minify.yuicss.path.jar',
  3348. 'minify.yuicss.options.line-break',
  3349. 'minify.csstidy.options.remove_bslash',
  3350. 'minify.csstidy.options.compress_colors',
  3351. 'minify.csstidy.options.compress_font-weight',
  3352. 'minify.csstidy.options.lowercase_s',
  3353. 'minify.csstidy.options.optimise_shorthands',
  3354. 'minify.csstidy.options.remove_last_;',
  3355. 'minify.csstidy.options.case_properties',
  3356. 'minify.csstidy.options.sort_properties',
  3357. 'minify.csstidy.options.sort_selectors',
  3358. 'minify.csstidy.options.merge_selectors',
  3359. 'minify.csstidy.options.discard_invalid_properties',
  3360. 'minify.csstidy.options.css_level',
  3361. 'minify.csstidy.options.preserve_css',
  3362. 'minify.csstidy.options.timestamp',
  3363. 'minify.csstidy.options.template'
  3364. ));
  3365. }
  3366. if ($new_config->get_boolean('minify.js.enable') && ($new_config->get_boolean('minify.auto') || count($new_config->get_array('minify.js.groups')))) {
  3367. $minify_dependencies = array_merge($minify_dependencies, array(
  3368. 'minify.js.engine',
  3369. 'minify.js.combine.header',
  3370. 'minify.js.combine.body',
  3371. 'minify.js.combine.footer',
  3372. 'minify.js.strip.comments',
  3373. 'minify.js.strip.crlf',
  3374. 'minify.js.groups',
  3375. 'minify.yuijs.path.java',
  3376. 'minify.yuijs.path.jar',
  3377. 'minify.yuijs.options.line-break',
  3378. 'minify.yuijs.options.nomunge',
  3379. 'minify.yuijs.options.preserve-semi',
  3380. 'minify.yuijs.options.disable-optimizations',
  3381. 'minify.ccjs.path.java',
  3382. 'minify.ccjs.path.jar',
  3383. 'minify.ccjs.options.compilation_level',
  3384. 'minify.ccjs.options.formatting'
  3385. ));
  3386. }
  3387. if ($new_config->get_boolean('cdn.enabled')) {
  3388. $minify_dependencies = array_merge($minify_dependencies, array(
  3389. 'cdn.engine'
  3390. ));
  3391. }
  3392. $old_minify_dependencies_values = array();
  3393. $new_minify_dependencies_values = array();
  3394. foreach ($minify_dependencies as $minify_dependency) {
  3395. $old_minify_dependencies_values[] = $old_config->get($minify_dependency);
  3396. $new_minify_dependencies_values[] = $new_config->get($minify_dependency);
  3397. }
  3398. if (serialize($old_minify_dependencies_values) != serialize($new_minify_dependencies_values)) {
  3399. $new_config->set('notes.need_empty_minify', true);
  3400. }
  3401. }
  3402. if ($new_config->get_boolean('cdn.enabled') && !w3_is_cdn_mirror($new_config->get_string('cdn.engine'))) {
  3403. /**
  3404. * Show notification when CDN enabled
  3405. */
  3406. if (!$old_config->get_boolean('cdn.enabled')) {
  3407. $new_config->set('notes.cdn_upload', true);
  3408. }
  3409. /**
  3410. * Show notification when Browser Cache settings changes
  3411. */
  3412. $cdn_dependencies = array(
  3413. 'browsercache.enabled'
  3414. );
  3415. if ($new_config->get_boolean('cdn.enabled')) {
  3416. $cdn_dependencies = array(
  3417. 'browsercache.cssjs.compression',
  3418. 'browsercache.cssjs.expires',
  3419. 'browsercache.cssjs.lifetime',
  3420. 'browsercache.cssjs.cache.control',
  3421. 'browsercache.cssjs.cache.policy',
  3422. 'browsercache.cssjs.etag',
  3423. 'browsercache.cssjs.w3tc',
  3424. 'browsercache.html.compression',
  3425. 'browsercache.html.expires',
  3426. 'browsercache.html.lifetime',
  3427. 'browsercache.html.cache.control',
  3428. 'browsercache.html.cache.policy',
  3429. 'browsercache.html.etag',
  3430. 'browsercache.html.w3tc',
  3431. 'browsercache.other.compression',
  3432. 'browsercache.other.expires',
  3433. 'browsercache.other.lifetime',
  3434. 'browsercache.other.cache.control',
  3435. 'browsercache.other.cache.policy',
  3436. 'browsercache.other.etag',
  3437. 'browsercache.other.w3tc'
  3438. );
  3439. }
  3440. $old_cdn_dependencies_values = array();
  3441. $new_cdn_dependencies_values = array();
  3442. foreach ($cdn_dependencies as $cdn_dependency) {
  3443. $old_cdn_dependencies_values[] = $old_config->get($cdn_dependency);
  3444. $new_cdn_dependencies_values[] = $new_config->get($cdn_dependency);
  3445. }
  3446. if (serialize($old_cdn_dependencies_values) != serialize($new_cdn_dependencies_values)) {
  3447. $new_config->set('notes.cdn_reupload', true);
  3448. }
  3449. }
  3450. /**
  3451. * Show need empty object cache notification
  3452. */
  3453. if ($this->_config->get_boolean('objectcache.enabled')) {
  3454. $objectcache_dependencies = array(
  3455. 'objectcache.groups.global',
  3456. 'objectcache.groups.nonpersistent'
  3457. );
  3458. $old_objectcache_dependencies_values = array();
  3459. $new_objectcache_dependencies_values = array();
  3460. foreach ($objectcache_dependencies as $objectcache_dependency) {
  3461. $old_objectcache_dependencies_values[] = $old_config->get($objectcache_dependency);
  3462. $new_objectcache_dependencies_values[] = $new_config->get($objectcache_dependency);
  3463. }
  3464. if (serialize($old_objectcache_dependencies_values) != serialize($new_objectcache_dependencies_values)) {
  3465. $new_config->set('notes.need_empty_objectcache', true);
  3466. }
  3467. }
  3468. /**
  3469. * Save config
  3470. */
  3471. if ($new_config->save($preview)) {
  3472. $w3_plugin_pgcache = & w3_instance('W3_Plugin_PgCacheAdmin');
  3473. $w3_plugin_dbcache = & w3_instance('W3_Plugin_DbCache');
  3474. $w3_plugin_objectcache = & w3_instance('W3_Plugin_ObjectCache');
  3475. $w3_plugin_browsercache = & w3_instance('W3_Plugin_BrowserCacheAdmin');
  3476. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnAdmin');
  3477. if (W3TC_PHP5) {
  3478. $w3_plugin_minify = & w3_instance('W3_Plugin_MinifyAdmin');
  3479. }
  3480. /**
  3481. * Empty caches on engine change or cache enable/disable
  3482. */
  3483. if ($old_config->get_string('pgcache.engine') != $new_config->get_string('pgcache.engine') || $old_config->get_string('pgcache.enabled') != $new_config->get_string('pgcache.enabled')) {
  3484. $this->flush_pgcache();
  3485. }
  3486. if ($old_config->get_string('dbcache.engine') != $new_config->get_string('dbcache.engine') || $old_config->get_string('dbcache.enabled') != $new_config->get_string('dbcache.enabled')) {
  3487. $this->flush_dbcache();
  3488. }
  3489. if ($old_config->get_string('objectcache.engine') != $new_config->get_string('objectcache.engine') || $old_config->get_string('objectcache.enabled') != $new_config->get_string('objectcache.enabled')) {
  3490. $this->flush_objectcache();
  3491. }
  3492. if ($old_config->get_string('minify.engine') != $new_config->get_string('minify.engine') || $old_config->get_string('minify.enabled') != $new_config->get_string('minify.enabled')) {
  3493. $this->flush_minify();
  3494. }
  3495. /**
  3496. * Unschedule events if changed file gc interval
  3497. */
  3498. $w3_plugin_pgcache->before_config_change($old_config, $new_config);
  3499. if ($old_config->get_integer('dbcache.file.gc') != $new_config->get_integer('dbcache.file.gc')) {
  3500. $w3_plugin_dbcache->unschedule();
  3501. }
  3502. if ($old_config->get_integer('objectcache.file.gc') != $new_config->get_integer('objectcache.file.gc')) {
  3503. $w3_plugin_objectcache->unschedule();
  3504. }
  3505. if ($old_config->get_integer('cdn.autoupload.interval') != $new_config->get_integer('cdn.autoupload.interval')) {
  3506. $w3_plugin_cdn->unschedule_upload();
  3507. }
  3508. if (W3TC_PHP5) {
  3509. $w3_plugin_minify->before_config_change($old_config, $new_config);
  3510. }
  3511. /**
  3512. * Create CDN queue table
  3513. */
  3514. if (($old_config->get_boolean('cdn.enabled') != $new_config->get_boolean('cdn.enabled') || $old_config->get_string('cdn.engine') != $new_config->get_string('cdn.engine')) && $new_config->get_boolean('cdn.enabled') && !w3_is_cdn_mirror($new_config->get_string('cdn.engine'))) {
  3515. $w3_plugin_cdn->table_create();
  3516. }
  3517. /**
  3518. * Update CloudFront CNAMEs
  3519. */
  3520. $update_cf_cnames = false;
  3521. if ($new_config->get_boolean('cdn.enabled') && in_array($new_config->get_string('cdn.engine'), array('cf', 'cf2'))) {
  3522. if ($new_config->get_string('cdn.engine') == 'cf') {
  3523. $old_cnames = $old_config->get_array('cdn.cf.cname');
  3524. $new_cnames = $new_config->get_array('cdn.cf.cname');
  3525. } else {
  3526. $old_cnames = $old_config->get_array('cdn.cf2.cname');
  3527. $new_cnames = $new_config->get_array('cdn.cf2.cname');
  3528. }
  3529. if (count($old_cnames) != count($new_cnames) || count(array_diff($old_cnames, $new_cnames))) {
  3530. $update_cf_cnames = true;
  3531. }
  3532. }
  3533. /**
  3534. * Refresh config
  3535. */
  3536. $old_config->load();
  3537. /**
  3538. * Schedule events
  3539. */
  3540. $w3_plugin_pgcache->after_config_change();
  3541. $w3_plugin_dbcache->schedule();
  3542. $w3_plugin_objectcache->schedule();
  3543. $w3_plugin_cdn->after_config_change();
  3544. /**
  3545. * Update support us option
  3546. */
  3547. $this->link_update();
  3548. /**
  3549. * Write browsercache rules
  3550. */
  3551. if ($new_config->get_boolean('browsercache.enabled')) {
  3552. if (w3_can_modify_rules(w3_get_browsercache_rules_cache_path())) {
  3553. $w3_plugin_browsercache->write_rules_cache();
  3554. }
  3555. if ($new_config->get_boolean('browsercache.no404wp')) {
  3556. if (w3_can_modify_rules(w3_get_browsercache_rules_no404wp_path())) {
  3557. $w3_plugin_browsercache->write_rules_no404wp();
  3558. }
  3559. } else {
  3560. if (w3_can_modify_rules(w3_get_browsercache_rules_no404wp_path())) {
  3561. $w3_plugin_browsercache->remove_rules_no404wp();
  3562. }
  3563. }
  3564. } else {
  3565. if (w3_can_modify_rules(w3_get_browsercache_rules_cache_path())) {
  3566. $w3_plugin_browsercache->remove_rules_cache();
  3567. }
  3568. if (w3_can_modify_rules(w3_get_browsercache_rules_no404wp_path())) {
  3569. $w3_plugin_browsercache->remove_rules_no404wp();
  3570. }
  3571. }
  3572. /**
  3573. * Write minify rewrite rules
  3574. */
  3575. if (W3TC_PHP5) {
  3576. $w3_plugin_minify->after_config_change();
  3577. }
  3578. /**
  3579. * Auto upload minify files to CDN
  3580. */
  3581. if ($new_config->get_boolean('minify.enabled') && $new_config->get_boolean('minify.upload') && $new_config->get_boolean('cdn.enabled') && !w3_is_cdn_mirror($new_config->get_string('cdn.engine'))) {
  3582. $this->cdn_upload_minify();
  3583. }
  3584. /**
  3585. * Auto upload browsercache files to CDN
  3586. */
  3587. if ($new_config->get_boolean('cdn.enabled') && $new_config->get_string('cdn.engine') == 'ftp') {
  3588. $this->cdn_delete_browsercache();
  3589. if ($new_config->get_boolean('browsercache.enabled')) {
  3590. $this->cdn_upload_browsercache();
  3591. }
  3592. }
  3593. /**
  3594. * Update CloudFront CNAMEs
  3595. */
  3596. if ($update_cf_cnames) {
  3597. $error = null;
  3598. $w3_plugin_cdn->update_cnames($error);
  3599. }
  3600. /**
  3601. * Save blognames into file
  3602. */
  3603. if (w3_is_network() && !w3_is_subdomain_install()) {
  3604. w3_save_blognames();
  3605. }
  3606. return true;
  3607. }
  3608. return false;
  3609. }
  3610. /**
  3611. * Flush specified cache
  3612. *
  3613. * @param string $type
  3614. * @return void
  3615. */
  3616. function flush($type) {
  3617. if ($this->_config->get_string('pgcache.engine') == $type && $this->_config->get_boolean('pgcache.enabled')) {
  3618. $this->_config->set('notes.need_empty_pgcache', false);
  3619. $this->_config->set('notes.plugins_updated', false);
  3620. if (!$this->_config->save()) {
  3621. $this->redirect(array(
  3622. 'w3tc_error' => 'config_save'
  3623. ));
  3624. }
  3625. $this->flush_pgcache();
  3626. }
  3627. if ($this->_config->get_string('dbcache.engine') == $type && $this->_config->get_boolean('dbcache.enabled')) {
  3628. $this->flush_dbcache();
  3629. }
  3630. if ($this->_config->get_string('objectcache.engine') == $type && $this->_config->get_boolean('objectcache.enabled')) {
  3631. $this->flush_objectcache();
  3632. }
  3633. if ($this->_config->get_string('minify.engine') == $type && $this->_config->get_boolean('minify.enabled')) {
  3634. $this->_config->set('notes.need_empty_minify', false);
  3635. if (!$this->_config->save()) {
  3636. $this->redirect(array(
  3637. 'w3tc_error' => 'config_save'
  3638. ));
  3639. }
  3640. $this->flush_minify();
  3641. }
  3642. }
  3643. /**
  3644. * Flush memcached cache
  3645. *
  3646. * @return void
  3647. */
  3648. function flush_memcached() {
  3649. $this->flush('memcached');
  3650. }
  3651. /**
  3652. * Flush APC cache
  3653. *
  3654. * @return void
  3655. */
  3656. function flush_opcode() {
  3657. $this->flush('apc');
  3658. $this->flush('eaccelerator');
  3659. $this->flush('xcache');
  3660. $this->flush('wincache');
  3661. }
  3662. /**
  3663. * Flush file cache
  3664. *
  3665. * @return void
  3666. */
  3667. function flush_file() {
  3668. $this->flush('file');
  3669. $this->flush('file_generic');
  3670. }
  3671. /**
  3672. * Flush all cache
  3673. *
  3674. * @return void
  3675. */
  3676. function flush_all() {
  3677. $this->flush_memcached();
  3678. $this->flush_opcode();
  3679. $this->flush_file();
  3680. }
  3681. /**
  3682. * Flush page cache
  3683. *
  3684. * @return void
  3685. */
  3686. function flush_pgcache() {
  3687. $w3_pgcache = & w3_instance('W3_PgCacheFlush');
  3688. $w3_pgcache->flush();
  3689. }
  3690. /**
  3691. * Flush page cache
  3692. *
  3693. * @return void
  3694. */
  3695. function flush_dbcache() {
  3696. require_once W3TC_LIB_W3_DIR . '/Db.php';
  3697. @$w3_db = & W3_Db::instance();
  3698. $w3_db->flush_cache();
  3699. }
  3700. /**
  3701. * Flush page cache
  3702. *
  3703. * @return void
  3704. */
  3705. function flush_objectcache() {
  3706. $w3_objectcache = & w3_instance('W3_ObjectCache');
  3707. $w3_objectcache->flush();
  3708. }
  3709. /**
  3710. * Flush minify cache
  3711. *
  3712. * @return void
  3713. */
  3714. function flush_minify() {
  3715. if (W3TC_PHP5) {
  3716. $w3_minify = & w3_instance('W3_Minify');
  3717. $w3_minify->flush();
  3718. }
  3719. }
  3720. /**
  3721. * Returns array of theme groups
  3722. *
  3723. * @param string $theme_name
  3724. * @return array
  3725. */
  3726. function get_theme_files($theme_name) {
  3727. $patterns = array(
  3728. '404',
  3729. 'search',
  3730. 'taxonomy(-.*)?',
  3731. 'front-page',
  3732. 'home',
  3733. 'index',
  3734. '(image|video|text|audio|application).*',
  3735. 'attachment',
  3736. 'single(-.*)?',
  3737. 'page(-.*)?',
  3738. 'category(-.*)?',
  3739. 'tag(-.*)?',
  3740. 'author(-.*)?',
  3741. 'date',
  3742. 'archive',
  3743. 'comments-popup',
  3744. 'paged'
  3745. );
  3746. $templates = array();
  3747. $theme = get_theme($theme_name);
  3748. if ($theme && isset($theme['Template Files'])) {
  3749. $template_files = (array) $theme['Template Files'];
  3750. foreach ($template_files as $template_file) {
  3751. /**
  3752. * Check file name
  3753. */
  3754. $template = basename($template_file, '.php');
  3755. foreach ($patterns as $pattern) {
  3756. $regexp = '~^' . $pattern . '$~';
  3757. if (preg_match($regexp, $template)) {
  3758. $templates[] = $template_file;
  3759. continue 2;
  3760. }
  3761. }
  3762. /**
  3763. * Check get_header function call
  3764. */
  3765. $template_content = @file_get_contents($template_file);
  3766. if ($template_content && preg_match('~\s*get_header[0-9_]*\s*\(~', $template_content)) {
  3767. $templates[] = $template_file;
  3768. }
  3769. }
  3770. sort($templates);
  3771. reset($templates);
  3772. }
  3773. return $templates;
  3774. }
  3775. /**
  3776. * Returns minify groups
  3777. *
  3778. * @param string $theme_name
  3779. * @return array
  3780. */
  3781. function get_theme_templates($theme_name) {
  3782. $groups = array(
  3783. 'default' => 'All Templates'
  3784. );
  3785. $templates = $this->get_theme_files($theme_name);
  3786. foreach ($templates as $template) {
  3787. $basename = basename($template, '.php');
  3788. $groups[$basename] = ucfirst($basename);
  3789. }
  3790. return $groups;
  3791. }
  3792. /**
  3793. * Returns array of detected URLs for theme templates
  3794. *
  3795. * @param string $theme_name
  3796. * @return array
  3797. */
  3798. function get_theme_urls($theme_name) {
  3799. $urls = array();
  3800. $theme = get_theme($theme_name);
  3801. if ($theme && isset($theme['Template Files'])) {
  3802. $front_page_template = false;
  3803. if (get_option('show_on_front') == 'page') {
  3804. $front_page_id = get_option('page_on_front');
  3805. if ($front_page_id) {
  3806. $front_page_template_file = get_post_meta($front_page_id, '_wp_page_template', true);
  3807. if ($front_page_template_file) {
  3808. $front_page_template = basename($front_page_template_file, '.php');
  3809. }
  3810. }
  3811. }
  3812. $home_url = w3_get_home_url();
  3813. $template_files = (array) $theme['Template Files'];
  3814. $mime_types = get_allowed_mime_types();
  3815. $custom_mime_types = array();
  3816. foreach ($mime_types as $mime_type) {
  3817. list ($type1, $type2) = explode('/', $mime_type);
  3818. $custom_mime_types = array_merge($custom_mime_types, array(
  3819. $type1,
  3820. $type2,
  3821. $type1 . '_' . $type2
  3822. ));
  3823. }
  3824. foreach ($template_files as $template_file) {
  3825. $link = false;
  3826. $template = basename($template_file, '.php');
  3827. /**
  3828. * Check common templates
  3829. */
  3830. switch (true) {
  3831. /**
  3832. * Handle home.php or index.php or front-page.php
  3833. */
  3834. case (!$front_page_template && $template == 'home'):
  3835. case (!$front_page_template && $template == 'index'):
  3836. case (!$front_page_template && $template == 'front-page'):
  3837. /**
  3838. * Handle custom home page
  3839. */
  3840. case ($template == $front_page_template):
  3841. $link = $home_url . '/';
  3842. break;
  3843. /**
  3844. * Handle 404.php
  3845. */
  3846. case ($template == '404'):
  3847. $permalink = get_option('permalink_structure');
  3848. if ($permalink) {
  3849. $link = sprintf('%s/%s/', $home_url, '404_test');
  3850. } else {
  3851. $link = sprintf('%s/?p=%d', $home_url, 999999999);
  3852. }
  3853. break;
  3854. /**
  3855. * Handle search.php
  3856. */
  3857. case ($template == 'search'):
  3858. $link = sprintf('%s/?s=%s', $home_url, 'search_test');
  3859. break;
  3860. /**
  3861. * Handle date.php or archive.php
  3862. */
  3863. case ($template == 'date'):
  3864. case ($template == 'archive'):
  3865. $posts = get_posts(array(
  3866. 'numberposts' => 1,
  3867. 'orderby' => 'rand'
  3868. ));
  3869. if (is_array($posts) && count($posts)) {
  3870. $time = strtotime($posts[0]->post_date);
  3871. $link = get_day_link(date('Y', $time), date('m', $time), date('d', $time));
  3872. }
  3873. break;
  3874. /**
  3875. * Handle author.php
  3876. */
  3877. case ($template == 'author'):
  3878. $author_id = false;
  3879. if (function_exists('get_users')) {
  3880. $users = get_users();
  3881. if (is_array($users) && count($users)) {
  3882. $user = current($users);
  3883. $author_id = $user->ID;
  3884. }
  3885. } else {
  3886. $author_ids = get_author_user_ids();
  3887. if (is_array($author_ids) && count($author_ids)) {
  3888. $author_id = $author_ids[0];
  3889. }
  3890. }
  3891. if ($author_id) {
  3892. $link = get_author_posts_url($author_id);
  3893. }
  3894. break;
  3895. /**
  3896. * Handle category.php
  3897. */
  3898. case ($template == 'category'):
  3899. $category_ids = get_all_category_ids();
  3900. if (is_array($category_ids) && count($category_ids)) {
  3901. $link = get_category_link($category_ids[0]);
  3902. }
  3903. break;
  3904. /**
  3905. * Handle tag.php
  3906. */
  3907. case ($template == 'tag'):
  3908. $term_ids = get_terms('post_tag', 'fields=ids');
  3909. if (is_array($term_ids) && count($term_ids)) {
  3910. $link = get_term_link($term_ids[0], 'post_tag');
  3911. }
  3912. break;
  3913. /**
  3914. * Handle taxonomy.php
  3915. */
  3916. case ($template == 'taxonomy'):
  3917. $taxonomy = '';
  3918. if (isset($GLOBALS['wp_taxonomies']) && is_array($GLOBALS['wp_taxonomies'])) {
  3919. foreach ($GLOBALS['wp_taxonomies'] as $wp_taxonomy) {
  3920. if (!in_array($wp_taxonomy->name, array(
  3921. 'category',
  3922. 'post_tag',
  3923. 'link_category'
  3924. ))) {
  3925. $taxonomy = $wp_taxonomy->name;
  3926. break;
  3927. }
  3928. }
  3929. }
  3930. if ($taxonomy) {
  3931. $terms = get_terms($taxonomy, array(
  3932. 'number' => 1
  3933. ));
  3934. if (is_array($terms) && count($terms)) {
  3935. $link = get_term_link($terms[0], $taxonomy);
  3936. }
  3937. }
  3938. break;
  3939. /**
  3940. * Handle attachment.php
  3941. */
  3942. case ($template == 'attachment'):
  3943. $attachments = get_posts(array(
  3944. 'post_type' => 'attachment',
  3945. 'numberposts' => 1,
  3946. 'orderby' => 'rand'
  3947. ));
  3948. if (is_array($attachments) && count($attachments)) {
  3949. $link = get_attachment_link($attachments[0]->ID);
  3950. }
  3951. break;
  3952. /**
  3953. * Handle single.php
  3954. */
  3955. case ($template == 'single'):
  3956. $posts = get_posts(array(
  3957. 'numberposts' => 1,
  3958. 'orderby' => 'rand'
  3959. ));
  3960. if (is_array($posts) && count($posts)) {
  3961. $link = get_permalink($posts[0]->ID);
  3962. }
  3963. break;
  3964. /**
  3965. * Handle page.php
  3966. */
  3967. case ($template == 'page'):
  3968. $pages_ids = get_all_page_ids();
  3969. if (is_array($pages_ids) && count($pages_ids)) {
  3970. $link = get_page_link($pages_ids[0]);
  3971. }
  3972. break;
  3973. /**
  3974. * Handle comments-popup.php
  3975. */
  3976. case ($template == 'comments-popup'):
  3977. $posts = get_posts(array(
  3978. 'numberposts' => 1,
  3979. 'orderby' => 'rand'
  3980. ));
  3981. if (is_array($posts) && count($posts)) {
  3982. $link = sprintf('%s/?comments_popup=%d', $home_url, $posts[0]->ID);
  3983. }
  3984. break;
  3985. /**
  3986. * Handle paged.php
  3987. */
  3988. case ($template == 'paged'):
  3989. global $wp_rewrite;
  3990. if ($wp_rewrite->using_permalinks()) {
  3991. $link = sprintf('%s/page/%d/', $home_url, 1);
  3992. } else {
  3993. $link = sprintf('%s/?paged=%d', 1);
  3994. }
  3995. break;
  3996. /**
  3997. * Handle author-id.php or author-nicename.php
  3998. */
  3999. case preg_match('~^author-(.+)$~', $template, $matches):
  4000. if (is_numeric($matches[1])) {
  4001. $link = get_author_posts_url($matches[1]);
  4002. } else {
  4003. $link = get_author_posts_url(null, $matches[1]);
  4004. }
  4005. break;
  4006. /**
  4007. * Handle category-id.php or category-slug.php
  4008. */
  4009. case preg_match('~^category-(.+)$~', $template, $matches):
  4010. if (is_numeric($matches[1])) {
  4011. $link = get_category_link($matches[1]);
  4012. } else {
  4013. $term = get_term_by('slug', $matches[1], 'category');
  4014. if (is_object($term)) {
  4015. $link = get_category_link($term->term_id);
  4016. }
  4017. }
  4018. break;
  4019. /**
  4020. * Handle tag-id.php or tag-slug.php
  4021. */
  4022. case preg_match('~^tag-(.+)$~', $template, $matches):
  4023. if (is_numeric($matches[1])) {
  4024. $link = get_tag_link($matches[1]);
  4025. } else {
  4026. $term = get_term_by('slug', $matches[1], 'post_tag');
  4027. if (is_object($term)) {
  4028. $link = get_tag_link($term->term_id);
  4029. }
  4030. }
  4031. break;
  4032. /**
  4033. * Handle taxonomy-taxonomy-term.php
  4034. */
  4035. case preg_match('~^taxonomy-(.+)-(.+)$~', $template, $matches):
  4036. $link = get_term_link($matches[2], $matches[1]);
  4037. break;
  4038. /**
  4039. * Handle taxonomy-taxonomy.php
  4040. */
  4041. case preg_match('~^taxonomy-(.+)$~', $template, $matches):
  4042. $terms = get_terms($matches[1], array(
  4043. 'number' => 1
  4044. ));
  4045. if (is_array($terms) && count($terms)) {
  4046. $link = get_term_link($terms[0], $matches[1]);
  4047. }
  4048. break;
  4049. /**
  4050. * Handle MIME_type.php
  4051. */
  4052. case in_array($template, $custom_mime_types):
  4053. $posts = get_posts(array(
  4054. 'post_mime_type' => '%' . $template . '%',
  4055. 'post_type' => 'attachment',
  4056. 'numberposts' => 1,
  4057. 'orderby' => 'rand'
  4058. ));
  4059. if (is_array($posts) && count($posts)) {
  4060. $link = get_permalink($posts[0]->ID);
  4061. }
  4062. break;
  4063. /**
  4064. * Handle single-posttype.php
  4065. */
  4066. case preg_match('~^single-(.+)$~', $template, $matches):
  4067. $posts = get_posts(array(
  4068. 'post_type' => $matches[1],
  4069. 'numberposts' => 1,
  4070. 'orderby' => 'rand'
  4071. ));
  4072. if (is_array($posts) && count($posts)) {
  4073. $link = get_permalink($posts[0]->ID);
  4074. }
  4075. break;
  4076. /**
  4077. * Handle page-id.php or page-slug.php
  4078. */
  4079. case preg_match('~^page-(.+)$~', $template, $matches):
  4080. if (is_numeric($matches[1])) {
  4081. $link = get_permalink($matches[1]);
  4082. } else {
  4083. $posts = get_posts(array(
  4084. 'pagename' => $matches[1],
  4085. 'post_type' => 'page',
  4086. 'numberposts' => 1
  4087. ));
  4088. if (is_array($posts) && count($posts)) {
  4089. $link = get_permalink($posts[0]->ID);
  4090. }
  4091. }
  4092. break;
  4093. /**
  4094. * Try to handle custom template
  4095. */
  4096. default:
  4097. $posts = get_posts(array(
  4098. 'pagename' => $template,
  4099. 'post_type' => 'page',
  4100. 'numberposts' => 1
  4101. ));
  4102. if (is_array($posts) && count($posts)) {
  4103. $link = get_permalink($posts[0]->ID);
  4104. }
  4105. break;
  4106. }
  4107. if ($link && !is_wp_error($link)) {
  4108. $urls[$template] = $link;
  4109. }
  4110. }
  4111. }
  4112. return $urls;
  4113. }
  4114. /**
  4115. * Returns theme recommendations
  4116. *
  4117. * @param string $theme_name
  4118. * @return array
  4119. */
  4120. function get_theme_recommendations($theme_name) {
  4121. $urls = $this->get_theme_urls($theme_name);
  4122. $js_groups = array();
  4123. $css_groups = array();
  4124. @set_time_limit($this->_config->get_integer('timelimit.minify_recommendations'));
  4125. foreach ($urls as $template => $url) {
  4126. /**
  4127. * Append theme identifier
  4128. */
  4129. $url .= (strstr($url, '?') !== false ? '&' : '?') . 'w3tc_theme=' . urlencode($theme_name);
  4130. /**
  4131. * If preview mode enabled append w3tc_preview
  4132. */
  4133. if (w3_is_preview_config()) {
  4134. $url .= '&w3tc_preview=1';
  4135. }
  4136. /**
  4137. * Get page contents
  4138. */
  4139. $response = w3_http_get($url);
  4140. if (!is_wp_error($response) && ($response['response']['code'] == 200 || ($response['response']['code'] == 404 && $template == '404'))) {
  4141. $js_files = $this->get_recommendations_js($response['body']);
  4142. $css_files = $this->get_recommendations_css($response['body']);
  4143. $js_groups[$template] = $js_files;
  4144. $css_groups[$template] = $css_files;
  4145. }
  4146. }
  4147. $js_groups = $this->get_theme_recommendations_by_groups($js_groups);
  4148. $css_groups = $this->get_theme_recommendations_by_groups($css_groups);
  4149. $recommendations = array(
  4150. $js_groups,
  4151. $css_groups
  4152. );
  4153. return $recommendations;
  4154. }
  4155. /**
  4156. * Find common files and place them into default group
  4157. *
  4158. * @param array $groups
  4159. * @return array
  4160. */
  4161. function get_theme_recommendations_by_groups($groups) {
  4162. /**
  4163. * First calculate file usage count
  4164. */
  4165. $all_files = array();
  4166. foreach ($groups as $template => $files) {
  4167. foreach ($files as $file) {
  4168. if (!isset($all_files[$file])) {
  4169. $all_files[$file] = 0;
  4170. }
  4171. $all_files[$file]++;
  4172. }
  4173. }
  4174. /**
  4175. * Determine default group files
  4176. */
  4177. $default_files = array();
  4178. $count = count($groups);
  4179. foreach ($all_files as $all_file => $all_file_count) {
  4180. /**
  4181. * If file usage count == groups count then file is common
  4182. */
  4183. if ($count == $all_file_count) {
  4184. $default_files[] = $all_file;
  4185. /**
  4186. * If common file found unset it from all groups
  4187. */
  4188. foreach ($groups as $template => $files) {
  4189. foreach ($files as $index => $file) {
  4190. if ($file == $all_file) {
  4191. array_splice($groups[$template], $index, 1);
  4192. if (!count($groups[$template])) {
  4193. unset($groups[$template]);
  4194. }
  4195. break;
  4196. }
  4197. }
  4198. }
  4199. }
  4200. }
  4201. /**
  4202. * If there are common files append add them into default group
  4203. */
  4204. if (count($default_files)) {
  4205. $new_groups = array();
  4206. $new_groups['default'] = $default_files;
  4207. foreach ($groups as $template => $files) {
  4208. $new_groups[$template] = $files;
  4209. }
  4210. $groups = $new_groups;
  4211. }
  4212. /**
  4213. * Unset empty templates
  4214. */
  4215. foreach ($groups as $template => $files) {
  4216. if (!count($files)) {
  4217. unset($groups[$template]);
  4218. }
  4219. }
  4220. return $groups;
  4221. }
  4222. /**
  4223. * Parse content and return JS recommendations
  4224. *
  4225. * @param string $content
  4226. * @return array
  4227. */
  4228. function get_recommendations_js(&$content) {
  4229. require_once W3TC_INC_DIR . '/functions/extract.php';
  4230. $files = w3_extract_js($content);
  4231. $files = array_map('w3_normalize_file_minify', $files);
  4232. $files = array_unique($files);
  4233. return $files;
  4234. }
  4235. /**
  4236. * Parse content and return CSS recommendations
  4237. *
  4238. * @param string $content
  4239. * @return array
  4240. */
  4241. function get_recommendations_css(&$content) {
  4242. require_once W3TC_INC_DIR . '/functions/extract.php';
  4243. $files = w3_extract_css($content);
  4244. $files = array_map('w3_normalize_file_minify', $files);
  4245. $files = array_unique($files);
  4246. return $files;
  4247. }
  4248. /**
  4249. * Returns button html
  4250. *
  4251. * @param string $text
  4252. * @param string $onclick
  4253. * @param string $class
  4254. * @return string
  4255. */
  4256. function button($text, $onclick = '', $class = '') {
  4257. return sprintf('<input type="button" class="button %s" value="%s" onclick="%s" />', htmlspecialchars($class), htmlspecialchars($text), htmlspecialchars($onclick));
  4258. }
  4259. /**
  4260. * Returns button link html
  4261. *
  4262. * @param string $text
  4263. * @param string $url
  4264. * @param boolean $new_window
  4265. * @return string
  4266. */
  4267. function button_link($text, $url, $new_window = false) {
  4268. $url = str_replace('&amp;', '&', $url);
  4269. if ($new_window) {
  4270. $onclick = sprintf('window.open(\'%s\');', addslashes($url));
  4271. } else {
  4272. $onclick = sprintf('document.location.href=\'%s\';', addslashes($url));
  4273. }
  4274. return $this->button($text, $onclick);
  4275. }
  4276. /**
  4277. * Returns hide note button html
  4278. *
  4279. * @param string $text
  4280. * @param string $note
  4281. * @param string $redirect
  4282. * @return string
  4283. */
  4284. function button_hide_note($text, $note, $redirect = '') {
  4285. $url = sprintf('admin.php?page=%s&w3tc_hide_note&note=%s', $this->_page, $note);
  4286. if ($redirect != '') {
  4287. $url .= '&redirect=' . urlencode($redirect);
  4288. }
  4289. $url = wp_nonce_url($url, 'w3tc');
  4290. return $this->button_link($text, $url);
  4291. }
  4292. /**
  4293. * Returns popup button html
  4294. *
  4295. * @param string $text
  4296. * @param string $action
  4297. * @param string $params
  4298. * @param integer $width
  4299. * @param integer $height
  4300. * @return string
  4301. */
  4302. function button_popup($text, $action, $params = '', $width = 800, $height = 600) {
  4303. $url = wp_nonce_url(sprintf('admin.php?page=w3tc_general&w3tc_%s%s', $action, ($params != '' ? '&' . $params : '')), 'w3tc');
  4304. $url = str_replace('&amp;', '&', $url);
  4305. $onclick = sprintf('window.open(\'%s\', \'%s\', \'width=%d,height=%d,status=no,toolbar=no,menubar=no,scrollbars=yes\');', $url, $action, $width, $height);
  4306. return $this->button($text, $onclick);
  4307. }
  4308. /**
  4309. * Returns postbox header
  4310. *
  4311. * @param string $title
  4312. * @param string $class
  4313. * @return string
  4314. */
  4315. function postbox_header($title, $class = '') {
  4316. return '<div class="postbox ' . $class . '"><div class="handlediv" title="Click to toggle"><br /></div><h3 class="hndle"><span>' . $title . '</span></h3><div class="inside">';
  4317. }
  4318. /**
  4319. * Returns postbox footer
  4320. *
  4321. * @return string
  4322. */
  4323. function postbox_footer() {
  4324. return '</div></div>';
  4325. }
  4326. /**
  4327. * Returns nonce field HTML
  4328. *
  4329. * @param string $action
  4330. * @param string $name
  4331. * @param bool $referer
  4332. * @param bool $echo
  4333. * @return string
  4334. */
  4335. function nonce_field($action = -1, $name = '_wpnonce', $referer = true) {
  4336. $name = esc_attr($name);
  4337. $return = '<input type="hidden" name="' . $name . '" value="' . wp_create_nonce($action) . '" />';
  4338. if ($referer) {
  4339. $return .= wp_referer_field(false);
  4340. }
  4341. return $return;
  4342. }
  4343. /**
  4344. * Returns true if advanced-cache.php is installed
  4345. *
  4346. * @return boolean
  4347. */
  4348. function advanced_cache_installed() {
  4349. return file_exists(W3TC_ADDIN_FILE_ADVANCED_CACHE);
  4350. }
  4351. /**
  4352. * Checks if advanced-cache.php exists
  4353. *
  4354. * @return boolean
  4355. */
  4356. function advanced_cache_check() {
  4357. return (($script_data = @file_get_contents(W3TC_ADDIN_FILE_ADVANCED_CACHE)) && strstr($script_data, 'W3_PgCache') !== false);
  4358. }
  4359. /**
  4360. * Returns true if db.php is installed
  4361. *
  4362. * @return boolean
  4363. */
  4364. function db_installed() {
  4365. return file_exists(W3TC_ADDIN_FILE_DB);
  4366. }
  4367. /**
  4368. * Checks if db.php exists
  4369. *
  4370. * @return boolean
  4371. */
  4372. function db_check() {
  4373. return (($script_data = @file_get_contents(W3TC_ADDIN_FILE_DB)) && strstr($script_data, 'W3_Db') !== false);
  4374. }
  4375. /**
  4376. * Returns true if object-cache.php is installed
  4377. *
  4378. * @return boolean
  4379. */
  4380. function objectcache_installed() {
  4381. return file_exists(W3TC_ADDIN_FILE_OBJECT_CACHE);
  4382. }
  4383. /**
  4384. * Checks if db.php exists
  4385. *
  4386. * @return boolean
  4387. */
  4388. function objectcache_check() {
  4389. return (($script_data = @file_get_contents(W3TC_ADDIN_FILE_OBJECT_CACHE)) && strstr($script_data, 'W3_ObjectCache') !== false);
  4390. }
  4391. /**
  4392. * Check if memcache is available
  4393. *
  4394. * @param array $servers
  4395. * @return boolean
  4396. */
  4397. function is_memcache_available($servers) {
  4398. static $results = array();
  4399. $key = md5(implode('', $servers));
  4400. if (!isset($results[$key])) {
  4401. require_once W3TC_LIB_W3_DIR . '/Cache/Memcached.php';
  4402. @$memcached = & new W3_Cache_Memcached(array(
  4403. 'servers' => $servers,
  4404. 'persistant' => false
  4405. ));
  4406. $test_string = sprintf('test_' . md5(time()));
  4407. $memcached->set($test_string, $test_string, 60);
  4408. $results[$key] = ($memcached->get($test_string) == $test_string);
  4409. }
  4410. return $results[$key];
  4411. }
  4412. /**
  4413. * Perform pgcache rules rewrite test
  4414. *
  4415. * @return bool
  4416. */
  4417. function test_rewrite_pgcache() {
  4418. $url = w3_get_home_url() . '/w3tc_rewrite_test';
  4419. return $this->test_rewrite($url);
  4420. }
  4421. /**
  4422. * Perform minify rules rewrite test
  4423. *
  4424. * @return bool
  4425. */
  4426. function test_rewrite_minify() {
  4427. $url = sprintf('%s/%s/w3tc_rewrite_test', w3_get_home_url(), W3TC_CONTENT_MINIFY_DIR_NAME);
  4428. return $this->test_rewrite($url);
  4429. }
  4430. /**
  4431. * Perform rewrite test
  4432. *
  4433. * @param string $url
  4434. * @return boolean
  4435. */
  4436. function test_rewrite($url) {
  4437. $key = sprintf('w3tc_rewrite_test_%s', substr(md5($url), 0, 16));
  4438. $result = get_transient($key);
  4439. if ($result === false) {
  4440. $response = w3_http_get($url);
  4441. $result = (!is_wp_error($response) && $response['response']['code'] == 200 && trim($response['body']) == 'OK');
  4442. if ($result) {
  4443. set_transient($key, $result, 30);
  4444. }
  4445. }
  4446. return $result;
  4447. }
  4448. /**
  4449. * Returns cookie domain
  4450. *
  4451. * @return string
  4452. */
  4453. function get_cookie_domain() {
  4454. $site_url = get_option('siteurl');
  4455. $parse_url = @parse_url($site_url);
  4456. if ($parse_url && !empty($parse_url['host'])) {
  4457. return $parse_url['host'];
  4458. }
  4459. return $_SERVER['HTTP_HOST'];
  4460. }
  4461. /**
  4462. * Checks COOKIE_DOMAIN definition existence
  4463. *
  4464. * @param string $content
  4465. * @return int
  4466. */
  4467. function is_cookie_domain_define($content) {
  4468. return preg_match(W3TC_PLUGIN_TOTALCACHE_REGEXP_COOKIEDOMAIN, $content);
  4469. }
  4470. /**
  4471. * Checks if COOKIE_DOMAIN is enabled
  4472. *
  4473. * @return bool
  4474. */
  4475. function is_cookie_domain_enabled() {
  4476. $cookie_domain = $this->get_cookie_domain();
  4477. return (defined('COOKIE_DOMAIN') && COOKIE_DOMAIN == $cookie_domain);
  4478. }
  4479. /**
  4480. * Enables COOKIE_DOMAIN
  4481. *
  4482. * @return bool
  4483. */
  4484. function enable_cookie_domain() {
  4485. $config_path = w3_get_wp_config_path();
  4486. $config_data = @file_get_contents($config_path);
  4487. if ($config_data === false) {
  4488. return false;
  4489. }
  4490. $cookie_domain = $this->get_cookie_domain();
  4491. if ($this->is_cookie_domain_define($config_data)) {
  4492. $new_config_data = preg_replace(W3TC_PLUGIN_TOTALCACHE_REGEXP_COOKIEDOMAIN, "define('COOKIE_DOMAIN', '" . addslashes($cookie_domain) . "')", $config_data, 1);
  4493. } else {
  4494. $new_config_data = preg_replace('~<\?(php)?~', "\\0\r\ndefine('COOKIE_DOMAIN', '" . addslashes($cookie_domain) . "'); // Added by W3 Total Cache\r\n", $config_data, 1);
  4495. }
  4496. if ($new_config_data != $config_data) {
  4497. if (!@file_put_contents($config_path, $new_config_data)) {
  4498. return false;
  4499. }
  4500. }
  4501. return true;
  4502. }
  4503. /**
  4504. * Disables COOKIE_DOMAIN
  4505. *
  4506. * @return bool
  4507. */
  4508. function disable_cookie_domain() {
  4509. $config_path = w3_get_wp_config_path();
  4510. $config_data = @file_get_contents($config_path);
  4511. if ($config_data === false) {
  4512. return false;
  4513. }
  4514. if ($this->is_cookie_domain_define($config_data)) {
  4515. $new_config_data = preg_replace(W3TC_PLUGIN_TOTALCACHE_REGEXP_COOKIEDOMAIN, "define('COOKIE_DOMAIN', false)", $config_data, 1);
  4516. if ($new_config_data != $config_data) {
  4517. if (!@file_put_contents($config_path, $new_config_data)) {
  4518. return false;
  4519. }
  4520. }
  4521. }
  4522. return true;
  4523. }
  4524. /**
  4525. * Uploads minify files to CDN
  4526. *
  4527. * @return void
  4528. */
  4529. function cdn_upload_minify() {
  4530. $w3_plugin_cdn = & w3_instance('W3_Plugin_Cdn');
  4531. $w3_plugin_cdncommon = & w3_instance('W3_Plugin_CdnCommon');
  4532. $files = $w3_plugin_cdn->get_files_minify();
  4533. $document_root = w3_get_document_root();
  4534. $upload = array();
  4535. $results = array();
  4536. foreach ($files as $file) {
  4537. $upload[$document_root . '/' . $file] = $file;
  4538. }
  4539. $w3_plugin_cdncommon->upload($upload, true, $results);
  4540. }
  4541. /**
  4542. * Uploads Browser Cache .htaccess to FTP
  4543. *
  4544. * @return void
  4545. */
  4546. function cdn_upload_browsercache() {
  4547. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnCommon');
  4548. $w3_plugin_browsercache = & w3_instance('W3_Plugin_BrowserCacheAdmin');
  4549. $rules = $w3_plugin_browsercache->generate_rules_cache(true);
  4550. $cdn_path = w3_get_cdn_rules_path();
  4551. $tmp_path = W3TC_TMP_DIR . '/' . $cdn_path;
  4552. if (@file_put_contents($tmp_path, $rules)) {
  4553. $results = array();
  4554. $upload = array(
  4555. $tmp_path => $cdn_path
  4556. );
  4557. $w3_plugin_cdn->upload($upload, true, $results);
  4558. }
  4559. }
  4560. /**
  4561. * Deletes Browser Cache .htaccess from FTP
  4562. *
  4563. * @return void
  4564. */
  4565. function cdn_delete_browsercache() {
  4566. $w3_plugin_cdn = & w3_instance('W3_Plugin_CdnCommon');
  4567. $cdn_path = w3_get_cdn_rules_path();
  4568. $tmp_path = W3TC_TMP_DIR . '/' . $cdn_path;
  4569. $results = array();
  4570. $delete = array(
  4571. $tmp_path => $cdn_path
  4572. );
  4573. $w3_plugin_cdn->delete($delete, false, $results);
  4574. }
  4575. /**
  4576. * Update plugin link
  4577. *
  4578. * @return void
  4579. */
  4580. function link_update() {
  4581. $this->link_delete();
  4582. $this->link_insert();
  4583. }
  4584. /**
  4585. * Insert plugin link into Blogroll
  4586. *
  4587. * @return void
  4588. */
  4589. function link_insert() {
  4590. $support = $this->_config->get_string('common.support');
  4591. $matches = null;
  4592. if ($support != '' && preg_match('~^link_category_(\d+)$~', $support, $matches)) {
  4593. require_once ABSPATH . 'wp-admin/includes/bookmark.php';
  4594. wp_insert_link(array(
  4595. 'link_url' => W3TC_LINK_URL,
  4596. 'link_name' => W3TC_LINK_NAME,
  4597. 'link_category' => array(
  4598. (int) $matches[1]
  4599. )
  4600. ));
  4601. }
  4602. }
  4603. /**
  4604. * Deletes plugin link from Blogroll
  4605. *
  4606. * @return void
  4607. */
  4608. function link_delete() {
  4609. $bookmarks = get_bookmarks();
  4610. $link_id = 0;
  4611. foreach ($bookmarks as $bookmark) {
  4612. if ($bookmark->link_url == W3TC_LINK_URL) {
  4613. $link_id = $bookmark->link_id;
  4614. break;
  4615. }
  4616. }
  4617. if ($link_id) {
  4618. require_once ABSPATH . 'wp-admin/includes/bookmark.php';
  4619. wp_delete_link($link_id);
  4620. }
  4621. }
  4622. /**
  4623. * PHPMailer init function
  4624. *
  4625. * @param PHPMailer $phpmailer
  4626. * @return void
  4627. */
  4628. function phpmailer_init(&$phpmailer) {
  4629. $phpmailer->Sender = $this->_phpmailer_sender;
  4630. }
  4631. /**
  4632. * Returns themes array
  4633. *
  4634. * @return array
  4635. */
  4636. function get_themes() {
  4637. $themes = array();
  4638. $wp_themes = get_themes();
  4639. foreach ($wp_themes as $wp_theme) {
  4640. $theme_key = w3_get_theme_key($wp_theme['Theme Root'], $wp_theme['Template'], $wp_theme['Stylesheet']);
  4641. $themes[$theme_key] = $wp_theme['Name'];
  4642. }
  4643. return $themes;
  4644. }
  4645. /**
  4646. * Returns server info
  4647. *
  4648. * @return array
  4649. */
  4650. function get_server_info() {
  4651. global $wp_version, $wp_db_version, $wpdb;
  4652. $wordpress_plugins = get_plugins();
  4653. $wordpress_plugins_active = array();
  4654. foreach ($wordpress_plugins as $wordpress_plugin_file => $wordpress_plugin) {
  4655. if (is_plugin_active($wordpress_plugin_file)) {
  4656. $wordpress_plugins_active[$wordpress_plugin_file] = $wordpress_plugin;
  4657. }
  4658. }
  4659. $mysql_version = $wpdb->get_var('SELECT VERSION()');
  4660. $mysql_variables_result = (array) $wpdb->get_results('SHOW VARIABLES', ARRAY_N);
  4661. $mysql_variables = array();
  4662. foreach ($mysql_variables_result as $mysql_variables_row) {
  4663. $mysql_variables[$mysql_variables_row[0]] = $mysql_variables_row[1];
  4664. }
  4665. $server_info = array(
  4666. 'w3tc' => array(
  4667. 'version' => W3TC_VERSION,
  4668. 'server' => (!empty($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'Unknown'),
  4669. 'dir' => W3TC_DIR,
  4670. 'content_dir' => W3TC_CONTENT_DIR,
  4671. 'blogname' => W3TC_BLOGNAME,
  4672. 'document_root' => w3_get_document_root(),
  4673. 'home_root' => w3_get_home_root(),
  4674. 'site_root' => w3_get_site_root(),
  4675. 'base_path' => w3_get_base_path(),
  4676. 'home_path' => w3_get_home_path(),
  4677. 'site_path' => w3_get_site_path()
  4678. ),
  4679. 'wp' => array(
  4680. 'version' => $wp_version,
  4681. 'db_version' => $wp_db_version,
  4682. 'abspath' => ABSPATH,
  4683. 'home' => get_option('home'),
  4684. 'siteurl' => get_option('siteurl'),
  4685. 'email' => get_option('admin_email'),
  4686. 'upload_info' => (array) w3_upload_info(),
  4687. 'theme' => get_theme(get_current_theme()),
  4688. 'wp_cache' => ((defined('WP_CACHE') && WP_CACHE) ? 'true' : 'false'),
  4689. 'plugins' => $wordpress_plugins_active
  4690. ),
  4691. 'mysql' => array(
  4692. 'version' => $mysql_version,
  4693. 'variables' => $mysql_variables
  4694. )
  4695. );
  4696. return $server_info;
  4697. }
  4698. /**
  4699. * Returns list of support types
  4700. *
  4701. * @return array
  4702. */
  4703. function get_supports() {
  4704. $supports = array(
  4705. 'footer' => 'page footer'
  4706. );
  4707. $link_categories = get_terms('link_category', array(
  4708. 'hide_empty' => 0
  4709. ));
  4710. foreach ($link_categories as $link_category) {
  4711. $supports['link_category_' . $link_category->term_id] = strtolower($link_category->name);
  4712. }
  4713. return $supports;
  4714. }
  4715. /**
  4716. * Returns true if upload queue is empty
  4717. *
  4718. * @return boolean
  4719. */
  4720. function is_queue_empty() {
  4721. global $wpdb;
  4722. $sql = sprintf('SELECT COUNT(*) FROM %s', $wpdb->prefix . W3TC_CDN_TABLE_QUEUE);
  4723. $result = $wpdb->get_var($sql);
  4724. return ($result == 0);
  4725. }
  4726. /**
  4727. * Redirect function
  4728. *
  4729. * @param array $params
  4730. * @param boolean $check_referrer
  4731. * @return void
  4732. */
  4733. function redirect($params = array(), $check_referrer = false) {
  4734. require_once W3TC_LIB_W3_DIR . '/Request.php';
  4735. $url = W3_Request::get_string('redirect');
  4736. if ($url == '') {
  4737. if ($check_referrer && !empty($_SERVER['HTTP_REFERER'])) {
  4738. $url = $_SERVER['HTTP_REFERER'];
  4739. } else {
  4740. $url = 'admin.php';
  4741. $params = array_merge(array(
  4742. 'page' => $this->_page
  4743. ), $params);
  4744. }
  4745. }
  4746. w3_redirect($url, $params);
  4747. }
  4748. /**
  4749. * Parses FAQ XML file into array
  4750. *
  4751. * @return array
  4752. */
  4753. function parse_faq() {
  4754. $faq = array();
  4755. $file = W3TC_INC_DIR . '/options/faq.xml';
  4756. $xml = @file_get_contents($file);
  4757. if ($xml) {
  4758. if (function_exists('xml_parser_create')) {
  4759. $parser = @xml_parser_create('UTF-8');
  4760. xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
  4761. xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
  4762. xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
  4763. $values = null;
  4764. $result = xml_parse_into_struct($parser, $xml, $values);
  4765. xml_parser_free($parser);
  4766. if ($result) {
  4767. $index = 0;
  4768. $current_section = '';
  4769. $current_entry = array();
  4770. foreach ($values as $value) {
  4771. switch ($value['type']) {
  4772. case 'open':
  4773. if ($value['tag'] === 'section') {
  4774. $current_section = $value['attributes']['name'];
  4775. }
  4776. break;
  4777. case 'complete':
  4778. switch ($value['tag']) {
  4779. case 'question':
  4780. $current_entry['question'] = $value['value'];
  4781. break;
  4782. case 'answer':
  4783. $current_entry['answer'] = $value['value'];
  4784. break;
  4785. }
  4786. break;
  4787. case 'close':
  4788. if ($value['tag'] == 'entry') {
  4789. $current_entry['index'] = ++$index;
  4790. $faq[$current_section][] = $current_entry;
  4791. }
  4792. break;
  4793. }
  4794. }
  4795. }
  4796. }
  4797. }
  4798. return $faq;
  4799. }
  4800. /**
  4801. * Read CloudFlare settings
  4802. *
  4803. * @param string $seclvl
  4804. * @param integer $devmode
  4805. * @return bool
  4806. */
  4807. function cloudflare_read(&$seclvl, &$devmode) {
  4808. $config = array(
  4809. 'email' => $this->_config->get_string('cloudflare.email'),
  4810. 'key' => $this->_config->get_string('cloudflare.key'),
  4811. 'zone' => $this->_config->get_string('cloudflare.zone')
  4812. );
  4813. require_once W3TC_LIB_W3_DIR . '/CloudFlare.php';
  4814. @$w3_cloudflare =& new W3_CloudFlare($config);
  4815. $response = $w3_cloudflare->api_request('stats');
  4816. if ($response && $response->result == 'success' && isset($response->response->result->objs[0])) {
  4817. switch ($response->response->result->objs[0]->userSecuritySetting) {
  4818. case 'High';
  4819. $seclvl = 'high';
  4820. break;
  4821. case 'Medium';
  4822. $seclvl = 'med';
  4823. break;
  4824. case 'Low';
  4825. $seclvl = 'low';
  4826. break;
  4827. }
  4828. $devmode = ($response->response->result->objs[0]->dev_mode >= time() ? $response->response->result->objs[0]->dev_mode : 0);
  4829. return true;
  4830. }
  4831. return false;
  4832. }
  4833. }