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 +182 -49 3.10.10 → 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
@@ -26,8 +27,9 @@
26 27
27 28 namespace ThemeisleSDK\Modules;
28 29
29 30 use ThemeisleSDK\Common\Abstract_Module;
31 +use ThemeisleSDK\Loader;
30 32 use ThemeisleSDK\Product;
31 33
32 34 // Exit if accessed directly.
33 35 if ( ! defined( 'ABSPATH' ) ) {
@@ -38,8 +40,42 @@
38 40 * Promotions module for ThemeIsle SDK.
39 41 */
40 42 class About_Us extends Abstract_Module {
41 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 + /**
42 78 * About data.
43 79 *
44 80 * @var array $about_data About page data, received from the filter.
45 81 *
@@ -93,12 +129,15 @@
93 129 if ( ! isset( $this->about_data['location'] ) ) {
94 130 return;
95 131 }
96 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 +
97 136 add_submenu_page(
98 137 $this->about_data['location'],
99 - __( 'About Us', 'textdomain' ),
100 - __( 'About Us', 'textdomain' ),
138 + Loader::$labels['about_us']['title'],
139 + Loader::$labels['about_us']['title'],
101 140 'manage_options',
102 141 $this->get_about_page_slug(),
103 142 array( $this, 'render_about_us_page' ),
104 143 100
@@ -122,14 +161,35 @@
122 161
123 162 add_submenu_page(
124 163 $this->about_data['location'],
125 164 $this->about_data['upgrade_text'],
126 - $this->about_data['upgrade_text'],
165 + '<span class="tsdk-upg-menu-item">' . $this->about_data['upgrade_text'] . '</span>',
127 166 'manage_options',
128 167 $this->about_data['upgrade_link'],
129 168 '',
130 169 101
131 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 + );
132 192 }
133 193
134 194 /**
135 195 * Render page content.
@@ -159,8 +219,10 @@
159 219 $handle = 'ti-sdk-about-' . $this->product->get_key();
160 220 $asset_file = require $themeisle_sdk_max_path . '/assets/js/build/about/about.asset.php';
161 221 $deps = array_merge( $asset_file['dependencies'], [ 'updates' ] );
162 222
223 + do_action( 'themeisle_internal_page', $this->product->get_slug(), 'about_us' );
224 +
163 225 wp_register_script( $handle, $this->get_sdk_uri() . 'assets/js/build/about/about.js', $deps, $asset_file['version'], true );
164 226 wp_localize_script( $handle, 'tiSDKAboutData', $this->get_about_localization_data() );
165 227
166 228 wp_enqueue_script( $handle );
@@ -174,15 +236,26 @@
174 236 */
175 237 private function get_about_localization_data() {
176 238 $links = isset( $this->about_data['page_menu'] ) ? $this->about_data['page_menu'] : [];
177 239 $product_pages = isset( $this->about_data['product_pages'] ) ? $this->about_data['product_pages'] : [];
240 + $page_slug = $this->get_about_page_slug();
241 +
178 242 return [
179 243 'links' => $links,
180 244 'logoUrl' => $this->about_data['logo'],
181 245 'productPages' => $this->get_product_pages_data( $product_pages ),
182 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 + ],
183 256 'homeUrl' => esc_url( home_url() ),
184 - 'pageSlug' => $this->get_about_page_slug(),
257 + 'pageSlug' => $page_slug,
185 258 'currentProduct' => [
186 259 'slug' => $this->product->get_key(),
187 260 'name' => $this->product->get_name(),
188 261 ],
@@ -187,25 +260,27 @@
187 260 'name' => $this->product->get_name(),
188 261 ],
189 262 'teamImage' => $this->get_sdk_uri() . 'assets/images/team.jpg',
190 263 'strings' => [
191 - 'aboutUs' => __( 'About us', 'textdomain' ),
192 - 'heroHeader' => __( 'Our Story', 'textdomain' ),
193 - 'heroTextFirst' => __( 'Themeisle was founded in 2012 by a group of passionate developers who wanted to create beautiful and functional WordPress themes and plugins. Since then, we have grown into a team of over 20 dedicated professionals who are committed to delivering the best possible products to our customers.', 'textdomain' ),
194 - 'heroTextSecond' => __( 'At Themeisle, we offer a wide range of WordPress themes and plugins that are designed to meet the needs of both beginners and advanced users. Our products are feature-rich, easy to use, and are designed to help you create beautiful and functional websites.', 'textdomain' ),
195 - 'teamImageCaption' => __( 'Our team in WCEU2022 in Portugal', 'textdomain' ),
196 - 'newsHeading' => __( 'Stay connected for news & updates!', 'textdomain' ),
197 - 'emailPlaceholder' => __( 'Your email address', 'textdomain' ),
198 - 'signMeUp' => __( 'Sign me up', 'textdomain' ),
199 - 'installNow' => __( 'Install Now', 'textdomain' ),
200 - 'activate' => __( 'Activate', 'textdomain' ),
201 - 'learnMore' => __( 'Learn More', 'textdomain' ),
202 - 'installed' => __( 'Installed', 'textdomain' ),
203 - 'notInstalled' => __( 'Not Installed', 'textdomain' ),
204 - 'active' => __( 'Active', 'textdomain' ),
264 + 'aboutUs' => Loader::$labels['about_us']['title'],
265 + 'heroHeader' => Loader::$labels['about_us']['heroHeader'],
266 + 'heroTextFirst' => Loader::$labels['about_us']['heroTextFirst'],
267 + 'heroTextSecond' => Loader::$labels['about_us']['heroTextSecond'],
268 + 'teamImageCaption' => Loader::$labels['about_us']['teamImageCaption'],
269 + 'newsHeading' => Loader::$labels['about_us']['newsHeading'],
270 + 'emailPlaceholder' => Loader::$labels['about_us']['emailPlaceholder'],
271 + 'signMeUp' => Loader::$labels['about_us']['signMeUp'],
272 + 'services' => Loader::$labels['about_us']['services'],
273 + 'installNow' => Loader::$labels['about_us']['installNow'],
274 + 'activate' => Loader::$labels['about_us']['activate'],
275 + 'learnMore' => Loader::$labels['about_us']['learnMore'],
276 + 'installed' => Loader::$labels['about_us']['installed'],
277 + 'notInstalled' => Loader::$labels['about_us']['notInstalled'],
278 + 'active' => Loader::$labels['about_us']['active'],
205 279 ],
206 280 'canInstallPlugins' => current_user_can( 'install_plugins' ),
207 281 'canActivatePlugins' => current_user_can( 'activate_plugins' ),
282 + 'showReviewLink' => ! ( isset( $this->about_data['review_link'] ) && false === $this->about_data['review_link'] ),
208 283 ];
209 284 }
210 285
211 286 /**
@@ -231,52 +306,52 @@
231 306 'hash' => '#otter-page',
232 307 'product' => $otter_slug,
233 308 'plugin' => $otter_plugin,
234 309 'strings' => [
235 - 'heading' => __( 'Build innovative layouts with Otter Blocks and Gutenberg', 'textdomain' ),
236 - 'text' => __( 'Otter is a lightweight, dynamic collection of page building blocks and templates for the WordPress block editor.', 'textdomain' ),
310 + 'heading' => Loader::$labels['about_us']['otter-page']['heading'],
311 + 'text' => Loader::$labels['about_us']['otter-page']['text'],
237 312 'buttons' => [
238 - 'install_otter_free' => __( "Install Otter - It's free!", 'textdomain' ),
239 - 'install_now' => __( 'Install Now', 'textdomain' ),
240 - 'learn_more' => __( 'Learn More', 'textdomain' ),
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'],
241 316 'learn_more_link' => tsdk_utmify( 'https://themeisle.com/plugins/otter-blocks/', 'otter-page', 'about-us' ),
242 317 ],
243 318 'features' => [
244 - 'advancedTitle' => __( 'Advanced Features', 'textdomain' ),
245 - 'advancedDesc' => __( 'Add features such as Custom CSS, Animations & Visibility Conditions to all blocks.', 'textdomain' ),
246 - 'fastTitle' => __( 'Lightweight and Fast', 'textdomain' ),
247 - 'fastDesc' => __( 'Otter enhances WordPress site building experience without impacting site speed.', 'textdomain' ),
248 - 'mobileTitle' => __( 'Mobile-Friendly', 'textdomain' ),
249 - 'mobileDesc' => __( 'Each block can be tweaked to provide a consistent experience across all devices.', 'textdomain' ),
319 + 'advancedTitle' => Loader::$labels['about_us']['otter-page']['features']['advancedTitle'],
320 + 'advancedDesc' => Loader::$labels['about_us']['otter-page']['features']['advancedDesc'],
321 + 'fastTitle' => Loader::$labels['about_us']['otter-page']['features']['fastTitle'],
322 + 'fastDesc' => Loader::$labels['about_us']['otter-page']['features']['fastDesc'],
323 + 'mobileTitle' => Loader::$labels['about_us']['otter-page']['features']['mobileTitle'],
324 + 'mobileDesc' => Loader::$labels['about_us']['otter-page']['features']['mobileDesc'],
250 325 ],
251 326 'details' => [
327 + 's1Title' => Loader::$labels['about_us']['otter-page']['details']['s1Title'],
328 + 's1Text' => Loader::$labels['about_us']['otter-page']['details']['s1Text'],
329 + 's2Title' => Loader::$labels['about_us']['otter-page']['details']['s2Title'],
330 + 's2Text' => Loader::$labels['about_us']['otter-page']['details']['s2Text'],
331 + 's3Title' => Loader::$labels['about_us']['otter-page']['details']['s3Title'],
332 + 's3Text' => Loader::$labels['about_us']['otter-page']['details']['s3Text'],
252 333 's1Image' => $this->get_sdk_uri() . 'assets/images/otter/otter-builder.png',
253 - 's1Title' => __( 'A Better Page Building Experience', 'textdomain' ),
254 - 's1Text' => __( 'Otter can be used to build everything from a personal blog to an e-commerce site without losing the personal touch. Otter’s ease of use transforms basic blocks into expressive layouts in seconds.', 'textdomain' ),
255 334 's2Image' => $this->get_sdk_uri() . 'assets/images/otter/otter-patterns.png',
256 - 's2Title' => __( 'A New Collection of Patterns', 'textdomain' ),
257 - 's2Text' => __( 'A New Patterns Library, containing a range of different elements in a variety of styles to help you build great pages. All of your website’s most important areas are covered: headers, testimonials, pricing tables, sections and more.', 'textdomain' ),
258 335 's3Image' => $this->get_sdk_uri() . 'assets/images/otter/otter-library.png',
259 - 's3Title' => __( 'Advanced Blocks', 'textdomain' ),
260 - 's3Text' => __( 'Enhance your website’s design with powerful blocks, like the Add to Cart, Business Hours, Review Comparison, and dozens of WooCommerce blocks.', 'textdomain' ),
261 336 ],
262 337 'testimonials' => [
263 - 'heading' => __( 'Trusted by more than 300K website owners', 'textdomain' ),
338 + 'heading' => Loader::$labels['about_us']['otter-page']['testimonials']['heading'],
264 339 'users' => [
265 340 [
266 341 'avatar' => 'https://mllj2j8xvfl0.i.optimole.com/cb:3970~373ad/w:80/h:80/q:mauto/https://themeisle.com/wp-content/uploads/2021/05/avatar-03.png',
267 342 'name' => 'Michael Burry',
268 - 'text' => 'Loved the collection of blocks. If you want to create nice Gutenberg Pages, this plugin will be very handy and useful.',
343 + 'text' => Loader::$labels['about_us']['otter-page']['testimonials']['users']['user_1'],
269 344 ],
270 345 [
271 346 'avatar' => 'https://mllj2j8xvfl0.i.optimole.com/cb:3970~373ad/w:80/h:80/q:mauto/https://themeisle.com/wp-content/uploads/2022/04/avatar-04.png',
272 347 'name' => 'Maria Gonzales',
273 - 'text' => 'I am very satisfied with Otter – a fantastic collection of blocks. And the plugin is perfectly integrated with Gutenberg and complete enough for my needs. ',
348 + 'text' => Loader::$labels['about_us']['otter-page']['testimonials']['users']['user_2'],
274 349 ],
275 350 [
276 351 'avatar' => 'https://mllj2j8xvfl0.i.optimole.com/cb:3970~373ad/w:80/h:80/q:mauto/https://themeisle.com/wp-content/uploads/2022/04/avatar-05.png',
277 352 'name' => 'Florian Henckel',
278 - 'text' => 'Otter Blocks work really well and I like the customization options. Easy to use and format to fit in with my site theme – and I’ve not encountered any compatibility or speed issues.',
353 + 'text' => Loader::$labels['about_us']['otter-page']['testimonials']['users']['user_3'],
279 354 ],
280 355 ],
281 356 ],
282 357 ],
@@ -302,25 +377,37 @@
302 377 private function get_other_products_data() {
303 378 $products = [
304 379 'optimole-wp' => [
305 380 'name' => 'Optimole',
306 - 'description' => 'Optimole is an image optimization service that automatically optimizes your images and serves them to your visitors via a global CDN, making your website lighter, faster and helping you reduce your bandwidth usage.',
381 + 'description' => Loader::$labels['about_us']['others']['optimole_desc'],
307 382 ],
308 383 'neve' => [
309 384 'skip_api' => true,
310 385 'name' => 'Neve',
311 - 'description' => __( 'A fast, lightweight, customizable WordPress theme offering responsive design, speed, and flexibility for various website types.', 'textdomain' ),
386 + 'description' => Loader::$labels['about_us']['others']['neve_desc'],
312 387 'icon' => $this->get_sdk_uri() . 'assets/images/neve.png',
313 388 ],
389 + 'learning-management-system' => [
390 + 'name' => 'Masteriyo LMS',
391 + ],
314 392 'otter-blocks' => [
315 393 'name' => 'Otter',
316 394 ],
317 395 'tweet-old-post' => [
318 - 'name' => 'Revive Old Post',
396 + 'name' => 'Revive Social',
319 397 ],
320 398 'feedzy-rss-feeds' => [
321 399 'name' => 'Feedzy',
322 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 + ],
323 410 'woocommerce-product-addon' => [
324 411 'name' => 'PPOM',
325 412 'condition' => class_exists( 'WooCommerce', false ),
326 413 ],
@@ -330,9 +417,9 @@
330 417 'wp-landing-kit' => [
331 418 'skip_api' => true,
332 419 'premiumUrl' => tsdk_utmify( 'https://themeisle.com/plugins/wp-landing-kit', $this->get_about_page_slug() ),
333 420 'name' => 'WP Landing Kit',
334 - 'description' => __( 'Turn WordPress into a landing page powerhouse with Landing Kit, map domains to pages or any other published resource.', 'textdomain' ),
421 + 'description' => Loader::$labels['about_us']['others']['landingkit_desc'],
335 422 'icon' => $this->get_sdk_uri() . 'assets/images/wplk.png',
336 423 ],
337 424 'multiple-pages-generator-by-porthas' => [
338 425 'name' => 'MPG',
@@ -340,16 +427,28 @@
340 427 'sparks-for-woocommerce' => [
341 428 'skip_api' => true,
342 429 'premiumUrl' => tsdk_utmify( 'https://themeisle.com/plugins/sparks-for-woocommerce', $this->get_about_page_slug() ),
343 430 'name' => 'Sparks',
344 - 'description' => __( 'Extend your store functionality with 8 ultra-performant features like product comparisons, variation swatches, wishlist, and more.', 'textdomain' ),
431 + 'description' => Loader::$labels['about_us']['others']['sparks_desc'],
345 432 'icon' => $this->get_sdk_uri() . 'assets/images/sparks.png',
346 433 'condition' => class_exists( 'WooCommerce', false ),
347 434 ],
348 435 'templates-patterns-collection' => [
349 436 'name' => 'Templates Cloud',
350 - 'description' => __( 'Design, save, and revisit your templates anytime with your personal vault on Templates Cloud.', 'textdomain' ),
437 + 'description' => Loader::$labels['about_us']['others']['tpc_desc'],
351 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 + ],
352 451 ];
353 452
354 453 foreach ( $products as $slug => $product ) {
355 454 if ( isset( $product['condition'] ) && ! $product['condition'] ) {
@@ -379,27 +478,61 @@
379 478 $products[ $slug ]['status'] = $this->is_plugin_installed( $slug ) ? 'installed' : 'not-installed';
380 479 $products[ $slug ]['status'] = $this->is_plugin_active( $slug ) ? 'active' : $products[ $slug ]['status'];
381 480 $products[ $slug ]['activationLink'] = $this->get_plugin_activation_link( $slug );
382 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 + }
383 486
487 +
384 488 if ( isset( $product['skip_api'] ) ) {
385 489 continue;
386 490 }
387 491
388 492 $api_data = $this->call_plugin_api( $slug );
389 -
390 - if ( ! isset( $product['icon'] ) ) {
493 + if ( ! isset( $product['icon'] ) && ( isset( $api_data->icons['2x'] ) || $api_data->icons['1x'] ) ) {
391 494 $products[ $slug ]['icon'] = isset( $api_data->icons['2x'] ) ? $api_data->icons['2x'] : $api_data->icons['1x'];
392 495 }
393 - if ( ! isset( $product['description'] ) ) {
496 + if ( ! isset( $product['description'] ) && isset( $api_data->short_description ) ) {
394 497 $products[ $slug ]['description'] = $api_data->short_description;
395 498 }
396 - if ( ! isset( $product['name'] ) ) {
499 + if ( ! isset( $product['name'] ) && isset( $api_data->name ) ) {
397 500 $products[ $slug ]['name'] = $api_data->name;
398 501 }
399 502 }
400 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 +
401 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 );
402 535 }
403 536
404 537 /**
405 538 * Get the page slug.