Sql syntax error

Sometimes in my error log i have this error:

You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version for the right syntax to 
use near '' at line 1    
    SELECT * 
    FROM c_posts 
    WHERE id = , 
    do_action('wp_ajax_inline-save'), 
    call_user_func_array, 
    wp_ajax_inline_save, 
    edit_post, 
    wp_update_post, 
    wp_insert_post, 
    wp_transition_post_status, 
    do_action('transition_post_status'), 
    call_user_func_array, 
    apt_check_required_transition, 
    apt_publish_post, 
    W3_Db->query

How to fix this ?

I think error in this plugin. It is piece of code :

/**
  * Function to check whether scheduled post is being published. If so, apt_publish_post should be called.
  *
  * @param $new_status
  * @param $old_status
  * @param $post
  * @return void
  */
 function apt_check_required_transition($new_status="", $old_status="", $post="") {
global $post_ID; // Using the post id from global reference since it is not available       in $post object. Strange!

if ('publish' == $new_status) {
    apt_publish_post($post_ID);
}
 }

 /**
 * Function to save first image in post as post thumbmail.
 */
 function apt_publish_post($post_id)
  {
global $wpdb;

// First check whether Post Thumbnail is already set for this post.
if (get_post_meta($post_id, '_thumbnail_id', true) || get_post_meta($post_id, 'skip_post_thumb', true)) {
    return;
}

$post = $wpdb->get_results("SELECT * FROM {$wpdb->posts} WHERE id = $post_id");

// Initialize variable used to store list of matched images as per provided regular expression
$matches = array();

// Get all images from post's body
preg_match_all('/<\s*img [^\>]*src\s*=\s*[\""\']?([^\""\'>]*)/i', $post[0]->post_content, $matches);

if (count($matches)) {
    foreach ($matches[0] as $key => $image) {
        /**
         * If the image is from wordpress's own media gallery, then it appends the thumbmail id to a css class.
         * Look for this id in the IMG tag.
         */
        preg_match('/wp-image-([\d]*)/i', $image, $thumb_id);
        $thumb_id = $thumb_id[1];

        // If thumb id is not found, try to look for the image in DB. Thanks to "Erwin Vrolijk" for providing this code.
        if (!$thumb_id) {
            $image = substr($image, strpos($image, '"')+1);
            $result = $wpdb->get_results("SELECT ID FROM {$wpdb->posts} WHERE guid = '".$image."'");
            $thumb_id = $result[0]->ID;
        }

        // Ok. Still no id found. Some other way used to insert the image in post. Now we must fetch the image from URL and do the needful.
        if (!$thumb_id) {
            $thumb_id = apt_generate_post_thumb($matches, $key, $post[0]->post_content, $post_id);
        }

        // If we succeed in generating thumg, let's update post meta
        if ($thumb_id) {
            update_post_meta( $post_id, '_thumbnail_id', $thumb_id );
            break;
        }
    }
}
 }// end apt_publish_post()

1 Answer
1

The error in the SQL statement is at the very end,

SELECT * 
FROM c_posts 
WHERE id = , 

There is no value being supplied to check against the id column. This is most likely because you didn’t check for a blank value in the ID field before forming and executing the query. Check the code in the function apt_publish_post to ensure that the value being inserted into the query for id is non-empty and a positive integer.

Update

Now that you’ve provided the code for apt_publish_post, it is clear why this could be happening.

  • apt_check_required_transition is hooked on the transition_post_status action, which accepts three arguments, $old_status, $new_status, and $post. If registered correctly with add_action, all three variables are guaranteed to be defined.

    add_action( 'transition_post_status', 'apt_check_required_transition', 10, 3);

    • It’s important that the last two arguments to add_action are provided: $priority and $num_arguments; here I have $priority = 10 and $num_arguments = 3, to correspond to the number of arguments the transition_post_status action supplies.
  • apt_check_required_transition thus will accept a $post object as the third argument, whose ID $post->ID should be passed to apt_publish_post

  • apt_publish_post should do some basic sanity checks on its argument, $post_id:

    if( ( $post_id = (int) $post_id ) < 1 )
    return;

    • This is just one of a whole variety of ways in PHP to check for type and domain validity.
  • Always use $wpdb->prepare() when creating SQL statements. This adds another layer of protection against injection attacks.

    $post = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->posts} WHERE id = %d", $post_id ) );

    • Despite this, the get_post() WordPress API function is a much better way to obtain a post object given a post ID:

    $post = get_post( $post_id );

    • This differs from your current method in that you get a single post, rather than an array of posts as you do using $wpdb->get_results()
  • You could also just pass the $post object provided to apt_check_required_transition directly to apt_publish_post rather than getting its ID and then looking it up again. This would eliminate the need for sanity checks, as $post would always be defined in this situation.

Leave a Comment