shallow copying req->params
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / TimeRangeCollection.pm
CommitLineData
1a1d8df4 1#package Reaction::UI::ViewPort::TimeRangeCollection;
2#
3# Marked commented out because unused and unmaintained. Should probably
4# be turned into a complex viewport example later instead --mst
5#
6#use Reaction::Class;
7#use Reaction::Types::DateTime;
8#use Moose::Util::TypeConstraints ();
9#use DateTime::Event::Recurrence;
10#use aliased 'Reaction::UI::ViewPort::Field::String';
11#use aliased 'Reaction::UI::ViewPort::Field::DateTime';
12#use aliased 'Reaction::UI::ViewPort::Field::HiddenArray';
13#use aliased 'Reaction::UI::ViewPort::Field::TimeRange';
14#
15#class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
16#
17# #has '+layout' => (default => 'timerangecollection');
18#
19# has '+column_order' => (
20# default => sub{[ qw/ time_from time_to pattern repeat_from repeat_to / ]},
21# );
22#
23# has time_from => (
24# isa => 'Reaction::UI::ViewPort::Field::DateTime',
25# is => 'rw', lazy_build => 1,
26# );
27#
28# has time_to => (
29# isa => 'Reaction::UI::ViewPort::Field::DateTime',
30# is => 'rw', lazy_build => 1,
31# );
32#
33# has repeat_from => (
34# isa => 'Reaction::UI::ViewPort::Field::DateTime',
35# is => 'rw', lazy_build => 1,
36# );
37#
38# has repeat_to => (
39# isa => 'Reaction::UI::ViewPort::Field::DateTime',
40# is => 'rw', lazy_build => 1,
41# );
42#
43# has pattern => (
44# isa => 'Reaction::UI::ViewPort::Field::String',
45# # valid_values => [ qw/none daily weekly monthly/ ],
46# is => 'rw', lazy_build => 1,
47# );
48#
49# has range_vps => (isa => 'ArrayRef', is => 'rw', lazy_build => 1,);
50#
51# has max_range_vps => (isa => 'Int', is => 'rw', lazy_build => 1,);
52#
53# has error => (
54# isa => 'Str',
55# is => 'rw',
56# required => 0,
57# );
58#
59# has field_names => (
60# isa => 'ArrayRef', is => 'rw',
61# lazy_build => 1, clearer => 'clear_field_names',
62# );
63#
64# has _field_map => (
65# isa => 'HashRef', is => 'rw', init_arg => 'fields',
66# clearer => '_clear_field_map',
67# predicate => '_has_field_map',
68# lazy_build => 1,
69# );
70#
71# has on_next_callback => (
72# isa => 'CodeRef',
73# is => 'rw',
74# predicate => 'has_on_next_callback',
75# );
76#
77# implements fields => as { shift->_field_map };
78#
79# implements _build_range_vps => as { [] };
80#
81# implements spanset => as {
82# my ($self) = @_;
83# my $spanset = DateTime::SpanSet->empty_set;
84# $spanset = $spanset->union($_->value) for @{$self->range_vps};
85# return $spanset;
86# };
87#
88# implements range_strings => as {
89# my ($self) = @_;
90# return [ map { $_->value_string } @{$self->range_vps} ];
91# };
92#
93# implements remove_range_vp => as {
94# my ($self, $to_remove) = @_;
95# $self->range_vps([ grep { $_ != $to_remove } @{$self->range_vps} ]);
96# $self->_clear_field_map;
97# $self->clear_field_names;
98# };
99#
100# implements add_range_vp => as {
101# my ($self) = @_;
102# if ($self->can_add) {
103# $self->_clear_field_map;
104# $self->clear_field_names;
105# my @span_info = (
106# $self->time_from->value,
107# $self->time_to->value,
108# (map { $_->has_value ? $_->value : '' }
109# map { $self->$_ } qw/repeat_from repeat_to/),
110# $self->pattern->value,
111# );
112# my $encoded_spanset = join ',', @span_info;
113# my $args = {
114# value_string => $encoded_spanset,
115# parent => $self
116# };
117# my $count = scalar(@{$self->range_vps});
118# my $field = $self->_build_simple_field(TimeRange, 'range-'.$count, $args);
119# my $d = DateTime::Format::Duration->new( pattern => '%s' );
120# if ($d->format_duration( $self->spanset->intersection($field->value)->duration ) > 0) {
121# # XXX - Stop using the stash here?
122# $self->ctx->stash->{warning} = 'Warning: Most recent time range overlaps '.
123# 'with existing time range in this booking.';
124# }
125# #warn "encoded spanset = $encoded_spanset\n";
126# #warn "current range = ".join(', ', (@{$self->range_vps}))."\n";
127# push(@{$self->range_vps}, $field);
128# }
129# };
130#
131# implements _build_field_map => as {
132# my ($self) = @_;
133# my %map;
134# foreach my $field (@{$self->range_vps}) {
135# $map{$field->name} = $field;
136# }
137# foreach my $name (@{$self->column_order}) {
138# $map{$name} = $self->$name;
139# }
140# return \%map;
141# };
142#
143# implements _build_field_names => as {
144# my ($self) = @_;
145# return [
146# (map { $_->name } @{$self->range_vps}),
147# @{$self->column_order}
148# ];
149# };
150#
151# implements can_add => as {
152# my ($self) = @_;
153# my $error;
154# if ($self->time_to->has_value && $self->time_from->has_value) {
155# my $time_to = $self->time_to->value;
156# my $time_from = $self->time_from->value;
157#
158# my ($pattern, $repeat_from, $repeat_to) = ('','','');
159# $pattern = $self->pattern->value if $self->pattern->has_value;
160# $repeat_from = $self->repeat_from->value if $self->repeat_from->has_value;
161# $repeat_to = $self->repeat_to->value if $self->repeat_to->has_value;
162#
163# my $duration = $time_to - $time_from;
164# if ($time_to < $time_from) {
165# $error = 'Please make sure that the Time To is after the Time From.';
166# } elsif ($time_to == $time_from) {
167# $error = 'Your desired booking slot is too small.';
168# } elsif ($pattern && $pattern ne 'none') {
169# my %pattern = (hourly => [ hours => 1 ],
170# daily => [ days => 1 ],
171# weekly => [ days => 7 ],
172# monthly => [ months => 1 ]);
173# my $pattern_comp = DateTime::Duration->compare(
174# $duration, DateTime::Duration->new( @{$pattern{$pattern}} )
175# );
176# if (!$repeat_to || !$repeat_from) {
177# $error = 'Please make sure that you enter a valid range for the '.
178# 'repetition period.';
179# } elsif ($time_to == $time_from) {
180# $error = 'Your desired repetition period is too short.';
181# } elsif ($repeat_to && ($repeat_to < $repeat_from)) {
182# $error = 'Please make sure that the Repeat To is after the Repeat From.';
183# } elsif ( ( ($pattern eq 'hourly') && ($pattern_comp > 0) ) ||
184# ( ($pattern eq 'daily') && ($pattern_comp > 0) ) ||
185# ( ($pattern eq 'weekly') && ($pattern_comp > 0) ) ||
186# ( ($pattern eq 'monthly') && ($pattern_comp > 0) ) ) {
187# $error = "Your repetition pattern ($pattern) is too short for your ".
188# "desired booking length.";
189# }
190# }
191# } else {
192# $error = 'Please complete both the Time To and Time From fields.';
193# }
194# $self->error($error);
195# return !defined($error);
196# };
197#
198# implements _build_simple_field => as {
199# my ($self, $class, $name, $args) = @_;
200# return $class->new(
201# name => $name,
202# location => join('-', $self->location, 'field', $name),
203# ctx => $self->ctx,
204# %$args
205# );
206# };
207#
208# implements _build_time_to => as {
209# my ($self) = @_;
210# return $self->_build_simple_field(DateTime, 'time_to', {});
211# };
212#
213# implements _build_time_from => as {
214# my ($self) = @_;
215# return $self->_build_simple_field(DateTime, 'time_from', {});
216# };
217#
218# implements _build_repeat_to => as {
219# my ($self) = @_;
220# return $self->_build_simple_field(DateTime, 'repeat_to', {});
221# };
222#
223# implements _build_repeat_from => as {
224# my ($self) = @_;
225# return $self->_build_simple_field(DateTime, 'repeat_from', {});
226# };
227#
228# implements _build_pattern => as {
229# my ($self) = @_;
230# return $self->_build_simple_field(String, 'pattern', {});
231# };
232#
233# implements next => as {
234# $_[0]->on_next_callback->(@_);
235# };
236#
237# override accept_events => sub {
238# my $self = shift;
239# ('add_range_vp', ($self->has_on_next_callback ? ('next') : ()), super());
240# };
241#
242# override child_event_sinks => sub {
243# my ($self) = @_;
244# return ((grep { ref($_) =~ 'Hidden' } values %{$self->_field_map}),
245# (grep { ref($_) !~ 'Hidden' } values %{$self->_field_map}),
246# super());
247# };
248#
249# override apply_events => sub {
250# my ($self, $ctx, $events) = @_;
251#
252# # auto-inflate range fields based on number from hidden field
253#
254# my $max = $events->{$self->location.':max_range_vps'};
255# my @range_vps = map {
256# TimeRange->new(
257# name => "range-$_",
258# location => join('-', $self->location, 'field', 'range', $_),
259# ctx => $self->ctx,
260# parent => $self,
261# )
262# } ($max ? (0 .. $max - 1) : ());
263# $self->range_vps(\@range_vps);
264# $self->_clear_field_map;
265# $self->clear_field_names;
266#
267# # call original event handling
268#
269# super();
270#
271# # repack range VPs in case of deletion
272#
273# my $prev_idx = -1;
274#
275# foreach my $vp (@{$self->range_vps}) {
276# my $cur_idx = ($vp->name =~ m/range-(\d+)/);
277# if (($cur_idx - $prev_idx) > 1) {
278# $cur_idx--;
279# my $name = "range-${cur_idx}";
280# $vp->name($name);
281# $vp->location(join('-', $self->location, 'field', $name));
282# }
283# $prev_idx = $cur_idx;
284# }
285# };
286#
287#};
288#
289#1;
290#
291#=head1 NAME
292#
293#Reaction::UI::ViewPort::TimeRangeCollection
294#
295#=head1 SYNOPSIS
296#
297# my $trc = $self->push_viewport(TimeRangeCollection,
298# layout => 'avail_search_form',
299# on_apply_callback => $search_callback,
300# name => 'TRC',
301# );
302#
303#=head1 DESCRIPTION
304#
305#=head1 ATTRIBUTES
306#
307#=head2 can_add
308#
309#=head2 column_order
310#
311#=head2 error
312#
313#=head2 field_names
314#
315#=head2 fields
316#
317#=head2 layout
318#
319#=head2 pattern
320#
321#Typically either: none, daily, weekly or monthly
322#
323#=head2 max_range_vps
324#
325#=head2 range_vps
326#
327#=head2 repeat_from
328#
329#A DateTime field.
330#
331#=head2 repeat_to
332#
333#A DateTime field.
334#
335#=head2 time_from
336#
337#A DateTime field.
338#
339#=head2 time_to
340#
341#A DateTime field.
342#
343#=head1 METHODS
344#
345#=head2 spanset
346#
347#Returns: $spanset consisting of all the TimeRange spans combined
348#
349#=head2 range_strings
350#
351#Returns: ArrayRef of Str consisting of the value_strings of all TimeRange
352#VPs
353#
354#=head2 remove_range_vp
355#
356#Arguments: $to_remove
357#
358#=head2 add_range_vp
359#
360#Arguments: $to_add
361#
362#=head2 _build_simple_field
363#
364#Arguments: $class, $name, $args
365#where $class is an object, $name is a scalar and $args is a hashref
366#
367#=head2 next
368#
369#=head2 on_next_callback
370#
371#=head2 clear_field_names
372#
373#=head2 child_event_sinks
374#
375#=head1 SEE ALSO
376#
377#=head2 L<Reaction::UI::ViewPort>
378#
379#=head2 L<Reaction::UI::ViewPort::Field::TimeRange>
380#
381#=head2 L<Reaction::UI::ViewPort::Field::DateTime>
382#
383#=head2 L<DateTime::Event::Recurrence>
384#
385#=head1 AUTHORS
386#
387#See L<Reaction::Class> for authors.
388#
389#=head1 LICENSE
390#
391#See L<Reaction::Class> for the license.
392#
393#=cut
7adfd53f 394
6ab43711 3951;