- my $r = bless { config => $class->config }, $class;
- $r->get_request();
- $r->parse_location();
-
- $r->model_class($r->config->{model}->class_of($r, $r->{table}));
- my $status = $r->is_applicable;
- if ($status == OK) {
- $status = $r->call_authenticate;
- return $status unless $status == OK;
- $r->additional_data();
-
- $r->model_class->process($r);
- } else {
- # Otherwise, it's just a plain template.
- delete $r->{model_class};
- $r->{path} =~ s{/}{}; # De-absolutify
- $r->template($r->{path});
+
+ # Create the request object
+ my $r = bless {
+ template_args => {},
+ config => $class->config
+ }, $class;
+
+ $r->headers_out(Maypole::Headers->new);
+
+ $r->get_request($req);
+
+ $r->parse_location;
+
+ my $status = $r->handler_guts;
+
+ # moving this here causes unit test failures - need to check why
+ # before committing the move
+ #$status = $r->__call_process_view unless $r->output;
+
+ return $status unless $status == OK;
+
+ $r->send_output;
+
+ return $status;
+}
+
+# The root of all evil
+sub handler_guts
+{
+ my ($r) = @_;
+
+ $r->__load_model;
+
+ my $applicable = __to_boolean $r->is_applicable;
+
+ $r->__setup_plain_template unless $applicable;
+
+ # We authenticate every request, needed for proper session management
+ my $status;
+
+ eval { $status = $r->call_authenticate };
+
+ if ( my $error = $@ )
+ {
+ $status = $r->call_exception($error);
+
+ if ( $status != OK )
+ {
+ warn "caught authenticate error: $error";
+ return $r->debug ? $r->view_object->error($r, $error) : ERROR;
+ }
+ }
+
+ if ( $r->debug and $status != OK and $status != DECLINED )
+ {
+ $r->view_object->error( $r,
+ "Got unexpected status $status from calling authentication" );
+ }
+
+ return $status unless $status == OK;
+
+ # We run additional_data for every request
+ $r->additional_data;
+
+ if ($applicable)
+ {
+ eval { $r->model_class->process($r) };
+
+ if ( my $error = $@ )
+ {
+ $status = $r->call_exception($error);
+
+ if ( $status != OK )
+ {
+ warn "caught model error: $error";
+ return $r->debug ? $r->view_object->error($r, $error) : ERROR;
+ }
+ }
+ }
+
+ # unusual path - perhaps output has been set to an error message
+ return OK if $r->output;
+
+ # normal path - no output has been generated yet
+ return $r->__call_process_view;
+}
+
+# is_applicable() returned false, so set up a plain template. Model processing
+# will be skipped, but need to remove the model anyway so the template can't
+# access it.
+sub __setup_plain_template
+{
+ my ($r) = @_;
+
+ # It's just a plain template
+ $r->model_class(undef);
+
+ my $path = $r->path;
+ $path =~ s{/$}{}; # De-absolutify
+ $r->path($path);
+
+ $r->template($r->path);
+}
+
+# The model has been processed or skipped (if is_applicable returned false),
+# any exceptions have been handled, and there's no content in $r->output
+sub __call_process_view
+{
+ my ($r) = @_;
+
+ my $status;
+
+ eval { $status = $r->view_object->process($r) };
+
+ if ( my $error = $@ )
+ {
+ $status = $r->call_exception($error);
+
+ if ( $status != OK )
+ {
+ warn "caught view error: $error" if $r->debug;
+ return $r->debug ? $r->view_object->error($r, $error) : ERROR;
+ }