Advertisement
Guest User

Untitled

a guest
Jun 21st, 2019
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.23 KB | None | 0 0
  1. <?php
  2. include_once '_include.php';
  3.  
  4. /**
  5.  * Works for gettings comments
  6.  * And load more comments
  7.  * Algo is quite hard to understand
  8.  * And, it's not the best way to select all records from the database
  9.  */
  10.  
  11. use Util\Ajax; // responsible for returning JSON response
  12. use Util\Input;
  13.  
  14. $user = new Groups\User($mysqli);
  15. $userId = $user -> getId();
  16.  
  17. $postId = Input::int( $_GET['postId'] ?? 0 );
  18. // some validations are dropped out, as not related to the question
  19.  
  20. $helper = $mysqli -> getHelper(); // helper is https://github.com/ThingEngineer/PHP-MySQLi-Database-Class#table-of-contents
  21.  
  22. // for later use
  23. $time = time();
  24.  
  25. $targetTime = Input::int($_GET['targetTime'] ?? 0);
  26. // when a user loads a page, he will get comments in a sorting
  27. // but, the sort changes when a comment gets upvotes (or downvotes)
  28. // therefore, target time is used to count upvotes until the time the user first loaded the page
  29. // this is sent to the client-side, and sent back in the next request
  30. if (!$targetTime)
  31.     $targetTime = $time;
  32.  
  33. // cvu = comments votes user
  34. $commentsResults = $helper -> rawQuery( '
  35.    SELECT
  36.        Id, UserId, PostId, CreateTime, Content, ParentId,
  37.        IsOfficial, IF ( IsRemovedByMod = 1 OR IsRemovedByUser = 1, 1, 0 ) as IsDeleted,
  38.        UserVote AS UserVoteStatus,
  39.    upvotes - downvotes as Score
  40.    FROM (
  41.        SELECT c.*,
  42.        COALESCE(SUM( IF(v.Value = 1, 1, 0) ), 0) as upvotes,
  43.        COALESCE(SUM( IF(v.Value = -1, 1, 0) ), 0) as downvotes,
  44.        ( SELECT Value from postscommentsvotes cvu WHERE cvu.CommentId = c.Id AND UserId = ? LIMIT 1 ) as  UserVote
  45.        FROM postscomments c
  46.        LEFT JOIN postscommentsvotes v ON v.CommentId = c.Id AND v.Time <= ?
  47.        WHERE c.PostId = ? AND
  48.        (
  49.            ( c.IsRemovedByUser = 0 AND c.IsRemovedByMod = 0 )
  50.                OR  
  51.            ( ( SELECT 1 FROM postscomments c2 WHERE c2.ParentId = c.Id LIMIT 1  ) = 1 )
  52.        )
  53.        GROUP BY c.Id
  54.    ) as s
  55.    ORDER BY COALESCE( ((upvotes + 1.9208) / (upvotes + downvotes) -
  56.    1.96 * SQRT((upvotes * downvotes) / (upvotes + downvotes) + 0.9604) /
  57.    (upvotes + downvotes)) / (1 + 3.8416 / (upvotes + downvotes)) , 0) DESC
  58. ',
  59. array ( $userId, $targetTime, $postId )
  60. );
  61.  
  62. if ($helper -> count === 0)
  63.     Ajax::success( ['comments' => []] ); // no comments
  64.  
  65. // this is the hard work done using PHP
  66. // comments are sorted and grouped
  67.  
  68. // variables
  69. $comments = [];
  70. $groupedComments = [
  71.     'parent' => []
  72. ];
  73. $maxParentComments = 20;
  74. $maxChildCommentsPerParent = 5;
  75. $userIdx = []; // note that usernames are not in this application. So, user ids are needed to fetch them
  76. $hasMores = []; // comments which has more childs
  77.  
  78. // load more options
  79. $offset = Input::int( $_GET['offset'] ?? 0 );
  80. // use POST_PARENT as string to load more parent comments
  81. $targetedParent = isset( $_GET['targetedParentId'] ) ? Input::int($_GET['targetedParentId']) : null;
  82. // save skips (for load more)
  83. $skipped = [];
  84. // parents found in targeted search
  85. $parentsFoundInTargetedSearch = [];
  86.  
  87. function addToHasMore($commentId) {
  88.     global $hasMores;
  89.     if (! in_array($commentId, $hasMores) ) {
  90.         $hasMores[] = $commentId;
  91.     }
  92. }
  93. function getSkipped($key) {
  94.     global $skipped;
  95.     return $skipped[$key] ?? 0;
  96. }
  97. function increaseSkipped($key) {
  98.     global $skipped;
  99.     if (!isset($skipped[$key]))
  100.         $skipped[$key] = 0;
  101.     $skipped[$key]++;
  102. }
  103.  
  104. function addComment($key, $comment) {
  105.     global $groupedComments, $userIdx;
  106.     $groupedComments[$key][] = $comment;
  107.     $userIdx[] = $comment['UserId'];
  108. }
  109.  
  110. foreach ($commentsResults as $comment) {
  111.     $commentId = $comment['Id'];
  112.     $comments[$commentId] = $comment;
  113. }
  114. // for memory saving
  115. unset($commentsResults);
  116.  
  117.  
  118. if ($targetedParent !== null && $targetedParent !== 'POST_PARENT') {
  119.     // we need a list of parent ids of targeted
  120.     // this is done for a ordered comments
  121.     // because comment ordering will have children before parents
  122.     $orderedComments = $comments;
  123.     uasort($orderedComments, function($a, $b) {
  124.         return $a['Id'] - $b['Id'];
  125.     });
  126.     foreach ($orderedComments as $c) {
  127.         if ($c['ParentId'] === $targetedParent || in_array($c['ParentId'], $parentsFoundInTargetedSearch))
  128.             $parentsFoundInTargetedSearch[] = $c['Id'];
  129.     }
  130.     unset($orderedComments);
  131. }
  132.  
  133. foreach ($comments as $commentId => $commentArray) {
  134.     $parentId = $commentArray['ParentId'];
  135.     if ($parentId === null) { // main comments
  136.  
  137.         if ($targetedParent !== 'POST_PARENT' && $targetedParent !== null)
  138.             // not interested in parent comments ;)
  139.             continue;
  140.  
  141.         if ( count($groupedComments['parent']) < $maxParentComments ) {
  142.             if ( $offset && getSkipped('parent') < $offset ) {
  143.                 increaseSkipped('parent');
  144.                 continue;
  145.             }
  146.             addComment('parent', $commentArray);
  147.         } else {
  148.             addToHasMore($parentId);
  149.         }
  150.     } else {
  151.         // parent group is already set
  152.         if ( !isset( $groupedComments[$parentId] ) ) {
  153.             $groupedComments[$parentId] = [];
  154.         }
  155.  
  156.         $parentFoundInTargetedSearch = in_array($parentId, $parentsFoundInTargetedSearch);
  157.         if (
  158.             $targetedParent !== null &&  // not targeting
  159.             $targetedParent !== $parentId && // not the targeting parent
  160.             !$parentFoundInTargetedSearch // if this parent was
  161.         ) {
  162.             continue;
  163.         }
  164.  
  165.         if ( count($groupedComments[$parentId]) < $maxChildCommentsPerParent ) {
  166.             if ( $offset && getSkipped($parentId) < $offset && !$parentFoundInTargetedSearch ) {
  167.                 increaseSkipped($parentId);
  168.                 continue;
  169.             }
  170.             addComment($parentId, $commentArray);
  171.  
  172.         } else {
  173.             addToHasMore($parentId);
  174.         }
  175.     }
  176. }
  177. // remove empties
  178. $groupedComments = array_filter( $groupedComments );
  179.  
  180. // get user data
  181. $userData = HyvorAuth\Userbase::getById($userIdx);
  182.  
  183. // return JSON response
  184. Ajax::success(
  185.     [
  186.         'comments' => $groupedComments,
  187.         'meta' => [
  188.             'hasMores' => $hasMores,
  189.             'targetTime' => $targetTime
  190.         ],
  191.         'userData' => $userData
  192.     ]
  193. );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement