Skip to content

Commit

Permalink
Merge pull request #119 from NewPath-Consulting/1.0.2
Browse files Browse the repository at this point in the history
Contact API request paging
  • Loading branch information
asirota authored Dec 14, 2022
2 parents 46f8f99 + d738e0e commit 34efbdf
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Tags: wildapricot, wild apricot, membership, event management, events, membershi
Requires at least: 5.0
Tested up to: 6.0
Requires PHP: 7.4
Stable Tag: 1.0.1
Stable Tag: 1.0.2
License: GPL v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Expand Down
2 changes: 2 additions & 0 deletions src/admin-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,8 @@ private static function obtain_and_save_wa_data_from_api($valid_api) {
WA_Integration::remove_wa_users();
delete_option(WA_Integration::LIST_OF_CHECKED_FIELDS);
delete_option(WA_Integration::ARRAY_OF_RESTRICTED_POSTS);

delete_option(WA_Integration::WA_CONTACTS_COUNT_KEY);
// delete post meta added by the plugin
delete_post_meta_by_key(WA_Integration::RESTRICTED_GROUPS);
delete_post_meta_by_key(WA_Integration::RESTRICTED_LEVELS);
Expand Down
12 changes: 8 additions & 4 deletions src/class-addon.php
Original file line number Diff line number Diff line change
Expand Up @@ -673,23 +673,27 @@ public static function check_license_properties($response, $slug) {
// else return the valid license key
if (array_key_exists('license-error', $response)) return false;

if (!(array_key_exists('Products', $response) && array_key_exists('Support Level', $response) && array_key_exists('expiration date', $response))) return false;
if (!(
array_key_exists('Products', $response) &&
array_key_exists('Support Level', $response) &&
array_key_exists('expiration date', $response)
)) {
return false;
}

// Get list of product(s) that this license is valid for
$valid_products = $response['Products'];
// $support_level = $response['Support Level'];
$exp_date = $response['expiration date'];


// Check if the addon_slug in in the products list, has support access and is expired
if (!in_array(CORE_SLUG, $valid_products) || self::is_expired($exp_date)) {
return false;
}

$name = self::get_title($slug);

if (self::is_expired($exp_date)) {
Log::wap_log_warning('License key for ' . $name . ' has expired.');
return false;
}

// Ensure that this license key is valid for the associated WildApricot ID and website
Expand Down
193 changes: 175 additions & 18 deletions src/class-wa-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,13 @@ public function get_account_url_and_id() {
$args = $this->request_data_args();
$url = self::API_URL . self::ADMIN_API_VERSION . '/accounts/' . $this->wa_user_id;
$response_api = wp_remote_get($url, $args);
$details_response = self::response_to_data($response_api);

try {
$details_response = self::response_to_data($response_api);
} catch (API_Exception $e) {
throw new API_Exception('There was an error retrieving the Wild Apricot account URL and ID.');
}

// Extract values
$wild_apricot_values = array();
if (array_key_exists('Id', $details_response)) {
Expand Down Expand Up @@ -227,7 +232,13 @@ public function retrieve_custom_fields() {
$url = self::API_URL . self::ADMIN_API_VERSION . '/accounts/' .
$this->wa_user_id . '/contactfields?showSectionDividers=true';
$response_api = wp_remote_get($url, $args);
$custom_field_response = self::response_to_data($response_api);

try {
$custom_field_response = self::response_to_data($response_api);
} catch (API_Exception $e) {
throw new API_Exception('There was an error retrieving the Wild Apricot custom fields.');
}


// Loop through custom fields and get field names with IDs
// Array that holds default fields
Expand Down Expand Up @@ -266,7 +277,7 @@ public function get_all_user_info() {
$wa_users = get_users($users_args);

// Loop through each WP_User and create filter
$filter_string = 'filter=';
$filter_string = 'filter=(';
$i = 0;
// Create array that stores the WildApricot ID associated with the WordPress ID
$user_emails_array = array();
Expand All @@ -285,19 +296,21 @@ public function get_all_user_info() {
$user_emails_array[$site_user_id] = $user_email;
$filter_string .= 'ID%20eq%20' . $wa_synced_id;
// Combine IDs with OR
if (!($i == count($wa_users) - 1)) { // not last element
if ($i < count($wa_users) - 1) {
// not last element
$filter_string .= '%20OR%20';
} else {
$filter_string .= ')%20AND%20';
}
$i++;
}
// Make API request
$args = $this->request_data_args();
$url = self::API_URL . self::ADMIN_API_VERSION . '/accounts/' .
$this->wa_user_id . '/contacts?%24async=false&%24' . $filter_string;
$all_contacts_request = wp_remote_get($url, $args);
// Ensure that responses are not empty
if (empty($all_contacts_request)) return;
$all_contacts = self::response_to_data($all_contacts_request);

// only retrieve contacts updated yesterday
$yesterday = $this->get_yesterdays_date();
$filter_string .= '\'Profile last updated\'%20gt%20' . $yesterday;

$all_contacts = $this->retrieve_contacts_list($filter_string);

if (empty($all_contacts)) return;
// Convert contacts object to an array
$all_contacts = (array) $all_contacts;
Expand Down Expand Up @@ -414,7 +427,13 @@ public static function get_new_access_token($refresh_token) {
'body' => 'grant_type=refresh_token&refresh_token=' . $refresh_token
);
$response = wp_remote_post('https://oauth.wildapricot.org/auth/token', $args);
$data = self::response_to_data($response);

try {
$data = self::response_to_data($response);
} catch (API_Exception $e) {
throw new API_Exception('There was an error retrieving the Wild Apricot API access token.');
}

return $data;
}

Expand All @@ -428,7 +447,13 @@ public function get_info_on_current_user() {
// Get user's contact ID
$args = $this->request_data_args();
$contact_info = wp_remote_get(self::API_URL . self::ADMIN_API_VERSION . '/accounts/' . $this->wa_user_id . '/contacts/me?getExtendedMembershipInfo=true', $args);
$contact_info = self::response_to_data($contact_info);

try {
$contact_info = self::response_to_data($contact_info);
} catch (API_Exception $e) {
throw new API_Exception('There was an error retrieving Wild Apricot contact info.');
}

// Get if user is administrator or not
$is_administrator = $contact_info['IsAccountAdministrator'];
// Perform API call based on if user is administrator or not
Expand All @@ -440,7 +465,13 @@ public function get_info_on_current_user() {
$user_data_api = wp_remote_get('https://api.wildapricot.org/publicview/' . self::MEMBER_API_VERSION . '/accounts/' . $this->wa_user_id . '/contacts/me?includeDetails=true', $args);
}
// Extract body
$full_info = self::response_to_data($user_data_api);

try {
$full_info = self::response_to_data($user_data_api);
} catch (API_Exception $e) {
throw new API_Exception('There was an error retriving Wild Apricot user info.');
}

// Get all information for current user
return $full_info;
}
Expand All @@ -460,8 +491,12 @@ public function get_membership_levels($request_groups = false) {
$membership_levels_response = wp_remote_get($url, $args);

// Return membership levels
$membership_levels_response = self::response_to_data($membership_levels_response);

try {
$membership_levels_response = self::response_to_data($membership_levels_response);
} catch (API_Exception $e) {
throw new API_Exception('There was an error retrieving the Wild Apricot membership levels.');
}

// Extract membership levels into array
$membership_levels = array();
if (!empty($membership_levels_response)) {
Expand Down Expand Up @@ -527,7 +562,129 @@ public static function login_email_password($valid_login) {
);
$response = wp_remote_post('https://oauth.wildapricot.org/auth/token', $args);

$data = self::response_to_data($response);
try {
$data = self::response_to_data($response);
} catch (API_Exception $e) {
throw new API_Exception('There was an error authorizing a Wild Apricot user\'s credentials.');
}

return $data;
}

/**
* Retrieves list of contacts from Wild Apricot.
*
* @param string $query additional query to append to the request url
* @param boolean $block whether a single block is requested or not, used
* for REST API requests. Default false.
* @param integer $skip skip query for request url. Default 0.
* @param integer $top top query for request url. Default 500.
* @return array list of contacts
*/
public function retrieve_contacts_list($query, $block = false, $skip = 0, $top = 200) {
$base_url = self::API_URL . self::ADMIN_API_VERSION . '/accounts/' .
$this->wa_user_id . '/contacts?%24async=false&%24' . $query;

// return single block
if ($block) {
return $this->request_contact_block($base_url, $skip, $top);
}

$all_contacts = array(
'Contacts' => array()
);
$count = $this->get_contacts_count();
$done = false;

// retrieve in blocks of 500
while (!$done) {
// if there are more than 500 entires left, include top query
if (($count - $skip) <= $top) {
$top = 0;
$done = true;
}

// make API request and add block to list of all contacts
$contacts_block = $this->request_contact_block($base_url, $skip, $top);
// Log::wap_log_debug($contacts_block);
$all_contacts['Contacts'] = array_merge(
$all_contacts['Contacts'],
$contacts_block['Contacts']
);

// increment by block size
$skip += $top;
}

return $all_contacts;

}

/**
* Retrieves number of contacts from Wild Apricot.
*
* @return int number of contacts
*/
public function get_contacts_count() {

$count = get_option(WA_Integration::WA_CONTACTS_COUNT_KEY);
if ($count) return $count;

$url = self::API_URL . self::ADMIN_API_VERSION . '/accounts/' .
$this->wa_user_id . '/contacts?%24async=false&%24count=true';

$args = $this->request_data_args();
$response = wp_remote_get($url, $args);

try {
$data = self::response_to_data($response);
$count = $data['Count'];
} catch (API_Exception $e) {
throw new API_Exception('There was an error retrieving the number of Wild Apricot contacts.');
}

update_option(WA_Integration::WA_CONTACTS_COUNT_KEY, $count);

return $count;
}

/**
* Requests a single block of contacts from Wild Apricot.
*
* @param string $url base url to which to make the request
* @param int $skip the number of contacts to skip from the beginning
* @param int $top the number of contacts to return
* @return array block of contacts
*/
private function request_contact_block($url, $skip, $top) {

if ($skip) {
$url .= '&$skip=' . $skip;
}

if ($top) {
$url .= '&$top=' . $top;
}

$args = $this->request_data_args();

$response = wp_remote_get($url, $args);

try {
$data = self::response_to_data($response);
} catch (API_Exception $e) {
throw new API_Exception('There was an error retrieving Wild Apricot contacts.');
}

return $data;
}

/**
* Returns yesterday's date in the format yyyy-mm-dd.
*
* @return string
*/
private function get_yesterdays_date() {
return date('Y-m-d',strtotime("-1 days"));
}
}
5 changes: 5 additions & 0 deletions src/class-wa-integration.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ class WA_Integration {
*/
const WA_CLIENT_SECRET_OPT = 'wawp_wal_client_secret';

/**
* Stores the total number of Wild Apricot contacts.
*/
const WA_CONTACTS_COUNT_KEY = 'wawp_contacts_count';

/**
* Stores user's WA user ID in the user meta data.
*
Expand Down

0 comments on commit 34efbdf

Please sign in to comment.