clean
[sgn.git] / lib / SGN / Controller / Locus.pm
blobb41b644946babf417b147dcd59c5a83648f8c6df
1 package SGN::Controller::Locus;
3 =head1 NAME
5 SGN::Controller::Locus - Catalyst controller for the locus page
6 (replacing the old cgi script)
8 =cut
10 use Moose;
11 use namespace::autoclean;
13 use URI::FromHash 'uri';
15 use CXGN::Phenome::Locus;
16 use CXGN::Phenome::Schema;
17 use CXGN::Tools::Organism;
18 use CXGN::Phenome::Locus::LinkageGroup;
20 BEGIN { extends 'Catalyst::Controller' }
21 with 'Catalyst::Component::ApplicationAttribute';
24 has 'schema' => (
25 is => 'rw',
26 isa => 'DBIx::Class::Schema',
27 lazy_build => 1,
32 sub locus_search : Path('/search/locus') Args(0) {
33 my $self = shift;
34 my $c = shift;
35 my ($organism_names_ref, $organism_ids_ref)=CXGN::Tools::Organism::get_existing_organisms( $c->dbc->dbh);
37 unshift @$organism_names_ref, '';
38 unshift @$organism_ids_ref, '';
39 my @organism_ref;
40 my $index;
41 for my $id ( @$organism_ids_ref ) {
42 push( @organism_ref, [$id, $organism_names_ref->[$index]] );
43 $index++;
45 my $lg_names_ref = CXGN::Phenome::Locus::LinkageGroup::get_all_lgs( $c->dbc->dbh );
46 $c->stash(
47 template => '/search/loci.mas',
48 organism_ref => \@organism_ref,
49 lg_names_ref => $lg_names_ref,
55 sub _build_schema {
56 shift->_app->dbic_schema( 'CXGN::Phenome::Schema' )
60 =head2 new_locus
62 Public path: /locus/0/new
64 Create a new locus.
66 Chained off of L</get_locus> below.
68 =cut
70 sub new_locus : Chained('get_locus') PathPart('new') Args(0) {
71 my ( $self, $c ) = @_;
72 $c->stash(
73 template => '/locus/index.mas',
75 locusref => {
76 action => "new",
77 locus_id => 0 ,
78 locus => $c->stash->{locus},
79 schema => $self->schema,
85 sub view_by_name : Path('/locus/view/') Args(0) {
87 my ($self, $c) = @_;
89 my $symbol = $c->req->param("symbol");
90 my $locusname = $c->req->param("locus");
91 my $species = $c->req->param("species");
93 my $locus_id = undef;
94 my $locus = undef;
95 if ($symbol && $species) {
96 $locus = $c->stash->{locus} = CXGN::Phenome::Locus->new_with_symbol_and_species($c->dbc->dbh, $symbol, $species);
99 if ($locusname) {
100 $locus = $c->stash->{locus} = CXGN::Phenome::Locus->new_with_locusname($c->dbc->dbh, $locusname);
103 if (defined($locus->get_locus_id())) {
104 my $locus_id = $locus->get_locus_id();
105 $c->stash->{locus} = $locus;
106 $c->detach("/locus/view/", [ $locus_id] ); #("/locus/$locus_id/view");
108 else {
109 $c->stash->{template} = 'generic_message.mas';
110 $c->stash->{message} = "No locus was found for the identifier provided ($symbol $locusname $species).";
111 # forward to search page ?
118 =head2 view_locus
120 Public path: /locus/<locus_id>/view
122 View a locus detail page.
124 Chained off of L</get_locus> below.
126 =cut
128 sub view_locus : Chained('get_locus') PathPart('view') Args(0) {
129 my ( $self, $c, $action) = @_;
130 my $locus = $c->stash->{locus};
131 if( $locus ) {
132 $c->forward('get_locus_extended_info');
135 my $logged_user = $c->user;
136 my $person_id = $logged_user->get_object->get_sp_person_id if $logged_user;
137 my $curator = $logged_user->check_roles('curator') if $logged_user;
138 my $submitter = $logged_user->check_roles('submitter') if $logged_user;
139 my $sequencer = $logged_user->check_roles('sequencer') if $logged_user;
140 my $dbh = $c->dbc->dbh;
142 my $trait_db_name => $c->get_conf('trait_ontology_db_name');
143 ##################
145 ###Check if a locus page can be printed###
146 my $locus_id = $locus ? $locus->get_locus_id : undef ;
148 print STDERR "LOCUS_ID: $locus_id ACTION: $action\n\n";
150 # print message if locus_id is not valid
151 unless ( ( $locus_id =~ m /^\d+$/ ) || ($action eq 'new' && !$locus_id) ) {
152 $c->throw_404( "No locus exists for that identifier." );
154 unless ( $locus || !$locus_id && $action && $action eq 'new' ) {
155 $c->throw_404( "No locus exists for that identifier." );
158 # print message if the locus is obsolete
159 my $obsolete = $locus->get_obsolete();
160 if ( $obsolete eq 't' && !$curator ) {
161 $c->throw(is_client_error => 0,
162 title => 'Obsolete locus',
163 message => "Locus $locus_id is obsolete!",
164 developer_message => 'only curators can see obsolete loci',
165 notify => 0, #< does not send an error email
170 # print message if locus_id does not exist
171 if ( !$locus && $action ne 'new' && $action ne 'store' ) {
172 $c->throw_404('No locus exists for this identifier');
175 ####################
176 my $is_owner;
177 my $owner_ids = $c->stash->{owner_ids} || [] ;
178 if ( $locus && ($curator || $person_id && ( grep /^$person_id$/, @$owner_ids ) ) ) {
179 $is_owner = 1;
181 my $dbxrefs = $locus->get_dbxrefs;
182 my $image_ids = $locus->get_figure_ids;
183 my $cview_tmp_dir = $c->tempfiles_subdir('cview');
185 #########
186 my @locus_xrefs =
187 # 4. look up xrefs for all of them
188 map $c->feature_xrefs( $_, { exclude => 'locuspages' } ),
189 # 3. plus primary locus name
190 $locus->get_locus_name,
191 # 2. list of locus alias strings
192 map $_->get_locus_alias,
193 # 1. list of locus alias objects
194 $locus->get_locus_aliases( 'f', 'f' );
195 #########
196 my ($feature, $src_feature) = $locus->get_src_feature;
197 ################
198 $c->stash(
199 template => '/locus/index.mas',
200 locusref => {
201 action => $action,
202 locus_id => $locus_id ,
203 curator => $curator,
204 submitter => $submitter,
205 sequencer => $sequencer,
206 person_id => $person_id,
207 user => $logged_user,
208 locus => $locus,
209 dbh => $dbh,
210 is_owner => $is_owner,
211 owners => $owner_ids,
212 dbxrefs => $dbxrefs,
213 cview_tmp_dir => $cview_tmp_dir,
214 cview_basepath => $c->get_conf('basepath'),
215 image_ids => $image_ids,
216 xrefs => \@locus_xrefs,
217 trait_db_name => $trait_db_name,
218 feature => $feature,
219 src_feature => $src_feature,
221 locus_add_uri => $c->uri_for( '/ajax/locus/associate_locus' )->relative(),
222 cvterm_add_uri => $c->uri_for( '/ajax/locus/associate_ontology')->relative(),
223 assign_owner_uri => $c->uri_for( '/ajax/locus/assign_owner' )->relative(),
228 =head1 PRIVATE ACTIONS
230 =head2 get_locus
232 Chain root for fetching a locus object to operate on.
234 Path part: /locus/<locus_id>
236 =cut
238 sub get_locus : Chained('/') PathPart('locus') CaptureArgs(1) {
239 my ($self, $c, $locus_id) = @_;
241 my $identifier_type = $c->stash->{identifier_type}
242 || $locus_id =~ /[^-\d]/ ? 'locus' : 'locus_id';
244 if( $identifier_type eq 'locus_id' ) {
245 if ( $locus_id == 0 ) {
246 $c->stash->{locus} = CXGN::Phenome::Locus->new($c->dbc->dbh);
247 return 1;
248 } elsif ( $locus_id < 0 ) {
249 $c->throw_client_error( public_message => 'Locus ID must be a positive integer.' );
252 $locus_id =~ s/(.*)(\.\d+)/$1/ ;
253 my $matching_loci = $self->schema->resultset('Locus')->search(
255 $identifier_type => $locus_id,
256 obsolete => 'f'
257 } );
259 if( $matching_loci->count > 1 ) {
260 $c->throw_client_error( public_message => 'Multiple matching loci' );
263 my ( $locus ) = $matching_loci->all
264 or $c->throw_404( "Locus not found" );
265 my $found_locus_id = $locus->locus_id;
267 $c->stash->{locus} = CXGN::Phenome::Locus->new($c->dbc->dbh, $found_locus_id);
270 return 1;
276 sub get_locus_owner_ids : Private {
277 my ( $self, $c ) = @_;
278 my $locus = $c->stash->{locus};
279 my @owner_ids = $locus ? $locus->get_owners : ();
280 $c->stash->{owner_ids} = \@owner_ids;
283 sub get_locus_owner_objects : Private {
284 my ( $self, $c ) = @_;
285 my $locus = $c->stash->{locus};
286 my $owner_objects = $locus ? $locus->get_owners(1) : ();
287 $c->stash->{owner_objects} = $owner_objects;
290 sub get_locus_extended_info : Private {
291 my ( $self, $c ) = @_;
292 $c->forward('get_locus_owner_ids');
297 #add the locus_dbxrefs to the stash.
298 sub get_locus_dbxrefs : Private {
299 my ( $self, $c ) = @_;
300 my $locus = $c->stash->{locus};
301 my $locus_dbxrefs = $locus->get_dbxrefs;
302 $c->stash->{locus_dbxrefs} = $locus_dbxrefs;
305 __PACKAGE__->meta->make_immutable;