get_posts_by_author_sql

The timeline below displays how wordpress function get_posts_by_author_sql has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.1

/**
 * Retrieves the post SQL based on capability, author, and type.
 *
 * @since 3.0.0
 * @since 4.3.0 Introduced the ability to pass an array of post types to `$post_type`.
 *
 * @see get_private_posts_cap_sql()
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string|string[] $post_type   Single post type or an array of post types.
 * @param bool            $full        Optional. Returns a full WHERE statement instead of just
 *                                     an 'andalso' term. Default true.
 * @param int             $post_author Optional. Query posts having a single author ID. Default null.
 * @param bool            $public_only Optional. Only return public posts. Skips cap checks for
 *                                     $current_user.  Default false.
 * @return string SQL WHERE code that can be added to a query.
 */
function get_posts_by_author_sql($post_type, $full = true, $post_author = null, $public_only = false)
{
    global $wpdb;
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type);
    }
    $post_type_clauses = array();
    foreach ($post_types as $post_type) {
        $post_type_obj = get_post_type_object($post_type);
        if (!$post_type_obj) {
            continue;
        }
        /**
         * Filters the capability to read private posts for a custom post type
         * when generating SQL for getting posts by author.
         *
         * @since 2.2.0
         * @deprecated 3.2.0 The hook transitioned from "somewhat useless" to "totally useless".
         *
         * @param string $cap Capability.
         */
        $cap = apply_filters_deprecated('pub_priv_sql_capability', array(''), '3.2.0');
        if (!$cap) {
            $cap = current_user_can($post_type_obj->cap->read_private_posts);
        }
        // Only need to check the cap if $public_only is false.
        $post_status_sql = "post_status = 'publish'";
        if (false === $public_only) {
            if ($cap) {
                // Does the user have the capability to view private posts? Guess so.
                $post_status_sql .= " OR post_status = 'private'";
            } elseif (is_user_logged_in()) {
                // Users can view their own private posts.
                $id = get_current_user_id();
                if (null === $post_author || !$full) {
                    $post_status_sql .= " OR post_status = 'private' AND post_author = {$id}";
                } elseif ($id == (int) $post_author) {
                    $post_status_sql .= " OR post_status = 'private'";
                }
                // Else none.
            }
            // Else none.
        }
        $post_type_clauses[] = "( post_type = '" . $post_type . "' AND ( {$post_status_sql} ) )";
    }
    if (empty($post_type_clauses)) {
        return $full ? 'WHERE 1 = 0' : '1 = 0';
    }
    $sql = '( ' . implode(' OR ', $post_type_clauses) . ' )';
    if (null !== $post_author) {
        $sql .= $wpdb->prepare(' AND post_author = %d', $post_author);
    }
    if ($full) {
        $sql = 'WHERE ' . $sql;
    }
    return $sql;
}

WordPress Version: 5.4

/**
 * Retrieve the post SQL based on capability, author, and type.
 *
 * @since 3.0.0
 * @since 4.3.0 Introduced the ability to pass an array of post types to `$post_type`.
 *
 * @see get_private_posts_cap_sql()
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string|string[] $post_type   Single post type or an array of post types.
 * @param bool            $full        Optional. Returns a full WHERE statement instead of just
 *                                     an 'andalso' term. Default true.
 * @param int             $post_author Optional. Query posts having a single author ID. Default null.
 * @param bool            $public_only Optional. Only return public posts. Skips cap checks for
 *                                     $current_user.  Default false.
 * @return string SQL WHERE code that can be added to a query.
 */
function get_posts_by_author_sql($post_type, $full = true, $post_author = null, $public_only = false)
{
    global $wpdb;
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type);
    }
    $post_type_clauses = array();
    foreach ($post_types as $post_type) {
        $post_type_obj = get_post_type_object($post_type);
        if (!$post_type_obj) {
            continue;
        }
        /**
         * Filters the capability to read private posts for a custom post type
         * when generating SQL for getting posts by author.
         *
         * @since 2.2.0
         * @deprecated 3.2.0 The hook transitioned from "somewhat useless" to "totally useless".
         *
         * @param string $cap Capability.
         */
        $cap = apply_filters_deprecated('pub_priv_sql_capability', array(''), '3.2.0');
        if (!$cap) {
            $cap = current_user_can($post_type_obj->cap->read_private_posts);
        }
        // Only need to check the cap if $public_only is false.
        $post_status_sql = "post_status = 'publish'";
        if (false === $public_only) {
            if ($cap) {
                // Does the user have the capability to view private posts? Guess so.
                $post_status_sql .= " OR post_status = 'private'";
            } elseif (is_user_logged_in()) {
                // Users can view their own private posts.
                $id = get_current_user_id();
                if (null === $post_author || !$full) {
                    $post_status_sql .= " OR post_status = 'private' AND post_author = {$id}";
                } elseif ($id == (int) $post_author) {
                    $post_status_sql .= " OR post_status = 'private'";
                }
                // Else none.
            }
            // Else none.
        }
        $post_type_clauses[] = "( post_type = '" . $post_type . "' AND ( {$post_status_sql} ) )";
    }
    if (empty($post_type_clauses)) {
        return $full ? 'WHERE 1 = 0' : '1 = 0';
    }
    $sql = '( ' . implode(' OR ', $post_type_clauses) . ' )';
    if (null !== $post_author) {
        $sql .= $wpdb->prepare(' AND post_author = %d', $post_author);
    }
    if ($full) {
        $sql = 'WHERE ' . $sql;
    }
    return $sql;
}

WordPress Version: 5.3

/**
 * Retrieve the post SQL based on capability, author, and type.
 *
 * @since 3.0.0
 * @since 4.3.0 Introduced the ability to pass an array of post types to `$post_type`.
 *
 * @see get_private_posts_cap_sql()
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array|string   $post_type   Single post type or an array of post types.
 * @param bool           $full        Optional. Returns a full WHERE statement instead of just
 *                                    an 'andalso' term. Default true.
 * @param int            $post_author Optional. Query posts having a single author ID. Default null.
 * @param bool           $public_only Optional. Only return public posts. Skips cap checks for
 *                                    $current_user.  Default false.
 * @return string SQL WHERE code that can be added to a query.
 */
function get_posts_by_author_sql($post_type, $full = true, $post_author = null, $public_only = false)
{
    global $wpdb;
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type);
    }
    $post_type_clauses = array();
    foreach ($post_types as $post_type) {
        $post_type_obj = get_post_type_object($post_type);
        if (!$post_type_obj) {
            continue;
        }
        /**
         * Filters the capability to read private posts for a custom post type
         * when generating SQL for getting posts by author.
         *
         * @since 2.2.0
         * @deprecated 3.2.0 The hook transitioned from "somewhat useless" to "totally useless".
         *
         * @param string $cap Capability.
         */
        $cap = apply_filters('pub_priv_sql_capability', '');
        if (!$cap) {
            $cap = current_user_can($post_type_obj->cap->read_private_posts);
        }
        // Only need to check the cap if $public_only is false.
        $post_status_sql = "post_status = 'publish'";
        if (false === $public_only) {
            if ($cap) {
                // Does the user have the capability to view private posts? Guess so.
                $post_status_sql .= " OR post_status = 'private'";
            } elseif (is_user_logged_in()) {
                // Users can view their own private posts.
                $id = get_current_user_id();
                if (null === $post_author || !$full) {
                    $post_status_sql .= " OR post_status = 'private' AND post_author = {$id}";
                } elseif ($id == (int) $post_author) {
                    $post_status_sql .= " OR post_status = 'private'";
                }
                // else none
            }
            // else none
        }
        $post_type_clauses[] = "( post_type = '" . $post_type . "' AND ( {$post_status_sql} ) )";
    }
    if (empty($post_type_clauses)) {
        return $full ? 'WHERE 1 = 0' : '1 = 0';
    }
    $sql = '( ' . implode(' OR ', $post_type_clauses) . ' )';
    if (null !== $post_author) {
        $sql .= $wpdb->prepare(' AND post_author = %d', $post_author);
    }
    if ($full) {
        $sql = 'WHERE ' . $sql;
    }
    return $sql;
}

WordPress Version: 4.6

/**
 * Retrieve the post SQL based on capability, author, and type.
 *
 * @since 3.0.0
 * @since 4.3.0 Introduced the ability to pass an array of post types to `$post_type`.
 *
 * @see get_private_posts_cap_sql()
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array|string   $post_type   Single post type or an array of post types.
 * @param bool           $full        Optional. Returns a full WHERE statement instead of just
 *                                    an 'andalso' term. Default true.
 * @param int            $post_author Optional. Query posts having a single author ID. Default null.
 * @param bool           $public_only Optional. Only return public posts. Skips cap checks for
 *                                    $current_user.  Default false.
 * @return string SQL WHERE code that can be added to a query.
 */
function get_posts_by_author_sql($post_type, $full = true, $post_author = null, $public_only = false)
{
    global $wpdb;
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type);
    }
    $post_type_clauses = array();
    foreach ($post_types as $post_type) {
        $post_type_obj = get_post_type_object($post_type);
        if (!$post_type_obj) {
            continue;
        }
        /**
         * Filters the capability to read private posts for a custom post type
         * when generating SQL for getting posts by author.
         *
         * @since 2.2.0
         * @deprecated 3.2.0 The hook transitioned from "somewhat useless" to "totally useless".
         *
         * @param string $cap Capability.
         */
        if (!$cap = apply_filters('pub_priv_sql_capability', '')) {
            $cap = current_user_can($post_type_obj->cap->read_private_posts);
        }
        // Only need to check the cap if $public_only is false.
        $post_status_sql = "post_status = 'publish'";
        if (false === $public_only) {
            if ($cap) {
                // Does the user have the capability to view private posts? Guess so.
                $post_status_sql .= " OR post_status = 'private'";
            } elseif (is_user_logged_in()) {
                // Users can view their own private posts.
                $id = get_current_user_id();
                if (null === $post_author || !$full) {
                    $post_status_sql .= " OR post_status = 'private' AND post_author = {$id}";
                } elseif ($id == (int) $post_author) {
                    $post_status_sql .= " OR post_status = 'private'";
                }
                // else none
            }
            // else none
        }
        $post_type_clauses[] = "( post_type = '" . $post_type . "' AND ( {$post_status_sql} ) )";
    }
    if (empty($post_type_clauses)) {
        return $full ? 'WHERE 1 = 0' : '1 = 0';
    }
    $sql = '( ' . implode(' OR ', $post_type_clauses) . ' )';
    if (null !== $post_author) {
        $sql .= $wpdb->prepare(' AND post_author = %d', $post_author);
    }
    if ($full) {
        $sql = 'WHERE ' . $sql;
    }
    return $sql;
}

WordPress Version: 4.4

/**
 * Retrieve the post SQL based on capability, author, and type.
 *
 * @since 3.0.0
 * @since 4.3.0 Introduced the ability to pass an array of post types to `$post_type`.
 *
 * @see get_private_posts_cap_sql()
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array|string   $post_type   Single post type or an array of post types.
 * @param bool           $full        Optional. Returns a full WHERE statement instead of just
 *                                    an 'andalso' term. Default true.
 * @param int            $post_author Optional. Query posts having a single author ID. Default null.
 * @param bool           $public_only Optional. Only return public posts. Skips cap checks for
 *                                    $current_user.  Default false.
 * @return string SQL WHERE code that can be added to a query.
 */
function get_posts_by_author_sql($post_type, $full = true, $post_author = null, $public_only = false)
{
    global $wpdb;
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type);
    }
    $post_type_clauses = array();
    foreach ($post_types as $post_type) {
        $post_type_obj = get_post_type_object($post_type);
        if (!$post_type_obj) {
            continue;
        }
        /**
         * Filter the capability to read private posts for a custom post type
         * when generating SQL for getting posts by author.
         *
         * @since 2.2.0
         * @deprecated 3.2.0 The hook transitioned from "somewhat useless" to "totally useless".
         *
         * @param string $cap Capability.
         */
        if (!$cap = apply_filters('pub_priv_sql_capability', '')) {
            $cap = current_user_can($post_type_obj->cap->read_private_posts);
        }
        // Only need to check the cap if $public_only is false.
        $post_status_sql = "post_status = 'publish'";
        if (false === $public_only) {
            if ($cap) {
                // Does the user have the capability to view private posts? Guess so.
                $post_status_sql .= " OR post_status = 'private'";
            } elseif (is_user_logged_in()) {
                // Users can view their own private posts.
                $id = get_current_user_id();
                if (null === $post_author || !$full) {
                    $post_status_sql .= " OR post_status = 'private' AND post_author = {$id}";
                } elseif ($id == (int) $post_author) {
                    $post_status_sql .= " OR post_status = 'private'";
                }
                // else none
            }
            // else none
        }
        $post_type_clauses[] = "( post_type = '" . $post_type . "' AND ( {$post_status_sql} ) )";
    }
    if (empty($post_type_clauses)) {
        return $full ? 'WHERE 1 = 0' : '1 = 0';
    }
    $sql = '( ' . implode(' OR ', $post_type_clauses) . ' )';
    if (null !== $post_author) {
        $sql .= $wpdb->prepare(' AND post_author = %d', $post_author);
    }
    if ($full) {
        $sql = 'WHERE ' . $sql;
    }
    return $sql;
}

WordPress Version: 4.3

/**
 * Retrieve the post SQL based on capability, author, and type.
 *
 * @since 3.0.0
 * @since 4.3.0 Introduced the ability to pass an array of post types to `$post_type`.
 *
 * @see get_private_posts_cap_sql()
 *
 * @global wpdb $wpdb
 *
 * @param array|string   $post_type   Single post type or an array of post types.
 * @param bool           $full        Optional. Returns a full WHERE statement instead of just
 *                                    an 'andalso' term. Default true.
 * @param int            $post_author Optional. Query posts having a single author ID. Default null.
 * @param bool           $public_only Optional. Only return public posts. Skips cap checks for
 *                                    $current_user.  Default false.
 * @return string SQL WHERE code that can be added to a query.
 */
function get_posts_by_author_sql($post_type, $full = true, $post_author = null, $public_only = false)
{
    global $wpdb;
    if (is_array($post_type)) {
        $post_types = $post_type;
    } else {
        $post_types = array($post_type);
    }
    $post_type_clauses = array();
    foreach ($post_types as $post_type) {
        $post_type_obj = get_post_type_object($post_type);
        if (!$post_type_obj) {
            continue;
        }
        /**
         * Filter the capability to read private posts for a custom post type
         * when generating SQL for getting posts by author.
         *
         * @since 2.2.0
         * @deprecated 3.2.0 The hook transitioned from "somewhat useless" to "totally useless".
         *
         * @param string $cap Capability.
         */
        if (!$cap = apply_filters('pub_priv_sql_capability', '')) {
            $cap = current_user_can($post_type_obj->cap->read_private_posts);
        }
        // Only need to check the cap if $public_only is false.
        $post_status_sql = "post_status = 'publish'";
        if (false === $public_only) {
            if ($cap) {
                // Does the user have the capability to view private posts? Guess so.
                $post_status_sql .= " OR post_status = 'private'";
            } elseif (is_user_logged_in()) {
                // Users can view their own private posts.
                $id = get_current_user_id();
                if (null === $post_author || !$full) {
                    $post_status_sql .= " OR post_status = 'private' AND post_author = {$id}";
                } elseif ($id == (int) $post_author) {
                    $post_status_sql .= " OR post_status = 'private'";
                }
                // else none
            }
            // else none
        }
        $post_type_clauses[] = "( post_type = '" . $post_type . "' AND ( {$post_status_sql} ) )";
    }
    if (empty($post_type_clauses)) {
        return $full ? 'WHERE 1 = 0' : '1 = 0';
    }
    $sql = '( ' . implode(' OR ', $post_type_clauses) . ' )';
    if (null !== $post_author) {
        $sql .= $wpdb->prepare(' AND post_author = %d', $post_author);
    }
    if ($full) {
        $sql = 'WHERE ' . $sql;
    }
    return $sql;
}

WordPress Version: 4.2

/**
 * Retrieve the post SQL based on capability, author, and type.
 *
 * @since 3.0.0
 *
 * @see get_private_posts_cap_sql()
 *
 * @param string $post_type   Post type.
 * @param bool   $full        Optional. Returns a full WHERE statement instead of just
 *                            an 'andalso' term. Default true.
 * @param int    $post_author Optional. Query posts having a single author ID. Default null.
 * @param bool   $public_only Optional. Only return public posts. Skips cap checks for
 *                            $current_user.  Default false.
 * @return string SQL WHERE code that can be added to a query.
 */
function get_posts_by_author_sql($post_type, $full = true, $post_author = null, $public_only = false)
{
    global $wpdb;
    // Private posts.
    $post_type_obj = get_post_type_object($post_type);
    if (!$post_type_obj) {
        return $full ? 'WHERE 1 = 0' : ' 1 = 0 ';
    }
    /**
     * Filter the capability to read private posts for a custom post type
     * when generating SQL for getting posts by author.
     *
     * @since 2.2.0
     * @deprecated 3.2.0 The hook transitioned from "somewhat useless" to "totally useless".
     *
     * @param string $cap Capability.
     */
    if (!$cap = apply_filters('pub_priv_sql_capability', '')) {
        $cap = $post_type_obj->cap->read_private_posts;
    }
    $sql = $wpdb->prepare('post_type = %s', $post_type);
    if (null !== $post_author) {
        $sql .= $wpdb->prepare(' AND post_author = %d', $post_author);
    }
    // Only need to check the cap if $public_only is false.
    $post_status_sql = "post_status = 'publish'";
    if (false === $public_only) {
        if (current_user_can($cap)) {
            // Does the user have the capability to view private posts? Guess so.
            $post_status_sql .= " OR post_status = 'private'";
        } elseif (is_user_logged_in()) {
            // Users can view their own private posts.
            $id = get_current_user_id();
            if (null === $post_author || !$full) {
                $post_status_sql .= " OR post_status = 'private' AND post_author = {$id}";
            } elseif ($id == (int) $post_author) {
                $post_status_sql .= " OR post_status = 'private'";
            }
            // else none
        }
        // else none
    }
    $sql .= " AND ({$post_status_sql})";
    if ($full) {
        $sql = 'WHERE ' . $sql;
    }
    return $sql;
}

WordPress Version: 4.0

/**
 * Retrieve the post SQL based on capability, author, and type.
 *
 * @since 3.0.0
 *
 * @see get_private_posts_cap_sql()
 *
 * @param string $post_type   Post type.
 * @param bool   $full        Optional. Returns a full WHERE statement instead of just
 *                            an 'andalso' term. Default true.
 * @param int    $post_author Optional. Query posts having a single author ID. Default null.
 * @param bool   $public_only Optional. Only return public posts. Skips cap checks for
 *                            $current_user.  Default false.
 * @return string SQL WHERE code that can be added to a query.
 */
function get_posts_by_author_sql($post_type, $full = true, $post_author = null, $public_only = false)
{
    global $wpdb;
    // Private posts.
    $post_type_obj = get_post_type_object($post_type);
    if (!$post_type_obj) {
        return $full ? 'WHERE 1 = 0' : ' 1 = 0 ';
    }
    /**
     * Filter the capability to read private posts for a custom post type
     * when generating SQL for getting posts by author.
     *
     * @since 2.2.0
     * @deprecated 3.2.0 The hook transitioned from "somewhat useless" to "totally useless".
     *
     * @param string $cap Capability.
     */
    if (!$cap = apply_filters('pub_priv_sql_capability', '')) {
        $cap = $post_type_obj->cap->read_private_posts;
    }
    if ($full) {
        if (null === $post_author) {
            $sql = $wpdb->prepare('WHERE post_type = %s AND ', $post_type);
        } else {
            $sql = $wpdb->prepare('WHERE post_author = %d AND post_type = %s AND ', $post_author, $post_type);
        }
    } else {
        $sql = '';
    }
    $sql .= "(post_status = 'publish'";
    // Only need to check the cap if $public_only is false.
    if (false === $public_only) {
        if (current_user_can($cap)) {
            // Does the user have the capability to view private posts? Guess so.
            $sql .= " OR post_status = 'private'";
        } elseif (is_user_logged_in()) {
            // Users can view their own private posts.
            $id = get_current_user_id();
            if (null === $post_author || !$full) {
                $sql .= " OR post_status = 'private' AND post_author = {$id}";
            } elseif ($id == (int) $post_author) {
                $sql .= " OR post_status = 'private'";
            }
            // else none
        }
        // else none
    }
    $sql .= ')';
    return $sql;
}

WordPress Version: 3.9

/**
 * Retrieve the post SQL based on capability, author, and type.
 *
 * @see get_private_posts_cap_sql() for full description.
 *
 * @since 3.0.0
 * @param string $post_type Post type.
 * @param bool $full Optional. Returns a full WHERE statement instead of just an 'andalso' term.
 * @param int $post_author Optional. Query posts having a single author ID.
 * @param bool $public_only Optional. Only return public posts. Skips cap checks for $current_user.  Default is false.
 * @return string SQL WHERE code that can be added to a query.
 */
function get_posts_by_author_sql($post_type, $full = true, $post_author = null, $public_only = false)
{
    global $wpdb;
    // Private posts
    $post_type_obj = get_post_type_object($post_type);
    if (!$post_type_obj) {
        return $full ? 'WHERE 1 = 0' : ' 1 = 0 ';
    }
    /**
     * Filter the capability to read private posts for a custom post type
     * when generating SQL for getting posts by author.
     *
     * @since 2.2.0
     * @deprecated 3.2.0 The hook transitioned from "somewhat useless" to "totally useless".
     *
     * @param string $cap Capability.
     */
    if (!$cap = apply_filters('pub_priv_sql_capability', '')) {
        $cap = $post_type_obj->cap->read_private_posts;
    }
    if ($full) {
        if (null === $post_author) {
            $sql = $wpdb->prepare('WHERE post_type = %s AND ', $post_type);
        } else {
            $sql = $wpdb->prepare('WHERE post_author = %d AND post_type = %s AND ', $post_author, $post_type);
        }
    } else {
        $sql = '';
    }
    $sql .= "(post_status = 'publish'";
    // Only need to check the cap if $public_only is false
    if (false === $public_only) {
        if (current_user_can($cap)) {
            // Does the user have the capability to view private posts? Guess so.
            $sql .= " OR post_status = 'private'";
        } elseif (is_user_logged_in()) {
            // Users can view their own private posts.
            $id = get_current_user_id();
            if (null === $post_author || !$full) {
                $sql .= " OR post_status = 'private' AND post_author = {$id}";
            } elseif ($id == (int) $post_author) {
                $sql .= " OR post_status = 'private'";
            }
            // else none
        }
        // else none
    }
    $sql .= ')';
    return $sql;
}

WordPress Version: 3.7

/**
 * Retrieve the post SQL based on capability, author, and type.
 *
 * @see get_private_posts_cap_sql() for full description.
 *
 * @since 3.0.0
 * @param string $post_type Post type.
 * @param bool $full Optional. Returns a full WHERE statement instead of just an 'andalso' term.
 * @param int $post_author Optional. Query posts having a single author ID.
 * @param bool $public_only Optional. Only return public posts. Skips cap checks for $current_user.  Default is false.
 * @return string SQL WHERE code that can be added to a query.
 */
function get_posts_by_author_sql($post_type, $full = true, $post_author = null, $public_only = false)
{
    global $wpdb;
    // Private posts
    $post_type_obj = get_post_type_object($post_type);
    if (!$post_type_obj) {
        return $full ? 'WHERE 1 = 0' : ' 1 = 0 ';
    }
    // This hook is deprecated. Why you'd want to use it, I dunno.
    if (!$cap = apply_filters('pub_priv_sql_capability', '')) {
        $cap = $post_type_obj->cap->read_private_posts;
    }
    if ($full) {
        if (null === $post_author) {
            $sql = $wpdb->prepare('WHERE post_type = %s AND ', $post_type);
        } else {
            $sql = $wpdb->prepare('WHERE post_author = %d AND post_type = %s AND ', $post_author, $post_type);
        }
    } else {
        $sql = '';
    }
    $sql .= "(post_status = 'publish'";
    // Only need to check the cap if $public_only is false
    if (false === $public_only) {
        if (current_user_can($cap)) {
            // Does the user have the capability to view private posts? Guess so.
            $sql .= " OR post_status = 'private'";
        } elseif (is_user_logged_in()) {
            // Users can view their own private posts.
            $id = get_current_user_id();
            if (null === $post_author || !$full) {
                $sql .= " OR post_status = 'private' AND post_author = {$id}";
            } elseif ($id == (int) $post_author) {
                $sql .= " OR post_status = 'private'";
            }
            // else none
        }
        // else none
    }
    $sql .= ')';
    return $sql;
}