| 
      
            Lines 24-56
          use Try::Tiny qw( catch try );
      
      
        Link Here
      
     | 
  
        
          | 24 | 
           | 
          24 | 
           | 
        
        
          | 25 | 
          use C4::Auth qw( get_template_and_user haspermission );  | 
          25 | 
          use C4::Auth qw( get_template_and_user haspermission );  | 
        
        
          | 26 | 
          use C4::Output qw( output_html_with_http_headers );  | 
          26 | 
          use C4::Output qw( output_html_with_http_headers );  | 
        
            
              | 27 | 
              use C4::Biblio qw(  | 
               | 
               | 
            
            
              | 28 | 
                  DelBiblio  | 
            
            
              | 29 | 
                  GetAuthorisedValueDesc  | 
            
            
              | 30 | 
                  GetMarcFromKohaField  | 
            
            
              | 31 | 
                  GetMarcStructure  | 
            
            
              | 32 | 
                  IsMarcStructureInternal  | 
            
            
              | 33 | 
                  TransformHtmlToXml  | 
            
            
              | 34 | 
              );  | 
            
            
              | 35 | 
              use C4::Items qw( GetItemsInfo Item2Marc ModItemFromMarc );  | 
            
            
              | 36 | 
              use C4::Circulation qw( LostItem IsItemIssued );  | 
            
        
          | 37 | 
          use C4::Context;  | 
          27 | 
          use C4::Context;  | 
        
            
              | 38 | 
              use C4::Koha;  | 
               | 
               | 
            
            
              | 39 | 
              use C4::BackgroundJob;  | 
            
            
              | 40 | 
              use C4::ClassSource qw( GetClassSources GetClassSource );  | 
            
        
          | 41 | 
          use MARC::File::XML;  | 
          28 | 
          use MARC::File::XML;  | 
        
        
          | 42 | 
          use List::MoreUtils qw( uniq );  | 
          29 | 
          use List::MoreUtils qw( uniq );  | 
        
            
               | 
               | 
              30 | 
              use Encode qw( encode_utf8 );  | 
            
        
          | 43 | 
           | 
          31 | 
           | 
        
        
          | 44 | 
          use Koha::Database;  | 
          32 | 
          use Koha::Database;  | 
        
            
               | 
               | 
              33 | 
              use Koha::DateUtils qw( dt_from_string );  | 
            
        
          | 45 | 
          use Koha::Exceptions::Exception;  | 
          34 | 
          use Koha::Exceptions::Exception;  | 
        
            
              | 46 | 
              use Koha::AuthorisedValues;  | 
               | 
               | 
            
        
          | 47 | 
          use Koha::Biblios;  | 
          35 | 
          use Koha::Biblios;  | 
        
            
              | 48 | 
              use Koha::DateUtils qw( dt_from_string );  | 
               | 
               | 
            
        
          | 49 | 
          use Koha::Items;  | 
          36 | 
          use Koha::Items;  | 
        
            
              | 50 | 
              use Koha::ItemTypes;  | 
               | 
               | 
            
        
          | 51 | 
          use Koha::Patrons;  | 
          37 | 
          use Koha::Patrons;  | 
        
          
            
              | 52 | 
              use Koha::SearchEngine::Indexer;  | 
              38 | 
              use Koha::Item::Attributes;  | 
            
            
               | 
               | 
              39 | 
              use Koha::BackgroundJob::BatchDeleteItem;  | 
            
            
              | 40 | 
              use Koha::BackgroundJob::BatchUpdateItem;  | 
            
        
          | 53 | 
          use Koha::UI::Form::Builder::Item;  | 
          41 | 
          use Koha::UI::Form::Builder::Item;  | 
        
            
               | 
               | 
              42 | 
              use Koha::UI::Table::Builder::Items;  | 
            
        
          | 54 | 
           | 
          43 | 
           | 
        
        
          | 55 | 
          my $input = CGI->new;  | 
          44 | 
          my $input = CGI->new;  | 
        
        
          | 56 | 
          my $dbh = C4::Context->dbh;  | 
          45 | 
          my $dbh = C4::Context->dbh;  | 
        
  
    | 
      
            Lines 90-346
          my $restrictededition = $uid ? haspermission($uid,  {'tools' => 'items_batchmod_
      
      
        Link Here
      
     | 
  
        
          | 90 | 
          # In case user is a superlibrarian, edition is not restricted  | 
          79 | 
          # In case user is a superlibrarian, edition is not restricted  | 
        
        
          | 91 | 
          $restrictededition = 0 if ($restrictededition != 0 && C4::Context->IsSuperLibrarian());  | 
          80 | 
          $restrictededition = 0 if ($restrictededition != 0 && C4::Context->IsSuperLibrarian());  | 
        
        
          | 92 | 
           | 
          81 | 
           | 
        
            
              | 93 | 
              $template->param(del       => $del);  | 
               | 
               | 
            
            
              | 94 | 
               | 
            
        
          | 95 | 
          my $nextop="";  | 
          82 | 
          my $nextop="";  | 
        
          
            
              | 96 | 
              my @errors; # store errors found while checking data BEFORE saving item.  | 
              83 | 
              my $display_items;  | 
            
            
              | 97 | 
              my $items_display_hashref;  | 
               | 
               | 
            
            
              | 98 | 
              our $tagslib = &GetMarcStructure(1);  | 
            
            
              | 99 | 
               | 
            
            
              | 100 | 
              my $deleted_items = 0;     # Number of deleted items  | 
            
            
              | 101 | 
              my $deleted_records = 0;   # Number of deleted records ( with no items attached )  | 
            
            
              | 102 | 
              my $not_deleted_items = 0; # Number of items that could not be deleted  | 
            
            
              | 103 | 
              my @not_deleted;           # List of the itemnumbers that could not be deleted  | 
            
            
              | 104 | 
              my $modified_items = 0;    # Numbers of modified items  | 
            
            
              | 105 | 
              my $modified_fields = 0;   # Numbers of modified fields  | 
            
        
          | 106 | 
           | 
          84 | 
           | 
        
        
          | 107 | 
          my %cookies = parse CGI::Cookie($cookie);  | 
          85 | 
          my %cookies = parse CGI::Cookie($cookie);  | 
        
        
          | 108 | 
          my $sessionID = $cookies{'CGISESSID'}->value; | 
          86 | 
          my $sessionID = $cookies{'CGISESSID'}->value; | 
        
        
          | 109 | 
           | 
          87 | 
           | 
        
            
               | 
               | 
              88 | 
              my @messages;  | 
            
        
          | 110 | 
           | 
          89 | 
           | 
        
          
            
              | 111 | 
              #--- ----------------------------------------------------------------------------  | 
              90 | 
              if ( $op eq "action" ) { | 
            
            
              | 112 | 
              if ($op eq "action") { | 
              91 | 
               | 
            
            
              | 113 | 
              #-------------------------------------------------------------------------------  | 
              92 | 
                  if ($del) { | 
            
            
              | 114 | 
                  my @tags      = $input->multi_param('tag'); | 
               | 
               | 
            
            
              | 115 | 
                  my @subfields = $input->multi_param('subfield'); | 
            
            
              | 116 | 
                  my @values    = $input->multi_param('field_value'); | 
            
            
              | 117 | 
                  my @searches  = $input->multi_param('regex_search'); | 
            
            
              | 118 | 
                  my @replaces  = $input->multi_param('regex_replace'); | 
            
            
              | 119 | 
                  my @modifiers = $input->multi_param('regex_modifiers'); | 
            
            
              | 120 | 
                  my @subfields_to_blank = $input->multi_param('disable_input'); | 
            
            
              | 121 | 
                  # build indicator hash.  | 
            
            
              | 122 | 
                  my @ind_tag   = $input->multi_param('ind_tag'); | 
            
            
              | 123 | 
                  my @indicator = $input->multi_param('indicator'); | 
            
            
              | 124 | 
               | 
            
            
              | 125 | 
                  my $upd_biblionumbers;  | 
            
            
              | 126 | 
                  my $del_biblionumbers;  | 
            
            
              | 127 | 
                  if ( $del ) { | 
            
        
          | 128 | 
                  try { | 
          93 | 
                  try { | 
        
          
            
              | 129 | 
                          my $schema = Koha::Database->new->schema;  | 
              94 | 
                          my $params = { | 
            
            
              | 130 | 
                          $schema->txn_do(  | 
              95 | 
                              record_ids     => \@itemnumbers,  | 
            
            
              | 131 | 
                              sub { | 
              96 | 
                              delete_biblios => $del_records,  | 
            
            
              | 132 | 
                                  foreach my $itemnumber (@itemnumbers) { | 
              97 | 
                          };  | 
            
            
              | 133 | 
                                      my $item = Koha::Items->find($itemnumber);  | 
              98 | 
                          my $job_id =  | 
            
            
              | 134 | 
                                      next  | 
              99 | 
                            Koha::BackgroundJob::BatchDeleteItem->new->enqueue($params);  | 
            
            
              | 135 | 
                                        unless $item  | 
              100 | 
                          $nextop = 'enqueued';  | 
            
            
              | 136 | 
                                        ; # Should have been tested earlier, but just in case...  | 
              101 | 
                          $template->param( job_id => $job_id, );  | 
            
            
              | 137 | 
                                      my $itemdata = $item->unblessed;  | 
               | 
               | 
            
            
              | 138 | 
                                      my $return = $item->safe_delete;  | 
            
            
              | 139 | 
                                      if ( ref( $return ) ) { | 
            
            
              | 140 | 
                                          $deleted_items++;  | 
            
            
              | 141 | 
                                          push @$upd_biblionumbers, $itemdata->{'biblionumber'}; | 
            
            
              | 142 | 
                                      }  | 
            
            
              | 143 | 
                                      else { | 
            
            
              | 144 | 
                                          $not_deleted_items++;  | 
            
            
              | 145 | 
                                          push @not_deleted,  | 
            
            
              | 146 | 
                                            { | 
            
            
              | 147 | 
                                              biblionumber => $itemdata->{'biblionumber'}, | 
            
            
              | 148 | 
                                              itemnumber   => $itemdata->{'itemnumber'}, | 
            
            
              | 149 | 
                                              barcode      => $itemdata->{'barcode'}, | 
            
            
              | 150 | 
                                              title        => $itemdata->{'title'}, | 
            
            
              | 151 | 
                                              reason       => $return,  | 
            
            
              | 152 | 
                                            };  | 
            
            
              | 153 | 
                                      }  | 
            
            
              | 154 | 
               | 
            
            
              | 155 | 
                                      # If there are no items left, delete the biblio  | 
            
            
              | 156 | 
                                      if ($del_records) { | 
            
            
              | 157 | 
                                          my $itemscount = Koha::Biblios->find( $itemdata->{'biblionumber'} )->items->count; | 
            
            
              | 158 | 
                                          if ( $itemscount == 0 ) { | 
            
            
              | 159 | 
                                              my $error = DelBiblio( $itemdata->{'biblionumber'}, { skip_record_index => 1 } ); | 
            
            
              | 160 | 
                                              unless ($error) { | 
            
            
              | 161 | 
                                                  $deleted_records++;  | 
            
            
              | 162 | 
                                                  push @$del_biblionumbers, $itemdata->{'biblionumber'}; | 
            
            
              | 163 | 
                                                  if ( $src eq 'CATALOGUING' ) { | 
            
            
              | 164 | 
                                                      # We are coming catalogue/detail.pl, there were items from a single bib record  | 
            
            
              | 165 | 
                                                      $template->param( biblio_deleted => 1 );  | 
            
            
              | 166 | 
                                                  }  | 
            
            
              | 167 | 
                                              }  | 
            
            
              | 168 | 
                                          }  | 
            
            
              | 169 | 
                                      }  | 
            
            
              | 170 | 
                                  }  | 
            
            
              | 171 | 
                                  if (@not_deleted) { | 
            
            
              | 172 | 
                                      Koha::Exceptions::Exception->throw(  | 
            
            
              | 173 | 
                                          'Some items have not been deleted, rolling back');  | 
            
            
              | 174 | 
                                  }  | 
            
            
              | 175 | 
                              }  | 
            
            
              | 176 | 
                          );  | 
            
        
          | 177 | 
                  }  | 
          102 | 
                  }  | 
        
        
          | 178 | 
                  catch { | 
          103 | 
                  catch { | 
        
        
          | 179 | 
                      warn $_;  | 
          104 | 
                      warn $_;  | 
        
          
            
              | 180 | 
                          if ( $_->isa('Koha::Exceptions::Exception') ) { | 
              105 | 
                          push @messages,  | 
            
            
              | 181 | 
                              $template->param( deletion_failed => 1 );  | 
              106 | 
                            { | 
            
            
              | 182 | 
                          }  | 
              107 | 
                              type  => 'error',  | 
            
            
              | 183 | 
                          die "Something terrible has happened!"  | 
              108 | 
                              code  => 'cannot_enqueue_job',  | 
            
            
              | 184 | 
                              if ($_ =~ /Rollback failed/); # Rollback failed  | 
              109 | 
                              error => $_,  | 
            
            
               | 
               | 
              110 | 
                            };  | 
            
            
              | 111 | 
                          $template->param( view => 'errors' );  | 
            
        
          | 185 | 
                  };  | 
          112 | 
                  };  | 
        
        
          | 186 | 
              }  | 
          113 | 
              }  | 
        
        
          | 187 | 
           | 
          114 | 
           | 
        
          
            
              | 188 | 
                  else { # modification | 
              115 | 
                  else {    # modification | 
            
        
          | 189 | 
           | 
          116 | 
           | 
        
          
            
              | 190 | 
                      my @columns = Koha::Items->columns;  | 
              117 | 
                      my @item_columns = Koha::Items->columns;  | 
            
        
          | 191 | 
           | 
          118 | 
           | 
        
        
          | 192 | 
                  my $new_item_data;  | 
          119 | 
                  my $new_item_data;  | 
        
          
            
              | 193 | 
                      my @columns_with_regex;  | 
              120 | 
                      my ( $columns_with_regex );  | 
            
            
              | 194 | 
                      for my $c ( @columns ) { | 
              121 | 
                      my @subfields_to_blank = $input->multi_param('disable_input'); | 
            
            
              | 195 | 
                          if ( $c eq 'more_subfields_xml' ) { | 
              122 | 
                      my @more_subfields = $input->multi_param("items.more_subfields_xml"); | 
            
            
              | 196 | 
                              my @more_subfields_xml = $input->multi_param("items.more_subfields_xml"); | 
              123 | 
                      for my $item_column (@item_columns) { | 
            
            
              | 197 | 
                              my @unlinked_item_subfields;  | 
              124 | 
                          my @attributes       = ($item_column);  | 
            
            
              | 198 | 
                              for my $subfield ( @more_subfields_xml ) { | 
              125 | 
                          my $cgi_param_prefix = 'items.';  | 
            
            
              | 199 | 
                                  my $v = $input->param('items.more_subfields_xml_' . $subfield); | 
              126 | 
                          if ( $item_column eq 'more_subfields_xml' ) { | 
            
            
              | 200 | 
                                  push @unlinked_item_subfields, $subfield, $v;  | 
              127 | 
                              @attributes       = ();  | 
            
            
              | 201 | 
                              }  | 
              128 | 
                              $cgi_param_prefix = 'items.more_subfields_xml_';  | 
            
            
              | 202 | 
                              if ( @unlinked_item_subfields ) { | 
              129 | 
                              for my $subfield (@more_subfields) { | 
            
            
              | 203 | 
                                  my $marc = MARC::Record->new();  | 
              130 | 
                                  push @attributes, $subfield;  | 
            
            
              | 204 | 
                                  # use of tag 999 is arbitrary, and doesn't need to match the item tag  | 
               | 
               | 
            
            
              | 205 | 
                                  # used in the framework  | 
            
            
              | 206 | 
                                  $marc->append_fields(MARC::Field->new('999', ' ', ' ', @unlinked_item_subfields)); | 
            
            
              | 207 | 
                                  $marc->encoding("UTF-8"); | 
            
            
              | 208 | 
                                  # FIXME This is WRONG! We need to use the values that haven't been modified by the batch tool!  | 
            
            
              | 209 | 
                                  $new_item_data->{more_subfields_xml} = $marc->as_xml("USMARC"); | 
            
            
              | 210 | 
                                  next;  | 
            
        
          | 211 | 
                          }  | 
          131 | 
                          }  | 
        
          
            
              | 212 | 
                              $new_item_data->{more_subfields_xml} = undef; | 
              132 | 
                          }  | 
            
            
              | 213 | 
                              # FIXME deal with more_subfields_xml and @subfields_to_blank  | 
               | 
               | 
            
            
              | 214 | 
                          } elsif ( grep { $c eq $_ } @subfields_to_blank ) { | 
            
            
              | 215 | 
                              # Empty this column  | 
            
            
              | 216 | 
                              $new_item_data->{$c} = undef | 
            
            
              | 217 | 
                          } else { | 
            
        
          | 218 | 
           | 
          133 | 
           | 
        
          
            
              | 219 | 
                              my @v = grep { $_ ne "" } | 
              134 | 
                          for my $attr (@attributes) { | 
            
            
              | 220 | 
                                  uniq $input->multi_param( "items." . $c );  | 
               | 
               | 
            
        
          | 221 | 
           | 
          135 | 
           | 
        
          
            
              | 222 | 
                              next unless @v;  | 
              136 | 
                              my $cgi_var_name = $cgi_param_prefix  | 
            
            
               | 
               | 
              137 | 
                                . encode_utf8($attr)  | 
            
            
              | 138 | 
                                ;  # We need to deal correctly with encoding on subfield codes  | 
            
        
          | 223 | 
           | 
          139 | 
           | 
        
          
            
              | 224 | 
                              $new_item_data->{$c} = join ' | ', @v; | 
              140 | 
                              if ( grep { $attr eq $_ } @subfields_to_blank ) { | 
            
            
              | 225 | 
                          }  | 
              141 | 
               | 
            
            
               | 
               | 
              142 | 
                                  # Empty this column  | 
            
            
              | 143 | 
                                  $new_item_data->{$attr} = undef; | 
            
            
              | 144 | 
                              }  | 
            
            
              | 145 | 
                              elsif ( my $regex_search =  | 
            
            
              | 146 | 
                                  $input->param( $cgi_var_name . '_regex_search' ) )  | 
            
            
              | 147 | 
                              { | 
            
            
              | 148 | 
                                  $columns_with_regex->{$attr} = { | 
            
            
              | 149 | 
                                      search => $regex_search,  | 
            
            
              | 150 | 
                                      replace =>  | 
            
            
              | 151 | 
                                        $input->param( $cgi_var_name . '_regex_replace' ),  | 
            
            
              | 152 | 
                                      modifiers =>  | 
            
            
              | 153 | 
                                        $input->param( $cgi_var_name . '_regex_modifiers' )  | 
            
            
              | 154 | 
                                  };  | 
            
            
              | 155 | 
                              }  | 
            
            
              | 156 | 
                              else { | 
            
            
              | 157 | 
                                  my @v =  | 
            
            
              | 158 | 
                                    grep { $_ ne "" } uniq $input->multi_param($cgi_var_name); | 
            
        
          | 226 | 
           | 
          159 | 
           | 
        
          
            
              | 227 | 
                          if ( my $regex_search = $input->param('items.'.$c.'_regex_search') ) { | 
              160 | 
                                  next unless @v;  | 
            
            
              | 228 | 
                              push @columns_with_regex, $c;  | 
              161 | 
               | 
            
            
               | 
               | 
              162 | 
                                  $new_item_data->{$attr} = join '|', @v; | 
            
            
              | 163 | 
                              }  | 
            
        
          | 229 | 
                      }  | 
          164 | 
                      }  | 
        
        
          | 230 | 
                  }  | 
          165 | 
                  }  | 
        
        
          | 231 | 
           | 
          166 | 
           | 
        
            
               | 
               | 
              167 | 
                      my $params = { | 
            
            
              | 168 | 
                          record_ids                        => \@itemnumbers,  | 
            
            
              | 169 | 
                          regex_mod                         => $columns_with_regex,  | 
            
            
              | 170 | 
                          new_values                        => $new_item_data,  | 
            
            
              | 171 | 
                          exclude_from_local_holds_priority => (  | 
            
            
              | 172 | 
                              defined $exclude_from_local_holds_priority  | 
            
            
              | 173 | 
                                && $exclude_from_local_holds_priority ne ""  | 
            
            
              | 174 | 
                            )  | 
            
            
              | 175 | 
                          ? $exclude_from_local_holds_priority  | 
            
            
              | 176 | 
                          : undef,  | 
            
            
              | 177 | 
               | 
            
            
              | 178 | 
                      };  | 
            
        
          | 232 | 
                  try { | 
          179 | 
                  try { | 
        
          
            
              | 233 | 
                          my $schema = Koha::Database->new->schema;  | 
              180 | 
                          my $job_id =  | 
            
            
              | 234 | 
                          $schema->txn_do(  | 
              181 | 
                            Koha::BackgroundJob::BatchUpdateItem->new->enqueue($params);  | 
            
            
              | 235 | 
                              sub { | 
              182 | 
                          $nextop = 'enqueued';  | 
            
            
              | 236 | 
               | 
              183 | 
                          $template->param( job_id => $job_id, );  | 
            
            
              | 237 | 
                                  foreach my $itemnumber (@itemnumbers) { | 
               | 
               | 
            
            
              | 238 | 
                                      my $item = Koha::Items->find($itemnumber);  | 
            
            
              | 239 | 
                                      next  | 
            
            
              | 240 | 
                                        unless $item  | 
            
            
              | 241 | 
                                        ; # Should have been tested earlier, but just in case...  | 
            
            
              | 242 | 
                                      my $itemdata = $item->unblessed;  | 
            
            
              | 243 | 
               | 
            
            
              | 244 | 
                                      my $modified_holds_priority = 0;  | 
            
            
              | 245 | 
                                      if ( defined $exclude_from_local_holds_priority && $exclude_from_local_holds_priority ne "" ) { | 
            
            
              | 246 | 
                                          if(!defined $item->exclude_from_local_holds_priority || $item->exclude_from_local_holds_priority != $exclude_from_local_holds_priority) { | 
            
            
              | 247 | 
                                              $item->exclude_from_local_holds_priority($exclude_from_local_holds_priority)->store;  | 
            
            
              | 248 | 
                                              $modified_holds_priority = 1;  | 
            
            
              | 249 | 
                                          }  | 
            
            
              | 250 | 
                                      }  | 
            
            
              | 251 | 
               | 
            
            
              | 252 | 
                                      my $modified = 0;  | 
            
            
              | 253 | 
                                      for my $c ( @columns_with_regex ) { | 
            
            
              | 254 | 
                                          my $regex_search = $input->param('items.'.$c.'_regex_search'); | 
            
            
              | 255 | 
                                          my $old_value = $item->$c;  | 
            
            
              | 256 | 
               | 
            
            
              | 257 | 
                                          my $value = apply_regex(  | 
            
            
              | 258 | 
                                              { | 
            
            
              | 259 | 
                                                  search  => $regex_search,  | 
            
            
              | 260 | 
                                                  replace => $input->param(  | 
            
            
              | 261 | 
                                                      'items' . $c . '_regex_replace'  | 
            
            
              | 262 | 
                                                  ),  | 
            
            
              | 263 | 
                                                  modifiers => $input->param(  | 
            
            
              | 264 | 
                                                      'items' . $c . '_regex_modifiers'  | 
            
            
              | 265 | 
                                                  ),  | 
            
            
              | 266 | 
                                                  value => $old_value,  | 
            
            
              | 267 | 
                                              }  | 
            
            
              | 268 | 
                                          );  | 
            
            
              | 269 | 
                                          unless ( $old_value eq $value ) { | 
            
            
              | 270 | 
                                              $modified++;  | 
            
            
              | 271 | 
                                              $item->$c($value);  | 
            
            
              | 272 | 
                                          }  | 
            
            
              | 273 | 
                                      }  | 
            
            
              | 274 | 
               | 
            
            
              | 275 | 
                                      $modified += scalar(keys %$new_item_data); # FIXME This is incorrect if old value == new value. Should we loop of the keys and compare the before/after values?  | 
            
            
              | 276 | 
                                      if ( $modified) { | 
            
            
              | 277 | 
                                          my $itemlost_pre = $item->itemlost;  | 
            
            
              | 278 | 
                                          $item->set($new_item_data)->store({skip_record_index => 1}); | 
            
            
              | 279 | 
               | 
            
            
              | 280 | 
                                          push @$upd_biblionumbers, $itemdata->{'biblionumber'}; | 
            
            
              | 281 | 
               | 
            
            
              | 282 | 
                                          LostItem(  | 
            
            
              | 283 | 
                                              $item->itemnumber, 'batchmod', undef,  | 
            
            
              | 284 | 
                                              { skip_record_index => 1 } | 
            
            
              | 285 | 
                                          ) if $item->itemlost  | 
            
            
              | 286 | 
                                                and not $itemlost_pre;  | 
            
            
              | 287 | 
                                      }  | 
            
            
              | 288 | 
               | 
            
            
              | 289 | 
                                      $modified_items++ if $modified || $modified_holds_priority;  | 
            
            
              | 290 | 
                                      $modified_fields += $modified + $modified_holds_priority;  | 
            
            
              | 291 | 
                                  }  | 
            
            
              | 292 | 
                              }  | 
            
            
              | 293 | 
                          );  | 
            
        
          | 294 | 
                  }  | 
          184 | 
                  }  | 
        
        
          | 295 | 
                  catch { | 
          185 | 
                  catch { | 
        
          
            
              | 296 | 
                          warn $_;  | 
              186 | 
                          push @messages,  | 
            
            
              | 297 | 
                          die "Something terrible has happened!"  | 
              187 | 
                            { | 
            
            
              | 298 | 
                              if ($_ =~ /Rollback failed/); # Rollback failed  | 
              188 | 
                              type  => 'error',  | 
            
            
               | 
               | 
              189 | 
                              code  => 'cannot_enqueue_job',  | 
            
            
              | 190 | 
                              error => $_,  | 
            
            
              | 191 | 
                            };  | 
            
            
              | 192 | 
                          $template->param( view => 'errors' );  | 
            
        
          | 299 | 
                  };  | 
          193 | 
                  };  | 
        
        
          | 300 | 
              }  | 
          194 | 
              }  | 
        
        
          | 301 | 
           | 
          195 | 
           | 
        
            
              | 302 | 
                  $upd_biblionumbers = [ uniq @$upd_biblionumbers ]; # Only update each bib once  | 
               | 
               | 
            
            
              | 303 | 
               | 
            
            
              | 304 | 
                  # Don't send specialUpdate for records we are going to delete  | 
            
            
              | 305 | 
                  my %del_bib_hash = map{ $_ => undef } @$del_biblionumbers; | 
            
            
              | 306 | 
                  @$upd_biblionumbers = grep( ! exists( $del_bib_hash{$_} ), @$upd_biblionumbers ); | 
            
            
              | 307 | 
               | 
            
            
              | 308 | 
                  my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX }); | 
            
            
              | 309 | 
                  $indexer->index_records( $upd_biblionumbers, 'specialUpdate', "biblioserver", undef ) if @$upd_biblionumbers;  | 
            
            
              | 310 | 
                  $indexer->index_records( $del_biblionumbers, 'recordDelete', "biblioserver", undef ) if @$del_biblionumbers;  | 
            
            
              | 311 | 
               | 
            
            
              | 312 | 
                  # Once the job is done  | 
            
            
              | 313 | 
                  # If we have a reasonable amount of items, we display them  | 
            
            
              | 314 | 
                  my $max_items = $del ? C4::Context->preference("MaxItemsToDisplayForBatchDel") : C4::Context->preference("MaxItemsToDisplayForBatchMod"); | 
            
            
              | 315 | 
                  if (scalar(@itemnumbers) <= $max_items ){ | 
            
            
              | 316 | 
                      if (scalar(@itemnumbers) <= 1000 ) { | 
            
            
              | 317 | 
                          $items_display_hashref=BuildItemsData(@itemnumbers);  | 
            
            
              | 318 | 
                      } else { | 
            
            
              | 319 | 
                          # Else, we only display the barcode  | 
            
            
              | 320 | 
                          my @simple_items_display = map { | 
            
            
              | 321 | 
                              my $itemnumber = $_;  | 
            
            
              | 322 | 
                              my $item = Koha::Items->find($itemnumber);  | 
            
            
              | 323 | 
                              { | 
            
            
              | 324 | 
                                  itemnumber   => $itemnumber,  | 
            
            
              | 325 | 
                                  barcode      => $item ? ( $item->barcode // q{} ) : q{}, | 
            
            
              | 326 | 
                                  biblionumber => $item ? $item->biblio->biblionumber : q{}, | 
            
            
              | 327 | 
                              };  | 
            
            
              | 328 | 
                          } @itemnumbers;  | 
            
            
              | 329 | 
                          $template->param("simple_items_display" => \@simple_items_display); | 
            
            
              | 330 | 
                      }  | 
            
            
              | 331 | 
                  } else { | 
            
            
              | 332 | 
                      $template->param( "too_many_items_display" => scalar(@itemnumbers) );  | 
            
            
              | 333 | 
                      $template->param( "job_completed" => 1 );  | 
            
            
              | 334 | 
                  }  | 
            
            
              | 335 | 
               | 
            
            
              | 336 | 
               | 
            
            
              | 337 | 
                  # Calling the template  | 
            
            
              | 338 | 
                  $template->param(  | 
            
            
              | 339 | 
                      modified_items => $modified_items,  | 
            
            
              | 340 | 
                      modified_fields => $modified_fields,  | 
            
            
              | 341 | 
                  );  | 
            
            
              | 342 | 
               | 
            
        
          | 343 | 
          }  | 
          196 | 
          }  | 
        
            
               | 
               | 
              197 | 
               | 
            
            
              | 198 | 
              $template->param(  | 
            
            
              | 199 | 
                  messages => \@messages,  | 
            
            
              | 200 | 
              );  | 
            
        
          | 344 | 
          #  | 
          201 | 
          #  | 
        
        
          | 345 | 
          #-------------------------------------------------------------------------------  | 
          202 | 
          #-------------------------------------------------------------------------------  | 
        
        
          | 346 | 
          # build screen with existing items. and "new" one  | 
          203 | 
          # build screen with existing items. and "new" one  | 
        
  
    | 
      
            Lines 376-385
          if ($op eq "show"){
      
      
        Link Here
      
     | 
  
        
          | 376 | 
                  }  | 
          233 | 
                  }  | 
        
        
          | 377 | 
              } else { | 
          234 | 
              } else { | 
        
        
          | 378 | 
                  if (defined $biblionumber && !@itemnumbers){ | 
          235 | 
                  if (defined $biblionumber && !@itemnumbers){ | 
        
          
            
              | 379 | 
                          my @all_items = GetItemsInfo( $biblionumber );  | 
              236 | 
                          my $biblio = Koha::Biblios->find($biblionumber);  | 
            
            
              | 380 | 
                          foreach my $itm (@all_items) { | 
              237 | 
                          @itemnumbers = $biblio ? $biblio->items->get_column('itemnumber') : (); | 
            
            
              | 381 | 
                              push @itemnumbers, $itm->{itemnumber}; | 
               | 
               | 
            
            
              | 382 | 
                          }  | 
            
        
          | 383 | 
                  }  | 
          238 | 
                  }  | 
        
        
          | 384 | 
                  if ( my $list = $input->param('barcodelist') ) { | 
          239 | 
                  if ( my $list = $input->param('barcodelist') ) { | 
        
        
          | 385 | 
                      my @barcodelist = grep /\S/, ( split /[$split_chars]/, $list );  | 
          240 | 
                      my @barcodelist = grep /\S/, ( split /[$split_chars]/, $list );  | 
        
  
    | 
      
            Lines 399-405
          if ($op eq "show"){
      
      
        Link Here
      
     | 
  
        
          | 399 | 
                  : C4::Context->preference("MaxItemsToDisplayForBatchMod"); | 
          254 | 
                  : C4::Context->preference("MaxItemsToDisplayForBatchMod"); | 
        
        
          | 400 | 
              $template->param("too_many_items_process" => scalar(@itemnumbers)) if !$del && scalar(@itemnumbers) > C4::Context->preference("MaxItemsToProcessForBatchMod"); | 
          255 | 
              $template->param("too_many_items_process" => scalar(@itemnumbers)) if !$del && scalar(@itemnumbers) > C4::Context->preference("MaxItemsToProcessForBatchMod"); | 
        
        
          | 401 | 
              if (scalar(@itemnumbers) <= ( $max_display_items // 1000 ) ) { | 
          256 | 
              if (scalar(@itemnumbers) <= ( $max_display_items // 1000 ) ) { | 
        
          
            
              | 402 | 
                      $items_display_hashref=BuildItemsData(@itemnumbers);  | 
              257 | 
                      $display_items = 1;  | 
            
        
          | 403 | 
              } else { | 
          258 | 
              } else { | 
        
        
          | 404 | 
                  $template->param("too_many_items_display" => scalar(@itemnumbers)); | 
          259 | 
                  $template->param("too_many_items_display" => scalar(@itemnumbers)); | 
        
        
          | 405 | 
                  # Even if we do not display the items, we need the itemnumbers  | 
          260 | 
                  # Even if we do not display the items, we need the itemnumbers  | 
        
  
    | 
      
            Lines 407-416
          if ($op eq "show"){
      
      
        Link Here
      
     | 
  
        
          | 407 | 
              }  | 
          262 | 
              }  | 
        
        
          | 408 | 
           | 
          263 | 
           | 
        
        
          | 409 | 
              # now, build the item form for entering a new item  | 
          264 | 
              # now, build the item form for entering a new item  | 
        
            
              | 410 | 
                  my @loop_data =();  | 
               | 
               | 
            
            
              | 411 | 
                  my $branch_limit = C4::Context->userenv ? C4::Context->userenv->{"branch"} : ""; | 
            
            
              | 412 | 
               | 
            
            
              | 413 | 
                  my $pref_itemcallnumber = C4::Context->preference('itemcallnumber'); | 
            
        
          | 414 | 
           | 
          265 | 
           | 
        
        
          | 415 | 
              # Getting list of subfields to keep when restricted batchmod edit is enabled  | 
          266 | 
              # Getting list of subfields to keep when restricted batchmod edit is enabled  | 
        
        
          | 416 | 
              my @subfields_to_allow = $restrictededition ? split ' ', C4::Context->preference('SubfieldsToAllowForRestrictedBatchmod') : (); | 
          267 | 
              my @subfields_to_allow = $restrictededition ? split ' ', C4::Context->preference('SubfieldsToAllowForRestrictedBatchmod') : (); | 
        
  
    | 
      
            Lines 423-429
          if ($op eq "show"){
      
      
        Link Here
      
     | 
  
        
          | 423 | 
                          ? ( subfields_to_allow => \@subfields_to_allow )  | 
          274 | 
                          ? ( subfields_to_allow => \@subfields_to_allow )  | 
        
        
          | 424 | 
                          : ()  | 
          275 | 
                          : ()  | 
        
        
          | 425 | 
                      ),  | 
          276 | 
                      ),  | 
        
          
            
              | 426 | 
                          subfields_to_ignore         => ['items.barcode'],  | 
              277 | 
                          ignore_not_allowed_subfields => 1,  | 
            
            
               | 
               | 
              278 | 
                          kohafields_to_ignore         => ['items.barcode'],  | 
            
        
          | 427 | 
                      prefill_with_default_values => $use_default_values,  | 
          279 | 
                      prefill_with_default_values => $use_default_values,  | 
        
        
          | 428 | 
                      default_branches_empty      => 1,  | 
          280 | 
                      default_branches_empty      => 1,  | 
        
        
          | 429 | 
                  }  | 
          281 | 
                  }  | 
        
  
    | 
      
            Lines 438-624
          if ($op eq "show"){
      
      
        Link Here
      
     | 
  
        
          | 438 | 
              $nextop="action"  | 
          290 | 
              $nextop="action"  | 
        
        
          | 439 | 
          } # -- End action="show"  | 
          291 | 
          } # -- End action="show"  | 
        
        
          | 440 | 
           | 
          292 | 
           | 
        
          
            
              | 441 | 
              $template->param(%$items_display_hashref) if $items_display_hashref;  | 
              293 | 
              if ( $display_items ) { | 
            
            
              | 442 | 
              $template->param(  | 
              294 | 
                  my $items_table =  | 
            
            
              | 443 | 
                  op      => $nextop,  | 
              295 | 
                    Koha::UI::Table::Builder::Items->new( { itemnumbers => \@itemnumbers } ) | 
            
            
              | 444 | 
              );  | 
              296 | 
                    ->build_table;  | 
            
            
              | 445 | 
              $template->param( $op => 1 ) if $op;  | 
               | 
               | 
            
            
              | 446 | 
               | 
            
            
              | 447 | 
              if ($op eq "action") { | 
            
            
              | 448 | 
               | 
            
            
              | 449 | 
                  #my @not_deleted_loop = map{{itemnumber=>$_}}@not_deleted; | 
            
            
              | 450 | 
               | 
            
        
          | 451 | 
              $template->param(  | 
          297 | 
              $template->param(  | 
        
          
            
              | 452 | 
              	not_deleted_items => $not_deleted_items,  | 
              298 | 
                      items        => $items_table->{items}, | 
            
            
              | 453 | 
              	deleted_items => $deleted_items,  | 
              299 | 
                      item_header_loop => $items_table->{headers}, | 
            
            
              | 454 | 
              	delete_records => $del_records,  | 
               | 
               | 
            
            
              | 455 | 
              	deleted_records => $deleted_records,  | 
            
            
              | 456 | 
              	not_deleted_loop => \@not_deleted   | 
            
        
          | 457 | 
              );  | 
          300 | 
              );  | 
        
        
          | 458 | 
          }  | 
          301 | 
          }  | 
        
        
          | 459 | 
           | 
          302 | 
           | 
        
          
            
              | 460 | 
              foreach my $error (@errors) { | 
              303 | 
              $template->param(  | 
            
            
              | 461 | 
                  $template->param($error => 1) if $error;  | 
              304 | 
                  op  => $nextop,  | 
            
            
              | 462 | 
              }  | 
              305 | 
                  del => $del,  | 
            
            
              | 463 | 
              $template->param(src => $src);  | 
              306 | 
                  ( $op ? ( $op => 1 ) : () ),  | 
            
            
              | 464 | 
              $template->param(biblionumber => $biblionumber);  | 
              307 | 
                  src          => $src,  | 
            
            
              | 465 | 
              output_html_with_http_headers $input, $cookie, $template->output;  | 
              308 | 
                  biblionumber => $biblionumber,  | 
            
            
              | 466 | 
              exit;  | 
              309 | 
              );  | 
            
            
              | 467 | 
               | 
               | 
               | 
            
            
              | 468 | 
               | 
            
            
              | 469 | 
              # ---------------- Functions  | 
            
            
              | 470 | 
               | 
            
            
              | 471 | 
              sub BuildItemsData{ | 
            
            
              | 472 | 
              	my @itemnumbers=@_;  | 
            
            
              | 473 | 
              		# now, build existiing item list  | 
            
            
              | 474 | 
              		my %witness; #---- stores the list of subfields used at least once, with the "meaning" of the code  | 
            
            
              | 475 | 
              		my @big_array;  | 
            
            
              | 476 | 
              		#---- finds where items.itemnumber is stored  | 
            
            
              | 477 | 
                  my (  $itemtagfield,   $itemtagsubfield) = &GetMarcFromKohaField( "items.itemnumber" );  | 
            
            
              | 478 | 
                  my ($branchtagfield, $branchtagsubfield) = &GetMarcFromKohaField( "items.homebranch" );  | 
            
            
              | 479 | 
              		foreach my $itemnumber (@itemnumbers){ | 
            
            
              | 480 | 
                          my $itemdata = Koha::Items->find($itemnumber);  | 
            
            
              | 481 | 
                          next unless $itemdata; # Should have been tested earlier, but just in case...  | 
            
            
              | 482 | 
                          $itemdata = $itemdata->unblessed;  | 
            
            
              | 483 | 
              			my $itemmarc=Item2Marc($itemdata);  | 
            
            
              | 484 | 
              			my %this_row;  | 
            
            
              | 485 | 
              			foreach my $field (grep {$_->tag() eq $itemtagfield} $itemmarc->fields()) { | 
            
            
              | 486 | 
              				# loop through each subfield  | 
            
            
              | 487 | 
              				my $itembranchcode=$field->subfield($branchtagsubfield);  | 
            
            
              | 488 | 
                              if ($itembranchcode && C4::Context->preference("IndependentBranches")) { | 
            
            
              | 489 | 
              						#verifying rights  | 
            
            
              | 490 | 
              						my $userenv = C4::Context->userenv();  | 
            
            
              | 491 | 
                                      unless (C4::Context->IsSuperLibrarian() or (($userenv->{'branch'} eq $itembranchcode))){ | 
            
            
              | 492 | 
              								$this_row{'nomod'}=1; | 
            
            
              | 493 | 
              						}  | 
            
            
              | 494 | 
              				}  | 
            
            
              | 495 | 
              				my $tag=$field->tag();  | 
            
            
              | 496 | 
              				foreach my $subfield ($field->subfields) { | 
            
            
              | 497 | 
              					my ($subfcode,$subfvalue)=@$subfield;  | 
            
            
              | 498 | 
              					next if ($tagslib->{$tag}->{$subfcode}->{tab} ne 10  | 
            
            
              | 499 | 
              							&& $tag        ne $itemtagfield   | 
            
            
              | 500 | 
              							&& $subfcode   ne $itemtagsubfield);  | 
            
            
              | 501 | 
               | 
            
            
              | 502 | 
              					$witness{$subfcode} = $tagslib->{$tag}->{$subfcode}->{lib} if ($tagslib->{$tag}->{$subfcode}->{tab}  eq 10); | 
            
            
              | 503 | 
              					if ($tagslib->{$tag}->{$subfcode}->{tab}  eq 10) { | 
            
            
              | 504 | 
              						$this_row{$subfcode}=GetAuthorisedValueDesc( $tag, | 
            
            
              | 505 | 
              									$subfcode, $subfvalue, '', $tagslib)   | 
            
            
              | 506 | 
              									|| $subfvalue;  | 
            
            
              | 507 | 
              					}  | 
            
            
              | 508 | 
               | 
            
            
              | 509 | 
              					$this_row{itemnumber} = $subfvalue if ($tag eq $itemtagfield && $subfcode eq $itemtagsubfield); | 
            
            
              | 510 | 
              				}  | 
            
            
              | 511 | 
              			}  | 
            
            
              | 512 | 
               | 
            
            
              | 513 | 
                          # grab title, author, and ISBN to identify bib that the item  | 
            
            
              | 514 | 
                          # belongs to in the display  | 
            
            
              | 515 | 
                          my $biblio = Koha::Biblios->find( $itemdata->{biblionumber} ); | 
            
            
              | 516 | 
                          $this_row{title}        = $biblio->title; | 
            
            
              | 517 | 
                          $this_row{author}       = $biblio->author; | 
            
            
              | 518 | 
                          $this_row{isbn}         = $biblio->biblioitem->isbn; | 
            
            
              | 519 | 
                          $this_row{biblionumber} = $biblio->biblionumber; | 
            
            
              | 520 | 
                          $this_row{holds}        = $biblio->holds->count; | 
            
            
              | 521 | 
                          $this_row{item_holds}   = Koha::Holds->search( { itemnumber => $itemnumber } )->count; | 
            
            
              | 522 | 
                          $this_row{item}         = Koha::Items->find($itemnumber); | 
            
            
              | 523 | 
               | 
            
            
              | 524 | 
              			if (%this_row) { | 
            
            
              | 525 | 
              				push(@big_array, \%this_row);  | 
            
            
              | 526 | 
              			}  | 
            
            
              | 527 | 
              		}  | 
            
            
              | 528 | 
              		@big_array = sort {$a->{0} cmp $b->{0}} @big_array; | 
            
            
              | 529 | 
               | 
            
            
              | 530 | 
              		# now, construct template !  | 
            
            
              | 531 | 
              		# First, the existing items for display  | 
            
            
              | 532 | 
              		my @item_value_loop;  | 
            
            
              | 533 | 
              		my @witnesscodessorted=sort keys %witness;  | 
            
            
              | 534 | 
              		for my $row ( @big_array ) { | 
            
            
              | 535 | 
              			my %row_data;  | 
            
            
              | 536 | 
              			my @item_fields = map +{ field => $_ || '' }, @$row{ @witnesscodessorted }; | 
            
            
              | 537 | 
              			$row_data{item_value} = [ @item_fields ]; | 
            
            
              | 538 | 
              			$row_data{itemnumber} = $row->{itemnumber}; | 
            
            
              | 539 | 
              			#reporting this_row values  | 
            
            
              | 540 | 
              			$row_data{'nomod'} = $row->{'nomod'}; | 
            
            
              | 541 | 
                    $row_data{bibinfo} = $row->{bibinfo}; | 
            
            
              | 542 | 
                    $row_data{author} = $row->{author}; | 
            
            
              | 543 | 
                    $row_data{title} = $row->{title}; | 
            
            
              | 544 | 
                    $row_data{isbn} = $row->{isbn}; | 
            
            
              | 545 | 
                    $row_data{biblionumber} = $row->{biblionumber}; | 
            
            
              | 546 | 
                    $row_data{holds}        = $row->{holds}; | 
            
            
              | 547 | 
                    $row_data{item_holds}   = $row->{item_holds}; | 
            
            
              | 548 | 
                    $row_data{item}         = $row->{item}; | 
            
            
              | 549 | 
                    $row_data{safe_to_delete} = $row->{item}->safe_to_delete; | 
            
            
              | 550 | 
                    my $is_on_loan = C4::Circulation::IsItemIssued( $row->{itemnumber} ); | 
            
            
              | 551 | 
                    $row_data{onloan} = $is_on_loan ? 1 : 0; | 
            
            
              | 552 | 
              			push(@item_value_loop,\%row_data);  | 
            
            
              | 553 | 
              		}  | 
            
            
              | 554 | 
              		my @header_loop=map { { header_value=> $witness{$_}} } @witnesscodessorted; | 
            
            
              | 555 | 
               | 
            
            
              | 556 | 
                  my @cannot_be_deleted = map { | 
            
            
              | 557 | 
                      $_->{safe_to_delete} == 1 ? () : $_->{item}->barcode | 
            
            
              | 558 | 
                  } @item_value_loop;  | 
            
            
              | 559 | 
                  return { | 
            
            
              | 560 | 
                      item_loop        => \@item_value_loop,  | 
            
            
              | 561 | 
                      cannot_be_deleted => \@cannot_be_deleted,  | 
            
            
              | 562 | 
                      item_header_loop => \@header_loop  | 
            
            
              | 563 | 
                  };  | 
            
            
              | 564 | 
              }  | 
            
            
              | 565 | 
               | 
            
            
              | 566 | 
              #BE WARN : it is not the general case   | 
            
            
              | 567 | 
              # This function can be OK in the item marc record special case  | 
            
            
              | 568 | 
              # Where subfield is not repeated  | 
            
            
              | 569 | 
              # And where we are sure that field should correspond  | 
            
            
              | 570 | 
              # And $tag>10  | 
            
            
              | 571 | 
              sub UpdateMarcWith { | 
            
            
              | 572 | 
                my ($marcfrom,$marcto)=@_;  | 
            
            
              | 573 | 
                  my (  $itemtag,   $itemtagsubfield) = &GetMarcFromKohaField( "items.itemnumber" );  | 
            
            
              | 574 | 
                  my $fieldfrom=$marcfrom->field($itemtag);  | 
            
            
              | 575 | 
                  my @fields_to=$marcto->field($itemtag);  | 
            
            
              | 576 | 
                  my $modified = 0;  | 
            
            
              | 577 | 
               | 
            
            
              | 578 | 
                  return $modified unless $fieldfrom;  | 
            
            
              | 579 | 
               | 
            
            
              | 580 | 
                  foreach my $subfield ( $fieldfrom->subfields() ) { | 
            
            
              | 581 | 
                      foreach my $field_to_update ( @fields_to ) { | 
            
            
              | 582 | 
                          if ( $subfield->[1] ) { | 
            
            
              | 583 | 
                              unless ( $field_to_update->subfield($subfield->[0]) eq $subfield->[1] ) { | 
            
            
              | 584 | 
                                  $modified++;  | 
            
            
              | 585 | 
                                  $field_to_update->update( $subfield->[0] => $subfield->[1] );  | 
            
            
              | 586 | 
                              }  | 
            
            
              | 587 | 
                          }  | 
            
            
              | 588 | 
                          else { | 
            
            
              | 589 | 
                              $modified++;  | 
            
            
              | 590 | 
                              $field_to_update->delete_subfield( code => $subfield->[0] );  | 
            
            
              | 591 | 
                          }  | 
            
            
              | 592 | 
                      }  | 
            
            
              | 593 | 
                  }  | 
            
            
              | 594 | 
                  return $modified;  | 
            
            
              | 595 | 
              }  | 
            
            
              | 596 | 
               | 
            
            
              | 597 | 
              sub apply_regex { | 
            
            
              | 598 | 
                  my ($params) = @_;  | 
            
            
              | 599 | 
                  my $search   = $params->{search}; | 
            
            
              | 600 | 
                  my $replace  = $params->{replace}; | 
            
            
              | 601 | 
                  my $modifiers = $params->{modifiers} || []; | 
            
            
              | 602 | 
                  my $value = $params->{value}; | 
            
            
              | 603 | 
               | 
            
            
              | 604 | 
                  my @available_modifiers = qw( i g );  | 
            
            
              | 605 | 
                  my $retained_modifiers  = q||;  | 
            
            
              | 606 | 
                  for my $modifier ( split //, @$modifiers ) { | 
            
            
              | 607 | 
                      $retained_modifiers .= $modifier  | 
            
            
              | 608 | 
                        if grep { /$modifier/ } @available_modifiers; | 
            
            
              | 609 | 
                  }  | 
            
            
              | 610 | 
                  if ( $retained_modifiers =~ m/^(ig|gi)$/ ) { | 
            
            
              | 611 | 
                      $value =~ s/$search/$replace/ig;  | 
            
            
              | 612 | 
                  }  | 
            
            
              | 613 | 
                  elsif ( $retained_modifiers eq 'i' ) { | 
            
            
              | 614 | 
                      $value =~ s/$search/$replace/i;  | 
            
            
              | 615 | 
                  }  | 
            
            
              | 616 | 
                  elsif ( $retained_modifiers eq 'g' ) { | 
            
            
              | 617 | 
                      $value =~ s/$search/$replace/g;  | 
            
            
              | 618 | 
                  }  | 
            
            
              | 619 | 
                  else { | 
            
            
              | 620 | 
                      $value =~ s/$search/$replace/;  | 
            
            
              | 621 | 
                  }  | 
            
        
          | 622 | 
           | 
          310 | 
           | 
        
          
            
              | 623 | 
                  return $value;  | 
              311 | 
              output_html_with_http_headers $input, $cookie, $template->output;  | 
            
            
              | 624 | 
              }  | 
               | 
               | 
            
            
              | 625 | 
              -   | 
               | 
               |