Skip to content

fix: distinguish Author URI from Plugin URI - #36

Merged
erseco merged 1 commit into
mainfrom
fix/distinct-author-uri
May 28, 2026
Merged

fix: distinguish Author URI from Plugin URI#36
erseco merged 1 commit into
mainfrom
fix/distinct-author-uri

Conversation

@erseco

@erseco erseco commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Plugin Check reports that Plugin URI and Author URI must not be identical. Point Author URI to https://exelearning.net/ while keeping Plugin URI on the GitHub repo.

Partially addresses exelearning/exelearning#1542 (one of the Plugin Check findings).

Test plan

  • Re-run Plugin Check; the duplicate-URI error is gone.

@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Test in WordPress Playground

Test the plugin with the code from this branch:

Preview in WordPress Playground

⚠️ The embedded eXeLearning editor is not included in this preview. You can install it from Settings > eXeLearning using the "Download & Install Editor" button. All other plugin features (ELP upload, shortcode, Gutenberg block, preview) work normally.

Plugin Check flagged identical Plugin URI and Author URI headers.
Point Author URI to https://exelearning.net/ while keeping Plugin URI
on the GitHub repo, and update translation catalogs so the new
msgid passes check-untranslated.

Partially addresses exelearning/exelearning#1542.
@erseco
erseco force-pushed the fix/distinct-author-uri branch from 2382ee9 to 2e9aa0b Compare May 28, 2026 15:27
@erseco erseco self-assigned this May 28, 2026
@erseco
erseco merged commit dbecd2f into main May 28, 2026
4 checks passed
@erseco
erseco deleted the fix/distinct-author-uri branch May 28, 2026 15:29
erseco added a commit that referenced this pull request Aug 4, 2026
…iew (#89)

* Stop the translation validator from reading directories

Every run printed one "file_get_contents(): Read of N bytes failed with
errno=21 Is a directory" notice per empty-of-JavaScript directory, in CI
logs as well as locally.

The filter callback returns true for a directory to mean "recurse into
it", but RecursiveIteratorIterator defaults to LEAVES_ONLY, and a
directory whose children the filter all rejected has no leaves -- so the
directory itself is yielded as one. Skip directories in the loop.

No behaviour change: those entries produced false from file_get_contents
and were already skipped by the check below, just noisily.

* Split the style upload validation out of handle_upload()

PHPMD flagged handle_upload() at an NPath complexity of 1152 against a
threshold of 500 (code scanning alert #36). The method is a flat chain of
guards, but each one calls redirect_with_notice() rather than returning,
and static analysis cannot know that ends the request -- so every guard
counts as a branch that might fall through and the paths multiply.

The four checks on the posted file move into accept_uploaded_archive(),
which returns the validated paths or ends the request. handle_upload() is
left with the capability check, the nonce, the install and the notice.

$_FILES is still read in handle_upload() and passed in, rather than read
in the callee. WordPress.Security.NonceVerification works per function
scope, so reading the superglobal in a method that does not itself call
check_admin_referer() trips the sniff -- and the honest fix is to keep the
nonce check and the read together, not to suppress the warning.

No behaviour change: the same checks run in the same order with the same
messages. PHPMD reports no violation for the file now, PHPCS is clean,
and the nine existing ExeLearning_Admin_Styles tests pass unchanged.

* Move the block to Block API version 3

exelearning/elp-upload declared no apiVersion, so it registered as
version 1, which WordPress 6.9 deprecates. That was not a local problem:
a single API-version-1 block forces the whole post editor onto the
non-iframe path, so the plugin was holding every editor it was installed
in back from a change WordPress is completing.

Three things stood in the way, and only the first is the one-line part.

The version is now declared in both places -- apiVersion in the JS,
api_version in register_block_type() -- with a test asserting they agree,
since they sit far apart and disagreeing is silent. The visible output of
both edit() branches is wrapped in one element carrying useBlockProps(),
with the hook called before the early return; InspectorControls and
BlockControls stay outside it, being Slot/Fill that render into the
editor's own chrome.

The stylesheets move onto the block type. Enqueued from
enqueue_block_editor_assets they land in the outer admin document, which
is not where an API version 3 block renders; declared as the block's
style/editor_style, WordPress injects them into the canvas iframe.
exelearning-frontend is still enqueued globally for the shortcode and
deduplicates by handle.

The fullscreen button is now wired by the component. elp-upload-fullscreen.js
attached a click listener and a MutationObserver to the admin document and
matched buttons to previews by DOM proximity -- none of which can see a
block that lives in another document. The edit component already held a
ref to the preview iframe, so the button gets a real onClick and a
disabled state for a file with no preview. The script, its enqueue and its
two test files are deleted: it existed only for the editor, and there is
no version of it that can watch a document it is not in. The frontend
button is unaffected; it is wired by inline JS emitted from PHP.

The E2E test is what proves this. It failed first at
`[data-type="exelearning/elp-upload"] .exelearning-block-preview iframe`
resolving to 0 elements in the main document, which is exactly the
migration working. It now looks inside iframe[name="editor-canvas"],
toggles the real inspector control in the outer sidebar, and asserts the
button appears in the canvas and takes the preview fullscreen. Its
fullscreen stub moved from the element to the prototype: pinned to one
node it vanished whenever the editor re-rendered, which made the
assertion flaky in a full-suite run while passing in isolation.

Designed in SDD-0005.

* Pull dashicons into the canvas iframe with the block styles

The download and fullscreen buttons rendered as blank boxes in the editor
while looking correct on the published page.

Moving the block to API version 3 in the previous commit moved its
rendering into the editor canvas iframe, which receives the block's
declared styles and their dependencies and nothing else. wp-admin loads
dashicons into the outer document, which used to be where the block was;
it is not any more. The frontend was unaffected because dashicons is
enqueued there separately.

Declaring dashicons as a dependency of exelearning-frontend is enough:
WordPress then carries the font wherever that sheet goes, canvas
included.

The failure mode here is quiet -- no error, no missing file, just icons
that do not draw -- so the E2E asserts the computed font-family of an
icon inside the canvas rather than that a stylesheet link exists.
Confirmed to fail without the dependency: the font falls back to the
system sans-serif, which is exactly the blank box.

* Refresh the translation references after the dashicons dependency

The comment explaining why dashicons is a dependency shifted the line
numbers that the POT and PO files record as source references. Only the
`#:` comments change -- 55 lines in, 55 out, no msgid or msgstr touched.
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.

1 participant