File Coverage

blib/lib/HTML/Shakan.pm
Criterion Covered Total %
statement 128 128 100.0
branch 30 38 78.9
condition 1 3 33.3
subroutine 30 30 100.0
pod 5 7 71.4
total 194 206 94.1


line stmt bran cond sub pod time code
1             package HTML::Shakan;
2 22     22   145914 use strict;
  22         45  
  22         722  
3 22     22   106 use warnings;
  22         38  
  22         530  
4 22     22   19523 use Mouse;
  22         790960  
  22         127  
5             our $VERSION = '2.00';
6 22     22   7696 use Carp ();
  22         47  
  22         379  
7 22     22   626 use 5.008001;
  22         71  
  22         1088  
8              
9 22     22   23057 use FormValidator::Lite 'Email', 'URL', 'Date', 'File';
  22         1101842  
  22         202  
10 22     22   3201207 use Hash::MultiValue;
  22         57416  
  22         676  
11              
12 22     22   14118 use HTML::Shakan::Renderer::HTML;
  22         1801  
  22         618  
13 22     22   12171 use HTML::Shakan::Filters;
  22         52  
  22         604  
14 22     22   12622 use HTML::Shakan::Widgets::Simple;
  22         59  
  22         642  
15 22     22   12685 use HTML::Shakan::Fields;
  22         52  
  22         2001  
16 22     22   11563 use HTML::Shakan::Field::Input;
  22         1513  
  22         832  
17 22     22   21900 use HTML::Shakan::Field::Date;
  22         1524  
  22         648  
18 22     22   13362 use HTML::Shakan::Field::Choice;
  22         1597  
  22         606  
19 22     22   12408 use HTML::Shakan::Field::File;
  22         1735  
  22         698  
20 22     22   133 use List::MoreUtils 'uniq';
  22         39  
  22         37959  
21              
22             sub import {
23 20     20   5627 HTML::Shakan::Fields->export_to_level(1);
24             }
25              
26             has '_fvl' => (
27             is => 'ro',
28             isa => 'FormValidator::Lite',
29             lazy => 1,
30             handles => [qw/has_error load_function_message get_error_messages is_error is_valid set_error set_message/],
31             default => sub {
32             my $self = shift;
33             $self->params(); # build laziness data
34              
35             FormValidator::Lite->new($self);
36             }
37             );
38              
39             sub BUILD {
40 53     53 1 90 my $self = shift;
41              
42 53         261 my $fvl = $self->_fvl;
43              
44             # simple check
45 53         1086 $fvl->check(do {
46 53         76 my @c;
47 53         75 for my $field (@{ $self->fields }) {
  53         176  
48 62         311 push @c, $field->get_constraints();
49             }
50 53         266 @c;
51             });
52              
53             # run custom validation
54 53 100       3052 if (my $cv = $self->custom_validation) {
55 2         6 $cv->( $self );
56             }
57 53         208 for my $field ($self->fields) {
58 62 100       389 if (my $cv = $field->custom_validation) {
59 2         8 $cv->($self, $field);
60             }
61             }
62              
63 53 100       238 if ($fvl->is_valid) {
64 33         425 $self->_inflate_values();
65             } else {
66 20         213 $fvl->set_param_message(
67             $self->_set_error_messages()
68             );
69             }
70             }
71              
72             has custom_validation => (
73             is => 'ro',
74             isa => 'CodeRef',
75             );
76              
77             sub _set_error_messages {
78 20     20   36 my ($self, ) = @_;
79              
80 20         28 my %x;
81 20         71 for my $field ($self->fields) {
82 27   33     193 $x{$field->name} = $field->label || $field->name;
83             }
84 20         131 %x;
85             }
86              
87             sub _inflate_values {
88 33     33   51 my $self = shift;
89              
90             # inflate values
91 33         86 my $params = $self->params;
92 33         63 for my $field (@{ $self->fields }) {
  33         119  
93 35 100       274 if (my $inf = $field->inflator) {
94 1         4 my $v = $params->{$field->name};
95 1 50       4 if (defined $v) {
96 1         5 $params->{$field->name} = $inf->inflate($v);
97             }
98             }
99             }
100             }
101              
102             has 'submitted' => (
103             is => 'ro',
104             isa => 'Bool',
105             lazy => 1,
106             builder => '_build_submitted',
107             );
108             sub _build_submitted {
109 5     5   65 my ($self, ) = @_;
110              
111 5         16 my $r = $self->request;
112 7 100       55 my $submitted_field = (
113             scalar
114 7         65 grep { defined $r->param($_) || defined $r->upload($_) }
115             uniq
116 5         18 map { $_->name }
117             $self->fields
118             );
119 5 100       413 return $submitted_field > 0 ? 1 : 0;
120             }
121              
122             sub submitted_and_valid {
123 2     2 1 5 my $self = shift;
124 2 50       19 $self->submitted && $self->is_valid;
125             }
126              
127             has model => (
128             is => 'rw',
129             isa => 'Object',
130             trigger => sub {
131             my ($self, $model) = @_;
132             $model->form($self);
133             $model;
134             },
135             );
136              
137             has renderer => (
138             is => 'rw',
139             isa => 'Object',
140             builder => '_build_renderer',
141             );
142             sub _build_renderer {
143 53     53   35861 HTML::Shakan::Renderer::HTML->new();
144             }
145             sub render {
146 9     9 1 893 my $self = shift;
147 9         56 $self->renderer()->render($self);
148             }
149              
150             sub render_field {
151 1     1 1 13 my ( $self, $name ) = @_;
152 1         5 my ( $field, ) = grep { $_->name eq $name } $self->fields;
  3         11  
153 1 50       3 return unless $field;
154 1         7 return $self->widgets->render( $self, $field );
155             }
156              
157             sub fillin_param {
158 35     35 0 53 my ($self, $key) = @_;
159 35         144 $self->fillin_params->{$key};
160             }
161             has fillin_params => (
162             is => 'ro',
163             isa => 'HashRef',
164             lazy => 1,
165             default => sub {
166             my $self = shift;
167             my $fp = {};
168             for my $name ($self->request->param) {
169             my @v = $self->request->param($name);
170             if (@v) {
171             $fp->{$name} = @v==1 ? $v[0] : \@v;
172             }
173             }
174             $fp;
175             },
176             );
177              
178             has fields => (
179             is => 'ro',
180             isa => 'ArrayRef',
181             required => 1,
182             auto_deref => 1,
183             );
184              
185             has request => (
186             is => 'ro',
187             isa => 'Object',
188             required => 1,
189             );
190              
191             has 'widgets' => (
192             is => 'ro',
193             isa => 'Str',
194             default => 'HTML::Shakan::Widgets::Simple',
195             );
196              
197             has 'params' => (
198             is => 'rw',
199             isa => 'Hash::MultiValue',
200             lazy => 1,
201             builder => '_build_params',
202             );
203              
204             has 'uploads' => (
205             is => 'rw',
206             isa => 'HashRef',
207             default => sub { +{} },
208             );
209             sub upload {
210 2     2 0 112 my ($self, $name) = @_;
211 2         11 $self->uploads->{$name};
212             }
213              
214             # code taken from MooseX::Param and changed a bit
215             sub param {
216 127     127 1 7268 my $self = shift;
217              
218 127         291 my $params = $self->params;
219              
220             # if they want the list of keys ...
221 127 50       297 return $params->keys if scalar @_ == 0;
222              
223             # if they want to fetch a particular key ...
224 127 100       250 if (scalar @_ == 1) {
225 126 100       555 return wantarray ? $params->get_all($_[0]) : $params->get($_[0]);
226             }
227              
228 1 50       6 ( ( scalar @_ % 2 ) == 0 ) || confess "parameter assignment must be an even numbered list";
229              
230 1         3 my %new = @_;
231 1         7 while ( my ( $key, $value ) = each %new ) {
232 1 50       5 my @values = ref $value eq 'ARRAY' ? @$value : ($value);
233 1         7 $self->params->set($key, @values);
234             }
235 1         27 return;
236             }
237              
238             sub _build_params {
239 53     53   107 my $self = shift;
240 53         91 my $params = {};
241 53         76 for my $field (@{$self->fields}) {
  53         192  
242 62 50       681 if ($self->widgets->can('field_filter')) {
243             # e.g. DateField
244 62         315 $self->widgets->field_filter($self, $field, $params);
245             }
246 62 100       453 if ($field->can('field_filter')) {
247             # e.g. FileField
248 6         27 $field->field_filter($self, $params);
249             }
250              
251 62         219 my $name = $field->name;
252              
253 62         303 my @val = $self->request->param($name);
254 62 100       1277 if (@val != 0) {
255 41 50       123 if ( my $filters = $field->{filters} ) {
256 41         81 @val = map { HTML::Shakan::Filters->filter( $filters, $_ ) } @val;
  44         202  
257             }
258 41 100       198 $params->{$name} = @val==1 ? $val[0] : \@val;
259             }
260             }
261              
262 53         395 Hash::MultiValue->from_mixed($params);
263             }
264              
265 22     22   144 no Mouse;
  22         42  
  22         126  
266             __PACKAGE__->meta->make_immutable;
267             __END__