Skip to content

Avoid re-running full plugin init during activation#1193

Draft
utkarshcloudinary wants to merge 1 commit into
developfrom
fix/activation-avoid-early-full-init
Draft

Avoid re-running full plugin init during activation#1193
utkarshcloudinary wants to merge 1 commit into
developfrom
fix/activation-avoid-early-full-init

Conversation

@utkarshcloudinary

Copy link
Copy Markdown
Collaborator

Summary

Utils::install() — registered as both the activation hook and the cloudinary_version_upgrade handler — unconditionally called get_plugin_instance()->init(). On the version-upgrade path this re-ran the plugin metadata bootstrap out of sequence (after Plugin::init() had already run on the init hook), which can destabilise plugin load order for the request — e.g. triggering other plugins such as ACF to initialise too early.

This was observed on an enterprise customer site (WP 7.0 / PHP 8.2, ACF Pro 6.8.3): for ~5 minutes after activating Cloudinary 3.3.3, frontend requests fataled with Call to undefined function have_rows() in their ACF-dependent theme, alongside a flood of _load_textdomain_just_in_time notices for the acf domain. The fatals correlate exclusively with the post-activation window across two weeks of logs.

Change

Only call ->init() when $plugin->version is not yet populated:

  • Fresh activation (wp-admin / WP-CLI): the plugin file is included during activation, after the init hook has fired, so version is empty → fallback ->init() runs as before. No behaviour change.
  • cloudinary_version_upgrade (init prio 100): Plugin::init() (init prio 10) has already populated version → the redundant re-bootstrap is skipped. This is the destabilising path.

Everything downstream of install() (get_table_sql, table_installed, dbDelta branch, upgrade_install and the upgrade_3_x methods) depends only on $plugin->version, which the guard guarantees.

Notes

  • The customer's root defect is theme-side (unguarded have_rows() calls); this change removes the plugin's contribution to out-of-sequence bootstrapping — defensive hardening that benefits any site with load-order-sensitive plugins.
  • Not yet reproduced end-to-end on staging; marking as draft until validated.

Testing

  • Fresh activation via wp-admin creates the relationship table (empty-version fallback path)
  • Fresh activation via WP-CLI
  • Version upgrade path (cloudinary_version_upgrade) runs upgrade sequence without re-running init()
  • Staging reproduction with ACF Pro + ACF-dependent theme: no early-ACF notices / fatals after activation

install() called get_plugin_instance()->init() unconditionally, which
re-ran the bootstrap out of sequence during plugin activation and could
destabilise plugin load order for the request (e.g. triggering ACF to
initialise too early). Only run init() when the plugin version has not
already been populated; the DB routines only need the version.
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.

2 participants