PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / 2.7.9
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts v2.7.9
2.7.9 2.7.8 2.7.7 2.7.6 2.7.5 2.7.4 trunk 1.3 2.0.4 2.0.6 2.1.91 2.2.4 2.2.7 2.2.9 2.3.1 2.3.10 2.4.10 2.4.2 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.6.0 All 30 releases
← All changes | vendor/codeinwp/themeisle-sdk/src/Loader.php +185 -17 2.6.0 → 2.7.9 View file →
@@ -45,8 +45,9 @@
45 45 *
46 46 * @var array The modules which SDK will be using.
47 47 */
48 48 private static $available_modules = [
49 + 'crash_reporter',
49 50 'script_loader',
50 51 'dashboard_widget',
51 52 'rollback',
52 53 'uninstall_feedback',
@@ -63,8 +64,10 @@
63 64 'about_us',
64 65 'announcements',
65 66 'featured_plugins',
66 67 'float_widget',
68 + 'migrator',
69 + 'ai_connect',
67 70 ];
68 71 /**
69 72 * Holds the labels for the modules.
70 73 *
@@ -71,12 +74,13 @@
71 74 * @var array The labels for the modules.
72 75 */
73 76 public static $labels = [
74 77 'announcements' => [
75 - 'notice_link_label' => 'See the Offer',
76 - 'max_savings' => 'Our biggest sale of the year: <strong>%s OFF everything!</strong> Don\'t miss this limited-time offer.',
77 - 'black_friday' => 'Black Friday Sale',
78 - 'time_left' => '%s left',
78 + 'notice_link_label' => 'See the deals',
79 + 'max_savings' => 'Best WordPress Black Friday deals of %s — themes, plugins, hosting. Curated by the Themeisle team.',
80 + 'black_friday' => 'Black Friday Sale',
81 + 'time_left' => '%s left',
82 + 'plugin_meta_message' => 'Black Friday Sale - 60% OFF',
79 83 ],
80 84 'compatibilities' => [
81 85 'notice' => '%s requires a newer version of %s. Please %supdate%s %s %s to the latest version.',
82 86 'notice2' => '%s update requires a newer version of %s. Please %supdate%s %s %s.',
@@ -107,12 +111,16 @@
107 111 'autoactivate_notice' => '%s has been successfully activated using %s license !',
108 112 'valid' => 'Valid',
109 113 'invalid' => 'Invalid',
110 114 'notice' => 'Enter your license from %s purchase history in order to get %s updates',
111 - 'expired' => 'Your %s\'s License Key has expired. In order to continue receiving support and software updates you must %srenew%s your license key.',
115 + 'expired' => '%s license expired',
116 + 'expired_date' => 'Expired on %s',
117 + 'expired_notice' => 'Your current setup continues working, but premium features are disabled and you\'re no longer receive updates - including critical patches - or support.',
112 118
113 119 'inactive' => 'In order to benefit from updates and support for %s, please add your license code from your %spurchase history%s and validate it %shere%s.',
114 120 'no_activations' => 'No more activations left for %s. You need to upgrade your plan in order to use %s on more websites. If you need assistance, please get in touch with %s staff.',
121 + 'renew_license' => 'Renew License',
122 + 'learn_more' => 'Learn More',
115 123 ],
116 124 'promotions' => [
117 125 'recommended' => 'Recommended by %s',
118 126 'installActivate' => 'Install & Activate',
@@ -177,8 +185,14 @@
177 185 'install' => 'Install Masteriyo',
178 186 'dismisscta' => 'Dismiss this notice.',
179 187 'message' => 'Transform your site into a learning hub with Masteriyo LMS. Build engaging courses with intuitive tools, track student progress effortlessly, and grow your education business with powerful marketing features and seamless payment integration.',
180 188 ],
189 + 'easy_mcp' => [
190 + 'gotodash' => 'Go to Easy MCP Dashboard',
191 + 'install' => 'Install Easy MCP AI',
192 + 'dismisscta' => 'Dismiss this notice.',
193 + 'message' => 'Connect Claude, ChatGPT, and other AI assistants to this site with Easy MCP AI — a free MCP server that lets your AI manage content, media, and SEO data, with per-scope permissions and a full audit trail.',
194 + ],
181 195 ],
182 196 'welcome' => [
183 197 'ctan' => 'No, thanks.',
184 198 'ctay' => 'Upgrade Now!',
@@ -191,13 +205,14 @@
191 205 'cta_info' => 'What info do we collect?',
192 206 'button_submit' => 'Submit &amp; Deactivate',
193 207 'button_cancel' => 'Skip &amp; Deactivate',
194 208 'disclosure' => [
195 - 'title' => 'Below is a detailed view of all data that Themeisle will receive if you fill in this survey. No email address or IP addresses are transmitted after you submit the survey.',
196 - 'version' => '%s %s version %s %s %s %s',
197 - 'website' => '%sCurrent website:%s %s %s %s',
198 - 'usage' => '%sUsage time:%s %s %s%s',
199 - 'reason' => '%s Uninstall reason %s %s Selected reason from the above survey %s ',
209 + 'title' => 'Below is a detailed view of all data that Themeisle will receive if you fill in this survey. No email address or IP addresses are transmitted after you submit the survey.',
210 + 'version' => '%s %s version %s %s %s %s',
211 + 'website' => '%sCurrent website:%s %s %s %s',
212 + 'usage' => '%sUsage time:%s %s %s%s',
213 + 'reason' => '%s Uninstall reason %s %s Selected reason from the above survey %s ',
214 + 'diagnostics' => '%sCrash diagnostics:%s Anonymized technical details of errors recorded for this product, if any.',
200 215 ],
201 216
202 217 'options' => [
203 218 'id3' => [
@@ -248,11 +263,11 @@
248 263 'rollback' => [
249 264 'cta' => 'Rollback to v%s',
250 265 ],
251 266 'logger' => [
252 - 'notice' => 'Do you enjoy <b>{product}</b>? Become a contributor by opting in to our anonymous data tracking. We guarantee no sensitive data is collected.',
253 - 'cta_y' => 'Sure, I would love to help.',
254 - 'cta_n' => 'No, thanks.',
267 + 'notice' => 'Help improve <b>{product}</b> by sharing anonymous usage data about your setup. No personal data collected.',
268 + 'cta_y' => 'Count me in',
269 + 'cta_n' => 'No thanks',
255 270 ],
256 271 'about_us' => [
257 272 'title' => 'About Us',
258 273 'heroHeader' => 'Our Story',
@@ -261,8 +276,44 @@
261 276 'teamImageCaption' => 'Our team in WCEU2022 in Portugal',
262 277 'newsHeading' => 'Stay connected for news & updates!',
263 278 'emailPlaceholder' => 'Your email address',
264 279 'signMeUp' => 'Sign me up',
280 + 'services' => [
281 + 'ariaLabel' => 'Themeisle services',
282 + 'trustpilotLabel' => 'Rated excellent on Trustpilot',
283 + 'trustpilotRated' => 'Rated',
284 + 'trustpilotOn' => 'on',
285 + 'trustpilotBrand' => 'Trustpilot',
286 + 'heading' => 'Expert WordPress services from the Themeisle team',
287 + 'description' => 'Done for you by the same people who build your plugins and themes.',
288 + 'cta' => 'Explore all services',
289 + 'items' => [
290 + 'websiteDesign' => [
291 + 'title' => 'Website Design',
292 + 'subtitle' => 'Built for your business',
293 + ],
294 + 'support' => [
295 + 'title' => 'Support',
296 + 'subtitle' => 'On-demand expert help',
297 + ],
298 + 'speed' => [
299 + 'title' => 'Speed Optimization',
300 + 'subtitle' => 'Core Web Vitals boost',
301 + ],
302 + 'seo' => [
303 + 'title' => 'SEO Foundation',
304 + 'subtitle' => 'Rank & get found',
305 + ],
306 + 'maintenance' => [
307 + 'title' => 'Maintenance',
308 + 'subtitle' => 'Updates, backups, security',
309 + ],
310 + 'hackedSite' => [
311 + 'title' => 'Hacked Site Repair',
312 + 'subtitle' => 'Malware removed fast',
313 + ],
314 + ],
315 + ],
265 316 'installNow' => 'Install Now',
266 317 'activate' => 'Activate',
267 318 'learnMore' => 'Learn More',
268 319 'installed' => 'Installed',
@@ -308,8 +359,46 @@
308 359 ],
309 360 ],
310 361 ],
311 362 ],
363 + 'ai_connect' => [
364 + 'row_link' => 'Connect with your AI agent',
365 + // translators: %s is the product name.
366 + 'notice_title' => 'Manage %s with your AI agent.',
367 + // translators: %s is a list of things the agent can do, e.g. "optimize new uploads, purge cached images or offload originals".
368 + 'notice_text' => 'Ask Claude, ChatGPT or Cursor to %s.',
369 + // translators: 1: comma-separated use cases, 2: the last use case.
370 + 'cases_join' => '%1$s or %2$s',
371 + 'notice_button' => 'Connect your AI agent',
372 + 'eyebrow' => 'Works with Claude, ChatGPT, Cursor and any MCP agent',
373 + // translators: %s is the product name.
374 + 'title' => 'Use %s from your AI agent',
375 + // translators: %s is the product name.
376 + 'lead' => 'Activate your site’s MCP URL, connect the agent you already use, and %s becomes something you can simply ask for.',
377 + 'enable' => 'Install and activate Easy MCP',
378 + 'enable_installed' => 'Activate Easy MCP',
379 + 'enabling' => 'Installing…',
380 + 'activating' => 'Activating…',
381 + 'enabled' => 'Easy MCP is active',
382 + // translators: %s is the product name.
383 + 'enable_note' => 'Easy MCP is free, by the %s team. It enables your site’s MCP URL.',
384 + 'url_label' => 'Your site’s MCP URL',
385 + 'copy' => 'Copy',
386 + 'copied' => 'Copied',
387 + 'close' => 'Close',
388 + 'connect_heading' => 'Connect your agent',
389 + 'connect_claude' => 'Connect to Claude',
390 + 'connect_chatgpt' => 'Connect to ChatGPT',
391 + 'connect_cursor' => 'Add to Cursor',
392 + 'hint_off' => 'Your agents can connect once Easy MCP is active.',
393 + 'hint_on' => 'Each button opens your agent with this site pre-filled. ChatGPT asks you to paste the URL above.',
394 + 'more_agents' => 'Using another agent?',
395 + 'more_agents_link' => 'See how to connect it.',
396 + 'prompts_off' => 'Once Easy MCP is active, you can ask your AI agent things like',
397 + 'prompts_on' => 'Try asking',
398 + 'error_permission' => 'You are not allowed to do this.',
399 + 'error_install' => 'Easy MCP could not be activated. Please try again.',
400 + ],
312 401 'float_widget' => [
313 402 'button' => 'Toggle Help Widget for %s',
314 403 'panel' => [
315 404 'greeting' => 'Thank you for using %s',
@@ -330,12 +419,9 @@
330 419 /**
331 420 * Initialize the sdk logic.
332 421 */
333 422 public static function init() {
334 - /**
335 - * This filter can be used to localize the labels inside each product.
336 - */
337 - self::$labels = apply_filters( 'themeisle_sdk_labels', self::$labels );
423 + self::localize_labels();
338 424 if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Loader ) ) {
339 425 self::$instance = new Loader();
340 426 $modules = array_merge( self::$available_modules, apply_filters( 'themeisle_sdk_modules', [] ) );
341 427 foreach ( $modules as $key => $module ) {
@@ -345,9 +431,91 @@
345 431 }
346 432 self::$available_modules = $modules;
347 433
348 434 add_action( 'themeisle_sdk_first_activation', array( __CLASS__, 'activate' ) );
435 +
349 436 }
437 + }
438 +
439 + /**
440 + * Localize the labels.
441 + */
442 + public static function localize_labels() {
443 + $originals = self::$labels;
444 + $all_translations = [];
445 +
446 + global $wp_filter;
447 + if ( isset( $wp_filter['themeisle_sdk_labels'] ) ) {
448 + foreach ( $wp_filter['themeisle_sdk_labels']->callbacks as $priority => $hooks ) {
449 + foreach ( $hooks as $hook ) {
450 + // Each callback gets fresh originals, not previous callback's output
451 + $result = call_user_func( $hook['function'], $originals );
452 + $all_translations[] = $result;
453 + }
454 + }
455 +
456 + // Remove the filter so it doesn't run again via apply_filters
457 + remove_all_filters( 'themeisle_sdk_labels' );
458 + }
459 +
460 + // Merge all results, first real translation wins
461 + self::$labels = self::merge_all_translations( $originals, $all_translations );
462 + }
463 + /**
464 + * Merge all translations.
465 + *
466 + * @param array $originals The original labels.
467 + * @param array $all_translations The all translations.
468 + *
469 + * @return array The merged labels.
470 + */
471 + private static function merge_all_translations( $originals, $all_translations ) {
472 + $result = $originals;
473 +
474 + foreach ( $all_translations as $translations ) {
475 + $result = self::merge_if_translated( $result, $translations, $originals );
476 + }
477 +
478 + return $result;
479 + }
480 + /**
481 + * Merge if translated.
482 + *
483 + * @param array $current The current labels.
484 + * @param array $new The new labels.
485 + * @param array $originals The original labels.
486 + * @return array The merged labels.
487 + */
488 + private static function merge_if_translated( $current, $new, $originals ) {
489 + foreach ( $new as $key => $value ) {
490 + if ( ! isset( $originals[ $key ] ) ) {
491 + // New key, accept it
492 + if ( ! isset( $current[ $key ] ) ) {
493 + $current[ $key ] = $value;
494 + }
495 + continue;
496 + }
497 +
498 + if ( is_array( $value ) && is_array( $originals[ $key ] ) ) {
499 + $current[ $key ] = self::merge_if_translated(
500 + $current[ $key ],
501 + $value,
502 + $originals[ $key ]
503 + );
504 + } else {
505 + // Only accept if:
506 + // 1. New value is actually translated (differs from original)
507 + // 2. Current value is NOT already translated
508 + $is_new_translated = ( $value !== $originals[ $key ] );
509 + $is_current_untranslated = ( $current[ $key ] === $originals[ $key ] );
510 +
511 + if ( $is_new_translated && $is_current_untranslated ) {
512 + $current[ $key ] = $value;
513 + }
514 + }
515 + }
516 +
517 + return $current;
350 518 }
351 519
352 520 /**
353 521 * Get cache token used in API requests.