3 # Copyright ByWater Solutions 2014
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 3 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 use List::MoreUtils qw( none );
30 Koha::Objects - Koha Object set base class
35 my @objects = Koha::Objects->search({ borrowernumber => $borrowernumber});
39 This class must be subclassed.
47 =head3 Koha::Objects->new();
49 my $object = Koha::Objects->new();
57 bless( $self, $class );
60 =head3 Koha::Objects->_new_from_dbic();
62 my $object = Koha::Objects->_new_from_dbic( $resultset );
67 my ( $class, $resultset ) = @_;
68 my $self = { _resultset => $resultset };
70 bless( $self, $class );
73 =head3 Koha::Objects->find();
75 Similar to DBIx::Class::ResultSet->find this method accepts:
76 \%columns_values | @pk_values, { key => $unique_constraint, %attrs }?
77 Strictly speaking, columns_values should only refer to columns under an
80 my $object = Koha::Objects->find( { col1 => $val1, col2 => $val2 } );
81 my $object = Koha::Objects->find( $id );
82 my $object = Koha::Objects->find( $idpart1, $idpart2, $attrs ); # composite PK
87 my ( $self, @pars ) = @_;
89 croak 'Cannot use "->find" in list context' if wantarray;
91 return if !@pars || none { defined($_) } @pars;
93 my $result = $self->_resultset()->find( @pars );
95 return unless $result;
97 my $object = $self->object_class()->_new_from_dbic( $result );
102 =head3 Koha::Objects->find_or_create();
104 my $object = Koha::Objects->find_or_create( $attrs );
109 my ( $self, $params ) = @_;
111 my $result = $self->_resultset->find_or_create($params);
113 return unless $result;
115 my $object = $self->object_class->_new_from_dbic($result);
120 =head3 Koha::Objects->search();
122 my @objects = Koha::Objects->search($params);
127 my ( $self, $params, $attributes ) = @_;
130 my @dbic_rows = $self->_resultset()->search($params, $attributes);
132 return $self->_wrap(@dbic_rows);
136 my $class = ref($self) ? ref($self) : $self;
137 my $rs = $self->_resultset()->search($params, $attributes);
139 return $class->_new_from_dbic($rs);
143 =head3 search_related
145 my @objects = Koha::Objects->search_related( $rel_name, $cond?, \%attrs? );
146 my $objects = Koha::Objects->search_related( $rel_name, $cond?, \%attrs? );
148 Searches the specified relationship, optionally specifying a condition and attributes for matching records.
153 my ( $self, $rel_name, @params ) = @_;
155 return if !$rel_name;
157 my @dbic_rows = $self->_resultset()->search_related($rel_name, @params);
158 return if !@dbic_rows;
159 my $object_class = _get_objects_class( $dbic_rows[0]->result_class );
161 eval "require $object_class";
162 return _wrap( $object_class, @dbic_rows );
165 my $rs = $self->_resultset()->search_related($rel_name, @params);
167 my $object_class = _get_objects_class( $rs->result_class );
169 eval "require $object_class";
170 return _new_from_dbic( $object_class, $rs );
174 =head3 search_for_api
176 my $objects = Koha::Objects->search_for_api( $c );
178 Searches for objects given a controller object I<$c>.
183 my ( $self, $c ) = @_;
185 my $args = $c->validation->output;
188 # Extract reserved params
189 my ( $filtered_params, $reserved_params ) = $c->extract_reserved_params($args);
191 # Merge sorting into query attributes
192 $c->dbic_merge_sorting(
194 attributes => $attributes,
195 params => $reserved_params
199 # Merge pagination into query attributes
200 $c->dbic_merge_pagination(
202 attributes => $attributes,
203 params => $reserved_params
208 my $objects = $self->search( $filtered_params, $attributes );
209 $c->add_pagination_headers({ total => $objects->count, params => $args })
210 if $objects->is_paged;
215 =head2 _build_query_params_from_api
217 my $params = _build_query_params_from_api( $filtered_params, $reserved_params );
219 Builds the params for searching on DBIC based on the selected matching algorithm.
220 Valid options are I<contains>, I<starts_with>, I<ends_with> and I<exact>. Default is
221 I<contains>. If other value is passed, a Koha::Exceptions::WrongParameter exception
226 sub _build_query_params_from_api {
228 my ( $filtered_params, $reserved_params ) = @_;
231 my $match = $reserved_params->{_match} // 'contains';
233 foreach my $param ( keys %{$filtered_params} ) {
234 if ( $match eq 'contains' ) {
236 { like => '%' . $filtered_params->{$param} . '%' };
238 elsif ( $match eq 'starts_with' ) {
239 $params->{$param} = { like => $filtered_params->{$param} . '%' };
241 elsif ( $match eq 'ends_with' ) {
242 $params->{$param} = { like => '%' . $filtered_params->{$param} };
244 elsif ( $match eq 'exact' ) {
245 $params->{$param} = $filtered_params->{$param};
248 Koha::Exceptions::WrongParameter->throw(
249 "Invalid value for _match param ($match)");
258 my $object = Koha::Objects->search({}, { rows => 1 })->single
260 Returns one and only one object that is part of this set.
261 Returns undef if there are no objects found.
263 This is optimal as it will grab the first returned result without instantiating
267 http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/Manual/Cookbook.pod#Retrieve_one_and_only_one_row_from_a_resultset
274 my $single = $self->_resultset()->single;
275 return unless $single;
277 return $self->object_class()->_new_from_dbic($single);
280 =head3 Koha::Objects->next();
282 my $object = Koha::Objects->next();
284 Returns the next object that is part of this set.
285 Returns undef if there are no more objects to return.
292 my $result = $self->_resultset()->next();
293 return unless $result;
295 my $object = $self->object_class()->_new_from_dbic( $result );
300 =head3 Koha::Objects->last;
302 my $object = Koha::Objects->last;
304 Returns the last object that is part of this set.
305 Returns undef if there are no object to return.
312 my $count = $self->_resultset->count;
313 return unless $count;
315 my ( $result ) = $self->_resultset->slice($count - 1, $count - 1);
317 my $object = $self->object_class()->_new_from_dbic( $result );
324 =head3 Koha::Objects->reset();
326 Koha::Objects->reset();
328 resets iteration so the next call to next() will start agein
329 with the first object in a set.
336 $self->_resultset()->reset();
341 =head3 Koha::Objects->as_list();
343 Koha::Objects->as_list();
345 Returns an arrayref of the objects in this set.
352 my @dbic_rows = $self->_resultset()->all();
354 my @objects = $self->_wrap(@dbic_rows);
356 return wantarray ? @objects : \@objects;
359 =head3 Koha::Objects->unblessed
361 Returns an unblessed representation of objects.
368 return [ map { $_->unblessed } $self->as_list ];
371 =head3 Koha::Objects->get_column
373 Return all the values of this set for a given column
378 my ($self, $column_name) = @_;
379 return $self->_resultset->get_column( $column_name )->all;
382 =head3 Koha::Objects->TO_JSON
384 Returns an unblessed representation of objects, suitable for JSON output.
391 return [ map { $_->TO_JSON } $self->as_list ];
394 =head3 Koha::Objects->_wrap
396 wraps the DBIC object in a corresponding Koha object
401 my ( $self, @dbic_rows ) = @_;
403 my @objects = map { $self->object_class->_new_from_dbic( $_ ) } @dbic_rows;
408 =head3 Koha::Objects->_resultset
410 Returns the internal resultset or creates it if undefined
418 $self->{_resultset} ||=
419 Koha::Database->new()->schema()->resultset( $self->_type() );
421 return $self->{_resultset};
424 return Koha::Database->new()->schema()->resultset( $self->_type() );
428 sub _get_objects_class {
432 if( $type->can('koha_objects_class') ) {
433 return $type->koha_objects_class;
435 $type =~ s|Schema::Result::||;
441 my @columns = Koha::Objects->columns
443 Return the table columns
449 return Koha::Database->new->schema->resultset( $class->_type )->result_source->columns;
454 The autoload method is used call DBIx::Class method on a resultset.
456 Important: If you plan to use one of the DBIx::Class methods you must provide
457 relevant tests in t/db_dependent/Koha/Objects.t
458 Currently count, pager, update and delete are covered.
463 my ( $self, @params ) = @_;
465 my @known_methods = qw( count is_paged pager update delete result_class single slice );
466 my $method = our $AUTOLOAD;
469 carp "The method $method is not covered by tests" and return unless grep {/^$method$/} @known_methods;
470 my $r = eval { $self->_resultset->$method(@params) };
472 carp "No method $method found for " . ref($self) . " " . $@;
480 The _type method must be set for all child classes.
481 The value returned by it should be the DBIC resultset name.
482 For example, for holds, _type should return 'Reserve'.
490 This method must be set for all child classes.
491 The value returned by it should be the name of the Koha
492 object class that is returned by this class.
493 For example, for holds, object_class should return 'Koha::Hold'.
503 Kyle M Hall <kyle@bywatersolutions.com>