0

When a user logs in I need to change an integer in a table on my db. For some reason the variables in the wp_user object are empty and nothing is being updated in the table. If I echo the query to a test page everything shows up correctly. Here's my exact code:

function mv_update_notification_data() {
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
    $current_user = wp_get_current_user();
    $user_id = $current_user->ID;
    $user_email = $current_user->user_email;
    $user_facility = get_user_meta( $user_id, 'user_facility',  true );
    $username = $current_user->user_login;

    if ( $username == $user_facility . 'DOC' ){
        $conn->query("UPDATE db SET doc_notified = 1 WHERE facility = '$user_facility'");
    }
}
add_action('wp_login', 'mv_update_notification_data');

If a user logs in and has a username of "testDOC" and the $user_facility is set to "test" for that user, the doc_notified column in the table should change to 1, but it's not.

The query fires if I don't nest it in the condition.

Eric Brockman
  • 824
  • 2
  • 10
  • 37

1 Answers1

0

Is there any particular reason you are creating your own mysqli connection and handler? Since you're using WordPress, you have access to the $wpdb class, which is significantly easier to use with less setup and without having to worry about about sanitizing values, etc. (unless you use one of the methods that runs a strict SQL query, at which point you'll want to use $wpdb::prepare())

If you NEED to use your own mysqli connection, feel free to replace the $wpdb->update function with your query below - but as @Dharman said, you need to use paramaterized prepared statements, otherwise you are open to SQL Injections.

That said, the issue is that the wp_login hook isn't fired late enough to have proper access to the wp_get_current_user() function.

If you look at the Docs for the wp_login hook, you'll see it has 2 arguments, $user_login and $user, these give you acces to the Username and WP_User object respectively.

In order to get those arguments to be available in the scope if your function, you need to tell that hook how many arguments to accept when you call add_action(). The default is 1.

This code below should work once you change your table name. You'll note that I'm using the $wpdb::update() method. This method takes care of calling $wpdb::prepare() for you, so you shouldn't need to worry about sanitizing that value anymore - but it's never a bad idea to make sure the data you're checking is in the format that you're expecting!. I didn't include anything like that, but you can run that value through some of WP's Sanitization/Escaping functions and/or PHP's filter_var if you wish.

add_action( 'wp_login', 'mv_update_notification_data', 99, 2 ); // Later priority, and pass 2 args)
function mv_update_notification_data( $user_login, $user ){
    global $wpdb; // Give this function access to the `$wpdb` class

    $user_facility = get_user_meta( $user->ID, 'user_facility', true );

    if( $user_login == $user_facility . 'DOC' ){
        $result = $wpdb->update(
            $YOUR_TABLE_NAME,
            array(
                'doc_notified' => 1
            ),
            array(
                'facility' => $user_facility
            ),
            array(
                '%d'
            ),
            array(
                '%s'
            )
        );

        // Do something with `$result` (returns: [int|false])
    }
}

EDIT:

If (for some reason) you wanted to use a strict query instead of $wpdb->update(), you can make use of the $wpdb::query() method. For simple inserts/updates, the built in static functions are usually enough, but for the sake of seeing how $wpdb deals with SQL queries, you can replace the whole $wpdb->update(); function above with the following:

$sql = "UPDATE db SET doc_notified = 1 WHERE facility = %s";
$args = array( $user_facility );

$result = $wpdb->query( $wpdb->prepare( $sql, $args ) );
Xhynk
  • 13,513
  • 8
  • 32
  • 69