Changeset 471 for TagSupplementals/trunk/TagSupplementals.pl
- Timestamp:
- 07/22/08 13:31:57 (6 months ago)
- Files:
-
- 1 modified
-
TagSupplementals/trunk/TagSupplementals.pl (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
TagSupplementals/trunk/TagSupplementals.pl
r470 r471 23 23 24 24 BEGIN { 25 our $VERSION = '0. 06';25 our $VERSION = '0.10'; 26 26 27 27 eval { require MT::XSearch; $HAVE_MT_XSEARCH = 1 }; 28 28 if ($HAVE_MT_XSEARCH) { 29 MT::XSearch->add_search_plugin('TagSupplementals', {30 label => 'Tag Search',31 description => 'Tag Search plugin for MT-XSearch',32 on_execute => \&xsearch_on_execute,33 on_stash => \&xsearch_on_stash,34 });29 MT::XSearch->add_search_plugin('TagSupplementals', { 30 label => 'Tag Search', 31 description => 'Tag Search plugin for MT-XSearch', 32 on_execute => \&xsearch_on_execute, 33 on_stash => \&xsearch_on_stash, 34 }); 35 35 } 36 36 37 37 my $plugin = __PACKAGE__->new({ 38 name => 'TagSupplementals Plugin',39 description=> 'A plugin for providing supplemental "tag" features for MT 3.3+',40 doc_link => 'http://code.as-is.net/wiki/TagSupplementals_Plugin',41 author_name=> 'Hirotaka Ogawa',42 author_link=> 'http://profile.typekey.com/ogawa/',43 version=> $VERSION,44 registry=> {45 tags => {46 block=> {47 RelatedEntries => \&related_entries,48 RelatedTags=> \&related_tags,49 ArchiveTags=> \&archive_tags,50 SearchTags=> \&search_tags,51 $HAVE_MT_XSEARCH ? (XSearchTags => \&xsearch_tags) : (),52 },53 function => {54 EntryTagsCount => \&entry_tags_count,55 TagLastUpdated => \&tag_last_updated,56 $HAVE_MT_XSEARCH ? (TagXSearchLink => \&tag_xsearch_link) : (),57 },58 modifier => {59 encode_urlplus => \&encode_urlplus,60 },61 },62 },63 template_tags=> {64 EntryTagsCount => \&entry_tags_count,65 TagLastUpdated => \&tag_last_updated,66 $HAVE_MT_XSEARCH ? (TagXSearchLink => \&tag_xsearch_link) : (),67 },68 container_tags => {69 RelatedEntries => \&related_entries,70 RelatedTags=> \&related_tags,71 ArchiveTags=> \&archive_tags,72 SearchTags=> \&search_tags,73 $HAVE_MT_XSEARCH ? (XSearchTags => \&xsearch_tags) : (),74 },75 global_filters => {76 encode_urlplus => \&encode_urlplus,77 },38 name => 'TagSupplementals', 39 description => 'A plugin for providing supplemental "tag" features for MT 3.3+', 40 doc_link => 'http://code.as-is.net/public/wiki/TagSupplementals_Plugin', 41 author_name => 'Hirotaka Ogawa', 42 author_link => 'http://profile.typekey.com/ogawa/', 43 version => $VERSION, 44 registry => { 45 tags => { 46 block => { 47 RelatedEntries => \&related_entries, 48 RelatedTags => \&related_tags, 49 ArchiveTags => \&archive_tags, 50 SearchTags => \&search_tags, 51 $HAVE_MT_XSEARCH ? (XSearchTags => \&xsearch_tags) : (), 52 }, 53 function => { 54 EntryTagsCount => \&entry_tags_count, 55 TagLastUpdated => \&tag_last_updated, 56 $HAVE_MT_XSEARCH ? (TagXSearchLink => \&tag_xsearch_link) : (), 57 }, 58 modifier => { 59 encode_urlplus => \&encode_urlplus, 60 }, 61 }, 62 }, 63 template_tags => { 64 EntryTagsCount => \&entry_tags_count, 65 TagLastUpdated => \&tag_last_updated, 66 $HAVE_MT_XSEARCH ? (TagXSearchLink => \&tag_xsearch_link) : (), 67 }, 68 container_tags => { 69 RelatedEntries => \&related_entries, 70 RelatedTags => \&related_tags, 71 ArchiveTags => \&archive_tags, 72 SearchTags => \&search_tags, 73 $HAVE_MT_XSEARCH ? (XSearchTags => \&xsearch_tags) : (), 74 }, 75 global_filters => { 76 encode_urlplus => \&encode_urlplus, 77 }, 78 78 }); 79 79 MT->add_plugin($plugin); … … 83 83 my $ctx = shift; 84 84 my $entry = $ctx->stash('entry') 85 or return $ctx->_no_entry_error('MT' . $ctx->stash('tag'));85 or return $ctx->_no_entry_error('MT' . $ctx->stash('tag')); 86 86 my @tags = $entry->get_tags; 87 87 scalar @tags; … … 91 91 my ($ctx, $args) = @_; 92 92 my $tag = $ctx->stash('Tag') or return ''; 93 my $blog_id = $ctx->stash('blog_id') or return ''; 93 my (%blog_terms, %blog_args); 94 $ctx->set_blog_load_context($args, \%blog_terms, \%blog_args) 95 or return $ctx->error($ctx->errstr); 94 96 95 97 my ($e) = MT::Entry->load(undef, { 96 sort => 'created_on', 97 direction => 'descend', 98 limit => 1, 99 join => [ 'MT::ObjectTag', 'object_id', { 100 tag_id => $tag->id, 101 blog_id => $blog_id, 102 object_datasource => MT::Entry->datasource, 103 }, { 104 unique => 1, 105 } ] }) 106 or return ''; 98 sort => 'created_on', 99 direction => 'descend', 100 limit => 1, 101 join => [ 'MT::ObjectTag', 'object_id', { 102 %blog_terms, 103 tag_id => $tag->id, 104 object_datasource => MT::Entry->datasource, 105 }, { 106 %blog_args, 107 unique => 1, 108 } ] }) 109 or return ''; 107 110 108 111 $args->{ts} = $e->created_on; … … 115 118 my $otag_cache = $r->stash('object_tags_cache:' . $blog_id) || {}; 116 119 if (!$otag_cache->{$tag_id}) { 117 my @otags = MT::ObjectTag->load({118 blog_id=> $blog_id,119 tag_id=> $tag_id,120 object_datasource => MT::Entry->datasource,121 });122 $otag_cache->{$tag_id} = \@otags;123 $r->stash('object_tags_cache:' . $blog_id, $otag_cache);120 my @otags = MT::ObjectTag->load({ 121 blog_id => $blog_id, 122 tag_id => $tag_id, 123 object_datasource => MT::Entry->datasource, 124 }); 125 $otag_cache->{$tag_id} = \@otags; 126 $r->stash('object_tags_cache:' . $blog_id, $otag_cache); 124 127 } 125 128 $otag_cache->{$tag_id}; … … 129 132 my ($ctx, $args, $cond) = @_; 130 133 my $entry = $ctx->stash('entry') 131 or return $ctx->_no_entry_error('MT' . $ctx->stash('tag'));134 or return $ctx->_no_entry_error('MT' . $ctx->stash('tag')); 132 135 133 136 my $weight = $args->{weight} || 'constant'; 134 my $lastn = $args->{lastn}|| 0;137 my $lastn = $args->{lastn} || 0; 135 138 my $offset = $args->{offset} || 0; 136 139 $lastn += $offset; 137 140 138 141 my $entry_id = $entry->id; 139 my $blog_id = $entry->blog_id; 142 my (%blog_terms, %blog_args); 143 $ctx->set_blog_load_context($args, \%blog_terms, \%blog_args) 144 or return $ctx->error($ctx->errstr); 145 140 146 my @tags = MT::Tag->load(undef, { 141 sort => 'name', 142 join => [ 'MT::ObjectTag', 'tag_id', { 143 object_id => $entry_id, 144 blog_id => $blog_id, 145 object_datasource => MT::Entry->datasource, 146 }, { 147 unique => 1, 148 } ] }) 149 or return ''; 147 sort => 'name', 148 join => [ 'MT::ObjectTag', 'tag_id', { 149 %blog_terms, 150 object_id => $entry_id, 151 object_datasource => MT::Entry->datasource, 152 }, { 153 %blog_args, 154 unique => 1, 155 } ] }) 156 or return ''; 150 157 my %tag_ids; 151 158 foreach (@tags) { 152 $tag_ids{$_->id} = 1;153 my @more = MT::Tag->load({ n8d_id => $_->n8d_id ? $_->n8d_id : $_->id });154 $tag_ids{$_->id} = 1 foreach @more;159 $tag_ids{$_->id} = 1; 160 my @more = MT::Tag->load({ n8d_id => $_->n8d_id ? $_->n8d_id : $_->id }); 161 $tag_ids{$_->id} = 1 foreach @more; 155 162 } 156 163 my @tag_ids = keys %tag_ids; … … 158 165 my %rank; 159 166 if ($weight eq 'constant') { 160 if (MT::Object->driver->can('count_group_by')) { 161 my $iter = MT::ObjectTag->count_group_by({ 162 blog_id => $blog_id, 163 tag_id => \@tag_ids, 167 if (MT::Object->driver->can('count_group_by')) { 168 my $iter = MT::ObjectTag->count_group_by({ 169 %blog_terms, 170 tag_id => \@tag_ids, 171 object_datasource => MT::Entry->datasource, 172 }, { 173 %blog_args, 174 group => ['object_id'], 175 }); 176 while (my ($count, $object_id) = $iter->()) { 177 $rank{$object_id} = $count; 178 } 179 } else { 180 my $iter = MT::ObjectTag->load_iter({ 181 %blog_terms, 182 tag_id => \@tag_ids, 183 object_datasource => MT::Entry->datasource, 184 }, { 185 %blog_args, 186 }); 187 while (my $otag = $iter->()) { 188 $rank{$otag->object_id}++; 189 } 190 } 191 } elsif ($weight eq 'idf') { 192 for my $tag_id (@tag_ids) { 193 my @otags = MT::ObjectTag->load({ 194 %blog_terms, 195 tag_id => $tag_id, 164 196 object_datasource => MT::Entry->datasource, 165 197 }, { 166 group => ['object_id'],198 %blog_args, 167 199 }); 168 while (my ($count, $object_id) = $iter->()) { 169 $rank{$object_id} = $count; 170 } 171 } else { 172 my $iter = MT::ObjectTag->load_iter({ 173 blog_id => $blog_id, 174 tag_id => \@tag_ids, 175 object_datasource => MT::Entry->datasource, 176 }); 177 while (my $otag = $iter->()) { 178 $rank{$otag->object_id}++; 179 } 180 } 181 } elsif ($weight eq 'idf') { 182 for my $tag_id (@tag_ids) { 183 my $otags = _object_tags($blog_id, $tag_id); 184 next if scalar @$otags == 1; 185 my $rank = 1 / (scalar @$otags - 1); 186 for my $otag (@$otags) { 187 $rank{$otag->object_id} += $rank; 188 } 189 } 200 next if scalar @otags == 1; 201 my $rank = 1 / (scalar @otags - 1); 202 for my $otag (@otags) { 203 $rank{$otag->object_id} += $rank; 204 } 205 } 190 206 } 191 207 delete $rank{$entry_id}; … … 197 213 my $i = 0; 198 214 foreach (@eids) { 199 my $e = MT::Entry->load($_);200 if ($e->status == MT::Entry::RELEASE()) {201 next if $i < $offset;202 push @entries, $e;203 $i++;204 last if $lastn && $i >= $lastn;205 }215 my $e = MT::Entry->load($_); 216 if ($e->status == MT::Entry::RELEASE()) { 217 next if $i < $offset; 218 push @entries, $e; 219 $i++; 220 last if $lastn && $i >= $lastn; 221 } 206 222 } 207 223 … … 211 227 $i = 0; 212 228 for my $e (@entries) { 213 local $ctx->{__stash}{entry} = $e;214 local $ctx->{current_timestamp} = $e->created_on;215 local $ctx->{modification_timestamp} = $e->modified_on;216 my $out = $builder->build($ctx, $tokens, {217 %$cond,218 EntriesHeader => !$i,219 EntriesFooter => !defined $entries[$i+1],220 });221 return $ctx->error($ctx->errstr) unless defined $out;222 $res .= $out;223 $i++;229 local $ctx->{__stash}{entry} = $e; 230 local $ctx->{current_timestamp} = $e->created_on; 231 local $ctx->{modification_timestamp} = $e->modified_on; 232 my $out = $builder->build($ctx, $tokens, { 233 %$cond, 234 EntriesHeader => !$i, 235 EntriesFooter => !defined $entries[$i+1], 236 }); 237 return $ctx->error($ctx->errstr) unless defined $out; 238 $res .= $out; 239 $i++; 224 240 } 225 241 $res; … … 229 245 my ($ctx, $args, $cond) = @_; 230 246 my $tag = $ctx->stash('Tag') or return ''; 231 my $blog_id = $ctx->stash('blog_id') or return ''; 232 233 my $otags = _object_tags($blog_id, $tag->id); 234 my @eids = map { $_->object_id } @$otags; 247 my (%blog_terms, %blog_args); 248 $ctx->set_blog_load_context($args, \%blog_terms, \%blog_args) 249 or return $ctx->error($ctx->errstr); 250 251 my @otags = MT::ObjectTag->load({ 252 %blog_terms, 253 tag_id => $tag_id, 254 object_datasource => MT::Entry->datasource, 255 }, { 256 %blog_args, 257 }); 258 my @eids = map { $_->object_id } @otags; 235 259 236 260 my $iter = MT::Tag->load_iter(undef, { 237 sort => 'name', 238 join => ['MT::ObjectTag', 'tag_id', { 239 blog_id => $blog_id, 240 object_id => \@eids, 241 object_datasource => MT::Entry->datasource, 242 }, { 243 unique => 1, 244 } ] }); 261 sort => 'name', 262 join => ['MT::ObjectTag', 'tag_id', { 263 %blog_terms, 264 object_id => \@eids, 265 object_datasource => MT::Entry->datasource, 266 }, { 267 %blog_args, 268 unique => 1, 269 } ] }); 245 270 246 271 my @res; … … 248 273 my $tokens = $ctx->stash('tokens'); 249 274 while (my $t = $iter->()) { 250 next if $t->is_private || ($t->id == $tag->id);251 local $ctx->{__stash}{Tag} = $t;252 local $ctx->{__stash}{tag_count} = undef;253 local $ctx->{__stash}{tag_entry_count} = undef;254 defined(my $out = $builder->build($ctx, $tokens))255 or return $ctx->error($ctx->errstr);256 push @res, $out;275 next if $t->is_private || ($t->id == $tag->id); 276 local $ctx->{__stash}{Tag} = $t; 277 local $ctx->{__stash}{tag_count} = undef; 278 local $ctx->{__stash}{tag_entry_count} = undef; 279 defined(my $out = $builder->build($ctx, $tokens)) 280 or return $ctx->error($ctx->errstr); 281 push @res, $out; 257 282 } 258 283 my $glue = $args->{glue} || ''; … … 262 287 sub archive_tags { 263 288 my ($ctx, $args, $cond) = @_; 264 my $blog_id = $ctx->stash('blog_id') or return '';265 289 my $entries = force($ctx->stash('entries')) or return ''; 290 my (%blog_terms, %blog_args); 291 $ctx->set_blog_load_context($args, \%blog_terms, \%blog_args) 292 or return $ctx->error($ctx->errstr); 266 293 267 294 my @eids = map { $_->id } grep { $_->status == MT::Entry::RELEASE() } @$entries; 268 295 269 296 my $iter = MT::Tag->load_iter(undef, { 270 sort => 'name', 271 join => ['MT::ObjectTag', 'tag_id', { 272 blog_id => $blog_id, 273 object_id => \@eids, 274 object_datasource => MT::Entry->datasource, 275 }, { 276 unique => 1, 277 } ] }); 297 sort => 'name', 298 join => ['MT::ObjectTag', 'tag_id', { 299 %blog_terms, 300 object_id => \@eids, 301 object_datasource => MT::Entry->datasource, 302 }, { 303 %blog_args, 304 unique => 1, 305 } ] }); 278 306 279 307 my @res; … … 281 309 my $tokens = $ctx->stash('tokens'); 282 310 while (my $t = $iter->()) { 283 next if $t->is_private;284 local $ctx->{__stash}{Tag} = $t;285 local $ctx->{__stash}{tag_count} = undef;286 local $ctx->{__stash}{tag_entry_count} = undef;287 defined(my $out = $builder->build($ctx, $tokens))288 or return $ctx->error($ctx->errstr);289 push @res, $out;311 next if $t->is_private; 312 local $ctx->{__stash}{Tag} = $t; 313 local $ctx->{__stash}{tag_count} = undef; 314 local $ctx->{__stash}{tag_entry_count} = undef; 315 defined(my $out = $builder->build($ctx, $tokens)) 316 or return $ctx->error($ctx->errstr); 317 push @res, $out; 290 318 } 291 319 my $glue = $args->{glue} || ''; … … 315 343 my $tokens = $ctx->stash('tokens'); 316 344 foreach (@tags) { 317 local $ctx->{__stash}{'Tag'} = $_;318 local $ctx->{__stash}{tag_count} = undef;319 defined(my $out = $builder->build($ctx, $tokens, $cond))320 or return $ctx->error($ctx->errstr);321 push @res, $out;345 local $ctx->{__stash}{'Tag'} = $_; 346 local $ctx->{__stash}{tag_count} = undef; 347 defined(my $out = $builder->build($ctx, $tokens, $cond)) 348 or return $ctx->error($ctx->errstr); 349 push @res, $out; 322 350 } 323 351 my $glue = $args->{glue} || ''; … … 332 360 333 361 $path . 'mt-xsearch.cgi' . '?blog_id=' . $ctx->stash('blog_id') . 334 '&search_key=TagSupplementals' .335 ($delimiter ? '&delimiter=' . MT::Util::encode_url($delimiter) : '') .336 '&search=' . MT::Util::encode_url($tag->name);362 '&search_key=TagSupplementals' . 363 ($delimiter ? '&delimiter=' . MT::Util::encode_url($delimiter) : '') . 364 '&search=' . MT::Util::encode_url($tag->name); 337 365 } 338 366 … … 348 376 my $tokens = $ctx->stash('tokens'); 349 377 foreach (@$tags) { 350 local $ctx->{__stash}{'Tag'} = $_;351 local $ctx->{__stash}{tag_count} = undef;352 defined(my $out = $builder->build($ctx, $tokens, $cond))353 or return $ctx->error($ctx->errstr);354 push @res, $out;378 local $ctx->{__stash}{'Tag'} = $_; 379 local $ctx->{__stash}{tag_count} = undef; 380 defined(my $out = $builder->build($ctx, $tokens, $cond)) 381 or return $ctx->error($ctx->errstr); 382 push @res, $out; 355 383 } 356 384 my $glue = $args->{glue} || ''; … … 377 405 my $tags = $args->{search} or MT->error('Search string is required.'); 378 406 my @tag_names = MT::Tag->split($delimiter, $tags) 379 or return [];407 or return []; 380 408 my $tag_count = scalar @tag_names; 381 409 382 410 my @tags = MT::Tag->load_by_datasource(MT::Entry->datasource, { 383 is_private => 0,384 $blog_id ? (blog_id => $blog_id) : (),385 name=> \@tag_names,411 is_private => 0, 412 $blog_id ? (blog_id => $blog_id) : (), 413 name => \@tag_names, 386 414 }); 387 415 $self->{xsearch_tags} = \@tags; … … 390 418 my @eids; 391 419 if (MT::Object->driver->can('count_group_by')) { 392 my $iter = MT::ObjectTag->count_group_by({393 blog_id=> $blog_id,394 tag_id=> \@tag_ids,395 object_datasource => MT::Entry->datasource,396 }, {397 group => ['object_id'],398 });399 while (my ($count, $object_id) = $iter->()) {400 push @eids, $object_id if $count == $tag_count;401 }420 my $iter = MT::ObjectTag->count_group_by({ 421 blog_id => $blog_id, 422 tag_id => \@tag_ids, 423 object_datasource => MT::Entry->datasource, 424 }, { 425 group => ['object_id'], 426 }); 427 while (my ($count, $object_id) = $iter->()) { 428 push @eids, $object_id if $count == $tag_count; 429 } 402 430 } else { 403 my $iter = MT::ObjectTag->load_iter({404 blog_id=> $blog_id,405 tag_id=> \@tag_ids,406 object_datasource => MT::Entry->datasource,407 });408 my %count;409 while (my $otag = $iter->()) {410 $count{$otag->object_id}++;411 }412 foreach (keys %count) {413 push @eids, $_ if $count{$_} == $tag_count;414 }431 my $iter = MT::ObjectTag->load_iter({ 432 blog_id => $blog_id, 433 tag_id => \@tag_ids, 434 object_datasource => MT::Entry->datasource, 435 }); 436 my %count; 437 while (my $otag = $iter->()) { 438 $count{$otag->object_id}++; 439 } 440 foreach (keys %count) { 441 push @eids, $_ if $count{$_} == $tag_count; 442 } 415 443 } 416 444 return [] unless scalar @eids; … … 419 447 map { push @entries, MT::Entry->load($_) } @eids; 420 448 @entries = $sort_order eq 'descend' ? 421 sort { $b->created_on <=> $a->created_on } @entries :422 sort { $a->created_on <=> $b->created_on } @entries;449 sort { $b->created_on <=> $a->created_on } @entries : 450 sort { $a->created_on <=> $b->created_on } @entries; 423 451 splice(@entries, $lastn) if $lastn && (scalar @entries > $lastn); 424 452
![(please configure the [header_logo] section in trac.ini)](/public/chrome/common/trac_banner.png)