PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.7.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.7.1
1.7.1 1.7.0 1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 All 51 releases
← All changes | app/CPT/FluentProducts.php +62 -3 1.6.3 → 1.7.1 View file →
@@ -110,12 +110,71 @@
110 110 "
111 111 );
112 112 });
113 113
114 + $this->handleClassicEditorModalSave();
115 +
114 116 add_action('update_post_meta', [$this, 'handleThumbChange'], 10, 4);
115 117 add_action('added_post_meta', [$this, 'handleThumbChange'], 10, 4);
116 118 }
117 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 +
118 177 public function registerElementorScript()
119 178 {
120 179 $custom_js = "console.log('doc ready - editor context');
121 180
@@ -310,11 +369,11 @@
310 369 ],
311 370 ]);
312 371
313 372 // product-tags is deliberately NOT registered: FluentCart ships
314 - // categories and brands only (product decision 2026-08-06). The former
315 - // dead consumers (Product tag getters, shop shortcode tag= filter)
316 - // were removed with that decision.
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:…".
317 376 }
318 377
319 378 private function enqueueCustomEditorStyles()
320 379 {