class-license-product-map.php
4 weeks ago
class-license-shop-client.php
4 weeks ago
class-license-site-activation.php
4 weeks ago
class-license-utils.php
4 weeks ago
class-license.php
4 weeks ago
class-license-product-map.php
149 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Map exchange/API product names to add-on ids used in legacy license storage. |
| 4 | * |
| 5 | * @package AdvancedAds |
| 6 | * @since 2.0.9 |
| 7 | * @author Advanced Ads <info@wpadvancedads.com> |
| 8 | */ |
| 9 | |
| 10 | namespace AdvancedAds\License; |
| 11 | |
| 12 | use AdvancedAds\Utilities\Addons; |
| 13 | |
| 14 | defined( 'ABSPATH' ) || exit; |
| 15 | |
| 16 | /** |
| 17 | * Product name ↔ addon id helpers. |
| 18 | */ |
| 19 | final class License_Product_Map { |
| 20 | |
| 21 | /** |
| 22 | * Add-on manifest for license name resolution (always includes missing add-ons). |
| 23 | * |
| 24 | * @return array<string, array{id: string, name: string, options_slug: string, path: string}> |
| 25 | */ |
| 26 | public static function addon_manifest(): array { |
| 27 | $slug_base = defined( 'ADVADS_SLUG' ) ? ADVADS_SLUG : 'advanced-ads'; |
| 28 | $names = [ |
| 29 | 'pro' => 'Pro', |
| 30 | 'responsive' => 'AMP Ads', |
| 31 | 'gam' => 'Google Ad Manager Integration', |
| 32 | 'layer' => 'PopUp and Layer Ads', |
| 33 | 'selling' => 'Selling Ads', |
| 34 | 'sticky' => 'Sticky Ads', |
| 35 | 'tracking' => 'Tracking', |
| 36 | ]; |
| 37 | $out = []; |
| 38 | |
| 39 | foreach ( Addons::plugin_files() as $addon_id => $file ) { |
| 40 | $slug = $slug_base . '-' . $addon_id; |
| 41 | $display_name = $names[ $addon_id ] ?? $addon_id; |
| 42 | $normalized = self::normalize_name( $display_name ); |
| 43 | $out[ $slug ] = [ |
| 44 | 'id' => $addon_id, |
| 45 | 'name' => $display_name, |
| 46 | 'options_slug' => $slug, |
| 47 | 'path' => $file, |
| 48 | 'aliases' => array_values( |
| 49 | array_unique( |
| 50 | array_filter( |
| 51 | [ |
| 52 | $normalized, |
| 53 | '' !== $normalized ? 'advanced ads ' . $normalized : '', |
| 54 | ] |
| 55 | ) |
| 56 | ) |
| 57 | ), |
| 58 | ]; |
| 59 | } |
| 60 | |
| 61 | return $out; |
| 62 | } |
| 63 | |
| 64 | /** |
| 65 | * Normalize a display name for comparison. |
| 66 | * |
| 67 | * @param string $name Raw name. |
| 68 | * @return string |
| 69 | */ |
| 70 | public static function normalize_name( string $name ): string { |
| 71 | $name = strtolower( trim( $name ) ); |
| 72 | return (string) preg_replace( '/\s+/', ' ', $name ); |
| 73 | } |
| 74 | |
| 75 | /** |
| 76 | * Remove site-tier suffix from a normalized product name (e.g. "advanced ads pro / 2 sites"). |
| 77 | * |
| 78 | * @param string $normalized Output of normalize_name(). |
| 79 | * @return string |
| 80 | */ |
| 81 | public static function strip_tier_suffix( string $normalized ): string { |
| 82 | $stripped = preg_replace( '#\s*/\s*\d+\s*sites?.*$#i', '', $normalized ); |
| 83 | $stripped = preg_replace( '#\s*\(\s*\d+\s*sites?\s*\).*$#i', '', (string) $stripped ); |
| 84 | |
| 85 | return trim( (string) $stripped ); |
| 86 | } |
| 87 | |
| 88 | /** |
| 89 | * Whether this product name represents an All Access–style bundle row. |
| 90 | * |
| 91 | * @param string $name From exchange payload `name`. |
| 92 | * @return bool |
| 93 | */ |
| 94 | public static function is_all_access_bundle_name( string $name ): bool { |
| 95 | $normalized = self::normalize_name( $name ); |
| 96 | |
| 97 | return '' !== $normalized && str_starts_with( $normalized, 'all access' ); |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * Resolve addon id (e.g. "tracking") from API product name using installed add-on metadata. |
| 102 | * |
| 103 | * @param string $product_name From exchange payload `name`. |
| 104 | * @param array<string, array{id: string, name: string, options_slug: string, path: string, aliases?: list<string>}>|null $addons Manifest rows; defaults to addon_manifest(). |
| 105 | * @return string|null Addon id or null if unknown / bundle row. |
| 106 | */ |
| 107 | public static function addon_id_from_product_name( string $product_name, ?array $addons = null ): ?string { |
| 108 | if ( self::is_all_access_bundle_name( $product_name ) ) { |
| 109 | return null; |
| 110 | } |
| 111 | |
| 112 | $target = self::normalize_name( $product_name ); |
| 113 | if ( '' === $target ) { |
| 114 | return null; |
| 115 | } |
| 116 | |
| 117 | $target = self::strip_tier_suffix( $target ); |
| 118 | if ( '' === $target ) { |
| 119 | return null; |
| 120 | } |
| 121 | |
| 122 | $addons = $addons ?? self::addon_manifest(); |
| 123 | |
| 124 | foreach ( $addons as $row ) { |
| 125 | if ( empty( $row['id'] ) || empty( $row['name'] ) ) { |
| 126 | continue; |
| 127 | } |
| 128 | |
| 129 | $addon_name = self::normalize_name( (string) $row['name'] ); |
| 130 | $aliases = isset( $row['aliases'] ) && is_array( $row['aliases'] ) |
| 131 | ? $row['aliases'] |
| 132 | : array_values( |
| 133 | array_filter( |
| 134 | [ |
| 135 | $addon_name, |
| 136 | '' !== $addon_name ? 'advanced ads ' . $addon_name : '', |
| 137 | ] |
| 138 | ) |
| 139 | ); |
| 140 | |
| 141 | if ( in_array( $target, $aliases, true ) || ( '' !== $addon_name && str_ends_with( $target, ' ' . $addon_name ) ) ) { |
| 142 | return (string) $row['id']; |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | return null; |
| 147 | } |
| 148 | } |
| 149 |