Merge branch '21.11.x-rmaint' into 21.11.x-security
This commit is contained in:
commit
4b94de1036
|
|
@ -1218,14 +1218,8 @@ sub GetMarcBiblio {
|
|||
return;
|
||||
}
|
||||
|
||||
my $dbh = C4::Context->dbh;
|
||||
my $sth = $dbh->prepare("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber=? ");
|
||||
$sth->execute($biblionumber);
|
||||
my $row = $sth->fetchrow_hashref;
|
||||
my $biblioitemnumber = $row->{'biblioitemnumber'};
|
||||
my $marcxml = GetXmlBiblio( $biblionumber );
|
||||
$marcxml = StripNonXmlChars( $marcxml );
|
||||
my $frameworkcode = GetFrameworkCode($biblionumber);
|
||||
MARC::File::XML->default_record_format( C4::Context->preference('marcflavour') );
|
||||
my $record = MARC::Record->new();
|
||||
|
||||
|
|
@ -1237,8 +1231,6 @@ sub GetMarcBiblio {
|
|||
if ($@) { warn " problem with :$biblionumber : $@ \n$marcxml"; }
|
||||
return unless $record;
|
||||
|
||||
C4::Biblio::_koha_marc_update_bib_ids( $record, $frameworkcode, $biblionumber,
|
||||
$biblioitemnumber );
|
||||
C4::Biblio::EmbedItemsInMarcBiblio({
|
||||
marc_record => $record,
|
||||
biblionumber => $biblionumber,
|
||||
|
|
|
|||
2
Koha.pm
2
Koha.pm
|
|
@ -29,7 +29,7 @@ use vars qw{ $VERSION };
|
|||
# - #4 : the developer version. The 4th number is the database subversion.
|
||||
# used by developers when the database changes. updatedatabase take care of the changes itself
|
||||
# and is automatically called by Auth.pm when needed.
|
||||
$VERSION = "21.11.21.000";
|
||||
$VERSION = "21.11.22.000";
|
||||
|
||||
sub version {
|
||||
return $VERSION;
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-v</option>|<option>--verbose</option></term>
|
||||
<listitem>
|
||||
<para>Enable verbose output.</para>
|
||||
</listitem>
|
||||
<term><option>--queue</option></term>
|
||||
<listitem>
|
||||
<para>Allows specifying the queue worker (defaults to 'default').</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-h</option>|<option>--help</option></term>
|
||||
|
|
|
|||
|
|
@ -72,3 +72,5 @@ do
|
|||
[ "$chdir" != "no" ] && cd "$starting_dir"
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use Modern::Perl;
|
|||
|
||||
return {
|
||||
bug_number => undef,
|
||||
description => 'Koha 21.11.12 release',
|
||||
description => 'Koha 21.11.21 release',
|
||||
up => sub {},
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
use Modern::Perl;
|
||||
|
||||
return {
|
||||
bug_number => undef,
|
||||
description => 'Koha 21.11.22 release',
|
||||
up => sub {},
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +72,11 @@
|
|||
<ol>
|
||||
<li>
|
||||
<label for="spec" class="required">setSpec: </label>
|
||||
<input type="text" id="spec" name="spec" value="[% spec | html %]" required="required" class="required" />
|
||||
[% IF ( spec == "" ) %]
|
||||
<input type="text" id="spec" class="focus" name="spec" value="[% spec | html %]" required="required" class="required" />
|
||||
[% ELSE %]
|
||||
<input type="text" id="spec" name="spec" value="[% spec | html %]" required="required" class="required" />
|
||||
[% END %]
|
||||
<span class="required">Required</span>
|
||||
</li>
|
||||
<li>
|
||||
|
|
|
|||
|
|
@ -376,22 +376,22 @@ Patrons:
|
|||
choices:
|
||||
1: Enable
|
||||
0: Disable
|
||||
- "pseudonymization to comply with GDPR for personal information."
|
||||
- "Patrons and transactions will be copied to a separate table for statistics purpose."
|
||||
- "pseudonymization to comply with data privacy policies and regulations like GDPR for managing personal information."
|
||||
- "Patrons and transactions will be copied to a separate table for statistical purposes."
|
||||
- "<br/>Use the following fields for patrons:"
|
||||
- pref: PseudonymizationPatronFields
|
||||
multiple:
|
||||
title: "Patron's title"
|
||||
city: "City"
|
||||
state: "State"
|
||||
zipcode: "Zipcode"
|
||||
zipcode: "ZIP/Postal code"
|
||||
country: "Country"
|
||||
branchcode: "Patron's library"
|
||||
categorycode: "Patron's category"
|
||||
categorycode: "Patron category"
|
||||
dateenrolled: "Date the patron was added to Koha"
|
||||
sex: "Patron's gender"
|
||||
sort1: "Sort1"
|
||||
sort2: "Sort2"
|
||||
sort1: "Sort 1"
|
||||
sort2: "Sort 2"
|
||||
- "<br/> And the following fields for the transactions:"
|
||||
- pref: PseudonymizationTransactionFields
|
||||
multiple:
|
||||
|
|
|
|||
|
|
@ -95,7 +95,12 @@
|
|||
<fieldset class="rows">
|
||||
<ol>
|
||||
<li><label for="name" class="required">Server name: </label>
|
||||
<input type="text" name="servername" id="servername" size="65" maxlength="100" value="[% server.servername | html %]" required="required" /> <span class="required">Required</span>
|
||||
[% IF server.servername %]
|
||||
<input type="text" name="servername" id="servername" size="65" maxlength="100" value="[% server.servername | html %]" required="required" />
|
||||
[% ELSE %]
|
||||
<input type="text" name="servername" id="servername" class="focus" size="65" maxlength="100" value="[% server.servername | html %]" required="required" />
|
||||
[% END %]
|
||||
<span class="required">Required</span>
|
||||
</li>
|
||||
|
||||
<li><label for="host" class="required">Hostname: </label> <input type="text" name="host" id="host" size="30" value="[% server.host | html %]" required="required" /> <span class="required">Required</span>
|
||||
|
|
|
|||
|
|
@ -451,20 +451,6 @@ function PopupMARCFieldDoc(field) {
|
|||
}
|
||||
}
|
||||
|
||||
function PopupMARCFieldDoc(field) {
|
||||
[% IF Koha.Preference('marcfielddocurl') %]
|
||||
var docurl = "[% Koha.Preference('marcfielddocurl').replace('"','"') | html %]";
|
||||
docurl = docurl.replace("{MARC}", "[% marcflavour | html %]");
|
||||
docurl = docurl.replace("{FIELD}", ""+field);
|
||||
docurl = docurl.replace("{LANG}", "[% lang | html %]");
|
||||
window.open(docurl);
|
||||
[% ELSIF ( marcflavour == 'MARC21' ) %]
|
||||
_MARC21FieldDoc(field);
|
||||
[% ELSIF ( marcflavour == 'UNIMARC' ) %]
|
||||
_UNIMARCFieldDoc(field);
|
||||
[% END %]
|
||||
}
|
||||
|
||||
function _MARC21FieldDoc(field) {
|
||||
if(field == 0) {
|
||||
window.open("http://www.loc.gov/marc/bibliographic/bdleader.html");
|
||||
|
|
|
|||
|
|
@ -1462,7 +1462,7 @@
|
|||
var value = parseInt($(this).val());
|
||||
var found_holds = $("select[name='rank-request'][disabled='disabled']").length ; //Count how many are found
|
||||
if( !isNaN(value) ) { //If moved to 'del'
|
||||
var after = row.parent().find("tr:nth-child("+(value+1+found_holds )+")"); //Go to the row 1 after the new value (and skip found holds)
|
||||
var after = row.parent().find(`tr:nth-child(${value+found_holds})`); //Go to the row 1 after the new value (and skip found holds)
|
||||
if (prev_rank_request > value) {
|
||||
row.insertBefore(after);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -395,14 +395,13 @@
|
|||
</table>
|
||||
[% ELSE %]
|
||||
<div class="dialog alert">
|
||||
No log found
|
||||
[% IF ( CATALOGUING ) %]
|
||||
for <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% object | url %]">Bibliographic record [% object | html %]</a>
|
||||
No log found for <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% object | url %]">Bibliographic record [% object | html %]</a>.
|
||||
[% ELSIF ( MEMBERS ) %]
|
||||
No log found for <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% object | url %]">[% INCLUDE 'patron-title.inc' %]</a>.
|
||||
[% ELSE %]
|
||||
No log found.
|
||||
[% END %]
|
||||
[% IF ( MEMBERS ) %]
|
||||
for <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% object | url %]">[% INCLUDE 'patron-title.inc' %]</a>
|
||||
[% END %]
|
||||
.
|
||||
</div>
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
|
|
|||
|
|
@ -450,6 +450,9 @@
|
|||
[% BLOCK jsinclude %]
|
||||
[% Asset.js("lib/jquery/plugins/jquery.deserialize.min.js") | $raw %]
|
||||
<script>
|
||||
window.addEventListener('pageshow', function( e ){
|
||||
$('.form-control').prop('disabled' , false );
|
||||
});
|
||||
$(document).ready(function() {
|
||||
[% IF search_groups %]
|
||||
function branch_limit() {
|
||||
|
|
@ -548,6 +551,5 @@ $(document).ready(function() {
|
|||
$(this).parent().parent().remove();
|
||||
$('.search-term-row .search-term-input select[name="op"]').first().prop("disabled",true).hide();
|
||||
});
|
||||
|
||||
</script>
|
||||
[% END %]
|
||||
|
|
|
|||
|
|
@ -1310,11 +1310,7 @@
|
|||
<xsl:call-template name="listCallNumbers">
|
||||
<xsl:with-param name="items" select="$reference_items[items:resultbranch=$currentbranch and items:substatus=$current_substatus]"/>
|
||||
<xsl:with-param name="max" select="$OPACResultsMaxItems"/>
|
||||
<xsl:with-param name="status_text">
|
||||
<xsl:value-of select="concat($currentbranch,': ')"/>
|
||||
<xsl:value-of select="exsl:node-set($item_status_list)/status[@english=$current_substatus]|$current_substatus"/>
|
||||
<!-- Note that value-of here picks string value of first node only from the union; keep in mind too that current_substatus may contain an authorised value -->
|
||||
</xsl:with-param>
|
||||
<xsl:with-param name="status_text" select="concat($currentbranch,': ',$current_substatus)"/>
|
||||
<xsl:with-param name="class_block" select="concat('notforloandesc_',$current_substatus)"/>
|
||||
<xsl:with-param name="class_status" select="'ItemBranch'"/>
|
||||
<xsl:with-param name="OPACItemLocation" select="$OPACItemLocation"/>
|
||||
|
|
@ -1335,7 +1331,6 @@
|
|||
<status english="Pending hold">Pending hold</status>
|
||||
<status english="In transit">In transit</status>
|
||||
<status english="Waiting">On hold</status>
|
||||
<status english="Not for loan">Not for loan</status>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="unavailable_items" select="key('item-by-status', 'reallynotforloan')|key('item-by-status', 'other')"/>
|
||||
<xsl:choose>
|
||||
|
|
@ -1355,7 +1350,12 @@
|
|||
<xsl:with-param name="status_text">
|
||||
<xsl:value-of select="$currentbranch"/>
|
||||
<xsl:text>: </xsl:text>
|
||||
<xsl:value-of select="exsl:node-set($item_status_list)/status[@english=$current_substatus]|$current_substatus"/><!-- See former comment on value-of and union -->
|
||||
<xsl:if test="items:status='other'">
|
||||
<xsl:value-of select="exsl:node-set($other_status_list)/status[@english=$current_substatus]"/>
|
||||
</xsl:if>
|
||||
<xsl:if test="items:status='reallynotforloan'">
|
||||
<xsl:value-of select="$current_substatus"/>
|
||||
</xsl:if>
|
||||
</xsl:with-param>
|
||||
<xsl:with-param name="class_block" select="concat('unavailable_',items:substatus)"/>
|
||||
<xsl:with-param name="class_status" select="'ItemBranch'"/>
|
||||
|
|
@ -1374,7 +1374,12 @@
|
|||
<xsl:with-param name="items" select="$unavailable_items[items:substatus=$current_substatus]"/>
|
||||
<xsl:with-param name="max" select="0"/>
|
||||
<xsl:with-param name="status_text">
|
||||
<xsl:value-of select="exsl:node-set($item_status_list)/status[@english=$current_substatus]|$current_substatus"/><!-- See former comment on value-of and union -->
|
||||
<xsl:if test="items:status='other'">
|
||||
<xsl:value-of select="exsl:node-set($other_status_list)/status[@english=$current_substatus]"/>
|
||||
</xsl:if>
|
||||
<xsl:if test="items:status='reallynotforloan'">
|
||||
<xsl:value-of select="$current_substatus"/>
|
||||
</xsl:if>
|
||||
</xsl:with-param>
|
||||
<xsl:with-param name="class_block" select="concat('unavailable_',$current_substatus)"/>
|
||||
<xsl:with-param name="class_status" select="UnavailableSubstatus"/>
|
||||
|
|
|
|||
|
|
@ -118,8 +118,10 @@ use C4::Biblio qw( GetMarcFromKohaField );
|
|||
}
|
||||
}
|
||||
|
||||
my @decoding_errors;
|
||||
my ( @decoding_errors, @ids_not_in_marc );
|
||||
my $biblios = Koha::Biblios->search;
|
||||
my ( $biblio_tag, $biblio_subfield ) = C4::Biblio::GetMarcFromKohaField( "biblio.biblionumber" );
|
||||
my ( $biblioitem_tag, $biblioitem_subfield ) = C4::Biblio::GetMarcFromKohaField( "biblioitems.biblioitemnumber" );
|
||||
while ( my $biblio = $biblios->next ) {
|
||||
my $record = eval{$biblio->metadata->record;};
|
||||
if ($@) {
|
||||
|
|
@ -160,6 +162,33 @@ use C4::Biblio qw( GetMarcFromKohaField );
|
|||
new_item($_) for @decoding_errors;
|
||||
new_hint("The bibliographic records must have a valid MARCXML or you will face encoding issues or wrong displays");
|
||||
}
|
||||
if (@ids_not_in_marc) {
|
||||
new_section("Bibliographic records have MARCXML without biblionumber or biblioitemnumber");
|
||||
for my $id (@ids_not_in_marc) {
|
||||
if ( exists $id->{biblioitemnumber} ) {
|
||||
new_item(
|
||||
sprintf(q{Biblionumber %s has biblioitemnumber '%s' but should be '%s' in %s$%s},
|
||||
$id->{biblionumber},
|
||||
$id->{biblioitemnumber},
|
||||
$id->{biblioitemnumber_in_marc},
|
||||
$biblioitem_tag,
|
||||
$biblioitem_subfield,
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
new_item(
|
||||
sprintf(q{Biblionumber %s has '%s' in %s$%s},
|
||||
$id->{biblionumber},
|
||||
$id->{biblionumber_in_marc},
|
||||
$biblio_tag,
|
||||
$biblio_subfield,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
new_hint("The bibliographic records must have the biblionumber and biblioitemnumber in MARCXML");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -420,8 +420,6 @@ sub run_tests {
|
|||
|
||||
is( GetMarcPrice( $record_for_isbn, $marcflavour ), 100,
|
||||
"GetMarcPrice returns the correct value");
|
||||
my $newincbiblioitemnumber=$biblioitemnumber+1;
|
||||
$dbh->do("UPDATE biblioitems SET biblioitemnumber = ? WHERE biblionumber = ?;", undef, $newincbiblioitemnumber, $biblionumber );
|
||||
my $updatedrecord = GetMarcBiblio({
|
||||
biblionumber => $biblionumber,
|
||||
embed_items => 0 });
|
||||
|
|
@ -434,7 +432,6 @@ sub run_tests {
|
|||
} else {
|
||||
$biblioitemnumbertotest = $updatedrecord->field($biblioitem_tag)->subfield($biblioitem_subfield);
|
||||
}
|
||||
is ($newincbiblioitemnumber, $biblioitemnumbertotest, 'Check newincbiblioitemnumber');
|
||||
|
||||
# test for GetMarcUrls
|
||||
$marc_record->append_fields(
|
||||
|
|
@ -597,14 +594,14 @@ sub create_author_field {
|
|||
}
|
||||
|
||||
subtest 'MARC21' => sub {
|
||||
plan tests => 47;
|
||||
plan tests => 46;
|
||||
run_tests('MARC21');
|
||||
$schema->storage->txn_rollback;
|
||||
$schema->storage->txn_begin;
|
||||
};
|
||||
|
||||
subtest 'UNIMARC' => sub {
|
||||
plan tests => 47;
|
||||
plan tests => 46;
|
||||
|
||||
# Mock the auth type data for UNIMARC
|
||||
$dbh->do("UPDATE auth_types SET auth_tag_to_report = '106' WHERE auth_tag_to_report = '100'") or die $dbh->errstr;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# Copyright 2021 Koha development team
|
||||
#
|
||||
# This file is part of Koha.
|
||||
#
|
||||
# Koha is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Koha is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
use Test::More tests => 1;
|
||||
use File::Find;
|
||||
use File::Slurp;
|
||||
use Data::Dumper;
|
||||
|
||||
my @themes;
|
||||
|
||||
# OPAC themes
|
||||
my $opac_dir = 'koha-tmpl/opac-tmpl';
|
||||
opendir ( my $dh, $opac_dir ) or die "can't opendir $opac_dir: $!";
|
||||
for my $theme ( grep { not /^\.|lib|js|xslt/ } readdir($dh) ) {
|
||||
push @themes, "$opac_dir/$theme/en";
|
||||
}
|
||||
close $dh;
|
||||
|
||||
# STAFF themes
|
||||
my $staff_dir = 'koha-tmpl/intranet-tmpl';
|
||||
opendir ( $dh, $staff_dir ) or die "can't opendir $staff_dir: $!";
|
||||
for my $theme ( grep { not /^\.|lib|js/ } readdir($dh) ) {
|
||||
push @themes, "$staff_dir/$theme/en";
|
||||
}
|
||||
close $dh;
|
||||
|
||||
my @files;
|
||||
sub wanted {
|
||||
my $name = $File::Find::name;
|
||||
push @files, $name
|
||||
if $name =~ m[\.(tt|inc)$] and -f $name;
|
||||
}
|
||||
|
||||
find({ wanted => \&wanted, no_chdir => 1 }, @themes );
|
||||
|
||||
my @errors;
|
||||
for my $file ( @files ) {
|
||||
my @e = check_csrf_in_forms($file);
|
||||
push @errors, { file => $file, errors => \@e } if @e;
|
||||
}
|
||||
|
||||
is( @errors, 0, "Template variables should be correctly escaped" )
|
||||
or diag(Dumper @errors);
|
||||
|
||||
sub check_csrf_in_forms {
|
||||
my ( $file ) = @_;
|
||||
|
||||
my @lines = read_file($file);
|
||||
my @errors;
|
||||
return @errors unless grep { $_ =~ m|<form| } @lines;
|
||||
my ( $open, $found ) = ( 0, 0 );
|
||||
my $line = 0 ;
|
||||
for my $l (@lines) {
|
||||
$line++;
|
||||
$open = $line if ( $l =~ m{<form} && !( $l =~ m{method=('|")get('|")} ) );
|
||||
$found++ if ( $l =~ m|csrf\-token\.inc| && $open );
|
||||
if ( $open && $l =~ m|</form| ) {
|
||||
push @errors,
|
||||
"The <form> starting on line $open is missing it's corresponding csrf_token include (see bug 22990)"
|
||||
if !$found;
|
||||
$found = 0;
|
||||
}
|
||||
}
|
||||
return @errors;
|
||||
}
|
||||
Loading…
Reference in New Issue