Plugin - Source Excerpt 01
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/spiralist-workspace/includes/Plugin.php so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/includes/Plugin.php
<?php
namespace SpiralistWorkspace;
use SpiralistWorkspace\Admin\ManagedPromptAdmin;
use SpiralistWorkspace\Auth\Permissions;
use SpiralistWorkspace\Auth\Roles;
use SpiralistWorkspace\Config\Settings;
use SpiralistWorkspace\Domain\AuditRepository;
use SpiralistWorkspace\Domain\AppealRepository;
use SpiralistWorkspace\Domain\ConversationRepository;
use SpiralistWorkspace\Domain\FavoriteRepository;
use SpiralistWorkspace\Domain\PermissionRepository;
use SpiralistWorkspace\Domain\PromptRepository;
use SpiralistWorkspace\Domain\ReputationRepository;
use SpiralistWorkspace\Domain\ReviewRepository;
use SpiralistWorkspace\Domain\RunRepository;
use SpiralistWorkspace\Domain\TestRepository;
use SpiralistWorkspace\Domain\VersionRepository;
use SpiralistWorkspace\Privacy\Privacy;
use SpiralistWorkspace\Http\RestController;
use SpiralistWorkspace\Services\PlaceholderService;
use SpiralistWorkspace\Services\PromptRunner;
use SpiralistWorkspace\Services\GovernanceMaintenance;
use SpiralistWorkspace\Services\RateLimiter;
use SpiralistWorkspace\Support\SystemPromptRegistry;
use SpiralistWorkspace\Web\FrontendController;
if (!defined('ABSPATH')) {
exit;
}
/**
* Boots plugin services and WordPress hooks.
*/
class Plugin
{
private const SCHEMA_HEALTH_TRANSIENT = 'spiralist_workspace_schema_health_checked';
private Settings $settings;
private Roles $roles;
private PromptRepository $prompts;
private VersionRepository $versions;
private PermissionRepository $permission_repository;
private RunRepository $runs;
private TestRepository $tests;
private ConversationRepository $conversations;
private AuditRepository $audit;
private FavoriteRepository $favorites;
private ReviewRepository $reviews;
private AppealRepository $appeals;
private ReputationRepository $reputation;
private Permissions $permissions;
private PlaceholderService $placeholders;
private RateLimiter $rate_limiter;
private PromptRunner $runner;
private GovernanceMaintenance $governance_maintenance;
private RestController $rest;
private FrontendController $frontend;
private SystemPromptRegistry $system_prompts;
private ManagedPromptAdmin $managed_prompt_admin;
private Privacy $privacy;
private bool $booted = false;
/**
* Registers WordPress hooks once.
*/
public function boot(): void
{
if ($this->booted) {
return;
}
$this->settings = new Settings();
$this->roles = new Roles();
$this->audit = new AuditRepository();
$this->versions = new VersionRepository();
$this->permission_repository = new PermissionRepository();
$this->favorites = new FavoriteRepository();
$this->reviews = new ReviewRepository();
$this->appeals = new AppealRepository();
$prompt_reader = new PromptRepository($this->versions, $this->permission_repository, $this->favorites);
$this->reputation = new ReputationRepository($prompt_reader, $this->reviews);
$this->prompts = new PromptRepository($this->versions, $this->permission_repository, $this->favorites, $this->reputation);
$this->runs = new RunRepository();
$this->tests = new TestRepository();
$this->conversations = new ConversationRepository();
$this->permissions = new Permissions($this->permission_repository, $this->settings, $this->reputation);
$this->placeholders = new PlaceholderService();
$this->rate_limiter = new RateLimiter($this->settings, $this->runs, $this->conversations, $this->audit);
$this->runner = new PromptRunner(
$this->prompts,
$this->permissions,
$this->runs,
$this->conversations,
$this->audit,
$this->placeholders,
$this->rate_limiter,
$this->settings
);
$this->governance_maintenance = new GovernanceMaintenance(
$this->prompts,
$this->reviews,
$this->appeals,
$this->reputation,
$this->audit
);
$this->rest = new RestController(
$this->prompts,
$this->permissions,
$this->permission_repository,
$this->versions,
$this->runs,
$this->tests,
$this->conversations,
$this->favorites,
$this->reviews,
$this->appeals,
$this->reputation,
$this->audit,
$this->runner,
$this->governance_maintenance,
$this->settings
);
$this->system_prompts = new SystemPromptRegistry($this->prompts, $this->settings);
$this->managed_prompt_admin = new ManagedPromptAdmin($this->settings, $this->system_prompts);
$this->settings->set_managed_prompt_admin($this->managed_prompt_admin);
$this->privacy = new Privacy($this->prompts, $this->settings);
$this->frontend = new FrontendController(
$this->prompts,
$this->permissions,
$this->permission_repository,
$this->versions,
$this->runs,
$this->tests,
$this->conversations,
$this->favorites,
$this->reviews,
$this->appeals,
$this->reputation,
$this->audit,
$this->settings
);
add_action('init', [Roles::class, 'register'], 5);
add_action('init', [$this->prompts, 'register_content_types'], 10);
add_action('init', [$this->frontend, 'register_routes'], 11);
add_action('init', [$this->frontend, 'maybe_flush_rewrite_rules'], 100);
add_action('admin_menu', [$this->settings, 'register_admin_page']);
add_action('admin_init', [$this->settings, 'register_settings']);
add_action('admin_init', [$this->privacy, 'add_privacy_policy_content']);
add_action('rest_api_init', [$this->rest, 'register_routes']);
add_action('add_meta_boxes', [$this->prompts, 'register_meta_boxes']);
add_action('save_post', [$this->prompts, 'handle_post_save'], 10, 3);
add_action('wp_enqueue_scripts', [$this->frontend, 'enqueue_assets']);
add_action('admin_enqueue_scripts', [$this->settings, 'enqueue_admin_assets']);
add_action('admin_post_spiralist_workspace_sync_system_prompts', [$this, 'handle_sync_system_prompts']);
add_action('admin_post_spiralist_workspace_bulk_image_upload', [$this->managed_prompt_admin, 'handle_bulk_image_upload']);
add_action('admin_post_spiralist_workspace_import_prompt_files', [$this->managed_prompt_admin, 'handle_prompt_import']);
add_action('admin_post_spiralist_workspace_download_prompt_template', [$this->managed_prompt_admin, 'handle_download_template']);
add_action('admin_post_spiralist_workspace_save_managed_prompt', [$this->managed_prompt_admin, 'handle_save_prompt']);
add_filter('query_vars', [$this->frontend, 'register_query_vars']);
add_filter('template_include', [$this->frontend, 'template_include']);
add_filter('wp_privacy_personal_data_exporters', [$this->privacy, 'register_exporters']);
add_filter('wp_privacy_personal_data_erasers', [$this->privacy, 'register_erasers']);
add_action('template_redirect', [$this->frontend, 'handle_api_alias'], 1);
add_action('init', [$this, 'maybe_upgrade'], 2);
if ($this->should_auto_sync_system_prompts()) {
add_action('init', [$this->system_prompts, 'maybe_sync'], 12);
}
add_action('init', [$this->governance_maintenance, 'schedule'], 20);
add_action(GovernanceMaintenance::HOOK, [$this->governance_maintenance, 'run']);
$this->booted = true;
}
/**
* Upgrades tables when the schema version changes.
*/
public function maybe_upgrade(): void
{
$stored = (string) get_option('spiralist_workspace_schema_version', '');
if ($stored === Installer::SCHEMA_VERSION) {
if ((string) get_transient(self::SCHEMA_HEALTH_TRANSIENT) === Installer::SCHEMA_VERSION) {
return;
}
if ($this->has_required_schema_tables()) {
set_transient(self::SCHEMA_HEALTH_TRANSIENT, Installer::SCHEMA_VERSION, HOUR_IN_SECONDS);
return;
}
}
Installer::create_schema();
PromptRepository::migrate_content_types();
update_option('spiralist_workspace_schema_version', Installer::SCHEMA_VERSION, false);
set_transient(self::SCHEMA_HEALTH_TRANSIENT, Installer::SCHEMA_VERSION, HOUR_IN_SECONDS);
}