diff --git a/README.md b/README.md index d01055b..e407672 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ git checkout -b my-pr-branch-name + [x] Options + [x] Public + [x] Sensitive - + [ ] Comments + + [x] Comments + [ ] Features + [x] Scrape trackers + [x] Peers @@ -71,7 +71,7 @@ git checkout -b my-pr-branch-name + [x] Leechers + [x] Stars + [x] Downloads - + [ ] Comments + + [x] Threading comments + [ ] Views + [ ] Info page diff --git a/database/yggtracker.mwb b/database/yggtracker.mwb index 59fce6f..9541d33 100644 Binary files a/database/yggtracker.mwb and b/database/yggtracker.mwb differ diff --git a/src/config/app.php.example b/src/config/app.php.example index 9feba8d..c459053 100644 --- a/src/config/app.php.example +++ b/src/config/app.php.example @@ -83,6 +83,12 @@ define('MAGNET_EDITOR_LOCK_TIMEOUT', 60*60); define('MAGNET_META_TITLE_MIN_LENGTH', 10); define('MAGNET_META_DESCRIPTION_MIN_LENGTH', 0); +// Comment +define('COMMENT_DEFAULT_APPROVED', false); +define('COMMENT_DEFAULT_PUBLIC', false); +define('COMMENT_MIN_LENGTH', 1); +define('COMMENT_MAX_LENGTH', 1000); + // Trackers define('TRACKER_LINKS', (object) [ diff --git a/src/library/database.php b/src/library/database.php index 1658d36..c6d78e1 100644 --- a/src/library/database.php +++ b/src/library/database.php @@ -471,6 +471,17 @@ class Database { return $this->addUser($address, $approved, $timeAdded); } + public function updateUserApproved(int $userId, mixed $approved, int $timeUpdated) : int { + + $this->_debug->query->update->total++; + + $query = $this->_db->prepare('UPDATE `user` SET `approved` = ?, `timeUpdated` = ? WHERE `userId` = ?'); + + $query->execute([(int) $approved, $timeUpdated, $userId]); + + return $query->rowCount(); + } + // Magnet public function addMagnet(int $userId, string $xt, @@ -961,6 +972,61 @@ class Database { } // Magnet comment + public function addMagnetComment( int $magnetId, + int $userId, + mixed $magnetCommentIdParent, + string $value, + bool $approved, + bool $public, + int $timeAdded) : int { + + $this->_debug->query->insert->total++; + + $query = $this->_db->prepare('INSERT INTO `magnetComment` SET `magnetId` = ?, + `userId` = ?, + `magnetCommentIdParent` = ?, + `value` = ?, + `approved` = ?, + `public` = ?, + `timeAdded` = ?'); + + $query->execute( + [ + $magnetId, + $userId, + $magnetCommentIdParent, + $value, + $approved, + $public, + $timeAdded + ] + ); + + return $this->_db->lastInsertId(); + } + + public function updateMagnetCommentPublic(int $magnetCommentId, mixed $public) : int { + + $this->_debug->query->update->total++; + + $query = $this->_db->prepare('UPDATE `magnetComment` SET `public` = ? WHERE `magnetCommentId` = ?'); + + $query->execute([(int) $public, $magnetCommentId]); + + return $query->rowCount(); + } + + public function updateMagnetCommentApproved(int $magnetCommentId, mixed $approved) : int { + + $this->_debug->query->update->total++; + + $query = $this->_db->prepare('UPDATE `magnetComment` SET `approved` = ? WHERE `magnetCommentId` = ?'); + + $query->execute([(int) $approved, $magnetCommentId]); + + return $query->rowCount(); + } + public function getMagnetCommentsTotal(int $magnetId) : int { $this->_debug->query->select->total++; @@ -972,6 +1038,26 @@ class Database { return $query->fetch()->result; } + public function getMagnetComments(int $magnetId, mixed $magnetCommentIdParent = null) { + + $this->_debug->query->select->total++; + + if ($magnetCommentIdParent) + { + $query = $this->_db->prepare('SELECT * FROM `magnetComment` WHERE `magnetId` = ? AND `magnetCommentIdParent` = ?'); + + $query->execute([$magnetId, $magnetCommentIdParent]); + } + else + { + $query = $this->_db->prepare('SELECT * FROM `magnetComment` WHERE `magnetId` = ? AND `magnetCommentIdParent` IS NULL'); + + $query->execute([$magnetId]); + } + + return $query->fetchAll(); + } + public function findMagnetCommentsTotalByUserId(int $magnetId, int $userId) : int { $this->_debug->query->select->total++; @@ -983,6 +1069,17 @@ class Database { return $query->fetch()->result; } + public function getMagnetComment(int $magnetCommentId) { + + $this->_debug->query->select->total++; + + $query = $this->_db->prepare('SELECT * FROM `magnetComment` WHERE `magnetCommentId` = ?'); + + $query->execute([$magnetCommentId]); + + return $query->fetch(); + } + // Magnet star public function addMagnetStar(int $magnetId, int $userId, int $timeAdded) : int { diff --git a/src/public/action.php b/src/public/action.php index 9ceba22..0cb7581 100644 --- a/src/public/action.php +++ b/src/public/action.php @@ -29,6 +29,246 @@ switch (isset($_GET['target']) ? urldecode($_GET['target']) : false) { case 'comment': + switch (isset($_GET['toggle']) ? $_GET['toggle'] : false) + { + case 'approved': + + // Yggdrasil connections only + if (!preg_match(YGGDRASIL_URL_REGEX, $_SERVER['REMOTE_ADDR'])) + { + $response->success = false; + $response->message = _('Yggdrasil connection required for this action'); + } + + // Init session + else if (!$userId = $db->initUserId($_SERVER['REMOTE_ADDR'], USER_DEFAULT_APPROVED, time())) + { + $response->success = false; + $response->message = _('Could not init user session'); + } + + // Get user + else if (!$user = $db->getUser($userId)) + { + $response->success = false; + $response->message = _('Could not init user info'); + } + + // Magnet comment exists + else if (!$magnetComment = $db->getMagnetComment(isset($_GET['magnetCommentId']) && $_GET['magnetCommentId'] > 0 ? (int) $_GET['magnetCommentId'] : 0)) + { + $response->success = false; + $response->message = _('Requested magnet comment not found'); + } + + // Access allowed + else if (!in_array($user->address, MODERATOR_IP_LIST)) { + + $response->success = false; + $response->message = _('Access denied'); + } + + // Validate callback + else if (empty($_GET['callback'])) + { + $response->success = false; + $response->message = _('Callback required'); + } + + // Validate base64 + else if (!$callback = (string) @base64_decode($_GET['callback'])) + { + $response->success = false; + $response->message = _('Invalid callback encoding'); + } + + // Request valid + else + { + if ($magnetComment->approved) + { + $db->updateMagnetCommentApproved($magnetComment->magnetCommentId, false); + + if (USER_AUTO_APPROVE_ON_COMMENT_APPROVE) + { + $db->updateUserApproved($magnetComment->userId, false, time()); + } + } + else + { + $db->updateMagnetCommentApproved($magnetComment->magnetCommentId, true); + + if (USER_AUTO_APPROVE_ON_COMMENT_APPROVE) + { + $db->updateUserApproved($magnetComment->userId, true, time()); + } + } + + // Redirect to edit page + header( + sprintf('Location: %s', $callback) + ); + } + + break; + + case 'public': + + // Yggdrasil connections only + if (!preg_match(YGGDRASIL_URL_REGEX, $_SERVER['REMOTE_ADDR'])) + { + $response->success = false; + $response->message = _('Yggdrasil connection required for this action'); + } + + // Init session + else if (!$userId = $db->initUserId($_SERVER['REMOTE_ADDR'], USER_DEFAULT_APPROVED, time())) + { + $response->success = false; + $response->message = _('Could not init user session'); + } + + // Get user + else if (!$user = $db->getUser($userId)) + { + $response->success = false; + $response->message = _('Could not init user info'); + } + + // Magnet comment exists + else if (!$magnetComment = $db->getMagnetComment(isset($_GET['magnetCommentId']) && $_GET['magnetCommentId'] > 0 ? (int) $_GET['magnetCommentId'] : 0)) + { + $response->success = false; + $response->message = _('Requested magnet comment not found'); + } + + // Access allowed + else if (!($user->address == $db->getUser($magnetComment->userId)->address || in_array($user->address, MODERATOR_IP_LIST))) { + + $response->success = false; + $response->message = _('Access denied'); + } + + // Validate callback + else if (empty($_GET['callback'])) + { + $response->success = false; + $response->message = _('Callback required'); + } + + // Validate base64 + else if (!$callback = (string) @base64_decode($_GET['callback'])) + { + $response->success = false; + $response->message = _('Invalid callback encoding'); + } + + // Request valid + else + { + if ($magnetComment->public) + { + $db->updateMagnetCommentPublic($magnetComment->magnetCommentId, false); + } + else{ + $db->updateMagnetCommentPublic($magnetComment->magnetCommentId, true); + } + + // Redirect to edit page + header( + sprintf('Location: %s', $callback) + ); + } + + break; + + case 'new': + + // Yggdrasil connections only + if (!preg_match(YGGDRASIL_URL_REGEX, $_SERVER['REMOTE_ADDR'])) + { + $response->success = false; + $response->message = _('Yggdrasil connection required for this action'); + } + + // Init session + else if (!$userId = $db->initUserId($_SERVER['REMOTE_ADDR'], USER_DEFAULT_APPROVED, time())) + { + $response->success = false; + $response->message = _('Could not init user session'); + } + + // Get user + else if (!$user = $db->getUser($userId)) + { + $response->success = false; + $response->message = _('Could not init user info'); + } + + // Magnet exists + else if (!$magnet = $db->getMagnet(isset($_GET['magnetId']) && $_GET['magnetId'] > 0 ? (int) $_GET['magnetId'] : 0)) + { + $response->success = false; + $response->message = _('Requested magnet not found'); + } + + // Access allowed + else if (!($user->address == $db->getUser($magnet->userId)->address || in_array($user->address, MODERATOR_IP_LIST) || ($magnet->public && $magnet->approved))) { + + $response->success = false; + $response->message = _('Magnet not available for this action'); + } + + // Validate callback + else if (empty($_GET['callback'])) + { + $response->success = false; + $response->message = _('Callback required'); + } + + // Validate base64 + else if (!$callback = (string) @base64_decode($_GET['callback'])) + { + $response->success = false; + $response->message = _('Invalid callback encoding'); + } + + // Validate comment value + else if (empty($_POST['comment']) || + mb_strlen($_POST['comment']) < COMMENT_MIN_LENGTH || + mb_strlen($_POST['comment']) > COMMENT_MAX_LENGTH) + { + $response->success = false; + $response->message = sprintf(_('Valid comment value required, %s-%s chars allowed'), COMMENT_MIN_LENGTH, COMMENT_MAX_LENGTH); + } + + // Request valid + else + { + if ($magnetCommentId = $db->addMagnetComment($magnet->magnetId, + $user->userId, + null, // @TODO implement threads + trim($_POST['comment']), + $user->approved || in_array($user->address, MODERATOR_IP_LIST) ? true : COMMENT_DEFAULT_APPROVED, + COMMENT_DEFAULT_PUBLIC, + time())) + { + // Redirect to referrer page + header( + sprintf('Location: %s#comment-%s', $callback, $magnetCommentId) + ); + } + } + + break; + + default: + + header( + sprintf('Location: %s', WEBSITE_URL) + ); + } + break; case 'star': diff --git a/src/public/assets/theme/default/css/common.css b/src/public/assets/theme/default/css/common.css index 2919dfb..1636283 100644 --- a/src/public/assets/theme/default/css/common.css +++ b/src/public/assets/theme/default/css/common.css @@ -50,9 +50,11 @@ input:focus { color: #fff; } +/* @TODO improve focus out textarea:focus { min-height: 120px; } +*/ textarea::placeholder, input::placeholder { diff --git a/src/public/edit.php b/src/public/edit.php index 888dfb0..309ca13 100644 --- a/src/public/edit.php +++ b/src/public/edit.php @@ -114,6 +114,10 @@ $response = (object) 'message' => false, ] ], + 'approved' => (object) + [ + 'value' => false, + ], ] ]; @@ -370,6 +374,7 @@ else { $response->form->public->value = (bool) $magnet->public; $response->form->comments->value = (bool) $magnet->comments; $response->form->sensitive->value = (bool) $magnet->sensitive; + $response->form->approved->value = (bool) $magnet->approved; // Display Name $response->form->dn->value = $magnet->dn; @@ -549,7 +554,7 @@ else { address, MODERATOR_IP_LIST)) { ?>