| 开发者 |
goonydev
philooo |
|---|---|
| 更新时间 | 2026年6月2日 12:25 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 6.9 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
<img> tags to <picture> elements with CDN URLs and WebP sources<picture> elements with WebP <source> fallbacksSQMEDIA_CRON_BATCH_SIZE — attachments per cron tick (default: 1)SQMEDIA_CRON_MAX_SECONDS — time budget per cron tick (default: 25)SQMEDIA_SCAN_BATCH_SIZE — attachments per scanner batch (default: 50)SQMEDIA_R2_ACCESS_KEY_ID — R2 API credentialsSQMEDIA_R2_SECRET_ACCESS_KEY — R2 API credentialsSQMEDIA_R2_BUCKET — R2 bucket nameSQMEDIA_R2_ACCOUNT_ID — Cloudflare account IDstaticq-media folder to /wp-content/plugins/.Images are not processed on upload. They enter a queue and are processed in batches by WordPress cron. Batch size and time budget are configurable. This avoids CPU spikes and timeouts, especially on shared hosting.
No — Cloudflare is optional. The plugin is optimized for Cloudflare workflows (R2 offload, Cloudflare Image Resizing, and the optional Worker fallback), but it runs fully on your own server without any cloud account. In local-only mode, StaticQ uses WordPress's native image editor (GD or Imagick) for resizing and WebP generation, files stay in your uploads directory, and the Media Library Scanner, Post Content Scanner, and Orphan Detection all work as a pure audit-and-cleanup toolkit. Cloudflare comes in when you want offsite storage, edge-based image resizing, or CDN fallback. R2's free tier (10 GB storage, 10 million reads/month) is generous for most WordPress sites if you decide to enable it.
No. Processing is fully decoupled from the upload request. WordPress cron handles it in the background.
Yes. The Media Manager registration tool indexes your entire existing library. Then run the Media Library Scanner to detect issues and repair them — missing sizes, WebP variants, and cloud sync gaps are all handled.
Your original files remain untouched. Cloud copies stay in your bucket. Front-end delivery stops — WordPress falls back to local URLs. No data is deleted on deactivation.
Yes. Front-end delivery uses output buffering, so it works with any theme, page builder, or caching plugin that outputs standard HTML.
The Media Manager page shows queue status, processed counts, and per-attachment state. Scanner results show issue breakdowns by category.
It checks every attachment against your current settings in one pass. Metadata is validated for missing sizes, wrong dimensions, deprecated entries, and missing WebP variants. Files are verified across local disk and cloud bucket to ensure they exist in the correct storage location. Issues are categorized by type and severity. You can repair individual attachments with one click, or use Batch Fix All to resolve everything at once.
It inspects every post, page, and custom post type for image references baked into the content. It detects URLs pointing to wrong domains (e.g. old CDN or migration leftovers), stale size references that no longer match current attachment metadata, deleted attachments still referenced in content, and broken URLs that cannot be resolved. Wrong domain and stale size issues can be fixed automatically — the scanner rewrites the URLs directly in the database. Deleted attachment and broken URL issues are reported for manual review.
Orphan Detection lists all files in your local uploads directory and cloud bucket, then compares them against the WordPress database. Any file with no matching attachment record is flagged as an orphan. You can exclude specific folders to avoid false positives. Orphans can be quarantined for safe review before permanent deletion. Run the Media Library Scanner first to fix metadata issues, then Orphan Detection to catch leftover files.
Yes. EXIF metadata (GPS coordinates, camera info, timestamps) is stripped during processing. This reduces file size and removes potentially sensitive location data.
Absolutely. Cloud offloading is just one part of the pipeline. The Media Library Scanner audits your entire library and lets you repair everything in one pass. Orphan Detection cleans up leftover files. The Post Content Scanner fixes stale image references in your posts. And the queue-based processing prevents CPU spikes on upload — all without moving a single file off your server.
content_save_pre filter (revert_cdn_urls_in_content). In Worker mode (the default), when the CDN host equals the WordPress site host, the previous logic computed a CDN prefix without the /wp-content/uploads/ path segment and then ran str_replace(cdn_prefix, local_prefix, $content), which prepended /wp-content/uploads/ to every internal URL in the post on save. This doubled the path on media URLs (/wp-content/uploads/wp-content/uploads/...) and injected the path on non-media internal links (/lm002/ became /wp-content/uploads/lm002/).encode_upload_url_paths rewriter. The same too-short prefix computation also misled its foreign-domain detection and stripped the /wp-content/uploads/ segment when rewriting legacy/foreign CDN URLs to the current CDN host. Visible on sites with legacy-domain URLs in content (e.g. static.example.com → www.example.com) or already-rewritten URLs from a separate CDN host.compute_current_cdn_prefix() helper that correctly returns {cdn_base}/{r2_prefix}/ in Direct mode and {cdn_base}/wp-content/uploads/ (host-swapped if needed) in Worker mode. When the CDN URL prefix equals the local prefix, the filters short-circuit.force_prefix_in_url through the URL rewriter and made get_url_prefix() return empty in Worker mode; the two affected functions then started producing wrong results because they relied on get_url_prefix() to fill in the URL's path segment, which only worked in Direct mode. Sites in Direct mode (force_prefix_in_url = true) were never affected.esc_attr() / esc_html() at the echo site (WP.org review hardening).render_pagination_buttons() to print directly with per-attribute escaping instead of building an HTML string and echoing it whole.<script type="application/json">) with JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT flags.completed despite producing nothing) and converts them to a real failure status, allowing the existing retry logic to recover the attachment on subsequent cron ticks.original_location from the current Original File Handling setting; it leaves the field NULL until verified. This prevents the Orphan Scanner from flagging legacy originals as orphans on sites where the setting was changed at some point — the scanner's NULL branch indexes both possible locations until the Media Library Scanner aligns the record to observed state.Move to /originals/ original file handling: the unscaled original is now actually moved to wp-content/uploads/originals/<dir>/ locally, mirroring the bucket placement. Previously only the bucket copy moved while the local copy stayed alongside the master.Undefined array key "status" PHP warning during quarantine restore.Table doesn't exist errors logged when the WordPress Plugin Check tool runs the plugin under its alternate wp_pc_ table prefix.debug.log (kept once-per-scan summaries).define('SQMEDIA_DEBUG_VERBOSE', true); in wp-config.php when investigating cron behavior.STATICQ_* wp-config.php constants to the SQMEDIA_* prefix for project-wide naming consistency (SQMEDIA_R2_ACCOUNT_ID, SQMEDIA_R2_ACCESS_KEY_ID, SQMEDIA_R2_SECRET_ACCESS_KEY, SQMEDIA_R2_BUCKET, SQMEDIA_R2_PREFIX, SQMEDIA_CF_TOKEN, SQMEDIA_SKIP_DIRS). Update wp-config.php on upgrade.<img> src and srcset via the the_content filter and the frontend output buffer with esc_url(), hardening rendered output.ob_start() / ob_get_clean() pair on template_redirect / shutdown (replacing the callback-based buffer) for clearer pairing and added a buffer-level guard so foreign nested buffers cannot trigger our close.ob_start() / ob_get_clean() pairing in the scanner UI renderer trivially auditable by capturing the buffer to a local variable before passing it to wp_add_inline_script().composer.json in the WordPress.org distribution zip.sq_ to sqmedia_ to meet WordPress.org prefix uniqueness requirements. Pre-3.3 dev-build installs: settings reset on upgrade — reconfigure R2 credentials and re-run the Cloudflare Worker wizard.<picture> tag delivery with format fallbacks.