PluginProbe
WP Super Minify • Minify, Compress and Cache HTML, CSS & JavaScript / 2.0
WP Super Minify • Minify, Compress and Cache HTML, CSS & JavaScript v2.0
trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.4 1.5 1.5.1 1.6 2.0 2.0.1
wp-super-minify / wp-super-minify.php

wp-super-minify.php in WP Super Minify • Minify, Compress and Cache HTML, CSS & JavaScript 2.0, at wp-super-minify.php

389 lines 15.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: WP Super Minify
4 Plugin URI: https://github.com/dipakcg/wp-super-minify
5 Description: Smartly minify, compress and cache HTML, CSS & JavaScript files to boost website speed. 🚀
6 Version: 2.0
7 Author: Dipak C. Gajjar
8 Author URI: https://dipakgajjar.com
9 */
10
11 // Define plugin version for future releases
12 if ( !defined ('WPSMY_PLUGIN_VERSION_NUM' ) ) {
13 define( 'WPSMY_PLUGIN_VERSION_NUM', '2.0' );
14 }
15 if ( !defined ('WPSMY_MINIFY_LIBRARY_PATH' ) ) {
16 define( 'WPSMY_MINIFY_LIBRARY_PATH', plugin_dir_path( __FILE__ ) . 'includes/min' );
17 }
18 if ( !defined ('WPSMY_CACHE_DIR' ) ) {
19 define( 'WPSMY_CACHE_DIR', WP_CONTENT_DIR . '/cache/wp-super-minify/' );
20 }
21 if ( !defined ('WPSMY_CSS_CACHE_DIR' ) ) {
22 define( 'WPSMY_CSS_CACHE_DIR', WPSMY_CACHE_DIR . 'css/' );
23 }
24 if ( !defined ('WPSMY_JS_CACHE_DIR' ) ) {
25 define( 'WPSMY_JS_CACHE_DIR', WPSMY_CACHE_DIR . 'js/' );
26 }
27
28 require_once( plugin_dir_path( __FILE__ ) . 'clear-minified-cache.php' );
29 require_once( plugin_dir_path( __FILE__ ) . 'rating-support.php' );
30
31 // require_once( WPSMY_MINIFY_LIBRARY_PATH . "/src/" . strtoupper($type) . '.php' );
32 require_once( WPSMY_MINIFY_LIBRARY_PATH . "/src/Minify.php" );
33 require_once( WPSMY_MINIFY_LIBRARY_PATH . "/src/CSS.php" );
34 require_once( WPSMY_MINIFY_LIBRARY_PATH . "/src/JS.php" );
35 require_once( WPSMY_MINIFY_LIBRARY_PATH . "/../path-converter/ConverterInterface.php" );
36 require_once( WPSMY_MINIFY_LIBRARY_PATH . '/../path-converter/Converter.php' );
37
38 update_option( 'wpsmy_plugin_version', WPSMY_PLUGIN_VERSION_NUM );
39
40 // Create Cache directories and sub-directories for CSS and JS
41 if ( !file_exists( WPSMY_CACHE_DIR ) ) mkdir( WPSMY_CACHE_DIR, 0755, true );
42 if ( !file_exists( WPSMY_CSS_CACHE_DIR ) ) mkdir( WPSMY_CSS_CACHE_DIR, 0755, true );
43 if ( !file_exists( WPSMY_JS_CACHE_DIR ) ) mkdir( WPSMY_JS_CACHE_DIR, 0755, true );
44
45 // Register with hook 'wp_enqueue_scripts', which can be used for front end CSS and JavaScript
46 add_action( 'admin_init', 'wpsmy_add_stylesheet' );
47 function wpsmy_add_stylesheet() {
48 // Respects SSL, Style.css is relative to the current file
49 wp_register_style( 'wpsmy-stylesheet', plugins_url('assets/css/style.min.css', __FILE__) );
50 wp_enqueue_style( 'wpsmy-stylesheet' );
51
52 // Hook 'Review this plugin'
53 do_action( 'wpsmy_rating_system_action' );
54 }
55
56 // Register admin menu
57 add_action( 'admin_menu', 'wpsmy_add_admin_menu' );
58 function wpsmy_add_admin_menu() {
59 // add_menu_page( 'WP Super Minify Settings', 'WP Super Minify', 'manage_options', 'wp-super-minify', 'wpsmy_admin_options', plugins_url('assets/images/wpsmy-icon-24x24.png', __FILE__) );
60 // add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function);
61 add_options_page( 'WP Super Minify', 'WP Super Minify', 'manage_options', 'wp-super-minify', 'wpsmy_admin_options' );
62 }
63
64 // Add settings link on plugin page
65 function wpsmy_settings_link( $links ) {
66 // $settings_link = '<a href="admin.php?page=wp-performance-score-booster">Settings</a>';
67 $settings_link = '<a href="options-general.php?page=wp-super-minify">Settings</a>';
68 array_unshift($links, $settings_link);
69 return $links;
70 }
71 $plugin = plugin_basename( __FILE__ );
72 add_filter( "plugin_action_links_$plugin", 'wpsmy_settings_link' );
73
74 // Adding WordPress plugin meta links
75 function wpsmy_plugin_meta_links( $links, $file ) {
76 $plugin = plugin_basename( __FILE__ );
77 // Create link
78 if ( $file == $plugin ) {
79 return array_merge(
80 $links,
81 array( '<a href="https://dipakgajjar.com/products/wordpress-speed-optimisation-service?utm_source=plugins%20page&utm_medium=text%20link&utm_campaign=wordplress%20plugins" style="color:#FF0000;" target="_blank">Order Pro-Level WordPress Speed Optimisation Services</a>' )
82 );
83 }
84 return $links;
85 }
86 add_filter( 'plugin_row_meta', 'wpsmy_plugin_meta_links', 10, 2 );
87
88 // Admin options/setting page
89 function wpsmy_admin_options() {
90 ?>
91 <div class="wrap">
92 <table width="100%" border="0">
93 <tr>
94 <td width="75%">
95 <h2>
96 <img src="<?php echo plugins_url( 'assets/images/wpsmy-icon-24x24.png', __FILE__ ); ?>"
97 style="vertical-align: middle; width="24" height="24">
98 WP Super Minify : Settings
99 </h2>
100 <hr />
101 <?php
102 if ( !current_user_can( 'manage_options' ) ) {
103 wp_die( __('You do not have sufficient permissions to access this page.') );
104 }
105
106 // Variables for the field and option names
107 $hidden_field_name = 'wpsmy_submit_hidden';
108 $combine_js = 'wpsmy_combine_js';
109 $combine_css = 'wpsmy_combine_css';
110
111 // Read in existing option value from database
112 $combine_js_val = get_option($combine_js);
113 $combine_css_val = get_option($combine_css);
114
115 // See if the user has posted us some information
116 // If they did, this hidden field will be set to 'Y'
117 if( isset( $_POST[$hidden_field_name] ) && $_POST[$hidden_field_name] == 'Y' ) {
118 // CSRF Check
119 if ( isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'wpsmy_settings_nonce' ) ) {
120 if ( isset( $_POST['wpsmy_clear_minified'] ) ) {
121 wpsmy_clear_minified_cache();
122 }
123 else {
124 // Read their posted value
125 $combine_js_val = ( isset( $_POST[$combine_js] ) ? sanitize_text_field( $_POST[$combine_js] ) : "" );
126 $combine_css_val = ( isset( $_POST[$combine_css] ) ? sanitize_text_field( $_POST[$combine_css] ) : "" );
127
128 // Save the posted value in the database
129 update_option( $combine_js, $combine_js_val );
130 update_option( $combine_css, $combine_css_val );
131
132 echo '<div class="updated"><p><strong>Settings Saved.</strong></p></div>';
133 }
134 }
135 }
136 ?>
137 <form method="post" name="options_form">
138 <?php wp_nonce_field( 'wpsmy_settings_nonce' ); ?>
139 <input type="hidden" name="<?php echo $hidden_field_name; ?>" value="Y">
140 <p>
141 <input type="checkbox" name="<?php echo $combine_css; ?>" id="<?php echo $combine_css; ?>" <?php checked( $combine_css_val == 'on',true); ?> />
142 <label for="<?php echo $combine_css; ?>" class="wpsmy_settings" style="display: inline;"> <?php _e('Optimise CSS'); ?> </label>
143 </p>
144 <p>
145 <input type="checkbox" name="<?php echo $combine_js; ?>" id="<?php echo $combine_js; ?>" <?php checked( $combine_js_val == 'on',true); ?> />
146 <label for="<?php echo $combine_js; ?>" class="wpsmy_settings" style="display: inline;"> <?php _e('Optimise JavaScript'); ?> </label>
147 </p>
148 <p><input type="submit" value="<?php esc_attr_e('Save Changes') ?>" class="button button-primary" name="submit" />
149 <button type="submit" name="wpsmy_clear_minified" class="button button-primary">Clear CSS & JS Cache</button>
150 </p>
151 </form>
152 <p> &nbsp; </p>
153 <?php
154 $message = "";
155 $css_enabled = ($combine_css_val == 'on');
156 $js_enabled = ($combine_js_val == 'on');
157
158 $templates = [
159 'css_js' => "�
160 WP Super Minify now minifies, compresses, and caches all %s files. Enable '<em>Optimise %s</em>' to further boost your site's performance.",
161 'both' => "�
162 WP Super Minify now minifies, compresses, and caches all CSS & JavaScript files making your site lighter, faster, and more optimised than ever! 🚀",
163 'none' => "<span style='color: RED !important;'> You haven’t selected any options above WP Super Minify isn’t currently optimising your site.
164 <br /> <br />If you’re not debugging or troubleshooting errors, consider enabling the options above to boost your site's performance.</span>",
165 ];
166 $hassle_free_updates = "�
167 Enjoy a seamless experience — Minified files are automatically updated whenever the original files are modified.";
168
169 if ( $js_enabled && !$css_enabled ) {
170 $message = sprintf($templates['css_js'], "JavaScript", "CSS") . '<br /> <br />' . $hassle_free_updates;
171 } elseif ( $css_enabled && !$js_enabled ) {
172 $message = sprintf($templates['css_js'], "CSS", "JS") . '<br /> <br />' . $hassle_free_updates;
173 } elseif ( $js_enabled && $css_enabled ) {
174 $message = $templates['both'] . '<br /> <br />' . $hassle_free_updates;
175 } else {
176 $message = $templates['none'];
177 }
178 // Output the final message
179 echo '<p style="color:#00a32a; font-weight: bold;">' . $message . '</p>';
180 ?>
181 </td>
182 <td style="text-align: left;">
183 <div class="wpsmy_admin_dev_sidebar_div">
184 <!-- <img src="//www.gravatar.com/avatar/38b380cf488d8f8c4007cf2015dc16ac.jpg" width="100px" height="100px" /> -->
185 <br />
186 <span class="wpsmy_admin_dev_sidebar"> <?php echo '<img src="' . plugins_url( 'assets/images/wpsmy-support-this-16x16.png' , __FILE__ ) . '" > '; ?> <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3S8BRPLWLNQ38" target="_blank"> Donate and support this plugin </a> </span>
187 <span class="wpsmy_admin_dev_sidebar"> <?php echo '<img src="' . plugins_url( 'assets/images/wpsmy-rate-this-16x16.png' , __FILE__ ) . '" > '; ?> <a href="http://wordpress.org/support/view/plugin-reviews/wp-super-minify" target="_blank"> Rate this plugin on WordPress.org </a> </span>
188 <span class="wpsmy_admin_dev_sidebar"> <?php echo '<img src="' . plugins_url( 'assets/images/wpsmy-wordpress-16x16.png' , __FILE__ ) . '" > '; ?> <a href="http://wordpress.org/support/plugin/wp-super-minify" target="_blank"> Get support on WordPress.org </a> </span>
189 <span class="wpsmy_admin_dev_sidebar"> <?php echo '<img src="' . plugins_url( 'assets/images/wpsmy-github-16x16.png' , __FILE__ ) . '" > '; ?> <a href="https://github.com/dipakcg/wp-super-minify" target="_blank"> Contribute development on GitHub </a> </span>
190 <span class="wpsmy_admin_dev_sidebar"> <?php echo '<img src="' . plugins_url( 'assets/images/wpsmy-other-plugins-16x16.png' , __FILE__ ) . '" > '; ?> <a href="http://profiles.wordpress.org/dipakcg#content-plugins" target="_blank"> Get my other plugins </a> </span>
191 <span class="wpsmy_admin_dev_sidebar"> <?php echo '<img src="' . plugins_url( 'assets/images/wpsmy-twitter-16x16.png' , __FILE__ ) . '" > '; ?>Follow me on Twitter: <a href="https://twitter.com/dipakcgajjar" target="_blank">@dipakcgajjar</a> </span>
192 <br />
193 <span class="wpsmy_admin_dev_sidebar" style="float: right;"> Version: <strong> <?php echo get_option('wpsmy_plugin_version'); ?> </strong> </span>
194 </div>
195 </td>
196 </tr>
197 </table>
198 </div>
199 <?php
200 }
201
202 // Make the default value of enable javascript and enable CSS to true on plugin activation
203 function wpsmy_activate_plugin() {
204
205 // Save default options value in the database
206 update_option( 'wpsmy_combine_js', 'on' );
207 update_option( 'wpsmy_combine_css', 'on' );
208
209 // Rate this plugin on wordpress.org - check for admin notice dismissal
210 if ( FALSE === get_option( 'wpsmy_review_notice' ) ) {
211 add_option( 'wpsmy_review_notice', 'on' );
212 }
213 }
214 register_activation_hook( __FILE__, 'wpsmy_activate_plugin' );
215
216 // Remove filters/functions on plugin deactivation
217 function wpsmy_deactivate_plugin() {
218 delete_option( 'wpsmy_plugin_version' );
219 }
220 register_deactivation_hook( __FILE__, 'wpsmy_deactivate_plugin' );
221
222 function wpsmy_minify_html( $buffer ) {
223 $wpsmy_plugin_version = get_option( 'wpsmy_plugin_version' );
224 $initial = strlen( $buffer );
225
226 // Include Minify libraries only if not already loaded
227 if ( !class_exists( 'Minify_HTML' ) ) {
228 require_once( WPSMY_MINIFY_LIBRARY_PATH . "/lib/Minify/HTML.php" );
229 require_once( WPSMY_MINIFY_LIBRARY_PATH . "/lib/Minify/Loader.php" );
230 Minify_Loader::register();
231 }
232
233 // Minify inline JavaScript if enabled
234 if ( get_option('wpsmy_combine_js', 1 ) === 'on') {
235 $buffer = Minify_HTML::minify( $buffer, array(
236 'jsMinifier' => array( 'JSMin', 'minify' )
237 ));
238 }
239
240 // Minify inline CSS if enabled
241 if (get_option( 'wpsmy_combine_css', 1 ) === 'on') {
242 $buffer = Minify_HTML::minify( $buffer, array(
243 'cssMinifier' => array( 'Minify_CSS', 'minify' )
244 ));
245 }
246
247 // Calculate savings
248 $final = strlen( $buffer );
249 if ($initial > 0) {
250 $savings = round((($initial - $final) / $initial * 100), 3);
251 } else {
252 $savings = 0; // Avoid division by zero
253 }
254
255 // Store the comment in a global variable instead of appending to the buffer
256 if ( $savings > 0 ) {
257 global $wpsmy_minify_comment;
258 $wpsmy_minify_comment = PHP_EOL . '<!--' . PHP_EOL .
259 '*** This site runs WP Super Minify plugin v' . esc_html($wpsmy_plugin_version) . ' - http://wordpress.org/plugins/wp-super-minify ***' . PHP_EOL .
260 '*** Total size saved: ' . esc_html($savings) . '% | Size before compression: ' . esc_html($initial) . ' bytes | Size after compression: ' . esc_html($final) . ' bytes. ***' . PHP_EOL .
261 '-->';
262 }
263
264 return $buffer;
265 }
266
267 // Start HTML Minification with output buffering
268 function wpsmy_html_minify_start() {
269 if (!is_admin() && !defined('DOING_AJAX')) {
270 ob_start('wpsmy_minify_html');
271 }
272 }
273 add_action( 'template_redirect', 'wpsmy_html_minify_start', 1 );
274
275 // Flush the buffer at the end of the page
276 function wpsmy_html_minify_end() {
277 if (!is_admin() && ob_get_length()) {
278 ob_end_flush();
279 }
280 }
281 add_action( 'shutdown', 'wpsmy_html_minify_end', 9999 );
282
283 // Output minification comment at the bottom of the page
284 function wpsmy_print_minify_comment() {
285 global $wpsmy_minify_comment;
286 if (!empty($wpsmy_minify_comment)) {
287 echo $wpsmy_minify_comment;
288 }
289 }
290 add_action( 'shutdown', 'wpsmy_print_minify_comment', 10000 );
291
292 // Hook to process and replace scripts and styles
293 add_action( 'wp_enqueue_scripts', 'wpsmy_minify_enqueue_scripts', 999 );
294 function wpsmy_minify_enqueue_scripts() {
295 global $wp_styles, $wp_scripts;
296
297 // Minify and replace styles
298 if ( !empty( $wp_styles->queue ) && get_option( 'wpsmy_combine_css', 1 ) === 'on' ) {
299 foreach ($wp_styles->queue as $handle) {
300 $src = $wp_styles->registered[$handle]->src;
301 if ($src) {
302 $minified_src = wpsmy_minify_file($src, 'css');
303 if ($minified_src) {
304 $wp_styles->registered[$handle]->src = $minified_src;
305 }
306 }
307 }
308 }
309
310 // Minify and replace scripts
311 if ( !empty( $wp_scripts->queue ) && get_option( 'wpsmy_combine_js', 1 ) === 'on' ) {
312 foreach ($wp_scripts->queue as $handle) {
313 $src = $wp_scripts->registered[$handle]->src;
314 if ($src) {
315 $minified_src = wpsmy_minify_file($src, 'js');
316 if ($minified_src) {
317 $wp_scripts->registered[$handle]->src = $minified_src;
318 }
319 }
320 }
321 }
322 }
323
324 /**
325 * Minifies a given CSS or JS file and stores it.
326 *
327 * @param string $file_url URL of the original file.
328 * @param string $type 'css' or 'js'.
329 * @return string|false Minified file URL or false if failed.
330 */
331 function wpsmy_minify_file( $file_url, $type ) {
332
333 if ( strpos($file_url, '.min.') !== false ) {
334 return $file_url; // Skip if already minified
335 }
336
337 $cache_filetype_dir = ( $type === 'js' ? 'js/' : 'css/' );
338 $cache_url = content_url() . '/cache/wp-super-minify/';
339
340 $file_path = str_replace(home_url(), ABSPATH, $file_url);
341 $minified_file_name = md5($file_url) . '.' . $type;
342 $minified_file_path = WPSMY_CACHE_DIR . $cache_filetype_dir . $minified_file_name;
343 $minified_file_url = $cache_url . $cache_filetype_dir . $minified_file_name;
344 $hash_file_path = $minified_file_path . '.hash'; // Store file hash
345
346 // Check if original file exists
347 if ( !file_exists( $file_path ) ) {
348 return false; // Skip if file is not local
349 }
350
351 // Get current file hash
352 $current_hash = md5_file($file_path);
353
354 // Check if minified file exists and hash matches
355 if ( file_exists($minified_file_path) && file_exists($hash_file_path) ) {
356 $saved_hash = file_get_contents( $hash_file_path );
357 if ( $saved_hash === $current_hash ) {
358 return $minified_file_url; // Return existing minified file
359 }
360 }
361
362 try {
363 if ( $type === 'css' ) {
364 $minifier = new MatthiasMullie\Minify\CSS( $file_path );
365 } elseif ( $type === 'js' ) {
366 $minifier = new MatthiasMullie\Minify\JS( $file_path );
367 } else {
368 return false;
369 }
370
371 $minifier->minify( $minified_file_path );
372
373 // Store hash to track changes
374 file_put_contents($hash_file_path, $current_hash);
375
376 // Store in options table
377 $stored_files = get_option( 'wpsmy_minified_files', [] );
378 $stored_files[$file_url] = $minified_file_url;
379 update_option( 'wpsmy_minified_files', $stored_files );
380
381 return $minified_file_url;
382 } catch ( Exception $e ) {
383 return false;
384 }
385 }
386
387 /* END OF PLUGIN */
388 ?>
389