PluginProbe
ZIP AI – AI Website Builder & AI Agent (Beta) / 0.0.5
ZIP AI – AI Website Builder & AI Agent (Beta) v0.0.5
0.0.10 0.0.9 trunk 0.0.4 0.0.5 0.0.6 0.0.7 0.0.8
zip-ai / loader.php

loader.php in ZIP AI – AI Website Builder & AI Agent (Beta) 0.0.5, at loader.php

347 lines 10.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Class.
4 *
5 * @package zip-ai
6 * @since 1.0.0
7 */
8
9 namespace ZipAI\MCP;
10
11 // Exit if accessed directly.
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 use ZipAI\MCP\Classes\Core\Container;
17 use ZipAI\MCP\Classes\Providers\Core_Service_Provider;
18 use ZipAI\MCP\Classes\Providers\Abilities_Service_Provider;
19 use ZipAI\MCP\Classes\Cli\CLI_Commands;
20 use ZipAI\MCP\Classes\Core\Helper;
21
22 if ( ! class_exists( '\ZipAI\MCP\Plugin' ) ) {
23 /**
24 * Plugin Class
25 *
26 * @since 1.0.0
27 */
28 class Plugin {
29
30 /**
31 * Instance
32 *
33 * @access private
34 * @var object Class Instance.
35 * @since 1.0.0
36 */
37 private static $instance;
38
39 /**
40 * The dependency injection container.
41 *
42 * @var Container
43 */
44 protected $container;
45
46 /**
47 * Service Providers.
48 *
49 * @var array
50 */
51 protected $providers = array();
52
53 /**
54 * Initiator
55 *
56 * @since 1.0.0
57 * @return object initialized object of class.
58 */
59 public static function get_instance() {
60 if ( ! isset( self::$instance ) ) {
61 self::$instance = new self();
62 }
63 return self::$instance;
64 }
65
66 /**
67 * Constructor
68 *
69 * @since 1.0.0
70 */
71 public function __construct() {
72 $this->container = new Container();
73
74 $this->define_constants();
75
76 // Register Services.
77 $this->register_services();
78
79 // Boot Services.
80 add_action( 'plugins_loaded', array( $this, 'boot_services' ), 5 );
81
82 $this->setup_activation_hooks();
83 $this->register_cli_commands();
84
85 // Site scanner — event-driven memory enrichment (after auth).
86 // \ZipAI\MCP\Classes\Core\Site_Scanner::register_hooks(); // TODO: class not yet committed.
87
88 // Code snippet executor — runs AI-created snippets (PHP/JS/CSS/HTML).
89 // This is the ONLY persistent hook needed — it auto-loads all snippets
90 // created by any tool (cookie consent, tracking codes, custom CSS, etc.)
91 \ZipAI\MCP\Classes\Core\Snippet_Executor::init();
92
93 // Plugin abilities toggler — listens for `activated_plugin` and
94 // enables MCP abilities for mapped slugs regardless of activation
95 // path (server-side ability, browser-proxied REST, admin UI,
96 // WP-CLI). Idempotent + slug-map gated.
97 \ZipAI\MCP\Classes\Core\Plugin_Abilities_Toggler::init();
98
99 // Privacy policy disclosure (WordPress Guideline 7).
100 add_action( 'admin_init', array( $this, 'add_privacy_policy_content' ) );
101 }
102
103 /**
104 * Register Service Providers.
105 */
106 private function register_services() {
107 $this->providers[] = new Core_Service_Provider( $this->container );
108 $this->providers[] = new Abilities_Service_Provider( $this->container );
109
110 foreach ( $this->providers as $provider ) {
111 $provider->register();
112 }
113 }
114
115 /**
116 * Boot Service Providers.
117 */
118 public function boot_services() {
119 $this->load_vendor_dependencies();
120
121 foreach ( $this->providers as $provider ) {
122 $provider->boot();
123 }
124 }
125
126 /**
127 * Define the required constants.
128 *
129 * @since 1.0.0
130 * @return void
131 */
132 public function define_constants() {
133 define( 'ZIPAI_MCP_FILE', __DIR__ . '/zip-ai.php' );
134 define( 'ZIPAI_MCP_DIR', plugin_dir_path( ZIPAI_MCP_FILE ) );
135 define( 'ZIPAI_MCP_URL', plugins_url( '/', ZIPAI_MCP_FILE ) );
136 define( 'ZIPAI_MCP_VERSION', '0.0.5');
137 define( 'ZIPAI_MCP_MENU_SLUG', 'zip-ai' );
138
139 // Base URL for ZIP AI credit server (Laravel app).
140 if ( ! defined( 'ZIPAI_MCP_BASE_URL' ) ) {
141 define( 'ZIPAI_MCP_BASE_URL', 'https://credits.startertemplates.com' );
142 }
143
144 if ( ! defined( 'ZIPAI_MCP_MIDDLEWARE' ) ) {
145 define( 'ZIPAI_MCP_MIDDLEWARE', 'https://app.zipwp.com/auth/' );
146 }
147
148 if ( ! defined( 'ZIPAI_API_BASE' ) ) {
149 define( 'ZIPAI_API_BASE', 'https://api.zipwp.com/api/' );
150 }
151
152 // Brain base URL for direct-to-brain calls (e.g. inline-edit),
153 // bypassing the Laravel relay. Override via wp-config.php or the
154 // `zipai_brain_url` filter.
155 if ( ! defined( 'ZIPAI_BRAIN_URL' ) ) {
156 define( 'ZIPAI_BRAIN_URL', 'https://brain.startertemplates.com' );
157 }
158
159 // API endpoint for credit server.
160 if ( ! defined( 'ZIPAI_MCP_CREDIT_SERVER_API' ) ) {
161 define( 'ZIPAI_MCP_CREDIT_SERVER_API', ZIPAI_MCP_BASE_URL . '/api/' );
162 }
163
164 }
165
166 /**
167 * Load vendor dependencies (mcp-adapter).
168 *
169 * @since 1.0.0
170 * @return void
171 */
172 private function load_vendor_dependencies() {
173 // Initialize mcp-adapter plugin if not already loaded. The library
174 // self-bootstraps (defines its own constants, runs its autoloader and
175 // calls \WP\MCP\Plugin::instance()) on require. Since it's bundled as a
176 // Composer dependency, its classes are already registered via our root
177 // vendor/autoload.php and it has no nested vendor/ of its own — so we
178 // tell it to skip its self-autoload, else it prints a false "Composer
179 // autoloader was not found" admin notice and bails before Plugin::instance().
180 if ( ! defined( 'WP_MCP_AUTOLOAD' ) ) {
181 define( 'WP_MCP_AUTOLOAD', false );
182 }
183 if ( ! defined( 'WP_MCP_VERSION' ) && file_exists( ZIPAI_MCP_DIR . 'vendor/wordpress/mcp-adapter/mcp-adapter.php' ) ) {
184 require_once ZIPAI_MCP_DIR . 'vendor/wordpress/mcp-adapter/mcp-adapter.php';
185 }
186 }
187
188 /**
189 * Setup plugin activation and deactivation hooks.
190 *
191 * @since 1.0.0
192 * @return void
193 */
194 public function setup_activation_hooks() {
195 register_activation_hook( ZIPAI_MCP_FILE, array( $this, 'plugin_activated' ) );
196 register_deactivation_hook( ZIPAI_MCP_FILE, array( $this, 'plugin_deactivated' ) );
197 }
198
199 /**
200 * Plugin activation callback.
201 *
202 * @since 1.0.0
203 * @return void
204 */
205 public function plugin_activated() {
206 // Add the required capability to administrator role.
207 $this->add_plugin_capabilities();
208
209 // Generate and register shared secret with Laravel on activation.
210 $this->register_hmac_secret();
211 }
212
213 /**
214 * Plugin deactivation callback.
215 *
216 * @since 1.0.0
217 * @return void
218 */
219 public function plugin_deactivated() {
220 // Remove the plugin capabilities from all roles.
221 $this->remove_plugin_capabilities();
222
223 // Clear scheduled site scan.
224 \ZipAI\MCP\Classes\Core\Site_Scanner::unschedule();
225 }
226
227 /**
228 * Suggest privacy policy content per WordPress Guideline 7.
229 *
230 * Discloses what data is sent to the ZIP AI SaaS platform.
231 *
232 * @since 1.0.0
233 * @return void
234 */
235 public function add_privacy_policy_content() {
236 $policy_text = '<h2>ZIP AI Assistant</h2>
237 <p>This site uses the ZIP AI Assistant plugin ("ZIP AI"), which connects to a cloud-based AI service operated by Starter Templates (Starter Templates, a Brainstorm Force product).</p>
238
239 <h3>What data is collected</h3>
240 <p>When authenticated and actively using ZIP AI, the following data may be sent to our servers:</p>
241 <ul>
242 <li><strong>Chat messages</strong> — Messages you send to the AI assistant and the assistant\'s responses.</li>
243 <li><strong>Site structure data</strong> — Page titles, post counts, active plugin names, active theme name, and content categories. This helps ZIP AI understand your site and provide relevant suggestions.</li>
244 <li><strong>Site identity</strong> — Site title, tagline, language, and domain name.</li>
245 <li><strong>E-commerce data</strong> (if applicable) — Product counts, product categories, currency, and whether reviews are enabled. No individual product details, prices, or customer data is sent.</li>
246 </ul>
247
248 <h3>What data is NOT collected</h3>
249 <ul>
250 <li>Page or post content/body text</li>
251 <li>Customer or visitor personal information</li>
252 <li>Passwords, payment details, or financial data</li>
253 <li>Email addresses of site visitors</li>
254 <li>Analytics or traffic data</li>
255 </ul>
256
257 <h3>How data is used</h3>
258 <p>Data is used solely to power the AI assistant\'s responses and to build a memory of your site preferences so you don\'t have to repeat yourself across conversations. You can clear all stored memory at any time via the "Clear Site Memory" option in the ZIP AI menu.</p>
259
260 <h3>Data retention</h3>
261 <p>Chat messages and memory data are stored on our servers for as long as your account is active. You can request deletion at any time by clearing your site memory or contacting support.</p>
262
263 <h3>Third-party services</h3>
264 <p>ZIP AI uses AI language models (such as Google Gemini and Anthropic Claude) to process your messages. Your messages may be sent to these providers for processing. Please refer to their respective privacy policies:</p>
265 <ul>
266 <li><a href="https://policies.google.com/privacy">Google Privacy Policy</a></li>
267 <li><a href="https://www.anthropic.com/privacy">Anthropic Privacy Policy</a></li>
268 </ul>
269
270 <p>For more information, please see our <a href="https://developer.brainstormforce.com/privacy-policy/">Privacy Policy</a>.</p>';
271
272 wp_add_privacy_policy_content( 'ZIP AI Assistant', $policy_text );
273 }
274
275 /**
276 * Add required capabilities to administrator role.
277 *
278 * @since 1.0.0
279 * @return void
280 */
281 private function add_plugin_capabilities() {
282 // Get the administrator role.
283 $admin_role = get_role( 'administrator' );
284
285 if ( $admin_role ) {
286 // Add the required capability for ZipWP MCP management.
287 $admin_role->add_cap( 'manage_zip_mcp_assistant', true );
288 }
289 }
290
291 /**
292 * Remove plugin capabilities from all roles.
293 *
294 * @since 1.0.0
295 * @return void
296 */
297 private function remove_plugin_capabilities() {
298 // Get all roles.
299 $roles = wp_roles();
300
301 // Remove the capability from all roles that have it.
302 foreach ( $roles->role_objects as $role ) {
303 if ( $role->has_cap( 'manage_zip_mcp_assistant' ) ) {
304 $role->remove_cap( 'manage_zip_mcp_assistant' );
305 }
306 }
307 }
308
309 /**
310 * Register HMAC shared secret with Laravel server.
311 *
312 * @since 1.0.0
313 * @return void
314 */
315 private function register_hmac_secret() {
316 // Only register if not already registered.
317 if ( ! Helper::is_hmac_registered() ) {
318 $registration_result = Helper::register_shared_secret_with_laravel();
319
320 if ( isset( $registration_result['error'] ) ) {
321 // Note: Error logging removed for production.
322 unset( $registration_result );
323 }
324 }
325 }
326
327 /**
328 * Register WP-CLI commands.
329 *
330 * @since 1.0.0
331 * @return void
332 */
333 private function register_cli_commands() {
334 if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
335 return;
336 }
337
338 \WP_CLI::add_command( 'zip-ai', CLI_Commands::class );
339 }
340 }
341
342 /**
343 * Kicking this off by calling 'get_instance()' method
344 */
345 Plugin::get_instance();
346 }
347