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 +63 -2 3.1.33.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,41 @@
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 +
157 197 $extendifyCodeData = (array) PartnerData::setting('extendifyCodeData');
158 198
159 199 // esc_url() strips the {DESCRIPTION} braces; shield the placeholder across it.
160 200 $extendifyCodeLink = str_replace(
@@ -181,9 +221,13 @@
181 221 'themeSlug' => \esc_attr(\get_option('stylesheet')),
182 222 'version' => \esc_attr(Config::$version),
183 223 'siteTitle' => \esc_attr(\get_bloginfo('name')),
184 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', [])),
185 227 'wpLanguage' => \esc_attr(\get_locale()),
228 + 'aiImageLabel' => $aiImageLabel,
229 + 'aiImageAltPattern' => $aiImageAltPattern,
186 230 'wpVersion' => \esc_attr(\get_bloginfo('version')),
187 231 'isBlockTheme' => function_exists('wp_is_block_theme') ? (bool) wp_is_block_theme() : false,
188 232 'userId' => \esc_attr(\get_current_user_id()),
189 233 // phpcs:ignore WordPress.Security.NonceVerification
@@ -194,8 +238,16 @@
194 238 'partnerId' => \esc_attr(PartnerData::$id),
195 239 'partnerName' => \esc_attr(PartnerData::$name),
196 240 'launchDataLegacy' => \wp_json_encode((UserSelectionController::get()->get_data() ?? [])),
197 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' => []],
198 250 'showAIConsent' => isset($partnerData['showAIConsent']) ? (bool) $partnerData['showAIConsent'] : false,
199 251 'showChat' => (bool) (PartnerData::setting('showChat') || constant('EXTENDIFY_DEVMODE')),
200 252 'useAgentOnboarding' => (bool) (
201 253 PartnerData::setting('useAgentOnboarding') ||
@@ -207,10 +259,12 @@
207 259 ),
208 260 'showAILogo' => (bool) PartnerData::setting('showAILogo'),
209 261 'showImprint' => array_map('esc_attr', (array) PartnerData::setting('showImprint')),
210 262 'showProductActivation' => array_values($productActivationPlugins),
211 - 'consentTermsCustom' => \wp_kses((html_entity_decode(($partnerData['consentTermsCustom'] ?? ''))
212 - ?? ''), $htmlAllowlist),
263 + 'consentTermsCustom' => \wp_kses((html_entity_decode(
264 + ($partnerData['consentTermsCustom'] ?? ''),
265 + ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401
266 + ) ?? ''), $htmlAllowlist),
213 267 'userGaveConsent' => $userConsent ? (bool) $userConsent : false,
214 268 'installedPlugins' => array_map('esc_attr', array_keys(\get_plugins())),
215 269 'activePlugins' => $activePlugins,
216 270 'installedPluginsSlugs' => array_values(array_filter(array_map(function ($p) {
@@ -283,8 +337,15 @@
283 337 'type' => 'boolean',
284 338 'show_in_rest' => true,
285 339 ]);
286 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', [
287 348 'single' => true,
288 349 'type' => 'boolean',
289 350 'show_in_rest' => true,
290 351 ]);