218 lines
5.7 KiB
PHP
218 lines
5.7 KiB
PHP
<?php
|
|
/**
|
|
* MultilingualPress 5 detection service.
|
|
*
|
|
* Detects whether MultilingualPress 5 is installed (active or inactive),
|
|
* reads its plugin metadata, and identifies its database tables.
|
|
*
|
|
* MLP5 must be network-active for migration to proceed. Unlike MLP2,
|
|
* the plugin itself needs to be running so its API is available.
|
|
*
|
|
* @package Robotstxt_Mlp2_Mlp5
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Class Robotstxt_Mlp2_Mlp5_Detector_Mlp5
|
|
*
|
|
* Instantiate once to detect MLP5; all detection results are cached in
|
|
* instance properties to avoid repeated file or database reads.
|
|
*
|
|
* Usage:
|
|
* $mlp5 = new Robotstxt_Mlp2_Mlp5_Detector_Mlp5();
|
|
* if ( $mlp5->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 );
|
|
}
|
|
}
|