Im using the below code in order to add all Wordpress posts (excluding the 'sliders' category) to a category called 'Frontpage' ID = 28
function add_category_automatically1($post_ID) {
global $wpdb;
$postsWeWants = $wpdb->get_results("SELECT ID, post_author FROM $wpdb->posts where ID = $post_ID");
foreach ($postsWeWants as $postsWeWant) {
if (!in_category('sliders')) {
$cat = array(28, );
wp_set_object_terms($post_ID, $cat, 'category', true);
}
}
I want to add the exception of an additional category called 'business-information' but I can't get the OR operator to validate properly.
I was looking at using something like below
function add_category_automatically1($post_ID) {
global $wpdb;
$postsWeWants = $wpdb->get_results("SELECT ID, post_author FROM $wpdb->posts where ID = $post_ID");
foreach ($postsWeWants as $postsWeWant) {
if (!in_category('sliders')) OR (!in_category('business-information')) {
$cat = array(28, );
wp_set_object_terms($post_ID, $cat, 'category', true);
}
}
This:
if (!in_category('sliders')) OR (!in_category('business-information'))
// ^ -- ^ -- and here
is wrong. Because you close ) and open ( too early.
Proper code is:
if (!in_category('sliders') OR !in_category('business-information'))
And by the way such logic is invalid. If item is in 'business-information' then !in_category('sliders') true. I suppose you need to check for not existing in both cats:
if (!in_category('sliders') AND !in_category('business-information'))
You are using it wrong instead if (!in_category('sliders')) OR (!in_category('business-information')) {
write it like this (one more thing which is mentioned by #FirstOne you need to use AND instead OR to apply both conditions not one of them)
if( !in_category('sliders') AND !in_category('business-information') ) {
...
}
so that both !in_category checks will be in same if( ... ) scops
Related
I need to let users only post once for custom post 'projects'.
The code below counts the number of the post:
$userid = get_current_user_id();
function count_user_posts_by_type($userid, $post_type = 'projects', $post_status = 'publish') {
global $wpdb;
$query = "SELECT COUNT(*) FROM $wpdb->posts WHERE post_author = $userid AND post_type = '$post_type' AND post_status = '$post_status'";
$count = $wpdb->get_var($query);
return apply_filters('get_usernumposts', $count, $userid);
}
And shows correct number with
<?php echo count_user_posts_by_type($userid); ?>
My question:
I need to combine it with add_action.
So that when the result is 0 the user can post, when the result is !=0 the user cannot post.
The code below is something that I want to implement but it doesn't work at all and I have no idea how to combine together.
Would you please let me know how to combine codes together?
add_action( 'count-user-posts-by-type', 'count_user_posts_by_type' );
$postcount = count_user_posts_by_type($userid);
if($postcount != 0){
return ( 'www.mywebsite.com/cannot-post/' );
} else{
return ( 'www.mywebsite.com/can-post/' );
}
}
Thank you.
You can use is_user_logged_in() to check whether the current user is logged in or not.
Then you can use the template_redirect hook to perform the check :
function only_post_once_redirect()
{
if( is_user_logged_in() ) {
$userid = get_current_user_id(); //-- get the user id
$postcount = count_user_posts_by_type( $userid ); //-- get the count
if( $postcount != 0 ){ //-- not equal to zero
wp_redirect( home_url( 'www.mywebsite.com/cannot-post/' ) );
die;
} else{ //-- equal to zero
wp_redirect( home_url( 'www.mywebsite.com/can-post/' ) );
die;
}
}
}
add_action( 'template_redirect', 'only_post_once_redirect' );
You may need to add some more login to it, say to check which the user is now or something like that.
Or if you want this check & redirect to happen just after the login, you could try the login_redirect hook.
EDIT
I believe you have to spend some time polishing your PHP skills. Look for some basic PHP tutorials like this. You will recall everything after you spend an hour or two in those tutorials.
To answer your question(which you asked in comments), you can simply pass the second parameter as string. No need of that $post_type = part in it. Only in function definition (ie, when you define how the function should perform), you write the default values. When you make function calls, you simply pass the values as parameter. No need of the assignments in the parameters.
In short, your function call should be like this:
$postcount = count_user_posts_by_type( $userid2, 'projects' );
Since you've already mentioned the default value of the second parameter to be projects in your function definition, you can simply use this:
$postcount = count_user_posts_by_type( $userid2 );
I solved the problem using different code, in case someone needs it :
add_shortcode( 'current-user-has-posts' , 'current_user_has_posts' );
function current_user_has_posts(){
$args = array(
'post_type' => 'projects',
'author' => get_current_user_id(),
);
$wp_posts = get_posts($args);
if (count($wp_posts)) {
return ( 'www.mywebsite.com/cannot-post/' );
} else {
return ( 'www.mywebsite.com/can-post/' );
}
}
I am using this code to hide the empty categories, and it works.
add_filter( 'wp_get_nav_menu_items', 'nav_remove_empty_category_menu_item', 10, 3 );
function nav_remove_empty_category_menu_item ( $items, $menu, $args ) {
global $wpdb;
$nopost = $wpdb->get_col( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE count = 0" );
foreach ( $items as $key => $item ) {
if ( ( 'taxonomy' == $item->type ) && ( in_array( $item->object_id, $nopost ) ) ) {
unset( $items[$key] );
}
}
return $items;
}
But I want it to work for subcategories only... not the parent category.
So right now it hides some parent categories and I don't want that. I want to hide only the empty subcategories.
How can I do that?
You don't need a recursive function at all. The term_taxonomy table has another column called parent, which is set to 0 if it's a top level item, and will be the parent's ID if it's a child at any level. Simply add
AND parent != 0
to your query, and that should take care of it. (That said, I feel like pulling the terms and looping through the items for a match to unset is a bit overkill, but without knowing more it's tough to recommend a better solution, and this isn't a bad way to go about it - one of those "hammers to kill a fly" things.)
It may be (quite) a bit pedantic, but I also prefer writing SQL statements outside of the helper functions to make it easier to see at a glance what needs to be run through ::prepare, and deal with longer queries easier
add_filter( 'wp_get_nav_menu_items', 'nav_remove_empty_category_menu_item', 10, 3 );
function nav_remove_empty_category_menu_item( $items, $menu, $args ){
global $wpdb;
$sql = "
SELECT term_taxonomy_id
FROM $wpdb->term_taxonomy
WHERE count = 0
AND parent != 0
";
$no_posts = $wpdb->get_col( $sql );
foreach( $items as $key => $item ){
if( 'taxonomy' == $item->type && in_array($item->object_id, $no_posts) ){
unset( $items[$key] );
}
}
return $items;
}
I am trying to create a custom filter with the custom table in woocommerce. there is approx 24 000 products that makes the custom filter very slow. How to make it faster?
here is my code:
function custom_wpquery( $query ){
if(isset($_GET['min-price'])){
// the main query
global $wp_the_query;
global $wpdb;
if ( 'product' === $query->get( 'post_type' ) ) {
$rr = g($_GET['min-price'],$_GET['max-price']);
foreach($rr as $rrr){
$fabricc = $wpdb->get_results("SELECT * FROM CWF_posts WHERE post_title = '".$rrr."' AND post_type = 'product'");
foreach($fabricc as $fabriccc){
$cID[] = $fabriccc->ID;
}
}
//print_r();exit;
// foreach($cID as $cIDD){
// $cat= wp_get_post_terms( $dd->ID, 'product_cat' );
// }
//$dd = get_page_by_title( $rrr, OBJECT, 'product' );
// $include[]=$dd->ID;
//
// $c[] = $cat[0]->slug;
//$c2[] = $cat[1]->slug;
$query->set('post__in', $cID);
}
}
}
add_filter( 'pre_get_posts', 'custom_wpquery' );
Thanks
You can create a multiple-index on fields that you are querying... Since your one field is constant I advise that convert your SQL to
SELECT * FROM CWF_posts WHERE post_type = 'product' AND post_title = '".$rrr."'
and create an index on post_type and post_title with this command on MySQL
CREATE INDEX type_title_index on CWF_posts (post_type, post_title)
also you can check
Understanding multiple column indexes in MySQL query
https://dev.mysql.com/doc/refman/8.0/en/create-index.html
I'm using below code to get posts by title.
protected function get_post_by_title($post_title, $output = OBJECT, $post_type = 'post' )
{
global $wpdb;
$post = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type= %s", $post_title, $post_type ));
if ( $post )
return get_page($post, $output);
return null;
}
Everything is working fine, except it will not find the posts having single quote in title. Consider below as $post_title.
This is a test's post
$wpdb->prepare will return query something like below.
This is a test\\\'s post
Which will return no result. Can anyone please help me on this ?
Thanks in advance
You should never compare with the real title. Wordpress offers you the possibility to create slugs without all those weird characters like " " or "'". Then you can compare them:
Use sanitize_title() to create a slug from your title, and then you can compare them.
I think this should fix the issue,
DOC: http://in1.php.net/manual/en/mysqli.real-escape-string.php
protected function get_post_by_title($post_title, $output = OBJECT, $post_type = 'post' )
{
global $wpdb;
$post_title = mysqli_real_escape_string($post_title); //escape special meaning
$post = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type= %s", $post_title, $post_type ));
if ( $post )
return get_page($post, $output);
return null;
}
edit:
That might not work, try this,
$post_title = addslashes($post_title);
Let me know which one works for you.
I have child categories (cities) which belongs to parent categories (countries). I get a list of categories (cities-countries) as below:
$categor = $wpdb->get_results("select * from $wpdb->terms c,$wpdb->term_taxonomy tt where tt.term_id=c.term_id and tt.taxonomy='hotelcategory' and c.name != 'Uncategorized' and c.name != 'Blog' $substr order by c.name");
for($i=0;$i<count($categor);$i++)
{
echo '"'.$categor[$i]->name.' - '.$categor[$i]->parent.'",';
}
I use the retrieved data in jquery autocomplete, and i can get the parent category id but not the name.
The problem is for example there are many cities named "Paris", so when i type in paris, i get like 8-9 cities with same name.(Picture1)
What i'd like to do is to have their parent category names beside the category.(Picture2)
http://s7.postimage.org/k85dhd4sr/catn.jpg
You just have the ID of the parent-term, so if you want the actual name of the term you have to fetch it. One way to do that is to simply join the term table again for the parent ID:
$categor = $wpdb->get_results( "select c.*,tt.*,pc.name as parent_name
from $wpdb->terms c,$wpdb->term_taxonomy tt,$wpdb->terms pc
where
tt.term_id=c.term_id and tt.parent=pc.term_id
and tt.taxonomy='hotelcategory' and c.name != 'Uncategorized'
and c.name != 'Blog' $substr order by c.name");
// I have optimized the loop a bit. If you really need the index you can leave
// it as it is. If you don't need the index I suggest you change that to a
// foreach loop
for($i=0,$n=count($categor);$i<$n;$i++)
{
echo '"'.$categor[$i]->name.' - '.$categor[$i]->parent_name.'",<br />';
}
An alternative solution without any SQL could look like that:
$excludes = array();
// build the "exclude" array. This step is necessary because
// get_terms expects the ID's of the terms to be excluded
foreach(array('Uncategorized', 'Blog') as $termName) {
$term = get_term_by('name', $termName, 'hotelcategory');
if($term) {
$excludes[] = $term->term_id;
}
}
$args = array(
'hide_empty' => false,
'exclude' => $excludes,
'name__like' => 'Paris', // replace this with your search term here
);
$categor = get_terms('hotelcategory', $args);
foreach($categor as $cat)
{
// look up the parent
$parent = get_term_by('id', $cat->parent, $cat->taxonomy);
echo '"'.$cat->name.' - '.($parent ? $parent->name : '-').'",<br />';
}
This solution is admittedly a bit more verbose, but you don't have to worry with SQL or the database layout.