mirror of
https://github.com/Heretek-AI/heretek-control-core.git
synced 2026-10-12 02:03:55 +00:00
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/`.