Skip to content

Commit

Permalink
added multi_cookie method to Mojolicious::Controller
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Oct 7, 2014
1 parent a815d47 commit 371f116
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 41 deletions.
15 changes: 13 additions & 2 deletions lib/Mojo/Message/Request.pm
Expand Up @@ -389,11 +389,22 @@ Check if connection is secure.
Check C<X-Requested-With> header for C<XMLHttpRequest> value.
=head2 multi_param
my $values = $req->multi_param('foo');
Access multiple C<GET> and C<POST> parameters with the same name extracted
from the query string and C<application/x-www-form-urlencoded> or
C<multipart/form-data> message body. Note that this method caches all data, so
it should not be called before the entire request body has been received.
Parts of the request body need to be loaded into memory to parse C<POST>
parameters, so you have to make sure it is not excessively large, there's a
10MB limit by default.
=head2 param
my @names = $req->param;
my $foo = $req->param('foo');
my @foo = $req->param('foo');
my $value = $req->param('foo');
my ($foo, $bar) = $req->param(['foo', 'bar']);
Access C<GET> and C<POST> parameters extracted from the query string and
Expand Down
18 changes: 8 additions & 10 deletions lib/Mojo/Parameters.pm
Expand Up @@ -43,7 +43,7 @@ sub merge {
return $self;
}

sub multi_param { _param(@_) }
sub multi_param { shift->_param(@_) }

sub new { @_ > 1 ? shift->SUPER::new->parse(@_) : shift->SUPER::new }

Expand All @@ -60,7 +60,7 @@ sub param {
$self->remove($name) if defined $_[0];
return $self->append($name => ref $_[0] eq 'ARRAY' ? $_[0] : [@_]) if @_;

return _param($self, $name)->[0];
return $self->_param($name)->[0];
}

sub params {
Expand Down Expand Up @@ -261,10 +261,10 @@ parameters.
=head2 multi_param
my $values = $param->multi_param('foo');
my $values = $params->multi_param('foo');
Returns an array reference containing all of the values for the given parameter.
Note that this method will normalize the parameters.
Check multiple parameter values with the same name. Note that this method will
normalize the parameters.
=head2 new
Expand All @@ -280,16 +280,14 @@ necessary.
=head2 param
my @names = $params->param;
my $foo = $params->param('foo');
my $value = $params->param('foo');
my ($foo, $bar) = $params->param(['foo', 'bar']);
$params = $params->param(foo => 'ba&r');
$params = $params->param(foo => qw(ba&r baz));
$params = $params->param(foo => ['ba;r', 'baz']);
Check and replace parameter value. Be aware that if you will receive only the
I<first> value for that parameter even if there are multiple values for that
name; to get all the parameters use L<multi_param>. Note that this method will
normalize the parameters.
Check and replace parameter values. Note that this method will normalize the
parameters.
=head2 params
Expand Down
9 changes: 5 additions & 4 deletions lib/Mojolicious.pm
Expand Up @@ -159,10 +159,11 @@ sub new {

# Hide controller attributes/methods and "handler"
$r->hide(qw(app continue cookie finish flash handler helpers match));
$r->hide(qw(multi_signed_cookie on param redirect_to render));
$r->hide(qw(render_exception render_later render_maybe render_not_found));
$r->hide(qw(render_to_string rendered req res respond_to send session));
$r->hide(qw(signed_cookie stash tx url_for validation write write_chunk));
$r->hide(qw(multi_cookie multi_param multi_signed_cookie on param));
$r->hide(qw(redirect_to render render_exception render_later render_maybe));
$r->hide(qw(render_not_found render_to_string rendered req res respond_to));
$r->hide(qw(send session signed_cookie stash tx url_for validation write));
$r->hide(qw(write_chunk));

# DEPRECATED in Tiger Face!
$r->hide('render_static');
Expand Down
38 changes: 25 additions & 13 deletions lib/Mojolicious/Controller.pm
Expand Up @@ -57,7 +57,6 @@ sub cookie {
}

# Request cookies
return map { $_->value } $self->req->cookie($name) if wantarray;
return undef unless my $cookie = $self->req->cookie($name);
return $cookie->value;
}
Expand Down Expand Up @@ -94,6 +93,10 @@ sub flash {

sub helpers { $_[0]->app->renderer->get_helper('')->($_[0]) }

sub multi_cookie {
[map { $_->value } shift->req->cookie(shift)];
}

sub multi_param { _param(@_) }

sub multi_signed_cookie { _signed_cookie(@_) }
Expand Down Expand Up @@ -357,16 +360,15 @@ sub write_chunk {

sub _param {
my ($self, $name) = @_;
my $captures = $self->stash->{'mojo.captures'} ||= {};

# Captured unreserved values
my $captures = $self->stash->{'mojo.captures'} ||= {};
if (!$RESERVED{$name} && defined(my $value = $captures->{$name})) {
return ref $value eq 'ARRAY' ? $value : [$value];
}

my $req = $self->req;

# Uploads
my $req = $self->req;
return [$req->upload($name)] if $req->upload($name);

# Param values
Expand All @@ -378,7 +380,7 @@ sub _signed_cookie {

my $secrets = $self->stash->{'mojo.secrets'};
my @results;
for my $value ($self->cookie($name)) {
for my $value (@{$self->multi_cookie($name)}) {

# Check signature with rotating secrets
if ($value =~ s/--([^\-]+)$//) {
Expand Down Expand Up @@ -496,8 +498,7 @@ Continue dispatch chain with L<Mojolicious::Routes/"continue">.
=head2 cookie
my $foo = $c->cookie('foo');
my @foo = $c->cookie('foo');
my $value = $c->cookie('foo');
my ($foo, $bar) = $c->cookie(['foo', 'bar']);
$c = $c->cookie(foo => 'bar');
$c = $c->cookie(foo => 'bar', {path => '/'});
Expand Down Expand Up @@ -540,11 +541,22 @@ L<Mojolicious::Plugin::DefaultHelpers> and L<Mojolicious::Plugin::TagHelpers>.
# Make sure to use the "title" helper and not the controller method
$c->helpers->title('Welcome!');
=head2 multi_cookie
my $values = $c->multi_cookie('foo');
Access multiple request cookie values with the same name.
=head2 multi_param
my $values = $c->multi_param('foo');
Returns an array reference containing all of the values for the given parameter.
Access multiple route placeholder values that are not reserved stash values,
file uploads as well as C<GET> and C<POST> parameters with the same name
extracted from the query string and C<application/x-www-form-urlencoded> or
C<multipart/form-data> message body, in that order. Parts of the request body
need to be loaded into memory to parse C<POST> parameters, so you have to make
sure it is not excessively large, there's a 10MB limit by default.
=head2 multi_signed_cookie
Expand Down Expand Up @@ -589,7 +601,7 @@ status.
=head2 param
my @names = $c->param;
my $foo = $c->param('foo');
my $value = $c->param('foo');
my ($foo, $bar) = $c->param(['foo', 'bar']);
$c = $c->param(foo => 'ba;r');
$c = $c->param(foo => qw(ba;r baz));
Expand All @@ -598,12 +610,12 @@ status.
Access route placeholder values that are not reserved stash values, file
uploads as well as C<GET> and C<POST> parameters extracted from the query
string and C<application/x-www-form-urlencoded> or C<multipart/form-data>
message body, in that order. This method will only return the first parameter
for a given name even if multiple are provided, to get all of the parameters
of that name use L<multi_param>. Parts of the request body need to be loaded
into memory to parse C<POST> parameters, so you have to make sure it is not
message body, in that order. Parts of the request body need to be loaded into
memory to parse C<POST> parameters, so you have to make sure it is not
excessively large, there's a 10MB limit by default.
my $values = $c->multi_param('foo');
For more control you can also access request information directly.
# Only GET parameters
Expand Down
6 changes: 3 additions & 3 deletions lib/Mojolicious/Plugin/DefaultHelpers.pm
Expand Up @@ -11,8 +11,8 @@ sub register {
my ($self, $app) = @_;

# Controller alias helpers
my @alias = qw(app flash multi_param param stash session url_for validation);
for my $name (@alias) {
my @names = qw(app flash multi_param param stash session url_for validation);
for my $name (@names) {
$app->helper($name => sub { shift->$name(@_) });
}

Expand Down Expand Up @@ -367,7 +367,7 @@ L</"stash">.
=head2 multi_param
%= multi_param 'foo'
%= multi_param('foo')->[2]
Alias for L<Mojolicious::Controller/"multi_param">.
Expand Down
4 changes: 2 additions & 2 deletions lib/Mojolicious/Plugin/TagHelpers.pm
Expand Up @@ -76,7 +76,7 @@ sub _input {
my %attrs = @_ % 2 ? (value => shift, @_) : @_;

# Special selection value
my @values = @{ $c->multi_param($name) };
my @values = @{$c->multi_param($name)};
my $type = $attrs{type} || '';
if (@values && $type ne 'submit') {

Expand Down Expand Up @@ -152,7 +152,7 @@ sub _password_field {
sub _select_field {
my ($c, $name, $options, %attrs) = (shift, shift, shift, @_);

my %values = map { $_ => 1 } @{ $c->multi_param($name) };
my %values = map { $_ => 1 } @{$c->multi_param($name)};

my $groups = '';
for my $group (@$options) {
Expand Down
4 changes: 2 additions & 2 deletions t/mojo/parameters.t
Expand Up @@ -39,8 +39,8 @@ is_deeply [$params->param(['a'])], [4], 'right structure';
is_deeply [$params->param([qw(a foo)])], [4, 'b;ar'], 'right structure';
$params->param(foo => 'bar');
is_deeply [$params->param('foo')], ['bar'], 'right structure';
is_deeply $params->param(foo => qw(baz yada))->multi_param('foo'), [qw(baz yada)],
'right structure';
is_deeply $params->param(foo => qw(baz yada))->multi_param('foo'),
[qw(baz yada)], 'right structure';

# Remove
$params->parse('q=1&w=2&e=3&e=4&r=6&t=7');
Expand Down
2 changes: 1 addition & 1 deletion t/mojo/request.t
Expand Up @@ -587,7 +587,7 @@ is_deeply $req->body_params->to_hash->{foo}, [qw(bar bar)], 'right values';
is $req->body_params->to_hash->{' tset'}, '23 ', 'right value';
is $req->body_params, 'foo=bar&+tset=23+&foo=bar', 'right parameters';
is_deeply $req->params->to_hash->{foo}, [qw(bar bar 13)], 'right values';
is_deeply $req->multi_param('foo'), [qw(bar bar 13)], 'right values';
is_deeply $req->multi_param('foo'), [qw(bar bar 13)], 'right values';
is $req->param(' tset'), '23 ', 'right value';
$req->param('set', 'single');
is $req->param('set'), 'single', 'setting single param works';
Expand Down
2 changes: 2 additions & 0 deletions t/mojolicious/app.t
Expand Up @@ -108,6 +108,8 @@ ok $t->app->routes->is_hidden('handler'), 'is hidden';
ok $t->app->routes->is_hidden('has'), 'is hidden';
ok $t->app->routes->is_hidden('helpers'), 'is hidden';
ok $t->app->routes->is_hidden('match'), 'is hidden';
ok $t->app->routes->is_hidden('multi_cookie'), 'is hidden';
ok $t->app->routes->is_hidden('multi_param'), 'is hidden';
ok $t->app->routes->is_hidden('multi_signed_cookie'), 'is hidden';
ok $t->app->routes->is_hidden('new'), 'is hidden';
ok $t->app->routes->is_hidden('on'), 'is hidden';
Expand Down
6 changes: 3 additions & 3 deletions t/mojolicious/group_lite_app.t
Expand Up @@ -474,9 +474,9 @@ Oops!
% my ($one, $three) = $c->cookie([qw(unsigned1 unsigned2)]);
%= $one // ''
%= $three // '';
% my @unsigned1 = $c->cookie('unsigned1');
%= $unsigned1[0] // ''
%= $unsigned1[1] // ''
% my $unsigned1 = $c->multi_cookie('unsigned1');
%= $unsigned1->[0] // ''
%= $unsigned1->[1] // ''
% my ($four, $six) = $c->signed_cookie([qw(signed1 signed2)]);
%= $four // ''
%= $six // '';
Expand Down
2 changes: 1 addition & 1 deletion t/mojolicious/upload_lite_app.t
Expand Up @@ -26,7 +26,7 @@ post '/upload' => sub {

post '/multi' => sub {
my $c = shift;
my @uploads = map { @{ $c->multi_param($_) } } @{ $c->multi_param('name') };
my @uploads = map { @{$c->multi_param($_)} } @{$c->multi_param('name')};
$c->render(text => join '', map { $_->filename, $_->asset->slurp } @uploads);
};

Expand Down

0 comments on commit 371f116

Please sign in to comment.