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 / PartnerData.php

PartnerData.php in Extendify 3.1.5, at app/PartnerData.php

345 lines 14.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The Partner Settings
5 */
6
7 namespace Extendify;
8
9 defined('ABSPATH') || die('No direct access.');
10
11 use Extendify\Constants;
12 use Extendify\Shared\Services\Sanitizer;
13
14 /**
15 * Controller for handling partner settings
16 */
17
18 class PartnerData
19 {
20 /**
21 * The partner id
22 *
23 * @var string
24 */
25 public static $id;
26
27 /**
28 * The partner logo
29 *
30 * @var string
31 */
32 public static $logo = '';
33
34 /**
35 * The partner display name
36 *
37 * @var string
38 */
39 public static $name = '';
40
41 /**
42 * The partner colors
43 *
44 * @var string
45 */
46 public static $colors = [];
47
48 /**
49 * The partner configuration.
50 *
51 * @var array
52 */
53 protected static $config = [
54 'showDomainBanner' => false,
55 'showDomainTask' => false,
56 'showSecondaryDomainBanner' => false,
57 'showSecondaryDomainTask' => false,
58 'showPrimaryDomainRecommendationAgent' => false,
59 'showSecondaryDomainRecommendationAgent' => false,
60 'domainTLDs' => ['com', 'net'],
61 'priorityDomainTLDs' => [],
62 'stagingSites' => ['wordpress'],
63 'domainSearchURL' => '',
64 'showDraft' => false,
65 'showChat' => false,
66 'showAIPageCreation' => false,
67 'enableImageImports-1-14-6' => false,
68 'disableLibraryAutoOpen' => false,
69 'enableApexDomain' => false,
70 'showLaunch' => false,
71 'showLaunchTitle' => false,
72 'deactivated' => true,
73 'launchRedirectWebsite' => false,
74 'showAILogo' => false,
75 'showProductRecommendations' => false,
76 'productRecommendations' => [
77 'showPartnerBranding' => false,
78 'disabledProducts' => [],
79 'customProducts' => [],
80 ],
81 'license' => 'active',
82 'showAIAgents' => false,
83 'agentAbilitiesAllowlist' => [],
84 'showQuickEdit' => false,
85 // Simple front-end Extendify toolbar (replaces WP core admin
86 // bar for editors who prefer it). Default style is Launch-aware
87 // (simple post-Launch, full before).
88 'showSimpleToolbar' => false,
89 'showImprint' => [],
90 'showLaunchQuestions' => false,
91 'pluginGroupId' => null,
92 'requiredPlugins' => null,
93 'showProductActivation' => [],
94 'useAgentOnboarding' => false,
95 'hidePluginNotifications' => false,
96 'hideLaunchExitLink' => false,
97 'useAutoUpdate' => false,
98 'showLaunchUpdate' => false,
99 'activeTests' => [],
100 'showExtendifyCode' => false,
101 'extendifyCodeData' => [
102 'link' => '',
103 'title' => '',
104 'message' => '',
105 'cta-primary' => '',
106 ],
107 ];
108
109 // phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
110 /**
111 * Set up and collect partner data
112 *
113 * @return void
114 */
115 public function __construct()
116 {
117 self::$id = defined('EXTENDIFY_PARTNER_ID') ? constant('EXTENDIFY_PARTNER_ID') : null;
118 $data = self::getPartnerData();
119 self::$config['showDomainBanner'] = ($data['showDomainBanner'] ?? self::$config['showDomainBanner']);
120 self::$config['showDomainTask'] = ($data['showDomainTask'] ?? self::$config['showDomainTask']);
121 self::$config['showSecondaryDomainTask'] = ($data['showSecondaryDomainTask']
122 ?? self::$config['showSecondaryDomainTask']);
123 self::$config['showSecondaryDomainBanner'] = ($data['showSecondaryDomainBanner']
124 ?? self::$config['showSecondaryDomainBanner']);
125 self::$config['showPrimaryDomainRecommendationAgent'] = ($data['showPrimaryDomainRecommendationAgent']
126 ?? self::$config['showPrimaryDomainRecommendationAgent']);
127 self::$config['showSecondaryDomainRecommendationAgent'] = ($data['showSecondaryDomainRecommendationAgent']
128 ?? self::$config['showSecondaryDomainRecommendationAgent']);
129 self::$config['domainTLDs'] = ($data['domainTLDs'] ?? self::$config['domainTLDs']);
130 self::$config['priorityDomainTLDs'] = ($data['priorityDomainTLDs']
131 ?? self::$config['priorityDomainTLDs']);
132 self::$config['stagingSites'] = array_map('trim', ($data['stagingSites'] ?? self::$config['stagingSites']));
133 self::$config['domainSearchURL'] = ($data['domainSearchURL'] ?? self::$config['domainSearchURL']);
134 self::$logo = isset($data['logo'][0]['thumbnails']['large']['url'])
135 ? $data['logo'][0]['thumbnails']['large']['url']
136 : self::$logo;
137 self::$config['showDraft'] = ($data['showDraft'] ?? self::$config['showDraft']);
138 self::$config['showChat'] = ($data['showChat'] ?? self::$config['showChat']);
139 self::$config['enableImageImports-1-14-6'] = ($data['enableImageImports-1-14-6']
140 ?? self::$config['enableImageImports-1-14-6']);
141 self::$config['disableLibraryAutoOpen'] = ($data['disableLibraryAutoOpen']
142 ?? self::$config['disableLibraryAutoOpen']);
143 self::$config['enableApexDomain'] = ($data['enableApexDomain'] ?? self::$config['enableApexDomain']);
144 self::$name = ($data['Name'] ?? self::$name);
145 self::$colors = [
146 'backgroundColor' => ($data['backgroundColor'] ?? null),
147 'foregroundColor' => ($data['foregroundColor'] ?? null),
148 'secondaryColor' => ($data['secondaryColor'] ?? ($data['backgroundColor'] ?? null)),
149 'secondaryColorText' => '#ffffff',
150 ];
151 self::$config['showAIPageCreation'] = ($data['showAIPageCreation'] ?? self::$config['showAIPageCreation']);
152 self::$config['showLaunch'] = ($data['showLaunch'] ?? self::$config['showLaunch']);
153 self::$config['showLaunchTitle'] = ($data['showLaunchTitle'] ?? self::$config['showLaunchTitle']);
154 self::$config['deactivated'] = ($data['deactivated'] ?? self::$config['deactivated']);
155 self::$config['launchRedirectWebsite'] = ($data['launchRedirectWebsite']
156 ?? self::$config['launchRedirectWebsite']);
157 self::$config['showAILogo'] = ($data['showAILogo'] ?? self::$config['showAILogo']);
158 self::$config['showProductRecommendations'] = ($data['showProductRecommendations']
159 ?? self::$config['showProductRecommendations']);
160 self::$config['productRecommendations'] = [
161 'showPartnerBranding' => ($data['productRecommendationShowPartnerBranding']
162 ?? self::$config['productRecommendations']['showPartnerBranding']),
163 'disabledProducts' => ($data['productRecommendationDisabledSlugs']
164 ?? self::$config['productRecommendations']['disabledProducts']),
165 'customProducts' => ($data['productRecommendationCustomSlugs']
166 ?? self::$config['productRecommendations']['customProducts']),
167 ];
168 self::$config['license'] = ($data['license'] ?? self::$config['license']);
169 self::$config['showImprint'] = ($data['showImprint'] ?? self::$config['showImprint']);
170 self::$config['showLaunchQuestions'] = ($data['showLaunchQuestions'] ?? self::$config['showLaunchQuestions']);
171 self::$config['showAIAgents'] = ($data['showAIAgents'] ?? self::$config['showAIAgents']);
172 self::$config['agentAbilitiesAllowlist'] = ($data['agentAbilitiesAllowlist']
173 ?? self::$config['agentAbilitiesAllowlist']);
174 self::$config['showQuickEdit'] = ($data['showQuickEdit'] ?? self::$config['showQuickEdit']);
175 self::$config['showSimpleToolbar'] = ($data['showSimpleToolbar']
176 ?? self::$config['showSimpleToolbar']);
177 self::$config['pluginGroupId'] = ($data['pluginGroup'] ?? self::$config['pluginGroupId']);
178 self::$config['requiredPlugins'] = ($data['requiredPlugins'] ?? self::$config['requiredPlugins']);
179 self::$config['showProductActivation'] = ($data['showProductActivation']
180 ?? self::$config['showProductActivation']);
181 self::$config['useAgentOnboarding'] = ($data['useAgentOnboarding'] ?? self::$config['useAgentOnboarding']);
182 self::$config['hidePluginNotifications'] = ($data['hidePluginNotifications']
183 ?? self::$config['hidePluginNotifications']);
184 self::$config['hideLaunchExitLink'] = ($data['hideLaunchExitLink'] ?? self::$config['hideLaunchExitLink']);
185 self::$config['useAutoUpdate'] = ($data['useAutoUpdate'] ?? self::$config['useAutoUpdate']);
186 self::$config['showLaunchUpdate'] = ($data['showLaunchUpdate'] ?? self::$config['showLaunchUpdate']);
187 self::$config['activeTests'] = ($data['activeTests'] ?? self::$config['activeTests']);
188 self::$config['showExtendifyCode'] = ($data['showExtendifyCode'] ?? self::$config['showExtendifyCode']);
189 self::$config['extendifyCodeData'] = ($data['extendifyCodeData'] ?? self::$config['extendifyCodeData']);
190
191 // Add the job hook to fetch the partner data.
192 \add_action('extendify_fetch_partner_data', [self::class, 'fetchPartnerData']);
193 }
194
195 /**
196 * Retrieve partner data from the options table or from the API.
197 *
198 * @return array
199 */
200 public static function getPartnerData()
201 {
202 // Do not make a request without a partner ID (i.e. it's opt in).
203 if (!defined('EXTENDIFY_PARTNER_ID')) {
204 return [];
205 }
206
207 $partnerData = \get_option('extendify_partner_data_v2', 'empty');
208 if ($partnerData !== 'empty') {
209 // We have data, but if it's been 10 minutes, check for new data.
210 $partnerRefresh = \get_transient('extendify_partner_data_cache_check');
211 if (!$partnerRefresh && \is_admin()) {
212 \add_action('init', function () {
213 if (!\wp_next_scheduled('extendify_fetch_partner_data')) {
214 \wp_schedule_single_event(time(), 'extendify_fetch_partner_data');
215 \spawn_cron();
216 }
217 });
218 }
219
220 return array_merge(self::$config, $partnerData);
221 }
222
223 $freshData = self::fetchPartnerData();
224 $mergedData = array_merge(self::$config, $freshData);
225 // Cache here even if empty [] to prevent multiple requests.
226 \update_option('extendify_partner_data_v2', $mergedData);
227 return $mergedData;
228 }
229
230 /**
231 * Fetch or refresh the partner data
232 *
233 * @return array
234 */
235 public static function fetchPartnerData()
236 {
237 if (!defined('EXTENDIFY_PARTNER_ID')) {
238 return [];
239 }
240
241 // Set a 10 minute transient to prevent multiple requests.
242 set_transient('extendify_partner_data_cache_check', true, (10 * MINUTE_IN_SECONDS));
243
244 $url = add_query_arg(
245 [
246 'partner' => self::$id,
247 'wp_language' => \get_locale(),
248 'site_url' => \home_url(),
249 'site_id' => \get_option('extendify_site_id', ''),
250 ],
251 Constants::DASHBOARD_HOST . '/api/onboarding/partner-data/'
252 );
253
254 $response = \wp_safe_remote_get($url, ['headers' => ['Accept' => 'application/json']]);
255
256 // If there was an error, we dont update the cache.
257 if (\is_wp_error($response) || \wp_remote_retrieve_response_code($response) !== 200) {
258 return [];
259 }
260
261 $result = json_decode(\wp_remote_retrieve_body($response), true);
262
263 // If the data didn't come back as we expected it to, or if we have an error, don't update the cache.
264 if (
265 json_last_error() !== JSON_ERROR_NONE
266 || !is_array($result)
267 || !array_key_exists('data', $result)
268 || empty($result['data'])
269 ) {
270 return [];
271 }
272
273 $sanitizedData = array_merge(
274 Sanitizer::sanitizeUnknown($result['data']),
275 ['consentTermsCustom' => \sanitize_text_field(htmlentities(
276 ($result['data']['consentTermsCustom'] ?? ''),
277 ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401
278 ))]
279 );
280
281 // Merge before persisting as this data is accessed directly elsewhere.
282 $mergedData = array_merge(self::$config, $sanitizedData);
283 \update_option('extendify_partner_data_v2', $mergedData);
284
285 return $mergedData;
286 }
287
288 /**
289 * Return colors mapped as css variables
290 *
291 * @return array
292 */
293 public static function cssVariableMapping()
294 {
295 $mapping = [
296 'backgroundColor' => '--ext-banner-main',
297 'foregroundColor' => '--ext-banner-text',
298 'secondaryColor' => '--ext-design-main',
299 'secondaryColorText' => '--ext-design-text',
300 ];
301
302 $cssVariables = [];
303 $adminTheme = \get_user_option('admin_color', get_current_user_id());
304 if (isset($GLOBALS['_wp_admin_css_colors'][$adminTheme])) {
305 $theme = $GLOBALS['_wp_admin_css_colors'][$adminTheme];
306 if (in_array($adminTheme, ['modern', 'blue'], true)) {
307 $cssVariables['--wp-admin-theme-main'] = $theme->colors[1];
308 $cssVariables['--wp-admin-theme-accent'] = $theme->colors[2];
309 } else {
310 $cssVariables['--wp-admin-theme-bg'] = $theme->colors[0];
311 $cssVariables['--wp-admin-theme-main'] = $theme->colors[2];
312 $cssVariables['--wp-admin-theme-accent'] = $theme->colors[3];
313 }
314 }
315
316 // Partner specific colors.
317 foreach ($mapping as $color => $variable) {
318 if (isset(self::$colors[$color])) {
319 $cssVariables[$variable] = self::$colors[$color];
320 }
321 }
322
323 return $cssVariables;
324 }
325
326 /**
327 * Retrieves the value of a setting.
328 *
329 * This method first checks if the setting exists as a static property of the class.
330 * If it does, it returns the value of that property. Otherwise, it looks for the
331 * setting in the config array and returns its value if found.
332 *
333 * @param string $settingKey The key of the setting to retrieve.
334 * @return mixed The value of the setting if found, or null if not found.
335 */
336 public static function setting($settingKey)
337 {
338 if (property_exists(self::class, $settingKey)) {
339 return self::$$settingKey;
340 }
341
342 return (self::$config[$settingKey] ?? null);
343 }
344 }
345