Bug 17600: Standardize our EXPORT_OK
[srvgit] / admin / searchengine / elasticsearch / mappings.pl
index de891ac..1058e94 100755 (executable)
 
 use Modern::Perl;
 use CGI;
-use Scalar::Util qw(looks_like_number);
+use Scalar::Util qw( looks_like_number );
 use List::Util qw( first );
-use C4::Koha;
 use C4::Output;
 use C4::Auth;
+use C4::Log;
 
 use Koha::SearchEngine::Elasticsearch;
-use Koha::SearchEngine::Elasticsearch::Indexer;
+use Koha::SearchEngine::Elasticsearch::QueryBuilder;
 use Koha::SearchMarcMaps;
 use Koha::SearchFields;
+use Koha::Caches;
 
-use Try::Tiny;
+use Try::Tiny qw( catch try );
+use Module::Load::Conditional qw( can_load );
 
-my $input = new CGI;
+
+my $input = CGI->new;
 my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
-    {   template_name   => 'admin/searchengine/elasticsearch/mappings.tt',
+    {
+        template_name   => 'admin/searchengine/elasticsearch/mappings.tt',
         query           => $input,
         type            => 'intranet',
-        authnotrequired => 0,
         flagsrequired   => { parameters => 'manage_search_engine_config' },
     }
 );
 
+unless ( can_load( modules => { 'Koha::SearchEngine::Elasticsearch::Indexer' => undef } ) ) {
+    output_and_exit( $input, $cookie, $template, 'missing_es_modules');
+}
+
+
 my $index = $input->param('index') || 'biblios';
 my $op    = $input->param('op')    || 'list';
 my @messages;
+push @messages, { type => 'message', code => 'elasticsearch_disabled' }
+  if ( C4::Context->preference('SearchEngine') ne 'Elasticsearch' );
 
 my $database = Koha::Database->new();
 my $schema   = $database->schema;
@@ -68,6 +78,14 @@ my $update_mappings = sub {
     }
 };
 
+my $search_fields_aliases = {};
+while ( my ( $key, $value ) = each(%{Koha::SearchEngine::Elasticsearch::QueryBuilder->get_index_field_convert}) ) {
+    my $field_aliases = $search_fields_aliases->{$value};
+    $field_aliases = [] unless $field_aliases;
+    push @$field_aliases, $key;
+    $search_fields_aliases->{$value} = $field_aliases;
+}
+
 if ( $op eq 'edit' ) {
 
     $schema->storage->txn_begin;
@@ -76,12 +94,15 @@ if ( $op eq 'edit' ) {
     my @field_label = $input->multi_param('search_field_label');
     my @field_type = $input->multi_param('search_field_type');
     my @field_weight = $input->multi_param('search_field_weight');
+    my @field_staff_client = $input->multi_param('search_field_staff_client');
+    my @field_opac = $input->multi_param('search_field_opac');
 
     my @index_name          = $input->multi_param('mapping_index_name');
-    my @search_field_name  = $input->multi_param('mapping_search_field_name');
+    my @search_field_name   = $input->multi_param('mapping_search_field_name');
     my @mapping_sort        = $input->multi_param('mapping_sort');
     my @mapping_facet       = $input->multi_param('mapping_facet');
     my @mapping_suggestible = $input->multi_param('mapping_suggestible');
+    my @mapping_search      = $input->multi_param('mapping_search');
     my @mapping_marc_field  = $input->multi_param('mapping_marc_field');
     my @faceted_field_names = $input->multi_param('display_facet');
 
@@ -92,6 +113,8 @@ if ( $op eq 'edit' ) {
             my $field_label = $field_label[$i];
             my $field_type = $field_type[$i];
             my $field_weight = $field_weight[$i];
+            my $field_staff_client = $field_staff_client[$i];
+            my $field_opac = $field_opac[$i];
 
             my $search_field = Koha::SearchFields->find( { name => $field_name }, { key => 'name' } );
             $search_field->label($field_label);
@@ -106,6 +129,8 @@ if ( $op eq 'edit' ) {
             else {
                 $search_field->weight($field_weight);
             }
+            $search_field->staff_client($field_staff_client ? 1 : 0);
+            $search_field->opac($field_opac ? 1 : 0);
 
             my $facet_order = first { $faceted_field_names[$_] eq $field_name } 0 .. $#faceted_field_names;
             $search_field->facet_order(defined $facet_order ? $facet_order + 1 : undef);
@@ -116,43 +141,61 @@ if ( $op eq 'edit' ) {
         my @facetable_fields = Koha::SearchEngine::Elasticsearch->get_facetable_fields();
         my @facetable_field_names = map { $_->name } @facetable_fields;
 
+        my $mandatory_before = Koha::SearchFields->search({mandatory=>1})->count;
+        my $mandatory_after  = 0;
+        my %seen_fields;
         for my $i ( 0 .. scalar(@index_name) - 1 ) {
             my $index_name          = $index_name[$i];
-            my $search_field_name  = $search_field_name[$i];
+            my $search_field_name   = $search_field_name[$i];
             my $mapping_marc_field  = $mapping_marc_field[$i];
             my $mapping_facet       = $mapping_facet[$i];
+            $mapping_facet = ( grep { $_ eq $search_field_name } @facetable_field_names ) ? $mapping_facet : 0;
             my $mapping_suggestible = $mapping_suggestible[$i];
-            my $mapping_sort        = $mapping_sort[$i];
-            $mapping_sort = undef if $mapping_sort eq 'undef';
-            $mapping_facet = ( grep {/^$search_field_name$/} @facetable_field_names ) ? $mapping_facet : 0;
+            my $mapping_sort        = $mapping_sort[$i] eq 'undef' ? undef : $mapping_sort[$i];
+            my $mapping_search      = $mapping_search[$i];
 
             my $search_field = Koha::SearchFields->find({ name => $search_field_name }, { key => 'name' });
+            $mandatory_after++ if $search_field->mandatory && !defined $seen_fields{$search_field_name};
+            $seen_fields{$search_field_name} = 1;
             # TODO Check mapping format
-            my $marc_field = Koha::SearchMarcMaps->find_or_create({ index_name => $index_name, marc_type => $marc_type, marc_field => $mapping_marc_field });
-            $search_field->add_to_search_marc_maps($marc_field, { facet => $mapping_facet, suggestible => $mapping_suggestible, sort => $mapping_sort } );
-
+            my $marc_field = Koha::SearchMarcMaps->find_or_create({
+                index_name => $index_name,
+                marc_type => $marc_type,
+                marc_field => $mapping_marc_field
+            });
+            $search_field->add_to_search_marc_maps($marc_field, {
+                facet => $mapping_facet,
+                suggestible => $mapping_suggestible,
+                sort => $mapping_sort,
+                search => $mapping_search
+            });
         }
+        push @messages, { type => 'error', code => 'missing_mandatory_fields' } if $mandatory_after < $mandatory_before;
     };
-    if ($@) {
+    if ($@ || @messages) {
         push @messages, { type => 'error', code => 'error_on_update', message => $@, };
         $schema->storage->txn_rollback;
     } else {
         push @messages, { type => 'message', code => 'success_on_update' };
+
+        C4::Log::logaction( 'SEARCHENGINE', 'EDIT_MAPPINGS', undef, q{} );
+
         $schema->storage->txn_commit;
+
+        Koha::SearchEngine::Elasticsearch->clear_search_fields_cache();
+
         $update_mappings->();
     }
 }
 elsif( $op eq 'reset_confirmed' ) {
-    Koha::SearchMarcMaps->delete;
-    Koha::SearchFields->delete;
     Koha::SearchEngine::Elasticsearch->reset_elasticsearch_mappings;
     push @messages, { type => 'message', code => 'success_on_reset' };
+    C4::Log::logaction( 'SEARCHENGINE', 'RESET_MAPPINGS', undef, q{} );
 }
 elsif( $op eq 'reset_confirm' ) {
     $template->param( reset_confirm => 1 );
 }
 
-
 my @indexes;
 
 for my $index_name (@index_names) {
@@ -176,32 +219,50 @@ for my $index_name (@index_names) {
     }
 }
 
+my @facetable_fields = Koha::SearchEngine::Elasticsearch->get_facetable_fields();
 for my $index_name (@index_names) {
     my $search_fields = Koha::SearchFields->search(
-        { 'search_marc_map.index_name' => $index_name, 'search_marc_map.marc_type' => $marc_type, },
-        {   join => { search_marc_to_fields => 'search_marc_map' },
-            '+select' => [ 'search_marc_to_fields.facet', 'search_marc_to_fields.suggestible', 'search_marc_to_fields.sort', 'search_marc_map.marc_field' ],
-            '+as'     => [ 'facet',                       'suggestible',                       'sort',                       'marc_field' ],
+        {
+            'search_marc_map.index_name' => $index_name,
+            'search_marc_map.marc_type' => $marc_type,
+        },
+        {
+            join => { search_marc_to_fields => 'search_marc_map' },
+            '+select' => [
+                'search_marc_to_fields.facet',
+                'search_marc_to_fields.suggestible',
+                'search_marc_to_fields.sort',
+                'search_marc_to_fields.search',
+                'search_marc_map.marc_field'
+            ],
+            '+as' => [
+                'facet',
+                'suggestible',
+                'sort',
+                'search',
+                'marc_field'
+            ],
             order_by => { -asc => [qw/name marc_field/] }
-        }
-    );
+         }
+     );
 
     my @mappings;
-    my @facetable_fields = Koha::SearchEngine::Elasticsearch->get_facetable_fields();
     my @facetable_field_names = map { $_->name } @facetable_fields;
 
     while ( my $s = $search_fields->next ) {
         my $name = $s->name;
-        push @mappings,
-          { search_field_name  => $name,
+        push @mappings, {
+            search_field_name  => $name,
             search_field_label => $s->label,
             search_field_type  => $s->type,
+            search_field_mandatory  => $s->mandatory,
             marc_field         => $s->get_column('marc_field'),
             sort               => $s->get_column('sort') // 'undef', # To avoid warnings "Use of uninitialized value in lc"
             suggestible        => $s->get_column('suggestible'),
+            search             => $s->get_column('search'),
             facet              => $s->get_column('facet'),
-            is_facetable       => ( grep {/^$name$/} @facetable_field_names ) ? 1 : 0,
-          };
+            is_facetable       => ( grep { $_ eq $name } @facetable_field_names ) ? 1 : 0,
+        };
     }
 
     push @indexes, { index_name => $index_name, mappings => \@mappings };
@@ -212,10 +273,10 @@ my @all_search_fields;
 while ( my $search_field = $search_fields->next ) {
     my $search_field_unblessed = $search_field->unblessed;
     $search_field_unblessed->{mapped_biblios} = 1 if $search_field->is_mapped_biblios;
+    $search_field_unblessed->{aliases} = $search_fields_aliases->{$search_field_unblessed->{name}};
     push @all_search_fields, $search_field_unblessed;
 }
 
-my @facetable_fields = Koha::SearchEngine::Elasticsearch->get_facetable_fields();
 $template->param(
     indexes           => \@indexes,
     all_search_fields => \@all_search_fields,