Changeset 211 for tagwire/trunk/tagwire.pl
- Timestamp:
- 05/28/06 10:08:06 (2 years ago)
- Files:
-
- 1 modified
-
tagwire/trunk/tagwire.pl (modified) (24 diffs)
Legend:
- Unmodified
- Added
- Removed
-
tagwire/trunk/tagwire.pl
r198 r211 1 # Tagwire Plugin (aka AllKeywords Plugin) 2 # a plugin for listing and handling "tags" 1 # Tagwire - A plugin for listing and handling "tags" 3 2 # 4 3 # $Id$ … … 7 6 # personal use. If you distribute it, please keep this notice intact. 8 7 # 9 # Copyright (c) 2005 Hirotaka Ogawa8 # Copyright (c) 2005,2006 Hirotaka Ogawa 10 9 11 10 package MT::Plugin::Tagwire; 12 11 use strict; 12 use MT; 13 use base qw(MT::Plugin); 14 13 15 use MT::Template::Context; 16 use MT::Entry; 14 17 use MT::Request; 15 use vars qw($VERSION);16 17 $VERSION = '0.25';18 18 19 19 # DEBUG 20 20 my $FORCE_PD_REFRESH = 0; 21 my $ENABLE_PD_INDEXES = 1; 22 my $ENABLE_REQ_CACHE = 1; 23 21 22 our $HAVE_MT_PLUGINDATA = 0; 23 our $HAVE_MT_XSEARCH = 0; 24 25 our $cache; 24 26 my $plugin; 25 eval { 26 require MT::Plugin; 27 $plugin = new MT::Plugin({ 27 28 BEGIN { 29 our $VERSION = '0.26'; 30 $plugin = __PACKAGE__->new({ 28 31 name => 'Tagwire Plugin', 29 32 description => 'A plugin for listing and handling blog-wide tags and entry tags.', 30 doc_link => 'http://as-is.net/ wiki/Tagwire_Plugin',33 doc_link => 'http://as-is.net/hacks/2005/06/tagwire_plugin.html', 31 34 author_name => 'Hirotaka Ogawa', 32 35 author_link => 'http://profile.typekey.com/ogawa/', 33 version => $VERSION 36 version => $VERSION, 37 }); 38 MT->add_plugin($plugin); 39 40 eval { require MT::PluginData; $HAVE_MT_PLUGINDATA = 1 }; 41 42 if ($HAVE_MT_PLUGINDATA) { 43 MT::Entry->add_callback('post_save', 10, $plugin, \&post_save); 44 MT::Entry->add_callback('post_remove', 10, $plugin, \&post_remove); 45 } 46 47 $cache = MT::Request->instance; 48 49 MT::Template::Context->add_container_tag(Tags => \&tags); 50 MT::Template::Context->add_container_tag(EntryTags => \&entry_tags); 51 MT::Template::Context->add_container_tag(RelatedTags => \&related_tags); 52 MT::Template::Context->add_tag(Tag => \&tag); 53 MT::Template::Context->add_tag(TagCount => \&tag_count); 54 MT::Template::Context->add_tag(TagDate => \&tag_date); 55 MT::Template::Context->add_tag(TagsTotal => \&tags_total); 56 MT::Template::Context->add_tag(TagsTotalSum => \&tags_total_sum); 57 MT::Template::Context->add_container_tag(EntriesWithTags => \&entries); 58 MT::Template::Context->add_container_tag(MostRelatedEntries => \&most_related_entries); 59 MT::Template::Context->add_global_filter(encode_urlplus => \&encode_urlplus); 60 61 # For compatibility (this plugin was formerly named 'AllKeywords') 62 MT::Template::Context->add_container_tag(AllKeywords => \&tags); 63 MT::Template::Context->add_container_tag(EntryAllKeywords => \&entry_tags); 64 MT::Template::Context->add_tag(AllKeyword => \&tag); 65 MT::Template::Context->add_tag(AllKeywordCount => \&tag_count); 66 MT::Template::Context->add_tag(AllKeywordsTotal => \&tags_total); 67 MT::Template::Context->add_tag(AllKeywordsTotalSum => \&tags_total_sum); 68 MT::Template::Context->add_container_tag(EntriesWithKeywords => \&entries); 69 70 eval { require MT::XSearch; $HAVE_MT_XSEARCH = 1 }; 71 72 if ($HAVE_MT_XSEARCH) { 73 MT::XSearch->add_search_plugin('Tagwire', { 74 label => 'Tag(Keyword) Search', 75 description => 'Tag(Keyword) Search plugin for MT-XSearch', 76 on_execute => \&xsearch_on_execute, 77 on_stash => \&xsearch_on_stash, 34 78 }); 35 MT->add_plugin($plugin); 36 }; 37 38 if (MT->can('add_callback')) { 39 my $mt = MT->instance; 40 MT->add_callback((ref $mt eq 'MT::App::CMS' ? 'AppPostEntrySave' : 'MT::Entry::post_save'), 41 10, $plugin, \&update_pd_indexes); 42 } 43 44 sub update_pd_indexes { 45 return unless $ENABLE_PD_INDEXES && $plugin; 46 my ($eh, $app, $entry) = @_; 47 require MT::Entry; 79 MT::Template::Context->add_container_tag(XSearchTags => \&xsearch_tags); 80 } 81 } 82 83 sub post_save { 84 my ($eh, $dummy, $obj) = @_; 85 update_plugindata($obj); 86 } 87 88 sub post_remove { 89 my ($eh, $obj) = @_; 90 # set it to be "draft" to remove 91 $obj->status(MT::Entry::HOLD()) if $obj->status == MT::Entry::RELEASE(); 92 update_plugindata($obj); 93 } 94 95 sub update_plugindata { 96 return unless $HAVE_MT_PLUGINDATA && $plugin; 97 my ($entry) = @_; 98 my $refresh = $FORCE_PD_REFRESH || 0; 99 my $version = $plugin->version; 48 100 my $blog_id = $entry->blog_id; 49 require MT::PluginData;50 101 my $pd = MT::PluginData->load({ plugin => $plugin->name, 51 102 key => $blog_id }); 52 my (%eindex, %tindex);53 my $data;54 my $refresh = $FORCE_PD_REFRESH || 0;55 103 if (!$pd) { 56 104 $pd = new MT::PluginData(); … … 59 107 $refresh = 1; 60 108 } 61 $data = $pd->data() || {}; 62 $refresh = 1 if !exists $data->{version} || ${$data->{version}} ne $VERSION; 109 my $data = $pd->data() || {}; 110 111 $refresh = 1 if !exists $data->{version} || ${$data->{version}} ne $version; 112 113 my (%eindex, %tindex); 63 114 if ($refresh) { 64 115 my $iter = MT::Entry->load_iter({ blog_id => $blog_id, … … 86 137 } 87 138 } 88 $data->{version} = \$ VERSION;139 $data->{version} = \$version; 89 140 $data->{eindex} = \%eindex; 90 141 $data->{tindex} = \%tindex; 91 142 $pd->data($data); 92 143 $pd->save or die $pd->errstr; 93 if ($ENABLE_REQ_CACHE) { 94 my $r = MT::Request->instance; 95 $r->cache('Tagwire::Cache::' . $blog_id, undef); 96 } 97 } 98 99 MT::Template::Context->add_container_tag('Tags' => \&tags); 100 MT::Template::Context->add_container_tag('EntryTags' => \&entry_tags); 101 MT::Template::Context->add_container_tag('RelatedTags' => \&related_tags); 102 MT::Template::Context->add_tag('Tag' => \&tag); 103 MT::Template::Context->add_tag('TagCount' => \&tag_count); 104 MT::Template::Context->add_tag('TagDate' => \&tag_date); 105 MT::Template::Context->add_tag('TagsTotal' => \&tags_total); 106 MT::Template::Context->add_tag('TagsTotalSum' => \&tags_total_sum); 107 MT::Template::Context->add_container_tag('EntriesWithTags' => \&entries); 108 MT::Template::Context->add_container_tag('MostRelatedEntries' => \&most_related_entries); 109 MT::Template::Context->add_global_filter('encode_urlplus' => \&encode_urlplus); 110 111 # For compatibility (this plugin was formerly named 'AllKeywords') 112 MT::Template::Context->add_container_tag('AllKeywords' => \&tags); 113 MT::Template::Context->add_container_tag('EntryAllKeywords' => \&entry_tags); 114 MT::Template::Context->add_tag('AllKeyword' => \&tag); 115 MT::Template::Context->add_tag('AllKeywordCount' => \&tag_count); 116 MT::Template::Context->add_tag('AllKeywordsTotal' => \&tags_total); 117 MT::Template::Context->add_tag('AllKeywordsTotalSum' => \&tags_total_sum); 118 MT::Template::Context->add_container_tag('EntriesWithKeywords' => \&entries); 144 $cache->cache('Tagwire::Cache::' . $blog_id, undef); 145 } 119 146 120 147 sub split_args { … … 162 189 } 163 190 164 sub get_pd_indexes { 165 return unless $ENABLE_PD_INDEXES && $plugin; 166 my $blog_id = $_[0] or return; 167 my ($r, $cname); 168 if ($ENABLE_REQ_CACHE) { 169 $r = MT::Request->instance; 170 $cname = 'Tagwire::Cache::' . $blog_id; 171 return $r->cache($cname) if defined $r->cache($cname); 172 $r->cache($cname, undef); 173 } 191 sub get_indexes { 192 my $blog_id = shift or return; 193 my $cname = 'Tagwire::Cache::' . $blog_id; 194 return $cache->cache($cname) if defined $cache->cache($cname); 195 $cache->cache($cname, undef); 196 174 197 my $data; 175 eval { 176 require MT::PluginData; 198 if ($HAVE_MT_PLUGINDATA && $plugin) { 177 199 my $pd = MT::PluginData->load({ plugin => $plugin->name, 178 200 key => $blog_id }); 179 201 $data = $pd->data() if $pd; 180 }; 181 return if !exists $data->{version} || ${$data->{version}} ne $VERSION; 182 $r->cache($cname, $data) if $ENABLE_REQ_CACHE && $data; 183 $data; 184 } 185 186 sub get_db_indexes { 187 my $blog_id = $_[0] or return; 188 my ($r, $cname); 189 if ($ENABLE_REQ_CACHE) { 190 $r = MT::Request->instance; 191 $cname = 'Tagwire::Cache::' . $blog_id; 192 return $r->cache($cname) if defined $r->cache($cname); 193 $r->cache($cname, undef); 194 } 195 my $data; 196 my (%eindex, %tindex); 202 203 $data = undef if (!exists $data->{version} || ${$data->{version}} ne $plugin->version); 204 } 205 206 $data = get_indexes_from_db($blog_id) unless defined $data; 207 208 $cache->cache($cname, $data) if $data; 209 } 210 211 sub get_indexes_from_db { 212 my $blog_id = shift or return; 213 my ($eindex, $tindex); 197 214 my $iter = MT::Entry->load_iter({ blog_id => $blog_id, 198 215 status => MT::Entry::RELEASE() }); 199 216 while (my $e = $iter->()) { 200 217 my @tags = split_tags($e->keywords, 1) or next; 201 $eindex {$e->id} = { tags => \@tags,202 created_on => $e->created_on };203 } 204 foreach my $eid (keys % eindex) {205 my $ ts = $eindex{$eid}->{created_on};206 foreach (@{$eindex{$eid}->{tags}}) {207 push @{$tindex{$_}->{eids}}, $eid;208 $tindex{$_}->{ts} = $ts if !exists $tindex{$_}->{ts} || $tindex{$_}->{ts} < $ts;209 }210 }211 $data->{eindex} = \%eindex;212 $data->{tindex} = \%tindex; 213 $r->cache($cname, $data) if $ENABLE_REQ_CACHE;218 $eindex->{$e->id} = { tags => \@tags, 219 created_on => $e->created_on }; 220 } 221 foreach my $eid (keys %$eindex) { 222 my $eidx = $eindex->{$eid}; 223 my $ts = $eidx->{created_on}; 224 foreach (@{$eidx->{tags}}) { 225 push @{$tindex->{$_}->{eids}}, $eid; 226 $tindex->{$_}->{ts} = $ts if !exists $tindex->{$_}->{ts} || $tindex->{$_}->{ts} < $ts; 227 } 228 } 229 230 my $data = { eindex => $eindex, tindex => $tindex }; 214 231 $data; 215 232 } … … 228 245 $args->{case_sensitive} : 1; 229 246 230 my $blog_id = $ctx->stash('blog_id'); 231 my %tags = (); 232 my %ts = (); 233 234 my $data = get_pd_indexes($blog_id) || get_db_indexes($blog_id) 235 or return ''; 236 my %tindex = %{$data->{tindex}}; 247 my $data = get_indexes($ctx->stash('blog_id')) or return ''; 248 my $tindex = $data->{tindex}; 249 250 my %tags; 237 251 if ($case_sensitive) { 238 foreach (keys %tindex) { 239 $tags{$_} = scalar @{$tindex{$_}->{eids}}; 240 $ts{$_} = $tindex{$_}->{ts}; 241 } 242 } else { 243 foreach (keys %tindex) { 252 foreach (keys %$tindex) { 253 my $tidx = $tindex->{$_}; 254 $tags{$_} = [ scalar @{$tidx->{eids}}, $tidx->{ts} ]; 255 } 256 } else { 257 foreach (keys %$tindex) { 258 my $tidx = $tindex->{$_}; 244 259 my $t = lc $_; 245 $tags{$t} += scalar @{$tindex{$_}->{eids}}; 246 $ts{$t} = $tindex{$_}->{ts} if !exists $ts{$t} || $ts{$t} < $tindex{$_}->{ts}; 260 if (!exists $tags{$t}) { 261 $tags{$t} = [ scalar @{$tidx->{eids}}, $tidx->{ts} ]; 262 } else { 263 $tags{$t}[0] += scalar @{$tidx->{eids}}; 264 $tags{$t}[1] = $tidx->{ts} if $tags{$t}[1] < $tidx->{ts}; 265 } 247 266 } 248 267 } … … 259 278 } else { 260 279 @list = $sort_order eq 'ascend' ? 261 sort { $tags{$a} <=> $tags{$b}} keys %tags :262 sort { $tags{$b} <=> $tags{$a}} keys %tags;280 sort { $tags{$a}[0] <=> $tags{$b}[0] } keys %tags : 281 sort { $tags{$b}[0] <=> $tags{$a}[0] } keys %tags; 263 282 } 264 283 … … 266 285 267 286 my $total_sum = 0; 268 $total_sum += $tags{$_} foreach (@list);287 $total_sum += $tags{$_}[0] foreach (@list); 269 288 $ctx->stash('Tagwire::tags_total_sum', $total_sum); 270 289 … … 276 295 last if $lastn && $i >= $lastn; 277 296 local $ctx->{__stash}{'Tagwire::tag'} = $_; 278 local $ctx->{__stash}{'Tagwire::tag_count'} = $tags{$_} ;279 local $ctx->{__stash}{'Tagwire::tag_date'} = $t s{$_};297 local $ctx->{__stash}{'Tagwire::tag_count'} = $tags{$_}[0]; 298 local $ctx->{__stash}{'Tagwire::tag_date'} = $tags{$_}[1]; 280 299 defined(my $out = $builder->build($ctx, $tokens)) 281 300 or return $ctx->error($ctx->errstr); … … 324 343 $args->{case_sensitive} : 1; 325 344 326 my $blog_id = $ctx->stash('blog_id'); 327 my %tags = (); 328 my %ts = (); 329 330 my $data = get_pd_indexes($blog_id) || get_db_indexes($blog_id) 331 or return ''; 332 my %tindex = %{$data->{tindex}}; 333 my %eindex = %{$data->{eindex}}; 345 my $data = get_indexes($ctx->stash('blog_id')) or return ''; 346 my ($tindex, $eindex) = ($data->{tindex}, $data->{eindex}); 347 348 my %tags; 334 349 if ($case_sensitive) { 335 foreach my $eid (@{$tindex {$tag}->{eids}}) {336 foreach (@{$eindex {$eid}->{tags}}) {350 foreach my $eid (@{$tindex->{$tag}->{eids}}) { 351 foreach (@{$eindex->{$eid}->{tags}}) { 337 352 next if $_ eq $tag; 338 $tags{$_} = exists $tags{$_} ? $tags{$_} + 1 : 1; 339 $ts{$_} = $tindex{$_}->{ts} if !defined $ts{$_}; 353 if (!exists $tags{$_}) { 354 $tags{$_} = [ 1, $tindex->{$_}->{ts} ]; 355 } else { 356 $tags{$_}[0]++; 357 } 340 358 } 341 359 } 342 360 } else { 343 361 $tag = lc $tag; 344 foreach my $nctag (grep { lc $_ eq $tag } keys %tindex) { 345 foreach my $eid (@{$tindex{$nctag}->{eids}}) { 346 foreach (@{$eindex{$eid}->{tags}}) { 347 my $mtag = lc $_; 348 next if $mtag eq $tag; 349 $tags{$mtag} = exists $tags{$mtag} ? $tags{$mtag} + 1 : 1; 350 $ts{$mtag} = $tindex{$_}->{ts} if $ts{$mtag} < $tindex{$_}->{ts}; 362 foreach my $nctag (grep { lc $_ eq $tag } keys %$tindex) { 363 foreach my $eid (@{$tindex->{$nctag}->{eids}}) { 364 foreach (@{$eindex->{$eid}->{tags}}) { 365 my $t = lc $_; 366 next if $t eq $tag; 367 if (!exists $tags{$t}) { 368 $tags{$t} = [ 1, $tindex->{$_}->{ts} ]; 369 } else { 370 $tags{$t}[0]++; 371 $tags{$t}[1] = $tindex->{$_}->{ts} if $tags{$t}[1] < $tindex->{$_}->{ts}; 372 } 351 373 } 352 374 } … … 364 386 } else { 365 387 @list = $sort_order eq 'ascend' ? 366 sort { $tags{$a} <=> $tags{$b}} keys %tags :367 sort { $tags{$b} <=> $tags{$a}} keys %tags;388 sort { $tags{$a}[0] <=> $tags{$b}[0] } keys %tags : 389 sort { $tags{$b}[0] <=> $tags{$a}[0] } keys %tags; 368 390 } 369 391 … … 371 393 372 394 my $total_sum = 0; 373 $total_sum += $tags{$_} foreach (@list);395 $total_sum += $tags{$_}[0] foreach (@list); 374 396 $ctx->stash('Tagwire::tags_total_sum', $total_sum); 375 397 … … 381 403 last if $lastn && $i >= $lastn; 382 404 local $ctx->{__stash}{'Tagwire::tag'} = $_; 383 local $ctx->{__stash}{'Tagwire::tag_count'} = $tags{$_} ;384 local $ctx->{__stash}{'Tagwire::tag_date'} = $t s{$_};405 local $ctx->{__stash}{'Tagwire::tag_count'} = $tags{$_}[0]; 406 local $ctx->{__stash}{'Tagwire::tag_date'} = $tags{$_}[1]; 385 407 defined(my $out = $builder->build($ctx, $tokens)) 386 408 or return $ctx->error($ctx->errstr); … … 420 442 # tags(keywords) (REQUIRED) 421 443 my $search = $args->{tags} || $args->{keywords} or return ''; 422 # delimiter for "tags" argument (default = space characters)444 # delimiter for "tags" argument (default = space) 423 445 my $delimiter = $args->{delimiter} || ''; 424 446 # case_sensitive (0/1, default = 1) … … 435 457 or return ''; 436 458 437 my $blog_id = $ctx->stash('blog_id'); 438 my $data = get_pd_indexes($blog_id) || get_db_indexes($blog_id) 439 or return ''; 440 my %tindex = %{$data->{tindex}}; 441 my %eindex = %{$data->{eindex}}; 459 my $data = get_indexes($ctx->stash('blog_id')) or return ''; 460 my ($tindex, $eindex) = ($data->{tindex}, $data->{eindex}); 461 442 462 my %match; 443 463 if ($case_sensitive) { 444 464 foreach my $tag (@tags) { 445 foreach (@{$tindex {$tag}->{eids}}) {465 foreach (@{$tindex->{$tag}->{eids}}) { 446 466 $match{$_} = exists $match{$_} ? $match{$_} + 1 : 1; 447 467 } … … 449 469 } else { 450 470 foreach my $tag (@tags) { 451 foreach my $ mtag (grep { lc $_ eq $tag } keys %tindex) {452 foreach (@{$tindex {$mtag}->{eids}}) {471 foreach my $t (grep { lc $_ eq $tag } keys %$tindex) { 472 foreach (@{$tindex->{$t}->{eids}}) { 453 473 $match{$_} = exists $match{$_} ? $match{$_} + 1 : 1; 454 474 } … … 459 479 my @eids = grep { $match{$_} == $count } keys %match or return ''; 460 480 @eids = $sort_order eq 'descend' ? 461 sort { $eindex {$b}->{created_on} <=> $eindex{$a}->{created_on} } @eids :462 sort { $eindex {$a}->{created_on} <=> $eindex{$b}->{created_on} } @eids;481 sort { $eindex->{$b}->{created_on} <=> $eindex->{$a}->{created_on} } @eids : 482 sort { $eindex->{$a}->{created_on} <=> $eindex->{$b}->{created_on} } @eids; 463 483 splice(@eids, $lastn) if $lastn && (scalar @eids > $lastn); 464 require MT::Entry; 484 465 485 my @entries; 466 486 map { push @entries, MT::Entry->load($_) } @eids; … … 507 527 or return ''; 508 528 509 my $blog_id = $ctx->stash('blog_id'); 510 my $data = get_pd_indexes($blog_id) || get_db_indexes($blog_id) 511 or return ''; 512 my %tindex = %{$data->{tindex}}; 513 my %eindex = %{$data->{eindex}}; 529 my $data = get_indexes($ctx->stash('blog_id')) or return ''; 530 my ($tindex, $eindex) = ($data->{tindex}, $data->{eindex}); 531 514 532 my %match; 533 my $entry_id = $entry->id; 515 534 if ($case_sensitive) { 516 535 foreach my $tag (@tags) { 517 foreach (@{$tindex {$tag}->{eids}}) {518 next if $_ == $entry ->id;536 foreach (@{$tindex->{$tag}->{eids}}) { 537 next if $_ == $entry_id; 519 538 $match{$_} = exists $match{$_} ? $match{$_} + 1 : 1; 520 539 } … … 522 541 } else { 523 542 foreach my $tag (@tags) { 524 foreach my $ mtag (grep { lc $_ eq $tag } keys %tindex) {525 foreach (@{$tindex {$mtag}->{eids}}) {526 next if $_ == $entry ->id;543 foreach my $t (grep { lc $_ eq $tag } keys %$tindex) { 544 foreach (@{$tindex->{$t}->{eids}}) { 545 next if $_ == $entry_id; 527 546 $match{$_} = exists $match{$_} ? $match{$_} + 1 : 1; 528 547 } … … 532 551 my @eids = keys %match or return ''; 533 552 @eids = $sort_order eq 'descend' ? 534 sort { $eindex {$b}->{created_on} <=> $eindex{$a}->{created_on} } @eids :535 sort { $eindex {$a}->{created_on} <=> $eindex{$b}->{created_on} } @eids;553 sort { $eindex->{$b}->{created_on} <=> $eindex->{$a}->{created_on} } @eids : 554 sort { $eindex->{$a}->{created_on} <=> $eindex->{$b}->{created_on} } @eids; 536 555 @eids = sort { $match{$b} <=> $match{$a} } @eids; 537 556 splice(@eids, $lastn) if $lastn && (scalar @eids > $lastn); 538 require MT::Entry;539 557 my @entries; 540 558 map { push @entries, MT::Entry->load($_) } @eids; … … 564 582 } 565 583 584 use MT::Util; 566 585 sub encode_urlplus { 567 586 my $s = $_[0]; 568 587 return $s unless $_[1]; 569 require MT::Util;570 588 $s =~ tr/ /+/; 571 589 MT::Util::encode_url($s); 572 590 } 573 591 574 eval {575 require MT::XSearch;576 MT::XSearch->add_search_plugin('Tagwire', {577 label => 'Tag(Keyword) Search',578 description => 'Tag(Keyword) Search plugin for MT-XSearch',579 on_execute => \&xsearch_on_execute,580 on_stash => \&xsearch_on_stash });581 };582 583 MT::Template::Context->add_container_tag('XSearchTags' => \&xsearch_tags);584 592 sub xsearch_tags { 585 593 my ($ctx, $args, $cond) = @_; 586 my $r = MT::Request->instance; 587 return '' unless defined $r->cache('Tagwire::xsearch_tags'); 588 my @tags = @{$r->cache('Tagwire::xsearch_tags')}; 594 595 return '' unless defined $ctx->stash('xsearch_tags'); 596 my $tags = $ctx->stash('xsearch_tags'); 597 589 598 my @res; 590 599 my $builder = $ctx->stash('builder'); 591 600 my $tokens = $ctx->stash('tokens'); 592 foreach (@ tags) {601 foreach (@$tags) { 593 602 local $ctx->{__stash}{'Tagwire::tag'} = $_; 594 603 defined(my $out = $builder->build($ctx, $tokens)) … … 601 610 602 611 sub xsearch_on_stash { 603 $_[0]->stash('entry', $_[1]); 604 $_[0]->{current_timestamp} = $_[1]->created_on; 605 $_[0]->{modification_timestamp} = $_[1]->modified_on; 612 my ($ctx, $val, $self) = @_; 613 $ctx->stash('entry', $val); 614 $ctx->{current_timestamp} = $val->created_on; 615 $ctx->{modification_timestamp} = $val->modified_on; 616 $ctx->stash('xsearch_tags', $self->{xsearch_tags}); 606 617 } 607 618 608 619 sub xsearch_on_execute { 609 my $args = shift; 610 my $blog_id = $args->{blog_id} or MT->error('Blog ID is required.'); 611 my $sort_by = $args->{sort_by} || 'created_on'; 612 my $sort_order = $args->{sort_order} || 'descend'; 620 my ($args, $self) = @_; 621 622 MT->error('Blog ID is required.') unless $args->{blog_id}; 613 623 my $delimiter = $args->{delimiter} || ''; 614 624 my $case_sensitive = defined $args->{case_sensitive} ? 615 625 $args->{case_sensitive} : 1; 616 617 my @entries; 626 my $sort_by = $args->{sort_by} || 'created_on'; 627 my $sort_order = $args->{sort_order} || 'descend'; 628 my $lastn = $args->{lastn} || 0; 629 618 630 my @tags = split_args($args->{search}, $delimiter, $case_sensitive) 619 or return \@entries; 620 621 my $r = MT::Request->instance; 622 $r->cache('Tagwire::xsearch_tags', \@tags); 623 624 my $data = get_pd_indexes($blog_id) || get_db_indexes($blog_id) 625 or return \@entries; 626 my %tindex = %{$data->{tindex}}; 627 my %eindex = %{$data->{eindex}}; 631 or return []; 632 633 $self->{xsearch_tags} = \@tags; 634 635 my $data = get_indexes($args->{blog_id}) or return []; 636 my ($tindex, $eindex) = ($data->{tindex}, $data->{eindex}); 637 628 638 my %match; 629 639 if ($case_sensitive) { 630 640 foreach my $tag (@tags) { 631 foreach (@{$tindex {$tag}->{eids}}) {641 foreach (@{$tindex->{$tag}->{eids}}) { 632 642 $match{$_} = exists $match{$_} ? $match{$_} + 1 : 1; 633 643 } … … 635 645 } else { 636 646 foreach my $tag (@tags) { 637 foreach my $ mtag (grep { lc $_ eq $tag } keys %tindex) {638 foreach (@{$tindex {$mtag}->{eids}}) {647 foreach my $t (grep { lc $_ eq $tag } keys %$tindex) { 648 foreach (@{$tindex->{$t}->{eids}}) { 639 649 $match{$_} = exists $match{$_} ? $match{$_} + 1 : 1; 640 650 } … … 643 653 } 644 654 my $count = scalar @tags; 645 my @eids = grep { $match{$_} == $count } keys %match 646 or return \@entries; 655 my @eids = grep { $match{$_} == $count } keys %match or return []; 647 656 @eids = $sort_order eq 'descend' ? 648 sort { $eindex{$b}->{created_on} <=> $eindex{$a}->{created_on} } @eids : 649 sort { $eindex{$a}->{created_on} <=> $eindex{$b}->{created_on} } @eids; 650 require MT::Entry; 657 sort { $eindex->{$b}->{created_on} <=> $eindex->{$a}->{created_on} } @eids : 658 sort { $eindex->{$a}->{created_on} <=> $eindex->{$b}->{created_on} } @eids; 659 splice(@eids, $lastn) if $lastn && (scalar @eids > $lastn); 660 661 my @entries; 651 662 map { push @entries, MT::Entry->load($_) } @eids; 663 652 664 \@entries; 653 665 } 654 666 655 667 1; 656 657 package MT::Plugin::Tagwire::Cache;658 use strict;659 use MT::Request;660 use vars qw($cache);661 662 sub new {663 $cache ||= MT::Request->instance;664 }
![(please configure the [header_logo] section in trac.ini)](/public/chrome/common/trac_banner.png)