NAME

Gantry::Plugins::SOAP::Doc - document style SOAP support

SYNOPSIS

In a controller:

use Your::App::BaseModule qw(
     -PluginNamespace=YourApp
     SOAP::Doc
);
# This exports these into the site object:
#    soap_out
#    do_wsdl
#    return_error

do_a_soap_action {
    my $self        = shift;
    my $data        = $self->get_post_body();
    my $parsed_data = XMLin( $data );

    # Use data to process the request, until you have a
    # structure like:

    my $ret_struct = [
        {
            yourResponseType => [
                { var  => value  },
                { var2 => value2 },
                { var3 => undef  }, # for required empty tags
                { nesting_var => [
                    { subvar => value },
                ] }
            ]
        }
    ] );

    return $self->soap_out( $ret_struct, 'prefix', 'pretty' );
}

DESCRIPTION

This module supports document style SOAP. If you need rpc style, see Gantry::Plugins::SOAP::RPC.

This module must be used as a plugin, so it can register a pre_init callback to take the POSTed body from the HTTP request before the engine can mangle it, in a vain attempt to make form parameters from it.

The document style SOAP request must find its way to your do_ method via its soap_action URL and Gantry's normal dispatching mechanism. Once the do_ method is called, your SOAP request is available via the get_post_body accessor exported by each engine. That request is exactly as received. You probably want to use XML::Simple's XMLin function to extract your data. I would do that for you here, but you might need to set attributes of the parsing like ForceArray.

When you have finished processing the request, you have two choices. If it did not go well, call return_error to deliver a SOAP fault to client. Using die or croak is a bad idea as that will return a regular Gantry error message which is obviously not SOAP compliant.

If you succeeded in handling the request, return an array of hashes. Each hash is keyed by XML tag (not including namespace prefix). The value can be a scalar or an array of hashes like the top level one. If the value is undef, an empty tag will be generated.

Generally, you need to take all of the exports from this module, unless you want to replace them with your own versions.

If you need to control the namespace of the returned parameters, call soap_namespace_set with the URL of the namespace before returning. If you don't do that the namespace will default to http://example.com/ns.

METHODS

new

For use by non-web scripts. Call this with a hash of attributes. Currently only the target_namespace key is used. It sets the namespace. Once you get your object, you can call soap_out on it as you would in a Gantry conroller.

get_callbacks

Only for use by Gantry.pm.

This is used to register steal_post_body as a pre init callback with Gantry.

steal_post_body

Not for external use.

Just a carefully timed call to consume_post_body exported by each engine. This is registered as a pre_init callback, so it gets the body before normal form parameter parsing would.

You may retrieve with the post body with get_post_body (also exported by each engine). No processing of the request is done. You will receive whatever the SOAP client generated. That should be XML, but even that depends on the client.

soap_current_time

Returns the UTC in SOAP format.

soap_serialize_xml

This method is registered as a callback. Durning the post_init phase it will create a hash from the $self->get_post_body() and store the result in $self->params();

soap_namespace

Called internally to retrieve the namespace for the XML tags in your SOAP response. Call soap_namespace_set if you need to set a particular namespace (some clients will care). Otherwise, the default namespace http://example.com/ns will be used.

soap_namespace_set

Use this to set the namespace for your the tags in your XML response. The default namespace is http://example.com/ns.

soap_out

Parameters:

structure

actual data to send to the client. See SYNOPSIS and DESCRIPTION.

namespace_style

prefix or internal. Use prefix to define the namespace in the soap:Envelope declaration and use it as a prefix on all the return parameter tags. Use internal if you want the prefix to be defined in the outer tag of the response parameters.

To set the value of the namespace, call soap_namespace_set before calling this method.

pretty

true if you want pretty printing, false if not

By default returned XML will be whitespace compressed. If you want it to be pretty printed for debugging, pass any true value to this method as the second parameter, in a scenario like this:

my $check_first = $self->soap_out(
        $structure, 'prefix', 'pretty_please'
);
warn $check_first;
return $check_first;

Call this with the data to return to the client. If that client cares about the namespace of the tags in the response, call soap_namespace_set first. See the SYNOPSIS for an example of the structure you must pass to this method. See the DESCRIPTION for an explanation of what you can put in the structure.

You should return the value returned from this method directly. It turns off all templating and sets the content type to text/xml.

build_args

Mostly for internal use.

soap_out uses this to turn your structure of return values into an XML snippet. If you need to re-implement soap_out, you could call this directly. The initial call should pass the same structure soap_out expects and (optionally) a pretty print flag. The returned value is the snippet of return params only. You would then need to build the SOAP envelope, etc.

return_error

This method returns a fault XML packet for you. Use it instead of die or croak.

do_wsdl

This method uses the wsdldoc.tt in your template path to return a WSDL file to your client. The view.data passed to that template comes directly from a call to get_soap_ops, which you must implement (even it it returns nothing).

AUTHOR

Phil Crow, <crow.phil@gmail.com> Tim Keefer, <tim@timkeefer.com<gt>

COPYRIGHT and LICENSE

Copyright (c) 2007, Phil Crow

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.6 or, at your option, any later version of Perl 5 you may have available.