I am trying to manipulate an elementor query for all post types. I am using the Profile Builder plugin to restrict content. Their support sent me this function to check wether the post is restricted or not:
wppb_content_restriction_is_post_restricted( $post_id )
When I output the result of this function on the post it is either 1 or nothing. (1 being restricted).
The support also send me a custom addon-plugin of another plugin they have, where I'd only need to add the new function. When I do this and install it to my page, nothing changes though.
Here is the code of their mini plugin:
<?php
/*
Plugin Name: Paid Member Subscriptions - Exclude Restricted Posts From Query
Plugin URI: http://www.cozmoslabs.com
Description: Exclude restricted posts and pages from the main queries like blog, archive and taxonomy pages. It does not exclude them from custom queries.
Author: Cristian Antohe
Version: 1.0
Author URI: http://www.cozmoslabs.com
*/
add_action( 'pre_get_posts', 'pmsc_exclude_post_from_query' );
function pmsc_exclude_post_from_query( $query ) {
remove_action('pre_get_posts', 'pmsc_exclude_post_from_query');
if( !function_exists( 'pms_is_post_restricted' ) || is_admin() || is_single() )
return;
if( $query->is_main_query() || ( $query->is_search() && isset( $_GET['s'] ) ) ) {
$args = $query->query_vars;
$args['suppress_filters'] = true;
$args['posts_per_page'] = get_option( 'posts_per_page' );
$posts = get_posts($args);
$ids = wp_list_pluck( $posts, 'ID' );
$restricted_ids = array_filter($ids,'pms_is_post_restricted');
$query->set( 'post__not_in', $restricted_ids );
}
}
In case that a post is restricted, I want to exclude it from my query. So that the user only sees posts that can be accessed.
Now the challenge is to write a custom query that I can then put inside of the query ID of elementor's post widget to perform my custom query.
My query looks like this so far:
function prevent_restricted_posts_from_loading( $query ) {
if( !function_exists( 'wppb_content_restriction_is_post_restricted' ) || is_admin() || is_single() )
return;
if( $query->is_main_query() || ( $query->is_search() && isset( $_GET['s'] ) ) ) {
$args = $query->query_vars;
$posts = get_posts($args);
$ids = wp_list_pluck( $posts, 'ID' );
$restricted_ids = array_filter($ids,'wppb_content_restriction_is_post_restricted');
$query->set( 'post__not_in', $restricted_ids );
}
}
add_action( 'elementor/query/prevent_restricted_posts_from_loading', 'prevent_restricted_posts_from_loading' );
Related
I want to check if is single product page, but this has no effect on single product page:
if (! is_admin() && is_product() ) {
var_dump('is product'); // this has no effect in single product page
}
Is there a limitation to use is_product() in functions.php? How can I achieve this?
EDIT:
In order to avoid var_dump issues, this is the final code I'm trying. It try to add product type (simple/variable) to body class:
add_action( 'woocommerce_after_single_product', function () {
if (! is_admin() && is_product() ) {
add_filter( 'body_class', function( $classes ) {
global $post;
$product = wc_get_product( $post->ID );
$tipo = $product->get_type();
return array_merge( $classes, array( $tipo ) );
});
}
}, 100 );
You can not use this function directly without a hook since your functions.php file is included before every other file - mostly. To make this thing work you need to work with hooks every time like this:
add_action( 'template_redirect', 'template_redirect_action' );
function template_redirect_action() {
if ( ! is_admin() && is_product() ) {
add_filter( 'body_class', function ( $classes ) {
global $post;
$product = wc_get_product( $post->ID );
$tipo = $product->get_type();
return array_merge( $classes, array( $tipo ) );
} );
}
}
Visit a product page and check your body classes.
By using the template_redirect hook you can be sure it's executed on every page. Otherwise your check would not make any sense when using a product hook which only gets executed on product pages.
Tested an works.
I have a Custom Post Type called Book, and the link is: mywebsite.com/book/mybookname
I want to change this so that the link is mywebsite.com/mybookname.
I have added the following code to change the link and it works as expected:
function books_theme_remove_slug( $post_link, $post, $leavename ) {
if ( 'book' != $post->post_type || 'publish' != $post->post_status ) {
return $post_link;
}
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
return $post_link;
}
add_filter( 'post_type_link', 'books_theme_remove_slug', 10, 3 );
function books_theme_parse_request( $query ) {
if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
return;
}
if ( ! empty( $query->query['name'] ) ) {
$query->set( 'post_type', array( 'post', 'book', 'page' ) );
}
}
add_action( 'pre_get_posts', 'books_theme_parse_request' );
The problem is that the old link(mywebsite.com/book/mybookname) is still working. I'd like to make that link go to a 404 page without breaking the current links.
I tried the following but it breaks everything:
function books_theme_parse_request( $query ) {
if(isset($query->query['post_type']) && $query->query['post_type'] == 'book'){
global $wp_query;
$wp_query->set_404();
status_header( 404 );
get_template_part( 404 ); exit();
}
if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
return;
}
if ( ! empty( $query->query['name'] ) ) {
$query->set( 'post_type', array( 'post', 'book', 'page' ) );
}
}
add_action( 'pre_get_posts', 'books_theme_parse_request' );
How do I delete old url?
This shouldn't be happening in the first place, so you shouldn't try to fix it programmatically - instead you should fix it at source. Try to identify the cause and fix it. Otherwise you could introduce other issues down the line.
Some possible solutions, depending on the cause:
Flush your Rewrite Cache
Wordpress doesn't write redirections into the .htaccess, it uses rewrite rules to parse the url and find a match for the redirection.
It means that if you don't refresh your rewrite rules, the old links still work.
Ref: SarahCoding's answer to 'Remove Old Permalinks?'
How to do it: Re-saving your permalinks will flush the rewrite rules, but there if that doesn't work there are Three Ways to Flush the Rewrite Cache in WordPress
Clear your Cache
If you have an Caching plugins installed, they will need to be cleared. Some security plugins also use caching e.g. Securi. It could also just be cached in your browser.
How to do it: See How to Clear Your Cache in WordPress
Delete old WP permalinks
When you update a slug, the old permalinks are still stored in the database. This could cause issues if you want to use a slug that you had previously used for example.
How to do it: The old permalinks are stored in the table postmeta with the meta_key of _wp_old_slug. To clear all of the old slugs, run this query in your WP database:
DELETE FROM wp_postmeta WHERE meta_key = '_wp_old_slug';
Ref Mark Dave Tumanda's answer to 'Remove Old Permalinks?'
Check Redirection Plugins
If you are using any redirection plugins, check the redirection rules in case there is anything there that is clashing with your new urls.
Based on your comment all you need then is to know if the url contains /book ... see below for the added snip-it:
function books_theme_parse_request( $query ) {
global $wp;
$current_url = home_url( $wp->request );
if (strpos($current_url, "/book" == false)) { return; }
if(isset($query->query['post_type']) && $query->query['post_type'] == 'book'){
global $wp_query;
$wp_query->set_404();
status_header( 404 );
get_template_part( 404 ); exit();
}
if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
return;
}
if ( ! empty( $query->query['name'] ) ) {
$query->set( 'post_type', array( 'post', 'book', 'page' ) );
}
}
add_action( 'pre_get_posts', 'books_theme_parse_request' );
As people have mentioned reference
A Warning About Admin Usage
This filter can also be used to affect admin screen queries. Be sure to check if your modification is affecting your post edit screens. For example, just checking is_main_query() and is_post_type_archive('movie') will also change the query for the edit.php?post_type=movie admin screen, unless you also check for !is_admin()
In WordPress, I'm using Jetpack's portfolio custom content type, but would like to change the slug from "portfolio" to "examples". I found this example on how to do it (http://www.markwarddesign.com/2014/02/remove-custom-post-type-slug-permalink/) and this plugin (https://github.com/devinsays/no-slug-portfolio-post-types). Both as based on a post on Wordpress VIP that was linked to by the Jetpack team and now has a dead link.
Here is my code, for some reason it is not working. I have refreshed my permalinks by going to Settings > Permalinks and hitting save changes.
/**
* Remove the slug from custom post type permalinks.
*/
function vipx_remove_cpt_slug( $post_link, $post, $leavename ) {
if ( ! in_array( $post->post_type, array( 'portfolio' ) ) || 'publish' != $post->post_status )
return $post_link;
$post_link = str_replace( '/' . $post->post_type . '/', '/examples', $post_link );
return $post_link;
}
add_filter( 'post_type_link', 'vipx_remove_cpt_slug', 10, 3 );
/**
* Some hackery to have WordPress match postname to any of our public post types
* All of our public post types can have /post-name/ as the slug, so they better be unique across all posts
* Typically core only accounts for posts and pages where the slug is /post-name/
*/
function vipx_parse_request_tricksy( $query ) {
// Only noop the main query
if ( ! $query->is_main_query() )
return;
// Only noop our very specific rewrite rule match
if ( 2 != count( $query->query )
|| ! isset( $query->query['page'] ) )
return;
// 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
if ( ! empty( $query->query['name'] ) )
$query->set( 'post_type', array( 'post', 'portfolio', 'page' ) );
}
add_action( 'pre_get_posts', 'vipx_parse_request_tricksy' );
Any ideas how to get this code working again?
function na_remove_slug($post_link, $post, $leavename) {
if ('POST TYPE SLUG' != $post - > post_type || 'publish' != $post - > post_status) {
return $post_link;
}
$post_link = str_replace('/'.$post - > post_type.
'/', '/', $post_link);
return $post_link;
}
add_filter('post_type_link', 'na_remove_slug', 10, 3);
function na_parse_request($query) {
if (!$query - > is_main_query() || 2 != count($query - > query) || !isset($query - > query['page'])) {
return;
}
if (!empty($query - > query['name'])) {
$query - > set('post_type', array('post', 'POST TYPE SLUG', 'page'));
}
}
add_action('pre_get_posts', 'na_parse_request');
In the settings on my WordPress website, I need Post Permalink looks like "zzzz.com/sample-post/". My website however uses custom posts so I downloaded the plugin 'Remove slug from custom post type' but all posts are still appearing in the format "zzzz.com/format/category/sample-post/". I want the 'format/category' part removed from the URL. Just wondering if there is another similar plugin to the above that would remove this or if there is some code I need to manually enter?
First Disable your plugin you installed !!
Set Custom Structure: /%postname%/
Set Category base: . (dot not /)
Try this before use change your_post_type to your post type
function firefog_remove_cpt_slug( $post_link, $post, $leavename ) {
if ( ! in_array( $post->post_type, array( 'your_post_type' ) ) || 'publish' != $post->post_status )
return $post_link;
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
return $post_link;
}
add_filter( 'post_type_link', 'firefog_remove_cpt_slug', 10, 3 );
function firefog_parse_request_tricksy( $query ) {
// Only noop the main query
if ( ! $query->is_main_query() )
return;
// Only noop our very specific rewrite rule match
if ( 2 != count( $query->query )
|| ! isset( $query->query['page'] ) )
return;
// 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
if ( ! empty( $query->query['name'] ) )
$query->set( 'post_type', array( 'post', 'your_post_type', 'page' ) );
}
add_action( 'pre_get_posts', 'firefog_parse_request_tricksy' );
In wp-admin go to the following menu: Settings -> Permalinks. You're now on Permalinks page, select Post name option. You can also play around with the Custom Structure option.
I have a search form containing select fields. The first two are populated with custom taxonomies and the third with the default wordpress categories. When using the first two only for a query it works fine. When I use the third( the categories), the search query just ignores the field and comes up with the same results. How can I fix this?
I've used these functions to make them work:
function ftiaxnospiti_filter_search($query) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_search ) {
$query->set( 'post_type', array('post', 'seller') );
}
return $query;
};
add_action('pre_get_posts', 'ftiaxnospiti_filter_search');
function ftiaxnospiti_add_custom_types_to_tax( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( is_category() || is_tag() && empty( $query->query_vars['suppress_filters'] ) ) {
// Get all your post types
$post_types = array( 'post', 'seller' );
$query->set( 'post_type', $post_types );
}
return $query;
}
add_action( 'pre_get_posts', 'ftiaxnospiti_add_custom_types_to_tax' );