r31500@martha (orig r1229): purge | 2009-09-11 05:51:11 -0400
[catagits/Reaction.git] / lib / Reaction / UI / Controller / Collection.pm
index 3c815a8..38cd61d 100644 (file)
@@ -1,18 +1,25 @@
 package Reaction::UI::Controller::Collection;
 
-use strict;
-use warnings;
 use base 'Reaction::UI::Controller';
 use Reaction::Class;
 
 use aliased 'Reaction::UI::ViewPort::Collection::Grid';
-use aliased 'Reaction::UI::ViewPort::Object';
 
-has model_name => (isa => 'Str', is => 'rw', required => 1);
-has collection_name => (isa => 'Str', is => 'rw', required => 1);
+__PACKAGE__->config(
+  action => {
+    list => { Chained => 'base', PathPart => '' },
+    object => { Chained => 'base', PathPart => 'id' },
+    view => { Chained => 'object', },
+  },
+);
 
-has action_viewport_map => (isa => 'HashRef', is => 'rw', lazy_build => 1);
-has action_viewport_args => (isa => 'HashRef', is => 'rw', lazy_build => 1);
+with(
+  'Reaction::UI::Controller::Role::GetCollection',
+  'Reaction::UI::Controller::Role::Action::Simple',
+  'Reaction::UI::Controller::Role::Action::Object',
+  'Reaction::UI::Controller::Role::Action::View',
+  'Reaction::UI::Controller::Role::Action::List'
+);
 
 has default_member_actions => (
   isa => 'ArrayRef',
@@ -30,34 +37,34 @@ sub _build_default_member_actions { ['view'] }
 
 sub _build_default_collection_actions { [] }
 
-sub _build_action_viewport_map {
-  my $self = shift;
-  my %map;
-  $map{list} = Grid;
-  $map{view} = Object; #if grep {$_ eq 'view'} @{$self->default_member_actions};
-  return \%map;
-}
+around _build_action_viewport_map => sub {
+  my $orig = shift;
+  my $map = shift->$orig( @_ );
+  $map->{list} = Grid;
+  return $map;
+};
 
-sub _build_action_viewport_args {
+around _build_action_viewport_args => sub {
+  my $orig = shift;
   my $self = shift;
   my $args = { list => { Member => {} } };
 
-  my $m_protos = $args->{list}{Member}{action_prototypes} = {};
-  for my $action_name( @{ $self->default_member_actions }){
-    my $label = ucfirst(join(' ', split(/_/, $action_name)));
-    my $proto = $self->_build_member_action_prototype($label, $action_name);
-    $m_protos->{$action_name} = $proto;
-  }
+   my $m_protos = $args->{list}{Member}{action_prototypes} = {};
+   for my $action_name( @{ $self->default_member_actions }){
+     my $label = join(' ', map { ucfirst } split(/_/, $action_name));
+     my $proto = $self->_build_member_action_prototype($label, $action_name);
+     $m_protos->{$action_name} = $proto;
+   }
 
-  my $c_protos = $args->{list}{action_prototypes} = {};
-  for my $action_name( @{ $self->default_collection_actions }){
-    my $label = ucfirst(join(' ', split(/_/, $action_name)));
-    my $proto = $self->_build_collection_action_prototype($label, $action_name);
-    $c_protos->{$action_name} = $proto;
-  }
+   my $c_protos = $args->{list}{action_prototypes} = {};
+   for my $action_name( @{ $self->default_collection_actions }){
+     my $label = join(' ', map { ucfirst } split(/_/, $action_name));
+     my $proto = $self->_build_collection_action_prototype($label, $action_name);
+     $c_protos->{$action_name} = $proto;
+   }
 
   return $args;
-}
+};
 
 sub _build_member_action_prototype {
   my ($self, $label, $action_name) = @_;
@@ -81,56 +88,21 @@ sub _build_collection_action_prototype {
   };
 }
 
-#XXX candidate for futre optimization, should cache reader?
-sub get_collection {
-  my ($self, $c) = @_;
-  my $model = $c->model( $self->model_name );
-  confess "Failed to find Catalyst model named: " . $self->model_name
-    unless $model;
-  my $collection = $self->collection_name;
-  if( my $meth = $model->can( $collection ) ){
-    return $model->$meth;
-  } elsif ( my $meta = $model->can('meta') ){
-    if ( my $attr = $model->$meta->find_attribute_by_name($collection) ) {
-      my $reader = $attr->get_read_method;
-      return $model->$reader;
-    }
-  }
-  confess "Failed to find collection $collection";
-}
 
-sub base :Action :CaptureArgs(0) {
+sub base :CaptureArgs(0) {
   my ($self, $c) = @_;
 }
 
-sub object :Chained('base') :PathPart('id') :CaptureArgs(1) {
-  my ($self, $c, $key) = @_;
-  my $object = $self->get_collection($c)->find($key);
-  $c->detach("/error_404") unless $object;
-  $c->stash(object => $object);
-}
-
-sub list :Chained('base') :PathPart('') :Args(0) {
-  my ($self, $c) = @_;
-  my $collection = $c->stash->{collection} || $self->get_collection($c);
-  $self->basic_page($c, { collection => $collection });
-}
-
-sub view :Chained('object') :Args(0) {
-  my ($self, $c) = @_;
-  $self->basic_page($c, { model => $c->stash->{object} });
-}
+##DEPRECATED ACTION
 
 sub basic_page {
-  my ($self, $c, $vp_args) = @_;
-  my $action_name = $c->stack->[-1]->name;
-  my $vp = $self->action_viewport_map->{$action_name},
-  my $args = $self->merge_config_hashes
-    (
-     $vp_args || {},
-     $self->action_viewport_args->{$action_name} || {} ,
-    );
-  return $self->push_viewport($vp, %$args);
+  my( $self, $c, @args) = @_;
+  if( $c->debug ){
+    my ($package,undef,$line,$sub_name,@rest) = caller(1);
+    my $message = "The method 'basic_page', called from sub '${sub_name}' in package ${package} at line ${line} is deprecated. Please use 'setup_viewport' instead.";
+    $c->log->debug( $message );
+  }
+  $self->setup_viewport( $c, @args );
 }
 
 1;
@@ -146,48 +118,25 @@ Reaction::UI::Controller
 Controller class used to make displaying collections easier.
 Inherits from L<Reaction::UI::Controller>.
 
-=head1 ATTRIBUTES
-
-=head2 model_name
+=head1 ROLES CONSUMED
 
-The name of the model this controller will use as it's data source. Should be a
-name that can be passed to C<$C-E<gt>model>
+This role also consumes the following roles:
 
-=head2 collection_name
+=over4
 
-The name of the collection whithin the model that this Controller will be
-utilizing.
+=item L<Reaction::UI::Controller::Role::Action::GetCollection>
 
-=head2 action_viewport_map
+=item L<Reaction::UI::Controller::Role::Action::Simple>
 
-=over 4
+=item L<Reaction::UI::Controller::Role::Action::Object>
 
-=item B<_build_action_viewport_map> - Provided builder method, see METHODS
+=item L<Reaction::UI::Controller::Role::Action::List>
 
-=item B<has_action_viewport_map> - Auto generated predicate
-
-=item B<clear_action_viewport_map>- Auto generated clearer method
+=item L<Reaction::UI::Controller::Role::Action::View>
 
 =back
 
-Read-write lazy building hashref. The keys should match action names in the
-Controller and the value should be the ViewPort class that this action should
-use. See method C<basic_page> for more info.
-
-=head2 action_viewport_args
-
-Read-write lazy building hashref. Additional ViewPort arguments for the action
-named as the key in the controller.  See method C<basic_page> for more info.
-
-=over 4
-
-=item B<_build_action_viewport_args> - Provided builder method, see METHODS
-
-=item B<has_action_viewport_args> - Auto generated predicate
-
-=item B<clear_action_viewport_args>- Auto generated clearer method
-
-=back
+=head1 ATTRIBUTES
 
 =head2 default_member_actions
 
@@ -198,7 +147,7 @@ target e.g. update,delete) to be enabled by default. By default, this is only
 
 =over 4
 
-=item B<_build_defualt_member_actions> - Provided builder method, see METHODS
+=item B<_build_default_member_actions> - Provided builder method, see METHODS
 
 =item B<has_default_member_actions> - Auto generated predicate
 
@@ -215,7 +164,7 @@ is only empty.
 
 =over 4
 
-=item B<_build_defualt_member_actions> - Provided builder method, see METHODS
+=item B<_build_default_member_actions> - Provided builder method, see METHODS
 
 =item B<has_default_member_actions> - Auto generated predicate
 
@@ -225,16 +174,9 @@ is only empty.
 
 =head1 METHODS
 
-=head2 get_collection $c
-
-Returns an instance of the collection this controller uses.
-
 =head2 _build_action_viewport_map
 
-Provided builder for C<action_viewport_map>. Returns a hash containing:
-
-    list => 'Reaction::UI::ViewPort::Collection::Grid',
-    view => 'Reaction::UI::ViewPort::Object',
+Set C<list> to L<Reaction::UI::ViewPort::Collection::Grid>
 
 =head2 _build_action_viewport_args
 
@@ -269,11 +211,7 @@ based on the action, current captures.
 
 =head2 basic_page $c, \%vp_args
 
-Accepts two arguments, context, and a hashref of viewport arguments. It will
-automatically determine the action name using the catalyst stack and call
-C<push_viewport> with the ViewPort class name contained in the
-C<action_viewport_map> with a set of options determined by merging C<$vp_args>
-and the arguments contained in C<action_viewport_args>, if any.
+Deprecated alias to C<setup_viewport>.
 
 =head1 ACTIONS
 
@@ -283,27 +221,15 @@ Chain link, no-op.
 
 =head2 list
 
-Chain link, chained to C<base>. C<list> fetches the collection for the model
-and calls C<basic_page> with a single argument, C<collection>.
-
-The default ViewPort for this action is C<Reaction::UI::ViewPort::ListView> and
-can be changed by altering the C<action_viewport_map> attribute hash.
+Chained to C<base>. See L<Reaction::UI::Controller::Role::Action::List>
 
 =head2 object
 
-Chain link, chained to C<base>, captures one argument, 'id'. Attempts to find
-a single object by searching for a member of the current collection which has a
-Primary Key or Unique constraint matching that argument. If the object is found
-it is stored in the stash under the C<object> key.
+Chained to C<base>. See L<Reaction::UI::Controller::Role::Action::Object>
 
 =head2 view
 
-Chain link, chained to C<object>. Calls C<basic page> with one argument,
-C<model>, which contains an instance of the object fetched by the C<object>
-action link.
-
-The default ViewPort for this action is C<Reaction::UI::ViewPort::Object> and
-can be changed by altering the C<action_viewport_map> attribute hash.
+Chained to C<object>. See L<Reaction::UI::Controller::Role::Action::View>
 
 =head1 SEE ALSO