new NoneAdapter(), 'wpml' => self::installed(new WpmlAdapter(), 'WPML'), 'polylang' => self::installed(new PolylangAdapter(), 'Polylang'), '' => self::detect(), default => throw new RuntimeException( sprintf('Unsupported WooCommerce translation plugin: %s.', $requested) ), }; } /** @param array $canonical */ public static function fromCanonical(array $canonical): MultilingualAdapter { $requested = sanitize_key((string) ($canonical['multilingual_plugin'] ?? '')); return self::make($requested !== '' ? $requested : null); } /** @param array $canonical */ public static function publicationProductId( MultilingualAdapter $adapter, int $productId, array $canonical = [] ): int { if ($productId <= 0) { return 0; } $language = sanitize_key((string) ($canonical['language'] ?? '')); $map = $adapter->translationMap($productId); if ($language !== '' && isset($map[$language]) && (int) $map[$language] > 0) { return (int) $map[$language]; } if ($language !== '' && $adapter->productLanguage($productId) === $language) { return $productId; } if ($language === '') { $default = sanitize_key($adapter->defaultLanguage()); if ($default !== '' && isset($map[$default]) && (int) $map[$default] > 0) { return (int) $map[$default]; } return $adapter->originalProductId($productId); } $original = $adapter->originalProductId($productId); $translated = $adapter->translatedProductId($original, $language); if ($translated) { return $translated; } if (!$adapter->available() || $adapter instanceof NoneAdapter) { return $original; } throw new RuntimeException('The selected product has no ' . $language . ' translation. Repair its language link before publication.'); } private static function detect(): MultilingualAdapter { $wpml = new WpmlAdapter(); if ($wpml->available()) { return $wpml; } $polylang = new PolylangAdapter(); // A store with neither plugin gets the adapter that does nothing, // instead of one that reports a language the store does not have. return $polylang->available() ? $polylang : new NoneAdapter(); } private static function installed(MultilingualAdapter $adapter, string $label): MultilingualAdapter { if (!$adapter->available()) { throw new RuntimeException($label . ' is not installed on this WooCommerce store.'); } return $adapter; } }