1use warnings;
2use strict;
3
4package Jifty::Collection;
5
6use base qw/Jifty::Object Jifty::DBI::Collection Class::Accessor::Fast/;
7use Data::Page;
8
9=head1 NAME
10
11Jifty::Collection - Collection of Jifty::Record objects
12
13=head1 SYNOPSIS
14
15  package Foo::Model::BarCollection
16  use base qw/Jifty::Collection/;
17
18=head1 DESCRIPTION
19
20This is a wrapper over L<Jifty::DBI::Collection> that at the same time
21is a L<Jifty::Object>.  To use it, subclass it.
22
23Alternatively, an 'anonymous' collection can be made by creating a new
24C<Jifty::Collection> object, and calling
25C<record_class('Application::Model::Foo')> or similar on it.
26
27In addition, each L<Jifty::Collection> includes a L<Data::Page> object
28to help with calculations related to paged data.  You should B<not>
29call the C<first_row> and C<rows_per_page> methods from
30L<Jifty::DBI::Collection> on a L<Jifty::Collection>.  Instead, if
31you'd like to use paging, you should use the C<set_page_info> method
32to B<set> the number of records per page and first record on the
33current page, and you should use the L<Data::Page> object returned by
34the C<pager> method to B<get> information related to paging.
35
36=head1 MODEL
37
38=head2 pager
39
40Returns a L<Data::Page> object associated with this collection.  This
41object defaults to 10 entries per page.  You should use only use
42L<Data::Page> methods on this object to B<get> information about
43paging, not to B<set> it; use C<set_page_info> to set paging
44information.
45
46=head2 results_are_readable
47
48If your results from the query are guaranteed to be readable by
49current_user, you can create the collection with
50C<< results_are_readable => 1 >>.  This causes check_read_rights to bypass
51normal current_user_can checks.
52
53=cut
54
55__PACKAGE__->mk_accessors(qw(results_are_readable));
56
57=head2 as_search_action PARAMHASH
58
59Returns the L<Jifty::Action::Record::Search> action for the model
60associated with this collection.
61
62The PARAMHASH allows you to add additional parameters to pass to
63L<Jifty::Web/new_action>.
64
65=cut
66
67sub as_search_action {
68    my $self = shift;
69    return $self->record_class->as_search_action(@_);
70}
71
72=head2 add_record
73
74If L</results_are_readable> is false, only add records to the
75collection that we can read (by checking
76L<Jifty::Record/check_read_rights>). Otherwise, make sure all records
77added are readable.
78
79=cut
80
81sub add_record {
82    my $self = shift;
83    my ($record) = (@_);
84
85    # If results_are_readable is set, guarantee that they are
86    $record->_is_readable(1)
87        if $self->results_are_readable;
88
89    # Only add a record if results_are_readable or the user has read rights
90    $self->SUPER::add_record($record)
91        if $self->results_are_readable || $record->check_read_rights;
92}
93
94# Overrides the _init method of Jifty::DBI::Collection and is called by new.
95# This does the following:
96#
97#  - Sets up the current user
98#  - Sets up the record class, if given as an argument
99#  - Sets up results_are_readable, if given as an argument
100#  - Sets up the table used for storage
101#
102sub _init {
103    my $self = shift;
104    my %args = (
105        record_class         => undef,
106        current_user         => undef,
107        results_are_readable => undef,
108        @_
109    );
110
111    # Setup the current user, record class, results_are_readable
112    $self->_get_current_user(%args);
113    $self->record_class( $args{record_class} ) if defined $args{record_class};
114    $self->results_are_readable( $args{results_are_readable} );
115
116    # Bad stuff, we really need one of these
117    unless ( $self->current_user ) {
118        Carp::confess("Collection created without a current user");
119    }
120
121    # Setup the table and call the super-implementation
122    $self->table( $self->new_item->table() );
123    $self->SUPER::_init(%args);
124}
125
126=head2 implicit_clauses
127
128Defaults to ordering by the C<id> column.
129
130=cut
131
132sub implicit_clauses {
133    my $self = shift;
134    $self->order_by( column => 'id', order => 'asc' );
135}
136
137sub _new_record_args {
138    my $self = shift;
139    return ( current_user => $self->current_user );
140}
141
142sub _new_collection_args {
143    my $self = shift;
144    return ( current_user => $self->current_user );
145}
146
147=head2 jifty_serialize_format
148
149This returns an array reference of the individual records that make up this
150collection.
151
152=cut
153
154sub jifty_serialize_format {
155    my $records = shift->items_array_ref;
156
157    return [ map { $_->jifty_serialize_format(@_) } @$records ];
158}
159
160=head1 SEE ALSO
161
162L<Jifty::DBI::Collection>, L<Jifty::Object>, L<Jifty::Record>
163
164=head1 LICENSE
165
166Jifty is Copyright 2005-2010 Best Practical Solutions, LLC.
167Jifty is distributed under the same terms as Perl itself.
168
169=cut
170
1711;
172