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

(-)a/Koha/XSLT_Handler.pm (-23 / +64 lines)
Lines 26-31 Koha::XSLT_Handler - Facilitate use of XSLT transformations Link Here
26
    use Koha::XSLT_Handler;
26
    use Koha::XSLT_Handler;
27
    my $xslt_engine = Koha::XSLT_Handler->new;
27
    my $xslt_engine = Koha::XSLT_Handler->new;
28
    my $output = $xslt_engine->transform($xml, $xsltfilename);
28
    my $output = $xslt_engine->transform($xml, $xsltfilename);
29
    $output = $xslt_engine->transform({ xml => $xml, file => $file });
30
    $output = $xslt_engine->transform({ xml => $xml, code => $code });
29
    my $err= $xslt_engine->err; # error number
31
    my $err= $xslt_engine->err; # error number
30
    my $errstr= $xslt_engine->errstr; # error message
32
    my $errstr= $xslt_engine->errstr; # error message
31
    $xslt_engine->refresh($xsltfilename);
33
    $xslt_engine->refresh($xsltfilename);
Lines 129-134 __PACKAGE__->mk_accessors(qw( do_not_return_source print_warns )); Link Here
129
=head2 transform
131
=head2 transform
130
132
131
    my $output= $xslt_engine->transform( $xml, $xsltfilename );
133
    my $output= $xslt_engine->transform( $xml, $xsltfilename );
134
    #Alternatively:
135
    #$output = $xslt_engine->transform({ xml => $xml, file => $file });
136
    #$output = $xslt_engine->transform({ xml => $xml, code => $code });
132
    if( $xslt_engine->err ) {
137
    if( $xslt_engine->err ) {
133
        #decide what to do on failure..
138
        #decide what to do on failure..
134
    }
139
    }
Lines 136-141 __PACKAGE__->mk_accessors(qw( do_not_return_source print_warns )); Link Here
136
141
137
    Pass a xml string and a fully qualified path of a XSLT file.
142
    Pass a xml string and a fully qualified path of a XSLT file.
138
    Instead of a filename, you may also pass a URL.
143
    Instead of a filename, you may also pass a URL.
144
    You may also pass the contents of a xsl file as a string like $code above.
139
    If you do not pass a filename, the last file used is assumed.
145
    If you do not pass a filename, the last file used is assumed.
140
    Returns the transformed string.
146
    Returns the transformed string.
141
    Check the error number in err to know if something went wrong.
147
    Check the error number in err to know if something went wrong.
Lines 144-182 __PACKAGE__->mk_accessors(qw( do_not_return_source print_warns )); Link Here
144
=cut
150
=cut
145
151
146
sub transform {
152
sub transform {
147
    my ( $self, $orgxml, $file ) = @_;
153
    my $self = shift;
154
155
    #check parameters
156
    #  old style: $xml, $filename
157
    #  new style: $hashref
158
    my ( $xml, $filename, $xsltcode );
159
    if( ref $_[0] eq 'HASH' ) {
160
        $xml = $_[0]->{xml};
161
        $xsltcode = $_[0]->{code};
162
        $filename = $_[0]->{file} if !$xsltcode; #xsltcode gets priority
163
    } else {
164
        ( $xml, $filename ) = @_;
165
    }
148
166
149
    #Initialized yet?
167
    #Initialized yet?
150
    if ( !$self->{xslt_hash} ) {
168
    if ( !$self->{xslt_hash} ) {
151
        $self->_init;
169
        $self->_init;
152
    }
170
    }
153
    else {
171
    else {
154
        $self->_set_error;    #clear error
172
        $self->_set_error;    #clear last error
155
    }
173
    }
156
    my $retval = $self->{do_not_return_source} ? undef : $orgxml;
174
    my $retval = $self->{do_not_return_source} ? undef : $xml;
157
175
158
    #check if no string passed
176
    #check if no string passed
159
    if ( !defined $orgxml ) {
177
    if ( !defined $xml ) {
160
        $self->_set_error(7);
178
        $self->_set_error(7);
161
        return;               #always undef
179
        return;               #always undef
162
    }
180
    }
163
181
164
    #If no file passed, use the last file again
165
    if ( !$file ) {
166
        if ( !$self->{last_xsltfile} ) {
167
            $self->_set_error(1);
168
            return $retval;
169
        }
170
        $file = $self->{last_xsltfile};
171
    }
172
173
    #load stylesheet
182
    #load stylesheet
174
    my $stsh = $self->{xslt_hash}->{$file} // $self->_load($file);
183
    my $key = $self->_load( $filename, $xsltcode );
184
    my $stsh = $key? $self->{xslt_hash}->{$key}: undef;
175
    return $retval if $self->{err};
185
    return $retval if $self->{err};
176
186
177
    #parse input and transform
187
    #parse input and transform
178
    my $parser = XML::LibXML->new();
188
    my $parser = XML::LibXML->new();
179
    my $source = eval { $parser->parse_string($orgxml) };
189
    my $source = eval { $parser->parse_string($xml) };
180
    if ($@) {
190
    if ($@) {
181
        $self->_set_error( 5, $@ );
191
        $self->_set_error( 5, $@ );
182
        return $retval;
192
        return $retval;
Lines 189-195 sub transform { Link Here
189
        $self->_set_error( 6, $@ );
199
        $self->_set_error( 6, $@ );
190
        return $retval;
200
        return $retval;
191
    }
201
    }
192
    $self->{last_xsltfile} = $file;
202
    $self->{last_xsltfile} = $key;
193
    return $str;
203
    return $str;
194
}
204
}
195
205
Lines 246-261 sub _init { Link Here
246
# Internal routine for loading a new stylesheet.
256
# Internal routine for loading a new stylesheet.
247
257
248
sub _load {
258
sub _load {
249
    my ( $self, $file ) = @_;
259
    my ( $self, $filename, $code ) = @_;
260
    my ( $digest, $codelen, $salt, $rv );
261
    $salt = 'AZ'; #just a constant actually
262
263
    #If no file or code passed, use the last file again
264
    if ( !$filename && !$code ) {
265
        my $last = $self->{last_xsltfile};
266
        if ( !$last || !exists $self->{xslt_hash}->{$last} ) {
267
            $self->_set_error(1);
268
            return;
269
        }
270
        return $last;
271
    }
250
272
251
    if ( !$file || ( $file !~ /^https?:\/\// && !-e $file ) ) {
273
    #check if it is loaded already
274
    if( $code ) {
275
        $codelen = length( $code );
276
        $digest = eval { crypt($code, $salt) };
277
        if( $digest && exists $self->{xslt_hash}->{$digest.$codelen} ) {
278
            return $digest.$codelen;
279
        }
280
    } elsif( $filename && exists $self->{xslt_hash}->{$filename} ) {
281
          return $filename;
282
    }
283
284
    #Check file existence (skipping URLs)
285
    if( $filename && $filename !~ /^https?:\/\// && !-e $filename ) {
252
        $self->_set_error(2);
286
        $self->_set_error(2);
253
        return;
287
        return;
254
    }
288
    }
255
289
256
    #load sheet
290
    #load sheet
257
    my $parser = XML::LibXML->new;
291
    my $parser = XML::LibXML->new;
258
    my $style_doc = eval { $parser->load_xml( location => $file ) };
292
    my $style_doc = eval {
293
        $parser->load_xml( $self->_load_xml_args($filename, $code) )
294
    };
259
    if ($@) {
295
    if ($@) {
260
        $self->_set_error( 3, $@ );
296
        $self->_set_error( 3, $@ );
261
        return;
297
        return;
Lines 263-275 sub _load { Link Here
263
299
264
    #parse sheet
300
    #parse sheet
265
    my $xslt = XML::LibXSLT->new;
301
    my $xslt = XML::LibXSLT->new;
266
    $self->{xslt_hash}->{$file} = eval { $xslt->parse_stylesheet($style_doc) };
302
    $rv = $code? $digest.$codelen: $filename;
303
    $self->{xslt_hash}->{$rv} = eval { $xslt->parse_stylesheet($style_doc) };
267
    if ($@) {
304
    if ($@) {
268
        $self->_set_error( 4, $@ );
305
        $self->_set_error( 4, $@ );
269
        delete $self->{xslt_hash}->{$file};
306
        delete $self->{xslt_hash}->{$rv};
270
        return;
307
        return;
271
    }
308
    }
272
    return $self->{xslt_hash}->{$file};
309
    return $rv;
310
}
311
312
sub _load_xml_args {
313
    my $self = shift;
314
    return $_[1]? { 'string' => $_[1]//'' }: { 'location' => $_[0]//'' };
273
}
315
}
274
316
275
# _set_error
317
# _set_error
276
- 

Return to bug 12973