File Coverage

blib/lib/Dancer/Plugin/Params/Normalization.pm
Criterion Covered Total %
statement 7 7 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 10 100.0


line stmt bran cond sub pod time code
1             #
2             # This file is part of Dancer-Plugin-Params-Normalization
3             #
4             # This software is copyright (c) 2011 by Damien "dams" Krotkine.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9             package Dancer::Plugin::Params::Normalization;
10             {
11             $Dancer::Plugin::Params::Normalization::VERSION = '0.52';
12             }
13              
14             # ABSTRACT: A plugin for normalizing query parameters in Dancer
15              
16 10     10   2532592 use Dancer ':syntax';
  10         377878  
  10         60  
17 10     10   13193 use Dancer::Plugin;
  10         15260  
  10         16894  
18              
19             my $conf = plugin_setting;
20              
21             # method that does nothing. It's optimized to nothing at compile time
22             my $void = sub(){};
23              
24             # set the params_filter
25             my $params_filter = sub () { 1; };
26             if (defined $conf->{params_filter}) {
27             my $re = $conf->{params_filter};
28             $params_filter = sub {
29             return scalar($_[0] =~ /$re/) };
30             }
31              
32             # method that loops on a hashref and apply a given method on its keys
33             my $apply_on_keys = sub {
34             my ($h, $func) = @_;
35             my $new_h = {};
36             while (my ($k, $v) = each (%$h)) {
37             my $new_k = $params_filter->($k) ? $func->($k) : $k;
38             exists $new_h->{$new_k} && ! ($conf->{no_conflict_warn} || 0)
39             and warn "paramater names conflict while doing normalization of parameters '$k' : it produces '$new_k', which alreay exists.";
40             $new_h->{$new_k} = $v;
41             }
42             return $new_h;
43             };
44              
45              
46             # default normalization method is passthrough (do nothing)
47             my $normalization_fonction = $void;
48             if (defined $conf->{method} && $conf->{method} ne 'passthrough') {
49             my $method;
50             if ($conf->{method} eq 'lowercase') {
51             $method = sub { my ($h) = @_; $apply_on_keys->($h, sub { lc($_[0]) } ) };
52             } elsif ($conf->{method} eq 'uppercase') {
53             $method = sub { my ($h) = @_; $apply_on_keys->($h, sub { uc($_[0]) } ) };
54             } elsif ($conf->{method} eq 'ucfirst') {
55             $method = sub { my ($h) = @_; $apply_on_keys->($h, sub { ucfirst($_[0]) } ) };
56             } else {
57             my $class = $conf->{method};
58             my $class_name = $class;
59             $class_name =~ s!::|'!/!g;
60             $class_name .= '.pm';
61             if ( ! $class->can('new') ) {
62             eval { require $class_name };
63             $@ and die "error while requiring custom normalization class '$class' : $@";
64             }
65             my $abstract_classname = __PACKAGE__ . '::Abstract';
66             $class->isa(__PACKAGE__ . '::Abstract')
67             or die "custom normalization class '$class' doesn't inherit from '$abstract_classname'";
68             my $instance = $class->new();
69             # using a custom normalization is incompatible with params filters
70             defined $conf->{params_filter}
71             and die "your configuration contains a 'params_filter' fields, and a custom 'method' normalization class name. The two fields are incompatible";
72             # todo : use *method = \&{$class->normalize} or somethin'
73             $method = sub { $instance->normalize($_[0]) };
74             }
75              
76             my $params_types = $conf->{params_types};
77             # default value
78             defined $params_types
79             or $params_types = [ qw(query body) ];
80             ref $params_types eq 'ARRAY'
81             or die "configuration field 'params_types' should be an array";
82              
83             my %params_types = map { $_ => 1 } @$params_types;
84             my $params_type_query = delete $params_types{query};
85             my $params_type_body = delete $params_types{body};
86             my $params_type_route = delete $params_types{route};
87             keys %params_types
88             and die "your configuration contains '" . join(', ', keys %params_types) .
89             "' as 'params_types' field(s), but only these are allowed : 'query', 'body', 'route'";
90              
91             $normalization_fonction = sub {
92             my ($new_query_params,
93             $new_body_params,
94             $new_route_params) = map { scalar(params($_)) } qw(query body route);
95             $params_type_query and $new_query_params = $method->($new_query_params);
96             $params_type_body and $new_body_params = $method->($new_body_params);
97             $params_type_route and $new_route_params = $method->($new_route_params);
98              
99             request->{params} = {};
100              
101             request->_set_query_params($new_query_params);
102             request->_set_body_params($new_body_params);
103             request->_set_route_params($new_route_params);
104             };
105             }
106              
107             if (defined $conf->{general_rule}) {
108             $conf->{general_rule} =~ /^always$|^ondemand$/
109             or die 'configuration field general_rule must be one of : always, ondemand';
110             if ($conf->{general_rule} eq 'ondemand') {
111 1     1   7225 register normalize => sub{ $normalization_fonction->() };
112             } else {
113             hook before => $normalization_fonction;
114             }
115             } else {
116             hook before => $normalization_fonction;
117             }
118              
119             register_plugin;
120              
121             1;
122              
123             __END__