[Resolved] How to show in CRED Parent Selector only posts of logged in user?
This thread is resolved. Here is a description of the problem and solution.
Problem:
A CRED form includes a selector to choose a related parent post. This field lists *all* such parent posts. Client wants it to only show parent posts authored by the current user (i.e. their own parent posts).
Solution:
This thread describes a custom code solution, but this is a common enough request and this feature will be added natively in an upcoming release and it is recommended to wait for that.
This support ticket is created 6 years, 11 months ago. There's a good chance that you are reading advice that it now obsolete.
This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.
Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.
There is no CRED API available to modify the list of parents in the parent post selector, so we need to use the standard WordPress pre_get_posts hook to modify the query that retrieves the list of parents.
The problem with the pre_get_posts hook is that it is fired for all queries, so we need to narrow this down to the page where the CRED form to publish child posts is inserted, and to the query which gets posts of the parent post type.
Edit the code below for the page and the parent post type and then add it to your theme's functions.php or using a plugin such as Code Snippets:
/**
* Limit CRED parent post selector to own posts
*/
function filter_parent_posts( $query ){
$target_page = 102; // ID of page with CRED form, or string of page slug
$parent_post_type = "thing"; // slug of parent post type
if ( is_page( $target_page ) && $query->get( 'post_type') == $parent_post_type ) {
$current_user = get_current_user_id();
$query->set( 'author', $current_user );
}
}
add_action( 'pre_get_posts', 'filter_parent_posts' );
Hi, thank you for the function, but its not working for me:
/**
* Limit CRED parent post selector to own posts
*/
function filter_parent_posts( $query ){
$target_page = 981; // ID of page with CRED form, or string of page slug
$parent_post_type = "zazitek"; // slug of parent post type
if ( is_page( $target_page ) && $query->get( 'post_type') == $parent_post_type ) {
$current_user = get_current_user_id();
$query->set( 'author', $current_user );
}
}
add_action( 'pre_get_posts', 'filter_parent_posts' );
981 is the ID of the page, where is CRED form inserted and "zazitek" is the parent slug. But I still see all the parent posts created by all the users.
OK. I tested it locally before posting it, so I expect it should work.
Can I get access to your site to see myself?
It would make it easier if you remove the code from your theme's functions.php file and I will add it again using the Code Snippets plugin where I can also use a debug plugin to check exactly what is happening.
Your next reply is private. Be sure you have a current backup.
Firstly, sorry for the delay getting back to you over the holidays.
I visited your site and after a little testing realise the problem is with the select2 library which is used for the parent select field when there are more than 15 parent posts that can be selected, that is interfering with the code I suggested.
When I temporarily moved a few of your posts to the trash so that there were no more than 15 then I found the code worked as expected.
I'll need to check with colleagues about modifying my code to handle this scenario and I'll get back to you with an update as soon as I can.
hope you enjoyed the holidays 🙂 I also took some rest...
And thank you for your reply. It works OK now. But can I make feature request for not disabling select2 when using filtering parent posts? I need to use select2 in the future, because of the growth number of posts. Thanks.
You think that even when you are only displaying parent posts of the current user there will still be a large number, i.e. more than 15?
If that's the case, let's leave this open for a while. When I have time I will take another look and see if I can find the query involved when select2 is used to filter that as well/instead.
The way CRED edit forms normally work is that, having inserted the edit form into a holding-template and adding an edit link to the template for the post type, the edit form will be displayed at the URL of post being edited with a URL parameter added to identify the content template of layout which holds the edit form.
If that is how you have this set up then you can modify the code I supplied earlier like so:
/**
* Limit CRED parent post selector to own posts
*/
function filter_parent_posts( $query ){
$target_page = 102; // ID of page with CRED form, or string of page slug
$parent_post_type = "thing"; // slug of parent post type
$child_post_type = "thingy"; // slug of child post type
if ( ( is_page( $target_page ) || is_singular( $child_post_type ) ) && $query->get( 'post_type') == $parent_post_type ) {
$current_user = get_current_user_id();
$query->set( 'author', $current_user );
}
}
add_action( 'pre_get_posts', 'filter_parent_posts' );
Note you now also need to specify the slug of the child post type.
I haven't re-worked this to be able to continue using select2 yet, let's leave this open.
I think I have a solution for you where you can continue with select2.
So, remove the attribute that disables select2.
Then update your code so that the if statement includes a test for ajax, as shown here:
/**
* Limit CRED parent post selector to own posts
*/
function filter_parent_posts( $query ){
$target_page = 102; // ID of page with CRED form, or string of page slug
$parent_post_type = "thing"; // slug of parent post type
$child_post_type = "thingy"; // slug of child post type
if ( ( is_page( $target_page ) || is_singular( $child_post_type ) || ( defined('DOING_AJAX') && DOING_AJAX ) ) && $query->get( 'post_type') == $parent_post_type ) {
$current_user = get_current_user_id();
$query->set( 'author', $current_user );
}
}
add_action( 'pre_get_posts', 'filter_parent_posts' );
We now test for 3 circumstances:
1. if we are on the page where the CRED publish form is included;
2. if we are showing the CRED edit form on a single post; or
3. if we are querying the parent posts via an ajax request, which is how the select2 library obtains the filtered list.
I tested it locally and it seems to work, if you could verify on your own site.
Hi Nigel, I´ve tested it and I can confirm that it works. Thank you so much for doing this 🙂
And is it possible for some post types to use select2 after filtering? I mean that the function will filter only user´s parent posts and by their count (bellow 15? or how much is it? and above) will use select2 or not. So select2 will not be used for example for 3 posts, when it is not neccessary.
function filter_parent_varianta( $query ){
$target_page = 981; // ID of page with CRED form, or string of page slug
$parent_post_type = "zazitek"; // slug of parent post type
$child_post_type = "varianta-zazitku"; // slug of child post type
if ( ( is_page( $target_page ) || is_singular( $child_post_type ) || ( defined('DOING_AJAX') && DOING_AJAX ) ) && $query->get( 'post_type') == $parent_post_type ) {
$current_user = get_current_user_id();
$query->set( 'author', $current_user );
}
}
add_action( 'pre_get_posts', 'filter_parent_varianta' );
causes error on homepage and non admin users could not upload images (they get error):
Notice: Trying to get property of non-object in /data/web/virtuals/.../wp-includes/class-wp-query.php on line 3732
Notice: Trying to get property of non-object in /data/web/virtuals/.../wp-includes/class-wp-query.php on line 3863