Parsed: 127322

  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'
      );
    }

    // If args were passed as an array (as in vsprintf), move them up.
    $passed_as_array = false;
    if ( isset( $args[0] ) && is_array( $args[0] ) && 1 === count( $args ) ) {
      $passed_as_array = true;
      $args            = $args[0];
    }

    foreach ( $args as $arg ) {
      if ( ! is_scalar( $arg ) && ! is_null( $arg ) ) {
        wp_load_translations_early();
        _doing_it_wrong(
          'wpdb::prepare',
          sprintf(
            /* translators: %s: Value type. */
            __( 'Unsupported value type (%s).' ),
            gettype( $arg )
          ),
          '4.8.2'
        );
      }
    }

    /*
		 * Specify the formatting allowed in a placeholder. The following are allowed:
		 *
		 * - Sign specifier, e.g. $+d
		 * - Numbered placeholders, e.g. %1$s
		 * - Padding specifier, including custom padding characters, e.g. %05s, %'#5s
		 * - Alignment specifier, e.g. %05-s
		 * - Precision specifier, e.g. %.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( '/(?<!%)%s/', "'%s'", $query ); // Quote the strings, avoiding escaped strings like %%s.

    $query = preg_replace( "/(?<!%)(%($allowed_format)?f)/", '%\\2F', $query ); // Force floats to be locale-unaware.

    $query = preg_replace( "/%(?:%|$|(?!($allowed_format)?[sdF]))/", '%%\\1', $query ); // Escape any unescaped percents.

    // Count the number of valid placeholders in the query.
    $placeholders = preg_match_all( "/(^|[^%]|(%%)+)%($allowed_format)?[sdF]/", $query, $matches );

    $args_count = count( $args );

    if ( $args_count !== $placeholders ) {
      if ( 1 === $placeholders && $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).' ),
            $placeholders,
            $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 < $placeholders ) {
          $max_numbered_placeholder = ! empty( $matches[3] ) ? max( array_map( 'intval', $matches[3] ) ) : 0;

          if ( ! $max_numbered_placeholder || $args_count < $max_numbered_placeholder ) {
            return '';
          }
        }
      }
    }

    array_walk( $args, array( $this, 'escape_by_ref' ) );
    $query = vsprintf( $query, $args );

    return $this->wpdb::add_placeholder_escape( $query );
  }