Caching & Transients

CWP Snippets provides a set of helper functions for caching data using WordPress transients. All cache keys are automatically prefixed with cwpUF_ to avoid conflicts with other plugins.


Core Caching Functions

cwpCacheData($key, $data = null, $expire = 3600)

Set or get cached data using WordPress transients. All keys are automatically prefixed with cwpUF_.

Set cache:

cwpCacheData('my_key', $data, 3600); // Cache for 1 hour

Get cache:

$data = cwpCacheData('my_key'); // Returns cached value or false if expired/not found

Disable caching (development):

// Set cache duration to 0 to disable caching
$cache_duration = 0;
if ($cache_duration > 0) {
    cwpCacheData('my_key', $data, $cache_duration);
}

Parameters:

  • $key (string, required): Unique cache key (will be automatically prefixed with cwpUF_)
  • $data (mixed, optional): Data to cache. If null, function returns the cached value
  • $expire (int, optional): Expiry in seconds (default: 3600 = 1 hour)

Returns:

  • When getting (data is null): Returns cached value or false
  • When setting: Returns true on success, false on failure

cwpClearCache($key)

Clear a specific cached item by key.

Usage:

$result = cwpClearCache('my_key'); // Returns true if deleted, false otherwise

Parameters:

  • $key (string, required): Cache key to clear (will be automatically prefixed with cwpUF_)

Returns: Boolean - true if deleted, false otherwise


cwpClearCacheWildcard($prefix, $limit = 25)

Delete multiple transients by prefix wildcard. For example, prefix alex_ deletes all keys starting with alex_.

Usage:

$result = cwpClearCacheWildcard('user_', 50);
// Returns: ['matched' => 3, 'deleted' => 3, 'matched_keys' => [...], 'warning' => null]

Parameters:

  • $prefix (string, required): Logical prefix (without cwpUF_ prefix). Do NOT include trailing *
  • $limit (int, optional): Maximum number of matches to process (default: 25)

Returns: Array with keys:

  • matched (int): Total number of matching transients found
  • deleted (int): Number successfully deleted
  • matched_keys (array): List of matched cache keys
  • warning (string|null): Warning message if limits exceeded or errors occurred

Important notes:

  • Do NOT include the asterisk (*) in the prefix parameter
  • If more keys match than the limit, only the first N (alphabetically) are processed
  • A warning is returned if the match count exceeds the limit
  • Invalid prefixes (empty string, contains *) return a warning

cwpClearAllTransients($prefix = 'cwpUF_')

Clear ALL transients with the specified prefix. By default, clears all CWP Snippets cache.

Usage:

$deleted = cwpClearAllTransients(); // Clears all cwpUF_* transients
// Returns: 12 (number of transients deleted)

Parameters:

  • $prefix (string, optional): Prefix to match (default: 'cwpUF_')

Returns: Integer - number of transients deleted


REST API Endpoint

POST /wp-json/cwp/v1/clear-cache

Allows external applications (e.g., FileMaker) to clear cache via REST API.

Open CWP Snippets → Integration Security and copy the generated API token. You can reveal, copy, or rotate it there. The token is generated on activation or upgrade and is stored as a non-autoloaded WordPress option.

Send the token in an Authorization: Bearer or X-CWP-Token header. Logged-in administrators may alternatively use standard WordPress REST cookie/nonce authentication. Requests are rejected when no integration token is configured.

Clear a Specific Key

Request:

curl -X POST https://example.com/wp-json/cwp/v1/clear-cache \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_CWP_TOKEN" \
  -d '{"cache_key":"my_key"}'

Response:

{
  "success": true,
  "message": "Cache 'my_key' cleared."
}

Clear Multiple Keys

Request:

curl -X POST https://example.com/wp-json/cwp/v1/clear-cache \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_CWP_TOKEN" \
  -d '{"cache_key":["key1","key2","key3"]}'

Response:

{
  "success": true,
  "results": {
    "exact": {
      "key1": true,
      "key2": true,
      "key3": false
    }
  },
  "message": "Processed multiple cache keys."
}

Clear by Wildcard Prefix

Request:

curl -X POST https://example.com/wp-json/cwp/v1/clear-cache \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_CWP_TOKEN" \
  -d '{"cache_key":"user_*"}'

Response:

{
  "success": true,
  "result": {
    "matched": 3,
    "deleted": 3,
    "matched_keys": ["user_123", "user_456", "user_789"],
    "warning": null
  },
  "message": "Processed wildcard prefix."
}

Clear All Cache

Request (Method 1 - clear_all flag):

curl -X POST https://example.com/wp-json/cwp/v1/clear-cache \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_CWP_TOKEN" \
  -d '{"clear_all":true}'

Request (Method 2 - special cache_key):

curl -X POST https://example.com/wp-json/cwp/v1/clear-cache \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_CWP_TOKEN" \
  -d '{"cache_key":"clear_all"}'

Response:

{
  "success": true,
  "deleted": 12,
  "message": "Deleted 12 transients."
}

Delimiter-Separated Keys

You can send comma, semicolon, or newline-separated keys as a string:

Request:

curl -X POST https://example.com/wp-json/cwp/v1/clear-cache \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_CWP_TOKEN" \
  -d '{"cache_key":"key1, key2, user_*"}'

FileMaker Integration

Insert from URL Examples

Clear Specific Key

FileMaker Script:

Set Variable [ $url ; Value: "https://your-site.com/wp-json/cwp/v1/clear-cache" ]
Set Variable [ $cacheKey ; Value: "my_cache_key" ]
Set Variable [ $curlOptions ; Value: "--request POST --header \"Content-Type: application/json\" --header \"Authorization: Bearer " & $$cwpToken & "\" --data \"{\\\"cache_key\\\":\\\"" & $cacheKey & "\\\"}\"" ]
Insert from URL [ Select ; With dialog: Off ; Target: $$result ; $url ; cURL options: $curlOptions ]

Clear All Cache

FileMaker Script:

Set Variable [ $url ; Value: "https://your-site.com/wp-json/cwp/v1/clear-cache" ]
Set Variable [ $curlOptions ; Value: "--request POST --header \"Content-Type: application/json\" --header \"Authorization: Bearer " & $$cwpToken & "\" --data \"{\\\"clear_all\\\":true}\"" ]
Insert from URL [ Select ; With dialog: Off ; Target: $$result ; $url ; cURL options: $curlOptions ]

Using Let Calculation (No Manual Escaping)

Let(
  [
    json = JSONSetElement("{}"; "cache_key"; "my_key"; JSONString);
    curl = "--request POST " &
           "--header " & Quote("Content-Type: application/json") & " " &
           "--header " & Quote("Authorization: Bearer " & $$cwpToken) & " " &
           "--data " & Quote(json) & " " &
           "--max-time 30"
  ];
  curl
)

Security Considerations

Important: The REST and AJAX endpoints require the generated integration token. Keep it in FileMaker's protected configuration rather than plugin source or snippets. CWP_SNIPPETS_API_TOKEN and the cwp_snippets_api_token filter remain available as advanced secret-manager overrides.

  • Rotate the token if it is exposed and update every external caller.
  • Prefer an authorization header; query-string tokens can appear in access logs.
  • The same token authorizes exact, wildcard, and clear-all operations, so only share it with trusted server-to-server clients.
  • Standard WordPress REST nonce authentication remains available to users with the manage_options capability.
  • Legacy Compatibility can temporarily preserve pre-2.0 unauthenticated calls. It is unsafe for normal operation, every use is logged, and strict token mode should be restored as soon as callers have been updated.
  • New installs and upgrades default to Legacy Compatibility mode to avoid silently breaking existing callers. The Settings screen displays the warning and lets an administrator disable it after adding the token to every caller. Once saved, the administrator's choice is preserved by future updates.

Additional Helper Functions

cwp_cache_bust($url, $version = null)

Append a cache-busting query string to asset URLs to force browsers to reload updated files.

Usage:

// Using file modification time (recommended)
$url = cwp_cache_bust(get_stylesheet_directory_uri() . '/style.css');
// Returns: https://site.com/style.css?v=1704844800

// Using custom version
$url = cwp_cache_bust(get_stylesheet_directory_uri() . '/script.js', '1.2.3');
// Returns: https://site.com/script.js?v=1.2.3

Parameters:

  • $url (string, required): The asset URL to modify
  • $version (string|int, optional): Version or timestamp. If null, uses file modification time or current timestamp

Returns: Cache-busted URL string, or false if URL is invalid


cwpIsURLValid($data, $logging = false, $checkCount = 1, $random = false)

Quickly check whether cached FileMaker responses contain expired Streaming_SSL image URLs.

Purpose: Validates FileMaker container image URLs before serving cached data to ensure images are still accessible.

Usage:

$cached = cwpCacheData('fm_records');
if ($cached && cwpIsURLValid($cached, true)) {
    // Cache is valid, use it
} else {
    // Refresh cache from FileMaker
}

Parameters:

  • $data (string|array, required): A URL string or FileMaker response array to validate
  • $logging (bool, optional): Log failures to CWP error log (default: false)
  • $checkCount (int, optional): Number of URLs to validate (default: 1)
  • $random (bool, optional): Sample URLs randomly if true, or use first N if false (default: false)

Returns: Boolean

  • true if all sampled URLs return 2xx HTTP status
  • false if any URL fails validation

Behavior:

  • Recursively scans arrays for values containing Streaming_SSL (case-insensitive)
  • Performs HTTP HEAD requests with short timeouts
  • Falls back to GET request if HEAD fails
  • Returns true immediately if no Streaming_SSL URLs found

Examples:

// Check single cached response with logging
if (!cwpIsURLValid($cached, true)) {
    // Refresh cache
}

// Check 3 random images
if (!cwpIsURLValid($response, true, 3, true)) {
    // One or more URLs failed
}

cwpShowTransients()

Display all current CWP transients and their expiry times for debugging.

Usage:

cwpShowTransients(); // Only visible to users with 'manage_options' capability

Security: Automatically restricted to admin users only.


Best Practices

  1. Use descriptive cache keys:

    // Good
    cwpCacheData('user_profile_123', $data);
    
    // Bad
    cwpCacheData('data', $data);
  2. Set appropriate expiry times:

    // Frequently changing data - 5 minutes
    cwpCacheData('stock_prices', $data, 300);
    
    // Rarely changing data - 7 days
    cwpCacheData('company_info', $data, 604800);
  3. Clear cache when data changes:

    // After updating a record
    cwpClearCache('user_profile_' . $user_id);
    
    // Or clear related wildcards
    cwpClearCacheWildcard('user_profile_', 50);
  4. Use wildcards for grouped data:

    // Cache with consistent prefix
    cwpCacheData('invoice_' . $invoice_id, $data);
    cwpCacheData('invoice_meta_' . $invoice_id, $meta);
    
    // Clear all invoice-related cache
    cwpClearCacheWildcard('invoice_', 100);
  5. Disable caching during development:

    $cache_duration = 0; // Set to 0 to disable
    if ($cache_duration > 0) {
        cwpCacheData($key, $data, $cache_duration);
    }
  6. Add logging for external clears:

    // In your REST endpoint permission_callback or handler
    cwpLog('cache_cleared', 'External API cleared cache: ' . $cache_key);
        "--max-time 30"

    ]; curl )

  • Append --header "Authorization: Bearer <token>" using Quote(); avoid placing secrets in URLs.

  • Admin-AJAX (authenticated compatibility endpoint):

    • Use POST with the token header; GET requests are rejected.
--request POST --header "Content-Type: application/x-www-form-urlencoded" --header "Authorization: Bearer YOUR_CWP_TOKEN" --data "action=cwp_clear_cache&clear_all=1" --max-time 30
  • From FileMaker, send the action and parameters in the POST body and the token in an authorization header.

Notes about escaping in FileMaker

  • If you paste raw cURL options into the cURL box, JSON double-quotes must be escaped (e.g., \"clear_all\":true).
  • Use Quote() and JSONSetElement() in a calculation to avoid manual escaping and to produce valid JSON automatically.

Why JSON vs form-encoded

  • The REST endpoint expects JSON and will parse the body automatically when Content-Type is application/json. Admin-AJAX can accept form-encoded parameters and is convenient for quick tests.

Safety & recommendations

  • The REST route and AJAX compatibility handler require the same long, unguessable integration token.
  • Add logging (cwpLog) for any external clears so you can audit who/when cleared caches.

Transient Expiry Viewer

cwpShowTransients()

Purpose:

  • Displays all current CWP transients (cache items) and their expiry times.
  • Only visible to users with manage_options capability (admins/webmasters).

Usage:

cwpShowTransients();

Security Note:

  • This function is for debugging and admin use only. It is not visible to regular users.
  • The code does not reveal or hint at any sensitive or private transients.