# HG changeset patch # User Dan # Date 1261131122 18000 # Node ID b5b8e7ab091403201f8eee35df865cfb4ae17818 # Parent db6b116b8ea72d71584016a3ada136397a05e45c Comments (AJAX): Now paginated server side. Fixes issue 2. diff -r db6b116b8ea7 -r b5b8e7ab0914 includes/clientside/static/comments.js --- a/includes/clientside/static/comments.js Fri Dec 18 05:05:01 2009 -0500 +++ b/includes/clientside/static/comments.js Fri Dec 18 05:12:02 2009 -0500 @@ -5,13 +5,14 @@ window.ajaxComments = function(parms) { - load_component(['l10n', 'paginate', 'template-compiler', 'toolbar', 'flyin']); + load_component(['l10n', 'paginate', 'template-compiler', 'toolbar', 'flyin', 'jquery', 'jquery-ui']); setAjaxLoading(); var pid = strToPageID(title); if(!parms) { var parms = { - 'mode' : 'fetch' + mode: 'fetch', + pagenum: 0 }; } parms.page_id = pid[0]; @@ -35,13 +36,25 @@ switch(response.mode) { case 'fetch': - document.getElementById('ajaxEditContainer').innerHTML = '
Rendering '+response.count_total+' comments...
'; if(response.template) comment_template = response.template; setAjaxLoading(); renderComments(response); unsetAjaxLoading(); break; + case 'refetch': + var html = ''; + for ( var i = 0; i < response.comments.length; i++ ) + { + html += window._render_comment(response.comments[i], response); + } + $('#' + response.passback.paginator_id + '_0') + .css('height', 'auto') + .css('background-color', 'transparent') + .css('background-image', 'none') + .fadeTo('fast', 100) + .html(html); + break; case 'redraw': redrawComment(response); break; @@ -118,7 +131,7 @@ if ( data.count_total > 0 ) { comment_render_track = 0; - var commentpages = new paginator(data.comments, _render_comment, 0, 10, data); + var commentpages = new paginator(data.comments, _render_comment, 0, data.per_page, data, Math.ceil(data.count_total / data.per_page), window._comment_page_flip); html += commentpages.html; } @@ -630,6 +643,36 @@ } } +window._comment_page_flip = function(paginator, page_number) +{ + // get ID + var random_id = paginator.random_id; + // update paginate control + paginator.set_page(page_number); + $('.' + random_id + '_control').html(paginator._build_control(page_number)); + paginator.offset = page_number; + // set to loading state + $('#' + random_id + '_0') + .css('height', 500) + .html('') + .fadeTo("fast", 0.7) + .css('background-position', 'center 51px') + .css('background-repeat', 'no-repeat') + .css('background-color', 'white') + .css('background-image', 'url(' + cdnPath + '/images/loading-big.gif' + ')') + .animate({ height: 150 }, 500, function() + { + // load the new comments + ajaxComments({ + mode: 'fetch', + pagenum: page_number, + passback: { + paginator_id: random_id + } + }); + }); +} + window.viewCommentIP = function(id, local_id) { // set "loading" indicator on IP button diff -r db6b116b8ea7 -r b5b8e7ab0914 includes/clientside/static/paginate.js --- a/includes/clientside/static/paginate.js Fri Dec 18 05:05:01 2009 -0500 +++ b/includes/clientside/static/paginate.js Fri Dec 18 05:12:02 2009 -0500 @@ -11,7 +11,7 @@ var pagin_objects = new Object(); -window.paginator = function(data, callback, offset, perpage, passer) +window.paginator = function(data, callback, offset, perpage, passer, ov_num_pages, ov_flip_func) { load_component('flyin'); if ( !perpage || typeof(perpage) != 'number' || ( typeof(perpage) == 'number' && perpage < 1 ) ) @@ -30,9 +30,26 @@ this.passer = passer; else this.passer = false; - this.num_pages = Math.ceil(data.length / perpage ); + if ( ov_num_pages ) + { + this.num_pages = ov_num_pages; + this.flip_func = ov_flip_func; + } + else + { + this.num_pages = Math.ceil(data.length / perpage); + this.flip_func = false; + } this.random_id = 'autopagin_' + Math.floor(Math.random() * 1000000); this._build_control = _build_paginator; + this.set_page = function(number) + { + this.offset = number * this.perpage; + var html = this._build_control(number); + var elements = getElementsByClassName(document.body, 'div', this.random_id + '_control'); + for ( var i = 0; i < elements.length; i++ ) + elements[i].innerHTML = html; + } if ( this.num_pages > 1 ) { var pg_control = '
'+this._build_control(0)+'
'; @@ -68,7 +85,7 @@ window._build_paginator = function(this_page) { - var div_styling = ( IE ) ? 'width: 1px; margin: 10px auto 10px 0;' : 'display: table; margin: 10px 0 0 auto;'; + var div_styling = ( IE ) ? 'width: 1px; margin: 10px auto 10px 0;' : 'display: table; margin: 10px 0 10px auto;'; var begin = '
'; var block = ''; var end = '
' + $lang.get('paginate_lbl_page') + '{LINK}
'; @@ -201,6 +218,12 @@ if ( __paginateLock ) return false; var theobj = pagin_objects[pagin_id]; + if ( theobj.flip_func ) + { + theobj.flip_func(theobj, jump_to); + __paginateLock = false; + return true; + } var current_div = false; var new_div = false; for ( var i = 0; i < theobj.num_pages; i++ ) diff -r db6b116b8ea7 -r b5b8e7ab0914 includes/comment.php --- a/includes/comment.php Fri Dec 18 05:05:01 2009 -0500 +++ b/includes/comment.php Fri Dec 18 05:12:02 2009 -0500 @@ -97,6 +97,8 @@ } $ret = Array(); $ret['mode'] = $data['mode']; + if ( isset($data['passback']) ) + $ret['passback'] = $data['passback']; switch ( $data['mode'] ) { case 'fetch': @@ -106,6 +108,31 @@ { $ret['template'] = file_get_contents(ENANO_ROOT . '/themes/' . $template->theme . '/comment.tpl'); } + $approve_clause = $this->perms->get_permissions('mod_comments') ? '' : " AND approved = " . COMMENT_APPROVED; + // Get totals + $q = $db->sql_query('SELECT approved FROM ' . table_prefix . "comments WHERE page_id = '$this->page_id' AND namespace = '$this->namespace'{$approve_clause};"); + if ( !$q ) + $db->die_json(); + $counts = array('total' => 0, 'approved' => 0, 'unapproved' => 0, 'spam' => 0); + while ( $row = $db->fetchrow() ) + { + $counts['total']++; + switch($row['approved']): + case COMMENT_APPROVED: $counts['approved']++; break; + case COMMENT_UNAPPROVED: $counts['unapproved']++; break; + case COMMENT_SPAM: $counts['spam']++; break; + endswitch; + } + $counts['unapproved'] = $counts['total'] - $counts['approved']; + $data['counts'] = $counts; + // FIXME, this should be a user preference eventually + $ret['per_page'] = $per_page = getConfig('comments_per_page', 10); + $page = ( !empty($data['pagenum']) ) ? intval($data['pagenum']) : 0; + if ( $page > 0 ) + { + $ret['mode'] = 'refetch'; + } + $limit_clause = "LIMIT $per_page OFFSET " . ($page * $per_page); $q = $db->sql_query('SELECT c.comment_id,c.name,c.subject,c.comment_data,c.time,c.approved,( c.ip_address IS NOT NULL ) AS have_ip,u.user_level,u.user_id,u.email,u.signature,u.user_has_avatar,u.avatar_type, b.buddy_id IS NOT NULL AS is_buddy, ( b.is_friend IS NOT NULL AND b.is_friend=1 ) AS is_friend FROM '.table_prefix.'comments AS c LEFT JOIN '.table_prefix.'users AS u ON (u.user_id=c.user_id) @@ -115,11 +142,10 @@ ON ( ( u.user_rank = r.rank_id ) ) WHERE page_id=\'' . $this->page_id . '\' AND namespace=\'' . $this->namespace . '\' + ' . $approve_clause . ' GROUP BY c.comment_id,c.name,c.subject,c.comment_data,c.time,c.approved,c.ip_address,u.user_level,u.user_id,u.email,u.signature,u.user_has_avatar,u.avatar_type,b.buddy_id,b.is_friend - ORDER BY c.time ASC;'); - $count_appr = 0; - $count_total = 0; - $count_unappr = 0; + ORDER BY c.time ASC + ' . $limit_clause . ';'); $ret['comments'] = Array(); if (!$q) $db->die_json(); @@ -127,10 +153,6 @@ { do { - // Increment counters - $count_total++; - ( $row['approved'] == 1 ) ? $count_appr++ : $count_unappr++; - if ( !$this->perms->get_permissions('mod_comments') && $row['approved'] != COMMENT_APPROVED ) continue; @@ -174,9 +196,10 @@ } while ( $row = $db->fetchrow($q) ); } $db->free_result(); - $ret['count_appr'] = $count_appr; - $ret['count_total'] = $count_total; - $ret['count_unappr'] = $count_unappr; + $ret['count_appr'] = $counts['approved']; + $ret['count_total'] = $counts['total']; + $ret['count_visible'] = $this->perms->get_permissions('mod_comments') ? $counts['total'] : $counts['approved']; + $ret['count_unappr'] = $counts['unapproved']; $ret['auth_mod_comments'] = $this->perms->get_permissions('mod_comments'); $ret['auth_post_comments'] = $this->perms->get_permissions('post_comments'); $ret['auth_edit_comments'] = $this->perms->get_permissions('edit_comments'); diff -r db6b116b8ea7 -r b5b8e7ab0914 includes/namespaces/default.php --- a/includes/namespaces/default.php Fri Dec 18 05:05:01 2009 -0500 +++ b/includes/namespaces/default.php Fri Dec 18 05:12:02 2009 -0500 @@ -1005,6 +1005,8 @@ $row = $db->fetchrow(); // Get comment counts + // FIXME: Apparently there's a bit of recursion in here. Fetching permissions depends on this cdata function. + // Perhaps we should eliminate session's dependency on cdata? (What is it used for?) $q = $db->sql_query('SELECT approved FROM ' . table_prefix . "comments WHERE page_id = '$page_id_db' AND namespace = '$namespace_db';"); // yay parallel assignment $row['comments_approved'] = $row['comments_unapproved'] = $row['comments_spam'] = 0; diff -r db6b116b8ea7 -r b5b8e7ab0914 includes/sessions.php --- a/includes/sessions.php Fri Dec 18 05:05:01 2009 -0500 +++ b/includes/sessions.php Fri Dec 18 05:12:02 2009 -0500 @@ -4356,9 +4356,10 @@ ORDER BY target_type ASC, page_id ASC, namespace ASC;'; $q = $session->sql($bs); - if ( $row = $db->fetchrow() ) + if ( $row = $db->fetchrow($q, true) ) { - do { + do + { $rules = $session->string_to_perm($row['rules']); $is_everyone = ( $row['target_type'] == ACL_TYPE_GROUP && $row['target_id'] == 1 ); // log where this comes from diff -r db6b116b8ea7 -r b5b8e7ab0914 includes/template.php --- a/includes/template.php Fri Dec 18 05:05:01 2009 -0500 +++ b/includes/template.php Fri Dec 18 05:12:02 2009 -0500 @@ -829,7 +829,9 @@ COMMENT_UNAPPROVED => $cdata['comments_unapproved'], COMMENT_SPAM => $cdata['comments_spam'] ); - $num_comments = array_sum($approval_counts); + $num_comments = $session->check_acl_scope('mod_comments', $this->namespace) && $this->page->perms->get_permissions('mod_comments') + ? array_sum($approval_counts) + : $approval_counts[COMMENT_APPROVED]; } else {