pods-framework / pods

The Pods Framework is a Content Development Framework for WordPress - It lets you create and extend content types that can be used for any project. Add fields of various types we've built in, or add your own with custom inputs, you have total control.
https://pods.io/
GNU General Public License v2.0
1.07k stars 264 forks source link

Relationships > Users > Add button - Users are created with default WP role when current user does not have promote_users cap #7333

Open agenciajhma opened 3 months ago

agenciajhma commented 3 months ago

Description

I have a custom post type created with Pods that has 2 user relationship fields, each one for a different custom user role. I'm using a filter to only show users with that specific role. In these fields, I enabled the possibility of adding new users.

The problem is that these users are created with the default role configured in Wordpress (subscriber) and not with the filtered field role. Only administrators has the option to choose the role (which is not the case, because who's creating users ate not administrators).

Example: "owner" field with filter to only show users who have the "owner" role. When creating a new user using the Add New button, the user is created with the role "subscriber" instead of "owner".

Version

3.2.1

Testing Instructions

  1. Create a custom user role
  2. Create a pod with a relationship field to users. Filter by the custom user role. Enable Add New
  3. Add new pod and on the user relationship field click add a new user
  4. The user created will be set to default Wordpress role and not to the relationship field filtered role

Screenshots / Screencast

User Relationship fields

image

Form the create users in a modal

image

Possible Workaround

No response

Site Health Information

No response

Pods Package

No response

sc0ttkclark commented 3 months ago

This one is a bit tricky for sure. We're limited by what WordPress capabilities allow here for when that role dropdown shows within the Add New User modal. Because of that not showing for those who do not have the promote_users capability, yes it does create them with the default user role.

But when someone goes to edit a user and they don't have that capability, they don't have the ability to change the role there in the user edit screen either.

As a result of these limitations, I'm not sure whether it's necessarily safe to allow creating and setting a default user from within the Pod field editor itself if a non-admin gets access to create a pod.

Relying on anything other than the default new user role for someone creating a new user would just be problematic for security reasons in general use.

I don't think there's a great workaround for this either other than to have us add a new feature that disallows creating new users if the user doesn't have the promote_users capability.

agenciajhma commented 3 months ago

I got a workaround as only specific users will be able to create these users on the website we are developing.

In the Slack Support group, I got help with this code that resolved the issue. I added it here so it can help other people in the same situation.

/**
 * Plugin Name: Pods - User Relationship Roles
 * Description: Set default user role for Add New button on Pods relationship fields when filtered to display only one user role.
 * Version: 1
 * Plugin URI: https://podswp.slack.com/archives/C02SVLHQF/p1723574513532549
 */

// Change Add New button for Pods user relationship fields.
add_filter(
    'pods_ui_dfv_pick_modals_iframe',
    function( $iframe, $config, $args ) {
        if (
            // Relationship field.
            'pick' === $config['type']
            // To users.
            && 'user' === $config['pick_object']
            // Filtered to one role in field settings.
            && 1 === count( (array) $config['pick_user_role'] )
        ) {
            // Get role from field setting.
            $role = $config['pick_user_role'][0];

            // Send role to the iframe.
            $iframe['src'] = add_query_arg( 'role', $role, $iframe['src'] );
            $iframe['query_args']['role'] = $role;

            // Add role to title of iframe.
            $iframe['title_add'] = sprintf( '%s %s', $iframe['title_add'], ucwords( $role ) );
        }
        return $iframe;
    },
    20,
    3
);

// Hide Role field from user interface if already set by filter pods_ui_dfv_pick_modals_iframe.
if (
    false !== strpos( $_SERVER['SCRIPT_FILENAME'], '/wp-admin/user-new.php' )
    && array_key_exists( 'pods_modal', $_GET )
    && array_key_exists( 'role', $_GET )
) {
    add_action(
        'admin_footer',
        function() {
            ?>
<script id="pods-default-role">
( function() {
    // Get Role select menu and new role.
    let roleSelect = document.getElementById("role");
    let newRole = '<?php echo esc_js( sanitize_key( $_GET['role'] ) ); ?>';

    // Change the selection.
    roleSelect.querySelector('option[selected="selected"]').selected = false;
    roleSelect.querySelector('option[value="' + newRole + '"]').selected = true;    

    // Hide the row.
    roleSelect.parentNode.parentNode.style.display = 'none';
} )();
</script>
            <?php
        }
    );
}