Commit b25fef73 authored by Henning Leutz's avatar Henning Leutz 🥋

Merge branch 'dev'

parents 70e0aba5 9bc8428c
<?php
/**
* This file contains package_quiqqer_frontend-users_ajax_frontend_profile_getControl
*/
use QUI\FrontendUsers\Utils;
/**
* @return string
* @throws \QUI\FrontendUsers\Exception
*/
QUI::$Ajax->registerFunction(
'package_quiqqer_frontend-users_ajax_frontend_profile_save',
......@@ -19,6 +18,14 @@ QUI::$Ajax->registerFunction(
$Request->request->set('profile-save', 1);
// Check permission
if (!Utils::hasPermissionToViewCategory($category, $settings)) {
throw new \QUI\FrontendUsers\Exception(
'quiqqer/frontend-users',
'exception.ajax.frontend.profile.save.no_category_permission'
);
}
$Control = QUI\FrontendUsers\Utils::getProfileSettingControl($category, $settings);
$Control->setAttribute('User', QUI::getUserBySession());
$Control->onSave();
......
......@@ -66,6 +66,19 @@ define('package/quiqqer/frontend-users/bin/frontend/controls/RegistrationSignUp'
QUI.fireEvent('quiqqerFrontendUsersRegisterStart', [this]);
// redirect
var Redirect = this.$Elm.getElement(
'.quiqqer-fu-registrationSignUp-registration-redirect'
);
if (Redirect) {
var redirectUrl = Redirect.get('data-redirecturl');
(function() {
window.location = redirectUrl;
}).delay(5000);
}
// if user, sign in is not possible
if (window.QUIQQER_USER.id) {
this.$RegistrationSection = this.getElm().getElement(
......
......@@ -23,7 +23,7 @@ define('package/quiqqer/frontend-users/bin/frontend/controls/login/Window', [
],
options: {
maxHeight: 600,
maxHeight: 640,
maxWidth : 500,
buttons : false,
logo : false
......
......@@ -27,7 +27,8 @@ define('package/quiqqer/frontend-users/bin/frontend/controls/profile/DeleteAccou
],
options: {
username: ''
username : '',
deletestarted: 0
},
initialize: function (options) {
......@@ -59,7 +60,7 @@ define('package/quiqqer/frontend-users/bin/frontend/controls/profile/DeleteAccou
}
SubmitBtn.addEvent('click', function (event) {
if (confirmed) {
if (confirmed || self.getAttribute('deletestarted')) {
return;
}
......@@ -92,7 +93,7 @@ define('package/quiqqer/frontend-users/bin/frontend/controls/profile/DeleteAccou
var SubmitBtn = Popup.getButton('submit');
SubmitBtn.disable();
Popup.Loader.show();
self.$checkDeleteAccount().then(function () {
......
<?xml version="1.0" encoding="UTF-8"?>
<console>
<tool exec="\QUI\FrontendUsers\Console\SendUserMails" />
<tool exec="\QUI\FrontendUsers\Console\SetUserGroups" />
</console>
\ No newline at end of file
......@@ -719,6 +719,41 @@
</groups>
<groups name="quiqqer/frontend-users" datatype="php">
<!-- Control: RegistrationSignUp -->
<locale name="RegistrationSignUp.message.success.activation">
<de><![CDATA[Ihr Benutzerkonto wurde erfolgreich aktiviert. Sie können Sich nun einloggen.]]></de>
<en><![CDATA[Your user account has been activated successfully. You can now sign in.]]></en>
</locale>
<locale name="RegistrationSignUp.message.success.activation_logged_in">
<de><![CDATA[Ihr Benutzerkonto wurde erfolgreich aktiviert.]]></de>
<en><![CDATA[Your user account has been activated successfully.]]></en>
</locale>
<locale name="RegistrationSignUp.message.success.emailconfirm">
<de><![CDATA[Ihre E-Mail-Adresse wurde erfolgreich bestätigt.]]></de>
<en><![CDATA[Your e-mail address has been confirmed successfully.]]></en>
</locale>
<locale name="RegistrationSignUp.message.success.userdelete">
<de><![CDATA[Ihre Benutzerkonto wurde erfolgreich gelöscht.]]></de>
<en><![CDATA[Your user account has been successfully.]]></en>
</locale>
<locale name="RegistrationSignUp.message.error.activation">
<de><![CDATA[Leider hat ist bei der Aktivierung Ihres Benutzerkontos ein Fehler aufgetreten. Bitte wiederholen Sie den Vorgang.]]></de>
<en><![CDATA[Unfortunately an error occurred during the activation of your user account. Please repeat the process.]]></en>
</locale>
<locale name="RegistrationSignUp.message.error.emailconfirm">
<de><![CDATA[Leider ist bei der Bestätigung Ihres E-Mail-Adresse ein Fehler aufgetreten. Bitte wiederholen Sie den Vorgang.]]></de>
<en><![CDATA[Unfortunately, an error occurred when confirming your e-mail address. Please repeat the process.]]></en>
</locale>
<locale name="RegistrationSignUp.message.errro.userdelete">
<de><![CDATA[Leider ist beim Löschen Ihres Benutzerkontos ein Fehler aufgetreten. Bitte wiederholen Sie den Vorgang.]]></de>
<en><![CDATA[Unfortunately an error occurred when deleting your user account. Please repeat the process.]]></en>
</locale>
<locale name="RegistrationSignUp.message.redirect">
<de><![CDATA[Sie werden in wenigen Sekunden automatisch weitergeleitet.]]></de>
<en><![CDATA[You will be automatically redirected in a few seconds.]]></en>
</locale>
<locale name="message.UserDeleteConfirmVerification.success">
<de><![CDATA[Ihr Benuterkonto wurde erfolgreich gelöscht.]]></de>
<en><![CDATA[Your user account has been successfully deleted.]]></en>
......@@ -1520,17 +1555,19 @@ The deletion of your user account on [host] was requested on [date]. Please conf
<de><![CDATA[Konto erstellen]]></de>
<en><![CDATA[Create Account]]></en>
</locale>
<!-- Control: package/quiqqer/frontend-users/bin/frontend/controls/profile/DeleteAccount -->
<locale name="controls.profile.DeleteAccount.confirm.information" html="true">
<de><![CDATA[Ihr Benutzerkonto <b>[username]</b> und alle damit verbundenen Vorteile gehen mit dem Löschvorgang verloren. Ihre persönlichen Daten werden, soweit nicht für geschäftliche Zwecke rechtlich notwendig, gelöscht. Sie müssen die Löschung über einen Link, der Ihnen per E-Mail zugesandt wird, bestätigen.]]></de>
<en><![CDATA[Your user account <b>[username]</b> and all associated benefits will be lost with the deletion process. Your personal data will be deleted unless legally required for business purposes. You must confirm the deletion via a link sent to you by e-mail.]]></en>
<de>
<![CDATA[Ihr Benutzerkonto <b>[username]</b> und alle damit verbundenen Vorteile gehen mit dem Löschvorgang verloren. Ihre persönlichen Daten werden, soweit nicht für geschäftliche Zwecke rechtlich notwendig, gelöscht. Sie müssen die Löschung über einen Link, der Ihnen per E-Mail zugesandt wird, bestätigen.]]></de>
<en>
<![CDATA[Your user account <b>[username]</b> and all associated benefits will be lost with the deletion process. Your personal data will be deleted unless legally required for business purposes. You must confirm the deletion via a link sent to you by e-mail.]]></en>
</locale>
<locale name="controls.profile.DeleteAccount.confirm.information_error" html="true">
<de><![CDATA[Ihr Benutzerkonto <b>[username]</b> kann z.Z. nicht gelöscht werden:<br/><br/>[error]]]></de>
<en><![CDATA[You user account <b>[username]</b> can currently not be deleted:<br/><br/>[error]]]></en>
</locale>
<locale name="controls.profile.DeleteAccount.confirm.text">
<de><![CDATA[Möchten Sie Ihr Benutzerkonto wirklich löschen?]]></de>
<en><![CDATA[Do you really want to delete your user account?]]></en>
......@@ -1543,6 +1580,6 @@ The deletion of your user account on [host] was requested on [date]. Please conf
<de><![CDATA[Ja, Benutzerkonto löschen]]></de>
<en><![CDATA[Yes, delete user account]]></en>
</locale>
</groups>
</locales>
\ No newline at end of file
......@@ -89,30 +89,16 @@ class ActivationVerification extends AbstractVerification
public function getOnSuccessRedirectUrl()
{
$RegistrarHandler = Handler::getInstance();
$RegistrationSite = $RegistrarHandler->getRegistrationSite(
$RegistrationSite = $RegistrarHandler->getRegistrationSignUpSite(
$this->getProject()
);
if (!$RegistrationSite) {
// Fallback if no registration site is set up
$registrationSettings = $RegistrarHandler->getRegistrationSettings();
$projectLang = $Project = QUI::getRewrite()->getProject()->getLang();
if (!empty($registrationSettings['autoRedirectOnSuccess'][$projectLang])) {
$RedirectSite = QUI\Projects\Site\Utils::getSiteByLink(
$registrationSettings['autoRedirectOnSuccess'][$projectLang]
);
return $RedirectSite->getUrlRewrittenWithHost();
}
if (empty($RegistrationSite)) {
return false;
}
return $RegistrationSite->getUrlRewritten([
'success'
], [
'registrar' => $this->getRegistrarHash()
return $RegistrationSite->getUrlRewritten([], [
'success' => 'activation'
]);
}
......@@ -123,7 +109,7 @@ class ActivationVerification extends AbstractVerification
*/
public function getOnErrorRedirectUrl()
{
$RegistrationSite = Handler::getInstance()->getRegistrationSite(
$RegistrationSite = Handler::getInstance()->getRegistrationSignUpSite(
QUI::getRewrite()->getProject()
);
......@@ -131,10 +117,8 @@ class ActivationVerification extends AbstractVerification
return false;
}
return $RegistrationSite->getUrlRewritten([
'error'
], [
'registrar' => $this->getRegistrarHash()
return $RegistrationSite->getUrlRewritten([], [
'error' => 'activation'
]);
}
......
<?php
namespace QUI\FrontendUsers\Console;
use QUI;
/**
* Console tool to send an e-mail to all (or a subset of) users in the system
*
* @author www.pcsg.de (Patrick Müller)
*/
class SendUserMails extends QUI\System\Console\Tool
{
/**
* Constructor
*/
public function __construct()
{
$this->setName('frontend-users:sendUserMails')
->setDescription(
"Send an e-mail to all (or subset of) users in the system"
);
$this->addArgument(
'bodyfile',
'File that contains the e-mail body (plaintext or html)'
);
}
/**
* Execute the console tool
*/
public function execute()
{
QUI\Permissions\Permission::isAdmin();
$bodyFile = $this->getArgument('bodyfile');
if (!file_exists($bodyFile) || !is_readable($bodyFile)) {
$this->exitFail("Body file $bodyFile was not found or is not readable by PHP.");
}
$body = file_get_contents($bodyFile);
// Determine users the email is being sent to
// LOCALE
$this->writeLn("System LOCALE language? [en]: ");
$lang = $this->readInput();
QUI::getLocale()->setCurrent($lang);
// INCLUDE INACTIVE USERS?
$this->writeLn("Send mail to INACTIVE users? (y/N): ");
$inactiveUsers = mb_strtolower($this->readInput()) === 'y';
// USER LANGUAGE
$this->writeLn("Languages of the users? (comma separated language abbreviations) [en]: ");
$languages = $this->readInput();
if (!empty($languages)) {
$languages = explode(',', $languages);
} else {
$languages = ['en'];
}
// RESTRICT TO GROUPS
$this->writeLn(
"Send mail to users in the following GROUPS only (comma separated list of group ids;"
." leave empty to ignore groups): "
);
$groupIds = $this->readInput();
if (empty($groupIds)) {
$groupIds = [];
} else {
$groupIds = explode(',', $groupIds);
}
// ORDER BY
$this->writeLn("ORDER BY clause for the `users` table (leave empty to use default order): ");
$orderBy = $this->readInput();
// Get all users
$sql = "SELECT `id`, `username`, `email`, `firstname`, `lastname` FROM ".QUI::getUsers()::table();
$where[] = "`lang` IN ('".implode("','", $languages)."')";
if (!$inactiveUsers) {
$where[] = "`active` = 1";
}
if (!empty($groupIds)) {
$whereOR = [];
foreach ($groupIds as $groupId) {
$whereOR[] = "`usergroup` LIKE '%,$groupId,%'";
}
$where[] = "(".implode(" OR ", $whereOR).")";
}
$sql .= " WHERE ".implode(" AND ", $where);
if (!empty($orderBy)) {
$sql .= " ORDER BY $orderBy";
}
$result = QUI::getDataBase()->fetchSQL($sql);
$recipients = [];
foreach ($result as $row) {
if (empty($row['email'])) {
continue;
}
$recipients[] = $row;
}
// EMAIL SETTINGS
$this->writeLn("E-Mail subject?: ");
$subject = $this->readInput();
$this->writeLn("E-Mail sender mail? [system default]: ");
$senderMail = $this->readInput();
if (empty($senderMail)) {
$senderMail = QUI::conf('mail', 'MAILFrom');
}
$this->writeLn("E-Mail sender name? [system default]: ");
$senderName = $this->readInput();
if (empty($senderName)) {
$senderName = QUI::conf('mail', 'MAILFromText');
}
// SUMMARY
$this->writeLn("\nSUMMARY\n===============================================\n");
$this->writeLn("LOCALE language: ".$lang);
$this->writeLn("Include INACTIVE users: ".($inactiveUsers ? "YES" : "NO"));
$this->writeLn("User languages: ".implode(', ', $languages));
$this->writeLn("User groups: ".(empty($groupIds) ? "ALL" : implode(', ', $groupIds)));
$this->writeLn("ORDER BY: ".(empty($orderBy) ? "DEFAULT" : $orderBy));
$this->writeLn("\nE-Mail subject: ".$subject);
$this->writeLn("\nE-Mail sender mail: ".$senderMail);
$this->writeLn("\nE-Mail sender name: ".$senderName);
$this->writeLn(
"\nE-Mail will be sent to ".count($recipients)." out of ".count($result)." selected users."
." ".(count($result) - count($recipients))." users have no e-mail address and are ignored."
);
// TEST MAIL
$this->writeLn("\n\nSend test mail? (Y/n): ");
$testMail = mb_strtolower($this->readInput()) !== 'n';
if ($testMail) {
$this->writeLn("Test e-mail address: ");
$testEmailAddress = $this->readInput();
if (!empty($testEmailAddress)) {
$this->writeLn("\nSend test mail...");
$this->sendMails(
$body,
$senderMail,
$senderName,
$subject,
[
0 => [
'username' => 'Test-User',
'email' => $testEmailAddress
]
]
);
$this->write(" SENT!");
}
}
// CONFIRM AND SEND E-MAILS
$this->writeLn("\n\nIs everything correct? Send e-mails NOW? (Y/n): ");
$confirm = mb_strtolower($this->readInput()) !== 'n';
if (!$confirm) {
$this->execute();
return;
}
$this->sendMails($body, $senderMail, $senderName, $subject, $recipients);
$this->exitSuccess();
}
/**
* @param string $body
* @param string $senderMail
* @param string $senderName
* @param string $subject
* @param array $recipients
* @return void
*/
protected function sendMails($body, $senderMail, $senderName, $subject, $recipients)
{
// Queue mails
foreach ($recipients as $recipient) {
if (!empty($recipient['firstname']) && !empty($recipient['lastname'])) {
$name = $recipient['firstname'].' '.$recipient['lastname'];
} else {
$name = $recipient['username'];
}
$email = $recipient['email'];
$body = str_replace(
['[name]', '[email]'],
[$name, $email],
$body
);
$Mailer = QUI::getMailManager()->getMailer();
$Mailer->setFrom($senderMail);
$Mailer->setFromName($senderName);
$Mailer->setSubject($subject);
$Mailer->setHTML(true);
$Mailer->setBody($body);
$Mailer->addRecipient($email);
$Mailer->send();
}
}
/**
* Exits the console tool with a success msg and status 0
*
* @return void
*/
protected function exitSuccess()
{
$this->writeLn("Mails have been successfully queued and will be sent via cron.");
$this->writeLn("");
exit(0);
}
/**
* Exits the console tool with an error msg and status 1
*
* @param $msg
* @return void
*/
protected function exitFail($msg)
{
$this->writeLn("Script aborted due to an error:");
$this->writeLn("");
$this->writeLn($msg);
$this->writeLn("");
$this->writeLn("");
exit(1);
}
}
<?php
namespace QUI\FrontendUsers\Console;
use QUI;
/**
* Console tool to add users to groups
*
* @author www.pcsg.de (Patrick Müller)
*/
class SetUserGroups extends QUI\System\Console\Tool
{
/**
* Constructor
*/
public function __construct()
{
$this->setName('frontend-users:setUserGroups')
->setDescription(
"Add users to groups"
);
}
/**
* Execute the console tool
*/
public function execute()
{
QUI\Permissions\Permission::isAdmin();
// Determine groups
$this->writeLn(
"Add users to the following groups (comma separated list of group ids): "
);
$groupIds = $this->readInput();
if (empty($groupIds)) {
$this->exitSuccess();
}
$groupIds = explode(',', $groupIds);
// Determine users
// INCLUDE INACTIVE USERS?
$this->writeLn("Include INACTIVE users? (y/N): ");
$inactiveUsers = mb_strtolower($this->readInput()) === 'y';
// USER LANGUAGE
$this->writeLn("Languages of the users? (comma separated language abbreviations) [all]: ");
$languages = $this->readInput();
if (!empty($languages) && mb_strtolower($languages) !== 'all') {
$languages = explode(',', $languages);
} else {
$languages = false;
}
// RESTRICT TO GROUPS
$this->writeLn(
"Select users in the following GROUPS only (comma separated list of group ids;"
." leave empty to ignore groups): "
);
$userGroupIds = $this->readInput();
if (empty($userGroupIds)) {
$userGroupIds = [];
} else {
$userGroupIds = explode(',', $userGroupIds);
}
// Get all users
$sql = "SELECT `id` FROM ".QUI::getUsers()::table();
$where = [];
if (!empty($languages)) {
$where[] = "`lang` IN ('".implode("','", $languages)."')";
}
if (!$inactiveUsers) {
$where[] = "`active` = 1";
}
if (!empty($userGroupIds)) {
$whereOR = [];
foreach ($userGroupIds as $groupId) {
$whereOR[] = "`usergroup` LIKE '%,$groupId,%'";
}
$where[] = "(".implode(" OR ", $whereOR).")";
}
if (!empty($where)) {
$sql .= " WHERE ".implode(" AND ", $where);
}
$result = QUI::getDataBase()->fetchSQL($sql);
// SUMMARY
$this->writeLn("\nSUMMARY\n===============================================\n");
$this->writeLn("Add users to groups: ".implode(', ', $groupIds));
$this->writeLn("Include INACTIVE users: ".($inactiveUsers ? "YES" : "NO"));
$this->writeLn("User languages: ".(empty($languages) ? 'ALL' : implode(', ', $languages)));
$this->writeLn(
"Select users in this groups only: ".(empty($userGroupIds) ? "ALL" : implode(', ', $userGroupIds))
);
$this->writeLn("\n\nIs everything correct? (Y/n): ");
$confirm = mb_strtolower($this->readInput()) !== 'n';
if (!$confirm) {
$this->execute();
return;
}
// Set groups
$this->writeLn("\n\nSTART SETTING GROUPS\n");
$Users = QUI::getUsers();
$SystemUser = QUI::getUsers()->getSystemUser();
foreach ($result as $row) {
$User = $Users->get($row['id']);
$this->writeLn("Add groups for User #".$User->getId()." (".$User->getUsername().")...");
foreach ($groupIds as $groupId) {
try {
$this->writeLn("\tGroup #$groupId...");
$User->addToGroup($groupId);
$User->save($SystemUser);
$this->write(" OK!");
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
$this->write(" ERROR: ".$Exception->getMessage());
}
}
}
$this->exitSuccess();
}
/**
* Exits the console tool with a success msg and status 0
*
* @return void
*/
protected function exitSuccess()
{
$this->writeLn("User groups have been successfully set.");
$this->writeLn("");
exit(0);
}
/**
* Exits the console tool with an error msg and status 1
*
* @param $msg
* @return void
*/
protected function exitFail($msg)
{
$this->writeLn("Script aborted due to an error:");
$this->writeLn("");
$this->writeLn($msg);
$this->writeLn("");
$this->writeLn("");
exit(1);
}
}
......@@ -51,6 +51,7 @@ class DeleteAccount extends AbstractProfileControl
if (Verifier::isVerificationValid($DeleteVerification)) {
$action = 'deleteaccount_confirm_wait';
$this->setJavaScriptControlOption('deletestarted', 1);
} else {
Verifier::removeVerification($DeleteVerification);
}
......
......@@ -299,6 +299,16 @@ class Registration extends QUI\Control
return $FilteredRegistrars;
}
/**
* Get the user that registered in this instance
*
* @return QUI\Users\User|null
*/
public function getRegisteredUser()
{
return $this->RegisteredUser;
}
/**
* Is registration started?
*
......
......@@ -88,6 +88,11 @@
padding-left: 30px;
}
.quiqqer-fu-registrationSignUp-registration-redirect {
display: block;
margin-top: 20px;
}
/** registration sign in
========================================== */
......@@ -138,6 +143,7 @@
right: -20px;
top: -20px;
z-index: 10;
cursor: pointer;
}
.quiqqer-fu-registrationSignUp-terms button[name="decline"]:hover {
......
......@@ -5,13 +5,28 @@
</noscript>
<section class="quiqqer-fu-registrationSignUp-registration" style="display: none">
{if $SessionUser->getId()}
{if $showLoggedInWarning}
<div class="quiqqer-fu-registrationSignUp-registration-logged-in message-information">
{locale group="quiqqer/frontend-users" var="message.types.registration.already_registered"}
</div>