v1.0.0
This commit is contained in:
parent
8caa140991
commit
5cdf7f48e5
29 changed files with 6526 additions and 0 deletions
197
includes/class-robotstxt-mlp2-mlp5-reader-content-relations.php
Normal file
197
includes/class-robotstxt-mlp2-mlp5-reader-content-relations.php
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
<?php
|
||||
/**
|
||||
* MLP2 content relations reader.
|
||||
*
|
||||
* Reads post and term relation data from the MLP2 backup content_relations
|
||||
* table. Relations are grouped by (ml_source_blogid, ml_source_elementid)
|
||||
* so that each group can be written as a single MLP5 relationship.
|
||||
*
|
||||
* MLP2 backup table schema (mlp2bak_content_relations or mlp2bak_relationships):
|
||||
* ml_source_blogid INT -- source site ID
|
||||
* ml_source_elementid INT -- source element (post/term) ID
|
||||
* ml_blogid INT -- target site ID
|
||||
* ml_elementid INT -- target element ID
|
||||
* ml_type VARCHAR -- 'post' or 'term'
|
||||
*
|
||||
* @package Robotstxt_Mlp2_Mlp5
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Robotstxt_Mlp2_Mlp5_Reader_Content_Relations
|
||||
*/
|
||||
class Robotstxt_Mlp2_Mlp5_Reader_Content_Relations {
|
||||
|
||||
/**
|
||||
* Count distinct source groups for a given type.
|
||||
*
|
||||
* @param string $type 'post' or 'term'.
|
||||
* @return int
|
||||
*/
|
||||
public static function count_groups( string $type ): int {
|
||||
global $wpdb;
|
||||
|
||||
$mlp2 = new Robotstxt_Mlp2_Mlp5_Detector_Mlp2();
|
||||
$table = $mlp2->get_content_relations_table();
|
||||
|
||||
if ( '' === $table ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
list( $src_blog, $src_elem ) = self::source_columns( $mlp2, $table );
|
||||
if ( '' === $src_blog ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$type_safe = ( 'term' === $type ) ? 'term' : 'post';
|
||||
|
||||
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
return (int) $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(DISTINCT {$src_blog}, {$src_elem}) FROM `{$table}` WHERE ml_type = %s",
|
||||
$type_safe
|
||||
)
|
||||
);
|
||||
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a batch of distinct source groups, with all their translation members.
|
||||
*
|
||||
* Each returned element is:
|
||||
* [
|
||||
* 'type' => string, // 'post' or 'term'
|
||||
* 'members' => [
|
||||
* ['site_id' => int, 'element_id' => int],
|
||||
* ...
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
* The source element itself is always included as a member.
|
||||
*
|
||||
* @param string $type 'post' or 'term'.
|
||||
* @param int $offset Offset into the distinct source list.
|
||||
* @param int $limit Number of groups to return.
|
||||
* @return array[]
|
||||
*/
|
||||
public static function get_groups_batch( string $type, int $offset, int $limit ): array {
|
||||
global $wpdb;
|
||||
|
||||
$mlp2 = new Robotstxt_Mlp2_Mlp5_Detector_Mlp2();
|
||||
$table = $mlp2->get_content_relations_table();
|
||||
|
||||
if ( '' === $table ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
list( $src_blog, $src_elem ) = self::source_columns( $mlp2, $table );
|
||||
if ( '' === $src_blog ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$type_safe = ( 'term' === $type ) ? 'term' : 'post';
|
||||
|
||||
// Fetch a page of distinct sources.
|
||||
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$sources = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT DISTINCT {$src_blog} AS source_blog, {$src_elem} AS source_elem FROM `{$table}` WHERE ml_type = %s ORDER BY {$src_blog}, {$src_elem} LIMIT %d OFFSET %d",
|
||||
$type_safe,
|
||||
$limit,
|
||||
$offset
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
|
||||
if ( empty( $sources ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$groups = array();
|
||||
|
||||
foreach ( $sources as $source ) {
|
||||
$src_blog_id = (int) $source['source_blog'];
|
||||
$src_elem_id = (int) $source['source_elem'];
|
||||
|
||||
// Fetch all translations for this source.
|
||||
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$translations = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT ml_blogid, ml_elementid FROM `{$table}` WHERE ml_type = %s AND {$src_blog} = %d AND {$src_elem} = %d",
|
||||
$type_safe,
|
||||
$src_blog_id,
|
||||
$src_elem_id
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
|
||||
// Build members: source + all translations (deduplicated).
|
||||
$seen = array();
|
||||
$members = array();
|
||||
|
||||
$source_key = $src_blog_id . ':' . $src_elem_id;
|
||||
$seen[ $source_key ] = true;
|
||||
$members[] = array(
|
||||
'site_id' => $src_blog_id,
|
||||
'element_id' => $src_elem_id,
|
||||
);
|
||||
|
||||
foreach ( (array) $translations as $t ) {
|
||||
$key = ( (int) $t['ml_blogid'] ) . ':' . ( (int) $t['ml_elementid'] );
|
||||
if ( isset( $seen[ $key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
$seen[ $key ] = true;
|
||||
$members[] = array(
|
||||
'site_id' => (int) $t['ml_blogid'],
|
||||
'element_id' => (int) $t['ml_elementid'],
|
||||
);
|
||||
}
|
||||
|
||||
if ( count( $members ) >= 2 ) {
|
||||
$groups[] = array(
|
||||
'type' => $type_safe,
|
||||
'members' => $members,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the source-blog and source-element column names.
|
||||
*
|
||||
* Returns ['', ''] when columns cannot be determined.
|
||||
*
|
||||
* @param Robotstxt_Mlp2_Mlp5_Detector_Mlp2 $mlp2 MLP2 detector.
|
||||
* @param string $table Content relations table name.
|
||||
* @return string[] [ $source_blog_col, $source_element_col ]
|
||||
*/
|
||||
private static function source_columns( Robotstxt_Mlp2_Mlp5_Detector_Mlp2 $mlp2, string $table ): array {
|
||||
$cols = $mlp2->describe_table( $table );
|
||||
|
||||
$blog_col = '';
|
||||
foreach ( array( 'ml_source_blogid', 'ml_blogid' ) as $c ) {
|
||||
if ( isset( $cols[ $c ] ) ) {
|
||||
$blog_col = $c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$elem_col = '';
|
||||
foreach ( array( 'ml_source_elementid', 'ml_elementid' ) as $c ) {
|
||||
if ( isset( $cols[ $c ] ) ) {
|
||||
$elem_col = $c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array( $blog_col, $elem_col );
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue