array( 'name' => 'OrderFloor', 'category' => __( 'Order rules', 'shieldlume-security' ), 'description' => __( 'Set order minimums, quantity limits and pack sizes before shoppers reach checkout.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => true, 'optional_woo' => false, 'url' => 'https://plugins.shop/orderfloor/', ), 'wakemycart' => array( 'name' => 'WakeMyCart', 'category' => __( 'Cart follow-up', 'shieldlume-security' ), 'description' => __( 'Give consenting shoppers a useful reminder to return to an unfinished cart.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => true, 'optional_woo' => false, 'url' => 'https://plugins.shop/wakemycart/', ), 'wishlistgenius' => array( 'name' => 'WishlistGenius', 'category' => __( 'Wishlists & saved products', 'shieldlume-security' ), 'description' => __( 'Let shoppers save products, share a list and return when they are ready.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => true, 'optional_woo' => false, 'url' => 'https://plugins.shop/wishlistgenius/', ), 'cartdini' => array( 'name' => 'Cartdini', 'category' => __( 'Checkout fields', 'shieldlume-security' ), 'description' => __( 'Ask the right checkout questions. Keep the answers with the order.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => true, 'optional_woo' => false, 'url' => 'https://plugins.shop/cartdini/', ), 'orderworth' => array( 'name' => 'OrderWorth', 'category' => __( 'Costs & contribution', 'shieldlume-security' ), 'description' => __( 'See order contribution after recorded product costs, expenses and refunds.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => true, 'optional_woo' => false, 'url' => 'https://plugins.shop/orderworth/', ), 'stockcontrols' => array( 'name' => 'StockControls', 'category' => __( 'Inventory & purchasing', 'shieldlume-security' ), 'description' => __( 'Review stock changes, receive purchase orders and plan replenishment with context.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => true, 'optional_woo' => false, 'url' => 'https://plugins.shop/stockcontrols/', ), 'clickclue' => array( 'name' => 'ClickClue', 'category' => __( 'Session replay', 'shieldlume-security' ), 'description' => __( 'Review consenting visitors’ recorded journeys and investigate where they get stuck.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'reason' => __( 'Review a consenting visitor’s journey when investigating a reported site problem.', 'shieldlume-security' ), 'preview' => false, 'woo' => false, 'optional_woo' => false, 'url' => 'https://plugins.shop/clickclue/', ), 'frictions' => array( 'name' => 'Frictions', 'category' => __( 'Checkout investigations', 'shieldlume-security' ), 'description' => __( 'Investigate checkout errors through consented, privacy-limited replay and review workflows.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => true, 'optional_woo' => false, 'url' => 'https://plugins.shop/frictions/', ), 'customfields' => array( 'name' => 'CustomFields', 'category' => __( 'Structured content', 'shieldlume-security' ), 'description' => __( 'Structure your content with reusable fields, then choose how to display it.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => false, 'optional_woo' => false, 'url' => 'https://plugins.shop/customfields/', ), 'killerconversions' => array( 'name' => 'KillerConversions', 'category' => __( 'Forms & enquiries', 'shieldlume-security' ), 'description' => __( 'Build useful enquiry forms, keep entries locally and add advanced workflows when needed.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => false, 'optional_woo' => false, 'url' => 'https://plugins.shop/killerconversions/', ), 'newsletterplatform' => array( 'name' => 'Newsletter Platform', 'category' => __( 'Newsletters & welcome emails', 'shieldlume-security' ), 'description' => __( 'Create newsletters and welcome journeys in WordPress using your own mail provider.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => false, 'optional_woo' => true, 'url' => 'https://plugins.shop/newsletterplatform/', ), 'logged' => array( 'name' => 'Logged.ai', 'category' => __( 'Site activity', 'shieldlume-security' ), 'description' => __( 'Find what changed on your WordPress site and give the next reviewer useful context.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'reason' => __( 'Review the activity record when a security finding follows a site change.', 'shieldlume-security' ), 'preview' => false, 'woo' => false, 'optional_woo' => false, 'url' => 'https://plugins.shop/logged/', ), 'redirectnest' => array( 'name' => 'RedirectNest', 'category' => __( 'Links & navigation', 'shieldlume-security' ), 'description' => __( 'Manage redirects and review broken-link problems before changing where visitors go.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'reason' => __( 'Investigate broken links and review redirects after cleanup or site changes.', 'shieldlume-security' ), 'preview' => false, 'woo' => false, 'optional_woo' => false, 'url' => 'https://plugins.shop/redirectnest/', ), 'tocgenius' => array( 'name' => 'TOC Genius', 'category' => __( 'Article navigation', 'shieldlume-security' ), 'description' => __( 'Help readers navigate long articles while keeping heading links and labels under control.', 'shieldlume-security' ), 'availability' => __( 'Preview · Public Free + Pro; directory review pending', 'shieldlume-security' ), 'preview' => true, 'woo' => false, 'optional_woo' => false, 'url' => 'https://plugins.shop/tocgenius/', ), 'catalogfaq' => array( 'name' => 'Catalog FAQ', 'category' => __( 'Reusable answers', 'shieldlume-security' ), 'description' => __( 'Write an answer once and reuse it across pages, products and FAQ groups.', 'shieldlume-security' ), 'availability' => __( 'Preview · Public Free + Pro; paid plans not open', 'shieldlume-security' ), 'preview' => true, 'woo' => false, 'optional_woo' => true, 'url' => 'https://plugins.shop/catalogfaq/', ), 'campaignbars' => array( 'name' => 'CampaignBars', 'category' => __( 'Announcements & offers', 'shieldlume-security' ), 'description' => __( 'Publish targeted announcements, countdowns and copyable coupons without editing your theme.', 'shieldlume-security' ), 'availability' => __( 'Free edition available', 'shieldlume-security' ), 'preview' => false, 'woo' => false, 'optional_woo' => true, 'url' => 'https://plugins.shop/campaignbars/', ), ); } public static function render(): void { $catalog = self::catalog(); $featured = array_intersect_key( $catalog, array_fill_keys( array( 'logged', 'clickclue', 'redirectnest' ), true ) ); $remaining = array_diff_key( $catalog, $featured ); uasort( $remaining, static function ( array $left, array $right ): int { return strnatcasecmp( $left['name'], $right['name'] ); } ); echo '
' . esc_html__( 'THE PLUGINS.SHOP COLLECTION', 'shieldlume-security' ) . '

' . esc_html__( 'More from Plugins.shop', 'shieldlume-security' ) . '

'; /* translators: %s: number of other plugins in the publisher collection. */ echo esc_html( sprintf( _n( 'Explore %s other plugin, with useful companions first.', 'Explore all %s other plugins, with useful companions first.', count( $catalog ), 'shieldlume-security' ), number_format_i18n( count( $catalog ) ) ) ); echo '

' . esc_html__( 'Visit Plugins.shop', 'shieldlume-security' ) . '
'; echo '

' . esc_html__( 'Useful alongside Shieldlume Security', 'shieldlume-security' ) . '

' . esc_html__( 'For reviewing site changes, visitor journeys and broken links.', 'shieldlume-security' ) . '

'; /* translators: %s: number of recommended companion plugins. */ echo esc_html( sprintf( _n( '%s useful companion', '%s useful companions', count( $featured ), 'shieldlume-security' ), number_format_i18n( count( $featured ) ) ) ); echo '
'; foreach ( array( 'logged', 'clickclue', 'redirectnest' ) as $slug ) { self::card( $slug, $featured[ $slug ], true ); } echo '

' . esc_html__( 'Explore more tools', 'shieldlume-security' ) . '

' . esc_html__( 'For the other jobs your website needs to do.', 'shieldlume-security' ) . '

'; /* translators: %s: number of plugins in the rest of the publisher collection. */ echo esc_html( sprintf( _n( '%s more plugin', '%s more plugins', count( $remaining ), 'shieldlume-security' ), number_format_i18n( count( $remaining ) ) ) ); echo '
'; foreach ( $remaining as $slug => $product ) { self::card( $slug, $product, false ); } echo '

' . esc_html__( 'Related tools, not a requirement to install more plugins. Downloads, support and purchases follow each product’s current availability and terms.', 'shieldlume-security' ) . '

'; } private static function card( string $slug, array $product, bool $featured ): void { $image = plugins_url( 'assets/catalog/' . $slug . '.svg', ANTIVIRUS_AI_FILE ); echo '

' . esc_html( $product['name'] ) . '

' . esc_html( $product['category'] ) . '

' . esc_html( $product['description'] ) . '

'; if ( $featured ) { echo '

' . esc_html__( 'Why it fits', 'shieldlume-security' ) . '

' . esc_html( $product['reason'] ) . '

'; } echo '

' . esc_html( $product['availability'] ) . ''; if ( $product['woo'] ) { echo '' . esc_html__( 'Requires WooCommerce', 'shieldlume-security' ) . ''; } elseif ( $product['optional_woo'] ) { echo '' . esc_html__( 'WooCommerce optional', 'shieldlume-security' ) . ''; } echo '

' . esc_html__( 'Explore plugin', 'shieldlume-security' ) . '
'; } }