mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-16 18:04:34 -05:00
248 lines
7.4 KiB
PHP
248 lines
7.4 KiB
PHP
<?php
|
|
|
|
namespace Gazelle;
|
|
|
|
class StaffPM extends BaseObject {
|
|
final public const tableName = 'staff_pm_conversations';
|
|
|
|
public function flush(): static {
|
|
unset($this->info);
|
|
return $this;
|
|
}
|
|
|
|
public function link(): string {
|
|
return sprintf('<a href="%s">%s</a>', $this->url(), display_str($this->subject()));
|
|
}
|
|
|
|
public function location(): string {
|
|
return 'staffpm.php?action=viewconv&id=' . $this->id;
|
|
}
|
|
|
|
public function flushUser(User $user): static {
|
|
self::$cache->delete_multi([
|
|
"num_staff_pms_" . $user->id,
|
|
"staff_pm_new_" . $user->id,
|
|
]);
|
|
return $this;
|
|
}
|
|
|
|
public function info(): array {
|
|
if (isset($this->info)) {
|
|
return $this->info;
|
|
}
|
|
$this->info = self::$db->rowAssoc("
|
|
SELECT spc.Subject AS subject,
|
|
spc.UserID AS user_id,
|
|
spc.Level AS class_level,
|
|
coalesce(p.Name, concat('Level ', spc.Level))
|
|
AS userclass_name,
|
|
spc.AssignedToUser AS assigned_user_id,
|
|
spc.Unread AS unread,
|
|
spc.Status AS status,
|
|
spc.Date AS date
|
|
FROM staff_pm_conversations spc
|
|
LEFT JOIN permissions p USING (Level)
|
|
WHERE spc.ID = ?
|
|
", $this->id
|
|
);
|
|
return $this->info;
|
|
}
|
|
|
|
public function assignedUserId(): int {
|
|
return (int)$this->info()['assigned_user_id'];
|
|
}
|
|
|
|
public function classLevel(): int {
|
|
return $this->info()['class_level'];
|
|
}
|
|
|
|
public function date(): string {
|
|
return $this->info()['date'];
|
|
}
|
|
|
|
public function inProgress(): bool {
|
|
return $this->info()['status'] !== 'Resolved';
|
|
}
|
|
|
|
public function isResolved(): bool {
|
|
return $this->info()['status'] === 'Resolved';
|
|
}
|
|
|
|
public function isUnread(): bool {
|
|
return (bool)$this->info()['unread'];
|
|
}
|
|
|
|
public function subject(): string {
|
|
return $this->info()['subject'];
|
|
}
|
|
|
|
public function unassigned(): bool {
|
|
return $this->assignedUserId() > 0;
|
|
}
|
|
|
|
public function userId(): int {
|
|
return (int)$this->info()['user_id'];
|
|
}
|
|
|
|
public function userclassName(): string {
|
|
return $this->info()['userclass_name'];
|
|
}
|
|
|
|
/**
|
|
* Can the viewer view this message?
|
|
* - They created it or it is assigned to them
|
|
* - They are FLS and it has not yet been assigned
|
|
* - They are Staff and the conversation is viewable at their class level
|
|
*
|
|
* @return bool Can they see it?
|
|
*/
|
|
public function visible(User $viewer): bool {
|
|
return in_array($viewer->id(), [$this->userId(), $this->assignedUserId()])
|
|
|| ($viewer->isFLS() && $this->classLevel() == 0)
|
|
|| ($viewer->isStaff() && $this->classLevel() <= $viewer->privilege()->effectiveClassLevel());
|
|
}
|
|
|
|
public function assign(User $to, User $by): int {
|
|
self::$db->prepared_query("
|
|
UPDATE staff_pm_conversations SET
|
|
Status = 'Unanswered',
|
|
AssignedToUser = ?,
|
|
Level = ?
|
|
WHERE ID = ?
|
|
", $to->id(), $to->privilege()->effectiveClassLevel(), $this->id,
|
|
);
|
|
$affected = self::$db->affected_rows();
|
|
$this->flush();
|
|
$this->flushUser($to);
|
|
$this->flushUser($by);
|
|
return $affected;
|
|
}
|
|
|
|
public function assignClass(int $level, User $viewer): int {
|
|
self::$db->prepared_query("
|
|
UPDATE staff_pm_conversations SET
|
|
Status = 'Unanswered',
|
|
AssignedToUser = NULL,
|
|
Level = ?
|
|
WHERE ID = ?",
|
|
$level, $this->id
|
|
);
|
|
$affected = self::$db->affected_rows();
|
|
$this->flush();
|
|
$this->flushUser($viewer);
|
|
return $affected;
|
|
}
|
|
|
|
public function markAsRead(User $viewer): int {
|
|
self::$db->prepared_query("
|
|
UPDATE staff_pm_conversations SET
|
|
Unread = false
|
|
WHERE ID = ?
|
|
", $this->id
|
|
);
|
|
$affected = self::$db->affected_rows();
|
|
$this->flush();
|
|
$this->flushUser($viewer);
|
|
return $affected;
|
|
}
|
|
|
|
public function reply(User $user, string $message): int {
|
|
self::$db->begin_transaction();
|
|
self::$db->prepared_query("
|
|
INSERT INTO staff_pm_messages
|
|
(UserID, Message, ConvID)
|
|
VALUES (?, ?, ?)
|
|
", $user->id, $message, $this->id
|
|
);
|
|
$affected = self::$db->affected_rows();
|
|
self::$db->prepared_query("
|
|
UPDATE staff_pm_conversations SET
|
|
Date = now(),
|
|
Unread = true,
|
|
Status = ?
|
|
WHERE ID = ?
|
|
", $user->isStaffPMReader() ? 'Open' : 'Unanswered', $this->id
|
|
);
|
|
self::$db->commit();
|
|
$this->flush();
|
|
$this->flushUser($user);
|
|
self::$cache->delete_value("staff_pm_new_{$this->userId()}");
|
|
|
|
$notifMan = new \Gazelle\Manager\Notification();
|
|
$pushToken = $notifMan->pushableTokensById([$this->userId()], \Gazelle\Enum\NotificationType::STAFFPM);
|
|
$notifMan->push($pushToken,
|
|
"Someone replied to your Staff PM", $this->subject(), SITE_URL . '/' . $this->location());
|
|
return $affected;
|
|
}
|
|
|
|
protected function modifyStatus(User $user, string $status, ?int $resolver): int {
|
|
self::$db->prepared_query("
|
|
UPDATE staff_pm_conversations SET
|
|
Date = now(),
|
|
Status = ?,
|
|
ResolverID = ?
|
|
WHERE ID = ?
|
|
", $status, $resolver, $this->id
|
|
);
|
|
$affected = self::$db->affected_rows();
|
|
$this->flush();
|
|
$this->flushUser($user);
|
|
return $affected;
|
|
}
|
|
|
|
public function resolve(User $user): int {
|
|
return $this->modifyStatus($user, 'Resolved', $user->id);
|
|
}
|
|
|
|
public function unresolve(User $user): int {
|
|
return $this->modifyStatus($user, 'Unanswered', null);
|
|
}
|
|
|
|
public function thread(): array {
|
|
self::$db->prepared_query("
|
|
SELECT spm.ID AS id,
|
|
spm.UserID AS user_id,
|
|
um.Username AS username,
|
|
spm.SentDate AS sent_date,
|
|
spm.Message AS body
|
|
FROM staff_pm_messages spm
|
|
INNER JOIN users_main um ON (um.ID = spm.UserID)
|
|
WHERE spm.ConvID = ?
|
|
ORDER BY spm.SentDate
|
|
", $this->id
|
|
);
|
|
return self::$db->to_array(false, MYSQLI_ASSOC);
|
|
}
|
|
|
|
public function postBody(int $postId): ?string {
|
|
foreach ($this->thread() as $post) {
|
|
if ($post['id'] === $postId) {
|
|
return $post['body'];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public function postUserId(int $postId): ?int {
|
|
foreach ($this->thread() as $post) {
|
|
if ($post['id'] === $postId) {
|
|
return $post['user_id'];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public function remove(): int {
|
|
self::$db->prepared_query("
|
|
DELETE spc, spm
|
|
FROM staff_pm_conversations spc
|
|
LEFT JOIN staff_pm_messages spm ON (spm.ConvID = spc.ID)
|
|
WHERE spc.ID = ?
|
|
", $this->id
|
|
);
|
|
$affected = self::$db->affected_rows();
|
|
$this->flush();
|
|
return $affected;
|
|
}
|
|
}
|