fix: Elementor idempotent-lifecycle mu-plugin (redeclaration fatal)#4
Merged
Merged
Conversation
Elementor's `Plugin::init()` handler (registered on `init` priority 0)
`include`s its element class files via `Elements_Manager::init_elements()`.
Under FPM, `init` fires once per process — correct. Under this adapter's
per-request `init` re-fire, the second request re-runs the include and
crashes the worker:
PHP Fatal error: Cannot redeclare class Elementor\Element_Column
.../wp-content/plugins/elementor/includes/elements/column.php:19
Elementor's Plugin singleton and element registry are already fully
populated at boot time; the per-request replay of Elementor's `init`
handler adds no functional value and only re-triggers the include.
Add `muplugins/elementor-idempotent-lifecycle.php` mirroring the shape
of the existing WooCommerce mu-plugin: on the first `wp_loaded` fire
(boot-time, at PHP_INT_MAX so it runs after all other boot-time init),
snapshot Elementor's `[Plugin::instance(), 'init']` binding and
`remove_action('init', ..., 0)` it. Subsequent request-loop `init`
re-fires skip Elementor's initializer. All other Elementor hooks
(REST, admin, editor, widget-render) stay intact.
Discovered by the tinfoyle/ePHPm-lab wordpress-v5 retest after this
adapter bumped to v0.1.1 (the WooCommerce cart lifecycle fix
introduced the per-request `init`/`wp_loaded` replay that surfaces
this Elementor compatibility gap). See:
https://github.com/tinfoyle/ePHPm-lab/blob/main/docs/wordpress-v5.md
and
https://github.com/tinfoyle/ePHPm-lab/blob/main/docs/wordpress-worker-investigation.md
§ "v5 Retest Against v0.1.1".
Ship together with a conservative `worker_max_requests` and instrument
for regressions until validated end-to-end in the lab.
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
muplugins/elementor-idempotent-lifecycle.phpto fix the ElementorCannot redeclare class Elementor\Element_Columnfatal that hits every request from N >= 2 under this adapter's per-requestinitre-fire. Reproduced locally against Elementor 4.1.4; fix verified.Root cause (source-verified)
Elementor's
Plugin::init()(registered oninitpriority 0 atplugin.php:833) calls$this->init_components(), which instantiatesnew Elements_Manager().Elements_Manager::__construct()atelements.php:58calls the privaterequire_files(), which atelements.php:461-463does:Under FPM,
initfires once per process ->require_files()runs once -> correct. Under this adapter's per-requestinitre-fire, request N >= 2 ->new Elements_Manager()again ->require(notrequire_once) -> redeclaration fatal.Fix
Mu-plugin at
wp_loadedPHP_INT_MAXthat on the first fire (boot-time) doesremove_action('init', [\Elementor\Plugin::instance(), 'init'], 0)— strips exactly the callback that triggers the redeclaring chain. All other Elementor hooks (REST, admin, editor, widget-render) stay intact. Static flag ensures the callback only fires once even thoughwp_loadedre-fires per request.Reproduction (local, this branch)
wordpress:cli-2.10.0-php8.2ephpm/wordpress-worker:dev-fix/elementor-idempotent-lifecycle(this branch)docker.io/ephpm/ephpm:v0.4.2-php8.4mode = "worker",worker_count = 1,worker_populate_superglobals = trueWithout the mu-plugin (removed from
wp-content/mu-plugins/):Each request kills a worker; ePHPm recycles and retries, so the client still gets 200 but the pool is churning.
With the mu-plugin (
muplugins/elementor-idempotent-lifecycle.phpinwp-content/mu-plugins/):Same 5 requests, single worker, zero crashes.
Docs
Not addressed by this PR (scope)
worker_max_requestsand instrument for regressions.e2e/suite. Not blocking this PR — validated against a real Elementor install as described above.Related