PluginProbe
Extendify / 3.2.1
Extendify v3.2.1
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.03.2.1 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 ]);