File Coverage

blib/lib/Maypole/Model/Base.pm
Criterion Covered Total %
statement 25 72 34.7
branch 0 14 0.0
condition 0 5 0.0
subroutine 8 26 30.7
pod 16 16 100.0
total 49 133 36.8


line stmt bran cond sub pod time code
1             package Maypole::Model::Base;
2 1     1   1459 use strict;
  1         2  
  1         33  
3              
4 1     1   6 use Maypole::Constants;
  1         2  
  1         53  
5 1     1   967 use attributes ();
  1         11080  
  1         401  
6              
7             # don't know why this is a global - drb
8             our %remember;
9              
10             sub MODIFY_CODE_ATTRIBUTES {
11 4     4   130 shift; # class name not used
12 4         8 my ($coderef, @attrs) = @_;
13 4         20 $remember{$coderef} = [$coderef, \@attrs];
14              
15             # previous version took care to return an empty array, not sure why,
16             # but shall cargo cult it until know better
17 4         13 return;
18             }
19              
20 0 0   0     sub FETCH_CODE_ATTRIBUTES { @{ $remember{$_[1]}->[1] || [] } }
  0            
21              
22             sub CLONE {
23             # re-hash %remember
24 0     0     for my $key (keys %remember) {
25 0           my $value = delete $remember{$key};
26 0           $key = $value->[0];
27 0           $remember{$key} = $value;
28             }
29             }
30              
31             sub process {
32 0     0 1   my ( $class, $r ) = @_;
33 0           my $method = $r->action;
34              
35 0           $r->{template} = $method;
36 0           my $obj = $class->fetch_objects($r);
37 0 0         $r->objects([$obj]) if $obj;
38            
39 0           $class->$method( $r, $obj, @{ $r->{args} } );
  0            
40             }
41              
42             sub list_columns {
43 0     0 1   shift->display_columns;
44             }
45              
46             sub display_columns {
47 0     0 1   sort shift->columns;
48             }
49              
50             =head1 NAME
51              
52             Maypole::Model::Base - Base class for model classes
53              
54             =head1 DESCRIPTION
55              
56             This is the base class for Maypole data models. This is an abstract class
57             that defines the interface, and can't be used directly.
58              
59             =head2 process
60              
61             This is the engine of this module. Given the request object, it populates
62             all the relevant variables and calls the requested action.
63              
64             Anyone subclassing this for a different database abstraction mechanism
65             needs to provide the following methods:
66              
67             =head2 setup_database
68              
69             $model->setup_database($config, $namespace, @data)
70              
71             Uses the user-defined data in C<@data> to specify a database- for
72             example, by passing in a DSN. The model class should open the database,
73             and create a class for each table in the database. These classes will
74             then be Ced. It should also populate C<< $config->tables >> and
75             C<< $config->classes >> with the names of the classes and tables
76             respectively. The classes should be placed under the specified
77             namespace. For instance, C should be mapped to the class
78             C.
79              
80             =head2 class_of
81              
82             $model->class_of($r, $table)
83              
84             This maps between a table name and its associated class.
85              
86             =head2 fetch_objects
87              
88             This class method is passed a request object and is expected to return an
89             object of the appropriate table class from information stored in the request
90             object.
91              
92             =head2 adopt
93              
94             This class method is passed the name of a model class that represensts a table
95             and allows the master model class to do any set-up required.
96              
97             =head2 columns
98              
99             This is a list of all the columns in a table. You may also override
100             see also C
101              
102             =head2 table
103              
104             This is the name of the table.
105              
106             =cut
107              
108 0     0 1   sub class_of { die "This is an abstract method" }
109 0     0 1   sub setup_database { die "This is an abstract method" }
110 0     0 1   sub fetch_objects { die "This is an abstract method" }
111              
112             =head2 Actions
113              
114             =over
115              
116             =item do_edit
117              
118             If there is an object in C<$r-Eobjects>, then it should be edited
119             with the parameters in C<$r-Eparams>; otherwise, a new object should
120             be created with those parameters, and put back into C<$r-Eobjects>.
121             The template should be changed to C, or C if there were any
122             errors. A hash of errors will be passed to the template.
123              
124             =cut
125              
126 0     0 1   sub do_edit { die "This is an abstract method" }
127              
128             =item list
129              
130             The C method should fill C<$r-Eobjects> with all of the
131             objects in the class. You may want to page this using C or
132             similar.
133              
134             =item edit
135              
136             Empty Action.
137              
138             =item view
139              
140             Empty Action.
141              
142             =item index
143              
144             Empty Action, calls list if provided with a table.
145              
146             =back
147              
148             =cut
149              
150             sub list : Exported {
151 0     0 1 0 die "This is an abstract method";
152 1     1   14 }
  1         2  
  1         7  
153              
154 0     0 1 0 sub view : Exported {
155 1     1   158 }
  1         2  
  1         4  
156              
157 0     0 1 0 sub edit : Exported {
158 1     1   128 }
  1         2  
  1         4  
159              
160             sub index : Exported {
161 0     0 1 0 my ( $self, $r ) = @_;
162 0 0       0 if ($r->table) {
163 0         0 $r->template("list");
164 0         0 return $self->list($r);
165             }
166 1     1   164 }
  1         1  
  1         4  
167              
168             =pod
169              
170             Also, see the exported commands in C.
171              
172             =head1 Other overrides
173              
174             Additionally, individual derived model classes may want to override the
175             following methods:
176              
177             =head2 display_columns
178              
179             Returns a list of columns to display in the model. By default returns
180             all columns in alphabetical order. Override this in base classes to
181             change ordering, or elect not to show columns.
182              
183             =head2 list_columns
184              
185             Same as display_columns, only for listings. Defaults to display_columns
186              
187             =head2 column_names
188              
189             Return a hash mapping column names with human-readable equivalents.
190              
191             =cut
192              
193             sub column_names {
194 0     0 1   my $class = shift;
195 0           map {
196 0           my $col = $_;
197 0           $col =~ s/_+(\w)?/ \U$1/g;
198 0           $_ => ucfirst $col
199             } $class->columns;
200             }
201              
202             =head2 is_public
203              
204             should return true if a certain action is supported, or false otherwise.
205             Defaults to checking if the sub has the C<:Exported> attribute.
206              
207             =cut
208              
209             sub is_public {
210 0     0 1   my ( $self, $action, $attrs ) = @_;
211 0           my $cv = $self->can($action);
212 0 0 0       warn "is_public failed . action is $action. self is $self" and return 0 unless $cv;
213              
214 0 0         my %attrs = (ref $attrs) ? %$attrs : map {$_ => 1} $self->method_attrs($action,$cv) ;
  0            
215              
216 0 0         do {
217 0           warn "is_public failed. $action not exported. attributes are : ", %attrs;
218 0           return 0;
219             } unless $attrs{Exported};
220 0           return 1;
221             }
222              
223              
224             =head2 add_model_superclass
225              
226             Adds model as superclass to model classes (if necessary)
227              
228             =cut
229              
230 0     0 1   sub add_model_superclass { return; }
231              
232             =head2 method_attrs
233              
234             Returns the list of attributes defined for a method. Maypole itself only
235             defines the C attribute.
236              
237             =cut
238              
239             sub method_attrs {
240 0     0 1   my ($class, $method, $cv) = @_;
241            
242 0   0       $cv ||= $class->can($method);
243            
244 0 0         return unless $cv;
245            
246 0           my @attrs = attributes::get($cv);
247              
248 0           return @attrs;
249             }
250              
251             =head2 related
252              
253             This can go either in the master model class or in the individual
254             classes, and returns a list of has-many accessors. A brewery has many
255             beers, so C needs to return C.
256              
257             =cut
258              
259 0     0 1   sub related {
260             }
261              
262             1;
263              
264              
265             =head1 SEE ALSO
266              
267             L, L.
268              
269             =head1 AUTHOR
270              
271             Maypole is currently maintained by Aaron Trevena.
272              
273             =head1 AUTHOR EMERITUS
274              
275             Simon Cozens, C
276              
277             Simon Flack maintained Maypole from 2.05 to 2.09
278              
279             Sebastian Riedel, C maintained Maypole from 1.99_01 to 2.04
280              
281             =head1 LICENSE
282              
283             You may distribute this code under the same terms as Perl itself.
284              
285             =cut