PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 4.0.9
Visualizer – Tables & Charts Manager with Built-in AI Generator v4.0.9
4.0.9 4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 All 150 releases
← All changes | vendor/codeinwp/themeisle-sdk/src/Modules/About_us.php +141 -10 3.10.13 → 4.0.9 View file →
@@ -13,8 +13,9 @@
13 13 * 'page_menu' => [['text' => '', 'url' => '']], // optional
14 14 * 'has_upgrade_menu' => <condition>,
15 15 * 'upgrade_link' => <url>,
16 16 * 'upgrade_text' => 'Get Pro Version',
17 + * 'review_link' => false, // Leave it empty for default WPorg link or false to hide it.
17 18 * ]
18 19 * }
19 20 *
20 21 * @package ThemeIsleSDK
@@ -39,8 +40,42 @@
39 40 * Promotions module for ThemeIsle SDK.
40 41 */
41 42 class About_Us extends Abstract_Module {
42 43 /**
44 + * Sort weight for products that are not explicitly ranked.
45 + *
46 + * @var int
47 + */
48 + const SORT_WEIGHT_UNRANKED = 99;
49 +
50 + /**
51 + * Hand-picked display order for featured products, keyed by WP.org slug.
52 + *
53 + * @var array
54 + */
55 + const COMMON_PRODUCTS_PRIORITY = [
56 + 'neve' => 0,
57 + 'otter-blocks' => 1,
58 + 'wp-cloudflare-page-cache' => 2,
59 + 'optimole-wp' => 3,
60 + 'hyve-lite' => 4,
61 + 'wp-full-stripe-free' => 5,
62 + 'insert-php' => 6, // Woody plugin slug on WP.org.
63 + 'anti-spam' => 7, // Titan Anti-spam & Security plugin slug on WP.org.
64 + ];
65 +
66 + /**
67 + * Sort weight per install status, lowest shows first.
68 + *
69 + * @var array
70 + */
71 + const STATUS_PRIORITY = [
72 + 'not-installed' => 0,
73 + 'installed' => 1,
74 + 'active' => 2,
75 + ];
76 +
77 + /**
43 78 * About data.
44 79 *
45 80 * @var array $about_data About page data, received from the filter.
46 81 *
@@ -94,8 +129,11 @@
94 129 if ( ! isset( $this->about_data['location'] ) ) {
95 130 return;
96 131 }
97 132
133 + // Refresh the about data to get the latest changes.
134 + $this->about_data = apply_filters( $this->product->get_key() . '_about_us_metadata', array() );
135 +
98 136 add_submenu_page(
99 137 $this->about_data['location'],
100 138 Loader::$labels['about_us']['title'],
101 139 Loader::$labels['about_us']['title'],
@@ -123,14 +161,35 @@
123 161
124 162 add_submenu_page(
125 163 $this->about_data['location'],
126 164 $this->about_data['upgrade_text'],
127 - $this->about_data['upgrade_text'],
165 + '<span class="tsdk-upg-menu-item">' . $this->about_data['upgrade_text'] . '</span>',
128 166 'manage_options',
129 167 $this->about_data['upgrade_link'],
130 168 '',
131 169 101
132 170 );
171 + add_action(
172 + 'admin_footer',
173 + function () {
174 + ?>
175 + <style>
176 + .tsdk-upg-menu-item {
177 + color: #009528;
178 + }
179 +
180 + .tsdk-upg-menu-item:hover {
181 + color: #008a20;
182 + }
183 + </style>
184 + <script type="text/javascript">
185 + jQuery(document).ready(function ($) {
186 + $('.tsdk-upg-menu-item').parent().attr('target', '_blank');
187 + });
188 + </script>
189 + <?php
190 + }
191 + );
133 192 }
134 193
135 194 /**
136 195 * Render page content.
@@ -160,8 +219,10 @@
160 219 $handle = 'ti-sdk-about-' . $this->product->get_key();
161 220 $asset_file = require $themeisle_sdk_max_path . '/assets/js/build/about/about.asset.php';
162 221 $deps = array_merge( $asset_file['dependencies'], [ 'updates' ] );
163 222
223 + do_action( 'themeisle_internal_page', $this->product->get_slug(), 'about_us' );
224 +
164 225 wp_register_script( $handle, $this->get_sdk_uri() . 'assets/js/build/about/about.js', $deps, $asset_file['version'], true );
165 226 wp_localize_script( $handle, 'tiSDKAboutData', $this->get_about_localization_data() );
166 227
167 228 wp_enqueue_script( $handle );
@@ -175,8 +236,9 @@
175 236 */
176 237 private function get_about_localization_data() {
177 238 $links = isset( $this->about_data['page_menu'] ) ? $this->about_data['page_menu'] : [];
178 239 $product_pages = isset( $this->about_data['product_pages'] ) ? $this->about_data['product_pages'] : [];
240 + $page_slug = $this->get_about_page_slug();
179 241
180 242 return [
181 243 'links' => $links,
182 244 'logoUrl' => $this->about_data['logo'],
@@ -181,10 +243,19 @@
181 243 'links' => $links,
182 244 'logoUrl' => $this->about_data['logo'],
183 245 'productPages' => $this->get_product_pages_data( $product_pages ),
184 246 'products' => $this->get_other_products_data(),
247 + 'services' => [
248 + 'websiteDesignUrl' => tsdk_utmify( 'https://themeisle.com/wordpress-website-design/', 'services-website-design', $page_slug ),
249 + 'supportUrl' => tsdk_utmify( 'https://themeisle.com/wordpress-support/', 'services-support', $page_slug ),
250 + 'speedUrl' => tsdk_utmify( 'https://themeisle.com/wordpress-speed-optimization/', 'services-speed-optimization', $page_slug ),
251 + 'seoFoundationUrl' => tsdk_utmify( 'https://themeisle.com/wordpress-seo-foundation/', 'services-seo-foundation', $page_slug ),
252 + 'maintenanceUrl' => tsdk_utmify( 'https://themeisle.com/wordpress-maintenance/', 'services-maintenance', $page_slug ),
253 + 'hackedRepairUrl' => tsdk_utmify( 'https://themeisle.com/wordpress-hacked-site-repair/', 'services-hacked-site-repair', $page_slug ),
254 + 'exploreAllUrl' => tsdk_utmify( 'https://themeisle.com/services/', 'services-explore-all', $page_slug ),
255 + ],
185 256 'homeUrl' => esc_url( home_url() ),
186 - 'pageSlug' => $this->get_about_page_slug(),
257 + 'pageSlug' => $page_slug,
187 258 'currentProduct' => [
188 259 'slug' => $this->product->get_key(),
189 260 'name' => $this->product->get_name(),
190 261 ],
@@ -197,8 +268,9 @@
197 268 'teamImageCaption' => Loader::$labels['about_us']['teamImageCaption'],
198 269 'newsHeading' => Loader::$labels['about_us']['newsHeading'],
199 270 'emailPlaceholder' => Loader::$labels['about_us']['emailPlaceholder'],
200 271 'signMeUp' => Loader::$labels['about_us']['signMeUp'],
272 + 'services' => Loader::$labels['about_us']['services'],
201 273 'installNow' => Loader::$labels['about_us']['installNow'],
202 274 'activate' => Loader::$labels['about_us']['activate'],
203 275 'learnMore' => Loader::$labels['about_us']['learnMore'],
204 276 'installed' => Loader::$labels['about_us']['installed'],
@@ -206,8 +278,9 @@
206 278 'active' => Loader::$labels['about_us']['active'],
207 279 ],
208 280 'canInstallPlugins' => current_user_can( 'install_plugins' ),
209 281 'canActivatePlugins' => current_user_can( 'activate_plugins' ),
282 + 'showReviewLink' => ! ( isset( $this->about_data['review_link'] ) && false === $this->about_data['review_link'] ),
210 283 ];
211 284 }
212 285
213 286 /**
@@ -236,11 +309,11 @@
236 309 'strings' => [
237 310 'heading' => Loader::$labels['about_us']['otter-page']['heading'],
238 311 'text' => Loader::$labels['about_us']['otter-page']['text'],
239 312 'buttons' => [
240 - 'install_otter_free' => Loader::$labels['about_us']['otter-page']['install_otter_free'],
241 - 'install_now' => Loader::$labels['about_us']['otter-page']['install_now'],
242 - 'learn_more' => Loader::$labels['about_us']['otter-page']['learn_more'],
313 + 'install_otter_free' => Loader::$labels['about_us']['otter-page']['buttons']['install_otter_free'],
314 + 'install_now' => Loader::$labels['about_us']['otter-page']['buttons']['install_now'],
315 + 'learn_more' => Loader::$labels['about_us']['otter-page']['buttons']['learn_more'],
243 316 'learn_more_link' => tsdk_utmify( 'https://themeisle.com/plugins/otter-blocks/', 'otter-page', 'about-us' ),
244 317 ],
245 318 'features' => [
246 319 'advancedTitle' => Loader::$labels['about_us']['otter-page']['features']['advancedTitle'],
@@ -312,17 +385,29 @@
312 385 'name' => 'Neve',
313 386 'description' => Loader::$labels['about_us']['others']['neve_desc'],
314 387 'icon' => $this->get_sdk_uri() . 'assets/images/neve.png',
315 388 ],
389 + 'learning-management-system' => [
390 + 'name' => 'Masteriyo LMS',
391 + ],
316 392 'otter-blocks' => [
317 393 'name' => 'Otter',
318 394 ],
319 395 'tweet-old-post' => [
320 - 'name' => 'Revive Old Post',
396 + 'name' => 'Revive Social',
321 397 ],
322 398 'feedzy-rss-feeds' => [
323 399 'name' => 'Feedzy',
324 400 ],
401 + 'insert-php' => [
402 + 'name' => 'Woody Code Snippets',
403 + ],
404 + 'wpcf7-redirect' => [
405 + 'name' => 'Redirection for Contact Form 7',
406 + ],
407 + 'anti-spam' => [
408 + 'name' => 'Titan Anti-spam & Security',
409 + ],
325 410 'woocommerce-product-addon' => [
326 411 'name' => 'PPOM',
327 412 'condition' => class_exists( 'WooCommerce', false ),
328 413 ],
@@ -350,8 +435,20 @@
350 435 'templates-patterns-collection' => [
351 436 'name' => 'Templates Cloud',
352 437 'description' => Loader::$labels['about_us']['others']['tpc_desc'],
353 438 ],
439 + 'wp-cloudflare-page-cache' => [
440 + 'name' => 'Super Page Cache',
441 + ],
442 + 'hyve-lite' => [
443 + 'name' => 'Hyve Lite',
444 + ],
445 + 'wp-full-stripe-free' => [
446 + 'name' => 'WP Full Pay',
447 + ],
448 + 'easy-mcp-ai' => [
449 + 'name' => 'Easy MCP AI',
450 + ],
354 451 ];
355 452
356 453 foreach ( $products as $slug => $product ) {
357 454 if ( isset( $product['condition'] ) && ! $product['condition'] ) {
@@ -381,27 +478,61 @@
381 478 $products[ $slug ]['status'] = $this->is_plugin_installed( $slug ) ? 'installed' : 'not-installed';
382 479 $products[ $slug ]['status'] = $this->is_plugin_active( $slug ) ? 'active' : $products[ $slug ]['status'];
383 480 $products[ $slug ]['activationLink'] = $this->get_plugin_activation_link( $slug );
384 481
482 + if ( 'easy-mcp-ai' === $slug ) {
483 + // The shared builder stamps optimole_reference_key on every non-Otter slug; carry Easy MCP attribution instead.
484 + $products[ $slug ]['activationLink'] = add_query_arg( 'easy_mcp_reference_key', 'a-' . $this->product->get_key(), remove_query_arg( 'optimole_reference_key', $products[ $slug ]['activationLink'] ) );
485 + }
385 486
487 +
386 488 if ( isset( $product['skip_api'] ) ) {
387 489 continue;
388 490 }
389 491
390 492 $api_data = $this->call_plugin_api( $slug );
391 -
392 - if ( ! isset( $product['icon'] ) ) {
493 + if ( ! isset( $product['icon'] ) && ( isset( $api_data->icons['2x'] ) || $api_data->icons['1x'] ) ) {
393 494 $products[ $slug ]['icon'] = isset( $api_data->icons['2x'] ) ? $api_data->icons['2x'] : $api_data->icons['1x'];
394 495 }
395 - if ( ! isset( $product['description'] ) ) {
496 + if ( ! isset( $product['description'] ) && isset( $api_data->short_description ) ) {
396 497 $products[ $slug ]['description'] = $api_data->short_description;
397 498 }
398 - if ( ! isset( $product['name'] ) ) {
499 + if ( ! isset( $product['name'] ) && isset( $api_data->name ) ) {
399 500 $products[ $slug ]['name'] = $api_data->name;
400 501 }
401 502 }
402 503
504 + uksort(
505 + $products,
506 + function ( $left_slug, $right_slug ) use ( $products ) {
507 + return $this->get_product_sort_key( $left_slug, $products )
508 + <=> $this->get_product_sort_key( $right_slug, $products );
509 + }
510 + );
511 +
403 512 return $products;
513 + }
514 +
515 + /**
516 + * Build a comparable sort key tuple for a product slug.
517 + *
518 + * @param string $slug Product slug.
519 + * @param array $products All products keyed by slug.
520 + *
521 + * @return array
522 + */
523 + private function get_product_sort_key( $slug, $products ) {
524 + $status = isset( $products[ $slug ]['status'] ) ? $products[ $slug ]['status'] : 'not-installed';
525 + $is_active = 'active' === $status ? 1 : 0;
526 + $common_weight = isset( self::COMMON_PRODUCTS_PRIORITY[ $slug ] ) ? self::COMMON_PRODUCTS_PRIORITY[ $slug ] : self::SORT_WEIGHT_UNRANKED;
527 +
528 + // Install status only breaks ties between unranked products.
529 + $status_weight = self::SORT_WEIGHT_UNRANKED === $common_weight
530 + ? ( isset( self::STATUS_PRIORITY[ $status ] ) ? self::STATUS_PRIORITY[ $status ] : self::SORT_WEIGHT_UNRANKED )
531 + : 0;
532 +
533 + // Tuple order = sort precedence: active last, featured rank, status, then slug.
534 + return array( $is_active, $common_weight, $status_weight, $slug );
404 535 }
405 536
406 537 /**
407 538 * Get the page slug.