CatalystX-ExtJS-Direct

 view release on metacpan or  search on metacpan

lib/CatalystX/Controller/ExtJS/Direct/API.pm  view on Meta::CPAN

    my $api    = $self->api;      # populates $self->routes
    my $routes = $self->routes;
    if ( keys %{ $c->req->body_params }
        && ( my $params = $c->req->body_params ) )
    {
        $reqs = [
            {
                map {
                    my $orig = $_;
                    $orig =~ s/^ext//;
                    ( lc($orig) => delete $params->{$_} )
                  } qw(extType extAction extMethod extTID extUpload)
            }
        ];
        if ( $params->{extData} ) {
            $reqs->[0]->{data} = JSON::decode_json( delete $params->{extData} );
        } else {
            $reqs->[0]->{data} = [{%$params}];
        }
    }
    
    my @requests;
    
    foreach my $req (@$reqs) {
        unless ( $req && $req->{action}
            && exists $routes->{ $req->{action} }
            && exists $routes->{ $req->{action} }->{ $req->{method} } )
        {
            $self->status_bad_request( $c, { message => sprintf('method %s in action %s does not exist', $req->{method} || '', $req->{action} || '') } );
            return;
        }
         my $route = $routes->{ $req->{action} }->{ $req->{method} };
        
        push(@requests, $route->prepare_request($req));

    }
    
    my @res;
    REQUESTS:
    foreach my $req (@requests) {
        $req->{data} = [$req->{data}] if(ref $req->{data} ne "ARRAY");
        $c->stash->{upload} = 1 if ( $req->{upload} );
        
        my $route = $routes->{ $req->{action} }->{ $req->{method} };
        my $params = @{$req->{data}} && ref $req->{data}->[-1] eq 'HASH' ? $req->{data}->[-1] : undef;
        my $body;
        {
            local $c->{response} = $c->response_class->new({});
            local $c->{stash} = {};
            local $c->{request} = $c->req;
            local $c->{error} = undef;
            
            $c->req->parameters($params);
            $c->req->body_parameters($params);
            my %req = $route->request($req);
            $c->req($c->request_class->new(%{$c->req}, %req));
            eval {
                $c->visit($route->build_url( $req->{data} ));
                my $response = $c->res;
                if ( $response->content_type eq 'application/json' ) {
                    (my $res_body = $response->body || '') =~ s/^\xEF\xBB\xBF//; # remove BOM
                    my $json = JSON::decode_json( $res_body );
                    $body = $json;
                } else {
                    $body = $response->body;
                }
                
                if(@{$c->error}) { 0 }
                elsif($response->status >= 400) {
                    $c->error($body);
                    0;
                } else { 1 } 
            } or do {
                my $msg;
                if(@{ $c->error } && List::MoreUtils::all { ref $_ } @{ $c->error }) {
                    $msg = @{$c->error} == 1 ? $c->error->[0] : $c->error;
                    $msg = "$msg" if(blessed $msg);
                } elsif(scalar @{ $c->error }) {
                    $msg = join "\n", map { blessed $_ ? "$_" : $_ } @{ $c->error };
                } else {
                    $msg = join("\n", "$@", $c->response->body || ());
                }
                push(@res, { type => 'exception', tid => $req->{tid}, message => $msg, status_code => $c->res->status });
                $c->log->error($msg) if($c->debug && !ref $msg);
                next REQUESTS;
            };
            
            
            
        }

        my $res = { map { $_ => $req->{$_} } qw(action method tid type) };
        push( @res, { %$res, result => $body } );

    }
    $c->stash->{rest} = @res != 1 ? \@res : $res[0];

}

sub set_namespace {
    my ($self, $api, $namespace) = @_;
    return $api unless($namespace && $namespace =~ /^\w+(\.\w+)?$/);
    return {%$api, namespace => $namespace };
}

sub end {
    my ( $self, $c ) = @_;
    $c->stash->{rest} ||= $self->set_namespace( $self->api, $c->req->params->{namespace} );
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

CatalystX::Controller::ExtJS::Direct::API - API and router controller for Ext.Direct



( run in 0.845 second using v1.01-cache-2.11-cpan-39bf76dae61 )