1 package C4
::CourseReserves
;
3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 use List
::MoreUtils
qw(any);
23 use C4
::Items
qw(GetItem ModItem);
24 use C4
::Biblio
qw(GetBiblioFromItemNumber);
25 use C4
::Circulation
qw(GetOpenIssue);
27 use vars
qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG @FIELDS);
51 &GetItemCourseReservesInfo
53 %EXPORT_TAGS = ( 'all' => \
@EXPORT_OK );
56 @FIELDS = ( 'itype', 'ccode', 'holdingbranch', 'location' );
61 C4::CourseReserves - Koha course reserves module
65 use C4::CourseReserves;
69 This module deals with course reserves.
75 $course = GetCourse( $course_id );
81 warn whoami
() . "( $course_id )" if $DEBUG;
83 my $query = "SELECT * FROM courses WHERE course_id = ?";
84 my $dbh = C4
::Context
->dbh;
85 my $sth = $dbh->prepare($query);
86 $sth->execute($course_id);
88 my $course = $sth->fetchrow_hashref();
91 SELECT b.* FROM course_instructors ci
92 LEFT JOIN borrowers b ON ( ci.borrowernumber = b.borrowernumber )
95 $sth = $dbh->prepare($query);
96 $sth->execute($course_id);
97 $course->{'instructors'} = $sth->fetchall_arrayref( {} );
104 ModCourse( [ course_id => $id ] [, course_name => $course_name ] [etc...] );
110 warn identify_myself
(%params) if $DEBUG;
112 my $dbh = C4
::Context
->dbh;
115 if ( defined $params{'course_id'} ) {
116 $course_id = $params{'course_id'};
117 delete $params{'course_id'};
125 $query .= ($course_id) ?
' UPDATE ' : ' INSERT ';
126 $query .= ' courses SET ';
128 foreach my $key ( keys %params ) {
129 push( @query_keys, "$key=?" );
130 push( @query_values, $params{$key} );
132 $query .= join( ',', @query_keys );
135 $query .= " WHERE course_id = ?";
136 push( @query_values, $course_id );
139 $dbh->do( $query, undef, @query_values );
141 $course_id = $course_id
142 || $dbh->last_insert_id( undef, undef, 'courses', 'course_id' );
144 EnableOrDisableCourseItems
(
145 course_id
=> $course_id,
146 enabled
=> $params{'enabled'}
154 @courses = GetCourses( [ fieldname => $value ] [, fieldname2 => $value2 ] [etc...] );
160 warn identify_myself
(%params) if $DEBUG;
168 LEFT JOIN course_reserves ON course_reserves.course_id = courses.course_id
169 LEFT JOIN course_items ON course_items.ci_id = course_reserves.ci_id
172 if ( keys %params ) {
176 foreach my $key ( keys %params ) {
177 push( @query_keys, " $key LIKE ? " );
178 push( @query_values, $params{$key} );
181 $query .= join( ' AND ', @query_keys );
184 $query .= " GROUP BY courses.course_id ";
186 my $dbh = C4
::Context
->dbh;
187 my $sth = $dbh->prepare($query);
188 $sth->execute(@query_values);
190 my $courses = $sth->fetchall_arrayref( {} );
192 foreach my $c (@
$courses) {
193 $c->{'instructors'} = GetCourseInstructors
( $c->{'course_id'} );
201 DelCourse( $course_id );
206 my ($course_id) = @_;
208 my $course_reserves = GetCourseReserves
( course_id
=> $course_id );
210 foreach my $res (@
$course_reserves) {
211 DelCourseReserve
( cr_id
=> $res->{'cr_id'} );
215 DELETE FROM course_instructors
218 C4
::Context
->dbh->do( $query, undef, $course_id );
224 C4
::Context
->dbh->do( $query, undef, $course_id );
227 =head2 EnableOrDisableCourseItems
229 EnableOrDisableCourseItems( course_id => $course_id, enabled => $enabled );
231 For each item on reserve for this course,
232 if the course item has no active course reserves,
233 swap the fields for the item to make it 'normal'
236 enabled => 'yes' to enable course items
237 enabled => 'no' to disable course items
241 sub EnableOrDisableCourseItems
{
243 warn identify_myself
(%params) if $DEBUG;
245 my $course_id = $params{'course_id'};
246 my $enabled = $params{'enabled'} || 0;
248 my $lookfor = ( $enabled eq 'yes' ) ?
'no' : 'yes';
250 return unless ( $course_id && $enabled );
251 return unless ( $enabled eq 'yes' || $enabled eq 'no' );
253 my $course_reserves = GetCourseReserves
( course_id
=> $course_id );
255 if ( $enabled eq 'yes' ) {
256 foreach my $course_reserve (@
$course_reserves) {
257 if (CountCourseReservesForItem
(
258 ci_id
=> $course_reserve->{'ci_id'},
262 EnableOrDisableCourseItem
(
263 ci_id
=> $course_reserve->{'ci_id'},
268 if ( $enabled eq 'no' ) {
269 foreach my $course_reserve (@
$course_reserves) {
271 CountCourseReservesForItem
(
272 ci_id
=> $course_reserve->{'ci_id'},
276 EnableOrDisableCourseItem
(
277 ci_id
=> $course_reserve->{'ci_id'},
284 =head2 EnableOrDisableCourseItem
286 EnableOrDisableCourseItem( ci_id => $ci_id );
290 sub EnableOrDisableCourseItem
{
292 warn identify_myself
(%params) if $DEBUG;
294 my $ci_id = $params{'ci_id'};
296 return unless ( $ci_id );
298 my $course_item = GetCourseItem
( ci_id
=> $ci_id );
300 my $info = GetItemCourseReservesInfo
( itemnumber
=> $course_item->{itemnumber
} );
302 my $enabled = any
{ $_->{course
}->{enabled
} eq 'yes' } @
$info;
303 $enabled = $enabled ?
'yes' : 'no';
305 ## We don't want to 'enable' an already enabled item,
306 ## or disable and already disabled item,
307 ## as that would cause the fields to swap
308 if ( $course_item->{'enabled'} ne $enabled ) {
309 _SwapAllFields
($ci_id);
317 C4
::Context
->dbh->do( $query, undef, $enabled, $ci_id );
323 =head2 GetCourseInstructors
325 @$borrowers = GetCourseInstructors( $course_id );
329 sub GetCourseInstructors
{
330 my ($course_id) = @_;
331 warn "C4::CourseReserves::GetCourseInstructors( $course_id )"
335 SELECT * FROM borrowers
336 RIGHT JOIN course_instructors ON ( course_instructors.borrowernumber = borrowers.borrowernumber )
337 WHERE course_instructors.course_id = ?
340 my $dbh = C4
::Context
->dbh;
341 my $sth = $dbh->prepare($query);
342 $sth->execute($course_id);
344 return $sth->fetchall_arrayref( {} );
347 =head2 ModCourseInstructors
349 ModCourseInstructors( mode => $mode, course_id => $course_id, [ cardnumbers => $cardnumbers ] OR [ borrowernumbers => $borrowernumbers );
351 $mode can be 'replace', 'add', or 'delete'
353 $cardnumbers and $borrowernumbers are both references to arrays
355 Use either cardnumbers or borrowernumber, but not both.
359 sub ModCourseInstructors
{
361 warn identify_myself
(%params) if $DEBUG;
363 my $course_id = $params{'course_id'};
364 my $mode = $params{'mode'};
365 my $cardnumbers = $params{'cardnumbers'};
366 my $borrowernumbers = $params{'borrowernumbers'};
368 return unless ($course_id);
370 unless ( $mode eq 'replace'
372 || $mode eq 'delete' );
373 return unless ( $cardnumbers || $borrowernumbers );
374 return if ( $cardnumbers && $borrowernumbers );
376 my ( @cardnumbers, @borrowernumbers );
377 @cardnumbers = @
$cardnumbers if ( ref($cardnumbers) eq 'ARRAY' );
378 @borrowernumbers = @
$borrowernumbers
379 if ( ref($borrowernumbers) eq 'ARRAY' );
381 my $field = (@cardnumbers) ?
'cardnumber' : 'borrowernumber';
382 my @fields = (@cardnumbers) ?
@cardnumbers : @borrowernumbers;
383 my $placeholders = join( ',', ('?') x
scalar @fields );
385 my $dbh = C4
::Context
->dbh;
387 $dbh->do( "DELETE FROM course_instructors WHERE course_id = ?", undef, $course_id )
388 if ( $mode eq 'replace' );
392 if ( $mode eq 'add' || $mode eq 'replace' ) {
394 INSERT INTO course_instructors ( course_id, borrowernumber )
395 SELECT ?, borrowernumber
397 WHERE $field IN ( $placeholders )
401 DELETE FROM course_instructors
403 AND borrowernumber IN (
404 SELECT borrowernumber FROM borrowers WHERE $field IN ( $placeholders )
409 my $sth = $dbh->prepare($query);
411 $sth->execute( $course_id, @fields ) if (@fields);
414 =head2 GetCourseItem {
416 $course_item = GetCourseItem( itemnumber => $itemnumber [, ci_id => $ci_id );
422 warn identify_myself
(%params) if $DEBUG;
424 my $ci_id = $params{'ci_id'};
425 my $itemnumber = $params{'itemnumber'};
427 return unless ( $itemnumber || $ci_id );
429 my $field = ($itemnumber) ?
'itemnumber' : 'ci_id';
430 my $value = ($itemnumber) ?
$itemnumber : $ci_id;
432 my $query = "SELECT * FROM course_items WHERE $field = ?";
433 my $dbh = C4
::Context
->dbh;
434 my $sth = $dbh->prepare($query);
435 $sth->execute($value);
437 my $course_item = $sth->fetchrow_hashref();
440 $query = "SELECT * FROM course_reserves WHERE ci_id = ?";
441 $sth = $dbh->prepare($query);
442 $sth->execute( $course_item->{'ci_id'} );
443 my $course_reserves = $sth->fetchall_arrayref( {} );
445 $course_item->{'course_reserves'} = $course_reserves
446 if ($course_reserves);
451 =head2 ModCourseItem {
453 ModCourseItem( %params );
455 Creates or modifies an existing course item.
461 warn identify_myself
(%params) if $DEBUG;
463 my $itemnumber = $params{'itemnumber'};
464 my $itype = $params{'itype'};
465 my $ccode = $params{'ccode'};
466 my $holdingbranch = $params{'holdingbranch'};
467 my $location = $params{'location'};
469 return unless ($itemnumber);
471 my $course_item = GetCourseItem
( itemnumber
=> $itemnumber );
476 $ci_id = $course_item->{'ci_id'};
480 course_item
=> $course_item,
484 $ci_id = _AddCourseItem
(%params);
491 =head2 _AddCourseItem
493 my $ci_id = _AddCourseItem( %params );
499 warn identify_myself
(%params) if $DEBUG;
501 my ( @fields, @values );
503 push( @fields, 'itemnumber = ?' );
504 push( @values, $params{'itemnumber'} );
508 push( @fields, "$_ = ?" );
509 push( @values, $params{$_} );
513 my $query = "INSERT INTO course_items SET " . join( ',', @fields );
514 my $dbh = C4
::Context
->dbh;
515 $dbh->do( $query, undef, @values );
517 my $ci_id = $dbh->last_insert_id( undef, undef, 'course_items', 'ci_id' );
522 =head2 _UpdateCourseItem
524 _UpdateCourseItem( %params );
528 sub _UpdateCourseItem
{
530 warn identify_myself
(%params) if $DEBUG;
532 my $ci_id = $params{'ci_id'};
533 my $course_item = $params{'course_item'};
534 my $itype = $params{'itype'};
535 my $ccode = $params{'ccode'};
536 my $holdingbranch = $params{'holdingbranch'};
537 my $location = $params{'location'};
539 return unless ( $ci_id || $course_item );
541 $course_item = GetCourseItem
( ci_id
=> $ci_id )
542 unless ($course_item);
543 $ci_id = $course_item->{'ci_id'} unless ($ci_id);
545 ## Revert fields that had an 'original' value, but now don't
546 ## Update the item fields to the stored values from course_items
547 ## and then set those fields in course_items to NULL
548 my @fields_to_revert;
550 if ( !$params{$_} && $course_item->{$_} ) {
551 push( @fields_to_revert, $_ );
556 fields
=> \
@fields_to_revert,
557 course_item
=> $course_item
558 ) if (@fields_to_revert);
560 ## Update fields that still have an original value, but it has changed
561 ## This necessitates only changing the current item values, as we still
562 ## have the original values stored in course_items
566 && $course_item->{$_}
567 && $params{$_} ne $course_item->{$_} ) {
568 $mod_params{$_} = $params{$_};
571 ModItem
( \
%mod_params, undef, $course_item->{'itemnumber'} ) if %mod_params;
573 ## Update fields that didn't have an original value, but now do
574 ## We must save the original value in course_items, and also
575 ## update the item fields to the new value
576 my $item = GetItem
( $course_item->{'itemnumber'} );
580 if ( $params{$_} && !$course_item->{$_} ) {
581 $mod_params_new{$_} = $params{$_};
582 $mod_params_old{$_} = $item->{$_};
585 _ModStoredFields
( 'ci_id' => $params{'ci_id'}, %mod_params_old );
586 ModItem
( \
%mod_params_new, undef, $course_item->{'itemnumber'} ) if %mod_params_new;
590 =head2 _ModStoredFields
592 _ModStoredFields( %params );
594 Updates the values for the 'original' fields in course_items
599 sub _ModStoredFields
{
601 warn identify_myself
(%params) if $DEBUG;
603 return unless ( $params{'ci_id'} );
605 my ( @fields_to_update, @values_to_update );
609 push( @fields_to_update, $_ );
610 push( @values_to_update, $params{$_} );
614 my $query = "UPDATE course_items SET " . join( ',', map { "$_=?" } @fields_to_update ) . " WHERE ci_id = ?";
616 C4
::Context
->dbh->do( $query, undef, @values_to_update, $params{'ci_id'} )
617 if (@values_to_update);
623 _RevertFields( ci_id => $ci_id, fields => \@fields_to_revert );
629 warn identify_myself
(%params) if $DEBUG;
631 my $ci_id = $params{'ci_id'};
632 my $course_item = $params{'course_item'};
633 my $fields = $params{'fields'};
634 my @fields = @
$fields;
636 return unless ($ci_id);
638 $course_item = GetCourseItem
( ci_id
=> $params{'ci_id'} )
639 unless ($course_item);
643 foreach my $field (@fields) {
645 if ( $field eq $_ && $course_item->{$_} ) {
646 $mod_item_params->{$_} = $course_item->{$_};
647 push( @fields_to_null, $_ );
651 ModItem
( $mod_item_params, undef, $course_item->{'itemnumber'} ) if $mod_item_params && %$mod_item_params;
653 my $query = "UPDATE course_items SET " . join( ',', map { "$_=NULL" } @fields_to_null ) . " WHERE ci_id = ?";
655 C4
::Context
->dbh->do( $query, undef, $ci_id ) if (@fields_to_null);
658 =head2 _SwapAllFields
660 _SwapAllFields( $ci_id );
666 warn "C4::CourseReserves::_SwapFields( $ci_id )" if $DEBUG;
668 my $course_item = GetCourseItem
( ci_id
=> $ci_id );
669 my $item = GetItem
( $course_item->{'itemnumber'} );
671 my %course_item_fields;
674 if ( $course_item->{$_} ) {
675 $course_item_fields{$_} = $course_item->{$_};
676 $item_fields{$_} = $item->{$_};
680 ModItem
( \
%course_item_fields, undef, $course_item->{'itemnumber'} ) if %course_item_fields;
681 _ModStoredFields
( %item_fields, ci_id
=> $ci_id );
684 =head2 GetCourseItems {
686 $course_items = GetCourseItems(
687 [course_id => $course_id]
688 [, itemnumber => $itemnumber ]
695 warn identify_myself
(%params) if $DEBUG;
697 my $course_id = $params{'course_id'};
698 my $itemnumber = $params{'itemnumber'};
700 return unless ($course_id);
705 my $query = "SELECT * FROM course_items";
707 if ( keys %params ) {
711 foreach my $key ( keys %params ) {
712 push( @query_keys, " $key LIKE ? " );
713 push( @query_values, $params{$key} );
716 $query .= join( ' AND ', @query_keys );
719 my $dbh = C4
::Context
->dbh;
720 my $sth = $dbh->prepare($query);
721 $sth->execute(@query_values);
723 return $sth->fetchall_arrayref( {} );
726 =head2 DelCourseItem {
728 DelCourseItem( ci_id => $cr_id );
734 warn identify_myself
(%params) if $DEBUG;
736 my $ci_id = $params{'ci_id'};
738 return unless ($ci_id);
740 _RevertFields
( ci_id
=> $ci_id, fields
=> \
@FIELDS );
743 DELETE FROM course_items
746 C4
::Context
->dbh->do( $query, undef, $ci_id );
749 =head2 GetCourseReserve {
751 $course_item = GetCourseReserve( %params );
755 sub GetCourseReserve
{
757 warn identify_myself
(%params) if $DEBUG;
759 my $cr_id = $params{'cr_id'};
760 my $course_id = $params{'course_id'};
761 my $ci_id = $params{'ci_id'};
763 return unless ( $cr_id || ( $course_id && $ci_id ) );
765 my $dbh = C4
::Context
->dbh;
770 SELECT * FROM course_reserves
773 $sth = $dbh->prepare($query);
774 $sth->execute($cr_id);
777 SELECT * FROM course_reserves
778 WHERE course_id = ? AND ci_id = ?
780 $sth = $dbh->prepare($query);
781 $sth->execute( $course_id, $ci_id );
784 my $course_reserve = $sth->fetchrow_hashref();
785 return $course_reserve;
788 =head2 ModCourseReserve
790 $id = ModCourseReserve( %params );
794 sub ModCourseReserve
{
796 warn identify_myself
(%params) if $DEBUG;
798 my $course_id = $params{'course_id'};
799 my $ci_id = $params{'ci_id'};
800 my $staff_note = $params{'staff_note'};
801 my $public_note = $params{'public_note'};
803 return unless ( $course_id && $ci_id );
805 my $course_reserve = GetCourseReserve
( course_id
=> $course_id, ci_id
=> $ci_id );
808 my $dbh = C4
::Context
->dbh;
810 if ($course_reserve) {
811 $cr_id = $course_reserve->{'cr_id'};
814 UPDATE course_reserves
815 SET staff_note = ?, public_note = ?
818 $dbh->do( $query, undef, $staff_note, $public_note, $cr_id );
821 INSERT INTO course_reserves SET
827 $dbh->do( $query, undef, $course_id, $ci_id, $staff_note, $public_note );
828 $cr_id = $dbh->last_insert_id( undef, undef, 'course_reserves', 'cr_id' );
831 EnableOrDisableCourseItem
(
832 ci_id
=> $params{'ci_id'},
838 =head2 GetCourseReserves {
840 $course_reserves = GetCourseReserves( %params );
847 include_courses => 1,
851 sub GetCourseReserves
{
853 warn identify_myself
(%params) if $DEBUG;
855 my $course_id = $params{'course_id'};
856 my $ci_id = $params{'ci_id'};
857 my $include_items = $params{'include_items'};
858 my $include_count = $params{'include_count'};
859 my $include_courses = $params{'include_courses'};
861 return unless ( $course_id || $ci_id );
863 my $field = ($course_id) ?
'course_id' : 'ci_id';
864 my $value = ($course_id) ?
$course_id : $ci_id;
867 SELECT cr.*, ci.itemnumber
868 FROM course_reserves cr, course_items ci
870 AND cr.ci_id = ci.ci_id
872 my $dbh = C4
::Context
->dbh;
873 my $sth = $dbh->prepare($query);
874 $sth->execute($value);
876 my $course_reserves = $sth->fetchall_arrayref( {} );
878 if ($include_items) {
879 foreach my $cr (@
$course_reserves) {
880 $cr->{'course_item'} = GetCourseItem
( ci_id
=> $cr->{'ci_id'} );
881 $cr->{'item'} = GetBiblioFromItemNumber
( $cr->{'itemnumber'} );
882 $cr->{'issue'} = GetOpenIssue
( $cr->{'itemnumber'} );
886 if ($include_count) {
887 foreach my $cr (@
$course_reserves) {
888 $cr->{'reserves_count'} = CountCourseReservesForItem
( ci_id
=> $cr->{'ci_id'} );
892 if ($include_courses) {
893 foreach my $cr (@
$course_reserves) {
894 $cr->{'courses'} = GetCourses
( itemnumber
=> $cr->{'itemnumber'} );
898 return $course_reserves;
901 =head2 DelCourseReserve {
903 DelCourseReserve( cr_id => $cr_id );
907 sub DelCourseReserve
{
909 warn identify_myself
(%params) if $DEBUG;
911 my $cr_id = $params{'cr_id'};
913 return unless ($cr_id);
915 my $dbh = C4
::Context
->dbh;
917 my $course_reserve = GetCourseReserve
( cr_id
=> $cr_id );
920 DELETE FROM course_reserves
923 $dbh->do( $query, undef, $cr_id );
925 ## If there are no other course reserves for this item
926 ## delete the course_item as well
927 unless ( CountCourseReservesForItem
( ci_id
=> $course_reserve->{'ci_id'} ) ) {
928 DelCourseItem
( ci_id
=> $course_reserve->{'ci_id'} );
933 =head2 GetItemCourseReservesInfo
935 my $arrayref = GetItemCourseReservesInfo( itemnumber => $itemnumber );
937 For a given item, returns an arrayref of reserves hashrefs,
938 with a course hashref under the key 'course'
942 sub GetItemCourseReservesInfo
{
944 warn identify_myself
(%params) if $DEBUG;
946 my $itemnumber = $params{'itemnumber'};
948 return unless ($itemnumber);
950 my $course_item = GetCourseItem
( itemnumber
=> $itemnumber );
952 return unless ( keys %$course_item );
954 my $course_reserves = GetCourseReserves
( ci_id
=> $course_item->{'ci_id'} );
956 foreach my $cr (@
$course_reserves) {
957 $cr->{'course'} = GetCourse
( $cr->{'course_id'} );
960 return $course_reserves;
963 =head2 CountCourseReservesForItem
965 $bool = CountCourseReservesForItem( %params );
967 ci_id - course_item id
969 itemnumber - course_item itemnumber
971 enabled = 'yes' or 'no'
972 Optional, if not supplied, counts reserves
973 for both enabled and disabled courses
977 sub CountCourseReservesForItem
{
979 warn identify_myself
(%params) if $DEBUG;
981 my $ci_id = $params{'ci_id'};
982 my $itemnumber = $params{'itemnumber'};
983 my $enabled = $params{'enabled'};
985 return unless ( $ci_id || $itemnumber );
987 my $course_item = GetCourseItem
( ci_id
=> $ci_id, itemnumber
=> $itemnumber );
989 my @params = ( $course_item->{'ci_id'} );
990 push( @params, $enabled ) if ($enabled);
993 SELECT COUNT(*) AS count
994 FROM course_reserves cr
995 LEFT JOIN courses c ON ( c.course_id = cr.course_id )
998 $query .= "AND c.enabled = ?" if ($enabled);
1000 my $dbh = C4
::Context
->dbh;
1001 my $sth = $dbh->prepare($query);
1002 $sth->execute(@params);
1004 my $row = $sth->fetchrow_hashref();
1006 return $row->{'count'};
1009 =head2 SearchCourses
1011 my $courses = SearchCourses( term => $search_term, enabled => 'yes' );
1017 warn identify_myself
(%params) if $DEBUG;
1019 my $term = $params{'term'};
1021 my $enabled = $params{'enabled'} || '%';
1024 my $query = "SELECT c.* FROM courses c";
1027 LEFT JOIN course_instructors ci
1028 ON ( c.course_id = ci.course_id )
1029 LEFT JOIN borrowers b
1030 ON ( ci.borrowernumber = b.borrowernumber )
1031 LEFT JOIN authorised_values av
1032 ON ( c.department = av.authorised_value )
1034 ( av.category = 'DEPARTMENT' OR av.category = 'TERM' )
1037 department LIKE ? OR
1038 course_number LIKE ? OR
1040 course_name LIKE ? OR
1042 public_note LIKE ? OR
1043 CONCAT(surname,' ',firstname) LIKE ? OR
1044 CONCAT(firstname,' ',surname) LIKE ? OR
1050 GROUP BY c.course_id
1055 @params = ($term) x
10;
1057 $query .= " ORDER BY department, course_number, section, term, course_name ";
1059 my $dbh = C4
::Context
->dbh;
1060 my $sth = $dbh->prepare($query);
1062 $sth->execute( @params, $enabled );
1064 my $courses = $sth->fetchall_arrayref( {} );
1066 foreach my $c (@
$courses) {
1067 $c->{'instructors'} = GetCourseInstructors
( $c->{'course_id'} );
1073 sub whoami
{ ( caller(1) )[3] }
1074 sub whowasi
{ ( caller(2) )[3] }
1076 sub stringify_params
{
1081 foreach my $key ( keys %params ) {
1082 $string .= " $key => " . $params{$key} . "\n";
1085 return "( $string )";
1088 sub identify_myself
{
1091 return whowasi
() . stringify_params
(%params);
1098 Kyle M Hall <kyle@bywatersolutions.com>