';
// If WP_DEBUG is enabled, log the error.
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
error_log( $error->get_error_message() );
}
}
$response_results_count = count( $response->results );
for ( $i = 0; $i < $response_results_count; $i++ ) {
if ( 'Not Found' !== $response->results[ $i ]->body ) {
$credentials = json_decode( $response->results[ $i ]->body );
$result[ $i ]['credentials'] = $credentials->credentials;
}
}
}
return $result;
}
/**
* Returns the count of users in the database.
*
* @return null|string
*/
public static function record_count() {
$user_count = count_users();
return $user_count['total_users'];
}
/** Text displayed when no user data is available */
public function no_items() {
esc_html_e( 'No users available.', 'accredible-certificates' );
}
/**
* Render a column when no column-specific method exists.
*
* @param array $item item.
* @param string $column_name column name.
*
* @return mixed
*/
public function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'user_login':
case 'user_nicename':
case 'user_email':
return $item[ $column_name ];
case 'credentials':
return $this->column_credentials( $item );
default:
// Return a formatted display of the column value if it exists.
if ( isset( $item[ $column_name ] ) ) {
return esc_html( $item[ $column_name ] );
}
// Return a dash for empty or undefined columns.
return '—';
}
}
/**
* Render the bulk edit checkbox
*
* @param array $item item.
*
* @return string
*/
public function column_cb( $item ) {
return sprintf(
'',
$item['id']
);
}
/**
* Render items in the credential column
*
* @param array $item item.
* @return string
*/
public function column_credentials( $item ) {
$string = '';
foreach ( $item['credentials'] as $credential ) {
$string = $string . "" . $credential->url . ' ';
}
return $string;
}
/**
* Associative array of columns
*
* @return array
*/
public function get_columns() {
$columns = array(
'cb' => '',
'user_login' => 'Login',
'user_nicename' => 'Username',
'user_email' => 'Email',
'credentials' => 'Credentials',
);
return $columns;
}
/**
* Columns to make sortable.
*
* @return array
*/
public function get_sortable_columns() {
$sortable_columns = array(
'user_login' => array( 'user_login', true ),
'user_nicename' => array( 'user_nicename', false ),
'user_email' => array( 'user_email', false ),
);
return $sortable_columns;
}
/**
* Get the select options for the group dropdown.
*
* @return string
*/
public function get_group_select_options() {
try {
$groups = $this->accredible_certificates->get_groups();
} catch ( Exception $e ) {
$groups = array();
$this->display_admin_notice( 'Error fetching groups. Please try again later.', 'error' );
}
$options = '';
$groups_count = count( $groups );
for ( $i = 0; $i < $groups_count; $i++ ) {
$options .= "\n\t';
}
// set the flag to show there are no groups.
if ( 0 === $groups_count ) {
$this->no_groups = true;
}
return $options;
}
/**
* Method to override the header nav and add our groups dropdown and button - https://github.com/WordPress/WordPress/blob/eeefec932f3d4f3b50369f6523c2cd8fad3d467f/wp-admin/includes/class-wp-users-list-table.php#L259
*
* @param type $which which.
*/
public function extra_tablenav( $which ) {
$id = 'bottom' === $which ? 'group_id2' : 'group_id';
?>
';
}
/**
* Handles data query and filter, sorting, and pagination.
*/
public function prepare_items() {
$columns = $this->get_columns();
$hidden = array();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array( $columns, $hidden, $sortable );
/** Process bulk action */
$this->process_bulk_action();
// Avoid bulk request overflows by limiting the page size.
$per_page = 20;
$current_page = $this->get_pagenum();
$total_items = self::record_count();
$this->set_pagination_args(
array(
'total_items' => $total_items, // WE have to calculate the total number of items.
'per_page' => 20, // WE have to determine how many items to show on a page.
)
);
$this->items = $this->get_users( 20, $current_page );
}
/**
* Capture the bulk action required, and return it.
*
* Overridden from the base class implementation to capture
* the role change drop-down.
*
* @since 3.1.0
* @access public
*
* @return string The bulk action required.
*/
public function current_action() {
$create_credentials = self::sanitize_request_parameter( 'create-credentials' );
if ( ! $create_credentials ) {
return parent::current_action();
}
$group_id = self::sanitize_request_parameter( 'group_id' );
$group_id2 = self::sanitize_request_parameter( 'group_id2' );
if ( empty( $group_id ) && empty( $group_id2 ) ) {
$this->display_admin_notice( 'You need to select a Group to create Credentials.', 'error' );
} else {
return 'create-credentials';
}
return parent::current_action();
}
/**
* When the action is submitted, we should do what the user suggested - make credentials
*/
public function process_bulk_action() {
// Detect when a bulk action is being triggered...
if ( 'create-credentials' === $this->current_action() ) {
// Verify nonce.
$nonce = self::sanitize_post_parameter( 'accredible_certificates_nonce' );
self::verify_nonce( $nonce, 'accredible_certificates_bulk_action' );
// Get and validate group_id from either group_id or group_id2.
$group_id = self::sanitize_post_parameter( 'group_id' );
if ( empty( $group_id ) ) {
$group_id = self::sanitize_post_parameter( 'group_id2' );
}
// Get and validate credential_users array.
$users = self::get_credential_users();
// Only proceed if we have both a group_id and users.
if ( ! empty( $group_id ) && ! empty( $users ) ) {
// Create credentials for each user.
foreach ( $users as $user_id ) {
// Find the user.
$userdata = WP_User::get_data_by( 'id', $user_id );
if ( ! $userdata ) {
continue;
}
$user_firstname = get_user_meta( $user_id, 'first_name', true );
$user_lastname = get_user_meta( $user_id, 'last_name', true );
$recipient_name = ( $user_firstname && $user_lastname )
? $user_firstname . ' ' . $user_lastname
: $userdata->display_name;
// Create a credential.
try {
$credential = $this->accredible_certificates->create_credential(
$recipient_name,
$userdata->user_email,
$group_id
);
} catch ( Exception $e ) {
$this->display_admin_notice( 'Failed to create credential for ' . $userdata->user_email, 'error' );
return;
}
}
$this->display_admin_notice( 'Credentials created!', 'success' );
} else {
$this->display_admin_notice( 'Failed to create credentials. Please ensure you have selected both a group and users.', 'error' );
}
}
}
/**
* Process and sanitize the credential users array from POST data.
*
* @return array Array of sanitized user IDs.
*/
private static function get_credential_users() {
$users = array();
// nonce verification is handled in the process_bulk_action method.
// phpcs:disable WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$credential_users = isset( $_POST['credential_users'] ) ? wp_unslash( $_POST['credential_users'] ) : array();
// phpcs:enable WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
if ( is_array( $credential_users ) ) {
$users = array_map( 'absint', $credential_users );
}
return $users;
}
/**
* Verify WP nonce for the action.
*
* @param string $nonce Nonce value that was used for verification.
* @param string $action Should give context to what is taking place and be the same when nonce was created.
*/
private static function verify_nonce( $nonce, $action ) {
if ( ! ( isset( $nonce ) && wp_verify_nonce( $nonce, $action ) ) ) {
wp_die( 'Invalid nonce.' );
}
}
/**
* Sanitize a string parameter.
*
* @param string $key The key of the parameter.
* @param string|null $default_value The default value if the parameter is not set.
*/
private static function sanitize_request_parameter( $key, $default_value = null ) {
// nonce verification is handled in the current_action method.
return isset( $_REQUEST[ $key ] ) ? sanitize_key( wp_unslash( $_REQUEST[ $key ] ) ) : $default_value; // phpcs:ignore WordPress.Security.NonceVerification
}
/**
* Sanitize a search parameter.
*
* @param string $key The key of the parameter.
* @param string|null $default_value The default value if the parameter is not set.
*/
private static function sanitize_search_parameter( $key, $default_value = null ) {
// nonce verification is handled in the current_action method.
return isset( $_REQUEST[ $key ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $key ] ) ) : $default_value; // phpcs:ignore WordPress.Security.NonceVerification
}
/**
* Sanitize a POST parameter.
*
* @param string $key The key of the parameter.
* @param string|null $default_value The default value if the parameter is not set.
*/
private static function sanitize_post_parameter( $key, $default_value = null ) {
// nonce verification is handled in the process_bulk_action method.
return isset( $_POST[ $key ] ) ? sanitize_text_field( wp_unslash( $_POST[ $key ] ) ) : $default_value; // phpcs:ignore WordPress.Security.NonceVerification
}
/**
* Display an admin notice.
*
* @param string $message The message to display.
* @param string $type The type of notice: 'success' or 'error'.
*/
private function display_admin_notice( $message, $type = 'success' ) {
$allowed_types = array( 'success', 'error' );
if ( ! in_array( $type, $allowed_types, true ) ) {
$type = 'success';
}
echo '