Hasan CALISIR
Forum Replies Created
-
Forum: Plugins
In reply to: [Nginx Cache Purge Preload] Clear the entire cache when a post is updated.Hi @marcoskito,
Just replace the single status guard line in the recipe:
Remove:
if ( $new !== 'publish' || $old !== 'publish' ) return;Replace with:
if ( $new !== 'publish' ) return;That’s it — the hook now fires on any transition to
publish, covering new posts, drafts going live, and scheduled posts, in addition to the content updates it already handled.Best~Hasan
Forum: Plugins
In reply to: [Nginx Cache Purge Preload] Clear the entire cache when a post is updated.Hello @marcoskito
Purging entire cache just for single post/page update is very costly. Adding such feature also can confuse users. I’ll keep this feedback open for now. If more users request this at the plugin level, I’ll consider implementing it properly.
In the meantime, if you genuinely need this behavior, you can achieve it with the following developer recipe in your child theme’s functions.php:
// NPP Drop-in | Clear the entire cache when a post is updated
add_action( 'transition_post_status', function ( string $new, string $old, WP_Post $post ): void {
if ( $new !== 'publish' || $old !== 'publish' ) return;
if ( ! function_exists( 'nppp_purge_callback' ) ) return;
// Gutenberg: second meta-box-loader request guard.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( isset( $_REQUEST['meta-box-loader'] ) ) return;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( ! is_post_type_viewable( $post->post_type ) ) return;
$options = get_option( 'nginx_cache_settings', [] );
if ( ( $options['nginx_cache_purge_on_update'] ?? 'no' ) !== 'yes' ) return;
if ( ( $options['nppp_autopurge_posts'] ?? 'no' ) !== 'yes' ) return;
// Cross-request dedup: Elementor fires multiple HTTP requests per save.
$dedup_key = 'nppp_fullpurge_recipe_' . $post->ID;
if ( get_transient( $dedup_key ) ) return;
set_transient( $dedup_key, 1, 10 );
nppp_purge_callback();
}, 20, 3 );This respects your existing NPP settings (Auto Purge master toggle and Posts & Comments sub-trigger), works correctly with Gutenberg, Elementor, and Classic Editor, and fires only on publish → publish content updates — not on new posts or deletions.
⚠️ Important: If Auto Preload is also ON in your NPP settings, every post save will trigger a full site crawl.
Please let me now if worked on your side.
Best~Hasan
nginx.conf (aaPanel): /www/server/nginx/conf/nginx.confAlready covered with NPP.
The thing that you need to check are these included to main nginx.conf with wildcards. Becuse NPP follows included paths to parse vhost configs from main nginx.conf.
aaPanel Vhost Dir: /www/server/panel/vhost/nginx
Nginx Vhost Dir: /www/server/nginx/conf/vhostAre these paths readable by your PHP process owner www?
Best~Hasan
- This reply was modified 1 month, 1 week ago by Hasan CALISIR.
- This reply was modified 1 month, 1 week ago by Hasan CALISIR.
Thank you both for contributions. Also special thanks to Slava for positive review and testing NPP.
Slava with v2.1.6 you just need to install ripgrep and enable it in settings RG Purge, you will not suffer from Advanced Tab load timings and Single Purge events with 4.000+ URL anymore.
Purge All can be still slow because it still completely rely on wpfilesystem. Preload All also can be slow because it makes full Purge All before.
I need to discuss with wordpress plugin team to implement pure rm -rf instead of relying wpfilesystem for cache purges specially for Purge All. Because they stricly mention all filesystem ops. need to use wp-filesystem. If they allow then I will push it with v2.1.7
Best~Hasan
Hello @neikoloves
Thank you for your feedback — I really appreciate it. Since the plugin is still used by a relatively small number of users, feedback and bug reports are limited, so development tends to move a bit slower.
I always follow the development roadmap based on user feedback. Honestly, I haven’t received much feedback from panel-based setups, as many panels and managed hosting providers already include their own built-in solutions for Nginx cache management, and some even implement custom Nginx modules.
NPP is primarily designed for pure VPS-based, self-hosted, and self-managed Linux environments, aimed at system administrators and intermediate-to-advanced technical users.
Regarding the issues you reported on aaPanel: there is nothing architecturally broken on the NPP side. These are related to panel-specific overrides and aaPanel’s own internal design, and can be adjusted accordingly.
As an open-source plugin developer, this is where the challenge begins. There are many environments—open-source panels, paid panels, and managed hosting platforms—and NPP is a completely free core plugin. Ensuring full compatibility across all of them is nearly impossible in practice, as it would require significant ongoing time, resources, and sponsorship.
However, if I choose to focus deep support on a specific panel, I would prefer it to be a fully open-source solution rather than paid or commercial platforms. From a philosophical standpoint, aligning a free open-source plugin with paid services is not the direction I want to take.
To move in that direction, I would likely need to turn the NPP into a commercial or paid product, which is not something I want. As I mentioned, I believe the best approach is to rely on contributions from technically skilled panel teams or users, through GitHub pull requests, all contributions are welcome and appreciated.
P.S: Honestly I don’t know the plugin you mention in bold. If it works for you please continue to use it.
Best~Hasan
open_basedir =
{ABSPATH}/ :
{ABSPATH}/../ :
/dev/shm/ :
/tmp/ :
/var/ :
/cache/ :
/proc/ :
/dev/null :
/etc/nginx/ :
/usr/bin/ :
/usr/sbin/ :
/usr/local/bin/ :
/usr/local/sbin/ :
/bin/ :
/sbin/Yes, if you use
open_basedir, you need to allow access to cache paths,nginx.confpaths, and other paths that NPP requires, which can be hard to manage.sudo chmod 644 /etc/nginx/nginx.conf
sudo -u www-data cat /etc/nginx/nginx.conf | head -n 10Ok, so you are running everything on a single monolithic server.
nginx.conf detected (strict): NoThat means plugin can not find the nginx.conf or perm issue.
ls -al /etc/nginx/nginx.conf
stat /etc/nginx/nginx.confAnd please share the your process owner and web server user on Status Tab
PHP Process Owner (Website User)
Web Server User (nginx | www-data)Ok, you just need to keep your live
nginx.confaccessible so the plugin can reach it. If you are in a containerized environment and Nginx runs in a separate container, you need to makenginx.confaccessible to the WordPress container. For now just copy livenginx.confto wordpress container as/etc/nginx/nginx.confthen plugin automatically disable Assume Nginx mode.because i copied the content of my nginx.conf to dummy-nginx.conf
You don’t need to take that action. On a fresh install, is NPP able to detect your production
nginx.conf, or are you redirected to the plugin setup page? Are you in ‘Assume Nginx’ mode or not?But in order to get it working, i had to – also just as a try – add /dev/null to php open_basedir
Honestly I did not understand your solution too here.
To diagnose this further, we need to try some technical workarounds. Since I don’t have access to your environment, it’s difficult to reproduce the issue you’re facing. I can guide you through the steps.
php -r "echo function_exists('proc_open') ? 'enabled' : 'disabled';"If proc_open enabled on your php env. the error messages produced by nppp_detect_premature_process() in preload.php. We need to bypass this function before assigning any blame.
In preload.php
Find line number 480 and 707
if (function_exists('proc_open') && is_callable('proc_open')) {And replace to bypass this check temporarily:
if (function_exists('proc_open_fake') && is_callable('proc_open_fake')) {Now you can try again, assuming you have the technical background to edit the plugin’s core files directly.
Best~Hasan
Hello @tvarga77
To debug this reliably, the simplest approach is to run the exact preload command directly on the server. You need to run the command directly on the server (~WordPress container) where the plugin is installed.
Please try this: change http://www.site.com and let me know what happens next.
wget --recursive -l inf --no-cache --no-config --no-cookies --no-directories --delete-after \
--no-dns-cache --no-check-certificate --prefer-family=IPv4 --retry-on-http-error=503,429 --waitretry=10 \
--dns-timeout=10 --connect-timeout=5 --read-timeout=60 --tries=2 --ignore-case \
-e robots=off \
-e use_proxy=no \
-e http_proxy=http://127.0.0.1:3434 \
-e https_proxy=http://127.0.0.1:3434 \
-P /tmp \
--limit-rate=5120k \
--wait=0 \
--reject-regex='/wp-admin/|/wp-content/|/wp-includes/|/wp-json/|/xmlrpc.php|/wp-.*\.php|/cart/|/checkout/|/order-received/|/order-pay/|/wc-ajax/|/wc-auth/|/my-account/|/wc-api/|/addons/|/robots\.txt|/sitemap(_index)?\.xml|[a-z0-9_-]+-sitemap([0-9]+)?\.xml|/wp-sitemap.*\.xml|comment-page-|/feed/|/embed/|/cgi-bin/|/login/|/logout/|/register/|/lost-password/|/password-reset/|/activate/|\.well-known/|\?|\=|\&|\#' \
--reject='*.css,*.min.css,*.js,*.min.js,*.png,*.jpg,*.jpeg,*.gif,*.ico,*.mp4,*.webm,*.mov,*.avi,*.mkv,*.flv,*.wmv,*.mpeg,*.mpg,*.m4v,*.3gp,*.woff,*.woff2,*.ttf,*.eot,*.svg,*.bmp,*.pdf,*.doc,*.docx,*.xls,*.xlsx,*.ppt,*.pptx,*.zip,*.rar,*.tar,*.gz,*.bz2,*.7z,*.xml,*.txt,*.sql,*.log,*.ini,*.conf,*.json,*.bak,*.old,*.tmp,*.swp,*.md,*.rst,*.py,*.sh,*.iso,*.crt,*.key,*.pem,*.out,*.xsl' \
--domains='site.com,www.site.com' \
--header='Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
--user-agent='NPP/2.1.5 (NginxCacheWarm; device=desktop; Desktop)' \
-- 'https://www.site.com'Dou you use safexec? Are you on v2.1.5? Can you share your Status Tab?
Best ~Hasan
Hello @kaganvmz
You are welcome. According to your cache_key :
fastcgi_cache_key "$scheme$FIRST_FASTCGI_HOST$request_uri";The real problem is the $request_method filter.
The plugin has a guard in place to skip non-GET entries (POST, HEAD, etc.) to avoid operating on cache files that shouldn’t be there. These are not represent Nginx cache.I think the below fix will be enough. Cause, the default NPP Cache Key Regex correctly parsing your key, you don’t need any adjustment in regex, but since $request_method is missing in your key, you need to find and replace all occurrences.
Find (all 5 occurrences):
includes/purge.php
includes/advanced.php
includes/advanced.php
includes/status.php
includes/related.php// FIND: (breaks Engintron)
if (strpos($key_line, 'GET') === false) {
continue;
}
// REPLACE: FIXED
if (strpos($key_line, 'POST') !== false ||
strpos($key_line, 'HEAD') !== false ||
strpos($key_line, 'PUT') !== false ||
strpos($key_line, 'DELETE') !== false ||
strpos($key_line, 'PATCH') !== false ||
strpos($key_line, 'OPTIONS') !== false) {
continue;
}Please let me know fixed now, maybe I miss something else. If works for you I will commit it.
Meanwhile, if you have time to do an end-to-end test of the v2.1.5, I would greatly appreciate it.
Best~Hasan
v2.1.5 is out. FYI.
v2.1.5 is out — if you’ve been using a direct download from the GitHub branch, please do a clean reinstall from the official WordPress repository to avoid any potential naming issues.
Best~Hasan