registered ) { return; } $this->registered = true; add_action( 'plugins_loaded', array( Installer::class, 'maybe_upgrade' ), 20 ); add_action( 'wp_initialize_site', array( Installer::class, 'initialize_site' ), 20 ); add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) ); if ( defined( 'WP_CLI' ) && WP_CLI && class_exists( 'WP_CLI' ) ) { SiteAuditCommand::register(); } if ( is_admin() ) { ( new AdminScreen( PX320_SITE_AUDIT_FILE, PX320_SITE_AUDIT_VERSION, plugin_dir_path( PX320_SITE_AUDIT_FILE ) . 'registry/audit-registry.v1.json', new ReportCatalogue() ) )->register(); } } public function register_rest_routes(): void { global $wpdb; $runs = new RunRepository( $wpdb, new RunStateMachine() ); $tasks = new TaskRepository( $wpdb ); $findings = new FindingRepository( $wpdb, new FindingContract() ); $decisions = new FindingDecisionRepository( $wpdb ); $reports = new ReportService( $runs, $findings, $decisions, new ReportProjector( new FindingContract(), new FindingComparison(), new ReportPriority(), new ReportReadiness() ) ); $coordinator = new RunCoordinator( $runs, $tasks ); $registry = new AuditRegistry( plugin_dir_path( PX320_SITE_AUDIT_FILE ) . 'registry/audit-registry.v1.json' ); $checkers = new CheckerRegistry( $registry ); $quick_runner = new ChunkRunner( $runs, $tasks, $findings, $checkers, $registry, $coordinator, new TransactionManager( $wpdb ) ); $quick_ids = $registry->local_implemented_for_profile( 'quick', $checkers->ids() ); $hash_key = ( new LocalHashKey() )->derive(); $operations = new ExternalOperationRepository( $wpdb, $hash_key ); $url_policy = new SameSiteUrlPolicy( home_url( '/' ) ); $crawl_pages = new CrawlPageRepository( $wpdb, $url_policy, new CrawlSignalContract(), $hash_key ); $analyzers = new SnapshotAnalyzerRegistry( new FindingFactory( $registry, new FindingContract() ) ); $full_same_site_ids = $registry->same_site_implemented_for_profile( 'full', $analyzers->ids() ); $full_local_ids = $registry->local_implemented_for_profile( 'full', $checkers->ids() ); $full_ids = array_merge( $full_same_site_ids, $full_local_ids ); $crawler = new SameSiteCrawler( $url_policy, $crawl_pages, new SameSiteHttpClient( $url_policy, new WordPressSafeHttpTransport( PX320_SITE_AUDIT_VERSION ) ), new HtmlSignalExtractor( $url_policy, $hash_key ), new SitemapSignalExtractor( $url_policy, $hash_key ) ); $full_runner = new FullChunkRunner( $runs, $tasks, $findings, $crawl_pages, $crawler, $analyzers, $checkers, $registry, $coordinator, new TransactionManager( $wpdb ) ); $paths = new WordPressPathProvider(); $scope_provider = new WordPressCodeScopeProvider( $paths ); $code_roots = array_merge( array( $paths->content_root(), $paths->mu_plugins_root() ), $paths->theme_roots() ); $code_scope = new CodeScopePolicy( array_values( array_filter( $code_roots ) ), $scope_provider->seeds(), $hash_key ); $code_files = new CodeFileRepository( $wpdb, $code_scope, new CodeSignalContract() ); $code_analyzers = new CodeAnalyzerRegistry( $code_files, new CodeFindingAnalyzer( new FindingFactory( $registry, new FindingContract() ) ) ); $deep_ids = $registry->local_implemented_for_profile( 'deep_code', $code_analyzers->ids() ); $deep_builder = new CodeSnapshotBuilder( $code_scope, $code_files, new CodeSignalExtractor( $hash_key ), new CodeSnippetsAdapter( $wpdb ) ); $deep_runner = new DeepCodeChunkRunner( $runs, $tasks, $findings, $code_files, $deep_builder, $code_analyzers, $registry, $coordinator, new TransactionManager( $wpdb ) ); $vendor_provider = new VendorCodeScopeProvider( $hash_key, PX320_SITE_AUDIT_FILE, $paths ); $vendor_roots = array_merge( array( $paths->plugins_root() ), $paths->theme_roots() ); $vendor_scope = new CodeScopePolicy( array_values( array_filter( $vendor_roots ) ), $vendor_provider->policy_seeds(), $hash_key ); $vendor_files = new CodeFileRepository( $wpdb, $vendor_scope, new CodeSignalContract() ); $vendor_analyzers = new CodeAnalyzerRegistry( $vendor_files, new CodeFindingAnalyzer( new FindingFactory( $registry, new FindingContract() ), 'vendor' ) ); $vendor_ids = $registry->local_implemented_for_profile( 'vendor', $vendor_analyzers->ids() ); $vendor_builder = new CodeSnapshotBuilder( $vendor_scope, $vendor_files, new CodeSignalExtractor( $hash_key ), new CodeSnippetsAdapter( $wpdb ), false, false, true ); $vendor_runner = new DeepCodeChunkRunner( $runs, $tasks, $findings, $vendor_files, $vendor_builder, $vendor_analyzers, $registry, $coordinator, new TransactionManager( $wpdb ) ); $rendered_analyzer = new RenderedFindingAnalyzer( new FindingFactory( $registry, new FindingContract() ) ); $rendered_ids = $registry->browser_implemented_for_profile( 'rendered', $rendered_analyzer->ids() ); $rendered_submission = new RenderedSubmissionService( $runs, $tasks, $findings, new RenderedObservationContract( $hash_key, $url_policy->origin() ), $rendered_analyzer, $coordinator, new TransactionManager( $wpdb ), $rendered_ids ); $runner = new ProfileChunkRunner( $runs, $quick_runner, $full_runner, $deep_runner, $vendor_runner ); $controller = new RunController( $coordinator, $runs, $reports, $runner, $quick_ids, $registry->plan_budget( $quick_ids ), $registry->registry_version(), $full_ids, $registry->combined_plan_budget( $full_local_ids, $full_same_site_ids ), $crawl_pages, $url_policy->origin(), new TransactionManager( $wpdb ), $deep_ids, $registry->plan_budget( $deep_ids ), $code_files, $vendor_ids, $registry->plan_budget( $vendor_ids ), $vendor_files, $vendor_provider, $rendered_ids, $registry->shared_browser_plan_budget( $rendered_ids ), $rendered_submission ); $controller->register_routes(); ( new FindingDecisionController( new FindingDecisionService( $runs, $findings, $decisions, new ManualCommentSanitizer() ) ) )->register_routes(); ( new ReviewRequestController( new ReviewRequestService( $runs, $reports, new ReviewPayloadBuilder( new ReportCatalogue(), PX320_SITE_AUDIT_VERSION ), new ReviewContactSanitizer(), new ReviewRequestClient( new WordPressReviewTransport( PX320_SITE_AUDIT_VERSION ) ), $operations ) ) )->register_routes(); $external_findings = new ExternalFindingBuilder( new FindingFactory( $registry, new FindingContract() ) ); $external_service = new ExternalAuditService( $runs, $findings, $operations, $registry, $external_findings, new TransactionManager( $wpdb ) ); ( new ExternalController( $external_service, $external_findings, new WordPressOrgClient( new WordPressJsonTransport( PX320_SITE_AUDIT_VERSION ) ), new PluginChecksumInventory( $hash_key ) ) )->register_routes(); $privacy_rule_pack = new PrivacyRulePack( plugin_dir_path( PX320_SITE_AUDIT_FILE ) . 'config/privacy-rule-packs.v1.json' ); ( new PrivacyChecklistController( new ManualChecklistService( $privacy_rule_pack, new ManualCommentSanitizer(), new ManualAssertionRepository( $wpdb ), $runs, $findings, new FindingFactory( $registry, new FindingContract() ), new TransactionManager( $wpdb ) ) ) )->register_routes(); } private function __construct() { } }