use Maypole::Config;
use Maypole::Constants;
use Maypole::Headers;
+use URI();
our $VERSION = '2.11';
$self->args(\@pi);
}
+=head3 make_path( %args or \%args or @args )
+
+This is the counterpart to C<Maypole::parse_path>. It generates a path to use
+in links, form actions etc. To implement your own path scheme, just override
+this method and C<parse_path>.
+
+ %args = ( table => $table,
+ action => $action,
+ additional => $additional, # optional - generally an object ID
+ );
+
+ \%args = as above, but a ref
+
+ @args = ( $table, $action, $additional ); # $additional is optional
+
+C<id> can be used as an alternative key to C<additional>.
+
+C<$additional> can be a string, an arrayref, or a hashref. An arrayref is
+expanded into extra path elements, whereas a hashref is translated into a query
+string.
+
+=cut
+
+sub make_path
+{
+ my $r = shift;
+
+ my %args;
+
+ if (@_ == 1 and ref $_[0] and ref $_[0] eq 'HASH')
+ {
+ %args = %{$_[0]};
+ }
+ elsif ( @_ > 1 and @_ < 4 )
+ {
+ $args{table} = shift;
+ $args{action} = shift;
+ $args{additional} = shift;
+ }
+ else
+ {
+ %args = @_;
+ }
+
+ do { die "no $_" unless $args{$_} } for qw( table action );
+
+ my $additional = $args{additional} || $args{id};
+
+ my @add = ();
+
+ if ($additional)
+ {
+ # if $additional is a href, make_uri() will transform it into a query
+ @add = (ref $additional eq 'ARRAY') ? @$additional : ($additional);
+ }
+
+ my $uri = $r->make_uri($args{table}, $args{action}, @add);
+
+ return $uri->as_string;
+}
+
+=head3 make_uri( @segments )
+
+Make a L<URI> object given table, action etc. Automatically adds
+the C<uri_base>.
+
+If the final element in C<@segments> is a hash ref, C<make_uri> will render it
+as a query string.
+
+=cut
+
+sub make_uri
+{
+ my ($r, @segments) = @_;
+
+ my $query = (ref $segments[-1] eq 'HASH') ? pop(@segments) : undef;
+
+ my $base = $r->config->uri_base;
+ $base =~ s|/$||;
+
+ my $uri = URI->new($base);
+ $uri->path_segments($uri->path_segments, grep {length} @segments);
+
+ my $abs_uri = $uri->abs('/');
+ $abs_uri->query_form($query) if $query;
+ return $abs_uri;
+}
+
+
# like CGI::param(), but read only
sub param
{
Only 1 named parameter is required but other than url, they can be combined as required and current values (from the request) will be used in place of any missing arguments. The url argument must be a full url including protocol and can only be combined with status.
+=head3 redirect_internal_request
+
=head3 handler
This method sets up the class if it's not done yet, sets some
--- /dev/null
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Test::More tests => 304;
+use Test::MockModule;
+
+# module compilation
+use Maypole;
+
+# simple test class that inherits from Maypole
+{
+ package MyDriver;
+ @MyDriver::ISA = 'Maypole';
+ @MyDriver::VERSION = 1;
+}
+
+# back to package main;
+my $driver_class = 'MyDriver';
+
+my $r = $driver_class->new;
+
+# make_uri
+{
+ my @bases = ( '/', '/foo', '/foo/', '', 'http://www.example.com',
+ 'http://www.example.com/', 'http://www.example.com/foo',
+ 'http://www.example.com/foo/', );
+
+ my $query = { string => 'baz',
+ number => 4,
+ list => [ qw/ fee fi fo / ],
+ };
+
+ my $query_string = '?number=4&string=baz&list=fee&list=fi&list=fo';
+
+ # expect # send
+ my @uris = (
+ { expect =>'',
+ send => [ '' ],
+ },
+ { expect => '',
+ send => [ () ],
+ },
+ { expect => '/table',
+ send => [ qw( table ) ],
+ },
+ { expect => '/table/action',
+ send => [ qw( table action ) ],
+ },
+ { expect => '/table/action/id',
+ send => [ qw( table action id ) ],
+ },
+
+
+ { expect =>'',
+ send => [ '', $query ],
+ },
+ { expect => '',
+ send => [ $query ],
+ },
+ { expect => '/table',
+ send => [ qw( table ), $query ],
+ },
+ { expect => '/table/action',
+ send => [ qw( table action ), $query ],
+ },
+ { expect => '/table/action/id',
+ send => [ qw( table action id ), $query ],
+ },
+
+ );
+
+ foreach my $base (@bases)
+ {
+ $driver_class->config->uri_base($base);
+
+ (my $base_no_slash = $base) =~ s|/$||;
+ my $base_or_slash = $base_no_slash || '/';
+
+ my $i = 1;
+
+ foreach my $test (@uris)
+ {
+ #diag "BASE: $base - URI #$i"; $i++;
+
+ my @s = @{ $test->{send} };
+ my $expect = $test->{expect};
+
+ my $uri = $r->make_uri(@s);
+
+ like("$uri", qr/^\Q$base_or_slash\E/,
+ "'$uri' starts with '$base_or_slash'");
+
+ my $q = ref $s[-1] ? $query_string : '';
+
+ my $msg =
+ sprintf "'%s' is '%s%s%s': base - '%s' segments - '%s'",
+ $uri, $base_no_slash, $expect, $q, $base,
+ @s ? join(', ', @s) : '()';
+
+ my $reconstructed = $expect =~ m|^/| ? "$base_no_slash$expect$q" :
+ "$base_or_slash$expect$q";
+
+ cmp_ok("$uri", 'eq', "$reconstructed" || '/', $msg);
+ }
+ }
+}
+
+# make_path
+{
+ my @bases = ( '/', '/foo', '/foo/', '', 'http://www.example.com',
+ 'http://www.example.com/', 'http://www.example.com/foo',
+ 'http://www.example.com/foo/', );
+
+ my $query = { string => 'baz',
+ number => 4,
+ list => [ qw/ fee fi fo / ],
+ };
+
+ my $query_string = '?number=4&string=baz&list=fee&list=fi&list=fo';
+
+ # expect # send
+ my @uris = (
+ { expect => '/table/action',
+ send => [ qw( table action ) ],
+ },
+ { expect => '/table/action/id',
+ send => [ qw( table action id ) ],
+ },
+
+
+ { expect => '/table/action',
+ send => [ qw( table action ), $query ],
+ },
+ );
+
+ foreach my $base (@bases)
+ {
+ $driver_class->config->uri_base($base);
+
+ (my $base_no_slash = $base) =~ s|/$||;
+ my $base_or_slash = $base_no_slash || '/';
+
+ my $i = 1;
+
+ foreach my $test (@uris)
+ {
+ #diag "BASE: $base - URI #$i"; $i++;
+
+ my @args = @{ $test->{send} };
+
+ my %args = ( table => $args[0],
+ action => $args[1],
+ additional => $args[2],
+ );
+
+ my %arg_sets = ( array => \@args,
+ hash => \%args,
+ hashref => \%args,
+ );
+
+ my $expect = $test->{expect};
+ my @s = @{ $test->{send} };
+
+ foreach my $set (keys %arg_sets)
+ {
+
+ my $path;
+ $path = $r->make_path(@{ $arg_sets{$set} }) if $set eq 'array';
+ $path = $r->make_path(%{ $arg_sets{$set} }) if $set eq 'hash';
+ $path = $r->make_path($arg_sets{$set}) if $set eq 'hashref';
+
+ like($path, qr/^\Q$base_or_slash\E/,
+ "'$path' starts with '$base_or_slash'");
+
+ my $q = ref $s[-1] ? $query_string : '';
+
+ my $msg =
+ sprintf "'%s' is '%s%s%s': base - '%s' segments - '%s'",
+ $path, $base_no_slash, $expect, $q, $base,
+ @s ? join(', ', @s) : '()';
+
+ my $reconstructed = $expect =~ m|^/|
+ ? "$base_no_slash$expect$q" :
+ "$base_or_slash$expect$q";
+
+ cmp_ok($path, 'eq', "$reconstructed" || '/', $msg);
+ }
+ }
+ }
+}
+