use CGI;

use Moops;

class Apache2::RequestData 0.01
{
    has request_record =>
    (
        is  => 'ro',
        isa => Object,
    );

    has params =>
    (
        is      => 'rw',
        isa     => HashRef,
        default => sub { {} },
    );

    #########################################################################
    #
    # the constructor wrapper
    #
    #  parameters:
    #   an Apache2::RequestRec or a query string
    #
    #  returns:
    #   the hash ref with the constructor paramaters
    #
    #########################################################################

    around BUILDARGS
    {
        return $self->$next(
            @_ == 1 ?
            ref($_[0]) eq 'HASH' ?
            $_[0] :
            ref($_[0]) ?
            { request_record => $_[0] } :
            { params => { split(/[=&]/, $_[0]) } } :
            { @_ }
                           );
    }

    #########################################################################
    #
    # the constructor
    #
    #  parameters:
    #   an Apache::RequestRec or a query string
    #
    #  returns:
    #   the new created object or undef
    #
    #########################################################################

    method BUILD($args = {})
    {
        my $params = $self->params;

        unless ($params && keys %$params)
        {
            my $post_params = '';
            $self->request_record->read($post_params, $self->request_record->headers_in->{'Content-Length'})
                if $self->request_record->headers_in->{'Content-Length'} > 0;
            my $get_params = $self->request_record->args();

            $params = $post_params;
            $params .= '&' if $params && $get_params;
            $params .= $get_params if $get_params;

            # unescape the params if necessary
            $params =~ s/\%([a-fA-F0-9][a-fA-F0-9])/pack('C',hex($1))/eg;

            my $cgi = CGI->new($params);

            $self->params({ $cgi->Vars() }); # CGI::Vars returns a tied hash
        }

        return $self;
    }

    #########################################################################
    #
    # retrieve all params as hash
    #
    #  parameters:
    #   nothing
    #
    #  returns:
    #   a reference to a hash with all params and their values
    #
    #  note:
    #   alias for the inspector method params
    #
    #########################################################################

    method param_hash
    {
        return $self->params;
    }

    #########################################################################
    #
    # the destructor
    #
    #  parameters:
    #   none
    #
    #  returns:
    #   nothing: or what do you expect
    #
    #########################################################################

    sub DESTROY
    {
    }
}

__END__

=pod

=encoding UTF-8

=head1 NAME

Apache2::RequestData - collects all query and post parameters in a hash ref

=head1 VERSION

version 0.1

=head1 SYNOPSIS

Handle all Apache2 mod_perl parameters in one hash ref regardless if they
are query or post parameters.

=head1 USAGE

 use Apache2::RequestData;

 # initialize from Apache2::RequestRec or Apache2::Dummy::RequestRec
 my $rd1 = Apache2::RequestData->new($r)
 my $params1 = $rd1->params;
 # access params
 $params1->{bla}...

 # initialize from query string
 my $rd2 = Apache2::RequestData->new('bla=blu&bli=blo');
 # access params
 say $rd2->params->{bli}...

=head1 DESCRIPTION

B<Apache2::RequestData> just collects all query and post parameters of an Apache2 request rec into one hash ref.
 
=head1 AUTHOR

Jens Fischer <jeff@lipsia.de>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2021 by Jens Fischer.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut

