162 lines
6.1 KiB
PHP
162 lines
6.1 KiB
PHP
<?php
|
|
namespace Seria\Torrents;
|
|
|
|
use InvalidArgumentException;
|
|
use RuntimeException;
|
|
use Index\Data\DbStatementCache;
|
|
use Index\Data\IDbConnection;
|
|
use Seria\Users\UserInfo;
|
|
|
|
class Torrents {
|
|
private IDbConnection $dbConn;
|
|
private DbStatementCache $cache;
|
|
|
|
public function __construct(IDbConnection $dbConn) {
|
|
$this->dbConn = $dbConn;
|
|
$this->cache = new DbStatementCache($dbConn);
|
|
}
|
|
|
|
public function getTorrents(
|
|
?bool $public = null,
|
|
?bool $approved = null,
|
|
UserInfo|string|null $userInfo = null,
|
|
int $startAt = -1,
|
|
int $take = -1
|
|
): array {
|
|
$hasPublic = $public !== null;
|
|
$hasApproved = $approved !== null;
|
|
$hasUserInfo = $userInfo !== null;
|
|
$hasStartAt = $startAt > 0;
|
|
$hasTake = $take > 0;
|
|
|
|
$args = 0;
|
|
$query = 'SELECT torrent_id, user_id, torrent_hash, torrent_active, torrent_name, UNIX_TIMESTAMP(torrent_created), UNIX_TIMESTAMP(torrent_approved), torrent_piece_length, torrent_private, torrent_comment FROM ser_torrents';
|
|
if($hasPublic) {
|
|
++$args;
|
|
$query .= sprintf(' WHERE torrent_private %s 0', $public ? '=' : '<>');
|
|
}
|
|
if($hasApproved)
|
|
$query .= sprintf(' %s torrent_approved %s NULL', ++$args > 1 ? 'AND' : 'WHERE', $approved ? 'IS NOT' : 'IS');
|
|
if($hasUserInfo)
|
|
$query .= sprintf(' %s user_id = ?', ++$args > 1 ? 'AND' : 'WHERE');
|
|
if($hasStartAt)
|
|
$query .= sprintf(' %s torrent_id < ?', ++$args > 1 ? 'AND' : 'WHERE');
|
|
$query .= ' ORDER BY torrent_id DESC';
|
|
if($hasTake)
|
|
$query .= ' LIMIT ?';
|
|
|
|
$args = 0;
|
|
$stmt = $this->cache->get($query);
|
|
if($hasUserInfo)
|
|
$stmt->addParameter(++$args, $userInfo instanceof UserInfo ? $userInfo->getId() : $userInfo);
|
|
if($hasStartAt)
|
|
$stmt->addParameter(++$args, $startAt);
|
|
if($hasTake)
|
|
$stmt->addParameter(++$args, $take);
|
|
$stmt->execute();
|
|
|
|
$torrents = [];
|
|
$result = $stmt->getResult();
|
|
|
|
while($result->next())
|
|
$torrents[] = new TorrentInfo($result);
|
|
|
|
return $torrents;
|
|
}
|
|
|
|
public const GET_TORRENT_ID = 0x01;
|
|
public const GET_TORRENT_HASH = 0x02;
|
|
|
|
private const GET_TORRENT_SELECT_ALIASES = [
|
|
'id' => self::GET_TORRENT_ID,
|
|
'hash' => self::GET_TORRENT_HASH,
|
|
];
|
|
|
|
public static function resolveGetTorrentSelectAlias(int|string $select): int {
|
|
if(is_string($select)) {
|
|
if(!array_key_exists($select, self::GET_TORRENT_SELECT_ALIASES))
|
|
throw new InvalidArgumentException('Invalid $select alias.');
|
|
$select = self::GET_TORRENT_SELECT_ALIASES[$select];
|
|
} elseif($select === 0)
|
|
throw new InvalidArgumentException('$select may not be zero.');
|
|
|
|
return $select;
|
|
}
|
|
|
|
public function getTorrent(string $value, int|string $select = self::GET_TORRENT_ID): TorrentInfo {
|
|
if($value === '')
|
|
throw new InvalidArgumentException('$value may not be empty.');
|
|
|
|
$select = self::resolveGetTorrentSelectAlias($select);
|
|
$selectId = ($select & self::GET_TORRENT_ID) > 0;
|
|
$selectHash = ($select & self::GET_TORRENT_HASH) > 0;
|
|
|
|
if(!$selectId && !$selectHash)
|
|
throw new InvalidArgumentException('$select flagset is invalid.');
|
|
|
|
$args = 0;
|
|
$query = 'SELECT torrent_id, user_id, torrent_hash, torrent_active, torrent_name, UNIX_TIMESTAMP(torrent_created), UNIX_TIMESTAMP(torrent_approved), torrent_piece_length, torrent_private, torrent_comment FROM ser_torrents';
|
|
if($selectId) {
|
|
++$args;
|
|
$query .= ' WHERE torrent_id = ?';
|
|
}
|
|
if($selectHash)
|
|
$query .= sprintf(' %s torrent_hash = ?', ++$args > 1 ? 'OR' : 'WHERE');
|
|
|
|
$args = 0;
|
|
$stmt = $this->cache->get($query);
|
|
if($selectId)
|
|
$stmt->addParameter(++$args, $value);
|
|
if($selectHash)
|
|
$stmt->addParameter(++$args, $value);
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->getResult();
|
|
if(!$result->next())
|
|
throw new RuntimeException('Download info not found.');
|
|
|
|
return new TorrentInfo($result);
|
|
}
|
|
|
|
public function createTorrent(
|
|
UserInfo|string|null $userInfo,
|
|
string $infoHash,
|
|
string $name,
|
|
int $created,
|
|
int $pieceLength,
|
|
bool $isPrivate,
|
|
string $comment
|
|
): string {
|
|
$stmt = $this->cache->get('INSERT INTO ser_torrents (user_id, torrent_hash, torrent_name, torrent_created, torrent_piece_length, torrent_private, torrent_comment) VALUES (?, ?, ?, FROM_UNIXTIME(?), ?, ?, ?)');
|
|
$stmt->addParameter(1, $userInfo === null ? null : ($userInfo instanceof UserInfo ? $userInfo->getId() : $userInfo));
|
|
$stmt->addParameter(2, $infoHash);
|
|
$stmt->addParameter(3, $name);
|
|
$stmt->addParameter(4, $created);
|
|
$stmt->addParameter(5, $pieceLength);
|
|
$stmt->addParameter(6, $isPrivate ? 1 : 0);
|
|
$stmt->addParameter(7, $comment);
|
|
$stmt->execute();
|
|
|
|
return (string)$this->dbConn->getLastInsertId();
|
|
}
|
|
|
|
public function updateTorrentInfoHash(TorrentInfo|string $torrentInfo, string $infoHash): void {
|
|
$stmt = $this->cache->get('UPDATE ser_torrents SET torrent_hash = ? WHERE torrent_id = ?');
|
|
$stmt->addParameter(1, $infoHash);
|
|
$stmt->addParameter(2, $torrentInfo instanceof TorrentInfo ? $torrentInfo->getId() : $torrentInfo);
|
|
$stmt->execute();
|
|
}
|
|
|
|
public function approveTorrent(TorrentInfo|string $torrentInfo): void {
|
|
$stmt = $this->cache->get('UPDATE ser_torrents SET torrent_approved = COALESCE(torrent_approved, NOW()) WHERE torrent_id = ?');
|
|
$stmt->addParameter(1, $torrentInfo instanceof TorrentInfo ? $torrentInfo->getId() : $torrentInfo);
|
|
$stmt->execute();
|
|
}
|
|
|
|
public function deleteTorrent(TorrentInfo|string $torrentInfo): void {
|
|
$stmt = $this->cache->get('DELETE FROM ser_torrents WHERE torrent_id = ?');
|
|
$stmt->addParameter(1, $torrentInfo instanceof TorrentInfo ? $torrentInfo->getId() : $torrentInfo);
|
|
$stmt->execute();
|
|
}
|
|
}
|