File: /var/www/biblioteka/wp-content/plugins/qtranslate-xt-3.15.2/src/admin/admin_utils_db.php
<?php
function qtranxf_convert_database( string $action ): string {
switch ( $action ) {
case 'b_only':
case 'c_dual':
{
global $wpdb;
$wpdb->show_errors();
@set_time_limit( 0 );
qtranxf_convert_database_options( $action );
qtranxf_convert_database_posts( $action );
qtranxf_convert_database_postmeta( $action );
}
break;
case 'db_split':
if ( ! empty( $_POST['db_file'] ) ) {
global $q_config;
$ifp = wp_unslash( sanitize_text_field( $_POST['db_file'] ) );
$q_config['db_file'] = $ifp;
$db_langs = wp_unslash( sanitize_text_field( $_POST['db_langs'] ) );
$languages_to_keep = preg_split( '/[,\\s]+/', $db_langs );
$enabled_languages = $q_config['enabled_languages'];
$default_language = $q_config['default_language'];
if ( ! is_array( $languages_to_keep ) ) {
$languages_to_keep = array( $default_language );
}
$q_config['db_langs'] = implode( ', ', $languages_to_keep );
$msg = qtranxf_split_database_file( $ifp, $languages_to_keep );
$q_config['enabled_languages'] = $enabled_languages;
$q_config['default_language'] = $default_language;
return $msg;
}
break;
case 'db_clean_terms':
return qtranxf_db_clean_terms();
default:
break;
}
switch ( $action ) {
case 'b_only':
return __( 'Database has been converted to square bracket format.', 'qtranslate' ) . '<br/>' . __( 'Note: custom entries are not touched.', 'qtranslate' );
case 'c_dual':
return __( 'Database has been converted to legacy dual-tag format.', 'qtranslate' ) . '<br/>' . __( 'Note: custom entries are not touched.', 'qtranslate' );
default:
return '';
}
}
function qtranxf_convert_to_b( $text ) {
$blocks = qtranxf_get_language_blocks( $text );
if ( count( $blocks ) > 1 ) {
foreach ( $blocks as $key => $block ) {
if ( empty( $block ) ) {
unset( $blocks[ $key ] );
}
}
}
if ( count( $blocks ) <= 1 ) {
return $text;
}
$text = '';
$lang = false;
$lang_closed = true;
$lang_code = QTX_LANG_CODE_FORMAT;
foreach ( $blocks as $block ) {
if ( preg_match( "#^<!--:($lang_code)-->$#ism", $block, $matches ) ) {
$lang_closed = false;
$lang = $matches[1];
$text .= '[:' . $lang . ']';
continue;
} elseif ( preg_match( "#^\[:($lang_code)]$#ism", $block, $matches ) ) {
$lang_closed = false;
$lang = $matches[1];
$text .= '[:' . $lang . ']';
continue;
}
switch ( $block ) {
case '[:]':
case '<!--:-->':
$lang = false;
break;
default:
if ( ! $lang && ! $lang_closed ) {
$text .= '[:]';
$lang_closed = true;
}
$text .= $block;
break;
}
}
$text .= '[:]';
return $text;
}
function qtranxf_convert_to_b_no_closing( $text ) {
$blocks = qtranxf_get_language_blocks( $text );
if ( count( $blocks ) > 1 ) {
foreach ( $blocks as $key => $b ) {
if ( empty( $b ) ) {
unset( $blocks[ $key ] );
}
}
}
if ( count( $blocks ) > 1 ) {
$texts = qtranxf_split_blocks( $blocks );
$text = qtranxf_join_b_no_closing( $texts );
}
return $text;
}
function qtranxf_convert_to_c( $text ) {
$blocks = qtranxf_get_language_blocks( $text );
if ( count( $blocks ) > 1 ) {
foreach ( $blocks as $key => $b ) {
if ( empty( $b ) ) {
unset( $blocks[ $key ] );
}
}
}
if ( count( $blocks ) > 1 ) {
$texts = qtranxf_split_blocks( $blocks );
$text = qtranxf_join_c( $texts );
}
return $text;
}
function qtranxf_convert_to_b_deep( $text ) {
if ( is_array( $text ) ) {
foreach ( $text as $key => $t ) {
$text[ $key ] = qtranxf_convert_to_b_deep( $t );
}
return $text;
}
if ( is_object( $text ) || $text instanceof __PHP_Incomplete_Class ) {
foreach ( get_object_vars( $text ) as $key => $t ) {
$text->$key = qtranxf_convert_to_b_deep( $t );
}
return $text;
}
if ( ! is_string( $text ) || empty( $text ) ) {
return $text;
}
return qtranxf_convert_to_b( $text );
}
function qtranxf_convert_to_b_no_closing_deep( $text ) {
if ( is_array( $text ) ) {
foreach ( $text as $key => $t ) {
$text[ $key ] = qtranxf_convert_to_b_no_closing_deep( $t );
}
return $text;
}
if ( is_object( $text ) || $text instanceof __PHP_Incomplete_Class ) {
foreach ( get_object_vars( $text ) as $key => $t ) {
$text->$key = qtranxf_convert_to_b_no_closing_deep( $t );
}
return $text;
}
if ( ! is_string( $text ) || empty( $text ) ) {
return $text;
}
return qtranxf_convert_to_b_no_closing( $text );
}
function qtranxf_convert_database_options( string $action ): void {
global $wpdb;
$wpdb->show_errors();
$result = $wpdb->get_results( 'SELECT option_id, option_value FROM ' . $wpdb->options );
if ( ! $result ) {
return;
}
switch ( $action ) {
case 'b_only':
foreach ( $result as $row ) {
if ( ! qtranxf_isMultilingual( $row->option_value ) ) {
continue;
}
$value = maybe_unserialize( $row->option_value );
$value_converted = qtranxf_convert_to_b_deep( $value );
$value_serialized = maybe_serialize( $value_converted );
if ( $value_serialized === $row->option_value ) {
continue;
}
// Since 3.2-b3: Replaced mysql_real_escape_string with $wpdb->prepare
$wpdb->query( $wpdb->prepare( 'UPDATE ' . $wpdb->options . ' set option_value = %s WHERE option_id = %d', $value_serialized, $row->option_id ) );
}
break;
case 'c_dual':
foreach ( $result as $row ) {
if ( ! qtranxf_isMultilingual( $row->option_value ) ) {
continue;
}
$value = maybe_unserialize( $row->option_value );
$value_converted = qtranxf_convert_to_b_no_closing_deep( $value );
$value_serialized = maybe_serialize( $value_converted );
if ( $value_serialized === $row->option_value ) {
continue;
}
// Since 3.2-b3: Replaced mysql_real_escape_string with $wpdb->prepare
$wpdb->query( $wpdb->prepare( 'UPDATE ' . $wpdb->options . ' set option_value = %s WHERE option_id = %d', $value_serialized, $row->option_id ) );
}
break;
default:
break;
}
}
function qtranxf_convert_database_posts( string $action ): void {
global $wpdb;
$result = $wpdb->get_results( 'SELECT ID, post_title, post_content, post_excerpt FROM ' . $wpdb->posts );
if ( ! $result ) {
return;
}
switch ( $action ) {
case 'b_only':
foreach ( $result as $row ) {
$title = qtranxf_convert_to_b( $row->post_title );
$content = qtranxf_convert_to_b( $row->post_content );
$excerpt = qtranxf_convert_to_b( $row->post_excerpt );
if ( $title == $row->post_title && $content == $row->post_content && $excerpt == $row->post_excerpt ) {
continue;
}
// Since 3.2-b3: Replaced mysql_real_escape_string with $wpdb->prepare
$wpdb->query( $wpdb->prepare( 'UPDATE ' . $wpdb->posts . ' set post_content = %s, post_title = %s, post_excerpt = %s WHERE ID = %d', $content, $title, $excerpt, $row->ID ) );
}
break;
case 'c_dual':
foreach ( $result as $row ) {
$title = qtranxf_convert_to_c( $row->post_title );
$content = qtranxf_convert_to_c( $row->post_content );
$excerpt = qtranxf_convert_to_c( $row->post_excerpt );
if ( $title == $row->post_title && $content == $row->post_content && $excerpt == $row->post_excerpt ) {
continue;
}
// Since 3.2-b3: Replaced mysql_real_escape_string with $wpdb->prepare
$wpdb->query( $wpdb->prepare( 'UPDATE ' . $wpdb->posts . ' set post_content = %s, post_title = %s, post_excerpt = %s WHERE ID = %d', $content, $title, $excerpt, $row->ID ) );
}
break;
default:
break;
}
}
function qtranxf_convert_database_postmeta( string $action ): void {
global $wpdb;
$result = $wpdb->get_results( 'SELECT meta_id, meta_value FROM ' . $wpdb->postmeta );
if ( ! $result ) {
return;
}
switch ( $action ) {
case 'b_only':
foreach ( $result as $row ) {
if ( ! qtranxf_isMultilingual( $row->meta_value ) ) {
continue;
}
$value = maybe_unserialize( $row->meta_value );
$value_converted = qtranxf_convert_to_b_deep( $value );
$value_serialized = maybe_serialize( $value_converted );
if ( $value_serialized === $row->meta_value ) {
continue;
}
$wpdb->query( $wpdb->prepare( 'UPDATE ' . $wpdb->postmeta . ' set meta_value = %s WHERE meta_id = %d', $value_serialized, $row->meta_id ) );
}
break;
case 'c_dual':
foreach ( $result as $row ) {
if ( ! qtranxf_isMultilingual( $row->meta_value ) ) {
continue;
}
$value = maybe_unserialize( $row->meta_value );
$value_converted = qtranxf_convert_to_b_no_closing_deep( $value );
$value_serialized = maybe_serialize( $value_converted );
if ( $value_serialized === $row->meta_value ) {
continue;
}
$wpdb->query( $wpdb->prepare( 'UPDATE ' . $wpdb->postmeta . ' set meta_value = %s WHERE meta_id = %d', $value_serialized, $row->meta_id ) );
}
break;
default:
break;
}
}
/**
*/
function qtranxf_split_database_file( string $ifp, array $languages_to_keep ): string {
global $q_config;
$errors = $q_config['url_info']['errors'];
$ifh = fopen( $ifp, 'r' );
if ( ! $ifh ) {
$errors[] = sprintf( __( 'Failed to open input database file "%s"', 'qtranslate' ), $ifp );
return '';
}
$fld = dirname( $ifp );
$bnm = basename( $ifp, '.sql' );
$q_config['enabled_languages'] = $languages_to_keep;
$default_language = $languages_to_keep[0];
$dfp = $fld . '/' . $bnm . '-' . $default_language . '.sql';
$dfh = fopen( $dfp, 'w' );
if ( ! $dfh ) {
fclose( $ifh );
$errors[] = sprintf( __( 'Failed to open output database file "%s"', 'qtranslate' ), $dfp );
return '';
}
$files[ $default_language ] = array( 'fp' => $dfp, 'fh' => $dfh );
$mfp = '';
$mfh = null;
$lang2keep = array();
$n = count( $languages_to_keep );
if ( $n > 1 ) {
$sfx = $n < 5 ? implode( '-', $languages_to_keep ) : $n . '_languages_requested';
$mfp = $fld . '/' . $bnm . '-' . $sfx . '.sql';
$mfh = fopen( $mfp, 'w' );
if ( ! $mfh ) {
fclose( $ifh );
fclose( $dfh );
$errors[] = sprintf( __( 'Failed to open output database file "%s"', 'qtranslate' ), $mfp );
return '';
}
}
foreach ( $languages_to_keep as $lang ) {
$lang2keep[ $lang ] = $lang;
}
$cnt = 0;
while ( ( $s = fgets( $ifh ) ) ) {
if ( qtranxf_isMultilingual( $s ) ) {
++$cnt;
$lns = qtranxf_split( $s );
$ok = true;
foreach ( $lns as $lang => $ln ) {
if ( ! isset( $lang2keep[ $lang ] ) && ! isset( $files[ $lang ] ) ) {
$ok = false;
$q_config['enabled_languages'][] = $lang;
$lfp = $fld . '/' . $bnm . '-' . $lang . '.sql';
fflush( $dfh );
copy( $dfp, $lfp );
$lfh = fopen( $lfp, 'a+' );
if ( ! $lfh ) {
fclose( $ifh );
foreach ( $files as $file ) {
if ( ! isset( $file['fh'] ) ) {
continue;
}
fclose( $file['fh'] );
}
$errors[] = sprintf( __( 'Failed to open output database file "%s"', 'qtranslate' ), $lfp );
return '';
}
$files[ $lang ] = array( 'fp' => $lfp, 'fh' => $lfh );
}
}
if ( ! $ok ) {
$lns = qtranxf_split( $s );
}
if ( $mfh ) {
foreach ( $languages_to_keep as $lang ) {
if ( $default_language != $lang ) {
unset( $lns[ $lang ] );
}
}
$ln = qtranxf_extract_languages( $s, $lang2keep );
fputs( $mfh, $ln );
}
foreach ( $lns as $lang => $ln ) {
fputs( $files[ $lang ]['fh'], $ln . PHP_EOL );
}
} else {
foreach ( $files as &$file ) {
fputs( $file['fh'], $s );
}
if ( $mfh ) {
fputs( $mfh, $s );
}
}
}
fclose( $ifh );
foreach ( $files as $file ) {
fclose( $file['fh'] );
}
if ( $mfh ) {
fclose( $mfh );
if ( isset( $lang2keep[ $default_language ] ) ) {
unlink( $files[ $default_language ]['fp'] );
unset( $files[ $default_language ] );
}
}
$fns = PHP_EOL . '<br/>' . implode( PHP_EOL . '<br/>', array_column( $files, 'fp' ) );
if ( $mfp ) {
$fns = PHP_EOL . '<br/>' . $mfp . $fns;
}
return sprintf( __( 'The database file provided has been split as requested. Number of multilingual strings found is %s. The result files are:%s', 'qtranslate' ), $cnt, $fns );
}
function qtranxf_extract_languages( $text, array $lang2keep ): string {
$blocks = qtranxf_get_language_blocks( $text );
$s = '';
$current_language = false;
$eol = false;
$lang_code = QTX_LANG_CODE_FORMAT;
foreach ( $blocks as $block ) {
// detect c-tags
if ( preg_match( "#^<!--:($lang_code)-->$#ism", $block, $matches ) ) {
$current_language = $matches[1];
if ( isset( $lang2keep[ $current_language ] ) ) {
$s .= $block;
$eol = true;
}
continue;
// detect b-tags
} elseif ( preg_match( "#^\[:($lang_code)]$#ism", $block, $matches ) ) {
$current_language = $matches[1];
if ( isset( $lang2keep[ $current_language ] ) ) {
$s .= $block;
$eol = true;
}
continue;
// detect s-tags @since 3.3.6 swirly bracket encoding added
} elseif ( preg_match( "#^{:($lang_code)}$#ism", $block, $matches ) ) {
$current_language = $matches[1];
if ( isset( $lang2keep[ $current_language ] ) ) {
$s .= $block;
$eol = true;
}
continue;
}
switch ( $block ) {
case '[:]':
case '{:}':
case '<!--:-->':
if ( $eol ) {
$s .= $block;
}
$current_language = false;
$eol = false;
break;
default:
if ( $current_language ) {
if ( isset( $lang2keep[ $current_language ] ) ) {
$s .= $block;
}
$current_language = false;
$eol = true;
} else {
$s .= $block;
}
break;
}
}
return $s;
}
function qtranxf_db_clean_terms(): string {
global $wpdb, $q_config;
$errors = &$q_config['url_info']['errors'];
$messages = &$q_config['url_info']['messages'];
$wpdb->show_errors();
@set_time_limit( 0 );
$result = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->terms );
if ( ! $result ) {
$errors[] = __( 'Could not fetch the list of terms from database.', 'qtranslate' );
return __( 'Nothing has been altered.', 'qtranslate' );
}
qtranxf_term_admin_remove_filters();
$default_langauge = $q_config['default_language'];
$term_name_cur = $q_config['term_name'];
$q_config['term_name'] = array();//to exclude any possible alternations of term names via filters.
$term_name = array();
$msgs = array();
foreach ( $result as $row ) {
$id = $row->term_id;
$nm = $row->name;
$term = get_term( $id );
if ( ! ( $term instanceof WP_Term ) ) {
if ( $term instanceof WP_Error ) {
$errs = $term->get_error_messages();
} else {
$errs = array( __( 'Term configuration is inconsistent.', 'qtranslate' ) );
}
$messages[] = sprintf( __( 'Term "%s" (id=%d) cannot be loaded and is left untouched. Error message on load was:%s', 'qtranslate' ), $nm, $id, '<br/>' . PHP_EOL . '"' . implode( '"<br/>"' . PHP_EOL, $errs ) . '"' ) . '<br/>';
continue;
} else {
$taxonomy = $term->taxonomy;
}
if ( $taxonomy == 'nav_menu' ) {
continue;
}
if ( qtranxf_isMultilingual( $nm ) ) {
$ts = qtranxf_split( $nm );
if ( empty( $ts[ $default_langauge ] ) ) {
foreach ( $q_config['enabled_languages'] as $lng ) {
$v = trim( $ts[ $lng ] );
$ts[ $lng ] = $v;
if ( empty( $v ) ) {
continue;
}
$ts[ $default_langauge ] = $v;
break;
}
}
} else if ( ! empty( $term_name_cur[ $nm ] ) && is_array( $term_name_cur[ $nm ] ) ) {
$ts = $term_name_cur[ $nm ];
} else {
continue;
}
$nm_cur = $nm;
$ts_cur = empty( $term_name_cur[ $nm ] ) ? array() : $term_name_cur[ $nm ];
foreach ( $ts as $lng => $v ) {
$val = trim( $v );
$val = addslashes( $val );
$val = apply_filters( 'pre_term_name', $val );
$val = stripcslashes( $val );
$ts[ $lng ] = $val;
}
$ok = ! empty( $ts[ $default_langauge ] );
if ( ! $ok ) {
$ts[ $default_langauge ] = $nm_cur;
} else {
$ok = ( $ts[ $default_langauge ] == $nm_cur );
}
if ( ! $ok ) {
$nm = $ts[ $default_langauge ];
wp_update_term( $id, $taxonomy, array( 'name' => $nm ) );
}
$term_name[ $nm ] = $ts;
if ( $ok && ! empty( $ts_cur ) ) {
$ok = qtranxf_array_compare( $ts, $ts_cur );
}
if ( $ok ) {
$ok = ( $nm == $nm_cur );
}
if ( $ok ) {
continue;
}
//report the change
$ts_old = array();
foreach ( $ts_cur as $lng => $val ) {
$ts_old[] = $lng . ' => "' . esc_html( $val ) . '"';
}
$ts_new = array();
foreach ( $ts as $lng => $val ) {
$ts_new[] = $lng . ' => "' . esc_html( $val ) . '"';
}
$msgs[] = sprintf( __( 'Term "%s" (id=%d) has been modified from:%sto:%s', 'qtranslate' ), esc_html( $nm ), $id
, '<br/>' . PHP_EOL . '"' . esc_html( $nm_cur ) . '" => { ' . implode( ', ', $ts_old ) . ' }<br/>' . PHP_EOL
, '<br/>' . PHP_EOL . '"' . esc_html( $nm ) . '" => { ' . implode( ', ', $ts_new ) . ' }<br/>' . PHP_EOL
);
}
if ( ! qtranxf_array_compare( $term_name_cur, $term_name ) ) {
update_option( 'qtranslate_term_name', $term_name );
}
$q_config['term_name'] = $term_name;
qtranxf_term_admin_add_filters();
if ( empty( $msgs ) ) {
$msg = __( 'No term has been modified. All terms are already in a consistent state.', 'qtranslate' );
} else {
$msg = '<ol>' . PHP_EOL . '<li>' . join( '</li>' . PHP_EOL . '<li>', $msgs ) . '</li>' . PHP_EOL . '</ol>' . PHP_EOL;
$msg .= __( 'Save this report for further analysis, if necessary.', 'qtranslate' );
}
return __( 'Legacy term names have been cleaned up:', 'qtranslate' ) . '<br/>' . PHP_EOL . $msg . PHP_EOL;
}