For Want of an API . . .

Untitled

We wanted to be able to know whether people signing up for Ram Pages were faculty or not but didn’t want to add fields for them to fill out. VCU has an online phonebook with faculty emails in it but there didn’t appear to be a way to hook into an API. But you can provision the site with search items via the URL like so https://phonebook.vcu.edu/?Qname=woodwardtw%40vcu.edu.

Since I knew that PHP can grab a website (file_get_contents) and parse out the text in various ways (preg_match) it seemed like we could automate this.

When the phonebook site fails to find a matching email it returns some text that says ‘No matches.’ That’s what I decided to look for.

If you look at the comments below, each line of the code is broken down and pretty much (over) explains what it does.

function user_status ($user){
    $email = $user->user_email; //get the user's email
    $user_id = $user->ID; //get the user's ID
    $url_email = urlencode($email); //make it pretty so it behaves in the URL
    $url = 'https://phonebook.vcu.edu/?Qname=' . $url_email . '&Qdepartment=*'; // go to the phone book page and search
    $site = file_get_contents($url); //get the results
    $fail = preg_match('/No matches/', $site, $matches); //look at the page and see if it says no matches
    if ($fail === 0) {
        $status = 'faculty';
        add_user_meta( $user_id, 'user_vcu_status',  $status, true ); //if the search = 0 then they are faculty & add that to user meta
    } else {
        $status = 'student';
        add_user_meta( $user_id, 'user_vcu_status', $status, true ); //else make them a student        
    }
}

add_action ('wpmu_new_user', 'user_status', 10, 1); //hook this action (user_status) to the new user creation on multisite

Update

Here’s a better version using curl and displaying the data in the user profile so you can see if you’re crazy or not. It also checks for the metadata field and updates or creates it as needed.

//write to user profile if user is faculty

function user_status ($user){
    //differentiates between new user ID and edit profile user object so I don't have to write two functions
    if (is_numeric($user)){
        $user_id = $user;
        $user_info = get_userdata($user_id);
        $email = $user_info->user_email;
    } else {
        $email = $user->user_email;
        $user_id = $user->ID;
    }
    $url_email = urlencode($email);
    $url = 'https://phonebook.vcu.edu/?Qname=' . $url_email . '&Qdepartment=*';
    
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 

    //return the transfer as a string 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

    // $output contains the output string 
    $output = curl_exec($ch);
    $fail = preg_match('/No matches/', $output, $matches);
    $user = get_user_meta($user_id);
    $exists = get_user_meta($user_id, 'user_vcu_status');
    if ($fail == 0) {
        $status = 'faculty';
        if ($exists){
            update_user_meta( $user_id, 'user_vcu_status',  $status );
        } else {
            add_user_meta( $user_id, 'user_vcu_status',  $status, true );
        }
    } else {
        $status = 'student';
       if ($exists){
            update_user_meta( $user_id, 'user_vcu_status',  $status );
        } else {
            add_user_meta( $user_id, 'user_vcu_status',  $status, true );
        }      
    }
    curl_close($ch);      
}


add_action ('wpmu_new_user', 'user_status', 10, 1);

add_action( 'edit_user_profile', 'user_status', 10, 1 );

/**
 * Show custom user profile fields
 * 
 * @param  object $profileuser A WP_User object
 * @return void
 */
function custom_user_profile_fields( $profileuser ) {
?>
    <table class="form-table">
        <tr>
            <th>
                <label for="user_status"><?php esc_html_e( 'Status' ); ?></label>
            </th>
            <td>
                <?php echo esc_attr( get_the_author_meta( 'user_vcu_status', $profileuser->ID ) ); ?>                
            </td>
        </tr>
    </table>
<?php
}
add_action( 'edit_user_profile', 'custom_user_profile_fields', 10, 1 );