Error in Include(/www/htdocs/nge/dispatcher.html):
Can't call method "region_name" on an undefined value at /www/lib/perl/NatGeo/Expeditions/Widget/Breadcrumbs.pm line 261.

[    1]    1: package NatGeo::Expeditions::Widget::Breadcrumbs;
[    2]    2: use strict;
[    3]    3: use vars qw(@ISA);
[    4]    4: use NatGeo::Expeditions::Widget;
[    5]    5: use NatGeo::Expeditions::Utils;
[    6]    6: use NatGeo::Expeditions::Model::Sweepstakes;
[    7]    7: use Data::Dumper;
[    8]    8: 
[    9]    9: @ISA = qw(NatGeo::Expeditions::Widget);
[   10]   10: 
[   11]   11: sub initialize {
[   12]   12:     my $self = shift;
[   13]   13:     my @crumbs;
[   14]   14: 
[   15]   15:     # take the contents of the URL straight-up for starters, assigning the url and label for each piece to be what was in the url
[   16]   16:     foreach(split '/', $self->{request}->{_page}->{real_path}) {
[   17]   17:         push @crumbs, {url => $_, label => $_};
[   18]   18:     }
[   19]   19: 
[   20]   20:     # if the last piece of the breadcrumb is a number, assume it's a pagination piece and change the label to be Page XX
[   21]   21:     if($crumbs[(scalar @crumbs -1 )]->{url} =~ /^(\d+)$/) {
[   22]   22:         $crumbs[(scalar @crumbs -1 )]->{label} = "Page ".$1;
[   23]   23:     }
[   24]   24: 
[   25]   25:     # the bread crumbs. its you. you are the crumbs.
[   26]   26:     if($self->{override}->[0]) {
[   27]   27:         undef @crumbs;
[   28]   28:         foreach my $r (@{$self->{override}->[0]->{link}}) {
[   29]   29:             push @crumbs, {label => $r->{label}, url => $r->{url}};
[   30]   30:         }
[   31]   31:     # munge the breadcrumb for an expert listing
[   32]   32:     } elsif($crumbs[0]->{url} eq 'photocontest') {
[   33]   33:         $crumbs[0]->{label} = 'Photo Contest';
[   34]   34:         $crumbs[0]->{url} = 'photocontest';
[   35]   35:         if($crumbs[1]->{label} eq 'entryform') { 
[   36]   36:             $crumbs[1]->{label} = 'Entry Form';
[   37]   37:         }
[   38]   38:     } elsif($crumbs[0]->{url} eq 'privatejourneys') {
[   39]   39:         $crumbs[0]->{label} = 'Private Journeys';
[   40]   40:         $crumbs[0]->{url} = 'privatejourneys';
[   41]   41:     } elsif($crumbs[0]->{url} eq 'experts' && !$crumbs[1]) {
[   42]   42:         $crumbs[1]->{label} = 'Featured';
[   43]   43:         $crumbs[1]->{url} = '';
[   44]   44:     } elsif($crumbs[0]->{url} eq 'experts' && $crumbs[1]->{url} =~ /^(destination|specialty)$/) {
[   45]   45:         $crumbs[2]->{label} = $self->get_region_label($crumbs[2]->{url}) 
[   46]   46:          if($crumbs[1]->{url} eq 'destination');
[   47]   47:         $crumbs[2]->{label} = $self->get_specialty_label($crumbs[2]->{url}) 
[   48]   48:          if($crumbs[1]->{url} eq 'specialty');
[   49]   49:     } elsif($crumbs[0]->{url} eq 'experts' && $crumbs[1]->{url} =~ /^(\d+)$/ && $crumbs[2]) {
[   50]   50:         my $expert = NatGeo::Expeditions::Model::Expert->fetch($1);
[   51]   51:         $crumbs[1]->{label} = $expert->full_name;
[   52]   52:         $crumbs[1]->{url} .= '/detail';
[   53]   53:         $crumbs[2]->{url} = '';
[   54]   54:         if($crumbs[2]->{label} eq 'fieldnote') { 
[   55]   55:             my $note = NatGeo::Expeditions::Model::FieldNote->search(
[   56]   56:                 where => 'field_note_id = ?',
[   57]   57:                 execargs => [$crumbs[3]->{url}] 
[   58]   58:             );
[   59]   59: 
[   60]   60:             $crumbs[2]->{label} = 'Field Note';
[   61]   61:             $crumbs[3]->{label} = $note->title;
[   62]   62: 
[   63]   63:             $crumbs[2]->{url} = 'fieldnote/'.$crumbs[3]->{url};
[   64]   64:             $crumbs[3]->{url} = '';
[   65]   65:         }
[   66]   66: 
[   67]   67:     # munge the breadcrumb for a triptypes page, by using the description of the triptype as the second-level label
[   68]   68:     } elsif($crumbs[0]->{url} eq 'triptypes') {
[   69]   69:         if ($crumbs[1]) {
[   70]   70:             $crumbs[1]->{label} = $self->get_triptype_label($crumbs[1]->{url});
[   71]   71:         }
[   72]   72:         $crumbs[0]->{label} = 'Trip Types';
[   73]   73: 
[   74]   74:     # munge the breadcrumb for a destinations page, by using the region name of the destination as the second-level label
[   75]   75:     } elsif($crumbs[0]->{url} eq 'destinations' && $crumbs[1]) {
[   76]   76:         $crumbs[1]->{label} = $self->get_region_label($crumbs[1]->{url});
[   77]   77: 
[   78]   78:     # munge the breadcrumb for an expeditions page, by using the full name of the expedition as the second-level label
[   79]   79:     # also splice in a link to the region/triptype, based on the referer and/or current associated regions/triptypes
[   80]   80:     } elsif($crumbs[0]->{url} eq 'expeditions' && $crumbs[1]) {
[   81]   81: 
[   82]   82:         my $expedition = NatGeo::Expeditions::Model::Expedition->search_deep(
[   83]   83:             where => 'link_text = ?',
[   84]   84:             execargs => [$crumbs[1]->{url}],
[   85]   85:         );
[   86]   86:         $crumbs[1]->{label} = $expedition->expedition_name;
[   87]   87: 
[   88]   88:         if ($crumbs[2]->{label} =~ /fieldnote/i) {
[   89]   89:             $crumbs[2]->{label} = 'Field Notes';
[   90]   90:         }
[   91]   91: 
[   92]   92:         if ($crumbs[2]->{label} =~ /experts/i) {
[   93]   93:             my $counts = NatGeo::Expeditions::Utils::magical_counting_query($expedition->link_text);
[   94]   94:             $crumbs[2]->{label} = 'Expedition Team' if ($counts->{is_team});
[   95]   95:         }
[   96]   96: 
[   97]   97:         # Build the level-1 cache dynamic bit.  Need to dynamically check the REFERER so we can splice in the
[   98]   98:         # appropriate bits to the breadcrumb, and/or one of the regions the expedition is already associated to.
[   99]   99:         my $dynamic_breadcrumb = q|<[%
[  100]  100: use NatGeo::Expeditions::Model::Expedition;
[  101]  101: use NatGeo::Expeditions::Model::Region;
[  102]  102: use NatGeo::Expeditions::Model::Triptype;
[  103]  103: use Cheetah::Page;
[  104]  104: use NatGeo::Expeditions::Request;
[  105]  105: 
[  106]  106: # Unfortunately have to replicate this code here for level-1 caching
[  107]  107: my @crumbs;
[  108]  108: my $page = Cheetah::Page->new;
[  109]  109: foreach(split '/', $page->{request}->{_page}->{real_path}) {
[  110]  110:     push @crumbs, {url => $_, label => $_};
[  111]  111: }
[  112]  112: 
[  113]  113: my $REFERER = $main::Request->ServerVariables('REFERER');
[  114]  114: 
[  115]  115: my @splice;
[  116]  116: 
[  117]  117: # User came from a specific destinations page, so use that
[  118]  118: if ($REFERER =~ /destinations\/([^\/\?]+)/) {
[  119]  119:     my $region = NatGeo::Expeditions::Model::Region->search(
[  120]  120:         where => qq{lower(regexp_replace(region_name, '[^a-zA-Z]', '', 'g')) = ?},
[  121]  121:         execargs => [$1]
[  122]  122:     );
[  123]  123:     push @splice, { url => $page->url_base . "/destinations", label => "Destinations" };
[  124]  124:     push @splice, { url => $page->url_base . "/destinations/$1", label => $region->region_name };
[  125]  125: }
[  126]  126: 
[  127]  127: # User came from a specific triptypes page, so use that
[  128]  128: elsif ($REFERER =~ /triptypes\/([^\/\?]+)/) {
[  129]  129:     my $triptype = NatGeo::Expeditions::Model::Triptype->search(
[  130]  130:         where => qq{lower(regexp_replace(description, '[^a-zA-Z]', '', 'g')) = ?},
[  131]  131:         execargs => [$1]
[  132]  132:     );
[  133]  133:     push @splice, { url => $page->url_base . "/triptypes", label => "Trip Type" };
[  134]  134:     push @splice, { url => $page->url_base . "/triptypes/$1", label => $triptype->description };
[  135]  135: }
[  136]  136: 
[  137]  137: # User came from somewhere else, so determine the first associated region by alphabetical order, and use that
[  138]  138: else {
[  139]  139:     my $expedition = NatGeo::Expeditions::Model::Expedition->search_deep(
[  140]  140:         where => 'link_text = ?',
[  141]  141:         execargs => [$crumbs[1]->{url}],
[  142]  142:         with => {
[  143]  143:             regions => {}
[  144]  144:         }
[  145]  145:     );
[  146]  146:     my $region = (sort { $a->region_name cmp $b->region_name } $expedition->regions->all)[0];
[  147]  147:     my $region_safe = $region->region_name;
[  148]  148:     $region_safe =~ s/[^a-zA-Z]//g; # make url safe
[  149]  149:     push @splice, { url => $page->url_base . "/destinations", label => "Destinations" };
[  150]  150:     push @splice, { url => $page->url_base . '/destinations/' . lc($region_safe), label => $region->region_name };
[  151]  151: }
[  152]  152: 
[  153]  153: foreach my $splice (@splice) {
[  154]  154:     print qq{ &raquo; <a href="} . $splice->{url} . qq{">} . $splice->{label} . qq{</a>};
[  155]  155: }
[  156]  156: %]>|;
[  157]  157: 
[  158]  158:         $crumbs[1]->{url} = "expeditions/" . $crumbs[1]->{url};
[  159]  159:         @crumbs = ({ code => $dynamic_breadcrumb, external => 1 }, @crumbs[1 .. (scalar(@crumbs)-1)]);
[  160]  160: 
[  161]  161:     # This is it. This is the worst hack. I'm so sorry.
[  162]  162:     } elsif($self->{request}->{_page}->{real_path} =~ /^about\/lindblad\/ship\/(\d+)/) {
[  163]  163:         my $ship = NatGeo::Expeditions::Model::Ship->fetch($1);
[  164]  164:         @crumbs = (
[  165]  165:             {url => 'about', label => 'About'},
[  166]  166:             {url => 'lindblad', label => 'Our Alliance with Lindblad Expeditions'},
[  167]  167:             {url => '', label => 'Our Ships'},
[  168]  168:             {url => 'ship/'.$ship->ship_id, label => $ship->ship_name},
[  169]  169:         ); 
[  170]  170:     # munge the breadcrumb for a static page, by using the title of the data page as the second-level label
[  171]  171:     } elsif($crumbs[0]->{url} =~ /^(about|information)$/ && $crumbs[1]) {
[  172]  172:         my $path = '/'.$self->{request}->{_page}->{real_path};
[  173]  173:         if($path =~ /\/confirm$/i) { # Hack for confirmation pages.
[  174]  174:             $path =~ s/\/confirm$//i;
[  175]  175:             pop @crumbs;
[  176]  176:         }
[  177]  177:         $self->__load('templates/'.$crumbs[0]->{url}.'_pages.xml');
[  178]  178:         foreach(@{$self->{data}->{_data}->{link}}) {
[  179]  179:             if($_->{url} eq $path) {
[  180]  180:                 $crumbs[1]->{label} = $_->{title};
[  181]  181:             }
[  182]  182:         }
[  183]  183: 
[  184]  184:         if (($crumbs[1]->{url} eq 'terms') && ($crumbs[2])) {
[  185]  185:             $crumbs[2]->{label} = $self->get_tc_label($crumbs[2]->{url});
[  186]  186:         }
[  187]  187: 
[  188]  188:         if ($crumbs[1]->{url} eq 'specialoffers') {
[  189]  189:             $crumbs[1]->{label} = 'Special Offers';
[  190]  190:         }
[  191]  191: 
[  192]  192:     # munge the breadcrumb for a sweepstakes page
[  193]  193:     } elsif ($crumbs[0]->{url} =~ /^sweepstakes$/ && $crumbs[1]) {
[  194]  194:         my $sweepstakes = NatGeo::Expeditions::Model::Sweepstakes->search_deep(
[  195]  195:             name => $crumbs[1]->{label}
[  196]  196:         );
[  197]  197:         if ($sweepstakes) {
[  198]  198:             $crumbs[1]->{label} = $sweepstakes->breadcrumb_name;
[  199]  199:         }
[  200]  200: 
[  201]  201:     # hack to kill the breadcrumb for sso pages, apparently
[  202]  202:     } elsif($crumbs[0]->{url} =~ /^sso$/) {
[  203]  203:         @crumbs = ();
[  204]  204:     }
[  205]  205: 
[  206]  206:     @{$self->{crumbs}} = @crumbs;
[  207]  207: 
[  208]  208:     return;
[  209]  209: }
[  210]  210: 
[  211]  211: sub render {
[  212]  212:     my $self = shift;
[  213]  213:     my $rv;
[  214]  214:     my $path;
[  215]  215: 
[  216]  216:     # ALL breadcrumbs start with a Home link.    
[  217]  217:     $rv .= '<div id="breadcrumb"><a href="'.$self->url_base.'/home" class="selected">Home</a>';
[  218]  218: 
[  219]  219:     foreach my $crumb (@{$self->{crumbs}}) {
[  220]  220:         my $label = $crumb->{label};
[  221]  221:         my $url = $crumb->{url};
[  222]  222:         $label = join ' ', map {ucfirst($_) } split '_', $label;
[  223]  223: 
[  224]  224:         # "external" tells the breadcrumb render to skip this element in the chain, and instead render a dynamic, level-1 cached bit
[  225]  225:         if ($crumb->{external}) {
[  226]  226:             $rv .= $crumb->{code};
[  227]  227:         }
[  228]  228: 
[  229]  229:         # ... otherwise, proceed as normal, building the path and fleshing out the breadcrumb.
[  230]  230:         else {
[  231]  231:             $path .= "/$url" if $url;
[  232]  232: 
[  233]  233:             # Yes, this is a hack, but I don't see any way around it.
[  234]  234:             # For an expedition, if we're missing the /detail on the end, we add it via rewrite rule.  But we can't do this for
[  235]  235:             # experts, because /experts/1 isn't expert_id = 1, it's the first page of the expert listing.  So no matter which
[  236]  236:             # method is used, some part of the breadcrumb breaks.  Solution is to hack it away.
[  237]  237:             $path =~ s/detail\/fieldnote/fieldnote/;
[  238]  238: 
[  239]  239:             $rv .= " &raquo; ";
[  240]  240:             if($path =~ /^\/experts\/(destination|last_name|specialty)$/) {
[  241]  241:                 $rv .= "<a href='#'>$label</a>\n";
[  242]  242:             } else {
[  243]  243:                 $rv .= "<a href='".$self->url_base."$path'>$label</a>\n";
[  244]  244:             }
[  245]  245:         }
[  246]  246:     }
[  247]  247: 
[  248]  248:     $rv .= "</div>\n";
[  249]  249: 
[  250]  250:     return $rv;
[  251]  251: }
[  252]  252: 
[  253]  253: sub get_region_label {
[  254]  254:     my $self = shift;
[  255]  255:     my $url = shift;
[  256]  256: 
[  257]  257:     my $region = NatGeo::Expeditions::Model::Region->search(
[  258]  258:         where => 'make_url_safe(region_name) = ?',
[  259]  259:         execargs => [$url]
[  260]  260:     );
[* 261]  261:     return $region->region_name;
[  262]  262: }
[  263]  263: 
[  264]  264: sub get_specialty_label {
[  265]  265:     my $self = shift;
[  266]  266:     my $url = shift;
[  267]  267: 
[  268]  268:     my $specialty = NatGeo::Expeditions::Model::Specialty->search(
[  269]  269:         where => 'make_url_safe(description) = ?',
[  270]  270:         execargs => [$url]
[  271]  271:     );
[  272]  272:     return $specialty->description;
[  273]  273: }
[  274]  274: 
[  275]  275: sub get_triptype_label {
[  276]  276:     my $self = shift;
[  277]  277:     my $url = shift;
[  278]  278: 
[  279]  279:     my $triptype = NatGeo::Expeditions::Model::Triptype->search(
[  280]  280:         where => 'make_url_safe(description) = ?',
[  281]  281:         execargs => [$url]
[  282]  282:     );
[  283]  283:     return $triptype->description;
[  284]  284: }
[  285]  285: 
[  286]  286: sub get_tc_label {
[  287]  287:     my $self = shift;
[  288]  288:     my $url = shift;
[  289]  289: 
[  290]  290:     if($url =~ /^\d+/) {
[  291]  291:         my $tc = NatGeo::Expeditions::Model::Expedition->search($url);
[  292]  292:         return $tc->expedition_name;
[  293]  293:     } else {
[  294]  294:         my $tc = NatGeo::Expeditions::Model::Triptype->search(
[  295]  295:             where    => 'make_url_safe(description) = ?',
[  296]  296:             execargs => [$url]
[  297]  297:         );
[  298]  298:         return $tc->description;
[  299]  299:     } 
[  300]  300: }
[  301]  301: 
[  302]  302: 1;