PageRenderTime 91ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 1ms

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

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