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   16825 use strict;
  39         95  
  39         1042  
4 39     39   183 use warnings;
  39         67  
  39         832  
5              
6 39     39   170 use URI ();
  39         59  
  39         740  
7 39     39   175 use URI::Escape qw(uri_unescape);
  39         110  
  39         67627  
8              
9             our $VERSION = '5.20';
10              
11             sub query
12             {
13 317     317 0 1337 my $self = shift;
14 317 50       1903 $$self =~ m,^([^?\#]*)(?:\?([^\#]*))?(.*)$,s or die;
15              
16 317 100       658 if (@_) {
17 93         142 my $q = shift;
18 93         225 $$self = $1;
19 93 100       200 if (defined $q) {
20 78         459 $q =~ s/([^$URI::uric])/ URI::Escape::escape_char($1)/ego;
  20         51  
21 78         214 utf8::downgrade($q);
22 78         190 $$self .= "?$q";
23             }
24 93         209 $$self .= $3;
25             }
26 317         819 $2;
27             }
28              
29             # Handle ...?foo=bar&bar=foo type of query
30             sub query_form {
31 92     92 0 7195 my $self = shift;
32 92         170 my $old = $self->query;
33 92 100       204 if (@_) {
34             # Try to set query string
35 42         57 my $delim;
36 42         63 my $r = $_[0];
37 42 100       128 if (ref($r) eq "ARRAY") {
    100          
38 17         22 $delim = $_[1];
39 17         42 @_ = @$r;
40             }
41             elsif (ref($r) eq "HASH") {
42 4         6 $delim = $_[1];
43 4         24 @_ = map { $_ => $r->{$_} } sort keys %$r;
  8         20  
44             }
45 42 100       114 $delim = pop if @_ % 2;
46              
47 42         58 my @query;
48 42         142 while (my($key,$vals) = splice(@_, 0, 2)) {
49 90 50       174 $key = '' unless defined $key;
50 90         174 $key =~ s/([;\/?:@&=+,\$\[\]%])/ URI::Escape::escape_char($1)/eg;
  7         18  
51 90         149 $key =~ s/ /+/g;
52 90 100       233 $vals = [ref($vals) eq "ARRAY" ? @$vals : $vals];
53 90         168 for my $val (@$vals) {
54 97 100       151 if (defined $val) {
55 94         159 $val =~ s/([;\/?:@&=+,\$\[\]%])/ URI::Escape::escape_char($1)/eg;
  19         35  
56 94         164 $val =~ s/ /+/g;
57 94         378 push(@query, "$key=$val");
58             }
59             else {
60 3         13 push(@query, $key);
61             }
62             }
63             }
64 42 100       112 if (@query) {
65 36 100       70 unless ($delim) {
66 33 100 100     180 $delim = $1 if $old && $old =~ /([&;])/;
67 33   100     160 $delim ||= $URI::DEFAULT_QUERY_FORM_DELIMITER || "&";
      66        
68             }
69 36         129 $self->query(join($delim, @query));
70             }
71             else {
72 6         14 $self->query(undef);
73             }
74             }
75 92 100 66     500 return if !defined($old) || !length($old) || !defined(wantarray);
      66        
76 47 100       161 return unless $old =~ /=/; # not a form
77 228 100       360 map { ( defined ) ? do { s/\+/ /g; uri_unescape($_) } : undef }
  223         314  
  223         383  
78 46 100       184 map { /=/ ? split(/=/, $_, 2) : ($_ => undef)} split(/[&;]/, $old);
  114         388  
79             }
80              
81             # Handle ...?dog+bones type of query
82             sub query_keywords
83             {
84 12     12 0 2746 my $self = shift;
85 12         28 my $old = $self->query;
86 12 100       31 if (@_) {
87             # Try to set query string
88 8         22 my @copy = @_;
89 8 100 100     32 @copy = @{$copy[0]} if @copy == 1 && ref($copy[0]) eq "ARRAY";
  2         5  
90 8         18 for (@copy) { s/([;\/?:@&=+,\$\[\]%])/ URI::Escape::escape_char($1)/eg; }
  17         45  
  6         13  
91 8 100       78 $self->query(@copy ? join('+', @copy) : undef);
92             }
93 12 100 100     70 return if !defined($old) || !defined(wantarray);
94 4 100       19 return if $old =~ /=/; # not keywords, but a form
95 2         9 map { uri_unescape($_) } split(/\+/, $old, -1);
  8         19  
96             }
97              
98             # Some URI::URL compatibility stuff
99 22     22 0 85 sub equery { goto &query }
100              
101             sub query_param {
102 12     12 0 21 my $self = shift;
103 12         23 my @old = $self->query_form;
104              
105 12 100       36 if (@_ == 0) {
106             # get keys
107 1         2 my (%seen, $i);
108 1   100     19 return grep !($i++ % 2 || $seen{$_}++), @old;
109             }
110              
111 11         18 my $key = shift;
112 11   100     101 my @i = grep $_ % 2 == 0 && $old[$_] eq $key, 0 .. $#old;
113              
114 11 100       25 if (@_) {
115 9         41 my @new = @old;
116 9         14 my @new_i = @i;
117 9 100       16 my @vals = map { ref($_) eq 'ARRAY' ? @$_ : $_ } @_;
  17         40  
118              
119 9         41 while (@new_i > @vals) {
120 11         25 splice @new, pop @new_i, 2;
121             }
122 9 100       15 if (@vals > @new_i) {
123 5 100       11 my $i = @new_i ? $new_i[-1] + 2 : @new;
124 5         11 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         22 $self->query_form(\@new);
134             }
135              
136 11 100       63 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 7 my $self = shift;
149 3         7 my $key = shift;
150 3         7 my @old = $self->query_form;
151 3         22 my @vals;
152              
153 3         9 for (my $i = @old - 2; $i >= 0; $i -= 2) {
154 8 100       18 next if $old[$i] ne $key;
155 5         13 push(@vals, (splice(@old, $i, 2))[1]);
156             }
157 3 50       10 $self->query_form(\@old) if @vals;
158 3 50       13 return wantarray ? reverse @vals : $vals[-1];
159             }
160              
161             sub query_form_hash {
162 2     2 0 11 my $self = shift;
163 2         7 my @old = $self->query_form;
164 2 100       7 if (@_) {
165 1 50       4 $self->query_form(@_ == 1 ? %{shift(@_)} : @_);
  1         8  
166             }
167 2         3 my %hash;
168 2         8 while (my($k, $v) = splice(@old, 0, 2)) {
169 6 100       15 if (exists $hash{$k}) {
170 2         6 for ($hash{$k}) {
171 2 50       7 $_ = [$_] unless ref($_) eq "ARRAY";
172 2         8 push(@$_, $v);
173             }
174             }
175             else {
176 4         13 $hash{$k} = $v;
177             }
178             }
179 2         19 return \%hash;
180             }
181              
182             1;