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/Shared/Admin.php +83 -2 3.1.1 → trunk View file →
@@ -9,14 +9,21 @@
9 9 defined('ABSPATH') || die('No direct access.');
10 10
11 11 use Extendify\Config;
12 12 use Extendify\PartnerData;
13 +use Extendify\Notifications\Availability;
13 14 use Extendify\Shared\Controllers\UserSelectionController;
15 +use Extendify\Shared\DataProvider\NotificationData;
14 16 use Extendify\Shared\DataProvider\ResourceData;
15 17 use Extendify\Shared\Services\AdminMenuList;
16 18 use Extendify\Shared\Services\ApexDomain\ApexDomain;
17 19 use Extendify\Shared\Services\Escaper;
18 20 use Extendify\Shared\Services\PluginDependencies\SimplyBook;
21 +use Extendify\Shared\Services\PluginsActivation\Imagify as ImagifyActivation;
22 +use Extendify\Shared\Services\PluginsActivation\Metricool as MetricoolActivation;
23 +use Extendify\Shared\Services\PluginsActivation\SimplyBook as SimplyBookActivation;
24 +use Extendify\Shared\Services\PluginsActivation\TranslatePress as TranslatePressActivation;
25 +use Extendify\Shared\Services\SiteImages;
19 26 use Extendify\SiteSettings;
20 27 use Extendify\Shared\Controllers\ImageGenerationController;
21 28 use Extendify\Shared\DataProvider\ProductsData;
22 29
@@ -153,8 +160,54 @@
153 160 return in_array($plugin['slug'], $activePluginSlugs);
154 161 }
155 162 );
156 163
164 + $activations = [
165 + ImagifyActivation::class,
166 + MetricoolActivation::class,
167 + SimplyBookActivation::class,
168 + TranslatePressActivation::class,
169 + ];
170 +
171 + $productActivationPlugins = array_map(function ($plugin) use ($activations) {
172 + foreach ($activations as $activation) {
173 + if ($plugin['slug'] === $activation::slug()) {
174 + return array_merge($plugin, [
175 + 'scriptData' => $activation::scriptData(),
176 + 'eligible' => $activation::isEligible(),
177 + 'endpoint' => Config::$slug . '/' . Config::$apiVersion
178 + . $activation::createAccountRoute(),
179 + ]);
180 + }
181 + }
182 +
183 + return $plugin;
184 + }, $productActivationPlugins);
185 +
186 + // Visitors read the stamp and the alt text, so both resolve in the site's locale.
187 + $switchedLocale = \switch_to_locale(\get_locale());
188 + // translators: Short label stamped onto an image marking it as AI-generated.
189 + // Give the all-caps form your language uses.
190 + $aiImageLabel = \_x('AI GENERATED', 'uppercase', 'extendify-local');
191 + // translators: %s is the image description. Alt text prefix marking an image as AI-generated.
192 + $aiImageAltPattern = \__('AI Generated: %s', 'extendify-local');
193 + if ($switchedLocale) {
194 + \restore_previous_locale();
195 + }
196 +
197 + $extendifyCodeData = (array) PartnerData::setting('extendifyCodeData');
198 +
199 + // esc_url() strips the {DESCRIPTION} braces; shield the placeholder across it.
200 + $extendifyCodeLink = str_replace(
201 + '__EXTENDIFY_DESCRIPTION__',
202 + '{DESCRIPTION}',
203 + \esc_url_raw(str_replace(
204 + '{DESCRIPTION}',
205 + '__EXTENDIFY_DESCRIPTION__',
206 + (string) ($extendifyCodeData['link'] ?? '')
207 + ))
208 + );
209 +
157 210 \wp_add_inline_script(
158 211 Config::$slug . '-shared-scripts',
159 212 'window.extSharedData = ' . \wp_json_encode([
160 213 'root' => \esc_url_raw(rest_url(Config::$slug . '/' . Config::$apiVersion)),
@@ -168,9 +221,13 @@
168 221 'themeSlug' => \esc_attr(\get_option('stylesheet')),
169 222 'version' => \esc_attr(Config::$version),
170 223 'siteTitle' => \esc_attr(\get_bloginfo('name')),
171 224 'siteProfile' => \get_option('extendify_site_profile', []),
225 + // Empty when the launch-time image fetch failed.
226 + 'siteImages' => SiteImages::normalize(\get_option('extendify_site_images', [])),
172 227 'wpLanguage' => \esc_attr(\get_locale()),
228 + 'aiImageLabel' => $aiImageLabel,
229 + 'aiImageAltPattern' => $aiImageAltPattern,
173 230 'wpVersion' => \esc_attr(\get_bloginfo('version')),
174 231 'isBlockTheme' => function_exists('wp_is_block_theme') ? (bool) wp_is_block_theme() : false,
175 232 'userId' => \esc_attr(\get_current_user_id()),
176 233 // phpcs:ignore WordPress.Security.NonceVerification
@@ -181,8 +238,16 @@
181 238 'partnerId' => \esc_attr(PartnerData::$id),
182 239 'partnerName' => \esc_attr(PartnerData::$name),
183 240 'launchDataLegacy' => \wp_json_encode((UserSelectionController::get()->get_data() ?? [])),
184 241 'resourceData' => \wp_json_encode((new ResourceData())->getData()),
242 + 'notifications' => \wp_json_encode(
243 + Availability::available(NotificationData::get())
244 + ),
245 + 'notificationState' => \get_user_meta(
246 + \get_current_user_id(),
247 + 'extendify_notification_state',
248 + true
249 + ) ?: ['cards' => []],
185 250 'showAIConsent' => isset($partnerData['showAIConsent']) ? (bool) $partnerData['showAIConsent'] : false,
186 251 'showChat' => (bool) (PartnerData::setting('showChat') || constant('EXTENDIFY_DEVMODE')),
187 252 'useAgentOnboarding' => (bool) (
188 253 PartnerData::setting('useAgentOnboarding') ||
@@ -194,10 +259,12 @@
194 259 ),
195 260 'showAILogo' => (bool) PartnerData::setting('showAILogo'),
196 261 'showImprint' => array_map('esc_attr', (array) PartnerData::setting('showImprint')),
197 262 'showProductActivation' => array_values($productActivationPlugins),
198 - 'consentTermsCustom' => \wp_kses((html_entity_decode(($partnerData['consentTermsCustom'] ?? ''))
199 - ?? ''), $htmlAllowlist),
263 + 'consentTermsCustom' => \wp_kses((html_entity_decode(
264 + ($partnerData['consentTermsCustom'] ?? ''),
265 + ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401
266 + ) ?? ''), $htmlAllowlist),
200 267 'userGaveConsent' => $userConsent ? (bool) $userConsent : false,
201 268 'installedPlugins' => array_map('esc_attr', array_keys(\get_plugins())),
202 269 'activePlugins' => $activePlugins,
203 270 'installedPluginsSlugs' => array_values(array_filter(array_map(function ($p) {
@@ -218,8 +285,15 @@
218 285 PartnerData::setting('showLaunchQuestions') || Config::preview('launch-questions')
219 286 ),
220 287 'products' => ProductsData::get(),
221 288 'showAIAgents' => (bool) (PartnerData::setting('showAIAgents') || Config::preview('ai-agent')),
289 + 'showExtendifyCode' => (bool) PartnerData::setting('showExtendifyCode'),
290 + 'extendifyCodeData' => [
291 + 'link' => $extendifyCodeLink,
292 + 'title' => $extendifyCodeData['title'] ?? '',
293 + 'message' => $extendifyCodeData['message'] ?? '',
294 + 'ctaPrimary' => $extendifyCodeData['cta-primary'] ?? '',
295 + ],
222 296 'pluginGroupId' => Escaper::recursiveEscAttr(PartnerData::setting('pluginGroupId')),
223 297 'adminPagesMenuList' => get_option('_transient_extendify_admin_pages_menu', []),
224 298 'globalState' => ImageGenerationController::get()->get_data(),
225 299 ]),
@@ -263,8 +337,15 @@
263 337 'type' => 'boolean',
264 338 'show_in_rest' => true,
265 339 ]);
266 340 register_post_meta('post', 'made_with_extendify_launch', [
341 + 'single' => true,
342 + 'type' => 'boolean',
343 + 'show_in_rest' => true,
344 + ]);
345 +
346 + // Marks AI-generated images for EU AI Act disclosure.
347 + register_post_meta('attachment', 'extendify_ai_generated', [
267 348 'single' => true,
268 349 'type' => 'boolean',
269 350 'show_in_rest' => true,
270 351 ]);