Cache Enabler – WordPress Cache - Version 1.1.0

Version Description

  • Added the possibility to clear the cache of a specific URL
  • Supports now Windows filesystems
  • Added X-Cache-Handler to indicate if loaded through PHP
  • Support of WebP images generated by ewww
  • Dynamic upload directory for WebP images
  • Fixed multisite purge issue
  • Added requirements checks
  • Made plugin ready for translation
Download this release

Release Info

Developer keycdn
Plugin Icon 128x128 Cache Enabler – WordPress Cache
Version 1.1.0
Comparing to
See all releases

Code changes from version 1.0.9 to 1.1.0

cache-enabler.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php
2
  /*
3
  Plugin Name: Cache Enabler
4
- Text Domain: cache
5
  Description: Simple and fast WordPress disk caching plugin.
6
  Author: KeyCDN
7
  Author URI: https://www.keycdn.com
8
  License: GPLv2 or later
9
- Version: 1.0.9
10
  */
11
 
12
  /*
@@ -38,7 +38,7 @@ define('CE_FILE', __FILE__);
38
  define('CE_DIR', dirname(__FILE__));
39
  define('CE_BASE', plugin_basename(__FILE__));
40
  define('CE_CACHE_DIR', WP_CONTENT_DIR. '/cache/cache-enabler');
41
-
42
 
43
  // hooks
44
  add_action(
1
  <?php
2
  /*
3
  Plugin Name: Cache Enabler
4
+ Text Domain: cache-enabler
5
  Description: Simple and fast WordPress disk caching plugin.
6
  Author: KeyCDN
7
  Author URI: https://www.keycdn.com
8
  License: GPLv2 or later
9
+ Version: 1.1.0
10
  */
11
 
12
  /*
38
  define('CE_DIR', dirname(__FILE__));
39
  define('CE_BASE', plugin_basename(__FILE__));
40
  define('CE_CACHE_DIR', WP_CONTENT_DIR. '/cache/cache-enabler');
41
+ define('CE_MIN_WP', '4.1');
42
 
43
  // hooks
44
  add_action(
inc/cache_enabler.class.php CHANGED
@@ -120,6 +120,13 @@ final class Cache_Enabler {
120
  'clear_total_cache'
121
  )
122
  );
 
 
 
 
 
 
 
123
 
124
  // add admin clear link
125
  add_action(
@@ -216,7 +223,6 @@ final class Cache_Enabler {
216
  'add_clear_dropdown'
217
  )
218
  );
219
-
220
  add_filter(
221
  'plugin_row_meta',
222
  array(
@@ -242,6 +248,13 @@ final class Cache_Enabler {
242
  'warning_is_permalink'
243
  )
244
  );
 
 
 
 
 
 
 
245
 
246
  // caching
247
  } else {
@@ -464,7 +477,7 @@ final class Cache_Enabler {
464
  * get options
465
  *
466
  * @since 1.0.0
467
- * @change 1.0.9
468
  *
469
  * @return array options array
470
  */
@@ -477,7 +490,7 @@ final class Cache_Enabler {
477
  'expires' => 0,
478
  'new_post' => 0,
479
  'new_comment' => 0,
480
- 'compress' => 1,
481
  'webp' => 0,
482
  'excl_ids' => '',
483
  'minify_html' => self::MINIFY_DISABLED,
@@ -500,7 +513,7 @@ final class Cache_Enabler {
500
  if ( !Cache_Enabler_Disk::is_permalink() AND current_user_can('manage_options') ) { ?>
501
 
502
  <div class="error">
503
- <p><?php printf( __('The <b>%s</b> plugin requires a custom permalink structure to start caching properly. Please go to <a href="%s">Permalink</a> to enable it.', 'cache'), 'Cache Enabler', admin_url( 'options-permalink.php' ) ); ?></p>
504
  </div>
505
 
506
  <?php
@@ -536,7 +549,7 @@ final class Cache_Enabler {
536
  ),
537
  admin_url('options-general.php')
538
  ),
539
- __('Settings')
540
  )
541
  )
542
  );
@@ -574,7 +587,7 @@ final class Cache_Enabler {
574
  * add dashboard cache size count
575
  *
576
  * @since 1.0.0
577
- * @change 1.0.0
578
  *
579
  * @param array $items initial array with dashboard items
580
  * @return array $items merged array with dashboard items
@@ -592,14 +605,16 @@ final class Cache_Enabler {
592
 
593
  // display items
594
  $items[] = sprintf(
595
- '<a href="%s" title="Disk Cache">%s Cache Size</a>',
596
  add_query_arg(
597
  array(
598
  'page' => 'cache-enabler'
599
  ),
600
  admin_url('options-general.php')
601
  ),
602
- ( empty($size) ? esc_html__('Empty', 'cache') : size_format($size) )
 
 
603
  );
604
 
605
  return $items;
@@ -637,7 +652,7 @@ final class Cache_Enabler {
637
  * add admin links
638
  *
639
  * @since 1.0.0
640
- * @change 1.0.1
641
  *
642
  * @hook mixed
643
  *
@@ -657,11 +672,23 @@ final class Cache_Enabler {
657
  'id' => 'clear-cache',
658
  'href' => wp_nonce_url( add_query_arg('_cache', 'clear'), '_cache__clear_nonce'),
659
  'parent' => 'top-secondary',
660
- 'title' => '<span class="ab-item">Clear Cache</span>',
661
- 'meta' => array( 'title' => esc_html__('clear Cache', 'cache') )
662
  )
663
  );
664
 
 
 
 
 
 
 
 
 
 
 
 
 
665
  }
666
 
667
 
@@ -669,7 +696,7 @@ final class Cache_Enabler {
669
  * process clear request
670
  *
671
  * @since 1.0.0
672
- * @change 1.0.0
673
  *
674
  * @param array $data array of metadata
675
  */
@@ -677,7 +704,7 @@ final class Cache_Enabler {
677
  public static function process_clear_request($data) {
678
 
679
  // check if clear request
680
- if ( empty($_GET['_cache']) OR $_GET['_cache'] !== 'clear' ) {
681
  return;
682
  }
683
 
@@ -696,47 +723,77 @@ final class Cache_Enabler {
696
  require_once( ABSPATH. 'wp-admin/includes/plugin.php' );
697
  }
698
 
 
 
 
699
  // multisite and network setup
700
  if ( is_multisite() && is_plugin_active_for_network(CE_BASE) ) {
701
 
702
- // legacy blog
703
- $legacy = $GLOBALS['wpdb']->blogid;
704
 
705
- // blog ids
706
- $ids = self::_get_blog_ids();
707
 
708
- // switch blogs
709
- foreach ($ids as $id) {
710
- switch_to_blog($id);
711
- self::clear_total_cache();
712
- }
713
 
714
- // restore
715
- switch_to_blog($legacy);
716
-
717
- // clear notice
718
- if ( is_admin() ) {
719
- add_action(
720
- 'network_admin_notices',
721
- array(
722
- __CLASS__,
723
- 'clear_notice'
724
- )
725
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
726
  }
727
  } else {
728
- // clear cache
729
- self::clear_total_cache();
 
 
 
 
730
 
731
- // clear notice
732
- if ( is_admin() ) {
733
- add_action(
734
- 'admin_notices',
735
- array(
736
- __CLASS__,
737
- 'clear_notice'
738
- )
739
- );
 
740
  }
741
  }
742
 
@@ -771,7 +828,7 @@ final class Cache_Enabler {
771
 
772
  echo sprintf(
773
  '<div class="notice notice-success is-dismissible"><p>%s</p></div>',
774
- esc_html__('The cache has been deleted.', 'cache')
775
  );
776
  }
777
 
@@ -1357,8 +1414,8 @@ final class Cache_Enabler {
1357
  // init variables
1358
  $dropdown_options = '';
1359
  $available_options = array(
1360
- esc_html__('Completely', 'cache'),
1361
- esc_html__('Page specific', 'cache')
1362
  );
1363
 
1364
  // set dropdown options
@@ -1388,7 +1445,7 @@ final class Cache_Enabler {
1388
  <a href="#" class="cancel-cache-action hide-if-no-js button-cancel">%6$s</a>
1389
  </div>
1390
  </div>',
1391
- esc_html__('Clear cache', 'cache'),
1392
  $available_options[$current_action],
1393
  esc_html__('Edit'),
1394
  $dropdown_options,
@@ -1468,13 +1525,72 @@ final class Cache_Enabler {
1468
  private static function _minify_select() {
1469
 
1470
  return array(
1471
- self::MINIFY_DISABLED => esc_html__('Disabled', 'cache'),
1472
- self::MINIFY_HTML_ONLY => 'HTML',
1473
- self::MINIFY_HTML_JS => 'HTML & Inline JS'
1474
  );
1475
  }
1476
 
1477
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1478
  /**
1479
  * register textdomain
1480
  *
@@ -1485,7 +1601,7 @@ final class Cache_Enabler {
1485
  public static function register_textdomain() {
1486
 
1487
  load_plugin_textdomain(
1488
- 'cache',
1489
  false,
1490
  'cache-enabler/lang'
1491
  );
@@ -1548,18 +1664,21 @@ final class Cache_Enabler {
1548
  * settings page
1549
  *
1550
  * @since 1.0.0
1551
- * @change 1.0.9
1552
  */
1553
 
1554
  public static function settings_page() { ?>
1555
 
1556
  <div class="wrap" id="cache-settings">
1557
  <h2>
1558
- <?php _e("Cache Enabler Settings", "cache") ?>
1559
  </h2>
1560
 
1561
- <p><?php $size=self::get_cache_size(); printf( __("Current cache size: <b>%s</b>", "cache"), ( empty($size) ? esc_html__("Empty", "cache") : size_format($size) ) ); ?></p>
 
 
1562
 
 
1563
 
1564
  <form method="post" action="options.php">
1565
  <?php settings_fields('cache-enabler') ?>
@@ -1569,47 +1688,47 @@ final class Cache_Enabler {
1569
  <table class="form-table">
1570
  <tr valign="top">
1571
  <th scope="row">
1572
- <?php _e("Cache Expiry", "cache") ?>
1573
  </th>
1574
  <td>
1575
  <fieldset>
1576
  <label for="cache_expires">
1577
  <input type="text" name="cache[expires]" id="cache_expires" value="<?php echo esc_attr($options['expires']) ?>" />
1578
- <p class="description"><?php _e("Cache expiry in hours. An expiry time of 0 means that the cache never expires.", "cache"); ?></p>
1579
  </label>
1580
  </fieldset>
1581
  </td>
1582
  </tr>
1583
  <tr valign="top">
1584
  <th scope="row">
1585
- <?php _e("Cache Behavior", "cache") ?>
1586
  </th>
1587
  <td>
1588
  <fieldset>
1589
  <label for="cache_new_post">
1590
  <input type="checkbox" name="cache[new_post]" id="cache_new_post" value="1" <?php checked('1', $options['new_post']); ?> />
1591
- <?php _e("Clear the complete cache if a new post has been published (instead of only the home page cache).", "cache") ?>
1592
  </label>
1593
 
1594
  <br />
1595
 
1596
  <label for="cache_new_comment">
1597
  <input type="checkbox" name="cache[new_comment]" id="cache_new_comment" value="1" <?php checked('1', $options['new_comment']); ?> />
1598
- <?php _e("Clear the complete cache if a new comment has been posted (instead of only the page specific cache).", "cache") ?>
1599
  </label>
1600
 
1601
  <br />
1602
 
1603
  <label for="cache_compress">
1604
  <input type="checkbox" name="cache[compress]" id="cache_compress" value="1" <?php checked('1', $options['compress']); ?> />
1605
- <?php _e("Pre-compression of cached pages. Needs to be disabled if the decoding fails in the web browser.", "cache") ?>
1606
  </label>
1607
 
1608
  <br />
1609
 
1610
  <label for="cache_webp">
1611
  <input type="checkbox" name="cache[webp]" id="cache_webp" value="1" <?php checked('1', $options['webp']); ?> />
1612
- <?php _e("Create an additional cached version for WebP image support. Convert your images to WebP with <a href=\"https://optimus.io/en/\" target=\"_blank\">Optimus</a>.", "cache") ?>
1613
  </label>
1614
  </fieldset>
1615
  </td>
@@ -1617,13 +1736,13 @@ final class Cache_Enabler {
1617
 
1618
  <tr valign="top">
1619
  <th scope="row">
1620
- <?php _e("Cache Exclusions", "cache") ?>
1621
  </th>
1622
  <td>
1623
  <fieldset>
1624
  <label for="cache_excl_ids">
1625
  <input type="text" name="cache[excl_ids]" id="cache_excl_ids" value="<?php echo esc_attr($options['excl_ids']) ?>" />
1626
- <p class="description"><?php _e("Post or Pages IDs separated by a <code>,</code> that should not be cached.", "cache"); ?></p>
1627
  </label>
1628
  </fieldset>
1629
  </td>
@@ -1631,7 +1750,7 @@ final class Cache_Enabler {
1631
 
1632
  <tr valign="top">
1633
  <th scope="row">
1634
- <?php _e("Cache Minification", "cache") ?>
1635
  </th>
1636
  <td>
1637
  <label for="cache_minify_html">
@@ -1651,13 +1770,12 @@ final class Cache_Enabler {
1651
  <?php submit_button() ?>
1652
  </th>
1653
  <td>
1654
- <p class="description"><?php _e("Saving these settings will clear the complete cache.","cache") ?></p>
1655
  </td>
1656
  </tr>
1657
  </table>
1658
  </form>
1659
- <p class="description"><?php _e("It is recommended to enable HTTP/2 on your origin server and use a CDN that supports HTTP/2. Avoid domain sharding and concatenation of your assets to benefit from parallelism of HTTP/2.","cache") ?></p>
1660
-
1661
  </div><?php
1662
  }
1663
  }
120
  'clear_total_cache'
121
  )
122
  );
123
+ add_action(
124
+ 'autoptimize_action_cachepurged',
125
+ array(
126
+ __CLASS__,
127
+ 'clear_total_cache'
128
+ )
129
+ );
130
 
131
  // add admin clear link
132
  add_action(
223
  'add_clear_dropdown'
224
  )
225
  );
 
226
  add_filter(
227
  'plugin_row_meta',
228
  array(
248
  'warning_is_permalink'
249
  )
250
  );
251
+ add_action(
252
+ 'admin_notices',
253
+ array(
254
+ __CLASS__,
255
+ 'requirements_check'
256
+ )
257
+ );
258
 
259
  // caching
260
  } else {
477
  * get options
478
  *
479
  * @since 1.0.0
480
+ * @change 1.1.0
481
  *
482
  * @return array options array
483
  */
490
  'expires' => 0,
491
  'new_post' => 0,
492
  'new_comment' => 0,
493
+ 'compress' => 0,
494
  'webp' => 0,
495
  'excl_ids' => '',
496
  'minify_html' => self::MINIFY_DISABLED,
513
  if ( !Cache_Enabler_Disk::is_permalink() AND current_user_can('manage_options') ) { ?>
514
 
515
  <div class="error">
516
+ <p><?php printf( __('The <b>%s</b> plugin requires a custom permalink structure to start caching properly. Please go to <a href="%s">Permalink</a> to enable it.', 'cache-enabler'), 'Cache Enabler', admin_url( 'options-permalink.php' ) ); ?></p>
517
  </div>
518
 
519
  <?php
549
  ),
550
  admin_url('options-general.php')
551
  ),
552
+ esc_html__('Settings')
553
  )
554
  )
555
  );
587
  * add dashboard cache size count
588
  *
589
  * @since 1.0.0
590
+ * @change 1.1.0
591
  *
592
  * @param array $items initial array with dashboard items
593
  * @return array $items merged array with dashboard items
605
 
606
  // display items
607
  $items[] = sprintf(
608
+ '<a href="%s" title="%s">%s %s</a>',
609
  add_query_arg(
610
  array(
611
  'page' => 'cache-enabler'
612
  ),
613
  admin_url('options-general.php')
614
  ),
615
+ esc_html__('Disk Cache', 'cache-enabler'),
616
+ ( empty($size) ? esc_html__('Empty', 'cache-enabler') : size_format($size) ),
617
+ esc_html__('Cache Size', 'cache-enabler')
618
  );
619
 
620
  return $items;
652
  * add admin links
653
  *
654
  * @since 1.0.0
655
+ * @change 1.1.0
656
  *
657
  * @hook mixed
658
  *
672
  'id' => 'clear-cache',
673
  'href' => wp_nonce_url( add_query_arg('_cache', 'clear'), '_cache__clear_nonce'),
674
  'parent' => 'top-secondary',
675
+ 'title' => '<span class="ab-item">'.esc_html__('Clear Cache', 'cache-enabler').'</span>',
676
+ 'meta' => array( 'title' => esc_html__('Clear Cache', 'cache-enabler') )
677
  )
678
  );
679
 
680
+ if ( ! is_admin() ) {
681
+ // add admin purge link
682
+ $wp_admin_bar->add_menu(
683
+ array(
684
+ 'id' => 'clear-url-cache',
685
+ 'href' => wp_nonce_url( add_query_arg('_cache', 'clearurl'), '_cache__clear_nonce'),
686
+ 'parent' => 'top-secondary',
687
+ 'title' => '<span class="ab-item">'.esc_html__('Clear URL Cache', 'cache-enabler').'</span>',
688
+ 'meta' => array( 'title' => esc_html__('Clear URL Cache', 'cache-enabler') )
689
+ )
690
+ );
691
+ }
692
  }
693
 
694
 
696
  * process clear request
697
  *
698
  * @since 1.0.0
699
+ * @change 1.1.0
700
  *
701
  * @param array $data array of metadata
702
  */
704
  public static function process_clear_request($data) {
705
 
706
  // check if clear request
707
+ if ( empty($_GET['_cache']) OR ( $_GET['_cache'] !== 'clear' && $_GET['_cache'] !== 'clearurl' ) ) {
708
  return;
709
  }
710
 
723
  require_once( ABSPATH. 'wp-admin/includes/plugin.php' );
724
  }
725
 
726
+ // set clear url w/o query string
727
+ $clear_url = preg_replace('/\?.*/', '', home_url( add_query_arg( NULL, NULL ) ));
728
+
729
  // multisite and network setup
730
  if ( is_multisite() && is_plugin_active_for_network(CE_BASE) ) {
731
 
732
+ if ( is_network_admin() ) {
 
733
 
734
+ // legacy blog
735
+ $legacy = $GLOBALS['wpdb']->blogid;
736
 
737
+ // blog ids
738
+ $ids = self::_get_blog_ids();
 
 
 
739
 
740
+ // switch blogs
741
+ foreach ($ids as $id) {
742
+ switch_to_blog($id);
743
+ self::clear_page_cache_by_url(home_url());
744
+ }
745
+
746
+ // restore
747
+ switch_to_blog($legacy);
748
+
749
+ // clear notice
750
+ if ( is_admin() ) {
751
+ add_action(
752
+ 'network_admin_notices',
753
+ array(
754
+ __CLASS__,
755
+ 'clear_notice'
756
+ )
757
+ );
758
+ }
759
+ } else {
760
+ if ($_GET['_cache'] == 'clearurl') {
761
+ // clear specific multisite url cache
762
+ self::clear_page_cache_by_url($clear_url);
763
+ } else {
764
+ // clear specific multisite cache
765
+ self::clear_page_cache_by_url(home_url());
766
+
767
+ // clear notice
768
+ if ( is_admin() ) {
769
+ add_action(
770
+ 'admin_notices',
771
+ array(
772
+ __CLASS__,
773
+ 'clear_notice'
774
+ )
775
+ );
776
+ }
777
+ }
778
  }
779
  } else {
780
+ if ($_GET['_cache'] == 'clearurl') {
781
+ // clear url cache
782
+ self::clear_page_cache_by_url($clear_url);
783
+ } else {
784
+ // clear cache
785
+ self::clear_total_cache();
786
 
787
+ // clear notice
788
+ if ( is_admin() ) {
789
+ add_action(
790
+ 'admin_notices',
791
+ array(
792
+ __CLASS__,
793
+ 'clear_notice'
794
+ )
795
+ );
796
+ }
797
  }
798
  }
799
 
828
 
829
  echo sprintf(
830
  '<div class="notice notice-success is-dismissible"><p>%s</p></div>',
831
+ esc_html__('The cache has been cleared.', 'cache-enabler')
832
  );
833
  }
834
 
1414
  // init variables
1415
  $dropdown_options = '';
1416
  $available_options = array(
1417
+ esc_html__('Completely', 'cache-enabler'),
1418
+ esc_html__('Page specific', 'cache-enabler')
1419
  );
1420
 
1421
  // set dropdown options
1445
  <a href="#" class="cancel-cache-action hide-if-no-js button-cancel">%6$s</a>
1446
  </div>
1447
  </div>',
1448
+ esc_html__('Clear cache', 'cache-enabler'),
1449
  $available_options[$current_action],
1450
  esc_html__('Edit'),
1451
  $dropdown_options,
1525
  private static function _minify_select() {
1526
 
1527
  return array(
1528
+ self::MINIFY_DISABLED => esc_html__('Disabled', 'cache-enabler'),
1529
+ self::MINIFY_HTML_ONLY => esc_html__('HTML', 'cache-enabler'),
1530
+ self::MINIFY_HTML_JS => esc_html__('HTML & Inline JS', 'cache-enabler')
1531
  );
1532
  }
1533
 
1534
 
1535
+ /**
1536
+ * Check plugin requirements
1537
+ *
1538
+ * @since 1.1.0
1539
+ * @change 1.1.0
1540
+ */
1541
+
1542
+ public static function requirements_check() {
1543
+
1544
+ // cache enabler options
1545
+ $options = self::$options;
1546
+
1547
+ // WordPress version check
1548
+ if ( version_compare($GLOBALS['wp_version'], CE_MIN_WP.'alpha', '<') ) {
1549
+ show_message(
1550
+ sprintf(
1551
+ '<div class="error"><p>%s</p></div>',
1552
+ sprintf(
1553
+ __('The <b>%s</b> is optimized for WordPress %s. Please disable the plugin or upgrade your WordPress installation (recommended).', 'cache-enabler'),
1554
+ 'Cache Enabler',
1555
+ CE_MIN_WP
1556
+ )
1557
+ )
1558
+ );
1559
+ }
1560
+
1561
+ // permission check
1562
+ if ( file_exists( CE_CACHE_DIR ) && !is_writable( CE_CACHE_DIR ) ) {
1563
+ show_message(
1564
+ sprintf(
1565
+ '<div class="error"><p>%s</p></div>',
1566
+ sprintf(
1567
+ __('The <b>%s</b> requires write permissions %s on %s. Please <a href="%s" target="_blank">change the permissions</a>.', 'cache-enabler'),
1568
+ 'Cache Enabler',
1569
+ '<code>755</code>',
1570
+ '<code>wp-content/cache</code>',
1571
+ 'http://codex.wordpress.org/Changing_File_Permissions',
1572
+ CE_MIN_WP
1573
+ )
1574
+ )
1575
+ );
1576
+ }
1577
+
1578
+ // mb string check
1579
+ if ( !function_exists('mb_convert_encoding') && $options['webp'] ) {
1580
+ show_message(
1581
+ sprintf(
1582
+ '<div class="error"><p>%s</p></div>',
1583
+ sprintf(
1584
+ __('The <b>%s</b> WebP option requires the <a href="%s" target="_blank">PHP Multibyte String Library (php-mbstring)</a>. Please contact your hosting provider to get <b>php-mbstring</b> installed.', 'cache-enabler'),
1585
+ 'Cache Enabler',
1586
+ 'http://php.net/manual/en/book.mbstring.php'
1587
+ )
1588
+ )
1589
+ );
1590
+ }
1591
+ }
1592
+
1593
+
1594
  /**
1595
  * register textdomain
1596
  *
1601
  public static function register_textdomain() {
1602
 
1603
  load_plugin_textdomain(
1604
+ 'cache-enabler',
1605
  false,
1606
  'cache-enabler/lang'
1607
  );
1664
  * settings page
1665
  *
1666
  * @since 1.0.0
1667
+ * @change 1.1.0
1668
  */
1669
 
1670
  public static function settings_page() { ?>
1671
 
1672
  <div class="wrap" id="cache-settings">
1673
  <h2>
1674
+ <?php _e("Cache Enabler Settings", "cache-enabler") ?>
1675
  </h2>
1676
 
1677
+ <div class="notice notice-info" style="margin-bottom: 35px;">
1678
+ <p><?php printf( __('Combine <b><a href="%s">%s</a></b> with Cache Enabler for even better WordPress performance and achieve the next level of caching with a CDN.', 'cache-enabler'), 'https://www.keycdn.com?utm_source=wp-admin&utm_medium=plugins&utm_campaign=cache-enabler', 'KeyCDN'); ?></p>
1679
+ </div>
1680
 
1681
+ <p><?php $size=self::get_cache_size(); printf( __("Current cache size: <b>%s</b>", "cache-enabler"), ( empty($size) ? esc_html__("Empty", "cache-enabler") : size_format($size) ) ); ?></p>
1682
 
1683
  <form method="post" action="options.php">
1684
  <?php settings_fields('cache-enabler') ?>
1688
  <table class="form-table">
1689
  <tr valign="top">
1690
  <th scope="row">
1691
+ <?php _e("Cache Expiry", "cache-enabler") ?>
1692
  </th>
1693
  <td>
1694
  <fieldset>
1695
  <label for="cache_expires">
1696
  <input type="text" name="cache[expires]" id="cache_expires" value="<?php echo esc_attr($options['expires']) ?>" />
1697
+ <p class="description"><?php _e("Cache expiry in hours. An expiry time of 0 means that the cache never expires.", "cache-enabler"); ?></p>
1698
  </label>
1699
  </fieldset>
1700
  </td>
1701
  </tr>
1702
  <tr valign="top">
1703
  <th scope="row">
1704
+ <?php _e("Cache Behavior", "cache-enabler") ?>
1705
  </th>
1706
  <td>
1707
  <fieldset>
1708
  <label for="cache_new_post">
1709
  <input type="checkbox" name="cache[new_post]" id="cache_new_post" value="1" <?php checked('1', $options['new_post']); ?> />
1710
+ <?php _e("Clear the complete cache if a new post has been published (instead of only the home page cache).", "cache-enabler") ?>
1711
  </label>
1712
 
1713
  <br />
1714
 
1715
  <label for="cache_new_comment">
1716
  <input type="checkbox" name="cache[new_comment]" id="cache_new_comment" value="1" <?php checked('1', $options['new_comment']); ?> />
1717
+ <?php _e("Clear the complete cache if a new comment has been posted (instead of only the page specific cache).", "cache-enabler") ?>
1718
  </label>
1719
 
1720
  <br />
1721
 
1722
  <label for="cache_compress">
1723
  <input type="checkbox" name="cache[compress]" id="cache_compress" value="1" <?php checked('1', $options['compress']); ?> />
1724
+ <?php _e("Pre-compression of cached pages. Needs to be disabled if the decoding fails in the web browser.", "cache-enabler") ?>
1725
  </label>
1726
 
1727
  <br />
1728
 
1729
  <label for="cache_webp">
1730
  <input type="checkbox" name="cache[webp]" id="cache_webp" value="1" <?php checked('1', $options['webp']); ?> />
1731
+ <?php _e("Create an additional cached version for WebP image support. Convert your images to WebP with <a href=\"https://optimus.io/en/\" target=\"_blank\">Optimus</a>.", "cache-enabler") ?>
1732
  </label>
1733
  </fieldset>
1734
  </td>
1736
 
1737
  <tr valign="top">
1738
  <th scope="row">
1739
+ <?php _e("Cache Exclusions", "cache-enabler") ?>
1740
  </th>
1741
  <td>
1742
  <fieldset>
1743
  <label for="cache_excl_ids">
1744
  <input type="text" name="cache[excl_ids]" id="cache_excl_ids" value="<?php echo esc_attr($options['excl_ids']) ?>" />
1745
+ <p class="description"><?php _e("Post or Pages IDs separated by a <code>,</code> that should not be cached.", "cache-enabler"); ?></p>
1746
  </label>
1747
  </fieldset>
1748
  </td>
1750
 
1751
  <tr valign="top">
1752
  <th scope="row">
1753
+ <?php _e("Cache Minification", "cache-enabler") ?>
1754
  </th>
1755
  <td>
1756
  <label for="cache_minify_html">
1770
  <?php submit_button() ?>
1771
  </th>
1772
  <td>
1773
+ <p class="description"><?php _e("Saving these settings will clear the complete cache.", "cache-enabler") ?></p>
1774
  </td>
1775
  </tr>
1776
  </table>
1777
  </form>
1778
+ <p class="description"><?php _e("It is recommended to enable HTTP/2 on your origin server and use a CDN that supports HTTP/2. Avoid domain sharding and concatenation of your assets to benefit from parallelism of HTTP/2.", "cache-enabler") ?></p>
 
1779
  </div><?php
1780
  }
1781
  }
inc/cache_enabler_disk.class.php CHANGED
@@ -184,6 +184,9 @@ final class Cache_Enabler_Disk {
184
 
185
  public static function get_asset() {
186
 
 
 
 
187
  // get if-modified request headers
188
  if ( function_exists( 'apache_request_headers' ) ) {
189
  $headers = apache_request_headers();
@@ -208,7 +211,7 @@ final class Cache_Enabler_Disk {
208
  header('Content-Encoding: gzip');
209
  readfile( self::_file_webp_gzip() );
210
  exit;
211
- } else {
212
  readfile( self::_file_webp_html() );
213
  exit;
214
  }
@@ -421,7 +424,7 @@ final class Cache_Enabler_Disk {
421
  * cache path
422
  *
423
  * @since 1.0.0
424
- * @change 1.0.0
425
  *
426
  * @param string $path uri or permlink
427
  * @return string $diff path to cached asset
@@ -443,7 +446,7 @@ final class Cache_Enabler_Disk {
443
  )
444
  );
445
 
446
- if ( validate_file($path) > 0 ) {
447
  wp_die('Path is not valid.');
448
  }
449
 
@@ -511,15 +514,18 @@ final class Cache_Enabler_Disk {
511
  * convert to webp
512
  *
513
  * @since 1.0.1
514
- * @change 1.0.8
515
  *
516
  * @return string converted HTML file
517
  */
518
 
519
  private static function _convert_webp($data) {
520
 
 
 
 
521
  $dom = new DOMDocument();
522
- @$dom->loadHTML(mb_convert_encoding($data, 'HTML-ENTITIES', 'UTF-8'));
523
 
524
  $imgs = $dom->getElementsByTagName("img");
525
 
@@ -528,11 +534,13 @@ final class Cache_Enabler_Disk {
528
  $src = $img->getAttribute('src');
529
  $src_webp = self::_convert_webp_src($src);
530
  if ($src != $src_webp) {
531
- $img->setAttribute('src' , $src_webp);
532
 
533
  // convert srcset attributes
534
- $srcset = $img->getAttribute('srcset');
535
- $img->setAttribute('srcset' , self::_convert_webp_srcset($srcset));
 
 
536
  }
537
 
538
  }
@@ -558,26 +566,38 @@ final class Cache_Enabler_Disk {
558
  * convert src to webp source
559
  *
560
  * @since 1.0.1
561
- * @change 1.0.6
562
  *
563
  * @return string converted src webp source
564
  */
565
 
566
  private static function _convert_webp_src($src) {
567
- if ( strpos($src, 'wp-content') !== false ) {
 
 
 
 
568
 
569
  $src_webp = str_replace('.jpg', '.webp', $src);
 
570
  $src_webp = str_replace('.png', '.webp', $src_webp);
571
 
572
- $parts = explode('/wp-content/uploads', $src_webp);
573
  $relative_path = $parts[1];
574
 
575
- $upload_path = wp_upload_dir();
576
- $base_dir = $upload_path['basedir'];
577
-
578
  // check if relative path is not empty and file exists
579
- if ( !empty($relative_path) && file_exists($base_dir.$relative_path) ) {
580
  return $src_webp;
 
 
 
 
 
 
 
 
 
 
581
  }
582
 
583
  }
@@ -590,7 +610,7 @@ final class Cache_Enabler_Disk {
590
  * convert srcset to webp source
591
  *
592
  * @since 1.0.8
593
- * @change 1.0.8
594
  *
595
  * @return string converted srcset webp source
596
  */
@@ -598,24 +618,37 @@ final class Cache_Enabler_Disk {
598
  private static function _convert_webp_srcset($srcset) {
599
 
600
  $sizes = explode(', ', $srcset);
 
 
 
601
 
602
  for ($i=0; $i<count($sizes); $i++) {
603
 
604
- if ( strpos($sizes[$i], 'wp-content') !== false ) {
605
 
606
  $src_webp = str_replace('.jpg', '.webp', $sizes[$i]);
 
607
  $src_webp = str_replace('.png', '.webp', $src_webp);
608
 
609
- $sizeParts = explode(' ', $src_webp);
610
- $parts = explode('/wp-content/uploads', $sizeParts[0]);
611
  $relative_path = $parts[1];
612
 
613
- $upload_path = wp_upload_dir();
614
- $base_dir = $upload_path['basedir'];
615
-
616
  // check if relative path is not empty and file exists
617
- if ( !empty($relative_path) && file_exists($base_dir.$relative_path) ) {
618
  $sizes[$i] = $src_webp;
 
 
 
 
 
 
 
 
 
 
 
 
619
  }
620
 
621
  }
184
 
185
  public static function get_asset() {
186
 
187
+ // set cache handler header
188
+ header('X-Cache-Handler: php');
189
+
190
  // get if-modified request headers
191
  if ( function_exists( 'apache_request_headers' ) ) {
192
  $headers = apache_request_headers();
211
  header('Content-Encoding: gzip');
212
  readfile( self::_file_webp_gzip() );
213
  exit;
214
+ } elseif ( is_readable( self::_file_webp_html() ) ) {
215
  readfile( self::_file_webp_html() );
216
  exit;
217
  }
424
  * cache path
425
  *
426
  * @since 1.0.0
427
+ * @change 1.1.0
428
  *
429
  * @param string $path uri or permlink
430
  * @return string $diff path to cached asset
446
  )
447
  );
448
 
449
+ if ( is_file($path) > 0 ) {
450
  wp_die('Path is not valid.');
451
  }
452
 
514
  * convert to webp
515
  *
516
  * @since 1.0.1
517
+ * @change 1.1.0
518
  *
519
  * @return string converted HTML file
520
  */
521
 
522
  private static function _convert_webp($data) {
523
 
524
+ // convert encoding to UTF-8
525
+ if(function_exists('mb_convert_encoding')) $data = mb_convert_encoding($data, 'HTML-ENTITIES', 'UTF-8');
526
+
527
  $dom = new DOMDocument();
528
+ @$dom->loadHTML($data);
529
 
530
  $imgs = $dom->getElementsByTagName("img");
531
 
534
  $src = $img->getAttribute('src');
535
  $src_webp = self::_convert_webp_src($src);
536
  if ($src != $src_webp) {
537
+ $img->setAttribute('src', $src_webp);
538
 
539
  // convert srcset attributes
540
+ if ($img->hasAttribute('srcset')) {
541
+ $srcset = $img->getAttribute('srcset');
542
+ $img->setAttribute('srcset', self::_convert_webp_srcset($srcset));
543
+ }
544
  }
545
 
546
  }
566
  * convert src to webp source
567
  *
568
  * @since 1.0.1
569
+ * @change 1.1.0
570
  *
571
  * @return string converted src webp source
572
  */
573
 
574
  private static function _convert_webp_src($src) {
575
+ $upload_dir = wp_upload_dir();
576
+ $src_url = parse_url($upload_dir['baseurl']);
577
+ $upload_path = $src_url['path'];
578
+
579
+ if ( strpos($src, $upload_path) !== false ) {
580
 
581
  $src_webp = str_replace('.jpg', '.webp', $src);
582
+ $src_webp = str_replace('.jpeg', '.webp', $src_webp);
583
  $src_webp = str_replace('.png', '.webp', $src_webp);
584
 
585
+ $parts = explode($upload_path, $src_webp);
586
  $relative_path = $parts[1];
587
 
 
 
 
588
  // check if relative path is not empty and file exists
589
+ if ( !empty($relative_path) && file_exists($upload_dir['basedir'].$relative_path) ) {
590
  return $src_webp;
591
+ } else {
592
+ // try appended webp extension
593
+ $src_webp_appended = $src.'.webp';
594
+ $parts_appended = explode($upload_path, $src_webp_appended);
595
+ $relative_path_appended = $parts_appended[1];
596
+
597
+ // check if relative path is not empty and file exists
598
+ if ( !empty($relative_path_appended) && file_exists($upload_dir['basedir'].$relative_path_appended) ) {
599
+ return $src_webp_appended;
600
+ }
601
  }
602
 
603
  }
610
  * convert srcset to webp source
611
  *
612
  * @since 1.0.8
613
+ * @change 1.1.0
614
  *
615
  * @return string converted srcset webp source
616
  */
618
  private static function _convert_webp_srcset($srcset) {
619
 
620
  $sizes = explode(', ', $srcset);
621
+ $upload_dir = wp_upload_dir();
622
+ $src_url = parse_url($upload_dir['baseurl']);
623
+ $upload_path = $src_url['path'];
624
 
625
  for ($i=0; $i<count($sizes); $i++) {
626
 
627
+ if ( strpos($sizes[$i], $upload_path) !== false ) {
628
 
629
  $src_webp = str_replace('.jpg', '.webp', $sizes[$i]);
630
+ $src_webp = str_replace('.jpeg', '.webp', $src_webp);
631
  $src_webp = str_replace('.png', '.webp', $src_webp);
632
 
633
+ $size_parts = explode(' ', $src_webp);
634
+ $parts = explode($upload_path, $size_parts[0]);
635
  $relative_path = $parts[1];
636
 
 
 
 
637
  // check if relative path is not empty and file exists
638
+ if ( !empty($relative_path) && file_exists($upload_dir['basedir'].$relative_path) ) {
639
  $sizes[$i] = $src_webp;
640
+ } else {
641
+ // try appended webp extension
642
+ $size_parts_appended = explode(' ', $sizes[$i]);
643
+ $src_webp_appended = $size_parts_appended[0].'.webp';
644
+ $parts_appended = explode($upload_path, $src_webp_appended);
645
+ $relative_path_appended = $parts_appended[1];
646
+ $src_webp_appended = $src_webp_appended.' '.$size_parts_appended[1];
647
+
648
+ // check if relative path is not empty and file exists
649
+ if ( !empty($relative_path_appended) && file_exists($upload_dir['basedir'].$relative_path_appended) ) {
650
+ $sizes[$i] = $src_webp_appended;
651
+ }
652
  }
653
 
654
  }
readme.txt CHANGED
@@ -1,8 +1,8 @@
1
  === Cache Enabler - WordPress Cache ===
2
  Contributors: keycdn
3
- Tags: cache, caching, wordpress cache, performance, gzip, webp, http2
4
  Requires at least: 4.1
5
- Tested up to: 4.4
6
  Stable tag: trunk
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -22,6 +22,7 @@ The Cache Enabler plugin creates static HTML files and stores them on the server
22
  = Features =
23
  * Efficient and fast disk cache engine
24
  * Automated and/or manual clearing of the cache
 
25
  * Display of the actual cache size in your dashboard
26
  * Minification of HTML and inline JavaScript
27
  * WordPress multisite support
@@ -68,6 +69,16 @@ This WordPress cache plugin is partially based on Cachify developed by [Sergej M
68
 
69
  == Changelog ==
70
 
 
 
 
 
 
 
 
 
 
 
71
  = 1.0.9 =
72
  * Option to disable pre-compression of cached pages if decoding fails
73
 
1
  === Cache Enabler - WordPress Cache ===
2
  Contributors: keycdn
3
+ Tags: cache, caching, wordpress cache, wp cache, performance, gzip, webp, http2
4
  Requires at least: 4.1
5
+ Tested up to: 4.5
6
  Stable tag: trunk
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
22
  = Features =
23
  * Efficient and fast disk cache engine
24
  * Automated and/or manual clearing of the cache
25
+ * Manually purge the cache of specific pages
26
  * Display of the actual cache size in your dashboard
27
  * Minification of HTML and inline JavaScript
28
  * WordPress multisite support
69
 
70
  == Changelog ==
71
 
72
+ = 1.1.0 =
73
+ * Added the possibility to clear the cache of a specific URL
74
+ * Supports now Windows filesystems
75
+ * Added X-Cache-Handler to indicate if loaded through PHP
76
+ * Support of WebP images generated by ewww
77
+ * Dynamic upload directory for WebP images
78
+ * Fixed multisite purge issue
79
+ * Added requirements checks
80
+ * Made plugin ready for translation
81
+
82
  = 1.0.9 =
83
  * Option to disable pre-compression of cached pages if decoding fails
84