: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Handle ajax requests to search for posts.
function et_builder_ajax_search_posts() {
et_core_security_check( 'edit_posts', 'et_builder_search_posts', 'nonce', '_GET' );
$current_page = isset( $_GET['page'] ) ? (int) $_GET['page'] : 0;
$current_page = max( $current_page, 1 );
$post_type = isset( $_GET['post_type'] ) ? sanitize_text_field( $_GET['post_type'] ) : '';
$value = isset( $_GET['value'] ) ? sanitize_text_field( $_GET['value'] ) : '';
$search = isset( $_GET['search'] ) ? sanitize_text_field( $_GET['search'] ) : '';
$prepend_value = (int)$value > 0;
$include_current_post = '1' === (string) et_()->array_get( $_GET, 'include_current_post', '0' );
$include_latest_post = '1' === (string) et_()->array_get( $_GET, 'include_latest_post', '0' );
$public_post_types = et_builder_get_public_post_types();
if ( ! isset( $public_post_types[ $post_type ] ) ) {
$post_type_object = get_post_type_object( $post_type );
$post_type_label = $post_type_object ? $post_type_object->labels->singular_name : '';
'post_type' => $post_type,
'posts_per_page' => $results_per_page,
'post_status' => 'attachment' === $post_type ? 'inherit' : 'publish',
'paged' => $current_page,
$value_post = get_post( $value );
if ( $value_post && 'publish' === $value_post->post_status && $value_post->post_type === $post_type ) {
$results['results'][] = array(
'label' => et_core_intentionally_unescaped( strip_tags( $value_post->post_title ), 'react_jsx' ),
'post_type' => et_core_intentionally_unescaped( $post_type_label, 'react_jsx' ),
// We will manually prepend the current value so we need to reduce the number of results.
$query['posts_per_page'] -= 1;
$query['post__not_in'] = array( $value );
if ( 'attachment' === $post_type ) {
add_filter( 'posts_join' , 'et_builder_ajax_search_posts_query_join' );
add_filter( 'posts_where' , 'et_builder_ajax_search_posts_query_where' );
$posts = new WP_Query( $query );
if ( 'attachment' === $post_type ) {
remove_filter( 'posts_join' , 'et_builder_ajax_search_posts_query_join' );
remove_filter( 'posts_where' , 'et_builder_ajax_search_posts_query_where' );
if ( $include_current_post && ! empty( $posts->posts ) ) {
$current_post_type = sanitize_text_field( et_()->array_get( $_GET, 'current_post_type', 'post' ) );
$current_post_type = isset( $public_post_types[ $current_post_type ] ) ? $current_post_type : 'post';
$current_post_type_object = get_post_type_object( $current_post_type );
$current_post_type_label = $current_post_type_object ? $current_post_type_object->labels->singular_name : '';
$results['results'][] = array(
// Translators: %1$s: Post type singular name.
'label' => et_core_intentionally_unescaped( sprintf( __( 'This %1$s', 'et_builder' ), $current_post_type_label ), 'react_jsx' ),
'post_type' => et_core_intentionally_unescaped( $current_post_type_label, 'react_jsx' ),
$query['posts_per_page'] -= 1;
if ( $include_latest_post && ! empty( $posts->posts ) ) {
$results['results'][] = array(
// Translators: %1$s: Post type singular name.
'label' => et_core_intentionally_unescaped( sprintf( __( 'Latest %1$s', 'et_builder' ),
$post_type_label ), 'react_jsx' ),
'post_type' => et_core_intentionally_unescaped( $post_type_label, 'react_jsx' ),
$query['posts_per_page'] -= 1;
foreach ( $posts->posts as $post ) {
$results['results'][] = array(
'value' => (int) $post->ID,
'label' => et_core_intentionally_unescaped( strip_tags( $post->post_title ), 'react_jsx' ),
'post_type' => et_core_intentionally_unescaped( $post_type_label, 'react_jsx' ),
$results['meta']['pagination'] = array(
'per_page' => (int) $results_per_page,
'total' => (int) $posts->found_posts,
'current' => (int) $current_page,
'total' => (int) $posts->max_num_pages,
wp_send_json_success( $results );
add_action( 'wp_ajax_et_builder_search_posts', 'et_builder_ajax_search_posts' );
* Join the parent post for attachments queries.
function et_builder_ajax_search_posts_query_join( $join ) {
$join .= " LEFT JOIN `$wpdb->posts` AS `parent` ON `parent`.`ID` = `$wpdb->posts`.`post_parent` ";
* Filter attachments based on the parent post status, if any.
function et_builder_ajax_search_posts_query_where( $where ) {
$public_post_types = array_keys( et_builder_get_public_post_types() );
// Add an empty value to:
// - Avoid syntax error for `IN ()` when there are no public post types.
// - Cause the query to only return posts with no parent when there are no public post types.
$public_post_types[] = '';
$where .= $wpdb->prepare( " AND (
`parent`.`ID` IS NULL OR (
`parent`.`post_status` = %s
`parent`.`post_type` IN (" . implode( ',', array_fill( 0, count( $public_post_types ), '%s' ) ) . ")
)", array_merge( array( "publish" ), $public_post_types ) );