#!/usr/bin/perl # # DW::Controller::Support::History # # This controller is for the Support History page. # # Authors: # hotlevel4 # # Copyright (c) 2015 by Dreamwidth Studios, LLC. # # This is based on code originally implemented on LiveJournal. # # 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::Support::History; use strict; use warnings; use DW::Controller; use DW::Routing; use DW::Template; DW::Routing->register_string( '/support/history', \&history_handler, app => 1 ); sub history_handler { my $r = DW::Request->get; my $args = $r->get_args; $args = $r->post_args if $r->did_post; my ( $ok, $rv ) = controller( anonymous => 0, form_auth => 1 ); return $rv unless $ok; my $vars = {}; my $remote = $rv->{remote}; my $fullsearch = $remote->has_priv('supporthelp'); $vars->{fullsearch} = $fullsearch; if ( $args->{user} || $args->{email} || $args->{userid} ) { my $dbr = LJ::get_db_reader(); return error_ml('/support/history.tt.error.nodatabase') unless $dbr; $vars->{get_user} = ( $args->{user} ) ? 1 : 0; $vars->{get_userid} = ( $args->{userid} ) ? 1 : 0; $vars->{get_email} = ( $args->{email} ) ? 1 : 0; $vars->{user} = $remote->user; my $reqlist; if ( $args->{user} || $args->{userid} ) { # get requests by a user, regardless of email (only gets user requests) my $userid = $args->{userid} ? $args->{userid} + 0 : LJ::get_userid( LJ::trim( $args->{user} ) ); return error_ml('/support/history.tt.error.invaliduser') unless $userid && ( $fullsearch || $remote->id == $userid ); $vars->{username} = LJ::ljuser( LJ::get_username($userid) ); $reqlist = $dbr->selectall_arrayref( 'SELECT spid, subject, state, spcatid, requserid, ' . 'timecreate, timetouched, timelasthelp, reqemail ' . 'FROM support WHERE reqtype = \'user\' AND requserid = ?', undef, $userid ); } elsif ( $args->{email} ) { # try by email, note that this gets requests opened by users and anonymous # requests, so we can view them all my $email = LJ::trim( $args->{email} ); $vars->{email} = LJ::ehtml($email); my %user_emails; unless ($fullsearch) { # check the list of allowable emails for this user my $query = "SELECT oldvalue FROM infohistory WHERE userid=? " . "AND what='email' AND other='A'"; my $rows = $dbr->selectall_arrayref( $query, undef, $remote->id ); $user_emails{ $_->[0] } = 1 foreach @$rows; $user_emails{ $remote->email_raw } = 1 if $remote->email_status eq 'A'; } return error_ml('/support/history.tt.error.invalidemail') unless $email =~ /^.+\@.+$/ && ( $fullsearch || $user_emails{$email} ); $reqlist = $dbr->selectall_arrayref( 'SELECT spid, subject, state, spcatid, requserid, ' . 'timecreate, timetouched, timelasthelp, reqemail ' . 'FROM support WHERE reqemail = ?', undef, $email ); } if ( @{ $reqlist || [] } ) { # construct a list of people who have answered these requests my @ids; foreach (@$reqlist) { next unless $_->[2] eq 'closed'; push @ids, $_->[0]; } my $idlist = join ',', map { $_ + 0 } @ids; my $winners = $dbr->selectall_arrayref( 'SELECT sp.spid, u.user, sp.points FROM useridmap u, supportpoints sp ' . "WHERE u.userid = sp.userid AND sp.spid IN ($idlist)" ); my %points; $points{ $_->[0] + 0 } = [ $_->[1], $_->[2] + 0 ] foreach @{ $winners || [] }; # now construct the request blocks my %reqs; my @userids; foreach my $row (@$reqlist) { $reqs{ $row->[0] } = { spid => $row->[0], winner => $points{ $row->[0] }->[0], points => $points{ $row->[0] }->[1] || 0, subject => LJ::ehtml( $row->[1] ), state => $row->[2], spcatid => $row->[3], requserid => $row->[4], timecreate => $row->[5], timetouched => $row->[6], timelasthelp => $row->[7], reqemail => LJ::ehtml( $row->[8] ), }; push @userids, $row->[4] if $row->[4]; } my $us = @userids ? LJ::load_userids(@userids) : undef; # get categories my $cats = LJ::Support::load_cats(); foreach my $id ( sort { $a <=> $b } keys %reqs ) { # verify user can see this category (public_read or has supportread in it) next unless $cats->{ $reqs{$id}->{spcatid} }{public_read} || LJ::Support::can_read_cat( $cats->{ $reqs{$id}->{spcatid} }, $remote ); my $status = $reqs{$id}->{state} eq "closed" ? "closed" : LJ::Support::open_request_status( $reqs{$id}->{timetouched}, $reqs{$id}->{timelasthelp} ); my $answered = 0; my $points = 0; my $answeredby = '-'; if ( $reqs{$id}->{state} eq 'closed' && $reqs{$id}->{winner} ) { $answeredby = LJ::ljuser( $reqs{$id}->{winner} ); $points = $reqs{$id}->{points}; $answered = 1; } push @{ $vars->{reqs} }, { spid => $reqs{$id}->{spid}, subject => $reqs{$id}->{subject}, status => $status, answeredby => $answeredby, points => $points, answered => $answered, catname => $cats->{ $reqs{$id}->{spcatid} }{catname}, openedby => $reqs{$id}->{requserid} ? LJ::ljuser( $us->{ $reqs{$id}->{requserid} } ) : $reqs{$id}->{reqemail}, timeopened => LJ::mysql_time( $reqs{$id}->{timecreate} ) }; } } else { $vars->{noresults} = 1; } } elsif ( $args->{fulltext} ) { $rv = DW::Controller::Support::Search::do_search( remoteid => $remote->id, query => $args->{fulltext} ); return DW::Template->render_template( 'support/search.tt', $rv ); } elsif ( !$fullsearch ) { my $redirect_user = $remote->user; $r->header_out( Location => "$LJ::SITEROOT/support/history?user=$redirect_user" ); return $r->REDIRECT; } return DW::Template->render_template( 'support/history.tt', $vars ); } 1;