File Coverage

blib/lib/URI/_query.pm
Criterion Covered Total %
statement 129 129 100.0
branch 69 76 90.7
condition 23 26 88.4
subroutine 12 12 100.0
pod 0 8 0.0
total 233 251 92.8


line stmt bran cond sub pod time code
1             package URI::_query;
2              
3 39     39   17125 use strict;
  39         82  
  39         1064  
4 39     39   198 use warnings;
  39         71  
  39         820  
5              
6 39     39   168 use URI ();
  39         73  
  39         761  
7 39     39   178 use URI::Escape qw(uri_unescape);
  39         135  
  39         69147  
8              
9             our $VERSION = '5.21';
10              
11             sub query
12             {
13 317     317 0 1314 my $self = shift;
14 317 50       1903 $$self =~ m,^([^?\#]*)(?:\?([^\#]*))?(.*)$,s or die;
15              
16 317 100       663 if (@_) {
17 93         147 my $q = shift;
18 93         196 $$self = $1;
19 93 100       195 if (defined $q) {
20 78         484 $q =~ s/([^$URI::uric])/ URI::Escape::escape_char($1)/ego;
  20         101  
21 78         223 utf8::downgrade($q);
22 78         188 $$self .= "?$q";
23             }
24 93         198 $$self .= $3;
25             }
26 317         857 $2;
27             }
28              
29             # Handle ...?foo=bar&bar=foo type of query
30             sub query_form {
31 92     92 0 7755 my $self = shift;
32 92         178 my $old = $self->query;
33 92 100       206 if (@_) {
34             # Try to set query string
35 42         60 my $delim;
36 42         65 my $r = $_[0];
37 42 100       141 if (ref($r) eq "ARRAY") {
    100          
38 17         25 $delim = $_[1];
39 17         42 @_ = @$r;
40             }
41             elsif (ref($r) eq "HASH") {
42 4         7 $delim = $_[1];
43 4         20 @_ = map { $_ => $r->{$_} } sort keys %$r;
  8         18  
44             }
45 42 100       126 $delim = pop if @_ % 2;
46              
47 42         56 my @query;
48 42         158 while (my($key,$vals) = splice(@_, 0, 2)) {
49 90 50       170 $key = '' unless defined $key;
50 90         180 $key =~ s/([;\/?:@&=+,\$\[\]%])/ URI::Escape::escape_char($1)/eg;
  7         22  
51 90         139 $key =~ s/ /+/g;
52 90 100       223 $vals = [ref($vals) eq "ARRAY" ? @$vals : $vals];
53 90         160 for my $val (@$vals) {
54 97 100       177 if (defined $val) {
55 94         152 $val =~ s/([;\/?:@&=+,\$\[\]%])/ URI::Escape::escape_char($1)/eg;
  19         42  
56 94         188 $val =~ s/ /+/g;
57 94         443 push(@query, "$key=$val");
58             }
59             else {
60 3         13 push(@query, $key);
61             }
62             }
63             }
64 42 100       129 if (@query) {
65 36 100       79 unless ($delim) {
66 33 100 100     189 $delim = $1 if $old && $old =~ /([&;])/;
67 33   100     178 $delim ||= $URI::DEFAULT_QUERY_FORM_DELIMITER || "&";
      66        
68             }
69 36         149 $self->query(join($delim, @query));
70             }
71             else {
72 6         13 $self->query(undef);
73             }
74             }
75 92 100 66     513 return if !defined($old) || !length($old) || !defined(wantarray);
      66        
76 47 100       166 return unless $old =~ /=/; # not a form
77 228 100       363 map { ( defined ) ? do { s/\+/ /g; uri_unescape($_) } : undef }
  223         316  
  223         407  
78 46 100       207 map { /=/ ? split(/=/, $_, 2) : ($_ => undef)} split(/[&;]/, $old);
  114         378  
79             }
80              
81             # Handle ...?dog+bones type of query
82             sub query_keywords
83             {
84 12     12 0 2884 my $self = shift;
85 12         28 my $old = $self->query;
86 12 100       29 if (@_) {
87             # Try to set query string
88 8         42 my @copy = @_;
89 8 100 100     37 @copy = @{$copy[0]} if @copy == 1 && ref($copy[0]) eq "ARRAY";
  2         8  
90 8         20 for (@copy) { s/([;\/?:@&=+,\$\[\]%])/ URI::Escape::escape_char($1)/eg; }
  17         49  
  6         29  
91 8 100       34 $self->query(@copy ? join('+', @copy) : undef);
92             }
93 12 100 100     76 return if !defined($old) || !defined(wantarray);
94 4 100       23 return if $old =~ /=/; # not keywords, but a form
95 2         9 map { uri_unescape($_) } split(/\+/, $old, -1);
  8         20  
96             }
97              
98             # Some URI::URL compatibility stuff
99 22     22 0 101 sub equery { goto &query }
100              
101             sub query_param {
102 12     12 0 20 my $self = shift;
103 12         45 my @old = $self->query_form;
104              
105 12 100       36 if (@_ == 0) {
106             # get keys
107 1         2 my (%seen, $i);
108 1   100     20 return grep !($i++ % 2 || $seen{$_}++), @old;
109             }
110              
111 11         19 my $key = shift;
112 11   100     104 my @i = grep $_ % 2 == 0 && $old[$_] eq $key, 0 .. $#old;
113              
114 11 100       25 if (@_) {
115 9         22 my @new = @old;
116 9         14 my @new_i = @i;
117 9 100       14 my @vals = map { ref($_) eq 'ARRAY' ? @$_ : $_ } @_;
  17         41  
118              
119 9         19 while (@new_i > @vals) {
120 11         23 splice @new, pop @new_i, 2;
121             }
122 9 100       19 if (@vals > @new_i) {
123 5 100       11 my $i = @new_i ? $new_i[-1] + 2 : @new;
124 5         10 my @splice = splice @vals, @new_i, @vals - @new_i;
125              
126 5         9 splice @new, $i, 0, map { $key => $_ } @splice;
  10         23  
127             }
128 9 100       20 if (@vals) {
129             #print "SET $new_i[0]\n";
130 2         7 @new[ map $_ + 1, @new_i ] = @vals;
131             }
132              
133 9         19 $self->query_form(\@new);
134             }
135              
136 11 100       66 return wantarray ? @old[map $_+1, @i] : @i ? $old[$i[0]+1] : undef;
    100          
137             }
138              
139             sub query_param_append {
140 2     2 0 4 my $self = shift;
141 2         3 my $key = shift;
142 2 50       4 my @vals = map { ref $_ eq 'ARRAY' ? @$_ : $_ } @_;
  4         12  
143 2         5 $self->query_form($self->query_form, $key => \@vals); # XXX
144 2         7 return;
145             }
146              
147             sub query_param_delete {
148 3     3 0 6 my $self = shift;
149 3         6 my $key = shift;
150 3         5 my @old = $self->query_form;
151 3         95 my @vals;
152              
153 3         12 for (my $i = @old - 2; $i >= 0; $i -= 2) {
154 8 100       18 next if $old[$i] ne $key;
155 5         15 push(@vals, (splice(@old, $i, 2))[1]);
156             }
157 3 50       9 $self->query_form(\@old) if @vals;
158 3 50       31 return wantarray ? reverse @vals : $vals[-1];
159             }
160              
161             sub query_form_hash {
162 2     2 0 13 my $self = shift;
163 2         7 my @old = $self->query_form;
164 2 100       8 if (@_) {
165 1 50       3 $self->query_form(@_ == 1 ? %{shift(@_)} : @_);
  1         10  
166             }
167 2         4 my %hash;
168 2         8 while (my($k, $v) = splice(@old, 0, 2)) {
169 6 100       12 if (exists $hash{$k}) {
170 2         5 for ($hash{$k}) {
171 2 50       7 $_ = [$_] unless ref($_) eq "ARRAY";
172 2         8 push(@$_, $v);
173             }
174             }
175             else {
176 4         14 $hash{$k} = $v;
177             }
178             }
179 2         23 return \%hash;
180             }
181              
182             1;