wp-super-cache/0000755000076500007650000000000011157413555013206 5ustar jhardijhardiwp-super-cache/advanced-cache.php0000644000076500007650000000012711151602174016514 0ustar jhardijhardi wp-super-cache/Changelog.txt0000644000076500007650000011505011151602174015627 0ustar jhardijhardi2009-02-26 11:53 donncha * Changelog.txt: Updated changelog 2009-02-26 11:51 donncha * readme.txt, wp-cache.php: Bump version to 0.9.1 2009-02-26 11:35 donncha * readme.txt: Updated docs on "expired pages" and the required modules needed to serve new data 2009-02-26 11:23 donncha * wp-cache.php: Remove "experimental" heading. 2009-02-26 11:07 donncha * wp-cache.php: Added "About the author" box to admin page. 2009-02-19 16:07 donncha * wp-cache.php: Make the donation box hidable. 2009-02-19 15:46 donncha * wp-cache.php: Added donation button, yes my html skills suck. 2009-02-19 15:00 donncha * wp-cache.php: Match IP against 192.168 instead of 192. 2009-02-19 13:43 donncha * readme.txt, wp-cache.php: Added checks for hostname = 127.x.x.x or 192.x.x.x or if available uses wp_remote_get() to load wp-cron.php Gives warning if checks fail Updated readme.txt with docs on how to resolve. Thanks to Joost de Valk for help debugging this. http://yoast.com/wp-cron-issues/ 2009-02-19 13:34 donncha * wp-cache-phase2.php: Hide file op warning. Removed register_shutdown command that's not used any more 2009-02-19 11:48 donncha * wp-cache.php: Hide rename warning. Possibly related to no global lock. 2009-02-17 13:04 donncha * Changelog.txt: Updated changelog 2009-02-17 12:58 donncha * wp-cache-phase2.php: Don't show no HTML tag warning for robots.txt, http://wordpress.org/support/topic/243904?replies=1 2009-02-17 12:36 donncha * wp-cache.php: Clear the supercache folder when it's disabled. Remove the .disabled folder if a supercache folder exists. Show Last and Next garbage collection times as UTC Added an admin notice on the plugins page if wp-super-cache caching is disabled Add plugin notice below plugin row if caching is disabled 2009-02-17 12:34 donncha * wp-cache-phase2.php: Hide some filemtime() warnings. Without a global file lock we'll get more of these. 2009-02-17 12:33 donncha * plugins/badbehaviour.php: Disable the supercache if Bad Behaviour support is enabled. 2009-02-14 11:48 donncha * readme.txt: Updated tag and added Donation link 2009-02-06 10:48 donncha * wp-cache-phase1.php, wp-cache-phase2.php: Just use the output buffer, no shutdown functions. 2009-02-05 20:53 donncha * wp-cache-phase2.php: No need to call this callback twice! 2009-02-05 15:32 donncha * wp-cache-config-sample.php: Remove any slashes left in the blogcacheid 2009-02-05 13:36 donncha * wp-cache.php: Replace blashslashes in WP_CONTENT_DIR here, possible Win32 fix 2009-02-05 10:20 donncha * readme.txt: Added "UserOnline" to the list of plugins that don't update when a page is cached 2009-02-05 09:55 donncha * wp-cache.php: Replace backslashes in WP_CONTENT_DIR too. Win32 fix. props Chris (beerfan) 2009-02-04 21:49 donncha * wp-cache-config-sample.php, wp-cache-phase2.php: Added $wp_cache_shutdown_gc config option to use shutdown instead of wp-cron Added comments on config options 2009-02-04 20:38 donncha * wp-cache-phase2.php: Don't create empty supercache directories. 2009-02-04 10:25 donncha * readme.txt: Troubleshooting updates: advanced-cache.php, cache on NFS warning 2009-02-03 21:53 donncha * plugins/badbehaviour.php, wp-cache-phase1.php: Things act strange when a function has a require_once(), even if it's never reached 2009-02-03 21:41 donncha * plugins/badbehaviour.php, plugins/searchengine.php, wp-cache-config-sample.php, wp-cache-phase1.php: Added Bad Behaviour plugin Allow SuperCache plugin directory to be relocated. See $wp_cache_plugins_dir in config file. Fixed updating Active status of searchengine plugin Added new cacheactions: 'wp_cache_served_cache_file' activated just before headers are sent for an existing cache file. 'wp_cache_file_contents' filter that every wp-cache cache file is sent through. (ignoring mfunc) 2009-02-03 12:11 donncha * wp-cache-phase1.php: Clean and echo the buffer 2009-02-03 11:49 donncha * wp-cache-phase1.php, wp-cache-phase2.php: Register supercache shutdown function right at the start of the process so it's executed before WP objects are destroyed 2009-02-02 15:48 donncha * wp-cache-phase2.php: Don't register shutdown function, call it from the output buffer callback. 2009-02-02 09:58 donncha * wp-cache-phase2.php: Don't read files into an array, reverting [86134] 2009-01-29 17:19 donncha * wp-cache.php: Remove double slashes from inst_root 2009-01-29 16:28 donncha * wp-cache.php: Guess the install root properly 2009-01-29 14:25 donncha * wp-cache-phase2.php: Revert prune_super_cache and garbage_collection code. 2009-01-29 06:41 donncha * wp-cache.php: Fix caching for blogs installed in sub dirs. See http://wordpress.org/support/topic/238022?replies=6 2009-01-27 19:57 donncha * wp-cache-phase2.php: Only rename the tmp cache file when it's created. Hide warnings about renames and unlinks 2009-01-27 06:18 donncha * Changelog.txt: Updated changelog 2009-01-27 06:17 donncha * readme.txt, wp-cache.php: Bump version to 0.9 2009-01-27 06:17 donncha * wp-cache-phase2.php: Bring back mfunc code 2009-01-27 05:53 donncha * wp-cache-phase2.php, wp-cache.php: Set GC to 10 minutes instead of 30. 2009-01-26 20:08 donncha * wp-cache.php: Show last and next garbage collection times 2009-01-26 18:11 donncha * wp-cache.php: Make sure constant value is displayed, props Jonathan Dingman 2009-01-26 17:32 donncha * wp-cache-phase1.php: Update mobile "enabled" variable 2009-01-26 17:32 donncha * wp-cache-phase2.php: Don't send gzip headers if headers already sent 2009-01-26 13:00 donncha * wp-cache-config-sample.php, wp-cache-phase2.php, wp-cache.php: Removed "dynamic caching" that isn't documented anywhere any more Fixed activate bugs with mobile device support 2009-01-26 11:12 donncha * wp-cache-config-sample.php, wp-cache-phase1.php, wp-cache.php: Mobile device support via http://wordpress.org/extend/plugins/wordpress-mobile-edition/ by Alex King 2009-01-26 10:03 donncha * readme.txt: Added extra FAQs 2009-01-25 11:21 donncha * wp-cache-phase2.php, wp-cache.php: Admin page updates If expiry time is over 30 minutes, set garbage collection to 30 minutes, else expiry time 2009-01-25 09:11 donncha * wp-cache-phase2.php: If supercache enabled, Don't create wp-cache files for anonymous users. Should cut down cached files by half ore more. 2009-01-25 07:56 donncha * wp-cache-phase2.php: Warn if cache expiry cron job took longer than 30 seconds, props SiriusBuzz 2009-01-25 07:49 donncha * advanced-cache.php, wp-cache-phase2.php, wp-cache.php: advanced-cache.php will load the phase1.php even in relocated plugin folders now. (NOTE. Must be updated if plugin folder changes) Removed error_log() 2009-01-24 06:03 donncha * wp-cache.php: Update advanced-cache.php message, props Jonathan Dingman 2009-01-23 19:10 donncha * Changelog.txt: Updated Changelog for 0.8.9 2009-01-23 19:09 donncha * readme.txt, wp-cache.php: Bump version number to 0.8.9 and update documentation 2009-01-23 18:34 donncha * wp-cache.php: Updated text 2009-01-23 12:43 donncha * wp-cache-phase2.php, wp-cache.php: Set garbage collection to 10 seconds after expiry 2009-01-23 12:13 donncha * wp-cache.php: mutext variable needs to be global 2009-01-23 12:06 donncha * advanced-cache.php, wp-cache.php: Added "advanced-cache.php" which will load wp-cache-phase1.php Copy that file to wp-content/ instead of symlinking Added checkboxes for "cache rebuild" and "disable file locking" remove #list anchor tag 2009-01-22 11:26 donncha * wp-cache-phase2.php: Delete lots more cache files in one go, for busy sites 2009-01-21 13:42 donncha * wp-cache-phase2.php: Removed "cron job called" debug message 2009-01-21 13:05 donncha * wp-cache.php: Show all sections of the admin page by default. Move cache contents up 2009-01-20 11:23 donncha * wp-cache.php: Admin page UI update, props Robert Wolf 2009-01-19 18:29 donncha * wp-cache-config-sample.php: Comment out $wp_cache_mutex_disabled by default 2009-01-19 18:27 donncha * wp-cache-config-sample.php, wp-cache-phase2.php: Allow mutex file locking to be disabled 2009-01-19 18:18 donncha * wp-cache.php: Fix the favourites if a non admin users logs in 2009-01-16 17:04 donncha * Changelog.txt: Updated Changelog 2009-01-16 17:03 donncha * wp-cache-config-sample.php, wp-cache-phase1.php, wp-cache-phase2.php: Added simple DEBUG mode. Activate by setting $wp_cache_debug to your email address in wp-cache-config.php Sends debug emails on: cron job, failed job, when gzip headers are missing from wp-cache meta file. 2009-01-16 16:14 donncha * readme.txt, wp-cache.php: Bump version to 0.8.8 2009-01-16 16:10 donncha * wp-cache.php: Added "Delete Cache" link to Favourites menu 2009-01-15 23:16 donncha * wp-cache-phase2.php: We clean up files as well as directories. Should fix issue with non-updating blogs 2009-01-14 22:47 donncha * wp-cache-config-sample.php, wp-cache-phase1.php, wp-cache-phase2.php: Remove debugging code 2009-01-14 18:51 donncha * wp-cache-config-sample.php, wp-cache-phase1.php, wp-cache-phase2.php: Lots of debug code 2009-01-14 14:33 donncha * readme.txt: Updated the "How do I know my blog is being cached?" FAQ 2009-01-12 17:51 donncha * wp-cache-phase2.php: Don't overwrite $dh directory handler 2009-01-12 17:38 donncha * wp-cache-phase2.php: When reading large directories, create array of files. The opendir handle seems to die. 2009-01-11 09:16 donncha * wp-cache-phase2.php, wp-cache.php: Use opendir()/readdir() instead of glob() 2009-01-09 21:16 donncha * wp-cache-phase2.php: Minor typo 2009-01-09 11:04 donncha * Changelog.txt: Updated changelog 2009-01-09 11:04 donncha * readme.txt, wp-cache.php: Bump version to 0.8.7 2009-01-09 10:59 donncha * wp-cache-phase2.php, wp-cache.php: Change default expiry time to 10 minutes Only clean out 100 files at a time. Should help with very large sites. Fix file pointer. 2008-12-05 09:57 donncha * wp-cache.php: Fix term -> meta typo, props kettari, http://wordpress.org/support/topic/222613?replies=1 2008-12-04 18:13 donncha * Changelog.txt: Updated changelog for 0.8.6 2008-12-04 18:12 donncha * wp-cache-phase1.php: Added "WP-Super-Cache: WP-Cache" header for cached php files. 2008-12-04 17:59 donncha * readme.txt, wp-cache.php: Bump version numberb to 2.7 2008-12-04 17:44 donncha * wp-cache.php: Hide unlink errors 2008-12-04 16:53 donncha * wp-cache-phase2.php: Use uniqid() instead of tempnam() to generate temporary filenames. No need for chmod. Fixed minor typo 2008-12-04 13:40 donncha * wp-cache-phase2.php: Record time of cache generation 2008-12-04 13:27 donncha * readme.txt: Added Apache configuration docs on AllowOverride 2008-12-02 11:00 donncha * wp-cache.php: If WP_CACHE is not enabled, but the define() line is in wp-config.php, stop, because it's probably commented out. 2008-12-01 11:38 donncha * wp-cache-phase2.php: Abort caching if plugin can't write to any cache file, and report error $gzsize may not survive to shutdown callback. Get the filesize again 2008-12-01 11:37 donncha * wp-cache-phase1.php: Push the headers into the headers array, not the meta object 2008-11-25 12:58 donncha * Changelog.txt: Updated changelog 2008-11-25 12:58 donncha * readme.txt, wp-cache.php: Bump version number to 0.8.5 2008-11-25 12:45 donncha * wp-cache-phase2.php: Added "supercache_dir" filter so supercache directory can be modified. 2008-11-25 12:40 donncha * wp-cache-phase2.php: Removed backslashes from the supercache filename 2008-11-25 12:27 donncha * wp-cache.php: Warn if Apache modules are missing. Display gzip cache rewrite rules. Deal with WordPress MU better as it can't upgrade the .htaccess file. 2008-11-25 12:24 donncha * wp-cache-phase1.php: Added wp_cache_key cacheaction to modify cache key (ie. add user agent, IP, etc) 2008-11-25 11:10 donncha * wp-cache-phase1.php, wp-cache-phase2.php: Check that cache file exists before serving, it may have been removed without the meta file 2008-11-25 11:01 donncha * wp-cache-phase2.php: Removed $gzipped variable 2008-11-25 10:54 donncha * wp-cache-phase2.php: No need to addslashes() to file functions 2008-11-14 13:20 donncha * wp-cache-phase2.php: Added wpsupercache_buffer filter so buffer can be manipulated before writing to cache file 2008-11-14 13:00 donncha * wp-cache-phase2.php: Move gzip header detection down 2008-11-14 10:09 donncha * wp-cache-phase1.php, wp-cache-phase2.php: Add gzip headers back if they are missing. Should fix problems with users seeing corrupted pages. 2008-11-14 10:00 donncha * readme.txt: Updated docs on file locking 2008-11-11 17:28 donncha * wp-cache-phase2.php: Write wp-cache php cache files to temporary files before moving into place. Increase gzip compression to 3 If cron job failed to get mutex lock, try again in 10 minutes 2008-11-07 09:43 donncha * wp-cache.php: Use WP_CONTENT_URL in mod_rewrite rules. Use WP_CONTENT_DIR in WPCACHEHOME definition. 2008-10-27 13:21 donncha * readme.txt: Added links section and link to WP Widget Cache, props to Ben @ http://www.binarymoon.co.uk/ Minor troubleshooting update 2008-10-23 08:14 donncha * wp-cache.php: wp_cache_check_global_config() fixes by joelhardi, http://wordpress.org/support/topic/211477?replies=1#post-879591 2008-10-22 15:57 donncha * Changelog.txt: Updated changelog 2008-10-22 15:55 donncha * readme.txt, wp-cache.php: Bump version number to 0.8.4 2008-10-11 22:10 donncha * wp-cache-phase2.php: Update the time of last gc 2008-10-10 11:54 donncha * wp-cache-phase2.php, wp-cache.php: Change garbage collection parameters to time rather than hits 2008-10-08 16:06 donncha * Changelog.txt: Updated changelog 2008-10-08 16:04 donncha * readme.txt, wp-cache.php: Bump version numbers to 0.8.3 Updated docs 2008-10-08 08:12 donncha * readme.txt: Note for WPMU users, http://wordpress.org/support/topic/208770?replies=3#post-871207 2008-10-07 12:03 donncha * readme.txt: x-gzip->gzip 2008-10-07 10:50 donncha * readme.txt: Minor typo, http://wordpress.org/support/topic/208770?replies=1#post-870518 2008-10-07 10:44 donncha * plugins/searchengine.php: Don't overwrite logged in user details in searchengine plugin. 2008-10-06 09:19 donncha * wp-cache-phase1.php, wp-cache.php: Encode as gzip, not x-gzip as IE7 has problems with it. ref: http://bugs.typo3.org/view.php?id=4623 2008-10-01 08:05 donncha * readme.txt, wp-cache.php: Options -> Settings, thanks webmaestro http://wordpress.org/support/topic/207576?replies=2 2008-09-29 09:29 donncha * wp-cache.php: Only update "clear on post" setting when saving status options, thanks Viper007Bond 2008-09-28 11:04 donncha * wp-cache-phase2.php: Only create compressed data if required 2008-09-28 06:16 donncha * wp-cache-phase2.php: Compress cache files with "dynamic content" too 2008-09-28 05:56 donncha * wp-cache-phase2.php: Only compress cached files once. Nice speed boost! 2008-09-28 05:46 donncha * wp-cache-phase2.php: Write gzipped supercache files using fopen instead of gzopen 2008-09-26 23:16 donncha * Changelog.txt: Updated changelog 2008-09-26 23:15 donncha * readme.txt, wp-cache.php: Bump the version number to 0.8.2 2008-09-26 23:14 donncha * wp-cache-config-sample.php, wp-cache-phase2.php, wp-cache.php: Added $cache_rebuild_files setting to switch off "need rebuild" functionality by default 2008-09-26 16:00 donncha * wp-cache-phase2.php: On post change clear the front page 2008-09-26 12:04 donncha * wp-cache-phase2.php: Move cache writers entry up above supercache cleaning. Only clean individual posts, don't clear cache when no post_id 2008-09-26 09:49 donncha * wp-cache.php: Only show "Delete Cache" link to MU site admins or admins on WP blogs 2008-09-25 12:47 donncha * wp-cache.php: Save "wp_cache_clear_on_post_edit" properly, thanks HarryRAR, http://wordpress.org/support/topic/206371?replies=2#post-861998 2008-09-25 11:12 donncha * wp-cache-phase2.php, wp-cache.php: Can't clear cache on edit_post because leaving a comment calls edit_post unfortunately Experimental code to preserve supercache version of a page while it's being regenerated. 2008-09-24 14:21 donncha * wp-cache.php: Added "Delete Cache" link at top of admin pages 2008-09-24 13:57 donncha * Changelog.txt: Updated changelog, still release 0.8.1 2008-09-24 13:03 donncha * wp-cache-phase2.php: Added function to clear cache when a post is edited 2008-09-24 13:02 donncha * wp-cache.php: Added "Clear on edit" checkbox to clear all cache files when a post or page is edited 2008-09-24 13:01 donncha * wp-cache.php: Remove meta and supercache directories when deactivating 2008-09-24 12:47 donncha * wp-cache.php: Switch status messages around. 2008-09-24 12:47 donncha * wp-cache.php: Remove cache/.htaccess when uninstalling. 2008-09-24 12:44 donncha * readme.txt: Make mod mime and rewrite line clearer, hopefully 2008-09-24 12:38 donncha * wp-cache-phase2.php: comment_id typo Only clear supercache files if it's enabled 2008-09-24 12:37 donncha * readme.txt: Updated mod_rewrite rules and expiry/mime type rules 2008-09-24 11:57 donncha * Changelog.txt: Updated changelog for 0.8.1 2008-09-24 11:57 donncha * readme.txt, wp-cache.php: Bump the version number 2008-09-24 10:01 donncha * wp-cache-phase2.php: Make the temporary filename world readable to avoid problems where Apache and PHP run as different users. Thanks Tigertech for the code. 2008-09-24 09:57 donncha * wp-cache-phase2.php: Check that rename worked, if not, remove cache file and rename again. Props tigertech 2008-09-23 19:55 donncha * wp-cache-phase2.php: Don't clear the supercache if it's not enabled (In blog context, when a moderated comment is made) 2008-09-23 13:09 donncha * Changelog.txt: Updated changelog 2008-09-23 13:05 donncha * readme.txt, wp-cache.php: Bump the version to 0.8 2008-09-23 13:01 donncha * wp-cache-phase1.php: Comment: reminder to update .htaccess rules if get_cookie cacheaction is used. 2008-09-23 12:58 donncha * wp-cache-phase1.php: Don't return if the $string is not '' 2008-09-23 12:50 donncha * wp-cache.php: Generate a semaphore id based on hostname and cache path, props Tigertech http://wordpress.org/support/topic/205195?replies=4#post-857610 2008-09-23 11:14 donncha * wp-cache.php: Make the expiry cleanup list an unordered list 2008-09-23 11:06 donncha * wp-cache-phase2.php: siteurl -> home for those who run WP in a different place 2008-09-23 10:44 donncha * wp-cache-config-sample.php, wp-cache-phase2.php, wp-cache.php: No need for $super_cache_max_time 2008-09-23 10:39 donncha * wp-cache-phase2.php: On post change: 1. Clear all files from permalink in supercache directory. 2. Clear siteurl/page/ permalinks. 3. Clear supercache files when corresponding php meta files are removed. 2008-09-18 09:45 donncha * wp-cache.php: Show mod_rewrite rules when .htaccess is RO, props Matt @ http://mattsblog.ca/ 2008-09-17 16:29 donncha * wp-cache-phase2.php, wp-cache.php: Decrease the chance of cleanup. 2008-09-17 11:01 donncha * wp-cache.php: Don't server cached static files when url contains "=". Should avoid lots of problems with query strings 2008-09-17 11:00 donncha * wp-cache-phase2.php: Replace the siteurl correctly for those who have installed in a subdir, but access from the directory above. Thanks Viper007Bond. 2008-09-16 13:01 donncha * wp-cache.php: Check for WordPress MU because .htaccess can't be updated. Set cache control and expiry headers of supercached files. Cached for 5 minutes, but with "must-revalidate" 2008-09-06 11:00 donncha * wp-cache-phase2.php: Write cache files to a temporary file first, then rename. Rename should be atomic. 2008-08-28 11:30 donncha * Changelog.txt: Updated changelog 2008-08-28 11:29 donncha * readme.txt, wp-cache.php: Bump the version number to 0.7.1 2008-08-28 11:00 donncha * wp-cache.php: Updated .htaccess code: Check that file is writable (again?) Fix warnings about upgrades. Bright yellow backgrounds on items that need attention Thanks Matt @ http://twitter.com/mattfreedman/statuses/901325274 for reporting. 2008-08-27 19:32 donncha * Changelog.txt: Updated changelog 2008-08-27 19:31 donncha * readme.txt, wp-cache.php: Bump to 0.7, fix activation link 2008-08-27 19:17 donncha * Changelog.txt: Updated Changelog 2008-08-27 19:16 donncha * readme.txt, wp-cache.php: Bump the version number to 0.6.8 2008-08-27 18:59 donncha * wp-cache.php: Added rules to redirect to urls ending with a "/", props Andylav and definitelynot, http://wordpress.org/support/topic/199542?replies=6 2008-08-21 16:41 donncha * wp-cache.php: Change menu options url 2008-08-20 11:47 donncha * Changelog.txt: Update Changelog 2008-08-20 10:49 donncha * readme.txt, wp-cache.php: Bump version number to 0.6.7 2008-08-20 09:38 donncha * wp-cache.php: Added CRs 2008-08-20 09:01 donncha * wp-cache.php: Added apache_request_headers() as suggested in http://wordpress.org/support/topic/197053 2008-08-19 16:27 donncha * plugins/searchengine.php, wp-cache.php: Updated styling with the help of the simple trackback validation plugin 2008-08-19 15:11 donncha * wp-cache-config-sample.php: Don't include rss files in cacheable list 2008-08-19 15:05 donncha * wp-cache.php: Added "deactivation hook" to remove advanced-cache.php and wp-cache-config.php and cached files. 2008-08-14 10:39 donncha * wp-cache-phase1.php: Only include once 2008-08-14 09:14 donncha * wp-cache-phase1.php, wp-cache-phase2.php: Cron fixed from Mike 2008-08-13 12:52 donncha * wp-cache-phase2.php, wp-cache.php: Fixes from Mike Beggs: Use custom is_writeable() that works in Win32 NTFS Update "Vary" header Let WP Cron handle cache cleaning. Don't let mod_deflate try to compress gzipped cached files 2008-08-09 10:13 donncha * wp-cache-phase2.php: Use get_comment(), props Lazy @ http://www.lazybrain.de/ 2008-07-31 15:53 donncha * Changelog.txt: Updated changelog 2008-07-31 10:47 donncha * readme.txt, wp-cache.php: Bump version numbers 2008-07-29 19:52 donncha * wp-cache-config-sample.php, wp-cache-phase1.php, wp-cache.php: WP 2.6 fixes. Use WP_CONTENT_DIR. Have not added to .htaccess rules yet 2008-07-28 09:37 donncha * readme.txt, wp-cache.php: Change wp-super-cache expiry to 3600 seconds. Avoid foreach error on empty directories Minor change to status message 2008-07-24 16:26 donncha * wp-cache-phase2.php, wp-cache.php: Removed debug error log Catch 404 file not found requests when themes use query_posts() 2008-07-24 13:17 donncha * wp-cache-phase2.php: If we can't get a file lock, warn user. 2008-07-23 18:30 donncha * readme.txt: Update FAQ on cache times. 2008-07-23 18:27 donncha * readme.txt, wp-cache.php: Added p= parameter to htacess rules so they'll be served by wp-cache only, http://wordpress.org/support/topic/191275?replies=3 2008-07-17 09:48 donncha * wp-cache.php: Handle if wp-config.php has been moved ../ in WordPress 2.6 2008-07-16 11:12 donncha * wp-cache.php: Don't warn the user wp-content is writable if webserver is running as user. Create correct .htaccess rules when WordPress is installed in a different location. Both fixes props Allan Bazinet @ http://sneezingfrog.com/blog/ 2008-07-15 10:17 donncha * Changelog.txt: Update changelog 2008-07-15 10:15 donncha * readme.txt, wp-cache.php: Bump the version number to 0.6.5 2008-07-15 10:14 donncha * readme.txt: Add "Subscribe to comments" rule to readme 2008-07-15 10:11 donncha * wp-cache-phase1.php: Use comment_author instead of email in case email isn't mandatory. props rhapsodyv @ http://wordpress.org/support/topic/188775 2008-07-14 10:42 donncha * wp-cache-phase2.php, wp-cache.php: Added "wp_cache_gc" option Allow chance of garbage collection to be configurable. 2008-07-14 10:06 donncha * readme.txt: If caching doesn't work, it could be advanced-cache.php 2008-07-14 09:53 donncha * wp-cache.php: Added Subscribe To Comments exclusion rewrite rule 2008-07-14 09:52 donncha * wp-cache.php: Warn if wp-content is writable, props alexleonard, http://wordpress.org/support/topic/188530 2008-07-08 10:41 donncha * wp-cache-phase2.php: Remove extra pages generated at the current permalink. ie. paged comments. 2008-06-20 16:16 donncha * wp-cache.php: Only need the config file writable to change it 2008-06-16 09:08 donncha * wp-cache-phase2.php: Increase the chance of expired file cleanup 2008-06-16 09:07 donncha * wp-cache-phase2.php: Warn if page is a 404 or not complete and won't be cached 2008-06-12 09:53 donncha * readme.txt: Add troubleshooting message for Dreamhost users 2008-05-26 09:12 donncha * wp-cache-phase2.php: Use [] instead of {} for array indexes Fix warning notices 2008-05-14 16:22 donncha * Changelog.txt: Updated changelog 2008-05-14 16:19 donncha * readme.txt, wp-cache-phase2.php, wp-cache.php: Remove comment. Bump version number 2008-05-14 12:21 donncha * wp-cache-phase2.php: Clean up the supercache if no post_id is defined 2008-05-14 12:11 donncha * wp-cache.php: Move menu code up 2008-05-13 14:57 donncha * wp-cache-phase2.php: Only prune files in the supercache directory Remove expired files 1/500's of the time 2008-05-11 08:51 donncha * wp-cache.php: Allow the "digg proof" message to be styled Removed whitespace 2008-05-05 09:49 donncha * wp-cache-phase1.php: Removed Last-Modified header so plugin works on godaddy servers. props Brad @ http://www.littleredrails.com/blog/2007/09/08/using-wp-cache-on-godaddy-500-error/ 2008-05-05 09:44 donncha * readme.txt, wp-cache.php: Added rewrite rules to stop POST requests to html static files. props eharris @ http://wordpress.org/support/topic/173972?replies=2 2008-04-24 19:14 donncha * Changelog.txt: Update Changelog 2008-04-24 19:14 donncha * readme.txt: Added changelog link Added attachment_id mod_rewrite rule 2008-04-24 19:11 donncha * Changelog.txt: Updated Changelog 2008-04-24 19:09 donncha * readme.txt, wp-cache.php: Bump the version number 2008-04-24 15:45 donncha * wp-cache-phase2.php: Put "could not write" message in a HTML comment at the end of the current page. 2008-04-20 07:48 donncha * wp-cache.php: Use blog charset for encoding. Don't supercache attachment pages, props Callum 2008-04-17 09:23 donncha * wp-cache.php: Make sure files are served as UTF-8, props tanguillo and nikolayb http://wordpress.org/support/topic/169540?replies=3 2008-04-12 07:06 donncha * Changelog.txt: Updated changelog 2008-04-12 07:05 donncha * readme.txt, wp-cache.php: Bump version number and update .htaccess example code 2008-04-11 23:30 donncha * wp-cache-phase1.php, wp-cache-phase2.php: Remove "index.php" from cached file paths 2008-04-11 23:17 donncha * wp-cache-config-sample.php, wp-cache.php: Add index.php to list of not to be cached pages Minor typo fix 2008-04-08 09:51 donncha * wp-cache.php: Delete all contents of cache dir, not just supercachedir when caching disabled. 2008-04-04 11:59 donncha * wp-cache.php: wp_specialchars the rules 2008-04-01 11:31 donncha * wp-cache.php: Added wpsc_remove_marker() to remove WordPress rewrite rules Super Cache rules now go in the WPSuperCache marker Check for comment cookie in one line, props askapache 2008-03-31 08:42 donncha * wp-cache.php: wp_specialchars() the mod_rewrite rules, props Viper007Bond 2008-03-30 10:42 donncha * readme.txt, wp-cache.php: Bump the version numbers 2008-03-30 10:41 donncha * Changelog.txt: Updated changelog 2008-03-30 10:41 donncha * wp-cache.php: Warn if mod_rewrite rules are out of date and encourage user to remove or update them manually 2008-03-30 10:26 donncha * Changelog.txt: Updated changelog 2008-03-28 17:37 donncha * wp-cache.php: Login cookie got shortened to "wordpress" in 2.5, still backwards compatible 2008-03-28 17:22 donncha * wp-cache.php: Move toggleLayer js around 2008-03-13 11:37 donncha * readme.txt, wp-cache.php: Bump to 0.6 2008-03-13 11:34 donncha * readme.txt: Added compression FAQ 2008-03-13 11:28 donncha * wp-cache.php: Only require mod_rewrite if super cache is enabled Hide super cache parts of page when not activated Add "/" to mod_rewrite rules for URLs not ending in a /, props Michael R Aulia @ http://www.michaelaulia.com/blogs/ 2008-03-13 11:25 donncha * readme.txt: Updated documentation 2008-03-12 18:55 donncha * wp-cache-phase2.php: This somehow stops PHP creating directories in the root folder, thanks to Cherie and Jennifer for their invaluable help! 2008-03-12 17:00 donncha * wp-cache.php: No need for this message any more 2008-03-11 13:04 donncha * wp-cache.php: Don't auto update .htaccess until user wants to. Hide listing of cached files, it's wrong anyway. Move advanced features to the end of backend page. 2008-02-11 20:52 donncha * readme.txt, wp-cache.php: You must define things before loading WordPress! (props s2j @ http://wordpress.org/support/topic/154996?replies=12#post-691402 ) 2008-02-08 10:27 donncha * wp-cache.php: Remember to delete compressed files from directly cached folders, props John Pozadzides 2008-01-16 12:14 donncha * Changelog.txt: Update changelog 2008-01-16 12:13 donncha * readme.txt, wp-cache.php: Bump version number Make admin page readonly if configuration page cannot be written to 2008-01-04 11:23 donncha * Changelog.txt, readme.txt, wp-cache.php: Bump version and update changelog 2008-01-04 11:22 donncha * wp-cache.php: Only update the hello_world option when updating the right form 2008-01-04 10:41 donncha * readme.txt, wp-cache.php: Bump version number 2008-01-04 10:40 donncha * wp-cache.php: Rearrange .htaccess generator. Allow mod_rewrite rules to be viewed later Only create wp-content/cache/.htaccess if it doesn't exist 2008-01-04 10:16 donncha * wp-cache.php: Added Super Cache footer message 2008-01-03 22:29 donncha * wp-cache.php: More fixes for sub directory blogs, props Otto42 - http://wordpress.org/support/topic/146443?replies=9#post-664254 2007-12-16 11:07 donncha * wp-cache.php: Warn if ABSPATH is writeable Add $home_root to cached files path in rewrite rules make mod_rewrite module warning more verbose 2007-12-09 07:39 donncha * wp-cache-phase2.php: Hide unlink errors 2007-12-04 10:18 donncha * wp-cache-phase2.php: Check that mutex is set, http://wordpress.org/support/topic/146052?replies=4 2007-11-28 11:29 donncha * wp-cache-phase2.php, wp-cache.php: Check that $entries is not empty Don't ever recurse from ABSPATH up 2007-11-26 11:33 donncha * Changelog.txt: Updated changelog 2007-11-26 11:32 donncha * wp-cache.php: It's WPLOCKDOWN 2007-11-26 11:31 donncha * Changelog.txt: Updated Changelog 2007-11-26 11:30 donncha * readme.txt, wp-cache.php: Bump the version number Docs for lockdown 2007-11-26 11:17 donncha * wp-cache.php: Bumpy bumpy 2007-11-26 11:12 donncha * Changelog.txt: Updated Changelog 2007-11-26 11:11 donncha * readme.txt: Bump version 2007-11-26 11:07 donncha * readme.txt: Warn about safe mode 2007-11-26 10:56 donncha * wp-cache.php: Print a warning message if PHP safe mode is enabled. Super Cache plugins will fail silently if advanced-cache.php is not loaded Updated "Directly Cached Files" text 2007-11-16 21:56 donncha * plugins/searchengine.php, wp-cache-phase1.php, wp-cache-phase2.php, wp-cache.php: Added » Updated formatting of admin backend Added "direct caching" of pages. 2007-11-12 21:23 donncha * wp-cache-phase2.php, wp-cache.php: PHP 5's mkdir() doesn't like slashes, http://ie2.php.net/manual/en/function.mkdir.php#73848 - props Tummmbler 2007-11-12 15:26 donncha * Changelog.txt: Updated changelog 2007-11-12 15:23 donncha * readme.txt, wp-cache.php: Bump version Update readme docs Add options page for wpmu site admins 2007-11-12 11:32 donncha * wp-cache.php: Check if cache config file is out of date 2007-11-12 11:14 donncha * wp-cache-phase2.php, wp-cache.php: Hide some warning messages Don't super cache $_GET requests Use wp_mkdir_p() instead of mkpath() Don't delete meta, supercache or .htaccess 2007-11-11 10:05 donncha * wp-cache.php: Don't want to check for .gz files twice! 2007-11-11 08:06 donncha * wp-cache.php: Added 'comment moderation' message when blog locked down. Formatting changes Use 'manage_options' instead of administrator because viper changed his role names :) 2007-11-11 01:13 donncha * wp-cache.php: If .htaccess updating fails, inform the user 2007-11-11 00:20 donncha * wp-cache-phase2.php, wp-cache.php: Added "Lockdown" function so static files won't be deleted by comments Minor changes to admin page formatting get_settings to get_option 2007-11-10 21:06 donncha * wp-cache.php: Spell out radio boxes a bit more. Modified .htaccess rules so search pages aren't served from super cache Actually insert_with_markers instead of echoing the command! Tell user rules have been updated Disable super cache *before* renaming directory. Sleep for a second before deleting to allow other processes to finish 2007-11-10 20:03 donncha * wp-cache-phase2.php: Make sure the .htaccess isn't deleted 2007-11-10 09:28 donncha * wp-cache-phase2.php: Don't remove super-cache file until comment is approved 2007-11-10 07:19 donncha * wp-cache.php: Check that WP_CACHE is defined before checking for do_cacheaction. Better instructions for verifying a new install 2007-11-09 21:33 donncha * wp-cache.php: Define WPCACHEHOME properly, thanks tummbler for testing! 2007-11-09 17:09 donncha * wp-cache-phase2.php: Don't super-cache WordPress searches. May need to extend that to any GET activity 2007-11-09 15:01 donncha * wp-cache-phase2.php: Change preg_match delimiter so slashes work again 2007-11-09 14:41 donncha * readme.txt: Updated documentation 2007-11-09 14:27 donncha * wp-cache.php: Use get_mod_rewrite() to detect if that module is loaded Automatically populate the .htaccess file if it's writable Add gzip encoding rules to the cache dir, props Dennis @ http://allmybrain.com/2007/11/08/making-wp-super-cache-gzip-compression-work/ Replace Windows folder deliminator, "\" with "/" in WPCACHEHOME, props Computer Guru @ http://neosmart.net/blog/2007/getting-wordpress-super-cache-to-run-on-a-windows-iis-or-apache-server/ 2007-11-09 01:19 donncha * wp-cache-phase2.php: Move is_feed() check earlier. Check that mkpath() path is in $cache_path 2007-11-08 21:57 donncha * wp-cache.php: Single quote ABSPATH Check advanced-cache.php for version, remove if necessary, fixed create conditions 2007-11-08 21:55 donncha * wp-cache-phase1.php: realpath() two filenames 2007-11-08 21:53 donncha * readme.txt: Fix subdirectory .htaccess rules, props Computer Guru 2007-11-08 21:51 donncha * plugins/searchengine.php: Hide setcookie errors Return correct string 2007-11-07 15:38 donncha * Changelog.txt: Added Changelog.txt 2007-11-07 15:27 donncha * readme.txt: Bump version to 0.3.1 (getting to 1.0 far too quickly!) Change formatting again 2007-11-07 15:26 donncha * wp-cache.php: Bump version to 0.3.1 2007-11-07 15:26 donncha * wp-cache-config-sample.php, wp-cache-phase2.php: Use preg_match() to match rejected URIs. Change "wp-" to "wp-.*.php" to match files and paths starting with "wp-" and ending in "php" 2007-11-07 11:56 donncha * wp-cache.php: Bump the version number 2007-11-06 22:50 donncha * readme.txt: Bump version 2007-11-06 22:18 donncha * wp-cache-phase2.php: Fix feed content-type, props Dougal, (http://dougal.gunters.org/blog/2007/06/19/wp-cache-fix-for-content-type-in-feeds) 2007-11-06 22:15 donncha * wp-cache.php: Check the do_cacheaction() exists Copy file if symlink is not found 2007-11-06 21:44 donncha * wp-cache.php: Move WP Super Cache to "Site Admin" menu on WordPress MU, http://www.darcynorman.net/2007/11/06/wordpress-super-cache/ 2007-11-06 21:19 donncha * wp-cache-phase1.php: Don't compress WP-Cache data files is PHP is already doing it 2007-11-06 10:29 donncha * readme.txt: Minor typo in tag 2007-11-06 10:06 donncha * readme.txt, wp-cache-phase1.php, wp-cache-phase2.php, wp-cache.php: Bump the version to 0.2 Enable gzip support in WP-Cache data files, fix feed content type, props tummbler: http://www.tummblr.com/wordpress/improving-wp-super-cache-gzip-for-logged-in-users/ http://elliottback.com/wp/archives/2005/07/12/getting-wp-cache-to-work/ http://blog.saddey.net/2007/02/18/how-to-prevent-wpcache-from-changing-a-feeds-content-type-to-text-html/ When Super Cache is disabled, still write to WP-Cache files Check that prune_super_cache() exists before calling it in wp-cache.php, props Dougal 2007-11-06 09:06 donncha * readme.txt: Fix line endings 2007-11-05 18:41 donncha * wp-cache.php: Fixed display of "compression changed" message 2007-11-05 18:06 donncha * readme.txt: Convert to DOS mode reformat lists for display on wporg 2007-11-05 17:25 donncha * readme.txt: Minor updates to the readme 2007-11-05 15:21 donncha * wp-cache.php: When disabling or enabling compression make sure the user knows about .htaccess 2007-11-05 15:11 donncha * wp-cache-phase2.php: Rejected URIs must have .php in them now so pages starting with "wp-" will be cached 2007-11-05 15:10 donncha * wp-cache.php: When disabling supercache, make sure wpcache is enabled. Avoid resetting cache_compression when submitting other forms Reset supercache meta cache when compression modified 2007-11-05 14:54 donncha * wp-cache-config-sample.php, wp-cache.php: Fix weirdness with radio buttons on admin page 2007-11-05 11:35 donncha * plugins, plugins/searchengine.php, readme.txt, wp-cache-base.php, wp-cache-config-sample.php, wp-cache-phase1.php, wp-cache-phase2.php, wp-cache.php: Initial import of WP Super Cache 2007-10-23 20:02 plugin-master * wp-super-cache, wp-super-cache/branches, wp-super-cache/tags, .: adding wp-super-cache by donncha wp-super-cache/min/0000755000076500007650000000000011157407116013765 5ustar jhardijhardiwp-super-cache/min/.htaccess0000644000076500007650000000014311064517524015563 0ustar jhardijhardi RewriteEngine on RewriteRule ^([a-z]=.*) index.php?$1 [L,NE] wp-super-cache/min/builder/0000755000076500007650000000000011157407116015413 5ustar jhardijhardiwp-super-cache/min/builder/_index.js0000644000076500007650000002051211066526152017220 0ustar jhardijhardivar MUB = { _uid : 0 ,_minRoot : '/min/?' ,checkRewrite : function () { var testUri = location.pathname.replace(/\/[^\/]*$/, '/rewriteTest.js').substr(1); function fail() { $('#minRewriteFailed')[0].className = 'topNote'; }; $.ajax({ url : '../f=' + testUri + '&' + (new Date()).getTime() ,success : function (data) { if (data === '1') { MUB._minRoot = '/min/'; $('span.minRoot').html('/min/'); } else fail(); } ,error : fail }); } /** * Get markup for new source LI element */ ,newLi : function () { return '
  • http://' + location.host + '/' + ' ' + '
  • '; } /** * Add new empty source LI and attach handlers to buttons */ ,addLi : function () { $('#sources').append(MUB.newLi()); var li = $('#li' + MUB._uid)[0]; $('button[title=Remove]', li).click(function () { $('#results').hide(); var hadValue = !!$('input', li)[0].value; $(li).remove(); }); $('button[title$=Earlier]', li).click(function () { $(li).prev('li').find('input').each(function () { $('#results').hide(); // this = previous li input var tmp = this.value; this.value = $('input', li).val(); $('input', li).val(tmp); MUB.updateAllTestLinks(); }); }); $('button[title$=Later]', li).click(function () { $(li).next('li').find('input').each(function () { $('#results').hide(); // this = next li input var tmp = this.value; this.value = $('input', li).val(); $('input', li).val(tmp); MUB.updateAllTestLinks(); }); }); ++MUB._uid; } /** * In the context of a source LI element, this will analyze the URI in * the INPUT and check the URL on the site. */ ,liUpdateTestLink : function () { // call in context of li element if (! $('input', this)[0].value) return; var li = this; $('span', this).html(''); var url = 'http://' + location.host + '/' + $('input', this)[0].value.replace(/^\//, ''); $.ajax({ url : url ,complete : function (xhr, stat) { if ('success' == stat) $('span', li).html('✓'); else { $('span', li).html('') .find('button').click(function () { MUB.liUpdateTestLink.call(li); }); } } ,dataType : 'text' }); } /** * Check all source URLs */ ,updateAllTestLinks : function () { $('#sources li').each(MUB.liUpdateTestLink); } /** * In a given array of strings, find the character they all have at * a particular index * @param Array arr array of strings * @param Number pos index to check * @return mixed a common char or '' if any do not match */ ,getCommonCharAtPos : function (arr, pos) { var i ,l = arr.length ,c = arr[0].charAt(pos); if (c === '' || l === 1) return c; for (i = 1; i < l; ++i) if (arr[i].charAt(pos) !== c) return ''; return c; } /** * Get the shortest URI to minify the set of source files * @param Array sources URIs */ ,getBestUri : function (sources) { var pos = 0 ,base = '' ,c; while (true) { c = MUB.getCommonCharAtPos(sources, pos); if (c === '') break; else base += c; ++pos; } base = base.replace(/[^\/]+$/, ''); var uri = MUB._minRoot + 'f=' + sources.join(','); if (base.charAt(base.length - 1) === '/') { // we have a base dir! var basedSources = sources ,i ,l = sources.length; for (i = 0; i < l; ++i) { basedSources[i] = sources[i].substr(base.length); } base = base.substr(0, base.length - 1); var bUri = MUB._minRoot + 'b=' + base + '&f=' + basedSources.join(','); //window.console && console.log([uri, bUri]); uri = uri.length < bUri.length ? uri : bUri; } return uri; } /** * Create the Minify URI for the sources */ ,update : function () { MUB.updateAllTestLinks(); var sources = [] ,ext = false ,fail = false; $('#sources input').each(function () { var m, val; if (! fail && this.value && (m = this.value.match(/\.(css|js)$/))) { var thisExt = m[1]; if (ext === false) ext = thisExt; else if (thisExt !== ext) { fail = true; return alert('extensions must match!'); } this.value = this.value.replace(/^\//, ''); if (-1 != $.inArray(this.value, sources)) { fail = true; return alert('duplicate file!'); } sources.push(this.value); } }); if (fail || ! sources.length) return; $('#groupConfig').val(" 'keyName' => array('//" + sources.join("', '//") + "'),"); var uri = MUB.getBestUri(sources) ,uriH = uri.replace(//, '>').replace(/&/, '&'); $('#uriA').html(uriH)[0].href = uri; $('#uriHtml').val( ext === 'js' ? '' : '' ); $('#results').show(); } /** * Handler for the "Add file +" button */ ,addButtonClick : function () { $('#results').hide(); MUB.addLi(); MUB.updateAllTestLinks(); $('#update').show().click(MUB.update); $('#sources li:last input')[0].focus(); } /** * Runs on DOMready */ ,init : function () { $('#app').show(); $('#sources').html(''); $('#add button').click(MUB.addButtonClick); // make easier to copy text out of $('#uriHtml, #groupConfig').click(function () { this.select(); }).focus(function () { this.select(); }); $('a.ext').attr({target:'_blank'}); if (location.hash) { // make links out of URIs from bookmarklet $('#getBm').hide(); $('#bmUris').html('

    Found by bookmarklet: /' + location.hash.substr(1).split(',').join(' | /') + '

    ' ); $('#bmUris a').click(function () { MUB.addButtonClick(); $('#sources li:last input').val(this.innerHTML) MUB.liUpdateTestLink.call($('#sources li:last')[0]); $('#results').hide(); return false; }).attr({title:'Add file +'}); } else { // copy bookmarklet code into href var bmUri = location.pathname.replace(/\/[^\/]*$/, '/bm.js').substr(1); $.ajax({ url : '../?f=' + bmUri ,success : function (code) { $('#bm')[0].href = code .replace('%BUILDER_URL%', location.href) .replace(/\n/g, ' '); } ,dataType : 'text' }); $.browser.msie && $('#getBm p:last').append(' Sorry, not supported in MSIE!'); MUB.addButtonClick(); } MUB.checkRewrite(); } }; window.onload = MUB.init;wp-super-cache/min/builder/bm.js0000644000076500007650000000265111063050546016350 0ustar jhardijhardijavascript:(function() { var d = document ,uris = [] ,i = 0 ,o ,home = (location + '').split('/').splice(0, 3).join('/') + '/'; function add(uri) { return (0 === uri.indexOf(home)) && (!/[\?&]/.test(uri)) && uris.push(escape(uri.substr(home.length))); }; function sheet(ss) { // we must check the domain with add() before accessing ss.cssRules // otherwise a security exception will be thrown if (ss.href && add(ss.href) && ss.cssRules) { var i = 0, r; while (r = ss.cssRules[i++]) r.styleSheet && sheet(r.styleSheet); } }; while (o = d.getElementsByTagName('script')[i++]) o.src && !(o.type && /vbs/i.test(o.type)) && add(o.src); i = 0; while (o = d.styleSheets[i++]) /* http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-DocumentStyle-styleSheets document.styleSheet is a list property where [0] accesses the 1st element and [outOfRange] returns null. In IE, styleSheets is a function, and also throws an exception when you check the out of bounds index. (sigh) */ sheet(o); if (uris.length) window.open('%BUILDER_URL%#' + uris.join(',')); else alert('No js/css files found with URLs within "' + home.split('/')[2] + '".\n(This tool is limited to URLs with the same domain.)'); })();wp-super-cache/min/builder/index.php0000644000076500007650000001525011122006010017212 0ustar jhardijhardi Minify URI Builder

    Note: Please set $min_cachePath in /min/config.php to improve performance.

    Note: Your webserver does not seem to support mod_rewrite (used in /min/.htaccess). Your Minify URIs will contain "?", which may reduce the benefit of proxy cache servers.

    Minify URI Builder

    Create a list of Javascript or CSS files (or 1 is fine) you'd like to combine and click [Update].

    Minify URI

    Place this URI in your HTML to serve the files above combined, minified, compressed and with cache headers.

    URI/min (opens in new window)
    HTML

    How to serve these files as a group

    For the best performance you can serve these files as a pre-defined group with a URI like: /min/?g=keyName

    To do this, add a line like this to /min/groupsConfig.php:

    return array(
        ... your existing groups here ...
    
    );

    Make sure to replace keyName with a unique key for this group.

    Find URIs on a Page

    You can use the bookmarklet below to fetch all CSS & Javascript URIs from a page on your site. When you active it, this page will open in a new window with a list of available URIs to add.

    Create Minify URIs (right-click, add to bookmarks)

    Combining CSS files that contain @import

    If your CSS files contain @import declarations, Minify will not remove them. Therefore, you will want to remove those that point to files already in your list, and move any others to the top of the first file in your list (imports below any styles will be ignored by browsers as invalid).

    If you desire, you can use Minify URIs in imports and they will not be touched by Minify. E.g. @import "/min/?g=css2";


    Need help? Search or post to the Minify discussion list.

    This app is minified :) view source

    ob_get_contents() ,'id' => __FILE__ ,'lastModifiedTime' => max( // regenerate cache if either of these change filemtime(__FILE__) ,filemtime(dirname(__FILE__) . '/../config.php') ) ,'minifyAll' => true ,'encodeOutput' => $encodeOutput ); ob_end_clean(); set_include_path(dirname(__FILE__) . '/../lib' . PATH_SEPARATOR . get_include_path()); require 'Minify.php'; if (0 === stripos(PHP_OS, 'win')) { Minify::setDocRoot(); // we may be on IIS } Minify::setCache(isset($min_cachePath) ? $min_cachePath : null); Minify::$uploaderHoursBehind = $min_uploaderHoursBehind; Minify::serve('Page', $serveOpts); wp-super-cache/min/builder/ocCheck.php0000644000076500007650000000144411072763364017474 0ustar jhardijhardi 'World!' ,'method' => 'deflate' )); $he->encode(); $he->sendAll(); } else { // echo status "0" or "1" header('Content-Type: text/plain'); echo (int)$_oc; } wp-super-cache/min/builder/rewriteTest.js0000644000076500007650000000000111063050546020256 0ustar jhardijhardi1wp-super-cache/min/config.php0000644000076500007650000001207111152621206015735 0ustar jhardijhardi * array('//symlink' => '/real/target/path') // unix * array('//static' => 'D:\\staticStorage') // Windows * */ $min_symlinks = array(); /** * If you upload files from Windows to a non-Windows server, Windows may report * incorrect mtimes for the files. This may cause Minify to keep serving stale * cache files when source file changes are made too frequently (e.g. more than * once an hour). * * Immediately after modifying and uploading a file, use the touch command to * update the mtime on the server. If the mtime jumps ahead by a number of hours, * set this variable to that number. If the mtime moves back, this should not be * needed. * * In the Windows SFTP client WinSCP, there's an option that may fix this * issue without changing the variable below. Under login > environment, * select the option "Adjust remote timestamp with DST". * @link http://winscp.net/eng/docs/ui_login_environment#daylight_saving_time */ $min_uploaderHoursBehind = 0; /** * Path to Minify's lib folder. If you happen to move it, change * this accordingly. */ $min_libPath = dirname(__FILE__) . '/lib'; // try to disable output_compression (may not have an effect) ini_set('zlib.output_compression', '0'); wp-super-cache/min/groupsConfig.php0000644000076500007650000000203611122006010017120 0ustar jhardijhardi array('//js/file1.js', '//js/file2.js'), // 'css' => array('//css/file1.css', '//css/file2.css'), // custom source example /*'js2' => array( dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', // do NOT process this file new Minify_Source(array( 'filepath' => dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', 'minifier' => create_function('$a', 'return $a;') )) ),//*/ /*'js3' => array( dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', // do NOT process this file new Minify_Source(array( 'filepath' => dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', 'minifier' => array('Minify_Packer', 'minify') )) ),//*/ );wp-super-cache/min/index.php0000644000076500007650000000356011153553666015621 0ustar jhardijhardi $target) { $link = str_replace('//', realpath($_SERVER['DOCUMENT_ROOT']), $link); $link = strtr($link, '/', DIRECTORY_SEPARATOR); $min_serveOptions['minifierOptions']['text/css']['symlinks'][$link] = realpath($target); } if ($min_allowDebugFlag && isset($_GET['debug'])) { $min_serveOptions['debug'] = true; } if ($min_errorLogger) { require_once 'Minify/Logger.php'; if (true === $min_errorLogger) { require_once 'FirePHP.php'; Minify_Logger::setLogger(FirePHP::getInstance(true)); } else { Minify_Logger::setLogger($min_errorLogger); } } // check for URI versioning if (preg_match('/&\\d/', $_SERVER['QUERY_STRING'])) { $min_serveOptions['maxAge'] = 31536000; } if (isset($_GET['g'])) { // well need groups config $min_serveOptions['minApp']['groups'] = (require MINIFY_MIN_DIR . '/groupsConfig.php'); } if (isset($_GET['f']) || isset($_GET['g'])) { // serve! Minify::serve('MinApp', $min_serveOptions); } elseif ($min_enableBuilder) { header('Location: builder/'); exit(); } else { header("Location: /"); exit(); } wp-super-cache/min/lib/0000755000076500007650000000000011157407116014533 5ustar jhardijhardiwp-super-cache/min/lib/FirePHP.php0000644000076500007650000012514611137165164016514 0ustar jhardijhardi * @license http://www.opensource.org/licenses/bsd-license.php * @package FirePHP */ /** * Sends the given data to the FirePHP Firefox Extension. * The data can be displayed in the Firebug Console or in the * "Server" request tab. * * For more information see: http://www.firephp.org/ * * @copyright Copyright (C) 2007-2008 Christoph Dorn * @author Christoph Dorn * @license http://www.opensource.org/licenses/bsd-license.php * @package FirePHP */ class FirePHP { /** * FirePHP version * * @var string */ const VERSION = '0.2.0'; /** * Firebug LOG level * * Logs a message to firebug console. * * @var string */ const LOG = 'LOG'; /** * Firebug INFO level * * Logs a message to firebug console and displays an info icon before the message. * * @var string */ const INFO = 'INFO'; /** * Firebug WARN level * * Logs a message to firebug console, displays an warning icon before the message and colors the line turquoise. * * @var string */ const WARN = 'WARN'; /** * Firebug ERROR level * * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count. * * @var string */ const ERROR = 'ERROR'; /** * Dumps a variable to firebug's server panel * * @var string */ const DUMP = 'DUMP'; /** * Displays a stack trace in firebug console * * @var string */ const TRACE = 'TRACE'; /** * Displays an exception in firebug console * * Increments the firebug error count. * * @var string */ const EXCEPTION = 'EXCEPTION'; /** * Displays an table in firebug console * * @var string */ const TABLE = 'TABLE'; /** * Starts a group in firebug console * * @var string */ const GROUP_START = 'GROUP_START'; /** * Ends a group in firebug console * * @var string */ const GROUP_END = 'GROUP_END'; /** * Singleton instance of FirePHP * * @var FirePHP */ protected static $instance = null; /** * Wildfire protocol message index * * @var int */ protected $messageIndex = 1; /** * Options for the library * * @var array */ protected $options = array(); /** * Filters used to exclude object members when encoding * * @var array */ protected $objectFilters = array(); /** * A stack of objects used to detect recursion during object encoding * * @var object */ protected $objectStack = array(); /** * Flag to enable/disable logging * * @var boolean */ protected $enabled = true; /** * The object constructor */ function __construct() { $this->options['maxObjectDepth'] = 10; $this->options['maxArrayDepth'] = 20; $this->options['useNativeJsonEncode'] = true; $this->options['includeLineNumbers'] = true; } /** * When the object gets serialized only include specific object members. * * @return array */ public function __sleep() { return array('options','objectFilters','enabled'); } /** * Gets singleton instance of FirePHP * * @param boolean $AutoCreate * @return FirePHP */ public static function getInstance($AutoCreate=false) { if($AutoCreate===true && !self::$instance) { self::init(); } return self::$instance; } /** * Creates FirePHP object and stores it for singleton access * * @return FirePHP */ public static function init() { return self::$instance = new self(); } /** * Enable and disable logging to Firebug * * @param boolean $Enabled TRUE to enable, FALSE to disable * @return void */ public function setEnabled($Enabled) { $this->enabled = $Enabled; } /** * Check if logging is enabled * * @return boolean TRUE if enabled */ public function getEnabled() { return $this->enabled; } /** * Specify a filter to be used when encoding an object * * Filters are used to exclude object members. * * @param string $Class The class name of the object * @param array $Filter An array or members to exclude * @return void */ public function setObjectFilter($Class, $Filter) { $this->objectFilters[$Class] = $Filter; } /** * Set some options for the library * * Options: * - maxObjectDepth: The maximum depth to traverse objects (default: 10) * - maxArrayDepth: The maximum depth to traverse arrays (default: 20) * - useNativeJsonEncode: If true will use json_encode() (default: true) * - includeLineNumbers: If true will include line numbers and filenames (default: true) * * @param array $Options The options to be set * @return void */ public function setOptions($Options) { $this->options = array_merge($this->options,$Options); } /** * Register FirePHP as your error handler * * Will throw exceptions for each php error. */ public function registerErrorHandler() { //NOTE: The following errors will not be caught by this error handler: // E_ERROR, E_PARSE, E_CORE_ERROR, // E_CORE_WARNING, E_COMPILE_ERROR, // E_COMPILE_WARNING, E_STRICT set_error_handler(array($this,'errorHandler')); } /** * FirePHP's error handler * * Throws exception for each php error that will occur. * * @param int $errno * @param string $errstr * @param string $errfile * @param int $errline * @param array $errcontext */ public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) { // Don't throw exception if error reporting is switched off if (error_reporting() == 0) { return; } // Only throw exceptions for errors we are asking for if (error_reporting() & $errno) { throw new ErrorException($errstr, 0, $errno, $errfile, $errline); } } /** * Register FirePHP as your exception handler */ public function registerExceptionHandler() { set_exception_handler(array($this,'exceptionHandler')); } /** * FirePHP's exception handler * * Logs all exceptions to your firebug console and then stops the script. * * @param Exception $Exception * @throws Exception */ function exceptionHandler($Exception) { $this->fb($Exception); } /** * Set custom processor url for FirePHP * * @param string $URL */ public function setProcessorUrl($URL) { $this->setHeader('X-FirePHP-ProcessorURL', $URL); } /** * Set custom renderer url for FirePHP * * @param string $URL */ public function setRendererUrl($URL) { $this->setHeader('X-FirePHP-RendererURL', $URL); } /** * Start a group for following messages * * @param string $Name * @return true * @throws Exception */ public function group($Name) { return $this->fb(null, $Name, FirePHP::GROUP_START); } /** * Ends a group you have started before * * @return true * @throws Exception */ public function groupEnd() { return $this->fb(null, null, FirePHP::GROUP_END); } /** * Log object with label to firebug console * * @see FirePHP::LOG * @param mixes $Object * @param string $Label * @return true * @throws Exception */ public function log($Object, $Label=null) { return $this->fb($Object, $Label, FirePHP::LOG); } /** * Log object with label to firebug console * * @see FirePHP::INFO * @param mixes $Object * @param string $Label * @return true * @throws Exception */ public function info($Object, $Label=null) { return $this->fb($Object, $Label, FirePHP::INFO); } /** * Log object with label to firebug console * * @see FirePHP::WARN * @param mixes $Object * @param string $Label * @return true * @throws Exception */ public function warn($Object, $Label=null) { return $this->fb($Object, $Label, FirePHP::WARN); } /** * Log object with label to firebug console * * @see FirePHP::ERROR * @param mixes $Object * @param string $Label * @return true * @throws Exception */ public function error($Object, $Label=null) { return $this->fb($Object, $Label, FirePHP::ERROR); } /** * Dumps key and variable to firebug server panel * * @see FirePHP::DUMP * @param string $Key * @param mixed $Variable * @return true * @throws Exception */ public function dump($Key, $Variable) { return $this->fb($Variable, $Key, FirePHP::DUMP); } /** * Log a trace in the firebug console * * @see FirePHP::TRACE * @param string $Label * @return true * @throws Exception */ public function trace($Label) { return $this->fb($Label, FirePHP::TRACE); } /** * Log a table in the firebug console * * @see FirePHP::TABLE * @param string $Label * @param string $Table * @return true * @throws Exception */ public function table($Label, $Table) { return $this->fb($Table, $Label, FirePHP::TABLE); } /** * Check if FirePHP is installed on client * * @return boolean */ public function detectClientExtension() { /* Check if FirePHP is installed on client */ if(!@preg_match_all('/\sFirePHP\/([\.|\d]*)\s?/si',$this->getUserAgent(),$m) || !version_compare($m[1][0],'0.0.6','>=')) { return false; } return true; } /** * Log varible to Firebug * * @see http://www.firephp.org/Wiki/Reference/Fb * @param mixed $Object The variable to be logged * @return true Return TRUE if message was added to headers, FALSE otherwise * @throws Exception */ public function fb($Object) { if(!$this->enabled) { return false; } if (headers_sent($filename, $linenum)) { throw $this->newException('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); } $Type = null; $Label = null; if(func_num_args()==1) { } else if(func_num_args()==2) { switch(func_get_arg(1)) { case self::LOG: case self::INFO: case self::WARN: case self::ERROR: case self::DUMP: case self::TRACE: case self::EXCEPTION: case self::TABLE: case self::GROUP_START: case self::GROUP_END: $Type = func_get_arg(1); break; default: $Label = func_get_arg(1); break; } } else if(func_num_args()==3) { $Type = func_get_arg(2); $Label = func_get_arg(1); } else { throw $this->newException('Wrong number of arguments to fb() function!'); } if(!$this->detectClientExtension()) { return false; } $meta = array(); $skipFinalObjectEncode = false; if($Object instanceof Exception) { $meta['file'] = $this->_escapeTraceFile($Object->getFile()); $meta['line'] = $Object->getLine(); $trace = $Object->getTrace(); if($Object instanceof ErrorException && isset($trace[0]['function']) && $trace[0]['function']=='errorHandler' && isset($trace[0]['class']) && $trace[0]['class']=='FirePHP') { $severity = false; switch($Object->getSeverity()) { case E_WARNING: $severity = 'E_WARNING'; break; case E_NOTICE: $severity = 'E_NOTICE'; break; case E_USER_ERROR: $severity = 'E_USER_ERROR'; break; case E_USER_WARNING: $severity = 'E_USER_WARNING'; break; case E_USER_NOTICE: $severity = 'E_USER_NOTICE'; break; case E_STRICT: $severity = 'E_STRICT'; break; case E_RECOVERABLE_ERROR: $severity = 'E_RECOVERABLE_ERROR'; break; case E_DEPRECATED: $severity = 'E_DEPRECATED'; break; case E_USER_DEPRECATED: $severity = 'E_USER_DEPRECATED'; break; } $Object = array('Class'=>get_class($Object), 'Message'=>$severity.': '.$Object->getMessage(), 'File'=>$this->_escapeTraceFile($Object->getFile()), 'Line'=>$Object->getLine(), 'Type'=>'trigger', 'Trace'=>$this->_escapeTrace(array_splice($trace,2))); $skipFinalObjectEncode = true; } else { $Object = array('Class'=>get_class($Object), 'Message'=>$Object->getMessage(), 'File'=>$this->_escapeTraceFile($Object->getFile()), 'Line'=>$Object->getLine(), 'Type'=>'throw', 'Trace'=>$this->_escapeTrace($trace)); $skipFinalObjectEncode = true; } $Type = self::EXCEPTION; } else if($Type==self::TRACE) { $trace = debug_backtrace(); if(!$trace) return false; for( $i=0 ; $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ } else if(isset($trace[$i]['class']) && isset($trace[$i+1]['file']) && $trace[$i]['class']=='FirePHP' && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { /* Skip fb() */ } else if($trace[$i]['function']=='fb' || $trace[$i]['function']=='trace' || $trace[$i]['function']=='send') { $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'', 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'', 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'', 'Message'=>$trace[$i]['args'][0], 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'', 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'', 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'', 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1))); $skipFinalObjectEncode = true; $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; break; } } } else if($Type==self::TABLE) { if(isset($Object[0]) && is_string($Object[0])) { $Object[1] = $this->encodeTable($Object[1]); } else { $Object = $this->encodeTable($Object); } $skipFinalObjectEncode = true; } else { if($Type===null) { $Type = self::LOG; } } if($this->options['includeLineNumbers']) { if(!isset($meta['file']) || !isset($meta['line'])) { $trace = debug_backtrace(); for( $i=0 ; $trace && $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ } else if(isset($trace[$i]['class']) && isset($trace[$i+1]['file']) && $trace[$i]['class']=='FirePHP' && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { /* Skip fb() */ } else if(isset($trace[$i]['file']) && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') { /* Skip FB::fb() */ } else { $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; break; } } } } else { unset($meta['file']); unset($meta['line']); } $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.self::VERSION); $structure_index = 1; if($Type==self::DUMP) { $structure_index = 2; $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); } else { $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); } if($Type==self::DUMP) { $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}'; } else { $msg_meta = array('Type'=>$Type); if($Label!==null) { $msg_meta['Label'] = $Label; } if(isset($meta['file'])) { $msg_meta['File'] = $meta['file']; } if(isset($meta['line'])) { $msg_meta['Line'] = $meta['line']; } $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']'; } $parts = explode("\n",chunk_split($msg, 5000, "\n")); for( $i=0 ; $i2) { // Message needs to be split into multiple parts $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, (($i==0)?strlen($msg):'') . '|' . $part . '|' . (($isetHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, strlen($part) . '|' . $part . '|'); } $this->messageIndex++; if ($this->messageIndex > 99999) { throw new Exception('Maximum number (99,999) of messages reached!'); } } } $this->setHeader('X-Wf-1-Index',$this->messageIndex-1); return true; } /** * Standardizes path for windows systems. * * @param string $Path * @return string */ protected function _standardizePath($Path) { return preg_replace('/\\\\+/','/',$Path); } /** * Escape trace path for windows systems * * @param array $Trace * @return array */ protected function _escapeTrace($Trace) { if(!$Trace) return $Trace; for( $i=0 ; $i_escapeTraceFile($Trace[$i]['file']); } if(isset($Trace[$i]['args'])) { $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']); } } return $Trace; } /** * Escape file information of trace for windows systems * * @param string $File * @return string */ protected function _escapeTraceFile($File) { /* Check if we have a windows filepath */ if(strpos($File,'\\')) { /* First strip down to single \ */ $file = preg_replace('/\\\\+/','\\',$File); return $file; } return $File; } /** * Send header * * @param string $Name * @param string_type $Value */ protected function setHeader($Name, $Value) { return header($Name.': '.$Value); } /** * Get user agent * * @return string|false */ protected function getUserAgent() { if(!isset($_SERVER['HTTP_USER_AGENT'])) return false; return $_SERVER['HTTP_USER_AGENT']; } /** * Returns a new exception * * @param string $Message * @return Exception */ protected function newException($Message) { return new Exception($Message); } /** * Encode an object into a JSON string * * Uses PHP's jeson_encode() if available * * @param object $Object The object to be encoded * @return string The JSON string */ protected function jsonEncode($Object, $skipObjectEncode=false) { if(!$skipObjectEncode) { $Object = $this->encodeObject($Object); } if(function_exists('json_encode') && $this->options['useNativeJsonEncode']!=false) { return json_encode($Object); } else { return $this->json_encode($Object); } } /** * Encodes a table by encoding each row and column with encodeObject() * * @param array $Table The table to be encoded * @return array */ protected function encodeTable($Table) { if(!$Table) return $Table; for( $i=0 ; $iencodeObject($Table[$i][$j]); } } } return $Table; } /** * Encodes an object including members with * protected and private visibility * * @param Object $Object The object to be encoded * @param int $Depth The current traversal depth * @return array All members of the object */ protected function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1) { $return = array(); if (is_object($Object)) { if ($ObjectDepth > $this->options['maxObjectDepth']) { return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **'; } foreach ($this->objectStack as $refVal) { if ($refVal === $Object) { return '** Recursion ('.get_class($Object).') **'; } } array_push($this->objectStack, $Object); $return['__className'] = $class = get_class($Object); $reflectionClass = new ReflectionClass($class); $properties = array(); foreach( $reflectionClass->getProperties() as $property) { $properties[$property->getName()] = $property; } $members = (array)$Object; foreach( $properties as $raw_name => $property ) { $name = $raw_name; if($property->isStatic()) { $name = 'static:'.$name; } if($property->isPublic()) { $name = 'public:'.$name; } else if($property->isPrivate()) { $name = 'private:'.$name; $raw_name = "\0".$class."\0".$raw_name; } else if($property->isProtected()) { $name = 'protected:'.$name; $raw_name = "\0".'*'."\0".$raw_name; } if(!(isset($this->objectFilters[$class]) && is_array($this->objectFilters[$class]) && in_array($raw_name,$this->objectFilters[$class]))) { if(array_key_exists($raw_name,$members) && !$property->isStatic()) { $return[$name] = $this->encodeObject($members[$raw_name], $ObjectDepth + 1, 1); } else { if(method_exists($property,'setAccessible')) { $property->setAccessible(true); $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1); } else if($property->isPublic()) { $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1); } else { $return[$name] = '** Need PHP 5.3 to get value **'; } } } else { $return[$name] = '** Excluded by Filter **'; } } // Include all members that are not defined in the class // but exist in the object foreach( $members as $raw_name => $value ) { $name = $raw_name; if ($name{0} == "\0") { $parts = explode("\0", $name); $name = $parts[2]; } if(!isset($properties[$name])) { $name = 'undeclared:'.$name; if(!(isset($this->objectFilters[$class]) && is_array($this->objectFilters[$class]) && in_array($raw_name,$this->objectFilters[$class]))) { $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1); } else { $return[$name] = '** Excluded by Filter **'; } } } array_pop($this->objectStack); } elseif (is_array($Object)) { if ($ArrayDepth > $this->options['maxArrayDepth']) { return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **'; } foreach ($Object as $key => $val) { // Encoding the $GLOBALS PHP array causes an infinite loop // if the recursion is not reset here as it contains // a reference to itself. This is the only way I have come up // with to stop infinite recursion in this case. if($key=='GLOBALS' && is_array($val) && array_key_exists('GLOBALS',$val)) { $val['GLOBALS'] = '** Recursion (GLOBALS) **'; } $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1); } } else { if(self::is_utf8($Object)) { return $Object; } else { return utf8_encode($Object); } } return $return; } /** * Returns true if $string is valid UTF-8 and false otherwise. * * @param mixed $str String to be tested * @return boolean */ protected static function is_utf8($str) { $c=0; $b=0; $bits=0; $len=strlen($str); for($i=0; $i<$len; $i++){ $c=ord($str[$i]); if($c > 128){ if(($c >= 254)) return false; elseif($c >= 252) $bits=6; elseif($c >= 248) $bits=5; elseif($c >= 240) $bits=4; elseif($c >= 224) $bits=3; elseif($c >= 192) $bits=2; else return false; if(($i+$bits) > $len) return false; while($bits > 1){ $i++; $b=ord($str[$i]); if($b < 128 || $b > 191) return false; $bits--; } } } return true; } /** * Converts to and from JSON format. * * JSON (JavaScript Object Notation) is a lightweight data-interchange * format. It is easy for humans to read and write. It is easy for machines * to parse and generate. It is based on a subset of the JavaScript * Programming Language, Standard ECMA-262 3rd Edition - December 1999. * This feature can also be found in Python. JSON is a text format that is * completely language independent but uses conventions that are familiar * to programmers of the C-family of languages, including C, C++, C#, Java, * JavaScript, Perl, TCL, and many others. These properties make JSON an * ideal data-interchange language. * * This package provides a simple encoder and decoder for JSON notation. It * is intended for use with client-side Javascript applications that make * use of HTTPRequest to perform server communication functions - data can * be encoded into JSON notation for use in a client-side javascript, or * decoded from incoming Javascript requests. JSON format is native to * Javascript, and can be directly eval()'ed with no further parsing * overhead * * All strings should be in ASCII or UTF-8 format! * * LICENSE: Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: Redistributions of source code must retain the * above copyright notice, this list of conditions and the following * disclaimer. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * @category * @package Services_JSON * @author Michal Migurski * @author Matt Knapp * @author Brett Stimmerman * @author Christoph Dorn * @copyright 2005 Michal Migurski * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ * @license http://www.opensource.org/licenses/bsd-license.php * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 */ /** * Keep a list of objects as we descend into the array so we can detect recursion. */ private $json_objectStack = array(); /** * convert a string from one UTF-8 char to one UTF-16 char * * Normally should be handled by mb_convert_encoding, but * provides a slower PHP-only method for installations * that lack the multibye string extension. * * @param string $utf8 UTF-8 character * @return string UTF-16 character * @access private */ private function json_utf82utf16($utf8) { // oh please oh please oh please oh please oh please if(function_exists('mb_convert_encoding')) { return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); } switch(strlen($utf8)) { case 1: // this case should never be reached, because we are in ASCII range // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return $utf8; case 2: // return a UTF-16 character from a 2-byte UTF-8 char // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0x07 & (ord($utf8{0}) >> 2)) . chr((0xC0 & (ord($utf8{0}) << 6)) | (0x3F & ord($utf8{1}))); case 3: // return a UTF-16 character from a 3-byte UTF-8 char // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr((0xF0 & (ord($utf8{0}) << 4)) | (0x0F & (ord($utf8{1}) >> 2))) . chr((0xC0 & (ord($utf8{1}) << 6)) | (0x7F & ord($utf8{2}))); } // ignoring UTF-32 for now, sorry return ''; } /** * encodes an arbitrary variable into JSON format * * @param mixed $var any number, boolean, string, array, or object to be encoded. * see argument 1 to Services_JSON() above for array-parsing behavior. * if var is a strng, note that encode() always expects it * to be in ASCII or UTF-8 format! * * @return mixed JSON string representation of input var or an error if a problem occurs * @access public */ private function json_encode($var) { if(is_object($var)) { if(in_array($var,$this->json_objectStack)) { return '"** Recursion **"'; } } switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT $ascii = ''; $strlen_var = strlen($var); /* * Iterate over every character in the string, * escaping with a slash or encoding to UTF-8 where necessary */ for ($c = 0; $c < $strlen_var; ++$c) { $ord_var_c = ord($var{$c}); switch (true) { case $ord_var_c == 0x08: $ascii .= '\b'; break; case $ord_var_c == 0x09: $ascii .= '\t'; break; case $ord_var_c == 0x0A: $ascii .= '\n'; break; case $ord_var_c == 0x0C: $ascii .= '\f'; break; case $ord_var_c == 0x0D: $ascii .= '\r'; break; case $ord_var_c == 0x22: case $ord_var_c == 0x2F: case $ord_var_c == 0x5C: // double quote, slash, slosh $ascii .= '\\'.$var{$c}; break; case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): // characters U-00000000 - U-0000007F (same as ASCII) $ascii .= $var{$c}; break; case (($ord_var_c & 0xE0) == 0xC0): // characters U-00000080 - U-000007FF, mask 110XXXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1})); $c += 1; $utf16 = $this->json_utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xF0) == 0xE0): // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2})); $c += 2; $utf16 = $this->json_utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xF8) == 0xF0): // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3})); $c += 3; $utf16 = $this->json_utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xFC) == 0xF8): // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3}), ord($var{$c + 4})); $c += 4; $utf16 = $this->json_utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xFE) == 0xFC): // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3}), ord($var{$c + 4}), ord($var{$c + 5})); $c += 5; $utf16 = $this->json_utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; } } return '"'.$ascii.'"'; case 'array': /* * As per JSON spec if any array key is not an integer * we must treat the the whole array as an object. We * also try to catch a sparsely populated associative * array with numeric keys here because some JS engines * will create an array with empty indexes up to * max_index which can cause memory issues and because * the keys, which may be relevant, will be remapped * otherwise. * * As per the ECMA and JSON specification an object may * have any string as a property. Unfortunately due to * a hole in the ECMA specification if the key is a * ECMA reserved word or starts with a digit the * parameter is only accessible using ECMAScript's * bracket notation. */ // treat as a JSON object if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $this->json_objectStack[] = $var; $properties = array_map(array($this, 'json_name_value'), array_keys($var), array_values($var)); array_pop($this->json_objectStack); foreach($properties as $property) { if($property instanceof Exception) { return $property; } } return '{' . join(',', $properties) . '}'; } $this->json_objectStack[] = $var; // treat it like a regular array $elements = array_map(array($this, 'json_encode'), $var); array_pop($this->json_objectStack); foreach($elements as $element) { if($element instanceof Exception) { return $element; } } return '[' . join(',', $elements) . ']'; case 'object': $vars = self::encodeObject($var); $this->json_objectStack[] = $var; $properties = array_map(array($this, 'json_name_value'), array_keys($vars), array_values($vars)); array_pop($this->json_objectStack); foreach($properties as $property) { if($property instanceof Exception) { return $property; } } return '{' . join(',', $properties) . '}'; default: return null; } } /** * array-walking function for use in generating JSON-formatted name-value pairs * * @param string $name name of key to use * @param mixed $value reference to an array element to be encoded * * @return string JSON-formatted name-value pair, like '"name":value' * @access private */ private function json_name_value($name, $value) { // Encoding the $GLOBALS PHP array causes an infinite loop // if the recursion is not reset here as it contains // a reference to itself. This is the only way I have come up // with to stop infinite recursion in this case. if($name=='GLOBALS' && is_array($value) && array_key_exists('GLOBALS',$value)) { $value['GLOBALS'] = '** Recursion **'; } $encoded_value = $this->json_encode($value); if($encoded_value instanceof Exception) { return $encoded_value; } return $this->json_encode(strval($name)) . ':' . $encoded_value; } } wp-super-cache/min/lib/HTTP/0000755000076500007650000000000011157407116015312 5ustar jhardijhardiwp-super-cache/min/lib/HTTP/ConditionalGet.php0000644000076500007650000002326011142435342020725 0ustar jhardijhardi * list($updateTime, $content) = getDbUpdateAndContent(); * $cg = new HTTP_ConditionalGet(array( * 'lastModifiedTime' => $updateTime * ,'isPublic' => true * )); * $cg->sendHeaders(); * if ($cg->cacheIsValid) { * exit(); * } * echo $content; * * * E.g. Shortcut for the above * * HTTP_ConditionalGet::check($updateTime, true); // exits if client has cache * echo $content; * * * E.g. Content from DB with no update time: * * $content = getContentFromDB(); * $cg = new HTTP_ConditionalGet(array( * 'contentHash' => md5($content) * )); * $cg->sendHeaders(); * if ($cg->cacheIsValid) { * exit(); * } * echo $content; * * * E.g. Static content with some static includes: * * // before content * $cg = new HTTP_ConditionalGet(array( * 'lastUpdateTime' => max( * filemtime(__FILE__) * ,filemtime('/path/to/header.inc') * ,filemtime('/path/to/footer.inc') * ) * )); * $cg->sendHeaders(); * if ($cg->cacheIsValid) { * exit(); * } * * @package Minify * @subpackage HTTP * @author Stephen Clay */ class HTTP_ConditionalGet { /** * Does the client have a valid copy of the requested resource? * * You'll want to check this after instantiating the object. If true, do * not send content, just call sendHeaders() if you haven't already. * * @var bool */ public $cacheIsValid = null; /** * @param array $spec options * * 'isPublic': (bool) if true, the Cache-Control header will contain * "public", allowing proxies to cache the content. Otherwise "private" will * be sent, allowing only browser caching. (default false) * * 'lastModifiedTime': (int) if given, both ETag AND Last-Modified headers * will be sent with content. This is recommended. * * 'eTag': (string) if given, this will be used as the ETag header rather * than values based on lastModifiedTime or contentHash. * * 'contentHash': (string) if given, only the ETag header can be sent with * content (only HTTP1.1 clients can conditionally GET). The given string * should be short with no quote characters and always change when the * resource changes (recommend md5()). This is not needed/used if * lastModifiedTime is given. * * 'invalidate': (bool) if true, the client cache will be considered invalid * without testing. Effectively this disables conditional GET. * (default false) * * 'maxAge': (int) if given, this will set the Cache-Control max-age in * seconds, and also set the Expires header to the equivalent GMT date. * After the max-age period has passed, the browser will again send a * conditional GET to revalidate its cache. * * @return null */ public function __construct($spec) { $scope = (isset($spec['isPublic']) && $spec['isPublic']) ? 'public' : 'private'; $maxAge = 0; // backwards compatibility (can be removed later) if (isset($spec['setExpires']) && is_numeric($spec['setExpires']) && ! isset($spec['maxAge'])) { $spec['maxAge'] = $spec['setExpires'] - $_SERVER['REQUEST_TIME']; } if (isset($spec['maxAge'])) { $maxAge = $spec['maxAge']; $this->_headers['Expires'] = self::gmtDate( $_SERVER['REQUEST_TIME'] + $spec['maxAge'] ); } if (isset($spec['lastModifiedTime'])) { $this->_setLastModified($spec['lastModifiedTime']); if (isset($spec['eTag'])) { // Use it $this->_setEtag($spec['eTag'], $scope); } else { // base both headers on time $this->_setEtag($spec['lastModifiedTime'], $scope); } } elseif (isset($spec['eTag'])) { // Use it $this->_setEtag($spec['eTag'], $scope); } elseif (isset($spec['contentHash'])) { // Use the hash as the ETag $this->_setEtag($spec['contentHash'], $scope); } $this->_headers['Cache-Control'] = "max-age={$maxAge}, {$scope}, must-revalidate"; // invalidate cache if disabled, otherwise check $this->cacheIsValid = (isset($spec['invalidate']) && $spec['invalidate']) ? false : $this->_isCacheValid(); } /** * Get array of output headers to be sent * * In the case of 304 responses, this array will only contain the response * code header: array('_responseCode' => 'HTTP/1.0 304 Not Modified') * * Otherwise something like: * * array( * 'Cache-Control' => 'max-age=0, public, must-revalidate' * ,'ETag' => '"foobar"' * ) * * * @return array */ public function getHeaders() { return $this->_headers; } /** * Set the Content-Length header in bytes * * With most PHP configs, as long as you don't flush() output, this method * is not needed and PHP will buffer all output and set Content-Length for * you. Otherwise you'll want to call this to let the client know up front. * * @param int $bytes * * @return int copy of input $bytes */ public function setContentLength($bytes) { return $this->_headers['Content-Length'] = $bytes; } /** * Send headers * * @see getHeaders() * * Note this doesn't "clear" the headers. Calling sendHeaders() will * call header() again (but probably have not effect) and getHeaders() will * still return the headers. * * @return null */ public function sendHeaders() { $headers = $this->_headers; if (array_key_exists('_responseCode', $headers)) { header($headers['_responseCode']); unset($headers['_responseCode']); } foreach ($headers as $name => $val) { header($name . ': ' . $val); } } /** * Exit if the client's cache is valid for this resource * * This is a convenience method for common use of the class * * @param int $lastModifiedTime if given, both ETag AND Last-Modified headers * will be sent with content. This is recommended. * * @param bool $isPublic (default false) if true, the Cache-Control header * will contain "public", allowing proxies to cache the content. Otherwise * "private" will be sent, allowing only browser caching. * * @param array $options (default empty) additional options for constructor * * @return null */ public static function check($lastModifiedTime = null, $isPublic = false, $options = array()) { if (null !== $lastModifiedTime) { $options['lastModifiedTime'] = (int)$lastModifiedTime; } $options['isPublic'] = (bool)$isPublic; $cg = new HTTP_ConditionalGet($options); $cg->sendHeaders(); if ($cg->cacheIsValid) { exit(); } } /** * Get a GMT formatted date for use in HTTP headers * * * header('Expires: ' . HTTP_ConditionalGet::gmtdate($time)); * * * @param int $time unix timestamp * * @return string */ public static function gmtDate($time) { return gmdate('D, d M Y H:i:s \G\M\T', $time); } protected $_headers = array(); protected $_lmTime = null; protected $_etag = null; protected function _setEtag($hash, $scope) { $this->_etag = '"' . $hash . substr($scope, 0, 3) . '"'; $this->_headers['ETag'] = $this->_etag; } protected function _setLastModified($time) { $this->_lmTime = (int)$time; $this->_headers['Last-Modified'] = self::gmtDate($time); } /** * Determine validity of client cache and queue 304 header if valid */ protected function _isCacheValid() { if (null === $this->_etag) { // lmTime is copied to ETag, so this condition implies that the // server sent neither ETag nor Last-Modified, so the client can't // possibly has a valid cache. return false; } $isValid = ($this->resourceMatchedEtag() || $this->resourceNotModified()); if ($isValid) { $this->_headers['_responseCode'] = 'HTTP/1.0 304 Not Modified'; } return $isValid; } protected function resourceMatchedEtag() { if (!isset($_SERVER['HTTP_IF_NONE_MATCH'])) { return false; } $cachedEtagList = get_magic_quotes_gpc() ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : $_SERVER['HTTP_IF_NONE_MATCH']; $cachedEtags = split(',', $cachedEtagList); foreach ($cachedEtags as $cachedEtag) { if (trim($cachedEtag) == $this->_etag) { return true; } } return false; } protected function resourceNotModified() { if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { return false; } $ifModifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE']; if (false !== ($semicolon = strrpos($ifModifiedSince, ';'))) { // IE has tacked on extra data to this header, strip it $ifModifiedSince = substr($ifModifiedSince, 0, $semicolon); } return ($ifModifiedSince == self::gmtDate($this->_lmTime)); } } wp-super-cache/min/lib/HTTP/Encoder.php0000644000076500007650000002254711142435342017410 0ustar jhardijhardi * // Send a CSS file, compressed if possible * $he = new HTTP_Encoder(array( * 'content' => file_get_contents($cssFile) * ,'type' => 'text/css' * )); * $he->encode(); * $he->sendAll(); * * * * // Shortcut to encoding output * header('Content-Type: text/css'); // needed if not HTML * HTTP_Encoder::output($css); * * * * // Just sniff for the accepted encoding * $encoding = HTTP_Encoder::getAcceptedEncoding(); * * * For more control over headers, use getHeaders() and getData() and send your * own output. * * Note: If you don't need header mgmt, use PHP's native gzencode, gzdeflate, * and gzcompress functions for gzip, deflate, and compress-encoding * respectively. * * @package Minify * @subpackage HTTP * @author Stephen Clay */ class HTTP_Encoder { /** * Should the encoder allow HTTP encoding to IE6? * * If you have many IE6 users and the bandwidth savings is worth troubling * some of them, set this to true. * * By default, encoding is only offered to IE7+. When this is true, * getAcceptedEncoding() will return an encoding for IE6 if its user agent * string contains "SV1". This has been documented in many places as "safe", * but there seem to be remaining, intermittent encoding bugs in patched * IE6 on the wild web. * * @var bool */ public static $encodeToIe6 = false; /** * Default compression level for zlib operations * * This level is used if encode() is not given a $compressionLevel * * @var int */ public static $compressionLevel = 6; /** * Get an HTTP Encoder object * * @param array $spec options * * 'content': (string required) content to be encoded * * 'type': (string) if set, the Content-Type header will have this value. * * 'method: (string) only set this if you are forcing a particular encoding * method. If not set, the best method will be chosen by getAcceptedEncoding() * The available methods are 'gzip', 'deflate', 'compress', and '' (no * encoding) * * @return null */ public function __construct($spec) { $this->_content = $spec['content']; $this->_headers['Content-Length'] = (string)strlen($this->_content); if (isset($spec['type'])) { $this->_headers['Content-Type'] = $spec['type']; } if (isset($spec['method']) && in_array($spec['method'], array('gzip', 'deflate', 'compress', ''))) { $this->_encodeMethod = array($spec['method'], $spec['method']); } else { $this->_encodeMethod = self::getAcceptedEncoding(); } } /** * Get content in current form * * Call after encode() for encoded content. * * return string */ public function getContent() { return $this->_content; } /** * Get array of output headers to be sent * * E.g. * * array( * 'Content-Length' => '615' * ,'Content-Encoding' => 'x-gzip' * ,'Vary' => 'Accept-Encoding' * ) * * * @return array */ public function getHeaders() { return $this->_headers; } /** * Send output headers * * You must call this before headers are sent and it probably cannot be * used in conjunction with zlib output buffering / mod_gzip. Errors are * not handled purposefully. * * @see getHeaders() * * @return null */ public function sendHeaders() { foreach ($this->_headers as $name => $val) { header($name . ': ' . $val); } } /** * Send output headers and content * * A shortcut for sendHeaders() and echo getContent() * * You must call this before headers are sent and it probably cannot be * used in conjunction with zlib output buffering / mod_gzip. Errors are * not handled purposefully. * * @return null */ public function sendAll() { $this->sendHeaders(); echo $this->_content; } /** * Determine the client's best encoding method from the HTTP Accept-Encoding * header. * * If no Accept-Encoding header is set, or the browser is IE before v6 SP2, * this will return ('', ''), the "identity" encoding. * * A syntax-aware scan is done of the Accept-Encoding, so the method must * be non 0. The methods are favored in order of deflate, gzip, then * compress. Yes, deflate is always smaller and faster! * * @param bool $allowCompress allow the older compress encoding * * @return array two values, 1st is the actual encoding method, 2nd is the * alias of that method to use in the Content-Encoding header (some browsers * call gzip "x-gzip" etc.) */ public static function getAcceptedEncoding($allowCompress = true) { // @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html if (! isset($_SERVER['HTTP_ACCEPT_ENCODING']) || self::_isBuggyIe()) { return array('', ''); } $ae = $_SERVER['HTTP_ACCEPT_ENCODING']; $aeRev = strrev($ae); // Fast tests for common AEs. If these don't pass we have to do // slow regex parsing if (0 === strpos($aeRev, 'etalfed ,') // ie, webkit || 0 === strpos($aeRev, 'etalfed,') // gecko || 0 === strpos($ae, 'deflate,') // opera 9.5b // slow parsing || preg_match( '@(?:^|,)\\s*deflate\\s*(?:$|,|;\\s*q=(?:0\\.|1))@', $ae)) { return array('deflate', 'deflate'); } if (preg_match( '@(?:^|,)\\s*((?:x-)?gzip)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@' ,$ae ,$m)) { return array('gzip', $m[1]); } if ($allowCompress && preg_match( '@(?:^|,)\\s*((?:x-)?compress)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@' ,$ae ,$m)) { return array('compress', $m[1]); } return array('', ''); } /** * Encode (compress) the content * * If the encode method is '' (none) or compression level is 0, or the 'zlib' * extension isn't loaded, we return false. * * Then the appropriate gz_* function is called to compress the content. If * this fails, false is returned. * * If successful, the Content-Length header is updated, and Content-Encoding * and Vary headers are added. * * @param int $compressionLevel given to zlib functions. If not given, the * class default will be used. * * @return bool success true if the content was actually compressed */ public function encode($compressionLevel = null) { if (null === $compressionLevel) { $compressionLevel = self::$compressionLevel; } if ('' === $this->_encodeMethod[0] || ($compressionLevel == 0) || !extension_loaded('zlib')) { return false; } if ($this->_encodeMethod[0] === 'deflate') { $encoded = gzdeflate($this->_content, $compressionLevel); } elseif ($this->_encodeMethod[0] === 'gzip') { $encoded = gzencode($this->_content, $compressionLevel); } else { $encoded = gzcompress($this->_content, $compressionLevel); } if (false === $encoded) { return false; } $this->_headers['Content-Length'] = strlen($encoded); $this->_headers['Content-Encoding'] = $this->_encodeMethod[1]; $this->_headers['Vary'] = 'Accept-Encoding'; $this->_content = $encoded; return true; } /** * Encode and send appropriate headers and content * * This is a convenience method for common use of the class * * @param string $content * * @param int $compressionLevel given to zlib functions. If not given, the * class default will be used. * * @return bool success true if the content was actually compressed */ public static function output($content, $compressionLevel = null) { if (null === $compressionLevel) { $compressionLevel = self::$compressionLevel; } $he = new HTTP_Encoder(array('content' => $content)); $ret = $he->encode($compressionLevel); $he->sendAll(); return $ret; } protected $_content = ''; protected $_headers = array(); protected $_encodeMethod = array('', ''); /** * Is the browser an IE version earlier than 6 SP2? */ protected static function _isBuggyIe() { $ua = $_SERVER['HTTP_USER_AGENT']; // quick escape for non-IEs if (0 !== strpos($ua, 'Mozilla/4.0 (compatible; MSIE ') || false !== strpos($ua, 'Opera')) { return false; } // no regex = faaast $version = (float)substr($ua, 30); return self::$encodeToIe6 ? ($version < 6 || ($version == 6 && false === strpos($ua, 'SV1'))) : ($version < 7); } } wp-super-cache/min/lib/JSMin.php0000644000076500007650000003000711137413652016224 0ustar jhardijhardi (PHP port) * @author Steve Clay (modifications + cleanup) * @author Andrea Giammarchi (spaceBeforeRegExp) * @copyright 2002 Douglas Crockford (jsmin.c) * @copyright 2008 Ryan Grove (PHP port) * @license http://opensource.org/licenses/mit-license.php MIT License * @link http://code.google.com/p/jsmin-php/ */ class JSMin { const ORD_LF = 10; const ORD_SPACE = 32; protected $a = ''; protected $b = ''; protected $input = ''; protected $inputIndex = 0; protected $inputLength = 0; protected $lookAhead = null; protected $output = ''; /** * Minify Javascript * * @param string $js Javascript to be minified * @return string */ public static function minify($js) { $jsmin = new JSMin($js); return $jsmin->min(); } protected function __construct($input) { $this->input = str_replace("\r\n", "\n", $input); $this->inputLength = strlen($this->input); } protected function action($d) { switch ($d) { case 1: $this->output .= $this->a; // fallthrough case 2: $this->a = $this->b; if ($this->a === "'" || $this->a === '"') { for (;;) { $this->output .= $this->a; $this->a = $this->get(); if ($this->a === $this->b) { break; } if (ord($this->a) <= self::ORD_LF) { throw new JSMinException('Unterminated string literal.'); } if ($this->a === '\\') { $this->output .= $this->a; $this->a = $this->get(); } } } // fallthrough case 3: $this->b = $this->next(); if ($this->b === '/') { switch ($this->a) { case "\n": case ' ': if (! $this->spaceBeforeRegExp($this->output)) { break; } case '{': case ';': case '(': case ',': case '=': case ':': case '[': case '!': case '&': case '|': case '?': $this->output .= $this->a.$this->b; for (;;) { $this->a = $this->get(); if ($this->a === '/') { break; // for (;;) } elseif ($this->a === '\\') { $this->output .= $this->a; $this->a = $this->get(); } elseif (ord($this->a) <= self::ORD_LF) { throw new JSMinException('Unterminated regular expression literal.'); } $this->output .= $this->a; } $this->b = $this->next(); break; // switch ($this->a) // end case ? } } break; // switch ($d) // end case 3 } } protected function get() { $c = $this->lookAhead; $this->lookAhead = null; if ($c === null) { if ($this->inputIndex < $this->inputLength) { $c = $this->input[$this->inputIndex]; $this->inputIndex += 1; } else { $c = null; } } return ($c === "\r") ? "\n" : ($c === null || $c === "\n" || ord($c) >= self::ORD_SPACE ? $c : ' '); } protected function isAlphaNum($c) { return (ord($c) > 126 || $c === '\\' || preg_match('/^[\w\$]$/', $c) === 1); } protected function min() { $this->a = "\n"; $this->action(3); while ($this->a !== null) { switch ($this->a) { case ' ': if ($this->isAlphaNum($this->b)) { $this->action(1); } else { $this->action(2); } break; case "\n": switch ($this->b) { case '{': case '[': case '(': case '+': case '-': $this->action(1); break; case ' ': $this->action(3); break; default: if ($this->isAlphaNum($this->b)) { $this->action(1); } else { $this->action(2); } } break; default: switch ($this->b) { case ' ': if ($this->isAlphaNum($this->a)) { $this->action(1); break; // switch ($this->b) } $this->action(3); break; // switch ($this->b) case "\n": switch ($this->a) { case '}': case ']': case ')': case '+': case '-': case '"': case "'": $this->action(1); break; // switch ($this->a) default: if ($this->isAlphaNum($this->a)) { $this->action(1); } else { $this->action(3); } } break; // switch ($this->b) default: $this->action(1); break; // switch ($this->b) } // end default } } return $this->output; } protected function next() { $get = $this->get(); if ($get === '/') { $commentContents = ''; switch ($this->peek()) { case '/': // "//" comment for (;;) { $get = $this->get(); $commentContents .= $get; if (ord($get) <= self::ORD_LF) { return preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $commentContents) ? "/{$commentContents}" : $get; } } case '*': // "/* */" comment $this->get(); for (;;) { $get = $this->get(); switch ($get) { case '*': if ($this->peek() === '/') { $this->get(); if (0 === strpos($commentContents, '!')) { // YUI Compressor style return "\n/*" . substr($commentContents, 1) . "*/\n"; } return preg_match('/^@(?:cc_on|if|elif|else|end)\\b/', $commentContents) ? "/*{$commentContents}*/" // IE conditional compilation : ' '; } break; case null: throw new JSMinException('Unterminated comment.'); } $commentContents .= $get; } default: return $get; } } return $get; } protected function peek() { $this->lookAhead = $this->get(); return $this->lookAhead; } protected function spaceBeforeRegExp($output) { $length = strlen($output); $isSpace = false; $tmp = ""; foreach (array("case", "else", "in", "return", "typeof") as $word) { if ($length === strlen($word)) { $isSpace = ($word === $output); } elseif ($length > strlen($word)) { $tmp = substr($output, $length - strlen($word) - 1); $isSpace = (substr($tmp, 1) === $word) && ! $this->isAlphaNum($tmp[0]); } if ($isSpace) { break; } } return ($length < 2) ? true : $isSpace; } } class JSMinException extends Exception { } wp-super-cache/min/lib/Minify/0000755000076500007650000000000011157407116015766 5ustar jhardijhardiwp-super-cache/min/lib/Minify/Build.php0000644000076500007650000000531311072266372017543 0ustar jhardijhardi * // in config file * $groupSources = array( * 'js' => array('file1.js', 'file2.js') * ,'css' => array('file1.css', 'file2.css', 'file3.css') * ) * * // during HTML generation * $jsBuild = new Minify_Build($groupSources['js']); * $cssBuild = new Minify_Build($groupSources['css']); * * $script = ""; * $link = ""; * * // in min.php * Minify::serve('Groups', array( * 'groups' => $groupSources * ,'setExpires' => (time() + 86400 * 365) * )); * * * @package Minify * @author Stephen Clay */ class Minify_Build { /** * Last modification time of all files in the build * * @var int */ public $lastModified = 0; /** * String to use as ampersand in uri(). Set this to '&' if * you are not HTML-escaping URIs. * * @var string */ public static $ampersand = '&'; /** * Get a time-stamped URI * * * echo $b->uri('/site.js'); * // outputs "/site.js?1678242" * * echo $b->uri('/scriptaculous.js?load=effects'); * // outputs "/scriptaculous.js?load=effects&1678242" * * * @param string $uri * @param boolean $forceAmpersand (default = false) Force the use of ampersand to * append the timestamp to the URI. * @return string */ public function uri($uri, $forceAmpersand = false) { $sep = ($forceAmpersand || strpos($uri, '?') !== false) ? self::$ampersand : '?'; return "{$uri}{$sep}{$this->lastModified}"; } /** * Create a build object * * @param array $sources array of Minify_Source objects and/or file paths * * @return null */ public function __construct($sources) { $max = 0; foreach ((array)$sources as $source) { if ($source instanceof Minify_Source) { $max = max($max, $source->lastModified); } elseif (is_string($source)) { if (0 === strpos($source, '//')) { $source = $_SERVER['DOCUMENT_ROOT'] . substr($source, 1); } if (is_file($source)) { $max = max($max, filemtime($source)); } } } $this->lastModified = $max; } } wp-super-cache/min/lib/Minify/Cache/0000755000076500007650000000000011157407116016771 5ustar jhardijhardiwp-super-cache/min/lib/Minify/Cache/APC.php0000644000076500007650000000503411122313630020074 0ustar jhardijhardi * Minify::setCache(new Minify_Cache_APC()); * * * @package Minify * @author Chris Edwards **/ class Minify_Cache_APC { /** * Create a Minify_Cache_APC object, to be passed to * Minify::setCache(). * * * @param int $expire seconds until expiration (default = 0 * meaning the item will not get an expiration date) * * @return null */ public function __construct($expire = 0) { $this->_exp = $expire; } /** * Write data to cache. * * @param string $id cache id * * @param string $data * * @return bool success */ public function store($id, $data) { return apc_store($id, "{$_SERVER['REQUEST_TIME']}|{$data}", $this->_exp); } /** * Get the size of a cache entry * * @param string $id cache id * * @return int size in bytes */ public function getSize($id) { return $this->_fetch($id) ? strlen($this->_data) : false; } /** * Does a valid cache entry exist? * * @param string $id cache id * * @param int $srcMtime mtime of the original source file(s) * * @return bool exists */ public function isValid($id, $srcMtime) { return ($this->_fetch($id) && ($this->_lm >= $srcMtime)); } /** * Send the cached content to output * * @param string $id cache id */ public function display($id) { echo $this->_fetch($id) ? $this->_data : ''; } /** * Fetch the cached content * * @param string $id cache id * * @return string */ public function fetch($id) { return $this->_fetch($id) ? $this->_data : ''; } private $_exp = null; // cache of most recently fetched id private $_lm = null; private $_data = null; private $_id = null; /** * Fetch data and timestamp from apc, store in instance * * @param string $id * * @return bool success */ private function _fetch($id) { if ($this->_id === $id) { return true; } $ret = apc_fetch($id); if (false === $ret) { $this->_id = null; return false; } list($this->_lm, $this->_data) = explode('|', $ret, 2); $this->_id = $id; return true; } } wp-super-cache/min/lib/Minify/Cache/File.php0000644000076500007650000000533711064350556020373 0ustar jhardijhardi_locking = $fileLocking; $this->_path = $path; } /** * Write data to cache. * * @param string $id cache id (e.g. a filename) * * @param string $data * * @return bool success */ public function store($id, $data) { $flag = $this->_locking ? LOCK_EX : null; if (is_file($this->_path . '/' . $id)) { @unlink($this->_path . '/' . $id); } if (! @file_put_contents($this->_path . '/' . $id, $data, $flag)) { return false; } // write control if ($data !== $this->fetch($id)) { @unlink($file); return false; } return true; } /** * Get the size of a cache entry * * @param string $id cache id (e.g. a filename) * * @return int size in bytes */ public function getSize($id) { return filesize($this->_path . '/' . $id); } /** * Does a valid cache entry exist? * * @param string $id cache id (e.g. a filename) * * @param int $srcMtime mtime of the original source file(s) * * @return bool exists */ public function isValid($id, $srcMtime) { $file = $this->_path . '/' . $id; return (is_file($file) && (filemtime($file) >= $srcMtime)); } /** * Send the cached content to output * * @param string $id cache id (e.g. a filename) */ public function display($id) { if ($this->_locking) { $fp = fopen($this->_path . '/' . $id, 'rb'); flock($fp, LOCK_SH); fpassthru($fp); flock($fp, LOCK_UN); fclose($fp); } else { readfile($this->_path . '/' . $id); } } /** * Fetch the cached content * * @param string $id cache id (e.g. a filename) * * @return string */ public function fetch($id) { if ($this->_locking) { $fp = fopen($this->_path . '/' . $id, 'rb'); flock($fp, LOCK_SH); $ret = stream_get_contents($fp); flock($fp, LOCK_UN); fclose($fp); return $ret; } else { return file_get_contents($this->_path . '/' . $id); } } private $_path = null; private $_locking = null; } wp-super-cache/min/lib/Minify/Cache/Memcache.php0000644000076500007650000000561011060150102021165 0ustar jhardijhardi * // fall back to disk caching if memcache can't connect * $memcache = new Memcache; * if ($memcache->connect('localhost', 11211)) { * Minify::setCache(new Minify_Cache_Memcache($memcache)); * } else { * Minify::setCache(); * } * **/ class Minify_Cache_Memcache { /** * Create a Minify_Cache_Memcache object, to be passed to * Minify::setCache(). * * @param Memcache $memcache already-connected instance * * @param int $expire seconds until expiration (default = 0 * meaning the item will not get an expiration date) * * @return null */ public function __construct($memcache, $expire = 0) { $this->_mc = $memcache; $this->_exp = $expire; } /** * Write data to cache. * * @param string $id cache id * * @param string $data * * @return bool success */ public function store($id, $data) { return $this->_mc->set($id, "{$_SERVER['REQUEST_TIME']}|{$data}", 0, $this->_exp); } /** * Get the size of a cache entry * * @param string $id cache id * * @return int size in bytes */ public function getSize($id) { return $this->_fetch($id) ? strlen($this->_data) : false; } /** * Does a valid cache entry exist? * * @param string $id cache id * * @param int $srcMtime mtime of the original source file(s) * * @return bool exists */ public function isValid($id, $srcMtime) { return ($this->_fetch($id) && ($this->_lm >= $srcMtime)); } /** * Send the cached content to output * * @param string $id cache id */ public function display($id) { echo $this->_fetch($id) ? $this->_data : ''; } /** * Fetch the cached content * * @param string $id cache id * * @return string */ public function fetch($id) { return $this->_fetch($id) ? $this->_data : ''; } private $_mc = null; private $_exp = null; // cache of most recently fetched id private $_lm = null; private $_data = null; private $_id = null; /** * Fetch data and timestamp from memcache, store in instance * * @param string $id * * @return bool success */ private function _fetch($id) { if ($this->_id === $id) { return true; } $ret = $this->_mc->get($id); if (false === $ret) { $this->_id = null; return false; } list($this->_lm, $this->_data) = explode('|', $ret, 2); $this->_id = $id; return true; } } wp-super-cache/min/lib/Minify/CommentPreserver.php0000644000076500007650000000525511057074240022003 0ustar jhardijhardi */ class Minify_CommentPreserver { /** * String to be prepended to each preserved comment * * @var string */ public static $prepend = "\n"; /** * String to be appended to each preserved comment * * @var string */ public static $append = "\n"; /** * Process a string outside of C-style comments that begin with "/*!" * * On each non-empty string outside these comments, the given processor * function will be called. The first "!" will be removed from the * preserved comments, and the comments will be surrounded by * Minify_CommentPreserver::$preprend and Minify_CommentPreserver::$append. * * @param string $content * @param callback $processor function * @param array $args array of extra arguments to pass to the processor * function (default = array()) * @return string */ public static function process($content, $processor, $args = array()) { $ret = ''; while (true) { list($beforeComment, $comment, $afterComment) = self::_nextComment($content); if ('' !== $beforeComment) { $callArgs = $args; array_unshift($callArgs, $beforeComment); $ret .= call_user_func_array($processor, $callArgs); } if (false === $comment) { break; } $ret .= $comment; $content = $afterComment; } return $ret; } /** * Extract comments that YUI Compressor preserves. * * @param string $in input * * @return array 3 elements are returned. If a YUI comment is found, the * 2nd element is the comment and the 1st and 2nd are the surrounding * strings. If no comment is found, the entire string is returned as the * 1st element and the other two are false. */ private static function _nextComment($in) { if ( false === ($start = strpos($in, '/*!')) || false === ($end = strpos($in, '*/', $start + 3)) ) { return array($in, false, false); } $ret = array( substr($in, 0, $start) ,self::$prepend . '/*' . substr($in, $start + 3, $end - $start - 1) . self::$append ); $endChars = (strlen($in) - $end - 2); $ret[] = (0 === $endChars) ? '' : substr($in, -$endChars); return $ret; } } wp-super-cache/min/lib/Minify/Controller/0000755000076500007650000000000011157407116020111 5ustar jhardijhardiwp-super-cache/min/lib/Minify/Controller/Base.php0000644000076500007650000001506411151573110021472 0ustar jhardijhardi */ abstract class Minify_Controller_Base { /** * Setup controller sources and set an needed options for Minify::source * * You must override this method in your subclass controller to set * $this->sources. If the request is NOT valid, make sure $this->sources * is left an empty array. Then strip any controller-specific options from * $options and return it. To serve files, $this->sources must be an array of * Minify_Source objects. * * @param array $options controller and Minify options * * return array $options Minify::serve options */ abstract public function setupSources($options); /** * Get default Minify options for this controller. * * Override in subclass to change defaults * * @return array options for Minify */ public function getDefaultMinifyOptions() { return array( 'isPublic' => true ,'encodeOutput' => function_exists('gzdeflate') ,'encodeMethod' => null // determine later ,'encodeLevel' => 9 ,'minifierOptions' => array() // no minifier options ,'contentTypeCharset' => 'UTF-8' ,'maxAge' => 1800 // 30 minutes ,'rewriteCssUris' => true ,'bubbleCssImports' => false ,'quiet' => false // serve() will send headers and output ,'debug' => false // if you override this, the response code MUST be directly after // the first space. ,'badRequestHeader' => 'HTTP/1.0 400 Bad Request' // callback function to see/modify content of all sources ,'postprocessor' => null // file to require to load preprocessor ,'postprocessorRequire' => null ); } /** * Get default minifiers for this controller. * * Override in subclass to change defaults * * @return array minifier callbacks for common types */ public function getDefaultMinifers() { $ret[Minify::TYPE_JS] = array('Minify_Javascript', 'minify'); $ret[Minify::TYPE_CSS] = array('Minify_CSS', 'minify'); $ret[Minify::TYPE_HTML] = array('Minify_HTML', 'minify'); return $ret; } /** * Load any code necessary to execute the given minifier callback. * * The controller is responsible for loading minification code on demand * via this method. This built-in function will only load classes for * static method callbacks where the class isn't already defined. It uses * the PEAR convention, so, given array('Jimmy_Minifier', 'minCss'), this * function will include 'Jimmy/Minifier.php'. * * If you need code loaded on demand and this doesn't suit you, you'll need * to override this function in your subclass. * @see Minify_Controller_Page::loadMinifier() * * @param callback $minifierCallback callback of minifier function * * @return null */ public function loadMinifier($minifierCallback) { if (is_array($minifierCallback) && is_string($minifierCallback[0]) && !class_exists($minifierCallback[0], false)) { require str_replace('_', '/', $minifierCallback[0]) . '.php'; } } /** * Is a user-given file within an allowable directory, existing, * and having an extension js/css/html/txt ? * * This is a convenience function for controllers that have to accept * user-given paths * * @param string $file full file path (already processed by realpath()) * * @param array $safeDirs directories where files are safe to serve. Files can also * be in subdirectories of these directories. * * @return bool file is safe */ public static function _fileIsSafe($file, $safeDirs) { $pathOk = false; foreach ((array)$safeDirs as $safeDir) { if (strpos($file, $safeDir) === 0) { $pathOk = true; break; } } $base = basename($file); if (! $pathOk || ! is_file($file) || $base[0] === '.') { return false; } list($revExt) = explode('.', strrev($base)); return in_array(strrev($revExt), array('js', 'css', 'html', 'txt')); } /** * @var array instances of Minify_Source, which provide content and * any individual minification needs. * * @see Minify_Source */ public $sources = array(); /** * Mix in default controller options with user-given options * * @param array $options user options * * @return array mixed options */ public final function mixInDefaultOptions($options) { $ret = array_merge( $this->getDefaultMinifyOptions(), $options ); if (! isset($options['minifiers'])) { $options['minifiers'] = array(); } $ret['minifiers'] = array_merge( $this->getDefaultMinifers(), $options['minifiers'] ); return $ret; } /** * Analyze sources (if there are any) and set $options 'contentType' * and 'lastModifiedTime' if they already aren't. * * @param array $options options for Minify * * @return array options for Minify */ public final function analyzeSources($options = array()) { if ($this->sources) { if (! isset($options['contentType'])) { $options['contentType'] = Minify_Source::getContentType($this->sources); } // last modified is needed for caching, even if setExpires is set if (! isset($options['lastModifiedTime'])) { $max = 0; foreach ($this->sources as $source) { $max = max($source->lastModified, $max); } $options['lastModifiedTime'] = $max; } } return $options; } /** * Send message to the Minify logger * @param string $msg * @return null */ protected function log($msg) { require_once 'Minify/Logger.php'; Minify_Logger::log($msg); } } wp-super-cache/min/lib/Minify/Controller/Files.php0000644000076500007650000000357711140162002021660 0ustar jhardijhardi * Minify::serve('Files', array( * 'files' => array( * '//js/jquery.js' * ,'//js/plugins.js' * ,'/home/username/file.js' * ) * )); * * * As a shortcut, the controller will replace "//" at the beginning * of a filename with $_SERVER['DOCUMENT_ROOT'] . '/'. * * @package Minify * @author Stephen Clay */ class Minify_Controller_Files extends Minify_Controller_Base { /** * Set up file sources * * @param array $options controller and Minify options * @return array Minify options * * Controller options: * * 'files': (required) array of complete file paths, or a single path */ public function setupSources($options) { // strip controller options $files = (array)$options['files']; unset($options['files']); $sources = array(); foreach ($files as $file) { if ($file instanceof Minify_Source) { $sources[] = $file; continue; } if (0 === strpos($file, '//')) { $file = $_SERVER['DOCUMENT_ROOT'] . substr($file, 1); } $realPath = realpath($file); if (is_file($realPath)) { $sources[] = new Minify_Source(array( 'filepath' => $realPath )); } else { $this->log("The path \"{$file}\" could not be found (or was not a file)"); return $options; } } if ($sources) { $this->sources = $sources; } return $options; } } wp-super-cache/min/lib/Minify/Controller/Groups.php0000644000076500007650000000511111140162002022057 0ustar jhardijhardi * Minify::serve('Groups', array( * 'groups' => array( * 'css' => array('//css/type.css', '//css/layout.css') * ,'js' => array('//js/jquery.js', '//js/site.js') * ) * )); * * * If the above code were placed in /serve.php, it would enable the URLs * /serve.php/js and /serve.php/css * * As a shortcut, the controller will replace "//" at the beginning * of a filename with $_SERVER['DOCUMENT_ROOT'] . '/'. * * @package Minify * @author Stephen Clay */ class Minify_Controller_Groups extends Minify_Controller_Base { /** * Set up groups of files as sources * * @param array $options controller and Minify options * @return array Minify options * * Controller options: * * 'groups': (required) array mapping PATH_INFO strings to arrays * of complete file paths. @see Minify_Controller_Groups */ public function setupSources($options) { // strip controller options $groups = $options['groups']; unset($options['groups']); // mod_fcgid places PATH_INFO in ORIG_PATH_INFO $pi = isset($_SERVER['ORIG_PATH_INFO']) ? substr($_SERVER['ORIG_PATH_INFO'], 1) : (isset($_SERVER['PATH_INFO']) ? substr($_SERVER['PATH_INFO'], 1) : false ); if (false === $pi || ! isset($groups[$pi])) { // no PATH_INFO or not a valid group $this->log("Missing PATH_INFO or no group set for \"$pi\""); return $options; } $sources = array(); foreach ((array)$groups[$pi] as $file) { if ($file instanceof Minify_Source) { $sources[] = $file; continue; } if (0 === strpos($file, '//')) { $file = $_SERVER['DOCUMENT_ROOT'] . substr($file, 1); } $realPath = realpath($file); if (is_file($realPath)) { $sources[] = new Minify_Source(array( 'filepath' => $realPath )); } else { $this->log("The path \"{$file}\" could not be found (or was not a file)"); return $options; } } if ($sources) { $this->sources = $sources; } return $options; } } wp-super-cache/min/lib/Minify/Controller/MinApp.php0000644000076500007650000001113011140162002021762 0ustar jhardijhardi */ class Minify_Controller_MinApp extends Minify_Controller_Base { /** * Set up groups of files as sources * * @param array $options controller and Minify options * @return array Minify options * */ public function setupSources($options) { // filter controller options $cOptions = array_merge( array( 'allowDirs' => '//' ,'groupsOnly' => false ,'groups' => array() ,'maxFiles' => 10 ) ,(isset($options['minApp']) ? $options['minApp'] : array()) ); unset($options['minApp']); $sources = array(); if (isset($_GET['g'])) { // try groups if (! isset($cOptions['groups'][$_GET['g']])) { $this->log("A group configuration for \"{$_GET['g']}\" was not set"); return $options; } foreach ((array)$cOptions['groups'][$_GET['g']] as $file) { if ($file instanceof Minify_Source) { $sources[] = $file; continue; } if (0 === strpos($file, '//')) { $file = $_SERVER['DOCUMENT_ROOT'] . substr($file, 1); } $file = realpath($file); if (is_file($file)) { $sources[] = new Minify_Source(array( 'filepath' => $file )); } else { $this->log("The path \"{$file}\" could not be found (or was not a file)"); return $options; } } } elseif (! $cOptions['groupsOnly'] && isset($_GET['f'])) { // try user files // The following restrictions are to limit the URLs that minify will // respond to. Ideally there should be only one way to reference a file. if (// verify at least one file, files are single comma separated, // and are all same extension ! preg_match('/^[^,]+\\.(css|js)(?:,[^,]+\\.\\1)*$/', $_GET['f']) // no "//" || strpos($_GET['f'], '//') !== false // no "\" || strpos($_GET['f'], '\\') !== false // no "./" || preg_match('/(?:^|[^\\.])\\.\\//', $_GET['f']) ) { $this->log("GET param 'f' invalid (see MinApp.php line 63)"); return $options; } $files = explode(',', $_GET['f']); if (count($files) > $cOptions['maxFiles'] || $files != array_unique($files)) { $this->log("Too many or duplicate files specified"); return $options; } if (isset($_GET['b'])) { // check for validity if (preg_match('@^[^/]+(?:/[^/]+)*$@', $_GET['b']) && false === strpos($_GET['b'], '..') && $_GET['b'] !== '.') { // valid base $base = "/{$_GET['b']}/"; } else { $this->log("GET param 'b' invalid (see MinApp.php line 84)"); return $options; } } else { $base = '/'; } $allowDirs = array(); foreach ((array)$cOptions['allowDirs'] as $allowDir) { $allowDirs[] = realpath(str_replace('//', $_SERVER['DOCUMENT_ROOT'] . '/', $allowDir)); } foreach ($files as $file) { $path = $_SERVER['DOCUMENT_ROOT'] . $base . $file; $file = realpath($path); if (false === $file) { $this->log("Path \"{$path}\" failed realpath()"); return $options; } elseif (! parent::_fileIsSafe($file, $allowDirs)) { $this->log("Path \"{$path}\" failed Minify_Controller_Base::_fileIsSafe()"); return $options; } else { $sources[] = new Minify_Source(array( 'filepath' => $file )); } } } if ($sources) { $this->sources = $sources; } else { $this->log("No sources to serve"); } return $options; } } wp-super-cache/min/lib/Minify/Controller/Page.php0000644000076500007650000000516011057602322021473 0ustar jhardijhardi */ class Minify_Controller_Page extends Minify_Controller_Base { /** * Set up source of HTML content * * @param array $options controller and Minify options * @return array Minify options * * Controller options: * * 'content': (required) HTML markup * * 'id': (required) id of page (string for use in server-side caching) * * 'lastModifiedTime': timestamp of when this content changed. This * is recommended to allow both server and client-side caching. * * 'minifyAll': should all CSS and Javascript blocks be individually * minified? (default false) * * @todo Add 'file' option to read HTML file. */ public function setupSources($options) { if (isset($options['file'])) { $sourceSpec = array( 'filepath' => $options['file'] ); } else { // strip controller options $sourceSpec = array( 'content' => $options['content'] ,'id' => $options['id'] ); unset($options['content'], $options['id']); } if (isset($options['minifyAll'])) { // this will be the 2nd argument passed to Minify_HTML::minify() $sourceSpec['minifyOptions'] = array( 'cssMinifier' => array('Minify_CSS', 'minify') ,'jsMinifier' => array('Minify_Javascript', 'minify') ); $this->_loadCssJsMinifiers = true; unset($options['minifyAll']); } $this->sources[] = new Minify_Source($sourceSpec); // may not be needed //$options['minifier'] = array('Minify_HTML', 'minify'); $options['contentType'] = Minify::TYPE_HTML; return $options; } protected $_loadCssJsMinifiers = false; /** * @see Minify_Controller_Base::loadMinifier() */ public function loadMinifier($minifierCallback) { if ($this->_loadCssJsMinifiers) { // Minify will not call for these so we must manually load // them when Minify/HTML.php is called for. require 'Minify/CSS.php'; require 'Minify/Javascript.php'; } parent::loadMinifier($minifierCallback); // load Minify/HTML.php } } wp-super-cache/min/lib/Minify/Controller/Version1.php0000644000076500007650000000717711056115304022335 0ustar jhardijhardi * Minify::serve('Version1'); * * * @package Minify * @author Stephen Clay */ class Minify_Controller_Version1 extends Minify_Controller_Base { /** * Set up groups of files as sources * * @param array $options controller and Minify options * @return array Minify options * */ public function setupSources($options) { self::_setupDefines(); if (MINIFY_USE_CACHE) { $cacheDir = defined('MINIFY_CACHE_DIR') ? MINIFY_CACHE_DIR : ''; Minify::setCache($cacheDir); } $options['badRequestHeader'] = 'HTTP/1.0 404 Not Found'; $options['contentTypeCharset'] = MINIFY_ENCODING; // The following restrictions are to limit the URLs that minify will // respond to. Ideally there should be only one way to reference a file. if (! isset($_GET['files']) // verify at least one file, files are single comma separated, // and are all same extension || ! preg_match('/^[^,]+\\.(css|js)(,[^,]+\\.\\1)*$/', $_GET['files'], $m) // no "//" (makes URL rewriting easier) || strpos($_GET['files'], '//') !== false // no "\" || strpos($_GET['files'], '\\') !== false // no "./" || preg_match('/(?:^|[^\\.])\\.\\//', $_GET['files']) ) { return $options; } $extension = $m[1]; $files = explode(',', $_GET['files']); if (count($files) > MINIFY_MAX_FILES) { return $options; } // strings for prepending to relative/absolute paths $prependRelPaths = dirname($_SERVER['SCRIPT_FILENAME']) . DIRECTORY_SEPARATOR; $prependAbsPaths = $_SERVER['DOCUMENT_ROOT']; $sources = array(); $goodFiles = array(); $hasBadSource = false; $allowDirs = isset($options['allowDirs']) ? $options['allowDirs'] : MINIFY_BASE_DIR; foreach ($files as $file) { // prepend appropriate string for abs/rel paths $file = ($file[0] === '/' ? $prependAbsPaths : $prependRelPaths) . $file; // make sure a real file! $file = realpath($file); // don't allow unsafe or duplicate files if (parent::_fileIsSafe($file, $allowDirs) && !in_array($file, $goodFiles)) { $goodFiles[] = $file; $srcOptions = array( 'filepath' => $file ); $this->sources[] = new Minify_Source($srcOptions); } else { $hasBadSource = true; break; } } if ($hasBadSource) { $this->sources = array(); } if (! MINIFY_REWRITE_CSS_URLS) { $options['rewriteCssUris'] = false; } return $options; } private static function _setupDefines() { $defaults = array( 'MINIFY_BASE_DIR' => realpath($_SERVER['DOCUMENT_ROOT']) ,'MINIFY_ENCODING' => 'utf-8' ,'MINIFY_MAX_FILES' => 16 ,'MINIFY_REWRITE_CSS_URLS' => true ,'MINIFY_USE_CACHE' => true ); foreach ($defaults as $const => $val) { if (! defined($const)) { define($const, $val); } } } } wp-super-cache/min/lib/Minify/CSS/0000755000076500007650000000000011157407116016416 5ustar jhardijhardiwp-super-cache/min/lib/Minify/CSS/Compressor.php0000644000076500007650000001740511140200462021255 0ustar jhardijhardi * @author http://code.google.com/u/1stvamp/ (Issue 64 patch) */ class Minify_CSS_Compressor { /** * Minify a CSS string * * @param string $css * * @param array $options (currently ignored) * * @return string */ public static function process($css, $options = array()) { $obj = new Minify_CSS_Compressor($options); return $obj->_process($css); } /** * @var array options */ protected $_options = null; /** * @var bool Are we "in" a hack? * * I.e. are some browsers targetted until the next comment? */ protected $_inHack = false; /** * Constructor * * @param array $options (currently ignored) * * @return null */ private function __construct($options) { $this->_options = $options; } /** * Minify a CSS string * * @param string $css * * @return string */ protected function _process($css) { $css = str_replace("\r\n", "\n", $css); // preserve empty comment after '>' // http://www.webdevout.net/css-hacks#in_css-selectors $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css); // preserve empty comment between property and value // http://css-discuss.incutio.com/?page=BoxModelHack $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css); $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css); // apply callback to all valid comments (and strip out surrounding ws $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@' ,array($this, '_commentCB'), $css); // remove ws around { } and last semicolon in declaration block $css = preg_replace('/\\s*{\\s*/', '{', $css); $css = preg_replace('/;?\\s*}\\s*/', '}', $css); // remove ws surrounding semicolons $css = preg_replace('/\\s*;\\s*/', ';', $css); // remove ws around urls $css = preg_replace('/ url\\( # url( \\s* ([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis) \\s* \\) # ) /x', 'url($1)', $css); // remove ws between rules and colons $css = preg_replace('/ \\s* ([{;]) # 1 = beginning of block or rule separator \\s* ([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter) \\s* : \\s* (\\b|[#\'"]) # 3 = first character of a value /x', '$1$2:$3', $css); // remove ws in selectors $css = preg_replace_callback('/ (?: # non-capture \\s* [^~>+,\\s]+ # selector part \\s* [,>+~] # combinators )+ \\s* [^~>+,\\s]+ # selector part { # open declaration block /x' ,array($this, '_selectorsCB'), $css); // minimize hex colors $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i' , '$1#$2$3$4$5', $css); // remove spaces between font families $css = preg_replace_callback('/font-family:([^;}]+)([;}])/' ,array($this, '_fontFamilyCB'), $css); $css = preg_replace('/@import\\s+url/', '@import url', $css); // replace any ws involving newlines with a single newline $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css); // separate common descendent selectors w/ newlines (to limit line lengths) $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css); // Use newline after 1st numeric value (to limit line lengths). $css = preg_replace('/ ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value \\s+ /x' ,"$1\n", $css); return trim($css); } /** * Replace what looks like a set of selectors * * @param array $m regex matches * * @return string */ protected function _selectorsCB($m) { // remove ws around the combinators return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]); } /** * Process a comment and return a replacement * * @param array $m regex matches * * @return string */ protected function _commentCB($m) { $m = $m[1]; // $m is the comment content w/o the surrounding tokens, // but the return value will replace the entire comment. if ($m === 'keep') { return '/**/'; } if ($m === '" "') { // component of http://tantek.com/CSS/Examples/midpass.html return '/*" "*/'; } if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) { // component of http://tantek.com/CSS/Examples/midpass.html return '/*";}}/* */'; } if ($this->_inHack) { // inversion: feeding only to one browser if (preg_match('@ ^/ # comment started like /*/ \\s* (\\S[\\s\\S]+?) # has at least some non-ws content \\s* /\\* # ends like /*/ or /**/ @x', $m, $n)) { // end hack mode after this comment, but preserve the hack and comment content $this->_inHack = false; return "/*/{$n[1]}/**/"; } } if (substr($m, -1) === '\\') { // comment ends like \*/ // begin hack mode and preserve hack $this->_inHack = true; return '/*\\*/'; } if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */ // begin hack mode and preserve hack $this->_inHack = true; return '/*/*/'; } if ($this->_inHack) { // a regular comment ends hack mode but should be preserved $this->_inHack = false; return '/**/'; } return ''; // remove all other comments } /** * Process a font-family listing and return a replacement * * @param array $m regex matches * * @return string */ protected function _fontFamilyCB($m) { $m[1] = preg_replace('/ \\s* ( "[^"]+" # 1 = family in double qutoes |\'[^\']+\' # or 1 = family in single quotes |[\\w\\-]+ # or 1 = unquoted family ) \\s* /x', '$1', $m[1]); return 'font-family:' . $m[1] . $m[2]; } } wp-super-cache/min/lib/Minify/CSS/UriRewriter.php0000644000076500007650000001416211140200462021401 0ustar jhardijhardi */ class Minify_CSS_UriRewriter { /** * Defines which class to call as part of callbacks, change this * if you extend Minify_CSS_UriRewriter * @var string */ protected static $className = 'Minify_CSS_UriRewriter'; /** * Rewrite file relative URIs as root relative in CSS files * * @param string $css * * @param string $currentDir The directory of the current CSS file. * * @param string $docRoot The document root of the web site in which * the CSS file resides (default = $_SERVER['DOCUMENT_ROOT']). * * @param array $symlinks (default = array()) If the CSS file is stored in * a symlink-ed directory, provide an array of link paths to * target paths, where the link paths are within the document root. Because * paths need to be normalized for this to work, use "//" to substitute * the doc root in the link paths (the array keys). E.g.: * * array('//symlink' => '/real/target/path') // unix * array('//static' => 'D:\\staticStorage') // Windows * * * @return string */ public static function rewrite($css, $currentDir, $docRoot = null, $symlinks = array()) { self::$_docRoot = $docRoot ? $docRoot : $_SERVER['DOCUMENT_ROOT']; self::$_docRoot = realpath(self::$_docRoot); self::$_currentDir = realpath($currentDir); self::$_symlinks = array(); // normalize symlinks foreach ($symlinks as $link => $target) { $link = str_replace('//', realpath(self::$_docRoot), $link); $link = strtr($link, '/', DIRECTORY_SEPARATOR); self::$_symlinks[$link] = realpath($target); } $css = self::_trimUrls($css); // rewrite $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/' ,array(self::$className, '_uriCB'), $css); $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/' ,array(self::$className, '_uriCB'), $css); return $css; } /** * Prepend a path to relative URIs in CSS files * * @param string $css * * @param string $path The path to prepend. * * @return string */ public static function prepend($css, $path) { self::$_prependPath = $path; $css = self::_trimUrls($css); // append $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/' ,array(self::$className, '_uriCB'), $css); $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/' ,array(self::$className, '_uriCB'), $css); self::$_prependPath = null; return $css; } /** * @var string directory of this stylesheet */ private static $_currentDir = ''; /** * @var string DOC_ROOT */ private static $_docRoot = ''; /** * @var array directory replacements to map symlink targets back to their * source (within the document root) E.g. '/var/www/symlink' => '/var/realpath' */ private static $_symlinks = array(); /** * @var string path to prepend */ private static $_prependPath = null; private static function _trimUrls($css) { return preg_replace('/ url\\( # url( \\s* ([^\\)]+?) # 1 = URI (really just a bunch of non right parenthesis) \\s* \\) # ) /x', 'url($1)', $css); } private static function _uriCB($m) { $isImport = ($m[0][0] === '@'); if ($isImport) { $quoteChar = $m[1]; $uri = $m[2]; } else { // is url() // $m[1] is either quoted or not $quoteChar = ($m[1][0] === "'" || $m[1][0] === '"') ? $m[1][0] : ''; $uri = ($quoteChar === '') ? $m[1] : substr($m[1], 1, strlen($m[1]) - 2); } if ('/' !== $uri[0]) { if (strpos($uri, '//') > 0 || 0 === strpos($uri, 'data:') ) { // probably starts with protocol, do not alter } else { // it's a file relative URI! // choose mode if (self::$_prependPath !== null) { // prepend path $uri = self::$_prependPath . $uri; } else { // rewrite path // prepend path with current dir separator (OS-independent) $path = strtr(self::$_currentDir, '/', DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . strtr($uri, '/', DIRECTORY_SEPARATOR); // "unresolve" a symlink back to doc root foreach (self::$_symlinks as $link => $target) { if (0 === strpos($path, $target)) { // replace $target with $link $path = $link . substr($path, strlen($target)); break; } } // strip doc root $path = substr($path, strlen(self::$_docRoot)); // fix to root-relative URI $uri = strtr($path, DIRECTORY_SEPARATOR, '/'); // remove /./ and /../ where possible $uri = str_replace('/./', '/', $uri); // inspired by patch from Oleg Cherniy do { $uri = preg_replace('@/[^/]+/\\.\\./@', '/', $uri, -1, $changed); } while ($changed); } } } if ($isImport) { return "@import {$quoteChar}{$uri}{$quoteChar}"; } else { return "url({$quoteChar}{$uri}{$quoteChar})"; } } } wp-super-cache/min/lib/Minify/CSS.php0000644000076500007650000000566411140200462017125 0ustar jhardijhardi * @author http://code.google.com/u/1stvamp/ (Issue 64 patch) */ class Minify_CSS { /** * Minify a CSS string * * @param string $css * * @param array $options available options: * * 'preserveComments': (default true) multi-line comments that begin * with "/*!" will be preserved with newlines before and after to * enhance readability. * * 'prependRelativePath': (default null) if given, this string will be * prepended to all relative URIs in import/url declarations * * 'currentDir': (default null) if given, this is assumed to be the * directory of the current CSS file. Using this, minify will rewrite * all relative URIs in import/url declarations to correctly point to * the desired files. For this to work, the files *must* exist and be * visible by the PHP process. * * 'symlinks': (default = array()) If the CSS file is stored in * a symlink-ed directory, provide an array of link paths to * target paths, where the link paths are within the document root. Because * paths need to be normalized for this to work, use "//" to substitute * the doc root in the link paths (the array keys). E.g.: * * array('//symlink' => '/real/target/path') // unix * array('//static' => 'D:\\staticStorage') // Windows * * * @return string */ public static function minify($css, $options = array()) { require_once 'Minify/CSS/Compressor.php'; if (isset($options['preserveComments']) && !$options['preserveComments']) { $css = Minify_CSS_Compressor::process($css, $options); } else { require_once 'Minify/CommentPreserver.php'; $css = Minify_CommentPreserver::process( $css ,array('Minify_CSS_Compressor', 'process') ,array($options) ); } if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) { return $css; } require_once 'Minify/CSS/UriRewriter.php'; if (isset($options['currentDir'])) { return Minify_CSS_UriRewriter::rewrite( $css ,$options['currentDir'] ,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT'] ,isset($options['symlinks']) ? $options['symlinks'] : array() ); } else { return Minify_CSS_UriRewriter::prepend( $css ,$options['prependRelativePath'] ); } } } wp-super-cache/min/lib/Minify/HTML.php0000644000076500007650000001603011140162002017223 0ustar jhardijhardi */ class Minify_HTML { /** * Defines which class to call as part of callbacks, change this * if you extend Minify_HTML * @var string */ protected static $className = 'Minify_HTML'; /** * "Minify" an HTML page * * @param string $html * * @param array $options * * 'cssMinifier' : (optional) callback function to process content of STYLE * elements. * * 'jsMinifier' : (optional) callback function to process content of SCRIPT * elements. Note: the type attribute is ignored. * * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If * unset, minify will sniff for an XHTML doctype. * * @return string */ public static function minify($html, $options = array()) { if (isset($options['cssMinifier'])) { self::$_cssMinifier = $options['cssMinifier']; } if (isset($options['jsMinifier'])) { self::$_jsMinifier = $options['jsMinifier']; } $html = str_replace("\r\n", "\n", trim($html)); self::$_isXhtml = ( isset($options['xhtml']) ? (bool)$options['xhtml'] : (false !== strpos($html, ']*?>)([\\s\\S]*?)<\\/script>(\\s*)/i' ,array(self::$className, '_removeScriptCB') ,$html); // replace STYLEs (and minify) with placeholders $html = preg_replace_callback( '/\\s*(]*?>)([\\s\\S]*?)<\\/style>\\s*/i' ,array(self::$className, '_removeStyleCB') ,$html); // remove HTML comments (not containing IE conditional comments). $html = preg_replace_callback( '//' ,array(self::$className, '_commentCB') ,$html); // replace PREs with placeholders $html = preg_replace_callback('/\\s*(]*?>[\\s\\S]*?<\\/pre>)\\s*/i' ,array(self::$className, '_removePreCB') , $html); // replace TEXTAREAs with placeholders $html = preg_replace_callback( '/\\s*(]*?>[\\s\\S]*?<\\/textarea>)\\s*/i' ,array(self::$className, '_removeTaCB') , $html); // trim each line. // @todo take into account attribute values that span multiple lines. $html = preg_replace('/^\\s+|\\s+$/m', '', $html); // remove ws around block/undisplayed elements $html = preg_replace('/\\s+(<\\/?(?:area|base(?:font)?|blockquote|body' .'|caption|center|cite|col(?:group)?|dd|dir|div|dl|dt|fieldset|form' .'|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta' .'|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h||r|foot|itle)' .'|ul)\\b[^>]*>)/i', '$1', $html); // remove ws outside of all elements $html = preg_replace_callback( '/>([^<]+)]+>)/i', "$1\n$2", $html); // fill placeholders $html = str_replace( array_keys(self::$_placeholders) ,array_values(self::$_placeholders) ,$html ); self::$_placeholders = array(); self::$_cssMinifier = self::$_jsMinifier = null; return $html; } protected static function _commentCB($m) { return (0 === strpos($m[1], '[') || false !== strpos($m[1], '' . preg_replace('/^\\s+|\\s+$/', ' ', $m[1]) . '<'; } protected static function _removePreCB($m) { return self::_reservePlace($m[1]); } protected static function _removeTaCB($m) { return self::_reservePlace($m[1]); } protected static function _removeStyleCB($m) { $openStyle = $m[1]; $css = $m[2]; // remove HTML comments $css = preg_replace('/(?:^\\s*\\s*$)/', '', $css); // remove CDATA section markers $css = self::_removeCdata($css); // minify $minifier = self::$_cssMinifier ? self::$_cssMinifier : 'trim'; $css = call_user_func($minifier, $css); return self::_reservePlace(self::_needsCdata($css) ? "{$openStyle}/**/" : "{$openStyle}{$css}" ); } protected static function _removeScriptCB($m) { $openScript = $m[2]; $js = $m[3]; // whitespace surrounding? preserve at least one space $ws1 = ($m[1] === '') ? '' : ' '; $ws2 = ($m[4] === '') ? '' : ' '; // remove HTML comments (and ending "//" if present) $js = preg_replace('/(?:^\\s*\\s*$)/', '', $js); // remove CDATA section markers $js = self::_removeCdata($js); // minify $minifier = self::$_jsMinifier ? self::$_jsMinifier : 'trim'; $js = call_user_func($minifier, $js); return self::_reservePlace(self::_needsCdata($js) ? "{$ws1}{$openScript}/**/{$ws2}" : "{$ws1}{$openScript}{$js}{$ws2}" ); } protected static function _removeCdata($str) { return (false !== strpos($str, ''), '', $str) : $str; } protected static function _needsCdata($str) { return (self::$_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str)); } } wp-super-cache/min/lib/Minify/ImportProcessor.php0000644000076500007650000001236011073147656021662 0ustar jhardijhardi */ class Minify_ImportProcessor { public static $filesIncluded = array(); public static function process($file) { self::$filesIncluded = array(); self::$_isCss = (strtolower(substr($file, -4)) === '.css'); $obj = new Minify_ImportProcessor(dirname($file)); return $obj->_getContent($file); } // allows callback funcs to know the current directory private $_currentDir = null; // allows _importCB to write the fetched content back to the obj private $_importedContent = ''; private static $_isCss = null; private function __construct($currentDir) { $this->_currentDir = $currentDir; } private function _getContent($file) { $file = realpath($file); if (! $file || in_array($file, self::$filesIncluded) || false === ($content = @file_get_contents($file)) ) { // file missing, already included, or failed read return ''; } self::$filesIncluded[] = realpath($file); $this->_currentDir = dirname($file); // remove UTF-8 BOM if present if (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3)) { $content = substr($content, 3); } // ensure uniform EOLs $content = str_replace("\r\n", "\n", $content); // process @imports $content = preg_replace_callback( '/ @import\\s+ (?:url\\(\\s*)? # maybe url( [\'"]? # maybe quote (.*?) # 1 = URI [\'"]? # maybe end quote (?:\\s*\\))? # maybe ) ([a-zA-Z,\\s]*)? # 2 = media list ; # end token /x' ,array($this, '_importCB') ,$content ); if (self::$_isCss) { // rewrite remaining relative URIs $content = preg_replace_callback( '/url\\(\\s*([^\\)\\s]+)\\s*\\)/' ,array($this, '_urlCB') ,$content ); } return $this->_importedContent . $content; } private function _importCB($m) { $url = $m[1]; $mediaList = preg_replace('/\\s+/', '', $m[2]); if (strpos($url, '://') > 0) { // protocol, leave in place for CSS, comment for JS return self::$_isCss ? $m[0] : "/* Minify_ImportProcessor will not include remote content */"; } if ('/' === $url[0]) { // protocol-relative or root path $url = ltrim($url, '/'); $file = realpath($_SERVER['DOCUMENT_ROOT']) . DIRECTORY_SEPARATOR . strtr($url, '/', DIRECTORY_SEPARATOR); } else { // relative to current path $file = $this->_currentDir . DIRECTORY_SEPARATOR . strtr($url, '/', DIRECTORY_SEPARATOR); } $obj = new Minify_ImportProcessor(dirname($file)); $content = $obj->_getContent($file); if ('' === $content) { // failed. leave in place for CSS, comment for JS return self::$_isCss ? $m[0] : "/* Minify_ImportProcessor could not fetch '{$file}' */";; } return (!self::$_isCss || preg_match('@(?:^$|\\ball\\b)@', $mediaList)) ? $content : "@media {$mediaList} {\n{$content}\n}\n"; } private function _urlCB($m) { // $m[1] is either quoted or not $quote = ($m[1][0] === "'" || $m[1][0] === '"') ? $m[1][0] : ''; $url = ($quote === '') ? $m[1] : substr($m[1], 1, strlen($m[1]) - 2); if ('/' !== $url[0]) { if (strpos($url, '//') > 0) { // probably starts with protocol, do not alter } else { // prepend path with current dir separator (OS-independent) $path = $this->_currentDir . DIRECTORY_SEPARATOR . strtr($url, '/', DIRECTORY_SEPARATOR); // strip doc root $path = substr($path, strlen(realpath($_SERVER['DOCUMENT_ROOT']))); // fix to absolute URL $url = strtr($path, DIRECTORY_SEPARATOR, '/'); // remove /./ and /../ where possible $url = str_replace('/./', '/', $url); // inspired by patch from Oleg Cherniy do { $url = preg_replace('@/[^/]+/\\.\\./@', '/', $url, -1, $changed); } while ($changed); } } return "url({$quote}{$url}{$quote})"; } } wp-super-cache/min/lib/Minify/Javascript.php0000644000076500007650000000104211060620714020574 0ustar jhardijhardi */ class Minify_Javascript { /** * Minify a Javascript string * * @param string $js * * @param array $options available options (none currently) * * @return string */ public static function minify($js, $options = array()) { return trim(JSMin::minify($js)); } } wp-super-cache/min/lib/Minify/Lines.php0000644000076500007650000000615111122006010017530 0ustar jhardijhardi * @author Adam Pedersen (Issue 55 fix) */ class Minify_Lines { /** * Add line numbers in C-style comments * * This uses a very basic parser easily fooled by comment tokens inside * strings or regexes, but, otherwise, generally clean code will not be * mangled. * * @param string $content * * @param array $options available options: * * 'id': (optional) string to identify file. E.g. file name/path * * @return string */ public static function minify($content, $options = array()) { $id = (isset($options['id']) && $options['id']) ? $options['id'] : ''; $content = str_replace("\r\n", "\n", $content); $lines = explode("\n", $content); $numLines = count($lines); // determine left padding $padTo = strlen($numLines); $inComment = false; $i = 0; $newLines = array(); while (null !== ($line = array_shift($lines))) { if (('' !== $id) && (0 == $i % 50)) { array_push($newLines, '', "/* {$id} */", ''); } ++$i; $newLines[] = self::_addNote($line, $i, $inComment, $padTo); $inComment = self::_eolInComment($line, $inComment); } return implode("\n", $newLines) . "\n"; } /** * Is the parser within a C-style comment at the end of this line? * * @param string $line current line of code * * @param bool $inComment was the parser in a comment at the * beginning of the line? * * @return bool */ private static function _eolInComment($line, $inComment) { while (strlen($line)) { $search = $inComment ? '*/' : '/*'; $pos = strpos($line, $search); if (false === $pos) { return $inComment; } else { if ($pos == 0 || ($inComment ? substr($line, $pos, 3) : substr($line, $pos-1, 3)) != '*/*') { $inComment = ! $inComment; } $line = substr($line, $pos + 2); } } return $inComment; } /** * Prepend a comment (or note) to the given line * * @param string $line current line of code * * @param string $note content of note/comment * * @param bool $inComment was the parser in a comment at the * beginning of the line? * * @param int $padTo minimum width of comment * * @return string */ private static function _addNote($line, $note, $inComment, $padTo) { return $inComment ? '/* ' . str_pad($note, $padTo, ' ', STR_PAD_RIGHT) . ' *| ' . $line : '/* ' . str_pad($note, $padTo, ' ', STR_PAD_RIGHT) . ' */ ' . $line; } } wp-super-cache/min/lib/Minify/Logger.php0000644000076500007650000000174011140162002017700 0ustar jhardijhardi */ class Minify_Logger { /** * Set logger object. * * The object should have a method "log" that accepts a value as 1st argument and * an optional string label as the 2nd. * * @param mixed $obj or a "falsey" value to disable * @return null */ public static function setLogger($obj = null) { self::$_logger = $obj ? $obj : null; } /** * Pass a message to the logger (if set) * * @param string $msg message to log * @return null */ public static function log($msg, $label = 'Minify') { if (! self::$_logger) return; self::$_logger->log($msg, $label); } /** * @var mixed logger object (like FirePHP) or null (i.e. no logger available) */ private static $_logger = null; } wp-super-cache/min/lib/Minify/Packer.php0000644000076500007650000000211611122006010017660 0ustar jhardijhardipack()); } } wp-super-cache/min/lib/Minify/Source.php0000644000076500007650000001156011056115304017733 0ustar jhardijhardi */ class Minify_Source { /** * @var int time of last modification */ public $lastModified = null; /** * @var callback minifier function specifically for this source. */ public $minifier = null; /** * @var array minification options specific to this source. */ public $minifyOptions = null; /** * @var string full path of file */ public $filepath = null; /** * Create a Minify_Source * * In the $spec array(), you can either provide a 'filepath' to an existing * file (existence will not be checked!) or give 'id' (unique string for * the content), 'content' (the string content) and 'lastModified' * (unixtime of last update). * * As a shortcut, the controller will replace "//" at the beginning * of a filepath with $_SERVER['DOCUMENT_ROOT'] . '/'. * * @param array $spec options */ public function __construct($spec) { if (isset($spec['filepath'])) { if (0 === strpos($spec['filepath'], '//')) { $spec['filepath'] = $_SERVER['DOCUMENT_ROOT'] . substr($spec['filepath'], 1); } $this->filepath = $spec['filepath']; $this->_id = $spec['filepath']; $this->lastModified = filemtime($spec['filepath']) // offset for Windows uploaders with out of sync clocks + round(Minify::$uploaderHoursBehind * 3600); } elseif (isset($spec['id'])) { $this->_id = 'id::' . $spec['id']; if (isset($spec['content'])) { $this->_content = $spec['content']; } else { $this->_getContentFunc = $spec['getContentFunc']; } $this->lastModified = isset($spec['lastModified']) ? $spec['lastModified'] : time(); } if (isset($spec['minifier'])) { $this->minifier = $spec['minifier']; } if (isset($spec['minifyOptions'])) { $this->minifyOptions = $spec['minifyOptions']; } } /** * Get content * * @return string */ public function getContent() { $content = (null !== $this->filepath) ? file_get_contents($this->filepath) : ((null !== $this->_content) ? $this->_content : call_user_func($this->_getContentFunc, $this->_id) ); // remove UTF-8 BOM if present return (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3)) ? substr($content, 3) : $content; } /** * Get id * * @return string */ public function getId() { return $this->_id; } /** * Verifies a single minification call can handle all sources * * @param array $sources Minify_Source instances * * @return bool true iff there no sources with specific minifier preferences. */ public static function haveNoMinifyPrefs($sources) { foreach ($sources as $source) { if (null !== $source->minifier || null !== $source->minifyOptions) { return false; } } return true; } /** * Get unique string for a set of sources * * @param array $sources Minify_Source instances * * @return string */ public static function getDigest($sources) { foreach ($sources as $source) { $info[] = array( $source->_id, $source->minifier, $source->minifyOptions ); } return md5(serialize($info)); } /** * Guess content type from the first filename extension available * * This is called if the user doesn't pass in a 'contentType' options * * @param array $sources Minify_Source instances * * @return string content type. e.g. 'text/css' */ public static function getContentType($sources) { $exts = array( 'css' => Minify::TYPE_CSS ,'js' => Minify::TYPE_JS ,'html' => Minify::TYPE_HTML ); foreach ($sources as $source) { if (null !== $source->filepath) { $segments = explode('.', $source->filepath); $ext = array_pop($segments); if (isset($exts[$ext])) { return $exts[$ext]; } } } return 'text/plain'; } protected $_content = null; protected $_getContentFunc = null; protected $_id = null; } wp-super-cache/min/lib/Minify/YUICompressor.php0000644000076500007650000000745211061146636021233 0ustar jhardijhardi * Minify_YUICompressor::$jarFile = '/path/to/yuicompressor-2.3.5.jar'; * Minify_YUICompressor::$tempDir = '/tmp'; * $code = Minify_YUICompressor::minifyJs( * $code * ,array('nomunge' => true, 'line-break' => 1000) * ); * * * @todo unit tests, $options docs * * @package Minify * @author Stephen Clay */ class Minify_YUICompressor { /** * Filepath of the YUI Compressor jar file. This must be set before * calling minifyJs() or minifyCss(). * * @var string */ public static $jarFile = null; /** * Writable temp directory. This must be set before calling minifyJs() * or minifyCss(). * * @var string */ public static $tempDir = null; /** * Filepath of "java" executable (may be needed if not in shell's PATH) * * @var string */ public static $javaExecutable = 'java'; /** * Minify a Javascript string * * @param string $js * * @param array $options (verbose is ignored) * * @see http://www.julienlecomte.net/yuicompressor/README * * @return string */ public static function minifyJs($js, $options = array()) { return self::_minify('js', $js, $options); } /** * Minify a CSS string * * @param string $css * * @param array $options (verbose is ignored) * * @see http://www.julienlecomte.net/yuicompressor/README * * @return string */ public static function minifyCss($css, $options = array()) { return self::_minify('css', $css, $options); } private static function _minify($type, $content, $options) { self::_prepare(); if (! ($tmpFile = tempnam(self::$tempDir, 'yuic_'))) { throw new Exception('Minify_YUICompressor : could not create temp file.'); } file_put_contents($tmpFile, $content); exec(self::_getCmd($options, $type, $tmpFile), $output); unlink($tmpFile); return implode("\n", $output); } private static function _getCmd($userOptions, $type, $tmpFile) { $o = array_merge( array( 'charset' => '' ,'line-break' => 5000 ,'type' => $type ,'nomunge' => false ,'preserve-semi' => false ,'disable-optimizations' => false ) ,$userOptions ); $cmd = self::$javaExecutable . ' -jar ' . escapeshellarg(self::$jarFile) . " --type {$type}" . (preg_match('/^[a-zA-Z\\-]+$/', $o['charset']) ? " --charset {$o['charset']}" : '') . (is_numeric($o['line-break']) && $o['line-break'] >= 0 ? ' --line-break ' . (int)$o['line-break'] : ''); if ($type === 'js') { foreach (array('nomunge', 'preserve-semi', 'disable-optimizations') as $opt) { $cmd .= $o[$opt] ? " --{$opt}" : ''; } } return $cmd . ' ' . escapeshellarg($tmpFile); } private static function _prepare() { if (! is_file(self::$jarFile) || ! is_dir(self::$tempDir) || ! is_writable(self::$tempDir) ) { throw new Exception('Minify_YUICompressor : $jarFile and $tempDir must be set.'); } } } wp-super-cache/min/lib/Minify.php0000644000076500007650000005103511151573110016473 0ustar jhardijhardi * @author Stephen Clay * @copyright 2008 Ryan Grove, Stephen Clay. All rights reserved. * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://code.google.com/p/minify/ */ class Minify { const TYPE_CSS = 'text/css'; const TYPE_HTML = 'text/html'; // there is some debate over the ideal JS Content-Type, but this is the // Apache default and what Yahoo! uses.. const TYPE_JS = 'application/x-javascript'; /** * How many hours behind are the file modification times of uploaded files? * * If you upload files from Windows to a non-Windows server, Windows may report * incorrect mtimes for the files. Immediately after modifying and uploading a * file, use the touch command to update the mtime on the server. If the mtime * jumps ahead by a number of hours, set this variable to that number. If the mtime * moves back, this should not be needed. * * @var int $uploaderHoursBehind */ public static $uploaderHoursBehind = 0; /** * If this string is not empty AND the serve() option 'bubbleCssImports' is * NOT set, then serve() will check CSS files for @import declarations that * appear too late in the combined stylesheet. If found, serve() will prepend * the output with this warning. * * @var string $importWarning */ public static $importWarning = "/* See http://code.google.com/p/minify/wiki/CommonProblems#@imports_can_appear_in_invalid_locations_in_combined_CSS_files */"; /** * Specify a cache object (with identical interface as Minify_Cache_File) or * a path to use with Minify_Cache_File. * * If not called, Minify will not use a cache and, for each 200 response, will * need to recombine files, minify and encode the output. * * @param mixed $cache object with identical interface as Minify_Cache_File or * a directory path, or null to disable caching. (default = '') * * @param bool $fileLocking (default = true) This only applies if the first * parameter is a string. * * @return null */ public static function setCache($cache = '', $fileLocking = true) { if (is_string($cache)) { require_once 'Minify/Cache/File.php'; self::$_cache = new Minify_Cache_File($cache, $fileLocking); } else { self::$_cache = $cache; } } /** * Serve a request for a minified file. * * Here are the available options and defaults in the base controller: * * 'isPublic' : send "public" instead of "private" in Cache-Control * headers, allowing shared caches to cache the output. (default true) * * 'quiet' : set to true to have serve() return an array rather than sending * any headers/output (default false) * * 'encodeOutput' : to disable content encoding, set this to false (default true) * * 'encodeMethod' : generally you should let this be determined by * HTTP_Encoder (leave null), but you can force a particular encoding * to be returned, by setting this to 'gzip', 'deflate', or '' (no encoding) * * 'encodeLevel' : level of encoding compression (0 to 9, default 9) * * 'contentTypeCharset' : appended to the Content-Type header sent. Set to a falsey * value to remove. (default 'UTF-8') * * 'maxAge' : set this to the number of seconds the client should use its cache * before revalidating with the server. This sets Cache-Control: max-age and the * Expires header. Unlike the old 'setExpires' setting, this setting will NOT * prevent conditional GETs. Note this has nothing to do with server-side caching. * * 'rewriteCssUris' : If true, serve() will automatically set the 'currentDir' * minifier option to enable URI rewriting in CSS files (default true) * * 'bubbleCssImports' : If true, all @import declarations in combined CSS * files will be move to the top. Note this may alter effective CSS values * due to a change in order. (default false) * * 'debug' : set to true to minify all sources with the 'Lines' controller, which * eases the debugging of combined files. This also prevents 304 responses. * @see Minify_Lines::minify() * * 'minifiers' : to override Minify's default choice of minifier function for * a particular content-type, specify your callback under the key of the * content-type: * * // call customCssMinifier($css) for all CSS minification * $options['minifiers'][Minify::TYPE_CSS] = 'customCssMinifier'; * * // don't minify Javascript at all * $options['minifiers'][Minify::TYPE_JS] = ''; * * * 'minifierOptions' : to send options to the minifier function, specify your options * under the key of the content-type. E.g. To send the CSS minifier an option: * * // give CSS minifier array('optionName' => 'optionValue') as 2nd argument * $options['minifierOptions'][Minify::TYPE_CSS]['optionName'] = 'optionValue'; * * * 'contentType' : (optional) this is only needed if your file extension is not * js/css/html. The given content-type will be sent regardless of source file * extension, so this should not be used in a Groups config with other * Javascript/CSS files. * * Any controller options are documented in that controller's setupSources() method. * * @param mixed instance of subclass of Minify_Controller_Base or string name of * controller. E.g. 'Files' * * @param array $options controller/serve options * * @return mixed null, or, if the 'quiet' option is set to true, an array * with keys "success" (bool), "statusCode" (int), "content" (string), and * "headers" (array). */ public static function serve($controller, $options = array()) { if (is_string($controller)) { // make $controller into object $class = 'Minify_Controller_' . $controller; if (! class_exists($class, false)) { require_once "Minify/Controller/" . str_replace('_', '/', $controller) . ".php"; } $controller = new $class(); } // set up controller sources and mix remaining options with // controller defaults $options = $controller->setupSources($options); $options = $controller->analyzeSources($options); self::$_options = $controller->mixInDefaultOptions($options); // check request validity if (! $controller->sources) { // invalid request! if (! self::$_options['quiet']) { header(self::$_options['badRequestHeader']); echo self::$_options['badRequestHeader']; return; } else { list(,$statusCode) = explode(' ', self::$_options['badRequestHeader']); return array( 'success' => false ,'statusCode' => (int)$statusCode ,'content' => '' ,'headers' => array() ); } } self::$_controller = $controller; if (self::$_options['debug']) { self::_setupDebug($controller->sources); self::$_options['maxAge'] = 0; } // check client cache require_once 'HTTP/ConditionalGet.php'; $cgOptions = array( 'lastModifiedTime' => self::$_options['lastModifiedTime'] ,'isPublic' => self::$_options['isPublic'] ); if (self::$_options['maxAge'] > 0) { $cgOptions['maxAge'] = self::$_options['maxAge']; } $cg = new HTTP_ConditionalGet($cgOptions); if ($cg->cacheIsValid) { // client's cache is valid if (! self::$_options['quiet']) { $cg->sendHeaders(); return; } else { return array( 'success' => true ,'statusCode' => 304 ,'content' => '' ,'headers' => $cg->getHeaders() ); } } else { // client will need output $headers = $cg->getHeaders(); unset($cg); } // determine encoding if (self::$_options['encodeOutput']) { if (self::$_options['encodeMethod'] !== null) { // controller specifically requested this $contentEncoding = self::$_options['encodeMethod']; } else { // sniff request header require_once 'HTTP/Encoder.php'; // depending on what the client accepts, $contentEncoding may be // 'x-gzip' while our internal encodeMethod is 'gzip'. Calling // getAcceptedEncoding() with false leaves out compress as an option. list(self::$_options['encodeMethod'], $contentEncoding) = HTTP_Encoder::getAcceptedEncoding(false); } } else { self::$_options['encodeMethod'] = ''; // identity (no encoding) } if (self::$_options['contentType'] === self::TYPE_CSS && self::$_options['rewriteCssUris']) { reset($controller->sources); while (list($key, $source) = each($controller->sources)) { if ($source->filepath && !isset($source->minifyOptions['currentDir']) && !isset($source->minifyOptions['prependRelativePath']) ) { $source->minifyOptions['currentDir'] = dirname($source->filepath); } } } // check server cache if (null !== self::$_cache) { // using cache // the goal is to use only the cache methods to sniff the length and // output the content, as they do not require ever loading the file into // memory. $cacheId = 'minify_' . self::_getCacheId(); $encodingExtension = self::$_options['encodeMethod'] ? ('deflate' === self::$_options['encodeMethod'] ? '.zd' : '.zg') : ''; $fullCacheId = $cacheId . $encodingExtension; // check cache for valid entry $cacheIsReady = self::$_cache->isValid($fullCacheId, self::$_options['lastModifiedTime']); if ($cacheIsReady) { $cacheContentLength = self::$_cache->getSize($fullCacheId); } else { // generate & cache content $content = self::_combineMinify(); self::$_cache->store($cacheId, $content); if (function_exists('gzdeflate')) { self::$_cache->store($cacheId . '.zd', gzdeflate($content, self::$_options['encodeLevel'])); self::$_cache->store($cacheId . '.zg', gzencode($content, self::$_options['encodeLevel'])); } } } else { // no cache $cacheIsReady = false; $content = self::_combineMinify(); } if (! $cacheIsReady && self::$_options['encodeMethod']) { // still need to encode $content = ('deflate' === self::$_options['encodeMethod']) ? gzdeflate($content, self::$_options['encodeLevel']) : gzencode($content, self::$_options['encodeLevel']); } // add headers $headers['Content-Length'] = $cacheIsReady ? $cacheContentLength : strlen($content); $headers['Content-Type'] = self::$_options['contentTypeCharset'] ? self::$_options['contentType'] . '; charset=' . self::$_options['contentTypeCharset'] : self::$_options['contentType']; if (self::$_options['encodeMethod'] !== '') { $headers['Content-Encoding'] = $contentEncoding; $headers['Vary'] = 'Accept-Encoding'; } if (! self::$_options['quiet']) { // output headers & content foreach ($headers as $name => $val) { header($name . ': ' . $val); } if ($cacheIsReady) { self::$_cache->display($fullCacheId); } else { echo $content; } } else { return array( 'success' => true ,'statusCode' => 200 ,'content' => $cacheIsReady ? self::$_cache->fetch($fullCacheId) : $content ,'headers' => $headers ); } } /** * Return combined minified content for a set of sources * * No internal caching will be used and the content will not be HTTP encoded. * * @param array $sources array of filepaths and/or Minify_Source objects * * @param array $options (optional) array of options for serve. By default * these are already set: quiet = true, encodeMethod = '', lastModifiedTime = 0. * * @return string */ public static function combine($sources, $options = array()) { $cache = self::$_cache; self::$_cache = null; $options = array_merge(array( 'files' => (array)$sources ,'quiet' => true ,'encodeMethod' => '' ,'lastModifiedTime' => 0 ), $options); $out = self::serve('Files', $options); self::$_cache = $cache; return $out['content']; } /** * On IIS, create $_SERVER['DOCUMENT_ROOT'] * * @param bool $unsetPathInfo (default false) if true, $_SERVER['PATH_INFO'] * will be unset (it is inconsistent with Apache's setting) * * @return null */ public static function setDocRoot($unsetPathInfo = false) { if (isset($_SERVER['SERVER_SOFTWARE']) && 0 === strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/') ) { $_SERVER['DOCUMENT_ROOT'] = substr( $_SERVER['PATH_TRANSLATED'] ,0 ,strlen($_SERVER['PATH_TRANSLATED']) - strlen($_SERVER['SCRIPT_NAME']) ); if ($unsetPathInfo) { unset($_SERVER['PATH_INFO']); } require_once 'Minify/Logger.php'; Minify_Logger::log("setDocRoot() set DOCUMENT_ROOT to \"{$_SERVER['DOCUMENT_ROOT']}\""); } } /** * @var mixed Minify_Cache_* object or null (i.e. no server cache is used) */ private static $_cache = null; /** * @var Minify_Controller active controller for current request */ protected static $_controller = null; /** * @var array options for current request */ protected static $_options = null; /** * Set up sources to use Minify_Lines * * @param array $sources Minify_Source instances * * @return null */ protected static function _setupDebug($sources) { foreach ($sources as $source) { $source->minifier = array('Minify_Lines', 'minify'); $id = $source->getId(); $source->minifyOptions = array( 'id' => (is_file($id) ? basename($id) : $id) ); } } /** * Combines sources and minifies the result. * * @return string */ protected static function _combineMinify() { $type = self::$_options['contentType']; // ease readability // when combining scripts, make sure all statements separated and // trailing single line comment is terminated $implodeSeparator = ($type === self::TYPE_JS) ? "\n;" : ''; // allow the user to pass a particular array of options to each // minifier (designated by type). source objects may still override // these $defaultOptions = isset(self::$_options['minifierOptions'][$type]) ? self::$_options['minifierOptions'][$type] : array(); // if minifier not set, default is no minification. source objects // may still override this $defaultMinifier = isset(self::$_options['minifiers'][$type]) ? self::$_options['minifiers'][$type] : false; if (Minify_Source::haveNoMinifyPrefs(self::$_controller->sources)) { // all source have same options/minifier, better performance // to combine, then minify once foreach (self::$_controller->sources as $source) { $pieces[] = $source->getContent(); } $content = implode($implodeSeparator, $pieces); if ($defaultMinifier) { self::$_controller->loadMinifier($defaultMinifier); $content = call_user_func($defaultMinifier, $content, $defaultOptions); } } else { // minify each source with its own options and minifier, then combine foreach (self::$_controller->sources as $source) { // allow the source to override our minifier and options $minifier = (null !== $source->minifier) ? $source->minifier : $defaultMinifier; $options = (null !== $source->minifyOptions) ? array_merge($defaultOptions, $source->minifyOptions) : $defaultOptions; if ($minifier) { self::$_controller->loadMinifier($minifier); // get source content and minify it $pieces[] = call_user_func($minifier, $source->getContent(), $options); } else { $pieces[] = $source->getContent(); } } $content = implode($implodeSeparator, $pieces); } if ($type === self::TYPE_CSS && false !== strpos($content, '@import')) { $content = self::_handleCssImports($content); } // do any post-processing (esp. for editing build URIs) if (self::$_options['postprocessorRequire']) { require_once self::$_options['postprocessorRequire']; } if (self::$_options['postprocessor']) { $content = call_user_func(self::$_options['postprocessor'], $content, $type); } return $content; } /** * Make a unique cache id for for this request. * * Any settings that could affect output are taken into consideration * * @return string */ protected static function _getCacheId() { return md5(serialize(array( Minify_Source::getDigest(self::$_controller->sources) ,self::$_options['minifiers'] ,self::$_options['minifierOptions'] ,self::$_options['postprocessor'] ,self::$_options['bubbleCssImports'] ))); } /** * Bubble CSS @imports to the top or prepend a warning if an * @import is detected not at the top. */ protected static function _handleCssImports($css) { if (self::$_options['bubbleCssImports']) { // bubble CSS imports preg_match_all('/@import.*?;/', $css, $imports); $css = implode('', $imports[0]) . preg_replace('/@import.*?;/', '', $css); } else if ('' !== self::$importWarning) { // remove comments so we don't mistake { in a comment as a block $noCommentCss = preg_replace('@/\\*[\\s\\S]*?\\*/@', '', $css); $lastImportPos = strrpos($noCommentCss, '@import'); $firstBlockPos = strpos($noCommentCss, '{'); if (false !== $lastImportPos && false !== $firstBlockPos && $firstBlockPos < $lastImportPos ) { // { appears before @import : prepend warning $css = self::$importWarning . $css; } } return $css; } } wp-super-cache/min/lib/MyMin.php0000644000076500007650000002104111077206576016303 0ustar jhardijhardi * @copyright 2002 Douglas Crockford (jsmin.c) * @copyright 2007 Ryan Grove (PHP port) * @copyright 2007 Andrea Giammarchi (improvements + MyMinCompressor + MyMinCSS) * @license http://opensource.org/licenses/mit-license.php MIT License * @version 1.0.1 (2007-10-05) - updated 2008-02-17 */ // -- Class MyMin -------------------------------------------------------------- class MyMin { const /* char */ LF = "\n", SPACE = ' ', EOS = "\x00"; protected /* boolean */ $cc_on; protected /* char */ $a, $ahead, $b; protected /* int */ $index = 0, $length; protected /* string */ $input, $output = ""; // -- Public Static Methods ---------------------------------------------------- static public final function /* string */ parse(/* string */ $input, /* boolean */ $cc_on = true){ return "".(new MyMin($input, $cc_on)); } // -- Public Instance Methods -------------------------------------------------- public final function /* object */ __construct(/* string */ $input, /* boolean */ $cc_on = true){ $this->input = preg_replace("/(\r\n|\n\r|\r|\n)+/", self::LF, trim($input)); $this->length = strlen($this->input); $this->cc_on = $cc_on; $this->b = $this->ahead = self::SPACE; $this->a = self::LF; $this->action(3); while($this->a !== self::EOS){ switch($this->a){ case self::SPACE: $this->action($this->isAlNum($this->b) ? 1 : 2); break; case self::LF: switch($this->b){ case '{': case '[': case '(': case '+': case '-': $this->action(1); break; case self::SPACE: $this->action(3); break; default: $this->action($this->isAlNum($this->b) ? 1 : 2); break; } break; default: switch($this->b){ case self::SPACE: $this->action($this->isAlNum($this->a) ? 1 : 3); break; case self::LF: switch($this->a){ case '}': case ']': case ')': case '+': case '-': case '"': case '\'': $this->action(1); break; default: $this->action($this->isAlNum($this->a) ? 1 : 3); break; } break; default: $this->action(1); break; } break; } } } public final function /* string */ __toString(/* void */){ return str_replace("\n\n", "\n", ltrim($this->output)); } // -- Protected Instance Methods ----------------------------------------------- protected function /* void */ action(/* int */ $i){ switch($i){ case 1: $this->output .= $this->a; case 2: $this->a = $this->b; if($this->a === '\'' || $this->a === '"'){ while(true){ $this->output .= $this->a; if(!$this->nextCharNoSlash($this->b, "Unterminated string literal.")) break; } } case 3: $this->b = $this->next(); if($this->b === '/'){ switch($this->a){ case self::LF: case self::SPACE: if(!$this->spaceBeforeRegExp($this->output)) break; case '{': case ';': case '(': case ',': case '=': case ':': case '[': case '!': case '&': case '|': case '?': $this->output .= $this->a.$this->b; while($this->nextCharNoSlash('/', "Unterminated regular expression literal.")) $this->output .= $this->a; $this->b = $this->next(); break; } } break; } } protected function /* void */ appendComment(/* int */ $pos, /* string */ $open, /* string */ $close) { $this->output .= $this->a.$open.(new MyMin(substr($this->input, $this->index, $pos - $this->index), $this->cc_on)).$close; $this->index = $pos; $this->a = self::LF; } protected function /* void */ conditionalComment(/* char */ $find) { $single = $find === self::LF; $pos = strpos($this->input, $find, $this->index); if($pos === false){ if($single) $pos = $this->length; else throw new MyMinException("Unterminated comment."); } $this->appendComment($pos, $single ? "//" : "/*", $find); } protected function /* char */ get(/* void */) { $c = $this->ahead; $this->ahead = self::EOS; if($c === self::EOS && $this->index < $this->length) $c = $this->input{$this->index++}; return ($c === self::EOS || $c === self::LF || $c >= self::SPACE) ? $c : self::SPACE; } protected function /* boolean */ isAlNum(/* char */ $c) { return $c > 126 || $c === '\\' || preg_match('/^(\w|\$)$/', $c); } protected function /* char */ next(/* void */) { $c = $this->get(); $loop = true; if($c === '/'){ switch($this->ahead = $this->get()){ case '/': if($this->cc_on && $this->input{$this->index} === '@') $this->conditionalComment(self::LF); while($loop){ $c = $this->get(); if($c <= self::LF) $loop = false; } break; case '*': $this->get(); if($this->cc_on && $this->input{$this->index} === '@') $this->conditionalComment("*/"); while($loop){ switch($this->get()){ case '*': if(($this->ahead = $this->get()) === '/'){ $this->get(); $c = self::SPACE; $loop = false; } break; case self::EOS: throw new MyMinException("Unterminated comment."); } } break; } } return $c; } protected function /* boolean */ nextCharNoSlash(/* char */ $c, /* string */ $message) { $loop = true; $this->a = $this->get(); if($this->a === $c) $loop = false; else{ if($this->a === '\\'){ $this->output .= $this->a; $this->a = $this->get(); } if($this->a <= self::LF) throw new MyMinException($message); } return $loop; } protected function /* boolean */ spaceBeforeRegExp(/* string */ $output){ for( $i = 0, $length = strlen($output), $reserved = array("case", "else", "in", "return", "typeof"), $result = false, $tmp = ""; $i < 5 && !$result; $i++ ){ if($length === strlen($reserved[$i])) $result = $reserved[$i] === $output; else if($length > strlen($reserved[$i])){ $tmp = substr($output, $length - strlen($reserved[$i]) - 1); $result = substr($tmp, 1) === $reserved[$i] && !$this->isAlNum($tmp{0}); } }; return $length < 2 ? true : $result; } } // -- MyMin Exceptions --------------------------------------------------------- class MyMinException extends Exception {} wp-super-cache/min/lib/Solar/0000755000076500007650000000000011157407116015613 5ustar jhardijhardiwp-super-cache/min/lib/Solar/Dir.php0000644000076500007650000001237510772760676017071 0ustar jhardijhardi * * @license http://opensource.org/licenses/bsd-license.php BSD * * @version $Id: Dir.php 2926 2007-11-09 16:25:44Z pmjones $ * */ class Solar_Dir { /** * * The OS-specific temporary directory location. * * @var string * */ protected static $_tmp; /** * * Hack for [[php::is_dir() | ]] that checks the include_path. * * Use this to see if a directory exists anywhere in the include_path. * * {{code: php * $dir = Solar_Dir::exists('path/to/dir') * if ($dir) { * $files = scandir($dir); * } else { * echo "Not found in the include-path."; * } * }} * * @param string $dir Check for this directory in the include_path. * * @return mixed If the directory exists in the include_path, returns the * absolute path; if not, returns boolean false. * */ public static function exists($dir) { // no file requested? $dir = trim($dir); if (! $dir) { return false; } // using an absolute path for the file? // dual check for Unix '/' and Windows '\', // or Windows drive letter and a ':'. $abs = ($dir[0] == '/' || $dir[0] == '\\' || $dir[1] == ':'); if ($abs && is_dir($dir)) { return $dir; } // using a relative path on the file $path = explode(PATH_SEPARATOR, ini_get('include_path')); foreach ($path as $base) { // strip Unix '/' and Windows '\' $target = rtrim($base, '\\/') . DIRECTORY_SEPARATOR . $dir; if (is_dir($target)) { return $target; } } // never found it return false; } /** * * "Fixes" a directory string for the operating system. * * Use slashes anywhere you need a directory separator. Then run the * string through fixdir() and the slashes will be converted to the * proper separator (for example '\' on Windows). * * Always adds a final trailing separator. * * @param string $dir The directory string to 'fix'. * * @return string The "fixed" directory string. * */ public static function fix($dir) { $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir); return rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; } /** * * Convenience method for dirname() and higher-level directories. * * @param string $file Get the dirname() of this file. * * @param int $up Move up in the directory structure this many * times, default 0. * * @return string The dirname() of the file. * */ public static function name($file, $up = 0) { $dir = dirname($file); while ($up --) { $dir = dirname($dir); } return $dir; } /** * * Returns the OS-specific directory for temporary files. * * @param string $sub Add this subdirectory to the returned temporary * directory name. * * @return string The temporary directory path. * */ public static function tmp($sub = '') { // find the tmp dir if needed if (! Solar_Dir::$_tmp) { // use the system if we can if (function_exists('sys_get_temp_dir')) { $tmp = sys_get_temp_dir(); } else { $tmp = Solar_Dir::_tmp(); } // remove trailing separator and save Solar_Dir::$_tmp = rtrim($tmp, DIRECTORY_SEPARATOR); } // do we have a subdirectory request? $sub = trim($sub); if ($sub) { // remove leading and trailing separators, and force exactly // one trailing separator $sub = trim($sub, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; } return Solar_Dir::$_tmp . DIRECTORY_SEPARATOR . $sub; } /** * * Returns the OS-specific temporary directory location. * * @return string The temp directory path. * */ protected static function _tmp() { // non-Windows system? if (strtolower(substr(PHP_OS, 0, 3)) != 'win') { $tmp = empty($_ENV['TMPDIR']) ? getenv('TMPDIR') : $_ENV['TMPDIR']; if ($tmp) { return $tmp; } else { return '/tmp'; } } // Windows 'TEMP' $tmp = empty($_ENV['TEMP']) ? getenv('TEMP') : $_ENV['TEMP']; if ($tmp) { return $tmp; } // Windows 'TMP' $tmp = empty($_ENV['TMP']) ? getenv('TMP') : $_ENV['TMP']; if ($tmp) { return $tmp; } // Windows 'windir' $tmp = empty($_ENV['windir']) ? getenv('windir') : $_ENV['windir']; if ($tmp) { return $tmp; } // final fallback for Windows return getenv('SystemRoot') . '\\temp'; } }wp-super-cache/min/README.txt0000644000076500007650000001042111101474046015454 0ustar jhardijhardiThe files in this directory represent the default Minify setup designed to ease integration with your site. This app will combine and minify your Javascript or CSS files and serve them with HTTP compression and cache headers. RECOMMENDED It's recommended to edit config.php to set $min_cachePath to a writeable (by PHP) directory on your system. This will improve performance. GETTING STARTED The quickest way to get started is to use the Minify URI Builder application on your website: http://example.com/min/builder/ MINIFYING A SINGLE FILE Let's say you want to serve this file: http://example.com/wp-content/themes/default/default.css Here's the "Minify URL" for this file: http://example.com/min/?f=wp-content/themes/default/default.css In other words, the "f" argument is set to the file path from root without the initial "/". As CSS files may contain relative URIs, Minify will automatically "fix" these by rewriting them as root relative. COMBINING MULTIPLE FILES IN ONE DOWNLOAD Separate the paths given to "f" with commas. Let's say you have CSS files at these URLs: http://example.com/scripts/jquery-1.2.6.js http://example.com/scripts/site.js You can combine these files through Minify by requesting this URL: http://example.com/min/?f=scripts/jquery-1.2.6.js,scripts/site.js SIMPLIFYING URLS WITH A BASE PATH If you're combining files that share the same ancestor directory, you can use the "b" argument to set the base directory for the "f" argument. Do not include the leading or trailing "/" characters. E.g., the following URLs will serve the exact same content: http://example.com/min/?f=scripts/jquery-1.2.6.js,scripts/site.js,scripts/home.js http://example.com/min/?b=scripts&f=jquery-1.2.6.js,site.js,home.js MINIFY URLS IN HTML In (X)HTML files, don't forget to replace any "&" characters with "&". SPECIFYING ALLOWED DIRECTORIES By default, Minify will serve any *.css/*.js files within the DOCUMENT_ROOT. If you'd prefer to limit Minify's access to certain directories, set the $min_serveOptions['minApp']['allowDirs'] array in config.php. E.g. to limit to the /js and /themes/default directories, use: $min_serveOptions['minApp']['allowDirs'] = array('//js', '//themes/default'); GROUPS: FASTER PERFORMANCE AND BETTER URLS For the best performance, edit groupsConfig.php to pre-specify groups of files to be combined under preset keys. E.g., here's an example configuration in groupsConfig.php: return array( 'js' => array('//js/Class.js', '//js/email.js') ); This pre-selects the following files to be combined under the key "js": http://example.com/js/Class.js http://example.com/js/email.js You can now serve these files with this simple URL: http://example.com/min/?g=js GROUPS: SPECIFYING FILES OUTSIDE THE DOC_ROOT In the groupsConfig.php array, the "//" in the file paths is a shortcut for the DOCUMENT_ROOT, but you can also specify paths from the root of the filesystem or relative to the DOC_ROOT: return array( 'js' => array( '//js/file.js' // file within DOC_ROOT ,'//../file.js' // file in parent directory of DOC_ROOT ,'C:/Users/Steve/file.js' // file anywhere on filesystem ) ); FAR-FUTURE EXPIRES HEADERS Minify can send far-future (one year) Expires headers. To enable this you must add a number to the querystring (e.g. /min/?g=js&1234 or /min/f=file.js&1234) and alter it whenever a source file is changed. If you have a build process you can use a build/source control revision number. If you serve files as a group, you can use the utility function Minify_groupUri() to get a "versioned" Minify URI for use in your HTML. E.g.: "; DEBUG MODE In debug mode, instead of compressing files, Minify sends combined files with comments prepended to each line to show the line number in the original source file. To enable this, set $min_allowDebugFlag to true in config.php and append "&debug=1" to your URIs. E.g. /min/?f=script1.js,script2.js&debug=1 Known issue: files with comment-like strings/regexps can cause problems in this mode. QUESTIONS? http://groups.google.com/group/minifywp-super-cache/min/utils.php0000644000076500007650000000470711072266372015651 0ustar jhardijhardi * * * * * If you do not want ampersands as HTML entities, set Minify_Build::$ampersand = "&" * before using this function. * * @param string $group a key from groupsConfig.php * @param boolean $forceAmpersand (default false) Set to true if the RewriteRule * directives in .htaccess are functional. This will remove the "?" from URIs, making them * more cacheable by proxies. * @return string */ function Minify_groupUri($group, $forceAmpersand = false) { $path = $forceAmpersand ? "/g={$group}" : "/?g={$group}"; return _Minify_getBuild($group)->uri( '/' . basename(dirname(__FILE__)) . $path ,$forceAmpersand ); } /** * Get the last modification time of the source js/css files used by Minify to * build the page. * * If you're caching the output of Minify_groupUri(), you'll want to rebuild * the cache if it's older than this timestamp. * * * // simplistic HTML cache system * $file = '/path/to/cache/file'; * if (! file_exists($file) || filemtime($file) < Minify_groupsMtime(array('js', 'css'))) { * // (re)build cache * $page = buildPage(); // this calls Minify_groupUri() for js and css * file_put_contents($file, $page); * echo $page; * exit(); * } * readfile($file); * * * @param array $groups an array of keys from groupsConfig.php * @return int Unix timestamp of the latest modification */ function Minify_groupsMtime($groups) { $max = 0; foreach ((array)$groups as $group) { $max = max($max, _Minify_getBuild($group)->lastModified); } return $max; } /** * @param string $group a key from groupsConfig.php * @return Minify_Build * @private */ function _Minify_getBuild($group) { static $builds = array(); static $gc = false; if (false === $gc) { $gc = (require dirname(__FILE__) . '/groupsConfig.php'); } if (! isset($builds[$group])) { $builds[$group] = new Minify_Build($gc[$group]); } return $builds[$group]; } wp-super-cache/plugins/0000755000076500007650000000000011157412333014660 5ustar jhardijhardiwp-super-cache/plugins/badbehaviour.php0000644000076500007650000000357311151602174020032 0ustar jhardijhardi'; wp_nonce_field('wp-cache'); echo 'Bad Behaviour support is '; if( $cache_badbehaviour == 0 ) { echo 'disabled'; } else { echo 'enabled'; wp_super_cache_disable(); } echo '. (Only half-on caching supported and requires Bad Behaviour in "' . WP_CONTENT_DIR . '/plugins/Bad-Behaviour/") '; if( $cache_badbehaviour == 0 ) { echo ''; } else { echo ''; } echo "\n"; if( $err ) echo "

    Warning! $err

    "; } add_cacheaction( 'cache_admin_page', 'wp_supercache_badbehaviour_admin' ); ?> wp-super-cache/plugins/searchengine.php0000644000076500007650000000531211151602174020023 0ustar jhardijhardi'; wp_nonce_field('wp-cache'); echo 'No Adverts for Friends plugin is '; if( $cache_no_adverts_for_friends == 'no' ) { echo 'disabled'; } else { echo 'enabled'; } echo '. (requires friendsadverts.php too) '; if( $cache_no_adverts_for_friends == 'no' ) { echo ''; } else { echo ''; } echo "\n"; } add_cacheaction( 'cache_admin_page', 'wp_supercache_searchengine_admin' ); ?> wp-super-cache/readme.txt0000644000076500007650000003425611151602174015205 0ustar jhardijhardi=== WP Super Cache === Contributors: donncha Tags: performance,caching,wp-cache,wp-super-cache,cache Tested up to: 2.7.1 Stable tag: 0.9.1 Requires at least: 2.2 Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3244504 A very fast caching engine for WordPress that produces static html files. == Description == This plugin generates static html files from your dynamic WordPress blog. After a html file is generated your webserver will serve that file instead of processing the comparatively heavier and more expensive WordPress PHP scripts. However, because a user's details are displayed in the comment form after they leave a comment, the plugin will only serve static html files to: 1. Users who are not logged in. 2. Users who have not left a comment on your blog. 3. Or users who have not viewed a password protected post. The good news is that probably more than 99% of your visitors don't do any of the above! Those users who don't see the static files will still benefit because they will see regular WP-Cache cached files and your server won't be as busy as before. This plugin should help your server cope with a front page appearance on digg.com or other social networking site. As this plugin is based on the older WP-Cache plugin you can switch off the Super Cache static html caching. Caching will still be performed, but every request will require loading the PHP engine. In normal circumstances this isn't that bad, but if your server is underpowered, or you're experiencing heavy traffic you may run into trouble. Super Cached html files will be server more quickly than PHP generated cached files so there's very little reason not to use the Super Cache feature. See the [WP Super Cache homepage](http://ocaoimh.ie/wp-super-cache/) for further information. The [changelog](http://svn.wp-plugins.org/wp-super-cache/trunk/Changelog.txt) is a good place to start if you want to know what has changed since you last downloaded the plugin. == Installation == 1. You should have the Apache mod mime and mod rewrite modules installed and WordPress fancy permalinks enabled. PHP safe mode should be disabled. If any of those are missing or off you can still use the slower WP-Cache part of the plugin. 2. If you have WP-Cache installed already, please disable it. Edit wp-config.php and make sure the WP_CACHE define is deleted, and remove the files wp-content/wp-cache-config.php and wp-content/advanced-cache.php. These will be recreated when you install this plugin. 3. Upload this directory to your plugins directory. It will create a 'wp-content/plugins/wp-super-cache/' directory. 4. If you are using WordPress MU you will need to install this in 'wp-content/mu-plugins/wp-super-cache/' and the file wp-cache.php must be copied into the mu-plugins directory. 5. WordPress users should go to their Plugins page and activate "WP Super Cache". 6. Now go to Settings->WP Super Cache and enable caching. If you see an error message or a blank screen you may need to fix it. See the "FAQ" section later in this readme for instructions. 7. mod_rewrite rules will be inserted into your .htaccess file. Look in your web root directory for this file. It should look similar to this: `-----------------.htaccess-----------------` `RewriteEngine On` `RewriteBase /` `RewriteCond %{REQUEST_METHOD} !=POST` `RewriteCond %{QUERY_STRING} !.*=.*` `RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$` `RewriteCond %{HTTP:Accept-Encoding} gzip` `RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz -f` `RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz [L]` `RewriteCond %{REQUEST_METHOD} !=POST` `RewriteCond %{QUERY_STRING} !.*=.*` `RewriteCond %{QUERY_STRING} !.*attachment_id=.*` `RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$` `RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html -f` `RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html [L]` `RewriteCond %{REQUEST_FILENAME} !-f` `RewriteCond %{REQUEST_FILENAME} !-d` `RewriteRule . /index.php [L]` `-----------------.htaccess-----------------` 8. After you have enabled the plugin, look for the file "wp-content/cache/.htaccess". If it's not there you must create it. It should read: `# BEGIN supercache` `` ` AddEncoding gzip .gz` ` AddType text/html .gz` `` `` ` SetEnvIfNoCase Request_URI \.gz$ no-gzip` `` `` ` Header set Cache-Control 'max-age=300, must-revalidate'` `` `` ` ExpiresActive On` ` ExpiresByType text/html A300` `` `` `# END supercache` 9. Apache must be configured to allow the modules above. If you receive a "500 internal error" when serving requests to anonymous users you need to dig into your Apache configuration. This configuration in my virtual host works for me: `` `AllowOverride All` `` == Frequently Asked Questions == = How do I know my blog is being cached? = View the source of any page on your site. When a page is first created, you'll see the text "Dynamic Page Served (once) in X.XXXXX seconds" and "Cached page generated by WP-Super-Cache on YYYY-MM-DD HH:MM:SS" at the end of the source code. On reload, a cached page will show the same timestamp so wait a few seconds before checking. If you have compression enabled, the text "Compression = gzip" will be added. If compression is disabled and the page is served as a static html file, the text "super cache" will be added. The only other way to check if your cached file was served by PHP script or from the static cache is by looking at the HTTP headers. WP-Cache (PHP) cached pages will have the header "WP-Super-Cache: WP-Cache". I used the Live HTTP Headers extension for Firefox to examine the headers. You should also check your cache directory in wp-content/cache/supercache/hostname/ for static cache files. = Why is WP-Super-Cache better than WP-Cache? = This plugin is based on the excellent WP-Cache plugin and therefore brings all the benefits of that plugin to WordPress. On top of that it creates copies of every page that is accessed on a blog in a form that is quickly served by the web server. It's almost as quick as if the you had saved a page in your browser and uploaded it to replace your homepage. = Will comments and other dynamic parts of my blog update immediately? = Comments will show as soon as they are moderated, depending on the comment policy of the blog owner. Other dynamic elements on a page may not update unless they are written in Javascript, Flash, Java or another client side browser language. The plugin really produces static html pages. No PHP is executed when those pages are served. "Popularity Contest" is one such plugin that will not work. Plugins that show different content for mobile users will probaby not work either. = Will the Super Cache compression slow down my server? = No, it will do the opposite in fact. Super Cache files are compressed and stored that way so the heavy compression is done only once. These files are generally much smaller and are sent to a visitor's browser much more quickly than uncompressed html. As a result, your server spends less time talking over the network which saves CPU time and bandwidth, and can also serve the next request much more quickly. = Why doesn't WP UserOnline, Popularity Contest, WP Postratings or plugin X not work or update on my blog now? = This plugin caches entire pages and some plugins expect they can run PHP code every time a page loads. To fix this, the plugin needs to use Javascript or AJAX methods to update. If the plugin displays information on the page, that must be a Javascript request too. = Why doesn't the plugin cache requests by search engine bots by default? = Those bots usually only visit each page once and if the page is not popular there's no point creating a cache file that will sit idle on your server. = Why can't I create a cache file of every page on my site? = Like the previous question, there's no point caching pages that won't be visited. The large number of cache files will slow down the garbage collection system as it attempts to check each file. It also causes problems for hosting companies. In the event of a disk failure on your server it may take much longer to check the files. Remember how long a scandisk or a fsck took on a large drive? = How do I uninstall WP Super Cache? = 1. Clear the cache in the backend page and then deactivate it on the plugins page. 2. Remove the Super Cache mod_rewrite rules from your .htaccess file. 3. Remove the WP_CACHE define from wp-config.php 4. Remove the files wp-content/advanced-cache.php and wp-content/wp-cache-config.php 5. Remove the directory wp-content/cache/ 6. Remove the directory wp-super-cache from your plugins directory. = Troubleshooting = If things don't work when you installed the plugin here are a few things to check: 1. Is wp-content writable by the web server? 2. Is there a wp-content/wp-cache-config.php ? If not, copy the file wp-super-cache/wp-cache-config-sample.php to wp-content/wp-cache-config.php and make sure WPCACHEHOME points at the right place. "plugins" should be "mu-plugins" if you're using WordPress MU. 3. Is there a wp-content/advanced-cache.php ? If not, then you must copy wp-super-cache/advanced-cache.php into wp-content/. You should edit the file and change the path so it points at the wp-super-cache folder. 4. If pages are not cached at all, remove wp-content/advanced-cache.php and recreate it, following the advice above. 5. Make sure the following line is in wp-config.php and it is ABOVE the "require_once(ABSPATH.'wp-settings.php');" line: `define( 'WP_CACHE', true );` 6. Try the Settings->WP Super Cache page again and enable cache. 7. Look in wp-content/cache/supercache/. Are there directories and files there? 8. Anything in your php error_log? 9. If your browser keeps asking you to save the file after the super cache is installed you must disable Super Cache compression. Go to the Settings->WP Super Cache page and disable it there. 10. The plugin does not work very well when PHP's safe mode is active. This must be disabled by your administrator. 11. If pages are randomly super cached and sometimes not, your blog can probably be viewed with and without the "www" prefix on the URL. You should choose one way and install the [Enforce www preference](http://txfx.net/code/wordpress/enforce-www-preference/) plugin if you are using an old WordPress install. The latest versions redirect themselves (you should always be running the latest version of WordPress anyway!) 12. Private Server users at Dreamhost should edit wp-content/wp-cache-config.php and set the cache dir to "/tmp/" if they are getting errors about increasing CPU usage. See this [discussion](http://wordpress.org/support/topic/145895?replies=42) for more. 13. File locking errors such as "failed to acquire key 0x152b: Permission denied in..." or "Page not cached by WP Super Cache. Could not get mutex lock." are a sign that you may have to use file locking. Edit wp-content/wp-cache-config.php and uncomment "$use_flock = true" or set $sem_id to a different value. You can also disable file locking from the Admin screen as a last resort. 14. Make sure cache/wp_cache_mutex.lock is writeable by the web server. 15. The cache folder cannot be put on an NFS or Samba or NAS share. It has to be on a local disk. File locking and deleting expired files will not work properly unless the cache folder is on the local machine. 16. Garbage collection of old cache files won't work if WordPress can't find wp-cron.php. If your hostname resolves to 127.0.0.1 it could be preventing the garbage collection from working. Check your access_logs for wp-cron.php entries. Do they return a 404 (file not found) or 200 code? If it's 404 or you don't see wp-cron.php anywhere WordPress may be looking for that script in the wrong place. You should speak to your server administator to correct this or edit /etc/hosts on Unix servers and remove the following line. Your hostname must resolve to the external IP address other servers on the network/Internet use. See http://yoast.com/wp-cron-issues/ for more. `127.0.0.1 myhostname.com` A line like "127.0.0.1 localhost localhost.localdomain" is ok. 17. If old pages are being served to your visitors via the supercache, you may be missing Apache modules (or their equivalents if you don't use Apache). 3 modules are required: mod_mime, mod_headers and mod_expires. The last two are especially important for making sure browsers load new versions of existing pages on your site. == Custom Caching == It is now possible to hook into the caching process using the add_cacheaction() function. Three hooks are available: 1. 'wp_cache_get_cookies_values' - modify the key used by WP Cache. 2. 'add_cacheaction' - runs in phase2. Allows a plugin to add WordPress hooks. 3. 'cache_admin_page' - runs in the admin page. Use it to modify that page, perhaps by adding new configuration options. There is one regular WordPress filter too. Use the "do_createsupercache" filter to customize the checks made before caching. The filter accepts one parameter. The output of WP-Cache's wp_cache_get_cookies_values() function. See plugins/searchengine.php as an example I use for my [No Adverts for Friends](plugin at http://ocaoimh.ie/no-adverts-for-friends/) == Links == [WP Widget Cache](http://wordpress.org/extend/plugins/wp-widget-cache/) is another caching plugin for WordPress. This plugin caches the output of widgets and may significantly speed up dynamic page generation times. == Updates == Updates to the plugin will be posted here, to [Holy Shmoly!](http://ocaoimh.ie/) and the [WP Super Cache homepage](http://ocaoimh.ie/wp-super-cache/) will always link to the newest version. == Thanks == I would sincerely like to thank [John Pozadzides](http://onemansblog.com/) for giving me the idea for this, for writing the "How it works" section and for testing the plugin through 2 front page appearances on digg.com Thanks to James Farmer and Andrew Billits of [Edu Blogs](http://edublogs.org/) fame who helped me make this more WordPress MU friendly. wp-super-cache/wp-cache-base.php0000644000076500007650000000043611151602174016310 0ustar jhardijhardi wp-super-cache/wp-cache-config-sample.php0000644000076500007650000000576511151602174020134 0ustar jhardijhardi\'\"\r\n\t\(\)]/', '', str_replace( '..', '', $_SERVER['REQUEST_URI'] ) ); if( strpos( $request_uri, '/', 1 ) ) { if( $base == '/' ) { $blogcacheid = substr( $request_uri, 1, strpos( $request_uri, '/', 1 ) - 1 ); } else { $blogcacheid = str_replace( $base, '', $request_uri ); $blogcacheid = substr( $blogcacheid, 0, strpos( $blogcacheid, '/', 1 ) ); } if ( '/' == substr($blogcacheid, -1)) $blogcacheid = substr($blogcacheid, 0, -1); } $blogcacheid = str_replace( '/', '', $blogcacheid ); } } // Array of files that have 'wp-' but should still be cached $cache_acceptable_files = array( 'wp-comments-popup.php', 'wp-links-opml.php', 'wp-locations.php' ); $cache_rejected_uri = array('wp-.*.php', 'index.php'); $cache_rejected_user_agent = array ( 0 => 'bot', 1 => 'ia_archive', 2 => 'slurp', 3 => 'crawl', 4 => 'spider'); // Change this to 1 to enable experimental code that tries to serve slightly // out of date content to anon users while a new supercache file is being // generated. $cache_rebuild_files = 0; // DEBUG mode. Change this to your email address to be sent debug emails. // Remove comment (//) to enable and add back to disable. //$wp_cache_debug = "you@example.com"; // Disable the file locking system. // If you are experiencing problems with clearing or creating cache files // uncommenting this may help. //$wp_cache_mutex_disabled = 1; // Just modify it if you have conflicts with semaphores $sem_id = 5419; if ( '/' != substr($cache_path, -1)) { $cache_path .= '/'; } $wp_cache_mobile = 0; $wp_cache_mobile_whitelist = 'Stand Alone/QNws'; $wp_cache_mobile_browsers = '2.0 MMP, 240x320, AvantGo, BlackBerry, Blazer, Cellphone, Danger, DoCoMo, Elaine/3.0, EudoraWeb, hiptop, IEMobile, iPhone, iPod, KYOCERA/WX310K, LG/U990, MIDP-2.0, MMEF20, MOT-V, NetFront, Newt, Nintendo Wii, Nitro, Nokia, Opera Mini, Palm, Playstation Portable, portalmmm, Proxinet, ProxiNet, SHARP-TQ-GX10, Small, SonyEricsson, Symbian OS, SymbianOS, TS21i-10, UP.Browser, UP.Link, Windows CE, WinWAP'; // gzip the first page generated for clients that support it. $wp_cache_gzip_first = 0; // change to relocate the supercache plugins directory $wp_cache_plugins_dir = WPCACHEHOME . 'plugins'; // set to 1 to do garbage collection during normal process shutdown instead of wp-cron $wp_cache_shutdown_gc = 0; ?> wp-super-cache/wp-cache-phase1.php0000644000076500007650000001324111151602174016555 0ustar jhardijhardi time() ) { $meta = new CacheMeta; if (! ($meta = unserialize(@file_get_contents($meta_pathname))) ) return; $file = do_cacheaction( 'wp_cache_served_cache_file', $cache_file ); // Sometimes the gzip headers are lost. If this is a gzip capable client, send those headers. if( $wp_cache_gzip_encoding && !in_array( 'Content-Encoding: ' . $wp_cache_gzip_encoding, $meta->headers ) ) { array_push($meta->headers, 'Content-Encoding: ' . $wp_cache_gzip_encoding); array_push($meta->headers, 'Vary: Accept-Encoding, Cookie'); array_push($meta->headers, 'Content-Length: ' . filesize( $cache_file ) ); wp_cache_debug( "Had to add gzip headers to the page {$_SERVER[ 'REQUEST_URI' ]}." ); } foreach ($meta->headers as $header) { // godaddy fix, via http://blog.gneu.org/2008/05/wp-supercache-on-godaddy/ and http://www.littleredrails.com/blog/2007/09/08/using-wp-cache-on-godaddy-500-error/ if( strpos( $header, 'Last-Modified:' ) === false ) header($header); } header( 'WP-Super-Cache: WP-Cache' ); if ( !($content_size = @filesize($cache_file)) > 0 || $mtime < @filemtime($cache_file)) return; if ($meta->dynamic) { include($cache_file); } else { echo do_cacheaction( 'wp_cache_file_contents', file_get_contents( $cache_file ) ); } die(); } $file_expired = true; // To signal this file was expired } /*register_shutdown_function( 'wp_cache_do_output' ); function wp_cache_do_output() { global $wp_cache_do_output; if( !$wp_cache_do_output ) { return false; } $buffer = ob_get_contents(); ob_end_clean(); $buffer = wp_cache_get_ob( $buffer ); wp_cache_shutdown_callback(); echo $buffer; }*/ function wp_cache_postload() { global $cache_enabled; if (!$cache_enabled) return; require_once( WPCACHEHOME . 'wp-cache-phase2.php'); wp_cache_phase2(); } function wp_cache_get_cookies_values() { $string = ''; while ($key = key($_COOKIE)) { if (preg_match("/^wp-postpass|^wordpress|^comment_author_/", $key)) { $string .= $_COOKIE[$key] . ","; } next($_COOKIE); } reset($_COOKIE); // If you use this hook, make sure you update your .htaccess rules with the same conditions $string = do_cacheaction( 'wp_cache_get_cookies_values', $string ); return $string; } function add_cacheaction( $action, $func ) { global $wp_supercache_actions; $wp_supercache_actions[ $action ][] = $func; } function do_cacheaction( $action, $value = '' ) { global $wp_supercache_actions; if( is_array( $wp_supercache_actions[ $action ] ) ) { $actions = $wp_supercache_actions[ $action ]; foreach( $actions as $func ) { $value = $func( $value ); } } return $value; } // From http://wordpress.org/extend/plugins/wordpress-mobile-edition/ by Alex King function wp_cache_check_mobile( $cache_key ) { global $wp_cache_mobile_enabled, $wp_cache_mobile_browser, $wp_cache_mobile_browsers; if( !isset( $wp_cache_mobile_enabled ) || false == $wp_cache_mobile_enabled ) return $cache_key; if (!isset($_SERVER["HTTP_USER_AGENT"])) { return $cache_key; } $whitelist = explode( ',', $wp_cache_mobile_whitelist ); foreach ($whitelist as $browser) { if (strstr($_SERVER["HTTP_USER_AGENT"], trim($browser))) { return $cache_key; } } $browsers = explode( ',', $wp_cache_mobile_browsers ); foreach ($browsers as $browser) { if (strstr($_SERVER["HTTP_USER_AGENT"], trim( $browser ))) { return $cache_key . $browser; } } return $cache_key; } function wp_cache_debug( $message ) { global $wp_cache_debug; if( !isset( $wp_cache_debug ) ) return; $message .= "\n\nDisable these emails by commenting out or deleting the line containing\n\$wp_cache_debug in wp-content/wp-cache-config.php on your server.\n"; mail( $wp_cache_debug, '[' . addslashes( $_SERVER[ 'HTTP_HOST' ] ) . "] WP Super Cache Debug", $message ); } ?> wp-super-cache/wp-cache-phase2.php0000644000076500000000000005637711157412474016430 0ustar jhardiwheel 0 && stristr($headers["User-Agent"], $expr)) return true; } return false; } function wp_cache_mutex_init() { global $use_flock, $mutex, $cache_path, $mutex_filename, $sem_id; if(!is_bool($use_flock)) { if(function_exists('sem_get')) $use_flock = false; else $use_flock = true; } $mutex = false; if ($use_flock) $mutex = @fopen($cache_path . $mutex_filename, 'w'); else $mutex = @sem_get($sem_id, 1, 0644 | IPC_CREAT, 1); } function wp_cache_writers_entry() { global $use_flock, $mutex, $cache_path, $mutex_filename, $wp_cache_mutex_disabled; if( isset( $wp_cache_mutex_disabled ) && $wp_cache_mutex_disabled ) return true; if( !$mutex ) return false; if ($use_flock) flock($mutex, LOCK_EX); else sem_acquire($mutex); return true; } function wp_cache_writers_exit() { global $use_flock, $mutex, $cache_path, $mutex_filename, $wp_cache_mutex_disabled; if( isset( $wp_cache_mutex_disabled ) && $wp_cache_mutex_disabled ) return true; if( !$mutex ) return false; if ($use_flock) flock($mutex, LOCK_UN); else sem_release($mutex); } function get_current_url_supercache_dir() { global $cached_direct_pages, $cache_path; $uri = preg_replace('/[ <>\'\"\r\n\t\(\)]/', '', str_replace( '/index.php', '/', str_replace( '..', '', preg_replace("/(\?.*)?$/", '', $_SERVER['REQUEST_URI'] ) ) ) ); $uri = str_replace( '\\', '', $uri ); $dir = strtolower(preg_replace('/:.*$/', '', $_SERVER["HTTP_HOST"])) . $uri; // To avoid XSS attacs $dir = apply_filters( 'supercache_dir', $dir ); $dir = trailingslashit( $cache_path . 'supercache/' . $dir ); if( is_array( $cached_direct_pages ) && in_array( $_SERVER[ 'REQUEST_URI' ], $cached_direct_pages ) ) { $dir = trailingslashit( ABSPATH . $uri ); } $dir = str_replace( '//', '/', $dir ); return $dir; } function wp_cache_ob_callback( $buffer ) { $buffer = wp_cache_get_ob( $buffer ); wp_cache_shutdown_callback(); return $buffer; } function wp_cache_get_ob($buffer) { global $cache_path, $cache_filename, $meta_file, $wp_start_time, $supercachedir; global $new_cache, $wp_cache_meta_object, $file_expired, $blog_id, $cache_compression; global $wp_cache_gzip_encoding, $super_cache_enabled, $cached_direct_pages; global $wp_cache_404, $gzsize, $supercacheonly, $wp_cache_gzip_first, $wp_cache_gmt_offset; $new_cache = true; /* Mode paranoic, check for closing tags * we avoid caching incomplete files */ if( $wp_cache_404 ) { $new_cache = false; $buffer .= "\n\n"; } if (!preg_match('/(<\/html>|<\/rss>|<\/feed>)/i',$buffer) ) { $new_cache = false; if( false === strpos( $_SERVER[ 'REQUEST_URI' ], 'robots.txt' ) ) $buffer .= "\n\n"; } if( !$new_cache ) return $buffer; $duration = wp_cache_microtime_diff($wp_start_time, microtime()); $duration = sprintf("%0.3f", $duration); $buffer .= "\n\n"; if( !wp_cache_writers_entry() ) { $buffer .= "\n\n"; return $buffer; } $mtime = @filemtime($cache_path . $cache_filename); /* Return if: the file didn't exist before but it does exist now (another connection created) OR the file was expired and its mtime is less than 5 seconds */ if( !((!$file_expired && $mtime) || ($mtime && $file_expired && (time() - $mtime) < 5)) ) { $dir = get_current_url_supercache_dir(); $supercachedir = $cache_path . 'supercache/' . preg_replace('/:.*$/', '', $_SERVER["HTTP_HOST"]); if( !empty( $_GET ) || is_feed() || ( $super_cache_enabled == true && is_dir( substr( $supercachedir, 0, -1 ) . '.disabled' ) ) ) $super_cache_enabled = false; $tmp_wpcache_filename = $cache_path . uniqid( mt_rand(), true ) . '.tmp'; // Don't create wp-cache files for anon users $supercacheonly = false; if( $super_cache_enabled && wp_cache_get_cookies_values() == '' ) $supercacheonly = true; if( !$supercacheonly ) { $fr = @fopen($tmp_wpcache_filename, 'w'); if (!$fr) { $buffer .= "\n"; return $buffer; } } if( $super_cache_enabled ) { $user_info = wp_cache_get_cookies_values(); $do_cache = apply_filters( 'do_createsupercache', $user_info ); if( $user_info == '' || $do_cache === true ) { if( @is_dir( $dir ) == false ) @wp_mkdir_p( $dir ); $cache_fname = "{$dir}index.html"; $tmp_cache_filename = $dir . uniqid( mt_rand(), true ) . '.tmp'; $fr2 = @fopen( $tmp_cache_filename, 'w' ); if (!$fr2) { $buffer .= "\n"; @fclose( $fr ); @nlink( $tmp_wpcache_filename ); return $buffer; } if( $cache_compression ) { $gz = @fopen( $tmp_cache_filename . ".gz", 'w'); if (!$gz) { $buffer .= "\n"; @close( $fr ); @nlink( $tmp_wpcache_filename ); @close( $fr2 ); @nlink( $tmp_cache_filename ); return $buffer; } } } } if (preg_match('/(.*?)|is', "\n\n", $buffer); $store = preg_replace('|(.*?)|is', "\n\n", $store); $store = apply_filters( 'wpsupercache_buffer', $store ); $wp_cache_meta_object->dynamic = true; /* Clean function calls in tag */ $buffer = preg_replace('||is', '', $buffer); $buffer = preg_replace('||is', '', $buffer); if( $fr ) fputs($fr, $store); // WP Super Cache static files are minified if option is enabled WPSCMin::getInstance()->minify($store); if( $fr2 ) fputs($fr2, $store . '' ); if( $gz ) fputs($gz, gzencode( $store . '', 1, FORCE_GZIP ) ); } else { $buffer = apply_filters( 'wpsupercache_buffer', $buffer ); // WP Super Cache static files AND wp-cache data are minified if option is enabled WPSCMin::getInstance()->minify($buffer); $log = "\n"; if( $gz || $wp_cache_gzip_encoding ) { $gzdata = gzencode( $buffer . $log . "", 3, FORCE_GZIP ); $gzsize = strlen($gzdata); } if ($wp_cache_gzip_encoding) { array_push($wp_cache_meta_object->headers, 'Content-Encoding: ' . $wp_cache_gzip_encoding); array_push($wp_cache_meta_object->headers, 'Vary: Accept-Encoding, Cookie'); array_push($wp_cache_meta_object->headers, 'Content-Length: ' . $gzsize); // Return uncompressed data & store compressed for later use if( $fr ) fputs($fr, $gzdata); } else { // no compression array_push($wp_cache_meta_object->headers, 'Vary: Cookie'); if( $fr ) fputs($fr, $buffer.$log); } if( $fr2 ) fputs($fr2, $buffer . $log . '' ); if( $gz ) fwrite($gz, $gzdata ); $buffer .= $log; } $new_cache = true; if( $fr ) { fclose($fr); if( !@rename( $tmp_wpcache_filename, $cache_path . $cache_filename ) ) { @unlink( $cache_path . $cache_filename ); @rename( $tmp_wpcache_filename, $cache_path . $cache_filename ); } } if( $fr2 ) { fclose($fr2); if( !@rename( $tmp_cache_filename, $cache_fname ) ) { @unlink( $cache_fname ); @rename( $tmp_cache_filename, $cache_fname ); } } if( $gz ) { fclose($gz); if( !@rename( $tmp_cache_filename . '.gz', $cache_fname . '.gz' ) ) { @unlink( $cache_fname . '.gz' ); @rename( $tmp_cache_filename . '.gz', $cache_fname . '.gz' ); } } } wp_cache_writers_exit(); if ( !headers_sent() && isset( $wp_cache_gzip_first ) && 1 == $wp_cache_gzip_first && $wp_cache_gzip_encoding && $gzdata) { header( 'Content-Encoding: ' . $wp_cache_gzip_encoding ); header( 'Vary: Accept-Encoding, Cookie' ); header( 'Content-Length: ' . $gzsize ); return $gzdata; } else { return $buffer; } } function wp_cache_phase2_clean_cache($file_prefix) { global $cache_path; if( !wp_cache_writers_entry() ) return false; if ( ($handle = @opendir( $cache_path )) ) { while ( false !== ($file = @readdir($handle))) { if ( preg_match("/^$file_prefix/", $file) ) @unlink($cache_path . $file); } closedir($handle); } wp_cache_writers_exit(); } function prune_super_cache( $directory, $force = false, $rename = false ) { global $cache_max_time, $cache_path, $super_cache_enabled, $cache_rebuild_files; if( !is_admin() && $super_cache_enabled == 0 ) return false; if( !isset( $cache_max_time ) ) $cache_max_time = 3600; $now = time(); $protected_directories = array( $cache_path . '.htaccess', $cache_path . 'meta', $cache_path . 'supercache' ); $oktodelete = false; if (is_dir($directory)) { if( $dh = @opendir( $directory ) ) { $directory = trailingslashit( $directory ); while( ( $entry = @readdir( $dh ) ) !== false ) { if ($entry == '.' || $entry == '..') continue; $entry = $directory . $entry; prune_super_cache( $entry, $force, $rename ); // If entry is a directory, AND it's not a protected one, AND we're either forcing the delete, OR the file is out of date, if( is_dir( $entry ) && !in_array( $entry, $protected_directories ) && ( $force || @filemtime( $entry ) + $cache_max_time <= $now ) ) { // if the directory isn't empty can't delete it if( $handle = @opendir( $entry ) ) { $donotdelete = false; while( !$donotdelete && ( $file = @readdir( $handle ) ) !== false ) { if ($file == '.' || $file == '..') continue; $donotdelete = true; } closedir($handle); } if( $donotdelete ) continue; if( !$rename ) @rmdir( $entry ); } } closedir($dh); } } elseif( is_file($directory) && ($force || @filemtime( $directory ) + $cache_max_time <= $now ) ) { $oktodelete = true; if( in_array( $directory, $protected_directories ) ) $oktodelete = false; if( $oktodelete && !$rename ) { @unlink( $directory ); } elseif( $oktodelete && $rename ) { if( $cache_rebuild_files && substr( $directory, -14 ) != '.needs-rebuild' ) { if( @rename($directory, $directory . '.needs-rebuild') ) { @touch( $directory . '.needs-rebuild' ); } } else { @unlink( $directory ); } } } } function wp_cache_phase2_clean_expired($file_prefix) { global $cache_path, $cache_max_time; clearstatcache(); if( !wp_cache_writers_entry() ) return false; $now = time(); if ( ($handle = opendir( $cache_path )) ) { while ( false !== ($file = readdir($handle))) { if ( preg_match("/^$file_prefix/", $file) && (@filemtime($cache_path . $file) + $cache_max_time) <= $now ) { @unlink($cache_path . $file); @unlink($cache_path . 'meta/' . str_replace( '.html', '.meta', $file ) ); continue; } if($file != '.' && $file != '..') { if( is_dir( $cache_path . $file ) == false && (@filemtime($cache_path . $file) + $cache_max_time) <= $now ) { if( substr( $file, -9 ) != '.htaccess' ) @unlink($cache_path . $file); } } } closedir($handle); prune_super_cache( $cache_path . 'supercache' ); } wp_cache_writers_exit(); return true; } function wp_cache_shutdown_callback() { global $cache_path, $cache_max_time, $file_expired, $file_prefix, $meta_file, $new_cache, $wp_cache_meta_object, $known_headers, $blog_id, $wp_cache_gzip_encoding, $gzsize, $cache_filename, $supercacheonly; $supercacheonly = false; $wp_cache_meta_object->uri = $_SERVER["SERVER_NAME"].preg_replace('/[ <>\'\"\r\n\t\(\)]/', '', $_SERVER['REQUEST_URI']); // To avoid XSS attacs $wp_cache_meta_object->blog_id=$blog_id; $wp_cache_meta_object->post = wp_cache_post_id(); $response = wp_cache_get_response_headers(); foreach ($known_headers as $key) { if(isset($response[$key])) { array_push($wp_cache_meta_object->headers, "$key: " . $response[$key]); } } /* Not used because it gives problems with some * PHP installations if (!$response{'Content-Length'}) { // WP does not set content size $content_size = ob_get_length(); @header("Content-Length: $content_size"); array_push($wp_cache_meta_object->headers, "Content-Length: $content_size"); } */ if (!isset( $response['Last-Modified'] )) { $value = gmdate('D, d M Y H:i:s') . ' GMT'; /* Dont send this the first time */ /* @header('Last-Modified: ' . $value); */ array_push($wp_cache_meta_object->headers, "Last-Modified: $value"); } if (!$response['Content-Type'] && !$response['Content-type']) { // On some systems, headers set by PHP can't be fetched from // the output buffer. This is a last ditch effort to set the // correct Content-Type header for feeds, if we didn't see // it in the response headers already. -- dougal if (is_feed()) { $type = get_query_var('feed'); $type = str_replace('/','',$type); switch ($type) { case 'atom': $value = "application/atom+xml"; break; case 'rdf': $value = "application/rdf+xml"; break; case 'rss': case 'rss2': default: $value = "application/rss+xml"; } } else { // not a feed $value = 'text/html'; } $value .= "; charset=\"" . get_option('blog_charset') . "\""; @header("Content-Type: $value"); array_push($wp_cache_meta_object->headers, "Content-Type: $value"); } if ( ! $supercacheonly && $new_cache ) { if( $wp_cache_gzip_encoding && !in_array( 'Content-Encoding: ' . $wp_cache_gzip_encoding, $wp_cache_meta_object->headers ) ) { array_push($wp_cache_meta_object->headers, 'Content-Encoding: ' . $wp_cache_gzip_encoding); array_push($wp_cache_meta_object->headers, 'Vary: Accept-Encoding, Cookie'); array_push($wp_cache_meta_object->headers, 'Content-Length: ' . filesize( $cache_path . $cache_filename )); } $serial = serialize($wp_cache_meta_object); if( !wp_cache_writers_entry() ) return false; $tmp_meta_filename = $cache_path . 'meta/' . uniqid( mt_rand(), true ) . '.tmp'; $fr = @fopen( $tmp_meta_filename, 'w'); if( !$fr ) @mkdir( $cache_path . 'meta' ); $fr = fopen( $tmp_meta_filename, 'w'); fputs($fr, $serial); fclose($fr); @chmod( $tmp_meta_filename, 0666 & ~umask()); if( !@rename( $tmp_meta_filename, $cache_path . 'meta/' . $meta_file ) ) { unlink( $cache_path . 'meta/' . $meta_file ); rename( $tmp_meta_filename, $cache_path . 'meta/' . $meta_file ); } wp_cache_writers_exit(); } if( !isset( $cache_max_time ) ) $cache_max_time = 600; $last_gc = get_option( "wpsupercache_gc_time" ); if( !$last_gc ) { update_option( 'wpsupercache_gc_time', time() ); return; } $next_gc = $cache_max_time < 1800 ? $cache_max_time : 600; if( $last_gc > ( time() - $next_gc ) ) return; update_option( 'wpsupercache_gc_time', time() ); global $wp_cache_shutdown_gc; if( isset( $wp_cache_shutdown_gc ) && $wp_cache_shutdown_gc == 1 ) { do_action( 'wp_cache_gc' ); } else { // we delete expired files, using a wordpress cron event // since flush() does not guarantee hand-off to client - problem on Win32 and suPHP if(!wp_next_scheduled('wp_cache_gc')) wp_schedule_single_event(time() + 10 , 'wp_cache_gc'); } } function wp_cache_no_postid($id) { return wp_cache_post_change(wp_cache_post_id()); } function wp_cache_get_postid_from_comment($comment_id) { global $super_cache_enabled; $comment = get_comment($comment_id, ARRAY_A); $postid = $comment['comment_post_ID']; // Do nothing if comment is not moderated // http://ocaoimh.ie/2006/12/05/caching-wordpress-with-wp-cache-in-a-spam-filled-world if( !preg_match('/wp-admin\//', $_SERVER['REQUEST_URI']) ) if( $comment['comment_approved'] == 'spam' ) { // changed from 1 to "spam" return $postid; } elseif( $comment['comment_approved'] == '0' ) { $super_cache_enabled = 0; // don't remove the super cache static file until comment is approved } // We must check it up again due to WP bugs calling two different actions // for delete, for example both wp_set_comment_status and delete_comment // are called when deleting a comment if ($postid > 0) return wp_cache_post_change($postid); else return wp_cache_post_change(wp_cache_post_id()); } function wp_cache_post_edit($post_id) { global $wp_cache_clear_on_post_edit, $cache_path; if( $wp_cache_clear_on_post_edit ) { prune_super_cache( $cache_path, true ); } else { wp_cache_post_change( $post_id ); } } function wp_cache_post_change($post_id) { global $file_prefix, $cache_path, $blog_id, $blogcacheid, $super_cache_enabled; static $last_processed = -1; if ($post_id == $last_processed) return $post_id; $last_processed = $post_id; if( !wp_cache_writers_entry() ) return $post_id; $permalink = trailingslashit( str_replace( get_option( 'siteurl' ), '', post_permalink( $post_id ) ) ); if( $super_cache_enabled ) { $siteurl = trailingslashit( strtolower( preg_replace( '/:.*$/', '', str_replace( 'http://', '', get_option( 'home' ) ) ) ) ); // make sure the front page has a rebuild file prune_super_cache( $cache_path . 'supercache/' . $siteurl . 'index.html', true, true ); prune_super_cache( $cache_path . 'supercache/' . $siteurl . 'index.html.gz', true, true ); if( $post_id != 0 ) { $permalink = trailingslashit( str_replace( get_option( 'home' ), '', post_permalink( $post_id ) ) ); $dir = $cache_path . 'supercache/' . $siteurl; prune_super_cache( $dir . $permalink, true, true ); @rmdir( $dir . $permalink ); prune_super_cache( $dir . 'page/', true ); } } $meta = new CacheMeta; $matches = array(); if ( ($handle = opendir( $cache_path . 'meta/' )) ) { while ( false !== ($file = readdir($handle))) { if ( preg_match("/^({$file_prefix}{$blogcacheid}.*)\.meta/", $file, $matches) ) { $meta_pathname = $cache_path . 'meta/' . $file; $content_pathname = $cache_path . $matches[1] . ".html"; $meta = unserialize(@file_get_contents($meta_pathname)); if ($post_id > 0 && $meta) { if ($meta->blog_id == $blog_id && (!$meta->post || $meta->post == $post_id) ) { @unlink($meta_pathname); @unlink($content_pathname); } } elseif ($meta->blog_id == $blog_id) { @unlink($meta_pathname); @unlink($content_pathname); } } } closedir($handle); } wp_cache_writers_exit(); return $post_id; } function wp_cache_microtime_diff($a, $b) { list($a_dec, $a_sec) = explode(' ', $a); list($b_dec, $b_sec) = explode(' ', $b); return $b_sec - $a_sec + $b_dec - $a_dec; } function wp_cache_post_id() { global $posts, $comment_post_ID, $post_ID; // We try hard all options. More frequent first. if ($post_ID > 0 ) return $post_ID; if ($comment_post_ID > 0 ) return $comment_post_ID; if (is_single() || is_page()) return $posts[0]->ID; if (isset( $_GET[ 'p' ] ) && $_GET['p'] > 0) return $_GET['p']; if (isset( $_POST[ 'p' ] ) && $_POST['p'] > 0) return $_POST['p']; return 0; } function wp_cache_gc_cron() { global $file_prefix, $cache_max_time; if( !isset( $cache_max_time ) ) $cache_max_time = 600; $start = time(); if( !wp_cache_phase2_clean_expired($file_prefix ) ) { wp_cache_debug( 'Cache Expiry cron job failed. Probably mutex locked.' ); update_option( 'wpsupercache_gc_time', time() - ( $cache_max_time - 10 ) ); // if GC failed then run it again in one minute } if( time() - $start > 30 ) wp_cache_debug( "Cache Expiry cron job took more than 30 seconds to execute.\nYou should reduce the Expiry Time in the WP Super Cache admin page\nas you probably have more cache files than your server can handle efficiently." ); } ?> wp-super-cache/wp-cache.php0000644000076500000000000020100511157412474015224 0ustar jhardiwheel '; echo "

    WP Super Cache Manager

    \n"; if( ini_get( 'safe_mode' ) ) { ?>

    Warning! PHP Safe Mode Enabled!

    You may experience problems running this plugin because SAFE MODE is enabled. Your server is set up to check the owner of PHP scripts before allowing them to read and write files.

    You or an administrator may be able to make it work by changing the group owner of the plugin scripts to match that of the web server user. The group owner of the /cache/ directory must also be changed. See the safe mode manual page for further details.

    You or an administrator must disable this. See the safe mode manual page for further details. This cannot be disabled in a .htaccess file unfortunately. It must be done in the php.ini config file.

    Configuration file changed, some values might be wrong. Load the page again from the "Settings" menu to reset them.'; } if ( !wp_cache_check_link() || !wp_cache_verify_config_file() || !wp_cache_verify_cache_dir() ) { echo "Cannot continue... fix previous problems and retry."; echo "\n"; return; } if (!wp_cache_check_global_config()) { echo "\n"; return; } if( $wp_cache_debug || !$wp_cache_cron_check ) { if( function_exists( "wp_remote_get" ) == false ) { $hostname = str_replace( 'http://', '', str_replace( 'https://', '', get_option( 'siteurl' ) ) ); if( strpos( $hostname, '/' ) ) $hostname = substr( $hostname, 0, strpos( $hostname, '/' ) ); $ip = gethostbyname( $hostname ); if( substr( $ip, 0, 3 ) == '127' || substr( $ip, 0, 7 ) == '192.168' ) { ?>

    Warning! Your hostname "" resolves to

    Your server thinks your hostname resolves to . Some services such as garbage collection by this plugin, and WordPress scheduled posts may not operate correctly.

    Please see entry 16 in the Troubleshooting section of the readme.txt

    0.01, 'blocking' => true)); if( is_array( $cron ) ) { if( $cron[ 'response' ][ 'code' ] == '404' ) { ?>

    Warning! wp-cron.php not found!

    Unfortunately WordPress cannot find the file wp-cron.php. This script is required for the the correct operation of garbage collection by this plugin, WordPress scheduled posts as well as other critical activities.

    Please see entry 16 in the Troubleshooting section of the readme.txt

    Mod rewrite may not be installed!

    It appears that mod_rewrite is not installed. Sometimes this check isn't 100% reliable, especially if you are not using Apache. Please verify that the mod_rewrite module is loaded. It is required for serving Super Cache static files. You will still be able to use WP-Cache.

    Read Only Mode. Configuration cannot be changed. Why

    Warning! is writeable!

    You should change the permissions on and make it more restrictive. Use your ftp client, or the following command to fix things:chmod 755 /

    updateOption($_POST[WPSCMin::$config_varname], $wp_cache_config_file); } ?>

    WP Super Cache Status

    '; ?>


    Note: If uninstalling this plugin, make sure the directory is writeable by the webserver so the files advanced-cache.php and cache-config.php can be deleted automatically. (Making sure those files are writeable too is probably a good idea!)

    "; wp_nonce_field('wp-cache'); ?> 'Required to serve compressed supercache files properly.', 'mod_headers' => 'Required to set caching information on supercache pages. IE7 users will see old pages without this module.', 'mod_expires' => 'Set the expiry date on supercached pages. Visitors may not see new pages when they refresh or leave comments without this module.' ); foreach( $required_modules as $req => $desc ) { if( !in_array( $req, $mods ) ) { $missing_mods[ $req ] = $desc; } } if( is_array( $missing_mods ) ) { echo "

    Missing Apache Modules

    "; echo "

    The following Apache modules are missing. The plugin will work without them but your visitors may see corrupted pages or out of date content.

    "; echo "
      "; foreach( $missing_mods as $req => $desc ) { echo "
    • $req - $desc
    • "; } echo "
    "; } } ?>

    Makes WordPress Faster

    WP Super Cache makes your blog go faster. Think that's worth $5? Click the "Donate" button below.

    Thanks!
    Donncha O Caoimh.


    Don't show me this again.

    " method="post">

    WP Super Cache is maintained and developed by Donncha O Caoimh with contributions from many others thanks to the GPL.

    He blogs at Holy Shmoly and posts photos at In Photos.org. You can say hi to him on Twitter too!

    Accepted Filenames & Rejected URIs

    '; wp_cache_edit_rejected(); echo "\n"; wp_cache_edit_accepted(); echo '
    '; wp_cache_edit_rejected_ua(); wp_lock_down(); wp_cache_restore(); ob_start(); if( defined( 'WP_CACHE' ) ) { if( function_exists( 'do_cacheaction' ) ) { do_cacheaction( 'cache_admin_page' ); } } $out = ob_get_contents(); ob_end_clean(); if( SUBMITDISABLED == ' ' && $out != '' ) { echo '

    Cache Plugins

    '; echo $out; echo '
    '; } echo "\n"; } function wsc_mod_rewrite() { global $super_cache_enabled, $cache_compression, $cache_compression_changed, $valid_nonce, $cache_path; if( $super_cache_enabled == false ) return; ?>

    Super Cache Compression

    " method="post">

    Compression is disabled by default because some hosts have problems with compressed files. Switching this on and off clears the cache.

    Super Cache compression is now disabled.

    Super Cache compression is now enabled.

    '; wp_nonce_field('wp-cache'); echo "
    \n"; ?>
    printOptionsForm($_SERVER['REQUEST_URI']); ?>

    Mod Rewrite Rules

    \n"; $rules .= "RewriteEngine On\n"; $rules .= "RewriteBase $home_root\n"; // props Chris Messina $charset = get_option('blog_charset') == '' ? 'UTF-8' : get_option('blog_charset'); $rules .= "AddDefaultCharset {$charset}\n"; $rules .= "CONDITION_RULES"; $rules .= "RewriteCond %{HTTP:Accept-Encoding} gzip\n"; $rules .= "RewriteCond %{DOCUMENT_ROOT}{$inst_root}cache/supercache/%{HTTP_HOST}{$home_root}$1/index.html.gz -f\n"; $rules .= "RewriteRule ^(.*) {$inst_root}cache/supercache/%{HTTP_HOST}{$home_root}$1/index.html.gz [L]\n\n"; $rules .= "CONDITION_RULES"; $rules .= "RewriteCond %{DOCUMENT_ROOT}{$inst_root}cache/supercache/%{HTTP_HOST}{$home_root}$1/index.html -f\n"; $rules .= "RewriteRule ^(.*) {$inst_root}cache/supercache/%{HTTP_HOST}{$home_root}$1/index.html [L]\n"; $rules .= "\n"; $rules = apply_filters( 'supercacherewriterules', $rules ); $rules = str_replace( "CONDITION_RULES", implode( "\n", $condition_rules ) . "\n", $rules ); $dohtaccess = true; if( function_exists( 'is_site_admin' ) ) { echo "

    WordPress MU Detected

    Unfortunately the rewrite rules cannot be updated automatically when running WordPress MU. Please open your .htaccess and add the following mod_rewrite rules above any other rules in that file.

    "; } elseif( !$wprules || $wprules == '' ) { echo "

    Mod Rewrite rules cannot be updated!

    "; echo "

    You must have BEGIN and END markers in {$home_path}.htaccess for the auto update to work. They look like this and surround the main WordPress mod_rewrite rules:

    # BEGIN WordPress RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] # END WordPress
    Refresh this page when you have updated your .htaccess file."; echo "
    "; return; } elseif( strpos( $wprules, 'wordpressuser' ) ) { // Need to clear out old mod_rewrite rules echo "

    Thank you for upgrading. The mod_rewrite rules changed since you last installed this plugin. Unfortunately you must remove the old supercache rules before the new ones are updated. Refresh this page when you have edited your .htaccess file. If you wish to manually upgrade, change the following line:

    RewriteCond %{HTTP_COOKIE} !^.*wordpressuser.*\$
    so it looks like this:
    RewriteCond %{HTTP:Cookie} !^.*wordpress.*\$
    The only changes are 'HTTP_COOKIE' becomes 'HTTP:Cookie' and 'wordpressuser' becomes 'wordpress'. This is a WordPress 2.5 change but it's backwards compatible with older versions if you're brave enough to use them.

    "; echo ""; return; } elseif( $scrules != '' && strpos( $scrules, '%{REQUEST_URI} !^.*[^/]$' ) === false && substr( get_option( 'permalink_structure' ), -1 ) == '/' ) { // permalink structure has a trailing slash, need slash check in rules. echo "

    Trailing slash check required.

    It looks like your blog has URLs that end with a '/'. Unfortunately since you installed this plugin a duplicate content bug has been found where URLs not ending in a '/' end serve the same content as those with the '/' and do not redirect to the proper URL."; echo "To fix, you must edit your .htaccess file and add these two rules to the two groups of Super Cache rules:

    "; echo "
    RewriteCond %{REQUEST_URI} !^.*[^/]$RewriteCond %{REQUEST_URI} !^.*//.*$
    "; echo "

    You can see where the rules go and examine the complete rules by clicking the 'View mod_rewrite rules' link below.

    "; $dohtaccess = false; } elseif( strpos( $scrules, 'supercache' ) || strpos( $wprules, 'supercache' ) ) { // only write the rules once $dohtaccess = false; } // cache/.htaccess rules $gziprules = "\n AddEncoding gzip .gz\n AddType text/html .gz\n\n"; $gziprules .= "\n SetEnvIfNoCase Request_URI \.gz$ no-gzip\n\n"; $gziprules .= "\n Header set Cache-Control 'max-age=300, must-revalidate'\n\n"; $gziprules .= "\n ExpiresActive On\n ExpiresByType text/html A300\n\n"; if( $dohtaccess && !$_POST[ 'updatehtaccess' ] ) { if( !is_writeable_ACLSafe( $home_path . ".htaccess" ) ) { echo "

    Cannot update .htaccess

    The file {$home_path}.htaccess cannot be modified by the web server. Please correct this using the chmod command or your ftp client.

    Refresh this page when the file permissions have been modified.

    Alternatively, you can edit your {$home_path}.htaccess file manually and add the following code (before any WordPress rules):

    "; echo "

    # BEGIN WPSuperCache\n" . wp_specialchars( $rules ) . "# END WPSuperCache

    "; } else { echo "

    To serve static html files your server must have the correct mod_rewrite rules added to a file called {$home_path}.htaccess "; if( !function_exists( 'is_site_admin' ) ) { echo "You must edit the file yourself add the following rules."; } else { echo "You can edit the file yourself add the following rules."; } echo " Make sure they appear before any existing WordPress rules.

    "; echo "
    # BEGIN WPSuperCache\n" . wp_specialchars( $rules ) . "# END WPSuperCache

    "; echo "

    Rules must be added to " . WP_CONTENT_DIR . "/cache/.htaccess too:

    "; echo "
    # BEGIN supercache\n" . wp_specialchars( $gziprules ) . "# END supercache

    "; if( !function_exists( 'is_site_admin' ) ) { echo '
    '; echo ''; echo '
    '; wp_nonce_field('wp-cache'); echo "
    \n"; } } } elseif( $dohtaccess && $valid_nonce && $_POST[ 'updatehtaccess' ] ) { wpsc_remove_marker( $home_path.'.htaccess', 'WordPress' ); // remove original WP rules so SuperCache rules go on top echo "
    "; if( insert_with_markers( $home_path.'.htaccess', 'WPSuperCache', explode( "\n", $rules ) ) && insert_with_markers( $home_path.'.htaccess', 'WordPress', explode( "\n", $wprules ) ) ) { echo "

    Mod Rewrite rules updated!

    "; echo "

    {$home_path}.htaccess has been updated with the necessary mod_rewrite rules. Please verify they are correct. They should look like this:

    \n"; } else { echo "

    Mod Rewrite rules must be updated!

    "; echo "

    Your {$home_path}.htaccess is not writable by the webserver and must be updated with the necessary mod_rewrite rules. The new rules go above the regular WordPress rules as shown in the code below:

    \n"; } echo "

    " . wp_specialchars( $rules ) . "

    \n
    "; } else { ?>

    WP Super Cache mod rewrite rules were detected in your .htaccess file.
    Click the following link to see the lines added to that file. If you have upgraded the plugin make sure these rules match.

    View Mod_Rewrite Rules

    Gzip encoding rules in {$cache_path}.htaccess created."; } ?>

    Fix Configuration

    '; echo '
    '; echo ''; echo '
    '; wp_nonce_field('wp-cache'); echo "
    \n"; echo ''; } function comment_form_lockdown_message() { ?>

    Lock Down: Disabled' : 'Enabled'; ?>

    Prepare your server for an expected spike in traffic by enabling the lock down. When this is enabled, new comments on a post will not refresh the cached static files.

    Developers: Make your plugin lock down compatible by checking the 'WPLOCKDOWN' constant. The following code will make sure your plugin respects the WPLOCKDOWN setting.

    if( defined( 'WPLOCKDOWN' ) && constant( 'WPLOCKDOWN' ) ) {     echo "Sorry. My blog is locked down. Updates will appear shortly"; }

    WordPress is locked down. Super Cache static files will not be deleted when new comments are made.

    WordPress is not locked down. New comments will refresh Super Cache static files as normal.

    '; echo ""; echo "
    "; wp_nonce_field('wp-cache'); echo "\n"; ?>

    Directly Cached Files

    escape( $page ); if( $page != '' ) { $cached_direct_pages[] = $page; $out .= "'$page', "; } } if( $out == '' ) { $out = "'', "; } } if( $valid_nonce && $_POST[ 'new_direct_page' ] && '' != $_POST[ 'new_direct_page' ] ) { $page = str_replace( get_option( 'siteurl' ), '', $_POST[ 'new_direct_page' ] ); if( substr( $page, 0, 1 ) != '/' ) $page = '/' . $page; $page = $wpdb->escape( $page ); if( in_array( $page, $cached_direct_pages ) == false ) { $cached_direct_pages[] = $page; $out .= "'$page', "; } } if( $out != '' ) { $out = substr( $out, 0, -2 ); $out = '$cached_direct_pages = array( ' . $out . ' );'; wp_cache_replace_line('^ *\$cached_direct_pages', "$out", $wp_cache_config_file); prune_super_cache( $cache_path, true ); } if( !empty( $expiredfiles ) ) { foreach( $expiredfiles as $file ) { if( $file != '' ) { $firstfolder = explode( '/', $file ); $firstfolder = ABSPATH . $firstfolder[1]; $file = ABSPATH . $file; @unlink( trailingslashit( $file ) . 'index.html' ); @unlink( trailingslashit( $file ) . 'index.html.gz' ); RecursiveFolderDelete( trailingslashit( $firstfolder ) ); } } } if( $valid_nonce && $_POST[ 'deletepage' ] ) { $page = preg_replace('/[ <>\'\"\r\n\t\(\)]/', '', str_replace( '..', '', $_POST['deletepage']) ); $pagefile = ABSPATH . $page . 'index.html'; $firstfolder = explode( '/', $page ); $firstfolder = ABSPATH . $firstfolder[1]; $page = ABSPATH . $page; if( is_file( $pagefile ) && is_writeable_ACLSafe( $pagefile ) && is_writeable_ACLSafe( $firstfolder ) ) { @unlink( $pagefile ); @unlink( $pagefile . '.gz' ); RecursiveFolderDelete( $firstfolder ); echo "$pagefile removed!"; prune_super_cache( $cache_path, true ); } } $readonly = ''; if( !is_writeable_ACLSafe( ABSPATH ) ) { $readonly = 'READONLY'; ?>

    Warning! You must make writable to enable this feature. As this is a security risk please make it readonly after your page is generated.

    Warning! is writable. Please make it readonly after your page is generated as this is a security risk.

    '; if( is_array( $cached_direct_pages ) ) { $out = ''; foreach( $cached_direct_pages as $page ) { if( $page == '' ) continue; $generated = ''; if( is_file( ABSPATH . $page . '/index.html' ) ) $generated = ''; $out .= "$generated"; } if( $out != '' ) { ?>"; } } if( $readonly != 'READONLY' ) echo "Add direct page: "; echo "

    Directly cached files are files created directly off " . ABSPATH . " where your blog lives. This feature is only useful if you are expecting a major Digg or Slashdot level of traffic to one post or page.

    "; if( $readonly != 'READONLY' ) { echo "

    For example: to cache '" . trailingslashit( get_option( 'siteurl' ) ) . "about/', you would enter '" . trailingslashit( get_option( 'siteurl' ) ) . "about/' or '/about/'. The cached file will be generated the next time an anonymous user visits that page.

    "; echo "

    Make the textbox blank to remove it from the list of direct pages and delete the cached file.

    "; } wp_nonce_field('wp-cache'); if( $readonly != 'READONLY' ) echo "
    "; echo "\n"; ?> 0) { $cache_max_time = $max_time; wp_cache_replace_line('^ *\$cache_max_time', "\$cache_max_time = $cache_max_time;", $wp_cache_config_file); } } ?>

    Expiry Time & Garbage Collection

    '; echo ' '; echo " seconds"; echo "

    Garbage Collection

    If expiry time is more than 1800 seconds (half an hour), garbage collection will be done every 10 minutes, otherwise it will happen 10 seconds after the expiry time above.

    "; echo "

    Checking for and deleting expired files is expensive, but it's expensive leaving them there too. On a very busy site you should set the expiry time to 300 seconds. Experiment with different values and visit this page to see how many expired files remain at different times during the day. Aim to have less than 500 cached files if possible.

    "; echo '
    '; wp_nonce_field('wp-cache'); echo "\n"; ?>

    Rejected User Agents

    '; echo "

    Strings in the HTTP 'User Agent' header that prevent WP-Cache from caching bot, spiders, and crawlers' requests. Note that cached files are still sent to these request if they already exists.

    \n"; echo '
    '; echo ' '; echo '
    '; wp_nonce_field('wp-cache'); echo ''; echo "
    \n"; } function wp_cache_edit_rejected() { global $cache_acceptable_files, $cache_rejected_uri, $wp_cache_config_file, $valid_nonce; if(isset($_REQUEST['wp_rejected_uri']) && $valid_nonce) { $text = wp_cache_sanitize_value($_REQUEST['wp_rejected_uri'], $cache_rejected_uri); wp_cache_replace_line('^ *\$cache_rejected_uri', "\$cache_rejected_uri = $text;", $wp_cache_config_file); } echo ''; echo "

    Add here strings (not a filename) that forces a page not to be cached. For example, if your URLs include year and you dont want to cache last year posts, it's enough to specify the year, i.e. '/2004/'. WP-Cache will search if that string is part of the URI and if so, it will not cache that page.

    \n"; echo ' '; echo '
    '; wp_nonce_field('wp-cache'); echo "\n"; } function wp_cache_edit_accepted() { global $cache_acceptable_files, $cache_rejected_uri, $wp_cache_config_file, $valid_nonce; if(isset($_REQUEST['wp_accepted_files']) && $valid_nonce) { $text = wp_cache_sanitize_value($_REQUEST['wp_accepted_files'], $cache_acceptable_files); wp_cache_replace_line('^ *\$cache_acceptable_files', "\$cache_acceptable_files = $text;", $wp_cache_config_file); } echo '
    '; echo "

    Add here those filenames that can be cached, even if they match one of the rejected substring specified above.

    \n"; echo ' '; echo '
    '; wp_nonce_field('wp-cache'); echo "\n"; } function wp_cache_enable() { global $wp_cache_config_file, $cache_enabled, $supercachedir; if(get_option('gzipcompression')) { echo "Error: GZIP compression is enabled, disable it if you want to enable wp-cache."; return false; } if( wp_cache_replace_line('^ *\$cache_enabled', '$cache_enabled = true;', $wp_cache_config_file) ) { $cache_enabled = true; } wp_super_cache_enable(); } function wp_cache_disable() { global $wp_cache_config_file, $cache_enabled; if (wp_cache_replace_line('^ *\$cache_enabled', '$cache_enabled = false;', $wp_cache_config_file)) { $cache_enabled = false; } wp_super_cache_disable(); } function wp_super_cache_enable() { global $supercachedir, $wp_cache_config_file, $super_cache_enabled; if( is_dir( $supercachedir . ".disabled" ) ) if( is_dir( $supercachedir ) ) { prune_super_cache( $supercachedir . ".disabled", true ); @unlink( $supercachedir . ".disabled" ); } else { @rename( $supercachedir . ".disabled", $supercachedir ); } wp_cache_replace_line('^ *\$super_cache_enabled', '$super_cache_enabled = true;', $wp_cache_config_file); $super_cache_enabled = true; } function wp_super_cache_disable() { global $cache_path, $supercachedir, $wp_cache_config_file, $super_cache_enabled; wp_cache_replace_line('^ *\$super_cache_enabled', '$super_cache_enabled = false;', $wp_cache_config_file); if( is_dir( $supercachedir ) ) @rename( $supercachedir, $supercachedir . ".disabled" ); $super_cache_enabled = false; sleep( 1 ); // allow existing processes to write to the supercachedir and then delete it if (function_exists ('prune_super_cache') && is_dir( $supercachedir ) ) { prune_super_cache( $cache_path, true ); } } function wp_cache_is_enabled() { global $wp_cache_config_file; if(get_option('gzipcompression')) { echo "Warning: GZIP compression is enabled in Wordpress, wp-cache will be bypassed until you disable gzip compression."; return false; } $lines = file($wp_cache_config_file); foreach($lines as $line) { if (preg_match('/^ *\$cache_enabled *= *true *;/', $line)) return true; } return false; } function wp_cache_replace_line($old, $new, $my_file) { if (!is_writeable_ACLSafe($my_file)) { echo "Error: file $my_file is not writable.\n"; return false; } $found = false; $lines = file($my_file); foreach($lines as $line) { if ( preg_match("/$old/", $line)) { $found = true; break; } } if ($found) { $fd = fopen($my_file, 'w'); foreach($lines as $line) { if ( !preg_match("/$old/", $line)) fputs($fd, $line); else { fputs($fd, "$new //Added by WP-Cache Manager\n"); } } fclose($fd); return true; } $fd = fopen($my_file, 'w'); $done = false; foreach($lines as $line) { if ( $done || !preg_match('/^define|\$|\?>/', $line)) fputs($fd, $line); else { fputs($fd, "$new //Added by WP-Cache Manager\n"); fputs($fd, $line); $done = true; } } fclose($fd); return true; } function wp_cache_verify_cache_dir() { global $cache_path; $dir = dirname($cache_path); if ( !file_exists($cache_path) ) { if ( !is_writeable_ACLSafe( $dir ) || !($dir = mkdir( $cache_path ) ) ) { echo "Error: Your cache directory ($cache_path) did not exist and couldn't be created by the web server. Check $dir permissions."; return false; } } if ( !is_writeable_ACLSafe($cache_path)) { echo "Error: Your cache directory ($cache_path) or $dir need to be writable for this plugin to work. Double-check it."; return false; } if ( '/' != substr($cache_path, -1)) { $cache_path .= '/'; } @mkdir( $cache_path . 'meta' ); return true; } function wp_cache_verify_config_file() { global $wp_cache_config_file, $wp_cache_config_file_sample, $sem_id, $cache_path; $new = false; $dir = dirname($wp_cache_config_file); if ( file_exists($wp_cache_config_file) ) { $lines = join( ' ', file( $wp_cache_config_file ) ); if( strpos( $lines, 'WPCACHEHOME' ) === false ) { if( is_writeable_ACLSafe( $wp_cache_config_file ) ) { @unlink( $wp_cache_config_file ); } else { echo "Error: Your WP-Cache config file ($wp_cache_config_file) is out of date and not writable by the Web server.Please delete it and refresh this page."; return false; } } } elseif( !is_writeable_ACLSafe($dir)) { echo "Error: Configuration file missing and " . WP_CONTENT_DIR . " directory ($dir) is not writable by the Web server.Check its permissions."; return false; } if ( !file_exists($wp_cache_config_file) ) { if ( !file_exists($wp_cache_config_file_sample) ) { echo "Error: Sample WP-Cache config file ($wp_cache_config_file_sample) does not exist.Verify you installation."; return false; } copy($wp_cache_config_file_sample, $wp_cache_config_file); $dir = str_replace( str_replace( '\\', '/', WP_CONTENT_DIR ), '', str_replace( '\\', '/', dirname(__FILE__) ) ); if( is_file( dirname(__FILE__) . '/wp-cache-config-sample.php' ) ) { wp_cache_replace_line('WPCACHEHOME', "define( 'WPCACHEHOME', WP_CONTENT_DIR . \"{$dir}/\" );", $wp_cache_config_file); } elseif( is_file( dirname(__FILE__) . '/wp-super-cache/wp-cache-config-sample.php' ) ) { wp_cache_replace_line('WPCACHEHOME', "define( 'WPCACHEHOME', WP_CONTENT_DIR . \"{$dir}/wp-super-cache/\" );", $wp_cache_config_file); } $new = true; } if( $sem_id == 5419 && $cache_path != '' ) { $sem_id = crc32( $_SERVER[ 'HTTP_HOST' ] . $cache_path ) & 0x7fffffff; wp_cache_replace_line('sem_id', '$sem_id = ' . $sem_id . ';', $wp_cache_config_file); } require($wp_cache_config_file); return true; } function wp_cache_create_advanced_cache() { global $wp_cache_link, $wp_cache_file; $ret = true; $file = file_get_contents( $wp_cache_file ); $file = str_replace( 'CACHEHOME', constant( 'WPCACHEHOME' ), $file ); $fp = @fopen( $wp_cache_link, 'w' ); if( $fp ) { fputs( $fp, $file ); fclose( $fp ); } else { $ret = false; } return $ret; } function wp_cache_check_link() { global $wp_cache_link, $wp_cache_file; $ret = true; if( file_exists($wp_cache_link) ) { $file = file_get_contents( $wp_cache_link ); if( strpos( $file, "WP SUPER CACHE 0.8.9.1" ) ) { return true; } else { if( !@unlink($wp_cache_link) ) { $ret = false; } else { $ret = wp_cache_create_advanced_cache(); } } } else { $ret = wp_cache_create_advanced_cache(); } if( false == $ret ) { echo "

    Warning! " . constant( 'WP_CONTENT_DIR' ) . "/advanced-cache.php does not exist or cannot be updated.

    "; echo "

    • 1. If it already exists please delete the file first.
    • "; echo "
    • 2. Make " . constant( 'WP_CONTENT_DIR' ) . " writable using the chmod command through your ftp or server software. (chmod 777 " . constant( 'WP_CONTENT_DIR' ) . ") and refresh this page. This is only a temporary measure and you'll have to make it read only afterwards again. (Change 777 to 755 in the previous command)
    • "; echo "
    • 3. Refresh this page to update " . constant( 'WP_CONTENT_DIR' ) . "/advanced-cache.php
    "; echo "If that doesn't work, make sure the file " . constant( 'WP_CONTENT_DIR' ) . "/advanced-cache.php doesn't exist:
      "; echo "
    1. 1. Open $wp_cache_file in a text editor.
    2. 2. Change the text CACHEHOME to " . constant( 'WPCACHEHOME' ) . "
    3. 3. Save the file and copy it to $wp_cache_link and refresh this page.
    4. "; return false; } return true; } function wp_cache_check_global_config() { if( defined( 'WP_CACHE' ) ) return true; if ( file_exists( ABSPATH . 'wp-config.php') ) { $global = ABSPATH . 'wp-config.php'; } else { $global = dirname(ABSPATH) . '/wp-config.php'; } $howtoenable = "Edit $global and add the following line: define('WP_CACHE', true);Otherwise, WP-Cache will not be executed by Wordpress core. "; $lines = file($global); foreach($lines as $line) { if (preg_match('/^\s*define\s*\(\s*\'WP_CACHE\'\s*,\s*(?i:TRUE|1)\s*\)\s*;/', $line)) { echo $howtoenable; return false; } } $line = 'define(\'WP_CACHE\', true);'; if (!is_writeable_ACLSafe($global) || !wp_cache_replace_line('define *\( *\'WP_CACHE\'', $line, $global) ) { echo "Error: WP_CACHE is not enabled in your wp-config.php file and I couldn't modify it."; echo $howtoenable; return false; } return true; } function wp_cache_files() { global $cache_path, $file_prefix, $cache_max_time, $valid_nonce, $supercachedir, $cache_enabled, $super_cache_enabled; if ( '/' != substr($cache_path, -1)) { $cache_path .= '/'; } if ( $valid_nonce ) { if(isset($_REQUEST['wp_delete_cache'])) { wp_cache_clean_cache($file_prefix); } if(isset($_REQUEST['wp_delete_cache_file'])) { wp_cache_clean_cache($_REQUEST['wp_delete_cache_file']); } if(isset($_REQUEST['wp_delete_expired'])) { wp_cache_clean_expired($file_prefix); } } if(isset($_REQUEST['wp_list_cache'])) { $list_files = true; $list_mess = "Update list"; } else $list_mess = "List files"; echo '

      Cache Contents

      '; /* echo '
      '; echo ''; echo '
      '; echo "\n"; */ $list_files = false; // it doesn't list supercached files, and removing single pages is buggy $count = 0; $expired = 0; $now = time(); if ( ($handle = @opendir( $cache_path . 'meta/' )) ) { if ($list_files) echo "
    Existing direct pageDelete cached file
    "; while ( false !== ($file = readdir($handle))) { if ( preg_match("/^$file_prefix.*\.meta/", $file) ) { $this_expired = false; $content_file = preg_replace("/meta$/", "html", $file); $mtime = filemtime($cache_path . 'meta/' . $file); if ( ! ($fsize = @filesize($cache_path.$content_file)) ) continue; // .meta does not exists $fsize = intval($fsize/1024); $age = $now - $mtime; if ( $age > $cache_max_time) { $expired++; $this_expired = true; } $count++; if ($list_files) { $meta = new CacheMeta; $meta = unserialize(file_get_contents($cache_path . 'meta/' . $file)); echo $flip ? '' : ''; $flip = !$flip; echo '"; if ($this_expired) echo ""; else echo ""; echo ""; echo '\n"; } } } closedir($handle); if ($list_files) echo "
    '; echo $meta->uri . "$age secs$age secs$fsize KB
    '; echo ''; echo ''; echo '
    '; wp_nonce_field('wp-cache'); echo "
    "; } if( $cache_enabled == true && $super_cache_enabled == true ) { $now = time(); $sizes = array( 'expired' => 0, 'cached' => 0, 'ts' => 0 ); if (is_dir($supercachedir)) { if( $dh = opendir( $supercachedir ) ) { while( ( $entry = readdir( $dh ) ) !== false ) { if ($entry != '.' && $entry != '..') { $sizes = wpsc_dirsize( trailingslashit( $supercachedir ) . $entry, $sizes ); } } closedir($dh); } } else { if(is_file($supercachedir) && filemtime( $supercachedir ) + $cache_max_time <= $now ) $sizes[ 'expired' ] ++; } $sizes[ 'ts' ] = time(); } echo "

    WP-Cache

    "; echo "
    • $count Cached Pages
    • "; echo "
    • $expired Expired Pages
    "; if( $cache_enabled == true && $super_cache_enabled == true ) { echo "

    WP-Super-Cache

    "; echo "
    • " . intval($sizes['cached']/2) . " Cached Pages
    • "; $age = intval(($now - $sizes['ts'])/60); echo "
    • " . intval($sizes['expired']/2) . " Expired Pages
    "; } $last_gc = get_option( "wpsupercache_gc_time" ); if( $last_gc ) { $next_gc = $cache_max_time < 1800 ? $cache_max_time : 600; echo "

    Garbage Collection
    Last: " . date( "Y-m-d H:i:s", ( $last_gc + ( get_option( 'gmt_offset' ) * 3600 ) ) ) . "
    "; echo "Next: " . date( "Y-m-d H:i:s", ( $next_gc + $last_gc + ( get_option( 'gmt_offset' ) * 3600 ) ) ) . "

    "; } echo "

    Expired files are files older than $cache_max_time seconds. They are still used by the plugin and are deleted periodically.

    "; echo '
    '; echo ''; echo '
    '; wp_nonce_field('wp-cache'); echo "
    \n"; echo '
    '; echo ''; echo '
    '; wp_nonce_field('wp-cache'); echo "
    \n"; echo '
    '; } function delete_cache_dashboard() { if( function_exists( 'is_site_admin' ) && !is_site_admin() ) return false; if( function_exists('current_user_can') && !current_user_can('manage_options') ) return false; echo "
  • Delete Cache
  • "; } add_action( 'dashmenu', 'delete_cache_dashboard' ); function wpsc_dirsize($directory, $sizes) { global $cache_max_time; $now = time(); if (is_dir($directory)) { if( $dh = opendir( $directory ) ) { while( ( $entry = readdir( $dh ) ) !== false ) { if ($entry != '.' && $entry != '..') { $sizes = wpsc_dirsize( trailingslashit( $directory ) . $entry, $sizes ); } } closedir($dh); } } else { if(is_file($directory) ) { if( filemtime( $directory ) + $cache_max_time <= $now ) { $sizes[ 'expired' ]+=1; } else { $sizes[ 'cached' ]+=1; } } } return $sizes; } function wp_cache_clean_cache($file_prefix) { global $cache_path, $supercachedir; // If phase2 was compiled, use its function to avoid race-conditions if(function_exists('wp_cache_phase2_clean_cache')) { if (function_exists ('prune_super_cache')) { if( is_dir( $supercachedir ) ) { prune_super_cache( $supercachedir, true ); } elseif( is_dir( $supercachedir . '.disabled' ) ) { prune_super_cache( $supercachedir . '.disabled', true ); } prune_super_cache( $cache_path, true ); $_POST[ 'super_cache_stats' ] = 1; // regenerate super cache stats; } return wp_cache_phase2_clean_cache($file_prefix); } $expr = "/^$file_prefix/"; if ( ($handle = opendir( $cache_path )) ) { while ( false !== ($file = readdir($handle))) { if ( preg_match($expr, $file) ) { @unlink($cache_path . $file); @unlink($cache_path . 'meta/' . str_replace( '.html', '.meta', $file ) ); } } closedir($handle); } } function wp_cache_clean_expired($file_prefix) { global $cache_path, $cache_max_time; // If phase2 was compiled, use its function to avoid race-conditions if(function_exists('wp_cache_phase2_clean_expired')) { if (function_exists ('prune_super_cache')) { $dir = $cache_path . 'supercache/' . preg_replace('/:.*$/', '', $_SERVER["HTTP_HOST"]); if( is_dir( $dir ) ) { prune_super_cache( $dir ); } elseif( is_dir( $dir . '.disabled' ) ) { prune_super_cache( $dir . '.disabled' ); } $_POST[ 'super_cache_stats' ] = 1; // regenerate super cache stats; } return wp_cache_phase2_clean_expired($file_prefix); } $expr = "/^$file_prefix/"; $now = time(); if ( ($handle = opendir( $cache_path )) ) { while ( false !== ($file = readdir($handle))) { if ( preg_match($expr, $file) && (filemtime($cache_path . $file) + $cache_max_time) <= $now) { unlink($cache_path . $file); unlink($cache_path . 'meta/' . str_replace( '.html', '.meta', $file ) ); } } closedir($handle); } } function wpsc_remove_marker( $filename, $marker ) { if (!file_exists( $filename ) || is_writeable_ACLSafe( $filename ) ) { if (!file_exists( $filename ) ) { return ''; } else { $markerdata = explode( "\n", implode( '', file( $filename ) ) ); } $f = fopen( $filename, 'w' ); $foundit = false; if ( $markerdata ) { $state = true; foreach ( $markerdata as $n => $markerline ) { if (strpos($markerline, '# BEGIN ' . $marker) !== false) $state = false; if ( $state ) { if ( $n + 1 < count( $markerdata ) ) fwrite( $f, "{$markerline}\n" ); else fwrite( $f, "{$markerline}" ); } if (strpos($markerline, '# END ' . $marker) !== false) { $state = true; } } } return true; } else { return false; } } function wp_super_cache_footer() { ?>

    is Digg proof thanks to caching by WP Super Cache!

    is_404 function wp_cache_catch_404() { global $wp_cache_404; $wp_cache_404 = false; if( is_404() ) $wp_cache_404 = true; } add_action( 'template_redirect', 'wp_cache_catch_404' ); function wp_cache_favorite_action( $actions ) { if( function_exists( 'is_site_admin' ) && !is_site_admin() ) return $actions; if( function_exists('current_user_can') && !current_user_can('manage_options') ) return $actions; $actions[ wp_nonce_url( 'options-general.php?page=wpsupercache&wp_delete_cache=1', 'wp-cache' ) ] = array( __( 'Delete Cache' ), 'manage_options' ); return $actions; } add_filter( 'favorite_actions', 'wp_cache_favorite_action' ); function wp_cache_plugin_notice( $plugin ) { global $cache_enabled; if( $plugin == 'wp-super-cache/wp-cache.php' ) { if( !$cache_enabled ) echo 'WP Super Cache must be configured. Go to the admin page to enable and configure the plugin.'; } } add_action( 'after_plugin_row', 'wp_cache_plugin_notice' ); function wp_cache_admin_notice() { global $cache_enabled; if( substr( $_SERVER["PHP_SELF"], -11 ) == 'plugins.php' && !$cache_enabled ) add_action('admin_notices', create_function('', 'echo \'

    \' . sprintf( __(\'WP Super Cache is disabled. Please go to the plugin admin page to enable caching.\', \'wpsupercache\') ,\'' . admin_url( 'options-general.php?page=wpsupercache' ) . '\') . \'

    \';') ); } add_action( 'admin_init', 'wp_cache_admin_notice' ); ?> wp-super-cache/WPSCMin-changelog.txt0000644000076500007650000000061111157413037017105 0ustar jhardijhardiWPSCMin changelog 2009-03-15 wp-super-cache.diff: updated to diff with WP Super Cache 0.9.1 WPSCMin.php: Reverted to pre-PHP 5.2.3 callback syntax per this thread: http://groups.google.com/group/minify/browse_thread/thread/3781cbaf19a9f770 2009-02-23 wp-super-cache.diff: updated to diff with WP Super Cache 0.9 WPSCMin.php: WordPress config screen button style now WP 2.7 style wp-super-cache/WPSCMin.php0000644000076500007650000000776511157412605015151 0ustar jhardijhardienabled = TRUE; } public static function getInstance() { if (empty(self::$instance)) self::$instance = new self(); return self::$instance; } // Minifies string referenced by $html, if $this->enabled is TRUE public function minify(& $html) { if (!$this->enabled) return; // Include Minify components unless they have already been required if (!class_exists('Minify_HTML')) { require('min/lib/Minify/HTML.php'); // Add min/lib to include_path for CSS.php to be able to find components ini_set('include_path', ini_get('include_path').':'.dirname(__FILE__).'/min/lib'); require('min/lib/Minify/CSS.php'); require('min/lib/JSMin.php'); } $html = Minify_HTML::minify($html, array('cssMinifier' => array('Minify_CSS', 'minify'), 'jsMinifier' => array('JSMin', 'minify'))); } public function updateOption($value, $config_file) { $enabled = (bool) $value; if ($enabled != $this->enabled) { $this->enabled = $enabled; $this->changed = TRUE; wp_cache_replace_line('^ *\$'.self::$config_varname, "\$".self::$config_varname." = " . var_export($enabled, TRUE) . ";", $config_file); } } public function printOptionsForm($action) { ?>

    HTML Minify

    Enables or disables Minify (stripping of unnecessary comments and whitespace) of cached HTML output. Disable this if you encounter any problems or need to read your source code.

    changed) { echo "

    HTML Minify is now "; if ($this->enabled) echo "enabled"; else echo "disabled"; echo ".

    "; } echo '
    '; wp_nonce_field('wp-cache'); ?>