package MT::Plugin::EntriesRanking; use strict; use MT; use MT::Template::Context; use MT::Plugin; use MT::Entry; use MT::Util qw(offset_time_list); # show plugin information to main menu eval("use Storable;"); if (!$@ && MT->can('add_plugin')) { my $plugin = MT::Plugin->new; $plugin->name('MTEntriesRanking 0.02'); $plugin->description('Rank entries by comments and/or trackbacks.'); MT->add_plugin($plugin); } # add tags MT::Template::Context->add_container_tag(EntriesRanking => \&entriesranking); MT::Template::Context->add_tag(EntryCommentAndPingCount => \&entrycommentandpingcount); MT::Template::Context->add_tag(EntryRank => \&entryrank); # main sub entriesranking { my ($ctx, $args, $cond) = @_; my $tokens = $ctx->stash('tokens'); my $builder = $ctx->stash('builder'); my @entries = (); my $ctr = 0; my $res = ''; my ($lastn, $mode, $entry, $force); my (%load_args, %load_terms); # get attributes $lastn = $args->{'lastn'} or $lastn = 0; $force = $args->{'force'} or $force = 0; $mode = $args->{'mode'} or $mode = 'both'; # get template context my $category = $ctx->stash('archive_category') || $ctx->stash('category'); my $date_start = $ctx->{'current_timestamp'}; my $date_end = $ctx->{'current_timestamp_end'}; # load entries $load_terms{blog_id} = $ctx->stash('blog_id'); $load_terms{status} = MT::Entry::RELEASE(); $load_args{sort} = 'created_on'; $load_args{direction} = 'descend'; if (my $limit = $args->{'limit'}) { $load_args{limit} = $limit; } elsif (my $days = $args->{'days'}) { my @ago = offset_time_list(time - 3600 * 24 * $days, $ctx->stash('blog_id')); my $ago = sprintf "%04d%02d%02d%02d%02d%02d", $ago[5] + 1900, $ago[4] + 1, @ago[3,2,1,0]; $load_terms{created_on} = [ $ago ]; $load_args{range} = { created_on => 1 }; } if ($category && !$force) { $load_args{join} = [ 'MT::Placement', 'entry_id', { category_id => $category->id } ]; } elsif ($date_start && !$force) { $load_terms{created_on} = [ $date_start, $date_end ]; $load_args{range} = { created_on => 1 }; } @entries = MT::Entry->load(\%load_terms, \%load_args); # sort entries if ($mode eq 'comment') { @entries = sort { $b->comment_count <=> $a->comment_count } @entries; } elsif ($mode eq 'trackback') { @entries = sort { $b->ping_count <=> $a->ping_count } @entries; } elsif ($mode eq 'both') { @entries = sort { $b->comment_count + $b->ping_count <=> $a->comment_count + $a->ping_count } @entries; } # limit entries if ($lastn != 0 && $lastn < scalar @entries) { @entries = @entries[0..$lastn - 1]; } # cut entries that has no comments/pings if ($mode eq 'comment') { @entries = grep { $_->comment_count != 0} @entries; } elsif ($mode eq 'trackback') { @entries = grep { $_->ping_count != 0} @entries; } elsif ($mode eq 'both') { @entries = grep { $_->comment_count + $_->ping_count != 0} @entries; } # backup stash('entry') my $entrybackup = $ctx->stash('entry'); # out entries $ctr = 0; my ($last_day, $next_day) = ('00000000') x 2; foreach $entry (@entries) { $ctx->stash('entry', $entry); $ctx->stash('rank', $ctr + 1); local $ctx->{current_timestamp} = $entry->created_on; my $this_day = substr $entry->created_on, 0, 8; my $next_day = $this_day; my $footer = 0; if (defined $entries[$ctr + 1]) { $next_day = substr($entries[$ctr + 1]->created_on, 0, 8); $footer = $this_day ne $next_day; } else { $footer++ } my $allow_comments ||= 0; defined(my $out = $builder->build($ctx, $tokens, { %$cond, DateHeader => ($this_day ne $last_day), DateFooter => $footer, EntryIfExtended => $entry->text_more ? 1 : 0, EntryIfAllowComments => $entry->allow_comments, EntryIfCommentsOpen => $entry->allow_comments && $entry->allow_comments eq '1', EntryIfAllowPings => $entry->allow_pings, EntriesHeader => !$ctr, EntriesFooter => !defined $entries[$ctr + 1] })) or return $ctx->error($ctx->errstr); $res .= $out; $ctr++; $last_day = $this_day; } # restore stash('entry') $ctx->stash('entry', $entrybackup); $res; } sub entrycommentandpingcount { my ($ctx, $args) = @_; my $out = ''; # get entry from stash my $entry = $ctx->stash('entry') or return $ctx->error('Not in ... context.'); # return comment and trackback count $out = $entry->comment_count + $entry->ping_count; $out; } sub entryrank { my ($ctx, $args) = @_; $ctx->stash('rank'); } 1;