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 79-93 sub handle_hit { Link Here
79
    $metadata->{date} //= $metadata->{date2};
79
    $metadata->{date} //= $metadata->{date2};
80
80
81
    push @{ $self->{results} }, {
81
    push @{ $self->{results} }, {
82
        %$hit,
82
        server => $server,
83
        server => $server,
83
        index => $index,
84
        index => $index,
84
        record => $marcrecord,
85
        metadata => $metadata,
85
        metadata => $metadata,
86
    };
86
    };
87
}
87
}
88
88
89
sub search {
89
sub search {
90
    my ( $self, $server_ids, $query ) = @_;
90
    my ( $self, $server_ids, $terms ) = @_;
91
91
92
    my $resultset_expiry = 300;
92
    my $resultset_expiry = 300;
93
93
Lines 142-148 sub search { Link Here
142
            }
142
            }
143
        }
143
        }
144
144
145
        $select->add( $self->_start_worker( $server, $query ) );
145
        $select->add( $self->_start_worker( $server, $terms ) );
146
    }
146
    }
147
147
148
    # Handle these while the servers are searching
148
    # Handle these while the servers are searching
Lines 182-189 sub search { Link Here
182
    return $stats;
182
    return $stats;
183
}
183
}
184
184
185
our $_pqf_mapping = {
186
    author => '1=1004',
187
    'cn-dewey' => '1=13',
188
    'cn-lc' => '1=16',
189
    date => '1=30',
190
    isbn => '1=7',
191
    issn => '1=8',
192
    keyword => '1=1016',
193
    lccn => '1=9',
194
    'local-number' => '1=12',
195
    'music-identifier' => '1=51',
196
    'standard-identifier' => '1=1007',
197
    subject => '1=21',
198
    title => '1=4',
199
};
200
201
our $_batch_db_mapping = {
202
    author => 'import_biblios.author',
203
    isbn => 'import_biblios.isbn',
204
    issn => 'import_biblios.issn',
205
    'local-number' => 'import_biblios.control_number',
206
    title => 'import_biblios.title',
207
};
208
209
our $_batch_db_text_columns = {
210
    author => 1,
211
    keyword => 1,
212
    title => 1,
213
};
214
215
sub _pqf_query_from_terms {
216
    my ( $terms ) = @_;
217
218
    my $query;
219
220
    while ( my ( $index, $value ) = each %$terms ) {
221
        $value =~ s/"/\\"/;
222
223
        my $term = '@attr ' . $_pqf_mapping->{$index} . ' "' . $value . '"';
224
225
        if ( $query ) {
226
            $query = '@and ' . $query . ' ' . $term;
227
        } else {
228
            $query = $term;
229
        }
230
    }
231
232
    return $query;
233
}
234
235
sub _db_query_get_match_conditions {
236
    my ( $index, $value ) = @_;
237
238
    if ( $value =~ /\*/ ) {
239
        $value =~ s/\*/%/;
240
        return { -like => $value };
241
    } elsif ( $_batch_db_text_columns->{$index} ) {
242
        return map +{ -regexp => '[[:<:]]' . $_ . '[[:>:]]' }, split( /\s+/, $value );
243
    } else {
244
        return $value;
245
    }
246
}
247
248
sub _batch_db_query_from_terms {
249
    my ( $import_batch_id, $terms ) = @_;
250
251
    my @db_terms;
252
253
    while ( my ( $index, $value ) = each %$terms ) {
254
        if ( $index eq 'keyword' ) {
255
            my @term;
256
257
            while ( my ( $index, $db_column ) = each %$_batch_db_mapping ) {
258
                push @term, { $db_column => [ _db_query_get_match_conditions( $index, $value ) ] };
259
            }
260
261
            # These are implicitly joined with OR because the arrayref doesn't start with -and
262
            push @db_terms, \@term;
263
        } elsif ( $_batch_db_mapping->{$index} ) {
264
            push @db_terms, $_batch_db_mapping->{$index} => [ -and => _db_query_get_match_conditions( $index, $value ) ];
265
        } else {
266
            # No such index, we should fail
267
            return undef;
268
        }
269
    }
270
271
    return {
272
        -and => [
273
            import_batch_id => $import_batch_id,
274
            @db_terms
275
        ],
276
    },
277
}
278
185
sub _start_worker {
279
sub _start_worker {
186
    my ( $self, $server, $query ) = @_;
280
    my ( $self, $server, $terms ) = @_;
187
    pipe my $readfh, my $writefh;
281
    pipe my $readfh, my $writefh;
188
282
189
    # Accessing the cache or Koha database after the fork is risky, so get any resources we need
283
    # Accessing the cache or Koha database after the fork is risky, so get any resources we need
Lines 207-212 sub _start_worker { Link Here
207
    my $connection;
301
    my $connection;
208
    my ( $num_hits, $num_fetched, $hits, $results );
302
    my ( $num_hits, $num_fetched, $hits, $results );
209
303
304
    my $pqf_query = _pqf_query_from_terms( $terms );
305
210
    eval {
306
    eval {
211
        if ( $server->{type} eq 'z3950' ) {
307
        if ( $server->{type} eq 'z3950' ) {
212
            my $zoptions = ZOOM::Options->new();
308
            my $zoptions = ZOOM::Options->new();
Lines 220-285 sub _start_worker { Link Here
220
            $connection = ZOOM::Connection->create($zoptions);
316
            $connection = ZOOM::Connection->create($zoptions);
221
317
222
            $connection->connect( $server->{host}, $server->{port} );
318
            $connection->connect( $server->{host}, $server->{port} );
223
            $results = $connection->search_pqf( $query ); # Starts the search
319
            $results = $connection->search_pqf( $pqf_query ); # Starts the search
224
        } elsif ( $server->{type} eq 'koha' ) {
320
        } elsif ( $server->{type} eq 'koha' ) {
225
            $connection = C4::Context->Zconn( $server->{extra} );
321
            $connection = C4::Context->Zconn( $server->{extra} );
226
            $results = $connection->search_pqf( $query ); # Starts the search
322
            $results = $connection->search_pqf( $pqf_query ); # Starts the search
227
        } elsif ( $server->{type} eq 'batch' )  {
323
        } elsif ( $server->{type} eq 'batch' )  {
228
            $server->{encoding} = 'utf-8';
324
            $server->{encoding} = 'utf-8';
229
        }
325
        }
230
    };
326
    };
231
    if ($@) {
327
    if ($@) {
232
        store_fd {
328
        store_fd {
233
            error => $connection ? $connection->exception() : $@,
329
            error => $connection ? $connection->exception()->message() : $@,
234
            server => $server,
330
            server => $server,
235
        }, $writefh;
331
        }, $writefh;
236
        exit;
332
        exit;
237
    }
333
    }
238
334
335
    my $error;
239
    if ( $server->{type} eq 'batch' ) {
336
    if ( $server->{type} eq 'batch' ) {
240
        # TODO: actually handle PQF
241
        $query =~ s/@\w+ (?:\d+=\d+ )?//g;
242
        $query =~ s/"//g;
243
244
        my $schema = Koha::Database->new->schema;
337
        my $schema = Koha::Database->new->schema;
245
        $schema->storage->debug(1);
338
        my $db_query = _batch_db_query_from_terms( $server->{extra}, $terms );
246
        my $match_condition = [ map +{ -like => '%' . $_ . '%' }, split( /\s+/, $query ) ];
339
247
        $hits = [ $schema->resultset('ImportRecord')->search(
340
        if ( $db_query ) {
248
            {
341
            $hits = [ $schema->resultset('ImportRecord')->search(
249
                import_batch_id => $server->{extra},
342
                $db_query,
250
                -or => [
343
                {
251
                    { 'import_biblios.title' => $match_condition },
344
                    columns => [ 'import_record_id', { record => 'marc' } ],
252
                    { 'import_biblios.author' => $match_condition },
345
                    join => [ 'import_biblios' ],
253
                    { 'import_biblios.isbn' => $match_condition },
346
                    offset => $self->{offset},
254
                    { 'import_biblios.issn' => $match_condition },
347
                    result_class => 'DBIx::Class::ResultClass::HashRefInflator',
255
                ],
348
                    rows => $self->{fetch},
256
            },
349
                }
257
            {
350
            )->all ];
258
                join => [ qw( import_biblios ) ],
351
259
                rows => $self->{fetch},
352
            $num_hits = $num_fetched = scalar @$hits;
260
            }
353
        } else {
261
        )->get_column( 'marc' )->all ];
354
            $error = "Invalid search";
262
355
        }
263
        $num_hits = $num_fetched = scalar @$hits;
264
    } else {
356
    } else {
265
        $num_hits = $results->size;
357
        $num_hits = $results->size;
266
        $num_fetched = ( $self->{offset} + $self->{fetch} ) < $num_hits ? $self->{fetch} : $num_hits;
358
        $num_fetched = ( $self->{offset} + $self->{fetch} ) < $num_hits ? $self->{fetch} : $num_hits;
267
359
268
        $hits = [ map { $_->raw() } @{ $results->records( $self->{offset}, $num_fetched, 1 ) } ];
360
        $hits = [ map +{ record => $_->raw() }, @{ $results->records( $self->{offset}, $num_fetched, 1 ) } ];
361
362
        $error = $connection->exception()->message() if ( !@$hits && $connection && $connection->exception() );
269
    }
363
    }
270
364
271
    if ( !@$hits && $connection && $connection->exception() ) {
365
    if ( $error ) {
272
        store_fd {
366
        store_fd {
273
            error => $connection->exception(),
367
            error => $error,
274
            server => $server,
368
            server => $server,
275
        }, $writefh;
369
        }, $writefh;
276
        exit;
370
        exit;
277
    }
371
    }
278
372
279
    if ( $server->{type} eq 'koha' ) {
373
    if ( $server->{type} eq 'koha' ) {
280
        $hits = [ map { C4::Search::new_record_from_zebra( $server->{extra}, $_ ) } @$hits ];
374
        $hits = [ map +{ %$_, record => C4::Search::new_record_from_zebra( $server->{extra}, $_->{record} ) }, @$hits ];
281
    } else {
375
    } else {
282
        $hits = [ map { $self->_import_record( $_, $marcflavour, $server->{encoding} ? $server->{encoding} : "iso-5426" ) } @$hits ];
376
        $hits = [ map +{ %$_, record => $self->_import_record( $_->{record}, $marcflavour, $server->{encoding} ? $server->{encoding} : "iso-5426" ) }, @$hits ];
283
    }
377
    }
284
378
285
    store_fd {
379
    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 172-188 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
172
174
173
        $('#quicksearch .search-box').each( function() {
175
        $('#quicksearch .search-box').each( function() {
174
            shortcut.add( 'enter', $.proxy( function() {
176
            shortcut.add( 'enter', $.proxy( function() {
175
                var terms = [];
177
                var terms = {};
176
178
177
                $('#quicksearch .search-box').each( function() {
179
                $('#quicksearch .search-box').each( function() {
178
                    if ( !this.value ) return;
180
                    if ( !this.value ) return;
179
181
180
                    terms.push( [ $(this).data('qualifier'), this.value ] );
182
                    terms[ $(this).data('qualifier') ] = this.value;
181
                } );
183
                } );
182
184
183
                if ( !terms.length ) return;
185
                if ( $.isEmptyObject(terms) ) return;
184
186
185
                if ( Search.Run( z3950Servers, Search.JoinTerms(terms) ) ) {
187
                if ( Search.Run( z3950Servers, terms ) ) {
186
                    $("#search-overlay").show();
188
                    $("#search-overlay").show();
187
                    showResultsBox();
189
                    showResultsBox();
188
                }
190
                }
Lines 388-393 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
388
        $( '#save-targets input[data-target-id="' + target_id + '"]' ).closest('li').toggle(enabled);
390
        $( '#save-targets input[data-target-id="' + target_id + '"]' ).closest('li').toggle(enabled);
389
    }
391
    }
390
392
393
    function setSearchTargetChecked( server_id, checked ) {
394
        if ( z3950Servers[server_id] == null ) return;
395
396
        z3950Servers[server_id].checked = checked;
397
        $( '.search-target-list li[data-server-id="' + server_id + '"] input' ).prop('checked', checked);
398
    }
399
400
    function setSearchTargetEnabled( server_id, enabled ) {
401
        if ( !enabled ) {
402
            setSearchTargetChecked( server_id, false );
403
        }
404
405
        z3950Servers[server_id].enabled = enabled;
406
        $( '.search-target-list li[data-server-id="' + server_id + '"]' ).toggle(enabled);
407
    }
408
391
    function setSource(parts) {
409
    function setSource(parts) {
392
        state.backend = parts[0];
410
        state.backend = parts[0];
393
        state.recordID = parts[1];
411
        state.recordID = parts[1];
Lines 488-510 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
488
    function showAdvancedSearch() {
506
    function showAdvancedSearch() {
489
        $('#advanced-search-servers').empty();
507
        $('#advanced-search-servers').empty();
490
        $.each( z3950Servers, function( server_id, server ) {
508
        $.each( z3950Servers, function( server_id, server ) {
509
            if ( !server.enabled ) return;
491
            $('#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>' );
510
            $('#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>' );
492
        } );
511
        } );
493
        $('#advanced-search-ui').modal('show');
512
        $('#advanced-search-ui').modal('show');
494
    }
513
    }
495
514
496
    function startAdvancedSearch() {
515
    function startAdvancedSearch() {
497
        var terms = [];
516
        var terms = {};
498
517
499
        $('#advanced-search-ui .search-box').each( function() {
518
        $('#advanced-search-ui .search-box').each( function() {
500
            if ( !this.value ) return;
519
            if ( !this.value ) return;
501
520
502
            terms.push( [ $(this).data('qualifier'), this.value ] );
521
            terms[ $(this).data('qualifier') ] = this.value;
503
        } );
522
        } );
504
523
505
        if ( !terms.length ) return;
524
        if ( $.isEmptyObject(terms) ) return;
506
525
507
        if ( Search.Run( z3950Servers, Search.JoinTerms(terms) ) ) {
526
        if ( Search.Run( z3950Servers, terms ) ) {
508
            $('#advanced-search-ui').modal('hide');
527
            $('#advanced-search-ui').modal('hide');
509
            $("#search-overlay").show();
528
            $("#search-overlay").show();
510
            showResultsBox();
529
            showResultsBox();
Lines 577-595 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
577
        $.each( data.hits, function( undef, hit ) {
596
        $.each( data.hits, function( undef, hit ) {
578
            backends.search.records[ hit.server + ':' + hit.index ] = hit.record;
597
            backends.search.records[ hit.server + ':' + hit.index ] = hit.record;
579
598
580
            switch ( hit.server ) {
599
            hit.id = 'search/' + hit.server + ':' + hit.index;
581
                case 'koha:biblioserver':
600
            if ( hit.server == 'koha:biblioserver' ) {
582
                    var bibnumField = hit.record.field( bibnumMap[0] );
601
                var bibnumField = hit.record.field( bibnumMap[0] );
583
584
                    if ( bibnumField && bibnumField.hasSubfield( bibnumMap[1] ) ) {
585
                        hit.id = 'catalog/' + bibnumField.subfield( bibnumMap[1] );
586
                        break;
587
                    }
588
589
                    // Otherwise, fallthrough
590
602
591
                default:
603
                if ( bibnumField && bibnumField.hasSubfield( bibnumMap[1] ) ) {
592
                    hit.id = 'search/' + hit.server + ':' + hit.index;
604
                    hit.id = 'catalog/' + bibnumField.subfield( bibnumMap[1] );
605
                }
606
            } else if ( /^batch:/.test(hit.server) && hit.import_record_id ) {
607
                hit.id = hit.server + '/' + hit.import_record_id;
593
            }
608
            }
594
609
595
            var result = '<tr>';
610
            var result = '<tr>';
Lines 710-718 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
710
        switch (pref) {
725
        switch (pref) {
711
            case 'enabledBatches':
726
            case 'enabledBatches':
712
                $.each( editable_batches, function( batch_id, batch ) {
727
                $.each( editable_batches, function( batch_id, batch ) {
713
                    $( '#batches-list li[data-batch-id=' + batch_id + '] input' )[0].checked = Preferences.user.enabledBatches[batch_id];
728
                    $( '#batches-table tr[data-batch-id=' + batch_id + '] input.is-save-target' )[0].checked = Preferences.user.enabledBatches[batch_id];
714
                    setSaveTargetEnabled( 'batch:' + batch_id + '/', Preferences.user.enabledBatches[batch_id] || false );
729
                    setSaveTargetEnabled( 'batch:' + batch_id + '/', Preferences.user.enabledBatches[batch_id] || false );
715
                } );
730
                } );
731
            case 'enabledSearchBatches':
732
                $.each( editable_batches, function( batch_id, batch ) {
733
                    $( '#batches-table tr[data-batch-id=' + batch_id + '] input.is-searchable' )[0].checked = Preferences.user.enabledSearchBatches[batch_id];
734
                    setSearchTargetEnabled( 'batch:' + batch_id, Preferences.user.enabledSearchBatches[batch_id] || false );
735
                } );
716
            case 'fieldWidgets':
736
            case 'fieldWidgets':
717
                $( '#set-field-widgets' ).text( value ? _("Show fields verbatim") : _("Show helpers for fixed and coded fields") );
737
                $( '#set-field-widgets' ).text( value ? _("Show fields verbatim") : _("Show helpers for fixed and coded fields") );
718
                break;
738
                break;
Lines 741-753 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
741
                    if ( saved_val != null ) setSaveTargetChecked( target_id, saved_val );
761
                    if ( saved_val != null ) setSaveTargetChecked( target_id, saved_val );
742
                } );
762
                } );
743
                break;
763
                break;
744
            case 'selected_search_targets':
745
                $.each( z3950Servers, function( server_id, server ) {
746
                    var saved_val = Preferences.user.selected_search_targets[server_id];
747
748
                    if ( saved_val != null ) server.checked = saved_val;
749
                } );
750
                break;
751
        }
764
        }
752
    }
765
    }
753
766
Lines 772-779 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
772
785
773
        switch (pref) {
786
        switch (pref) {
774
            case 'enabledBatches':
787
            case 'enabledBatches':
775
                _addLiveHandler( '#batches-list input', 'change', function() {
788
                _addLiveHandler( '#batches-table input.is-save-target', 'change', function() {
776
                    Preferences.user.enabledBatches[ $( this ).closest('li').data('batch-id') ] = this.checked;
789
                    Preferences.user.enabledBatches[ $( this ).closest('tr').data('batch-id') ] = this.checked;
790
                } );
791
                break;
792
            case 'enabledSearchBatches':
793
                _addLiveHandler( '#batches-table input.is-searchable', 'change', function() {
794
                    Preferences.user.enabledSearchBatches[ $( this ).closest('tr').data('batch-id') ] = this.checked;
777
                } );
795
                } );
778
                break;
796
                break;
779
            case 'fieldWidgets':
797
            case 'fieldWidgets':
Lines 930-943 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
930
        };
948
        };
931
949
932
        // Build batch UI
950
        // Build batch UI
933
        var $batch_entry = $( '<li data-batch-id="' + batch.batch_id + '"><input type="checkbox" />' + batch.name + '</li>' );
951
        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>' );
934
952
935
        var $batch_buttons = $('<span class="batch-buttons"></span>').appendTo($batch_entry);
953
        var $batch_buttons = $('<td class="batch-buttons"></td>').appendTo($batch_entry);
936
        var $export_button = $( '<button>' + _("Export...") + '</button>' ).appendTo($batch_buttons).click( function() {
954
        var $export_button = $( '<button>' + _("Export...") + '</button>' ).appendTo($batch_buttons).click( function() {
937
            $('#batches-list .batch-export').hide();
955
            $('#batches-table .batch-export').hide();
938
            $export_screen.show();
956
            $export_screen.show();
939
        } );
957
        } );
940
958
959
        timestamp_pattern = '\\d{4}(0\\d|1[012])([012]\\d|3[01])(([01]\\d|2[0-3])[0-5]\\d[0-5]\\d)?'
960
941
        var $export_screen = $(
961
        var $export_screen = $(
942
            '<form class="batch-export form-horizontal" style="display: none">'
962
            '<form class="batch-export form-horizontal" style="display: none">'
943
            + '<div class="control-group">'
963
            + '<div class="control-group">'
Lines 945-958 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
945
            + '<div class="controls"><input class="batch-control-number-start" type="text"> - <input class="batch-control-number-end" type="text"></div>'
965
            + '<div class="controls"><input class="batch-control-number-start" type="text"> - <input class="batch-control-number-end" type="text"></div>'
946
            + '</div>'
966
            + '</div>'
947
            + '<label class="control-label">' + _("Timestamp range (YYYYMMDD or YYYMMDDHHMMSS):") + '</label>'
967
            + '<label class="control-label">' + _("Timestamp range (YYYYMMDD or YYYMMDDHHMMSS):") + '</label>'
948
            + '<div class="controls"><input class="batch-timestamp-start" type="text"> - <input class="batch-timestamp-end" type="text"></div>'
968
            + '<div class="controls"><input class="batch-timestamp-start" type="text" pattern="' + timestamp_pattern + '"> - <input class="batch-timestamp-end" type="text" pattern="' + timestamp_pattern + '"></div>'
949
            + '</div>'
969
            + '</div>'
950
            + '<div class="control-group">'
970
            + '<div class="control-group">'
951
            + '<div class="controls"><button class="batch-export-start">' + _("Start export") + '</div>'
971
            + '<div class="controls"><button class="batch-export-start">' + _("Start export") + '</div>'
952
            + '</form>'
972
            + '</form>'
953
        ).appendTo($batch_entry);
973
        ).appendTo($batch_buttons);
954
974
955
        $export_screen.find('.batch-export-start').click( function() {
975
        $export_screen.submit( function() {
956
            function getFormVal(name) {
976
            function getFormVal(name) {
957
                return $export_screen.find( '.batch-' + name ).val();
977
                return $export_screen.find( '.batch-' + name ).val();
958
            }
978
            }
Lines 967-973 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
967
            KohaBackend.StartBatchExport( batch.batch_id, options );
987
            KohaBackend.StartBatchExport( batch.batch_id, options );
968
        } );
988
        } );
969
989
970
        $('#batches-list').append( $batch_entry );
990
        $('#batches-table tbody').append( $batch_entry );
971
    }
991
    }
972
992
973
    $(document).ready( function() {
993
    $(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 136-142 Link Here
136
    <div class="col-md-3">
136
    <div class="col-md-3">
137
        <div id="search-facets">
137
        <div id="search-facets">
138
            <ul>
138
            <ul>
139
                <li>Servers:<ul id="advanced-search-servers"></ul></li>
139
                <li>Servers:<ul id="advanced-search-servers" class="search-target-list"></ul></li>
140
            </ul>
140
            </ul>
141
        </div>
141
        </div>
142
    </div>
142
    </div>
Lines 168-174 Link Here
168
            </li>
168
            </li>
169
            <li>
169
            <li>
170
                <label for="advanced-search-by-lc-number">LC call number:</label>
170
                <label for="advanced-search-by-lc-number">LC call number:</label>
171
                <input class="search-box" data-qualifier="cn_lc" id="advanced-search-by-lc-number" />
171
                <input class="search-box" data-qualifier="cn-lc" id="advanced-search-by-lc-number" />
172
            </li>
172
            </li>
173
            <li>
173
            <li>
174
                <label for="advanced-search-by-lccn">LCCN:</label>
174
                <label for="advanced-search-by-lccn">LCCN:</label>
Lines 176-194 Link Here
176
            </li>
176
            </li>
177
            <li>
177
            <li>
178
                <label for="advanced-search-by-control-number">Control number:</label>
178
                <label for="advanced-search-by-control-number">Control number:</label>
179
                <input class="search-box" data-qualifier="local_number" id="advanced-search-by-control-number" />
179
                <input class="search-box" data-qualifier="local-number" id="advanced-search-by-control-number" />
180
            </li>
180
            </li>
181
            <li>
181
            <li>
182
                <label for="advanced-search-by-dewey">Dewey number:</label>
182
                <label for="advanced-search-by-dewey">Dewey number:</label>
183
                <input class="search-box" data-qualifier="cn_dewey" id="advanced-search-by-dewey" />
183
                <input class="search-box" data-qualifier="cn-dewey" id="advanced-search-by-dewey" />
184
            </li>
184
            </li>
185
            <li>
185
            <li>
186
                <label for="advanced-search-by-standard-number">Standard number:</label>
186
                <label for="advanced-search-by-standard-number">Standard number:</label>
187
                <input class="search-box" data-qualifier="standard_identifier" id="advanced-search-by-standard-number" />
187
                <input class="search-box" data-qualifier="standard-identifier" id="advanced-search-by-standard-number" />
188
            </li>
188
            </li>
189
            <li>
189
            <li>
190
                <label for="advanced-search-by-publisher-number">Publisher number:</label>
190
                <label for="advanced-search-by-publisher-number">Publisher number:</label>
191
                <input class="search-box" data-qualifier="music_identifier" id="advanced-search-by-publisher-number" />
191
                <input class="search-box" data-qualifier="music-identifier" id="advanced-search-by-publisher-number" />
192
            </li>
192
            </li>
193
            <li>
193
            <li>
194
                <label for="advanced-search-by-publication-date">Publication date:</label>
194
                <label for="advanced-search-by-publication-date">Publication date:</label>
Lines 217-223 Link Here
217
    <div class="col-md-3">
217
    <div class="col-md-3">
218
        <div id="search-facets">
218
        <div id="search-facets">
219
            <ul>
219
            <ul>
220
                <li>Servers:<ul id="search-serversinfo"></ul></li>
220
                <li>Servers:<ul id="search-serversinfo" class="search-target-list"></ul></li>
221
            </ul>
221
            </ul>
222
        </div>
222
        </div>
223
    </div>
223
    </div>
Lines 308-314 Link Here
308
            <button class="btn btn-small" type="submit" id="create-batch"><i class="icon-plus"></i> <span>Create new batch...</span></button>
308
            <button class="btn btn-small" type="submit" id="create-batch"><i class="icon-plus"></i> <span>Create new batch...</span></button>
309
            <button class="btn btn-small" type="submit" id="manage-batches"><i class="icon-list"></i> <span>Manage import batches...</span></button>
309
            <button class="btn btn-small" type="submit" id="manage-batches"><i class="icon-list"></i> <span>Manage import batches...</span></button>
310
        </div>
310
        </div>
311
        <ul id="batches-list"></ul>
311
        <table id="batches-table">
312
            <thead>
313
                <tr>
314
                    <th>Batch</th>
315
                    <th>Searchable?</th>
316
                    <th>Save target?</th>
317
                    <th>&nbsp;</th>
318
                </tr>
319
            </thead>
320
            <tbody>
321
            </tbody>
322
        </table>
312
    </div>
323
    </div>
313
    <div class="span3">
324
    <div class="span3">
314
    </div>
325
    </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