WordPress - Only Display Posts That Are Associated To Logged In User - php

In my WordPress Site, I have custom post types setup for Tanks, Locations, and Users using the PODS plugin. Currently I have some PHP that allows me to only show the logged in user a post, if they are listed as the author of it. Which is a good start, but not exactly how I need it to work. Because of the way WordPress stores their Author field, I am only able to have one User associated per Tank/Location instead of many. My question is, how would I go about making it so that WordPress will check to see what Tanks/Locations the current logged in user has associated to them, and only display those? In both the Tanks and Locations PODS, I have already setup a relationship field to my Users POD which allows me to assign each Tank/Location with as many users as necessary. All I need now is to figure out how display that information. If it makes any difference, the storage type for all my PODS is Table Based.

So in case anyone has the same question I did, here is how I ended up solving my issue. The variable 'users.ID' is referring to the relationship field I had in each of my Locations/Tanks.
if(!current_user_can('administrator')){
add_shortcode( 'pods_by_current_user_cpt', 'pods_by_current_user_cpt' );
function pods_by_current_user_cpt( $atts, $content = null ) {
$current_user = wp_get_current_user();
$user_id = $current_user->ID;
$atts['where'] = 'users.ID = ' . (int) $user_id;
return pods_shortcode( $atts, $content );
}
}
else{
add_shortcode( 'pods_by_current_user_cpt', 'pods_by_current_user_cpt' );
function pods_by_current_user_cpt( $atts, $content = null ) {
$current_user = wp_get_current_user();
$user_id = $current_user->ID;
return pods_shortcode( $atts, $content );
}
}

Related

Woocommerce - Include custom user meta in order 'filter by registered customer' Ajax search

I am trying to include a users custom meta named 'sageaccountnumber' within the 'filter by registered customer' section of the WooCommerce orders list as shown below:
I already have the custom meta field named 'sageaccountnumber' working with the following PHP code:
add_action( 'personal_options_update', 'sab_save_sageaccount_user_profile_fields' );
add_action( 'edit_user_profile_update', 'sab_save_sageaccount_user_profile_fields' );
function sab_save_sageaccount_user_profile_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) ) {
return false;
}
update_user_meta( $user_id, 'sageaccountnumber', $_POST['sageaccountnumber'] );
}
When searching for a registered customer I would like to include the user meta 'sageaccountnumber' within the search and display matching results.
I understand this uses AJAX within the file class-wc-ajax.php. This is the function in question: https://wp-kama.com/plugin/woocommerce/function/WC_AJAX::json_search_customers
I do not know alot about AJAX and I have not been able to find a way to include a custom user meta value in this search. I have not found anyone else doing this.
Any guidance or suggestions would be much appreciated? Thank you.
After getting lost with trying to understand the class-wc-ajax.php file, I completely missed a more obvious and simple solution. Here is the code I am using which works perfectly. I hope this helps others looking for similar solution.
This filter-hook allows you to add an additional meta_query to the existing search parameters. This will also allow your custom user meta to display in AJAX searches from the Orders & Subscriptions pages.
If you have a custom meta field setup for your users, simply change 'sageaccountnumber' to the name of your meta and it will be included in the AJAX search results.
add_filter ('woocommerce_customer_search_customers', 'sab_sageaccount_order_subscription_search', 10, 4);
function sab_sageaccount_order_subscription_search ($filter, $term, $limit, $type){
if ($type == 'meta_query'){ $filter['meta_query'][] = array('key' => 'sageaccountnumber', 'value' => $term, 'compare' => 'LIKE');
}
return $filter;
}
If you need to include the custom meta field in the normal users search, you can use the following code, again changing 'sageaccountnumber' to your custom meta name.
add_action( 'pre_user_query', 'sab_sageaccount_user_search' );
function sab_sageaccount_user_search( $query ) {
global $wpdb;
global $pagenow;
if (is_admin() && 'users.php' == $pagenow) {
if( empty($_REQUEST['s']) ){return;}
$query->query_fields = 'DISTINCT '.$query->query_fields;
$query->query_from .= ' LEFT JOIN '.$wpdb->usermeta.' ON '.$wpdb->usermeta.'.user_id = '.$wpdb->users.'.ID';
$query->query_where = "WHERE 1=1 AND (user_login LIKE '%".$_REQUEST['s']."%' OR ID = '".$_REQUEST['s']."' OR (meta_value LIKE '%".$_REQUEST['s']."%' AND meta_key = 'sageaccountnumber'))";
}
return $query;
}

Sorting WP user columns by non-meta value (PHP)

UPDATE: I've read a few more posts about similar issues and the consensus seemed to be that filtering by the actual data in the user admin table isn't an option, and that sorting needs to be done via adding the data to postmeta if it isn't there already. Hoping this isn't the case, but it's starting to sound like it.
I have added a handful of custom columns to the user admin table. Some of the columns get their values from custom user meta, but some do not. I've been able to make the columns that source their content from meta just fine with
if ( 'member_number' == $query->get( 'orderby' )) {
$query->set( 'orderby', 'meta_value' );
$query->set( 'meta_key', 'number' );
}
...but the column I'm unable to sort a column that gets its values by cross-referencing the user's info against entries from a Gravity Form, sorting the GF entries by date, and outputting the position of the GF entry that was matched to the user.
It might be simpler to just say that I want to display a "wait-list position" that can change frequently and would require updating postmeta of ~100 posts on a regular basis to accurately display the users position in the queue. Not thinking that was practical to do, the best I could come up with is to reference the user's email address against the list of those on the wait-list.
If it helps, the code that references my custom function and applies it to my column is:
if ('waitlist_pos' == $column_name){
$waitlistNumber = get_waitlist_position( $user_id );
$value = $waitlistNumber;
return $value;
}
...and my function to get those values is:
function get_waitlist_position( $user_id ){
$waitlistUser = get_user_by( 'id', $user_id);
if ( empty( $waitlistUser ) ) {
return;
} else {
$waitlistUserEmail = $waitlistUser->user_email;
$form_id = '18';
$entries = GFAPI::get_entries($form_id);
usort($entries, make_comparer('date_created'));
$emails = array_column( $entries, '3' );
$waitlistposition = array_search( $waitlistUserEmail, $emails );
if ( !in_array( $waitlistUserEmail, $emails, true )) {
return;
}
}
return $waitlistposition +1;
}
Only a few percent of users are on the waitlist.
I've managed to get the custom column created and to display the appropriate wait-list position of the user in the user admin table, but every guide I've found on making the column's content sortable either describe default WordPress sortable criteria, or by a meta query like I've done for other columns in the code above.
Any thoughts on simply sorting these columns by their value if the value does not actually exist as user meta or user data? The values are simple integers, starting from 1 and going to 100 or so.
I've tried leaving the created column alone, and although it does have the arrows indicating it is sort-able, clicking it does not change the order of the entries, and trying to force a query like the WP_Query used earlier, of course, results in a blank table once I try to sort.
Thanks for reading the long question about my simple problem! Also happy to hear if making the wait-list position into some sort of dynamic post-meta may make more sense.

Get the author ID - Wordpress, WP Job Manager

I am using Wp Job Manager plugin with job_listing as the post_type
On single job listing page, I am trying to show the list of all job listing posted by the same user > author.
I can't figure out how to correctly get the ID of the author of the post
I've been trying with 'author' => get_current_user_id() query, but that's not it.
This only fetches the ID of the current user, which is me as I'm logged in, and shows all my listings.
How can I get the the author of the post that I'm currently viewing?
This is what I'm currently trying, but it will only show my own listings as a logged in user:
function my_query_args($query_args, $grid_name) {
if ($grid_name == 'author-listings') {
global $current_user;
get_currentuserinfo();
// all query parameters can be modified (https://codex.wordpress.org/Class_Reference/WP_Query)
$query_args['author'] = $current_user->ID;
}
return $query_args;
}
add_filter('tg_wp_query_args', 'my_query_args', 10, 2);
global $post;
$author_id = $post->post_author;
If $post is undefined, are you really on a single page or is the setup you have working its' own magic?
To get the author ID, try
https://developer.wordpress.org/reference/functions/get_the_author_meta/
To simply display it, try https://developer.wordpress.org/reference/functions/the_author_meta/
So you could try
$query_args['author'] = $get_the_author_meta('ID');

Can I create a function for auto-enrolling WP Roles in a Learndash course?

Currently, LearnDash has a function (to be added to functions.php) that allows you to auto enroll a specific user in a course. I was wondering if a simple function could be added to my theme's function file and change this from user_id to a user ROLE? That way every user in that role is enrolled.
Here is the starting point: (found in the dev section on Learndash)
//* To enroll user to course:
ld_update_course_access($user_id, $course_id, $remove = false);
I have tried this:
//* Add users to course by role
ld_update_course_access($role_name = Subscriber, $course_id = 949, $remove = false);
On the "edit course" page editor I now see "1,0,12,Subscriber" inside the "course access list" but it doesn't actually work. Obviously, that access list is working with users only.
My thought process is creating a function that will:
1) Get user IDs from user role "My-Custom-Role"
2) Return IDs and update course access.
Is something like this possible?
Yep, totally possible. The get_users() function allows you to get a list of users by role. See: https://codex.wordpress.org/Function_Reference/get_users
For example:
$users = get_users( [ 'role__in' => [ 'subscriber', 'author' ] ] );
foreach ( $users as $user ) {
ld_update_course_access( $user->ID, 949, false );
}
I worked with the development team and came up with a different although incomplete solution, so I've marked Linnea's as correct, because it works as asked in the question. This solution goes through their access hook sfwd_lms_has_access, however the "course list" never gets updated so a user is not officially "enrolled" until they start the course. By this I mean, you wont see them enrolled in the course on their profile, but if they start a lesson, it all of a sudden shows up! Thought it might help to post here in case it may help anyone as a starting point.
add_filter( 'sfwd_lms_has_access', function( $return, $post_id, $user_id ) {
if ( empty( $user_id ) ) {
$user_id = get_current_user_id();
}
if(empty($user_id))
return $return;
$course_id = learndash_get_course_id( $post_id );
$allowed_course_ids = array( 949, 1135 );
if( !in_array($course_id, $allowed_course_ids))
return $return;
if(user_can($user_id, "3a_textbook"))
return true;
if(user_can($user_id, "subscriber"))
return true;
return $return;
}, 10, 3 );

Restrict certain tags from non-admins in Wordpress

I run a multiple author website. I want to restrict a few tags from being selected by my authors.
The only options that I found so far was techniques to replace the free tag text field with a list (similar to the category list). This is not a solution for me as I will need my authors to be able to create new tags.
Surely there must be a way to restrict specific tags from non-admins? Do you know how? Any brainstorming or proper solutions are welcome.
I think the ideal solution would be to conditionally filter the taxonomy query used in post_tags_meta_box as it ajaxes its suggestions, and maybe even providing some error-handling if someone tried to manually type the tag you don't want them to use, but I'm not aware of a filter that could aid in pulling that off.
Expanding on Giordano's suggestion and referencing this other question, you could use something like this in functions.php
add_action('save_post', 'remove_tags_function', 10, 1); //whenever a post is saved, run the below function
function remove_tags_function( $post_id ){
if(!current_user_can('manage_options')){ // if the logged in user cannot manage options (only admin can)
$post_tags = wp_get_post_terms( $post_id, 'post_tag', array( 'fields'=>'names' ) ); //grab all assigned post tags
$pos = array_search( 'tag-to-be-deleted', $post_tags ); //check for the prohibited tag
if( false !== $pos ) { //if found
unset( $post_tags[$pos] ); //unset the tag
wp_set_post_terms ($post_id, $post_tags, 'post_tag'); //override the posts tags with all prior tags, excluding the tag we just unset
}
}//end if. If the current user CAN manage options, the above lines will be skipped, and the tag will remain
}
Non-admin users will still be able to type in and add tag-to-be-deleted, but it will not stick to the post. Once saved, the tag will be stripped. If the user is really dedicated, they could spell it differently, or, as you saw, change the capitalization, but whatever they do it wont technically be the same tag, and you will be able to keep it pure for whatever theme purpose you need. I can't imagine a situation in which a user without admin capabilities could add the forbidden tag, but I know better than to never say never.
If you want to allow certain non-admin users to assign the forbidden tag to a post, you'll have to revise the parameter passed into line 4 if(!current_user_can('...'){. For information on other capabilities you can pass to this conditional statement, check the Wordpress documentation of Roles & Capabilities. It's much easier to check for a capability than a role, so pick a logical capability that is restricted to the levels of user that you wish to be exempt from the tag deletion.
You could probably create a simple plugin that deletes the specified tags from the post when saved if the author is not you.
You can call your function when the post is saved with add_action('save_post', 'remove_tags_function',10,2);
Then you would create a function like
function remove_tags_function($postID, $post){
if($parent_id = wp_is_post_revision($postID))
{
$postID = $parent_id;
$post = get_post($postID);
}
if($post->post_author != 'YOUR AUTHOR NUMBER'){
$tags = wp_get_post_tags( $post_id );
$i = 0;
foreach($tags as $tag){
if(in_array("TAG NAME", $tag)) unset $tags[$i];
$i++;
}
}}
I have not tested it, but logically it would work.
EDIT:
That's not gonna work!
Try to put the following in a .php file in your plugin folder. Not tested for now, but it looks fine.
<?php
add_action('save_post', 'remove_tags_function',10,2);
function remove_tags_function($postID, $post){
if($parent_id = wp_is_post_revision($postID))
{
$postID = $parent_id;
$post = get_post($postID);
}
$user_info = $user_info = get_userdata($post->post_author);
if($user_info->user_level != 10){ // 10 = admin
untag_post($postID, array('TAGS', ... ));
}}
function untag_post($post_ids, $tags) {
global $wpdb;
if(! is_array($post_ids) ) {
$post_ids = array($post_ids);
}
if(! is_array($tags) ) {
$tags = array($tags);
}
foreach($post_ids as $post_id) {
$terms = wp_get_object_terms($post_id, 'post_tag');
$newterms = array();
foreach($terms as $term) {
if ( !in_array($term->name,$tags) ) { //$term will be a wordpress Term object.
$newterms[] = $term;
}
}
wp_set_object_terms($post_id, $newterms, 'post_tag', FALSE);
}
} // I got this from http://wordpress.stackexchange.com/questions/49248/remove-tags-from-posts-in-php/49256#49256
?>
based on crowjonah's wonderful answer, here is a function to remove multiple tags:
<?php
/** block non-admins from using specific post tags **/
function remove_tags_function( $post_id ){
if(!current_user_can('manage_options')){ // if the logged in user cannot manage options (only admin can)
$post_tags = wp_get_post_terms( $post_id, 'post_tag', array( 'fields'=>'names' ) ); //grab all assigned post tags
$pos = array_intersect( array('TAG1', 'TAG2', 'TAG3', 'ETC...'), $post_tags ); //check for the prohibited tag
if( !empty($pos) ) { //if found
$post_tags = array_diff($post_tags, $pos);
wp_set_post_terms ($post_id, $post_tags, 'post_tag'); //override the posts tags with all prior tags, excluding the tag we just unset
}
}//end if. If the current user CAN manage options, the above lines will be skipped, and the tag will remain
}
add_action('save_post', 'remove_tags_function', 10, 1); //whenever a post is saved, run the below function
?>
Itamar

Categories