View | Details | Raw Unified | Return to bug 8628
Collapse All | Expand All

(-)a/koha-tmpl/opac-tmpl/bootstrap/css/signs.css (+100 lines)
Line 0 Link Here
1
.carousel-container {
2
    height: 225px;
3
    position: relative;
4
    margin: 0 auto 40px;
5
    -webkit-perspective: 1100px;
6
    -moz-perspective: 1100px;
7
    -o-perspective: 1100px;
8
    -ms-perspective: 1100px;
9
    perspective: 1100px;
10
}
11
12
.carousel {
13
    width: 100%;
14
    height: 100%;
15
    -webkit-transform-style: preserve-3d;
16
    -moz-transform-style: preserve-3d;
17
    -o-transform-style: preserve-3d;
18
    -ms-transform-style: preserve-3d;
19
    transform-style: preserve-3d;
20
}
21
22
.unicorn {
23
    display: inline;
24
    position: relative;
25
    width: 150px;
26
    height: 225px;
27
    left: 10px;
28
    top: 10px;
29
    -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));
30
}
31
32
.ui-li {
33
    padding-top: 0px !important;
34
    padding-bottom: 0px !important;
35
    margin-bottom: -7px !important;
36
}
37
38
.ui-li h4 {
39
    margin-top: 2px !important;
40
    margin-bottom: 2px !important;
41
}
42
43
.ui-li-icon {
44
    top: 15% !important;
45
}
46
47
.vspace {
48
    margin-top: 2em;
49
}
50
51
.content {
52
    text-align: center;
53
}
54
55
.btn-record {
56
    margin: 10px;
57
}
58
59
.cover {
60
    border: none;
61
    display: inline-block;
62
    height: 225px;
63
    width: 150px;
64
    background-size: 100%;
65
    background-repeat: round;
66
}
67
68
.cover.cover-blank {
69
}
70
71
.cover.placeholder {
72
}
73
74
.cover .cover-inner {
75
    display: table-cell;
76
    vertical-align: middle;
77
    padding: 25px;
78
    border: 2px solid #fff;
79
    height: 171px;
80
    max-height: 171px;
81
    width: inherit;
82
}
83
84
.cover-text {
85
    text-align: center;
86
    position: relative;
87
    font-family: Georgia, "Palatino Linotype", "Book Antiqua", Palatino, "Times New Roman", serif;
88
    font-size: 1em;
89
    max-height: inherit;
90
    overflow: hidden;
91
}
92
93
.cover-text .title {
94
    font-weight: bold;
95
}
96
97
.cover-text .author {
98
    font-style: italic;
99
    margin-top: 1em;
100
}
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-signs.tt (+564 lines)
Line 0 Link Here
1
[% USE Koha %]
2
[% USE KohaDates %]
3
[% USE Branches %]
4
[% USE JSON.Escape %]
5
6
[%- BLOCK item_status -%]
7
    [%- SET itemavailable = 1 -%]
8
    [%- IF ( item.itemlost ) -%]
9
        [%- SET itemavailable = 0 -%]
10
        [%-%]Item lost
11
    [%- END -%]
12
    [%- IF ( item.datedue || issue.date_due ) -%]
13
        [%- SET itemavailable = 0 -%]
14
        [%- IF item.onsite_checkout -%]
15
            [%-%]Currently in local use
16
        [%- ELSE -%]
17
            [%-%]Checked out
18
        [%- END -%]
19
    [%- END -%]
20
    [%- IF ( item.transfertwhen ) %]
21
        [%- SET itemavailable = 0 -%]
22
        [%-%]In transit from [%- item.transfertfrom %] to [%- item.transfertto %] since [%- item.transfertwhen | $KohaDates %]
23
    [%- END %]
24
    [%- IF ( item.waiting ) -%]
25
        [%- SET itemavailable = 0 -%]
26
        [%-%]On hold
27
    [%- END -%]
28
    [%- IF ( item.withdrawn ) -%]
29
        [%- SET itemavailable = 0 -%]
30
        [%-%]Item withdrawn
31
    [%- END -%]
32
    [%- IF ( item.itemnotforloan ) -%]
33
        [%- SET itemavailable = 0 -%]
34
        [%- IF ( item.notforloanvalueopac ) -%]
35
            [%- item.notforloanvalueopac -%] [%- IF ( item.restrictedopac ) -%] ([%- item.restrictedopac -%])[%- END -%]
36
        [%- ELSE -%]
37
            [%-%]Not for loan [%- IF ( item.restrictedopac ) -%] ([%- item.restrictedopac -%])[%- END -%]
38
        [%- END -%]
39
    [%- ELSIF ( item.notforloan_per_itemtype ) -%]
40
        [%- SET itemavailable = 0 -%]
41
        [%-%]Not for loan [%- IF ( item.restrictedopac ) -%] ([%- item.restrictedopac -%])[%- END -%]
42
    [%- END -%]
43
    [%- IF ( item.damaged ) -%]
44
        [%- SET itemavailable = 0 -%]
45
        [%-%]Item damaged
46
    [%- END -%]
47
    [%- IF item.on_order -%]
48
        [%- SET itemavailable = 0 -%]
49
        [%-%]On order
50
    [%- END -%]
51
    [%- IF ( itemavailable ) -%]
52
        [%-%]Available [%- IF ( item.restrictedopac ) -%] ([%- item.restrictedopac -%])[%- END -%]
53
    [%- END -%]
54
[%- END -%]
55
56
[% INCLUDE 'doc-head-open.inc' %]
57
<title>[% IF ( sign )  %][% sign.name %] - Koha[% ELSE %]Koha digital signs[% END %]</title>
58
[%- IF ( sign.webapp ) %]
59
    <meta name="apple-mobile-web-app-capable" content="yes" />
60
    <meta name="viewport" content="width=device-width, initial-scale=1">
61
[% END -%]
62
[% BLOCK cssinclude %]
63
    [%- IF Koha.Preference( 'OPACDigitalSignsCSS' ) != '' -%]
64
      <style type="text/css">
65
        [% Koha.Preference( 'OPACDigitalSignsCSS' ) %]
66
      </style>
67
      <link rel="stylesheet" href="[% interface %]/lib/jquery/mobile/jquery.mobile.structure.min.css" />
68
    [%- ELSE -%]
69
      <link rel="stylesheet" href="[% interface %]/bootstrap/css/signs.css" />
70
      <link rel="stylesheet" href="[% interface %]/lib/jquery/mobile/jquery.mobile.min.css" />
71
    [%- END -%]
72
[% END # BLOCK cssinclude %]
73
[% INCLUDE 'doc-head-close.inc' %]
74
</head>
75
[% INCLUDE 'bodytag.inc' bodyid='opac-signs' %]
76
77
[%- UNLESS Koha.Preference( 'OPACDigitalSigns' ) -%]
78
  <p>Digital signs are not enabled!</p>
79
[%- ELSE -%]
80
  [%# Display a sign, all its streams and all records  %]
81
  [%- IF ( sign )  -%]
82
    [%- IF ( streams.0 )  -%]
83
      [%# Iterate through the streams, creating one front page for each %]
84
      [%- FOREACH s IN streams -%]
85
          <div data-role="page" class="page-stream" data-stream-id="[% s.sign_stream_id %]" data-theme="[% sign.swatch %]" id="stream_[% s.sign_stream_id %]">
86
              <div data-role="header" data-theme="[% sign.swatch %]" data-position="fixed">
87
                  <div style="text-align: center;">
88
                      [%# The header has a list of buttons for all the streams %]
89
                      [%- SET localstreams = streams -%]
90
                      [%- FOREACH stream IN localstreams -%]
91
                          [% IF s.sign_stream_id == stream.sign_stream_id %]
92
                              <a href="#stream_[% stream.sign_stream_id %]" data-stream-id="[% stream.sign_stream_id %]" class="btn-stream stream-active" data-inline="true" data-icon="star" data-role="button">[% stream.name %]</a>
93
                          [% ELSE %]
94
                              <a href="#stream_[% stream.sign_stream_id %]" data-stream-id="[% stream.sign_stream_id %]" class="btn-stream" data-inline="true" data-role="button">[% stream.name %]</a>
95
                          [% END %]
96
                      [% END -%]
97
                  </div>
98
              </div> <!-- /header -->
99
              <div data-role="content" class="content">
100
                  <h1>[% s.name %]</h1>
101
              </div> <!-- /content -->
102
          </div> <!-- /page -->
103
104
      [% END # FOREACH s IN streams %]
105
    [% ELSE %]
106
      <p>No streams attached to this sign.</p>
107
    [% END # IF ( streams.0 ) %]
108
  [% END # IF ( sign ) %]
109
110
  [%# 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. %]
111
  [%# This page is not meant to be viewed by non-librarians, so it can not be themed. %]
112
  [% IF ( signs )  %]
113
    <div data-role="page" id="allsigns">
114
      <div data-role="header" data-position="fixed">
115
        <h1>All signs</h1>
116
      </div>
117
      <div data-role="content">
118
        <ul data-role="listview">
119
        [% FOREACH SIGN IN signs %]
120
          <li><a href="?sign=[% SIGN.sign_id %]" data-ajax="false">[% SIGN.name %]</a></li>
121
        [% END %]
122
        </ul>
123
      </div>
124
    </div>
125
  [% END # IF ( signs ) %]
126
[% END # UNLESS Koha.Preference( 'OPACDigitalSigns' ) %]
127
128
[% INCLUDE 'opac-bottom.inc' is_popup=1 %]
129
[% BLOCK jsinclude %]
130
    [% IF sign && Koha.Preference( 'OPACDigitalSigns') %]
131
    <script type="text/javascript">
132
    //<![CDATA[
133
        $(function (){
134
            var active_stream = '#' + $('.page-stream').first().attr('id');
135
            var active_record;
136
137
            /*****************************************************************
138
            * Page idle handling
139
            */
140
            var doIdle = false;
141
            var idleTimePage = 0;
142
            var idleTime = 0;
143
            var idleInterval = setInterval(idleIncrementer, 1000);
144
145
            function resetIdle() {
146
                idleTimePage = 0;
147
                idleTime = 0;
148
                doIdle = false;
149
            }
150
151
            function idleIncrementer() {
152
                idleTimePage++;
153
                idleTime++;
154
155
                [% IF ( sign.idleafter ) -%]
156
                if (idleTime >= [% sign.idleafter %]) {
157
                    doIdle = true;
158
                }
159
                [%- END -%]
160
161
                [%- IF ( sign.pagedelay ) -%]
162
                if (doIdle && idleTimePage >= [% sign.pagedelay %]) {
163
                    idleTimePage = 0;
164
                    swipe('next', true, true);
165
                }
166
                [%- END -%]
167
168
                [%- IF ( sign.reloadafter ) -%]
169
                if (doIdle && idleTime >= [% sign.reloadafter %]) {
170
                    resetIdle();
171
                    window.location.reload(true);
172
                }
173
                [%- END -%]
174
            }
175
176
            /*****************************************************************
177
            * User interaction methods
178
            */
179
            $('.btn-stream').click(function(){
180
                active_stream = $(this).attr('href');
181
                active_record = $(active_stream).find('.content a').first().attr('href');
182
            });
183
184
            /* swipe to next/previous record/stream */
185
            function swipe(direction, forceRecordView, warp) {
186
                var delta = direction == 'prev' ? -1 : 1;
187
                var isInRecordView = forceRecordView || window.location.hash.indexOf('#record') >= 0;
188
189
                if(isInRecordView) {
190
                    active_record = do_swipe(
191
                                        $(active_stream).find('.content a'),
192
                                        function($elm){
193
                                            return $elm.attr('href');
194
                                        },
195
                                        active_record
196
                                    );
197
                }
198
                else { // in stream view
199
                    active_stream = do_swipe(
200
                                        $('.page-stream'),
201
                                        function($elm) {
202
                                            return '#'+$elm.attr('id');
203
                                        },
204
                                        active_stream
205
                                    );
206
                }
207
208
                /* jump to next/prev page in pages returned from <selector>
209
                *  filtered through <filter> in references to <active>.
210
                *
211
                *  Return new active page.
212
                */
213
                function do_swipe(selector, filter, active) {
214
                    var list = [];
215
                    selector.each(function(){
216
                        list.push(filter($(this)));
217
                    });
218
219
                    var i = list.indexOf(active);
220
                    i = i == -1 ? 0 : i; // default to first if no active found
221
222
                    if(i >= 0) {
223
                        if(i >= list.length-1 && delta > 0) {
224
                            if(warp)
225
                                i = 0; // warp to start
226
                            else
227
                                return list[i];
228
                        } else if(i == 0 && delta < 0) {
229
                            if(warp)
230
                                i = list.length-1; // warp to end
231
                            else
232
                                return list[i];
233
                        } else {
234
                            i += delta;
235
                        }
236
237
                        $.mobile.changePage(list[i]);
238
                        return list[i];
239
                    }
240
241
                    return active;
242
                }
243
            }
244
245
            /*****************************************************************
246
            * Global events
247
            */
248
            $(window).on( 'swiperight', function() { resetIdle(); swipe('prev'); });
249
            $(window).on( 'swipeleft',  function() { resetIdle(); swipe('next'); });
250
            $(window).on( 'mousemove',  function() { resetIdle(); });
251
            $(window).on( 'keypress',   function() { resetIdle(); });
252
            $(window).on( 'tap',        function() { resetIdle(); });
253
254
            /*****************************************************************
255
            * Carousel
256
            */
257
            var Carousel = function ($elm) {
258
                var self = this;
259
                this.$elm = $elm;
260
                this.unicornCount = $elm.children().length;
261
                this.rotateFn = 'rotateY';
262
                this.$unicorns = this.$elm.children();
263
                this.i_active = this.$unicorns.index(this.$elm.children('.active'));
264
                this.unicornSize = this.$unicorns.first().outerWidth();
265
266
                this.modify = function() {
267
                    var offsetScale = $(window).width() / (this.unicornSize*this.unicornCount);
268
                    offsetScale = offsetScale > 1 ? 1 : offsetScale;
269
270
                    for ( i = 0; i < this.unicornCount ; i++ ) {
271
                        var $unicorn = this.$unicorns.eq(i);
272
                        var angle = 50*(i < this.i_active ? 1 : -1);
273
                        var scale = 0.75/Math.abs(i-this.i_active);
274
                        if(i == this.i_active) {
275
                            scale=1;
276
                            angle=0;
277
                        }
278
279
                        var transform = this.rotateFn + '(' + angle + 'deg) scale('+scale+')';
280
                        $unicorn.css({
281
                                        '-webkit-transform': transform,
282
                                        '-moz-transform': transform,
283
                                        '-o-transform': transform,
284
                                        '-ms-transform': transform,
285
                                        'transform': transform
286
                                    });
287
                        $unicorn.css('left', offsetScale*this.unicornSize*(i-this.i_active)+'px');
288
                        $unicorn.css('z-index', -1*Math.abs(i-this.i_active));
289
                    }
290
                };
291
            };
292
293
294
            /*****************************************************************
295
            * ImageCache
296
            */
297
            var ImageCache = function() {
298
                var self = this;
299
                self.cached = {};
300
                self.nocover = {};
301
302
                /* get cover image from local cover or fallbacks */
303
                self.get = function(record, finished_cb) {
304
                    if( record.biblionumber in self.cached ) {
305
                        finished_cb(self.cached[record.biblionumber]);
306
                    } else {
307
                        // first try local cover
308
                        var $img = $('<img/>')
309
                                    .attr('src','opac-image.pl?biblionumber='+record.biblionumber)
310
                                    .css('display','none')
311
                                    .appendTo('body');
312
313
                        $img.on('load', function() {
314
                            self.cached[record.biblionumber] = $(this);
315
                            // have a 1x1 pixel image, fallback to openlibrary ...
316
                            if($(this).height() <= 1) {
317
                                // ... if we can
318
                                if(record.isbn) {
319
                                    var ol_url = 'http://covers.openlibrary.org/b/isbn/';
320
                                    ol_url += record.isbn + '-M.jpg?default=false';
321
322
                                    var $ol_img = $('<img/>')
323
                                        .attr('src',ol_url)
324
                                        .css('display','none')
325
                                        .appendTo('body')
326
                                        .on('load', function() {
327
                                            $img.remove(); // remove old 1x1 pixel image
328
                                            self.cached[record.biblionumber] = $ol_img;
329
                                            finished_cb($(this));
330
                                        })
331
                                        .on('error', function() {
332
                                            // fallback to no cover image
333
                                            self.nocover[record.biblionumber] = true;
334
                                            finished_cb($(this));
335
                                        });
336
                                } else {
337
                                    // fallback to no cover image
338
                                    self.nocover[record.biblionumber] = true;
339
                                    finished_cb($(this));
340
                                }
341
                            } else {
342
                                finished_cb($(this));
343
                            }
344
                        });
345
                    }
346
                }
347
348
                self.have_cover = function(record) { return !(record.biblionumber in self.nocover) }
349
            };
350
            var img_cache = new ImageCache();
351
352
            /*****************************************************************
353
            * Cover
354
            */
355
            var coverCounter = 0;
356
            var Cover = function(record) {
357
                var self = this;
358
                self.record = record;
359
                self.id = coverCounter++;
360
361
                /* generate cover div */
362
                self.render = function(finished_cb) {
363
                    img_cache.get(record, function($img) {
364
                        self.$cover = $('<div class="cover cover_'+self.id+'" data-id="'+self.id+'"/>');
365
                        self.$cover.css('background-image', 'url("'+$img.attr('src')+'")');
366
                        self.$cover.css('background-size', '100%');
367
                        self.$cover.css('background-position', 'center center');
368
                        self.$cover.css('background-repeat', 'no-repeat');
369
                        self.$cover.addClass('ui-bar-[% sign.swatch %]');
370
371
                        if( !img_cache.have_cover(record) ) {
372
                            self.$vcontainer = $('<div class="cover-inner"/>');
373
                            self.$vcontainer.addClass('ui-bar-[% sign.swatch %]');
374
                            self.$cover.append(self.$vcontainer);
375
376
                            self.$cover.addClass('cover-blank');
377
                            self.$cover.css('border-color', $('.ui-bar-[% sign.swatch %]').first().css('background-color'));
378
379
                            var $covertext = $('<div class="cover-text"></div>');
380
                            $covertext.append($('<div class="title">'+record.title+'</div>'));
381
                            $covertext.append($('<div class="author">'+record.author+'</div>'));
382
383
                            self.$vcontainer.append($covertext);
384
                        }
385
386
                        finished_cb(self);
387
                    });
388
                }
389
            };
390
391
            /* create page for a cover */
392
            function create_CoverPage(cover, sid) {
393
                var $cover = cover.$cover.clone();
394
                var $stream = $('#stream_'+sid);
395
396
                var $page = $('<div data-role="page" data-close-btn="none" data-theme="[% sign.swatch %]" id="record_'+sid+'_'+cover.record.biblionumber+'"/>');
397
                var $head = $('<div data-role="header" data-theme="[% sign.swatch %]"/>');
398
                var $content = $('<div data-role="content" class="content"/>')
399
                var $foot = $('<div data-role="foot" data-position="fixed" class="foot"/>')
400
401
                /***************
402
                * header
403
                *******/
404
                $head.append($('<h1 aria-level="1" role="heading" class="ui-title">'+cover.record.title+'</h1>'));
405
406
                /***************
407
                * content
408
                ********/
409
                /* carousel */
410
                var $carousel_container = $('<div class="carousel-container"/>');
411
                $content.append($carousel_container);
412
413
                var $carousel = $('<ul class="carousel"/>');
414
                var neighbours= 2; // on each side
415
                var unicorns = [];
416
417
                /* grab <neighbours> covers around the active */
418
                $stream.find('.cover').each(function() {
419
                    unicorns.push($(this).data('id'));
420
                });
421
                var this_unicorn = unicorns.indexOf(cover.id);
422
                unicorns = unicorns.slice(
423
                        Math.max(this_unicorn-neighbours, 0),
424
                        1+Math.min(this_unicorn+neighbours, unicorns.length-1)
425
                        );
426
427
                /* create unicorns and add to carousel */
428
                for(var i=0; i < unicorns.length; i++) {
429
                    var $unicorn_cover = $('#stream_'+sid).find('.cover_'+unicorns[i]);
430
                    $unicorn_cover = $unicorn_cover.parent('a').clone();
431
                    var $unicorn = $('<li class="unicorn"/>').append($unicorn_cover);
432
                    if(unicorns[i] == cover.id) {
433
                        $unicorn.addClass('active');
434
                    }
435
                    $carousel.append($unicorn);
436
                }
437
                $carousel_container.append($carousel);
438
439
                /* initilize carousel on pagecreate */
440
                $page.on("pagecreate", function(){
441
                        var carousel = new Carousel($carousel);
442
                        $page.data('carousel', carousel);
443
                        carousel.modify();
444
                });
445
446
                /* item info */
447
                var $info = $('<div/>')
448
                $info.append($('<span><strong>'+_("Author")+':</strong> ' + cover.record.author+'</span>'));
449
                if(cover.record.publisher) {
450
                    $info.append($('<br/><span><strong>'+_("Publisher")+':</strong> ' + cover.record.publisher + '</span>'));
451
                }
452
453
                if(cover.record.items.length > 0) {
454
                    $info.append('<div class="vspace"/>');
455
                }
456
                var $items = $('<ul data-role="listview"/>');
457
                for(var i=0; i < cover.record.items.length; i++) {
458
                    var $li = $('<li/>');
459
                    var item = cover.record.items[i];
460
461
                    if(item.type) {
462
                        $li.append($('<img src="/opac-tmpl/lib/famfamfam/'+item.type+'.png" class="ui-li-icon"/>'));
463
                    }
464
                    var location = item.location_description ? item.location_description + _(" in ") + item.home_branch: item.home_branch;
465
                    var item_info = item.status + _(" at ") + location;
466
                    $li.append($('<h4>'+item_info+'</h4>'));
467
                    if(item.datedue) {
468
                        $li.append('<p>'+_("Date due") + ': ' + item.datedue+'</p>');
469
                    }
470
                    $items.append($li);
471
                }
472
                $info.append($items);
473
                $content.append($info);
474
475
                /***************
476
                * footer
477
                *******/
478
                $foot.append($('<a href="#stream_'+sid+'" data-role="button" data-theme="[% sign.swatch %]" data-transition="[% sign.transition %]">'+_("Back")+'</a>'));
479
480
                /***************
481
                * page
482
                *****/
483
                $page.append($head);
484
                $page.append($content);
485
                $page.append($foot);
486
                $page.appendTo('body');
487
488
                return $page;
489
            };
490
491
            /*****************************************************************
492
            * Page generation
493
            */
494
            var streams = {
495
                [%- FOREACH stream IN streams %]
496
                    '[% stream.sign_stream_id %]': {
497
                        'name': [% stream.name.json || '""' %],
498
                        'records': [
499
                        [%- FOREACH record IN stream.records %]
500
                            {'author': [% record.author.json || '""' %],
501
                            'title': [% record.title.json || '""' %],
502
                            'publisher': [% record.publishercode.json || '""' %],
503
                            'biblionumber': [% record.biblionumber.json || '""' %],
504
                            'isbn': [% record.isbn.json || '""' %],
505
                            'items': [
506
                                [%- FOREACH item IN record.items %]
507
                                    {
508
                                        'type': [% item.itemtype.json || '""' %],
509
                                        'datedue': "[% item.datedue | $KohaDates as_due_date => 1 %]",
510
                                        'location': [% item.location.json || '""' %],
511
                                        'location_description': [% item.location_description.json || '""' %],
512
                                        'home_branch': "[% Branches.GetName(item.homebranch) | json %]",
513
                                        'status': "[% INCLUDE item_status item = item %]"
514
515
                                    }
516
                                    [%- UNLESS loop.last -%],[%- END -%]
517
                                [%- END %]
518
                            ]
519
                            }
520
                            [%- UNLESS loop.last -%],[%- END -%]
521
                        [%- END %]
522
                        ]
523
                }
524
                [%- UNLESS loop.last -%],[%- END -%]
525
                [%- END %]
526
            };
527
528
            /* fill up streams with records */
529
            var firstLoadedRecord = true;
530
            $('.page-stream').each(function() {
531
                var sid = $(this).data('stream-id');
532
                var $content = $(this).children('.content').first();
533
534
                for(var i in streams[sid].records) {
535
                    var cover = new Cover(streams[sid].records[i]);
536
                    var $link = $('<a href="#record_'+sid+'_'+cover.record.biblionumber+'" class="btn-record" data-transition="[% sign.transition %]"/>')
537
                    $link.click(function(){ active_record = $(this).attr('href'); });
538
                    $content.append($link.append($('<div class="cover placeholder ui-bar-[% sign.swatch %] cover_'+cover.id+'" data-id="'+cover.id+'"/>')));
539
540
                    cover.render(function(cover_rendered) {
541
                        var $coverPage = create_CoverPage(cover_rendered, sid);
542
                        /* initialize active_record with first loaded record from active stream */
543
                        if(firstLoadedRecord && sid == $(active_stream).data('stream-id') ){
544
                            active_record = cover_rendered.$cover.attr('href');
545
                            firstLoadedRecord = false;
546
                        }
547
548
                        /* replace all placeholders for this cover with rendered version*/
549
                        $('.placeholder.cover_'+cover_rendered.id).each(function() {
550
                            $(this).replaceWith(cover_rendered.$cover.clone());
551
                        });
552
                    });
553
                }
554
555
            });
556
        });
557
    //]]>
558
    </script>
559
    [% END # IF ( sign ) %]
560
    <script src="/opac-tmpl/lib/jquery/mobile/jquery.mobile.min.js"></script>
561
[% END # BLOCK jsinclude %]
562
563
</body>
564
</html>
(-)a/opac/opac-signs.pl (+113 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2012 Magnus Enger Libriotech
4
#
5
# This file is part of Koha.
6
#
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
10
# version.
11
#
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.
15
#
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.
19
20
use CGI;
21
use C4::Auth;
22
use C4::Output;
23
use C4::Biblio;
24
use C4::Reports::Guided;
25
use C4::Context;
26
use C4::Koha;
27
use C4::Items;
28
use Koha::AuthorisedValues;
29
use Koha::Signs;
30
use Koha::SignStreams;
31
use Koha::SignsToStreams;
32
use Koha::Reports;
33
use Modern::Perl;
34
35
binmode STDOUT, ':encoding(UTF-8)'; # FIXME Non-ASCII is broken without this
36
37
my $query   = CGI->new;
38
my $sign_id = $query->param('sign')         || '';
39
40
my ( $template, $borrowernumber, $cookie ) = get_template_and_user({
41
    'template_name'   => 'opac-signs.tt',
42
    'query'           => $query,
43
    'type'            => 'opac',
44
    'authnotrequired' => ( C4::Context->preference('OpacPublic') ? 1 : 0 ),
45
    'flagsrequired'   => { borrowers => 1 },
46
});
47
48
if ( C4::Context->preference('OPACDigitalSigns') ) {
49
    if ( $sign_id ne '' ) { # Display a sign with streams
50
        $template->{VARS}->{'sign'} = Koha::Signs->find( $sign_id );
51
52
        # Getting sign streams attached to sign with records
53
        my $schema = Koha::Database->new()->schema();
54
        my @signstostreams = $schema->resultset('SignsToStream')->search({ 'me.sign_id' => $sign_id }, { prefetch => 'sign_stream' });
55
        my @changedstreams;
56
        my %record_cache = ();
57
        foreach my $s ( @signstostreams ) {
58
            my $stream = Koha::SignStreams->find( $s->sign_stream_id );
59
            my $sql = Koha::Reports->find($stream->saved_sql_id);
60
            my $params = Koha::SignsToStreams->find({ sign_to_stream_id => $s->sign_to_stream_id });
61
62
            # Generate SQL with added params
63
            my $newsql = $sql->savedsql;
64
            foreach my $param ( split /&/, $params->params ) {
65
                $param =~ tr/ //ds; # replace any whitespace with nothing, strip the spaces out so the query works
66
                my ( $key, $value ) = split /=|<|>/, $param; # The < and > in the split are just to prevent software errors, the sign in the query must be changed in the report itself
67
                $newsql =~ s/$key/$value/g;
68
            }
69
70
            # Run query with new sql
71
            my ( $records, $error ) = execute_query( $newsql, 0, 999999 );
72
            if ( ! $error ) {
73
                $records = $records->fetchall_arrayref({});
74
            }
75
            # Include marc
76
            my @processed_records;
77
            foreach my $rec ( @{$records} ) {
78
                unless (defined $record_cache{$rec->{'biblionumber'}}) {
79
                    my $marc = GetMarcBiblio({ biblionumber => $rec->{'biblionumber'} });
80
                    if ( ! $marc ) {
81
                        next;
82
                    }
83
84
                    my $isbn = GetNormalizedISBN( undef, $marc, C4::Context->preference("marcflavor") ) || '';
85
                    $rec->{'isbn'} = $isbn;
86
87
                    my $dat = GetBiblioData($rec->{'biblionumber'});
88
                    my @items = GetItemsInfo($rec->{'biblionumber'});
89
                    foreach my $item ( @items ) {
90
                        my $shelflocations = { map { $_->authorised_value => $_->opac_description } Koha::AuthorisedValues->search_by_koha_field( { frameworkcode => $dat->{frameworkcode}, kohafield => 'items.location' } ) };
91
                        if ( defined $item->{'location'} ) {
92
                            $item->{'location_description'} = $shelflocations->{ $item->{'location'} };
93
                        }
94
                    }
95
                    $rec->{'items'} = \@items;
96
                    foreach ( keys %{$dat} ) {
97
                        $rec->{"$_"} = defined $dat->{$_} ? $dat->{$_} : '';
98
                    }
99
                    $rec->{'marc'} = $marc;
100
                    $record_cache{$rec->{'biblionumber'}} = $rec;
101
                }
102
                push @processed_records, $record_cache{$rec->{'biblionumber'}};
103
            }
104
            $s->{'records'} = \@processed_records;
105
            push @changedstreams, $s;
106
        }
107
        $template->{VARS}->{'streams'} = \@changedstreams;
108
    } else { # Display a list of all available signs
109
        $template->{VARS}->{'signs'} = Koha::Signs->search({});
110
    }
111
}
112
113
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/tools/signs.pl (-1 / +1 lines)
Lines 188-193 if ( $op eq 'add_stream' ) { Link Here
188
        # Generate SQL with added params
188
        # Generate SQL with added params
189
        my $newsql = $sql->savedsql;
189
        my $newsql = $sql->savedsql;
190
        foreach my $param ( split /&/, $params->params ) {
190
        foreach my $param ( split /&/, $params->params ) {
191
            $param =~ tr/ //ds; # replace any whitespace with nothing, strip the spaces out so the query works
191
            my ( $key, $value ) = split /=|<|>/, $param; # The < and > in the split are just to prevent software errors, the sign in the query must be changed in the report itself
192
            my ( $key, $value ) = split /=|<|>/, $param; # The < and > in the split are just to prevent software errors, the sign in the query must be changed in the report itself
192
            $newsql =~ s/$key/$value/g;
193
            $newsql =~ s/$key/$value/g;
193
        }
194
        }
194
- 

Return to bug 8628