PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / 4.2.15
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization v4.2.15
4.2.15 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 All 136 releases
← All changes | vendor/codeinwp/themeisle-sdk/src/Modules/About_us.php +259 -37 3.10.0 → 4.2.15 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 );
@@ -172,41 +234,143 @@
172 234 *
173 235 * @return array
174 236 */
175 237 private function get_about_localization_data() {
176 - $links = isset( $this->about_data['page_menu'] ) ? $this->about_data['page_menu'] : [];
238 + $links = isset( $this->about_data['page_menu'] ) ? $this->about_data['page_menu'] : [];
239 + $product_pages = isset( $this->about_data['product_pages'] ) ? $this->about_data['product_pages'] : [];
240 + $page_slug = $this->get_about_page_slug();
177 241
178 242 return [
179 - 'links' => $links,
180 - 'logoUrl' => $this->about_data['logo'],
181 - 'products' => $this->get_other_products_data(),
182 - 'homeUrl' => esc_url( home_url() ),
183 - 'pageSlug' => $this->get_about_page_slug(),
184 - 'currentProduct' => [
243 + 'links' => $links,
244 + 'logoUrl' => $this->about_data['logo'],
245 + 'productPages' => $this->get_product_pages_data( $product_pages ),
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 + ],
256 + 'homeUrl' => esc_url( home_url() ),
257 + 'pageSlug' => $page_slug,
258 + 'currentProduct' => [
185 259 'slug' => $this->product->get_key(),
186 260 'name' => $this->product->get_name(),
187 261 ],
188 - 'teamImage' => $this->get_sdk_uri() . 'assets/images/team.jpg',
189 - 'strings' => [
190 - 'aboutUs' => __( 'About us', 'textdomain' ),
191 - 'heroHeader' => __( 'Our Story', 'textdomain' ),
192 - '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' ),
193 - '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' ),
194 - 'teamImageCaption' => __( 'Our team in WCEU2022 in Portugal', 'textdomain' ),
195 - 'newsHeading' => __( 'Stay connected for news & updates!', 'textdomain' ),
196 - 'emailPlaceholder' => __( 'Your email address', 'textdomain' ),
197 - 'signMeUp' => __( 'Sign me up', 'textdomain' ),
198 - 'installNow' => __( 'Install Now', 'textdomain' ),
199 - 'activate' => __( 'Activate', 'textdomain' ),
200 - 'learnMore' => __( 'Learn More', 'textdomain' ),
201 - 'installed' => __( 'Installed', 'textdomain' ),
202 - 'notInstalled' => __( 'Not Installed', 'textdomain' ),
203 - 'active' => __( 'Active', 'textdomain' ),
262 + 'teamImage' => $this->get_sdk_uri() . 'assets/images/team.jpg',
263 + 'strings' => [
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'],
204 279 ],
280 + 'canInstallPlugins' => current_user_can( 'install_plugins' ),
281 + 'canActivatePlugins' => current_user_can( 'activate_plugins' ),
282 + 'showReviewLink' => ! ( isset( $this->about_data['review_link'] ) && false === $this->about_data['review_link'] ),
205 283 ];
206 284 }
207 285
208 286 /**
287 + * Get product pages data.
288 + *
289 + * @param array $product_pages Product pages.
290 + *
291 + * @return array
292 + */
293 + private function get_product_pages_data( $product_pages ) {
294 +
295 + $otter_slug = 'otter-blocks';
296 + $otter_plugin = [
297 + 'status' => 'not-installed',
298 + ];
299 + $otter_plugin['status'] = $this->is_plugin_installed( $otter_slug ) ? 'installed' : 'not-installed';
300 + $otter_plugin['status'] = $this->is_plugin_active( $otter_slug ) ? 'active' : $otter_plugin['status'];
301 + $otter_plugin['activationLink'] = $this->get_plugin_activation_link( $otter_slug );
302 +
303 + $pages = [
304 + 'otter-page' => [
305 + 'name' => 'Otter Blocks',
306 + 'hash' => '#otter-page',
307 + 'product' => $otter_slug,
308 + 'plugin' => $otter_plugin,
309 + 'strings' => [
310 + 'heading' => Loader::$labels['about_us']['otter-page']['heading'],
311 + 'text' => Loader::$labels['about_us']['otter-page']['text'],
312 + 'buttons' => [
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'],
316 + 'learn_more_link' => tsdk_utmify( 'https://themeisle.com/plugins/otter-blocks/', 'otter-page', 'about-us' ),
317 + ],
318 + 'features' => [
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'],
325 + ],
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'],
333 + 's1Image' => $this->get_sdk_uri() . 'assets/images/otter/otter-builder.png',
334 + 's2Image' => $this->get_sdk_uri() . 'assets/images/otter/otter-patterns.png',
335 + 's3Image' => $this->get_sdk_uri() . 'assets/images/otter/otter-library.png',
336 + ],
337 + 'testimonials' => [
338 + 'heading' => Loader::$labels['about_us']['otter-page']['testimonials']['heading'],
339 + 'users' => [
340 + [
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',
342 + 'name' => 'Michael Burry',
343 + 'text' => Loader::$labels['about_us']['otter-page']['testimonials']['users']['user_1'],
344 + ],
345 + [
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',
347 + 'name' => 'Maria Gonzales',
348 + 'text' => Loader::$labels['about_us']['otter-page']['testimonials']['users']['user_2'],
349 + ],
350 + [
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',
352 + 'name' => 'Florian Henckel',
353 + 'text' => Loader::$labels['about_us']['otter-page']['testimonials']['users']['user_3'],
354 + ],
355 + ],
356 + ],
357 + ],
358 + ],
359 + ];
360 +
361 + return array_filter(
362 + $pages,
363 + function ( $page_data, $page_key ) use ( $product_pages ) {
364 + return in_array( $page_key, $product_pages, true ) &&
365 + isset( $page_data['plugin']['status'] ) &&
366 + $page_data['plugin']['status'] === 'not-installed';
367 + },
368 + ARRAY_FILTER_USE_BOTH
369 + );
370 + }
371 +
372 + /**
209 373 * Get products data.
210 374 *
211 375 * @return array
212 376 */
@@ -213,25 +377,37 @@
213 377 private function get_other_products_data() {
214 378 $products = [
215 379 'optimole-wp' => [
216 380 'name' => 'Optimole',
217 - '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'],
218 382 ],
219 383 'neve' => [
220 384 'skip_api' => true,
221 385 'name' => 'Neve',
222 - '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'],
223 387 'icon' => $this->get_sdk_uri() . 'assets/images/neve.png',
224 388 ],
389 + 'learning-management-system' => [
390 + 'name' => 'Masteriyo LMS',
391 + ],
225 392 'otter-blocks' => [
226 393 'name' => 'Otter',
227 394 ],
228 395 'tweet-old-post' => [
229 - 'name' => 'Revive Old Post',
396 + 'name' => 'Revive Social',
230 397 ],
231 398 'feedzy-rss-feeds' => [
232 399 'name' => 'Feedzy',
233 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 + ],
234 410 'woocommerce-product-addon' => [
235 411 'name' => 'PPOM',
236 412 'condition' => class_exists( 'WooCommerce', false ),
237 413 ],
@@ -241,9 +417,9 @@
241 417 'wp-landing-kit' => [
242 418 'skip_api' => true,
243 419 'premiumUrl' => tsdk_utmify( 'https://themeisle.com/plugins/wp-landing-kit', $this->get_about_page_slug() ),
244 420 'name' => 'WP Landing Kit',
245 - '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'],
246 422 'icon' => $this->get_sdk_uri() . 'assets/images/wplk.png',
247 423 ],
248 424 'multiple-pages-generator-by-porthas' => [
249 425 'name' => 'MPG',
@@ -251,16 +427,28 @@
251 427 'sparks-for-woocommerce' => [
252 428 'skip_api' => true,
253 429 'premiumUrl' => tsdk_utmify( 'https://themeisle.com/plugins/sparks-for-woocommerce', $this->get_about_page_slug() ),
254 430 'name' => 'Sparks',
255 - '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'],
256 432 'icon' => $this->get_sdk_uri() . 'assets/images/sparks.png',
257 433 'condition' => class_exists( 'WooCommerce', false ),
258 434 ],
259 435 'templates-patterns-collection' => [
260 - 'name' => 'Template Cloud',
261 - 'description' => __( 'Ultimate Free Templates Cloud for WordPress, for blocks, patters of full pages.', 'textdomain' ),
436 + 'name' => 'Templates Cloud',
437 + 'description' => Loader::$labels['about_us']['others']['tpc_desc'],
262 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 + ],
263 451 ];
264 452
265 453 foreach ( $products as $slug => $product ) {
266 454 if ( isset( $product['condition'] ) && ! $product['condition'] ) {
@@ -290,27 +478,61 @@
290 478 $products[ $slug ]['status'] = $this->is_plugin_installed( $slug ) ? 'installed' : 'not-installed';
291 479 $products[ $slug ]['status'] = $this->is_plugin_active( $slug ) ? 'active' : $products[ $slug ]['status'];
292 480 $products[ $slug ]['activationLink'] = $this->get_plugin_activation_link( $slug );
293 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 + }
294 486
487 +
295 488 if ( isset( $product['skip_api'] ) ) {
296 489 continue;
297 490 }
298 491
299 492 $api_data = $this->call_plugin_api( $slug );
300 -
301 - if ( ! isset( $product['icon'] ) ) {
493 + if ( ! isset( $product['icon'] ) && ( isset( $api_data->icons['2x'] ) || $api_data->icons['1x'] ) ) {
302 494 $products[ $slug ]['icon'] = isset( $api_data->icons['2x'] ) ? $api_data->icons['2x'] : $api_data->icons['1x'];
303 495 }
304 - if ( ! isset( $product['description'] ) ) {
496 + if ( ! isset( $product['description'] ) && isset( $api_data->short_description ) ) {
305 497 $products[ $slug ]['description'] = $api_data->short_description;
306 498 }
307 - if ( ! isset( $product['name'] ) ) {
499 + if ( ! isset( $product['name'] ) && isset( $api_data->name ) ) {
308 500 $products[ $slug ]['name'] = $api_data->name;
309 501 }
310 502 }
311 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 +
312 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 );
313 535 }
314 536
315 537 /**
316 538 * Get the page slug.