mourningdove/cgi-bin/DW/Controller/Search/Directory.pm

152 lines
5.1 KiB
Perl
Raw Normal View History

2026-05-24 01:03:05 +00:00
#!/usr/bin/perl
#
# DW::Controller::Search::Directory
#
# Directory search, based on code from LiveJournal.
#
# Authors:
# Jen Griffin <kareila@livejournal.com>
#
# Copyright (c) 2011 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::Directory;
use strict;
use DW::Routing;
use DW::Template;
use DW::Controller;
use LJ::Directory::Search; # also loads Results and Constraint
use LJ::Widget;
DW::Routing->register_string( '/directorysearch', \&directory_handler, app => 1 );
DW::Routing->register_string( '/community/search', \&directory_handler, app => 1 );
sub directory_handler {
my $r = DW::Request->get;
my $args = $r->get_args;
my ( $ok, $rv ) = controller();
return $rv unless $ok;
my $remote = $rv->{remote};
return error_ml('cprod.directory.text3.v1')
unless $remote->can_use_directory;
# check for the /community/search path (same form)
if ( $r->uri =~ m:^/community/search: ) {
$rv->{comm_page} = 1;
}
# see if we submitted the form (the directory.bml section)
if ( $args->{opt_pagesize} || $args->{s_loc} ) {
# if the search hasn't started, show the interstitial
unless ( $args->{start_search} ) {
# do a refresh to the page with the finished results.
$rv->{refurl} = LJ::ehtml( LJ::page_change_getargs( start_search => 1 ) );
$rv->{dots} = LJ::img( 'searchdots', '' );
return DW::Template->render_template( 'directory/searchdots.tt', $rv );
}
my $journaltype = $rv->{journaltype} = uc( $args->{journaltype} || '' );
$rv->{searchurl} = $journaltype eq 'C' ? "community/search" : "directorysearch";
$rv->{filter_linkbar} = sub {
# create the links to filter by journal type
my $filter_url = sub {
my $jt = $_[0] || '';
my %get = ( start_search => 1, journaltype => $jt, page => '' );
return LJ::ehtml( LJ::page_change_getargs(%get) );
};
my $linkify = sub {
my ( $text, $filter ) = @_;
return $text if $journaltype eq $filter;
my $url = $filter_url->($filter);
return "<a href='$url'>$text</a>";
};
my $strings = $_[0] or return '';
my @links;
push @links, $linkify->( $strings->{all}, '' );
push @links, $linkify->( $strings->{comm}, 'C' );
push @links, $linkify->( $strings->{user}, 'P' );
push @links, $linkify->( $strings->{ident}, 'I' );
return join "&nbsp;|&nbsp;", @links;
};
$rv->{ignore} = LJ::Hooks::run_hook( "interest_search_ignore", query => $args->{int_like} );
unless ( $rv->{ignore} ) {
# manipulate form arguments
my %searchargs = (
page => delete $args->{page} || 1,
page_size => $args->{opt_pagesize},
format => $args->{opt_format}
);
# country, state and city fields are generated by
# LJ::Widget::GeoSearchLocation widget, hence all
# corresponding <input>-tags have widget-specific
# prefixed 'name' attribute.
# calling post_fields to fix this
my $widget_params = LJ::Widget::GeoSearchLocation->post_fields($args);
$args->{loc_cn} ||= $widget_params->{country};
$args->{loc_ci} ||= $widget_params->{city};
$args->{loc_st} ||= $widget_params->{statedrop}
|| $widget_params->{stateother};
# parse GET args into search constraints
my @constraints = LJ::Directory::Constraint->constraints_from_formargs($args);
# do the actual search (synchronous)
my $dir = LJ::Directory::Search->new( %searchargs, constraints => \@constraints );
my LJ::Directory::Results $res = $dir->search;
$res = $dir->search while !$res;
if ($res) {
my $self_link = {
self_link => sub {
LJ::page_change_getargs(
page => $_[0],
start_search => ''
);
}
};
$rv->{paging_bar} =
LJ::paging_bar( $searchargs{page}, $res->pages, $self_link );
my @users = $res->users;
$rv->{numusers} = scalar @users;
$rv->{results} = $res->render;
}
else {
$rv->{search_err} = 1;
}
}
return DW::Template->render_template( 'directory/results.tt', $rv );
}
# show the search form
my $w = LJ::Widget::GeoSearchLocation->new;
$rv->{location_widget} = $w->render( country => '', state => '', city => '' );
return DW::Template->render_template( 'directory/index.tt', $rv );
}
1;