error in Advanced Search Form for Custom Post Types in WordPress array_key_exists() expects parameter 2to be array, string given

I am building an advanced search form but the search is showing all post all time with this error too array_key_exists() expects parameter 2 to be array, string was given

this is my code in header.php

<?php $query_types = get_query_var('post_type'); ?>
<?php

     $args = array(
                 'public'   => true,
                 '_builtin' => false
             );

     $output="names"; // names or objects, note names is the default
     $operator="and"; // 'and' or 'or'

     $post_types = get_post_types( $args, $output, $operator ); 

     //array array_slice ( array $array , int $offset [, int $length = NULL [, bool $preserve_keys = false ]] ) see http://php.net/manual/en/function.array-slice.php
    foreach ( array_slice($post_types, 0, 5) as $post_type ) { //display max 5 post_type
         ?> 
    <li>
        <a>
           <input id="<?php  echo $post_type ?>" class="btn btn-lg" type="checkbox" name="post_type[]" value="<?php  echo $post_type ?>" <?php if (!empty($query_types) && array_key_exists($post_type , $query_types)) { echo 'checked="checked"'; } ?>/> 
           <!-- array_key_exists($post_type , $query_types) -->
           <label for="<?php  echo $post_type ?>"><span><?php  echo $post_type ?></span></label> 
       </a> 
    </li> 
 <?php 
} 
?>

in searchform.php a have this:

<?php
    $postType = array("construction","renovation","agrandissement","bradage");

    foreach ($postType as &$value) {
        echo '<input type="hidden" name="post_type[]" value="'.$value.'" />';
    }
    unset($value); // break the reference with the last element
?>

when I add && is_array($query_types) in header.php array_key_exists() expects parameter 2 to be array, string given doesn`t show anymore but the result is empty.
i also get

%5B%5D  

in the url

mywebsite.com/?s=LED70266765IKEA&post_type%5B%5D=boutique

please help me figuring out what I am doing wrong.

UPDATE:

here is my search.php

<?php

 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

?>
<section id="primary" class="row">
    <main id="main" class="container" role="main">
    <?php if ( have_posts() ) : ?>

        <header class="page-header">
            <h5 class="page-title">
                <?php printf( __( 'Résultats de recherche pour: %s', 'igorconstructions' ), '<span>' . esc_html( get_search_query() ) . '</span>' ); ?>
            </h5>
        </header><!-- .page-header --> 
        <?php
        // Start the loop.
        while ( have_posts() ) : the_post();

            /**
             * Run the loop for the search to output the results.
             * If you want to overload this in a child theme then include a file
             * called content-search.php and that will be used instead.
             */
            get_template_part( 'template-parts/content', 'search' );

        // End the loop.
        endwhile;
        ?>
        <!-- PAGINATION -->
        <div class="row">
            <div class="col-md-12">
                <div class="paging-navigation text-right">
                    <?php    
                        the_posts_pagination( array(
                            'screen_reader_text' => ( '' ),
                            'type'      => 'list',
                            'end_size'      => 3,
                            'mid_size'      => 3,
                            'format' => '?paged=%#%',
                            'prev_text' => '<span class="icon-angle-left">&larr;</span>',
                            'next_text' => '<span class="icon-angle-right">&rarr;</span>',
                            'before_page_number' => 'Page',
                            'after_page_number'  => '', 
                        ) ); 
                    ?>      
                </div><!--  end pagination container -->
            </div><!-- end large-12 -->
        </div>
        <!-- end PAGINATION -->
        <?php 
    // If no content, include the "No posts found" template.
    else :
        get_template_part( 'template-parts/content', 'none' );

    endif;
    ?>

    </main><!-- .site-main -->
</section><!-- .content-area -->

and content-search.php looks like this:

 <?php if(isset($_GET['post_type'])) {
    $type = $_GET['post_type'];
    //$type = $wp_query->query['post_type'];
    if ( in_array( $type, array('boutique','news','text') ) ) {?>

    <section class="col-md-4">
        <article id="product-<?php the_ID(); ?>" <?php post_class(); ?>>    
            <!--
                Thumbnail
            -->
            <div class="product-image">
                <figure  class="product-thumb">
                    <!-- === Confitional thumbnail=== -->
                    <?php if (  (function_exists('has_post_thumbnail')) && (has_post_thumbnail())) : ?> 
                            <!--Image size //thumbnail medium large full-->
                            <?php the_post_thumbnail('medium', 'blog-thumb', array('class' => 'blog-thumb')); ?>

                            <?php else :?>

                            <img class="blog-thumb" src="https://wordpress.stackexchange.com/questions/265499/<?php echo get_template_directory_uri(); ?>/images/cat-images/<?php $category = get_the_category(); echo $category[0]->slug; ?>.jpg" /> 

                    <?php endif; ?>
                </figure>
            </div>

            <div class="product-description">
                 <!--
                    The Title
                -->
                <h4>
                    <a href="<?php the_permalink() ?>" rel="bookmark" title="m'en dire plus à ce sujet '<?php the_title_attribute(); ?>' svp!"><?php the_title(); ?></a>
                </h4>
                <P>
                    <?php 
                        $url = get_post_meta( $post->ID, 'price', true ); 

                        if ($url) {
                            echo '<strong>à partir de:</strong> <strong class=thumbnail-price>'.$url.' FCFA TTC</strong>/ Unité';
                        }
                    ?>
                </P> 
            </div>

            <div class="user-actions">
            <!--
                User actions
            -->

                <!-- Product reference-->

                <p class="text-right">
                    <strong>Référence: </strong>
                    <span><?php echo get_post_meta( $post->ID, 'reference', true ) ?></span>
                </p>
                <p class="text-right">
                    <button class="action-btn-prim">
                        <a href="<?php the_permalink() ?>">Voir l'article</a>
                    </button>
                </p>
                <form class="text-right"> 
                    <button class="add-to-cart action-bt"> 
                        <a><svg class="pull-left" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" width="20px" height="20px" viewBox="0 0 29 30" version="1.1">

                            <g xmlns="http://www.w3.org/2000/svg" id="Group">
                                <path fill="floralwhite" d="M5.87076823,28.1796875 C4.57567676,28.1796875 3.52246094,27.1264717 3.52246094,25.8313802 C3.52246094,24.5362887 4.57567676,23.4830729 5.87076823,23.4830729 C7.1658597,23.4830729 8.21907552,24.5362887 8.21907552,25.8313802 C8.21907552,27.1264717 7.1658597,28.1796875 5.87076823,28.1796875 L5.87076823,28.1796875 Z M5.87076823,24.6572266 C5.22322249,24.6572266 4.69661458,25.1838345 4.69661458,25.8313802 C4.69661458,26.4789259 5.22322249,27.0055339 5.87076823,27.0055339 C6.51831396,27.0055339 7.04492188,26.4789259 7.04492188,25.8313802 C7.04492188,25.1838345 6.51831396,24.6572266 5.87076823,24.6572266 L5.87076823,24.6572266 Z" id="Shape"/>
                                <path fill="floralwhite" d="M18.7864583,28.1796875 C17.4913669,28.1796875 16.438151,27.1264717 16.438151,25.8313802 C16.438151,24.5362887 17.4913669,23.4830729 18.7864583,23.4830729 C20.0815498,23.4830729 21.1347656,24.5362887 21.1347656,25.8313802 C21.1347656,27.1264717 20.0815498,28.1796875 18.7864583,28.1796875 L18.7864583,28.1796875 Z M18.7864583,24.6572266 C18.1389126,24.6572266 17.6123047,25.1838345 17.6123047,25.8313802 C17.6123047,26.4789259 18.1389126,27.0055339 18.7864583,27.0055339 C19.4340041,27.0055339 19.960612,26.4789259 19.960612,25.8313802 C19.960612,25.1838345 19.4340041,24.6572266 18.7864583,24.6572266 L18.7864583,24.6572266 Z" id="Shape"/>
                                <path fill="floralwhite" d="M12.3286133,9.39322917 C12.0039598,9.39322917 11.7415365,9.13080583 11.7415365,8.80615234 L11.7415365,0.587076823 C11.7415365,0.26242334 12.0039598,0 12.3286133,0 C12.6532668,0 12.9156901,0.26242334 12.9156901,0.587076823 L12.9156901,8.80615234 C12.9156901,9.13080583 12.6532668,9.39322917 12.3286133,9.39322917 L12.3286133,9.39322917 Z" id="Shape"/>
                                <path fill="floralwhite" d="M12.3286133,9.39322917 C12.1783216,9.39322917 12.0280299,9.33569564 11.91355,9.22121566 L8.39108903,5.69875472 C8.16154199,5.46920768 8.16154199,5.09817513 8.39108903,4.86862809 C8.62063607,4.63908105 8.99166862,4.63908105 9.22121566,4.86862809 L12.3286133,7.97602572 L15.4360109,4.86862809 C15.6655579,4.63908105 16.0365905,4.63908105 16.2661375,4.86862809 C16.4956846,5.09817513 16.4956846,5.46920768 16.2661375,5.69875472 L12.7436766,9.22121566 C12.6291966,9.33569564 12.4789049,9.39322917 12.3286133,9.39322917 L12.3286133,9.39322917 Z" id="Shape"/>
                                <path fill="floralwhite" d="M18.7864583,24.6572266 L5.87076823,24.6572266 C5.54611475,24.6572266 5.28369141,24.3948032 5.28369141,24.0701497 C5.28369141,23.7454963 5.54611475,23.4830729 5.87076823,23.4830729 L18.3214935,23.4830729 L22.9112601,3.97509717 C22.9740773,3.70973844 23.2106693,3.52246094 23.4830729,3.52246094 L27.5926107,3.52246094 C27.9172642,3.52246094 28.1796875,3.78488428 28.1796875,4.10953776 C28.1796875,4.43419124 27.9172642,4.69661458 27.5926107,4.69661458 L23.9480378,4.69661458 L19.3582712,24.2045903 C19.2954539,24.4699491 19.058862,24.6572266 18.7864583,24.6572266 L18.7864583,24.6572266 Z" id="Shape"/>
                                <path fill="floralwhite" d="M19.3735352,22.3089193 L4.10953776,22.3089193 C3.85650765,22.3089193 3.63283138,22.1474731 3.55298893,21.9073587 L0.0305279948,11.3399759 C-0.029940918,11.1609175 0.000587076823,10.9636597 0.11095752,10.8110197 C0.221327962,10.6577926 0.398625163,10.5673828 0.587076823,10.5673828 L21.7218424,10.5673828 C22.0464959,10.5673828 22.3089193,10.8298062 22.3089193,11.1544596 C22.3089193,11.4791131 22.0464959,11.7415365 21.7218424,11.7415365 L1.40193945,11.7415365 L4.53282015,21.1347656 L19.3735352,21.1347656 C19.6981886,21.1347656 19.960612,21.397189 19.960612,21.7218424 C19.960612,22.0464959 19.6981886,22.3089193 19.3735352,22.3089193 L19.3735352,22.3089193 Z" id="Shape"/>
                            </g>
                            </svg>
                             Ajouter
                        </a>
                    </button>
                </form>
            </div>
            <hr>
        </article>
    </section>     
    <?php } 
  elseif($type == 'construction'){


  }
  elseif($type == 'blog'){


   }
 }else { ?>

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>


<?php if ( 'post' === get_post_type() ) : ?>

<?php else : ?>

    <?php get_the_title() ?>

<?php endif; ?>

2 Answers
2

The core issue is that you’re having trouble creating a filtered search. Why not use a pre_get_posts hook to modify the query before it actually gets called, then you don’t need to modify the template files at all:

/**
 * Modify WP_Query before it asks the database what data to retrieve
 * Belongs in functions.php
 *
 * @param WP_Query Object $query
 *
 * @return void
 */
function wpse_265499( $query ) {

    // Don't run on admin
    if( $query->is_admin ) {
        return;
    }

    // IF main query and search page
    if( $query->is_main_query() && $query->is_search() ) {

        // IF we have our post type array set 
        if( isset( $_GET, $_GET['post_type'] ) && ! empty( $_GET['post_type'] ) ) {
            $query->set( 'post_type', $_GET['post_type'] );     // Will be set as boutique
        }

    }

}
add_action( 'pre_get_posts', 'wpse_265499' );

The above would be added to your functions.php file and what pre_get_posts does is before it goes to the database and grabs the data to be displayed, we can modify what is being requested. In this case we’re saying IF we have post_types set in the URL as a $_GET, grab only those post types. So your main query will now only show the post types assigned in $_GET at which point there’s no need for the conditional statements in your template.


Let’s break this down starting with the error itself.

array_key_exists() expects parameter 2 to be array, string was given

So based on the error we know that array_key_exists() needs parameter 2 to be an array, so that it can search for a key, but at some point a string was given instead of an array.

As far as I can tell you only have one instance of array_key_exists() and it looks like this:

array_key_exists( $post_type , $query_types )

Combined with the PHP error we can surmise that $query_types must be a string instead of the array that we need for array_key_exists() to work. Let’s look at how $query_types is set:

$query_types = get_query_var( 'post_type' );

If we look at the get_query_var() function we see it can return an array because the return type is mixed. That being said, we’re only asking for one post_type so it’s probably returning a string for the queried post type.

I’m not sure what it is you’re trying to accomplish but hopefully that clears up the reason you’re getting that error.

Leave a Comment