bug 2505: turn on warnings in admin/systemprefernces.pl
[koha.git] / admin / systempreferences.pl
index 740cc33..f1d69bc 100755 (executable)
@@ -41,25 +41,36 @@ ALGO :
 =cut
 
 use strict;
+use warnings;
+
 use CGI;
 use C4::Auth;
 use C4::Context;
 use C4::Koha;
 use C4::Languages qw(getTranslatedLanguages);
 use C4::ClassSource;
+use C4::Log;
 use C4::Output;
-use C4::Context;
 
 # use Smart::Comments;
 
 
 # FIXME, shouldnt we store this stuff in the systempreferences table? 
 
+# FIXME: This uses hash in a backwards way.  What we really want is:
+#       $tabsysprefs{key} = $array_ref;
+#               like
+#       $tabsysprefs{Cataloguing} = [qw(autoBarcode ISBD marc ...)];
+#
+#   Because some things *should* be on more than one tab.
+#   And the tabname is the unique part (the key).
+
 my %tabsysprefs;
 # Acquisitions
     $tabsysprefs{acquisitions}="Acquisitions";
     $tabsysprefs{gist}="Acquisitions";
     $tabsysprefs{emailPurchaseSuggestions}="Acquisitions";
+    $tabsysprefs{RenewSerialAddsSuggestion}="Acquisitions";
 
 # Admin
     $tabsysprefs{singleBranchMode}="Admin";
@@ -70,7 +81,6 @@ my %tabsysprefs;
     $tabsysprefs{libraryAddress}="Admin";
     $tabsysprefs{delimiter}="Admin";
     $tabsysprefs{IndependantBranches}="Admin";
-    $tabsysprefs{HomeOrHoldingBranch}="Admin";
     $tabsysprefs{insecure}="Admin";
     $tabsysprefs{KohaAdmin}="Admin";
     $tabsysprefs{KohaAdminEmailAddress}="Admin";
@@ -81,6 +91,8 @@ my %tabsysprefs;
     $tabsysprefs{DebugLevel}="Admin";
     $tabsysprefs{SessionStorage}="Admin";
     $tabsysprefs{noItemTypeImages}="Admin";
+    $tabsysprefs{OPACBaseURL}="Admin";
+    $tabsysprefs{GranularPermissions}="Admin";
 
 # Authorities
     $tabsysprefs{authoritysep}="Authorities";
@@ -97,7 +109,6 @@ my %tabsysprefs;
     $tabsysprefs{LabelMARCView}="Cataloguing";
     $tabsysprefs{marc}="Cataloguing";
     $tabsysprefs{marcflavour}="Cataloguing";
-    $tabsysprefs{serialsadditems}="Cataloguing";
     $tabsysprefs{MARCOrgCode}="Cataloguing";
     $tabsysprefs{z3950AuthorAuthFields}="Cataloguing";
     $tabsysprefs{z3950NormalizeAuthor}="Cataloguing";
@@ -109,6 +120,7 @@ my %tabsysprefs;
     $tabsysprefs{DefaultClassificationSource}="Cataloguing";
     $tabsysprefs{RoutingSerials}="Cataloguing";
     $tabsysprefs{'item-level_itypes'}="Cataloguing";
+    $tabsysprefs{OpacSuppression}="Cataloguing"; 
 
 # Circulation
     $tabsysprefs{maxoutstanding}="Circulation";
@@ -125,18 +137,23 @@ my %tabsysprefs;
     $tabsysprefs{useDaysMode}="Circulation";
     $tabsysprefs{ReservesNeedReturns}="Circulation";
     $tabsysprefs{CircAutocompl}="Circulation";
+    $tabsysprefs{AllowRenewalLimitOverride}="Circulation";
     $tabsysprefs{canreservefromotherbranches}="Circulation";
     $tabsysprefs{finesMode}="Circulation";
     $tabsysprefs{emailLibrarianWhenHoldIsPlaced}="Circulation";
     $tabsysprefs{globalDueDate}="Circulation";
     $tabsysprefs{holdCancelLength}="Circulation";
     $tabsysprefs{itemBarcodeInputFilter}="Circulation";
-    $tabsysprefs{noOPACHolds}="Circulation";
     $tabsysprefs{WebBasedSelfCheck}="Circulation";
     $tabsysprefs{CircControl}="Circulation";
     $tabsysprefs{finesCalendar}="Circulation";
     $tabsysprefs{previousIssuesDefaultSortOrder}="Circulation";
     $tabsysprefs{todaysIssuesDefaultSortOrder}="Circulation";
+    $tabsysprefs{HomeOrHoldingBranch}="Circulation";
+    $tabsysprefs{RandomizeHoldsQueueWeight}="Circulation";
+    $tabsysprefs{StaticHoldsQueueWeight}="Circulation";
+    $tabsysprefs{AllowOnShelfHolds}="Circulation";
+    $tabsysprefs{AllowHoldsOnDamagedItems}="Circulation";
 
 # Staff Client
     $tabsysprefs{TemplateEncoding}="StaffClient";
@@ -149,7 +166,7 @@ my %tabsysprefs;
     $tabsysprefs{IntranetmainUserblock}="StaffClient";
     
 # Patrons
-    $tabsysprefs{automembernum}="Patrons";
+    $tabsysprefs{autoMemberNum}="Patrons";
     $tabsysprefs{checkdigit}="Patrons";
     $tabsysprefs{intranetreadinghistory}="Patrons";
     $tabsysprefs{NotifyBorrowerDeparture}="Patrons";
@@ -164,26 +181,23 @@ my %tabsysprefs;
     $tabsysprefs{NoReturnSetLost}="Patrons";
     $tabsysprefs{MaxFine}="Patrons";
     $tabsysprefs{NotifyBorrowerDeparture}="Patrons";
-
-# FRBR
-    $tabsysprefs{FRBRizeEditions}="FRBR";
-    $tabsysprefs{XISBN}="FRBR";
-    $tabsysprefs{OCLCAffiliateID}="FRBR";
-    $tabsysprefs{XISBNDailyLimit}="FRBR";
-    $tabsysprefs{PINESISBN}="FRBR";
-    $tabsysprefs{ThingISBN}="FRBR";
-    $tabsysprefs{OPACFRBRizeEditions}="FRBR";
-    $tabsysprefs{XISBNAmazonSimilarItems}="FRBR";
+    $tabsysprefs{AddPatronLists}="Patrons";
+    $tabsysprefs{PatronsPerPage}="Patrons";
+    $tabsysprefs{ExtendedPatronAttributes}="Patrons";
+    $tabsysprefs{AutoEmailOpacUser}="Patrons";
+    $tabsysprefs{AutoEmailPrimaryAddress}="Patrons";
+    $tabsysprefs{EnhancedMessagingPreferences}="Patrons";
+    $tabsysprefs{'SMSSendDriver'}             = 'Patrons';
 
 # I18N/L10N
     $tabsysprefs{dateformat}="I18N/L10N";
     $tabsysprefs{opaclanguages}="I18N/L10N";
     $tabsysprefs{opacthemes}="I18N/L10N";
+    $tabsysprefs{language}="I18N/L10N";
 
 # Searching
     $tabsysprefs{defaultSortField}="Searching";
     $tabsysprefs{defaultSortOrder}="Searching";
-    $tabsysprefs{maxItemsInSearchResults}="Searching";
     $tabsysprefs{numSearchResults}="Searching";
     $tabsysprefs{OPACdefaultSortField}="Searching";
     $tabsysprefs{OPACdefaultSortOrder}="Searching";
@@ -194,19 +208,48 @@ my %tabsysprefs;
     $tabsysprefs{QueryWeightFields}="Searching";
     $tabsysprefs{expandedSearchOption}="Searching";
     $tabsysprefs{sortbynonfiling}="Searching";
-
+    $tabsysprefs{QueryAutoTruncate}="Searching";
+    $tabsysprefs{QueryRemoveStopwords}="Searching";
+    $tabsysprefs{AdvancedSearchTypes}="Searching";
+
+# EnhancedContent
+   $tabsysprefs{AmazonContent}="EnhancedContent";
+   $tabsysprefs{AWSAccessKeyID}="EnhancedContent";
+   $tabsysprefs{AmazonLocale}="EnhancedContent";
+   $tabsysprefs{AmazonAssocTag}="EnhancedContent";
+   $tabsysprefs{AmazonSimilarItems}="EnhancedContent";
+   $tabsysprefs{OPACAmazonContent}="EnhancedContent";
+   $tabsysprefs{OPACAmazonSimilarItems}="EnhancedContent";
+
+# Baker & Taylor 
+   $tabsysprefs{BakerTaylorBookstoreURL} = 'EnhancedContent';
+   $tabsysprefs{BakerTaylorEnabled}      = 'EnhancedContent';
+   $tabsysprefs{BakerTaylorPassword}     = 'EnhancedContent';
+   $tabsysprefs{BakerTaylorUsername}     = 'EnhancedContent';
+# FRBR    
+   $tabsysprefs{FRBRizeEditions}="EnhancedContent";
+   $tabsysprefs{XISBN}="EnhancedContent";
+   $tabsysprefs{OCLCAffiliateID}="EnhancedContent";
+   $tabsysprefs{XISBNDailyLimit}="EnhancedContent";
+   $tabsysprefs{PINESISBN}="EnhancedContent";
+   $tabsysprefs{ThingISBN}="EnhancedContent";
+   $tabsysprefs{OPACFRBRizeEditions}="EnhancedContent";
+# Tags
+   $tabsysprefs{TagsEnabled}            = 'EnhancedContent';
+   $tabsysprefs{TagsExternalDictionary} = 'EnhancedContent';
+   $tabsysprefs{TagsInputOnDetail}      = 'EnhancedContent';
+   $tabsysprefs{TagsInputOnList}        = 'EnhancedContent';
+   $tabsysprefs{TagsShowOnDetail}       = 'EnhancedContent';
+   $tabsysprefs{TagsShowOnList}         = 'EnhancedContent';
+   $tabsysprefs{TagsModeration}         = 'EnhancedContent';
+   $tabsysprefs{GoogleJackets}          = 'EnhancedContent';
+   $tabsysprefs{AuthorisedValueImages}  = "EnhancedContent";
 
 # OPAC
-    $tabsysprefs{AmazonAssocTag}="OPAC";
-    $tabsysprefs{AmazonSimilarItems}="OPAC";
-    $tabsysprefs{AmazonContent}="OPAC";
-    $tabsysprefs{OPACAmazonContent}="OPAC";
-    $tabsysprefs{AmazonDevKey}="OPAC";
     $tabsysprefs{BiblioDefaultView}="OPAC";
     $tabsysprefs{LibraryName}="OPAC";
     $tabsysprefs{opaccolorstylesheet}="OPAC";
     $tabsysprefs{opaccredits}="OPAC";
-    $tabsysprefs{opaclargeimage}="OPAC";
     $tabsysprefs{opaclayoutstylesheet}="OPAC";
     $tabsysprefs{OpacNav}="OPAC";
     $tabsysprefs{opacsmallimage}="OPAC";
@@ -215,49 +258,59 @@ my %tabsysprefs;
     $tabsysprefs{opacuserjs}="OPAC";
     $tabsysprefs{SubscriptionHistory}="OPAC";
     $tabsysprefs{opacheader}="OPAC";
-    $tabsysprefs{OPACAmazonSimilarItems}="OPAC";
-    $tabsysprefs{OPACXISBNAmazonSimilarItems}="OPAC";
-
-    $tabsysprefs{hideBiblioNumber}="OPAC";
     $tabsysprefs{noOPACUserLogin}="OPAC";
+    $tabsysprefs{hideBiblioNumber}="OPAC";
     $tabsysprefs{OPACDisplayExtendedSubInfo}="OPAC";
     $tabsysprefs{OpacMainUserBlock}="OPAC";
     $tabsysprefs{OPACSubscriptionDisplay}="OPAC";
     $tabsysprefs{OPACURLOpenInNewWindow}="OPAC";
     $tabsysprefs{OPACUserCSS}="OPAC";
+    $tabsysprefs{OPACHighlightedWords}="OPAC";
     $tabsysprefs{OPACViewOthersSuggestions}="OPAC";
     $tabsysprefs{URLLinkText}="OPAC";
+    $tabsysprefs{OPACShelfBrowser}="OPAC";
 
-# OPACFeatures
-    $tabsysprefs{SearchMyLibraryFirst}="OPACFeatures";
-    $tabsysprefs{Disable_Dictionary}="OPACFeatures";
-    $tabsysprefs{hidelostitems}="OPACFeatures";
-    $tabsysprefs{opacbookbag}="OPACFeatures";
-    $tabsysprefs{opaclanguagesdisplay}="OPACFeatures";
-    $tabsysprefs{OpacPasswordChange}="OPACFeatures";
-    $tabsysprefs{opacreadinghistory}="OPACFeatures";
-    $tabsysprefs{virtualshelves}="OPACFeatures";
-    $tabsysprefs{RequestOnOpac}="OPACFeatures";
-    $tabsysprefs{reviewson}="OPACFeatures";
-    $tabsysprefs{OpacTopissues}="OPACFeatures";
-    $tabsysprefs{OpacAuthorities}="OPACFeatures";
-    $tabsysprefs{OpacCloud}="OPACFeatures";
-    $tabsysprefs{opacuserlogin}="OPACFeatures";
-    $tabsysprefs{AnonSuggestions}="OPACFeatures";
-    $tabsysprefs{suggestion}="OPACFeatures";
-    $tabsysprefs{OpacTopissue}="OPACFeatures";
-    $tabsysprefs{OpacBrowser}="OPACFeatures";
-    $tabsysprefs{kohaspsuggest} = "OPACFeatures";
+# OPAC
+    $tabsysprefs{SearchMyLibraryFirst}="OPAC";
+    $tabsysprefs{hidelostitems}="OPAC";
+    $tabsysprefs{opacbookbag}="OPAC";
+    $tabsysprefs{opaclanguagesdisplay}="OPAC";
+    $tabsysprefs{OpacPasswordChange}="OPAC";
+    $tabsysprefs{opacreadinghistory}="OPAC";
+    $tabsysprefs{virtualshelves}="OPAC";
+    $tabsysprefs{RequestOnOpac}="OPAC";
+    $tabsysprefs{reviewson}="OPAC";
+    $tabsysprefs{OpacTopissues}="OPAC";
+    $tabsysprefs{OpacAuthorities}="OPAC";
+    $tabsysprefs{OpacCloud}="OPAC";
+    $tabsysprefs{opacuserlogin}="OPAC";
+    $tabsysprefs{AnonSuggestions}="OPAC";
+    $tabsysprefs{suggestion}="OPAC";
+    $tabsysprefs{OpacTopissue}="OPAC";
+    $tabsysprefs{OpacBrowser}="OPAC";
+    $tabsysprefs{kohaspsuggest} = "OPAC";
+    $tabsysprefs{OpacRenewalAllowed} = "OPAC";
+    $tabsysprefs{OPACItemHolds} = "OPAC";
+    $tabsysprefs{OPACGroupResults}="OPAC";
+    $tabsysprefs{XSLTDetailsDisplay}="OPAC";
+    $tabsysprefs{XSLTResultsDisplay}="OPAC";
 
 # LOGFeatures
-    $tabsysprefs{CataloguingLog}  = "LOGFeatures";
-    $tabsysprefs{BorrowersLog}    = "LOGFeatures";
-    $tabsysprefs{SubscriptionLog} = "LOGFeatures";
-    $tabsysprefs{IssueLog}        = "LOGFeatures";
-    $tabsysprefs{ReturnLog}       = "LOGFeatures";
-    $tabsysprefs{LetterLog}       = "LOGFeatures";
-    $tabsysprefs{FinesLog}        = "LOGFeatures";
+    $tabsysprefs{CataloguingLog}  = "Logs";
+    $tabsysprefs{BorrowersLog}    = "Logs";
+    $tabsysprefs{SubscriptionLog} = "Logs";
+    $tabsysprefs{IssueLog}        = "Logs";
+    $tabsysprefs{ReturnLog}       = "Logs";
+    $tabsysprefs{LetterLog}       = "Logs";
+    $tabsysprefs{FinesLog}        = "Logs";
     
+# OAI-PMH variables
+   $tabsysprefs{'OAI-PMH'}           = "OAI-PMH";
+   $tabsysprefs{'OAI-PMH:archiveID'} = "OAI-PMH";
+   $tabsysprefs{'OAI-PMH:MaxCount'}  = "OAI-PMH";
+   $tabsysprefs{'OAI-PMH:Set'}       = "OAI-PMH";
+   $tabsysprefs{'OAI-PMH:Subset'}    = "OAI-PMH";
+
 sub StringSearch  {
     my ($searchstring,$type)=@_;
     my $dbh = C4::Context->dbh;
@@ -266,31 +319,17 @@ sub StringSearch  {
     my $count=@data;
     my @results;
     my $cnt=0;
+    my $sth;
 
     # used for doing a plain-old sys-pref search
-    if ($type eq 'all' ){
-        my $sth=$dbh->prepare("SELECT * FROM systempreferences 
-                WHERE variable LIKE ? OR explanation LIKE ? 
-                ORDER BY VARIABLE");
-        $sth->execute("%$searchstring%", "%$searchstring%");
-        while (my $data=$sth->fetchrow_hashref){
-            $data->{value} =~ s/</&lt;/g;
-            $data->{value} =~ s/>/&gt;/g;
-            $data->{value}=substr($data->{value},0,100)."..." if length($data->{value}) >100;
-            push(@results,$data);
-            $cnt++;
-        }
-        $sth->finish;
-
-    }  elsif ($type){
+    if ($type && $type ne 'all') {
         foreach my $syspref (sort { lc $a cmp lc $b } keys %tabsysprefs){
             if ($tabsysprefs{$syspref} eq $type){
                 my $sth=$dbh->prepare("Select variable,value,explanation,type,options from systempreferences where (variable like ?) order by variable");
                 $sth->execute($syspref);
                 while (my $data=$sth->fetchrow_hashref){
-                    $data->{value} =~ s/</&lt;/g;
-                    $data->{value} =~ s/>/&gt;/g;
-                    $data->{value}=substr($data->{value},0,100)."..." if length($data->{value}) >100;
+                    $data->{shortvalue} = $data->{value};
+                    $data->{shortvalue} = substr($data->{value},0,60)."..." if defined($data->{value}) and length($data->{value}) >60;
                     push(@results,$data);
                     $cnt++;
                 }
@@ -298,27 +337,150 @@ sub StringSearch  {
             }
         }
     } else {
-        my $strsth ="Select variable,value,explanation,type,options from systempreferences where variable not in (";
-        foreach my $syspref (keys %tabsysprefs){
-            $strsth .= $dbh->quote($syspref).",";
+               my $sth;
+
+        if ($type and $type eq 'all' ){
+            $sth=$dbh->prepare("
+            SELECT *
+              FROM systempreferences 
+              WHERE variable LIKE ? OR explanation LIKE ? 
+              ORDER BY VARIABLE");
+            $sth->execute("%$searchstring%", "%$searchstring%");
+        } else {
+            my $strsth ="Select variable,value,explanation,type,options from systempreferences where variable not in (";
+            foreach my $syspref (keys %tabsysprefs){
+                $strsth .= $dbh->quote($syspref).",";
+            }
+            $strsth =~ s/,$/) /;
+            $strsth .= " order by variable";
+            $sth=$dbh->prepare($strsth);
+            $sth->execute();
         }
-        $strsth =~ s/,$/) /;
-        $strsth .= " order by variable";
-        my $sth=$dbh->prepare($strsth);
-        $sth->execute();
-        while (my $data=$sth->fetchrow_hashref){
-            $data->{value}=substr($data->{value},0,100);
-            push(@results,$data);
-            $cnt++;
+
+               while (my $data=$sth->fetchrow_hashref){
+                       $data->{shortvalue} = $data->{value};
+                       $data->{shortvalue} = substr($data->{value},0,60)."..." if length($data->{value}) >60;
+                       push(@results,$data);
+                       $cnt++;
+               }
+
+               $sth->finish;
+    }  
+    return ($cnt,\@results);
+}
+
+sub GetPrefParams {
+    my $data = shift;
+    my $params = $data;
+    my @options;
+   
+    if (defined $data->{'options'}) { 
+        foreach my $option (split(/\|/, $data->{'options'})) {
+            my $selected='0';
+            defined($data->{'value'}) and $option eq $data->{'value'} and $selected=1;
+            push @options, { option => $option, selected => $selected };
         }
-        $sth->finish;
     }
-    return ($cnt,\@results);
+
+    $params->{'prefoptions'} = $data->{'options'};
+
+    if (not defined($data->{'type'})) {
+        $params->{'type-free'} = 1;
+        $params->{'fieldlength'} = (defined($data->{'options'}) and $data->{'options'} and $data->{'options'}>0)
+    } elsif ($data->{'type'} eq 'Choice') {
+        $params->{'type-choice'} = 1;
+    } elsif ($data->{'type'} eq 'YesNo') {
+        $params->{'type-yesno'} = 1;
+        $data->{'value'}=C4::Context->boolean_preference($data->{'variable'});
+        if (defined($data->{'value'}) and $data->{'value'} eq '1') {
+            $params->{'value-yes'} = 1;
+        } else {
+            $params->{'value-no'} = 1;
+        }
+    } elsif ($data->{'type'} eq 'Integer' || $data->{'type'} eq 'Float') {
+        $params->{'type-free'} = 1;
+        $params->{'fieldlength'} = (defined($data->{'options'}) and $data->{'options'} and $data->{'options'}>0)
+                                   ? $data->{'options'} : 10;
+    } elsif ($data->{'type'} eq 'Textarea') {
+        $params->{'type-textarea'} = 1;
+        $data->{options} =~ /(.*)\|(.*)/;
+        $params->{'cols'} = $1;
+        $params->{'rows'} = $2;
+    } elsif ($data->{'type'} eq 'Themes') {
+        $params->{'type-choice'} = 1;
+        my $type='';
+        ($data->{'variable'}=~m#opac#i) ? ($type='opac') : ($type='intranet');
+        @options=();
+        my $currently_selected_themes;
+        my $counter=0;
+        foreach my $theme (split /\s+/, $data->{'value'}) {
+            push @options, { option => $theme, counter => $counter };
+            $currently_selected_themes->{$theme}=1;
+            $counter++;
+        }
+        foreach my $theme (getallthemes($type)) {
+            my $selected='0';
+            next if $currently_selected_themes->{$theme};
+            push @options, { option => $theme, counter => $counter };
+            $counter++;
+        }
+    } elsif ($data->{'type'} eq 'ClassSources') {
+        $params->{'type-choice'} = 1;
+        my $type='';
+        @options=();
+        my $sources = GetClassSources();
+        my $counter=0;
+        foreach my $cn_source (sort keys %$sources) {
+            if ($cn_source eq $data->{'value'}) {
+                push @options, { option => $cn_source, counter => $counter, selected => 1 };
+            } else {
+                push @options, { option => $cn_source, counter => $counter };
+            }
+            $counter++; 
+        }
+    } elsif ($data->{'type'} eq 'Languages') {
+    my $currently_selected_languages;
+        foreach my $language (split /\s+/, $data->{'value'}) {
+            $currently_selected_languages->{$language}=1;
+        }
+        # current language
+        my $lang = $params->{'lang'};
+        my $theme;
+        my $interface;
+        if ($data->{'variable'} =~ /opac/) {
+            # this is the OPAC
+            $interface = 'opac';
+                $theme = C4::Context->preference('opacthemes');
+        }
+        else {
+            # this is the staff client  
+            $interface = 'intranet';
+            $theme = C4::Context->preference('template');
+        }
+        my $languages_loop = getTranslatedLanguages($interface,$theme,$lang,$currently_selected_languages);
+
+        $params->{'languages_loop'} = $languages_loop;
+        $params->{'type-langselector'} = 1;
+    } else {
+        $params->{'type-free'} = 1;
+        $params->{'fieldlength'} = (defined($data->{'options'}) and $data->{'options'} and $data->{'options'}>0)
+                                   ? $data->{'options'} : 30;
+    }
+
+    if ( $params->{'type-choice'} || $params->{'type-free'} || $params->{'type-yesno'} ) {
+        $params->{'oneline'} = 1;
+    }
+
+       $params->{'preftype'} = $data->{'type'};
+    $params->{'options'} = \@options;
+
+    return $params;
 }
 
 my $input = new CGI;
-my $searchfield=$input->param('searchfield');
-my $offset=$input->param('offset');
+my $searchfield = $input->param('searchfield') || '';
+my $Tvalue = $input->param('Tvalue');
+my $offset = $input->param('offset') || 0;
 my $script_name="/cgi-bin/koha/admin/systempreferences.pl";
 
 my ($template, $borrowernumber, $cookie)
@@ -330,7 +492,7 @@ my ($template, $borrowernumber, $cookie)
                  debug => 1,
                  });
 my $pagesize=100;
-my $op = $input->param('op');
+my $op = $input->param('op') || '';
 $searchfield=~ s/\,//g;
 
 if ($op) {
@@ -380,16 +542,18 @@ if ($op eq 'update_and_reedit') {
     my $sth=$dbh->prepare($query);
     $sth->execute($input->param('variable'));
     if ($sth->rows) {
-        unless (C4::Context->config('demo') eq 1) {
+        unless (C4::Context->config('demo')) {
             my $sth=$dbh->prepare("update systempreferences set value=?,explanation=?,type=?,options=? where variable=?");
             $sth->execute($value, $input->param('explanation'), $input->param('variable'), $input->param('preftype'), $input->param('prefoptions'));
             $sth->finish;
+            logaction('SYSTEMPREFERENCE','MODIFY',undef, $input->param('variable') . " | " . $value );
         }
     } else {
-        unless (C4::Context->config('demo') eq 1) {
+        unless (C4::Context->config('demo')) {
             my $sth=$dbh->prepare("insert into systempreferences (variable,value,explanation) values (?,?,?,?,?)");
             $sth->execute($input->param('variable'), $input->param('value'), $input->param('explanation'), $input->param('preftype'), $input->param('prefoptions'));
             $sth->finish;
+            logaction('SYSTEMPREFERENCE','ADD',undef, $input->param('variable') . " | " . $input->param('value') );
         }
     }
     $sth->finish;
@@ -413,91 +577,11 @@ if ($op eq 'add_form') {
         $template->param(return_tab => $tabsysprefs{$searchfield});
     }
 
-    my @options;
-    foreach my $option (split(/\|/, $data->{'options'})) {
-        my $selected='0';
-        $option eq $data->{'value'} and $selected=1;
-        push @options, { option => $option, selected => $selected };
-    }
-    if ($data->{'type'} eq 'Choice') {
-        $template->param('type-choice' => 1);
-    } elsif ($data->{'type'} eq 'YesNo') {
-        $template->param('type-yesno' => 1);
-        $data->{'value'}=C4::Context->boolean_preference($data->{'variable'});
-        ($data->{'value'} eq '1') ? ($template->param('value-yes'=>1)) : ($template->param('value-no'=>1));
-    } elsif ($data->{'type'} eq 'Integer') {
-        $template->param('type-free' => 1);
-        $template->param('fieldlength' => $data->{'options'});
-    } elsif ($data->{'type'} eq 'Textarea') {
-        $template->param('type-textarea' => 1);
-        $data->{options} =~ /(.*)\|(.*)/;
-        $template->param('cols' => $1, 'rows' => $2);;
-    } elsif ($data->{'type'} eq 'Float') {
-        $template->param('type-free' => 1);
-        $template->param('fieldlength' => $data->{'options'});
-    } elsif ($data->{'type'} eq 'Themes') {
-        $template->param('type-choice' => 1);
-        my $type='';
-        ($data->{'variable'}=~m#opac#i) ? ($type='opac') : ($type='intranet');
-        @options=();
-        my $currently_selected_themes;
-        my $counter=0;
-        foreach my $theme (split /\s+/, $data->{'value'}) {
-            push @options, { option => $theme, counter => $counter };
-            $currently_selected_themes->{$theme}=1;
-            $counter++;
-        }
-        foreach my $theme (getallthemes($type)) {
-            my $selected='0';
-            next if $currently_selected_themes->{$theme};
-            push @options, { option => $theme, counter => $counter };
-            $counter++;
-        }
-    } elsif ($data->{'type'} eq 'ClassSources') {
-        $template->param('type-choice' => 1);
-        my $type='';
-        @options=();
-        my $sources = GetClassSources();
-        my $counter=0;
-        foreach my $cn_source (sort keys %$sources) {
-            if ($cn_source eq $data->{'value'}) {
-                push @options, { option => $cn_source, counter => $counter, selected => 1 };
-            } else {
-                push @options, { option => $cn_source, counter => $counter };
-            }
-            $counter++; 
-        }
-    } elsif ($data->{'type'} eq 'Languages') {
-        $template->param('type-choice' => 1);
-        my $type='';
-        @options=();
-        my $currently_selected_languages;
-        my $counter=0;
-        foreach my $language (split /\s+/, $data->{'value'}) {
-            next if $language eq 'images';
-            push @options, { option => $language, counter => $counter };
-            $currently_selected_languages->{$language}=1;
-            $counter++;
-        }
-        my $langavail = getTranslatedLanguages();
-        foreach my $language (@$langavail) {
-            my $selected='0';
-            next if $currently_selected_languages->{$language->{'language_code'}};
-            #FIXME: could add language_name and language_locale_name for better display
-            push @options, { option => $language->{'language_code'}, counter => $counter };
-            $counter++;
-        }
-    } else {
-        $template->param('type-free' => 1);
-        $template->param('fieldlength' => $data->{'options'}>0?$data->{'options'}:60);
-    }
-    $template->param(explanation => $data->{'explanation'},
-             value => $data->{'value'},
-             type => $data->{'type'},
-             options => \@options,
-             preftype => $data->{'type'},
-             prefoptions => $data->{'options'},
-             searchfield => $searchfield);
+    $data->{'lang'} = $template->param('lang');
+
+    $template->param( GetPrefParams( $data ) );
+
+    $template->param( searchfield => $searchfield );
 
 ################## ADD_VALIDATE ##################################
 # called by add_form, used to insert/modify data in DB
@@ -505,17 +589,29 @@ if ($op eq 'add_form') {
     my $dbh = C4::Context->dbh;
     my $sth=$dbh->prepare("select * from systempreferences where variable=?");
     $sth->execute($input->param('variable'));
+    # to handle multiple values
+    my $value;
+    # handle multiple value strings (separated by ',')
+    my $params = $input->Vars;
+    my @values = ();
+    @values = split("\0",$params->{'value'}) if $params->{'value'};
+    for my $vl (@values) {
+        $value .= "$vl,";
+    }
+    $value =~ s/,$//;
     if ($sth->rows) {
-        unless (C4::Context->config('demo') eq 1) {
+        unless (C4::Context->config('demo')) {
             my $sth=$dbh->prepare("update systempreferences set value=?,explanation=?,type=?,options=? where variable=?");
-            $sth->execute($input->param('value'), $input->param('explanation'), $input->param('preftype'), $input->param('prefoptions'), $input->param('variable'));
+            $sth->execute($value, $input->param('explanation'), $input->param('preftype'), $input->param('prefoptions'), $input->param('variable'));
             $sth->finish;
+            logaction('SYSTEMPREFERENCE','MODIFY',undef, $input->param('variable') . " | " . $value );
         }
     } else {
-        unless (C4::Context->config('demo') eq 1) {
+        unless (C4::Context->config('demo')) {
             my $sth=$dbh->prepare("insert into systempreferences (variable,value,explanation,type,options) values (?,?,?,?,?)");
-            $sth->execute($input->param('variable'), $input->param('value'), $input->param('explanation'), $input->param('preftype'), $input->param('prefoptions'));
+            $sth->execute($input->param('variable'), $value, $input->param('explanation'), $input->param('preftype'), $input->param('prefoptions'));
             $sth->finish;
+            logaction('SYSTEMPREFERENCE','ADD',undef, $input->param('variable') . " | " . $value );
         }
     }
     $sth->finish;
@@ -540,6 +636,8 @@ if ($op eq 'add_form') {
     my $dbh = C4::Context->dbh;
     my $sth=$dbh->prepare("delete from systempreferences where variable=?");
     $sth->execute($searchfield);
+    my $logstring =  $searchfield . " | " . $Tvalue ;
+    logaction('SYSTEMPREFERENCE','DELETE',undef,$logstring);
     $sth->finish;
 
                                                     # END $OP eq DELETE_CONFIRMED
@@ -552,23 +650,20 @@ if ($op eq 'add_form') {
     my $toggle=0;
     my @loop_data = ();
     for (my $i=$offset; $i < ($offset+$pagesize<$count?$offset+$pagesize:$count); $i++){
-          if ($toggle eq 0){
+          if ($toggle == 0){
             $toggle=1;
           } else {
             $toggle=0;
           }
-        my %row_data;  # get a fresh hash for the row data
-        $row_data{variable} = $results->[$i]{'variable'};
-        $row_data{value} = $results->[$i]{'value'};
-        $row_data{yes} = 1 if ($results->[$i]{'value'} == 1);
-        $row_data{yesno} = 1 if ($results->[$i]{'type'} eq 'YesNo');
-        $row_data{explanation} = $results->[$i]{'explanation'};
-        $row_data{toggle} = $toggle;
-        $row_data{edit} = "$script_name?op=add_form&amp;searchfield=".$results->[$i]{'variable'};
-        $row_data{delete} = "$script_name?op=delete_confirm&amp;searchfield=".$results->[$i]{'variable'};
-        push(@loop_data, \%row_data);
+        my $row_data = $results->[$i];
+        $row_data->{'lang'} = $template->param('lang');
+        $row_data = GetPrefParams( $row_data );  # get a fresh hash for the row data
+        $row_data->{toggle} = $toggle;
+        $row_data->{edit} = "$script_name?op=add_form&amp;searchfield=".$results->[$i]{'variable'};
+        $row_data->{delete} = "$script_name?op=delete_confirm&amp;searchfield=".$results->[$i]{'variable'};
+        push(@loop_data, $row_data);
     }
-    $tab=($tab?$tab:"Others");
+    $tab=($tab?$tab:"Local Use");
     $template->param(loop => \@loop_data, $tab => 1);
     if ($offset>0) {
         my $prevpage = $offset-$pagesize;