1 package AddressBook::Controller::Search; 2 use strict; 3 use warnings; 4 use Text::CSV_XS; 5 use parent qw(Catalyst::Controller::HTML::FormFu); 6 7 sub search : Global FormConfig { 8 my ($self, $c, $query) = @_; 9 my $form = $c->stash->{form}; 10 11 # Get query from search form 12 if ($form->submitted_and_valid) { 13 $query = $c->request->param('query'); 14 } 15 return unless $query; # No query? We're done 16 $c->stash->{query} = $query; 17 18 # Parse query into tokens 19 my $csv = Text::CSV_XS->new(); 20 $csv->parse($query) or die "Error parsing query"; 21 my @tokens = $csv->fields(); 22 23 # Process query from search form and stash results 24 my $result; 25 if ($form->submitted_and_valid) { 26 if ($c->request->param('domain') eq 'Names') { 27 $result = $c->forward('search_names', \@tokens); 28 $c->stash->{template} = 'search/name_results.tt2'; 29 } else { 30 $result = $c->forward('search_addresses', \@tokens); 31 $c->stash->{template} = 'search/address_results.tt2'; 32 } 33 $c->stash->{result} = $result; 34 my $page = $c->request->param('page'); 35 $page = 1 if ($page !~ /^\d+$/); 36 my $page_result = $result->page($page); 37 $c->stash->{pager} = $page_result->pager; 38 } 39 } 40 41 sub search_names : Private { 42 my ($self, $c, @tokens) = @_; 43 my @people_fields = qw/firstname lastname/; 44 @people_fields = cross(\@people_fields, \@tokens); 45 return $c->model('AddressDB::People')->search(\@people_fields); 46 } 47 48 sub search_addresses : Private { 49 my ($self, $c, @tokens) = @_; 50 my @address_fields = qw/postal phone email location/; 51 @address_fields = cross(\@address_fields, \@tokens); 52 return $c->model('AddressDB::Addresses')->search(\@address_fields); 53 } 54 55 sub cross { 56 my $columns = shift || []; 57 my $tokens = shift || []; 58 map {s/%/\\%/g} @$tokens; 59 my @result; 60 foreach my $column (@$columns){ 61 push @result, (map +{$column => {-like => "%$_%"}}, @$tokens); 62 } 63 return @result; 64 } 65 66 1;