PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.3.3
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.3.3
1.3.3 1.3.2 1.3.1 1.3.0 1.2.4 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 All 29 releases
← All changes | includes/class-cloudflare.php +37 -9 1.0.31.3.3 View file →
@@ -58,16 +58,35 @@
58 58 );
59 59 }
60 60
61 61 /**
62 - * Purge a specific list of URLs. CF accepts up to 30 per call;
63 - * caller should chunk if it has more.
62 + * Files sent per `purge_cache` call.
64 63 *
64 + * Cloudflare's own limit is higher and varies by plan; 30 is what its
65 + * official WordPress plugin chunks at, and staying there keeps the
66 + * request body small on hosts with a modest `max_execution_time`.
67 + */
68 + private const PURGE_FILES_PER_CALL = 30;
69 +
70 + /**
71 + * Purge a specific list of URLs.
72 + *
73 + * Sent in chunks, so a list longer than one call still arrives in full.
74 + * It used to be truncated to the first 30 instead, and the
75 + * caller was told the purge succeeded — so on a site with more than 30
76 + * affected pages the rest silently stayed at the edge. Nothing in the
77 + * result said which, because as far as the response was concerned the
78 + * call did succeed.
79 + *
80 + * Stops at the first failure and returns it, rather than carrying on and
81 + * reporting the last outcome: the usual reason a chunk fails is the token
82 + * or the zone, which the next chunk would hit too.
83 + *
65 84 * @param string[] $urls
66 85 * @return array{ok:bool,status:int,body:array}
67 86 */
68 87 public static function purge_urls( array $opts, array $urls ): array {
69 - $urls = array_values( array_filter( array_map( 'strval', $urls ) ) );
88 + $urls = array_values( array_unique( array_filter( array_map( 'strval', $urls ) ) ) );
70 89 if ( empty( $urls ) ) {
71 90 return self::fail( 0, 'No URLs supplied.' );
72 91 }
73 92 $zone = (string) ( $opts['zone_id'] ?? '' );
@@ -73,14 +92,23 @@
73 92 $zone = (string) ( $opts['zone_id'] ?? '' );
74 93 if ( '' === $zone ) {
75 94 return self::fail( 0, 'Zone ID is empty.' );
76 95 }
77 - return self::request(
78 - $opts,
79 - 'POST',
80 - '/zones/' . rawurlencode( $zone ) . '/purge_cache',
81 - array( 'files' => array_slice( $urls, 0, 30 ) )
82 - );
96 +
97 + $result = array();
98 + foreach ( array_chunk( $urls, self::PURGE_FILES_PER_CALL ) as $chunk ) {
99 + $result = self::request(
100 + $opts,
101 + 'POST',
102 + '/zones/' . rawurlencode( $zone ) . '/purge_cache',
103 + array( 'files' => $chunk )
104 + );
105 + if ( empty( $result['ok'] ) ) {
106 + return $result;
107 + }
108 + }
109 +
110 + return $result;
83 111 }
84 112
85 113 /**
86 114 * Flip development mode on or off. CF auto-disables it after 3