Bug 21959: Batch item modification - ability to apply regular expression on text...
authorAlex Arnaud <alex.arnaud@biblibre.com>
Thu, 6 Dec 2018 08:43:42 +0000 (09:43 +0100)
committerMartin Renvoize <martin.renvoize@ptfs-europe.com>
Wed, 8 Jan 2020 14:35:50 +0000 (14:35 +0000)
Test plan:
  - go to Tools > Batch item modification,
  - select items to modify,
  - for one or some text fields, check the second checkbox (Use regular
    expression) and type your regex,
  - check the regex has been applied.

Signed-off-by: Pierre-Marc Thibault <pierre-marc.thibault@inLibro.com>
Signed-off-by: Mathilde Formery <mathilde.formery@ville-nimes.fr>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

koha-tmpl/intranet-tmpl/prog/en/modules/tools/batchMod-edit.tt
tools/batchMod.pl

index 30afde8..8097f41 100644 (file)
@@ -24,17 +24,37 @@ $(document).ready(function(){
       var row = $(this).attr("id");
       row = row.replace("row","hint");
       var todisable = $(this).parent().find("[name='field_value'],[name='tag'],[name='subfield'],[name='mandatory']");
+      var regex_input = $(this).parent().find("[name='field_regex']");
       if ($(this).is(":checked")) {
           $(todisable).prop('disabled', true);
           $("#"+row).html(_("This subfield will be deleted"));
+          $(regex_input).prop('disabled', true);
       } else {
           $(todisable).prop('disabled', false);
           $("#"+row).html("");
+          $(regex_input).prop('disabled', false);
       }
   });
     $("#mainformsubmit").on("click",function(){
         return submitBackgroundJob(this.form);
     });
+  $('input[name="field_regex"]').change(function() {
+    var id = $(this).attr('id');
+    var editor = $(this).parent().find("[name='field_value']");
+    var regex = $(this).parent().find("[name='regex_fields']");
+    var disable_input = $(this).parent().find("[name='disable_input']");
+    if ($(this).is(':checked')) {
+      $(editor).hide();
+      $(regex).show();
+      $(this).parent().find('.hint').html(_("Enter a regular expression for this subflied"));
+      $(disable_input).prop('disabled', true);
+    } else {
+      $(editor).show();
+      $(regex).hide();
+      $(this).parent().find('.hint').html(_(""));
+      $(disable_input).prop('disabled', false);
+    }
+  });
 });
 //]]>
 </script>
@@ -285,12 +305,22 @@ $(document).ready(function(){
                 <textarea tabindex="1" id="[%- mv.id | html -%]" name="field_value" class="input_marceditor" size="50" maxlength="255">[%- mv.value | html -%]"</textarea>
               [%- END -%]
 
+              <span name="regex_fields" style="display: none;">
+                s/<input type="text" id="[% mv.id | html %]" name="regex_search" placeholder="regex pattern" />/
+                <input type="text" id="[% mv.id | html %]" name="regex_replace" placeholder="regex replacement" />/
+                <input type="text" id="[% mv.id | html %]" name="regex_modifiers" placeholder="ig" size="3" />
+              </span>
+
               [% UNLESS ( ite.mandatory ) %]
                 <input type="checkbox" id="row[% ite.tag | html %][% ite.subfield | html %][% ite.random | html %]" title="Check to delete subfield [% ite.subfield | html %]" name="disable_input" value="[% ite.subfield | html %]" />
               [% ELSE %]
                 <span class="required">Required</span>
               [% END %]
 
+              [% IF (mv.type == 'text' || mv.type == 'textarea' ) %]
+                <input type="checkbox" name="field_regex" id="[% ite.id | html %]" title="Use regular expression">
+              [% END %]
+
               <input type="hidden" name="tag"       value="[% ite.tag | html %]" />
               <input type="hidden" name="subfield"       value="[% ite.subfield | html %]" />
               <input type="hidden" name="mandatory"       value="[% ite.mandatory | html %]" />
index 9ed3301..7077ca2 100755 (executable)
@@ -105,6 +105,9 @@ if ($op eq "action") {
     my @tags      = $input->multi_param('tag');
     my @subfields = $input->multi_param('subfield');
     my @values    = $input->multi_param('field_value');
+    my @searches  = $input->multi_param('regex_search');
+    my @replaces  = $input->multi_param('regex_replace');
+    my @modifiers = $input->multi_param('regex_modifiers');
     my @disabled  = $input->multi_param('disable_input');
     # build indicator hash.
     my @ind_tag   = $input->multi_param('ind_tag');
@@ -112,8 +115,9 @@ if ($op eq "action") {
 
     # Is there something to modify ?
     # TODO : We shall use this var to warn the user in case no modification was done to the items
-    my $values_to_modify = scalar(grep {!/^$/} @values);
+    my $values_to_modify = scalar(grep {!/^$/} @values) || scalar(grep {!/^$/} @searches);
     my $values_to_blank  = scalar(@disabled);
+
     my $marcitem;
 
     # Once the job is done
@@ -217,8 +221,32 @@ if ($op eq "action") {
                } else {
             if ($values_to_modify || $values_to_blank) {
                 my $localmarcitem = Item2Marc($itemdata);
+                my $modified = 0;
+
+                for ( my $i = 0 ; $i < @tags ; $i++ ) {
+                    my $search = $searches[$i];
+                    next unless $search;
+
+                    my $tag = $tags[$i];
+                    my $subfield = $subfields[$i];
+                    my $replace = $replaces[$i];
+                    my $mod = $modifiers[$i];
+
+                    my $value = $localmarcitem->field( $tag )->subfield( $subfield );
+                    my $old_value = $value;
+                    ## no critic (StringyEval)
+                    eval "\$value =~ s/$search/$replace/$mod";
+
+                    my @fields_to = $localmarcitem->field($tag);
+                    foreach my $field_to_update ( @fields_to ) {
+                        unless ( $old_value eq $value ) {
+                            $modified++;
+                            $field_to_update->update( $subfield => $value );
+                        }
+                    }
+                }
 
-                my $modified = UpdateMarcWith( $marcitem, $localmarcitem );
+                $modified += UpdateMarcWith( $marcitem, $localmarcitem );
                 if ( $modified ) {
                     eval {
                         if ( my $item = ModItemFromMarc( $localmarcitem, $itemdata->{biblionumber}, $itemnumber ) ) {
@@ -634,6 +662,9 @@ sub UpdateMarcWith {
     my $fieldfrom=$marcfrom->field($itemtag);
     my @fields_to=$marcto->field($itemtag);
     my $modified = 0;
+
+    return $modified unless $fieldfrom;
+
     foreach my $subfield ( $fieldfrom->subfields() ) {
         foreach my $field_to_update ( @fields_to ) {
             if ( $subfield->[1] ) {