PluginProbe
Extendify / 3.2.2
Extendify v3.2.2
3.2.2 3.2.1 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 All 128 releases
← All changes | app/Agent/Admin.php +52 -10 3.1.4 → 3.2.2 View file →
@@ -11,8 +11,9 @@
11 11 use Extendify\Agent\Controllers\ChatHistoryController;
12 12 use Extendify\Agent\Controllers\TourController;
13 13 use Extendify\Config;
14 14 use Extendify\Constants;
15 +use Extendify\Mcp\Profile as McpProfile;
15 16 use Extendify\Shared\Services\Escaper;
16 17 use Extendify\Shared\Services\HttpClient;
17 18 use Extendify\Agent\TagBlocks;
18 19 use Extendify\Agent\TagTemplateParts;
@@ -17,11 +18,11 @@
17 18 use Extendify\Agent\TagBlocks;
18 19 use Extendify\Agent\TagTemplateParts;
19 20 use Extendify\Agent\WooProductImages;
20 21 use Extendify\Agent\AbilitiesDiscovery;
21 -use Extendify\Agent\Controllers\SiteNavigationController;
22 22 use Extendify\PartnerData;
23 23 use Extendify\Shared\DataProvider\ProductsData;
24 +use Extendify\SiteVisibility;
24 25
25 26 /**
26 27 * This class handles any file loading for the admin area.
27 28 */
@@ -41,10 +42,9 @@
41 42 // Tag blocks so we can identify them later
42 43 TagBlocks::init();
43 44 TagTemplateParts::init();
44 45
45 - // Add the site navigation ids to the navigation blocks
46 - SiteNavigationController::init();
46 + Skeleton::init();
47 47
48 48 WooProductImages::init();
49 49
50 50 \add_action('extendify_agent_suggestions_refresh', [$this, 'refreshSuggestions']);
@@ -50,8 +50,22 @@
50 50 \add_action('extendify_agent_suggestions_refresh', [$this, 'refreshSuggestions']);
51 51 }
52 52
53 53 /**
54 + * Where the agent panel mounts — docked-left only on the onboarding front end.
55 + *
56 + * @return string
57 + */
58 + public static function agentPosition()
59 + {
60 + $agentOnboarding = PartnerData::setting('useAgentOnboarding') ||
61 + Config::preview('agent-onboarding') ||
62 + constant('EXTENDIFY_DEVMODE');
63 +
64 + return $agentOnboarding && !is_admin() ? 'docked-left' : 'floating';
65 + }
66 +
67 + /**
54 68 * Adds various JS scripts and styles
55 69 *
56 70 * @return void
57 71 */
@@ -58,9 +72,9 @@
58 72 public function loadScriptsAndStyles()
59 73 {
60 74 // The Customizer preview iframe is a front-end render, so this fires
61 75 // there too — but the Agent only belongs on the live, top-level page.
62 - if (is_customize_preview()) {
76 + if (is_customize_preview() || McpProfile::isOwnScreen()) {
63 77 return;
64 78 }
65 79
66 80 $version = constant('EXTENDIFY_DEVMODE') ? uniqid() : Config::$version;
@@ -102,11 +116,11 @@
102 116 (bool) use_block_editor_for_post($this->getCurrentPostId()) :
103 117 false,
104 118 'isOnEditorOrFSE' => $this->isGutenbergOrFse(),
105 119 'activePlugins' => array_values(\get_option('active_plugins', [])),
106 - // Whether the user is using the vibes experience or not.
107 - 'isUsingVibes' => (bool) file_exists(EXTENDIFY_PATH . 'src/Launch/_data/block-style-variations.json') &&
108 - version_compare(wp_get_theme("extendable")->get('Version'), '2.0.32', '>='),
120 + // The accessor also reads a key set by the IMAGIFY_API_KEY constant.
121 + 'hasImagifyApiKey' => function_exists('get_imagify_option') && (bool) \get_imagify_option('api_key'),
122 + 'isUsingVibes' => version_compare((string) wp_get_theme('extendable')->get('Version'), '2.0.32', '>='),
109 123 'siteTitle' => \esc_attr(\get_bloginfo('name')),
110 124 'siteDescription' => \esc_attr(\get_bloginfo('description')),
111 125 'themePresets' => $this->getThemePresets(),
112 126 'presetSlugs' => $this->getPresetSlugs(),
@@ -125,8 +139,10 @@
125 139 }, $pluginRecommendations));
126 140 $agentContext = [
127 141 'availableAdminPages' => get_option('_transient_extendify_admin_pages_menu', []),
128 142 'pluginRecommendations' => $mappedPluginRecommendations,
143 + 'sitePublished' => SiteVisibility::isPublished(),
144 + 'comingSoonEnabled' => (bool) PartnerData::setting('useComingSoon'),
129 145 ];
130 146 $abilities = [
131 147 'canEditPost' => (bool) \current_user_can('edit_post', \get_queried_object_id()),
132 148 // TODO: this may be true for a user, while they still can't edit every post
@@ -149,9 +165,9 @@
149 165 Config::$slug . '-agent-scripts',
150 166 'window.extAgentData = ' . \wp_json_encode([
151 167 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
152 168 'startOnboarding' => isset($_GET['extendify-launch-success']) && $agentOnboarding,
153 - 'agentPosition' => $agentOnboarding && !is_admin() ? 'docked-left' : 'floating',
169 + 'agentPosition' => self::agentPosition(),
154 170 // Add context about where they are
155 171 'context' => $context,
156 172 // Material a workflow may want; each declares the keys it reads.
157 173 'agentContext' => $agentContext,
@@ -159,10 +175,9 @@
159 175 // For example, we could check whether their theme has variations.
160 176 'abilities' => $abilities,
161 177 // Registered WordPress Abilities (6.9+) this user may run.
162 178 'wpAbilities' => AbilitiesDiscovery::discover(),
163 - // List of suggestions the AI can make for this user.
164 - // For example, we could check whether they need to set up a specific plugin.
179 + // The domain card reads only the register-domain record.
165 180 'suggestions' => $this->getSuggestions(),
166 181 'domainsSuggestionSettings' => [
167 182 'showPrimary' => (bool) PartnerData::setting('showPrimaryDomainRecommendationAgent'),
168 183 'showSecondary' => (bool) PartnerData::setting('showSecondaryDomainRecommendationAgent'),
@@ -297,12 +312,39 @@
297 312 $typography = \wp_get_global_settings(['typography']);
298 313
299 314 return [
300 315 'color' => $this->originSlugs($color, 'palette', 'defaultPalette'),
316 + 'colorValues' => $this->originValues($color, 'palette', 'defaultPalette', 'color'),
301 317 'gradient' => $this->originSlugs($color, 'gradients', 'defaultGradients'),
302 318 'fontSize' => $this->originSlugs($typography, 'fontSizes', 'defaultFontSizes'),
303 319 'fontFamily' => $this->originSlugs($typography, 'fontFamilies', 'defaultFontFamilies'),
304 320 ];
321 + }
322 +
323 + /**
324 + * Slug => value, so a colour written as its own hex finds the token naming it.
325 + *
326 + * @return array<string, string>
327 + */
328 + private function originValues($node, $listKey, $defaultKey, $valueKey)
329 + {
330 + $list = $node[$listKey] ?? [];
331 +
332 + $origins = ['custom', 'theme'];
333 + if (($node[$defaultKey] ?? true) !== false) {
334 + $origins[] = 'default';
335 + }
336 +
337 + $values = [];
338 + foreach ($origins as $origin) {
339 + foreach ($list[$origin] ?? [] as $item) {
340 + if (isset($item['slug'], $item[$valueKey])) {
341 + $values[(string) $item['slug']] = (string) $item[$valueKey];
342 + }
343 + }
344 + }
345 +
346 + return $values;
305 347 }
306 348
307 349 /**
308 350 * Preset slugs from a settings node's origin buckets; drops the `default`