@@ -150,6 +150,7 @@ function is_plugin_active( string $plugin_file ): bool {
150150 function activate_plugin ( string $ plugin_file ) {
151151 $ GLOBALS ['ssi_companion_active ' ][] = $ plugin_file ;
152152 $ GLOBALS ['ssi_companion_activated ' ][] = $ plugin_file ;
153+ require_once WP_PLUGIN_DIR . '/ ' . $ plugin_file ;
153154 return null ;
154155 }
155156}
@@ -436,17 +437,16 @@ function update_option( string $name, mixed $value, bool $autoload = false ): bo
436437$ assert ( file_exists ( WP_PLUGIN_DIR . '/ssi-example-site/blocks/custom-hero/render.php ' ), 'install-writes-render-php-to-disk ' );
437438$ assert ( file_exists ( WP_PLUGIN_DIR . '/ssi-example-site/blocks/custom-hero/block.json ' ), 'install-emits-block-json ' );
438439$ assert ( file_exists ( WP_PLUGIN_DIR . '/ssi-example-site/blocks/custom-hero/editor.js ' ), 'install-emits-declared-editor-asset ' );
440+ $ assert ( in_array ( 'example/custom-hero ' , WP_Block_Type_Registry::$ registered , true ), 'install-registers-generated-block-before-editor-use ' );
441+ $ assert ( isset ( $ GLOBALS ['static_site_importer_companion_block_owners ' ]['example/custom-hero ' ] ), 'install-records-generated-block-owner-before-editor-use ' );
439442$ written_main = file_exists ( WP_PLUGIN_DIR . '/ssi-example-site/ssi-example-site.php ' ) ? (string ) file_get_contents ( WP_PLUGIN_DIR . '/ssi-example-site/ssi-example-site.php ' ) : '' ;
440443$ assert ( str_contains ( $ written_main , 'register_block_type ' ), 'written-main-file-registers-blocks ' );
441444
442445// A foreign registration that wins before generated plugin init must never be
443446// marked as companion-owned, so a later materialization still fails closed.
444447WP_Block_Type_Registry::$ registered [] = 'example/custom-hero ' ;
445448$ GLOBALS ['static_site_importer_companion_block_owners ' ] = array ();
446- require WP_PLUGIN_DIR . '/ssi-example-site/ssi-example-site.php ' ;
447- foreach ( $ GLOBALS ['ssi_companion_actions ' ]['init ' ] ?? array () as $ callback ) {
448- call_user_func ( $ callback );
449- }
449+ ssi_example_site_register_blocks ();
450450$ assert ( ! isset ( $ GLOBALS ['static_site_importer_companion_block_owners ' ]['example/custom-hero ' ] ), 'foreign-registration-before-generated-init-records-no-owner ' );
451451$ foreign_init_collision = Static_Site_Importer_Plugin_Materializer::ensure_generated_plugin ( $ payload , static fn (): bool => true );
452452$ assert ( 'failed ' === ( $ foreign_init_collision ['status ' ] ?? '' ) && 'runtime_block_name_collision ' === ( $ foreign_init_collision ['diagnostics ' ][0 ]['reason_code ' ] ?? '' ), 'foreign-registration-before-generated-init-blocks-refresh ' );
@@ -522,12 +522,39 @@ function update_option( string $name, mixed $value, bool $autoload = false ): bo
522522
523523// A new site replaces the previous regular companion so document-global
524524// scripts from separate imports cannot execute together.
525+ $ GLOBALS ['static_site_importer_companion_block_owners ' ] = array ();
526+ WP_Block_Type_Registry::$ registered = array ();
525527$ replacement_payload = array_merge ( $ payload , array ( 'site_slug ' => 'replacement-site ' ) );
526528$ replacement_report = Static_Site_Importer_Plugin_Materializer::ensure_generated_plugin ( $ replacement_payload );
527529$ assert ( in_array ( 'ssi-example-site/ssi-example-site.php ' , $ GLOBALS ['ssi_companion_deactivated ' ], true ), 'replacement-deactivates-previous-companion ' );
528530$ assert ( in_array ( 'replaced:ssi-example-site/ssi-example-site.php ' , $ replacement_report ['actions ' ] ?? array (), true ), 'replacement-reports-previous-companion ' );
529531$ assert ( 'ssi-replacement-site/ssi-replacement-site.php ' === get_option ( Static_Site_Importer_Plugin_Materializer::ACTIVE_COMPANION_OPTION ), 'replacement-records-current-companion-plugin ' );
530532
533+ $ control_payload = array_merge (
534+ $ payload ,
535+ array (
536+ 'site_slug ' => 'editor-controls ' ,
537+ 'blocks ' => array (
538+ array (
539+ 'name ' => 'form-select ' ,
540+ 'block_json ' => array ( 'name ' => 'blocks-engine/form-select ' , 'title ' => 'Form Select ' , 'editorScript ' => 'file:./editor.js ' ),
541+ 'render ' => '<select><option>One</option></select> ' ,
542+ 'assets ' => array ( 'editor.js ' => 'window.SSIFormSelect = true; ' ),
543+ ),
544+ array (
545+ 'name ' => 'form-input ' ,
546+ 'block_json ' => array ( 'name ' => 'blocks-engine/form-input ' , 'title ' => 'Form Input ' , 'editorScript ' => 'file:./editor.js ' ),
547+ 'render ' => '<input type="text"> ' ,
548+ 'assets ' => array ( 'editor.js ' => 'window.SSIFormInput = true; ' ),
549+ ),
550+ ),
551+ )
552+ );
553+ $ control_report = Static_Site_Importer_Plugin_Materializer::ensure_generated_plugin ( $ control_payload );
554+ $ assert ( 'installed_activated ' === ( $ control_report ['status ' ] ?? '' ), 'control-companion-materializes ' );
555+ $ assert ( in_array ( 'blocks-engine/form-select ' , WP_Block_Type_Registry::$ registered , true ), 'form-select-registers-before-editor-use ' );
556+ $ assert ( in_array ( 'blocks-engine/form-input ' , WP_Block_Type_Registry::$ registered , true ), 'form-input-registers-before-editor-use ' );
557+
531558// Cleanup generated fixtures.
532559$ cleanup = static function ( string $ dir ) use ( &$ cleanup ): void {
533560 if ( ! is_dir ( $ dir ) ) {
0 commit comments