public function get_extension_suggestions( string $location, string $context = '' ): array {
$preferred_psp = null;
$preferred_apm = null;
$other = array();
$extensions = $this->extension_suggestions->get_country_extensions( $location, $context );
// Sort them by _priority.
usort(
$extensions,
function ( $a, $b ) {
return $a['_priority'] <=> $b['_priority'];
}
);
$has_enabled_ecommerce_gateways = $this->has_enabled_ecommerce_gateways();
// Keep track of the active extensions.
$active_extensions = array();
foreach ( $extensions as $extension ) {
$extension = $this->enhance_extension_suggestion( $extension );
if ( self::EXTENSION_ACTIVE === $extension['plugin']['status'] ) {
// If the suggested extension is active, we no longer suggest it.
// But remember it for later.
$active_extensions[] = $extension['id'];
continue;
}
// Determine if the suggestion is preferred or not by looking at its tags.
$is_preferred = in_array( ExtensionSuggestions::TAG_PREFERRED, $extension['tags'], true );
// Determine if the suggestion is hidden (from the preferred locations).
$is_hidden = $this->is_payment_extension_suggestion_hidden( $extension );
if ( ! $is_hidden && $is_preferred ) {
// If the suggestion is preferred, add it to the preferred list.
if ( empty( $preferred_psp ) && ExtensionSuggestions::TYPE_PSP === $extension['_type'] ) {
$preferred_psp = $extension;
continue;
}
if ( empty( $preferred_apm ) && ExtensionSuggestions::TYPE_APM === $extension['_type'] ) {
$preferred_apm = $extension;
continue;
}
}
if ( $is_hidden &&
ExtensionSuggestions::TYPE_APM === $extension['_type'] &&
ExtensionSuggestions::PAYPAL_FULL_STACK === $extension['id'] ) {
// If the PayPal Full Stack suggestion is hidden, we no longer suggest it,
// because we have the PayPal Express Checkout (Wallet) suggestion.
continue;
}
// If there are no enabled ecommerce gateways (no PSP selected),
// we don't suggest express checkout or BNPL extensions.
if ( (
ExtensionSuggestions::TYPE_EXPRESS_CHECKOUT === $extension['_type'] ||
ExtensionSuggestions::TYPE_BNPL === $extension['_type']
) && ! $has_enabled_ecommerce_gateways ) {
continue;
}
// If WooPayments or Stripe is active, we don't suggest other BNPLs.
if ( ExtensionSuggestions::TYPE_BNPL === $extension['_type'] &&
(
in_array( ExtensionSuggestions::STRIPE, $active_extensions, true ) ||
in_array( ExtensionSuggestions::WOOPAYMENTS, $active_extensions, true )
)
) {
continue;
}
// If we made it to this point, the suggestion goes into the other list.
// But first, make sure there isn't already an extension added to the other list with the same plugin slug.
// This can happen if the same extension is suggested as both a PSP and an APM.
// The first entry that we encounter is the one that we keep.
$extension_slug = $extension['plugin']['slug'];
$extension_exists = array_filter(
$other,
function ( $suggestion ) use ( $extension_slug ) {
return $suggestion['plugin']['slug'] === $extension_slug;
}
);
if ( ! empty( $extension_exists ) ) {
continue;
}
$other[] = $extension;
}
// Make sure that the preferred suggestions are not among the other list by removing any entries with their plugin slug.
$other = array_values(
array_filter(
$other,
function ( $suggestion ) use ( $preferred_psp, $preferred_apm ) {
return ( empty( $preferred_psp ) || $suggestion['plugin']['slug'] !== $preferred_psp['plugin']['slug'] ) &&
( empty( $preferred_apm ) || $suggestion['plugin']['slug'] !== $preferred_apm['plugin']['slug'] );
}
)
);
// The preferred PSP gets a recommended tag that instructs the UI to highlight it further.
if ( ! empty( $preferred_psp ) ) {
$preferred_psp['tags'][] = ExtensionSuggestions::TAG_RECOMMENDED;
}
return array(
'preferred' => array_values(
array_filter(
array(
// The PSP should naturally have a higher priority than the APM.
// No need to impose a specific order here.
$preferred_psp,
$preferred_apm,
)
)
),
'other' => $other,
);
}