File Coverage

blib/lib/Minima/Controller.pm
Criterion Covered Total %
statement 29 29 100.0
branch n/a
condition n/a
subroutine 10 10 100.0
pod n/a
total 39 39 100.0


line stmt bran cond sub pod time code
1 4     4   1502 use v5.40;
  4         17  
2 4     4   26 use experimental 'class';
  4         8  
  4         29  
3              
4             class Minima::Controller;
5              
6 4     4   3316 use Data::Dumper;
  4         32857  
  4         368  
7 4     4   697 use Encode qw(decode);
  4         20699  
  4         484  
8 4     4   2008 use Hash::MultiValue;
  4         8283  
  4         179  
9 4     4   2649 use JSON;
  4         36894  
  4         29  
10 4     4   2962 use Minima::View::PlainText;
  4         18  
  4         199  
11 4     4   2335 use Plack::Request;
  4         273949  
  4         223  
12 4     4   2229 use Plack::Response;
  4         9012  
  4         193  
13 4     4   27 use Scalar::Util qw(reftype);
  4         9  
  4         9789  
14              
15             field $env :reader;
16             field $app :param :reader;
17             field $route :param :reader = {};
18              
19             field $request :reader;
20             field $response :reader;
21             field $params :reader;
22              
23             field $req_encoding;
24              
25             ADJUST {
26             $env = $app->env // {};
27              
28             $request = Plack::Request->new($env);
29             $response = Plack::Response->new(200);
30              
31             $params = $self->_get_request_parameters;
32             }
33              
34             method before_action ($m) { }
35             method after_action ($r) { }
36              
37             method trimmed_params ($options = {})
38             {
39             my $exclude = $options->{exclude} // [];
40             my @f_params = $params->flatten;
41             my @params;
42              
43             for my ($k, $v) (@f_params) {
44             if (defined $v) {
45             my $skip = 0;
46             for my $pat (@$exclude) {
47             if (ref $pat && reftype $pat eq 'REGEXP') {
48             if (defined $k && $k =~ $pat) { $skip = 1; last }
49             } else {
50             if (defined $k && $k eq $pat) { $skip = 1; last }
51             }
52             }
53             if (!$skip) {
54             if (!ref $v) {
55             $v = trim $v;
56             } elsif (ref $v eq ref []) {
57             $v = [ map { defined $_ ? trim($_) : $_ } @$v ];
58             }
59             }
60             }
61             push @params, $k, $v;
62             }
63             return Hash::MultiValue->new(@params);
64             }
65              
66             method json_body
67             {
68             my $c_type = $request->content_type // '';
69             return undef unless $c_type =~ m|\Aapplication/json\b|i;
70              
71             my $body = $request->content // '';
72             return undef unless length $body;
73              
74             my $data;
75              
76             try {
77             $data = decode_json($body);
78             } catch ($e) {
79             return undef;
80             }
81              
82             return $data;
83             }
84              
85             method hello
86             {
87             $self->render(Minima::View::PlainText->new, "hello, world\n");
88             }
89              
90             method not_found
91             {
92             $response->code(404);
93             $self->render(Minima::View::PlainText->new, "not found\n");
94             }
95              
96             method redirect ($url, $code = 302)
97             {
98             $response->redirect($url, $code);
99             $response->finalize;
100             }
101              
102             method render ($view, $data = {})
103             {
104             $response->body($view->render($data));
105             $view->prepare_response($response);
106              
107             $response->finalize;
108             }
109              
110             method print_env
111             {
112             return $self->redirect('/') unless $app->development;
113              
114             my $max = 0;
115             for (map { length } keys %$env) {
116             $max = $_ if $_ > $max;
117             }
118              
119             $self->render(
120             Minima::View::PlainText->new,
121             join '', map {
122             sprintf "%*s => %s\n", -$max, $_, $env->{$_}
123             } sort keys %$env
124             );
125             }
126              
127             method dd ($ref)
128             {
129             my $dumper = Data::Dumper->new([ $ref ]);
130             $dumper->Terse(1);
131              
132             $self->render(
133             Minima::View::PlainText->new,
134             $dumper->Dump,
135             );
136             }
137              
138             method _get_request_parameters
139             {
140             $req_encoding = $app->config->{request_encoding} // 'UTF-8';
141              
142             my @parameters = map {
143             $self->_decode($_)
144             } $request->parameters->flatten;
145              
146             $params = Hash::MultiValue->new(@parameters);
147             }
148              
149             method _decode ($data)
150             {
151             if (ref $data eq ref {}) {
152             my %encoded;
153             for my ($k, $v) (%$data) {
154             $encoded{ $self->_decode($k) } = $self->_decode($v);
155             }
156             return \%encoded;
157             }
158              
159             if (ref $data eq ref []) {
160             my @encoded;
161             for my $v (@$data) {
162             push @encoded, $self->_decode($v);
163             }
164             return \@encoded;
165             }
166              
167             if (defined $data) {
168             return decode($req_encoding, $data);
169             }
170              
171             undef;
172             }
173              
174             __END__