|
1 | 1 | # CloudScale Cleanup |
2 | 2 |
|
3 | | -**Version:** 2.0.1 |
4 | | -**Author:** Andrew Baker |
5 | | -**Author URI:** https://andrewbaker.ninja |
6 | | -**License:** GPL-2.0+ |
7 | | -**Requires at least:** WordPress 5.8 |
8 | | -**Requires PHP:** 7.4 |
| 3 | +    |
9 | 4 |
|
10 | | -## Description |
| 5 | +WordPress database and media library cleanup plugin. Removes accumulated junk (revisions, drafts, transients, orphaned metadata, spam), finds unused images and orphaned filesystem files, and optimises oversized images. Full dry run preview before anything is touched. Completely free. |
11 | 6 |
|
12 | | -CloudScale Cleanup is a free, open source WordPress plugin that combines database cleanup, media library cleanup, image optimisation, and PNG to JPEG conversion in a single tool. Every operation supports dry run preview and chunked processing safe on any shared host. No accounts, no API keys, no subscriptions, no data leaves your server. |
| 7 | +No subscriptions. No external services. No calls home. |
| 8 | + |
| 9 | +> Full write up with screenshots: [WordPress Space Cleanup: A Free WordPress Database and Media Library Cleanup Plugin](https://andrewbaker.ninja/2026/02/25/wordpress-space-cleanup-a-free-wordpress-database-and-media-library-cleanup-plugin/) |
13 | 10 |
|
14 | 11 | ## Features |
15 | 12 |
|
16 | | -### 1 Database Cleanup |
17 | | -- Post revisions, drafts, trashed posts, auto drafts |
18 | | -- Expired transients, orphaned post meta, orphaned user meta |
19 | | -- Spam and trashed comments |
20 | | -- Per item toggles and configurable age thresholds |
21 | | -- Scheduled automatic cleanup via WordPress Cron |
22 | | - |
23 | | -### 2 Image Cleanup |
24 | | -- Scans the media library for unused attachments not referenced in published content, widgets, or theme mods |
25 | | -- Protects site logo, site icon, and featured images |
26 | | -- Orphan file scanner with recycle bin (move, restore, permanently delete) |
27 | | -- Scheduled automatic cleanup via WordPress Cron |
28 | | - |
29 | | -### 3 Image Optimisation |
30 | | -- Resizes oversized originals to configurable maximum dimensions |
31 | | -- Recompresses JPEGs at a configurable quality target |
32 | | -- Optional PNG to JPEG conversion for non transparent PNGs (integrated into the library) |
33 | | -- Regenerates all WordPress thumbnail sizes after processing |
34 | | -- Chunked processing (5 images per request) for any server |
35 | | - |
36 | | -### 4 PNG to JPEG Converter |
37 | | -- Drag and drop or browse to upload PNG files |
38 | | -- Batch conversion: queue multiple files and convert all at once |
39 | | -- JPEG quality slider from 1 to 100 |
40 | | -- Preset output sizes: Original, 4K, 2K/QHD, Full HD, HD, XGA, SVGA, VGA, 512x512, 256x256 |
41 | | -- Custom width/height with optional proportional constraint |
42 | | -- Chunked uploads for large files (configurable chunk size) |
43 | | -- Download converted JPEG directly |
44 | | -- Rename and add converted JPEG to WordPress Media Library with one click |
45 | | -- PNG transparency composited onto white background |
46 | | -- Full debug console with copy/clear functionality |
47 | | -- Files stored in standard WordPress uploads folder |
48 | | - |
49 | | -### 5 Settings and Status |
50 | | -- Dashboard widget with last run timestamps |
51 | | -- Front end sidebar widget |
52 | | -- WordPress Cron status display |
53 | | -- About page with plugin links |
54 | | - |
55 | | -## Chunked Processing Architecture |
56 | | - |
57 | | -Every destructive operation works in three AJAX steps: |
58 | | - |
59 | | -1. **Start** — Build the full list of IDs to process, store in a transient, return the total count to JS. |
60 | | -2. **Chunk** — Process one small batch, update the transient with remaining IDs, return log lines and remaining count. JS fires repeatedly until remaining equals zero. |
61 | | -3. **Finish** — Clean up the transient, write the last run timestamp, return a summary line. |
62 | | - |
63 | | -Each AJAX request completes in well under 30 seconds on any shared host. Chunk sizes: 50 DB items, 25 image deletions, 5 image optimisations. |
64 | | - |
65 | | -PNG to JPEG uploads use a similar chunked approach: the client splits large PNG files into configurable chunks (default 1.5 MB) and uploads them sequentially. The server reassembles chunks, validates the file is a valid PNG, then converts to JPEG. |
| 13 | +### Database Cleanup |
66 | 14 |
|
67 | | -## Installation |
| 15 | +- **Post Revisions** older than configurable threshold (default 30 days) |
| 16 | +- **Draft Posts** older than threshold (default 90 days) |
| 17 | +- **Trashed Posts** older than threshold (default 30 days) |
| 18 | +- **Auto Drafts** created when opening Add New Post and never saved (default 7 days) |
| 19 | +- **Expired Transients** that WordPress never cleaned up |
| 20 | +- **Orphaned Post Meta** referencing post IDs that no longer exist |
| 21 | +- **Orphaned User Meta** left behind when users are deleted |
| 22 | +- **Spam Comments** older than threshold (default 30 days) |
| 23 | +- **Trashed Comments** older than threshold (default 30 days) |
| 24 | + |
| 25 | +### Image Cleanup |
| 26 | + |
| 27 | +- **Unused Images** in your media library not found in any post content, featured images, widget settings, theme mods, site logo, or site icon |
| 28 | +- **Orphaned Filesystem Files** on disk in `wp-content/uploads` with no corresponding WordPress attachment record |
| 29 | + |
| 30 | +### Image Optimisation |
| 31 | + |
| 32 | +- Resize and recompress JPEG and PNG images exceeding configurable maximum dimensions or quality thresholds |
| 33 | +- Destructive operation with explicit confirmation required |
| 34 | +- Backup recommended before running |
| 35 | + |
| 36 | +## How It Works |
| 37 | + |
| 38 | +### Dry Run Preview |
68 | 39 |
|
69 | | -1. Upload the `cloudscale-cleanup` folder to `/wp-content/plugins/`. |
70 | | -2. Activate the plugin from the WordPress Plugins screen. |
71 | | -3. Navigate to **Tools > CloudScale Cleanup** in the admin menu. |
| 40 | +Always run a dry run first. The plugin scans your database and reports exactly what it found, with counts per category, individual post IDs, titles, and dates, without touching anything. Toggle states are respected so the dry run accurately reflects what the actual cleanup will do. |
72 | 41 |
|
73 | | -## Security |
| 42 | +### Chunked Processing |
74 | 43 |
|
75 | | -- All AJAX endpoints are nonce protected. |
76 | | -- All operations require the `manage_options` capability. |
77 | | -- File paths validated against WordPress uploads base directory. |
78 | | -- Upload sessions are user scoped and expire after 6 hours. |
79 | | -- Stale chunks cleaned up automatically via hourly cron. |
| 44 | +Cleanup operations use a three phase chunked engine: a start action builds the queue and stores it in a transient, a chunk action processes one batch (default 50 items) and updates the transient, and a finish action reports the final summary. The browser never waits more than a few seconds per request. Handles arbitrarily large datasets without PHP timeout issues. |
80 | 45 |
|
81 | | -## Changelog |
| 46 | +### Toggle Controls |
82 | 47 |
|
83 | | -### 1.8.6 |
84 | | -- Massively improved debug console logging: every AJAX call now logs request URL, payload, response status, response body, and full error details. |
85 | | -- Added pre-conversion checks that log AJAX URL and nonce status before each file and abort with clear error if missing. |
| 48 | +Each category has an independent toggle. Green means included, grey means skipped. Toggle states are saved with **Save Selection** and respected at scan time. Categories you never want touched can be permanently disabled. |
86 | 49 |
|
87 | | -### 1.8.5 |
88 | | -- Added inline CSC fallback: nonce, AJAX URL, chunk settings, and version are now injected directly into the page HTML so conversion works even if wp_localize_script fails to fire. |
| 50 | +### Configurable Thresholds |
89 | 51 |
|
90 | | -### 1.8.4 |
91 | | -- Repackaged zip to extract files directly into plugin folder to prevent nested directory issues. |
| 52 | +Every time based category has an age cutoff to prevent deleting recent items. Defaults are conservative. Adjust to match your workflow. |
92 | 53 |
|
93 | | -### 1.8.3 |
94 | | -- Fixed critical issue: AJAX URL and nonce showing as "NOT SET" causing all conversions to fail. Added detailed debug header showing AJAX URL, nonce status, chunk size, and server max. Added preflight check that blocks conversion with a clear error message if configuration is missing. Added console error if CSC localize object is missing. |
| 54 | +### Scheduled Cleanup |
95 | 55 |
|
96 | | -### 1.8.2 |
97 | | -- Fixed "Failed to start upload" error caused by AJAX action name conflict with standalone PNG to JPEG plugin. All merged AJAX actions now use the `csc_pj_` prefix instead of `cspj_` so both plugins can coexist if needed. |
98 | | -- Fixed upload progress badge: single file uploads now show "Uploading…" instead of confusing chunk counters like "Uploading 0 of 2". |
99 | | -- Changed PNG TO JPEG tab colour from purple to lime green so it is visually distinct from the purple Settings tab. |
| 56 | +WordPress Cron based scheduler runs database cleanup automatically on selected days at a configured hour. For precise scheduling on low traffic sites, disable WP Cron and use a real system cron hitting `wp-cron.php`. |
100 | 57 |
|
101 | | -### 1.8.1 |
102 | | -- Fixed PNG to JPEG tab colour: now uses a distinct teal/green gradient instead of duplicating the purple Settings tab colour. |
103 | | -- Added delete button (×) on each converted file in the Converted Files results list, with server side cleanup of the file on disk. |
104 | | -- Fixed upload progress badge: now shows percentage for multi chunk uploads instead of confusing chunk numbers (e.g. was showing "Uploading 2/2" which looked like "file 2 of 2"). Single chunk uploads simply show "Uploading…" with no numbers. |
| 58 | +## Requirements |
105 | 59 |
|
106 | | -### 1.8.0 |
107 | | -- Merged CloudScale PNG to JPEG Converter into CloudScale Cleanup as a new tab. |
108 | | -- Added PNG to JPEG tab with drag and drop upload, batch conversion, quality control, output size presets, custom dimensions, chunked uploads, download, rename and add to Media Library, and full debug console. |
109 | | -- Added PNG Conversions counter to Settings tab stats grid. |
110 | | -- Updated CSS and JS assets to v7 with 5 tab support and converter specific styles. |
111 | | -- All CSPJ AJAX handlers now use the shared `csc_nonce` for consistency. |
112 | | -- Added chunk cleanup cron job for stale upload sessions. |
113 | | -- Bumped version to 1.8.0. |
| 60 | +- WordPress 6.0 or higher |
| 61 | +- PHP 8.0 or higher |
114 | 62 |
|
115 | | -### 1.7.5 |
116 | | -- Previous release with database cleanup, image cleanup, image optimisation, orphan file scanner with recycle bin, scheduled cleanup, dashboard and front end widgets. |
| 63 | +## Installation |
| 64 | + |
| 65 | +1. Download the latest release zip from the [Releases](../../releases) page |
| 66 | +2. In WordPress admin go to **Plugins > Add New > Upload Plugin** |
| 67 | +3. Upload the zip file, click **Install Now**, then **Activate Plugin** |
| 68 | +4. Go to **Tools > CloudScale Cleanup** |
| 69 | + |
| 70 | +### Upgrading |
| 71 | + |
| 72 | +Deactivate > Delete > Upload zip > Activate. If you have an opcode cache running (OPcache, Redis, WP Rocket, W3 Total Cache), deactivate and reactivate after installation to ensure new files are loaded cleanly. |
| 73 | + |
| 74 | +## Architecture |
| 75 | + |
| 76 | +Self contained: single PHP file plus two asset files (CSS and JS). No external dependencies, no calls home. Uses WordPress `$wpdb` for all database operations, respects WordPress nonces for AJAX security, hooks into the standard admin menu and enqueue system. |
117 | 77 |
|
118 | 78 | ## License |
119 | 79 |
|
120 | | -This plugin is licensed under the GNU General Public License v2.0 or later. |
121 | | -See https://www.gnu.org/licenses/gpl-2.0.html for the full license text. |
| 80 | +GPLv2 or later. See [LICENSE](LICENSE) for the full text. |
| 81 | + |
| 82 | +## Author |
| 83 | + |
| 84 | +[Andrew Baker](https://andrewbaker.ninja/) - CIO at Capitec Bank, South Africa. |
0 commit comments