PluginProbe
Extendify / 3.1.5
Extendify v3.1.5
3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 0.7.0 All 126 releases
extendify / app / QuickEdit / Frontend.php

Frontend.php in Extendify 3.1.5, at app/QuickEdit/Frontend.php

180 lines 6.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Extendify\QuickEdit;
4
5 defined('ABSPATH') || die('No direct access.');
6
7 use Extendify\Agent\Admin;
8 use Extendify\Config;
9 use Extendify\PartnerData;
10 use Extendify\QuickEdit\Controllers\SaveController;
11 use Extendify\QuickEdit\Controllers\SiteIdentityController;
12 use Extendify\QuickEdit\Controllers\WCProductController;
13 use Extendify\QuickEdit\Controllers\WPFormsController;
14 use Extendify\QuickEdit\Controllers\WPNavigationController;
15 use Extendify\QuickEdit\Schemas\Registry;
16 use Extendify\QuickEdit\Services\IdentityTagger;
17 use Extendify\QuickEdit\Services\MediaTextTagger;
18 use Extendify\QuickEdit\Services\NavRefTagger;
19 use Extendify\QuickEdit\Services\TranslatedContext;
20 use Extendify\QuickEdit\Services\WCProductTagger;
21 use Extendify\QuickEdit\Services\WPFormsTagger;
22
23 class Frontend
24 {
25 public function __construct()
26 {
27 Registry::init();
28 SaveController::init();
29 SiteIdentityController::init();
30 WCProductController::init();
31 WPNavigationController::init();
32 WPFormsController::init();
33 IdentityTagger::init();
34 WCProductTagger::init();
35 NavRefTagger::init();
36 WPFormsTagger::init();
37 MediaTextTagger::init();
38
39 // TagBlocks + TagTemplateParts are initialized by Agent\Admin.
40 add_action('wp_enqueue_scripts', [$this, 'enqueue']);
41 // Landing after the agent button's 4 stops admin-bar.js moving it post-paint.
42 $beside = Admin::agentPosition() === 'docked-left' ? 5 : 100;
43 add_action('admin_bar_menu', [$this, 'registerAdminBar'], $beside);
44 }
45
46 /**
47 * Whether inline Quick Edit surfaces are enabled for this install —
48 * the showQuickEdit partner flag or the matching preview opt-in.
49 *
50 * @return boolean
51 */
52 public static function quickEditEnabled(): bool
53 {
54 return (bool) (PartnerData::setting('showQuickEdit') || Config::preview('quick-edit'));
55 }
56
57 public function registerAdminBar($bar)
58 {
59 if (is_admin() || !is_user_logged_in() || !current_user_can(Config::$requiredCapability)) {
60 return;
61 }
62 if (!self::quickEditEnabled()) {
63 return;
64 }
65 $bar->add_node([
66 'id' => 'extendify-quick-edit-toggle',
67 'title' => '<span class="extendify-quick-edit-toggle-pill" aria-hidden="true">'
68 . '<span class="extendify-quick-edit-toggle-thumb"></span></span>'
69 . '<span class="extendify-quick-edit-toggle-label">'
70 . esc_html__('Quick Edit', 'extendify-local')
71 . '</span>',
72 'href' => '#',
73 'meta' => [
74 'role' => 'switch',
75 'aria-label' => esc_attr__('Quick Edit', 'extendify-local'),
76 ],
77 ]);
78 }
79
80 public function enqueue()
81 {
82 // The Customizer preview iframe is a front-end render (is_admin() false),
83 // so QE would otherwise enqueue and mount inside it — bail before then.
84 if (!current_user_can(Config::$requiredCapability) || is_admin() || is_customize_preview()) {
85 return;
86 }
87
88 $version = constant('EXTENDIFY_DEVMODE') ? (string) time() : Config::$version;
89 $manifest = Config::$assetManifest;
90 $assetMeta = $manifest['extendify-quick-edit.php'] ?? null;
91 $jsFile = $manifest['extendify-quick-edit.js'] ?? null;
92 $cssFile = $manifest['extendify-quick-edit.css'] ?? null;
93 if (!$assetMeta || !$jsFile) {
94 return;
95 }
96 $assetPath = EXTENDIFY_PATH . 'public/build/' . $assetMeta;
97 $asset = file_exists($assetPath)
98 ? require $assetPath
99 : ['dependencies' => [], 'version' => $version];
100
101 $jsHandle = 'extendify-quick-edit';
102 // wp-format-library isn't auto-detected — we access wp.formatLibrary
103 // at runtime to avoid invalid build-module/* handles.
104 $deps = array_merge(
105 $asset['dependencies'] ?? [],
106 ['wp-format-library']
107 );
108 wp_enqueue_script(
109 $jsHandle,
110 EXTENDIFY_BASE_URL . 'public/build/' . $jsFile,
111 $deps,
112 $asset['version'] ?? $version,
113 true
114 );
115 wp_set_script_translations($jsHandle, 'extendify-local', EXTENDIFY_PATH . 'languages/js');
116
117 if ($cssFile) {
118 wp_enqueue_style(
119 $jsHandle,
120 EXTENDIFY_BASE_URL . 'public/build/' . $cssFile,
121 [],
122 $asset['version'] ?? $version
123 );
124 }
125
126 // Required for BlockEditor canvas + toolbar styling.
127 wp_enqueue_style('wp-components');
128 wp_enqueue_style('wp-block-editor');
129 wp_enqueue_style('wp-block-library');
130 wp_enqueue_style('wp-format-library');
131 wp_enqueue_media();
132
133 global $post;
134 $sourceForCurrentPost = ($post instanceof \WP_Post)
135 ? ['kind' => 'post', 'id' => $post->ID]
136 : null;
137
138 $context = ['currentSource' => $sourceForCurrentPost];
139 if (function_exists('get_woocommerce_currency_symbol')) {
140 // WC returns HTML entities for some currencies (e.g. ₹ as
141 // `&#8377;`); the price modal renders it as React text, so
142 // decode before shipping.
143 $context['currencySymbol'] = html_entity_decode(
144 get_woocommerce_currency_symbol(),
145 ENT_QUOTES,
146 'UTF-8'
147 );
148 }
149
150 // EXTENDIFY_QUICK_EDIT_DEBUG (wp-config constant) or ?qe-debug=1 turns
151 // on selector-layer console traces — used to repro the "second block
152 // selected" report without shipping logs in prod builds.
153 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
154 $debug = (defined('EXTENDIFY_QUICK_EDIT_DEBUG') && constant('EXTENDIFY_QUICK_EDIT_DEBUG'))
155 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
156 || (isset($_GET['qe-debug']) && $_GET['qe-debug'] === '1');
157
158 // QE off (showQuickEdit) keeps the selector bundle loaded for Ask AI
159 // but suppresses every inline-edit surface: no auto-on post-Launch
160 // (the agent's Select button is the entry point then) and the
161 // hover/keyboard pills gate on quickEditEnabled.
162 $quickEditEnabled = self::quickEditEnabled();
163
164 wp_add_inline_script(
165 $jsHandle,
166 'window.extQuickEditData = ' . wp_json_encode([
167 'restRoot' => esc_url_raw(rest_url('extendify/v1')),
168 'nonce' => wp_create_nonce('wp_rest'),
169 'schemas' => Registry::describe(),
170 'context' => $context,
171 'translatedContext' => TranslatedContext::detect(),
172 'quickEditEnabled' => $quickEditEnabled,
173 'defaultOn' => ((bool) constant('EXTENDIFY_DEVMODE') || Config::$launchCompleted) && $quickEditEnabled,
174 'debug' => $debug,
175 ]) . ';',
176 'before'
177 );
178 }
179 }
180