Skip to content

Add Media Resource Checker plugin#536

Open
t-hamano wants to merge 23 commits intoWordPress:trunkfrom
t-hamano:media-resource-checker
Open

Add Media Resource Checker plugin#536
t-hamano wants to merge 23 commits intoWordPress:trunkfrom
t-hamano:media-resource-checker

Conversation

@t-hamano
Copy link
Copy Markdown

@t-hamano t-hamano commented Dec 21, 2025

Closes: https://meta.trac.wordpress.org/ticket/8149

This PR adds a plugin that displays a warning for blocks that contain inappropriate external resources. This helps encourage contributors to upload resources when creating documentation by copying content from external documents, preventing media from potentially disappearing in the future.

How this plugin works

  • Check the three blocks that allow you to set external resources as media.
  • Check whether the media URL matches your site's domain. If not, this plugin checks whether it matches one of the allowed domains. Finally, if the media URL does not match any domain, it is considered an inappropriate media resource.
  • Blocks with invalid media resources will have a red border and overlay.
    Additionally, the block toolbar will have a red icon button. Clicking that button will display a popover with details about the error.

Testing Instructions

Use the .wp-env.override.json file to map the plugin to your local wp-env environment:

{
	"plugins": [
		"./your/plugins/plugin",
		"../path/to/wordpress.org/wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker"
	]
}

Screenshot

image

@t-hamano t-hamano force-pushed the media-resource-checker branch from a189f1f to d12ab9f Compare December 21, 2025 06:45
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the right place for this file; maybe it should be in a higher directory to cover all plugin files?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably define this into /.gitignore or just leave it in the project-specific area since it doesn't matter all that much.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no strong opinion about where this file should be located 😄 Please feel free to move it elsewhere if necessary.

* License: GPLv2 or later
*/

namespace WPOrg_Media_Resource_Checker;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use WordPressdotorg\Media_Resource_Checker instead?


namespace WPOrg_Media_Resource_Checker;

use function WPOrg_Media_Resource_Checker\{ get_build_path, get_build_url };
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the purpose of this is? Importing the functions defined in the current file into the file?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've imitated the implementation of the Learn plugin:

/**
* Shortcut to the build directory.
*
* @return string
*/
function get_build_path() {
return PLUGIN_DIR . 'build/';
}
/**
* Shortcut to the build URL.
*
* @return string
*/
function get_build_url() {
return PLUGIN_URL . 'build/';
}

use function WPOrg_Learn\{ get_build_path, get_build_url };

We can also use an approach that doesn't use it if we don't need it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 9d72889

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably define this into /.gitignore or just leave it in the project-specific area since it doesn't matter all that much.

Comment on lines +26 to +36
// List of allowed domain regexes.
export const ALLOWED_DOMAINS = [
{
authority: 'wordpress.org',
regex: /^(.*\.)?wordpress\.org$/,
},
{
authority: 'wp.com',
regex: /^(.*\.)?wp\.com$/,
},
];
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if wp.com should be allowed here, since WordPress.org != WordPress.com, and often using wpcom hosted images ends up invalid.

I can imagine this might also be intended for photon images? In which case, allowing ^(.*\.)?wp.com/(.*\.)?wordpress\.org/ could make sense?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can imagine this might also be intended for photon images?

Yes, that's right. For example, the handbook uses images that are actually delivered from the Photon CDN:

https://github.com/search?q=repo%3AWordPress%2Fdeveloper-plugins-handbook%20wp.com&type=code

In which case, allowing ^(.*\.)?wp.com/(.*\.)?wordpress\.org/ could make sense?

I agree, fixed in e1db353.

Specific examples of allowed URLs can be found here.

https://github.com/WordPress/wordpress.org/pull/536/changes#diff-6b3ed010975581690ee4c331ff822c288910b4e110783cb70ede501d96183e36R66-R70

Comment on lines +28 to +31
{
authority: 'wordpress.org',
regex: /^(.*\.)?wordpress\.org$/,
},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We likely should also allow the WordPress.org CDNs here:

Suggested change
{
authority: 'wordpress.org',
regex: /^(.*\.)?wordpress\.org$/,
},
{
authority: 'wordpress.org',
regex: /^(.*\.)?wordpress\.org$/,
},
{
authority: 'wordpress.org',
regex: /^(.*\.)?w\.org$/,
},

Eg; https://s.w.org/images/core/6.9/01-notes.webp?v=24082

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 302493e

Just to be sure, I have distinguished between the authority texts wordpress.org and w.org.

image

Copilot AI review requested due to automatic review settings April 26, 2026 12:31
@github-actions
Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props wildworks, dd32.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new wporg-media-resource-checker plugin that flags certain Gutenberg blocks when they reference media URLs from non-recommended external domains, surfacing an in-editor warning UI (overlay + toolbar control).

Changes:

  • Registers/enqueues editor JS/CSS assets for the checker plugin.
  • Implements block attribute inspection + domain allowlist validation for image/video/cover blocks.
  • Adds editor UI affordances (block overlay + toolbar dropdown) to explain and link to the offending resource.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/wporg-media-resource-checker.php Enqueues built editor script and styles.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/index.js Adds editor HOCs/controls to display warnings and domain list.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/utils.js Block targeting + URL/domain allowlist validation helpers.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/hooks.js Hook to fetch site URL and compute invalid resource state.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/style.scss Visual warning styling (overlay/border) and popover styling.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/package.json Build tooling dependencies and scripts for wp-scripts.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/index.js Compiled editor script bundle.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/index.asset.php Asset metadata for script dependencies/versioning.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/style-index.css Compiled stylesheet.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/style-index-rtl.css Compiled RTL stylesheet.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/.gitignore Ignores local Node/npm artifacts for the plugin.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

t-hamano and others added 2 commits April 26, 2026 21:53
Use 'wporg' as the text domain for consistency with other wordpress.org plugins (wporg-meeting-posttype, wporg-abilities, handbook). Also adds the missing text domain to the toolbar button label so all translatable strings are properly registered.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 26, 2026 13:02
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new wporg-media-resource-checker plugin intended to warn block-editor users when certain blocks reference media hosted on non-recommended external domains, encouraging uploads to approved locations for long-term stability.

Changes:

  • Introduces a new WordPress plugin that enqueues a block-editor script and styles to flag blocks with non-recommended media URLs.
  • Implements client-side URL validation logic and a block-editor UI (toolbar warning + popover + red overlay styling).
  • Adds built JS/CSS artifacts and a package.json for building the plugin assets with @wordpress/scripts.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/wporg-media-resource-checker.php Plugin bootstrap; enqueues editor script and admin styles.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/index.js Adds Block Editor filters/HOCs to display warning UI and apply invalid-resource class.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/hooks.js Adds a useSelect-based hook to fetch site URL and compute invalid-resource state.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/utils.js Defines allowed domains and core URL/resource validation helpers.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/style.scss Styles for invalid-resource overlay, toolbar icon, and popover content.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/index.js Built editor script bundle.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/index.asset.php Build-generated dependency/version metadata for the script bundle.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/style-index.css Built stylesheet.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/style-index-rtl.css Built RTL stylesheet.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/package.json Build tooling/dependency definitions for the plugin.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/.gitignore Ignores node_modules and package-lock.json.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

t-hamano and others added 3 commits April 26, 2026 22:16
…sInvalidResource.

The previous comment contradicted the implementation by stating the media
was "not an external resource" while the function returns true (invalid).
Reword to reflect that a non-URL value is treated as invalid.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…source.

The hook returns hasInvalidResource and the rest of the codebase uses
"resource" terminology, so align the hook name for consistency. Also
rebuild the stylesheet to pick up the previously unbundled overlay
change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When the site authority overlaps with an entry in ALLOWED_RESOURCES
(e.g., wordpress.org), the rendered list produced duplicate React keys,
triggering warnings and unstable rendering. Wrap the list in a Set to
ensure each domain appears once.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 26, 2026 13:23
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new wp-admin/editor-only plugin (wporg-media-resource-checker) that highlights Gutenberg blocks (image/video/cover) using media URLs from non-recommended external domains, helping documentation contributors avoid fragile external media links.

Changes:

  • Enqueues editor JS/CSS that detects and visually marks blocks with “invalid” media resource URLs.
  • Implements URL/domain validation logic with an allowlist (wordpress.org, w.org, limited wp.com proxy paths).
  • Adds build artifacts and package metadata for @wordpress/scripts-based builds.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/wporg-media-resource-checker.php Registers/enqueues editor script and admin-only stylesheet for the checker UI.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/index.js Adds editor UI (toolbar warning dropdown) and wrapper class injection via HOCs/filters.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/hooks.js Provides useHasInvalidResource hook to derive site URL + per-block invalid state.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/utils.js Encapsulates allowed-domain list and URL validation helpers.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/style.scss Defines editor warning styles (overlay/border, toolbar icon, popover layout).
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/package.json Adds build tooling/scripts and JS dependencies.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/index.js Compiled editor script bundle.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/index.asset.php Build-generated WP script dependency/version metadata.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/style-index.css Compiled stylesheet for the warning UI.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/style-index-rtl.css Compiled RTL stylesheet variant for the warning UI.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/.gitignore Ignores node_modules and npm lockfile for local development.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

t-hamano and others added 4 commits April 26, 2026 22:28
The stylesheet was enqueued via enqueue_block_assets and only gated by
is_admin(), so it loaded on every wp-admin screen even though the CSS
only styles editor-specific overlays. Move the wp_enqueue_style call
into the existing enqueue_block_editor_assets callback so the asset
loads only where the UI is rendered.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The idKey field was defined for each block entry but never read
anywhere, so remove it to keep the configuration minimal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Without the !! prefix, hasInvalidResource could leak the empty-string
or undefined value of mediaUrl into the consumer, which then has to
guard against truthy non-boolean values. Force a boolean so callers
can rely on the type.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…urn null.

When the matching attribute is missing, the function previously
returned undefined, breaking the documented string|null contract and
forcing callers to guard against a third return type. Use optional
chaining with a nullish coalesce so the result always conforms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 26, 2026 13:36
The plugin builds a style-index-rtl.css alongside the LTR variant, but
the enqueued style was not flagged for RTL replacement, so RTL sites
kept loading the LTR CSS and rendered the overlay with mirrored
left/right positioning. Mark the style with wp_style_add_data so
WordPress swaps in the -rtl variant automatically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new wp-admin/block-editor plugin (wporg-media-resource-checker) to flag Gutenberg blocks that reference media hosted on non-recommended external domains, helping documentation contributors avoid linking to potentially transient assets.

Changes:

  • Introduces a block-editor-only warning UI (block border/overlay + toolbar button + popover) for core/image, core/video, and core/cover when an external media URL is not from an allowed domain.
  • Implements URL/domain validation utilities and a React hook to determine invalid media resources in-editor.
  • Adds built JS/CSS assets (and build tooling via package.json) for deployment.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/wporg-media-resource-checker.php Registers/enqueues the plugin’s block editor scripts/styles and translations.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/index.js Adds editor UI (toolbar button + popover) and block wrapper styling via HOCs/filters.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/hooks.js Determines site URL + block media URL and computes invalid state.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/utils.js Defines block targets, allowed domains, and URL validation logic.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/style.scss Defines invalid-resource overlay styling and popover content styles.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/package.json Adds build scripts and JS dependencies for asset compilation.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/index.js Compiled editor JS bundle.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/index.asset.php Asset metadata for dependencies/versioning.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/style-index.css Compiled stylesheet (LTR).
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/style-index-rtl.css Compiled stylesheet (RTL).
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/.gitignore Ignores node_modules and npm lockfile for the plugin.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

t-hamano and others added 3 commits April 26, 2026 22:43
These files are emitted by @wordpress/scripts on every build, so the
filename and array formatting are dictated by webpack and cannot be
adjusted to satisfy WordPress coding standards. Excluding them keeps
PHPCS focused on hand-written code.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ed resources.

The popover advertised wp.com as an allowed domain even though it is
only accepted under /wordpress.org/, so users could pick any *.wp.com
URL and still hit the warning. Add a pathLabel field for entries with
a pathRegex and append it when rendering the list, so the displayed
guidance matches what isInvalidResource actually accepts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
require is a language construct, not a function, so PHPCS flags the
parenthesised form. Use the bare statement form to satisfy
PEAR.Files.IncludingFile.BracketsNotRequired.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 26, 2026 13:51
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new WordPress.org plugin that flags Gutenberg blocks using “inappropriate” external media URLs in the block editor, encouraging contributors to upload media to recommended domains.

Changes:

  • Introduces the wporg-media-resource-checker plugin with editor asset enqueueing and built JS/CSS.
  • Implements URL/domain validation logic for select core blocks and editor UI warnings (border/overlay + toolbar dropdown).
  • Updates PHPCS config to ignore generated build/index.asset.php files.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/wporg-media-resource-checker.php Registers/enqueues block editor script + styles and translations.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/utils.js Defines block/media URL extraction and allowed-domain validation logic.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/hooks.js Adds selector hook to fetch site URL and compute invalid-resource state.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/index.js Adds editor HOCs to decorate invalid blocks and show toolbar popover details.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/src/style.scss Styles invalid-resource overlay, toolbar icon color, and popover content.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/package.json Adds build tooling/scripts and dependency declarations for the plugin.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/index.js Built editor script bundle.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/index.asset.php Generated dependency/version manifest for the built script.
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/style-index.css Built editor styles (LTR).
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/build/style-index-rtl.css Built editor styles (RTL).
wordpress.org/public_html/wp-content/plugins/wporg-media-resource-checker/.gitignore Ignores plugin-local node_modules and npm lockfile.
phpcs.xml.dist Excludes generated build/index.asset.php from PHPCS scans.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread phpcs.xml.dist
t-hamano and others added 2 commits April 26, 2026 22:59
The plugin header advertised 1.0 while package.json carried 1.0.0,
which is confusing when correlating builds with releases. Sibling
wporg plugins (e.g., wporg-learn) use 1.0.0 in both places, so align
on that format.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…block_assets.

The earlier PHPCS fix only updated the editor-assets callback; the
parenthesised require survived in enqueue_block_assets after the
revert that restored that function. Strip the parentheses here as
well so the file passes PEAR.Files.IncludingFile.BracketsNotRequired.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants