Ark
view release on metacpan or search on metacpan
lib/Ark/Context.pm view on Meta::CPAN
unless (@args) {
@args = @{ $self->req->captures } ? @{ $self->req->captures }
: @{ $self->req->args };
}
if (Scalar::Util::blessed($target)) {
if ($target->isa('Ark::Action')) {
$target->dispatch($self, @args);
return $self->state;
}
elsif ($target->can('process')) {
$self->execute($target, 'process', @args);
return $self->state;
}
}
else {
if ($target =~ m!^/.+!) {
my ($namespace, $name) = $target =~ m!^(.*/)([^/]+)$!;
$namespace =~ s!(^/|/$)!!g;
if (my $action = $self->get_action($name, $namespace || '')) {
$action->dispatch($self, @args);
return $self->state;
}
}
else {
my $last = $self->stack->[-1];
if ($last
and $last->{obj}->isa('Ark::Controller')
and my $action = $self->get_action($target, $last->{obj}->namespace)) {
$action->dispatch($self, @args);
return $self->state;
}
}
}
my $error = qq/Couldn't forward to $target, Invalid action or component/;
$self->log( error => $error );
push @{ $self->error }, $error;
return 0;
}
sub detach {
shift->forward(@_);
die $DETACH;
}
sub dispatch {
my $self = shift;
my $match = $self->request->match;
if ($match) {
$self->dispatch_private_action('begin')
and $self->dispatch_auto_action
and $match->dispatch($self);
$self->detached(0);
$self->dispatch_private_action('end')
unless $self->res->is_deferred or $self->res->is_streaming;
}
else {
$self->log( error => 'no action found' );
}
}
sub dispatch_action {
my ($self, $name) = @_;
my $action = ($self->router->get_actions($name, $self->req->action->namespace))[-1]
or return 1;
$action->dispatch($self);
!@{ $self->error };
}
sub dispatch_private_action {
my ($self, $name) = @_;
my $action = ($self->router->get_actions($name, $self->req->action->namespace))[-1];
return 1 unless ($action and $action->attributes->{Private});
$action->dispatch($self);
!@{ $self->error };
}
sub dispatch_auto_action {
my $self = shift;
for my $auto ($self->router->get_actions('auto', $self->req->action->namespace)) {
next unless $auto->attributes->{Private};
$auto->dispatch($self);
return 0 unless $self->state;
}
1;
}
sub depth {
scalar @{ shift->stack };
}
sub execute {
my ($self, $obj, $method, @args) = @_;
my $class = ref $obj;
$self->state(0);
push @{ $self->stack }, {
obj => $obj,
method => $method,
args => \@args,
as_string => "${class}->${method}"
};
my $error;
try {
$self->execute_action($obj, $method, @args);
} catch {
$error = $_;
( run in 1.098 second using v1.01-cache-2.11-cpan-140bd7fdf52 )