207 lines
6.2 KiB
Perl
207 lines
6.2 KiB
Perl
#!/usr/bin/perl
|
|
#
|
|
# DW::Controller::Search::Multisearch
|
|
#
|
|
# Conversion of LJ's multisearch.bml, used for handling redirects
|
|
# from sitewide search bar (LJ::Widget::Search).
|
|
#
|
|
# Also includes handler for /tools/search which simply renders
|
|
# the search widget on a separate page.
|
|
#
|
|
# Authors:
|
|
# Jen Griffin <kareila@livejournal.com>
|
|
#
|
|
# Copyright (c) 2011-2016 by Dreamwidth Studios, LLC.
|
|
#
|
|
# This program is free software; you may redistribute it and/or modify it under
|
|
# the same terms as Perl itself. For a copy of the license, please reference
|
|
# 'perldoc perlartistic' or 'perldoc perlgpl'.
|
|
#
|
|
|
|
package DW::Controller::Search::Multisearch;
|
|
|
|
use strict;
|
|
|
|
use DW::Routing;
|
|
use DW::Template;
|
|
use DW::Controller;
|
|
use Locale::Codes::Country;
|
|
|
|
DW::Routing->register_string( '/multisearch', \&multisearch_handler, app => 1 );
|
|
DW::Routing->register_string( '/tools/search', \&toolsearch_handler, app => 1 );
|
|
|
|
sub multisearch_handler {
|
|
my $r = DW::Request->get;
|
|
my $args = $r->did_post ? $r->post_args : $r->get_args;
|
|
|
|
my $type = lc( $args->{'type'} || '' );
|
|
my $q = lc( $args->{'q'} || '' );
|
|
my $output = lc( $args->{'output'} || '' );
|
|
|
|
my ( $ok, $rv ) = controller( anonymous => 1 );
|
|
return $rv unless $ok;
|
|
|
|
# functions for handling various call types
|
|
my ( $f_nav, $f_user, $f_int, $f_email, $f_faq, $f_region );
|
|
|
|
$f_nav = sub {
|
|
|
|
# Some special shortcuts used for easy navigation
|
|
return $r->redirect("$LJ::SITEROOT/support/faqbrowse?faqid=$1&view=full")
|
|
if $q =~ /^faq (\d+)$/;
|
|
return $r->redirect("$LJ::SITEROOT/support/see_request?id=$2")
|
|
if $q =~ /^req(uest)? (\d+)$/;
|
|
|
|
if ( $q =~ m!(.+)/(pics|full)! ) {
|
|
if ( my $u = LJ::load_user_or_identity($1) ) {
|
|
return $r->redirect( $u->profile_url( full => 1 ) )
|
|
if $2 eq "full";
|
|
return $r->redirect( $u->allpics_base )
|
|
if $2 eq "pics";
|
|
}
|
|
}
|
|
|
|
if ( $type eq "nav_and_user" ) {
|
|
if ( my $u = LJ::load_user_or_identity($q) ) {
|
|
return $r->redirect( $u->profile_url() );
|
|
}
|
|
}
|
|
|
|
my $eq = LJ::ehtml($q);
|
|
return error_ml( '/multisearch.tt.errorpage.nomatch.nav', { query => $eq } );
|
|
};
|
|
|
|
$f_user = sub {
|
|
my $user = $q;
|
|
$user =~ s!\@$LJ::USER_DOMAIN!!;
|
|
$user =~ s!/(\w+)!!;
|
|
my $what = defined $1 ? $1 : '';
|
|
|
|
$user =~ s/-/_/g;
|
|
$user =~ s/[^\w]//g;
|
|
|
|
return $r->redirect("$LJ::SITEROOT/random") unless $user;
|
|
|
|
my $u = LJ::load_user($user);
|
|
return $r->redirect("$LJ::SITEROOT/profile?user=$user") unless $u;
|
|
|
|
return $r->redirect( $u->allpics_base ) if $what eq "pics";
|
|
|
|
my $url = $u->profile_url;
|
|
$url .= "?mode=full" if $what eq 'full';
|
|
return $r->redirect($url);
|
|
};
|
|
|
|
$f_int = sub {
|
|
return error_ml('/multisearch.tt.errorpage.nointerest') unless $q;
|
|
return $r->redirect( "$LJ::SITEROOT/interests?int=" . LJ::eurl($q) );
|
|
};
|
|
|
|
$f_email = sub {
|
|
return error_ml('/multisearch.tt.errorpage.noaddress') unless $q;
|
|
|
|
my $dbr = LJ::get_db_reader();
|
|
my $uid = $dbr->selectrow_array(
|
|
qq{
|
|
SELECT userid FROM user WHERE journaltype='P' AND statusvis='V'
|
|
AND allow_contactshow='Y' AND email=? LIMIT 1 }, undef, $q
|
|
);
|
|
|
|
# if not in the user table, try the email table
|
|
$uid ||= $dbr->selectrow_array(
|
|
qq{
|
|
SELECT e.userid FROM user u, email e WHERE e.email=?
|
|
AND e.userid=u.userid AND u.journaltype='P' AND u.statusvis='V'
|
|
AND u.allow_contactshow='Y' LIMIT 1 }, undef, $q
|
|
);
|
|
|
|
if ( my $u = LJ::load_userid($uid) ) {
|
|
my $show = $u->opt_whatemailshow;
|
|
if ( $show eq "A" || $show eq "B" ) {
|
|
return $r->redirect( $u->profile_url );
|
|
}
|
|
}
|
|
return error_ml('/multisearch.tt.errorpage.nomatch');
|
|
};
|
|
|
|
$f_region = sub {
|
|
$q = LJ::trim($q);
|
|
my @parts = split /\s*,\s*/, $q;
|
|
if ( @parts == 0 || @parts > 3 ) {
|
|
$rv->{type} = 'region';
|
|
return DW::Template->render_template( 'multisearch.tt', $rv );
|
|
}
|
|
|
|
my $ctc = $parts[-1];
|
|
my $country;
|
|
if ( length($ctc) > 2 ) {
|
|
|
|
# Must be country name
|
|
$country = uc country2code($ctc);
|
|
}
|
|
else {
|
|
# Likely country code or invalid
|
|
$country = uc country_code2code( $ctc, LOCALE_CODE_ALPHA_2, LOCALE_CODE_ALPHA_2 );
|
|
$country ||= uc country2code($ctc); # 2-letter country name??
|
|
}
|
|
|
|
my ( $state, $city );
|
|
|
|
if ($country) {
|
|
pop @parts;
|
|
if ( @parts == 1 ) {
|
|
$state = $parts[0];
|
|
}
|
|
else {
|
|
( $city, $state ) = @parts;
|
|
}
|
|
|
|
}
|
|
else {
|
|
$country = "US";
|
|
|
|
if ( @parts == 1 ) {
|
|
$city = $parts[0];
|
|
}
|
|
else {
|
|
( $city, $state ) = @parts;
|
|
}
|
|
}
|
|
|
|
( $city, $state, $country ) = map { LJ::eurl($_) } ( $city, $state, $country );
|
|
return $r->redirect( "$LJ::SITEROOT/directorysearch?s_loc=1"
|
|
. "&loc_cn=$country&loc_st=$state&loc_ci=$city"
|
|
. "&opt_sort=ut&opt_format=pics&opt_pagesize=50" );
|
|
};
|
|
|
|
$f_faq = sub {
|
|
return error_ml('/multisearch.tt.errorpage.nofaq') unless $q;
|
|
return $r->redirect( "$LJ::SITEROOT/support/faqsearch?q=" . LJ::eurl($q) );
|
|
};
|
|
|
|
# set up dispatch table
|
|
my $dispatch = {
|
|
nav_and_user => $f_nav,
|
|
user => $f_user,
|
|
int => $f_int,
|
|
email => $f_email,
|
|
region => $f_region,
|
|
faq => $f_faq,
|
|
};
|
|
|
|
return $dispatch->{$type}->() if exists $dispatch->{$type};
|
|
|
|
# No type specified - redirect them somewhere useful.
|
|
return $r->redirect("$LJ::SITEROOT/tools/search");
|
|
}
|
|
|
|
sub toolsearch_handler {
|
|
my ( $ok, $rv ) = controller( anonymous => 1 );
|
|
return $rv unless $ok;
|
|
|
|
$rv->{widget} = LJ::Widget::Search->render;
|
|
$rv->{sitename} = $LJ::SITENAMESHORT;
|
|
return DW::Template->render_template( 'tools/search.tt', $rv );
|
|
}
|
|
|
|
1;
|