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

(-)a/Koha/MetaSearcher.pm (-37 / +131 lines)
Lines 56-64 sub new { Link Here
56
}
56
}
57
57
58
sub handle_hit {
58
sub handle_hit {
59
    my ( $self, $index, $server, $marcrecord ) = @_;
59
    my ( $self, $index, $server, $hit ) = @_;
60
60
61
    my $record = Koha::MetadataRecord->new( { schema => 'marc', record => $marcrecord } );
61
    my $record = Koha::MetadataRecord->new( { schema => 'marc', record => $hit->{record} } );
62
62
63
    my %fetch = (
63
    my %fetch = (
64
        title => 'biblio.title',
64
        title => 'biblio.title',
Lines 80-94 sub handle_hit { Link Here
80
    $metadata->{date} //= $metadata->{date2};
80
    $metadata->{date} //= $metadata->{date2};
81
81
82
    push @{ $self->{results} }, {
82
    push @{ $self->{results} }, {
83
        %$hit,
83
        server => $server,
84
        server => $server,
84
        index => $index,
85
        index => $index,
85
        record => $marcrecord,
86
        metadata => $metadata,
86
        metadata => $metadata,
87
    };
87
    };
88
}
88
}
89
89
90
sub search {
90
sub search {
91
    my ( $self, $server_ids, $query ) = @_;
91
    my ( $self, $server_ids, $terms ) = @_;
92
92
93
    my $resultset_expiry = 300;
93
    my $resultset_expiry = 300;
94
94
Lines 143-149 sub search { Link Here
143
            }
143
            }
144
        }
144
        }
145
145
146
        $select->add( $self->_start_worker( $server, $query ) );
146
        $select->add( $self->_start_worker( $server, $terms ) );
147
    }
147
    }
148
148
149
    # Handle these while the servers are searching
149
    # Handle these while the servers are searching
Lines 183-190 sub search { Link Here
183
    return $stats;
183
    return $stats;
184
}
184
}
185
185
186
our $_pqf_mapping = {
187
    author => '1=1004',
188
    'cn-dewey' => '1=13',
189
    'cn-lc' => '1=16',
190
    date => '1=30',
191
    isbn => '1=7',
192
    issn => '1=8',
193
    keyword => '1=1016',
194
    lccn => '1=9',
195
    'local-number' => '1=12',
196
    'music-identifier' => '1=51',
197
    'standard-identifier' => '1=1007',
198
    subject => '1=21',
199
    title => '1=4',
200
};
201
202
our $_batch_db_mapping = {
203
    author => 'import_biblios.author',
204
    isbn => 'import_biblios.isbn',
205
    issn => 'import_biblios.issn',
206
    'local-number' => 'import_biblios.control_number',
207
    title => 'import_biblios.title',
208
};
209
210
our $_batch_db_text_columns = {
211
    author => 1,
212
    keyword => 1,
213
    title => 1,
214
};
215
216
sub _pqf_query_from_terms {
217
    my ( $terms ) = @_;
218
219
    my $query;
220
221
    while ( my ( $index, $value ) = each %$terms ) {
222
        $value =~ s/"/\\"/;
223
224
        my $term = '@attr ' . $_pqf_mapping->{$index} . ' "' . $value . '"';
225
226
        if ( $query ) {
227
            $query = '@and ' . $query . ' ' . $term;
228
        } else {
229
            $query = $term;
230
        }
231
    }
232
233
    return $query;
234
}
235
236
sub _db_query_get_match_conditions {
237
    my ( $index, $value ) = @_;
238
239
    if ( $value =~ /\*/ ) {
240
        $value =~ s/\*/%/;
241
        return { -like => $value };
242
    } elsif ( $_batch_db_text_columns->{$index} ) {
243
        return map +{ -regexp => '[[:<:]]' . $_ . '[[:>:]]' }, split( /\s+/, $value );
244
    } else {
245
        return $value;
246
    }
247
}
248
249
sub _batch_db_query_from_terms {
250
    my ( $import_batch_id, $terms ) = @_;
251
252
    my @db_terms;
253
254
    while ( my ( $index, $value ) = each %$terms ) {
255
        if ( $index eq 'keyword' ) {
256
            my @term;
257
258
            while ( my ( $index, $db_column ) = each %$_batch_db_mapping ) {
259
                push @term, { $db_column => [ _db_query_get_match_conditions( $index, $value ) ] };
260
            }
261
262
            # These are implicitly joined with OR because the arrayref doesn't start with -and
263
            push @db_terms, \@term;
264
        } elsif ( $_batch_db_mapping->{$index} ) {
265
            push @db_terms, $_batch_db_mapping->{$index} => [ -and => _db_query_get_match_conditions( $index, $value ) ];
266
        } else {
267
            # No such index, we should fail
268
            return undef;
269
        }
270
    }
271
272
    return {
273
        -and => [
274
            import_batch_id => $import_batch_id,
275
            @db_terms
276
        ],
277
    },
278
}
279
186
sub _start_worker {
280
sub _start_worker {
187
    my ( $self, $server, $query ) = @_;
281
    my ( $self, $server, $terms ) = @_;
188
    pipe my $readfh, my $writefh;
282
    pipe my $readfh, my $writefh;
189
283
190
    # Accessing the cache or Koha database after the fork is risky, so get any resources we need
284
    # Accessing the cache or Koha database after the fork is risky, so get any resources we need
Lines 208-213 sub _start_worker { Link Here
208
    my $connection;
302
    my $connection;
209
    my ( $num_hits, $num_fetched, $hits, $results );
303
    my ( $num_hits, $num_fetched, $hits, $results );
210
304
305
    my $pqf_query = _pqf_query_from_terms( $terms );
306
211
    eval {
307
    eval {
212
        if ( $server->{type} eq 'z3950' ) {
308
        if ( $server->{type} eq 'z3950' ) {
213
            my $zoptions = ZOOM::Options->new();
309
            my $zoptions = ZOOM::Options->new();
Lines 221-286 sub _start_worker { Link Here
221
            $connection = ZOOM::Connection->create($zoptions);
317
            $connection = ZOOM::Connection->create($zoptions);
222
318
223
            $connection->connect( $server->{host}, $server->{port} );
319
            $connection->connect( $server->{host}, $server->{port} );
224
            $results = $connection->search_pqf( $query ); # Starts the search
320
            $results = $connection->search_pqf( $pqf_query ); # Starts the search
225
        } elsif ( $server->{type} eq 'koha' ) {
321
        } elsif ( $server->{type} eq 'koha' ) {
226
            $connection = C4::Context->Zconn( $server->{extra} );
322
            $connection = C4::Context->Zconn( $server->{extra} );
227
            $results = $connection->search_pqf( $query ); # Starts the search
323
            $results = $connection->search_pqf( $pqf_query ); # Starts the search
228
        } elsif ( $server->{type} eq 'batch' )  {
324
        } elsif ( $server->{type} eq 'batch' )  {
229
            $server->{encoding} = 'utf-8';
325
            $server->{encoding} = 'utf-8';
230
        }
326
        }
231
    };
327
    };
232
    if ($@) {
328
    if ($@) {
233
        store_fd {
329
        store_fd {
234
            error => $connection ? $connection->exception() : $@,
330
            error => $connection ? $connection->exception()->message() : $@,
235
            server => $server,
331
            server => $server,
236
        }, $writefh;
332
        }, $writefh;
237
        exit;
333
        exit;
238
    }
334
    }
239
335
336
    my $error;
240
    if ( $server->{type} eq 'batch' ) {
337
    if ( $server->{type} eq 'batch' ) {
241
        # TODO: actually handle PQF
242
        $query =~ s/@\w+ (?:\d+=\d+ )?//g;
243
        $query =~ s/"//g;
244
245
        my $schema = Koha::Database->new->schema;
338
        my $schema = Koha::Database->new->schema;
246
        $schema->storage->debug(1);
339
        my $db_query = _batch_db_query_from_terms( $server->{extra}, $terms );
247
        my $match_condition = [ map +{ -like => '%' . $_ . '%' }, split( /\s+/, $query ) ];
340
248
        $hits = [ $schema->resultset('ImportRecord')->search(
341
        if ( $db_query ) {
249
            {
342
            $hits = [ $schema->resultset('ImportRecord')->search(
250
                import_batch_id => $server->{extra},
343
                $db_query,
251
                -or => [
344
                {
252
                    { 'import_biblios.title' => $match_condition },
345
                    columns => [ 'import_record_id', { record => 'marc' } ],
253
                    { 'import_biblios.author' => $match_condition },
346
                    join => [ 'import_biblios' ],
254
                    { 'import_biblios.isbn' => $match_condition },
347
                    offset => $self->{offset},
255
                    { 'import_biblios.issn' => $match_condition },
348
                    result_class => 'DBIx::Class::ResultClass::HashRefInflator',
256
                ],
349
                    rows => $self->{fetch},
257
            },
350
                }
258
            {
351
            )->all ];
259
                join => [ qw( import_biblios ) ],
352
260
                rows => $self->{fetch},
353
            $num_hits = $num_fetched = scalar @$hits;
261
            }
354
        } else {
262
        )->get_column( 'marc' )->all ];
355
            $error = "Invalid search";
263
356
        }
264
        $num_hits = $num_fetched = scalar @$hits;
265
    } else {
357
    } else {
266
        $num_hits = $results->size;
358
        $num_hits = $results->size;
267
        $num_fetched = ( $self->{offset} + $self->{fetch} ) < $num_hits ? $self->{fetch} : $num_hits;
359
        $num_fetched = ( $self->{offset} + $self->{fetch} ) < $num_hits ? $self->{fetch} : $num_hits;
268
360
269
        $hits = [ map { $_->raw() } @{ $results->records( $self->{offset}, $num_fetched, 1 ) } ];
361
        $hits = [ map +{ record => $_->raw() }, @{ $results->records( $self->{offset}, $num_fetched, 1 ) } ];
362
363
        $error = $connection->exception()->message() if ( !@$hits && $connection && $connection->exception() );
270
    }
364
    }
271
365
272
    if ( !@$hits && $connection && $connection->exception() ) {
366
    if ( $error ) {
273
        store_fd {
367
        store_fd {
274
            error => $connection->exception(),
368
            error => $error,
275
            server => $server,
369
            server => $server,
276
        }, $writefh;
370
        }, $writefh;
277
        exit;
371
        exit;
278
    }
372
    }
279
373
280
    if ( $server->{type} eq 'koha' ) {
374
    if ( $server->{type} eq 'koha' ) {
281
        $hits = [ map { C4::Search::new_record_from_zebra( $server->{extra}, $_ ) } @$hits ];
375
        $hits = [ map +{ %$_, record => C4::Search::new_record_from_zebra( $server->{extra}, $_->{record} ) }, @$hits ];
282
    } else {
376
    } else {
283
        $hits = [ map { $self->_import_record( $_, $marcflavour, $server->{encoding} ? $server->{encoding} : "iso-5426" ) } @$hits ];
377
        $hits = [ map +{ %$_, record => $self->_import_record( $_->{record}, $marcflavour, $server->{encoding} ? $server->{encoding} : "iso-5426" ) }, @$hits ];
284
    }
378
    }
285
379
286
    store_fd {
380
    store_fd {
(-)a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/preferences.js (+1 lines)
Lines 30-35 define( function() { Link Here
30
            Preferences.user = $.extend( {
30
            Preferences.user = $.extend( {
31
                // Preference defaults
31
                // Preference defaults
32
                enabledBatches: {},
32
                enabledBatches: {},
33
                enabledSearchBatches: {},
33
                fieldWidgets: true,
34
                fieldWidgets: true,
34
                font: 'monospace',
35
                font: 'monospace',
35
                fontSize: '1em',
36
                fontSize: '1em',
(-)a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/search.js (-21 / +11 lines)
Lines 42-63 define( [ 'koha-backend', 'marc-record' ], function( KohaBackend, MARC ) { Link Here
42
        Init: function( options ) {
42
        Init: function( options ) {
43
            _options = options;
43
            _options = options;
44
        },
44
        },
45
        JoinTerms: function( terms ) {
45
        Run: function( servers, terms, options ) {
46
            var q = '';
47
48
            $.each( terms, function( i, term ) {
49
                var term = '@attr ' + _pqfMapping[ term[0] ] + ' "' + term[1].replace( '"', '\\"' ) + '"'
50
51
                if ( q ) {
52
                    q = '@and ' + q + ' ' + term;
53
                } else {
54
                    q = term;
55
                }
56
            } );
57
58
            return q;
59
        },
60
        Run: function( servers, q, options ) {
61
            options = $.extend( {
46
            options = $.extend( {
62
                offset: 0,
47
                offset: 0,
63
                page_size: 20,
48
                page_size: 20,
Lines 67-76 define( [ 'koha-backend', 'marc-record' ], function( KohaBackend, MARC ) { Link Here
67
            _records = {};
52
            _records = {};
68
            _last = {
53
            _last = {
69
                servers: servers,
54
                servers: servers,
70
                q: q,
55
                terms: terms,
71
                options: options,
56
                options: options,
72
            };
57
            };
73
58
59
            var newTerms = {};
60
            $.each( terms, function( index, value ) {
61
                newTerms[ "term-" + index ] = value;
62
            } );
63
            terms = newTerms;
64
74
            var itemTag = KohaBackend.GetSubfieldForKohaField('items.itemnumber')[0];
65
            var itemTag = KohaBackend.GetSubfieldForKohaField('items.itemnumber')[0];
75
66
76
            $.each( servers, function ( id, info ) {
67
            $.each( servers, function ( id, info ) {
Lines 81-95 define( [ 'koha-backend', 'marc-record' ], function( KohaBackend, MARC ) { Link Here
81
72
82
            $.get(
73
            $.get(
83
                '/cgi-bin/koha/svc/cataloguing/metasearch',
74
                '/cgi-bin/koha/svc/cataloguing/metasearch',
84
                {
75
                $.extend( {
85
                    q: q,
86
                    servers: Search.includedServers.join( ',' ),
76
                    servers: Search.includedServers.join( ',' ),
87
                    offset: options.offset,
77
                    offset: options.offset,
88
                    page_size: options.page_size,
78
                    page_size: options.page_size,
89
                    sort_direction: options.sort_direction,
79
                    sort_direction: options.sort_direction,
90
                    sort_key: options.sort_key,
80
                    sort_key: options.sort_key,
91
                    resultset: options.resultset,
81
                    resultset: options.resultset,
92
                }
82
                }, terms )
93
            )
83
            )
94
                .done( function( data ) {
84
                .done( function( data ) {
95
                    _last.options.resultset = data.resultset;
85
                    _last.options.resultset = data.resultset;
Lines 115-121 define( [ 'koha-backend', 'marc-record' ], function( KohaBackend, MARC ) { Link Here
115
        Fetch: function( options ) {
105
        Fetch: function( options ) {
116
            if ( !_last ) return;
106
            if ( !_last ) return;
117
            $.extend( _last.options, options );
107
            $.extend( _last.options, options );
118
            return Search.Run( _last.servers, _last.q, _last.options );
108
            return Search.Run( _last.servers, _last.terms, _last.options );
119
        }
109
        }
120
    };
110
    };
121
111
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc (-37 / +57 lines)
Lines 44-49 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
44
        'koha:biblioserver': {
44
        'koha:biblioserver': {
45
            name: _("Local catalog"),
45
            name: _("Local catalog"),
46
            recordtype: 'biblio',
46
            recordtype: 'biblio',
47
            enabled: true,
47
            checked: false,
48
            checked: false,
48
        },
49
        },
49
        [%- FOREACH batch = editable_batches -%]
50
        [%- FOREACH batch = editable_batches -%]
Lines 58-63 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
58
                name: '[% server.servername | html %]',
59
                name: '[% server.servername | html %]',
59
                recordtype: '[% server.recordtype | html %]',
60
                recordtype: '[% server.recordtype | html %]',
60
                checked: [% server.checked ? 'true' : 'false' | html %],
61
                checked: [% server.checked ? 'true' : 'false' | html %],
62
                enabled: true,
61
            },
63
            },
62
        [%- END -%]
64
        [%- END -%]
63
    };
65
    };
Lines 174-190 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
174
176
175
        $('#quicksearch .search-box').each( function() {
177
        $('#quicksearch .search-box').each( function() {
176
            shortcut.add( 'enter', $.proxy( function() {
178
            shortcut.add( 'enter', $.proxy( function() {
177
                var terms = [];
179
                var terms = {};
178
180
179
                $('#quicksearch .search-box').each( function() {
181
                $('#quicksearch .search-box').each( function() {
180
                    if ( !this.value ) return;
182
                    if ( !this.value ) return;
181
183
182
                    terms.push( [ $(this).data('qualifier'), this.value ] );
184
                    terms[ $(this).data('qualifier') ] = this.value;
183
                } );
185
                } );
184
186
185
                if ( !terms.length ) return;
187
                if ( $.isEmptyObject(terms) ) return;
186
188
187
                if ( Search.Run( z3950Servers, Search.JoinTerms(terms) ) ) {
189
                if ( Search.Run( z3950Servers, terms ) ) {
188
                    $("#search-overlay").show();
190
                    $("#search-overlay").show();
189
                    showResultsBox();
191
                    showResultsBox();
190
                }
192
                }
Lines 391-396 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
391
        $( '#save-targets input[data-target-id="' + target_id + '"]' ).closest('li').toggle(enabled);
393
        $( '#save-targets input[data-target-id="' + target_id + '"]' ).closest('li').toggle(enabled);
392
    }
394
    }
393
395
396
    function setSearchTargetChecked( server_id, checked ) {
397
        if ( z3950Servers[server_id] == null ) return;
398
399
        z3950Servers[server_id].checked = checked;
400
        $( '.search-target-list li[data-server-id="' + server_id + '"] input' ).prop('checked', checked);
401
    }
402
403
    function setSearchTargetEnabled( server_id, enabled ) {
404
        if ( !enabled ) {
405
            setSearchTargetChecked( server_id, false );
406
        }
407
408
        z3950Servers[server_id].enabled = enabled;
409
        $( '.search-target-list li[data-server-id="' + server_id + '"]' ).toggle(enabled);
410
    }
411
394
    function setSource(parts) {
412
    function setSource(parts) {
395
        state.backend = parts[0];
413
        state.backend = parts[0];
396
        state.recordID = parts[1];
414
        state.recordID = parts[1];
Lines 491-513 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
491
    function showAdvancedSearch() {
509
    function showAdvancedSearch() {
492
        $('#advanced-search-servers').empty();
510
        $('#advanced-search-servers').empty();
493
        $.each( z3950Servers, function( server_id, server ) {
511
        $.each( z3950Servers, function( server_id, server ) {
512
            if ( !server.enabled ) return;
494
            $('#advanced-search-servers').append( '<li data-server-id="' + server_id + '"><label><input class="search-toggle-server" type="checkbox"' + ( server.checked ? ' checked="checked">' : '>' ) + server.name + '</label></li>' );
513
            $('#advanced-search-servers').append( '<li data-server-id="' + server_id + '"><label><input class="search-toggle-server" type="checkbox"' + ( server.checked ? ' checked="checked">' : '>' ) + server.name + '</label></li>' );
495
        } );
514
        } );
496
        $('#advanced-search-ui').modal('show');
515
        $('#advanced-search-ui').modal('show');
497
    }
516
    }
498
517
499
    function startAdvancedSearch() {
518
    function startAdvancedSearch() {
500
        var terms = [];
519
        var terms = {};
501
520
502
        $('#advanced-search-ui .search-box').each( function() {
521
        $('#advanced-search-ui .search-box').each( function() {
503
            if ( !this.value ) return;
522
            if ( !this.value ) return;
504
523
505
            terms.push( [ $(this).data('qualifier'), this.value ] );
524
            terms[ $(this).data('qualifier') ] = this.value;
506
        } );
525
        } );
507
526
508
        if ( !terms.length ) return;
527
        if ( $.isEmptyObject(terms) ) return;
509
528
510
        if ( Search.Run( z3950Servers, Search.JoinTerms(terms) ) ) {
529
        if ( Search.Run( z3950Servers, terms ) ) {
511
            $('#advanced-search-ui').modal('hide');
530
            $('#advanced-search-ui').modal('hide');
512
            $("#search-overlay").show();
531
            $("#search-overlay").show();
513
            showResultsBox();
532
            showResultsBox();
Lines 580-598 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
580
        $.each( data.hits, function( undef, hit ) {
599
        $.each( data.hits, function( undef, hit ) {
581
            backends.search.records[ hit.server + ':' + hit.index ] = hit.record;
600
            backends.search.records[ hit.server + ':' + hit.index ] = hit.record;
582
601
583
            switch ( hit.server ) {
602
            hit.id = 'search/' + hit.server + ':' + hit.index;
584
                case 'koha:biblioserver':
603
            if ( hit.server == 'koha:biblioserver' ) {
585
                    var bibnumField = hit.record.field( bibnumMap[0] );
604
                var bibnumField = hit.record.field( bibnumMap[0] );
586
587
                    if ( bibnumField && bibnumField.hasSubfield( bibnumMap[1] ) ) {
588
                        hit.id = 'catalog/' + bibnumField.subfield( bibnumMap[1] );
589
                        break;
590
                    }
591
592
                    // Otherwise, fallthrough
593
605
594
                default:
606
                if ( bibnumField && bibnumField.hasSubfield( bibnumMap[1] ) ) {
595
                    hit.id = 'search/' + hit.server + ':' + hit.index;
607
                    hit.id = 'catalog/' + bibnumField.subfield( bibnumMap[1] );
608
                }
609
            } else if ( /^batch:/.test(hit.server) && hit.import_record_id ) {
610
                hit.id = hit.server + '/' + hit.import_record_id;
596
            }
611
            }
597
612
598
            var result = '<tr>';
613
            var result = '<tr>';
Lines 713-721 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
713
        switch (pref) {
728
        switch (pref) {
714
            case 'enabledBatches':
729
            case 'enabledBatches':
715
                $.each( editable_batches, function( batch_id, batch ) {
730
                $.each( editable_batches, function( batch_id, batch ) {
716
                    $( '#batches-list li[data-batch-id=' + batch_id + '] input' )[0].checked = Preferences.user.enabledBatches[batch_id];
731
                    $( '#batches-table tr[data-batch-id=' + batch_id + '] input.is-save-target' )[0].checked = Preferences.user.enabledBatches[batch_id];
717
                    setSaveTargetEnabled( 'batch:' + batch_id + '/', Preferences.user.enabledBatches[batch_id] || false );
732
                    setSaveTargetEnabled( 'batch:' + batch_id + '/', Preferences.user.enabledBatches[batch_id] || false );
718
                } );
733
                } );
734
            case 'enabledSearchBatches':
735
                $.each( editable_batches, function( batch_id, batch ) {
736
                    $( '#batches-table tr[data-batch-id=' + batch_id + '] input.is-searchable' )[0].checked = Preferences.user.enabledSearchBatches[batch_id];
737
                    setSearchTargetEnabled( 'batch:' + batch_id, Preferences.user.enabledSearchBatches[batch_id] || false );
738
                } );
719
            case 'fieldWidgets':
739
            case 'fieldWidgets':
720
                $( '#set-field-widgets' ).text( value ? _("Show fields verbatim") : _("Show helpers for fixed and coded fields") );
740
                $( '#set-field-widgets' ).text( value ? _("Show fields verbatim") : _("Show helpers for fixed and coded fields") );
721
                break;
741
                break;
Lines 744-756 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
744
                    if ( saved_val != null ) setSaveTargetChecked( target_id, saved_val );
764
                    if ( saved_val != null ) setSaveTargetChecked( target_id, saved_val );
745
                } );
765
                } );
746
                break;
766
                break;
747
            case 'selected_search_targets':
748
                $.each( z3950Servers, function( server_id, server ) {
749
                    var saved_val = Preferences.user.selected_search_targets[server_id];
750
751
                    if ( saved_val != null ) server.checked = saved_val;
752
                } );
753
                break;
754
        }
767
        }
755
    }
768
    }
756
769
Lines 775-782 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
775
788
776
        switch (pref) {
789
        switch (pref) {
777
            case 'enabledBatches':
790
            case 'enabledBatches':
778
                _addLiveHandler( '#batches-list input', 'change', function() {
791
                _addLiveHandler( '#batches-table input.is-save-target', 'change', function() {
779
                    Preferences.user.enabledBatches[ $( this ).closest('li').data('batch-id') ] = this.checked;
792
                    Preferences.user.enabledBatches[ $( this ).closest('tr').data('batch-id') ] = this.checked;
793
                } );
794
                break;
795
            case 'enabledSearchBatches':
796
                _addLiveHandler( '#batches-table input.is-searchable', 'change', function() {
797
                    Preferences.user.enabledSearchBatches[ $( this ).closest('tr').data('batch-id') ] = this.checked;
780
                } );
798
                } );
781
                break;
799
                break;
782
            case 'fieldWidgets':
800
            case 'fieldWidgets':
Lines 933-946 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
933
        };
951
        };
934
952
935
        // Build batch UI
953
        // Build batch UI
936
        var $batch_entry = $( '<li data-batch-id="' + batch.batch_id + '"><input type="checkbox" />' + batch.name + '</li>' );
954
        var $batch_entry = $( '<tr data-batch-id="' + batch.batch_id + '"><td>' + batch.name + '</td><td><input type="checkbox" class="is-searchable" /></td><td><input type="checkbox" class="is-save-target" /></td></tr>' );
937
955
938
        var $batch_buttons = $('<span class="batch-buttons"></span>').appendTo($batch_entry);
956
        var $batch_buttons = $('<td class="batch-buttons"></td>').appendTo($batch_entry);
939
        var $export_button = $( '<button>' + _("Export...") + '</button>' ).appendTo($batch_buttons).click( function() {
957
        var $export_button = $( '<button>' + _("Export...") + '</button>' ).appendTo($batch_buttons).click( function() {
940
            $('#batches-list .batch-export').hide();
958
            $('#batches-table .batch-export').hide();
941
            $export_screen.show();
959
            $export_screen.show();
942
        } );
960
        } );
943
961
962
        timestamp_pattern = '\\d{4}(0\\d|1[012])([012]\\d|3[01])(([01]\\d|2[0-3])[0-5]\\d[0-5]\\d)?'
963
944
        var $export_screen = $(
964
        var $export_screen = $(
945
            '<form class="batch-export form-horizontal" style="display: none">'
965
            '<form class="batch-export form-horizontal" style="display: none">'
946
            + '<div class="control-group">'
966
            + '<div class="control-group">'
Lines 948-961 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
948
            + '<div class="controls"><input class="batch-control-number-start" type="text"> - <input class="batch-control-number-end" type="text"></div>'
968
            + '<div class="controls"><input class="batch-control-number-start" type="text"> - <input class="batch-control-number-end" type="text"></div>'
949
            + '</div>'
969
            + '</div>'
950
            + '<label class="control-label">' + _("Timestamp range (YYYYMMDD or YYYMMDDHHMMSS):") + '</label>'
970
            + '<label class="control-label">' + _("Timestamp range (YYYYMMDD or YYYMMDDHHMMSS):") + '</label>'
951
            + '<div class="controls"><input class="batch-timestamp-start" type="text"> - <input class="batch-timestamp-end" type="text"></div>'
971
            + '<div class="controls"><input class="batch-timestamp-start" type="text" pattern="' + timestamp_pattern + '"> - <input class="batch-timestamp-end" type="text" pattern="' + timestamp_pattern + '"></div>'
952
            + '</div>'
972
            + '</div>'
953
            + '<div class="control-group">'
973
            + '<div class="control-group">'
954
            + '<div class="controls"><button class="batch-export-start">' + _("Start export") + '</div>'
974
            + '<div class="controls"><button class="batch-export-start">' + _("Start export") + '</div>'
955
            + '</form>'
975
            + '</form>'
956
        ).appendTo($batch_entry);
976
        ).appendTo($batch_buttons);
957
977
958
        $export_screen.find('.batch-export-start').click( function() {
978
        $export_screen.submit( function() {
959
            function getFormVal(name) {
979
            function getFormVal(name) {
960
                return $export_screen.find( '.batch-' + name ).val();
980
                return $export_screen.find( '.batch-' + name ).val();
961
            }
981
            }
Lines 970-976 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
970
            KohaBackend.StartBatchExport( batch.batch_id, options );
990
            KohaBackend.StartBatchExport( batch.batch_id, options );
971
        } );
991
        } );
972
992
973
        $('#batches-list').append( $batch_entry );
993
        $('#batches-table tbody').append( $batch_entry );
974
    }
994
    }
975
995
976
    $(document).ready( function() {
996
    $(document).ready( function() {
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/editor.tt (-9 / +20 lines)
Lines 99-105 Link Here
99
                    <fieldset class="brief">
99
                    <fieldset class="brief">
100
                    <ol>
100
                    <ol>
101
                        <li><label for="search-by-keywords">Keywords:</label></li>
101
                        <li><label for="search-by-keywords">Keywords:</label></li>
102
                        <li><input class="search-box" data-qualifier="term" id="search-by-keywords" placeholder="(Ctrl-Alt-K)" /></li>
102
                        <li><input class="search-box" data-qualifier="keyword" id="search-by-keywords" placeholder="(Ctrl-Alt-K)" /></li>
103
                        <li><label for="search-by-author">Author:</label></li>
103
                        <li><label for="search-by-author">Author:</label></li>
104
                        <li><input class="search-box" data-qualifier="author" id="search-by-author" placeholder="(Ctrl-Alt-A)" /></li>
104
                        <li><input class="search-box" data-qualifier="author" id="search-by-author" placeholder="(Ctrl-Alt-A)" /></li>
105
                        <li><label for="search-by-isbn">ISBN:</label></li>
105
                        <li><label for="search-by-isbn">ISBN:</label></li>
Lines 141-147 Link Here
141
    <div class="col-md-3">
141
    <div class="col-md-3">
142
        <div id="search-facets">
142
        <div id="search-facets">
143
            <ul>
143
            <ul>
144
                <li>Servers:<ul id="advanced-search-servers"></ul></li>
144
                <li>Servers:<ul id="advanced-search-servers" class="search-target-list"></ul></li>
145
            </ul>
145
            </ul>
146
        </div>
146
        </div>
147
    </div>
147
    </div>
Lines 173-179 Link Here
173
            </li>
173
            </li>
174
            <li>
174
            <li>
175
                <label for="advanced-search-by-lc-number">LC call number:</label>
175
                <label for="advanced-search-by-lc-number">LC call number:</label>
176
                <input class="search-box" data-qualifier="cn_lc" id="advanced-search-by-lc-number" />
176
                <input class="search-box" data-qualifier="cn-lc" id="advanced-search-by-lc-number" />
177
            </li>
177
            </li>
178
            <li>
178
            <li>
179
                <label for="advanced-search-by-lccn">LCCN:</label>
179
                <label for="advanced-search-by-lccn">LCCN:</label>
Lines 181-199 Link Here
181
            </li>
181
            </li>
182
            <li>
182
            <li>
183
                <label for="advanced-search-by-control-number">Control number:</label>
183
                <label for="advanced-search-by-control-number">Control number:</label>
184
                <input class="search-box" data-qualifier="local_number" id="advanced-search-by-control-number" />
184
                <input class="search-box" data-qualifier="local-number" id="advanced-search-by-control-number" />
185
            </li>
185
            </li>
186
            <li>
186
            <li>
187
                <label for="advanced-search-by-dewey">Dewey number:</label>
187
                <label for="advanced-search-by-dewey">Dewey number:</label>
188
                <input class="search-box" data-qualifier="cn_dewey" id="advanced-search-by-dewey" />
188
                <input class="search-box" data-qualifier="cn-dewey" id="advanced-search-by-dewey" />
189
            </li>
189
            </li>
190
            <li>
190
            <li>
191
                <label for="advanced-search-by-standard-number">Standard number:</label>
191
                <label for="advanced-search-by-standard-number">Standard number:</label>
192
                <input class="search-box" data-qualifier="standard_identifier" id="advanced-search-by-standard-number" />
192
                <input class="search-box" data-qualifier="standard-identifier" id="advanced-search-by-standard-number" />
193
            </li>
193
            </li>
194
            <li>
194
            <li>
195
                <label for="advanced-search-by-publisher-number">Publisher number:</label>
195
                <label for="advanced-search-by-publisher-number">Publisher number:</label>
196
                <input class="search-box" data-qualifier="music_identifier" id="advanced-search-by-publisher-number" />
196
                <input class="search-box" data-qualifier="music-identifier" id="advanced-search-by-publisher-number" />
197
            </li>
197
            </li>
198
            <li>
198
            <li>
199
                <label for="advanced-search-by-publication-date">Publication date:</label>
199
                <label for="advanced-search-by-publication-date">Publication date:</label>
Lines 222-228 Link Here
222
    <div class="col-md-3">
222
    <div class="col-md-3">
223
        <div id="search-facets">
223
        <div id="search-facets">
224
            <ul>
224
            <ul>
225
                <li>Servers:<ul id="search-serversinfo"></ul></li>
225
                <li>Servers:<ul id="search-serversinfo" class="search-target-list"></ul></li>
226
            </ul>
226
            </ul>
227
        </div>
227
        </div>
228
    </div>
228
    </div>
Lines 313-319 Link Here
313
            <button class="btn btn-small" type="submit" id="create-batch"><i class="icon-plus"></i> <span>Create new batch...</span></button>
313
            <button class="btn btn-small" type="submit" id="create-batch"><i class="icon-plus"></i> <span>Create new batch...</span></button>
314
            <button class="btn btn-small" type="submit" id="manage-batches"><i class="icon-list"></i> <span>Manage import batches...</span></button>
314
            <button class="btn btn-small" type="submit" id="manage-batches"><i class="icon-list"></i> <span>Manage import batches...</span></button>
315
        </div>
315
        </div>
316
        <ul id="batches-list"></ul>
316
        <table id="batches-table">
317
            <thead>
318
                <tr>
319
                    <th>Batch</th>
320
                    <th>Searchable?</th>
321
                    <th>Save target?</th>
322
                    <th>&nbsp;</th>
323
                </tr>
324
            </thead>
325
            <tbody>
326
            </tbody>
327
        </table>
317
    </div>
328
    </div>
318
    <div class="span3">
329
    <div class="span3">
319
    </div>
330
    </div>
(-)a/svc/cataloguing/metasearch (-5 / +13 lines)
Lines 25-31 use Koha::MetaSearcher; Link Here
25
25
26
my ( $query, $response ) = C4::Service->init( catalogue => 1 );
26
my ( $query, $response ) = C4::Service->init( catalogue => 1 );
27
27
28
my ( $query_string, $servers ) = C4::Service->require_params( 'q', 'servers' );
28
my ( $servers ) = C4::Service->require_params( 'servers' );
29
29
30
my $server_errors = {};
30
my $server_errors = {};
31
31
Lines 35-53 my $offset = $query->param( 'offset' ) || 0; Link Here
35
my $page_size = $query->param( 'page_size' ) || 20;
35
my $page_size = $query->param( 'page_size' ) || 20;
36
my $fetched = $query->param( 'fetched' ) || 100;
36
my $fetched = $query->param( 'fetched' ) || 100;
37
37
38
my $terms = {};
39
40
foreach my $term ( $query->param ) {
41
    next unless ( $term =~ /^term-([A-Za-z0-9-]+)/ );
42
43
    $terms->{$1} = $query->param($term);
44
}
45
38
my $searcher = Koha::MetaSearcher->new( {
46
my $searcher = Koha::MetaSearcher->new( {
39
    fetched => $fetched,
47
    fetched => $fetched,
40
    on_error => sub {
48
    on_error => sub {
41
        my ( $server, $exception ) = @_;
49
        my ( $server, $exception ) = @_;
42
50
43
        $server_errors->{ $server->{id} } = $exception->message;
51
        $server_errors->{ $server->{id} } = $exception;
44
    },
52
    },
45
} );
53
} );
46
54
47
$searcher->resultset( $query->param('resultset') ) if ( $query->param('resultset') );
55
$searcher->resultset( $query->param('resultset') ) if ( $query->param('resultset') );
48
56
49
my @server_ids = split( /,/, $servers );
57
my @server_ids = split( /,/, $servers );
50
my $stats = $searcher->search( \@server_ids, $query_string );
58
my $stats = $searcher->search( \@server_ids, $terms );
51
59
52
$searcher->sort( $sort_key, $sort_direction eq 'desc' ? -1 : 1 );
60
$searcher->sort( $sort_key, $sort_direction eq 'desc' ? -1 : 1 );
53
61
Lines 55-64 my @hits; Link Here
55
63
56
foreach my $hit ( $searcher->results( $offset, $page_size ) ) {
64
foreach my $hit ( $searcher->results( $offset, $page_size ) ) {
57
    push @hits, {
65
    push @hits, {
66
        %$hit,
58
        server => $hit->{server}->{id},
67
        server => $hit->{server}->{id},
59
        index => $hit->{index},
68
        index => $hit->{index},
60
        record => $hit->{record}->as_xml_record(),
69
        record => $hit->{record}->as_xml_record(),
61
        metadata => $hit->{metadata}
70
        metadata => $hit->{metadata},
62
    };
71
    };
63
}
72
}
64
73
65
- 

Return to bug 18823