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 38     38   16323 use strict;
  38         80  
  38         1078  
4 38     38   177 use warnings;
  38         75  
  38         808  
5              
6 38     38   167 use URI ();
  38         64  
  38         722  
7 38     38   188 use URI::Escape qw(uri_unescape);
  38         114  
  38         66349  
8              
9             our $VERSION = '5.19';
10              
11             sub query
12             {
13 313     313 0 1147 my $self = shift;
14 313 50       2651 $$self =~ m,^([^?\#]*)(?:\?([^\#]*))?(.*)$,s or die;
15              
16 313 100       647 if (@_) {
17 92         126 my $q = shift;
18 92         209 $$self = $1;
19 92 100       223 if (defined $q) {
20 77         429 $q =~ s/([^$URI::uric])/ URI::Escape::escape_char($1)/ego;
  20         55  
21 77         213 utf8::downgrade($q);
22 77         185 $$self .= "?$q";
23             }
24 92         200 $$self .= $3;
25             }
26 313         905 $2;
27             }
28              
29             # Handle ...?foo=bar&bar=foo type of query
30             sub query_form {
31 90     90 0 5242 my $self = shift;
32 90         189 my $old = $self->query;
33 90 100       199 if (@_) {
34             # Try to set query string
35 41         62 my $delim;
36 41         64 my $r = $_[0];
37 41 100       140 if (ref($r) eq "ARRAY") {
    100          
38 17         20 $delim = $_[1];
39 17         44 @_ = @$r;
40             }
41             elsif (ref($r) eq "HASH") {
42 4         16 $delim = $_[1];
43 4         22 @_ = map { $_ => $r->{$_} } sort keys %$r;
  8         19  
44             }
45 41 100       118 $delim = pop if @_ % 2;
46              
47 41         50 my @query;
48 41         144 while (my($key,$vals) = splice(@_, 0, 2)) {
49 88 50       173 $key = '' unless defined $key;
50 88         157 $key =~ s/([;\/?:@&=+,\$\[\]%])/ URI::Escape::escape_char($1)/eg;
  7         20  
51 88         134 $key =~ s/ /+/g;
52 88 100       211 $vals = [ref($vals) eq "ARRAY" ? @$vals : $vals];
53 88         164 for my $val (@$vals) {
54 95 100       186 if (defined $val) {
55 92         158 $val =~ s/([;\/?:@&=+,\$\[\]%])/ URI::Escape::escape_char($1)/eg;
  19         43  
56 92         171 $val =~ s/ /+/g;
57 92         365 push(@query, "$key=$val");
58             }
59             else {
60 3         14 push(@query, $key);
61             }
62             }
63             }
64 41 100       93 if (@query) {
65 35 100       68 unless ($delim) {
66 32 100 100     181 $delim = $1 if $old && $old =~ /([&;])/;
67 32   100     139 $delim ||= $URI::DEFAULT_QUERY_FORM_DELIMITER || "&";
      66        
68             }
69 35         143 $self->query(join($delim, @query));
70             }
71             else {
72 6         16 $self->query(undef);
73             }
74             }
75 90 100 66     542 return if !defined($old) || !length($old) || !defined(wantarray);
      66        
76 46 100       150 return unless $old =~ /=/; # not a form
77 226 100       355 map { ( defined ) ? do { s/\+/ /g; uri_unescape($_) } : undef }
  221         305  
  221         432  
78 45 100       185 map { /=/ ? split(/=/, $_, 2) : ($_ => undef)} split(/[&;]/, $old);
  113         367  
79             }
80              
81             # Handle ...?dog+bones type of query
82             sub query_keywords
83             {
84 12     12 0 2107 my $self = shift;
85 12         29 my $old = $self->query;
86 12 100       31 if (@_) {
87             # Try to set query string
88 8         21 my @copy = @_;
89 8 100 100     32 @copy = @{$copy[0]} if @copy == 1 && ref($copy[0]) eq "ARRAY";
  2         6  
90 8         16 for (@copy) { s/([;\/?:@&=+,\$\[\]%])/ URI::Escape::escape_char($1)/eg; }
  17         50  
  6         18  
91 8 100       36 $self->query(@copy ? join('+', @copy) : undef);
92             }
93 12 100 100     71 return if !defined($old) || !defined(wantarray);
94 4 100       22 return if $old =~ /=/; # not keywords, but a form
95 2         9 map { uri_unescape($_) } split(/\+/, $old, -1);
  8         16  
96             }
97              
98             # Some URI::URL compatibility stuff
99 22     22 0 90 sub equery { goto &query }
100              
101             sub query_param {
102 12     12 0 21 my $self = shift;
103 12         26 my @old = $self->query_form;
104              
105 12 100       36 if (@_ == 0) {
106             # get keys
107 1         2 my (%seen, $i);
108 1   100     34 return grep !($i++ % 2 || $seen{$_}++), @old;
109             }
110              
111 11         20 my $key = shift;
112 11   100     99 my @i = grep $_ % 2 == 0 && $old[$_] eq $key, 0 .. $#old;
113              
114 11 100       26 if (@_) {
115 9         23 my @new = @old;
116 9         14 my @new_i = @i;
117 9 100       14 my @vals = map { ref($_) eq 'ARRAY' ? @$_ : $_ } @_;
  17         39  
118              
119 9         20 while (@new_i > @vals) {
120 11         26 splice @new, pop @new_i, 2;
121             }
122 9 100       20 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         7 splice @new, $i, 0, map { $key => $_ } @splice;
  10         23  
127             }
128 9 100       18 if (@vals) {
129             #print "SET $new_i[0]\n";
130 2         7 @new[ map $_ + 1, @new_i ] = @vals;
131             }
132              
133 9         20 $self->query_form(\@new);
134             }
135              
136 11 100       68 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         7 $self->query_form($self->query_form, $key => \@vals); # XXX
144 2         6 return;
145             }
146              
147             sub query_param_delete {
148 3     3 0 5 my $self = shift;
149 3         6 my $key = shift;
150 3         7 my @old = $self->query_form;
151 3         12 my @vals;
152              
153 3         10 for (my $i = @old - 2; $i >= 0; $i -= 2) {
154 8 100       18 next if $old[$i] ne $key;
155 5         12 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         6 my @old = $self->query_form;
164 2 100       7 if (@_) {
165 1 50       3 $self->query_form(@_ == 1 ? %{shift(@_)} : @_);
  1         11  
166             }
167 2         4 my %hash;
168 2         7 while (my($k, $v) = splice(@old, 0, 2)) {
169 6 100       14 if (exists $hash{$k}) {
170 2         4 for ($hash{$k}) {
171 2 50       7 $_ = [$_] unless ref($_) eq "ARRAY";
172 2         9 push(@$_, $v);
173             }
174             }
175             else {
176 4         14 $hash{$k} = $v;
177             }
178             }
179 2         16 return \%hash;
180             }
181              
182             1;