mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-16 18:04:34 -05:00
show invite source in invite pool
This commit is contained in:
@@ -15,7 +15,7 @@ class Invite extends \Gazelle\Base {
|
||||
INSERT INTO invites
|
||||
(InviterID, InviteKey, Email, Notes, Reason, Expires)
|
||||
VALUES (?, ?, ?, ?, ?, now() + INTERVAL 3 DAY)
|
||||
", $user->id(), $inviteKey, $email, $notes, $reason
|
||||
", $user->id, $inviteKey, $email, $notes, $reason
|
||||
);
|
||||
$invite = new \Gazelle\Invite($inviteKey);
|
||||
if (is_number($source)) {
|
||||
@@ -25,7 +25,7 @@ class Invite extends \Gazelle\Base {
|
||||
return $invite;
|
||||
}
|
||||
|
||||
public function findUserByKey(string $inviteKey, User $manager): ?\Gazelle\User {
|
||||
public function findUserByKey(string $inviteKey, User $manager = new User()): ?\Gazelle\User {
|
||||
return $manager->findById(
|
||||
(int)self::$db->scalar("
|
||||
SELECT InviterID FROM invites WHERE InviteKey = ?
|
||||
@@ -59,7 +59,7 @@ class Invite extends \Gazelle\Base {
|
||||
FROM invites
|
||||
WHERE InviterID = ?
|
||||
AND Email = ?
|
||||
", $user->id(), $email
|
||||
", $user->id, $email
|
||||
);
|
||||
}
|
||||
|
||||
@@ -86,12 +86,15 @@ class Invite extends \Gazelle\Base {
|
||||
|
||||
self::$db->prepared_query("
|
||||
SELECT i.InviterID AS user_id,
|
||||
um.IP AS ipaddr,
|
||||
i.InviteKey AS `key`,
|
||||
i.Expires AS expires,
|
||||
i.Email AS email
|
||||
FROM invites AS i
|
||||
um.IP AS ipaddr,
|
||||
i.InviteKey AS `key`,
|
||||
i.Expires AS expires,
|
||||
i.Email AS email,
|
||||
ivs.name AS source_name
|
||||
FROM invites i
|
||||
INNER JOIN users_main AS um ON (um.ID = i.InviterID)
|
||||
LEFT JOIN invite_source_pending ivsp ON (ivsp.invite_key = i.InviteKey)
|
||||
LEFT JOIN invite_source ivs USING (invite_source_id)
|
||||
$where
|
||||
ORDER BY i.Expires DESC
|
||||
LIMIT ? OFFSET ?
|
||||
@@ -101,7 +104,7 @@ class Invite extends \Gazelle\Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an invite
|
||||
* Remove an invite without restoring it to the issuer
|
||||
*
|
||||
* @return bool true if something was actually removed
|
||||
*/
|
||||
@@ -115,25 +118,24 @@ class Invite extends \Gazelle\Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Expire unused invitations
|
||||
* Expire unused invitations and return them to the user
|
||||
*/
|
||||
public function expire(\Gazelle\Task|null $task = null): int {
|
||||
self::$db->begin_transaction();
|
||||
self::$db->prepared_query("SELECT InviterID FROM invites WHERE Expires < now()");
|
||||
$list = self::$db->collect(0, false);
|
||||
|
||||
self::$db->prepared_query("DELETE FROM invites WHERE Expires < now()");
|
||||
self::$db->prepared_query("
|
||||
DELETE isp FROM invite_source_pending isp
|
||||
LEFT JOIN invites i ON (i.InviteKey = isp.invite_key)
|
||||
WHERE i.InviteKey IS NULL
|
||||
");
|
||||
|
||||
public function expire(\Gazelle\Task|null $task = null, User $manager = new User()): int {
|
||||
$expired = 0;
|
||||
foreach ($list as $userId) {
|
||||
self::$db->prepared_query("UPDATE users_main SET Invites = Invites + 1 WHERE ID = ?", $userId);
|
||||
self::$cache->delete_value("u_$userId");
|
||||
$task?->debug("Expired invite from user $userId", $userId);
|
||||
self::$db->begin_transaction();
|
||||
self::$db->prepared_query("
|
||||
SELECT InviterID AS 'user_id',
|
||||
InviteKey AS 'invite_key'
|
||||
FROM invites
|
||||
WHERE Expires < now()
|
||||
");
|
||||
foreach (self::$db->to_array(false, MYSQLI_ASSOC, false) as $row) {
|
||||
$user = $manager->findById($row['user_id']);
|
||||
if (is_null($user)) {
|
||||
continue;
|
||||
}
|
||||
$user->invite()->revoke($row['invite_key']);
|
||||
$task?->debug("Expired invite {$row['invite_key']} for user {$user->username()}", $row['user_id']);
|
||||
$expired++;
|
||||
}
|
||||
self::$db->commit();
|
||||
|
||||
@@ -9,7 +9,7 @@ class Registration extends \Gazelle\Base {
|
||||
protected string $afterDate;
|
||||
|
||||
public function __construct(
|
||||
protected User $manager,
|
||||
protected User $manager = new User(),
|
||||
) {}
|
||||
|
||||
public function setBeforeDate(string $date): static {
|
||||
|
||||
18
app/User.php
18
app/User.php
@@ -12,7 +12,7 @@ use Gazelle\Util\Time;
|
||||
|
||||
class User extends BaseObject {
|
||||
final public const tableName = 'users_main';
|
||||
final protected const CACHE_KEY = 'u2_%d';
|
||||
final protected const CACHE_KEY = 'u_%d';
|
||||
final protected const CACHE_NOTIFY = 'u_notify_%d';
|
||||
final protected const CACHE_REFERRAL = 'u_refer_%d';
|
||||
final protected const USER_RECENT_UPLOAD = 'u_recent_up_%d';
|
||||
@@ -46,7 +46,7 @@ class User extends BaseObject {
|
||||
$this->stats()->flush();
|
||||
$this->ordinal()->flush();
|
||||
$this->privilege()->flush();
|
||||
unset($this->info, $this->ordinal, $this->privilege, $this->stats, $this->tokenCache);
|
||||
unset($this->info, $this->invite, $this->ordinal, $this->privilege, $this->stats, $this->tokenCache);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -157,6 +157,7 @@ class User extends BaseObject {
|
||||
um.torrent_pass,
|
||||
um.updated,
|
||||
um.Visible,
|
||||
um.ipcc,
|
||||
ui.AdminComment,
|
||||
ui.BanDate,
|
||||
ui.NavItems,
|
||||
@@ -472,6 +473,10 @@ class User extends BaseObject {
|
||||
return $this->info()['IP'];
|
||||
}
|
||||
|
||||
public function ipCountryIso(): string {
|
||||
return $this->info()['ipcc'];
|
||||
}
|
||||
|
||||
public function IRCKey(): ?string {
|
||||
return $this->info()['IRCKey'];
|
||||
}
|
||||
@@ -1583,6 +1588,15 @@ class User extends BaseObject {
|
||||
return (int)$this->info()['inviter_user_id'];
|
||||
}
|
||||
|
||||
public function inviteSource(): ?string {
|
||||
return $this->getSingleValue('user_invitesource', "
|
||||
SELECT ivs.name
|
||||
FROM user_has_invite_source uhivs
|
||||
LEFT JOIN invite_source ivs using (invite_source_id)
|
||||
WHERE uhivs.user_id = ?
|
||||
");
|
||||
}
|
||||
|
||||
/**
|
||||
* This can be used to add a signature to a URL to prevent tampering with the parameter list.
|
||||
*/
|
||||
|
||||
@@ -27,35 +27,6 @@ class Invite extends \Gazelle\BaseUser {
|
||||
return $affected > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke an active invitation (restore previous invite total)
|
||||
*/
|
||||
public function revoke(string $key): bool {
|
||||
self::$db->begin_transaction();
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM invites WHERE InviteKey = ?
|
||||
", $key
|
||||
);
|
||||
if (self::$db->affected_rows() == 0) {
|
||||
self::$db->rollback();
|
||||
return false;
|
||||
}
|
||||
if ($this->user()->permitted('site_send_unlimited_invites')) {
|
||||
self::$db->commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
self::$db->prepared_query("
|
||||
UPDATE users_main SET
|
||||
Invites = Invites + 1
|
||||
WHERE ID = ?
|
||||
", $this->id()
|
||||
);
|
||||
self::$db->commit();
|
||||
$this->user()->flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function pendingTotal(): int {
|
||||
return (int)self::$db->scalar("
|
||||
SELECT count(*) FROM invites WHERE InviterID = ?
|
||||
@@ -65,12 +36,15 @@ class Invite extends \Gazelle\BaseUser {
|
||||
|
||||
public function pendingList(): array {
|
||||
self::$db->prepared_query("
|
||||
SELECT InviteKey AS invite_key,
|
||||
Email AS email,
|
||||
Expires AS expires
|
||||
FROM invites
|
||||
WHERE InviterID = ?
|
||||
ORDER BY Expires
|
||||
SELECT i.InviteKey AS invite_key,
|
||||
i.Email AS email,
|
||||
i.Expires AS expires,
|
||||
ivs.name AS source_name
|
||||
FROM invites i
|
||||
LEFT JOIN invite_source_pending ivsp ON (ivsp.invite_key = i.InviteKey)
|
||||
LEFT JOIN invite_source ivs USING (invite_source_id)
|
||||
WHERE i.InviterID = ?
|
||||
ORDER BY i.Expires
|
||||
", $this->id()
|
||||
);
|
||||
return self::$db->to_array('invite_key', MYSQLI_ASSOC, false);
|
||||
@@ -96,4 +70,39 @@ class Invite extends \Gazelle\BaseUser {
|
||||
);
|
||||
return self::$db->collect(0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke an active invitation (restore previous invite total)
|
||||
*/
|
||||
public function revoke(string $key): int {
|
||||
self::$db->begin_transaction();
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM invites WHERE InviteKey = ?
|
||||
", $key
|
||||
);
|
||||
$affected = self::$db->affected_rows();
|
||||
if ($affected == 0) {
|
||||
self::$db->rollback();
|
||||
return 0;
|
||||
}
|
||||
if ($this->user()->permitted('site_send_unlimited_invites')) {
|
||||
self::$db->commit();
|
||||
return $affected;
|
||||
}
|
||||
self::$db->prepared_query("
|
||||
DELETE FROM invite_source_pending WHERE invite_key = ?
|
||||
", $key
|
||||
);
|
||||
$affected += self::$db->affected_rows();
|
||||
self::$db->prepared_query("
|
||||
UPDATE users_main SET
|
||||
Invites = Invites + 1
|
||||
WHERE ID = ?
|
||||
", $this->id()
|
||||
);
|
||||
$affected += self::$db->affected_rows();
|
||||
self::$db->commit();
|
||||
$this->user()->flush();
|
||||
return $affected;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ if (!$Viewer->permittedAny('users_view_ips', 'users_view_email')) {
|
||||
error(403);
|
||||
}
|
||||
|
||||
$registration = new Manager\Registration(new Manager\User());
|
||||
$registration = new Manager\Registration();
|
||||
|
||||
if (isset($_REQUEST['before_date'])) {
|
||||
if (!str_contains($_SERVER['REQUEST_URI'], '&before_date=')) {
|
||||
|
||||
@@ -35,7 +35,7 @@ if ($Viewer->isInterviewer() || $Viewer->isStaff()) {
|
||||
}
|
||||
|
||||
$inviteSourceMan = null;
|
||||
if ($Viewer->isRecruiter()) {
|
||||
if ($Viewer->isRecruiter() || $Viewer->isStaff()) {
|
||||
$inviteSourceMan = new Manager\InviteSource();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
{{ header('Registration log', {'js': 'resolve-ip'}) }}
|
||||
<div class="thin">
|
||||
<div class="header">
|
||||
{% if not list %}
|
||||
<h2 align="center">No new User Registrations
|
||||
{%- else -%}
|
||||
<h2 align="center">{{ paginator.total|number_format }} new User Registration{{ paginator.total|plural }}
|
||||
{%- endif %}
|
||||
{%- if after -%}
|
||||
{%- if before %} between {{ after }} and {{ before }}
|
||||
{%- else %} after {{ after -}}
|
||||
{%- endif -%}
|
||||
{%- elseif before %} before {{ before -}}
|
||||
{%- else %} in the last 72 hours
|
||||
{%- endif -%}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="linkbox">
|
||||
<a href="?action=invite_pool" class="brackets">Invite Pool</a>
|
||||
</div>
|
||||
<div class="box pad">
|
||||
<form action="" method="post" acclass="thin box pad">
|
||||
<input type="hidden" name="action" value="registration_log" />
|
||||
@@ -12,22 +30,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not list %}
|
||||
<h2 align="center">No new user registrations
|
||||
{%- else -%}
|
||||
<h2 align="center">{{ paginator.total|number_format }} New user registration{{ paginator.total|plural }}
|
||||
{%- endif %}
|
||||
{%- if after -%}
|
||||
{%- if before %} between {{ after }} and {{ before }}
|
||||
{%- else %} after {{ after -}}
|
||||
{%- endif -%}
|
||||
{%- elseif before %} before {{ before -}}
|
||||
{%- else %} in the last 72 hours
|
||||
{%- endif -%}
|
||||
</h2>
|
||||
|
||||
{% if list %}
|
||||
{{ paginator.linkbox|raw }}
|
||||
{% for user in list %}
|
||||
{% if loop.first %}
|
||||
{{ paginator.linkbox|raw }}
|
||||
<table width="100%">
|
||||
<tr class="colhead">
|
||||
<td>User</td>
|
||||
@@ -39,8 +44,9 @@
|
||||
<td colspan="2">Host</td>
|
||||
<td>Country</td>
|
||||
<td>Registered</td>
|
||||
<td>Source</td>
|
||||
</tr>
|
||||
{% for user in list %}
|
||||
{% endif %}
|
||||
<tr class="row{{ cycle(['a', 'b'], loop.index0) }}">
|
||||
<td>
|
||||
{{ user.id|user_full }}
|
||||
@@ -49,24 +55,24 @@
|
||||
</td>
|
||||
<td style="vertical-align: top">
|
||||
{{- user.uploadedSize|octet_size -}}
|
||||
{%- if user.inviter -%}
|
||||
{% if user.inviter -%}
|
||||
<br />
|
||||
{{- user.inviter.uploadedSize|octet_size -}}
|
||||
{%- endif -%}
|
||||
{% endif -%}
|
||||
</td>
|
||||
<td style="vertical-align: top">
|
||||
{{- user.downloadedSize|octet_size -}}
|
||||
{%- if user.inviter -%}
|
||||
{% if user.inviter -%}
|
||||
<br />
|
||||
{{- user.inviter.downloadedSize|octet_size -}}
|
||||
{%- endif -%}
|
||||
{% endif -%}
|
||||
</td>
|
||||
<td style="vertical-align: top">
|
||||
{{- ratio(user.uploadedSize, user.downloadedSize) -}}
|
||||
{%- if user.inviter -%}
|
||||
{% if user.inviter -%}
|
||||
<br />
|
||||
{{- ratio(user.inviter.uploadedSize, user.inviter.downloadedSize) -}}
|
||||
{%- endif -%}
|
||||
{% endif -%}
|
||||
</td>
|
||||
<td style="vertical-align: top">
|
||||
{{- user.email -}}
|
||||
@@ -76,62 +82,66 @@
|
||||
<td style="vertical-align: top">
|
||||
<a href="userhistory.php?action=email&userid={{ user.id }}" title="Email History" class="brackets tooltip">H</a>
|
||||
<a href="/user.php?action=search&email_history=on&email={{ user.email }}" title="Email Search" class="brackets tooltip">S</a>
|
||||
{%- if user.inviter -%}
|
||||
{% if user.inviter -%}
|
||||
<br />
|
||||
<a href="userhistory.php?action=email&userid={{ user.inviter.id }}" title="Email History" class="brackets tooltip">H</a>
|
||||
<a href="/user.php?action=search&email_history=on&email={{ user.inviter.email }}" title="Email Search" class="brackets tooltip">S</a>
|
||||
{%- endif -%}
|
||||
{% endif -%}
|
||||
</td>
|
||||
<td style="vertical-align: top">
|
||||
<span style="float: left">
|
||||
{{- user.ipaddr -}}
|
||||
{%- if user.inviter.id -%}
|
||||
{% if user.inviter.id -%}
|
||||
<br />
|
||||
{{- user.inviter.ipaddr -}}
|
||||
{%- endif -%}
|
||||
{% endif -%}
|
||||
</span>
|
||||
{%- if user.inviter and user.ipaddr == user.inviter.ipaddr -%}
|
||||
{% if user.inviter and user.ipaddr == user.inviter.ipaddr -%}
|
||||
<span title="IP addresses match" style="float: left; padding: 0px 5px; color: #ffff00; font-size: large">⚠</span>
|
||||
{%- endif -%}
|
||||
{% endif -%}
|
||||
</td>
|
||||
<td style="vertical-align: top">
|
||||
<span style="float: left; padding-left: 2px;" title="Duplicate usage by other users">
|
||||
{{- ipv4.duplicateTotal(user) -}}
|
||||
{%- if user.inviter and user.ipaddr != user.inviter.ipaddr -%}
|
||||
{% if user.inviter and user.ipaddr != user.inviter.ipaddr -%}
|
||||
<br />
|
||||
{{- ipv4.duplicateTotal(user.inviter) -}}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</span>
|
||||
</td>
|
||||
<td style="vertical-align: top">
|
||||
<span class="resolve-ipv4" data-ip="{{ user.ipaddr }}">Resolving...</span>
|
||||
{% if user.inviter.id and user.inviter.ipaddr != user.ipaddr %}
|
||||
{% if user.inviter.id and user.inviter.ipaddr != user.ipaddr %}
|
||||
<br />
|
||||
<span class="resolve-ipv4" data-ip="{{ user.inviter.ipaddr }}">Resolving...</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="vertical-align: top">
|
||||
<a href="userhistory.php?action=ips&userid{{ user.id }}" title="IP History" class="brackets tooltip">H</a>
|
||||
<a href="/user.php?action=search&ip_history=on&ip={{ user.ipaddr }}" title="IP Search" class="brackets tooltip">S</a>
|
||||
<a href="http://whatismyipaddress.com/ip/{{ user.ipaddr }}" title="whatismyipaddress.com" class="brackets tooltip">WI</a>
|
||||
{% if user.inviter.id and user.inviter.ipaddr != user.ipaddr %}
|
||||
{% if user.inviter.id and user.inviter.ipaddr != user.ipaddr %}
|
||||
<br />
|
||||
<a href="userhistory.php?action=ips&userid={{ user.inviter.id }}" title="IP History" class="brackets tooltip">H</a>
|
||||
<a href="/user.php?action=search&ip_history=on&ip={{ user.inviter.ipaddr }}" title="IP Search" class="brackets tooltip">S</a>
|
||||
<a href="http://whatismyipaddress.com/ip/{{ user.inviter.ipaddr }}" title="WI" class="brackets tooltip">WI</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
TODO
|
||||
{{ user.ipCountryIso }}
|
||||
</td>
|
||||
<td>
|
||||
<span style="white-space: nowrap">{{- user.created|time_diff -}}</span>
|
||||
<br />
|
||||
<span style="white-space: nowrap">{{- user.inviter.created|time_diff -}}</span>
|
||||
</td>
|
||||
<td>
|
||||
{{ user.inviteSource }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if loop.last %}
|
||||
</table>
|
||||
{{ paginator.linkbox|raw }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ footer() }}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
<div class="header">
|
||||
<h2>Invite Pool</h2>
|
||||
</div>
|
||||
|
||||
<div class="linkbox">
|
||||
<a href="?action=registration_log" class="brackets">Registration Log</a>
|
||||
</div>
|
||||
<div class="box pad">
|
||||
<p>{{ pending|number_format }} unused invites have been sent.</p>
|
||||
{% if removed is not empty %}
|
||||
@@ -34,6 +36,7 @@
|
||||
<tr class="colhead">
|
||||
<td>Inviter</td>
|
||||
<td>Email address</td>
|
||||
<td>Source</td>
|
||||
<td>IP address</td>
|
||||
<td>Invite link</td>
|
||||
<td>Expires</td>
|
||||
@@ -46,8 +49,9 @@
|
||||
<tr class="row{{ cycle(['a', 'b'], loop.index0) }}">
|
||||
<td>{{ invite.user_id|user_full }}</td>
|
||||
<td>{{ invite.email }}</td>
|
||||
<td>{{ invite.source_name }}</td>
|
||||
<td>{{ ipaddr(invite.ipaddr) }}</td>
|
||||
<td><a href="register.php?invite={{ invite.key }}">{{ invite.key }}</a></td>
|
||||
<td>{{ constant('SITE_URL') }}/register.php?invite={{ invite.key }}</td>
|
||||
<td>{{ invite.expires|time_diff }}</td>
|
||||
{% if viewer.permitted('users_edit_invites') %}
|
||||
<td>
|
||||
|
||||
@@ -122,20 +122,26 @@
|
||||
{% endif %}
|
||||
|
||||
{% for p in user.invite.pendingList %}
|
||||
{% if loop.first %}
|
||||
{% if loop.first %}
|
||||
<h3>Pending invites</h3>
|
||||
<div class="box pad">
|
||||
<table width="100%">
|
||||
<tr class="colhead">
|
||||
<td>Email address</td>
|
||||
<td>Expires in</td>
|
||||
{% if is_site_inviter %}
|
||||
<td>Source</td>
|
||||
{% endif %}
|
||||
<td>Invite link</td>
|
||||
<td>Revoke invite</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<tr class="row{{ cycle(['a', 'b'], loop.index0) }}">
|
||||
<td>{{ p.email }}</td>
|
||||
<td>{{ p.expires|time_diff }}</td>
|
||||
{% if is_site_inviter %}
|
||||
<td>{{ p.source_name }}</td>
|
||||
{% endif %}
|
||||
<td>{{ constant('SITE_URL') }}/register.php?invite={{ p.invite_key }}</td>
|
||||
<td><a href="user.php?action=delete_invite&invite={{ p.invite_key }}&auth={{ user.auth }}"
|
||||
onclick="return confirm('Are you sure you want to revoke this invite?');">Revoke invite</a></td>
|
||||
|
||||
@@ -330,7 +330,7 @@ class InviteTest extends TestCase {
|
||||
'invite-source-create-pending'
|
||||
);
|
||||
|
||||
// create auser from the invite
|
||||
// create user from the invite
|
||||
$this->invitee = (new UserCreator())
|
||||
->setUsername('create.' . randomString(6))
|
||||
->setEmail(randomString(6) . '@example.com')
|
||||
@@ -342,6 +342,7 @@ class InviteTest extends TestCase {
|
||||
$inviteSourceMan->findSourceNameByUser($this->invitee),
|
||||
'invitee-invite-source'
|
||||
);
|
||||
$this->assertEquals($sourceName, $this->invitee->inviteSource(), 'invitee-source-name');
|
||||
$this->assertEquals($profile, $this->invitee->externalProfile()->profile(), 'invite-source-profile');
|
||||
$this->assertStringContainsString(
|
||||
'phpunit notes',
|
||||
@@ -421,16 +422,99 @@ class InviteTest extends TestCase {
|
||||
$this->assertEquals(1, $inviteSourceMan->remove($sourceId), 'invite-source-create-remove');
|
||||
}
|
||||
|
||||
public function testRemoveInvite(): void {
|
||||
$this->user->setField('Invites', 1)->modify();
|
||||
$manager = new Manager\Invite();
|
||||
$invite = $manager->create(
|
||||
$this->user,
|
||||
'invite-unittest@unitte.st',
|
||||
'unittest invite remove notes',
|
||||
'unittest invite remove reason',
|
||||
''
|
||||
);
|
||||
$this->assertTrue($manager->removeInviteKey($invite->key()), 'invite-remove-key');
|
||||
$this->assertNull($manager->findUserByKey($invite->key()), 'invite-removed-key');
|
||||
}
|
||||
|
||||
public function testExpireInvite(): void {
|
||||
$this->user->setField('Invites', 1)->modify();
|
||||
$this->assertEquals(1, $this->user->unusedInviteTotal(), 'invite-user-has-invite');
|
||||
$manager = new Manager\Invite();
|
||||
$invite = $manager->create(
|
||||
$this->user,
|
||||
'invite-unittest@unitte.st',
|
||||
'unittest invite remove notes',
|
||||
'unittest invite remove reason',
|
||||
''
|
||||
);
|
||||
$this->assertEquals(0, $this->user->unusedInviteTotal(), 'invite-user-all-used');
|
||||
// invites are not BaseObjects
|
||||
DB::DB()->prepared_query("
|
||||
UPDATE invites SET
|
||||
Expires = now() - INTERVAL 1 SECOND
|
||||
WHERE InviteKey = ?
|
||||
", $invite->key()
|
||||
);
|
||||
$this->assertEquals(1, DB::DB()->affected_rows(), 'invite-modify-expiry');
|
||||
$this->assertEquals(1, $manager->expire(), 'invite-manager-expire');
|
||||
$this->assertEquals(1, $this->user->flush()->unusedInviteTotal(), 'invite-user-invite-restored');
|
||||
}
|
||||
|
||||
public function testRevokeInvite(): void {
|
||||
$this->user->setField('Invites', 1)->modify();
|
||||
|
||||
$manager = new Manager\Invite();
|
||||
$initial = $manager->totalPending();
|
||||
$email = randomString(10) . "@invitee.example.com";
|
||||
$this->assertFalse($manager->emailExists($this->user, $email), 'invitee-email-not-pending');
|
||||
$invite = $manager->create($this->user, $email, 'unittest notes', 'unittest reason', '');
|
||||
$this->assertFalse($this->user->invite()->revoke('nosuchthing'), 'invite-revoke-inexistant');
|
||||
$this->assertTrue($this->user->invite()->revoke($invite->key()), 'invite-revoke-existing');
|
||||
$this->assertEquals(1, $this->user->unusedInviteTotal(), 'invite-unused-1');
|
||||
$this->assertFalse(
|
||||
$manager->emailExists($this->user, $email),
|
||||
'invitee-email-not-pending'
|
||||
);
|
||||
$invite = $manager->create(
|
||||
$this->user,
|
||||
$email,
|
||||
'unittest notes',
|
||||
'unittest reason',
|
||||
''
|
||||
);
|
||||
$this->assertEquals(
|
||||
$initial + 1,
|
||||
$manager->totalPending(),
|
||||
'invite-total-pending-invites',
|
||||
);
|
||||
$this->assertEquals(
|
||||
$this->user->id,
|
||||
$manager->findUserByKey($invite->key(), new Manager\User())->id,
|
||||
'invite-manager-find-by-key',
|
||||
);
|
||||
$pending = $manager->pendingInvites(1, 0);
|
||||
$this->assertGreaterThan(0, count($pending), 'invite-list-pending');
|
||||
$this->assertEquals(
|
||||
['user_id', 'ipaddr', 'key', 'expires', 'email', 'source_name'],
|
||||
array_keys($pending[0]),
|
||||
'invite-pending-array-keys',
|
||||
);
|
||||
$this->assertEquals($this->user->id, $pending[0]['user_id'], 'invite-pending-id');
|
||||
$this->assertEquals($invite->key(), $pending[0]['key'], 'invite-pending-id');
|
||||
$this->assertTrue(
|
||||
$manager->emailExists($this->user, $email),
|
||||
'invite-email-exists',
|
||||
);
|
||||
$this->assertEquals(
|
||||
0,
|
||||
$this->user->invite()->revoke('nosuchthing'),
|
||||
'invite-revoke-inexistant',
|
||||
);
|
||||
$this->assertEquals(
|
||||
2,
|
||||
$this->user->invite()->revoke($invite->key()),
|
||||
'invite-revoke-existing',
|
||||
);
|
||||
$this->assertEquals(
|
||||
1,
|
||||
$this->user->unusedInviteTotal(),
|
||||
'invite-unused-1',
|
||||
);
|
||||
}
|
||||
|
||||
public function testEtm(): void {
|
||||
|
||||
@@ -166,6 +166,7 @@ class UserTest extends TestCase {
|
||||
$this->assertEquals(0.0, $this->user->requiredRatio(), 'utest-required-ratio');
|
||||
$this->assertEquals('', $this->user->forbiddenForumsList(), 'utest-forbidden-forum-list');
|
||||
$this->assertEquals('', $this->user->referral(), 'utest-referral');
|
||||
$this->assertEquals('??', $this->user->ipCountryIso(), 'utest-country-iso');
|
||||
$this->assertEquals([], $this->user->tagSnatchCounts(), 'utest-tag-snatch-counts');
|
||||
$this->assertEquals([], $this->user->tokenList(new Manager\Torrent(), 0, 0), 'utest-token-list');
|
||||
$this->assertEquals([], $this->user->navigationList(), 'utest-navigation-list');
|
||||
|
||||
Reference in New Issue
Block a user