package EPrints::Plugin::Screen::REF::Listing; use EPrints::Plugin::Screen::REF; @ISA = qw( EPrints::Plugin::Screen::AbstractSearch EPrints::Plugin::Screen::REF ); use strict; sub new { my( $class, %params ) = @_; my $self = $class->EPrints::Plugin::Screen::REF::new( %params ); push @{$self->{actions}}, qw/ update search newsearch search_authored search_deposited select unselect sync /; $self->{appears} = [ { place => "key_tools", position => 1000, } ]; $self->{stime} = time(); return $self; } sub can_be_viewed { shift->EPrints::Plugin::Screen::REF::can_be_viewed } sub allow_search_authored { 1 } sub allow_search_deposited { 1 } sub allow_select { shift->can_select } sub allow_unselect { shift->allow_select } sub allow_sync { shift->allow_select } sub wishes_to_export { shift->{session}->param( "ajax" ) } sub export_mimetype { "text/html; charset=utf-8" } sub properties_from { my( $self ) = @_; $self->EPrints::Plugin::Screen::REF::properties_from; $self->EPrints::Plugin::Screen::AbstractSearch::properties_from; $self->{processor}->{dataset} = $self->{session}->dataset( "ref_selection" ); } sub from { my( $self ) = @_; my $action = $self->{processor}->{action}; $action = "" if !defined $action; $self->search_from( $action ); $action = $self->{processor}->{action}; $self->EPrints::Plugin::Screen::from; if( $action eq "search" || $action eq "update" || $action eq "search_authored" || $action eq "search_deposited" ) { $self->run_search; } } sub redirect_to_me_url { my( $self ) = @_; # landing from another plugin, so make sure we clear any POSTs if( $self->{session}->param( "screen" ) ne $self->get_subtype ) { return $self->EPrints::Plugin::Screen::REF::redirect_to_me_url; } return $self->SUPER::redirect_to_me_url; # AbstractSearch } # Copied from AbstractSearch but without the brain-dead actions override sub search_from { my( $self, $action ) = @_; $self->{processor}->{search} = new EPrints::Search( keep_cache => 1, for_web => 1, session => $self->{session}, filters => [$self->search_filters], dataset => $self->search_dataset, %{$self->{processor}->{sconf}} ); if( $action eq "search" || $action eq "update" || $action eq "search_authored" || $action eq "search_deposited" ) { foreach my $sf ( $self->{processor}->{search}->get_non_filter_searchfields ) { my $prob = $sf->from_form(); if( defined $prob ) { $self->{processor}->add_message( "warning", $prob ); } } my $exp = $self->{session}->param( "exp" ); $self->{processor}->{search}->from_string( $exp ) if EPrints::Utils::is_set( $exp ); } if( $action eq "search" || $action eq "update" ) { if( $self->{processor}->{search}->is_blank ) { $self->{processor}->add_message( "warning", $self->{session}->html_phrase( "lib/searchexpression:least_one" ) ); $self->{processor}->{action} = ""; } } my $anyall = $self->{session}->param( "satisfyall" ); if( defined $anyall ) { $self->{processor}->{search}->{satisfy_all} = ( $anyall eq "ALL" ); } my $order_opt = $self->{session}->param( "order" ); if( !defined $order_opt ) { $order_opt = ""; } my $allowed_order = 0; foreach my $order_key ( keys %{$self->{processor}->{sconf}->{order_methods}} ) { $allowed_order = 1 if( $order_opt eq $self->{processor}->{sconf}->{order_methods}->{$order_key} ); } if( $allowed_order ) { $self->{processor}->{search}->{custom_order} = $order_opt; } else { $self->{processor}->{search}->{custom_order} = $self->{processor}->{sconf}->{order_methods}->{$self->{processor}->{sconf}->{default_order}}; } } sub action_search_authored { my( $self ) = @_; } sub action_search_deposited { my( $self ) = @_; } sub action_select { my( $self ) = @_; my $repo = $self->{session}; $self->_action_redirect; my $search = $self->{processor}->{search}; my $eprintid = $repo->param( "eprint" ); my $dataset = $self->{processor}->{dataset}; my $user = $repo->current_user; my $role = $self->{processor}->{role}; my $benchmark = $self->{processor}->{benchmark}; $search->add_field( $search->{dataset}->field( "eprintid" ), $eprintid, "EX" ); my $eprint = $search->perform_search->item( 0 ); if( !defined $eprint ) { EPrints->abort( "Permissions error" ); } # already selected my $selection = $dataset->dataobj_class->new_from_parts( $repo, eprint => $eprint, user => $role, ); if( !defined $selection ) { $selection = $dataset->dataobj_class->create_from_parts( $repo, eprint => $eprint, user => $role, user_actual => $user, ); } $selection->select_for( $benchmark, $role->value( "ref_uoa" ) ); $selection->commit; # $repo->{database}->save_user_message( # $user->id, # "message", # $self->html_phrase( "selected", # selection => $selection->render_description, # ) # ); } sub action_unselect { my( $self ) = @_; my $repo = $self->{session}; $self->_action_redirect; my $selectionid = $repo->param( "selection" ); my $dataset = $self->{processor}->{dataset}; my $user = $repo->current_user; my $role = $self->{processor}->{role}; my $benchmark = $self->{processor}->{benchmark}; my $selection = $dataset->dataobj( $selectionid ); return if !defined $selection; if( $role->id != $selection->value( "user_id" ) ) { EPrints->abort( "Permissions error" ); } $selection->unselect_for( $benchmark ); $selection->commit; # $repo->{database}->save_user_message( # $user->id, # "message", # $self->html_phrase( "unselected", # selection => $selection->render_description, # ) # ); } sub action_sync { my( $self ) = @_; my $repo = $self->{session}; $self->_action_redirect; my $selectionid = $repo->param( "selection" ); my $dataset = $self->{processor}->{dataset}; my $user = $repo->current_user; my $role = $self->{processor}->{role}; my $benchmark = $self->{processor}->{benchmark}; my $selection = $dataset->dataobj( $selectionid ); return if !defined $selection; if( $role->id != $selection->value( "user_id" ) ) { EPrints->abort( "Permissions error" ); } $selection->unselect_for( $benchmark ); $selection->select_for( $benchmark, $role->value( "ref_uoa" ) ); $selection->commit; } sub search_dataset { my( $self ) = @_; return $self->{session}->dataset( "archive" ); } sub search_filters { my( $self ) = @_; # any pre-defined searches? my $action = $self->{processor}->{action}; my @filters = $self->SUPER::search_filters; if( $action ) { if( $action eq 'search_authored' ) { my $author_name = $self->{processor}->{role}->get_value( "name" ); my $search_string = $author_name->{family}; if( defined $author_name->{given} && length $author_name->{given} ) { $search_string .= ",".substr( $author_name->{given}, 0, 1 ); } push @filters, { meta_fields=>[ 'creators_name' ], value=> $search_string }; } elsif( $action eq 'search_deposited' ) { push @filters, { meta_fields=>[ 'userid' ], value=> $self->{processor}->{role}->get_id, match=>'EX', describe=>0 }; } } return @filters; } sub render_action_link { my( $self ) = @_; local $self->{processor}->{role}; $self->SUPER::render_action_link; } sub render_title { shift->EPrints::Plugin::Screen::render_title } sub render_predefined_searches { my( $self ) = @_; my $session = $self->{session}; my $chunk = $session->make_doc_fragment; my $base_url = URI->new( $session->config( "http_cgiroot" ) . "/users/home", ); $base_url->query_form( screen => $self->{processor}->{screenid} ); my $button; my $action = $self->{processor}->{action}; $action = "" if !defined $action; my $div; my $link; # Co-authored eprints: $div = $chunk->appendChild( $session->make_element( "div" ) ); $div->setAttribute( style => "font-weight: bold;" ) if $action eq "search_authored"; $link = $div->appendChild( $session->render_link( $base_url."&_action_search_authored=1" ) ); $link->appendChild( $session->html_phrase( "ref/select:search_authored_button" ) ); $div->appendChild( $session->make_text( " (" ) ); $link = $div->appendChild( $session->render_link( $base_url."&_action_search_authored=1&date=2008-" ) ); $link->appendChild( $session->make_text( "2008-" ) ); $div->appendChild( $session->make_text( ")" ) ); # Deposited eprints $div = $chunk->appendChild( $session->make_element( "div" ) ); $div->setAttribute( style => "font-weight: bold;" ) if $action eq "search_deposited"; $link = $div->appendChild( $session->render_link( $base_url."&_action_search_deposited=1" ) ); $link->appendChild( $session->html_phrase( "ref/select:search_deposited_button" ) ); $div->appendChild( $session->make_text( " (" ) ); $link = $div->appendChild( $session->render_link( $base_url."&_action_search_deposited=1&date=2008-" ) ); $link->appendChild( $session->make_text( "2008-" ) ); $div->appendChild( $session->make_text( ")" ) ); return $chunk; } sub render_search_form { my( $self ) = @_; my $chunk = $self->{session}->make_doc_fragment; return $chunk if !$self->can_select; #### Add some pre-defined searches #### $chunk->appendChild( $self->render_predefined_searches ); # the actual search form: $chunk->appendChild( $self->SUPER::render_search_form() ); return $chunk; } sub paginate_opts { my( $self ) = @_; my %opts = $self->SUPER::paginate_opts; my $action = $self->{processor}->{action}; if( $action eq "search_authored" || $action eq "search_deposited" ) { delete $opts{params}->{_action_search}; $opts{params}->{"_action_$action"} = 1; } return %opts; } # called 'internally' by AbstractSearch.pm sub render_result_row { my ( $self, $repo, $eprint, $searchexp, $n ) = @_; my $dataset = $self->{processor}->{dataset}; my $role = $self->{processor}->{role}; my $user = $repo->current_user; my $benchmark = $self->{processor}->{benchmark}; my $phraseid = "ref/select:selected_by"; my $tr = $repo->make_element( "tr" ); if( defined $n ) { my $td_n = $repo->make_element( "td" ); my $span = $repo->make_element( "span", "style"=>"font-weight:bold;" ); $span->appendChild( $repo->make_text( "$n." ) ); $td_n->appendChild( $span ); $tr->appendChild( $td_n ); } # Each row contains a citation... my $td_cite = $repo->make_element( "td" ); $tr->appendChild( $td_cite ); # Use citation style defined by search configuration $td_cite->appendChild( $eprint->render_citation_link( $searchexp->{citation} ) ); # ... a list of other users related to that item ... my $td_users = $repo->make_element( "td" ); my $already_selected = 0; my @names; $benchmark->eprint_selections( $eprint )->map(sub { my( undef, undef, $other ) = @_; my $user_id = $other->value( "user_id" ); if( $user_id == $role->id ) { $already_selected = 1; return; } my $user = $repo->user( $user_id ); if( defined $user ) { push @names, EPrints::Utils::tree_to_utf8( $user->render_description ); } else { push @names, $repo->phrase( "ref:unknown_user", id => $user_id ); } }); if( scalar( @names ) > 0 ) { $td_users->appendChild( $repo->html_phrase( $phraseid, names => $repo->make_text( join(", ", @names) ) ) ); } $tr->appendChild( $td_users ); # ... and an action button my $td_act = $repo->make_element( "td" ); if( !$already_selected ) { my $uri = URI->new( $repo->current_url( query => 1 ) ); $uri->query_form( screen => $self->{processor}->{screenid}, role => $role->id, user => $user->id, eprint => $eprint->id, _action_select => 1, params => $uri->query, ); my $button = $repo->make_element( "a", href => "$uri", onclick => "", ); $button->appendChild( $repo->html_phrase( "ref/select:add_button" ) ); $td_act->appendChild( $button ); } else { $td_act->appendChild( $repo->html_phrase( "ref/select:already_selected" ) ); } $tr->appendChild( $td_act ); return $tr; } sub render_export_bar { return shift->{session}->make_doc_fragment; } sub render_selections { my( $self ) = @_; my $repo = $self->{session}; my $processor = $self->{processor}; my $dataset = $processor->{dataset}; my $role = $processor->{role}; my $user = $repo->current_user; my $benchmark = $self->{processor}->{benchmark}; my $selections = $benchmark->user_selections( $role ); return $repo->html_phrase( "ref/select:none_selected" ) if $selections->count == 0; my $table = $repo->make_element( "table", class=>"ref_current_selections" ); my $n = 1; $selections->map(sub { my( undef, undef, $selection ) = @_; my $eprintid = $selection->value( 'eprint_id' ); my $eprint = $repo->dataset( "eprint" )->dataobj( $eprintid ); if( !defined $eprint ) { $repo->dataset( "eprint" )->make_dataobj( { id => $eprintid } ); } my @names; my $others = $repo->make_doc_fragment; $benchmark->eprint_selections( $eprint )->map(sub { my( undef, undef, $other ) = @_; my $user_id = $other->value( "user_id" ); if( $user_id == $role->id ) { return; } my $user = $repo->user( $user_id ); if( defined $user ) { push @names, EPrints::Utils::tree_to_utf8( $user->render_description ); } else { push @names, $repo->phrase( "ref:unknown_user", id => $user_id ); } }); if( scalar( @names ) > 0 ) { $others->appendChild( $repo->html_phrase( 'ref/select:also_selected_by', names => $repo->make_text( join(", ", @names) ) ) ); } my $uoaid = $selection->uoa( $benchmark ); my $uoa = $repo->dataset( "subject" )->dataobj( $uoaid ); if( !defined $uoa ) { $uoa = $repo->dataset( "subject" )->make_object( $repo, { subjectid => $uoaid } ); } my $actions = $repo->make_element( "ul", style => "margin: 0 0; padding: 0 0; list-style-type: none;", ); if( $self->can_select ) { my $li = $repo->make_element( "li" ); $actions->appendChild( $li ); my $uri = URI->new( $repo->current_url( query => 1 ) ); $uri->query_form( screen => $self->{processor}->{screenid}, selection => $selection->id, role => $role->id, _action_unselect => 1, params => $uri->query, ); my $link = $repo->render_link( "$uri" ); $link->appendChild( $repo->html_phrase( "ref/select:remove_button" ) ); $li->appendChild( $link ); # edit selection $li = $repo->make_element( "li" ); $actions->appendChild( $li ); $link = $repo->render_link( $selection->get_control_url ); $link->appendChild( $repo->html_phrase( "ref/select:qualify_button" ) ); $li->appendChild( $link ); # synchronise UoA if( $uoa->id ne $role->value( "ref_uoa" ) ) { $uri = URI->new( $repo->current_url( query => 1 ) ); $uri->query_form( screen => $self->{processor}->{screenid}, selection => $selection->id, role => $role->id, _action_sync => 1, params => $uri->query, ); $li = $repo->make_element( "li" ); $actions->appendChild( $li ); $link = $repo->render_link( "$uri" ); $link->appendChild( $self->html_phrase( "action:sync:title" ) ); $li->appendChild( $link ); } } $table->appendChild( $selection->render_citation( 'action', n => [ $n++, 'INTEGER' ], actions => [ $actions, 'XHTML' ], others => [ $others, 'XHTML' ], uoa => [ $uoa->render_description, 'XHTML' ], ) ); }); return $table; } sub render_results { my( $self ) = @_; my $chunk = $self->{session}->make_doc_fragment; return $chunk if !$self->can_select; #### Add some pre-defined searches #### $chunk->appendChild( $self->render_predefined_searches ); $chunk->appendChild( $self->SUPER::render_results ); return $chunk; } # sf2 - render(): # if no current exercise exists -> render a message (saying there's nothing to select against) # if an exercise exists -> render the selections + the name of the exercise + the search form sub render { my( $self ) = @_; my $repo = $self->{session}; my $frag = $repo->make_doc_fragment; # landed from another plugin but we still need our init for searching if( !defined $self->{processor}->{search} ) { delete $self->{processor}->{action}; $self->properties_from; $self->from; } # search form my $results; if( $self->{processor}->{results} ) { $results = $self->render_results; } else { $results = $self->render_search_form; } my %inserts; $inserts{benchmark} = $self->{processor}->{benchmark}->render_citation; $inserts{benchmarks} = $self->render_benchmarks( "ref:benchmarks_tools" ); $inserts{role} = $self->{processor}->{role}->render_citation( "ref" ); $inserts{roles} = $self->render_roles; $inserts{tools} = $self->render_tools; $inserts{selections} = $self->render_selections; $inserts{results} = $results; $inserts{messages} = $self->render_warnings; $frag->appendChild( $self->{processor}->{role}->render_citation( "ref_listing_page", can_select => $self->can_select, pindata => { inserts => \%inserts }, ) ); return $frag; } sub export { my( $self ) = @_; my $repo = $self->{session}; my $frag = $repo->make_doc_fragment; my $part = $repo->param( "part" ); $part = "" if !defined $part; my $f = "ajax_$part"; if( $self->can( $f ) ) { $frag->appendChild( $self->$f() ); } binmode(STDOUT, ":utf8" ); print $repo->xhtml->to_xhtml( $frag ); } 1;