Plugin Directory

Changeset 3436416


Ignore:
Timestamp:
01/10/2026 07:00:48 AM (3 months ago)
Author:
leopardhost
Message:

v2.1.1: Module Pulse Check

Location:
tnc-toolbox
Files:
19 added
4 edited

Legend:

Unmodified
Added
Removed
  • tnc-toolbox/trunk/core/settings.php

    r3435613 r3436416  
    216216                            </td>
    217217                        </tr>
    218                         <?php $status = TNC_Cache_Purge::get_status(); ?>
     218                        <?php $status = TNC_Cache_Purge::get_status( true ); // Force recheck on settings page ?>
    219219                        <tr>
    220220                            <th scope="row">
  • tnc-toolbox/trunk/readme.txt

    r3435613 r3436416  
    22Author URI: https://tnc.works
    33Plugin URI: https://merlot.digital
    4 Donate link: 
    5 Contributors: 
     4Donate link:
     5Contributors:
    66Tags: NGINX, Cache Purge, Web Performance, Automatic Purge, Freeware
    77Tested up to: 6.9
    8 Stable tag: 2.1.0
     8Stable tag: 2.1.1
    99License: GPLv3
    1010License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    1515== Description ==
    1616
    17 TNC Toolbox aims to enhance your WordPress experience with NGINX-on-cPanel (ea-nginx). 
     17TNC Toolbox aims to enhance your WordPress experience with NGINX-on-cPanel (ea-nginx).
    1818
    1919**Built for our Managed Server clients, we've open-sourced it so others can enjoy it too!**
    2020
    21 With a heavy focus on the Apache + NGINX as Reverse Caching Proxy web stack, the plugin aims to help with Website Management, Performance and Security. 
     21With a heavy focus on the Apache + NGINX as Reverse Caching Proxy web stack, the plugin aims to help with Website Management, Performance and Security.
    2222
    2323> ❤️ **FOSS by [The Network Crew Pty Ltd](https://tnc.works) (TNC) for [Merlot Digital](https://merlot.digital) & the world.** ❤️
     
    3838**Eager for even more capabilities?**
    3939
    40 We plan to add further features as clients & the community request it. 
     40We plan to add further features as clients & the community request it.
    4141
    4242_Please let us know your ideas on [GitHub](https://github.com/The-Network-Crew/TNC-Toolbox-for-WordPress/) - we'd love to hear from you!_
     
    152152
    153153== Changelog ==
     154
     155= 2.1.1: Jan 10, 2026 =
     156* Bug Fix: Fix false positive cache-purge module detection
    154157
    155158= 2.1.0: Jan 8, 2026 =
  • tnc-toolbox/trunk/tnc-toolbox.php

    r3435613 r3436416  
    66 * @author            The Network Crew Pty Ltd (Merlot Digital)
    77 * @license           gplv3
    8  * @version           2.1.0
     8 * @version           2.1.1
    99 *
    1010 * @wordpress-plugin
     
    1212 * Plugin URI:        https://merlot.digital
    1313 * Description:       Designed for ea-NGINX (Cache/Proxy) on cPanel+WHM. Now with selective cache purging support!
    14  * Version:           2.1.0
     14 * Version:           2.1.1
    1515 * Author:            The Network Crew Pty Ltd (Merlot Digital)
    1616 * Author URI:        https://tnc.works
  • tnc-toolbox/trunk/vendor/cache-purge.php

    r3435613 r3436416  
    8383     * set to the actual domain. This is how ea-nginx-cache-purge is configured.
    8484     *
     85     * The module returns specific signatures in the response body:
     86     * - HTTP 200 with body containing "Successful purge" = module working.
     87     * - HTTP 412 can occur when item not in cache, but we need body signature.
     88     *
     89     * Without the module, nginx may return 301/404/405 with generic HTML.
     90     *
    8591     * @return bool True if PURGE is supported.
    8692     */
     
    112118        $body = wp_remote_retrieve_body( $response );
    113119
    114         // ea-nginx-cache-purge returns:
    115         // - 200 OK with "Successful purge" if entry existed.
    116         // - 404 Not Found if entry didn't exist (but PURGE is supported).
    117         // - 412 Precondition Failed if entry wasn't in cache.
    118         // - 405 Method Not Allowed if PURGE is not configured.
    119         if ( 200 === $code || 404 === $code || 412 === $code ) {
    120             // Check for cache-purge signature in body.
    121             if ( stripos( $body, 'purge' ) !== false || stripos( $body, 'cache' ) !== false ) {
    122                 self::log( 'PURGE test successful: module detected' );
    123                 return true;
    124             }
    125             // Even without body, 200/404/412 on PURGE is a good sign.
    126             self::log( 'PURGE test: got ' . $code . ', assuming module available' );
     120        // ea-nginx-cache-purge module returns specific signatures:
     121        // - 200 OK with body "Successful purge" and "Key :" when purged.
     122        // - 412 Precondition Failed when item wasn't in cache.
     123        //
     124        // Without module: 301 redirect, 404 generic HTML, or 405 Method Not Allowed.
     125        //
     126        // We MUST check body for "Successful purge" signature to confirm module.
     127        if ( 200 === $code && stripos( $body, 'Successful purge' ) !== false ) {
     128            self::log( 'PURGE test successful: module detected (200 + signature)' );
    127129            return true;
    128130        }
    129131
    130         self::log( 'PURGE test: got ' . $code . ', module not available' );
     132        // 412 from module still indicates it's working (item just wasn't cached).
     133        // But generic nginx 412 doesn't have our signature, so check for module output.
     134        if ( 412 === $code && stripos( $body, 'Precondition Failed' ) !== false ) {
     135            // This is likely the module - generic nginx rarely returns 412 for PURGE.
     136            self::log( 'PURGE test successful: module detected (412 Precondition Failed)' );
     137            return true;
     138        }
     139
     140        self::log( 'PURGE test: got HTTP ' . $code . ', module not detected' );
    131141        return false;
    132142    }
     
    135145     * Check if selective purging is enabled.
    136146     *
    137      * @return bool True if enabled and available.
     147     * Returns true if the user has enabled selective purging via checkbox.
     148     * Module availability is checked separately during actual purge operations.
     149     *
     150     * @return bool True if enabled by user.
    138151     */
    139152    public static function is_enabled() {
    140         $enabled   = get_option( self::OPTION_ENABLED, 'yes' );
    141         $available = get_option( self::OPTION_AVAILABLE, 'unknown' );
    142 
    143         return 'yes' === $enabled && 'yes' === $available;
     153        return 'yes' === get_option( self::OPTION_ENABLED, 'no' );
    144154    }
    145155
     
    208218
    209219        $code = wp_remote_retrieve_response_code( $response );
    210 
    211         // 200 = successfully purged, 404 = wasn't in cache (ok), 412 = wasn't in cache.
    212         if ( 200 === $code || 404 === $code || 412 === $code ) {
    213             self::log( 'Purged: ' . $url . ' (HTTP ' . $code . ')' );
     220        $body = wp_remote_retrieve_body( $response );
     221
     222        // ea-nginx-cache-purge module returns:
     223        // - 200 with "Successful purge" = item was in cache and purged.
     224        // - 412 Precondition Failed = item wasn't in cache (still success).
     225        //
     226        // Without module: 301/404/405 with generic nginx HTML (not a real purge).
     227        if ( 200 === $code && stripos( $body, 'Successful purge' ) !== false ) {
     228            self::log( 'Purged: ' . $url . ' (HTTP 200)' );
    214229            return array(
    215230                'success' => true,
     
    219234        }
    220235
     236        // 412 means item wasn't cached - that's fine, nothing to purge.
     237        if ( 412 === $code ) {
     238            self::log( 'Not in cache: ' . $url . ' (HTTP 412)' );
     239            return array(
     240                'success' => true,
     241                'message' => 'Not in cache (already clean)',
     242                'code'    => $code,
     243            );
     244        }
     245
     246        // Got a 200 but without cache-purge signature = module not working.
     247        if ( 200 === $code ) {
     248            self::log( 'Purge returned 200 but without module signature for ' . $url );
     249            return array(
     250                'success' => false,
     251                'message' => 'Cache purge module not responding correctly',
     252                'code'    => $code,
     253            );
     254        }
     255
     256        // 301/404/405 = module not installed or not configured for this domain.
     257        $error_msg = 'Purge failed (HTTP ' . $code . ')';
     258        if ( 404 === $code || 301 === $code ) {
     259            $error_msg = 'Cache purge module not detected - install ea-nginx-cache-purge';
     260        } elseif ( 405 === $code ) {
     261            $error_msg = 'PURGE method not allowed - cache purge module not configured';
     262        }
     263
    221264        self::log( 'Purge failed for ' . $url . ': HTTP ' . $code );
    222265        return array(
    223266            'success' => false,
    224             'message' => 'Unexpected response: HTTP ' . $code,
     267            'message' => $error_msg,
    225268            'code'    => $code,
    226269        );
     
    467510     * Get availability status for display.
    468511     *
     512     * Detection only runs on settings page (force_recheck=true) to avoid
     513     * HTTP requests on every page load. Admin bar uses cached result.
     514     *
     515     * @param bool $force_recheck Force a fresh detection check (use on settings page).
    469516     * @return array Status info with 'available', 'enabled', 'message' keys.
    470517     */
    471     public static function get_status() {
     518    public static function get_status( $force_recheck = false ) {
     519        $enabled   = self::is_enabled();
    472520        $available = get_option( self::OPTION_AVAILABLE, 'unknown' );
    473         $enabled   = get_option( self::OPTION_ENABLED, 'yes' );
    474 
    475         if ( 'unknown' === $available ) {
    476             $available = self::is_available() ? 'yes' : 'no';
     521
     522        // Only recheck on settings page (force_recheck=true).
     523        // This avoids HTTP requests on every page load.
     524        if ( $force_recheck && $enabled ) {
     525            $available = self::is_available( true ) ? 'yes' : 'no';
    477526        }
    478527
    479528        $message = '';
    480         if ( 'yes' === $available && 'yes' === $enabled ) {
    481             $message = 'Selective purging active — only changed pages are purged for maximum efficiency';
    482         } elseif ( 'yes' === $available && 'no' === $enabled ) {
    483             $message = 'Selective purging available but disabled';
     529        if ( $enabled ) {
     530            if ( 'yes' === $available ) {
     531                $message = 'Selective purging active — only changed pages are purged for maximum efficiency';
     532            } elseif ( 'no' === $available ) {
     533                $message = 'Selective purging enabled but module not detected — purges may fail';
     534            } else {
     535                $message = 'Selective purging enabled — checking module availability...';
     536            }
    484537        } else {
    485             $message = 'nginx-module-cache-purge not detected — using full cache purge via cPanel API';
     538            $message = 'Selective purging disabled — using full cache purge via cPanel API';
    486539        }
    487540
    488541        return array(
    489542            'available' => 'yes' === $available,
    490             'enabled'   => 'yes' === $enabled,
     543            'enabled'   => $enabled,
    491544            'message'   => $message,
    492545        );
Note: See TracChangeset for help on using the changeset viewer.