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 37-42 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
37
        'koha:biblioserver': {
37
        'koha:biblioserver': {
38
            name: _("Local catalog"),
38
            name: _("Local catalog"),
39
            recordtype: 'biblio',
39
            recordtype: 'biblio',
40
            enabled: true,
40
            checked: false,
41
            checked: false,
41
        },
42
        },
42
        [%- FOREACH batch = editable_batches -%]
43
        [%- FOREACH batch = editable_batches -%]
Lines 51-56 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
51
                name: '[% server.servername | html %]',
52
                name: '[% server.servername | html %]',
52
                recordtype: '[% server.recordtype | html %]',
53
                recordtype: '[% server.recordtype | html %]',
53
                checked: [% server.checked ? 'true' : 'false' | html %],
54
                checked: [% server.checked ? 'true' : 'false' | html %],
55
                enabled: true,
54
            },
56
            },
55
        [%- END -%]
57
        [%- END -%]
56
    };
58
    };
Lines 165-181 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
165
167
166
        $('#quicksearch .search-box').each( function() {
168
        $('#quicksearch .search-box').each( function() {
167
            shortcut.add( 'enter', $.proxy( function() {
169
            shortcut.add( 'enter', $.proxy( function() {
168
                var terms = [];
170
                var terms = {};
169
171
170
                $('#quicksearch .search-box').each( function() {
172
                $('#quicksearch .search-box').each( function() {
171
                    if ( !this.value ) return;
173
                    if ( !this.value ) return;
172
174
173
                    terms.push( [ $(this).data('qualifier'), this.value ] );
175
                    terms[ $(this).data('qualifier') ] = this.value;
174
                } );
176
                } );
175
177
176
                if ( !terms.length ) return;
178
                if ( $.isEmptyObject(terms) ) return;
177
179
178
                if ( Search.Run( z3950Servers, Search.JoinTerms(terms) ) ) {
180
                if ( Search.Run( z3950Servers, terms ) ) {
179
                    $("#search-overlay").show();
181
                    $("#search-overlay").show();
180
                    showResultsBox();
182
                    showResultsBox();
181
                }
183
                }
Lines 366-371 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
366
        $( '#save-targets input[data-target-id="' + target_id + '"]' ).closest('li').toggle(enabled);
368
        $( '#save-targets input[data-target-id="' + target_id + '"]' ).closest('li').toggle(enabled);
367
    }
369
    }
368
370
371
    function setSearchTargetChecked( server_id, checked ) {
372
        if ( z3950Servers[server_id] == null ) return;
373
374
        z3950Servers[server_id].checked = checked;
375
        $( '.search-target-list li[data-server-id="' + server_id + '"] input' ).prop('checked', checked);
376
    }
377
378
    function setSearchTargetEnabled( server_id, enabled ) {
379
        if ( !enabled ) {
380
            setSearchTargetChecked( server_id, false );
381
        }
382
383
        z3950Servers[server_id].enabled = enabled;
384
        $( '.search-target-list li[data-server-id="' + server_id + '"]' ).toggle(enabled);
385
    }
386
369
    function setSource(parts) {
387
    function setSource(parts) {
370
        state.backend = parts[0];
388
        state.backend = parts[0];
371
        state.recordID = parts[1];
389
        state.recordID = parts[1];
Lines 466-488 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
466
    function showAdvancedSearch() {
484
    function showAdvancedSearch() {
467
        $('#advanced-search-servers').empty();
485
        $('#advanced-search-servers').empty();
468
        $.each( z3950Servers, function( server_id, server ) {
486
        $.each( z3950Servers, function( server_id, server ) {
487
            if ( !server.enabled ) return;
469
            $('#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>' );
488
            $('#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>' );
470
        } );
489
        } );
471
        $('#advanced-search-ui').modal('show');
490
        $('#advanced-search-ui').modal('show');
472
    }
491
    }
473
492
474
    function startAdvancedSearch() {
493
    function startAdvancedSearch() {
475
        var terms = [];
494
        var terms = {};
476
495
477
        $('#advanced-search-ui .search-box').each( function() {
496
        $('#advanced-search-ui .search-box').each( function() {
478
            if ( !this.value ) return;
497
            if ( !this.value ) return;
479
498
480
            terms.push( [ $(this).data('qualifier'), this.value ] );
499
            terms[ $(this).data('qualifier') ] = this.value;
481
        } );
500
        } );
482
501
483
        if ( !terms.length ) return;
502
        if ( $.isEmptyObject(terms) ) return;
484
503
485
        if ( Search.Run( z3950Servers, Search.JoinTerms(terms) ) ) {
504
        if ( Search.Run( z3950Servers, terms ) ) {
486
            $('#advanced-search-ui').modal('hide');
505
            $('#advanced-search-ui').modal('hide');
487
            $("#search-overlay").show();
506
            $("#search-overlay").show();
488
            showResultsBox();
507
            showResultsBox();
Lines 555-573 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
555
        $.each( data.hits, function( undef, hit ) {
574
        $.each( data.hits, function( undef, hit ) {
556
            backends.search.records[ hit.server + ':' + hit.index ] = hit.record;
575
            backends.search.records[ hit.server + ':' + hit.index ] = hit.record;
557
576
558
            switch ( hit.server ) {
577
            hit.id = 'search/' + hit.server + ':' + hit.index;
559
                case 'koha:biblioserver':
578
            if ( hit.server == 'koha:biblioserver' ) {
560
                    var bibnumField = hit.record.field( bibnumMap[0] );
579
                var bibnumField = hit.record.field( bibnumMap[0] );
561
562
                    if ( bibnumField && bibnumField.hasSubfield( bibnumMap[1] ) ) {
563
                        hit.id = 'catalog/' + bibnumField.subfield( bibnumMap[1] );
564
                        break;
565
                    }
566
567
                    // Otherwise, fallthrough
568
580
569
                default:
581
                if ( bibnumField && bibnumField.hasSubfield( bibnumMap[1] ) ) {
570
                    hit.id = 'search/' + hit.server + ':' + hit.index;
582
                    hit.id = 'catalog/' + bibnumField.subfield( bibnumMap[1] );
583
                }
584
            } else if ( /^batch:/.test(hit.server) && hit.import_record_id ) {
585
                hit.id = hit.server + '/' + hit.import_record_id;
571
            }
586
            }
572
587
573
            var result = '<tr>';
588
            var result = '<tr>';
Lines 688-696 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
688
        switch (pref) {
703
        switch (pref) {
689
            case 'enabledBatches':
704
            case 'enabledBatches':
690
                $.each( editable_batches, function( batch_id, batch ) {
705
                $.each( editable_batches, function( batch_id, batch ) {
691
                    $( '#batches-list li[data-batch-id=' + batch_id + '] input' )[0].checked = Preferences.user.enabledBatches[batch_id];
706
                    $( '#batches-table tr[data-batch-id=' + batch_id + '] input.is-save-target' )[0].checked = Preferences.user.enabledBatches[batch_id];
692
                    setSaveTargetEnabled( 'batch:' + batch_id + '/', Preferences.user.enabledBatches[batch_id] || false );
707
                    setSaveTargetEnabled( 'batch:' + batch_id + '/', Preferences.user.enabledBatches[batch_id] || false );
693
                } );
708
                } );
709
            case 'enabledSearchBatches':
710
                $.each( editable_batches, function( batch_id, batch ) {
711
                    $( '#batches-table tr[data-batch-id=' + batch_id + '] input.is-searchable' )[0].checked = Preferences.user.enabledSearchBatches[batch_id];
712
                    setSearchTargetEnabled( 'batch:' + batch_id, Preferences.user.enabledSearchBatches[batch_id] || false );
713
                } );
694
            case 'fieldWidgets':
714
            case 'fieldWidgets':
695
                $( '#set-field-widgets' ).text( value ? _("Show fields verbatim") : _("Show helpers for fixed and coded fields") );
715
                $( '#set-field-widgets' ).text( value ? _("Show fields verbatim") : _("Show helpers for fixed and coded fields") );
696
                break;
716
                break;
Lines 719-731 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
719
                    if ( saved_val != null ) setSaveTargetChecked( target_id, saved_val );
739
                    if ( saved_val != null ) setSaveTargetChecked( target_id, saved_val );
720
                } );
740
                } );
721
                break;
741
                break;
722
            case 'selected_search_targets':
723
                $.each( z3950Servers, function( server_id, server ) {
724
                    var saved_val = Preferences.user.selected_search_targets[server_id];
725
726
                    if ( saved_val != null ) server.checked = saved_val;
727
                } );
728
                break;
729
        }
742
        }
730
    }
743
    }
731
744
Lines 750-757 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
750
763
751
        switch (pref) {
764
        switch (pref) {
752
            case 'enabledBatches':
765
            case 'enabledBatches':
753
                _addLiveHandler( '#batches-list input', 'change', function() {
766
                _addLiveHandler( '#batches-table input.is-save-target', 'change', function() {
754
                    Preferences.user.enabledBatches[ $( this ).closest('li').data('batch-id') ] = this.checked;
767
                    Preferences.user.enabledBatches[ $( this ).closest('tr').data('batch-id') ] = this.checked;
768
                } );
769
                break;
770
            case 'enabledSearchBatches':
771
                _addLiveHandler( '#batches-table input.is-searchable', 'change', function() {
772
                    Preferences.user.enabledSearchBatches[ $( this ).closest('tr').data('batch-id') ] = this.checked;
755
                } );
773
                } );
756
                break;
774
                break;
757
            case 'fieldWidgets':
775
            case 'fieldWidgets':
Lines 908-921 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
908
        };
926
        };
909
927
910
        // Build batch UI
928
        // Build batch UI
911
        var $batch_entry = $( '<li data-batch-id="' + batch.batch_id + '"><input type="checkbox" />' + batch.name + '</li>' );
929
        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>' );
912
930
913
        var $batch_buttons = $('<span class="batch-buttons"></span>').appendTo($batch_entry);
931
        var $batch_buttons = $('<td class="batch-buttons"></td>').appendTo($batch_entry);
914
        var $export_button = $( '<button>' + _("Export...") + '</button>' ).appendTo($batch_buttons).click( function() {
932
        var $export_button = $( '<button>' + _("Export...") + '</button>' ).appendTo($batch_buttons).click( function() {
915
            $('#batches-list .batch-export').hide();
933
            $('#batches-table .batch-export').hide();
916
            $export_screen.show();
934
            $export_screen.show();
917
        } );
935
        } );
918
936
937
        timestamp_pattern = '\\d{4}(0\\d|1[012])([012]\\d|3[01])(([01]\\d|2[0-3])[0-5]\\d[0-5]\\d)?'
938
919
        var $export_screen = $(
939
        var $export_screen = $(
920
            '<form class="batch-export form-horizontal" style="display: none">'
940
            '<form class="batch-export form-horizontal" style="display: none">'
921
            + '<div class="control-group">'
941
            + '<div class="control-group">'
Lines 923-936 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
923
            + '<div class="controls"><input class="batch-control-number-start" type="text"> - <input class="batch-control-number-end" type="text"></div>'
943
            + '<div class="controls"><input class="batch-control-number-start" type="text"> - <input class="batch-control-number-end" type="text"></div>'
924
            + '</div>'
944
            + '</div>'
925
            + '<label class="control-label">' + _("Timestamp range (YYYYMMDD or YYYMMDDHHMMSS):") + '</label>'
945
            + '<label class="control-label">' + _("Timestamp range (YYYYMMDD or YYYMMDDHHMMSS):") + '</label>'
926
            + '<div class="controls"><input class="batch-timestamp-start" type="text"> - <input class="batch-timestamp-end" type="text"></div>'
946
            + '<div class="controls"><input class="batch-timestamp-start" type="text" pattern="' + timestamp_pattern + '"> - <input class="batch-timestamp-end" type="text" pattern="' + timestamp_pattern + '"></div>'
927
            + '</div>'
947
            + '</div>'
928
            + '<div class="control-group">'
948
            + '<div class="control-group">'
929
            + '<div class="controls"><button class="batch-export-start">' + _("Start export") + '</div>'
949
            + '<div class="controls"><button class="batch-export-start">' + _("Start export") + '</div>'
930
            + '</form>'
950
            + '</form>'
931
        ).appendTo($batch_entry);
951
        ).appendTo($batch_buttons);
932
952
933
        $export_screen.find('.batch-export-start').click( function() {
953
        $export_screen.submit( function() {
934
            function getFormVal(name) {
954
            function getFormVal(name) {
935
                return $export_screen.find( '.batch-' + name ).val();
955
                return $export_screen.find( '.batch-' + name ).val();
936
            }
956
            }
Lines 945-951 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
945
            KohaBackend.StartBatchExport( batch.batch_id, options );
965
            KohaBackend.StartBatchExport( batch.batch_id, options );
946
        } );
966
        } );
947
967
948
        $('#batches-list').append( $batch_entry );
968
        $('#batches-table tbody').append( $batch_entry );
949
    }
969
    }
950
970
951
    $(document).ready( function() {
971
    $(document).ready( function() {
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/editor.tt (-9 / +20 lines)
Lines 97-103 Link Here
97
    <fieldset class="brief">
97
    <fieldset class="brief">
98
    <ol>
98
    <ol>
99
        <li><label for="search-by-keywords">Keywords:</label></li>
99
        <li><label for="search-by-keywords">Keywords:</label></li>
100
        <li><input class="search-box" data-qualifier="term" id="search-by-keywords" placeholder="(Ctrl-Alt-K)" /></li>
100
        <li><input class="search-box" data-qualifier="keyword" id="search-by-keywords" placeholder="(Ctrl-Alt-K)" /></li>
101
        <li><label for="search-by-author">Author:</label></li>
101
        <li><label for="search-by-author">Author:</label></li>
102
        <li><input class="search-box" data-qualifier="author" id="search-by-author" placeholder="(Ctrl-Alt-A)" /></li>
102
        <li><input class="search-box" data-qualifier="author" id="search-by-author" placeholder="(Ctrl-Alt-A)" /></li>
103
        <li><label for="search-by-isbn">ISBN:</label></li>
103
        <li><label for="search-by-isbn">ISBN:</label></li>
Lines 134-140 Link Here
134
    <div class="col-md-3">
134
    <div class="col-md-3">
135
        <div id="search-facets">
135
        <div id="search-facets">
136
            <ul>
136
            <ul>
137
                <li>Servers:<ul id="advanced-search-servers"></ul></li>
137
                <li>Servers:<ul id="advanced-search-servers" class="search-target-list"></ul></li>
138
            </ul>
138
            </ul>
139
        </div>
139
        </div>
140
    </div>
140
    </div>
Lines 166-172 Link Here
166
            </li>
166
            </li>
167
            <li>
167
            <li>
168
                <label for="advanced-search-by-lc-number">LC call number:</label>
168
                <label for="advanced-search-by-lc-number">LC call number:</label>
169
                <input class="search-box" data-qualifier="cn_lc" id="advanced-search-by-lc-number" />
169
                <input class="search-box" data-qualifier="cn-lc" id="advanced-search-by-lc-number" />
170
            </li>
170
            </li>
171
            <li>
171
            <li>
172
                <label for="advanced-search-by-lccn">LCCN:</label>
172
                <label for="advanced-search-by-lccn">LCCN:</label>
Lines 174-192 Link Here
174
            </li>
174
            </li>
175
            <li>
175
            <li>
176
                <label for="advanced-search-by-control-number">Control number:</label>
176
                <label for="advanced-search-by-control-number">Control number:</label>
177
                <input class="search-box" data-qualifier="local_number" id="advanced-search-by-control-number" />
177
                <input class="search-box" data-qualifier="local-number" id="advanced-search-by-control-number" />
178
            </li>
178
            </li>
179
            <li>
179
            <li>
180
                <label for="advanced-search-by-dewey">Dewey number:</label>
180
                <label for="advanced-search-by-dewey">Dewey number:</label>
181
                <input class="search-box" data-qualifier="cn_dewey" id="advanced-search-by-dewey" />
181
                <input class="search-box" data-qualifier="cn-dewey" id="advanced-search-by-dewey" />
182
            </li>
182
            </li>
183
            <li>
183
            <li>
184
                <label for="advanced-search-by-standard-number">Standard number:</label>
184
                <label for="advanced-search-by-standard-number">Standard number:</label>
185
                <input class="search-box" data-qualifier="standard_identifier" id="advanced-search-by-standard-number" />
185
                <input class="search-box" data-qualifier="standard-identifier" id="advanced-search-by-standard-number" />
186
            </li>
186
            </li>
187
            <li>
187
            <li>
188
                <label for="advanced-search-by-publisher-number">Publisher number:</label>
188
                <label for="advanced-search-by-publisher-number">Publisher number:</label>
189
                <input class="search-box" data-qualifier="music_identifier" id="advanced-search-by-publisher-number" />
189
                <input class="search-box" data-qualifier="music-identifier" id="advanced-search-by-publisher-number" />
190
            </li>
190
            </li>
191
            <li>
191
            <li>
192
                <label for="advanced-search-by-publication-date">Publication date:</label>
192
                <label for="advanced-search-by-publication-date">Publication date:</label>
Lines 215-221 Link Here
215
    <div class="col-md-3">
215
    <div class="col-md-3">
216
        <div id="search-facets">
216
        <div id="search-facets">
217
            <ul>
217
            <ul>
218
                <li>Servers:<ul id="search-serversinfo"></ul></li>
218
                <li>Servers:<ul id="search-serversinfo" class="search-target-list"></ul></li>
219
            </ul>
219
            </ul>
220
        </div>
220
        </div>
221
    </div>
221
    </div>
Lines 287-293 Link Here
287
            <button class="btn btn-small" type="submit" id="create-batch"><i class="icon-plus"></i> <span>Create new batch...</span></button>
287
            <button class="btn btn-small" type="submit" id="create-batch"><i class="icon-plus"></i> <span>Create new batch...</span></button>
288
            <button class="btn btn-small" type="submit" id="manage-batches"><i class="icon-list"></i> <span>Manage import batches...</span></button>
288
            <button class="btn btn-small" type="submit" id="manage-batches"><i class="icon-list"></i> <span>Manage import batches...</span></button>
289
        </div>
289
        </div>
290
        <ul id="batches-list"></ul>
290
        <table id="batches-table">
291
            <thead>
292
                <tr>
293
                    <th>Batch</th>
294
                    <th>Searchable?</th>
295
                    <th>Save target?</th>
296
                    <th>&nbsp;</th>
297
                </tr>
298
            </thead>
299
            <tbody>
300
            </tbody>
301
        </table>
291
    </div>
302
    </div>
292
    <div class="span3">
303
    <div class="span3">
293
    </div>
304
    </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