order_by fixes including enable_order_by and coerce_order_by
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / Collection / Role / Order.pm
1 package Reaction::UI::ViewPort::Collection::Role::Order;
2
3 use Reaction::Role;
4
5 use namespace::clean -except => [ qw(meta) ];
6
7 has enable_order_by => (is => 'rw', isa => 'ArrayRef');
8 has coerce_order_by => (isa => 'HashRef', is => 'rw');
9
10 has order_by => (
11   isa => 'Str',
12   is => 'rw',
13   trigger_adopt('order_by'),
14   clearer => 'clear_order_by'
15 );
16
17 has order_by_desc => (
18   isa => 'Int',
19   is => 'rw',
20   trigger_adopt('order_by'),
21   lazy_build => 1
22 );
23
24 sub _build_order_by_desc { 0 }
25
26 sub adopt_order_by {
27   shift->clear_current_collection;
28 }
29
30 sub can_order_by {
31   my ($self,$order_by) = @_;
32   return 1 unless $self->has_enable_order_by;
33   return scalar grep { $order_by eq $_ } @{ $self->enable_order_by };
34 }
35
36 sub _order_search_attrs {
37   my $self = shift;
38   my %attrs;
39   if ($self->has_order_by) {
40     my $order_by = $self->order_by;
41     if( $self->has_coerce_order_by ){
42       $order_by = $self->coerce_order_by->{$order_by}
43         if exists $self->coerce_order_by->{$order_by};
44     }
45     my $key = $self->order_by_desc ? '-desc' : '-asc';
46     $attrs{order_by} = { $key => $order_by };
47   }
48   return \%attrs;
49 }
50
51 after clear_order_by => sub {
52   my ($self) = @_;
53   $self->order_by_desc(0);
54   $self->clear_current_collection;
55 };
56
57 around _build_current_collection => sub {
58   my $orig = shift;
59   my ($self) = @_;
60   my $collection = $orig->(@_);
61   return $collection->where(undef, $self->_order_search_attrs);
62 };
63
64 around accept_events => sub { ('order_by', 'order_by_desc', shift->(@_)); };
65
66
67
68 1;