| 1 |
<?php |
| 2 |
/** |
| 3 |
* Gutenberg editor integration module (spec 033-gutenberg-integration). |
| 4 |
* |
| 5 |
* PHP relocated: includes/Core/Platform/Gutenberg.php (the platform driver — |
| 6 |
* create_page/insert/import_in_library/print_admin_js_template/ |
| 7 |
* update_gutenberg_hide_buttons/ui_theme) + |
| 8 |
* modules/full-site-import/Utils/GutenbergHelper.php (FSI block-tree |
| 9 |
* processing — parse_images/process_images/replace/replace_archive_id) + |
| 10 |
* modules/full-site-import/Utils/GutenbergSettingsMerger.php (Essential |
| 11 |
* Blocks global colors/typography resolution). Namespace: |
| 12 |
* Templately\Core\Platform\Gutenberg -> this module's Platform\Gutenberg; |
| 13 |
* Templately\Modules\FullSiteImport\Utils\{GutenbergHelper, |
| 14 |
* GutenbergSettingsMerger} -> this module's own Utils\*. |
| 15 |
* |
| 16 |
* NOT relocated: modules/full-site-import/Runners/GutenbergContent.php (the |
| 17 |
* FSI runner, get_name()==='content'). Confirmed via grep it calls |
| 18 |
* $this->loop() directly (twice, for the outer post-type loop and the inner |
| 19 |
* per-post loop) — per the resume-key-identity gotcha documented in |
| 20 |
* modules/full-site-import/Runners/CLAUDE.md ("Resume key") and established |
| 21 |
* in spec 031 (ElementorContent stayed for the same reason), relocating a |
| 22 |
* runner class that calls loop() directly would change its Class::method |
| 23 |
* resume-key identity and strand in-flight imports. GutenbergHelper, by |
| 24 |
* contrast, does NOT call $this->loop() itself (confirmed via grep) — the |
| 25 |
* Loop trait's resume context is derived ONCE by the runner's own loop() |
| 26 |
* call and threaded into the helper as a parameter, so GutenbergHelper is |
| 27 |
* safe to relocate despite extending ImportHelper (which `use`s the Loop |
| 28 |
* trait). This mirrors spec 032, which moved ElementorSettingsMerger (031) |
| 29 |
* but left ElementorHelper.php in place — here the equivalent split moves |
| 30 |
* BOTH Gutenberg utility classes because this spec's own FR-006..FR-009/ |
| 31 |
* FR-015/FR-016 explicitly own GutenbergHelper (unlike 032, whose spec.md |
| 32 |
* never claimed ElementorHelper). |
| 33 |
* |
| 34 |
* CRITICAL ORDERING FIX applied during the PHP move (identical to spec 032's |
| 35 |
* Elementor fix): Plugin::platforms() used to eagerly call |
| 36 |
* Gutenberg::get_instance() during plugins_loaded — but that runs BEFORE |
| 37 |
* Modules_Manager::boot() registers this module's autoloader (plugins_loaded |
| 38 |
* calls platforms() then apis() then Modules_Manager::boot(), in that fixed |
| 39 |
* order), so leaving the eager call in Plugin.php would fatal on |
| 40 |
* class-not-found. Gutenberg's self-registration (which internally calls |
| 41 |
* Templately\Core\Platform_Registry::get_instance()->add() — the platform-adapter |
| 42 |
* registry, unrelated to Module_Base/Modules_Manager) now happens from this |
| 43 |
* module's own init_hooks() instead, which runs during Modules_Manager::boot() |
| 44 |
* — after the autoloader for this module's namespace is registered. |
| 45 |
* Plugin::platforms() is now an empty no-op (both Elementor and Gutenberg |
| 46 |
* self-register from their own modules). Confirmed via grep that nothing |
| 47 |
* between platforms()/apis() and Modules_Manager::boot() eagerly resolves |
| 48 |
* Platform_Registry::get_instance()->active('gutenberg') (all such calls happen later, |
| 49 |
* during actual request handling — REST routes, template rendering — never |
| 50 |
* during the plugins_loaded bootstrap chain), so this timing shift is safe. |
| 51 |
* |
| 52 |
* @package Templately |
| 53 |
*/ |
| 54 |
|
| 55 |
namespace Templately\Modules\GutenbergIntegration; |
| 56 |
|
| 57 |
use Templately\Core\Module_Base; |
| 58 |
use Templately\Modules\GutenbergIntegration\Platform\Gutenberg; |
| 59 |
use Templately\Modules\GutenbergIntegration\REST\Visibility; |
| 60 |
|
| 61 |
class Module extends Module_Base { |
| 62 |
|
| 63 |
public function get_name(): string { |
| 64 |
return 'gutenberg-integration'; |
| 65 |
} |
| 66 |
|
| 67 |
public function get_dependencies(): array { |
| 68 |
// GutenbergHelper extends full-site-import's ImportHelper and the driver |
| 69 |
// calls FSI Utils (get_json_helper / import_and_replace_attachments / |
| 70 |
// read_json_file / import_page_settings). The driver also uses theme-builder |
| 71 |
// (PageTemplates / TemplateFactory). Both are real, |
| 72 |
// one-directional structural edges — FSI and theme-builder declare nothing back |
| 73 |
// (FSI resolves this module lazily via the templately_fsi_* filter seams). |
| 74 |
return [ 'full-site-import', 'theme-builder' ]; |
| 75 |
} |
| 76 |
|
| 77 |
protected function init_hooks(): void { |
| 78 |
Gutenberg::get_instance(); |
| 79 |
} |
| 80 |
|
| 81 |
public function register_rest_routes(): void { |
| 82 |
// FR-003 / FR-020: the toolbar-visibility toggle's REST transport |
| 83 |
// (PUT/POST /templately/v1/gutenberg/visibility) — replaces the primary use of the |
| 84 |
// wp_ajax_update_gutenberg_hide_buttons action, which stays as a deprecated shim |
| 85 |
// (see Platform\Gutenberg::hooks()). Standard lazy rest_api_init registration. |
| 86 |
Visibility::get_instance()->register_routes(); |
| 87 |
} |
| 88 |
} |
| 89 |
|