[Catalyst-commits] r7144 - in trunk/Catalyst-Model-PayPal-IPN: . lib/Catalyst/Model/PayPal

ghenry at dev.catalyst.perl.org ghenry at dev.catalyst.perl.org
Tue Nov 20 14:57:28 GMT 2007


Author: ghenry
Date: 2007-11-20 14:57:26 +0000 (Tue, 20 Nov 2007)
New Revision: 7144

Modified:
   trunk/Catalyst-Model-PayPal-IPN/README
   trunk/Catalyst-Model-PayPal-IPN/lib/Catalyst/Model/PayPal/IPN.pm
Log:
Docs complete (as well as they can be just now).

Modified: trunk/Catalyst-Model-PayPal-IPN/README
===================================================================
--- trunk/Catalyst-Model-PayPal-IPN/README	2007-11-19 21:22:05 UTC (rev 7143)
+++ trunk/Catalyst-Model-PayPal-IPN/README	2007-11-20 14:57:26 UTC (rev 7144)
@@ -1,34 +1,299 @@
 NAME
-    Catalyst::Model::PayPal::IPN - [One line description of module's purpose
-    here]
+    Catalyst::Model::PayPal::IPN - Handle Instant Payment Notifications and
+    PayPal Button Generation
 
 VERSION
     This document describes Catalyst::Model::PayPal::IPN version 0.02
 
 SYNOPSIS
-        use Catalyst::Model::PayPal::IPN;
+        package MyApp::Model::Paypal::IPN;
 
+        use strict;
+        use warnings;
+        use base 'Catalyst::Model::PayPal::IPN';
+
+        =head1 NAME
+
+        MyApp::Model::Paypal::IPN - Catalyst Model
+
+        =head1 DESCRIPTION
+
+        Catalyst Model.
+
+        =head1 AUTHOR
+
+        Gavin Henry
+
+        =head1 LICENSE
+
+        This library is free software, you can redistribute it and/or modify
+        it under the same terms as Perl itself.
+
+        =cut
+
+        1;
+
+        myapp.yml
+
+        paypal:
+            cert_id: 3TFC4UDJER95J
+            page_style: MyApp
+            no_note: 1
+            no_shipping: 1
+            lc: GB      
+            bn: PP-BuyNowBF
+
+        Model::Paypal::IPN:    
+            debug_mode: 1
+            encrypt_mode: 0
+            business_email: ghenry_1188297224_biz at suretecsystems.com
+            currency_code: GBP
+            cert: /home/ghenry/MyApp/root/auth/paypal_certs/www.myapp.net.crt
+            cert_key: /home/ghenry/MyApp/root/auth/paypal_certs/www.myapp.net.key
+            paypal_cert: /home/ghenry/MyApp/root/auth/paypal_certs/paypal_sandbox_cert.pem 
+            completion_action:
+                - Subscribe
+                - subscribe
+                - payment
+                - received 
+            postback_action:
+                - Subscribe
+                - subscribe
+                - payment
+                - ipn
+            cancellation_action:
+                - Subscribe
+                - subscribe
+                - payment
+                - cancelled
+
+        MyApp::Controller::Subscribe
+
+        =head2 ipn
+
+        Handle PayPal IPN stuff
+
+        =cut
+
+        sub ipn : Path('payment/ipn') {
+            my ( $self, $c ) = @_;
+
+            my $ipn = $c->model('Paypal::IPN');
+
+            if ( $ipn->is_completed ) {
+                my %ipn_vars = $ipn->buyer_info();
+                $c->stash->{ipn_vars} = \%ipn_vars;
+
+                Do stuff here
+
+                # Just so we reply with something, which in turn sends a HTTP Status 200
+                # OK, which we need to stop PayPal.
+                # We don't get as we don't use a template and RenderView looks for a
+                # template, a body or status equal to 3XX
+                $c->res->body('ok');
+            }
+            else {
+
+            # Just so we reply with something, which in turn sends a HTTP Status 200
+            # OK, which we need to stop PayPal.
+            # We don't get as we don't use a template and RenderView looks for a
+            # template, a body or status equal to 3XX
+                $c->res->body('not_ok');
+                $c->log->debug( $record_payment_result->transmsgtext ) if $c->debug;
+                $c->log->debug( $ipn->error ) if $ipn->error && $c->debug;
+            }
+        }
+
+        =head2 cancelled
+
+        Cancelled Payment
+
+        =cut
+
+        sub cancelled : Path('payment/cancelled') {
+            my ( $self, $c ) = @_;
+    
+            Do stuff on cancel
+   
+            $c->stash->{template} = 'user/subscribe/cancelled.tt';
+        }
+
+        =head2 generate_paypal_buttons
+
+        =cut
+
+        sub generate_paypal_buttons : Private {
+            my ( $self, $c ) = @_;
+    
+            if ( $c->stash->{all_buttons} ) {
+                $c->stash->{subtypes} = [
+                    $c->model('FTMAdminDB::FTMTariffs')->search(
+                        {
+                            objectname => 'FTM_SUB_TARIFFS',
+                            objectitem => 'TARIFFTYPENO',
+                            lovlangid  => $langid,
+                        },
+                    )
+                ];
+
+                for my $tariff ( @{ $c->stash->{subtypes} } ) {
+                    next if $tariff->tariffid == 1;
+                    my %data = (
+                        #cert_id     => $c->config->{paypal}->{cert_id},
+                        cmd         => '_xclick',
+                        item_name   => $tariff->itemdesc,
+                        item_number => $tariff->tariffid,
+                        amount      => $tariff->peruser,
+                        page_style  => $c->config->{paypal}->{page_style},
+                        no_shipping => $c->config->{paypal}->{no_shipping},
+                        no_note     => $c->config->{paypal}->{no_note},
+                        'lc'        => $c->config->{paypal}->{lc},
+                        bn          => $c->config->{paypal}->{bn},
+                        custom      => $c->req->param('subid'),
+                    );
+    
+                    if ( $c->debug ) {
+                        for my $param ( keys %data ) {
+                            $c->log->debug( $param . '=' . $data{$param} );
+                        }
+                    }
+                    $c->stash->{unencrypted_form_data} =
+                      $c->model('Paypal::IPN')->form_info( \%data );
+    
+                    my @button_info = (
+                        $tariff->itemdesc, $tariff->peruser,
+                        $c->stash->{unencrypted_form_data}
+                    );
+                    push @{ $c->stash->{unencrypted_buttons} }, \@button_info;
+                
+                    #$c->stash->{encrypted_form_data} =
+                    #  $c->model('Paypal::IPN')->encrypt_form( \%data );
+    
+                    #my @button_info = (
+                    #    $tariff->itemdesc, $tariff->peruser,
+                    #    $c->stash->{encrypted_form_data}
+                    #);
+                    #push @{ $c->stash->{encrypted_buttons} }, \@button_info;
+                }
+            }
+        }
+    
+        buttons.tt
+
+        <table>
+            [% FOREACH button IN unencrypted_buttons %]
+                <tr>
+                    <td><b>[% button.0 %]</b></td>
+                    <td><b>Price:</b> £[% button.1 %]</td>
+                    <td class="content">    
+                        <form method="post" action="[% c.model('Paypal::IPN').paypal_gateway %]">
+                        <input type="hidden" name="cmd" value="_xclick">
+                        <input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but23.gif" border="0"
+                        name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
+                        <img alt="" border="0" src="https://www.paypal.com/en_GB/i/scr/pixel.gif" width="1" height="1">
+                [% FOREACH key IN button.2.keys %]
+                        <input type="hidden" name="[% key %]" value="[% button.2.$key %]" />
+                [% END %]
+                        </form>
+                    </td>
+                </tr>
+            [% END %]
+                <tr>
+                    <td class="content">
+                        <input type="button" onclick="dojo.widget.byId('profdiag').hide();" value="Close" name="close"/>
+                    </td>
+                    <td class="content" colspan="2">
+                        <a href="#" onclick="javascript:window.open('https://www.paypal.com/uk/cgi-bin/webscr?cmd=xpt/cps/popup/OLCWhatIsPayPal-outside','olcwhatispaypal','toolbar=no,location=no, directories=no, status=no, menubar=no, scrollbars=yes,resizable=yes, width=400, height=350');"><img src="https://www.paypal.com/en_GB/i/bnr/horizontal_solution_PP.gif" border="0"
+    alt="Solution Graphics"></a>
+                    </td>
+                </tr>
+        </table>
+  
 DESCRIPTION
+    This model handles all the latest PayPal IPN vars, and provides an easy
+    method for checking that the transaction was successful.
+
+    There are also convience methods for generating encrypted and
+    non-encrypted PayPal forms and buttons.
+
+    See Business::PayPal::IPN for more info.
+
 INTERFACE
-DIAGNOSTICS
-    "Error message here, perhaps with %s placeholders"
-        [Description of error here]
+  build_paypal_gateway
+    If debug_mode is on, returns sandbox url, otherwise normal PayPal
+    gateway
 
-    "Another error message here"
-        [Description of error here]
+  is_completed
+    Calls is_completed from Business::PayPal::IPN
 
-        [Et cetera, et cetera]
+  error
+    Calls error from Business::PayPal::IPN
 
+  buyer_info
+    Returns IPN vars via Business::PayPal::IPN
+
+    See
+    <https://www.paypal.com/IntegrationCenter/ic_ipn-pdt-variable-reference.
+    html>
+
+  form_info
+    Takes a hashref and returns form data for looping through to create your
+    form.
+
+    See SYNOPSIS
+
+  encrypt_form
+    Encrypts form data.
+
+        $c->model('Paypal::IPN')->encrypt_form( \%data );
+
 CONFIGURATION AND ENVIRONMENT
-    Catalyst::Model::PayPal::IPN requires no configuration files or
-    environment variables.
+    The usual techniques for suppling model configuration data in Catalyst
+    apply, but the follow should be present:
 
+        Model::Paypal::IPN:    
+            debug_mode: 1
+            encrypt_mode: 0
+            business_email: ghenry_1188297224_biz at suretecsystems.com
+            currency_code: GBP
+            completion_action:
+                - Subscribe
+                - subscribe
+                - payment
+                - received 
+            postback_action:
+                - Subscribe
+                - subscribe
+                - payment
+                - ipn
+            cancellation_action:
+                - Subscribe
+                - subscribe
+                - payment
+                - cancelled
+
+    debug_mode switches form url to the PayPal sandbox url. If using
+    encrypted buttons, i.e.
+
+        encrypt_mode: 1
+
+    then the following will be needed:
+
+        cert: /home/ghenry/MyApp/root/auth/paypal_certs/www.myapp.net.crt
+        cert_key: /home/ghenry/MyApp/root/auth/paypal_certs/www.myapp.net.key
+        paypal_cert: /home/ghenry/MyApp/root/auth/paypal_certs/paypal_sandbox_cert.pem 
+
+    Catalyst::Model::PayPal::IPN requires:
+
 DEPENDENCIES
-    None.
+    Moose
 
-INCOMPATIBILITIES
-    None reported.
+    namespace::clean
 
+    Business::PayPal::IPN
+
+    Business::PayPal::EWP
+
 BUGS AND LIMITATIONS
     No bugs have been reported.
 
@@ -37,16 +302,16 @@
     interface at <http://rt.cpan.org>.
 
 AUTHOR
-    Matt S Trout "<mst at shadowcatsystems.co.uk>"
+    Matt S Trout "mst at shadowcatsystems.co.uk"
 
-    Gavin Henry "<ghenry at suretecsystems.com>"
+    Gavin Henry "ghenry at suretecsystems.com"
 
 LICENCE AND COPYRIGHT
-    Copyright (c) 2007, Matt S Trout, "<mst at shadowcatsystems.co.uk>". All
+    Copyright (c) 2007, Matt S Trout, "mst at shadowcatsystems.co.uk". All
     rights reserved.
 
-    Copyright (c) 2007, Gavin Henry "<ghenry at suretecsystems.com>". All
-    rights reserved.
+    Copyright (c) 2007, Gavin Henry "ghenry at suretecsystems.com". All rights
+    reserved.
 
     This module is free software; you can redistribute it and/or modify it
     under the same terms as Perl itself. See perlartistic.

Modified: trunk/Catalyst-Model-PayPal-IPN/lib/Catalyst/Model/PayPal/IPN.pm
===================================================================
--- trunk/Catalyst-Model-PayPal-IPN/lib/Catalyst/Model/PayPal/IPN.pm	2007-11-19 21:22:05 UTC (rev 7143)
+++ trunk/Catalyst-Model-PayPal-IPN/lib/Catalyst/Model/PayPal/IPN.pm	2007-11-20 14:57:26 UTC (rev 7144)
@@ -239,111 +239,321 @@
 1;
 __END__
 
-=head1 NAME
+=head1 NAME 
 
-Catalyst::Model::PayPal::IPN - [One line description of module's purpose here]
+Catalyst::Model::PayPal::IPN - Handle Instant Payment Notifications and PayPal Button Generation
 
-
 =head1 VERSION
 
 This document describes Catalyst::Model::PayPal::IPN version 0.02
 
-
 =head1 SYNOPSIS
 
-    use Catalyst::Model::PayPal::IPN;
+    package MyApp::Model::Paypal::IPN;
 
-=for author to fill in:
-    Brief code example(s) here showing commonest usage(s).
-    This section will be as far as many users bother reading
-    so make it as educational and exeplary as possible.
+    use strict;
+    use warnings;
+    use base 'Catalyst::Model::PayPal::IPN';
+
+    =head1 NAME
+
+    MyApp::Model::Paypal::IPN - Catalyst Model
+
+    =head1 DESCRIPTION
+
+    Catalyst Model.
+
+    =head1 AUTHOR
+
+    Gavin Henry
+
+    =head1 LICENSE
+
+    This library is free software, you can redistribute it and/or modify
+    it under the same terms as Perl itself.
+
+    =cut
+
+    1;
+
+
+    myapp.yml
+
+    paypal:
+        cert_id: 3TFC4UDJER95J
+        page_style: MyApp
+        no_note: 1
+        no_shipping: 1
+        lc: GB      
+        bn: PP-BuyNowBF
+
+    Model::Paypal::IPN:    
+        debug_mode: 1
+        encrypt_mode: 0
+        business_email: ghenry_1188297224_biz at suretecsystems.com
+        currency_code: GBP
+        cert: /home/ghenry/MyApp/root/auth/paypal_certs/www.myapp.net.crt
+        cert_key: /home/ghenry/MyApp/root/auth/paypal_certs/www.myapp.net.key
+        paypal_cert: /home/ghenry/MyApp/root/auth/paypal_certs/paypal_sandbox_cert.pem 
+        completion_action:
+            - Subscribe
+            - subscribe
+            - payment
+            - received 
+        postback_action:
+            - Subscribe
+            - subscribe
+            - payment
+            - ipn
+        cancellation_action:
+            - Subscribe
+            - subscribe
+            - payment
+            - cancelled
+
+
+    MyApp::Controller::Subscribe
+
+    =head2 ipn
+
+    Handle PayPal IPN stuff
+
+    =cut
+
+    sub ipn : Path('payment/ipn') {
+        my ( $self, $c ) = @_;
+
+        my $ipn = $c->model('Paypal::IPN');
+
+        if ( $ipn->is_completed ) {
+            my %ipn_vars = $ipn->buyer_info();
+            $c->stash->{ipn_vars} = \%ipn_vars;
+
+            Do stuff here
+
+            # Just so we reply with something, which in turn sends a HTTP Status 200
+            # OK, which we need to stop PayPal.
+            # We don't get as we don't use a template and RenderView looks for a
+            # template, a body or status equal to 3XX
+            $c->res->body('ok');
+        }
+        else {
+
+        # Just so we reply with something, which in turn sends a HTTP Status 200
+        # OK, which we need to stop PayPal.
+        # We don't get as we don't use a template and RenderView looks for a
+        # template, a body or status equal to 3XX
+            $c->res->body('not_ok');
+            $c->log->debug( $record_payment_result->transmsgtext ) if $c->debug;
+            $c->log->debug( $ipn->error ) if $ipn->error && $c->debug;
+        }
+    }
+
+    =head2 cancelled
+
+    Cancelled Payment
+
+    =cut
+
+    sub cancelled : Path('payment/cancelled') {
+        my ( $self, $c ) = @_;
+    
+        Do stuff on cancel
+   
+        $c->stash->{template} = 'user/subscribe/cancelled.tt';
+    }
+
+    =head2 generate_paypal_buttons
+
+    =cut
+
+    sub generate_paypal_buttons : Private {
+        my ( $self, $c ) = @_;
+    
+        if ( $c->stash->{all_buttons} ) {
+            $c->stash->{subtypes} = [
+                $c->model('FTMAdminDB::FTMTariffs')->search(
+                    {
+                        objectname => 'FTM_SUB_TARIFFS',
+                        objectitem => 'TARIFFTYPENO',
+                        lovlangid  => $langid,
+                    },
+                )
+            ];
+
+            for my $tariff ( @{ $c->stash->{subtypes} } ) {
+                next if $tariff->tariffid == 1;
+                my %data = (
+                    #cert_id     => $c->config->{paypal}->{cert_id},
+                    cmd         => '_xclick',
+                    item_name   => $tariff->itemdesc,
+                    item_number => $tariff->tariffid,
+                    amount      => $tariff->peruser,
+                    page_style  => $c->config->{paypal}->{page_style},
+                    no_shipping => $c->config->{paypal}->{no_shipping},
+                    no_note     => $c->config->{paypal}->{no_note},
+                    'lc'        => $c->config->{paypal}->{lc},
+                    bn          => $c->config->{paypal}->{bn},
+                    custom      => $c->req->param('subid'),
+                );
+    
+                if ( $c->debug ) {
+                    for my $param ( keys %data ) {
+                        $c->log->debug( $param . '=' . $data{$param} );
+                    }
+                }
+                $c->stash->{unencrypted_form_data} =
+                  $c->model('Paypal::IPN')->form_info( \%data );
+    
+                my @button_info = (
+                    $tariff->itemdesc, $tariff->peruser,
+                    $c->stash->{unencrypted_form_data}
+                );
+                push @{ $c->stash->{unencrypted_buttons} }, \@button_info;
+                
+                #$c->stash->{encrypted_form_data} =
+                #  $c->model('Paypal::IPN')->encrypt_form( \%data );
+    
+                #my @button_info = (
+                #    $tariff->itemdesc, $tariff->peruser,
+                #    $c->stash->{encrypted_form_data}
+                #);
+                #push @{ $c->stash->{encrypted_buttons} }, \@button_info;
+            }
+        }
+    }
+    
+    buttons.tt
+
+    <table>
+        [% FOREACH button IN unencrypted_buttons %]
+            <tr>
+                <td><b>[% button.0 %]</b></td>
+                <td><b>Price:</b> £[% button.1 %]</td>
+                <td class="content">    
+                    <form method="post" action="[% c.model('Paypal::IPN').paypal_gateway %]">
+                    <input type="hidden" name="cmd" value="_xclick">
+                    <input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but23.gif" border="0"
+                    name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
+                    <img alt="" border="0" src="https://www.paypal.com/en_GB/i/scr/pixel.gif" width="1" height="1">
+            [% FOREACH key IN button.2.keys %]
+                    <input type="hidden" name="[% key %]" value="[% button.2.$key %]" />
+            [% END %]
+                    </form>
+                </td>
+            </tr>
+        [% END %]
+            <tr>
+                <td class="content">
+                    <input type="button" onclick="dojo.widget.byId('profdiag').hide();" value="Close" name="close"/>
+                </td>
+                <td class="content" colspan="2">
+                    <a href="#" onclick="javascript:window.open('https://www.paypal.com/uk/cgi-bin/webscr?cmd=xpt/cps/popup/OLCWhatIsPayPal-outside','olcwhatispaypal','toolbar=no,location=no, directories=no, status=no, menubar=no, scrollbars=yes,resizable=yes, width=400, height=350');"><img src="https://www.paypal.com/en_GB/i/bnr/horizontal_solution_PP.gif" border="0"
+alt="Solution Graphics"></a>
+                </td>
+            </tr>
+    </table>
   
   
 =head1 DESCRIPTION
 
-=for author to fill in:
-    Write a full description of the module and its features here.
-    Use subsections (=head2, =head3) as appropriate.
+This model handles all the latest PayPal IPN vars, and provides an
+easy method for checking that the transaction was successful.
 
+There are also convience methods for generating encrypted and non-encrypted 
+PayPal forms and buttons.
 
+See L<Business::PayPal::IPN> for more info.
+
+
 =head1 INTERFACE 
 
-=for author to fill in:
-    Write a separate section listing the public components of the modules
-    interface. These normally consist of either subroutines that may be
-    exported, or methods that may be called on objects belonging to the
-    classes provided by the module.
 
+=head2 build_paypal_gateway 
 
-=head1 DIAGNOSTICS
+If debug_mode is on, returns sandbox url, otherwise normal PayPal gateway
 
-=for author to fill in:
-    List every single error and warning message that the module can
-    generate (even the ones that will "never happen"), with a full
-    explanation of each problem, one or more likely causes, and any
-    suggested remedies.
+=head2 is_completed 
 
-=over
+Calls is_completed from L<Business::PayPal::IPN>
 
-=item C<< Error message here, perhaps with %s placeholders >>
+=head2 error 
 
-[Description of error here]
+Calls error from L<Business::PayPal::IPN>
 
-=item C<< Another error message here >>
+=head2 buyer_info 
 
-[Description of error here]
+Returns IPN vars via L<Business::PayPal::IPN>
 
-[Et cetera, et cetera]
+See L<https://www.paypal.com/IntegrationCenter/ic_ipn-pdt-variable-reference.html>
 
-=back
+=head2 form_info 
 
+Takes a hashref and returns form data for looping through to create your form.
 
+See L<SYNOPSIS>
+
+=head2 encrypt_form
+
+Encrypts form data.
+
+    $c->model('Paypal::IPN')->encrypt_form( \%data );
+
 =head1 CONFIGURATION AND ENVIRONMENT
 
-=for author to fill in:
-    A full explanation of any configuration system(s) used by the
-    module, including the names and locations of any configuration
-    files, and the meaning of any environment variables or properties
-    that can be set. These descriptions must also include details of any
-    configuration language used.
-  
-Catalyst::Model::PayPal::IPN requires no configuration files or environment variables.
+The usual techniques for suppling model configuration data in Catalyst apply,
+but the follow should be present:
 
+    Model::Paypal::IPN:    
+        debug_mode: 1
+        encrypt_mode: 0
+        business_email: ghenry_1188297224_biz at suretecsystems.com
+        currency_code: GBP
+        completion_action:
+            - Subscribe
+            - subscribe
+            - payment
+            - received 
+        postback_action:
+            - Subscribe
+            - subscribe
+            - payment
+            - ipn
+        cancellation_action:
+            - Subscribe
+            - subscribe
+            - payment
+            - cancelled
 
-=head1 DEPENDENCIES
+debug_mode switches form url to the PayPal sandbox url. If using encrypted 
+buttons, i.e.
 
-=for author to fill in:
-    A list of all the other modules that this module relies upon,
-    including any restrictions on versions, and an indication whether
-    the module is part of the standard Perl distribution, part of the
-    module's distribution, or must be installed separately. ]
+    encrypt_mode: 1
 
-None.
+then the following will be needed:
 
+    cert: /home/ghenry/MyApp/root/auth/paypal_certs/www.myapp.net.crt
+    cert_key: /home/ghenry/MyApp/root/auth/paypal_certs/www.myapp.net.key
+    paypal_cert: /home/ghenry/MyApp/root/auth/paypal_certs/paypal_sandbox_cert.pem 
 
-=head1 INCOMPATIBILITIES
+ 
+Catalyst::Model::PayPal::IPN requires:
 
-=for author to fill in:
-    A list of any modules that this module cannot be used in conjunction
-    with. This may be due to name conflicts in the interface, or
-    competition for system or program resources, or due to internal
-    limitations of Perl (for example, many modules that use source code
-    filters are mutually incompatible).
 
-None reported.
 
+=head1 DEPENDENCIES
 
+L<Moose>
+
+L<namespace::clean>
+
+L<Business::PayPal::IPN>
+
+L<Business::PayPal::EWP>
+
+
 =head1 BUGS AND LIMITATIONS
 
-=for author to fill in:
-    A list of known problems with the module, together with some
-    indication Whether they are likely to be fixed in an upcoming
-    release. Also a list of restrictions on the features the module
-    does provide: data types that cannot be handled, performance issues
-    and the circumstances in which they may arise, practical
-    limitations on the size of data sets, special cases that are not
-    (yet) handled, etc.
-
 No bugs have been reported.
 
 Please report any bugs or feature requests to
@@ -353,15 +563,15 @@
 
 =head1 AUTHOR
 
-Matt S Trout C<< <mst at shadowcatsystems.co.uk> >>
+Matt S Trout C<mst at shadowcatsystems.co.uk>
 
-Gavin Henry  C<< <ghenry at suretecsystems.com> >>
+Gavin Henry  C<ghenry at suretecsystems.com>
 
 =head1 LICENCE AND COPYRIGHT
 
-Copyright (c) 2007, Matt S Trout, C<< <mst at shadowcatsystems.co.uk> >>. All rights reserved.
+Copyright (c) 2007, Matt S Trout, C<mst at shadowcatsystems.co.uk>. All rights reserved.
 
-Copyright (c) 2007, Gavin Henry C<< <ghenry at suretecsystems.com> >>. All rights reserved.
+Copyright (c) 2007, Gavin Henry C<ghenry at suretecsystems.com>. All rights reserved.
 
 This module is free software; you can redistribute it and/or
 modify it under the same terms as Perl itself. See L<perlartistic>.




More information about the Catalyst-commits mailing list