Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- include_once '_include.php';
- /**
- * Works for gettings comments
- * And load more comments
- * Algo is quite hard to understand
- * And, it's not the best way to select all records from the database
- */
- use Util\Ajax; // responsible for returning JSON response
- use Util\Input;
- $user = new Groups\User($mysqli);
- $userId = $user -> getId();
- $postId = Input::int( $_GET['postId'] ?? 0 );
- // some validations are dropped out, as not related to the question
- $helper = $mysqli -> getHelper(); // helper is https://github.com/ThingEngineer/PHP-MySQLi-Database-Class#table-of-contents
- // for later use
- $time = time();
- $targetTime = Input::int($_GET['targetTime'] ?? 0);
- // when a user loads a page, he will get comments in a sorting
- // but, the sort changes when a comment gets upvotes (or downvotes)
- // therefore, target time is used to count upvotes until the time the user first loaded the page
- // this is sent to the client-side, and sent back in the next request
- if (!$targetTime)
- $targetTime = $time;
- // cvu = comments votes user
- $commentsResults = $helper -> rawQuery( '
- SELECT
- Id, UserId, PostId, CreateTime, Content, ParentId,
- IsOfficial, IF ( IsRemovedByMod = 1 OR IsRemovedByUser = 1, 1, 0 ) as IsDeleted,
- UserVote AS UserVoteStatus,
- upvotes - downvotes as Score
- FROM (
- SELECT c.*,
- COALESCE(SUM( IF(v.Value = 1, 1, 0) ), 0) as upvotes,
- COALESCE(SUM( IF(v.Value = -1, 1, 0) ), 0) as downvotes,
- ( SELECT Value from postscommentsvotes cvu WHERE cvu.CommentId = c.Id AND UserId = ? LIMIT 1 ) as UserVote
- FROM postscomments c
- LEFT JOIN postscommentsvotes v ON v.CommentId = c.Id AND v.Time <= ?
- WHERE c.PostId = ? AND
- (
- ( c.IsRemovedByUser = 0 AND c.IsRemovedByMod = 0 )
- OR
- ( ( SELECT 1 FROM postscomments c2 WHERE c2.ParentId = c.Id LIMIT 1 ) = 1 )
- )
- GROUP BY c.Id
- ) as s
- ORDER BY COALESCE( ((upvotes + 1.9208) / (upvotes + downvotes) -
- 1.96 * SQRT((upvotes * downvotes) / (upvotes + downvotes) + 0.9604) /
- (upvotes + downvotes)) / (1 + 3.8416 / (upvotes + downvotes)) , 0) DESC
- ',
- array ( $userId, $targetTime, $postId )
- );
- if ($helper -> count === 0)
- Ajax::success( ['comments' => []] ); // no comments
- // this is the hard work done using PHP
- // comments are sorted and grouped
- // variables
- $comments = [];
- $groupedComments = [
- 'parent' => []
- ];
- $maxParentComments = 20;
- $maxChildCommentsPerParent = 5;
- $userIdx = []; // note that usernames are not in this application. So, user ids are needed to fetch them
- $hasMores = []; // comments which has more childs
- // load more options
- $offset = Input::int( $_GET['offset'] ?? 0 );
- // use POST_PARENT as string to load more parent comments
- $targetedParent = isset( $_GET['targetedParentId'] ) ? Input::int($_GET['targetedParentId']) : null;
- // save skips (for load more)
- $skipped = [];
- // parents found in targeted search
- $parentsFoundInTargetedSearch = [];
- function addToHasMore($commentId) {
- global $hasMores;
- if (! in_array($commentId, $hasMores) ) {
- $hasMores[] = $commentId;
- }
- }
- function getSkipped($key) {
- global $skipped;
- return $skipped[$key] ?? 0;
- }
- function increaseSkipped($key) {
- global $skipped;
- if (!isset($skipped[$key]))
- $skipped[$key] = 0;
- $skipped[$key]++;
- }
- function addComment($key, $comment) {
- global $groupedComments, $userIdx;
- $groupedComments[$key][] = $comment;
- $userIdx[] = $comment['UserId'];
- }
- foreach ($commentsResults as $comment) {
- $commentId = $comment['Id'];
- $comments[$commentId] = $comment;
- }
- // for memory saving
- unset($commentsResults);
- if ($targetedParent !== null && $targetedParent !== 'POST_PARENT') {
- // we need a list of parent ids of targeted
- // this is done for a ordered comments
- // because comment ordering will have children before parents
- $orderedComments = $comments;
- uasort($orderedComments, function($a, $b) {
- return $a['Id'] - $b['Id'];
- });
- foreach ($orderedComments as $c) {
- if ($c['ParentId'] === $targetedParent || in_array($c['ParentId'], $parentsFoundInTargetedSearch))
- $parentsFoundInTargetedSearch[] = $c['Id'];
- }
- unset($orderedComments);
- }
- foreach ($comments as $commentId => $commentArray) {
- $parentId = $commentArray['ParentId'];
- if ($parentId === null) { // main comments
- if ($targetedParent !== 'POST_PARENT' && $targetedParent !== null)
- // not interested in parent comments ;)
- continue;
- if ( count($groupedComments['parent']) < $maxParentComments ) {
- if ( $offset && getSkipped('parent') < $offset ) {
- increaseSkipped('parent');
- continue;
- }
- addComment('parent', $commentArray);
- } else {
- addToHasMore($parentId);
- }
- } else {
- // parent group is already set
- if ( !isset( $groupedComments[$parentId] ) ) {
- $groupedComments[$parentId] = [];
- }
- $parentFoundInTargetedSearch = in_array($parentId, $parentsFoundInTargetedSearch);
- if (
- $targetedParent !== null && // not targeting
- $targetedParent !== $parentId && // not the targeting parent
- !$parentFoundInTargetedSearch // if this parent was
- ) {
- continue;
- }
- if ( count($groupedComments[$parentId]) < $maxChildCommentsPerParent ) {
- if ( $offset && getSkipped($parentId) < $offset && !$parentFoundInTargetedSearch ) {
- increaseSkipped($parentId);
- continue;
- }
- addComment($parentId, $commentArray);
- } else {
- addToHasMore($parentId);
- }
- }
- }
- // remove empties
- $groupedComments = array_filter( $groupedComments );
- // get user data
- $userData = HyvorAuth\Userbase::getById($userIdx);
- // return JSON response
- Ajax::success(
- [
- 'comments' => $groupedComments,
- 'meta' => [
- 'hasMores' => $hasMores,
- 'targetTime' => $targetTime
- ],
- 'userData' => $userData
- ]
- );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement