Skip to content
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
9 changes: 4 additions & 5 deletions wcfsetup/install/files/acp/install_com.woltlab.wcf_step2.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<?php

use wcf\command\user\UpdateUserOnlineMarking;
use wcf\command\user\UpdateUserRank;
use wcf\data\category\CategoryEditor;
use wcf\data\object\type\ObjectTypeCache;
use wcf\data\reaction\type\ReactionTypeEditor;
use wcf\data\user\rank\UserRankEditor;
use wcf\data\user\UserEditor;
use wcf\data\user\UserProfileAction;
use wcf\system\image\adapter\ImagickImageAdapter;
use wcf\system\WCF;

Expand Down Expand Up @@ -44,10 +45,8 @@

// update administrator user rank and user online marking
$editor = new UserEditor(WCF::getUser());
$action = new UserProfileAction([$editor], 'updateUserRank');
$action->executeAction();
$action = new UserProfileAction([$editor], 'updateUserOnlineMarking');
$action->executeAction();
(new UpdateUserRank(WCF::getUser()))();
(new UpdateUserOnlineMarking(WCF::getUser()))();

// install default reactions
foreach ([
Expand Down
10 changes: 4 additions & 6 deletions wcfsetup/install/files/lib/acp/form/UserEditForm.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

namespace wcf\acp\form;

use wcf\command\user\UpdateUserOnlineMarking;
use wcf\command\user\UpdateUserRank;
use wcf\data\file\File;
use wcf\data\style\Style;
use wcf\data\user\cover\photo\IUserCoverPhoto;
use wcf\data\user\group\UserGroup;
use wcf\data\user\User;
use wcf\data\user\UserAction;
use wcf\data\user\UserEditor;
use wcf\data\user\UserProfileAction;
use wcf\form\AbstractForm;
use wcf\system\cache\runtime\FileRuntimeCache;
use wcf\system\cache\runtime\UserProfileRuntimeCache;
Expand All @@ -19,7 +20,6 @@
use wcf\system\html\upcast\HtmlUpcastProcessor;
use wcf\system\message\embedded\object\MessageEmbeddedObjectManager;
use wcf\system\moderation\queue\ModerationQueueManager;
use wcf\system\option\user\UserOptionHandler;
use wcf\system\style\StyleHandler;
use wcf\system\user\command\SetColorScheme;
use wcf\system\user\multifactor\Setup;
Expand Down Expand Up @@ -500,12 +500,10 @@ public function save()

// update user rank
if (MODULE_USER_RANK) {
$action = new UserProfileAction([$this->user], 'updateUserRank');
$action->executeAction();
(new UpdateUserRank($this->user->getDecoratedObject()))();
}
if (MODULE_USERS_ONLINE) {
$action = new UserProfileAction([$this->user], 'updateUserOnlineMarking');
$action->executeAction();
(new UpdateUserOnlineMarking($this->user->getDecoratedObject()))();
}

// remove assignments
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

namespace wcf\command\user;

use wcf\data\user\group\UserGroup;
use wcf\data\user\User;
use wcf\data\user\UserEditor;
use wcf\system\user\storage\UserStorageHandler;

/**
* Updates the mandatory user groups of a user.
* Adds missing groups and removes groups in which the user is not allowed to be.
*
* @author Olaf Braun
* @copyright 2001-2025 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.3
*/
final class UpdateMandatoryUserGroups
{
public function __construct(
private readonly User $user
) {}

/**
* @return list<int>
*/
public function __invoke(): array
{
$groupIDs = $this->user->getGroupIDs();

$fixGroupIDs = [];
$removeGroupIDs = [];

if (!\in_array(UserGroup::EVERYONE, $groupIDs)) {
$fixGroupIDs[] = UserGroup::EVERYONE;
$groupIDs[] = UserGroup::EVERYONE;
}

if ($this->user->pendingActivation()) {
if (!\in_array(UserGroup::GUESTS, $groupIDs)) {
$fixGroupIDs[] = UserGroup::GUESTS;
$groupIDs[] = UserGroup::GUESTS;
}

if (\in_array(UserGroup::USERS, $groupIDs)) {
$removeGroupIDs[] = UserGroup::USERS;
}
} else {
if (!\in_array(UserGroup::USERS, $groupIDs)) {
$fixGroupIDs[] = UserGroup::USERS;
$groupIDs[] = UserGroup::USERS;
}

if (\in_array(UserGroup::GUESTS, $groupIDs)) {
$removeGroupIDs[] = UserGroup::GUESTS;
}
}

$this->addUserGroups($fixGroupIDs);
$this->removeUserGroups($removeGroupIDs);

UserStorageHandler::getInstance()->update($this->user->userID, 'groupIDs', \serialize($groupIDs));

return $groupIDs;
}

/**
* @param list<int> $groupIDs
*/
private function addUserGroups(array $groupIDs): void
{
if ($groupIDs === []) {
return;
}

(new UserEditor($this->user))->addToGroups($groupIDs, false, false);
}

/**
* @param list<int> $groupIDs
*/
private function removeUserGroups(array $groupIDs): void
{
if ($groupIDs === []) {
return;
}

(new UserEditor($this->user))->removeFromGroups($groupIDs);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace wcf\command\user;

use wcf\data\user\User;
use wcf\event\user\UserOnlineMarkingUpdated;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\event\EventHandler;
use wcf\system\WCF;

/**
* Updates the online marking group ID of a user.
*
* @author Olaf Braun
* @copyright 2001-2025 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.3
*/
final class UpdateUserOnlineMarking
{
public function __construct(
private readonly User $user
) {}

public function __invoke(): void
{
$groupIDs = (new UpdateMandatoryUserGroups($this->user))();

$newOnlineGroupID = $this->newOnlineGroupID($groupIDs);

$this->updateOnlineGroupID($newOnlineGroupID);

$event = new UserOnlineMarkingUpdated($this->user, $newOnlineGroupID);
EventHandler::getInstance()->fire($event);
}

/**
* @param list<int> $groupIDs
*/
private function newOnlineGroupID(array $groupIDs): ?int
{
$conditionBuilder = new PreparedStatementConditionBuilder();
$conditionBuilder->add('groupID IN (?)', [$groupIDs]);

$sql = "SELECT groupID
FROM wcf1_user_group
" . $conditionBuilder . "
ORDER BY priority DESC";
$statement = WCF::getDB()->prepare($sql, 1);
$statement->execute($conditionBuilder->getParameters());

return $statement->fetchSingleColumn() ?: null;
}

private function updateOnlineGroupID(?int $newOnlineGroupID): void
{
$sql = "UPDATE wcf1_user SET userOnlineGroupID = ? WHERE userID = ?";
$statement = WCF::getDB()->prepare($sql);

$statement->execute([$newOnlineGroupID, $this->user->userID]);
}
}
64 changes: 64 additions & 0 deletions wcfsetup/install/files/lib/command/user/UpdateUserRank.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace wcf\command\user;

use wcf\data\user\User;
use wcf\data\user\UserEditor;
use wcf\event\user\UserRankUpdated;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\event\EventHandler;
use wcf\system\WCF;

/**
* Updates the rank of a user.
*
* @author Olaf Braun
* @copyright 2001-2025 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.3
*/
final class UpdateUserRank
{
public function __construct(
private readonly User $user
) {}

public function __invoke(): void
{
$newRankID = $this->getNewRankId();

$this->updateUserRank($this->user, $newRankID);

$event = new UserRankUpdated($this->user, $newRankID);
EventHandler::getInstance()->fire($event);
}

private function getNewRankId(): ?int
{
$conditionBuilder = new PreparedStatementConditionBuilder();
$conditionBuilder->add('user_rank.groupID IN (?)', [$this->user->getGroupIDs()]);
$conditionBuilder->add('user_rank.requiredPoints <= ?', [$this->user->activityPoints]);

if ($this->user->gender) {
$conditionBuilder->add('user_rank.requiredGender IN (?)', [[0, $this->user->gender]]);
} else {
$conditionBuilder->add('user_rank.requiredGender = ?', [0]);
}

$sql = "SELECT user_rank.rankID
FROM wcf1_user_rank user_rank
LEFT JOIN wcf1_user_group user_group
ON user_group.groupID = user_rank.groupID
" . $conditionBuilder . "
ORDER BY user_group.priority DESC, user_rank.requiredPoints DESC, user_rank.requiredGender DESC";
$statement = WCF::getDB()->prepare($sql, 1);
$statement->execute($conditionBuilder->getParameters());

return $statement->fetchSingleColumn() ?: null;
}

private function updateUserRank(User $user, ?int $rankID): void
{
(new UserEditor($user))->update(['rankID' => $rankID]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace wcf\command\user;

use wcf\data\user\User;
use wcf\event\user\UserSpecialTrophiesUpdated;
use wcf\system\event\EventHandler;
use wcf\system\user\storage\UserStorageHandler;
use wcf\system\WCF;

/**
* Updates the special trophies of a user.
*
* @author Olaf Braun
* @copyright 2001-2025 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.3
*/
final class UpdateUserSpecialTrophies
{
public function __construct(
private readonly User $user,
/** @var int[] */
private readonly array $trophyIDs
) {
}

public function __invoke(): void
{
$this->deleteExistingSpecialTrophies();
$this->insertSpecialTrophies();

UserStorageHandler::getInstance()->reset([$this->user->userID], 'specialTrophies');

$event = new UserSpecialTrophiesUpdated($this->user, $this->trophyIDs);
EventHandler::getInstance()->fire($event);
}

private function deleteExistingSpecialTrophies(): void
{
$sql = "DELETE FROM wcf1_user_special_trophy
WHERE userID = ?";
$statement = WCF::getDB()->prepare($sql);
$statement->execute([$this->user->userID]);
}

private function insertSpecialTrophies(): void
{
if ($this->trophyIDs === []) {
return;
}

$sql = "INSERT INTO wcf1_user_special_trophy
(userID, trophyID)
VALUES (?, ?)";
$statement = WCF::getDB()->prepare($sql);

foreach ($this->trophyIDs as $trophyID) {
$statement->execute([
$this->user->userID,
$trophyID,
]);
}
}
}
Loading