Filter uncanny-learndash-groups

download_keys_csv_permission

Filters the permission level required to download CSV files, allowing customization of access for 'group_leader'.

add_filter( 'download_keys_csv_permission', $callback, 10, 1 );

Description

Allows developers to modify the user role required to download CSV files of download keys. By default, 'group_leader' is checked. Developers can filter this hook to grant access to other user roles or implement custom permission logic for this download action.


Usage

add_filter( 'download_keys_csv_permission', 'your_function_name', 10, 1 );

Return Value

The filtered value.


Examples

// Allow only administrators and users with the 'group_leader' role to download the CSV.
// This filter is intended to restrict the permission string passed to current_user_can().
add_filter( 'download_keys_csv_permission', 'my_custom_download_keys_csv_permission', 10, 1 );

/**
 * Custom function to modify the permission required for downloading keys CSV.
 *
 * @param mixed $permission The current permission string.
 * @return string The modified permission string.
 */
function my_custom_download_keys_csv_permission( $permission ) {
	// If the current permission is 'group_leader', we want to allow administrators as well.
	// We can check if the current user has the 'administrator' role directly here
	// or ensure that 'administrator' is always part of the check that uses this permission string.
	// For simplicity, let's ensure that if the permission is 'group_leader',
	// the check `current_user_can('administrator')` would also pass.
	// The original code already checks for 'administrator' separately,
	// so we can return a more specific capability if needed or just ensure
	// the check is robust.

	// In this realistic example, the original code checks `current_user_can($permission)`
	// and also checks against a list of `$allowed_roles`.
	// If we want to *only* allow administrators and group leaders specifically
	// for this CSV download, we might modify this filter to return a capability
	// that only those roles can fulfill, or perhaps a custom capability.

	// A common WordPress pattern is to use custom capabilities for fine-grained control.
	// Let's assume there's a custom capability 'manage_group_keys_csv'.
	// However, based on the provided context, it seems the intention is to use
	// existing roles or capabilities.

	// If we want to enforce that only users with the 'administrator' role *or*
	// users with the 'group_leader' role can download, and the original code
	// already checks `current_user_can($permission)` and then checks against
	// `$allowed_roles` which includes 'administrator' and 'group_leader',
	// we might not need to change the `$permission` string itself if the logic
	// using it is comprehensive.

	// However, if the goal is to *solely* use the result of this filter for the
	// `current_user_can()` check and NOT rely on the `$allowed_roles` array,
	// we would return a capability that represents the desired permission.
	// For example, we could return 'edit_posts' if we assume administrators
	// can do that. But 'group_leader' is a specific role.

	// Let's assume the intention is to allow users who can 'edit_users'
	// (which typically includes administrators) or specifically 'group_leader'.
	// The `current_user_can()` function can accept role names.
	// So, if the original code uses `current_user_can('group_leader')` and
	// this filter *only* returns 'group_leader', it would restrict it to that role.
	// To be more flexible, we can return a string that is a union of permissions,
	// or a custom capability.

	// A simpler, and perhaps more aligned with the original code's structure,
	// is to allow modification of the *exact* permission string.
	// If the original intent was to only allow 'group_leader' by default from
	// this filter, and the calling code separately checks for 'administrator',
	// then returning 'group_leader' is correct.

	// Let's demonstrate a scenario where we're adding a higher level of access
	// via this filter, allowing 'administrator' to download by returning
	// a capability that administrators possess.

	// Option 1: Return a capability that administrators have, ensuring they can pass.
	// The original code checks `current_user_can($permission)` AND `array_intersect(wp_get_current_user()->roles, $allowed_roles)`.
	// If we return 'administrator' here, `current_user_can('administrator')` will be true for admins.
	// If we return 'group_leader', it will only be true for group leaders.
	// Let's assume we want to allow both 'administrator' and 'group_leader' *via this specific filter check*.
	// The most straightforward way to do this is to ensure the capability string works for both.
	// Since `current_user_can()` can accept role names, and the calling code checks against roles anyway,
	// we can return a string that prioritizes administrator if they are present.

	// This example will make it so that if the user is an administrator, they can download.
	// If they are not an administrator, but have the 'group_leader' role, they can also download.
	// The original `! array_intersect( wp_get_current_user()->roles, $allowed_roles )` acts as a fallback/additional check.

	if ( current_user_can( 'administrator' ) ) {
		// If the user is an administrator, they inherently have permission.
		// Returning 'administrator' here ensures the `current_user_can($permission)` check passes for admins.
		return 'administrator';
	} elseif ( $permission === 'group_leader' ) {
		// If the current permission is 'group_leader' and the user is not an administrator,
		// we stick with 'group_leader' to allow that role.
		return $permission;
	} else {
		// For any other scenario, or if the default permission was something else,
		// we can return a more general capability like 'read' as a fallback,
		// but this is less likely to be the intended use case.
		// For this example, let's ensure it remains restrictive unless specifically 'group_leader'.
		// The original code allows the filter to override the default 'group_leader'.
		// So if a plugin filters this to 'edit_posts', that will be used.
		// To keep it realistic and aligned with the prompt's parameters:
		return $permission; // Returns the value passed to the filter.
	}

	// A more direct approach that modifies the permission string for the `current_user_can` check:
	// If the intent is to simply ensure that 'administrator' users can pass this check,
	// and 'group_leader' users can pass this check, we can return a capability that
	// covers both. Since 'administrator' is a more privileged role, we can prioritize it.
	// The calling code already has a separate check for `$allowed_roles`.
	// This filter modifies the `$permission` variable passed to `current_user_can()`.

	// Let's assume we want to make sure administrators can *always* download,
	// and group leaders can download if they meet the criteria.
	// The original code's `! current_user_can( $permission ) && ! array_intersect( wp_get_current_user()->roles, $allowed_roles )`
	// implies that *either* `current_user_can($permission)` is true, *OR* the user's role is in `$allowed_roles`.

	// If the default `$permission` is 'group_leader', and we want to also allow administrators through `current_user_can`,
	// we can return 'administrator'. This means the check becomes `current_user_can('administrator')`.
	// If the user is an administrator, this is true.
	// If the user is *not* an administrator, then the check `! current_user_can('administrator')` is true,
	// and the code falls back to `! array_intersect( wp_get_current_user()->roles, $allowed_roles )`.
	// So, if the user has a role in `$allowed_roles` (like 'group_leader'), the condition becomes false, and they are allowed.

	// Let's refine the example:
	// The filter is called with 'group_leader'.
	// The calling code checks: `! current_user_can('group_leader') && ! array_intersect( wp_get_current_user()->roles, $allowed_roles )`
	// This means if EITHER `current_user_can('group_leader')` is true, OR a user's role is in `$allowed_roles`, they are allowed.

	// If we want to explicitly grant administrators permission via this filter:
	// If the current user is an administrator, they should be able to download.
	if ( current_user_can( 'administrator' ) ) {
		// If the user has the administrator role, return a capability that administrators possess.
		// 'manage_options' is a common capability for administrators.
		// This makes the `current_user_can('manage_options')` check pass for administrators.
		// The subsequent `array_intersect` check will still apply if this filter's result
		// doesn't grant permission on its own, or if the user isn't an administrator.
		return 'manage_options';
	}

	// Otherwise, return the original permission passed to the filter.
	// This ensures that if the permission was 'group_leader', it remains 'group_leader',
	// and the `array_intersect` check will then determine if 'group_leader' (or other allowed roles) have access.
	return $permission;
}

Placement

This code should be placed in the functions.php file of your active theme, a custom plugin, or using a code snippets plugin.


Source Code

src/classes/helpers/rest-api-end-points.php:1503

public static function download_keys_csv( WP_REST_Request $request ) {

		// Actions permitted by the pi call (collected from input element with name action )
		$permitted_actions = array( 'download' );

		// Was an action received, and is the actions allowed
		if ( $request->has_param( 'action' ) && in_array( $request->get_param( 'action' ), $permitted_actions ) ) {

			$action = (string) $request->get_param( 'action' );

		} else {
			$action          = '';
			$data['message'] = __( 'Select an action.', 'uncanny-learndash-groups' );
			wp_send_json_error( $data );
		}

		// Does the current user have permission
		$allowed_roles = apply_filters(
			'ulgm_gm_allowed_roles',
			array(
				'administrator',
				'group_leader',
				'ulgm_group_management',
				'super_admin',
			)
		);
		$permission    = apply_filters( 'download_keys_csv_permission', 'group_leader' );
		if ( ! current_user_can( $permission ) && ! array_intersect( wp_get_current_user()->roles, $allowed_roles ) ) {
			$data['message'] = __( 'You do not have permission to download csv keys.', 'uncanny-learndash-groups' );
			wp_send_json_error( $data );
		}

		$group_leader_id                = get_current_user_id();
		$user_group_ids                 = LearndashFunctionOverrides::learndash_get_administrators_group_ids( $group_leader_id );
		$can_the_user_manage_this_group = SharedFunctions::can_user_manage_this_group( $group_leader_id, absint( $request->get_param( 'group-id' ) ), $user_group_ids );
		// is the current user able to administer this group
		if ( false === $can_the_user_manage_this_group ) {
			$data['message'] = __( 'You do not have permission to manage this group.', 'uncanny-learndash-groups' );
			$data['error']   = 'invalid-group-id';
			wp_send_json_error( $data );
		}

		$group_id = absint( $request->get_param( 'group-id' ) );

		$users = apply_filters( 'ulgm_download_users_keys', Group_Management_Helpers::get_unused__key_users_data( $group_id ), $group_id );
		$csv   = '';

		if ( ! empty( $users ) ) {
			$headers = apply_filters( 'ulgm_download_keys_header', "Group,Keyn", $group_id );
			$csv     .= $headers;
			foreach ( $users as $row ) {
				$csv .= implode( ',', $row ) . "n";
			}
		} else {
			$headers = apply_filters( 'ulgm_download_keys_header', "Group,Keyn", $group_id );
			$csv     .= $headers;
		}

		// File name
		$group_slug = get_post_field( 'post_name', $group_id );
		$file_name  = 'keys-' . $group_slug . '-' . date( 'Y-m-d' );
		$file_name  = apply_filters( 'csv_file_name', $file_name, $group_slug, $group_id, $group_leader_id );

		/// Trigger file creation to frontend
		$data['reload']        = false;
		$data['call_function'] = 'downloadCsv';
		$data['function_vars'] = array(
			'csvDataString' => $csv,
			'fileName'      => $file_name,

		);

		wp_send_json_success( $data );
	}


Scroll to Top