Digital Sovereignty for everyone

Architecture

Files

  • lh-add-media-from-url.php — main plugin file. Singleton LH_add_media_from_url_plugin, hooked via plugins_loaded. Registers the Media -> Add from URL admin page and handles the upload form submission on admin_init. Thin controller only — no HTML lives in this class.
  • includes/lh-add-media-from-url-copy-from-url.php — LH_add_media_from_url_copy_from_url, a composed helper class (not a PHP subclass of the main plugin) that does the actual remote fetch and sideload into the media library.
  • includes/lh-add-media-from-url-abilities.php — LH_add_media_from_url_abilities, registers the plugin’s MCP ability. Loaded from plugins_init() only on the main site and only if the Abilities API is present.
  • partials/admin-page.php — the admin page’s own markup: header, any upload error, the upload form include, and the bookmarklet block.
  • partials/upload.php — the upload form markup itself, included from admin-page.php.

Key methods

  • LH_add_media_from_url_copy_from_url::save_external_file( $url, $post_id, $desc, $check ) — downloads $url to a temp file via wp_safe_remote_get(), validates it, guesses its extension with wp_check_filetype_and_ext(), and sideloads it via media_handle_sideload(). Stores the original URL as post meta _lh_copy_from_url-original_file.
  • guess_file_extension() inspects the already-downloaded local temp file rather than re-fetching the remote URL, so extension/MIME detection stays inside WP core’s own SSRF-protected fetch path.

Hooks

  • Filter lh_add_media_from_url_remote_get_args — filters the args array passed to wp_safe_remote_get() when fetching the remote file.
  • Filter lh_add_media_from_url_init_plugin — return false to prevent the plugin’s admin_menu/admin_init hooks and the MCP ability (see Abilities) from registering.

Capability

Gated to upload_files rather than the LH-standard install_plugins default — deliberate, since this is a media-upload tool for any user who can already upload files, not developer/admin tooling. The MCP ability uses the same capability as the manual form, not edit_posts, so a Contributor who cannot upload in wp-admin cannot upload through MCP either.

Database / cron

No custom database tables. No cron jobs. The only persistent data is the _lh_copy_from_url-original_file post meta on each created attachment.

Notes

  • The bookmarklet’s $_GET read in plugin_options() is a read-only display convenience (pre-filling the URL field), not a state-changing action — it can’t carry a nonce, since a bookmarklet is a static link with no server round-trip to mint one. The actual state-changing step, handle_upload_v2(), does verify a nonce before anything is fetched or written.

If you like this plugin please consider making a donation to further development

Install LHero.org

lhero.org

Open it straight from your home screen, full screen and quicker to load.

  1. Tap the Share button . If you cannot see it, tap ••• first.
  2. Scroll down and tap Add to Home Screen.
  3. Tap Add.
  1. Tap the browser menu â‹®.
  2. Tap Install app or Add to Home screen.
  1. In the menu bar, choose File, then Add to Dock.

Use your browser's menu to install this site or add it to your home screen.