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 )