From 351b51c6f6475d8dfeabc99fb7f2fcc84aa6a738 Mon Sep 17 00:00:00 2001 From: Martin Stenberg Date: Fri, 18 Sep 2015 14:29:50 +0200 Subject: [PATCH] Bug 8628: Add digital signs to the OPAC See http://wiki.koha-community.org/wiki/Digital_signs_RFC for details. To test: 1. Apply this patch and the database updates patch 2. Run updatedatabase.pl 3. In staff client, go to Tools/Additional Tools/Digital signs 4. You should be warned about OPACDigitalSigns not being enabled, you can ignore this for now. 5. Add a new sign by clicking the "+ New sign" button 6. Enter a name and optionally numbers for automatic page turing 7. Your new sign should appear in the Signs list 8. Add a new stream by clicking the "+ New stream" button 9. Unless you already have reports in the report group with code SIG, you should be warned that there are no reports in the group with code SIG and given a link for creating a new report. Follow the link and create a new report with report group code SIG. En example SQL command for the report could be: SELECT * FROM biblio WHERE timestamp > DATE_SUB(NOW(), INTERVAL 7 DAY) 10. Go back to the "new stream" page, and reload. You should no longer see a warning message, and your newly created report should appear in the list of reports. 11. Select the report and click Submit. Your newly created stream should now appear in the list of streams. 12. In the list of signs, press "edit streams" for the sign you previously created. 13. Choose a stream to attach and click Submit. Your sign is now ready for OPAC. 14. In OPAC, visit /cgi-bin/koha/opac-signs.pl 15. You should be told that Digital signs are not enabled. Enable with new system preference OPACDigitalSigns and reload the page. 15. You should see a list of available signs, click on a sign that you wish to display. 16. You should now see a list of all books matching the SQL query in the report that you attached to your stream. 17. If you have OPACLocalCoverImages enabled, all books with local covers attached should be presented using this cover. If no local cover is available and the book has a ISBN with a cover in openlibrary.org, the cover image from openlibrary.org should be shown. If all of the above fails, a cover matching the theme of the page should be seen, showing the book title and author. 18. Clicking a book should bring you to a detailed view of the book where you can see the books availability. You should also see the two next books and the two previous books in the stream (unless you're at the beginning or end of the stream) 19. Swiping (if no touch screen, click and hold left mouse button and drag) left/right should bring you to next/previous book. Clicking on the next/previous books (right/left of the active one) should bring you to the detailed view of the clicked book. 20. Leaving the page idle (i.e no user interaction) for the amount of time specified in step 6. should result in the page automatically switching to the next book in the stream. Sponsored-by: Regionbibliotek Halland / County library of Halland Signed-off-by: Chris Cormack In theory this could/should be rewritten to use Koha::Schema instead of direct sql, but this predates the switch, so would be unfair to reject it on that basis (plus until we fix the speed straight sql is way faster anyway) --- Koha/Signs.pm | 330 ++++++++++++ .../prog/en/modules/admin/preferences/opac.pref | 21 +- .../intranet-tmpl/prog/en/modules/tools/signs.tt | 479 +++++++++++++++++ .../prog/en/modules/tools/tools-home.tt | 5 + koha-tmpl/opac-tmpl/bootstrap/css/signs.css | 102 ++++ .../opac-tmpl/bootstrap/en/modules/opac-signs.tt | 565 +++++++++++++++++++++ opac/opac-signs.pl | 49 ++ tools/signs.pl | 258 ++++++++++ 8 files changed, 1808 insertions(+), 1 deletion(-) create mode 100644 Koha/Signs.pm create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/signs.tt create mode 100644 koha-tmpl/opac-tmpl/bootstrap/css/signs.css create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-signs.tt create mode 100755 opac/opac-signs.pl create mode 100755 tools/signs.pl diff --git a/Koha/Signs.pm b/Koha/Signs.pm new file mode 100644 index 0000000..a542e2e --- /dev/null +++ b/Koha/Signs.pm @@ -0,0 +1,330 @@ +package Koha::Signs; + +use C4::Context; +use C4::Biblio; +use C4::Koha; +use C4::Items; +use Modern::Perl; + +use base qw( Exporter ); + +# set the version for version checking +our @EXPORT = qw( + + AddSignStream + ModSignStream + GetSignStream + GetSignStreams + DelSignStream + + GetSignStreamRecords + + AddSign + ModSign + GetSign + GetSigns + DelSign + + AttachSignStreamToSign + DetachSignStreamFromSign + GetSignStreamsAttachedToSign + GetSignStreamsAttachedToSignWithRecords + + ModSignStreamParams + GetSignStreamParams +); + +my $dbh = C4::Context->dbh; + +# Streams + +# Returns id of new sign_stream +sub AddSignStream { + + my ( $name, $report ) = @_; + + my $sth=$dbh->prepare("INSERT INTO sign_streams SET name = ?, saved_sql_id = ?"); + $sth->execute( $name, $report ); + return $dbh->last_insert_id( undef, undef, 'sign_streams', 'sign_stream_id' ); + +} + +sub ModSignStream { + + my ( $name, $report, $sign_stream_id ) = @_; + + my $sth = $dbh->prepare("UPDATE sign_streams SET name = ?, saved_sql_id = ? WHERE sign_stream_id = ?"); + return $sth->execute( $name, $report, $sign_stream_id ); + +} + +sub GetSignStream { + + my ( $sign_id ) = @_; + + return unless $sign_id; + + my $query = "SELECT s.*, sq.report_name, sq.savedsql + FROM sign_streams AS s, saved_sql AS sq + WHERE s.saved_sql_id = sq.id + AND s.sign_stream_id = ?"; + my $sth = $dbh->prepare($query); + $sth->execute($sign_id); + return $sth->fetchrow_hashref(); + +} + +sub GetSignStreams { + + my $query = "SELECT s.*, sq.report_name, sq.savedsql + FROM sign_streams AS s, saved_sql AS sq + WHERE s.saved_sql_id = sq.id + ORDER BY s.name"; + my $sth = $dbh->prepare($query); + $sth->execute(); + return $sth->fetchall_arrayref({}); + +} + +sub DelSignStream { + + my ( $sign_stream_id ) = @_; + + return unless $sign_stream_id; + + my $sth = $dbh->prepare('DELETE FROM sign_streams WHERE sign_stream_id = ?'); + return $sth->execute($sign_stream_id); + +} + +sub GetSignStreamRecords { + my ( $stream, $sign_to_stream_id) = @_; + my $sql = $stream->{'savedsql'}; + + if ( defined $sign_to_stream_id ) { + my $params = GetSignStreamParams( $sign_to_stream_id ); + $sql = ReplaceParamsInSQL( $sql, $params ); + return undef if ( $sql =~ m/< RunSQL( $sql ), sql => $sql }; +} + +# Signs + +# Returns id of new sign +sub AddSign { + + my ( $name, $webapp, $swatch, $transition, $idleafter, $pagedelay, $reloadafter ) = @_; + + my $sth=$dbh->prepare("INSERT INTO signs SET name = ?, webapp = ?, swatch = ?, transition = ?, idleafter = ?, pagedelay = ?, reloadafter = ?"); + $sth->execute( $name, $webapp, $swatch, $transition, $idleafter, $pagedelay, $reloadafter ); + return $dbh->last_insert_id( undef, undef, 'signs', 'sign_id' ); + +} + +sub ModSign { + + my ( $name, $webapp, $swatch, $transition, $idleafter, $pagedelay, $reloadafter, $sign_id ) = @_; + + my $sth = $dbh->prepare("UPDATE signs SET name = ?, webapp = ?, swatch = ?, transition = ?, idleafter = ?, pagedelay = ?, reloadafter = ? WHERE sign_id = ?"); + return $sth->execute( $name, $webapp, $swatch, $transition, $idleafter, $pagedelay, $reloadafter, $sign_id ); + +} + +sub GetSign { + + my ( $sign_id ) = @_; + + return unless $sign_id; + + my $query = "SELECT * + FROM signs + WHERE sign_id = ?"; + my $sth = $dbh->prepare($query); + $sth->execute($sign_id); + return $sth->fetchrow_hashref(); + +} + +sub GetSigns { + + my $query = "SELECT * + FROM signs + ORDER BY name"; + my $sth = $dbh->prepare($query); + $sth->execute(); + return $sth->fetchall_arrayref({}); + +} + +sub DelSign { + + my ( $sign_id ) = @_; + + return unless $sign_id; + + my $sth = $dbh->prepare('DELETE FROM signs WHERE sign_id = ?'); + return $sth->execute($sign_id); + +} + +# Streams attached to signs + +# Returns the ID of the connection between sign and stream +sub AttachSignStreamToSign { + + my ( $sign_stream_id, $sign_id ) = @_; + + return unless $sign_stream_id || $sign_id; + + my $sth = $dbh->prepare( 'INSERT INTO signs_to_streams SET sign_stream_id = ?, sign_id = ?' ); + $sth->execute( $sign_stream_id, $sign_id ); + return $dbh->last_insert_id( undef, undef, 'signs_to_streams', 'sign_to_stream_id' ); + +} + +sub ModSignStreamParams { + + my ( $sign_to_stream_id, $params ) = @_; + return unless $sign_to_stream_id; + my $sth = $dbh->prepare( 'UPDATE signs_to_streams SET params = ? WHERE sign_to_stream_id = ?' ); + return $sth->execute( $params, $sign_to_stream_id ); + +} + +# Returns the string of params for a given stream-attached-to-sign +sub GetSignStreamParams { + + my ( $sign_to_stream_id ) = @_; + + return unless $sign_to_stream_id; + + my $query = 'SELECT params FROM signs_to_streams WHERE sign_to_stream_id = ?'; + my $sth = $dbh->prepare( $query ); + $sth->execute( $sign_to_stream_id ); + return $sth->fetchrow_array(); + +} + +sub ReplaceParamsInSQL { + + my ( $sql, $params ) = @_; + + return unless $sql || $params; + return $sql unless $sql =~ m/<>/$value/g; + } + return $sql; + +} + +sub GetSignStreamsAttachedToSign { + + my ( $sign_id ) = @_; + + return unless $sign_id; + + my $query = 'SELECT s.*, sts.sign_to_stream_id, sts.params, sq.report_name, sq.savedsql + FROM sign_streams AS s, signs_to_streams AS sts, saved_sql AS sq + WHERE s.sign_stream_id = sts.sign_stream_id + AND s.saved_sql_id = sq.id + AND sts.sign_id = ? + ORDER BY s.name'; + my $sth = $dbh->prepare( $query ); + $sth->execute( $sign_id ); + return $sth->fetchall_arrayref({}); + +} + +sub GetSignStreamsAttachedToSignWithRecords { + + my ( $sign_id, $include_marc ) = @_; + + return unless $sign_id; + + my $streams = GetSignStreamsAttachedToSign( $sign_id ); + my @changedstreams; + my %record_cache = (); + + # Add records to the streams + foreach my $stream ( @{$streams} ) { + + my $records = RunSQL( ReplaceParamsInSQL( $stream->{'savedsql'}, $stream->{'params'} ) ); + + if ( $include_marc ) { + + my @processed_records; + foreach my $rec ( @{$records} ) { + unless(defined $record_cache{$rec->{'biblionumber'}}) { + my $marc = GetMarcBiblio( $rec->{'biblionumber'} ); + if ( ! $marc ) { + next; + } + + my $isbn = GetNormalizedISBN( undef, $marc, C4::Context->preference("marcflavor") ) || ''; + $rec->{'isbn'} = $isbn; + + my $dat = GetBiblioData($rec->{'biblionumber'}); + my @items = GetItemsInfo($rec->{'biblionumber'}); + foreach my $item ( @items ) { + my $shelflocations = GetKohaAuthorisedValues('items.location',$dat->{'frameworkcode'}, 'opac'); + if ( defined $item->{'location'} ) { + $item->{'location_description'} = $shelflocations->{ $item->{'location'} }; + } + } + $rec->{'items'} = \@items; + foreach ( keys %{$dat} ) { + $rec->{"$_"} = defined $dat->{$_} ? $dat->{$_} : ''; + } + + $rec->{'marc'} = $marc; + + $record_cache{$rec->{'biblionumber'}} = $rec; + } + push @processed_records, $record_cache{$rec->{'biblionumber'}}; + } + $stream->{'records'} = \@processed_records; + + } else { + + $stream->{'records'} = $records; + + } + + push @changedstreams, $stream; + + } + + return \@changedstreams; + +} + +sub DetachSignStreamFromSign { + + my ( $sign_to_stream_id ) = @_; + + return unless $sign_to_stream_id; + + my $sth = $dbh->prepare( 'DELETE FROM signs_to_streams WHERE sign_to_stream_id = ?' ); + return $sth->execute( $sign_to_stream_id ); + +} + +sub RunSQL { + + my ( $query ) = @_; + + return unless $query; + + my $sth = $dbh->prepare($query); + $sth->execute(); + return $sth->fetchall_arrayref({}); + +} + +1; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref index b6954ef..849b96d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -710,7 +710,6 @@ OPAC: yes: Use no: "Don't use" - "the item collection code when finding items for the shelf browser." - Self Registration: - - pref: PatronSelfRegistration @@ -772,6 +771,26 @@ OPAC: no: "Do not display and prefill" - "password and login form after a patron has self registered." + Digital Signs: + - + - pref: OPACDigitalSigns + default: 0 + choices: + yes: Enable + no: Disable + - "digital signs in the OPAC. Please note: Digital signs are not linked to from the OPAC by default, so you will have to load the relevant URL by hand on displays where you want to use them." + - + - "Include the following CSS in all digital signs:" + - pref: OPACDigitalSignsCSS + type: textarea + class: code + - (If you use this option to create custom swatches (e.g. with the ThemeRoller for jQuery Mobile) you might have to adjust the list of letters identifying available themes (swatches) in the OPACDigitalSignsSwatches preference.) + - + - Make it possible to choose one of the themes (swatches) + - pref: OPACDigitalSignsSwatches + class: long + - when creating a new sign. By default the themes a-e are provided, but you can override these by creating your own themes and entering them into the OPACDigitalSignsCSS system preference. If you do add your own custom themes there you will want to adjust the letters in this system preference to match the themes you created. + Advanced Search Options: - - Show search options diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/signs.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/signs.tt new file mode 100644 index 0000000..100c814 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/signs.tt @@ -0,0 +1,479 @@ +[% USE Koha %] +[% INCLUDE 'doc-head-open.inc' %] +Koha › Tools › Digital signs +[% INCLUDE 'doc-head-close.inc' %] + +[% INCLUDE 'datatables.inc' %] + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + +[% BLOCK dslink %]Digital signs ›[% END %] + + +
+ +
+
+
+ +[% UNLESS Koha.Preference( 'OPACDigitalSigns' ) %] +
+

+ Digital signs are not enabled. Please enable + OPACDigitalSigns + for OPAC digital signs to work. +

+
+[% END %] + +[% IF ( else ) %] +
+ +
+[% END %] + +[% IF op == 'stream_form' %] + [% UNLESS ( reports ) %] +
+

No reports found

+

No reports with group code "SIG" were found. Please create + a new report with group code "SIG" and try again.

+
+ [% END %] + + [% IF ( stream.sign_stream_id ) %] +

Edit stream

+ [% ELSE %] +

Add stream

+ [% END %] +
+ + [% IF ( stream.sign_stream_id ) %] + + [% END %] +
+
    +
  1. +
  2. + +
  3. +
+
+
+
+ +[% ELSIF op == 'sign_form' %] + + [% IF ( sign.sign_id ) %] +

Edit sign

+ [% ELSE %] +

Add sign

+ [% END %] +
+ + [% IF ( sign.sign_id ) %] + + [% END %] +
+ General settings +
    +
  1. +
+
+
+ Appearance +
    +
  1. + +
  2. +
  3. + +
  4. +
  5. + +
  6. +
+
+
+ Automatic page turning +
    +
  1. + seconds. (Set to 0 to disable automatic page turning.) +
  2. +
  3. + seconds. +
  4. +
  5. + seconds. +
  6. +
+
+
+
+ +[% ELSIF op == 'edit_streams' %] + +

Edit streams attached to [% sign.name %]

+

Streams already attached to this sign

+ [% IF ( attached.size ) %] + + + + + + [% FOREACH s IN attached %] + + + + + + + [% END %] + +
NameParametersEdit parametersDetach
[% s.name %][% s.params %][% IF s.savedsql.match('<<') %]Edit parameters[% ELSE %]No parameters[% END %]Detach
+ [% ELSE %] +

There are no streams attached to this sign, yet.

+ [% END %] + +

Attach a new stream to this sign

+
+ + +
+
    +
  1. + +
  2. +
+
+
+
+ +[% ELSIF op == 'get_params' %] + +

Parameters for [% stream.name %]

+

Based on report: [% stream.report_name %] | Edit this report

+ +
+ + + + +
+ [% IF ( params ) %] + Edit parameters + [% ELSE %] + Add parameters + [% END %] +
    +
  1. + +
  2. +
+
+
+
+ +

Raw SQL

+
[% stream.savedsql | html %]
+ +

SQL with current parameters replaced

+
[% newsql | html %]
+ [% IF ( has_params ) %] +

Sorry, your SQL still contains placeholders. You need to add more parameters.

+ [% ELSE %] +

Records

+ [% INCLUDE display_records %] + [% END %] + +[% ELSIF op == 'del_stream' %] + +
+

Confirm deletion of stream '[% stream.name %]'?

+
+ + +
+ +
+ +
+
+ +[% ELSIF op == 'del_stream_ok' %] + +
+

Stream deleted

+
+ +
+
+ +[% ELSIF op == 'del_sign' %] + +
+

Confirm deletion of sign '[% sign.name %]'?

+
+ + +
+ +
+ +
+
+ +[% ELSIF op == 'del_sign_ok' %] + +
+

Sign deleted

+
+ +
+
+ +[% ELSIF op == 'view_sign' %] + +

[% sign.name %]

+

Streams

+ + [% IF ( streams ) %] + [% FOREACH stream IN streams %] +

[% stream.name %]

+ + [% END %] + [% ELSE %] +

No streams attached.

+ [% END%] + +[% ELSIF op == 'view_stream' %] + +

[% stream.name %]

+

Based on report: [% stream.report_name %] | Edit this report

+

SQL

+
[% stream.savedsql | html %]
+

Records

+ [% IF ( has_params ) %] +

Sorry, the report this stream is based on has parameters and displaying it only makes sense after it has been attached to a sign and parameters have been added.

+ [% ELSE %] + [% INCLUDE display_records %] + [% END %] + +[% ELSE %] + +

Digital signs

+ + [% IF signs %] +

Signs

+ + + + + + + + + + + + + + + + + + [% FOREACH s IN signs %] + + + + + + + + + + + + + + [% END %] + +
NameWeb-appTheme (swatch)TransitionIdle afterPage delayReload afterEditEdit streamsDeleteView sign
[% s.name %][% IF ( s.webapp ) %]Yes[% ELSE %]No[% END %][% s.swatch %][% s.transition %][% s.idleafter %][% s.pagedelay %][% s.reloadafter %]EditEdit streamsDelete[% IF ( OPACBaseURL ) %]View sign[% END %]
+ [% UNLESS ( OPACBaseURL ) %]

Please note: Links to view signs in the OPAC will only be displayed if you fill in the OPACBaseURL system preference.

[% END %] + [% ELSE %] +

No signs defined!

+ [% END %] + + [% IF streams %] +

Streams

+ + + + + + + + + + + [% FOREACH s IN streams %] + + + + + + + [% END %] + +
NameReportEditDelete
[% s.name %][% s.report_name %]EditDelete
+ [% ELSE %] +

No streams defined!

+ [% END %] + +[% END %] + + + +
+
+
+[% INCLUDE 'tools-menu.inc' %] +
+
+[% INCLUDE 'intranet-bottom.inc' %] + +[% BLOCK display_records %] + [% IF ( records.0 ) %] + + + + + + + + + [% FOREACH r IN records %] + + [% END %] + +
biblionumbertitle
[% r.biblionumber %][% r.title %]
+ [% ELSE %] +

No records found.

+ [% END %] +[% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt index 4c8cca9..ec70760 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt @@ -104,6 +104,11 @@
Quote editor for Quote-of-the-day feature in OPAC
[% END %] + [% IF ( CAN_user_tools_edit_digital_signs ) %] +
Digital signs
+
Create and edit digital signs for the OPAC
+ [% END %] + [% IF ( UseKohaPlugins && CAN_user_plugins_tool ) %]
Tool plugins
Use tool plugins
diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/signs.css b/koha-tmpl/opac-tmpl/bootstrap/css/signs.css new file mode 100644 index 0000000..e1bf843 --- /dev/null +++ b/koha-tmpl/opac-tmpl/bootstrap/css/signs.css @@ -0,0 +1,102 @@ +.carousel-container { + width: 225px; + height: 225px; + position: relative; + margin: 0 auto 40px; + -webkit-perspective: 1100px; + -moz-perspective: 1100px; + -o-perspective: 1100px; + -ms-perspective: 1100px; + perspective: 1100px; +} + +.carousel { + width: 100%; + height: 100%; + position: absolute; + -webkit-transform-style: preserve-3d; + -moz-transform-style: preserve-3d; + -o-transform-style: preserve-3d; + -ms-transform-style: preserve-3d; + transform-style: preserve-3d; +} + +.unicorn { + display: block; + position: absolute; + width: 150px; + height: 225px; + left: 10px; + top: 10px; + -webkit-box-reflect: below 0 -webkit-gradient(linear, left bottom, left top, color-stop(0.05, rgba(255, 255, 255, 0.12)), color-stop(0.2, transparent)); +} + +.ui-li { + padding-top: 0px !important; + padding-bottom: 0px !important; + margin-bottom: -7px !important; +} + +.ui-li h4 { + margin-top: 2px !important; + margin-bottom: 2px !important; +} + +.ui-li-icon { + top: 15% !important; +} + +.vspace { + margin-top: 2em; +} + +.content { + text-align: center; +} + +.btn-record { + margin: 10px; +} + +.cover { + border: none; + display: inline-block; + height: 225px; + width: 150px; + background-size: 100%; + background-repeat: round; +} + +.cover.cover-blank { +} + +.cover.placeholder { +} + +.cover .cover-inner { + display: table-cell; + vertical-align: middle; + padding: 25px; + border: 2px solid #fff; + height: 171px; + max-height: 171px; + width: inherit; +} + +.cover-text { + text-align: center; + position: relative; + font-family: Georgia, "Palatino Linotype", "Book Antiqua", Palatino, "Times New Roman", serif; + font-size: 1em; + max-height: inherit; + overflow: hidden; +} + +.cover-text .title { + font-weight: bold; +} + +.cover-text .author { + font-style: italic; + margin-top: 1em; +} diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-signs.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-signs.tt new file mode 100644 index 0000000..812e8f1 --- /dev/null +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-signs.tt @@ -0,0 +1,565 @@ +[% USE Koha %] +[% USE KohaDates %] +[% USE Branches %] +[% USE JSON.Escape %] + +[%- BLOCK item_status -%] + [%- SET itemavailable = 1 -%] + [%- IF ( item.itemlost ) -%] + [%- SET itemavailable = 0 -%] + [%-%]Item lost + [%- END -%] + [%- IF ( item.datedue || issue.date_due ) -%] + [%- SET itemavailable = 0 -%] + [%- IF item.onsite_checkout -%] + [%-%]Currently in local use + [%- ELSE -%] + [%-%]Checked out + [%- END -%] + [%- END -%] + [%- IF ( item.transfertwhen ) %] + [%- SET itemavailable = 0 -%] + [%-%]In transit from [%- item.transfertfrom %] to [%- item.transfertto %] since [%- item.transfertwhen | $KohaDates %] + [%- END %] + [%- IF ( item.waiting ) -%] + [%- SET itemavailable = 0 -%] + [%-%]On hold + [%- END -%] + [%- IF ( item.withdrawn ) -%] + [%- SET itemavailable = 0 -%] + [%-%]Item withdrawn + [%- END -%] + [%- IF ( item.itemnotforloan ) -%] + [%- SET itemavailable = 0 -%] + [%- IF ( item.notforloanvalueopac ) -%] + [%- item.notforloanvalueopac -%] [%- IF ( item.restrictedopac ) -%] ([%- item.restrictedopac -%])[%- END -%] + [%- ELSE -%] + [%-%]Not for loan [%- IF ( item.restrictedopac ) -%] ([%- item.restrictedopac -%])[%- END -%] + [%- END -%] + [%- ELSIF ( item.notforloan_per_itemtype ) -%] + [%- SET itemavailable = 0 -%] + [%-%]Not for loan [%- IF ( item.restrictedopac ) -%] ([%- item.restrictedopac -%])[%- END -%] + [%- END -%] + [%- IF ( item.damaged ) -%] + [%- SET itemavailable = 0 -%] + [%-%]Item damaged + [%- END -%] + [%- IF item.on_order -%] + [%- SET itemavailable = 0 -%] + [%-%]On order + [%- END -%] + [%- IF ( itemavailable ) -%] + [%-%]Available [%- IF ( item.restrictedopac ) -%] ([%- item.restrictedopac -%])[%- END -%] + [%- END -%] +[%- END -%] + +[% INCLUDE 'doc-head-open.inc' %] +[% IF ( sign ) %][% sign.name %] - Koha[% ELSE %]Koha digital signs[% END %] +[%- IF ( sign.webapp ) %] + + +[% END -%] +[% BLOCK cssinclude %] + [%- IF Koha.Preference( 'OPACDigitalSignsCSS' ) != '' -%] + + + [%- ELSE -%] + + + [%- END -%] +[% END # BLOCK cssinclude %] +[% INCLUDE 'doc-head-close.inc' %] + +[% INCLUDE 'bodytag.inc' bodyid='opac-signs' %] + +[%- UNLESS Koha.Preference( 'OPACDigitalSigns' ) -%] +

Digital signs are not enabled!

+[%- ELSE -%] + [%# Display a sign, all its streams and all records %] + [%- IF ( sign ) -%] + [%- IF ( streams.0 ) -%] + [%# Iterate through the streams, creating one front page for each %] + [%- FOREACH s IN streams -%] +
+
+
+ [%# The header has a list of buttons for all the streams %] + [%- SET localstreams = streams -%] + [%- FOREACH stream IN localstreams -%] + [% IF s.sign_stream_id == stream.sign_stream_id %] + [% stream.name %] + [% ELSE %] + [% stream.name %] + [% END %] + [% END -%] +
+
+
+

[% s.name %]

+
+
+ + [% END # FOREACH s IN streams %] + [% ELSE %] +

No streams attached to this sign.

+ [% END # IF ( streams.0 ) %] + [% END # IF ( sign ) %] + + [%# Display a list of all signs, as a default. Links use data-ajax="false" so signs will replace the first page, not be AJAXed in. %] + [%# This page is not meant to be viewed by non-librarians, so it can not be themed. %] + [% IF ( signs ) %] +
+
+

All signs

+
+
+ +
+
+ [% END # IF ( signs ) %] +[% END # UNLESS Koha.Preference( 'OPACDigitalSigns' ) %] + +[% INCLUDE 'opac-bottom.inc' is_popup=1 %] +[% BLOCK jsinclude %] + [% IF sign && Koha.Preference( 'OPACDigitalSigns') %] + + [% END # IF ( sign ) %] + +[% END # BLOCK jsinclude %] + + + diff --git a/opac/opac-signs.pl b/opac/opac-signs.pl new file mode 100755 index 0000000..66057df --- /dev/null +++ b/opac/opac-signs.pl @@ -0,0 +1,49 @@ +#!/usr/bin/perl + +# Copyright 2012 Magnus Enger Libriotech +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use CGI; +use C4::Auth; +use C4::Output; +use Koha::Signs; +use Modern::Perl; + +binmode STDOUT, ':encoding(UTF-8)'; # FIXME Non-ASCII is broken without this + +my $query = CGI->new; +my $sign_id = $query->param('sign') || ''; + +my ( $template, $borrowernumber, $cookie ) = get_template_and_user({ + 'template_name' => 'opac-signs.tt', + 'query' => $query, + 'type' => 'opac', + 'authnotrequired' => ( C4::Context->preference('OpacPublic') ? 1 : 0 ), + 'flagsrequired' => { borrow => 1 }, +}); + +if ( C4::Context->preference('OPACDigitalSigns') ) { + if ( $sign_id ne '' ) { # Display a sign with streams + $template->{VARS}->{'sign'} = GetSign( $sign_id ); + $template->{VARS}->{'streams'} = GetSignStreamsAttachedToSignWithRecords( $sign_id, 1 ); + } + else { # Display a list of all available signs + $template->{VARS}->{'signs'} = GetSigns(); + } +} + +output_html_with_http_headers $query, $cookie, $template->output; diff --git a/tools/signs.pl b/tools/signs.pl new file mode 100755 index 0000000..702829d --- /dev/null +++ b/tools/signs.pl @@ -0,0 +1,258 @@ +#!/usr/bin/perl +# +# Copyright 2012 Magnus Enger Libriotech +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# +# + +=head1 NAME + +signs.pl - Script for managing digital signs for the OPAC. + +=head1 SYNOPSIS + +signs.pl + +=head1 DESCRIPTION + +Allows authorized users to create and manage digital signs for the OPAC. + +=cut + +use Koha::Signs; +use CGI; +use C4::Auth; +use C4::Context; +use C4::Log; +use C4::Output; +use C4::Reports::Guided; +use Modern::Perl; + +my $cgi = new CGI; +my $dbh = C4::Context->dbh; +my $script_name = 'signs.pl'; + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user({ + template_name => "tools/signs.tt", + query => $cgi, + type => "intranet", + authnotrequired => 0, + flagsrequired => { tools => 'edit_digital_signs' }, + debug => 0, +}); + +my $op = $cgi->param('op') || ''; +my $sign_id = $cgi->param('sign_id') || ''; +my $sign_stream_id = $cgi->param('sign_stream_id') || ''; +my $sign_to_stream_id = $cgi->param('sign_to_stream_id') || ''; +my $parameters = $cgi->param('parameters') || ''; + +# Streams + +if ( $op eq 'add_stream' ) { + + $template->param( + 'op' => 'stream_form', + 'reports' => get_saved_reports( { group => 'SIG' } ), + ); + +} elsif ( $op eq 'edit_stream' && $sign_stream_id ne '') { + + my $stream = GetSignStream( $sign_stream_id ); + + $template->param( + 'op' => 'stream_form', + 'stream' => $stream, + 'reports' => get_saved_reports( { group => 'SIG' } ), + 'script_name' => $script_name + ); + +} elsif ( $op eq 'save_stream' ) { + + if ( $sign_stream_id ne '' ) { + ModSignStream( $cgi->param('name'), $cgi->param('report'), $cgi->param('sign_stream_id') ); + } else { + AddSignStream( $cgi->param('name'), $cgi->param('report'), ); + } + print $cgi->redirect($script_name); + +} elsif ( $op eq 'view_stream' && $sign_stream_id ne '' ) { + + my $stream = GetSignStream( $sign_stream_id ); + + if ( $stream->{'savedsql'} =~ m/<param( 'has_params' => 1 ); + } else { + my $records = GetSignStreamRecords( $stream ); + $template->param( 'records' => $records->{result} ); + } + + $template->param( + 'op' => 'view_stream', + 'stream' => $stream, + 'script_name' => $script_name + ); + +} elsif ( $op eq 'del_stream' ) { + + my $stream = GetSignStream( $sign_stream_id ); + + $template->param( + 'op' => 'del_stream', + 'stream' => $stream, + 'script_name' => $script_name, + ); + +} elsif ( $op eq 'del_stream_ok' ) { + + DelSignStream( $sign_stream_id ); + + $template->param( + 'op' => 'del_stream_ok', + 'script_name' => $script_name, + ); + +# Signs + +} elsif ( $op eq 'add_sign' ) { + + $template->param( + 'op' => 'sign_form', + ); + +} elsif ( $op eq 'edit_sign' && $sign_id ne '' ) { + + $template->param( + 'op' => 'sign_form', + 'sign' => GetSign( $sign_id ), + 'script_name' => $script_name, + ); + +} elsif ( $op eq 'save_sign' ) { + + if ($cgi->param('sign_id')) { + ModSign( $cgi->param('name'), $cgi->param('webapp'), $cgi->param('swatch'), $cgi->param('transition'), $cgi->param('idleafter'), $cgi->param('pagedelay'), $cgi->param('reloadafter'), $cgi->param('sign_id') ); + } else { + AddSign( $cgi->param('name'), $cgi->param('webapp'), $cgi->param('swatch'), $cgi->param('transition'), $cgi->param('idleafter'), $cgi->param('pagedelay'), $cgi->param('reloadafter') ); + } + print $cgi->redirect($script_name); + +} elsif ( $op eq 'view_sign' && $sign_id ne '' ) { + + $template->param( + 'op' => 'view_sign', + 'sign' => GetSign( $sign_id ), + 'streams' => GetSignStreamsAttachedToSignWithRecords( $sign_id, 0 ), + 'script_name' => $script_name, + ); + +} elsif ( $op eq 'del_sign' && $sign_id ne '' ) { + + $template->param( + 'op' => 'del_sign', + 'sign' => GetSign( $sign_id ), + 'script_name' => $script_name, + ); + +} elsif ( $op eq 'del_sign_ok' ) { + + DelSign( $sign_id ); + + $template->param( + 'op' => 'del_sign_ok', + 'script_name' => $script_name, + ); + +# Signs and streams + +} elsif ( $op eq 'edit_streams' && $sign_id ne '') { + + $template->param( + 'op' => 'edit_streams', + 'sign' => GetSign( $sign_id ), + 'sign_id' => $sign_id, + 'streams' => GetSignStreams(), + 'attached' => GetSignStreamsAttachedToSign( $sign_id ), + 'script_name' => $script_name + ); + +} elsif ( $op eq 'attach_stream_to_sign' && $sign_stream_id ne '' && $sign_id ne '' ) { + + my $sign_to_stream_id = AttachSignStreamToSign( $sign_stream_id, $sign_id ); + + # Check if the SQL associated with the stream needs parameters + my $stream = GetSignStream( $sign_stream_id ); + if ( $stream->{'savedsql'} =~ m/<redirect( $script_name . '?op=get_params&sign_to_stream_id=' . $sign_to_stream_id . '&sign_stream_id=' . $sign_stream_id . '&sign_id=' . $sign_id ); + } else { + print $cgi->redirect( $script_name . '?op=edit_streams&sign_id=' . $sign_id ); + } + +} elsif ( $op eq 'get_params' && $sign_to_stream_id ne '' && $sign_stream_id ne '' && $sign_id ne '' ) { + + my $stream = GetSignStream( $sign_stream_id ); + my $records = GetSignStreamRecords($stream, $sign_to_stream_id); + if ( $records ) { + $template->param( 'records' => $records->{result} ); + } else { + $template->param( 'has_params' => 1 ); + } + + $template->param( + 'op' => 'get_params', + 'stream' => $stream, + 'sign_id' => $sign_id, + 'sign_stream_id' => $sign_stream_id, + 'sign_to_stream_id' => $sign_to_stream_id, + 'params' => GetSignStreamParams( $sign_to_stream_id ), + 'newsql' => $records->{sql}, + 'script_name' => $script_name, + ); + +} elsif ( $op eq 'save_params' && $sign_to_stream_id ne '' && $sign_id ne '' ) { + + ModSignStreamParams( $sign_to_stream_id, $parameters ); + print $cgi->redirect( $script_name . '?op=get_params&sign_to_stream_id=' . $sign_to_stream_id . '&sign_stream_id=' . $sign_stream_id . '&sign_id=' . $sign_id ); + +} elsif ( $op eq 'detach_stream_from_sign' && $sign_to_stream_id ne '' ) { + + DetachSignStreamFromSign( $sign_to_stream_id ); + print $cgi->redirect($script_name . '?op=edit_streams&sign_id=' . $sign_id); + +} else { + + # TODO Check the setting of OPACDigitalSigns, give a warning if it is off + + $template->param( + 'streams' => GetSignStreams(), + 'signs' => GetSigns(), + 'OPACBaseURL' => C4::Context->preference( 'OPACBaseURL' ) || '', + 'else' => 1 + ); + +} + +output_html_with_http_headers $cgi, $cookie, $template->output; + +exit 0; + +=head1 AUTHORS + +Written by Magnus Enger of Libriotech. + +=cut -- 2.1.4