Files
John Smith 460afbadce fix(admin): stop the plugin deactivating itself, and 403ing on activation
Two fork-specific defects made "Activate" a dead end, ending at core's
"Sorry, you are not allowed to access this page." (403).

1. Self-deactivation. `.emcp-pro` is committed, so the build counts as
   premium, and the premium guard retired `$emcp_tools_free_basename` --
   which on the documented layout (wp-content/plugins/heretek-control-core)
   IS this plugin. The first admin_init after activation deactivated the
   site's only working copy. emcp_tools_retire_sibling() now refuses its own
   basename, and sibling candidates inside our own folder are filtered out
   (the same file loaded twice is deduplicated by require_once, so retiring
   it can only ever switch the plugin off). Legacy folders -- emcp-tools/,
   elementor-mcp/ -- are still retired whichever build runs.

2. Freemius owned the activation flow. Its post-activation redirect
   (class-freemius.php:24546) is the only code in the plugin that builds
   admin.php?page=emcp-tools, a URL that exists only if the bootstrap
   finished; its _prepare_admin_menu also replaced our dashboard with the
   opt-in/connect screen on a site that has never been connected. The fork
   hard-codes every licensing answer to "unlocked", so both are dropped:
   `redirect_on_activation` is filtered off and the _prepare_admin_menu hook
   is removed.

When neither the real menu nor anything else owned the `emcp-tools` slug,
WordPress core ended the request from wp-admin/includes/menu.php -- which
runs during admin_menu, BEFORE admin_init -- with that 403 and no
explanation.

New EMCP_Tools_Admin_Fallback (includes/admin/class-admin-fallback.php)
makes the slug always resolve. At the end of admin_menu it registers a
diagnostics page when nothing else claimed the slug (a no-op on a healthy
install), and admin_page_access_denied bounces emcp-tools-* sub-screens
there instead of letting core kill the request. The page reports boot
state, MCP adapter resolution, PHP/WordPress versions, other active copies
of the plugin, and a file-integrity check that flags 0-byte files -- the
issue #100 signature of a host malware scanner emptying a file in place so
require_once succeeds while nothing is declared.

Also: the release workflow still packaged the zip under `elementor-mcp/`,
the legacy folder name this plugin's own conflict guards look for. Release
assets are now built under `heretek-control-core/`.
2026-09-12 16:51:55 -04:00
..