← 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. |