WP_query repeater "NOT LIKE" dosen't working - php

I have very annoying problem with WP_query and repeater . I try display something if $_GET is not equal to value in my DB. But when compare => NOT LIKE it now working correctly.
Here is my code:
function wyszukiwanie_trasy()
{
echo '<form action="" method="get">';
echo '<input type="text" name="od" placeholder="Stacja początkowa">';
echo '<input type="text" name="do" placeholder="Stacja końcowa">';
echo '<input type="date" name="data">';
echo '<input type="submit" value="Wyszukaj">';
echo '</form>';
$loop = new WP_Query(array('meta_query' => array(
'relation' => 'AND',
array(
'key' => 'date_%_daty_wykluczone',
'value' => str_replace("-","",$_GET['data'],$i),
'compare' => 'NOT LIKE'),
),
array(
'value' => $_GET['od'],
),
array(
'value' => $_GET['do'],
),'post_type' => 'trasy', 'posts_per_page' => -1));
while ($loop->have_posts()) : $loop->the_post();
$id = get_the_ID();
if($_GET['od'] && $_GET['do'] && $_GET['data'] && $_GET['od']!=$_GET['do'])
{
if( have_rows('location') ):
// loop through the rows of data
while ( have_rows('location') ) : the_row();
// display a sub field value
?>
<span style="font-weight: bold"><?php the_sub_field('lokacja');?></span>
<?php
echo ' ';
endwhile;
echo '<br />';
else :
echo 'Brak połączeń';
endif;
}
echo $loop->request;
endwhile; wp_reset_query();
}
Here is my SQL request:
SELECT wp_posts.* FROM wp_posts INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) WHERE 1=1 AND ( ( wp_postmeta.meta_key LIKE 'date_%_daty_wykluczone' AND wp_postmeta.meta_value LIKE '%20180715%' ) ) AND wp_posts.post_type = 'trasy' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'acf-disabled' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC
Imo is is something wrong with 'key' => 'date_%_daty_wykluczone', in my DB that meta keys looks like: date_0_daty_wykluczone date_1_daty_wykluczone, cause when i change this 'key' => 'date_%_daty_wykluczone', to 'key' => 'date_1_daty_wykluczone', 'NOT LIKE' works correctly
Thanks in advance :)

Try this code structure,
Using the "Relation" for the Meta Query, you can select multiple Meta Keys. You can change the "Compare" to any of the operations available for that function. (From the Codex) compare (string) - Operator to test. Possible values are '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS' and 'NOT EXISTS'. Default value is '='.
// WP_Query arguments
$args = array (
'post_type' => 'your-post-type',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'color',
'value' => 'Red',
'compare' => 'LIKE',
),
array(
'key' => 'color',
'value' => 'Plain',
'compare' => 'Like'
),
),
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
// do something
}
} else {
// no posts found
}
// Restore original Post Data
wp_reset_postdata();
Meta_query compare operator explanation
The first several work about like you would expect:
= equals
!= does not equal
> greater than
>= greater than or equal to
< less than
<= less than or equal to
LIKE and NOT LIKE are SQL operators that let you add in wild-card symbols, so you could have a meta query that looks like this:
array(
'key' => 'name',
'value' => 'Pat',
'compare' => 'LIKE'
)
This would return all posts where the meta value "name" has the string "Pat". In this case, "Pat" "Patricia" and "Patrick" would all be returned back to you. There's a non-WordPress tutorial explanation here

Related

Meta query key with POST OBJECT (ACF) (post_title) in wordpress

I have big problem with my meta query. I would like to filter my posts, and I need query to compare post_title with my $_POST value.
Code:
function postsFilter(){
$args = array(
'post_type' => 'posts',
'meta_query' => array(
'relation' => 'AND'
)
);
if( isset($_POST['year']) && $_POST['year'] )
$args['meta_query'][] = array(
'key' => 'year',
'value' => $_POST['year'],
'compare' => '='
);
if( isset($_POST['theme']) && $_POST['theme'] )
$args['meta_query'][] = array(
'key' => 'theme',
'value' => $_POST['theme'],
'compare' => '='
);
if( isset($_POST['member']) && $_POST['member'] )
$args['meta_query'][] = array(
'key' => 'member_relation',
'value' => ``.$_POST['member'].``,
'compare' => 'LIKE'
);
$query = new WP_Query( $args );
echo "<script>
var posts_p = '" . json_encode( $query->query_vars ) . "',
current_page_p = " . 1 . " ,
max_page_p = " . $query->max_num_pages . ";
console.log(current_page_p, max_page_p);
</script>";
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
get_template_part('template-parts/content', 'posts');
endwhile;
if ( $query->max_num_pages > 1 )
echo '<div class="button-load-more_p btn-load-more text-center mx-auto w-100"><a class="btn btn-primary btn-md btn-with-icon fade-in full-visible load-more"><span>Load more</span></div></a></div>';
wp_reset_postdata();
else :
echo 'No publications found';
endif;
die();
}
and problem exists here:
if( isset($_POST['member']) && $_POST['member'] )
$args['meta_query'][] = array(
'key' => 'member_relation',
'value' => $_POST['member']
'compare' => 'LIKE'
);
because I don't know how to write this part of query,
member relation is POST OBJECT type file in Wordpress, I need compare $_POST['member'] with post_title value (maybe I am wrong ?)
$member = get_field('member_relation', $post_object->ID);
$member->post_title;
Is it possible to write this query? Please give me any advice or example solution of my problem.
Try This, merge your meta query argument with the post title arg.
if( isset( $_POST['title'] ) && !empty( $_POST['title'] ) ){
$args2 = array(
's' => '"'.$_POST['title'].'"'
) ;
$args = array_merge( $args, $args2);
}

Query on a ACF repeater field

I would like to query an ACF repeater field. I've a repeater field called Library (in a CPT called Book) and, in this repeater, I have a relation field called Library (that is connected to an other custom post type called Library). It is this field that I would like to query*.
I look to recover, thanks to an unique value given by the user (selected thanks to a select), all the books that are in relation with this Library.
Ex : 'Library 1' is selected. Return : 'Harry Potter 1' and 'Harry Potter 2'.
Trials (not working)
function my_posts_where( $where ) {
$where = str_replace("meta_key = 'library_$", "meta_key LIKE 'library_%", $where);
return $where; } add_filter('posts_where', 'my_posts_where');
$library= $_GET['library'];
$v_args = array(
'post_type' => 'book',
'meta_query' => array(
array(
'key' => 'library_$_library',
'compare' => '=',
'value' => $library,
),
)
); $Query = new WP_Query($v_args);
if($Query->have_posts()) :
while($Query->have_posts()) : $Query->the_post();
...
endwhile;
else :
...
endif;
And this
$library= $_GET['library'];
$v_args = array(
'post_type' => 'book',
'meta_query' => array(
array(
'key' => 'library',
'value' => $library,
'compare' => 'LIKE',
),
)
);
$Query = new WP_Query($v_args);
I searched on the Internet, I could not resolve my problem ...
Thanks a lot.
-* : I also have a repeater field called Tags and in it a Taxonomy field in relation with tags. I would like to show all the books that have thig tag.
This is a bit late, but in case this helps anyone else, this works for me:
//Since the changed behaviour of esc_sql() in WordPress 4.8.3,
//cannot use the % character as a placeholder, hence need to alter 'where' close:
function my_posts_where( $where ) {
$where = str_replace("meta_key = 'library_$", "meta_key LIKE 'library_%", $where);
return $where;
}
add_filter('posts_where', 'my_posts_where');
$library_id = $_GET['library']; //get querystr var
$args = array(
'post_type' => 'book',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'library_$_library', // our repeater field post object
'value' => '"'. $library_id .'"', //matches exactly "123", not just 123 - prevents a match for "1234"
'compare' => 'LIKE'
)
)
);
$query = new WP_Query($args);
if ($query->have_posts()):
while ($query->have_posts()) : $query->the_post();
echo $post->post_title.'<br>';
endwhile;
endif;
wp_reset_query();

Exclude Featured Post from Custom Query WordPress

This is the custom query I'm running to display post from 2 categories.
I have installed WordPress Plugin "Featured Post" but the featured post is not excluding from the displayed list.
<?php
$category_id = get_cat_ID($strReports || $strInsights);
$custom_query = new WP_Query( 'cat=' .$category_id. '&featured=no&posts_per_page=6&order=desc' );
while($custom_query->have_posts()) : $custom_query->the_post();
?>
HTML Content Here
<?php endwhile; ?>
<?php wp_reset_query(); // reset the query ?>
Looking through "Featured Post" you can see that it just test against yes value. What feature=yes does is just check a meta field, so I think you can do the reverse way to achieve what you want, like this:
$args = array(
'cat' => $category_id,
'posts_per_page' => 6,
'order' => 'DESC', // since order default value is already DESC you can remove this line
'meta_query' => array(
'relation' => 'OR',
array(
'key' => '_is_featured',
'value' => 'yes',
'compare' => '!=',
),
array(
'key' => '_is_featured',
'value' => 'foo', // Prior to WP 3.9 we have to provide any non-empty string here
'compare' => 'NOT EXISTS',
),
) ,
);
$custom_query = new WP_Query($args);
Hope it helps!
your'e running an invalid argument on get_cat_ID.
should be something like this:
<?php
$cat_names = array('Cat_Name1', 'Cat_Name2');
$category_Name = implode(',', $cat_names);
$args = array(
'category_name' => $category_Name,
'posts_per_page' => 6,
'meta_query' => array(
array(
'key' => 'featured',
'value' => true,
'compare' => '!=',
),
),
);
$custom_query = new WP_Query( $args );
while($custom_query->have_posts()) : $custom_query->the_post();
?>
<?php the_title();?>
<?php endwhile; ?>
<?php wp_reset_query(); // reset the query ?>
create your custom query and add filter.
function SearchFilter($query){
$query=" SELECT Distinct SQL_CALC_FOUND_ROWS p.* FROM `$wpdb->posts` as p left join `$wpdb->postmeta` as m on m.post_id=p.ID "
." left join `$wpdb->term_relationships` as r ON (p.ID = r.object_id) "
." left join `$wpdb->term_taxonomy` as x ON (x.term_taxonomy_id = r.term_taxonomy_id) "
." left join `$wpdb->terms` as t ON (t.term_id = x.term_id AND x.taxonomy='category') "
." WHERE p.post_type = 'post' AND p.post_status = 'publish' "
." AND t.term_id='$idcategorie' "
return $query;
}
add_filter( 'posts_request', 'SearchFilter' );

WP_Query custom post type by multiple custom fields

Alright guys, I'm in way over my head.
I'm trying to build a filter for a custom post type, 'Villas'. These villas have multiple custom fields, these custom fields exist in a group named 'features'.
I've build a search / filter form that POST's the data, which I'm then able to capture using a $_GET request.
The data I'm sending includes:
- Region, type, style select fields;
- Sea view, Sea access, Swimming pool, Reform project checkboxes;
- Price input field
What I'm trying to accomplish is get a query going that filters all 'Villas' using the form values. After extensive googling I found it is possible to loop through custom post_type's with custom fields by using meta_key's. Basicly what I'm trying to do is:
$propertyPrice = $_GET['price'];
$propertyRegion = $_GET['region'];
$propertyType = $_GET['type'];
$propertyStyle = $_GET['style'];
$hasSeaview = $_GET['seaview'];
$hasSeaAccess = $_GET['sea-access'];
$hasSwimmingPool = $_GET['swimming-pool'];
$hasReformProject = $_GET['reform-project'];
if( isset($propertyPrice) || isset($propertyRegion || isset($propertyType)) || isset($propertyStyle) || isset($hasSeaview) || isset($hasSeaAccess) || isset($hasSwimmingPool) || isset($hasReformProject)) {
$args = array(
'meta_query' => array(
'relation' => 'OR'
array(
'key' => 'property-price',
'value' => $propertyPrice,
),
array(
'key' => 'property-region',
'value' => $propertyRegion,
),
array(
'key' => 'property-type',
'value' => $propertyType,
),
etc......
)
);
}
However, I cannot for the life of me figure out how to filter through the posts with variable meta values, send from the form.
If anyone could point me in the right direction, it would be extremely appreciated.
To give you an idea, this is what the filter looks like:
Custom post type filter
EDIT
After xphan's suggestion I edited my code like so, however the var_dump returns nothing even though the _GET's are filled correctly.
<?php
$propertyPrice = $_GET['price'];
$propertyRegion = $_GET['region'];
if($propertyRegion === 'all') { $propertyRegion = array('ibiza-city', 'southwest', 'north', 'east', 'center'); }
$propertyType = $_GET['type'];
if($propertyType === 'all') { $propertyType = array('villa', 'apartment', 'plot'); }
$propertyStyle = $_GET['style'];
if($propertyStyle === 'all') { $propertyStyle = array('rustic', 'modern'); }
$hasSeaview = $_GET['seaview'];
if( isset($hasSeaview) ) { $hasSeaview = 1; }
$hasSeaAccess = $_GET['sea-access'];
if( isset($hasSeaAccess) ) { $hasSeaAccess = 1; }
$hasSwimmingPool = $_GET['swimming-pool'];
if( isset($hasSwimmingPool) ) { $hasSwimmingPool = 1; }
$hasReformProject = $_GET['reform-project'];
if( isset($hasReformProject) ) { $hasReformProject = 1; }
?>
<?php
echo $propertyRegion .'<br>';
echo $propertyType .'<br>';
echo $propertyStyle .'<br>';
echo $propertyPrice .'<br>';
?>
<?php if( isset($propertyPrice) || isset($propertyRegion) || isset($propertyType) || isset($propertyStyle) || isset($hasSeaview) || isset($hasSeaAccess) || isset($hasSwimmingPool) || isset($hasReformProject)) {
$args = array(
'post_type' => 'villas',
'meta_query' => array(
array(
'key' => 'property-price',
'value' => $propertyPrice
),
array(
'key' => 'property-region',
'value' => $propertyRegion,
'compare' => 'IN'
),
array(
'key' => 'property-type',
'value' => $propertyType,
'compare' => 'IN'
),
array(
'key' => 'property-style',
'value' => $propertyStyle,
'compare' => 'IN'
),
array(
'key' => 'sea-view',
'value' => $hasSeaview
)
)
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post(); ?>
<?php var_dump($the_query->the_post()); ?>
<?php
}
} else {
// no posts found
}
/* Restore original Post Data */
wp_reset_postdata();
}
You can pass an array of values to the value attribute of your meta_query. Further you can specify the relation the target meta values must have with your provided values.
Here is an example where you search for a post that has (besides the matching propert-price meta value) either value1 or value2 saved in the meta field property-region
$args = array(
'meta_query' => array(
'relation' => 'OR'
array(
'key' => 'property-price',
'value' => $propertyPrice,
),
array(
'key' => 'property-region',
'value' => array('value1', 'value2'),
'compare' => 'IN'
)
)
);

PHP/MySQL query find string in field

Ive written a query that searches for all posts that have X as a meta/custom field value.
// PSV National Query
if ($_POST['vehicleType'] == 'psv' && $_POST['coverageRegion'] == 'national' ) {
$customkey = 'vehicleType';
$customvalue = $_POST['vehicleType'];
$customkey1 = 'coverageRegion';
$customvalue1 = $_POST['coverageRegion'];
$customkey2 = 'locationType';
$customvalue2 = $_POST['locationType'];
global $wpdb;
$my_posts = $wpdb->get_results("
SELECT $wpdb->posts.*
FROM $wpdb->posts, $wpdb->postmeta, $wpdb->postmeta AS mt1
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->postmeta.meta_key = '$customkey'
AND $wpdb->postmeta.meta_value = '$customvalue'
AND mt1.meta_key = '$customkey1'
AND mt1.meta_value = '$customvalue1'
AND mt2.meta_key = '$customkey2'
AND mt2.meta_value = '$customvalue2'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
ORDER BY $wpdb->posts.post_date DESC
");
$args = array(
'meta_query' => array(
array(
'key' => $customkey,
'value' => $customvalue,
'compare' => '='
),
array(
'key' => $customkey1,
'value' => $customvalue1,
'compare' => '='
),
array(
'key' => $customkey2,
'value' => $customvalue2,
'compare' => '='
)
)
);
$query = new WP_Query( $args );
foreach ($query as $post) :
setup_postdata($post);
echo '<div><a href="';
the_permalink();
echo '"></div>';
the_title();
endforeach;
}
Now for my post I have 1 value for each meta key and this works fine, I want to however have multiple values.
For example...
"gas, electricity, water"
When I add multiple values however the query returns null, I presumer its because im saying if...
postmeta.meta_value = '$customvalue'
Can anybody give me advice on where im going wrong?
Why don't you use the built in WP QUERY, it supports meta field array operators.
for example:
$query = new WP_Query( array(
'meta_key' => 'color',
'meta_value' => 'blue',
'meta_compare' => '!='
));
Ref: http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
If you are using multiple matches in a query's where clause you should use the IN variant istead of the =.
The only row I see in your query where you use $customvalue is here
AND $wpdb->postmeta.meta_value = '$customvalue'
You should change the = to IN and seperate the values with a , and quotes ' ' like this for example
AND $wpdb->postmeta.meta_value IN ('gas','electricity','water')
I ditched the $customvalue in the above code to make the point of the seperator of the IN value.
Hopefully this puts you on the right track.

Categories