/[Frey]/trunk/lib/Frey/Action.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/lib/Frey/Action.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 645 - (show annotations)
Sun Nov 30 16:22:45 2008 UTC (15 years, 4 months ago) by dpavlin
File size: 5094 byte(s)
some work on support for checkboxes and default values,
still incomplete and untested
1 package Frey::Action;
2 use Moose;
3 extends 'Frey::PPI';
4 with 'Frey::Web';
5 with 'Frey::Config';
6
7 use Clone qw/clone/;
8 use Data::Dump qw/dump/;
9
10 =head1 DESCRIPTION
11
12 Invoke any L<Frey> object creating html for with various default parameters
13 if not supplied at invocation.
14
15 =cut
16
17 has 'class' => (
18 is => 'rw',
19 isa => 'Str',
20 required => 1,
21 );
22
23 has 'params' => (
24 is => 'rw',
25 isa => 'HashRef',
26 default => sub { {} },
27 );
28
29 =head2 required
30
31 my @required_attributes = $self->required;
32 my $required_attributes = $self->required;
33
34 =cut
35
36 sub required {
37 my ( $self ) = @_;
38 $self->load_class( $self->class );
39 my @required =
40 grep {
41 defined $_ && $_->can('name') &&
42 ! defined( $self->params->{ $_->name } ) &&
43 ! $_->is_lazy
44 }
45 map {
46 my $attr = $self->class->meta->get_attribute($_);
47 blessed $attr && $attr->is_required && $attr;
48 } $self->class->meta->get_attribute_list;
49
50 warn "## required = ",dump( map { $_->name } @required ), " for ", $self->class if @required && $self->debug;
51 return @required if wantarray;
52 return \@required;
53 }
54
55 =head2 attributes
56
57 Generated from attributes specified in code (extracted using L<Frey::PPI>)
58 and required atributes
59
60 my @class_attributes = $self->attributes;
61 my @class_attributes = $self->attributes;
62
63 =cut
64
65 sub attributes {
66 my ( $self ) = @_;
67 my $a;
68 my @attrs = @{ $self->attribute_order };
69 @attrs = map { $a->{$_}++; $_ } @attrs;
70 push @attrs, $_ foreach grep { ! $a->{$_} } map { $_->name } @{ $self->required };
71 warn "# attributes = ",dump( @attrs ) if $self->debug;
72 return @attrs if wantarray;
73 return \@attrs;
74 }
75
76 =head2 params_form
77
78 my $html = $self->params_form;
79 my ($html,$default_params) = $self->params_form;
80
81 =cut
82
83 sub params_form {
84 my ( $self ) = @_;
85 my @required = $self->required;
86 if ( ! @required ) {
87 warn "all params available ", dump( $self->params ), " not creating form" if $self->debug;
88 return (undef,$self->params) if wantarray;
89 return;
90 } else {
91 warn $self->class, " required params ", map { $_->dump(2) } @required if $self->debug;
92 }
93
94 my $class = $self->class;
95
96 $self->load_class( $class );
97
98 my $default = clone $self->params; # XXX we really don't want to modify params!
99
100 my $config_params = {};
101 $config_params = $self->config($class);
102 warn "# $class config = ",dump( $config_params ) if $self->debug;
103
104 my $form;
105
106 sub select_values {
107 my ( $name, $attr_type, $values ) = @_;
108 my $options = join("\n",
109 map {
110 my $v = ref($_) eq 'HASH' ? $_->{$name} : $_;
111 qq|<option value="$v">$v</option>| if $v;
112 } @$values
113 );
114 qq|<select title="$attr_type" name="$name">$options</select>| if $options;
115 }
116
117 foreach my $checkbox ( split(/\s+/, $default->{'frey-checkboxes'} ) ) {
118 next if defined $default->{ $checkbox };
119
120 $default->{ $checkbox } = 0;
121 $self->params->{ $checkbox } = 0;
122 warn "# checkbox $checkbox not ticked";
123 }
124
125 my @checkboxes;
126
127 foreach my $name (
128 grep {
129 ! $class->meta->get_attribute($_)->is_lazy
130 && ! defined $default->{$_}
131 } $self->attributes
132 ) {
133 my $attr_type = '';
134 my $type = $name =~ m/^pass/ ? 'password' : 'text';
135 my $label = $name;
136 my $label_title = '';
137 my $value_html = '';
138
139 my $attr = $class->meta->get_attribute( $name );
140 $attr_type = $attr->type_constraint->name if $attr->has_type_constraint;
141
142 my $value =
143 defined $default->{$name} ? $default->{$name} :
144 $attr->has_default ? $attr->default( $name ) :
145 '';
146
147 if ( ref($config_params) eq 'HASH' ) {
148 $value = $config_params->{$name};
149 } elsif ( ref($config_params) eq 'ARRAY' ) {
150 $value_html = select_values( $name, $attr_type, $config_params );
151 $default->{$name} = $config_params->[0]->{$name};
152 } elsif ( $attr->has_type_constraint && $attr->type_constraint->can('values') ) {
153 $value_html = select_values( $name, $attr_type, $attr->type_constraint->values );
154 } elsif ( $attr_type =~ m{^Bool} ) {
155 my $suffix = '';
156 $suffix = ' checked' if $value;
157 $value_html = qq|<input type="checkbox" name="$name" title="$attr_type" value="$value"$suffix>|;
158 push @checkboxes, $name;
159 } elsif ( $attr_type !~ m{^(Str|Int)$} ) {
160 $value_html = qq|<textarea name="$name" title="$attr_type">$value</textarea>|;
161 }
162
163 $label_title = qq| title="| . $attr->documentation . qq|"| if $attr->has_documentation;
164
165 $default->{$name} = $value unless defined $default->{$name};
166
167 $value_html = qq|<input type="$type" name="$name" title="$attr_type" value="$value">| unless $value_html;
168
169 # warn "# required $name ", $class->meta->get_attribute( $name )->dump( 2 );
170 $form .= qq|<label for="$name"$label_title>$label</label>| . $value_html;
171 }
172 $form .= qq|<input type="hidden" name="frey-checkboxes" value="| . join(' ', @checkboxes) . qq|">| if @checkboxes;
173
174 my $html;
175
176 $html = qq|
177 <h1>$class params</h1>
178 <form method="post">
179 $form
180 <input type="submit" value="Run $class">
181 </form>
182 | if $form;
183
184 $self->add_status({
185 $self->class => {
186 params => $self->params,
187 config_params => $config_params,
188 default => $default
189 },
190 });
191
192 return ($html,$default) if wantarray;
193 return $html;
194 }
195
196 1;

  ViewVC Help
Powered by ViewVC 1.1.26