diff --git a/database/2019_03_10_183155_change_enum_to_int_in_comment_votes.php b/database/2019_03_10_183155_change_enum_to_int_in_comment_votes.php new file mode 100644 index 00000000..f8a6b87a --- /dev/null +++ b/database/2019_03_10_183155_change_enum_to_int_in_comment_votes.php @@ -0,0 +1,49 @@ +exec(" + ALTER TABLE `msz_comments_votes` + ADD COLUMN `comment_vote` TINYINT NOT NULL DEFAULT '0' AFTER `user_id`, + CHANGE COLUMN `comment_vote` `comment_vote_old` ENUM('Like','Dislike') NULL DEFAULT NULL COLLATE 'utf8mb4_bin' AFTER `comment_vote`, + ADD INDEX `comments_vote_old` (`comment_vote_old`); + "); + + // Step 2, migrate old values + $conn->exec(sprintf( + ' + UPDATE `msz_comments_votes` + SET `comment_vote` = %d + WHERE `comment_vote_old` = "Like" + ', + MSZ_COMMENTS_VOTE_LIKE + )); + $conn->exec(sprintf( + ' + UPDATE `msz_comments_votes` + SET `comment_vote` = %d + WHERE `comment_vote_old` = "Dislike" + ', + MSZ_COMMENTS_VOTE_DISLIKE + )); + + // Step 3, nuke the old column + $conn->exec(' + ALTER TABLE `msz_comments_votes` + DROP COLUMN `comment_vote_old`; + '); +} + +function migrate_down(PDO $conn): void +{ + // this one only goes one way! + $conn->exec("TRUNCATE `msz_comments_votes`"); + $conn->exec(" + ALTER TABLE `msz_comments_votes` + CHANGE COLUMN `comment_vote` `comment_vote` ENUM('Like','Dislike') NULL DEFAULT NULL COLLATE 'utf8mb4_bin' AFTER `user_id`; + "); +} diff --git a/public/comments.php b/public/comments.php index 73efb24b..424e78d6 100644 --- a/public/comments.php +++ b/public/comments.php @@ -87,9 +87,9 @@ switch ($_GET['m'] ?? null) { break; } - $vote = (int)($_GET['v'] ?? 0); + $vote = (int)($_GET['v'] ?? MSZ_COMMENTS_VOTE_INDIFFERENT); - if (!array_key_exists($vote, MSZ_COMMENTS_VOTE_TYPES)) { + if (!comments_vote_type_valid($vote)) { echo render_info_or_json($isXHR, 'Invalid vote action.', 400); break; } @@ -102,7 +102,6 @@ switch ($_GET['m'] ?? null) { break; } - $vote = MSZ_COMMENTS_VOTE_TYPES[(int)($_GET['v'] ?? 0)]; $voteResult = comments_vote_add( $comment, user_session_current('user_id', 0), diff --git a/src/comments.php b/src/comments.php index 22c6f217..c5b137ad 100644 --- a/src/comments.php +++ b/src/comments.php @@ -10,13 +10,13 @@ define('MSZ_PERM_COMMENTS_PIN', 1 << 5); define('MSZ_PERM_COMMENTS_LOCK', 1 << 6); define('MSZ_PERM_COMMENTS_VOTE', 1 << 7); -define('MSZ_COMMENTS_VOTE_INDIFFERENT', null); -define('MSZ_COMMENTS_VOTE_LIKE', 'Like'); -define('MSZ_COMMENTS_VOTE_DISLIKE', 'Dislike'); +define('MSZ_COMMENTS_VOTE_INDIFFERENT', 0); +define('MSZ_COMMENTS_VOTE_LIKE', 1); +define('MSZ_COMMENTS_VOTE_DISLIKE', -1); define('MSZ_COMMENTS_VOTE_TYPES', [ - 0 => MSZ_COMMENTS_VOTE_INDIFFERENT, - 1 => MSZ_COMMENTS_VOTE_LIKE, - -1 => MSZ_COMMENTS_VOTE_DISLIKE, + MSZ_COMMENTS_VOTE_INDIFFERENT, + MSZ_COMMENTS_VOTE_LIKE, + MSZ_COMMENTS_VOTE_DISLIKE, ]); // gets parsed on post @@ -25,6 +25,11 @@ define('MSZ_COMMENTS_MARKUP_USERNAME', '#\B(?:@{1}(' . MSZ_USERNAME_REGEX . '))# // gets parsed on fetch define('MSZ_COMMENTS_MARKUP_USER_ID', '#\B(?:@{2}([0-9]+))#u'); +function comments_vote_type_valid(int $voteType): bool +{ + return in_array($voteType, MSZ_COMMENTS_VOTE_TYPES, true); +} + function comments_parse_for_store(string $text): string { return preg_replace_callback(MSZ_COMMENTS_MARKUP_USERNAME, function ($matches) { @@ -115,9 +120,9 @@ function comments_pin_status(int $comment, bool $mode): ?string return $setPinStatus->execute() ? $status : null; } -function comments_vote_add(int $comment, int $user, ?string $vote): bool +function comments_vote_add(int $comment, int $user, int $vote = MSZ_COMMENTS_VOTE_INDIFFERENT): bool { - if (!in_array($vote, MSZ_COMMENTS_VOTE_TYPES, true)) { + if (!comments_vote_type_valid($vote)) { return false; } @@ -135,21 +140,25 @@ function comments_vote_add(int $comment, int $user, ?string $vote): bool function comments_votes_get(int $commentId): array { - $getVotes = db_prepare(' - SELECT :id as `id`, - ( - SELECT COUNT(`user_id`) - FROM `msz_comments_votes` - WHERE `comment_id` = `id` - AND `comment_vote` = \'Like\' - ) as `likes`, - ( - SELECT COUNT(`user_id`) - FROM `msz_comments_votes` - WHERE `comment_id` = `id` - AND `comment_vote` = \'Dislike\' - ) as `dislikes` - '); + $getVotes = db_prepare(sprintf( + ' + SELECT :id as `id`, + ( + SELECT COUNT(`user_id`) + FROM `msz_comments_votes` + WHERE `comment_id` = `id` + AND `comment_vote` = %1$d + ) as `likes`, + ( + SELECT COUNT(`user_id`) + FROM `msz_comments_votes` + WHERE `comment_id` = `id` + AND `comment_vote` = %2$d + ) as `dislikes` + ', + MSZ_COMMENTS_VOTE_LIKE, + MSZ_COMMENTS_VOTE_DISLIKE + )); $getVotes->bindValue('id', $commentId); return db_fetch($getVotes); } @@ -219,39 +228,43 @@ function comments_category_info($category, bool $createIfNone = false): array ); } -define('MSZ_COMMENTS_CATEGORY_QUERY', ' - SELECT - p.`comment_id`, p.`comment_text`, p.`comment_reply_to`, - p.`comment_created`, p.`comment_pinned`, p.`comment_deleted`, - u.`user_id`, u.`username`, - COALESCE(u.`user_colour`, r.`role_colour`) as `user_colour`, - ( - SELECT COUNT(`comment_id`) - FROM `msz_comments_votes` - WHERE `comment_id` = p.`comment_id` - AND `comment_vote` = \'Like\' - ) as `comment_likes`, - ( - SELECT COUNT(`comment_id`) - FROM `msz_comments_votes` - WHERE `comment_id` = p.`comment_id` - AND `comment_vote` = \'Dislike\' - ) as `comment_dislikes`, - ( - SELECT `comment_vote` - FROM `msz_comments_votes` - WHERE `comment_id` = p.`comment_id` - AND `user_id` = :user - ) as `comment_user_vote` - FROM `msz_comments_posts` as p - LEFT JOIN `msz_users` as u - ON u.`user_id` = p.`user_id` - LEFT JOIN `msz_roles` as r - ON r.`role_id` = u.`display_role` - WHERE p.`category_id` = :category - %1$s - ORDER BY p.`comment_deleted` ASC, p.`comment_pinned` DESC, p.`comment_id` %2$s -'); +define('MSZ_COMMENTS_CATEGORY_QUERY', sprintf( + ' + SELECT + p.`comment_id`, p.`comment_text`, p.`comment_reply_to`, + p.`comment_created`, p.`comment_pinned`, p.`comment_deleted`, + u.`user_id`, u.`username`, + COALESCE(u.`user_colour`, r.`role_colour`) AS `user_colour`, + ( + SELECT COUNT(`comment_id`) + FROM `msz_comments_votes` + WHERE `comment_id` = p.`comment_id` + AND `comment_vote` = %1$d + ) AS `comment_likes`, + ( + SELECT COUNT(`comment_id`) + FROM `msz_comments_votes` + WHERE `comment_id` = p.`comment_id` + AND `comment_vote` = %2$d + ) AS `comment_dislikes`, + ( + SELECT `comment_vote` + FROM `msz_comments_votes` + WHERE `comment_id` = p.`comment_id` + AND `user_id` = :user + ) AS `comment_user_vote` + FROM `msz_comments_posts` AS p + LEFT JOIN `msz_users` AS u + ON u.`user_id` = p.`user_id` + LEFT JOIN `msz_roles` AS r + ON r.`role_id` = u.`display_role` + WHERE p.`category_id` = :category + %%1$s + ORDER BY p.`comment_deleted` ASC, p.`comment_pinned` DESC, p.`comment_id` %%2$s + ', + MSZ_COMMENTS_VOTE_LIKE, + MSZ_COMMENTS_VOTE_DISLIKE +)); // The $parent param should never be used outside of this function itself and should always remain the last of the list. function comments_category_get(int $category, int $user, ?int $parent = null): array diff --git a/templates/_layout/comments.twig b/templates/_layout/comments.twig index f85aa9bf..f15d722c 100644 --- a/templates/_layout/comments.twig +++ b/templates/_layout/comments.twig @@ -89,16 +89,23 @@
{% if not is_deleted and user is not null %} {% if perms.can_vote %} - + {% set like_vote_state = comment.comment_user_vote == constant('MSZ_COMMENTS_VOTE_LIKE') + ? constant('MSZ_COMMENTS_VOTE_INDIFFERENT') + : constant('MSZ_COMMENTS_VOTE_LIKE') %} + {% set dislike_vote_state = comment.comment_user_vote == constant('MSZ_COMMENTS_VOTE_DISLIKE') + ? constant('MSZ_COMMENTS_VOTE_INDIFFERENT') + : constant('MSZ_COMMENTS_VOTE_DISLIKE') %} + + Like {% if comment.comment_likes > 0 %} ({{ comment.comment_likes|number_format }}) {% endif %} - + Dislike {% if comment.comment_dislikes > 0 %}