is_plugin_active() ) { return false; } // Check if the plugin has a valid default language configured $default_language = $this->get_default_language(); if ( empty( $default_language ) ) { return false; } return true; } /** * Get all available languages * * @return array Array of language data */ abstract public function get_available_languages(): array; /** * Get the default language code * * @return string|null Default language code or null if not set */ abstract public function get_default_language(): ?string; /** * Check if the plugin is installed (but not necessarily active) * * @return bool True if plugin files exist */ public function is_plugin_installed(): bool { $plugin_file = WP_PLUGIN_DIR . '/' . $this->get_plugin_file_name(); return file_exists( $plugin_file ); } /** * Get plugin version if available * * @return string|null Plugin version or null if not available */ public function get_plugin_version(): ?string { if ( ! $this->is_plugin_active() ) { return null; } $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $this->get_plugin_file_name() ); return $plugin_data['Version'] ?? null; } /** * Get products from the default language * * Uses a template method pattern to reduce code duplication. * Subclasses only need to implement the plugin-specific language checking logic. * * @param int $limit Maximum number of products to return (-1 for all products) * @param int $offset Offset for pagination * @return array Array of product IDs from the default language */ public function get_products_from_default_language( int $limit = 10, int $offset = 0 ): array { if ( ! $this->is_plugin_active() ) { return []; } $default_language_locale = $this->get_default_language(); if ( ! $default_language_locale ) { return []; } // Get plugin-specific language identifier for the default language $default_language_identifier = $this->get_plugin_language_identifier( $default_language_locale ); if ( ! $default_language_identifier ) { return []; } // Query products $args = [ 'post_type' => 'product', 'post_status' => 'publish', 'posts_per_page' => $limit, 'offset' => $offset, 'fields' => 'ids', ]; $all_products = get_posts( $args ); $default_language_products = []; // Filter products using plugin-specific language check foreach ( $all_products as $product_id ) { if ( $this->is_product_in_language( $product_id, $default_language_identifier ) ) { $default_language_products[] = $product_id; } } return $default_language_products; } /** * Get the plugin-specific language identifier for a given locale * * Converts a full locale (e.g., 'es_ES') to the plugin's internal language identifier. * For WPML, this is the WPML language code. For Polylang, this is the language slug. * * @param string $locale Full locale code (e.g., 'es_ES', 'fr_FR') * @return string|null Plugin-specific language identifier or null if not found */ abstract protected function get_plugin_language_identifier( string $locale ): ?string; /** * Check if a product is in a specific language * * Uses plugin-specific API to determine if a product belongs to a language. * * @param int $product_id Product ID to check * @param string $language_identifier Plugin-specific language identifier * @return bool True if product is in the specified language */ abstract protected function is_product_in_language( int $product_id, string $language_identifier ): bool; /** * Get detailed translation information for a product * * Default implementation that can be overridden by specific integrations. * * @param int $product_id Product ID (should be from default language) * @return array Detailed translation information */ public function get_product_translation_details( int $product_id ): array { // Default implementation - return basic structure // Specific integrations should override this method return [ 'product_id' => $product_id, 'default_language' => $this->get_default_language(), 'translations' => [], 'translation_status' => [], 'translated_fields' => [], ]; } /** * Switch to a specific language context * * This method is used by the Facebook_Fields_Translation_Trait to switch * the current language context when checking for translated permalinks. * Implementations should store and return the previous language code. * * @param string $locale Full locale code (e.g., 'es_ES', 'zh_CN') * @return string|null The previous language code if successful, null otherwise * @since 3.6.0 */ abstract public function switch_to_language( string $locale ): ?string; /** * Restore a previous language context * * This method is used by the Facebook_Fields_Translation_Trait to restore * the original language context after checking for translated permalinks. * * @param string $language_code The language code to restore * @return void * @since 3.6.0 */ abstract public function restore_language( string $language_code ): void; /** * Get availability data for telemetry reporting * * Provides standardized data collection for integration availability logging. * This method is used by the IntegrationAvailabilityLogger to collect * telemetry data about which integrations are available and active. * * @return array Integration availability data */ public function get_availability_data(): array { $data = [ 'plugin_name' => $this->get_plugin_name(), 'plugin_file' => $this->get_plugin_file_name(), 'is_installed' => $this->is_plugin_installed(), 'is_active' => $this->is_plugin_active(), ]; // Add version if available $version = $this->get_plugin_version(); if ( $version ) { $data['version'] = $version; } return $data; } }