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

Make inviting individual users or a collection of users easier #228

Merged
merged 5 commits into from
Feb 12, 2016
Merged
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
27 changes: 22 additions & 5 deletions assets/dist/css/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -307,14 +307,31 @@ Styles
float: none; }
#clef-settings-container .sync iframe, #connect-clef-account .sync iframe {
display: none; }
#clef-settings-container .invite-users h3, #connect-clef-account .invite-users h3 {
margin-bottom: 20px; }
#clef-settings-container .invite-users .invite-users-message, #connect-clef-account .invite-users .invite-users-message {
margin: 10px 0 0 0;
clear: both; }
#clef-settings-container .invite-users .header h3, #clef-settings-container .invite-users .header h4, #connect-clef-account .invite-users .header h3, #connect-clef-account .invite-users .header h4 {
margin-top: 0;
margin-bottom: 5px; }
#clef-settings-container .invite-users .button, #connect-clef-account .invite-users .button {
margin-top: 20px; }
#clef-settings-container .invite-users .invite-users__img, #connect-clef-account .invite-users .invite-users__img {
width: 50%;
float: left; }
#clef-settings-container .invite-users .invite-users__individually-container, #connect-clef-account .invite-users .invite-users__individually-container {
padding-bottom: 25px;
margin-bottom: 25px;
border-bottom: 1px solid #eee; }
#clef-settings-container .invite-users .invite-users__individually, #connect-clef-account .invite-users .invite-users__individually {
float: left;
width: 50%;
padding-left: 20px; }
#clef-settings-container .invite-users .invite-users__individually .button, #connect-clef-account .invite-users .invite-users__individually .button {
margin-top: 0; }
#clef-settings-container .invite-users .invite-users__individually p, #connect-clef-account .invite-users .invite-users__individually p {
margin-top: 5px; }
#clef-settings-container .invite-users .invite-role-button, #connect-clef-account .invite-users .invite-role-button {
margin-top: 15px; }
#clef-settings-container .invite-users .next, #connect-clef-account .invite-users .next {
float: right;
cursor: pointer; }

.clef-settings__buttons p.submit {
margin-top: 0;
Expand Down
2 changes: 1 addition & 1 deletion assets/dist/css/admin.min.css

Large diffs are not rendered by default.

Binary file added assets/dist/img/invite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions assets/dist/js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
if ($messageEl.length) {
$messageEl.remove();
}
return this.$el.find('.button').first().before(this.messageTemplate(data));
return this.$el.find('.invite-role-button').first().before(this.messageTemplate(data));
},
template: function() {
return _.template($('#invite-users-template').html());
Expand All @@ -60,13 +60,15 @@
inviteUsers: function(e) {
var data, failure;
e.preventDefault();
$(e.target).attr('disabled', 'disabled');
data = {
_wpnonce: this.opts.nonces.inviteUsers,
roles: $("select[name='invite-users-role']").val(),
networkAdmin: this.opts.isNetworkSettings
};
failure = (function(_this) {
return function(msg) {
$(e.target).removeAttr('disabled');
return _this.showMessage({
message: _.template(clefTranslations.messages.error.invite)({
error: msg
Expand All @@ -77,10 +79,11 @@
})(this);
return $.post(this.inviteUsersAction, data).success((function(_this) {
return function(data) {
$(e.target).removeAttr('disabled');
if (data.success) {
_this.trigger("invited");
return _this.showMessage({
message: clefTranslations.messages.success.invite,
message: data.message,
type: "updated"
});
} else {
Expand Down
2 changes: 1 addition & 1 deletion assets/dist/js/settings.min.js

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions assets/src/coffee/settings/invite.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,27 @@
showMessage: (data) ->
$messageEl = @$el.find('.invite-users-message')
$messageEl.remove() if $messageEl.length
@$el.find('.button').first().before(@messageTemplate(data))
@$el.find('.invite-role-button').first()
.before(@messageTemplate(data))

template: -> _.template($('#invite-users-template').html())
initialize: (@opts) ->
if @opts.el
@setElement(@opts.el)

inviteUsersAction: ajaxurl + "?action=clef_invite_users"
inviteUsers: (e) ->
e.preventDefault()

$(e.target).attr('disabled', 'disabled')

data =
_wpnonce: @opts.nonces.inviteUsers
roles: $("select[name='invite-users-role']").val()
networkAdmin: @opts.isNetworkSettings

failure = (msg) =>
$(e.target).removeAttr('disabled')
@showMessage
message: _.template(
clefTranslations.messages.error.invite
Expand All @@ -34,10 +39,11 @@

$.post @inviteUsersAction, data
.success (data) =>
$(e.target).removeAttr('disabled')
if data.success
@trigger "invited"
@showMessage
message: clefTranslations.messages.success.invite
message: data.message
type:"updated"
else
failure ClefUtils.getErrorMessage data
Expand Down
Binary file added assets/src/img/invite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 38 additions & 11 deletions assets/src/sass/_settings-page.scss
Original file line number Diff line number Diff line change
Expand Up @@ -104,19 +104,46 @@
}

.invite-users {
.invite-users-message {
margin: 10px 0 0 0;
clear: both;
}
.header {
h3, h4 {
margin-top: 0;
margin-bottom: 5px;
}
}
h3 {
margin-bottom: 20px;
}

.invite-users-message {
margin: 10px 0 0 0;
clear: both;
}

.invite-users__img {
width: 50%;
float: left;
}

.invite-users__individually-container {
padding-bottom: 25px;
margin-bottom: 25px;
border-bottom: 1px solid #eee;
}

.invite-users__individually {
float: left;
width: 50%;
padding-left: 20px;
.button {
margin-top: 20px;
margin-top: 0;
}
p {
margin-top: 5px;
}
}

.invite-role-button {
margin-top: 15px;
}

.next {
float: right;
cursor: pointer;
}
}
}

Expand Down
83 changes: 62 additions & 21 deletions includes/class.clef-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public function initialize_hooks() {
add_action('clef_hook_admin_menu', array($this, "hook_admin_menu"));
add_filter('clef_add_affiliate', array($this, "add_affiliates"));
add_action('admin_enqueue_scripts', array($this, "admin_enqueue_scripts"));
add_action('admin_footer-users.php', array($this, "add_invite_bulk_action_to_dropdown"));
add_action('admin_action_invite_to_clef', array($this, "handle_invite_bulk_action"));
add_action('admin_notices', array($this, 'handle_invite_bulk_action_admin_notices') );
add_action('admin_notices', array($this, 'display_messages') );
add_action('clef_onboarding_after_first_login', array($this, 'disable_passwords_for_clef_users'));
add_action('wp_dashboard_setup', array($this, 'add_dashboard_widget'));
Expand Down Expand Up @@ -360,6 +363,59 @@ public function disable_passwords_for_clef_users() {
$this->settings->generate_and_send_override_link(wp_get_current_user());
}

public function add_invite_bulk_action_to_dropdown() {
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('<option>').val('invite_to_clef').text('Invite to use Clef')
.appendTo("select[name='action'], select[name='action2']");
});
</script>
<?php
}

public function handle_invite_bulk_action () {
$user_is_admin = current_user_can('manage_options');
if (isset($_REQUEST['users']) && isset($_REQUEST['_wpnonce']) && $user_is_admin) {
check_admin_referer('bulk-users');

$users = get_users(array("include" => $_REQUEST['users']));
if (empty($users)) {
return new WP_Error('no_users', __("No users were invited to use Clef.", "wpclef"));
}

try {
ClefInvite::invite_users($users, false);

$redirect_to = remove_query_arg('action', wp_get_referer());
wp_redirect(add_query_arg('clef_invite_success', count($users), $redirect_to));
exit();

} catch (Exception $e) {
add_settings_error(
CLEF_OPTIONS_NAME,
"clef_invite_error",
sprintf(__("There was an error inviting users to Clef: %s", "wpclef"), $e->getMessage()),
"error"
);
unset($_GET['_wp_http_referer']);
}

}
}

public function handle_invite_bulk_action_admin_notices() {
if (isset($_GET['clef_invite_success'])) {
$num_invited = (int) $_GET['clef_invite_success'];
add_settings_error(
CLEF_OPTIONS_NAME,
"clef_invite_success",
sprintf(__("%d %s successfully invited to Clef.", "wpclef"), $num_invited, _n("user", "users", $num_invited)),
"updated"
);
}
}

public function add_dashboard_widget() {
if ($this->settings->is_configured()) return;

Expand Down Expand Up @@ -431,27 +487,12 @@ public function ajax_invite_users() {
return new WP_Error('no_users', __("there are no other users without Clef with this role or greater", "wpclef"));
}

$errors = array();
foreach ($filtered_users as &$user) {
$invite = new ClefInvite($user, $is_network_admin);
$invite->persist();
$success = $invite->send_email($from_email);
if (!$success) {
$errors[] = $user->user_email;
}
}

if (count($errors) > 0) {
if (count($errors) == count($filtered_users)) {
$message = __("there was an error sending the invite email to all users. Copy and paste the preview email to your users and they'll be walked through a tutorial to connect with Clef", 'wpclef');
} else {
$message = __("unable to send emails to the following users: ", 'wpclef');
$message .= join(", ", $errors);
$message .= __(". Copy and paste the preview email to your users and they'll be walked through a tutorial to connect with Clef", 'wpclef');
}
return new WP_Error('clef_mail_error', $message);
} else {
return array("success" => true);
try {
ClefInvite::invite_users($filtered_users, $is_network_admin);
$num_invited = count($filtered_users);
return array("success" => true, "message" => sprintf(__("%d %s successfully invited to Clef.", "wpclef"), $num_invited, _n("user", "users", $num_invited)));
} catch (Exception $e) {
return new WP_Error('clef_email_error', $e->getMessage());
}
}

Expand Down
28 changes: 27 additions & 1 deletion includes/class.clef-invite.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class ClefInvite {
public $code;
public $created_at;
private $user_email;

function __construct($user, $is_network_admin=false) {
$this->code = md5(uniqid(mt_rand(), true));
$this->user_email = $user->user_email;
Expand Down Expand Up @@ -33,7 +34,7 @@ function get_link() {
'&clef_invite_id=' . urlencode(base64_encode($this->user_email)));
}

function send_email($from_email) {
function send_email() {
if (empty($this->user_email)) return true;

$subject = '['. $this->site_name . '] ' . __('Set up Clef for your account', "wpclef");
Expand All @@ -50,6 +51,31 @@ function send_email($from_email) {
$vars
);
}

public static function invite_users($users, $is_network_admin) {
$errors = array();
foreach ($users as &$user) {
$invite = new ClefInvite($user, $is_network_admin);
$invite->persist();
$success = $invite->send_email();
if (!$success) {
$errors[] = $user->user_email;
}
}

if (count($errors) > 0) {
if (count($errors) == count($filtered_users)) {
$message = __("there was an error sending the invite email to all users. Copy and paste the preview email to your users and they'll be walked through a tutorial to connect with Clef", 'wpclef');
} else {
$message = __("unable to send emails to the following users: ", 'wpclef');
$message .= join(", ", $errors);
$message .= __(". Copy and paste the preview email to your users and they'll be walked through a tutorial to connect with Clef", 'wpclef');
}
throw new Exception($message);
} else {
return true;
}
}
}

?>
1 change: 0 additions & 1 deletion includes/class.clef-translation.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public static function javascript() {
"success" => array(
"connect" => __("You've successfully connected your account with Clef", "wpclef"),
"configured" => __("You're all set up!", "wpclef"),
"invite" => __("Email invitations have been sent to your users.", "wpclef"),
"disconnect" => __("Successfully disconnected Clef account.", "wpclef")
),
"saving" => __("Settings are being saved. Are you sure you want to navigate away?", "wpclef")
Expand Down
22 changes: 16 additions & 6 deletions templates/js-templates/invite.tpl.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
<script id="invite-users-template" type="text/template">
<div class="invite-users">
<a class="next" style="display:none;"><?php _e("Skip and finish setup", "wpclef"); ?></a>
<div class="inputs-container">
<div class="header">
<h3><?php _e('Invite your users', "wpclef"); ?></h3>
<h4 class='subheader'><?php _e('Your site is only as secure as its weakest password.', "wpclef"); ?></h4>
<div class="invite-users__individually-container">
<h3>Invite users individually or in bulk</h3>
<div>
<img src="<?php echo CLEF_URL ?>assets/dist/img/invite.png" alt="invite individual users" class="invite-users__img">
<div class="invite-users__individually">
<p><?php _e("To invite users individually or in bulk, go to the users page and use the dropdown.", "wpclef"); ?></p>
<a href="<?php echo admin_url('users.php') ?>" class="button button-primary" target="_blank"><?php _e("Go to users page", "wpclef"); ?></a>
</div>
<div class="clear"></div>
</div>
</div>


<h3>Invite users by role</h3>
<p><?php _e("We've made it really easy to get all of your site's users up and running with Clef. Click the button below and we'll send an email inviting your users to set up their Clef account on your site. The invite email has <b>step-by-step instructions</b> and a video walkthrough.", "wpclef"); ?></p>

<div class="input-container">
Expand All @@ -18,8 +29,7 @@
<option value="Super Administrator"><?php _e("Super Administrator", "wpclef"); ?></option>
</select>
</div>
<a href="#" name="invite-users-button" class="button button-primary"><?php _e("Invite Users", "wpclef"); ?></a>
<div class="button next" style="display:none;"><?php _e("Continue and finish setup", "wpclef"); ?></div>
<a href="#" name="invite-users-button" class="button button-primary invite-role-button"><?php _e("Invite users by role", "wpclef"); ?></a>
</div>

<div class="preview-container">
Expand All @@ -29,4 +39,4 @@
</div>
</div>
</div>
</script>
</script>