assets
3 weeks ago
abilities.php
3 weeks ago
manager.php
3 weeks ago
rest-proxy.php
3 weeks ago
server.php
3 weeks ago
service.php
3 weeks ago
manager.php
112 lines
| 1 | <?php |
| 2 | namespace ElementsKit_Lite\Mcp; |
| 3 | |
| 4 | use ElementsKit_Lite\Traits\Singleton; |
| 5 | |
| 6 | defined( 'ABSPATH' ) || exit; |
| 7 | |
| 8 | /** |
| 9 | * Entry point for ElementsKit's MCP support. |
| 10 | * |
| 11 | * Wires together the layers described in the architecture: |
| 12 | * - shared PHP service ({@see Service}), |
| 13 | * - the public backend contract: WP Abilities ({@see Abilities}) and the |
| 14 | * optional MCP server ({@see Server}), |
| 15 | * - the editor convenience layer: the REST proxy ({@see Rest_Proxy}) and the |
| 16 | * Angie integration JS. |
| 17 | * |
| 18 | * The Angie integration is a browser bundle built with @elementor/angie-sdk that |
| 19 | * registers an ElementsKit MCP server with Angie over postMessage. Angie loads |
| 20 | * globally in wp-admin, so this is enqueued globally (not only in the Elementor |
| 21 | * editor) and gated on the Angie plugin being active — the same mechanism the |
| 22 | * Amelia plugin uses. Each tool forwards to the REST proxy. |
| 23 | * |
| 24 | * Instantiated directly from the plugin bootstrap; not a toggleable module. |
| 25 | * |
| 26 | * @since 3.10.x |
| 27 | */ |
| 28 | class Manager { |
| 29 | |
| 30 | use Singleton; |
| 31 | |
| 32 | const ANGIE_HANDLE = 'elementskit-angie-mcp'; |
| 33 | const ANGIE_PLUGIN = 'angie/angie.php'; |
| 34 | |
| 35 | public function __construct() { |
| 36 | ( new Abilities() )->hooks(); |
| 37 | ( new Server() )->hooks(); |
| 38 | ( new Rest_Proxy() )->hooks(); |
| 39 | |
| 40 | add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_angie_integration' ] ); |
| 41 | } |
| 42 | |
| 43 | /** |
| 44 | * Register the ElementsKit MCP server with Angie, wherever Angie is available |
| 45 | * in wp-admin (dashboard and the Elementor editor alike). |
| 46 | */ |
| 47 | public function enqueue_angie_integration() { |
| 48 | if ( ! $this->angie_active() ) { |
| 49 | return; |
| 50 | } |
| 51 | |
| 52 | // The Script Modules API (wp_enqueue_script_module) landed in WordPress 6.5. |
| 53 | if ( ! function_exists( 'wp_enqueue_script_module' ) ) { |
| 54 | return; |
| 55 | } |
| 56 | |
| 57 | $path = \ElementsKit_Lite::plugin_dir() . 'mcp/assets/elementskit-angie.js'; |
| 58 | |
| 59 | if ( ! file_exists( $path ) ) { |
| 60 | return; |
| 61 | } |
| 62 | |
| 63 | // Script modules cannot receive wp_localize_script, so hand the bundle its |
| 64 | // REST endpoint + nonce through a global printed before the module runs. |
| 65 | add_action( 'admin_print_scripts', [ $this, 'print_angie_config' ] ); |
| 66 | |
| 67 | // Version by file mtime so every rebuild busts the browser's module cache. |
| 68 | $version = \ElementsKit_Lite::version() . '.' . (string) filemtime( $path ); |
| 69 | |
| 70 | wp_enqueue_script_module( |
| 71 | self::ANGIE_HANDLE, |
| 72 | \ElementsKit_Lite::plugin_url() . 'mcp/assets/elementskit-angie.js', |
| 73 | [], |
| 74 | $version |
| 75 | ); |
| 76 | } |
| 77 | |
| 78 | /** |
| 79 | * Print the config the Angie bundle reads (window.ElementsKitMcpConfig). |
| 80 | */ |
| 81 | public function print_angie_config() { |
| 82 | static $printed = false; |
| 83 | |
| 84 | if ( $printed ) { |
| 85 | return; |
| 86 | } |
| 87 | $printed = true; |
| 88 | |
| 89 | $config = [ |
| 90 | 'restUrl' => esc_url_raw( get_rest_url( null, Rest_Proxy::NAMESPACE . Rest_Proxy::ROUTE ) ), |
| 91 | 'nonce' => wp_create_nonce( 'wp_rest' ), |
| 92 | 'adminUrl' => esc_url_raw( admin_url() ), |
| 93 | ]; |
| 94 | |
| 95 | printf( |
| 96 | "<script>window.ElementsKitMcpConfig = %s;</script>\n", |
| 97 | wp_json_encode( $config ) |
| 98 | ); |
| 99 | } |
| 100 | |
| 101 | /** |
| 102 | * @return bool Whether the Angie plugin is active. |
| 103 | */ |
| 104 | private function angie_active() { |
| 105 | if ( ! function_exists( 'is_plugin_active' ) ) { |
| 106 | require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 107 | } |
| 108 | |
| 109 | return function_exists( 'is_plugin_active' ) && is_plugin_active( self::ANGIE_PLUGIN ); |
| 110 | } |
| 111 | } |
| 112 |