been asked to help a friend display some custom data on a Wordpress site, easy I thought...
Have a table with customer data in. Idea a plugin to is to query the table based on current user id and spit it out as shortcodes so they can place the output where ever they like.
After much googling (I'm not a coder) I got something that worked! Problem is, even to my untrained eye, it looks like a bodge, repeating queries when there's clearly a more intelligent way of doing it.... Can someone clever please show me the way based on the this >> ?
<?php
Plugin Name: do stuff
Description: Do site specific stuff
function spend_data() {
global $wpdb;
global $current_user;
wp_get_current_user();
$userid = $current_user->ID;
$spend = $wpdb->get_var ( "SELECT spend FROM mytable WHERE the_id=$userid");
return $spend;
}
function detail_data() {
global $wpdb;
global $current_user;
wp_get_current_user();
$userid = $current_user->ID;
$detail = $wpdb->get_var ( "SELECT detail FROM mytable WHERE the_id=$userid");
return $programs;
}
add_shortcode('spend', 'spend_data');
add_shortcode('detail', 'detail_data');
/* Stop Adding Functions Below this Line */
I guess you could do a query for all fields at a hook that fires before the shortcodes and then store it all in $current_user. Don't forget to replace mytable with the correct tablename.
function marks_prepare_user_shortcodes () {
global $wpdb;
global $current_user;
$current_user = wp_get_current_user();
$userid = $current_user->ID;
$row = $wpdb->get_row( "SELECT * FROM mytable WHERE the_id=".$userid, ARRAY_A);
$current_user->marks_shortcodes = $row;
}
add_action( 'wp_head', 'marks_prepare_user_shortcodes');
And then your shortcodes change to
function spend_data() {
global $current_user;
$spend = $current_user->marks_shortcodes['spend'];
if (!is_null($spend))
return $spend;
}
function detail_data() {
global $current_user;
$detail = $current_user->marks_shortcodes['detail'];
if (!is_null($detail))
return $detail;
}
add_shortcode('spend', 'spend_data');
add_shortcode('detail', 'detail_data');
I'm not sure if wp_head is the correct /best action to pick here, you could give it a try. I figured it is called before all the shortcodes are. Code is untested.
Ps. As a sidenote, I believe your extra user data should actually be stored in the wp_usermeta table, instead of a separate table. You'd retrieve the fields with get_user_meta(): https://developer.wordpress.org/reference/functions/get_user_meta/
Update
Instead of the code block directly above, you could also use this:
function mikes_data_shortcode($atts) {
global $current_user;
$atts = array_change_key_case((array)$atts, CASE_LOWER);
// override default attributes with user attributes
$actual_atts = shortcode_atts([
'field' => 'YouDidntEnterAFieldNameAsAttribute',
], $atts);
$data = $current_user->marks_shortcodes[$actual_atts['field']];
if (!is_null($data))
return $data;
}
function mikes_shortcodes_init()
{
add_shortcode('mikes_data_shortcode', 'mikes_data_shortcode');
}
add_action('init', 'mikes_shortcodes_init');
Where you use shortcodes like this:
[mikes_data_shortcode field="spend"]
or
[mikes_data_shortcode field="detail"]
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/' );
}
}
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 );
}
}
public function action_save_post($post_id) {
global $wpdb;
$wooqty = $_POST['qty'];
if( !empty( $wooqty ) )
update_post_meta( $post_id, 'qty', esc_attr( $wooqty ) );
}
This will save the data from a Form field in Metabox in wordpess. I would like to use this variable $wooqty which has a value to another function.
public function action_woocommerce_add_order_item_meta($item_id, $values) {
global $wpdb;
$product_no = (int) $values['product_id'];
$qty_no = (int) $values['quantity'];
}
I would like to replace the variable $qty_no data to the $wooqty. my problem is how do i pass the variable $wooqty to this function so that i can replace the values of $qty_no.
Seems simple enough to me. You don't need to set a global, since it is already in Wordpress post meta data. Just call get_post_meta($product_no, 'qty', TRUE); within the function.
So, your new function will look like this:
public function action_woocommerce_add_order_item_meta($item_id, $values) {
global $wpdb;
$product_no = (int) $values['product_id'];
$qty_no = get_post_meta($product_no, 'qty', TRUE);
}
Not sure why you are globalizing $wpdb, since the function doesn't do any database operations using that variable. You should be fine with removing the global $wpdb; definition at the top of your function as well.
Furthermore, I would check $item_id variable and see if that is equal to $values['product_id'], and if it is, use that instead of refetching the product id from the $values array.
Hope I helped, if not be clearer in your question. Question seems a bit old, so you probably already got this figured out by now. But just in case you haven't.
so you can use the following syntax to set the global from within a function and then access it elsewhere in PHP.
function foo(){
$GLOBALS['foobar'] = 'somestring';
}
function bar(){
echo $GLOBALS['foobar'];
}
foo();
bar();
However, it's not often a good idea and there may be a better way to pass the variable to the functions. How about a third function that sets the variable locally that's called from within functions 1 and 2 for instance.
I'm using Woocommerce + the groups plugin on my main site to promote users to a 'Premium' group upon purchasing items which works great.
If a user on the main site then browses to the second site within my network, I can no longer check to see if they're within the 'Premium' group.
On my main site, I can use this code:
<?php
$user_id = get_current_user_id();
$group = Groups_Group::read_by_name( 'Premium' );
if ( Groups_User_Group::read( $user_id, $group->group_id ) ) {
?>
Premium content here!
<?php } ?>
But this does not work on the subsite. Is there anyway I can check to see if the user is in a group on my main site FROM a subsite?
I managed to achieve this using the following code:
<?php
$blog_id = 1; //set the blog id to the main site id
switch_to_blog( $blog_id );
$user_id = get_current_user_id();
$group = Groups_Group::read_by_name( 'Premium' );
if ( Groups_User_Group::read( $user_id, $group->group_id ) ) {
echo 'PREMIUM!!';
} else {
echo 'Not premium';
}
restore_current_blog();
?>
Probably not a definitive answer but this should lead to it at least.
Your current code is using a wordpress function to get the users id. This should work across the board and is therefore fine. The next variabe/method uses the class from the groups plugin which I presume is just not being pulled on the subsite.
$user_id = get_current_user_id();
$group = Groups_Group::read_by_name( 'Premium' );
Groups_User_Group::read( $user_id, $group->group_id )
From the look of the class files
$group = Groups_Group::read_by_name( 'Premium' );
This line simply does the method below
public static function read_by_name( $name ) {
global $wpdb;
$result = false;
$group_table = _groups_get_tablename( 'group' );
$group = $wpdb->get_row( $wpdb->prepare(
"SELECT * FROM $group_table WHERE name = %s",
$name
) );
if ( isset( $group->group_id ) ) {
$result = $group;
}
return $result;
}
The next line
Groups_User_Group::read( $user_id, $group->group_id )
Does this method
public static function read( $user_id, $group_id ) {
global $wpdb;
$result = false;
$user_group_table = _groups_get_tablename( 'user_group' );
$user_group = $wpdb->get_row( $wpdb->prepare(
"SELECT * FROM $user_group_table WHERE user_id = %d AND group_id = %d",
Groups_Utility::id( $user_id ),
Groups_Utility::id( $group_id )
) );
if ( $user_group !== null ) {
$result = $user_group;
}
return $result;
}
So all you are doing is pretty simple calls to the database. The issue being that due to the use of multisite there will be discrepancies with the table prefixes etc.
According to this part of the codex
http://codex.wordpress.org/Class_Reference/wpdb#Multi-Site_Variables
You can access other sites on the network much in the same way you can access the current site using $wpdb as a global variable. Therefore once you have ascertained the correct names of your tables, you should be able to modify these methods into simple functions that do the necessary work.
The first method doesn't even need to be used
$group = Groups_Group::read_by_name( 'Premium' );
As $group simply equals the id shown in the dashboard
Therefore the line can be coded statically ie
$group = 2;
The second method is purely checking if there is an entry of user_id 2 for example and group_id 2 say, in the group_users_group table. Here we have user 2 with both registered and premium group privileges. Shown here.
Therefore user 2 (again id can be seen in the dashboard in the users section) will qualify.
I hope this helps.
Hey guys so I am trying to access my database which is within wordpress to get some field values and I tried doing just straight up PDO style but it seems to not work so I went into wordpress codex and did their way to call things, but still no success!
CODE:
/***GET USERNAME***/
global $current_user;
get_currentuserinfo();
$accusername = $current_user->user_login ;
/******SEE IF FIRST TIME DISCOUNT CODE BEEN USED*******/
$wpdb->query(
$wpdb->prepare(
"
SELECT firsttime_discount
FROM $wpdb->users
WHERE user-login = %d
",
$accusername
)
);
/******CHECK IT******/
echo"working";
$wpdb->query('query');
echo"working";
if ($checkFTDiscount->firsttimediscount != 1){
$validFTDiscount = 1;
}
else{
$validFTDiscount = 0;
echo"wori";
}
So it's suppose to go in and see if the value for discount code is set to 1 in the wp_user area, and if not just set a value to 0.
Let me know if you have any other questions.
Before you can use $wpdb, you must declare global $wpdb;
global $current_user, $wpdb;
Should do the trick.