<?php

class wpdb2 extends wpdb {

    
/**
     * Version number, to check what features are available.
     *
     * @since 6.0.0 - V2: wbdb::prepare() supports Identifiers via 'SELECT * FROM %i', and Variadics via 'IN (%...d)'
     *
     * @var int
     */
    
public $version 2;

    
/**
     * Backwards compatibility, where wpdb::prepare() would not quote string placeholders with formatting.
     * They were used in the middle of longer strings, or as table name placeholders.
     * But they are risky, e.g. forgetting to add the quotes:
     *   $sql = $wpdb->prepare('WHERE (id = %s) OR (id = %1s) OR (id = %3$s)', ['id', 'id', 'id']);
     *
     * @since 6.0.0
     * @var bool
     */
    
public $allow_unsafe_unquoted_parameters true;

    public function 
__construct($dbuser$dbpassword$dbname$dbhost) {
        
parent::__construct($dbuser$dbpassword$dbname$dbhost);
    }

    
/**
     * Escapes an identifier for a MySQL database (e.g. table/field names).
     *
     * @since 6.0.0
     *
     * @param string $identifier Identifier to escape.
     */
    
public function escape_identifier$identifier ) {
        return 
'`' $this->_escape_identifier_value$identifier ) . '`';
    }

    
/**
     * Escapes an identifier value, but does not add the quote marks itself.
     * https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
     *   Permitted characters in quoted identifiers include the full Unicode Basic Multilingual Plane (BMP), except U+0000
     *   To quote the identifier itself, then you need to double the character, e.g. `a``b`
     *
     * @since 6.0.0
     *
     * @param string $identifier Identifier to escape.
     */
    
private function _escape_identifier_value$identifier ) {
        return 
str_replace'`''``'$identifier );
    }

    
/**
     * Prepares a SQL query for safe execution.
     *
     * Uses sprintf()-like syntax. The following placeholders can be used in the query string:
     *
     * - %d (integer)
     * - %f (float)
     * - %s (string)
     * - %i (identifier, e.g. table/field names)
     *
     * - %...d (an array of integers, e.g. 'WHERE id IN (%...d)')
     *
     * All placeholders MUST be left unquoted in the query string. A corresponding argument
     * MUST be passed for each placeholder.
     *
     * Note: There is one exception to the above: for compatibility with old behavior,
     * numbered or formatted string placeholders (eg, `%1$s`, `%5s`) will not have quotes
     * added by this function, so should be passed with appropriate quotes around them.
     *
     * Literal percentage signs (`%`) in the query string must be written as `%%`. Percentage wildcards
     * (for example, to use in LIKE syntax) must be passed via a substitution argument containing
     * the complete LIKE string, these cannot be inserted directly in the query string.
     * Also see wpdb::esc_like().
     *
     * Arguments may be passed as individual arguments to the method, or as a single array
     * containing all arguments. A combination of the two is not supported.
     *
     * Examples:
     *
     *     $wpdb->prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d OR `other_field` LIKE %s", array( 'foo', 1337, '%bar' ) );
     *     $wpdb->prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
     *
     * @since 2.3.0
     * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
     *              by updating the function signature. The second parameter was changed
     *              from `$args` to `...$args`.
     * @since 6.0.0 Added %i for Identifiers, e.g. table or field names.
     *              This preserves compatibility with sprinf, as the C version uses %d and $i
     *              as a signed integer, whereas PHP only supports %d.
     * @since 6.0.0 Added `%...d` and `%...s` to work with the `IN()` operator, e.g.
     *              'WHERE type = %s AND id IN (%...d)', ['post', [4, 29, 51]]
     *
     * @link https://www.php.net/sprintf Description of syntax.
     *
     * @param string      $query   Query statement with sprintf()-like placeholders.
     * @param array|mixed $args    The array of variables to substitute into the query's placeholders
     *                             if being called with an array of arguments, or the first variable
     *                             to substitute into the query's placeholders if being called with
     *                             individual arguments.
     * @param mixed       ...$args Further variables to substitute into the query's placeholders
     *                             if being called with individual arguments.
     * @return string|void Sanitized query string, if there is a query to prepare.
     */
    
public function prepare$query, ...$args ) {
        if ( 
is_null$query ) ) {
            return;
        }

        
// This is not meant to be foolproof -- but it will catch obviously incorrect usage.
        
if ( strpos$query'%' ) === false ) {
            
wp_load_translations_early();
            
_doing_it_wrong(
                
'wpdb::prepare',
                
sprintf(
                    
/* translators: %s: wpdb::prepare() */
                    
__'The query argument of %s must have a placeholder.' ),
                    
'wpdb::prepare()'
                
),
                
'3.9.0'
            
);
        }

        
/*
         * Specify the formatting allowed in a placeholder. The following are allowed:
         *
         * - Sign specifier. eg, $+d
         * - Numbered placeholders. eg, %1$s
         * - Padding specifier, including custom padding characters. eg, %05s, %'#5s
         * - Alignment specifier. eg, %05-s
         * - Precision specifier. eg, %.2f
         */
        
$allowed_format '(?:[1-9][0-9]*[$])?[-+0-9]*(?: |0|\'.)?[-+0-9]*(?:\.[0-9]+)?';

        
/*
         * If a %s placeholder already has quotes around it, removing the existing quotes and re-inserting them
         * ensures the quotes are consistent.
         *
         * For backward compatibility, this is only applied to %s, and not to placeholders like %1$s, which are frequently
         * used in the middle of longer strings, or as table name placeholders.
         */
        
$query str_replace"'%s'"'%s'$query ); // Strip any existing single quotes.
        
$query str_replace'"%s"''%s'$query ); // Strip any existing double quotes.

        
$query preg_replace"/%(?:%|$|(?!($allowed_format|\.\.\.)?[sdfFi]))/"'%%\\1'$query ); // Escape any unescaped percents (i.e. anything unrecognised).

        // Extract placeholders from the query.
        
$split_query preg_split"/(^|[^%]|(?:%%)+)(%(?:$allowed_format|\.\.\.)?[sdfFi])/"$query, -1PREG_SPLIT_DELIM_CAPTURE );

        
$split_query_count count$split_query );
        
$placeholder_count = ( ( $split_query_count ) / ); // Split always returns with 1 value before the first placeholder (even with $query = "%s"), then 3 additional values per placeholder.

        // If args were passed as an array (as in vsprintf), move them up.
        
$passed_as_array = ( isset( $args[0] ) && is_array$args[0] ) && count$args ) === );
        if ( 
$passed_as_array && isset( $split_query[2] ) && substr$split_query[2], 1, -) === '...' ) { // If the single placeholder is using variadics (e.g. '%...d').
            
$passed_as_array = ( count$args[0] ) === && is_array$args[0][0] ) ); // Only move up if it's a double array, (e.g. `[ [ 1, 2, 3 ] ]`).
        
}
        if ( 
$passed_as_array ) {
            
$args $args[0];
        }

        
$new_query       '';
        
$key             2// keys 0 and 1 in $split_query contain values before the first placeholder.
        
$arg_id          0;
        
$arg_identifiers = array();
        
$arg_strings     = array();
        
$arg_variadics   = array();
        while ( 
$key $split_query_count ) {

            
$placeholder $split_query$key ];

            
$format substr$placeholder1, -);
            
$type   substr$placeholder, -);

            if ( 
'f' === $type ) { // Force floats to be locale-unaware.
                
$type        'F';
                
$placeholder '%' $format $type;
            }

            if ( 
'...' === $format ) {
                if ( 
'i' === $type ) {
                    
$new_placeholder   '`%s`';
                    
$arg_identifiers[] = $arg_id;
                } elseif ( 
'd' === $type || 'F' === $type ) {
                    
$new_placeholder '%' $type// No need to quote integers or floats.
                
} else {
                    
$new_placeholder "'%" $type "'";
                }
                
$placeholder     substrstr_repeat$new_placeholder ','count$args$arg_id ] ) ), 0, -);
                
$arg_variadics[] = $arg_id;
            } elseif ( 
'i' === $type ) {
                
$placeholder '`%' $format 's`';
                
$argnum_pos  strpos$format'$' ); // Using a simple strpos() due to previous checking (e.g. $allowed_format).
                
if ( false !== $argnum_pos ) {
                    
$arg_identifiers[] = ( intvalsubstr$format0$argnum_pos ) ) - ); // sprintf argnum starts at 1, $arg_id from 0.
                
} else {
                    
$arg_identifiers[] = $arg_id;
                }
            } elseif ( 
's' === $type ) {
                
$argnum_pos strpos$format'$' );
                if ( 
false !== $argnum_pos ) {
                    
$arg_strings[] = ( intvalsubstr$format0$argnum_pos ) ) - );
                }
                if ( 
true !== $this->allow_unsafe_unquoted_parameters || '' === $format ) { // Unquoted strings for backwards compatibility (dangerous).
                    
$placeholder "'%" $format "s'";
                }
            } 
// elseif ( 'd' === $type || 'F' === $type ), nothing needs to be done (keep $placeholder)

            
$new_query .= $split_query$key ] . $split_query$key ] . $placeholder;
                
// Glue (-2), any prefix characters (-1), then the new $placeholder.

            
$key += 3;
            
$arg_id++;

        }
        
$query $new_query $split_query$key ]; // Replace $query; and add remaining $query characters, or index 0 if there were no placeholders.

        
$dual_use array_intersect$arg_identifiers$arg_strings );
        if ( 
count$dual_use ) ) {

            
wp_load_translations_early();
            
_doing_it_wrong(
                
'wpdb::prepare',
                
sprintf(
                    
/* translators: %s: A comma separated list of arguments found to be a problem. */
                    
__'Arguments (%s) cannot be used for both String and Identifier escaping.' ),
                    
implode', '$dual_use )
                ),
                
'6.0.0'
            
);

            return;
        }

        
$args_count count$args );

        if ( 
$args_count !== $placeholder_count ) {
            if ( 
=== $placeholder_count && $passed_as_array ) {
                
// If the passed query only expected one argument, but the wrong number of arguments were sent as an array, bail.
                
wp_load_translations_early();
                
_doing_it_wrong(
                    
'wpdb::prepare',
                    
__'The query only expected one placeholder, but an array of multiple placeholders was sent.' ),
                    
'4.9.0'
                
);

                return;
            } else {
                
/*
                 * If we don't have the right number of placeholders, but they were passed as individual arguments,
                 * or we were expecting multiple arguments in an array, throw a warning.
                 */
                
wp_load_translations_early();
                
_doing_it_wrong(
                    
'wpdb::prepare',
                    
sprintf(
                        
/* translators: 1: Number of placeholders, 2: Number of arguments passed. */
                        
__'The query does not contain the correct number of placeholders (%1$d) for the number of arguments passed (%2$d).' ),
                        
$placeholder_count,
                        
$args_count
                    
),
                    
'4.8.3'
                
);

                
/*
                 * If we don't have enough arguments to match the placeholders,
                 * return an empty string to avoid a fatal error on PHP 8.
                 */
                
if ( $args_count $placeholder_count ) {
                    
$max_numbered_placeholder 0;
                    for ( 
$i 2$l $split_query_count$i $l$i += ) {
                        
$argnum intvalsubstr$split_query$i ], ) ); // Assume a leading number is for a numbered placeholder, e.g. '%3$s'.
                        
if ( $max_numbered_placeholder $argnum ) {
                            
$max_numbered_placeholder $argnum;
                        }
                    }
                    if ( ! 
$max_numbered_placeholder || $args_count $max_numbered_placeholder ) {
                        return 
'';
                    }
                }
            }
        }

        
$args_escaped = array();

        foreach ( 
$args as $i => $value ) {
            if ( 
in_array$i$arg_variadicstrue ) ) {
                if ( 
in_array$i$arg_identifierstrue ) ) {
                    
$args_escaped array_merge$args_escapedarray_map( array( $this'_escape_identifier_value' ), $value ) );
                } else {
                    
$args_escaped array_merge$args_escapedarray_map( array( $this'_real_escape' ), $value ) );
                }
            } elseif ( 
in_array$i$arg_identifierstrue ) ) {
                
$args_escaped[] = $this->_escape_identifier_value$value );
            } elseif ( 
is_int$value ) || is_float$value ) ) {
                
$args_escaped[] = $value;
            } else {
                if ( ! 
is_scalar$value ) && ! is_null$value ) ) {
                    
wp_load_translations_early();
                    
_doing_it_wrong(
                        
'wpdb::prepare',
                        
sprintf(
                            
/* translators: %s: Value type. */
                            
__'Unsupported value type (%s).' ),
                            
gettype$value )
                        ),
                        
'4.8.2'
                    
);
                    
$value ''// Preserving old behaviour, where values are escaped as strings.
                
}
                
$args_escaped[] = $this->_real_escape$value );
            }
        }

        
$query vsprintf$query$args_escaped );

        return 
$this->add_placeholder_escape$query );
    }

    public function 
prepare_current$query, ...$args ) {
        return 
parent::prepare$query, ...$args );
    }

}

global 
$wpdb;
$wpdb = new wpdb2(DB_USERDB_PASSWORDDB_NAMEDB_HOST);

?>