Bugzilla – Attachment 50715 Details for
Bug 15562
Make Koha more suitable for shared hosting with plack
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
[SIGNED-OFF] bug_15562: Multi-host helper for plack installations
SIGNED-OFF-bug15562-Multi-host-helper-for-plack-in.patch (text/plain), 47.95 KB, created by
Kyle M Hall (khall)
on 2016-04-26 11:22:23 UTC
(
hide
)
Description:
[SIGNED-OFF] bug_15562: Multi-host helper for plack installations
Filename:
MIME Type:
Creator:
Kyle M Hall (khall)
Created:
2016-04-26 11:22:23 UTC
Size:
47.95 KB
patch
obsolete
>From f483fc9152ea1bd5036296b03fecc6b88ec7c235 Mon Sep 17 00:00:00 2001 >From: Srdjan <srdjan@catalyst.net.nz> >Date: Mon, 28 Jul 2014 15:17:09 +1200 >Subject: [PATCH] [SIGNED-OFF] bug_15562: Multi-host helper for plack > installations > >Sort of an apocalypse >* C4::Context->new() must be called with at least config file param. > If you want current context, call C4::Context->current(). > C4::Context->some_method() will still work as is. >* Koha::Database->new_schema() now takes optional context param. >* C4::Context->set_context() and restore_context() are synched with > database set_schema() and restore_schema(). > Created run_within_context() that wraps set_context() and > restore_context() around code. >* Created Koha::Handler::Plack* to facilitate running same code within > different (database) contexts. >* This initial version does not run with memcached turned on. Next patch > will correct that. > >https://bugs.koha-community.org/show_bug.cgi?id=15562 > >Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com> >--- > C4/Auth_with_cas.pm | 2 +- > C4/Auth_with_ldap.pm | 2 +- > C4/Context.pm | 352 ++++++++++++++--------------- > Koha/Cache.pm | 14 +- > Koha/Database.pm | 38 +++- > Koha/Handler/Plack.pm | 163 +++++++++++++ > Koha/Handler/Plack/CGI.pm | 228 +++++++++++++++++++ > about.pl | 2 +- > admin/systempreferences.pl | 2 +- > misc/cronjobs/check-url.pl | 2 +- > misc/plack/koha-multi.psgi | 29 +++ > misc/translator/LangInstaller.pm | 4 +- > t/Koha_Handler_Plack.t | 136 +++++++++++ > t/conf/dummy/koha-conf.xml | 7 + > t/conf/koha1/koha-conf.xml | 7 + > t/conf/koha2/koha-conf.xml | 5 + > t/db_dependent/Amazon.t | 2 +- > t/db_dependent/Context.t | 2 +- > t/db_dependent/Template/Plugin/KohaDates.t | 2 +- > t/db_dependent/XISBN.t | 2 +- > t/db_dependent/sysprefs.t | 13 +- > 21 files changed, 802 insertions(+), 212 deletions(-) > create mode 100644 Koha/Handler/Plack.pm > create mode 100644 Koha/Handler/Plack/CGI.pm > create mode 100644 misc/plack/koha-multi.psgi > create mode 100644 t/Koha_Handler_Plack.t > create mode 100644 t/conf/dummy/koha-conf.xml > create mode 100644 t/conf/koha1/koha-conf.xml > create mode 100644 t/conf/koha2/koha-conf.xml > >diff --git a/C4/Auth_with_cas.pm b/C4/Auth_with_cas.pm >index c9174da..f78e3b5 100644 >--- a/C4/Auth_with_cas.pm >+++ b/C4/Auth_with_cas.pm >@@ -36,7 +36,7 @@ BEGIN { > @ISA = qw(Exporter); > @EXPORT = qw(check_api_auth_cas checkpw_cas login_cas logout_cas login_cas_url); > } >-my $context = C4::Context->new() or die 'C4::Context->new failed'; >+my $context = C4::Context->current() or die 'No current context'; > my $defaultcasserver; > my $casservers; > my $yamlauthfile = C4::Context->config('intranetdir') . "/C4/Auth_cas_servers.yaml"; >diff --git a/C4/Auth_with_ldap.pm b/C4/Auth_with_ldap.pm >index c50df76..0f7a174 100644 >--- a/C4/Auth_with_ldap.pm >+++ b/C4/Auth_with_ldap.pm >@@ -53,7 +53,7 @@ sub ldapserver_error { > } > > use vars qw($mapping @ldaphosts $base $ldapname $ldappassword); >-my $context = C4::Context->new() or die 'C4::Context->new failed'; >+my $context = C4::Context->current() or die 'No current context'; > my $ldap = C4::Context->config("ldapserver") or die 'No "ldapserver" in server hash from KOHA_CONF: ' . $ENV{KOHA_CONF}; > my $prefhost = $ldap->{hostname} or die ldapserver_error('hostname'); > my $base = $ldap->{base} or die ldapserver_error('base'); >diff --git a/C4/Context.pm b/C4/Context.pm >index c80647a..63a71d6 100644 >--- a/C4/Context.pm >+++ b/C4/Context.pm >@@ -31,7 +31,7 @@ BEGIN { > eval {C4::Context->dbh();}; > if ($@){ > $debug_level = 1; >- } >+ } > else { > $debug_level = C4::Context->preference("DebugLevel"); > } >@@ -49,7 +49,7 @@ BEGIN { > # a little example table with various version info"; > print " > <h1>Koha error</h1> >- <p>The following fatal error has occurred:</p> >+ <p>The following fatal error has occurred:</p> > <pre><code>$msg</code></pre> > <table> > <tr><th>Apache</th><td> $versions{apacheVersion}</td></tr> >@@ -63,11 +63,11 @@ BEGIN { > } elsif ($debug_level eq "1"){ > print " > <h1>Koha error</h1> >- <p>The following fatal error has occurred:</p> >+ <p>The following fatal error has occurred:</p> > <pre><code>$msg</code></pre>"; > } else { > print "<p>production mode - trapped fatal error</p>"; >- } >+ } > print "</body></html>"; > } > #CGI::Carp::set_message(\&handle_errors); >@@ -112,6 +112,7 @@ use Koha::Cache; > use POSIX (); > use DateTime::TimeZone; > use Module::Load::Conditional qw(can_load); >+use Data::Dumper; > use Carp; > > use C4::Boolean; >@@ -179,10 +180,6 @@ environment variable to the pathname of a configuration file to use. > # file (/etc/koha/koha-conf.xml). > # dbh > # A handle to the appropriate database for this context. >-# dbh_stack >-# Used by &set_dbh and &restore_dbh to hold other database >-# handles for this context. >-# Zconn > # A connection object for the Zebra server > > # Koha's main configuration file koha-conf.xml >@@ -191,7 +188,7 @@ environment variable to the pathname of a configuration file to use. > # 1. Path supplied via use C4::Context '/path/to/koha-conf.xml' > # 2. Path supplied in KOHA_CONF environment variable. > # 3. Path supplied in INSTALLED_CONFIG_FNAME, as long >-# as value has changed from its default of >+# as value has changed from its default of > # '__KOHA_CONF_DIR__/koha-conf.xml', as happens > # when Koha is installed in 'standard' or 'single' > # mode. >@@ -201,52 +198,25 @@ environment variable to the pathname of a configuration file to use. > > use constant CONFIG_FNAME => "/etc/koha/koha-conf.xml"; > # Default config file, if none is specified >- >+ > my $INSTALLED_CONFIG_FNAME = '__KOHA_CONF_DIR__/koha-conf.xml'; > # path to config file set by installer > # __KOHA_CONF_DIR__ is set by rewrite-confg.PL > # when Koha is installed in 'standard' or 'single' >- # mode. If Koha was installed in 'dev' mode, >+ # mode. If Koha was installed in 'dev' mode, > # __KOHA_CONF_DIR__ is *not* rewritten; instead >- # developers should set the KOHA_CONF environment variable >- >-$context = undef; # Initially, no context is set >-@context_stack = (); # Initially, no saved contexts >- >- >-=head2 read_config_file >- >-Reads the specified Koha config file. >- >-Returns an object containing the configuration variables. The object's >-structure is a bit complex to the uninitiated ... take a look at the >-koha-conf.xml file as well as the XML::Simple documentation for details. Or, >-here are a few examples that may give you what you need: >+ # developers should set the KOHA_CONF environment variable > >-The simple elements nested within the <config> element: >+@context_stack = (); # Initially, no saved contexts > >- my $pass = $koha->{'config'}->{'pass'}; >+=head2 current > >-The <listen> elements: >- >- my $listen = $koha->{'listen'}->{'biblioserver'}->{'content'}; >- >-The elements nested within the <server> element: >- >- my $ccl2rpn = $koha->{'server'}->{'biblioserver'}->{'cql2rpn'}; >- >-Returns undef in case of error. >+Returns the current context > > =cut > >-sub read_config_file { # Pass argument naming config file to read >- my $koha = XMLin(shift, keyattr => ['id'], forcearray => ['listen', 'server', 'serverinfo'], suppressempty => ''); >- >- if ($ismemcached) { >- $memcached->set('kohaconf',$koha); >- } >- >- return $koha; # Return value: ref-to-hash holding the configuration >+sub current { >+ return $context; > } > > =head2 ismemcached >@@ -274,6 +244,15 @@ sub memcached { > } > } > >+sub db_driver { >+ my $self = shift; >+ >+ $self = $context unless ref ($self); >+ return unless $self; >+ >+ return $self->{db_driver}; >+} >+ > =head2 db_scheme2dbi > > my $dbd_driver_name = C4::Context::db_schema2dbi($scheme); >@@ -294,32 +273,85 @@ sub import { > # Create the default context ($C4::Context::Context) > # the first time the module is called > # (a config file can be optionaly passed) >+ # If ":no_config" is passed, no config load will be attempted >+ # Config file defaults to either the file given by the $KOHA_CONF >+ # environment variable, or /etc/koha/koha-conf.xml. >+ # It saves the context values in the declared memcached server(s) >+ # if currently available and uses those values until them expire and >+ # re-reads them. >+ >+ my ($pkg,$config_file) = @_ ; > > # default context already exists? > return if $context; > >+ if ($ismemcached) { >+ # retrieve from memcached >+ if (my $self = $memcached->get('kohaconf')) { >+ $context = $self; >+ return; >+ } >+ } >+ >+ # check that the specified config file exists and is not empty >+ undef $config_file if defined $config_file && >+ !( ref($config_file) || openhandle($config_file) || -s $config_file ); >+ # Figure out a good config file to load if none was specified. >+ if (!defined($config_file)) >+ { >+ # If the $KOHA_CONF environment variable is set, use >+ # that. Otherwise, use the built-in default. >+ if ($ENV{'KOHA_CONF'} and ref($ENV{'KOHA_CONF'}) || -s $ENV{"KOHA_CONF"}) { >+ $config_file = $ENV{"KOHA_CONF"}; >+ } elsif ($INSTALLED_CONFIG_FNAME !~ /__KOHA_CONF_DIR/ and -s $INSTALLED_CONFIG_FNAME) { >+ # NOTE: be careful -- don't change __KOHA_CONF_DIR in the above >+ # regex to anything else -- don't want installer to rewrite it >+ $config_file = $INSTALLED_CONFIG_FNAME; >+ } elsif (-s CONFIG_FNAME) { >+ $config_file = CONFIG_FNAME; >+ } else { >+ die "unable to locate Koha configuration file koha-conf.xml"; >+ } >+ } >+ > # no ? so load it! >- my ($pkg,$config_file) = @_ ; >+ return if $config_file && $config_file eq ":no_config"; > my $new_ctx = __PACKAGE__->new($config_file); > return unless $new_ctx; > > # if successfully loaded, use it by default >- $new_ctx->set_context; >- 1; >+ $context = $new_ctx; >+ >+ if ($ismemcached) { >+ $memcached->set('kohaconf',$new_ctx); >+ } > } > >+use Scalar::Util qw(openhandle); > =head2 new > >- $context = new C4::Context; > $context = new C4::Context("/path/to/koha-conf.xml"); > > Allocates a new context. Initializes the context from the specified >-file, which defaults to either the file given by the C<$KOHA_CONF> >-environment variable, or F</etc/koha/koha-conf.xml>. >+file. > >-It saves the koha-conf.xml values in the declared memcached server(s) >-if currently available and uses those values until them expire and >-re-reads them. >+XML structure is a bit complex to the uninitiated ... take a look at the >+koha-conf.xml file as well as the XML::Simple documentation for details. Or, >+here are a few examples that may give you what you need: >+ >+The simple elements nested within the <config> element: >+ >+ my $pass = $koha->{'config'}->{'pass'}; >+ >+The <listen> elements: >+ >+ my $listen = $koha->{'listen'}->{'biblioserver'}->{'content'}; >+ >+The elements nested within the <server> element: >+ >+ my $ccl2rpn = $koha->{'server'}->{'biblioserver'}->{'cql2rpn'}; >+ >+Returns undef in case of error. > > C<&new> does not set this context as the new default context; for > that, use C<&set_context>. >@@ -331,46 +363,22 @@ that, use C<&set_context>. > # 2004-08-10 A. Tarallo: Added check if the conf file is not empty > sub new { > my $class = shift; >- my $conf_fname = shift; # Config file to load >- my $self = {}; >- >- # check that the specified config file exists and is not empty >- undef $conf_fname unless >- (defined $conf_fname && -s $conf_fname); >- # Figure out a good config file to load if none was specified. >- if (!defined($conf_fname)) >- { >- # If the $KOHA_CONF environment variable is set, use >- # that. Otherwise, use the built-in default. >- if (exists $ENV{"KOHA_CONF"} and $ENV{'KOHA_CONF'} and -s $ENV{"KOHA_CONF"}) { >- $conf_fname = $ENV{"KOHA_CONF"}; >- } elsif ($INSTALLED_CONFIG_FNAME !~ /__KOHA_CONF_DIR/ and -s $INSTALLED_CONFIG_FNAME) { >- # NOTE: be careful -- don't change __KOHA_CONF_DIR in the above >- # regex to anything else -- don't want installer to rewrite it >- $conf_fname = $INSTALLED_CONFIG_FNAME; >- } elsif (-s CONFIG_FNAME) { >- $conf_fname = CONFIG_FNAME; >- } else { >- warn "unable to locate Koha configuration file koha-conf.xml"; >- return; >- } >- } >- >- if ($ismemcached) { >- # retrieve from memcached >- $self = $memcached->get('kohaconf'); >- if (not defined $self) { >- # not in memcached yet >- $self = read_config_file($conf_fname); >- } >- } else { >- # non-memcached env, read from file >- $self = read_config_file($conf_fname); >- } >- >- $self->{"config_file"} = $conf_fname; >- warn "read_config_file($conf_fname) returned undef" if !defined($self->{"config"}); >- return if !defined($self->{"config"}); >+ my $conf_fname = shift or croak "No conf"; >+ my $namespace = shift; >+ >+ my $self = XMLin( >+ $conf_fname, >+ keyattr => ['id'], >+ forcearray => ['listen', 'server', 'serverinfo'], >+ suppressempty => '', >+ ); >+ die "Invalid config ".(ref($conf_fname) ? $$conf_fname : $conf_fname).": ".Dumper($self) >+ unless ref($self) && $self->{"config"}; >+ >+ $self->{config_file} = $conf_fname; >+ $self->{namespace} = $namespace; >+ $self->{use_syspref_cache} = 1; >+ $self->{syspref_cache} = Koha::Cache->new({namespace => $namespace}); > > $self->{"Zconn"} = undef; # Zebra Connections > $self->{"marcfromkohafield"} = undef; # the hash with relations between koha table fields and MARC field/subfield >@@ -386,7 +394,6 @@ sub new { > > =head2 set_context > >- $context = new C4::Context; > $context->set_context(); > or > set_context C4::Context $context; >@@ -419,17 +426,21 @@ sub set_context > if (ref($self) eq "") > { > # Class method. The new context is the next argument. >- $new_context = shift; >+ $new_context = shift or croak "No new context"; > } else { > # Instance method. The new context is $self. > $new_context = $self; > } > >- # Save the old context, if any, on the stack >- push @context_stack, $context if defined($context); >+ # undef $new_context->{schema} if $new_context->{schema} && !$new_context->{schema}->ping >+ my $schema = $new_context->{schema} ||= Koha::Database->new_schema($new_context); >+ >+ # Save the old context on the stack >+ push @context_stack, $context; > > # Set the new context > $context = $new_context; >+ Koha::Database->set_schema($schema); > } > > =head2 restore_context >@@ -445,19 +456,38 @@ sub restore_context > { > my $self = shift; > >- if ($#context_stack < 0) >- { >- # Stack underflow. >- die "Context stack underflow"; >- } >- > # Pop the old context and set it. > $context = pop @context_stack; >+ Koha::Database->restore_schema(); > > # FIXME - Should this return something, like maybe the context > # that was current when this was called? > } > >+=head2 run_within_context >+ >+ $context->run_within_context(sub {...}); >+ >+Runs code within context >+ >+=cut >+ >+#' >+sub run_within_context >+{ >+ my $self = shift; >+ my $code = shift or croak "No code"; >+ >+ $self->set_context; >+ >+ local $@; >+ my $ret = eval { $code->(@_) }; >+ my $died = $@; >+ $self->restore_context; >+ die $died if $died; >+ return $ret; >+} >+ > =head2 config > > $value = C4::Context->config("config_variable"); >@@ -474,26 +504,32 @@ C<C4::Config-E<gt>new> will not return it. > =cut > > sub _common_config { >- my $var = shift; >- my $term = shift; >- return if !defined($context->{$term}); >+ my $self = shift; >+ my $var = shift; >+ my $term = shift; >+ >+ $self = $context unless ref $self; >+ return if !defined($self->{$term}); > # Presumably $self->{$term} might be > # undefined if the config file given to &new > # didn't exist, and the caller didn't bother > # to check the return value. > > # Return the value of the requested config variable >- return $context->{$term}->{$var}; >+ return $self->{$term}->{$var}; > } > > sub config { >- return _common_config($_[1],'config'); >+ my $self = shift; >+ return $self->_common_config($_[0],'config'); > } > sub zebraconfig { >- return _common_config($_[1],'server'); >+ my $self = shift; >+ return $self->_common_config($_[0],'server'); > } > sub ModZebrations { >- return _common_config($_[1],'serverinfo'); >+ my $self = shift; >+ return $self->_common_config($_[0],'serverinfo'); > } > > =head2 preference >@@ -512,10 +548,9 @@ with this method. > > =cut > >-my $syspref_cache = Koha::Cache->get_instance(); >-my $use_syspref_cache = 1; > sub preference { > my $self = shift; >+ $self = $context unless ref $self; > my $var = shift; # The system preference to return > > $var = lc $var; >@@ -523,8 +558,8 @@ sub preference { > return $ENV{"OVERRIDE_SYSPREF_$var"} > if defined $ENV{"OVERRIDE_SYSPREF_$var"}; > >- my $cached_var = $use_syspref_cache >- ? $syspref_cache->get_from_cache("syspref_$var") >+ my $cached_var = $self->{use_syspref_cache} >+ ? $self->{syspref_cache}->get_from_cache("syspref_$var") > : undef; > return $cached_var if defined $cached_var; > >@@ -532,8 +567,8 @@ sub preference { > eval { $syspref = Koha::Config::SysPrefs->find( lc $var ) }; > my $value = $syspref ? $syspref->value() : undef; > >- if ( $use_syspref_cache ) { >- $syspref_cache->set_in_cache("syspref_$var", $value); >+ if ( $self->{use_syspref_cache} ) { >+ $self->{syspref_cache}->set_in_cache("syspref_$var", $value); > } > return $value; > } >@@ -556,7 +591,8 @@ default behavior. > > sub enable_syspref_cache { > my ($self) = @_; >- $use_syspref_cache = 1; >+ $self = $context unless ref $self; >+ $self->{use_syspref_cache} = 1; > # We need to clear the cache to have it up-to-date > $self->clear_syspref_cache(); > } >@@ -572,7 +608,8 @@ used with Plack and other persistent environments. > > sub disable_syspref_cache { > my ($self) = @_; >- $use_syspref_cache = 0; >+ $self = $context unless ref $self; >+ $self->{use_syspref_cache} = 0; > $self->clear_syspref_cache(); > } > >@@ -587,8 +624,10 @@ will not be seen by this process. > =cut > > sub clear_syspref_cache { >- return unless $use_syspref_cache; >- $syspref_cache->flush_all; >+ my ($self) = @_; >+ $self = $context unless ref $self; >+ return unless $self->{use_syspref_cache}; >+ $self->{syspref_cache}->flush_all; > } > > =head2 set_preference >@@ -604,6 +643,7 @@ preference. > > sub set_preference { > my ( $self, $variable, $value, $explanation, $type, $options ) = @_; >+ $self = $context unless ref $self; > > $variable = lc $variable; > >@@ -639,8 +679,8 @@ sub set_preference { > )->store(); > } > >- if ( $use_syspref_cache ) { >- $syspref_cache->set_in_cache( "syspref_$variable", $value ); >+ if ( $self->{use_syspref_cache} ) { >+ $self->{syspref_cache}->set_in_cache( "syspref_$variable", $value ); > } > > return $syspref; >@@ -658,10 +698,11 @@ was no syspref of the name. > > sub delete_preference { > my ( $self, $var ) = @_; >+ $self = $context unless ref $self; > > if ( Koha::Config::SysPrefs->find( $var )->delete ) { >- if ( $use_syspref_cache ) { >- $syspref_cache->clear_from_cache("syspref_$var"); >+ if ( $self->{use_syspref_cache} ) { >+ $self->{syspref_cache}->clear_from_cache("syspref_$var"); > } > > return 1; >@@ -675,7 +716,7 @@ sub delete_preference { > > Returns a connection to the Zebra database > >-C<$self> >+C<$self> > > C<$server> one of the servers defined in the koha-conf.xml file > >@@ -786,8 +827,7 @@ creates one, and connects to the database. > > This database handle is cached for future use: if you call > C<C4::Context-E<gt>dbh> twice, you will get the same handle both >-times. If you need a second database handle, use C<&new_dbh> and >-possibly C<&set_dbh>. >+times. If you need a second database handle, use C<&new_dbh>. > > =cut > >@@ -826,64 +866,6 @@ sub new_dbh > return &dbh({ new => 1 }); > } > >-=head2 set_dbh >- >- $my_dbh = C4::Connect->new_dbh; >- C4::Connect->set_dbh($my_dbh); >- ... >- C4::Connect->restore_dbh; >- >-C<&set_dbh> and C<&restore_dbh> work in a manner analogous to >-C<&set_context> and C<&restore_context>. >- >-C<&set_dbh> saves the current database handle on a stack, then sets >-the current database handle to C<$my_dbh>. >- >-C<$my_dbh> is assumed to be a good database handle. >- >-=cut >- >-#' >-sub set_dbh >-{ >- my $self = shift; >- my $new_dbh = shift; >- >- # Save the current database handle on the handle stack. >- # We assume that $new_dbh is all good: if the caller wants to >- # screw himself by passing an invalid handle, that's fine by >- # us. >- push @{$context->{"dbh_stack"}}, $context->{"dbh"}; >- $context->{"dbh"} = $new_dbh; >-} >- >-=head2 restore_dbh >- >- C4::Context->restore_dbh; >- >-Restores the database handle saved by an earlier call to >-C<C4::Context-E<gt>set_dbh>. >- >-=cut >- >-#' >-sub restore_dbh >-{ >- my $self = shift; >- >- if ($#{$context->{"dbh_stack"}} < 0) >- { >- # Stack underflow >- die "DBH stack underflow"; >- } >- >- # Pop the old database handle and set it. >- $context->{"dbh"} = pop @{$context->{"dbh_stack"}}; >- >- # FIXME - If it is determined that restore_context should >- # return something, then this function should, too. >-} >- > =head2 queryparser > > $queryparser = C4::Context->queryparser >diff --git a/Koha/Cache.pm b/Koha/Cache.pm >index eeb2723..a403836 100644 >--- a/Koha/Cache.pm >+++ b/Koha/Cache.pm >@@ -286,7 +286,7 @@ sub set_in_cache { > $value = clone( $value ) if ref($value) and not $unsafe; > > # Set in L1 cache >- $L1_cache{ $key } = $value; >+ $L1_cache{ $self->{namespace} }{ $key } = $value; > > # We consider an expiry of 0 to be inifinite > if ( $expiry ) { >@@ -337,12 +337,12 @@ sub get_from_cache { > return unless ( $self->{$cache} && ref( $self->{$cache} ) =~ m/^Cache::/ ); > > # Return L1 cache value if exists >- if ( exists $L1_cache{$key} ) { >+ if ( exists $L1_cache{ $self->{namespace} }{ $key } ) { > # No need to deep copy if it's a scalar > # Or if we do not need to deep copy >- return $L1_cache{$key} >- if not ref $L1_cache{$key} or $unsafe; >- return clone $L1_cache{$key}; >+ return $L1_cache{ $self->{namespace} }{ $key } >+ if not ref $L1_cache{ $self->{namespace} }{ $key } or $unsafe; >+ return clone $L1_cache{ $self->{namespace} }{ $key }; > } > > my $get_sub = $self->{ref($self->{$cache}) . "_get"}; >@@ -373,7 +373,7 @@ sub clear_from_cache { > return unless ( $self->{$cache} && ref( $self->{$cache} ) =~ m/^Cache::/ ); > > # Clear from L1 cache >- delete $L1_cache{$key}; >+ delete $L1_cache{ $self->{namespace} }{ $key }; > > return $self->{$cache}->delete($key) > if ( ref( $self->{$cache} ) =~ m'^Cache::Memcached' ); >@@ -402,7 +402,7 @@ sub flush_all { > > sub flush_L1_cache { > my( $self ) = @_; >- %L1_cache = (); >+ delete $L1_cache{ $self->{namespace} }; > } > > =head1 TIED INTERFACE >diff --git a/Koha/Database.pm b/Koha/Database.pm >index d40eb52..959c00d 100644 >--- a/Koha/Database.pm >+++ b/Koha/Database.pm >@@ -47,10 +47,9 @@ __PACKAGE__->mk_accessors(qw( )); > # database connection from the data given in the current context, and > # returns it. > sub _new_schema { >+ my $context = shift || C4::Context->current(); > >- my $context = C4::Context->new(); >- >- my $db_driver = $context->{db_driver}; >+ my $db_driver = $context->db_driver; > > my $db_name = $context->config("database"); > my $db_host = $context->config("hostname"); >@@ -122,16 +121,16 @@ sub schema { > return $database->{schema} if defined $database->{schema}; > } > >- $database->{schema} = &_new_schema(); >+ $database->{schema} = &_new_schema($params->{context}); > return $database->{schema}; > } > > =head2 new_schema > >- $schema = $database->new_schema; >+ $schema = $database->new_schema($context); > >-Creates a new connection to the Koha database for the current context, >-and returns the database handle (a C<DBI::db> object). >+Creates a new connection to the Koha database for the context >+(current is default), and returns the database handle (a C<DBI::db> object). > > The handle is not saved anywhere: this method is strictly a > convenience function; the point is that it knows which database to >@@ -143,7 +142,7 @@ connect to so that the caller doesn't have to know. > sub new_schema { > my $self = shift; > >- return &_new_schema(); >+ return &_new_schema(@_); > } > > =head2 set_schema >@@ -200,6 +199,29 @@ sub restore_schema { > # return something, then this function should, too. > } > >+=head2 run_with_schema >+ >+ $database->run_with_schema( $schema, sub {...} ); >+ >+Restores the database handle saved by an earlier call to >+C<$database-E<gt>set_schema> C<$database-E<gt>restore_schema> wrapper. >+ >+=cut >+ >+sub run_with_schema { >+ my $self = shift; >+ my $schema = shift or croak "No schema"; >+ my $code = shift or croak "No sub"; >+ >+ $self->set_schema; >+ local $@; >+ my $ret = eval { $code->(@_) }; >+ my $died = $@; >+ $self->restore_schema; >+ die $died if $died; >+ return $ret; >+} >+ > =head2 EXPORT > > None by default. >diff --git a/Koha/Handler/Plack.pm b/Koha/Handler/Plack.pm >new file mode 100644 >index 0000000..af3f6cb >--- /dev/null >+++ b/Koha/Handler/Plack.pm >@@ -0,0 +1,163 @@ >+package Koha::Handler::Plack; >+ >+# Copyright (c) 2016 Catalyst IT >+# >+# 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 2 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, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+=head1 NAME >+ >+ Koha::Handler::Plack - Plack helper >+ >+=head1 SYNOPSIS >+ >+ koha.psgi: >+ use Koha::Handler::Plack; >+ >+ my %HOST_CONF = ( >+ 'koha1.com' => { ... }, >+ 'koha2.com' => { ... }, >+ ... >+ ); >+ # last line >+ Koha::Handler::Plack->app_per_host(\%HOST_CONF); >+ >+ See C<app_per_host()> below >+ >+=head1 DESCRIPTION >+ >+ Some handy function to help with Koha/Plack in a multi-host situation. >+ >+ The problem: >+ Koha app relies on env vars. This should be changed, ie C4::Context should >+ be upgraded to Koha::App, but until then we need a gap filler. That's >+ because once up, there's no way to pass on new env to a psgi container. >+ In Apache, for instance, we can specify env vars per virtual host. Plack >+ has no such concept. >+ >+ Solution: >+ We need to modify the environment in situ, per virtual host - app_per_host(). >+ We specify env for each hostname, and apply. >+ >+=cut >+ >+use Modern::Perl; >+use Carp; >+ >+use Plack::App::URLMap; >+ >+=head1 CLASS METHODS >+ >+=head2 app_per_host($host_apps) >+ >+ App wrapper for per virtual host scenario. >+ >+ C<$host_apps>: >+ { >+ hostname => 'koha1.com', >+ app => $app1, >+ context => $context1, >+ }, >+ { >+ hostname => ['koha2.com', 'www.koha2.com'], >+ app => $app2, >+ context => $context2, >+ }, >+ ... >+ >+ C<hostname> is mandatory. >+ >+ koha.psgi: >+ >+ use Plack::Builder; >+ use Plack::App::CGIBin; >+ >+ use C4::Context; >+ >+ my $opac_app = builder { >+ enable "Plack::Middleware::Static", >+ path => qr{^/opac-tmpl/}, root => '/usr/share/koha/opac/htdocs/'; >+ >+ enable 'StackTrace'; >+ mount "/cgi-bin/koha" => Plack::App::CGIBin->new(root => "/usr/share/koha/opac/cgi-bin/opac"); >+ }; >+ my $intranet_app = builder { >+ enable "Plack::Middleware::Static", >+ path => qr{^/intranet-tmpl/}, root => '/usr/share/koha/intranet/htdocs/'; >+ >+ enable 'StackTrace'; >+ mount "/cgi-bin/koha" => Plack::App::CGIBin->new(root => "/usr/share/koha/cgi-bin"); >+ }; >+ >+ my @host_def; >+ >+ my $conf_file_1 = "/etc/koha/site-1/koha_conf.xml"; >+ my $context_1 = C4::Context->new($conf_file_1); >+ push @host_def, >+ { >+ hostname => [ "public.host.for.site-1", "www.public.host.for.site-1" ], >+ app => $opac_app, >+ context => $context_1, >+ }, >+ { >+ hostname => "intranet.host.for.site-1", >+ app => $intranet_app, >+ context => $context_1, >+ }; >+ >+ my $conf_file_2 = "/etc/koha/site-1/koha_conf.xml"; >+ my $context_2 = C4::Context->new($conf_file_2); >+ push @host_def, >+ { >+ hostname => "public.host.for.site-2", >+ app => $opac_app, >+ context => $context_2, >+ }, >+ { >+ hostname => "intranet.host.for.site-2", >+ app => $intranet_app, >+ context => $context_2, >+ }; >+ >+ ... >+ >+ Koha::Handler::Plack->app_per_host( \@host_def ); >+ >+=cut >+ >+sub app_per_host { >+ my $class = shift; >+ my $sites = shift or die "No sites spec"; >+ >+ my $map = Plack::App::URLMap->new; >+ foreach my $site_params ( @$sites ) { >+ my $hosts = $site_params->{hostname} or croak "No hostname"; >+ $hosts = [$hosts] unless ref $hosts; >+ >+ my $app = $site_params->{app} or croak "No app"; >+ my $context = $site_params->{context} or croak "No Koha Context"; >+ >+ foreach my $host (@$hosts) { >+ $map->map("http://$host/" => sub { >+ my $env = shift; >+ >+ return $context->run_within_context(sub { $app->($env) }); >+ }); >+ } >+ } >+ return $map->to_app; >+} >+ >+1; >diff --git a/Koha/Handler/Plack/CGI.pm b/Koha/Handler/Plack/CGI.pm >new file mode 100644 >index 0000000..36c6907 >--- /dev/null >+++ b/Koha/Handler/Plack/CGI.pm >@@ -0,0 +1,228 @@ >+package Koha::Handler::Plack::CGI; >+ >+# Copyright (c) 2016 Catalyst IT >+# >+# 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 2 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, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+=head1 NAME >+ >+ Koha::Handler::Plack::CGI - Plack helper for CGI scripts >+ >+=head1 SYNOPSIS >+ >+ koha.psgi: >+ use Koha::Handler::Plack::CGI; >+ >+ my %koha_env = ( >+ opac => { >+ static_root => '/usr/share/koha/opac/htdocs', >+ script_root => '/usr/share/koha/opac', >+ }, >+ intranet => { >+ static_root => '/usr/share/koha/intranet/htdocs', >+ script_root => '/usr/share/koha/intranet' >+ } >+ ); >+ my @sites = ( >+ { >+ opac_hostname => 'koha1-opac.com', >+ intranet_hostname => 'koha1-intranet.com', >+ config = '/etc/koha/koha1/koha-conf.xml' >+ }, >+ { >+ opac_hostname => ['opac.koha2.com', 'www.opackoha2.com'], >+ intranet_hostname => ['intranet.koha2.com', 'www.intranetkoha2.com'], >+ config = '/etc/koha/koha2/koha-conf.xml' >+ }, >+ ); >+ >+ # last line >+ Koha::Handler::Plack::CGI->app_per_host(\%HOST_CONF); >+ >+ See C<app_per_host()> below >+ >+=head1 DESCRIPTION >+ >+ CGI script runner. >+ >+ One beautiful day wiwill move away from that and have proper App module >+ with router and handlers</dream> >+ >+ See C<Koha::Handler::Plack> >+ >+=cut >+ >+use Modern::Perl; >+use Carp; >+ >+use Plack::Builder; >+use Plack::App::CGIBin; >+ >+use parent "Koha::Handler::Plack"; >+ >+use C4::Context; >+ >+=head1 CLASS METHODS >+ >+=head2 app($context, $env) >+ >+ Plack app builder fora CGI app >+ >+ C<$context>: "opac" or "intranet" >+ C<$env>: >+ { >+ static_root => '...', >+ script_root => '...', >+ pugins => [ >+ [ 'StackTrace' ], >+ ... >+ ], >+ } >+ >+ koha.psgi: >+ >+ Koha::Handler::Plack::CGI->app( "opac", \%opac_app_env ); >+ >+=cut >+ >+sub app { >+ my $class = shift; >+ my $context = shift; >+ croak "Invalid app context '$context' - must be 'opac' or 'intranet'" >+ unless $context =~ m/^(opac|intranet)$/; >+ my $env = shift or croak "No $context env details"; >+ >+ my $static_root = $env->{static_root} or croak "No $context static_root"; >+ $static_root = "$static_root/" unless $static_root =~ m!/$!; >+ my $script_root = $env->{script_root} or croak "No $context script_root"; >+ $script_root =~ s!/$!!; >+ my $plugins = $env->{plugins} || []; >+ my $is_intranet = $context eq "intranet"; >+ >+ builder { >+ enable "Plack::Middleware::Static", >+ path => qr{^/$context-tmpl/}, root => $static_root; >+ >+ map enable(@$_), @$plugins; >+ >+ mount "/cgi-bin/koha" => Plack::App::CGIBin->new(root => $script_root)->to_app; >+ mount "/" => sub { >+ return [ 302, [ Location => '/cgi-bin/koha/' . ( $is_intranet ? 'mainpage.pl' : 'opac-main.pl' ) ], [] ]; >+ }; >+ }; >+} >+ >+=head2 multi_site($env, $sites) >+ >+ App wrapper for per virtual host scenario. >+ >+ C<$env>: >+ { >+ opac => { >+ static_root => '/usr/share/koha/opac/htdocs', >+ script_root => '/usr/share/koha/opac/cgi-bin/opac', >+ pugins => [ >+ [ 'StackTrace' ], >+ ], >+ }, >+ intranet => { >+ static_root => '/usr/share/koha/intranet/htdocs', >+ script_root => '/usr/share/koha/cgi-bin' >+ } >+ } >+ C<$sites>: >+ { >+ namespace => 'koha1', >+ opac_hostname => 'koha1-opac.com', >+ intranet_hostname => 'koha1-intranet.com', >+ config => '/etc/koha/sites/koha1/koha-conf.xml', >+ shared_config => 1 >+ }, >+ { >+ namespace => 'koha2', >+ opac_hostname => ['opac.koha2.com', 'www.opackoha2.com'], >+ intranet_hostname => ['intranet.koha2.com', 'www.intranetkoha2.com'], >+ config => '/etc/koha/sites/koha2/koha-conf.xml' >+ }, >+ ... >+ >+ koha.psgi: >+ >+ Koha::Handler::Plack::CGI->multi_site( \%koha_app_env, \@sites ); >+ >+=cut >+ >+my $DUMMY_KOHA_CONF = "<yazgfs><config>DUMMY</config></yazgfs>"; >+sub multi_site { >+ my $class = shift; >+ my $env = shift or croak "No Koha env details"; >+ my $sites = shift or croak "No sites spec"; >+ >+ my ($opac_app, $intranet_app); >+ >+ if (my $opac = $env->{opac}) { >+ $opac_app = $class->app('opac', $opac); >+ } >+ >+ if (my $intranet = $env->{intranet}) { >+ $intranet_app = $class->app('intranet', $intranet); >+ } >+ >+ my @host_def = map { >+ my $namespace = $_->{namespace} or croak "No namespace"; >+ my $config = $_->{config} or croak "Site without config"; >+ my $shared_context = $_->{shared_context}; >+ >+ my $context = C4::Context->new($config, $namespace); >+ >+ my @hd; >+ if (my $hostname = $_->{opac_hostname}) { >+ croak "You have OPAC hosts without OPAC env details" unless $opac_app; >+ push @hd, { >+ hostname => $hostname, >+ app => sub { >+ # XXX this may need some rethinking >+ local $ENV{KOHA_CONF} = \$DUMMY_KOHA_CONF; >+ local $ENV{MEMCACHED_NAMESPACE} = $namespace; >+ >+ $opac_app->(@_); >+ }, >+ context => $context, >+ shared_context => $shared_context, >+ }; >+ } >+ if (my $hostname = $_->{intranet_hostname}) { >+ croak "You have Intranet hosts without Intranet env details" unless $intranet_app; >+ push @hd, { >+ hostname => $hostname, >+ app => sub { >+ # XXX this may need some rethinking >+ local $ENV{KOHA_CONF} = \$DUMMY_KOHA_CONF; >+ local $ENV{MEMCACHED_NAMESPACE} = $namespace; >+ >+ $intranet_app->(@_); >+ }, >+ context => $context, >+ shared_context => $shared_context, >+ }; >+ } >+ @hd; >+ } @$sites; >+ >+ return $class->app_per_host( \@host_def ); >+} >+ >+1; >diff --git a/about.pl b/about.pl >index 6b77677..a1469c1 100755 >--- a/about.pl >+++ b/about.pl >@@ -92,7 +92,7 @@ my $warnIsRootUser = (! $loggedinuser); > my $warnNoActiveCurrency = (! defined Koha::Acquisition::Currencies->get_active); > my @xml_config_warnings; > >-my $context = new C4::Context; >+my $context = C4::Context->current; > > if ( ! defined C4::Context->config('zebra_bib_index_mode') ) { > push @xml_config_warnings, { >diff --git a/admin/systempreferences.pl b/admin/systempreferences.pl >index 67e0638..861508f 100755 >--- a/admin/systempreferences.pl >+++ b/admin/systempreferences.pl >@@ -387,7 +387,7 @@ output_html_with_http_headers $input, $cookie, $template->output; > # .pref files. > > sub get_prefs_from_files { >- my $context = C4::Context->new(); >+ my $context = C4::Context->current(); > my $path_pref_en = $context->config('intrahtdocs') . > '/prog/en/modules/admin/preferences'; > # Get all .pref file names >diff --git a/misc/cronjobs/check-url.pl b/misc/cronjobs/check-url.pl >index 71885ab..2869446 100755 >--- a/misc/cronjobs/check-url.pl >+++ b/misc/cronjobs/check-url.pl >@@ -190,7 +190,7 @@ sub check_all_url { > my $checker = C4::URL::Checker->new($timeout,$agent); > $checker->{ host_default } = $host; > >- my $context = new C4::Context( ); >+ my $context = C4::Context->current(); > my $dbh = $context->dbh; > my $sth = $dbh->prepare( > "SELECT biblionumber FROM biblioitems WHERE url <> ''" ); >diff --git a/misc/plack/koha-multi.psgi b/misc/plack/koha-multi.psgi >new file mode 100644 >index 0000000..e897f02 >--- /dev/null >+++ b/misc/plack/koha-multi.psgi >@@ -0,0 +1,29 @@ >+#!/usr/bin/perl >+ >+# This is a minimal example. You can include all frills from koha.psgi >+# To try it: >+# plackup -I /usr/share/koha/lib --port 5010 koha-multi.psgi >+ >+my %KOHA_ENV = ( >+ opac => { >+ static_root => '/usr/share/koha/opac/htdocs', >+ script_root => '/usr/share/koha/opac/cgi-bin/opac', >+ pugins => [ >+ # don't enable this plugin in production, since stack traces reveal too much information >+ # about system to potential attackers! >+ [ 'StackTrace' ], >+ ], >+ }, >+ intranet => { >+ static_root => '/usr/share/koha/intranet/htdocs', >+ script_root => '/usr/share/koha/intranet/cgi-bin', >+ } >+); >+my @SITES = map { >+ namespace => $_, >+ opac_hostname => "opac.$_.my-koha-multisite.net", >+ intranet_hostname => "intranet.$_.my-koha-multisite.net", >+ config => "/etc/koha/sites/$_/koha-conf.xml" >+}, qw(koha1 koha2 koha3); >+ >+Koha::Handler::Plack::CGI->multi_site( \%KOHA_ENV, \@SITES ); >diff --git a/misc/translator/LangInstaller.pm b/misc/translator/LangInstaller.pm >index 683897d..14a21c7 100644 >--- a/misc/translator/LangInstaller.pm >+++ b/misc/translator/LangInstaller.pm >@@ -56,7 +56,7 @@ sub new { > > my $self = { }; > >- my $context = C4::Context->new(); >+ my $context = C4::Context->current(); > $self->{context} = $context; > $self->{path_pref_en} = $context->config('intrahtdocs') . > '/prog/en/modules/admin/preferences'; >@@ -140,7 +140,7 @@ sub new { > sub po_filename { > my $self = shift; > >- my $context = C4::Context->new; >+ my $context = C4::Context->current(); > my $trans_path = $Bin . '/po'; > my $trans_file = "$trans_path/" . $self->{lang} . "-pref.po"; > return $trans_file; >diff --git a/t/Koha_Handler_Plack.t b/t/Koha_Handler_Plack.t >new file mode 100644 >index 0000000..8172940 >--- /dev/null >+++ b/t/Koha_Handler_Plack.t >@@ -0,0 +1,136 @@ >+#!/usr/bin/perl >+ >+use Test::More tests => 15; >+use Plack::Test; >+use Plack::Test::MockHTTP; >+use Test::Mock::LWP::Dispatch; >+use Test::MockModule; >+use HTTP::Request::Common; >+use FindBin qw($Bin); >+use Data::Dumper; >+ >+use_ok("Koha::Handler::Plack"); >+use_ok("Koha::Handler::Plack::CGI"); >+ >+use C4::Context; >+ >+my $db = Test::MockModule->new('Koha::Database'); >+$db->mock( >+ _new_schema => sub { >+ return $_[0]; >+ } >+); >+ >+sub make_response { >+ return join ";", map defined($_) ? $_ : "", @_; >+} >+sub dummy_val { >+ return C4::Context->config("dummy"); >+} >+sub check_context { >+ my $dummy_val = dummy_val(); >+ is $dummy_val, undef, "context preserved" >+ or diag("dummy val: $dummy_val"); >+} >+ >+my $app = sub { >+ return [ >+ 200, >+ [ 'Content-Type' => 'text/plain' ], >+ [ make_response(dummy_val()) ] >+ ]; >+}; >+my $generic_url = "http://dummyhost.com/"; >+ >+my $KOHA_CONF_XML = <<EOS; >+<yazgfs> >+ <config> >+ <kohasite>test</kohasite> >+ <dummy>XML</dummy> >+ <intrahtdocs>.</intrahtdocs> >+ </config> >+</yazgfs> >+EOS >+ >+my @HOST_CONF = ( >+ { >+ hostname => ['koha-file.com', 'www.koha-file.com'], >+ app => $app, >+ context => C4::Context->new("$Bin/conf/koha1/koha-conf.xml"), >+ _dummy => "KOHA1" >+ }, >+ { >+ hostname => ['koha-xml.com', 'www.koha-xml.com'], >+ app => $app, >+ context => C4::Context->new(\$KOHA_CONF_XML), >+ _dummy => "XML" >+ }, >+); >+test_psgi >+ app => Koha::Handler::Plack->app_per_host(\@HOST_CONF), >+ client => sub { >+ my $cb = shift; >+ >+ foreach my $site_params ( @HOST_CONF ) { >+ my $valid_response = make_response( >+ $site_params->{_dummy} >+ ); >+ foreach (@{$site_params->{hostname}}) { >+ my $res = $cb->(GET "http://$_/"); >+ is $res->content, $valid_response, $_ >+ or diag(Dumper($site_params, $_, $res->as_string)); >+ check_context(); >+ } >+ } >+ >+ $res = $cb->(GET $generic_url); >+ is $res->code, 404, "app_per_host unknown host" >+ or diag($res->as_string); >+ }; >+ >+my %MULTI_HOST_ENV = ( >+ opac => { >+ static_root => "$Bin/../koha-tmpl/opac-tmpl/bootstrap", >+ script_root => "$Bin/../opac", >+ }, >+ intranet => { >+ static_root => "$Bin/../koha-tmpl/intranet-tmpl/bootstrap", >+ script_root => "$Bin/.." >+ } >+); >+my @MULTI_HOST_SITES = ( >+ { >+ namespace => 'koha1', >+ opac_hostname => ['opac.koha1.com', 'www.opac.koha1.com'], >+ intranet_hostname => ['intranet.koha1.com', 'www.intranet.koha1.com'], >+ config => "$Bin/conf/koha1/koha-conf.xml", >+ }, >+ { >+ namespace => 'koha2', >+ opac_hostname => ['opac.koha2.com', 'www.opac.koha2.com'], >+ intranet_hostname => ['intranet.koha2.com', 'www.intranet.koha2.com'], >+ config => "$Bin/conf/koha2/koha-conf.xml", >+ shared_context => 1, >+ }, >+); >+test_psgi >+ app => Koha::Handler::Plack::CGI->multi_site(\%MULTI_HOST_ENV, \@MULTI_HOST_SITES), >+ client => sub { >+ my $cb = shift; >+ >+ foreach my $site (@MULTI_HOST_SITES) { >+ my $opac = $site->{opac_hostname}; >+ foreach my $host (@$opac) { >+# this is not really a test, but cannot do any better atm >+# TODO: a complex test involving two database connections >+ my $res = $cb->(GET "http://$host/"); >+ # A future implementation may not redirect >+ if ($res->is_redirect) { >+ my $loc = $res->header("Location"); >+ $res = $cb->(GET "http://$host$loc"); >+ } >+ is $res->code, 500, "multi_site() $host" >+ or diag($res->as_string); >+ } >+ } >+ }; >diff --git a/t/conf/dummy/koha-conf.xml b/t/conf/dummy/koha-conf.xml >new file mode 100644 >index 0000000..d4c96b0 >--- /dev/null >+++ b/t/conf/dummy/koha-conf.xml >@@ -0,0 +1,7 @@ >+<yazgfs> >+ <config> >+ <kohasite>dummy</kohasite> >+ <dummy>DUMMY</dummy> >+ <intrahtdocs>.</intrahtdocs> >+ </config> >+</yazgfs> >diff --git a/t/conf/koha1/koha-conf.xml b/t/conf/koha1/koha-conf.xml >new file mode 100644 >index 0000000..371d039 >--- /dev/null >+++ b/t/conf/koha1/koha-conf.xml >@@ -0,0 +1,7 @@ >+<yazgfs> >+ <config> >+ <kohasite>koha1</kohasite> >+ <dummy>KOHA1</dummy> >+ <intrahtdocs>.</intrahtdocs> >+ </config> >+</yazgfs> >diff --git a/t/conf/koha2/koha-conf.xml b/t/conf/koha2/koha-conf.xml >new file mode 100644 >index 0000000..437e772 >--- /dev/null >+++ b/t/conf/koha2/koha-conf.xml >@@ -0,0 +1,5 @@ >+<yazgfs> >+ <config> >+ <dummy>KOHA2</dummy> >+ </config> >+</yazgfs> >diff --git a/t/db_dependent/Amazon.t b/t/db_dependent/Amazon.t >index 2304073..a5b316f 100755 >--- a/t/db_dependent/Amazon.t >+++ b/t/db_dependent/Amazon.t >@@ -14,7 +14,7 @@ BEGIN { > use_ok('C4::External::Amazon'); > } > >-my $context = C4::Context->new(); >+my $context = C4::Context->current(); > > my $locale = $context->preference('AmazonLocale'); > >diff --git a/t/db_dependent/Context.t b/t/db_dependent/Context.t >index b5a050f..c3f6066 100755 >--- a/t/db_dependent/Context.t >+++ b/t/db_dependent/Context.t >@@ -47,7 +47,7 @@ C4::Context->clear_syspref_cache(); > C4::Context->enable_syspref_cache(); > $dbh->rollback; > >-ok($koha = C4::Context->new, 'C4::Context->new'); >+ok($koha = C4::Context->current, 'C4::Context->current'); > my @keys = keys %$koha; > my $width = 0; > if (ok(@keys)) { >diff --git a/t/db_dependent/Template/Plugin/KohaDates.t b/t/db_dependent/Template/Plugin/KohaDates.t >index fe18836..2088347 100644 >--- a/t/db_dependent/Template/Plugin/KohaDates.t >+++ b/t/db_dependent/Template/Plugin/KohaDates.t >@@ -14,7 +14,7 @@ BEGIN { > my $module_context = new Test::MockModule('C4::Context'); > > my $date = "1973-05-21"; >-my $context = C4::Context->new(); >+my $context = C4::Context->current(); > > my $filter = Koha::Template::Plugin::KohaDates->new(); > ok ($filter, "new()"); >diff --git a/t/db_dependent/XISBN.t b/t/db_dependent/XISBN.t >index 2f6d63b..45e01dd 100755 >--- a/t/db_dependent/XISBN.t >+++ b/t/db_dependent/XISBN.t >@@ -26,7 +26,7 @@ my $search_module = new Test::MockModule('C4::Search'); > > $search_module->mock('SimpleSearch', \&Mock_SimpleSearch ); > >-my $context = C4::Context->new; >+my $context = C4::Context->current; > > my ( $biblionumber_tag, $biblionumber_subfield ) = > GetMarcFromKohaField( 'biblio.biblionumber', '' ); >diff --git a/t/db_dependent/sysprefs.t b/t/db_dependent/sysprefs.t >index 340e89a..07552f1 100755 >--- a/t/db_dependent/sysprefs.t >+++ b/t/db_dependent/sysprefs.t >@@ -19,7 +19,7 @@ > # along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; >-use Test::More tests => 8; >+use Test::More tests => 11; > use C4::Context; > > # Start transaction >@@ -60,4 +60,15 @@ is(C4::Context->preference('testpreference'), 'def', 'caching preferences'); > C4::Context->clear_syspref_cache(); > is(C4::Context->preference('testpreference'), undef, 'clearing preference cache'); > >+delete $ENV{OVERRIDE_SYSPREF_opacheader}; >+ >+my $DUMMY_KOHA_CONF = "<yazgfs><config><dummy>DUMMY</dummy></config></yazgfs>"; >+my $context1 = C4::Context->new($DUMMY_KOHA_CONF, "context1"); >+is( $context1->preference('opacheader'), $opacheader, 'context1 "opacheader"'); >+ >+my $context2 = C4::Context->new($DUMMY_KOHA_CONF, "context2"); >+$context2->set_preference( 'opacheader', $newopacheader ); >+is( $context1->preference('opacheader'), $opacheader, 'context1 "opacheader"'); >+is( $context2->preference('opacheader'), $newopacheader, 'context2 "opacheader"'); >+ > $dbh->rollback; >-- >2.1.4
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 15562
:
47420
|
47421
|
47422
|
47838
|
47944
|
47945
|
47946
|
47947
|
49370
|
49371
|
49372
|
49373
|
49664
|
49665
|
49666
|
49667
|
49709
|
50702
|
50703
|
50713
|
50714
|
50715
|
50716
|
50870
|
51939
|
51940
|
53296
|
53297
|
55577
|
55578
|
60723
|
60724
|
60725
|
60726
|
66374
|
66375
|
66376
|
66377
|
76062