is_active() ) { ... } */ class Robotstxt_Mlp2_Mlp5_Detector_Mlp5 { /** * Known plugin basename for MultilingualPress 5 (commercial, Inpsyde). * * @var string */ const PLUGIN_BASENAME = 'multilingualpress/multilingualpress.php'; /** * Resolved MLP5 plugin basename, or empty string if not found on disk. * * @var string */ private string $plugin_file; /** * Plugin header data from get_plugin_data(), or empty array if unavailable. * * @var array */ private array $plugin_data; /** * Constructor. Locates the MLP5 plugin file and loads its header data. */ public function __construct() { $this->plugin_file = $this->find_plugin_file(); $this->plugin_data = $this->plugin_file ? $this->load_plugin_data() : array(); } /** * Whether MultilingualPress 5 is currently network-active. * * MLP5 must be active for migration to proceed; its API tables and * internal state are only available when the plugin is running. * * @return bool */ public function is_active(): bool { if ( ! function_exists( 'is_plugin_active_for_network' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } return '' !== $this->plugin_file && is_plugin_active_for_network( $this->plugin_file ); } /** * Return the MLP5 version string, or empty string if unavailable. * * @return string */ public function get_version(): string { return isset( $this->plugin_data['Version'] ) ? (string) $this->plugin_data['Version'] : ''; } /** * Return the resolved MLP5 plugin basename, or empty string if not on disk. * * @return string */ public function get_plugin_file(): string { return $this->plugin_file; } /** * Return the MLP5 site relations table name, or empty string if absent. * * MLP5 uses the same mlp_site_relations table name as MLP2. * * @return string */ public function get_site_relations_table(): string { global $wpdb; $table = $wpdb->base_prefix . 'mlp_site_relations'; return $this->table_exists( $table ) ? $table : ''; } /** * Return the MLP5 relationship groups table name, or empty string if absent. * * MLP5 stores one row per group of related content here (id, type). * The content_relations table references this table via relationship_id. * * @return string */ public function get_relationships_table(): string { global $wpdb; $table = $wpdb->base_prefix . 'mlp_relationships'; return $this->table_exists( $table ) ? $table : ''; } /** * Return the MLP5 content relations table name, or empty string if absent. * * MLP5 uses mlp_content_relations (the newer name introduced in MLP2 * late versions and carried forward). * * @return string */ public function get_content_relations_table(): string { global $wpdb; $table = $wpdb->base_prefix . 'mlp_content_relations'; return $this->table_exists( $table ) ? $table : ''; } /** * Return all tables in the database that match the MLP table prefix pattern. * * @return string[] Array of full table names. */ public function get_all_tables(): array { global $wpdb; $like = $wpdb->esc_like( $wpdb->base_prefix . 'mlp_' ) . '%'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $tables = $wpdb->get_col( $wpdb->prepare( 'SHOW TABLES LIKE %s', $like ) ); return is_array( $tables ) ? $tables : array(); } /** * Check whether a given table exists in the database. * * @param string $table Full table name (including prefix). * @return bool */ private function table_exists( string $table ): bool { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching return (string) $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ) === $table; } /** * Locate the MLP5 plugin file on disk. * * Checks the known canonical basename first. If not found, scans all * installed plugins for a plugin named "MultilingualPress" with a * version of 3.0.0 or higher (MLP3+ series includes MLP5). * * @return string Plugin basename, or empty string if not found. */ private function find_plugin_file(): string { if ( file_exists( WP_PLUGIN_DIR . '/' . self::PLUGIN_BASENAME ) ) { return self::PLUGIN_BASENAME; } if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } foreach ( get_plugins() as $basename => $data ) { if ( isset( $data['Name'], $data['Version'] ) && 'MultilingualPress' === $data['Name'] && version_compare( (string) $data['Version'], '3.0.0', '>=' ) ) { return $basename; } } return ''; } /** * Load plugin header data from the MLP5 main file. * * @return array Plugin data from get_plugin_data(), or empty array on failure. */ private function load_plugin_data(): array { if ( ! function_exists( 'get_plugin_data' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $path = WP_PLUGIN_DIR . '/' . $this->plugin_file; if ( ! file_exists( $path ) ) { return array(); } return get_plugin_data( $path, false, false ); } }