Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds core support for user role widget contexts #22

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions css/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@

.context-group-word_count select { max-width:4em; min-width:2em; }

.context-group-user_roles .context-group-wrap { max-height:10em; overflow:auto; padding:0.5em; margin-bottom:0.5em; background:#fff; border:1px solid #ddd; }
.context-group-user_roles label { display:block; padding:0.25em 0; }

/** Settings UI **/

.widget-context-form th { width:auto; }
Expand Down
179 changes: 179 additions & 0 deletions modules/user-roles/module.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<?php

// Check for Widget Context plugin
if ( ! class_exists( 'widget_context' ) )
die;


// Go!
WidgetContextUserRole::instance();


class WidgetContextUserRole {

private static $instance;
private $wc;


static function instance() {

if ( ! self::$instance )
self::$instance = new self();

return self::$instance;

}


private function __construct() {

$this->wc = widget_context::instance();

add_filter( 'widget_contexts', array( $this, 'add_context' ) );

add_filter( 'widget_context_control-user_roles', array( $this, 'context_controls' ), 10, 2 );

add_filter( 'widget_context_check-user_roles', array( $this, 'context_check' ), 10, 2 );

}


function add_context( $contexts ) {

$contexts[ 'user_roles' ] = array(
'label' => __( 'User Roles', 'widget-context' ),
'description' => __( 'Context based user roles', 'widget-context' ),
'weight' => 10
);

return $contexts;

}


function context_check( $check, $settings ) {

// Assume:
// "return $check" = Pass-through case
// "return true" = Affirmative case

if ( empty( $settings ) ) {

return $check;
}

$current_user = wp_get_current_user();
$is_logged_in = ( $current_user->ID !== 0 && $current_user->ID );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use is_user_logged_in() instead?


//
// 1. Logged-in/logged-out check:
//

// Check for logged-out user
if( $settings['logged-out'] === '1' && $is_logged_in !== true ) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@folkhack You should probably ensure that logged-out exists before using it. A good solution is wp_parse_args() with a set of defaults.


// Check for logged-out and user not auth'd, affirmative case
return true;
}

// Check for logged-in user
if( $settings['logged-in'] === '1' && $is_logged_in ) {

// Check for logged-in and user is auth'd, affirmative case
return true;
}

// Drop the auth settings before additional iteration
unset( $settings['logged-in'], $settings['logged-out'] );

//
// 2. User role intersection check:
//

// Build whitelist of user roles that are allowed to see widget
$role_check_array = array();

foreach( $settings as $role_key => $setting_val ) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can skip all of this if the user is not logged in, correct?


if( $setting_val === '1' ) {

// Push role onto whitelist without "role-" prepend
array_push( $role_check_array, substr( $role_key, 5 ) );
}
}

if(
// User is auth'd
$is_logged_in &&

// There are roles to check for
! empty( $role_check_array ) &&

// The current auth'd user has roles to check
is_array( $current_user->roles ) &&
! empty( $current_user->roles )
) {

// Calculate an intersecting set of current user roles and roles to check against
$roles_intersection = array_intersect( $current_user->roles, $role_check_array );

if( ! empty( $roles_intersection ) ) {

// Roles intersect, affirmative case
return true;
}
}

// No roles intersect, pass-through case
return $check;
}


function context_controls( $control_args ) {

$options = array();
$out = array();

// Grab editable roles and work down to a key => value assoc. array
$pre_roles = $this->get_roles();
$roles = array();

foreach( $pre_roles as $key => $role ) {

$roles[ $key ] = $role['name'];
}

// Alphabetically sort roles for best UIX
asort( $roles );

// First two options are the logged-in and logged-out options
$options[ 'logged-in' ] = __( 'When user is logged in (all types, global)', 'widget-context' );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe simplify these to User logged in and User logged out?

$options[ 'logged-out' ] = __( 'When user is logged out (global)', 'widget-context' );

// Add the roles that the user can currently edit as whitelist user role options
foreach( $roles as $role_key => $role_name ) {

$options[ 'role-' . $role_key ] = sprintf( __( 'When user has role "%s" (%s)', 'widget-context' ), $role_name, $role_key );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here, something like User role "%s"?

}

// Build the output array of checkbox input HTML
foreach( $options as $option => $label ) {

$out[] = $this->wc->make_simple_checkbox( $control_args, $option, $label );
}

return implode( '', $out );
}


/**
* Get editable roles for user
* - "editable_roles" filter solution from http://wordpress.stackexchange.com/a/1666
* @return mixed|void
*/
function get_roles() {

global $wp_roles;
return apply_filters( 'editable_roles', $wp_roles->roles );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@folkhack There is get_editable_roles() -- could we use that?

}
}
1 change: 1 addition & 0 deletions widget-context.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class widget_context {
private $sidebars_widgets_copy;

private $core_modules = array(
'user-roles',
'word-count',
'custom-post-types-taxonomies'
);
Expand Down