| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package RapidApp::RootModule; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 6 |  |  | 6 |  | 44 | use Moose; | 
|  | 6 |  |  |  |  | 16 |  | 
|  | 6 |  |  |  |  | 42 |  | 
| 4 | 6 |  |  | 6 |  | 39772 | use RapidApp::Util qw(:all); | 
|  | 6 |  |  |  |  | 16 |  | 
|  | 6 |  |  |  |  | 6712 |  | 
| 5 |  |  |  |  |  |  | extends 'RapidApp::Module'; | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | require Module::Runtime; | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | =head1 NAME | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | RapidApp::RootModule; | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | RootModule adds a small amount of custom processing needed for the usual "root module". | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | =head1 METHODS | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | =head2 BUILD | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | RootModule enables the auto_viewport capability of Controller by default. | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | =cut | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | our @GLOBAL_INIT_CODEREFS = (); | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | has 'app_title', is => 'rw', isa => 'Str', default => 'RapidApp Application'; | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | has 'main_module_class', is => 'ro', isa => 'Maybe[Str]', lazy => 1, default => undef; | 
| 30 |  |  |  |  |  |  | has 'main_module_params', is => 'ro', isa => 'HashRef', lazy => 1, default => sub {{}}; | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | # default_module now 'main' by default: | 
| 33 |  |  |  |  |  |  | around 'BUILDARGS' => sub { | 
| 34 |  |  |  |  |  |  | my ($orig, $class, @args)= @_; | 
| 35 |  |  |  |  |  |  | my $params= $class->$orig(@args); | 
| 36 |  |  |  |  |  |  | $params->{default_module} ||= 'main'; | 
| 37 |  |  |  |  |  |  | $params->{module_name} ||= ''; | 
| 38 |  |  |  |  |  |  | return $params; | 
| 39 |  |  |  |  |  |  | }; | 
| 40 |  |  |  |  |  |  |  | 
| 41 |  |  |  |  |  |  | around 'apply_init_modules' => sub { | 
| 42 |  |  |  |  |  |  | my ($orig,$self,@args) = @_; | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  | # Make the root module instance available via global. We have to do it here so it is | 
| 45 |  |  |  |  |  |  | # available to submodules that are still loading. This is a hack which is currently | 
| 46 |  |  |  |  |  |  | # only used/needed in RapidApp::TableSpec::Role::DBIC::get_or_create_rapidapp_module() | 
| 47 |  |  |  |  |  |  | local $RapidApp::ROOT_MODULE_INSTANCE = $self; | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | $self->$orig(@args) | 
| 50 |  |  |  |  |  |  | }; | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | sub BUILD { | 
| 53 | 4 |  |  | 4 | 1 | 18 | my $self= shift; | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | # Execute arbitrary code setup earlier in the init process that needs | 
| 56 |  |  |  |  |  |  | # to be called after the RapidApp Module tree has been loaded | 
| 57 |  |  |  |  |  |  | # See RapidApp::Util::rapidapp_add_global_init_coderef() for more info | 
| 58 | 4 |  |  |  |  | 18 | foreach my $coderef (@RapidApp::RootModule::GLOBAL_INIT_CODEREFS) { | 
| 59 | 0 |  |  |  |  | 0 | $coderef->($self); | 
| 60 |  |  |  |  |  |  | } | 
| 61 |  |  |  |  |  |  |  | 
| 62 | 4 |  |  |  |  | 174 | $self->auto_viewport(1); | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | ## --- | 
| 65 |  |  |  |  |  |  | ## NEW: optional auto initialization of the 'main' Module | 
| 66 | 4 | 50 |  |  |  | 146 | if($self->main_module_class) { | 
| 67 | 4 |  |  |  |  | 116 | Module::Runtime::require_module($self->main_module_class); | 
| 68 | 4 |  |  |  |  | 159 | $self->apply_init_modules( | 
| 69 |  |  |  |  |  |  | main => { | 
| 70 |  |  |  |  |  |  | class => $self->main_module_class, | 
| 71 |  |  |  |  |  |  | params => $self->main_module_params | 
| 72 |  |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  | ); | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  | ## | 
| 76 |  |  |  |  |  |  | ## --- | 
| 77 |  |  |  |  |  |  | } | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | # Another ugly hack, added to make it easier to hook/wrap the top Controller. | 
| 80 |  |  |  |  |  |  | # Does nothing but call the original by default, but can be changed. | 
| 81 |  |  |  |  |  |  | # (Added for Plugin::AuthCore) | 
| 82 |  |  |  |  |  |  | has '_around_Controller', is => 'rw', isa => 'CodeRef', default => sub { sub { | 
| 83 |  |  |  |  |  |  | my ($orig,$self,@args) = @_; | 
| 84 |  |  |  |  |  |  | return $self->$orig(@args); | 
| 85 |  |  |  |  |  |  | }}; | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | around 'Controller' => sub { | 
| 88 |  |  |  |  |  |  | my ($orig,$self,@a) = @_; | 
| 89 |  |  |  |  |  |  | my $c = $self->c; | 
| 90 |  |  |  |  |  |  | my $config = $c->config->{'Model::RapidApp'}; | 
| 91 |  |  |  |  |  |  |  | 
| 92 |  |  |  |  |  |  | $c->stash->{title} = $self->app_title; | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | # Also ugly - double-nested around. We're doing it this way because we | 
| 95 |  |  |  |  |  |  | # want the '_around_Controller' to take priority over this code, which | 
| 96 |  |  |  |  |  |  | # still takes priority over the original. | 
| 97 |  |  |  |  |  |  | return $self->_around_Controller->(sub { | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | # ----------- | 
| 100 |  |  |  |  |  |  | # The special handling below only applies when we're deployed at the root | 
| 101 |  |  |  |  |  |  | # namespace of the app. If not, skip it and return now with default handling: | 
| 102 |  |  |  |  |  |  | return $self->$orig(@a) unless ($c->module_root_namespace eq ''); | 
| 103 |  |  |  |  |  |  | # ----------- | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | my $args = $c->req->arguments; | 
| 106 |  |  |  |  |  |  | my ($opt) = @$args; | 
| 107 |  |  |  |  |  |  |  | 
| 108 |  |  |  |  |  |  | # SPECIAL HANDLING FOR ROOT ('/') REQUEST: | 
| 109 |  |  |  |  |  |  | return $self->content unless ($opt || !$c->can('session') || ( | 
| 110 |  |  |  |  |  |  | $c->can('session') && $c->session && | 
| 111 |  |  |  |  |  |  | $c->session->{RapidApp_username} | 
| 112 |  |  |  |  |  |  | )); | 
| 113 |  |  |  |  |  |  |  | 
| 114 |  |  |  |  |  |  | return $self->$orig(@a) unless ( | 
| 115 |  |  |  |  |  |  | $opt && !$self->has_subarg($opt) && | 
| 116 |  |  |  |  |  |  | $config->{root_template_prefix} | 
| 117 |  |  |  |  |  |  | ); | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | return $c->template_dispatcher->default($c,@$args); | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | return $self->$orig(@a); | 
| 122 |  |  |  |  |  |  | },$self,@a); | 
| 123 |  |  |  |  |  |  | }; | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  | # build a HTML viewport for the ExtJS content | 
| 126 |  |  |  |  |  |  | # we override the config_url and the title | 
| 127 |  |  |  |  |  |  | sub viewport { | 
| 128 | 1 |  |  | 1 | 0 | 3 | my $self= shift; | 
| 129 | 1 |  |  |  |  | 10 | my $ret= $self->SUPER::viewport; | 
| 130 | 1 |  |  |  |  | 108 | $self->c->stash->{config_url} = $self->base_url . '/' . $self->default_module; | 
| 131 | 1 |  |  |  |  | 79 | return $ret; | 
| 132 |  |  |  |  |  |  | }; | 
| 133 |  |  |  |  |  |  |  | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | # NEW: handle root ('/') request with a template instead of error: | 
| 136 |  |  |  |  |  |  | sub content { | 
| 137 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 138 | 0 |  |  |  |  |  | my $c = $self->c; | 
| 139 | 0 |  |  |  |  |  | return $c->template_dispatcher->default($c); | 
| 140 |  |  |  |  |  |  | } | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  |  | 
| 143 | 6 |  |  | 6 |  | 51 | no Moose; | 
|  | 6 |  |  |  |  | 14 |  | 
|  | 6 |  |  |  |  | 35 |  | 
| 144 |  |  |  |  |  |  | __PACKAGE__->meta->make_immutable; | 
| 145 |  |  |  |  |  |  | 1; |