</pages>
</action>
- <action name="sendMail">
- <actionclassname><![CDATA[wcf\system\clipboard\action\UserClipboardAction]]></actionclassname>
+ <action name="merge">
+ <actionclassname><![CDATA[wcf\system\clipboard\action\UserExtendedClipboardAction]]></actionclassname>
+ <showorder>4</showorder>
+ <pages>
+ <page><![CDATA[wcf\acp\page\UserListPage]]></page>
+ </pages>
+ </action>
+
+ <action name="enable">
+ <actionclassname><![CDATA[wcf\system\clipboard\action\UserExtendedClipboardAction]]></actionclassname>
<showorder>5</showorder>
<pages>
<page><![CDATA[wcf\acp\page\UserListPage]]></page>
</pages>
</action>
- <action name="exportMailAddress">
+ <action name="sendMail">
<actionclassname><![CDATA[wcf\system\clipboard\action\UserClipboardAction]]></actionclassname>
<showorder>6</showorder>
<pages>
</pages>
</action>
- <action name="merge">
- <actionclassname><![CDATA[wcf\system\clipboard\action\UserExtendedClipboardAction]]></actionclassname>
- <showorder>4</showorder>
+ <action name="exportMailAddress">
+ <actionclassname><![CDATA[wcf\system\clipboard\action\UserClipboardAction]]></actionclassname>
+ <showorder>7</showorder>
<pages>
<page><![CDATA[wcf\acp\page\UserListPage]]></page>
</pages>
</action>
- <action name="enable">
- <actionclassname><![CDATA[wcf\system\clipboard\action\UserExtendedClipboardAction]]></actionclassname>
- <showorder>5</showorder>
+
+ <action name="sendNewPassword">
+ <actionclassname><![CDATA[wcf\system\clipboard\action\UserClipboardAction]]></actionclassname>
+ <showorder>8</showorder>
<pages>
<page><![CDATA[wcf\acp\page\UserListPage]]></page>
</pages>
/**
* Initialize WCF.ACP namespace
*/
-WCF.ACP = {};
+WCF.ACP = { };
/**
* Namespace for ACP application management.
this._setIcon('spinner');
// collect form values
- var $additionalData = {};
+ var $additionalData = { };
$('#packageInstallationInnerContent input').each(function(index, inputElement) {
var $inputElement = $(inputElement);
var $type = $inputElement.attr('type');
* @param object additionalData
*/
_executeStep: function(step, node, additionalData) {
- if (!additionalData) additionalData = {};
+ if (!additionalData) additionalData = { };
var $data = $.extend({
node: node,
/**
* Namespace for category-related functions.
*/
-WCF.ACP.Category = {};
+WCF.ACP.Category = { };
/**
* Handles collapsing categories.
$('.collapsibleButton').remove();
// reinit containers
- this._containers = {};
- this._containerData = {};
+ this._containers = { };
+ this._containerData = { };
var $containers = this._getContainers();
if ($containers.length == 0) {
}
};
+/**
+ * Handles the send new password clipboard action.
+ */
+WCF.ACP.User.SendNewPasswordHandler = {
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * Initializes WCF.ACP.User.SendNewPasswordHandler on first use.
+ */
+ init: function() {
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+
+ // bind clipboard event listener
+ $('.jsClipboardEditor').each($.proxy(function(index, container) {
+ var $container = $(container);
+ var $types = eval($container.data('types'));
+ if (WCF.inArray('com.woltlab.wcf.user', $types)) {
+ $container.on('clipboardAction', $.proxy(this._execute, this));
+ return false;
+ }
+ }, this));
+ },
+
+ /**
+ * Handles clipboard actions.
+ *
+ * @param object event
+ * @param string type
+ * @param string actionName
+ * @param object parameters
+ */
+ _execute: function(event, type, actionName, parameters) {
+ if (actionName == 'com.woltlab.wcf.user.sendNewPassword') {
+ WCF.System.Confirmation.show(parameters.confirmMessage, function(action) {
+ if (action === 'confirm') {
+ new WCF.ACP.Worker('sendingNewPasswords', 'wcf\\system\\worker\\SendNewPasswordWorker', WCF.Language.get('wcf.acp.user.sendNewPassword.workerTitle'), {
+ userIDs: parameters.objectIDs
+ });
+ }
+ });
+ }
+ }
+};
+
/**
* Namespace for import-related classes.
*/
WCF.Language.addObject({
'wcf.acp.user.banReason': '{lang}wcf.acp.user.banReason{/lang}',
'wcf.acp.user.banReason.description': '{lang}wcf.acp.user.banReason.description{/lang}',
- 'wcf.acp.user.ban.sure': '{lang}wcf.acp.user.ban.sure{/lang}'
+ 'wcf.acp.user.ban.sure': '{lang}wcf.acp.user.ban.sure{/lang}',
+ 'wcf.acp.user.sendNewPassword.workerTitle': '{lang}wcf.acp.user.sendNewPassword.workerTitle{/lang}',
+ 'wcf.acp.worker.abort.confirmMessage': '{lang}wcf.acp.worker.abort.confirmMessage{/lang}'
});
WCF.ACP.User.BanHandler.init();
- {if $__wcf->session->getPermission('admin.user.canEnableUser')}WCF.ACP.User.EnableHandler.init();{/if}
+
+ {if $__wcf->session->getPermission('admin.user.canEnableUser')}
+ WCF.ACP.User.EnableHandler.init();
+ {/if}
+
+ {if $__wcf->session->getPermission('admin.user.canEditPassword')}
+ WCF.ACP.User.SendNewPasswordHandler.init();
+ {/if}
{event name='javascriptInit'}
});
/**
* @see \wcf\system\clipboard\action\AbstractClipboardAction::$supportedActions
*/
- protected $supportedActions = array('assignToGroup', 'ban', 'delete', 'exportMailAddress', 'sendMail');
+ protected $supportedActions = array('assignToGroup', 'ban', 'delete', 'exportMailAddress', 'sendMail', 'sendNewPassword');
/**
* @see \wcf\system\clipboard\action\IClipboardAction::execute()
case 'sendMail':
$item->setURL(LinkHandler::getInstance()->getLink('UserMail'));
break;
+
+ case 'sendNewPassword':
+ $item->addParameter('confirmMessage', WCF::getLanguage()->getDynamicVariable('wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword.confirmMessage', array(
+ 'count' => $item->getCount()
+ )));
+ break;
}
return $item;
if (!isset($userToGroup[$row['userID']])) {
$userToGroup[$row['userID']] = array();
}
-
+
$userToGroup[$row['userID']][] = $row['groupID'];
}
return $userIDs;
}
+
+ /**
+ * Returns the ids of the users which can be sent new passwords.
+ *
+ * @return array<integer>
+ */
+ public function validateSendNewPassword() {
+ // check permissions
+ if (!WCF::getSession()->getPermission('admin.user.canEditPassword')) {
+ return array();
+ }
+
+ return $this->__validateAccessibleGroups(array_keys($this->objects));
+ }
}
--- /dev/null
+<?php
+namespace wcf\system\worker;
+use wcf\data\user\UserAction;
+use wcf\data\user\UserEditor;
+use wcf\data\user\UserList;
+use wcf\system\clipboard\ClipboardHandler;
+use wcf\system\exception\SystemException;
+use wcf\system\mail\Mail;
+use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
+use wcf\util\PasswordUtil;
+
+/**
+ * Worker implementation for sending new passwords.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2014 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.worker
+ * @category Community Framework
+ */
+class SendNewPasswordWorker extends AbstractWorker {
+ /**
+ * @see \wcf\system\worker\AbstractWorker::$limit
+ */
+ protected $limit = 50;
+
+ /**
+ * @see \wcf\system\worker\IWorker::countObjects()
+ */
+ public function countObjects() {
+ $userList = new UserList();
+ $userList->getConditionBuilder()->add('user_table.userID IN (?)', array($this->parameters['userIDs']));
+
+ return $userList->countObjects();
+ }
+
+ /**
+ * @see \wcf\system\worker\IWorker::execute()
+ */
+ public function execute() {
+ $userList = new UserList();
+ $userList->decoratorClassName = 'wcf\data\user\UserEditor';
+ $userList->getConditionBuilder()->add('user_table.userID IN (?)', array($this->parameters['userIDs']));
+ $userList->sqlLimit = $this->limit;
+ $userList->sqlOffset = $this->limit * $this->loopCount;
+ $userList->readObjects();
+
+ foreach ($userList as $userEditor) {
+ $this->sendNewPassword($userEditor);
+ }
+ }
+
+ /**
+ * @see \wcf\system\worker\IWorker::getProceedURL()
+ */
+ public function getProceedURL() {
+ return LinkHandler::getInstance()->getLink('UserList');
+ }
+
+ /**
+ * @see \wcf\system\worker\IWorker::getProgress()
+ */
+ public function getProgress() {
+ $progress = parent::getProgress();
+
+ if ($progress == 100) {
+ // unmark users
+ ClipboardHandler::getInstance()->unmark($this->parameters['userIDs'], ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.user'));
+ }
+
+ return $progress;
+ }
+
+ /**
+ * Sends a new password to the given user.
+ *
+ * @param \wcf\data\user\UserEditor $userEditor
+ */
+ protected function sendNewPassword(UserEditor $userEditor) {
+ $newPassword = PasswordUtil::getRandomPassword();
+
+ $userAction = new UserAction(array($userEditor), 'update', array(
+ 'data' => array(
+ 'password' => $newPassword
+ )
+ ));
+ $userAction->executeAction();
+
+ // send mail
+ $mail = new Mail(array($userEditor->username => $userEditor->email), $userEditor->getLanguage()->getDynamicVariable('wcf.acp.user.sendNewPassword.mail.subject'), $userEditor->getLanguage()->getDynamicVariable('wcf.acp.user.sendNewPassword.mail', array(
+ 'password' => $newPassword,
+ 'username' => $userEditor->username,
+ )));
+ $mail->send();
+ }
+
+ /**
+ * @see \wcf\system\worker\IWorker::validate()
+ */
+ public function validate() {
+ WCF::getSession()->checkPermissions(array('admin.user.canEditPassword'));
+
+ if (!isset($this->parameters['userIDs']) || !is_array($this->parameters['userIDs']) || empty($this->parameters['userIDs'])) {
+ throw new SystemException("'userIDs' parameter is missing or invalid");
+ }
+ }
+}
<item name="wcf.acp.user.usersAwaitingApprovalInfo"><![CDATA[<a href="{link controller='UserQuickSearch'}mode=disabled{/link}">{#$usersAwaitingApproval} Benutzer</a> {if $usersAwaitingApproval == 1}wartet auf seine{else}warten auf ihre{/if} Aktivierung.]]></item>
<item name="wcf.acp.user.search.conditions.state.enabled"><![CDATA[Aktiviert]]></item>
<item name="wcf.acp.user.search.conditions.state.disabled"><![CDATA[Nicht aktiviert]]></item>
+ <item name="wcf.acp.user.sendNewPassword.mail"><![CDATA[Hallo {@$username},
+
+Ihr Kennwort wurde von einem Administrator geändert.
+Ihr neues Kennwort lautet: {$password}
+
+Klicken Sie hier, um sich mit Ihrem neuen Kennwort anzumelden: {link controller='Login' isEmail=true}{/link}]]></item>
+ <item name="wcf.acp.user.sendNewPassword.mail.subject"><![CDATA[Neues Kennwort für Ihr Benutzerkonto auf der Website: {@PAGE_TITLE|language}]]></item>
+ <item name="wcf.acp.user.sendNewPassword.workerTitle"><![CDATA[Neue Passwörter zusenden]]></item>
</category>
<category name="wcf.acp.worker">
<item name="wcf.clipboard.item.com.woltlab.wcf.user.delete.confirmMessage"><![CDATA[{if $count == 1}Einen{else}{#$count}{/if} Benutzer löschen?]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.exportMailAddress"><![CDATA[E-Mail-Adressen exportieren]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.sendMail"><![CDATA[E-Mail senden]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword"><![CDATA[Neues Kennwort senden ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword.confirmMessage"><![CDATA[Wollen Sie wirklich {if $count == 1}einem{else}{#$count}{/if} Benutzer ein neues Kennwort zusenden?]]></item>
<item name="wcf.clipboard.label.com.woltlab.wcf.user.marked"><![CDATA[{if $count == 1}Ein{else}{#$count}{/if} Benutzer markiert]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.merge"><![CDATA[Zusammenfügen]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.enable"><![CDATA[Aktivieren]]></item>
<item name="wcf.user.lostPassword.mail"><![CDATA[Hallo {@$username},
wenn Sie Ihr Kennwort vergessen haben, können Sie über folgenden Link ein neues Kennwort anfordern.
-Klicken Sie hier, um ein neues Kennwort anzufordern: {link controller='NewPassword' isEmail=true}u={@$userID}&k={@$key}{/link}
+Klicken Sie hier, um ein neues Kennwort anzufordern: {link controller='NewPassword' isEmail=true}u={@$userID}&k={@$key}{/link}
Falls Sie Ihr Kennwort nicht vergessen haben, können Sie diese E-Mail ignorieren.]]></item>
<item name="wcf.user.lostPassword.mail.sent"><![CDATA[Sie erhalten in Kürze eine E-Mail mit weiteren Informationen.]]></item>
<item name="wcf.acp.user.usersAwaitingApprovalInfo"><![CDATA[<a href="{link controller='UserQuickSearch'}mode=disabled{/link}">{#$usersAwaitingApproval} User{if $usersAwaitingApproval != 1}s{/if}</a> {if $usersAwaitingApproval == 1}is{else}are{/if} awaiting your approval.]]></item>
<item name="wcf.acp.user.search.conditions.state.enabled"><![CDATA[Approved]]></item>
<item name="wcf.acp.user.search.conditions.state.disabled"><![CDATA[Awaiting approval]]></item>
+ <item name="wcf.acp.user.sendNewPassword.mail"><![CDATA[Dear {@$username},
+
+Your password has been changed by an administrator.
+Your new password is: {$password}
+
+Login with your new password: {link controller='Login' isEmail=true}{/link}]]></item>
+ <item name="wcf.acp.user.sendNewPassword.mail.subject"><![CDATA[New Password for your Account for Website: {@PAGE_TITLE|language}]]></item>
+ <item name="wcf.acp.user.sendNewPassword.workerTitle"><![CDATA[Sending New Passwords]]></item>
</category>
<category name="wcf.acp.worker">
<item name="wcf.clipboard.item.com.woltlab.wcf.user.delete.confirmMessage"><![CDATA[Do you really want to delete {#$count} user{if $count != 1}s{/if}?]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.exportMailAddress"><![CDATA[Export Email addresses]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.sendMail"><![CDATA[Send Email]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword"><![CDATA[Send New Password ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword.confirmMessage"><![CDATA[Do you really want to send a new password to {#$count} user{if $count != 1}s{/if}?]]></item>
<item name="wcf.clipboard.label.com.woltlab.wcf.user.marked"><![CDATA[{#$count} User{if $count != 1}s{/if} marked]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.merge"><![CDATA[Merge]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.enable"><![CDATA[Approve]]></item>
<item name="wcf.user.lostPassword.mail"><![CDATA[Dear {@$username},
if you have lost your password you can request a new one using the link below.
-Request a new password: {link controller='NewPassword' isEmail=true}u={@$userID}&k={@$key}{/link}
+Request a new password: {link controller='NewPassword' isEmail=true}u={@$userID}&k={@$key}{/link}
If you have not lost your password, you can safely ignore this email.]]></item>
<item name="wcf.user.lostPassword.mail.sent"><![CDATA[You should receive an email shortly.]]></item>