| @@ -40,13 +40,19 @@ | ||
| 40 | 40 | $this->registerProductTaxonomies(); |
| 41 | 41 | }); |
| 42 | 42 | |
| 43 | 43 | add_action('admin_enqueue_scripts', function () { |
| 44 | + $screen = get_current_screen(); | |
| 45 | + $isProductEditingScreen = $screen && $screen->post_type === 'fluent-products' && $screen->base === 'post'; | |
| 46 | + | |
| 44 | 47 | if ($this->showStandaloneMenu) { |
| 48 | + if ($isProductEditingScreen && App::request()->get('custom-editor') === 'true') { | |
| 49 | + wp_enqueue_style('wp-admin'); | |
| 50 | + $this->enqueueCustomEditorStyles(); | |
| 51 | + } | |
| 45 | 52 | return; |
| 46 | 53 | } |
| 47 | - $screen = get_current_screen(); | |
| 48 | - $isProductEditingScreen = $screen && $screen->post_type === 'fluent-products' && $screen->base === 'post'; | |
| 54 | + | |
| 49 | 55 | if (!$isProductEditingScreen) { |
| 50 | 56 | if ($screen && $screen->post_type === 'fluent-products' && ($screen->base == 'edit-tags' || $screen->base == 'term')) { |
| 51 | 57 | $this->customizeTaxonomyScreen(); |
| 52 | 58 | } |
| @@ -55,27 +61,10 @@ | ||
| 55 | 61 | |
| 56 | 62 | // Make sure the default admin styles are enqueued |
| 57 | 63 | wp_enqueue_style('wp-admin'); |
| 58 | 64 | |
| 59 | - $custom_css = | |
| 60 | - '#editor .editor-sidebar__panel .editor-post-summary .editor-post-trash,' . | |
| 61 | - '#wpadminbar,' . | |
| 62 | - '#adminmenu,' . | |
| 63 | - '#adminmenuback,' . | |
| 64 | - '#adminmenuwrap {' . | |
| 65 | - 'display: none !important;' . | |
| 66 | - '}' . | |
| 67 | - '#wpbody-content .interface-interface-skeleton {' . | |
| 68 | - 'left: 0 !important;' . | |
| 69 | - 'top: 0 !important;' . | |
| 70 | - '}' . | |
| 71 | - '#wpcontent, #wpfooter {' . | |
| 72 | - 'margin-left: 0 !important;' . | |
| 73 | - 'margin-right: 0 !important;' . | |
| 74 | - '}'; | |
| 65 | + $this->enqueueCustomEditorStyles(); | |
| 75 | 66 | |
| 76 | - wp_add_inline_style('wp-admin', $custom_css); | |
| 77 | - | |
| 78 | 67 | wp_register_script('fluent-products-inline-js', '', [], FLUENTCART_VERSION, true); |
| 79 | 68 | wp_enqueue_script('fluent-products-inline-js'); |
| 80 | 69 | |
| 81 | 70 | $custom_js = "window.addEventListener('click', function (event) { |
| @@ -121,12 +110,71 @@ | ||
| 121 | 110 | " |
| 122 | 111 | ); |
| 123 | 112 | }); |
| 124 | 113 | |
| 114 | + $this->handleClassicEditorModalSave(); | |
| 115 | + | |
| 125 | 116 | add_action('update_post_meta', [$this, 'handleThumbChange'], 10, 4); |
| 126 | 117 | add_action('added_post_meta', [$this, 'handleThumbChange'], 10, 4); |
| 127 | 118 | } |
| 128 | 119 | |
| 120 | + /** | |
| 121 | + * When Gutenberg is disabled (e.g. "Disable Gutenberg" plugin) the modal iframe | |
| 122 | + * shows the classic edit screen, whose Update button is a full form POST to | |
| 123 | + * post.php followed by a redirect. Carry `custom-editor` through both so the | |
| 124 | + * iframe stays chrome-less, then tell the parent modal the save finished. | |
| 125 | + */ | |
| 126 | + private function handleClassicEditorModalSave() | |
| 127 | + { | |
| 128 | + $isCustomEditor = function () { | |
| 129 | + return App::request()->get('custom-editor') === 'true' | |
| 130 | + || (isset($_POST['custom-editor']) && $_POST['custom-editor'] === 'true'); // phpcs:ignore WordPress.Security.NonceVerification | |
| 131 | + }; | |
| 132 | + | |
| 133 | + add_action('edit_form_top', function ($post) use ($isCustomEditor) { | |
| 134 | + if ($post->post_type === self::CPT_NAME && $isCustomEditor()) { | |
| 135 | + echo '<input type="hidden" name="custom-editor" value="true" />'; | |
| 136 | + } | |
| 137 | + }); | |
| 138 | + | |
| 139 | + add_filter('redirect_post_location', function ($location, $postId) use ($isCustomEditor) { | |
| 140 | + if (get_post_type($postId) === self::CPT_NAME && $isCustomEditor()) { | |
| 141 | + // WP builds $location from get_edit_post_link(), which this class | |
| 142 | + // filters to the SPA dashboard URL; send the iframe back to the | |
| 143 | + // real edit screen instead. | |
| 144 | + wp_parse_str((string)wp_parse_url($location, PHP_URL_QUERY), $query); | |
| 145 | + | |
| 146 | + return add_query_arg([ | |
| 147 | + 'post' => $postId, | |
| 148 | + 'action' => 'edit', | |
| 149 | + 'message' => (int)($query['message'] ?? 1) ?: 1, | |
| 150 | + 'custom-editor' => 'true', | |
| 151 | + ], admin_url('post.php')); | |
| 152 | + } | |
| 153 | + return $location; | |
| 154 | + }, 10, 2); | |
| 155 | + | |
| 156 | + add_action('admin_footer', function () { | |
| 157 | + $screen = get_current_screen(); | |
| 158 | + if (!$screen || $screen->post_type !== self::CPT_NAME || $screen->base !== 'post') { | |
| 159 | + return; | |
| 160 | + } | |
| 161 | + | |
| 162 | + $request = App::request(); | |
| 163 | + if ($request->get('custom-editor') !== 'true' || !$request->get('message') || $request->get('is-preview-mode')) { | |
| 164 | + return; | |
| 165 | + } | |
| 166 | + | |
| 167 | + // Notify once, then drop `message` from the URL so a later reload of | |
| 168 | + // this iframe doesn't re-send the save signal and close the modal. | |
| 169 | + echo '<script>if (window.parent !== window) {' | |
| 170 | + . 'window.parent.postMessage({type: "classicEditorSaved"}, "*");' | |
| 171 | + . 'var u = new URL(window.location.href); u.searchParams.delete("message");' | |
| 172 | + . 'window.history.replaceState(null, "", u.toString());' | |
| 173 | + . '}</script>'; | |
| 174 | + }); | |
| 175 | + } | |
| 176 | + | |
| 129 | 177 | public function registerElementorScript() |
| 130 | 178 | { |
| 131 | 179 | $custom_js = "console.log('doc ready - editor context'); |
| 132 | 180 | |
| @@ -319,8 +367,35 @@ | ||
| 319 | 367 | 'view_item' => __('View Brand', 'fluent-cart'), |
| 320 | 368 | 'not_found' => __('No Brand found', 'fluent-cart'), |
| 321 | 369 | ], |
| 322 | 370 | ]); |
| 371 | + | |
| 372 | + // product-tags is deliberately NOT registered: FluentCart ships | |
| 373 | + // categories and brands only (product decision 2026-08-06). Stores that | |
| 374 | + // register it themselves can still filter the shop shortcode with | |
| 375 | + // taxonomies="product-tags:…". | |
| 376 | + } | |
| 377 | + | |
| 378 | + private function enqueueCustomEditorStyles() | |
| 379 | + { | |
| 380 | + $custom_css = | |
| 381 | + '#editor .editor-sidebar__panel .editor-post-summary .editor-post-trash,' . | |
| 382 | + '#wpadminbar,' . | |
| 383 | + '#adminmenu,' . | |
| 384 | + '#adminmenuback,' . | |
| 385 | + '#adminmenuwrap {' . | |
| 386 | + 'display: none !important;' . | |
| 387 | + '}' . | |
| 388 | + '#wpbody-content .interface-interface-skeleton {' . | |
| 389 | + 'left: 0 !important;' . | |
| 390 | + 'top: 0 !important;' . | |
| 391 | + '}' . | |
| 392 | + '#wpcontent, #wpfooter {' . | |
| 393 | + 'margin-left: 0 !important;' . | |
| 394 | + 'margin-right: 0 !important;' . | |
| 395 | + '}'; | |
| 396 | + | |
| 397 | + wp_add_inline_style('wp-admin', $custom_css); | |
| 323 | 398 | } |
| 324 | 399 | |
| 325 | 400 | public function customizeTaxonomyScreen() |
| 326 | 401 | { |