PluginProbe
Extendify / trunk
Extendify vtrunk
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 0.6.0 All 127 releases
← All changes | app/PartnerData.php +122 -1 3.0.6 → trunk View file →
@@ -54,11 +54,14 @@
54 54 'showDomainBanner' => false,
55 55 'showDomainTask' => false,
56 56 'showSecondaryDomainBanner' => false,
57 57 'showSecondaryDomainTask' => false,
58 + 'showPrimaryDomainRecommendationAgent' => false,
59 + 'showSecondaryDomainRecommendationAgent' => false,
58 60 'domainTLDs' => ['com', 'net'],
59 61 'priorityDomainTLDs' => [],
60 62 'stagingSites' => ['wordpress'],
63 + 'trialDomains' => [],
61 64 'domainSearchURL' => '',
62 65 'showDraft' => false,
63 66 'showChat' => false,
64 67 'showAIPageCreation' => false,
@@ -65,8 +68,9 @@
65 68 'enableImageImports-1-14-6' => false,
66 69 'disableLibraryAutoOpen' => false,
67 70 'enableApexDomain' => false,
68 71 'showLaunch' => false,
72 + 'showLaunchTitle' => false,
69 73 'deactivated' => true,
70 74 'launchRedirectWebsite' => false,
71 75 'showAILogo' => false,
72 76 'showProductRecommendations' => false,
@@ -76,15 +80,35 @@
76 80 'customProducts' => [],
77 81 ],
78 82 'license' => 'active',
79 83 'showAIAgents' => false,
84 + 'agentAbilitiesAllowlist' => [],
85 + 'showQuickEdit' => false,
86 + // Simple front-end Extendify toolbar (replaces WP core admin
87 + // bar for editors who prefer it). Default style is Launch-aware
88 + // (simple post-Launch, full before).
89 + 'showSimpleToolbar' => false,
80 90 'showImprint' => [],
81 91 'showLaunchQuestions' => false,
82 92 'pluginGroupId' => null,
83 93 'requiredPlugins' => null,
94 + 'showProductActivation' => [],
84 95 'useAgentOnboarding' => false,
85 96 'hidePluginNotifications' => false,
86 97 'hideLaunchExitLink' => false,
98 + 'useAutoUpdate' => false,
99 + 'showLaunchUpdate' => false,
100 + 'activeTests' => [],
101 + 'showExtendifyCode' => false,
102 + 'useComingSoon' => false,
103 + 'extendifyCodeData' => [
104 + 'link' => '',
105 + 'title' => '',
106 + 'message' => '',
107 + 'cta-primary' => '',
108 + ],
109 + 'customDesign' => null,
110 + 'strings' => [],
87 111 ];
88 112
89 113 // phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
90 114 /**
@@ -101,12 +125,17 @@
101 125 self::$config['showSecondaryDomainTask'] = ($data['showSecondaryDomainTask']
102 126 ?? self::$config['showSecondaryDomainTask']);
103 127 self::$config['showSecondaryDomainBanner'] = ($data['showSecondaryDomainBanner']
104 128 ?? self::$config['showSecondaryDomainBanner']);
129 + self::$config['showPrimaryDomainRecommendationAgent'] = ($data['showPrimaryDomainRecommendationAgent']
130 + ?? self::$config['showPrimaryDomainRecommendationAgent']);
131 + self::$config['showSecondaryDomainRecommendationAgent'] = ($data['showSecondaryDomainRecommendationAgent']
132 + ?? self::$config['showSecondaryDomainRecommendationAgent']);
105 133 self::$config['domainTLDs'] = ($data['domainTLDs'] ?? self::$config['domainTLDs']);
106 134 self::$config['priorityDomainTLDs'] = ($data['priorityDomainTLDs']
107 135 ?? self::$config['priorityDomainTLDs']);
108 136 self::$config['stagingSites'] = array_map('trim', ($data['stagingSites'] ?? self::$config['stagingSites']));
137 + self::$config['trialDomains'] = array_map('trim', ($data['trialDomains'] ?? self::$config['trialDomains']));
109 138 self::$config['domainSearchURL'] = ($data['domainSearchURL'] ?? self::$config['domainSearchURL']);
110 139 self::$logo = isset($data['logo'][0]['thumbnails']['large']['url'])
111 140 ? $data['logo'][0]['thumbnails']['large']['url']
112 141 : self::$logo;
@@ -125,8 +154,9 @@
125 154 'secondaryColorText' => '#ffffff',
126 155 ];
127 156 self::$config['showAIPageCreation'] = ($data['showAIPageCreation'] ?? self::$config['showAIPageCreation']);
128 157 self::$config['showLaunch'] = ($data['showLaunch'] ?? self::$config['showLaunch']);
158 + self::$config['showLaunchTitle'] = ($data['showLaunchTitle'] ?? self::$config['showLaunchTitle']);
129 159 self::$config['deactivated'] = ($data['deactivated'] ?? self::$config['deactivated']);
130 160 self::$config['launchRedirectWebsite'] = ($data['launchRedirectWebsite']
131 161 ?? self::$config['launchRedirectWebsite']);
132 162 self::$config['showAILogo'] = ($data['showAILogo'] ?? self::$config['showAILogo']);
@@ -143,14 +173,29 @@
143 173 self::$config['license'] = ($data['license'] ?? self::$config['license']);
144 174 self::$config['showImprint'] = ($data['showImprint'] ?? self::$config['showImprint']);
145 175 self::$config['showLaunchQuestions'] = ($data['showLaunchQuestions'] ?? self::$config['showLaunchQuestions']);
146 176 self::$config['showAIAgents'] = ($data['showAIAgents'] ?? self::$config['showAIAgents']);
177 + self::$config['agentAbilitiesAllowlist'] = ($data['agentAbilitiesAllowlist']
178 + ?? self::$config['agentAbilitiesAllowlist']);
179 + self::$config['showQuickEdit'] = ($data['showQuickEdit'] ?? self::$config['showQuickEdit']);
180 + self::$config['showSimpleToolbar'] = ($data['showSimpleToolbar']
181 + ?? self::$config['showSimpleToolbar']);
147 182 self::$config['pluginGroupId'] = ($data['pluginGroup'] ?? self::$config['pluginGroupId']);
148 183 self::$config['requiredPlugins'] = ($data['requiredPlugins'] ?? self::$config['requiredPlugins']);
184 + self::$config['showProductActivation'] = ($data['showProductActivation']
185 + ?? self::$config['showProductActivation']);
149 186 self::$config['useAgentOnboarding'] = ($data['useAgentOnboarding'] ?? self::$config['useAgentOnboarding']);
150 187 self::$config['hidePluginNotifications'] = ($data['hidePluginNotifications']
151 188 ?? self::$config['hidePluginNotifications']);
152 189 self::$config['hideLaunchExitLink'] = ($data['hideLaunchExitLink'] ?? self::$config['hideLaunchExitLink']);
190 + self::$config['useAutoUpdate'] = ($data['useAutoUpdate'] ?? self::$config['useAutoUpdate']);
191 + self::$config['showLaunchUpdate'] = ($data['showLaunchUpdate'] ?? self::$config['showLaunchUpdate']);
192 + self::$config['activeTests'] = ($data['activeTests'] ?? self::$config['activeTests']);
193 + self::$config['showExtendifyCode'] = ($data['showExtendifyCode'] ?? self::$config['showExtendifyCode']);
194 + self::$config['useComingSoon'] = ($data['useComingSoon'] ?? self::$config['useComingSoon']);
195 + self::$config['extendifyCodeData'] = ($data['extendifyCodeData'] ?? self::$config['extendifyCodeData']);
196 + self::$config['customDesign'] = ($data['customDesign'] ?? self::$config['customDesign']);
197 + self::$config['strings'] = ($data['strings'] ?? self::$config['strings']);
153 198
154 199 // Add the job hook to fetch the partner data.
155 200 \add_action('extendify_fetch_partner_data', [self::class, 'fetchPartnerData']);
156 201 }
@@ -208,8 +253,9 @@
208 253 [
209 254 'partner' => self::$id,
210 255 'wp_language' => \get_locale(),
211 256 'site_url' => \home_url(),
257 + 'site_id' => \get_option('extendify_site_id', ''),
212 258 ],
213 259 Constants::DASHBOARD_HOST . '/api/onboarding/partner-data/'
214 260 );
215 261
@@ -233,9 +279,16 @@
233 279 }
234 280
235 281 $sanitizedData = array_merge(
236 282 Sanitizer::sanitizeUnknown($result['data']),
237 - ['consentTermsCustom' => \sanitize_text_field(htmlentities(($result['data']['consentTermsCustom'] ?? '')))]
283 + [
284 + 'consentTermsCustom' => \sanitize_text_field(htmlentities(
285 + ($result['data']['consentTermsCustom'] ?? ''),
286 + ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401
287 + )),
288 + 'customDesign' => self::sanitizeDesign($result['data']['customDesign'] ?? null),
289 + 'strings' => self::sanitizeStrings($result['data']['strings'] ?? null),
290 + ]
238 291 );
239 292
240 293 // Merge before persisting as this data is accessed directly elsewhere.
241 294 $mergedData = array_merge(self::$config, $sanitizedData);
@@ -241,8 +294,76 @@
241 294 $mergedData = array_merge(self::$config, $sanitizedData);
242 295 \update_option('extendify_partner_data_v2', $mergedData);
243 296
244 297 return $mergedData;
298 + }
299 +
300 + /**
301 + * Partner copy overriding the shipped strings.
302 + *
303 + * Which keys exist is the flow's to know, so only shape and text are checked here.
304 + *
305 + * @param mixed $strings The map as the partner-data response carried it.
306 + * @return array
307 + */
308 + public static function sanitizeStrings($strings)
309 + {
310 + return array_map(
311 + 'sanitize_text_field',
312 + self::designEntries($strings, '/^[a-zA-Z][a-zA-Z0-9]*$/', 'is_string')
313 + );
314 + }
315 +
316 + /**
317 + * A design carries GLSL, which the text sanitizers break, so only its shape is checked.
318 + *
319 + * Empty members are left out rather than kept: json_encode writes an empty
320 + * PHP array as [], and the page reads the design as an object.
321 + *
322 + * @param mixed $design The design as the partner-data response carried it.
323 + * @return array|null
324 + */
325 + private static function sanitizeDesign($design)
326 + {
327 + if (!is_array($design)) {
328 + return null;
329 + }
330 +
331 + $shader = ($design['shader'] ?? null);
332 + $logo = ($design['logo'] ?? null);
333 + $kept = array_filter([
334 + 'vars' => self::designEntries(
335 + ($design['vars'] ?? null),
336 + '/^--ext-(ui|tpl)-[a-z0-9-]+$/',
337 + function ($value) {
338 + // A CSS value is a string, but 0.88 is a natural way to write one.
339 + return is_string($value) || is_int($value) || is_float($value);
340 + }
341 + ),
342 + 'templates' => self::designEntries(($design['templates'] ?? null), '/^[A-Za-z0-9_-]+$/', 'is_string'),
343 + 'shader' => is_string($shader) ? \wp_check_invalid_utf8($shader) : '',
344 + 'logo' => is_string($logo) ? \esc_url_raw($logo) : '',
345 + ]);
346 +
347 + return $kept ?: null;
348 + }
349 +
350 + private static function designEntries($entries, $keyPattern, callable $accepts)
351 + {
352 + if (!is_array($entries)) {
353 + return [];
354 + }
355 +
356 + $kept = [];
357 + foreach ($entries as $key => $value) {
358 + if (!is_string($key) || !preg_match($keyPattern, $key) || !$accepts($value)) {
359 + continue;
360 + }
361 +
362 + $kept[$key] = is_string($value) ? \wp_check_invalid_utf8($value) : $value;
363 + }
364 +
365 + return $kept;
245 366 }
246 367
247 368 /**
248 369 * Return colors mapped as css variables