Jifty::Request::Mapper - Maps response values into arbitrary query


Jifty documentation Contained in the Jifty distribution.

Index


Code Index:

NAME

Top

Jifty::Request::Mapper - Maps response values into arbitrary query parameters

DESCRIPTION

Top

Jifty::Request::Mapper is used to insert values into parameters that you can't know when you originally constructed the request. The prime example of this is a Create action to a View page -- where you can't know what ID to supply to the View page until after the Create action has run. This problem can be fixed by establishing a mapping between some part of the Jifty::Result of the Create action, and the ID query parameter.

METHODS

Top

query_parameters HASH

Extended syntax for generating query parameters. This is used by Jifty::Web::Form::Clickable for its parameters argument, as well as for results of continuations.

Possible formats for each key => value pair in the HASH are:

KEY => STRING

The simplest form -- the KEY will have the literal value of the STRING supplied

KEY => { result => ACTION }

The KEY will take on the value of the content named KEY from the result of the ACTION. ACTION may either be a Jifty::Action object, or a moniker thereof.

KEY => { result => ACTION, name => STRING }

The KEY will take on the value of the content named STRING from the result of the ACTION. ACTION may either be a Jifty::Action object, or a moniker thereof.

KEY => { request_argument => STRING }

The KEY will take on the value of the argument named STRING from the request.

KEY => { argument => ACTION }

The KEY will take on the value of the argument named KEY from the ACTION. ACTION may either be a Jifty::Action object, or a moniker thereof.

KEY => { argument => ACTION. name => STRING }

The KEY will take on the value of the argument named STRING from the ACTION. ACTION may either be a Jifty::Action object, or a moniker thereof.

result_of and argument_to are valid synonyms for result and argument, above.

map PARAMHASH

Responsible for doing the actual mapping that query_parameters above sets up. That is, takes magical query parameters and extracts the values they were meant to have.

destination

The key from a query parameter

source

The value of a query parameter

request

The Jifty::Request object to pull action arguments from. Defaults to the current request.

response

The Jifty::Response object to pull results from. Defaults to the current response.

Returns a key => value pair.


Jifty documentation Contained in the Jifty distribution.
use warnings;
use strict;

package Jifty::Request::Mapper;

sub query_parameters {
    my $class = shift;

    my %parameters = @_;
    my %return;
    for my $key (keys %parameters) {
        if (ref $parameters{$key} eq "HASH") {
            my %mapping = %{$parameters{$key}};

            if ($mapping{request_argument}) {
                $return{"J:M-$key"} = join("`","A", $mapping{request_argument});
            }

            for (grep {/^(result(_of)?|argument(_to)?)$/} keys %mapping) {
                my $action  = $mapping{$_};
                my $moniker = ref $action ? $action->moniker : $action;
                # If $key is for an argument of an action, we want to
                # extract only the argument's name, and not just use
                # the whole encoded J:A:F-... string.
                my (undef, $a, undef) = Jifty::Request->parse_form_field_name($key);
                my $name = $mapping{name} || $a || $key;

                my $type = ($_ =~ /result/) ? "R" : "A";

                $return{"J:M-$key"} = join("`", $type, $moniker, $name);
            }
        } else {
            $return{$key} = $parameters{$key};
        }
    }

    return %return;
}


sub map {
    my $class = shift;

    my %args = (
        source      => undef,
        destination => undef,
        request     => Jifty->web->request,
        response    => Jifty->web->response,
        @_
    );

    my @original = ($args{destination} => $args{source});

    # In case the source is a hashref, we force ourselves to go the
    # *other* direction first.
    ($args{destination}, $args{source}) = $class->query_parameters($args{destination} => $args{source});

    # Bail unless it's a mapping
    return ( @original )
        unless defined $args{destination} and $args{destination} =~ /^J:M-(.*)/;

    my $destination = $1;

    my @bits = split( /\`/, $args{source} );
    if ( $bits[0] ) {
        if ( $bits[0] eq "A" and @bits == 3 ) {
            # No such action -- value is undef
            return ( $destination => undef ) unless $args{request}->top_request->action( $bits[1] );
            # We have a value
            return ( $destination => $args{request}->top_request->action( $bits[1] )->argument( $bits[2] ) );
        } elsif ( $bits[0] eq "R" and @bits == 3 ) { 
            # No such action -- value is undef
            return ( $destination => undef ) unless $args{request}->top_request->action( $bits[1] );
            # Action exists but hasn't run yet -- defer until later
            return ( @original ) unless $args{response}->result( $bits[1] );
            # We have a value
            return ( $destination => $args{response}->result( $bits[1] )->content( $bits[2] ) );
        } elsif ( $bits[0] eq "A" and @bits == 2 ) {
            return ( $destination => $args{request}->arguments->{ $bits[1] } );
        }
    }
    # As a fallback, just set it to the value
    return ( $destination => $args{source} );

}


1;