dshovchko / flarum-image-migrate
Check and migrate external images in posts
Installs: 67
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 0
Forks: 0
Open Issues: 0
Type:flarum-extension
pkg:composer/dshovchko/flarum-image-migrate
Requires
- flarum/core: ^1.0
- guzzlehttp/guzzle: ^7.0
README
A Flarum extension that detects external images in posts and helps migrate them to your own storage.
Features
- đ Detects external images from non-whitelisted domains
- đ Migration mode (
--fix) that downloads external files, pushes them to your configured backend, and rewrites post content automatically - đ§ Email reports with detailed statistics and optional on-demand emails
- â° Scheduled automatic checks (daily/weekly/monthly)
- đ¯ Flexible checking: all posts, specific discussion, or single post
- đ Admin-configurable backend credentials with built-in health-check
- đ Grouped reporting by discussions and posts, plus a persistent audit log for migrated URLs
- âī¸ Configurable allowed domains
Installation
composer require dshovchko/flarum-image-migrate
Usage
Configuration
Configure the extension via the admin panel:
- Go to Admin â Extensions â Image Migrate
- Set Allowed Origins (comma-separated domains, e.g.,
example.com, cdn.example.com) - Provide the backend connection details: Backend Base URL, Backend Environment (production/sandbox/etc.), and Backend API Key
- Enable Scheduled Checks (optional)
- Set Check Frequency (daily/weekly/monthly)
- Add Email Recipients (comma-separated)
Saving the settings will ping the backend health endpoint; the form cannot be saved while the backend is unreachable. After upgrading to v1.1.0, run php flarum migrate once to create the migration log table.
â ī¸ Scheduled checks require Flarum scheduler to be configured. Add to your crontab:
* * * * * cd /path/to/flarum && php flarum schedule:run >> /dev/null 2>&1
Manual Console Command
Check for external images using the image-migrate:check console command:
# Check a single discussion php flarum image-migrate:check --discussion=123 # Check a specific post php flarum image-migrate:check --post=456 # Scan all discussions php flarum image-migrate:check --all # Run the scan and migrate matching images immediately php flarum image-migrate:check --all --fix # Run the scan and migrate matching images immediately with scale php flarum image-migrate:check --all --fix --scale=1.5 # Email the report php flarum image-migrate:check --all --mailto=admin@example.com # Combine options php flarum image-migrate:check --all --mailto=admin@example.com,moderator@example.com
âšī¸ The command requires one of
--discussion=<id>,--post=<id>, or--all. đ When using--fix, the backend settings must be valid and reachable.
Migration Mode (--fix)
When --fix is present, the command will:
- Run the same detection logic as the regular scan
- Download each external image to a temporary file
- Upload it to the configured backend using the selected environment
- Replace the original
srcattribute in the post with the new URL - Store an entry in
dshovchko_image_migratefor auditing (discussion/post IDs, author, old/new URLs)
The command aborts on the first failed upload so that no discussion is partially migrated. Consider running without --fix first to review the report, then re-run with --fix for the same filters.
đ If the SnapGrab backend reports a duplicate upload (HTTP 208), the migration stops immediately and the CLI prints both the original external URL and the already-hosted optimized asset so you can reconcile the post manually. No changes are written to the post in that scenario.
Email Reports
Reports include:
- Total number of external images found
- Number of discussions with issues
- Detailed breakdown by discussion and post
- Direct links to affected discussions and posts
- List of external image URLs
Example report format:
External Images Report
Total external images: 56
â ī¸ Discussions with issues: 8
==================================================
â ī¸ Discussion 8
https://example.com/d/8
external images in posts (10)
posts: 14 15 16 17 18 19
Post #14: 3 image(s)
https://example.com/d/8/1
- https://external-cdn.com/image1.jpg
- https://external-cdn.com/image2.jpg
How It Works
- The extension scans post content for
<img>tags - Extracts image URLs from the
srcattribute - Compares image domains against your allowed origins list
- Reports any images hosted on external domains
- Groups results by discussion and post for easy review
Allowed Origins
Domains in the allowed origins list are considered "internal" and won't be flagged:
- Exact domain match:
example.commatchesexample.com - Subdomain match:
example.commatchescdn.example.com,images.example.com - Case-insensitive matching
- Automatic
www.prefix handling
Requirements
- Flarum ^1.0
- PHP 7.4+
Release Checklist
When tagging a new version:
- Run
cd js && npm ci && npm run buildto regeneratejs/dist/admin.js. - Commit the updated
js/distassets together with any code changes (do not rely on production servers having Node.js available). - Update
CHANGELOG.mdwith the new version and summary. - Tag the release (
git tag -a vX.Y.Z -m "vX.Y.Z") and push the tag to origin.
This ensures Packagist builds include the already-tested TypeScript admin bundle.
Development
The admin UI is authored in TypeScript and lives in js/src/admin (entry point js/admin.ts). To work on it locally:
cd jsnpm cinpm run devfor a watch build ornpm run buildfor a production bundle
Webpack reads tsconfig.json, so updating the TypeScript sources automatically recompiles the js/dist/admin.js asset that ships with the extension.
Future Features
- Automatic retries/backoff for flaky external hosts
- Extended reporting in the admin panel
- Additional image transformation presets