Changeset 1708
- Timestamp:
- 04/02/08 06:12:41 (23 months ago)
- Location:
- branches/release-33/lib/MT
- Files:
-
- 2 modified
-
App/Search.pm (modified) (9 diffs)
-
Template/Context/Search.pm (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/release-33/lib/MT/App/Search.pm
r1647 r1708 50 50 my $app = shift; 51 51 return { 52 params => [ qw( searchTerms search count limit startIndex offset ) ], 52 params => [ qw( searchTerms search count limit startIndex offset 53 category author )], 53 54 types => { 54 55 #author => { … … 58 59 #}, 59 60 entry => { 60 columns => [ qw( title keywords text text_more ) ], 61 columns => { 62 title => 'like', 63 keywords => 'like', 64 text => 'like', 65 text_more => 'like' 66 }, 61 67 'sort' => 'authored_on', 62 68 terms => { status => 2 }, #MT::Entry::RELEASE() 69 filter_types => { 70 author => \&_join_author, 71 category => \&_join_category, 72 }, 63 73 }, 64 74 }, … … 281 291 282 292 $count = $class->count( $terms, $args ); 293 return $app->error($class->errstr) unless defined $count; 283 294 284 295 my $cache_driver = $app->{cache_driver}; … … 296 307 297 308 my $count = $app->count( $class, $terms, $args ); 298 return $app->err or($class->errstr) unless defined $count;309 return $app->errtrans("Invalid query. [_1]", $app->errstr) unless defined $count; 299 310 300 311 my $iter = $class->load_iter( $terms, $args ) … … 334 345 335 346 my $columns = $params->{columns}; 347 delete $columns->{'plugin'}; #FIXME: why is this in here? 336 348 return $app->errtrans('No column was specified to search for [_1].', $app->{searchparam}{Type}) 337 unless $columns && @$columns;338 339 my $parsed = $app->query_parse( $columns );349 unless $columns && %$columns; 350 351 my $parsed = $app->query_parse( %$columns ); 340 352 return $app->errtrans('Parse error: [1]', $app->errstr) 341 353 unless $parsed && %$parsed; … … 474 486 # load specified template 475 487 my $filename; 476 if (my @tmpls = ($app->config->default('SearchAltTemplate'), $app->config->SearchAltTemplate)) { 488 if (my @tmpls = ( 489 $app->config->default('SearchAltTemplate'), 490 $app->config->SearchAltTemplate) ) { 477 491 for my $tmpl (@tmpls) { 478 492 next unless defined $tmpl; … … 550 564 sub query_parse { 551 565 my $app = shift; 552 my ( $columns ) = @_; 566 my ( %columns ) = @_; 567 568 my $search = $app->{search_string}; 569 570 my $reg = $app->registry( $app->mode, 'types', $app->{searchparam}{Type} ); 571 my $filter_types = $reg->{ 'filter_types' }; 572 foreach my $type ( keys %$filter_types ) { 573 if ( my $filter = $app->param($type) ) { 574 $search .= " $type:$filter"; 575 } 576 } 553 577 554 578 require Lucene::QueryParser; 555 my $lucene_struct = Lucene::QueryParser::parse_query( $app->{search_string} ); 556 my %columns = map { $_ => 1 } @$columns; 557 my $structure = $app->_query_parse_core( $lucene_struct, \%columns ); 558 { terms => $structure }; 579 my $lucene_struct = Lucene::QueryParser::parse_query( $search ); 580 my ( $terms, $joins ) = $app->_query_parse_core( $lucene_struct, \%columns, $filter_types ); 581 my $return = { 582 $terms && @$terms ? (terms => $terms) : () 583 }; 584 if ( $joins && @$joins ) { 585 my $args = {}; 586 _create_join_arg( $args, $joins ); 587 if ( $args && %$args ) { 588 $return->{args} = $args; 589 } 590 } 591 $return; 592 } 593 594 sub _create_join_arg { 595 my ( $args, $joins ) = @_; 596 my $join = shift @$joins; 597 return unless $join && @$join; 598 my $next = $join->[3]; 599 if ( defined $next ) { 600 if ( exists $next->{'join'} ) { 601 $next = $next->{'join'}->[3]; 602 } 603 } 604 else { 605 $next = {}; 606 $join->[3] = $next; 607 } 608 _create_join_arg($next, $joins); 609 $args->{'join'} = $join; 559 610 } 560 611 561 612 sub _query_parse_core { 562 613 my $app = shift; 563 my ( $lucene_struct, $columns ) = @_; 564 565 my @structure; 614 my ( $lucene_struct, $columns, $filter_types ) = @_; 615 616 my $rvalue = sub { 617 my %rvalues = ( 618 NORMALlike => { like => '%' . $_[1] . '%' }, 619 NORMAL1 => $_[1], 620 PROHIBITEDlike => { not_like => '%' . $_[1] . '%' }, 621 PROHIBITED1 => { not => $_[1] } 622 ); 623 $rvalues{$_[0]}; 624 }; 625 626 my ( @structure, @joins ); 566 627 for my $term ( @$lucene_struct ) { 567 next if exists( $term->{field} ) 568 && !exists( $columns->{ $term->{field} } ); 569 570 my $test; 628 if ( exists $term->{field} ) { 629 unless ( exists $columns->{ $term->{field} } ) { 630 next if $filter_types && %$filter_types 631 && !exists( $filter_types->{ $term->{field} } ); 632 } 633 } 634 635 my @tmp; 571 636 if ( ( 'TERM' eq $term->{query} ) || ( 'PHRASE' eq $term->{query} ) ){ 572 if ( 'PROHIBITED' eq $term->{type} ) { 573 $test = { not_like => '%'.$term->{term}.'%' }; 637 my $test; 638 if ( exists( $term->{field} ) ) { 639 if ( $filter_types && %$filter_types 640 && exists( $filter_types->{ $term->{field} } ) ) { 641 my $code = $app->handler_to_coderef($filter_types->{ $term->{field} }); 642 if ( $code ) { 643 my $join_args = $code->( $app, $term ); 644 push @joins, $join_args; 645 next; 646 } 647 } 648 elsif ( exists $columns->{ $term->{field} } ) { 649 my $test = $rvalue->( 650 ( $term->{type} || '' ) . $columns->{ $term->{field} }, 651 $term->{term} 652 ); 653 push @tmp, { $term->{field} => $test }; 654 } 574 655 } 575 656 else { 576 $test = { like => '%'.$term->{term}.'%' }; 657 my @cols = keys %$columns; 658 my $number = scalar @cols; 659 for ( my $i = 0; $i < $number; $i++ ) { 660 my $test = $rvalue->( 661 ( $term->{type} || '' ) . $columns->{ $cols[$i] }, 662 $term->{term} 663 ); 664 push @tmp, { $cols[$i] => $test }; 665 unless ( $i == $number - 1 ) { 666 push @tmp, '-or'; 667 } 668 } 577 669 } 578 670 } 579 671 elsif ( 'SUBQUERY' eq $term->{query} ) { 580 $test = $app->_query_parse_core( $term->{subquery}, $columns ); 672 my ( $test, $more_joins ) = $app->_query_parse_core( 673 $term->{subquery}, $columns, $filter_types ); 581 674 next unless $test && @$test; 582 675 if ( @structure ) { … … 586 679 } 587 680 push @structure, $test->[0]; 681 push @joins, @$more_joins; 588 682 next; 589 683 } 590 684 591 my @tmp;592 if ( exists( $term->{field} ) ) {593 push @tmp, { $term->{field} => $test };594 }595 else {596 my @columns = keys %$columns;597 my $number = scalar @columns;598 for ( my $i = 0; $i < $number; $i++) {599 push @tmp, { $columns[$i] => $test };600 unless ( $i == $number - 1 ) {601 push @tmp, '-or';602 }603 }604 }605 685 if ( exists($term->{conj}) && ( 'OR' eq $term->{conj} ) ) { 606 686 if ( my $prev = pop @structure ) { … … 615 695 } 616 696 } 617 \@structure; 697 ( \@structure, \@joins ); 698 } 699 700 # add category filter to entry search 701 sub _join_category { 702 my ( $app, $term ) = @_; 703 704 my $query = $term->{term}; 705 if ( 'PHRASE' eq $term->{query} ) { 706 $query =~ s/'/"/g; 707 } 708 709 my $lucene_struct = Lucene::QueryParser::parse_query( $query ); 710 if ( 'PROHIBITED' eq $term->{type} ) { 711 $_->{type} = 'PROHIBITED' foreach @$lucene_struct; 712 } 713 # search for exact match 714 my ( $terms ) = $app->_query_parse_core( $lucene_struct, { label => 1 }, {} ); 715 return unless $terms && @$terms; 716 push @$terms, '-and', { 717 id => \'= placement_category_id', 718 blog_id => \'= entry_blog_id', 719 }; 720 721 require MT::Placement; 722 require MT::Category; 723 return MT::Placement->join_on( undef, 724 { entry_id => \'= entry_id', blog_id => \'= entry_blog_id' }, 725 { join => MT::Category->join_on( undef, $terms, {} ), 726 unique => 1 } 727 ); 728 } 729 730 # add author filter to entry search 731 sub _join_author { 732 my ( $app, $term ) = @_; 733 734 my $query = $term->{term}; 735 if ( 'PHRASE' eq $term->{query} ) { 736 $query =~ s/'/"/g; 737 } 738 739 my $lucene_struct = Lucene::QueryParser::parse_query( $query ); 740 if ( 'PROHIBITED' eq $term->{type} ) { 741 $_->{type} = 'PROHIBITED' foreach @$lucene_struct; 742 } 743 my ( $terms ) = $app->_query_parse_core( $lucene_struct, { nickname => 'like' }, {} ); 744 return unless $terms && @$terms; 745 push @$terms, '-and', { 746 id => \'= entry_author_id', 747 }; 748 require MT::Author; 749 return MT::Author->join_on( undef, 750 $terms, 751 { unique => 1 } 752 ); 618 753 } 619 754 -
branches/release-33/lib/MT/Template/Context/Search.pm
r1640 r1708 9 9 use strict; 10 10 use base qw( MT::Template::Context ); 11 use MT::Util qw( encode_url );11 use MT::Util qw( encode_url decode_html ); 12 12 13 13 sub load_core_tags { … … 134 134 my ( $ctx, $args, $cond ) = @_; 135 135 136 my $search_string = encode_url($ctx->stash('search_string'));136 my $search_string = decode_html( $ctx->stash('search_string') ) ; 137 137 my $cgipath = $ctx->_hdlr_cgi_path($args); 138 138 my $script = $ctx->{config}->SearchScript; 139 my $link = $cgipath.$script . '?search=' . $search_string;139 my $link = $cgipath.$script . '?search=' . encode_url( $search_string ); 140 140 if ( my $mode = $ctx->stash('mode') ) { 141 141 $mode = encode_url($mode);
