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 +63 -2 3.1.3 → 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,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 ]);