Assuming you have variables to hold your custom values for each:
$category
$tag
$author
$search
Then just create an arguments array, and add keys to it conditionally:
$custom_query_args = array(
// Set any default args here
// NOTE: This is where you'd add
// things like pagination (posts_per_page),
// order/sort parameters, and the like
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC'
);
// If user defines $category, add it
if ( '' != $category ) {
$custom_query_args['cat'] = $category;
}
// If user defines $tag, add it
if ( '' != $tag ) {
$custom_query_args['tag'] = $tag;
}
// If user defines $author, add it
if ( '' != $author ) {
$custom_query_args['author'] = $author;
}
// If user defines $search, add it
if ( '' != $search ) {
$custom_query_args['s'] = $search;
}
// Run the query
$custom_query = new WP_Query( $custom_query_args );
Note: how you define $category
, $tag
, $author
, and $search
is outside the scope of this answer.
Edit
If you want to include a meta query (i.e. custom field) parameter, you can do that as well:
Assuming (user-defined) $post_meta_key
and (static) $post_meta_key
:
// If user defines $post_meta_value, add it
if ( '' != $post_meta_value ) {
$custom_query_args['meta_query'] = array(
array(
'key' => $post_meta_key,
'value' => $post_meta_value,
'compare' => '=',
)
);
}