litespeedtech / litespeedtech/lscache_wp
Purge::purge_url() returns void — callers cannot distinguish a purge from a silent rejection
- Dominant language
- PHP
- Stars
- 257
- Forks
- 123
- PR merge metrics
- No merged PRs in 30d
Description
### Summary
`Purge::purge_url()` returns `void` and has three distinct paths that reject the request and return early. A caller has no way to distinguish "purged" from any of the three rejections, so integrations that expose purging to users report success on a guaranteed no-op.
### Detail
`src/purge.cls.php` in 7.9.1, `purge_url()` at line 943:
```php
public function purge_url( $url, $purge2 = false, $quite = false ) {
$val = trim( (string) $url );
if ( '' === $val ) {
return; // (1) empty — no debug line either
}
if ( false !== strpos( $val, '<' ) ) {
self::debug( "$val url contains <" ); // (2) angle bracket
return;
}
$val = Utility::make_relative( $val );
$hash = Tag::get_uri_tag( $val );
if ( false === $hash ) {
self::debug( "$val url invalid" ); // (3) tag lookup failed
return;
}
self::add( $hash, $purge2 );
...
do_action( 'litespeed_purged_link', $url );
}
```
All four exits — one success, three rejections — are `void`. Two of the rejections write a debug line, which is only visible when debug logging is on, and the first writes nothing at all.
### Why it matters
Any wrapper that offers "purge this URL" to a user or an API client has to report an outcome. With no return value the only options are to report unconditional success (wrong), mirror the vendor's validation rules in the wrapper (brittle — it silently stops matching the moment a fourth rule is added), or require debug logging and scrape the log (fragile, and the log format is internal).
We currently mirror the rules, which fails open: a new rejection path added upstream would not be inherited and we would resume reporting success on a no-op.
### Suggested fix
Return a value. `bool` would be enough:
```php
if ( false !== strpos( $val, '<' ) ) {
self::debug( "$val url contains <" );
return false;
}
...
do_action( 'litespeed_purged_link', $url );
return true;
```
This is backward compatible — existing callers ignore the return. A `WP_Error` carrying the reason would be even better, but a bool solves the reporting problem.
### Note
`do_action( 'litespeed_purged_link', $url )` already fires on the success path only, so a caller can partially infer the outcome by listening for it. That is a workaround rather than an interface, and it does not cover `purge_post`/`purge_all` style calls, but it does show the success signal already exists internally.
### Environment
- LiteSpeed Cache **7.9.1** (also present in 7.9 — `src/purge.cls.php` is byte-identical between the two)
- Verified by reading the shipped artifact from the wp.org ZIP, not from a running site
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in src/purge.cls.php at Purge::purge_url() around line 943 and inspect its four exit paths plus the existing litespeed_purged_link action. Check callers that use purge_url(), then verify that successful purges and each rejection are distinguishable while existing callers that ignore the return remain compatible.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php, wordpress
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100