custom post types – How to modify a query in functions.php to involve both post_title and fields from wp_postmeta?


On my Fusion Builder powered WP website I have created a CPT called movies. The title of each post (i.e. each movie) has a post_title property which is located in wp_posts table, other custom properties like production_date (int(8)) and movie_subtitle (‘varchar(255)’) are located inside wp_postmeta table.

Now, I have an archive page www.mydomain.com/movies which lists all posts of type movies and I want to be able to filter movies based on production_date‘s year and a string typed into a search bar.

The url like this: www.mydomain.com/movies?production_year=2004&search=batman would filter out only those movies which have wp_postmeta.production_year as 2004 and which contain a string batman in either wp_posts.post_title or wp_postmeta.movie_subtitle

This is one of my movies:

wp_posts.post_title: Batman & Robin

wp_postmeta.production_date: 20041803 (i.e. 18th March 2004)

wp_postmeta.movie_subtitle: Joker’s revenge

functions.php

<?php
class searchMovies{
 
    function __construct(){
        add_action( 'pre_get_posts', array( $this, 'filterquery' ) );
    }

    function filterquery( $query ){
        global $pagenow;
        global $typenow;

        if ( is_archive()
            && $query->is_main_query()
            && isset( $_GET('production_year') )
            && !empty( $_GET('production_year') )
            && isset( $_GET('search') )
            && !empty( $_GET('search') )
        ) {
            $query->set(
                'meta_query',
                array(
                    'relation' => 'AND',
                    array(
                        'key' => 'production_date',
                        'value' => array(sanitize_text_field( $_GET('production_year') . '0101'), sanitize_text_field( $_GET('production_year')) . '1231'),
                        'type' => 'DATE',
                        'compare' => 'BETWEEN'
                    ),
                    array(
                        'relation' => 'OR', 
                        array(
                            'key' => 'post_title',
                            'value' => $_GET('search'),
                            'compare' => 'LIKE'
                        ),
                        array(
                            'key' => 'movie_subtitle',
                            'value' => $_GET('search'),
                            'compare' => 'LIKE'
                        )
                    )
                )
            );
        }

        // THIS DOES NOT SEEM TO WORK HERE ↓↓↓
        if ( is_archive()
            && $query->is_main_query()
            && isset( $_GET('search') )
            && !empty( $_GET('search') )
            && ( !isset( $_GET('production_year') ) || empty( $_GET('production_year') ) )
        ) {
            $query->set(
                'meta_query',
                array(
                    'relation' => 'OR',
                    array(
                        'key' => 'post_title',
                        'value' => $_GET('search'),
                        'compare' => 'LIKE'
                    ),
                    array(
                        'key' => 'movie_subtitle',
                        'value' => $_GET('search'),
                        'compare' => 'LIKE'
                    )
                )
            );
        }

        if ( is_archive()
            && $query->is_main_query()
            && ( ! empty( $_GET('production_year') ) )
        ) {
            $query->set(
                'meta_query',
                array(
                    array(
                        'key' => 'production_date',
                        'value' => array(sanitize_text_field( $_GET('production_year') . '0101'), sanitize_text_field( $_GET('production_year')) . '1231'),
                        'type' => 'DATE',
                        'compare' => 'BETWEEN'
                    )
                )
            );
        }
        return $main_query;
    }
}

new searchMovies();

PROBLEM:

This works OK: www.mydomain.com/movies?production_year=2004&search=batman

This DOES NOT work: www.mydomain.com/movies?search=batman

Apparently something is wrong with my 2nd if condition inside my function filterquery() in functions.php, but I don’t know what is wrong.