root/branches/release-30/lib/MT/Template/Context/Search.pm @ 1420

Revision 1420, 4.4 kB (checked in by fumiakiy, 21 months ago)

Initial attempt to pluggable, extensible and hopefully faster search framework. BugId:69030, BugId:69029, BugId:69031

mt-search.cgi still defaults to legacy search application for now.

  • Property svn:keywords set to Id Date Author Revision
Line 
1# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
2# This program is distributed under the terms of the
3# GNU General Public License, version 2.
4#
5# $Id$
6
7package MT::Template::Context::Search;
8
9use strict;
10use base qw( MT::Template::Context );
11
12sub load_core_tags {
13    require MT::Template::Context;
14    return {
15        function => {
16            SearchString => \&_hdlr_search_string,
17            SearchResultCount => \&_hdlr_result_count,
18            MaxResults => \&_hdlr_max_results,
19            SearchIncludeBlogs => \&_hdlr_include_blogs,
20            SearchTemplateID => \&_hdlr_template_id,
21        },
22        block => {
23            SearchResults => \&_hdlr_results,
24            'IfTagSearch?' => sub { MT->instance->mode eq 'tag' },
25            'IfStraightSearch?' => sub { MT->instance->mode eq 'search' },
26            'NoSearchResults?' => sub { $_[0]->stash('count') ? 0 : 1; },
27            'NoSearch?' => sub { ( $_[0]->stash('search_string') &&
28                                   $_[0]->stash('search_string') =~ /\S/ ) ? 0 : 1 },
29            BlogResultHeader => \&MT::Template::Context::_hdlr_pass_tokens,
30            BlogResultFooter => \&MT::Template::Context::_hdlr_pass_tokens,
31            IfMaxResultsCutoff => \&MT::Template::Context::_hdlr_pass_tokens,
32        },
33    };
34}
35
36sub _hdlr_include_blogs { $_[0]->stash('include_blogs') || '' }
37sub _hdlr_search_string { $_[0]->stash('search_string') || '' }
38sub _hdlr_template_id { $_[0]->stash('template_id') || '' }
39sub _hdlr_max_results { $_[0]->stash('maxresults') || '' }
40
41sub _hdlr_result_count {
42    my $results = $_[0]->stash('results');
43    $results && ref($results) eq 'ARRAY' ? scalar @$results : 0;
44}
45
46sub _hdlr_results {
47    my($ctx, $args, $cond) = @_;
48
49    ## If there are no results, return the empty string, knowing
50    ## that the handler for <MTNoSearchResults> will fill in the
51    ## no results message.
52    my $iter = $ctx->stash('results') or return '';
53    my $count = $ctx->stash('count') or return '';
54    my $max = $ctx->stash('maxresults');
55    my $stash_key = $ctx->stash('stash_key') || 'entry';
56
57    my $output = '';
58    my $build = $ctx->stash('builder');
59    my $tokens = $ctx->stash('tokens');
60    my $blog_header = 1;
61    my $blog_footer = 0;
62    my $count_per_blog = 0;
63    my $max_reached = 0;
64    my ( $this_object, $next_object );
65    $this_object = $iter->();
66    for ( my $i = 0; $i < $count; $i++) {
67        $count_per_blog++;
68        $ctx->stash($stash_key, $this_object);
69        if ( $this_object->can('blog') ) {
70            local $ctx->{__stash}{blog} = $this_object->blog;
71        }
72        if ( $this_object->isa('MT::Entry') ) {
73            local $ctx->{current_timestamp} = $this_object->authored_on;
74        }
75        elsif ( $this_object->properties->{audit} ) {
76            local $ctx->{current_timestamp} = $this_object->created_on;
77        }
78
79        # TODO: per blog max objects?
80        #if ( $count_per_blog >= $max ) {
81        #    while (1) {
82        #        if ( $count > $i + 1 ) {
83        #            $next_object = $results->[$i + 1];
84        #            if ( $next_object->blog_id ne $this_object->blog_id ) {
85        #                $blog_footer = 1;
86        #                last;
87        #            }
88        #            else {
89        #                $max_reached = 1;
90        #            }
91        #        }
92        #        else {
93        #            $next_object = undef;
94        #            $blog_footer = 1;
95        #            last;
96        #        }
97        #        $i++;
98        #    }
99        #}
100        #elsif ( $count > $i + 1 ) {
101        #    $next_object = $results->[$i + 1];
102        #    $blog_footer = $next_object->blog_id ne $this_object->blog_id ? 1 : 0;
103        #}
104        #else {
105        #    $blog_footer = 1;
106        #}
107        if ( $next_object = $iter->() ) {
108            $blog_footer = $next_object->blog_id ne $this_object->blog_id ? 1 : 0;
109        }
110        else {
111            $blog_footer = 1;
112        }
113
114        defined(my $out = $build->build($ctx, $tokens,
115            { %$cond, 
116                BlogResultHeader => $blog_header,
117                BlogResultFooter => $blog_footer,
118                IfMaxResultsCutoff => $max_reached,
119            }
120            )) or return $ctx->error( $build->errstr );
121        $output .= $out;
122
123        $this_object = $next_object;
124        last unless $this_object;
125        $blog_header = $blog_footer ? 1 : 0;
126    }
127    $output;
128}
129
1301;
131__END__
132
Note: See TracBrowser for help on using the browser.