From 1c0c257d5de644ee854424adfe9cab2c12d893ed Mon Sep 17 00:00:00 2001 From: zPlus <-> Date: Fri, 18 Mar 2016 15:46:20 +0100 Subject: [PATCH] Fix votes --- .htaccess | 3 + css/freepost.css | 87 +++++++--- database.php | 371 +++++++++++++++++++++++++++++++++++++++-- images/downvote.png | Bin 0 -> 1049 bytes images/upvote.png | Bin 0 -> 1047 bytes javascript/freepost.js | 56 ++++++- post.php | 15 +- template/comment.twig | 62 ++++--- template/index.twig | 60 +++---- template/post.twig | 56 +++---- template/vote.twig | 21 +++ vote.php | 12 +- 12 files changed, 620 insertions(+), 123 deletions(-) create mode 100755 images/downvote.png create mode 100755 images/upvote.png create mode 100644 template/vote.twig diff --git a/.htaccess b/.htaccess index 56fbae38..eb39e68d 100755 --- a/.htaccess +++ b/.htaccess @@ -16,6 +16,9 @@ # Redirect /new to index.php RewriteRule ^new$ index.php?new [NC,L,QSA] + # For votes from post/... + RewriteRule post/vote$ vote.php [NC,L,QSA] + # Show a post's page RewriteRule post/(.+)$ post.php?hash_id=$1 [NC,L,QSA] diff --git a/css/freepost.css b/css/freepost.css index cd55ac8e..9bac743c 100644 --- a/css/freepost.css +++ b/css/freepost.css @@ -69,40 +69,69 @@ html, body line-height: 1.5em; } - /* Home page */ - .content table.posts + .content .vote { + margin: 0 1.5em 0 0; } - - .content table.posts .bump + + .content .vote > a { - color: #888; + display: inline-block; + margin: 0; + overflow: hidden; + padding: 0; + text-decoration: none; + vertical-align: middle; + } + + .content .vote img { cursor: pointer; - font-size: 1.5em; - font-weight: bold; - padding: 0 0 1em 0; - vertical-align: top; + height: 1em; + margin: 0; + padding: .2em; + float: left; } - .content table.posts .bump > a, - .content table.posts .bump > a:hover - { - color: #AAA; - text-decoration: none; - } + .content .vote .upvoted + { + background-color: #fff; + border: 1px solid #00E313; + border-radius: 999em; + } + + .content .vote .downvoted + { + background-color: #fff; + border: 1px solid #FF0000; + border-radius: 999em; + } - .content table.posts .post + .content .vote .count { + margin: 0 .5em; + } + + /* Home page */ + .content .posts + { + } + + .content .posts .post { - padding: 0 0 1em 1em; + margin: 0 0 2em 0; vertical-align: top; } - .content table.posts .post > .title + .content .posts .post > .title { font-size: 1.5em; } - .content table.posts .post > .info + .content .posts .post > .title > a + { + color: #000; + } + + .content .posts .post > .info { color: #666; } @@ -161,20 +190,28 @@ html, body { margin: 0 0 2em 0; } - - .content > .post > .comments > .comment > .info + + .content > .post > .comments > .comment .pin + { + color: #CD006B; + font-size: .8em; + } + + .content > .post > .comments > .comment .info { font-size: .9em; + padding: 0 0 0 .5em; } - .content > .post > .comments > .comment > .info > .username > a, - .content > .post > .comments > .comment > .info > .username > a:hover + .content > .post > .comments > .comment .info .username > a, + .content > .post > .comments > .comment .info .username > a:hover { + font-weight: bold; padding: 0em 0.5em; } - .content > .post > .comments > .comment > .info > .op > a, - .content > .post > .comments > .comment > .info > .op > a:hover + .content > .post > .comments > .comment > .info .op > a, + .content > .post > .comments > .comment > .info .op > a:hover { background-color: rgb(255, 175, 50); border-radius: 4px; diff --git a/database.php b/database.php index 9a0ee8c5..68098c58 100644 --- a/database.php +++ b/database.php @@ -172,21 +172,21 @@ class Database */ function get_post_comments ($post_id) { - $comments = array(); + $comments = array (); - if (is_null($this->database)) + if (is_null ($this->database)) return $comments; - $query = $this->database->prepare( + $query = $this->database->prepare ( 'SELECT C.*, U.`username`' . 'FROM `comment` AS C ' . 'JOIN `user` AS U ON C.`userId` = U.`id`' . 'WHERE C.`postId` = ? ' . 'ORDER BY C.`vote` DESC, C.`created` ASC'); - $query->execute(array($post_id)); + $query->execute (array ($post_id)); - $comments = $query->fetchAll(PDO::FETCH_ASSOC); + $comments = $query->fetchAll (PDO::FETCH_ASSOC); // Group comments by parentId $comments_group = array(); @@ -290,7 +290,7 @@ class Database 'ORDER BY P.`created` DESC ' . 'LIMIT 50'); - $submissions = $query->fetchAll(PDO::FETCH_ASSOC); + $submissions = $query->fetchAll (PDO::FETCH_ASSOC); return $submissions; } @@ -433,6 +433,49 @@ class Database return $sorted_votes; } + /** + * Retrieve a list of votes for a range of comments. + * + * @param comments_id list of IDs (eg. "2,4,5"). + * NOTE: Because arrays can't be used with PDO, $comments_id + * is a string that's concatenated to the SQL query. For + * this reason is the responsibility of the caller to + * check that $comments_id is a valid string of integers + * separated by commans (beware of SQL injection). + */ + function get_comments_votes ($comments_id, $user_id) + { + $votes = array(); + + if (is_null ($this->database) || is_null ($comments_id) || is_null ($user_id)) + return $votes; + + // Run a test anyway to make sure $posts_id is a valid string + $comments_id_array = explode (',', $comments_id); + + foreach ($comments_id_array as $comment_id) + if (!is_numeric ($comment_id)) + return $votes; + + // Retrieve the votes + $query = $this->database->prepare ( + 'SELECT * ' . + 'FROM `vote_comment`' . + 'WHERE `commentId` IN(' . $comments_id . ') AND `userId` = ?'); + + $query->execute (array ($user_id)); + + $votes = $query->fetchAll (PDO::FETCH_ASSOC); + + // Create an array of votes with `commentId` as key + $sorted_votes = array(); + + foreach ($votes as $vote) + $sorted_votes[$vote['commentId']] = $vote; + + return $sorted_votes; + } + /** * Create new user account */ @@ -696,13 +739,41 @@ class Database return false; $query = $this->database->prepare( - 'SELECT 1 ' . + 'SELECT * ' . 'FROM `vote_post`' . 'WHERE `postId` = ? and `userId` = ?'); - $query->execute(array($post_id, $user_id)); + $query->execute (array ($post_id, $user_id)); + + $vote = $query->fetch (PDO::FETCH_ASSOC); + + if (is_null ($vote) || empty ($vote)) + return false; - return $query->rowCount() > 0; + return $vote; + } + + /** + * Tell if a user has voted a comment + */ + function voted_comment ($comment_id, $user_id) + { + if (is_null($this->database)) + return false; + + $query = $this->database->prepare( + 'SELECT * ' . + 'FROM `vote_comment`' . + 'WHERE `commentId` = ? and `userId` = ?'); + + $query->execute (array ($comment_id, $user_id)); + + $vote = $query->fetch (PDO::FETCH_ASSOC); + + if (is_null ($vote) || empty ($vote)) + return false; + + return $vote; } /** @@ -718,24 +789,298 @@ class Database $post = self::get_post ($post_hash_id); // Already voted? - $voted = self::voted_post ($post['id'], $user_id); + $vote = self::voted_post ($post['id'], $user_id); - if (!$voted) + if (false == $vote) { // Cast upvote $query = $this->database->prepare( 'INSERT INTO `vote_post` (`vote`, `datetime`, `postId`, `userId`)' . 'VALUES (1, NOW(), ?, ?)'); + + $query->execute (array ($post['id'], $user_id)); + + // Add +1 to post + $query = $this->database->prepare ( + 'UPDATE `post`' . + 'SET `vote` = `vote` + 1 ' . + 'WHERE `id` = ?'); - $query->execute(array($post['id'], $user_id)); + $query->execute (array ($post['id'])); + + } elseif ($vote['vote'] == 1) { + // Already upvoted before. Remove upvote. - // Add +1 to vote + $query = $this->database->prepare( + 'DELETE FROM `vote_post`' . + 'WHERE `postId` = ? AND `userId` = ?'); + + $query->execute (array ($post['id'], $user_id)); + + // Remove upvote from post + $query = $this->database->prepare ( + 'UPDATE `post`' . + 'SET `vote` = `vote` - 1 ' . + 'WHERE `id` = ?'); + + $query->execute (array ($post['id'])); + + } elseif ($vote['vote'] == -1) { + // Already downvoted before. Change to upvote. + + $query = $this->database->prepare( + 'UPDATE `vote_post`' . + 'SET `vote` = 1 ' . + 'WHERE `postId` = ? AND `userId` = ?'); + + $query->execute (array ($post['id'], $user_id)); + + /* Update post vote count + * +2 because of the previous downvote + */ + $query = $this->database->prepare ( + 'UPDATE `post`' . + 'SET `vote` = `vote` + 2 ' . + 'WHERE `id` = ?'); + + $query->execute (array ($post['id'])); + } + + $this->database->commit (); + + } catch(PDOException $ex) { + + $this->database->rollBack(); + + } + } + + /** + * Downvote a post + */ + function downvote_post ($post_hash_id, $user_id) + { + try { + + $this->database->beginTransaction(); + + // Get the post + $post = self::get_post ($post_hash_id); + + // Already voted? + $vote = self::voted_post ($post['id'], $user_id); + + if (false == $vote) + { + // Cast downvote + $query = $this->database->prepare( + 'INSERT INTO `vote_post` (`vote`, `datetime`, `postId`, `userId`)' . + 'VALUES (-1, NOW(), ?, ?)'); + + $query->execute (array ($post['id'], $user_id)); + + // Add -1 to post + $query = $this->database->prepare ( + 'UPDATE `post`' . + 'SET `vote` = `vote` - 1 ' . + 'WHERE `id` = ?'); + + $query->execute (array ($post['id'])); + + } elseif ($vote['vote'] == -1) { + // Already downvoted before. Remove downvote. + + $query = $this->database->prepare( + 'DELETE FROM `vote_post`' . + 'WHERE `postId` = ? AND `userId` = ?'); + + $query->execute (array ($post['id'], $user_id)); + + // Remove downvote from post $query = $this->database->prepare ( 'UPDATE `post`' . 'SET `vote` = `vote` + 1 ' . 'WHERE `id` = ?'); $query->execute (array ($post['id'])); + + } elseif ($vote['vote'] == 1) { + // Already upvoted before. Change to downvote. + + $query = $this->database->prepare( + 'UPDATE `vote_post`' . + 'SET `vote` = -1 ' . + 'WHERE `postId` = ? AND `userId` = ?'); + + $query->execute (array ($post['id'], $user_id)); + + /* Update post vote count + * -2 because of the previous upvote + */ + $query = $this->database->prepare ( + 'UPDATE `post`' . + 'SET `vote` = `vote` - 2 ' . + 'WHERE `id` = ?'); + + $query->execute (array ($post['id'])); + } + + $this->database->commit (); + + } catch(PDOException $ex) { + + $this->database->rollBack(); + + } + } + + /** + * Upvote a comment + */ + function upvote_comment ($comment_hash_id, $user_id) + { + try { + + $this->database->beginTransaction(); + + // Get the comment + $comment = self::get_comment ($comment_hash_id); + + // Already voted? + $vote = self::voted_comment ($comment['id'], $user_id); + + if (false == $vote) + { + // Cast upvote + $query = $this->database->prepare( + 'INSERT INTO `vote_comment` (`vote`, `datetime`, `commentId`, `userId`)' . + 'VALUES (1, NOW(), ?, ?)'); + + $query->execute (array ($comment['id'], $user_id)); + + // Add +1 to comment + $query = $this->database->prepare ( + 'UPDATE `comment`' . + 'SET `vote` = `vote` + 1 ' . + 'WHERE `id` = ?'); + + $query->execute (array ($comment['id'])); + + } elseif ($vote['vote'] == 1) { + // Already upvoted before. Remove upvote. + + $query = $this->database->prepare( + 'DELETE FROM `vote_comment`' . + 'WHERE `commentId` = ? AND `userId` = ?'); + + $query->execute (array ($comment['id'], $user_id)); + + // Remove upvote from comment + $query = $this->database->prepare ( + 'UPDATE `comment`' . + 'SET `vote` = `vote` - 1 ' . + 'WHERE `id` = ?'); + + $query->execute (array ($comment['id'])); + + } elseif ($vote['vote'] == -1) { + // Already downvoted before. Change to upvote. + + $query = $this->database->prepare( + 'UPDATE `vote_comment`' . + 'SET `vote` = 1 ' . + 'WHERE `commentId` = ? AND `userId` = ?'); + + $query->execute (array ($comment['id'], $user_id)); + + /* Update comment vote count + * +2 because of the previous downvote + */ + $query = $this->database->prepare ( + 'UPDATE `comment`' . + 'SET `vote` = `vote` + 2 ' . + 'WHERE `id` = ?'); + + $query->execute (array ($comment['id'])); + } + + $this->database->commit (); + + } catch(PDOException $ex) { + + $this->database->rollBack(); + + } + } + + /** + * Downvote a comment + */ + function downvote_comment ($comment_hash_id, $user_id) + { + try { + + $this->database->beginTransaction(); + + // Get the comment + $comment = self::get_comment ($comment_hash_id); + + // Already voted? + $vote = self::voted_comment ($comment['id'], $user_id); + + if (false == $vote) + { + // Cast downvote + $query = $this->database->prepare( + 'INSERT INTO `vote_comment` (`vote`, `datetime`, `commentId`, `userId`)' . + 'VALUES (-1, NOW(), ?, ?)'); + + $query->execute (array ($comment['id'], $user_id)); + + // Add -1 to comment + $query = $this->database->prepare ( + 'UPDATE `comment`' . + 'SET `vote` = `vote` - 1 ' . + 'WHERE `id` = ?'); + + $query->execute (array ($comment['id'])); + + } elseif ($vote['vote'] == -1) { + // Already downvoted before. Remove downvote. + + $query = $this->database->prepare( + 'DELETE FROM `vote_comment`' . + 'WHERE `commentId` = ? AND `userId` = ?'); + + $query->execute (array ($comment['id'], $user_id)); + + // Remove downvote from comment + $query = $this->database->prepare ( + 'UPDATE `comment`' . + 'SET `vote` = `vote` + 1 ' . + 'WHERE `id` = ?'); + + $query->execute (array ($comment['id'])); + + } elseif ($vote['vote'] == 1) { + // Already upvoted before. Change to downvote. + + $query = $this->database->prepare( + 'UPDATE `vote_comment`' . + 'SET `vote` = -1 ' . + 'WHERE `commentId` = ? AND `userId` = ?'); + + $query->execute (array ($comment['id'], $user_id)); + + /* Update comment vote count + * -2 because of the previous upvote + */ + $query = $this->database->prepare ( + 'UPDATE `comment`' . + 'SET `vote` = `vote` - 2 ' . + 'WHERE `id` = ?'); + + $query->execute (array ($comment['id'])); } $this->database->commit (); diff --git a/images/downvote.png b/images/downvote.png new file mode 100755 index 0000000000000000000000000000000000000000..3cc8c565861f5fc013f448f685977fd611651ed2 GIT binary patch literal 1049 zcmeAS@N?(olHy`uVBq!ia0vp^4nSl@xwq=GylsM<- z=BDPA0J#hd&iMtEMVaXtB?^aDDpUpJlooTjWEPhcWhRxDq^2m8=B1<-DL5CUCYEHD zr7D1Q=I0eFIF>+EWaj57_+%!h<`t(ZXk?U>6ck(O>nB51CqoqLnBy} zo9G#6>Tz*}WMmdAq-Ex$Dgfz%#G(>~{4|BMqSVxa{NfS?T?LSFK+_;1dc`Hm=4DeD z7?`emx;Tbp+AeodA5_z#`WaU@6rNqdSHb+GVVXpzz2>Yq=GQrH(v8!T zW=zeF<~cH-FQZB?N_>Opi61<+j|(3Jv>cUZRpZ@dwCJb2?tzd6%lEt%*`VC?sGP~T zYuV$2Y?%qyE+q)v5LNtmw(Cda#VnPl#%EZi>X>FJDb$&NFrBbF{`AbFGBGUAn0xpB z7R(jnW#oLY*|8?fBsOBzV!h^y_f|QxT%8Z3J(#Qdd``xx?y{xAah?Y@Y>2&9G5g22 zrxt6OteBHey#HYsAkFk~>w)0YGtPImt(rRJlx^8Bzv^QCQ$IXUc7(-#$~ zU0<3LWOw4E?*!gY_R+huU3#LuPX02xz{y#eroAy=C~%j!Wk96%)7QeOlS^lFY-X!i z((#&IPGjzufEt&1j;R(m=J5&{v+10k^)kOfBIx{~`|`Q-Yu$2^J((mz+YYQq?d%bq z&GdTje!CURojgAM51%vVj`~W2Z>P#Co!)6rGJ7BbPG%M|sSosDc^u#pQCZ9j%9Nh2 KelF{r5}E)sbi^?L literal 0 HcmV?d00001 diff --git a/images/upvote.png b/images/upvote.png new file mode 100755 index 0000000000000000000000000000000000000000..e7e68a4a191ef18dba226081c5b09d03cb9119f5 GIT binary patch literal 1047 zcmeAS@N?(olHy`uVBq!ia0vp^4nSlxC{)=`303lnduoN3WruIR0ZUe7IV2|7MB!dCY6??rYMx=rKA=qI2WZRmSmQt zDu8t6=M^hBmOxZw=I1H+WG1KP6{jj_WR#Q?6kF-*Cqq>yLlo=f7p3dxKok}0Cspd3 z=ox70adCxYWELx=W#*(R0O^9nq7sGtG=;RH)YO9f;t~a21(0z-(;y;x#U;w-Wm6a! zn67%dIEG~0dpq;IcSxYfaeI@Q0nU@vrY5d7S~#hxC^BTr37*rTx?EY&)x{HAzRHWF zSQjTMUe(J|4Ds1E>4@)wnT`@1j!S#mGR|#z!E@H;oo(;A_22K^;kSAAamV{Pziq$o zt3Geb%-4SSVS$C#RF9c|w=-8a_D_}gla>&+?wObHes&4=prYQ>o4XRU4Kxo;E?W8| zGWW*O;|(u)K5Cx-yJZWf>Q;w43iqU2Dk9PkO>o@uR*Gx(kHo_s>i<9ISnwP&XE;A4 z)1Jd7(5`)XlJbTxT94*2OE+qKaN@l5cR|`nt`|md%UcKQe(;tI1oG*Wy?eDZ_)`<|?n15iR>5ZI;<-TU(N0#ebFr10rwlVTS zgxt1%=Hh9&C2=*=r@AGaH1gWt;LZA>FfwOmjn351615yNHkRZpb$DdlydmkMsdBBR zrgekn=`H?D;$06uFFG2|^+Tmri!<=wwGTdvH}c%kS@b^dW8x=U#aeBxuLo94+H_Cv zAj6%&pf`aD(Hmv*+3snyPm@;t!?Jsd^EK_4*^ZqI%w9>CyfeMu2tH_>RKY8<$v)I! zztTU!4f}X@2Z(-%u(YwAVpi$C%fGXvUUAM7$ri`df?uCza=uQvdX-D+s@(~f)s53n z-MXS173RBq)2)5XuWCxfREi3QjgN6%^wJ*PD_3!WP6fP(Kb#3dsHYG+y zs5SW7t#d!paNf)Dsh1urZ}cw9smYFu@4R8(r;+)q^6i0*88e-V57;#wc3f(=Q6p+| z2CL9CaiIf#O~>_AIXEAbq&D+$yuy%gJ26ZB$DGd@ zRcqfS1wPnolA~%fN7Pq&=bNP71DuDBYbKaOl9|jQ`9HJvD{**MhJv!Br>mdKI;Vst E0DPprq5uE@ literal 0 HcmV?d00001 diff --git a/javascript/freepost.js b/javascript/freepost.js index 5c61a53e..50917895 100644 --- a/javascript/freepost.js +++ b/javascript/freepost.js @@ -3,6 +3,58 @@ * to the user after clicks. */ -function hide (dom_element) { - dom_element.style.visibility = 'hidden'; +function vote (action, dom_element) { + var arrow_up = dom_element.children[0]; + var vote_counter = dom_element.children[1]; + var arrow_down = dom_element.children[2]; + + // Voted/Upvoted + var current_status = 0; + + if ("upvoted" == arrow_up.className) + current_status = 1; + + if ("downvoted" == arrow_down.className) + current_status = -1; + + // Current vote + var current_vote = Number (vote_counter.textContent); + + // Remove class from arrows + arrow_up.className = ""; + arrow_down.className = ""; + + // Toggle upvote class for arrow + if ("up" == action) + switch (current_status) + { + case -1: + vote_counter.textContent = current_vote + 2; + arrow_up.className = "upvoted"; + break; + case 0: + vote_counter.textContent = current_vote + 1; + arrow_up.className = "upvoted"; + break; + case 1: + vote_counter.textContent = current_vote - 1; + break; + } + + // Toggle downvote class for arrow + if ("down" == action) + switch (current_status) + { + case -1: + vote_counter.textContent = current_vote + 1; + break; + case 0: + vote_counter.textContent = current_vote - 1; + arrow_down.className = "downvoted"; + break; + case 1: + vote_counter.textContent = current_vote - 2; + arrow_down.className = "downvoted"; + break; + } } \ No newline at end of file diff --git a/post.php b/post.php index 0af8ae70..5be3509a 100644 --- a/post.php +++ b/post.php @@ -56,11 +56,20 @@ if (empty ($post)) } // Retrieve if user has voted this post -$votes = $db->get_posts_votes ($post['id'], Session::get_userid ()); +$votes_post = $db->get_posts_votes ($post['id'], Session::get_userid ()); // Retrieve comments for this post $comments = $db->get_post_comments ($post['id']); +// Retrieve a list of user votes for the comments +$IDs = array(); + +foreach ($comments as $parent) + foreach ($parent as $child) + $IDs[] = $child['id']; + +$votes_comment = $db->get_comments_votes (implode (',', $IDs), Session::get_userid ()); + // Render template echo $twig->render ( 'post.twig', @@ -68,7 +77,9 @@ echo $twig->render ( 'title' => $post['title'], 'post' => $post, 'comments' => $comments, - 'votes' => $votes)); + 'votes' => array ( + 'post' => $votes_post, + 'comment' => $votes_comment))); diff --git a/template/comment.twig b/template/comment.twig index 6b40fbc2..8cacf9fb 100644 --- a/template/comment.twig +++ b/template/comment.twig @@ -1,38 +1,56 @@ {% if comments[parent_id] %} {% for comment in comments[parent_id] %} -
+ {# Add an anchor link for this comment #} -
- {# Username #} - - {{ comment.username }} - +
+ - {# DateTime #} - {{ comment.created|ago }} - - — - - {# Reply #} - Reply - - {# Edit #} - {% if user and comment.userId == user.id %} - Edit - {% endif %} - - - {{ comment.text|markdown|raw }} - + + + + + + +
+ {# Username #} + + {{ comment.username }} + + + {% + include 'vote.twig' with { + target: 'comment', + hash_id: comment.hashId, + vote: votes[comment.id] is defined ? votes[comment.id].vote : null, + vote_count: comment.vote + } only + %} + + {# DateTime #} + {{ comment.created|ago }} + + — + + {# Reply #} + Reply + + {# Edit #} + {% if user and comment.userId == user.id %} + Edit + {% endif %} +
+ {{ comment.text|markdown|raw }} +
{# Add replies #} {% include 'comment.twig' with { 'post': post, 'comments': comments, + 'votes': votes.comment, 'parent_id': comment.id, 'depth': depth + 1 } %} diff --git a/template/index.twig b/template/index.twig index 36a63971..d69d2d6f 100644 --- a/template/index.twig +++ b/template/index.twig @@ -1,37 +1,41 @@ {% include 'header.twig' %} - +
+ {% for post in posts %} -
- + - - + {{ post.commentsCount ? post.commentsCount }} comments + + + {% endfor %} -
- {% if not votes[post.id] %} - + +
+
+ {% if post.link|length > 0 %} + + {{ post.title }} + + {% else %} + + {{ post.title }} + {% endif %} -
-
- {% if post.link|length > 0 %} - - {{ post.title }} - - {% else %} - - {{ post.title }} - - {% endif %} -
+
+ {% + include 'vote.twig' with { + target: 'post', + hash_id: post.hashId, + vote: votes[post.id] is defined ? votes[post.id].vote : null, + vote_count: post.vote + } only + %} + + {{ post.created|ago }} + by {{ post.username }} • - -
+ +
{% include 'footer.twig' %} diff --git a/template/post.twig b/template/post.twig index 9aaca20e..ef27fbc6 100644 --- a/template/post.twig +++ b/template/post.twig @@ -2,36 +2,33 @@
- - - - - - -
- {% if not votes[post.id] %} - - {% endif %} - -
- {% if post.link|length > 0 %} - - {{ post.title }} - - {% else %} - {{ post.title }} - {% endif %} -
+
+ {% if post.link|length > 0 %} + + {{ post.title }} + + {% else %} + {{ post.title }} + {% endif %} +
-
- by {{ post.username }} {{ post.created|ago }} - — {{ post.vote }} votes, {{ post.commentsCount }} comments - - {% if user and post.userId == user.id %} - — Edit - {% endif %} -
-
+
+ {% + include 'vote.twig' with { + target: 'post', + hash_id: post.hashId, + vote: votes.post[post.id] is defined ? votes.post[post.id].vote : null, + vote_count: post.vote + } only + %} + + by {{ post.username }} {{ post.created|ago }} + — {{ post.vote }} votes, {{ post.commentsCount }} comments + + {% if user and post.userId == user.id %} + — Edit + {% endif %} +
{{ post.text|markdown|raw }} @@ -51,6 +48,7 @@ {% include 'comment.twig' with { 'post': post, 'comments': comments, + 'votes': votes.comment, 'parent_id': 0, 'depth': 0 } %} diff --git a/template/vote.twig b/template/vote.twig new file mode 100644 index 00000000..3288e0fa --- /dev/null +++ b/template/vote.twig @@ -0,0 +1,21 @@ +{# Template for up/down vote arrows. + # This template expects these inputs + # + # - target: ('post', 'comment') + # - hash_id: the post/comment hashId + # - vote: (optional) the vote already cast by current logged in user + # - vote_count: the sum of votes for this post/comment + #} + + + + bump + + + {# Show number of votes #} + {{ vote_count }} + + + sink + + \ No newline at end of file diff --git a/vote.php b/vote.php index e6425ff9..371f7b7b 100644 --- a/vote.php +++ b/vote.php @@ -16,12 +16,20 @@ if (isset ($_GET['post'])) if (isset ($_GET['up'])) $db->upvote_post ($_GET['post'], Session::get_userid ()); + if (isset ($_GET['down'])) + $db->downvote_post ($_GET['post'], Session::get_userid ()); + exit (); } // Vote a comment if (isset ($_GET['comment'])) { + if (isset ($_GET['up'])) + $db->upvote_comment ($_GET['comment'], Session::get_userid ()); + + if (isset ($_GET['down'])) + $db->downvote_comment ($_GET['comment'], Session::get_userid ()); + exit (); -} - +} \ No newline at end of file