• Hello Members

    I am developing a plugin and before submitting to the repository, I am testing it with “plugin checker”. I am using wordpress version 6.7.2. Still it shows error like below.

    WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder
    The %i modifier is only supported in WP 6.2 or higher. Found: “%i”.

    My query is like this :

    $table_name = $this->table_prefix . LSFW_TABLE_APPLICATIONS;
    $query = $wpdb->prepare("SELECT * FROM %i ORDER BY id DESC LIMIT 1", $table_name);
    $row = $wpdb->get_row($query);

    I am really frustrated with this plugin, because of so many false positive. Suggest me how to proceed. Since i have to wait longer after the plugin submission to get the feedback from plugin reviewer.

Viewing 7 replies - 1 through 7 (of 7 total)
  • Hi @rahul78275,

    Based on your code, I believe there’s no real need to sanitize $table_name using prepare statement since the value is static and not based on user input. I think you can simply add “ignore” line for CodeSniffer.

    Cheers!

    • This reply was modified 1 month, 1 week ago by rollybueno.
    Thread Starter rahul78275

    (@rahul78275)

    Thank you for the reply @rollybueno

    There are some other queries where I need to sanitize input like below

    $wpdb->prepare(
    "SELECT t1.id, t1.product_id, t1.scheduled_at, t1.timezone, t1.thumb, t1.created_at, t2.streamid, t2.overlay
    FROM %i t1
    LEFT JOIN %i t2 ON t1.id = t2.streamid
    WHERE t1.status = %d
    ORDER BY t1.id DESC",
    $table_1,
    $table_2,
    $status_value
    )

    Table name i am always using from constant file.
    If i use query like this

    $wpdb->prepare("SELECT * FROM {$table_name} ORDER BY id DESC LIMIT 1");

    It always throw error in “plugin checker”.

    So you mean, I can safely ignore this right @rollybueno ?

    Moderator bcworkz

    (@bcworkz)

    "SELECT * FROM {$table_name} ORDER BY id DESC LIMIT 1"

    Will it work? Yes. Is it correct? No. We should always use sprintf() type syntax with prepare(), i.e. a string with placeholders followed by variable data. The entire purpose of prepare assumes the use of placeholders and your data will not be properly sanitized if you instead use double quoted string syntax.

    The warning about using %i is what can be ignored. The purpose of the warning is for those concerned with reverse compatibility. Mainly a concern for those wanting to distribute their plugin to others. If your code is for your own use, do as you wish ?? For better reverse compatibility, use %s instead.

    Do you need to sanitize a query which only uses constant values? No, but it makes the plugin checker happy ?? For the sake of maintainability it might be a good idea to sanitize anyway. Someone could come along in the future and alter the query to use a risky value without realizing the query is not sanitized.

    Thread Starter rahul78275

    (@rahul78275)

    Thank you @bcworkz for the detailed explanation. I want my plugin to work with reverse compatibility

    $wpdb->prepare(
    "SELECT t1.id, t1.product_id, t1.scheduled_at, t1.timezone, t1.thumb, t1.created_at, t2.streamid, t2.overlay
    FROM %i t1
    LEFT JOIN %i t2 ON t1.id = t2.streamid
    WHERE t1.status = %d
    ORDER BY t1.id DESC",
    $table_1,
    $table_2,
    $status_value
    )

    $wpdb->prepare("SELECT * FROM {$table_name} ORDER BY id DESC LIMIT 1");

    Can you please help me to fix this query such that it is widely supported across different versions.

    I tried to create two files one for legacy and other for the latest version like this

    private function load_helper() {

    // Load helper class
    global $wp_version;

    if (version_compare($wp_version, '6.2', '>=')) {
    require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-lsfw-helper.php';

    } else {

    // Legacy support
    require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/legacy/class-lsfw-helper.php';
    }

    $this->helper = new LSFW_Helper();
    }

    Plugin checker warnings are bothering me. It takes long time to review the plugin so i want to make it error free so that reviewer pass it soon.

    Thank you one again.

    Moderator bcworkz

    (@bcworkz)

    Simply replace any instances of %i with %s.

    Regarding $wpdb->prepare("SELECT * FROM {$table_name} ORDER BY id DESC LIMIT 1");,
    do it like this:
    $wpdb->prepare('SELECT * FROM %s ORDER BY ID DESC LIMIT 1;', $table_name );

    Note that I also made the ID column name upper case, assuming this is for a posts table. The posts column name is upper case. The distinction between upper and lower case may not matter on your system, but it does matter on some.

    You wouldn’t be the only dev doing something that’s not strictly necessary only to make the plugin checker happy ??

    Thread Starter rahul78275

    (@rahul78275)

    Hi @bcworkz , Sorry to bother you again. This is my first plugin and i am losing my interest only due to this plugin checker. It took a lot time in the development and finally everything working expected in the plugin but following standard is an obstacle.

    I tried your solution unfortunately, it didn’t worked as expected. It added single quote around the table name, Cause SQL error

    WordPress database error: [You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ”wp_lsfw_applications’ ORDER BY ID DESC LIMIT 1′ at line 1]

    SELECT * FROM 'wp_lsfw_tablename' ORDER BY ID DESC LIMIT 1

    Please suggest me a solution so that atleast i am able to submit the initial version of my plugin and keep the motivation up.

    Thank you

    • This reply was modified 1 month ago by rahul78275.
    Moderator bcworkz

    (@bcworkz)

    In MySQL, table and column names are normally demarcated with backticks. It’s difficult to use them in forum post content because they demarcate code blocks. If you’re not going to use sprintf() style syntax, replace the single quotes with backticks.

    The problem is thornier in prepare() when we replace %i with %s. The prepare() method applies backticks with %i, but single quotes with %s. In order to use the proper backtick syntax with %s, use %1s instead, which suppresses any sort of quoting. Then include the backticks yourself in your SQL string.

    Similar to this:
    $wpdb->prepare('SELECT * FROM "%1s" ORDER BY ID DESC LIMIT 1;', $table_name );
    except replace the double quotes with backticks

Viewing 7 replies - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.