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

(-)a/Koha/REST/V1/Biblios/Geo.pm (+60 lines)
Line 0 Link Here
1
package Koha::REST::V1::Biblios::Geo;
2
3
use utf8;
4
use Mojo::Base 'Mojolicious::Controller';
5
6
use C4::Context;
7
use C4::Biblio;
8
use C4::XSLT;
9
10
use Koha::Biblios;
11
use Mojo::JSON qw(decode_json encode_json);
12
use Encode qw(encode_utf8);
13
14
sub post {
15
    my $c = shift->openapi->valid_input or return;
16
    my $biblionumbers = $c->validation->every_param('biblionumber');
17
18
##     my $dbh = C4::Context->dbh;
19
## 
20
##     my $sql= <<'SQL';
21
## with search as (
22
## select authid, 
23
##        ExtractValue(marcxml, '//datafield[@tag="035"]/subfield[@code="a"]')  as idn,
24
##        ExtractValue(marcxml, '//datafield[@tag="150"]/subfield[@code="a"]') as fieldvalue,
25
##        gnd_id nid
26
##   from auth_header where authtypecode = 'GENRE/FORM' and origincode = 'rda')
27
## select * from search where biblionumber in  ?
28
## order by fieldvalue
29
## SQL
30
## 
31
##     my $query = $dbh->prepare($sql);
32
##     $query->execute($searchterm);
33
##     my $items = $query->fetchall_arrayref({});
34
35
    return $c->render( status => 200, openapi => {data => $biblionumbers, info => 'test'}  );
36
}
37
38
39
sub biblio_coordinates {
40
    my $c = shift->openapi->valid_input or return;
41
    my $biblionumbers = $c->validation->every_param('bn');
42
    my $data = [];
43
    my $i = 0;
44
    for my $b (@$biblionumbers) {
45
        my $d = {};
46
        my $marcxml =  C4::Biblio::GetXmlBiblio( $b );
47
        my $record  = MARC::Record->new_from_xml( $marcxml, 'UTF-8', 'MARC21' );
48
        if ( $record->field('034') ) { 
49
          $d->{coordinates} = [$record->field('034')->subfield("s"), $record->field('034')->subfield("t")];
50
          $d->{title}       = sprintf("<a href='/cgi-bin/koha/opac-detail.pl?biblionumber=%d'>%s</a>",
51
                            $b, $record->field('245')->subfield("a"));
52
          push @$data, $d;
53
          $i++;
54
        } 
55
    }
56
    return $c->render( status => 200, openapi => {data => $data,  count => $i}  );
57
}
58
59
1;
60
(-)a/Koha/Schema/Result/SearchField.pm (-3 / +4 lines)
Lines 48-54 the human readable name of the field, for display Link Here
48
=head2 type
48
=head2 type
49
49
50
  data_type: 'enum'
50
  data_type: 'enum'
51
  extra: {list => ["","string","date","number","boolean","sum","isbn","stdno","year","callnumber"]}
51
  extra: {list => ["","string","date","number","boolean","sum","isbn","stdno","year","callnumber","geo_point"]}
52
  is_nullable: 0
52
  is_nullable: 0
53
53
54
what type of data this holds, relevant when storing it in the search engine
54
what type of data this holds, relevant when storing it in the search engine
Lines 109-114 __PACKAGE__->add_columns( Link Here
109
        "stdno",
109
        "stdno",
110
        "year",
110
        "year",
111
        "callnumber",
111
        "callnumber",
112
        "geo_point",
112
      ],
113
      ],
113
    },
114
    },
114
    is_nullable => 0,
115
    is_nullable => 0,
Lines 169-176 __PACKAGE__->has_many( Link Here
169
);
170
);
170
171
171
172
172
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2022-07-18 15:10:43
173
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2022-09-29 12:18:11
173
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Uk5JsfPJo0XVvGfMfJg3cg
174
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:xtsGkd3Gjnqw8ZDmoeRDzQ
174
175
175
__PACKAGE__->add_columns(
176
__PACKAGE__->add_columns(
176
    '+mandatory' => { is_boolean => 1 },
177
    '+mandatory' => { is_boolean => 1 },
(-)a/Koha/SearchEngine/Elasticsearch.pm (+22 lines)
Lines 212-217 sub get_elasticsearch_mappings { Link Here
212
                    $es_type = 'year';
212
                    $es_type = 'year';
213
                } elsif ($type eq 'callnumber') {
213
                } elsif ($type eq 'callnumber') {
214
                    $es_type = 'cn_sort';
214
                    $es_type = 'cn_sort';
215
                } elsif ($type eq 'geo_point') {
216
                    $es_type = 'geo_point';
217
                }
218
219
                if ($type eq 'geo_point') {
220
                    $name =~ s/_(lat|lon)$//;
215
                }
221
                }
216
222
217
                if ($search) {
223
                if ($search) {
Lines 733-738 sub marc_records_to_documents { Link Here
733
            }
739
            }
734
        }
740
        }
735
741
742
        foreach my $field (@{$rules->{geo_point}}) {
743
            next unless $record_document->{$field};
744
            my $geofield = $field;
745
            $geofield =~ s/_(lat|lon)$//;
746
            my $axis = $1;
747
            my $vals = $record_document->{$field};
748
            for my $i (0 .. @$vals - 1) {
749
                my $val = $record_document->{$field}[$i];
750
                $record_document->{$geofield}[$i]{$axis} = $val;
751
            }
752
            delete $record_document->{$field};
753
        }
754
736
        # Remove duplicate values and collapse sort fields
755
        # Remove duplicate values and collapse sort fields
737
        foreach my $field (keys %{$record_document}) {
756
        foreach my $field (keys %{$record_document}) {
738
            if (ref($record_document->{$field}) eq 'ARRAY') {
757
            if (ref($record_document->{$field}) eq 'ARRAY') {
Lines 1056-1061 sub _get_marc_mapping_rules { Link Here
1056
        elsif ($type eq 'isbn') {
1075
        elsif ($type eq 'isbn') {
1057
            push @{$rules->{isbn}}, $name;
1076
            push @{$rules->{isbn}}, $name;
1058
        }
1077
        }
1078
        elsif ($type eq 'geo_point') {
1079
            push @{$rules->{geo_point}}, $name;
1080
        }
1059
        elsif ($type eq 'boolean') {
1081
        elsif ($type eq 'boolean') {
1060
            # boolean gets special handling, if value doesn't exist for a field,
1082
            # boolean gets special handling, if value doesn't exist for a field,
1061
            # it is set to false
1083
            # it is set to false
(-)a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm (-1 / +45 lines)
Lines 137-142 our %index_field_convert = ( Link Here
137
);
137
);
138
my $field_name_pattern = '[\w\-]+';
138
my $field_name_pattern = '[\w\-]+';
139
my $multi_field_pattern = "(?:\\.$field_name_pattern)*";
139
my $multi_field_pattern = "(?:\\.$field_name_pattern)*";
140
my $es_advanced_searches = [];
140
141
141
=head2 get_index_field_convert
142
=head2 get_index_field_convert
142
143
Lines 245-250 sub build_query { Link Here
245
        or $display_library_facets eq 'holding' ) {
246
        or $display_library_facets eq 'holding' ) {
246
        $res->{aggregations}{holdingbranch} = { terms => { field => "holdingbranch__facet", size => $size } };
247
        $res->{aggregations}{holdingbranch} = { terms => { field => "holdingbranch__facet", size => $size } };
247
    }
248
    }
249
250
    $res = _rebuild_to_es_advanced_query($res) if @$es_advanced_searches ;
248
    return $res;
251
    return $res;
249
}
252
}
250
253
Lines 929-934 operand. Link Here
929
932
930
sub _create_query_string {
933
sub _create_query_string {
931
    my ( $self, @queries ) = @_;
934
    my ( $self, @queries ) = @_;
935
    foreach my $q (@queries) {
936
        if ($q->{field} && $q->{field} eq 'geolocation') {
937
            push(@$es_advanced_searches, $q);
938
        }
939
    }
940
    @queries = grep { $_->{field} ne 'geolocation' } @queries;
932
941
933
    map {
942
    map {
934
        my $otor  = $_->{operator} ? $_->{operator} . ' ' : '';
943
        my $otor  = $_->{operator} ? $_->{operator} . ' ' : '';
Lines 1082-1088 sub _fix_limit_special_cases { Link Here
1082
1091
1083
    my @new_lim;
1092
    my @new_lim;
1084
    foreach my $l (@$limits) {
1093
    foreach my $l (@$limits) {
1085
1086
        # This is set up by opac-search.pl
1094
        # This is set up by opac-search.pl
1087
        if ( $l =~ /^yr,st-numeric,ge[=:]/ ) {
1095
        if ( $l =~ /^yr,st-numeric,ge[=:]/ ) {
1088
            my ( $start, $end ) =
1096
            my ( $start, $end ) =
Lines 1335-1338 sub _search_fields { Link Here
1335
    }
1343
    }
1336
}
1344
}
1337
1345
1346
sub _rebuild_to_es_advanced_query {
1347
    my ($res) = @_;
1348
    my $query_string = $res->{query}->{query_string};
1349
    $query_string->{query} = '*' unless $query_string->{query};
1350
    delete $res->{query}->{query_string};
1351
1352
    my %filter;
1353
    for my $advanced_query (@$es_advanced_searches) {
1354
        if ( $advanced_query->{field} eq 'geolocation') {
1355
            my ($lat, $lon, $distance) = map { $_ =~ /:(.*)\*/ } split('\s+', $advanced_query->{operand});
1356
            $filter{geo_distance} = {
1357
                distance => $distance,
1358
                geolocation => {
1359
                    lat => $lat,
1360
                    lon => $lon,
1361
                }
1362
            };
1363
        }
1364
        else {
1365
            warn "unknown advanced ElasticSearch query: ".join(', ',%$advanced_query);
1366
        }
1367
    }
1368
1369
    $res->{query} = {
1370
        bool => {
1371
             must => {
1372
                 query_string =>  $query_string
1373
             },
1374
             filter => \%filter,
1375
        }
1376
    };
1377
1378
    return $res;
1379
}
1380
1381
1338
1;
1382
1;
(-)a/Koha/SearchEngine/Elasticsearch/Search.pm (+5 lines)
Lines 91-96 sub search { Link Here
91
        $query->{from} = $page * $query->{size};
91
        $query->{from} = $page * $query->{size};
92
    }
92
    }
93
    my $elasticsearch = $self->get_elasticsearch();
93
    my $elasticsearch = $self->get_elasticsearch();
94
95
    # FixMe: investigate where empty query_string is coming from
96
    delete $query->{query}->{query_string} if
97
      $query->{query}->{query_string} && !%{$query->{query}->{query_string}};
98
94
    my $results = eval {
99
    my $results = eval {
95
        $elasticsearch->search(
100
        $elasticsearch->search(
96
            index => $self->index_name,
101
            index => $self->index_name,
(-)a/admin/searchengine/elasticsearch/field_config.yaml (+2 lines)
Lines 41-46 search: Link Here
41
      ci_raw:
41
      ci_raw:
42
        type: keyword
42
        type: keyword
43
        normalizer: icu_folding_normalizer
43
        normalizer: icu_folding_normalizer
44
  geo_point:
45
     type: geo_point
44
  default:
46
  default:
45
    type: text
47
    type: text
46
    analyzer: analyzer_standard
48
    analyzer: analyzer_standard
(-)a/admin/searchengine/elasticsearch/mappings.yaml (+18 lines)
Lines 1855-1860 biblios: Link Here
1855
    opac: 1
1855
    opac: 1
1856
    staff_client: 1
1856
    staff_client: 1
1857
    type: ''
1857
    type: ''
1858
  geolocation_lat:
1859
    label: geolocation_lat
1860
    mappings:
1861
      - facet: ''
1862
        marc_field: 034s
1863
        marc_type: marc21
1864
        sort: 0
1865
        suggestible: ''
1866
    type: geo_point
1867
  geolocation_lon:
1868
    label: geolocation_lon
1869
    mappings:
1870
      - facet: ''
1871
        marc_field: 034t
1872
        marc_type: marc21
1873
        sort: 0
1874
        suggestible: ''
1875
    type: geo_point
1858
  holdingbranch:
1876
  holdingbranch:
1859
    facet_order: 8
1877
    facet_order: 8
1860
    label: holdinglibrary
1878
    label: holdinglibrary
(-)a/api/v1/swagger/paths/biblios_geosearch.yaml (+49 lines)
Line 0 Link Here
1
---
2
/biblios/geo:
3
  get:
4
    x-mojo-to: Biblios::Geo#biblio_coordinates
5
    operationId: getBiblioGeoCoordinates
6
    tags:
7
      - biblios
8
    summary: Get biblio Geo (public)
9
    parameters:
10
      - name: bn
11
        in: query
12
        required: true
13
        description: Embed list sent in path
14
        type: array
15
    produces:
16
      - application/json
17
    responses:
18
      "200":
19
        description: A biblio
20
      "401":
21
        description: Authentication required
22
        schema:
23
          $ref: "../swagger.yaml#/definitions/error"
24
      "403":
25
        description: Access forbidden
26
        schema:
27
          $ref: "../swagger.yaml#/definitions/error"
28
      "404":
29
        description: Biblio not found
30
        schema:
31
          $ref: "../swagger.yaml#/definitions/error"
32
      "406":
33
        description: Not acceptable
34
        schema:
35
          type: array
36
          description: Accepted content-types
37
          items:
38
            type: string
39
      "500":
40
        description: |
41
          Internal server error. Possible `error_code` attribute values:
42
43
          * `internal_server_error`
44
        schema:
45
          $ref: "../swagger.yaml#/definitions/error"
46
      "503":
47
        description: Under maintenance
48
        schema:
49
          $ref: "../swagger.yaml#/definitions/error"
(-)a/api/v1/swagger/swagger.yaml (+2 lines)
Lines 191-196 paths: Link Here
191
    $ref: "./paths/biblios_item_groups.yaml#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items"
191
    $ref: "./paths/biblios_item_groups.yaml#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items"
192
  "/biblios/{biblio_id}/item_groups/{item_group_id}/items/{item_id}":
192
  "/biblios/{biblio_id}/item_groups/{item_group_id}/items/{item_id}":
193
    $ref: "./paths/biblios_item_groups.yaml#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items~1{item_id}"
193
    $ref: "./paths/biblios_item_groups.yaml#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items~1{item_id}"
194
  /public/biblios/geo:
195
    $ref: ./paths/biblios_geosearch.yaml#/~1biblios~1geo 
194
  "/cash_registers/{cash_register_id}/cashups":
196
  "/cash_registers/{cash_register_id}/cashups":
195
    $ref: "./paths/cash_registers.yaml#/~1cash_registers~1{cash_register_id}~1cashups"
197
    $ref: "./paths/cash_registers.yaml#/~1cash_registers~1{cash_register_id}~1cashups"
196
  "/cashups/{cashup_id}":
198
  "/cashups/{cashup_id}":
(-)a/installer/data/mysql/atomicupdate/bug_31652_add_geo_search.pl (+17 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number => "31652",
5
    description => "Add geo-search: new value for search_field.type enum",
6
    up => sub {
7
        my ($args) = @_;
8
        my ($dbh, $out) = @$args{qw(dbh out)};
9
        # Do you stuffs here
10
        $dbh->do(q{ alter table search_field MODIFY COLUMN type enum('','string','date','number','boolean','sum','isbn','stdno','year','callnumber','geo_point') });
11
        # Print useful stuff here
12
        say $out "Added new value 'geo_point' to search_field.type enum";
13
        $dbh->do(q{INSERT IGNORE INTO systempreferences ( 'variable', 'value', 'options', 'explanation', 'type' ) VALUES ('GeoSearchEnabled', '0', NULL, 'Enable GeoSearch Feature via Elasticsearch', 'YesNo')
14
        say $out "Added new system preference 'GeoSearchEnabled'";
15
12      });
16
    },
17
};
(-)a/installer/data/mysql/kohastructure.sql (-3 / +3 lines)
Lines 5161-5169 DROP TABLE IF EXISTS `search_field`; Link Here
5161
/*!40101 SET character_set_client = utf8 */;
5161
/*!40101 SET character_set_client = utf8 */;
5162
CREATE TABLE `search_field` (
5162
CREATE TABLE `search_field` (
5163
  `id` int(11) NOT NULL AUTO_INCREMENT,
5163
  `id` int(11) NOT NULL AUTO_INCREMENT,
5164
  `name` varchar(255) NOT NULL COMMENT 'the name of the field as it will be stored in the search engine',
5164
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'the name of the field as it will be stored in the search engine',
5165
  `label` varchar(255) NOT NULL COMMENT 'the human readable name of the field, for display',
5165
  `label` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'the human readable name of the field, for display',
5166
  `type` enum('','string','date','number','boolean','sum','isbn','stdno','year','callnumber') NOT NULL COMMENT 'what type of data this holds, relevant when storing it in the search engine',
5166
  `type` enum('','string','date','number','boolean','sum','isbn','stdno','year','callnumber','geo_point') COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'what type of data this holds, relevant when storing it in the search engine',
5167
  `weight` decimal(5,2) DEFAULT NULL,
5167
  `weight` decimal(5,2) DEFAULT NULL,
5168
  `facet_order` tinyint(4) DEFAULT NULL COMMENT 'the order place of the field in facet list if faceted',
5168
  `facet_order` tinyint(4) DEFAULT NULL COMMENT 'the order place of the field in facet list if faceted',
5169
  `staff_client` tinyint(1) NOT NULL DEFAULT 1,
5169
  `staff_client` tinyint(1) NOT NULL DEFAULT 1,
(-)a/installer/data/mysql/mandatory/sysprefs.sql (+1 lines)
Lines 258-263 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
258
('FRBRizeEditions','0','','If ON, Koha will query one or more ISBN web services for associated ISBNs and display an Editions tab on the details pages','YesNo'),
258
('FRBRizeEditions','0','','If ON, Koha will query one or more ISBN web services for associated ISBNs and display an Editions tab on the details pages','YesNo'),
259
('GenerateAuthorityField667', 'Machine generated authority record', NULL, 'When BiblioAddsAuthorities and AutoCreateAuthorities are enabled, use this as a default value for the 667$a field of MARC21 records', 'free'),
259
('GenerateAuthorityField667', 'Machine generated authority record', NULL, 'When BiblioAddsAuthorities and AutoCreateAuthorities are enabled, use this as a default value for the 667$a field of MARC21 records', 'free'),
260
('GenerateAuthorityField670', 'Work cat.', NULL, 'When BiblioAddsAuthorities and AutoCreateAuthorities are enabled, use this as a default value for the 670$a field of MARC21 records', 'free'),
260
('GenerateAuthorityField670', 'Work cat.', NULL, 'When BiblioAddsAuthorities and AutoCreateAuthorities are enabled, use this as a default value for the 670$a field of MARC21 records', 'free'),
261
('GeoSearchEnabled', '0', NULL, 'Enable GeoSearch Feature via Elasticsearch', 'YesNo'),
261
('GoogleJackets','0',NULL,'if ON, displays jacket covers from Google Books API','YesNo'),
262
('GoogleJackets','0',NULL,'if ON, displays jacket covers from Google Books API','YesNo'),
262
('GoogleOpenIDConnect', '0', NULL, 'if ON, allows the use of Google OpenID Connect for login', 'YesNo'),
263
('GoogleOpenIDConnect', '0', NULL, 'if ON, allows the use of Google OpenID Connect for login', 'YesNo'),
263
('GoogleOAuth2ClientID', '', NULL, 'Client ID for the web app registered with Google', 'Free'),
264
('GoogleOAuth2ClientID', '', NULL, 'Client ID for the web app registered with Google', 'Free'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/searching.pref (+7 lines)
Lines 94-99 Searching: Link Here
94
                  1: Enable
94
                  1: Enable
95
                  0: Disable
95
                  0: Disable
96
            - "the option for staff with permission to create/edit custom saved search filters."
96
            - "the option for staff with permission to create/edit custom saved search filters."
97
        -
98
            - pref: GeoSearchEnabled
99
              type: boolean
100
              choices:
101
                  1: Enable
102
                  0: Disable
103
            - 'GeoSearch via Elasticsearch'
97
    Search form:
104
    Search form:
98
        -
105
        -
99
            - pref : LoadSearchHistoryToTheFirstLoggedUser
106
            - pref : LoadSearchHistoryToTheFirstLoggedUser
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt (+5 lines)
Lines 217-222 a.add, a.delete { Link Here
217
                                            [% ELSE %]
217
                                            [% ELSE %]
218
                                                <option value="callnumber">Call Number</option>
218
                                                <option value="callnumber">Call Number</option>
219
                                            [% END %]
219
                                            [% END %]
220
                                            [% IF search_field.type == "geo_point" %]
221
                                              <option value="geo_point" selected="selected">Geo Point</option>
222
                                            [% ELSE %]
223
                                              <option value="geo_point">Geo Point</option>
224
                                            [% END %]
220
                                        </select>
225
                                        </select>
221
                                    </td>
226
                                    </td>
222
                                        <td data-order="[% search_field.weight | html %]">
227
                                        <td data-order="[% search_field.weight | html %]">
(-)a/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss (+4 lines)
Lines 2724-2729 $star-selected: #EDB867; Link Here
2724
    }
2724
    }
2725
}
2725
}
2726
2726
2727
#geo_search_map {
2728
  height: 400px;
2729
}
2730
2727
@media print {
2731
@media print {
2728
    .br-theme-fontawesome-stars {
2732
    .br-theme-fontawesome-stars {
2729
        .br-widget {
2733
        .br-widget {
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt (+8 lines)
Lines 5-10 Link Here
5
[% USE To %]
5
[% USE To %]
6
[% SET TagsShowEnabled = ( ( Koha.Preference( 'TagsEnabled' ) == 1 ) && TagsShowOnList ) %]
6
[% SET TagsShowEnabled = ( ( Koha.Preference( 'TagsEnabled' ) == 1 ) && TagsShowOnList ) %]
7
[% SET TagsInputEnabled = ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) && ( Koha.Preference( 'TagsEnabled' ) == 1 ) && TagsInputOnList ) %]
7
[% SET TagsInputEnabled = ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) && ( Koha.Preference( 'TagsEnabled' ) == 1 ) && TagsInputOnList ) %]
8
[% SET GeoSearchEnabled = ( Koha.Preference( 'GeoSearchEnabled' ) == 1 ) %]
8
[% SET CoverImagePlugins = KohaPlugins.get_plugins_opac_cover_images %]
9
[% SET CoverImagePlugins = KohaPlugins.get_plugins_opac_cover_images %]
9
10
10
[% IF firstPage %]
11
[% IF firstPage %]
Lines 34-39 Link Here
34
[% INCLUDE 'masthead.inc' %]
35
[% INCLUDE 'masthead.inc' %]
35
36
36
    <div class="main">
37
    <div class="main">
38
        [% IF GeoSearchEnabled %]<div id="geo_search_map"></div>[% END %]
37
        <nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumbs">
39
        <nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumbs">
38
            <ol class="breadcrumb">
40
            <ol class="breadcrumb">
39
                <li class="breadcrumb-item">
41
                <li class="breadcrumb-item">
Lines 589-595 Link Here
589
    [% IF OpenLibraryCovers || OpenLibrarySearch %]
591
    [% IF OpenLibraryCovers || OpenLibrarySearch %]
590
        [% Asset.js("js/openlibrary.js") | $raw %]
592
        [% Asset.js("js/openlibrary.js") | $raw %]
591
    [% END %]
593
    [% END %]
594
    [% IF ( GeoSearchEnabled ) %]
595
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.1/dist/leaflet.css" integrity="sha256-sA+zWATbFveLLNqWO2gtiw3HL/lh1giY/Inf1BJ0z14=" crossorigin=""/>
596
        <script src="https://unpkg.com/leaflet@1.9.1/dist/leaflet.js" integrity="sha256-NDI0K41gVbWqfkkaHj15IzU7PtMoelkzyKp8TOaFQ3s=" crossorigin=""></script>
597
        [% Asset.js("js/geosearchdisplaymap.js") | $raw %]
598
    [% END %]
592
    [% CoverImagePlugins | $raw %]
599
    [% CoverImagePlugins | $raw %]
600
593
    <script>
601
    <script>
594
        [% IF ( Koha.Preference( 'opacuserlogin' ) == 1 ) && ( Koha.Preference( 'OPACHoldRequests' ) == 1 ) %]
602
        [% IF ( Koha.Preference( 'opacuserlogin' ) == 1 ) && ( Koha.Preference( 'OPACHoldRequests' ) == 1 ) %]
595
            function holdMultiple() {
603
            function holdMultiple() {
(-)a/koha-tmpl/opac-tmpl/bootstrap/js/geosearchdisplaymap.js (+39 lines)
Line 0 Link Here
1
$( document ).ready(function() {
2
  if ($("#geo_search_map")) {
3
4
    var biblionumbers = [];
5
    $(".addtocart").each(function() {
6
      biblionumbers.push( $(this).attr("data-biblionumber") );
7
    });
8
    if (biblionumbers.length === 0) {
9
      $('#geo_search_map').hide();
10
      return;
11
    }
12
    var map = L.map('geo_search_map');
13
    var tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
14
      maxZoom: 19,
15
      attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
16
    }).addTo(map);
17
18
    $(function(e) {
19
      var ajaxData = { 'bn': biblionumbers };
20
      $.ajax({
21
        url: '/api/v1/public/biblios/geo',
22
        type: 'GET',
23
        dataType: 'json',
24
        data: ajaxData,
25
        traditional: true
26
      })
27
      .done(function(data) {
28
        var bounds = L.latLngBounds()
29
        $.each(data['data'], function( index, value ) {
30
          var marker = L.marker(value['coordinates']).addTo(map);
31
          marker.bindPopup(index+1 + '. ' + value['title'] );
32
          bounds.extend(value['coordinates']);
33
        });
34
        map.fitBounds(bounds);
35
      })
36
      .error(function(data) {});
37
    });
38
  }
39
});
(-)a/opac/opac-search.pl (-4 / +18 lines)
Lines 106-112 my $format = $cgi->param("format") || ''; Link Here
106
if ($format =~ /(rss|atom|opensearchdescription)/) {
106
if ($format =~ /(rss|atom|opensearchdescription)/) {
107
    $template_name = 'opac-opensearch.tt';
107
    $template_name = 'opac-opensearch.tt';
108
}
108
}
109
elsif ((@params>=1) || (defined $cgi->param("q") && $cgi->param("q") ne "") || ($cgi->param('multibranchlimit')) || ($cgi->param('limit-yr')) || @searchCategories ) {
109
elsif ((@params>=1) || (defined $cgi->param("q") && $cgi->param("q") ne "") ||
110
      ($cgi->param('multibranchlimit')) || ($cgi->param('limit-yr')) || @searchCategories
111
      || $cgi->param('lat') ){
110
    $template_name = 'opac-results.tt';
112
    $template_name = 'opac-results.tt';
111
}
113
}
112
else {
114
else {
Lines 401-408 my @operators = $cgi->multi_param('op'); Link Here
401
403
402
# indexes are query qualifiers, like 'title', 'author', etc. They
404
# indexes are query qualifiers, like 'title', 'author', etc. They
403
# can be single or multiple parameters separated by comma: kw,right-Truncation 
405
# can be single or multiple parameters separated by comma: kw,right-Truncation 
406
407
if ($params->{'lat'} && $params->{'lng'} && $params->{'distance'} ) {
408
    $params->{q}   = sprintf("lat:%s lng:%s distance:%s",
409
          $params->{'lat'}, $params->{'lng'}, $params->{'distance'});
410
411
    $params->{idx} = 'geolocation';
412
    delete $params->{'lat'};
413
    delete $params->{'lng'};
414
    delete $params->{'radius'};
415
}
416
417
418
404
my @indexes = $cgi->multi_param('idx');
419
my @indexes = $cgi->multi_param('idx');
405
@indexes = map { uri_unescape($_) } @indexes;
420
@indexes = grep { $_ } @indexes;
421
@indexes = map {  uri_unescape($_) } @indexes;
406
422
407
# if a simple index (only one)  display the index used in the top search box
423
# if a simple index (only one)  display the index used in the top search box
408
if ($indexes[0] && !$indexes[1]) {
424
if ($indexes[0] && !$indexes[1]) {
Lines 456-462 foreach my $limit(@limits) { Link Here
456
}
472
}
457
$template->param(available => $available);
473
$template->param(available => $available);
458
474
459
# append year limits if they exist
460
if ($params->{'limit-yr'}) {
475
if ($params->{'limit-yr'}) {
461
    if ($params->{'limit-yr'} =~ /\d{4}/) {
476
    if ($params->{'limit-yr'} =~ /\d{4}/) {
462
        push @limits, "yr,st-numeric=$params->{'limit-yr'}";
477
        push @limits, "yr,st-numeric=$params->{'limit-yr'}";
463
- 

Return to bug 31652