PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / trunk
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization vtrunk
4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 2.5.5 2.5.6 2.5.7 3.0.0 3.0.1 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.11.0 3.11.1 3.11.2 3.11.3 3.12.0 All 135 releases
← All changes | vendor/codeinwp/themeisle-sdk/src/Modules/About_us.php +182 -49 3.11.1 → trunk 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.