mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-16 18:04:34 -05:00
minor refactor to simplify removing test users
This commit is contained in:
@@ -592,8 +592,8 @@ class Artist extends BaseObject implements CollageEntry {
|
||||
stem = VALUES(stem),
|
||||
name = VALUES(name),
|
||||
user_id = VALUES(user_id)
|
||||
", $discogs->id(), $this->id, (int)($this->homonymCount() == 0),
|
||||
$discogs->sequence(), $discogs->stem(), $discogs->name(), $this->updateUser->id()
|
||||
", $discogs->id, $this->id, (int)($this->homonymCount() == 0),
|
||||
$discogs->sequence(), $discogs->stem(), $discogs->name(), $this->updateUser->id
|
||||
);
|
||||
return self::$db->affected_rows();
|
||||
}
|
||||
@@ -618,18 +618,17 @@ class Artist extends BaseObject implements CollageEntry {
|
||||
self::$db->begin_transaction();
|
||||
|
||||
// Get the ids of the objects that need to be flushed
|
||||
$oldId = $old->id();
|
||||
$oldName = $old->name();
|
||||
self::$db->prepared_query("
|
||||
SELECT UserID FROM bookmarks_artists WHERE ArtistID = ?
|
||||
", $oldId
|
||||
", $old->id
|
||||
);
|
||||
$bookmarkList = self::$db->collect(0, false);
|
||||
self::$db->prepared_query("
|
||||
SELECT ca.CollageID
|
||||
FROM collages_artists AS ca
|
||||
WHERE ca.ArtistID = ?
|
||||
", $oldId
|
||||
", $old->id
|
||||
);
|
||||
$artistCollageList = self::$db->collect(0, false);
|
||||
self::$db->prepared_query("
|
||||
@@ -637,7 +636,7 @@ class Artist extends BaseObject implements CollageEntry {
|
||||
FROM torrents_artists ta
|
||||
INNER JOIN artists_alias aa ON (ta.AliasID = aa.AliasID)
|
||||
WHERE aa.ArtistID = ?
|
||||
", $oldId
|
||||
", $old->id
|
||||
);
|
||||
$groupList = self::$db->collect(0, false);
|
||||
self::$db->prepared_query("
|
||||
@@ -645,7 +644,7 @@ class Artist extends BaseObject implements CollageEntry {
|
||||
FROM requests_artists ra
|
||||
INNER JOIN artists_alias aa ON (ra.AliasID = aa.AliasID)
|
||||
WHERE aa.ArtistID = ?
|
||||
", $oldId
|
||||
", $old->id
|
||||
);
|
||||
$requestList = self::$db->collect(0, false);
|
||||
|
||||
@@ -656,7 +655,7 @@ class Artist extends BaseObject implements CollageEntry {
|
||||
INNER JOIN torrents_artists ta USING (GroupID)
|
||||
INNER JOIN artists_alias aa ON (ta.AliasID = aa.AliasID)
|
||||
WHERE aa.ArtistID = ?
|
||||
", $oldId
|
||||
", $old->id
|
||||
);
|
||||
$collageList = self::$db->collect(0, false);
|
||||
|
||||
@@ -664,28 +663,28 @@ class Artist extends BaseObject implements CollageEntry {
|
||||
// if it does not yet exists there. Delete any remaining old ids
|
||||
// as the new id is already present in the target object.
|
||||
// In Postgresql this will be handled by a merge statement.
|
||||
$newId = $this->id();
|
||||
$newId = $this->id;
|
||||
self::$db->prepared_query("
|
||||
UPDATE bookmarks_artists
|
||||
LEFT JOIN (SELECT UserID FROM bookmarks_artists WHERE ArtistID = ?) X USING (UserID)
|
||||
SET ArtistID = ?
|
||||
WHERE ArtistID = ? AND X.UserID IS NULL;
|
||||
", $newId, $newId, $oldId
|
||||
", $newId, $newId, $old->id
|
||||
);
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM bookmarks_artists WHERE ArtistID = ?
|
||||
", $oldId
|
||||
", $old->id
|
||||
);
|
||||
self::$db->prepared_query("
|
||||
UPDATE collages_artists Old
|
||||
LEFT JOIN (SELECT CollageID from collages_artists where ArtistID = ?) New using (CollageID)
|
||||
SET Old.ArtistID = ?
|
||||
WHERE Old.ArtistID = ? AND New.CollageID IS NULL
|
||||
", $newId, $newId, $oldId
|
||||
", $newId, $newId, $old->id
|
||||
);
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM collages_artists WHERE ArtistID = ?
|
||||
", $oldId
|
||||
", $old->id
|
||||
);
|
||||
|
||||
// Merge all of this artist's aliases with the new artist
|
||||
@@ -693,7 +692,7 @@ class Artist extends BaseObject implements CollageEntry {
|
||||
UPDATE artists_alias SET
|
||||
ArtistID = ?
|
||||
WHERE ArtistID = ?
|
||||
", $newId, $oldId
|
||||
", $newId, $old->id
|
||||
);
|
||||
|
||||
if ($redirect) {
|
||||
@@ -722,7 +721,7 @@ class Artist extends BaseObject implements CollageEntry {
|
||||
);
|
||||
}
|
||||
|
||||
$commMan->merge('artist', $oldId, $newId);
|
||||
$commMan->merge('artist', $old->id, $newId);
|
||||
|
||||
// Cache clearing
|
||||
self::$cache->delete_multi([array_map(fn ($id) => "notify_artists_$id", $bookmarkList)]);
|
||||
@@ -740,16 +739,16 @@ class Artist extends BaseObject implements CollageEntry {
|
||||
// Delete the old artist
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM artists_group WHERE ArtistID = ?
|
||||
", $oldId
|
||||
", $old->id
|
||||
);
|
||||
$affected = self::$db->affected_rows();
|
||||
self::$db->commit();
|
||||
$this->logger()->general(
|
||||
"The artist $oldId ($oldName) was made into a "
|
||||
"The artist {$old->id} ($oldName) was made into a "
|
||||
. ($redirect ? "" : "non-")
|
||||
. "redirecting alias of artist $newId ({$this->name()}) by user {$user->label()}"
|
||||
);
|
||||
self::$cache->delete_value("zz_a_$oldId");
|
||||
self::$cache->delete_value("zz_a_{$old->id}");
|
||||
$this->flush();
|
||||
$old->flush();
|
||||
return $affected;
|
||||
|
||||
@@ -22,6 +22,11 @@ class ErrorLog extends BaseManager {
|
||||
array $request,
|
||||
array $errorList,
|
||||
): \Gazelle\ErrorLog {
|
||||
$len = strlen($trace);
|
||||
if ($len > 4000) {
|
||||
$clipped = $len - 4000;
|
||||
$trace = substr($trace, 0, 4000) . "[...$clipped chars clipped]";
|
||||
}
|
||||
$id = $this->pg()->scalar("
|
||||
merge into error_log using (
|
||||
select ? as uri,
|
||||
@@ -51,7 +56,7 @@ class ErrorLog extends BaseManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an eror log based on its ID
|
||||
* Get an error log based on its ID
|
||||
*/
|
||||
public function findById(int $id): ?\Gazelle\ErrorLog {
|
||||
$errorId = (int)$this->pg()->scalar("
|
||||
@@ -62,7 +67,7 @@ class ErrorLog extends BaseManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an eror log based on its digest
|
||||
* Get an error log based on its digest
|
||||
*/
|
||||
public function findByDigest(string $trace, array $errorList): ?\Gazelle\ErrorLog {
|
||||
$id = (int)$this->pg()->scalar("
|
||||
|
||||
45
app/User.php
45
app/User.php
@@ -344,21 +344,24 @@ class User extends BaseObject {
|
||||
* Twig will use these pieces to construct the markup for their avatar.
|
||||
*/
|
||||
public function avatarComponentList(User $viewed): array {
|
||||
$viewedId = $viewed->id();
|
||||
if (!isset($this->avatarCache[$viewedId])) {
|
||||
if (!isset($this->avatarCache[$viewed->id])) {
|
||||
$donor = new User\Donor($viewed);
|
||||
$this->avatarCache[$viewedId] = [
|
||||
$this->avatarCache[$viewed->id] = [
|
||||
'image' => match ($this->avatarMode()) {
|
||||
AvatarDisplay::show => $viewed->avatar() ?: USER_DEFAULT_AVATAR,
|
||||
AvatarDisplay::fallbackSynthetic => $viewed->avatar() ?: (new User\SyntheticAvatar($this))->avatar($viewed->username()),
|
||||
AvatarDisplay::forceSynthetic => (new User\SyntheticAvatar($this))->avatar($viewed->username()),
|
||||
AvatarDisplay::none => USER_DEFAULT_AVATAR, /** @phpstan-ignore-line */
|
||||
AvatarDisplay::show
|
||||
=> $viewed->avatar() ?: USER_DEFAULT_AVATAR,
|
||||
AvatarDisplay::fallbackSynthetic
|
||||
=> $viewed->avatar() ?: (new User\SyntheticAvatar($this))->avatar($viewed->username()),
|
||||
AvatarDisplay::forceSynthetic
|
||||
=> (new User\SyntheticAvatar($this))->avatar($viewed->username()),
|
||||
AvatarDisplay::none /** @phpstan-ignore-line */
|
||||
=> USER_DEFAULT_AVATAR,
|
||||
},
|
||||
'hover' => $donor->avatarHover(),
|
||||
'text' => $donor->avatarHoverText(),
|
||||
];
|
||||
}
|
||||
return $this->avatarCache[$viewedId];
|
||||
return $this->avatarCache[$viewed->id];
|
||||
}
|
||||
|
||||
public function banDate(): ?string {
|
||||
@@ -384,7 +387,7 @@ class User extends BaseObject {
|
||||
* This method returns a hash of the current modified date
|
||||
* and state of the audit trail. This is used to verify that
|
||||
* a staff member is not operating on an out-of-date version
|
||||
* of a user.
|
||||
* of a user profile page.
|
||||
*/
|
||||
public function checkpoint(): string {
|
||||
return signature(
|
||||
@@ -717,7 +720,7 @@ class User extends BaseObject {
|
||||
* returns PARANOIA_HIDE, PARANOIA_OVERRIDDEN, PARANOIA_ALLOWED
|
||||
*/
|
||||
public function propertyVisible(User $viewer, string $property): int {
|
||||
if ($this->id === $viewer->id()) {
|
||||
if ($this->id === $viewer->id) {
|
||||
return PARANOIA_ALLOWED;
|
||||
}
|
||||
|
||||
@@ -852,7 +855,7 @@ class User extends BaseObject {
|
||||
);
|
||||
$this->lastRead = self::$db->to_pair('TopicID', 'PostID', false);
|
||||
}
|
||||
return $this->lastRead[$thread->id()] ?? 0;
|
||||
return $this->lastRead[$thread->id] ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1660,7 +1663,7 @@ class User extends BaseObject {
|
||||
}
|
||||
$this->tokenCache = $tokenCache;
|
||||
}
|
||||
return isset($this->tokenCache[$torrent->id()]);
|
||||
return isset($this->tokenCache[$torrent->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1860,7 +1863,7 @@ class User extends BaseObject {
|
||||
WHERE uid = ?
|
||||
AND fid = ?
|
||||
LIMIT 1;
|
||||
", $this->id, $torrent->id()
|
||||
", $this->id, $torrent->id
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1973,6 +1976,22 @@ class User extends BaseObject {
|
||||
$username = $this->username();
|
||||
// Many, but not all, of the associated user tables will drop their entries via foreign key cascades.
|
||||
// But some won't. If this call fails, you will need to decide what to do about the tables in question.
|
||||
DB::DB()->prepared_query("
|
||||
DELETE FROM user_read_forum WHERE user_id = ?
|
||||
", $this->id
|
||||
);
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM users_stats_daily WHERE UserID = ?
|
||||
", $this->id
|
||||
);
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM users_stats_monthly WHERE UserID = ?
|
||||
", $this->id
|
||||
);
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM users_stats_yearly WHERE UserID = ?
|
||||
", $this->id
|
||||
);
|
||||
$affected = parent::remove();
|
||||
self::$cache->delete_multi([
|
||||
sprintf(Manager\User::ID_KEY, $this->id),
|
||||
|
||||
@@ -107,7 +107,7 @@ class UserCreator extends Base {
|
||||
'auth_key'
|
||||
];
|
||||
$mainArgs = [
|
||||
(int)$inviter?->id(),
|
||||
(int)$inviter?->id,
|
||||
$this->username,
|
||||
current($this->email),
|
||||
$this->passHash,
|
||||
@@ -150,28 +150,6 @@ class UserCreator extends Base {
|
||||
", $this->id
|
||||
);
|
||||
|
||||
if ($inviter) {
|
||||
(new Manager\InviteSource())->resolveInviteSource($this->inviteKey, $user);
|
||||
$inviter->stats()->increment('invited_total');
|
||||
$user->externalProfile()->modifyProfile($inviterReason);
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM invites WHERE InviteKey = ?
|
||||
", $this->inviteKey
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($this->inviteKey)) {
|
||||
self::$db->prepared_query("
|
||||
UPDATE referral_users SET
|
||||
UserID = ?,
|
||||
Active = 1,
|
||||
Joined = now(),
|
||||
InviteKey = ''
|
||||
WHERE InviteKey = ?
|
||||
", $this->id, $this->inviteKey
|
||||
);
|
||||
}
|
||||
|
||||
// Log the one or two email addresses known to be associated with the user.
|
||||
// Each additional previous email address is staggered one second back in the past.
|
||||
$past = count($this->email);
|
||||
@@ -220,6 +198,28 @@ class UserCreator extends Base {
|
||||
", $this->id, "{$attr}-pop");
|
||||
}
|
||||
|
||||
if ($inviter) {
|
||||
(new Manager\InviteSource())->resolveInviteSource($this->inviteKey, $user);
|
||||
$inviter->stats()->increment('invited_total');
|
||||
$user->externalProfile()->modifyProfile($inviterReason);
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM invites WHERE InviteKey = ?
|
||||
", $this->inviteKey
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($this->inviteKey)) {
|
||||
self::$db->prepared_query("
|
||||
UPDATE referral_users SET
|
||||
Active = 1,
|
||||
InviteKey = '',
|
||||
Joined = now(),
|
||||
UserID = ?
|
||||
WHERE InviteKey = ?
|
||||
", $this->id, $this->inviteKey
|
||||
);
|
||||
}
|
||||
|
||||
self::$db->commit();
|
||||
|
||||
(new Tracker())->addUser($user);
|
||||
|
||||
@@ -7,7 +7,7 @@ class Discogs extends \Gazelle\Base {
|
||||
protected array $info;
|
||||
|
||||
public function __construct(
|
||||
protected int $id,
|
||||
public readonly int $id,
|
||||
?int $sequence = null,
|
||||
?string $name = null,
|
||||
?string $stem = null,
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: '#^Strict comparison using \=\=\= between false and false will always evaluate to true\.$#'
|
||||
identifier: identical.alwaysTrue
|
||||
count: 1
|
||||
path: ../app/DB/Mysql.php
|
||||
|
||||
-
|
||||
message: '#^Match expression does not handle remaining value\: string$#'
|
||||
identifier: match.unhandled
|
||||
@@ -18,36 +12,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../app/Feed.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of function array_keys expects array, array\|false given\.$#'
|
||||
identifier: argument.type
|
||||
count: 2
|
||||
path: ../app/Search/Torrent.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$array of function array_slice expects array, array\|false given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../app/Search/Torrent.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$value of function count expects array\|Countable, array\|false given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../app/Search/Torrent.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always false\.$#'
|
||||
identifier: if.alwaysFalse
|
||||
count: 1
|
||||
path: ../app/Torrent/Report.php
|
||||
|
||||
-
|
||||
message: '#^Method Gazelle\\Torrent\\Report\:\:torrent\(\) should return Gazelle\\TorrentAbstract\|null but returns Gazelle\\TorrentAbstract\|false\|null\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: ../app/Torrent/Report.php
|
||||
|
||||
-
|
||||
message: '#^Method Gazelle\\Util\\Proxy\:\:fetch\(\) has no return type specified\.$#'
|
||||
identifier: missingType.return
|
||||
|
||||
@@ -582,19 +582,25 @@ class ArtistTest extends TestCase {
|
||||
$artist = $manager->create('phpunit.' . randomString(12));
|
||||
$this->artistIdList[] = $artist->id;
|
||||
|
||||
$id = -100000 + random_int(1, 100000);
|
||||
$id = (int)DB::DB()->scalar("
|
||||
SELECT 1+coalesce(max(artist_discogs_id), 0) FROM artist_discogs
|
||||
");
|
||||
$name = 'discogs phpunit ' . randomString(10);
|
||||
$discogs = new Util\Discogs(
|
||||
id: $id,
|
||||
stem: 'discogs phpunit',
|
||||
name: 'discogs phpunit',
|
||||
stem: $name,
|
||||
name: $name,
|
||||
sequence: 2,
|
||||
);
|
||||
$this->assertEquals($id, $discogs->id(), 'artist-discogs-id');
|
||||
$this->assertEquals('discogs phpunit', $discogs->name(), 'artist-discogs-name');
|
||||
$this->assertEquals('discogs phpunit', $discogs->stem(), 'artist-discogs-stem');
|
||||
$this->assertEquals($id, $discogs->id, 'artist-discogs-id');
|
||||
$this->assertEquals($name, $discogs->name(), 'artist-discogs-name');
|
||||
$this->assertEquals($name, $discogs->stem(), 'artist-discogs-stem');
|
||||
$this->assertEquals(2, $discogs->sequence(), 'artist-discogs-sequence');
|
||||
|
||||
$artist->setField('discogs', $discogs)->setUpdateUser($this->user)->modify();
|
||||
$this->assertEquals('discogs phpunit', $artist->discogs()->name(), 'artist-self-discogs-name');
|
||||
$this->assertTrue(
|
||||
$artist->setField('discogs', $discogs)->setUpdateUser($this->user)->modify(),
|
||||
'artist-add-discogs'
|
||||
);
|
||||
$this->assertEquals($name, $artist->discogs()->name(), 'artist-self-discogs-name');
|
||||
$this->assertEquals(1, $artist->removeDiscogsRelation(), 'artist-discogs-remove');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class UserCreateTest extends TestCase {
|
||||
'user-create-staff-notes'
|
||||
);
|
||||
$this->assertTrue($this->user->isUnconfirmed(), 'user-create-unconfirmed');
|
||||
$this->assertStringStartsWith(
|
||||
$this->assertStringContainsString(
|
||||
'/static/styles/apollostage/style.css?v=',
|
||||
(new User\Stylesheet($this->user))->cssUrl(),
|
||||
'user-create-stylesheet'
|
||||
|
||||
@@ -17,14 +17,6 @@ class UserTest extends TestCase {
|
||||
|
||||
public function tearDown(): void {
|
||||
if (isset($this->user)) {
|
||||
DB::DB()->prepared_query("
|
||||
DELETE FROM user_read_forum WHERE user_id = ?
|
||||
", $this->user->id
|
||||
);
|
||||
DB::DB()->prepared_query("
|
||||
DELETE FROM users_stats_daily WHERE UserID = ?
|
||||
", $this->user->id
|
||||
);
|
||||
$this->user->remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,13 +12,7 @@ class UsersTest extends TestCase {
|
||||
public function tearDown(): void {
|
||||
if (isset($this->userList)) {
|
||||
foreach ($this->userList as $user) {
|
||||
if (isset($user)) {
|
||||
DB::DB()->prepared_query("
|
||||
DELETE FROM users_stats_daily WHERE UserID = ?
|
||||
", $user->id
|
||||
);
|
||||
$user->remove();
|
||||
}
|
||||
$user?->remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user