Bug 9587 Follow up to fix the problem Katrin identified
[srvgit] / C4 / Context.pm
index 5e9feae..8451609 100644 (file)
@@ -18,9 +18,7 @@ package C4::Context;
 
 use strict;
 use warnings;
-use vars qw($VERSION $AUTOLOAD $context @context_stack);
-
-use Koha::Cache;
+use vars qw($VERSION $AUTOLOAD $context @context_stack $servers $memcached $ismemcached);
 
 BEGIN {
        if ($ENV{'HTTP_USER_AGENT'})    {
@@ -81,6 +79,22 @@ BEGIN {
                }
     }          # else there is no browser to send fatals to!
 
+    # Check if there are memcached servers set
+    $servers = $ENV{'MEMCACHED_SERVERS'};
+    if ($servers) {
+        # Load required libraries and create the memcached object
+        require Cache::Memcached;
+        $memcached = Cache::Memcached->new({
+        servers => [ $servers ],
+        debug   => 0,
+        compress_threshold => 10_000,
+        expire_time => 600,
+        namespace => $ENV{'MEMCACHED_NAMESPACE'} || 'koha'
+    });
+        # Verify memcached available (set a variable and test the output)
+    $ismemcached = $memcached->set('ismemcached','1');
+    }
+
     $VERSION = '3.07.00.049';
 }
 
@@ -206,6 +220,18 @@ sub KOHAVERSION {
     do $cgidir."/kohaversion.pl" || die "NO $cgidir/kohaversion.pl";
     return kohaversion();
 }
+
+=head2 final_linear_version
+
+Returns the version number of the final update to run in updatedatabase.pl.
+This number is equal to the version in kohaversion.pl
+
+=cut
+
+sub final_linear_version {
+    return KOHAVERSION;
+}
+
 =head2 read_config_file
 
 Reads the specified Koha config file. 
@@ -234,14 +260,38 @@ Returns undef in case of error.
 sub read_config_file {         # Pass argument naming config file to read
     my $koha = XMLin(shift, keyattr => ['id'], forcearray => ['listen', 'server', 'serverinfo'], suppressempty => '');
 
-    if (Koha::Cache->is_cache_active()) {
-        my $cache = Koha::Cache->new();
-        $cache->set_in_cache('kohaconf', $koha) if defined $cache;
+    if ($ismemcached) {
+      $memcached->set('kohaconf',$koha);
     }
 
     return $koha;                      # Return value: ref-to-hash holding the configuration
 }
 
+=head2 ismemcached
+
+Returns the value of the $ismemcached variable (0/1)
+
+=cut
+
+sub ismemcached {
+    return $ismemcached;
+}
+
+=head2 memcached
+
+If $ismemcached is true, returns the $memcache variable.
+Returns undef otherwise
+
+=cut
+
+sub memcached {
+    if ($ismemcached) {
+      return $memcached;
+    } else {
+      return;
+    }
+}
+
 # db_scheme2dbi
 # Translates the full text name of a database into de appropiate dbi name
 # 
@@ -255,7 +305,7 @@ sub db_scheme2dbi {
         if (/Postgres|Pg|PostgresSQL/) { return("Pg"); }
         if (/oracle/) { return("Oracle"); }
     }
-    return undef;         # Just in case
+    return;         # Just in case
 }
 
 sub import {
@@ -285,8 +335,9 @@ 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>.
 
-It saves the koha-conf.xml values in the cache (if configured) and uses
-those values until them expire and re-reads them.
+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.
 
 C<&new> does not set this context as the new default context; for
 that, use C<&set_context>.
@@ -319,24 +370,25 @@ sub new {
             $conf_fname = CONFIG_FNAME;
         } else {
             warn "unable to locate Koha configuration file koha-conf.xml";
-            return undef;
+            return;
         }
     }
     
-    if (Koha::Cache->is_cache_active()) {
-        # retrieve from cache
-        my $cache = Koha::Cache->new();
-        $self = $cache->get_from_cache('kohaconf') if defined $cache;
-        $self = { };
-    }
-    if (!keys %$self) {
-        # not cached yet
+    if ($ismemcached) {
+        # retreive 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 undef if !defined($self->{"config"});
+    return if !defined($self->{"config"});
 
     $self->{"dbh"} = undef;        # Database handle
     $self->{"Zconn"} = undef;    # Zebra Connections
@@ -440,10 +492,10 @@ C<C4::Config-E<gt>new> will not return it.
 
 =cut
 
-sub _common_config ($$) {
+sub _common_config {
        my $var = shift;
        my $term = shift;
-    return undef if !defined($context->{$term});
+    return if !defined($context->{$term});
        # Presumably $self->{$term} might be
        # undefined if the config file given to &new
        # didn't exist, and the caller didn't bother
@@ -483,12 +535,13 @@ with this method.
 # flushing the caching mechanism.
 
 my %sysprefs;
+my $use_syspref_cache = 1;
 
 sub preference {
     my $self = shift;
     my $var  = lc(shift);                          # The system preference to return
 
-    if (exists $sysprefs{$var}) {
+    if ($use_syspref_cache && exists $sysprefs{$var}) {
         return $sysprefs{$var};
     }
 
@@ -505,13 +558,42 @@ END_SQL
     return $sysprefs{$var};
 }
 
-sub boolean_preference ($) {
+sub boolean_preference {
     my $self = shift;
     my $var = shift;        # The system preference to return
     my $it = preference($self, $var);
     return defined($it)? C4::Boolean::true_p($it): undef;
 }
 
+=head2 enable_syspref_cache
+
+  C4::Context->enable_syspref_cache();
+
+Enable the in-memory syspref cache used by C4::Context. This is the
+default behavior.
+
+=cut
+
+sub enable_syspref_cache {
+    my ($self) = @_;
+    $use_syspref_cache = 1;
+}
+
+=head2 disable_syspref_cache
+
+  C4::Context->disable_syspref_cache();
+
+Disable the in-memory syspref cache used by C4::Context. This should be
+used with Plack and other persistent environments.
+
+=cut
+
+sub disable_syspref_cache {
+    my ($self) = @_;
+    $use_syspref_cache = 0;
+    $self->clear_syspref_cache();
+}
+
 =head2 clear_syspref_cache
 
   C4::Context->clear_syspref_cache();
@@ -616,6 +698,8 @@ sub Zconn {
         $context->{"Zconn"}->{$server}->destroy() if defined($context->{"Zconn"}->{$server});
 
         $context->{"Zconn"}->{$server} = &_new_Zconn($server,$async,$auth,$piggyback,$syntax);
+        $context->{ Zconn }->{ $server }->option(
+            preferredRecordSyntax => C4::Context->preference("marcflavour") );
         return $context->{"Zconn"}->{$server};
     }
 }
@@ -715,8 +799,23 @@ sub _new_dbh
     my $db_user   = $context->config("user");
     my $db_passwd = $context->config("pass");
     # MJR added or die here, as we can't work without dbh
-    my $dbh= DBI->connect("DBI:$db_driver:dbname=$db_name;host=$db_host;port=$db_port",
+    my $dbh = DBI->connect("DBI:$db_driver:dbname=$db_name;host=$db_host;port=$db_port",
     $db_user, $db_passwd, {'RaiseError' => $ENV{DEBUG}?1:0 }) or die $DBI::errstr;
+
+    # Check for the existence of a systempreference table; if we don't have this, we don't
+    # have a valid database and should not set RaiseError in order to allow the installer
+    # to run; installer will not run otherwise since we raise all db errors
+
+    eval {
+                local $dbh->{PrintError} = 0;
+                local $dbh->{RaiseError} = 1;
+                $dbh->do(qq{SELECT * FROM systempreferences WHERE 1 = 0 });
+    };
+
+    if ($@) {
+        $dbh->{RaiseError} = 0;
+    }
+
        my $tz = $ENV{TZ};
     if ( $db_driver eq 'mysql' ) { 
         # Koha 3.0 is utf-8, so force utf8 communication between mySQL and koha, whatever the mysql default config.
@@ -958,7 +1057,8 @@ sub userenv {
 =head2 set_userenv
 
   C4::Context->set_userenv($usernum, $userid, $usercnum, $userfirstname, 
-                  $usersurname, $userbranch, $userflags, $emailaddress);
+                  $usersurname, $userbranch, $userflags, $emailaddress, $branchprinter,
+                  $persona);
 
 Establish a hash of user environment variables.
 
@@ -968,8 +1068,8 @@ set_userenv is called in Auth.pm
 
 #'
 sub set_userenv {
-    my ($usernum, $userid, $usercnum, $userfirstname, $usersurname, $userbranch, $branchname, $userflags, $emailaddress, $branchprinter)= @_;
-    my $var=$context->{"activeuser"};
+    my ($usernum, $userid, $usercnum, $userfirstname, $usersurname, $userbranch, $branchname, $userflags, $emailaddress, $branchprinter, $persona)= @_;
+    my $var=$context->{"activeuser"} || '';
     my $cell = {
         "number"     => $usernum,
         "id"         => $userid,
@@ -981,25 +1081,26 @@ sub set_userenv {
         "branchname" => $branchname,
         "flags"      => $userflags,
         "emailaddress"     => $emailaddress,
-        "branchprinter"    => $branchprinter
+        "branchprinter"    => $branchprinter,
+       "persona"    => $persona,
     };
     $context->{userenv}->{$var} = $cell;
     return $cell;
 }
 
-sub set_shelves_userenv ($$) {
-       my ($type, $shelves) = @_ or return undef;
-       my $activeuser = $context->{activeuser} or return undef;
+sub set_shelves_userenv {
+       my ($type, $shelves) = @_ or return;
+       my $activeuser = $context->{activeuser} or return;
        $context->{userenv}->{$activeuser}->{barshelves} = $shelves if $type eq 'bar';
        $context->{userenv}->{$activeuser}->{pubshelves} = $shelves if $type eq 'pub';
        $context->{userenv}->{$activeuser}->{totshelves} = $shelves if $type eq 'tot';
 }
 
-sub get_shelves_userenv () {
+sub get_shelves_userenv {
        my $active;
        unless ($active = $context->{userenv}->{$context->{activeuser}}) {
                $debug and warn "get_shelves_userenv cannot retrieve context->{userenv}->{context->{activeuser}}";
-               return undef;
+               return;
        }
        my $totshelves = $active->{totshelves} or undef;
        my $pubshelves = $active->{pubshelves} or undef;