Main Koha release repository https://koha-community.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

329 lines
8.4 KiB

  1. #!/usr/bin/perl
  2. #
  3. # Copyright 2010 Jesse Weaver, Koha Dev Team
  4. #
  5. # This file is part of Koha.
  6. #
  7. # Koha is free software; you can redistribute it and/or modify it
  8. # under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # Koha is distributed in the hope that it will be useful, but
  13. # WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with Koha; if not, see <http://www.gnu.org/licenses>.
  19. #
  20. use Modern::Perl;
  21. use Koha::Script;
  22. use C4::Boolean;
  23. use C4::Context;
  24. use C4::Debug;
  25. use C4::Log;
  26. use Getopt::Long;
  27. use Pod::Usage;
  28. use YAML::Syck qw();
  29. $YAML::Syck::ImplicitTyping = 1;
  30. $YAML::Syck::SortKeys = 1;
  31. our %NOT_SET_PREFS = map { $_, 1 } qw( Version );
  32. =head1 NAME
  33. koha-preferences - Get, set, dump and load Koha system preferences
  34. =head1 SYNOPSIS
  35. misc/admin/koha-preferences COMMAND ...
  36. =cut
  37. sub print_usage {
  38. my ( $annoyed ) = @_;
  39. if ( $annoyed ) {
  40. pod2usage( -verbose => 1, -exitval => 1, -output => \*STDERR );
  41. } else {
  42. pod2usage( -verbose => 1, -exitval => 0 );
  43. }
  44. }
  45. sub _debug {
  46. my ( $message ) = @_;
  47. print STDERR $message . "\n" if ( $C4::Debug::debug );
  48. }
  49. sub _normalize_value {
  50. my ($row) = @_;
  51. # AFAIK, there are no sysprefs where NULL has a different meaning than ''.
  52. return ( $row->{'value'} || '' ) unless ( $row->{'type'} eq 'YesNo' );
  53. #
  54. # In theory, YesNo sysprefs should always contain 1/0.
  55. # In practice, however, they don't.
  56. # - Yogi Berra
  57. #
  58. my $bool_value = eval {
  59. return C4::Boolean::true_p( $row->{'value'} ) ? 1 : 0;
  60. };
  61. if ( $@ ) {
  62. return 0;
  63. } else {
  64. return $bool_value;
  65. }
  66. }
  67. sub _set_preference {
  68. my ( $preference, $value ) = @_;
  69. _debug( "Setting $preference to $value" );
  70. C4::Context->set_preference( $preference, $value );
  71. }
  72. sub GetPreferences {
  73. my $dbh = C4::Context->dbh;
  74. return {
  75. map { $_->{'variable'}, _normalize_value($_) }
  76. @{ $dbh->selectall_arrayref( "
  77. SELECT
  78. variable, value, type
  79. FROM systempreferences
  80. ", { Slice => {} } ) }
  81. };
  82. }
  83. sub SetPreferences {
  84. my ( %preferences ) = @_;
  85. my $dbh = C4::Context->dbh;
  86. # First, a quick check to make sure all of the system preferences exist
  87. my $current_state = $dbh->selectall_arrayref( "
  88. SELECT
  89. variable, type, value
  90. FROM systempreferences
  91. WHERE variable IN (" . join( ', ', map( "?", keys %preferences ) ) . ")
  92. ", { Slice => {} }, keys %preferences );
  93. exit 2 if ( scalar( @$current_state ) != scalar( keys %preferences ) );
  94. foreach my $row ( @$current_state ) {
  95. # YAML::Syck encodes no as '', so deal with that
  96. $preferences{$row->{'variable'}} = $preferences{$row->{'variable'}} eq '' ? 0 : C4::Boolean::true_p( $preferences{$row->{'variable'}} ) if ( $row->{'type'} eq 'YesNo' );
  97. }
  98. # Iterate through again, now that we've checked all of the YesNo sysprefs
  99. foreach my $row ( @$current_state ) {
  100. next if ( $preferences{$row->{'variable'}} eq $row->{'value'} );
  101. _set_preference( $row->{'variable'}, $preferences{$row->{'variable'}} );
  102. }
  103. # FIXME This may be not needed
  104. C4::Context->clear_syspref_cache();
  105. }
  106. sub _fetch_preference {
  107. my ( $preference ) = @_;
  108. my $dbh = C4::Context->dbh;
  109. my $row = $dbh->selectrow_hashref( "
  110. SELECT
  111. variable, value, type
  112. FROM systempreferences
  113. WHERE variable = ?
  114. LIMIT 1
  115. ", {}, $preference );
  116. exit 2 unless ( $row );
  117. return $row;
  118. }
  119. sub GetPreference {
  120. my ( $preference ) = @_;
  121. my $row = _fetch_preference( $preference );
  122. return _normalize_value( $row );
  123. }
  124. sub SetPreference {
  125. my ( $preference, $value ) = @_;
  126. my $row = _fetch_preference( $preference );
  127. $value = C4::Boolean::true_p($value) ? 1 : 0 if ( $row->{'type'} eq 'YesNo' );
  128. exit 3 if ( $value eq $row->{'value'} );
  129. _set_preference( $preference, $value );
  130. }
  131. sub ClearPreference {
  132. my ( $preference ) = @_;
  133. my $value = '';
  134. my $row = _fetch_preference( $preference );
  135. $value = 0 if ( $row->{'type'} eq 'YesNo' );
  136. exit 3 if ( $value eq $row->{'value'} );
  137. _set_preference( $preference, $value );
  138. }
  139. =head1 OPTIONS
  140. COMMAND can be any of the following:
  141. =over
  142. =item B<dump> [ -o I<OUTFILE> ]
  143. Dump all of Koha's system preferences as a simple YAML mapping into OUTFILE or
  144. STDOUT.
  145. =item B<load> [ -i I<INFILE> ] [ -f|--force ]
  146. Reads system preferences specified in YAML in INFILE or STDIN. Will exit with a
  147. status of 2, without setting any sysprefs, if any of the sysprefs do not exist.
  148. Will also exit if any of the sysprefs are YesNo and have an invalid value.
  149. If there is a Version syspref in the input, it will not be set in the database,
  150. but it will be checked to make sure the running Koha version is equal or higher.
  151. The script will exit with a status of 4 if this is not true. Pass the -f option
  152. to skip this check.
  153. =item B<get> I<PREFERENCE>
  154. Print the value of the system preference PREFERENCE, followed by a newline. If
  155. no such syspref exists, will exit with a status of 2.
  156. =item B<set> I<PREFERENCE> I<VALUE>
  157. Set the system preference PREFERENCE to the value VALUE. If no such syspref
  158. exists, will exit with a status of 2. If the syspref already has that value,
  159. will exit with a status of 3.
  160. If the syspref is YesNo, will accept only a boolean value, but the syntax for
  161. these is fairly lax (yes/no, on/off, 1/0, n/y, true/false are all accepted).
  162. =item B<clear> I<PREFERENCE>
  163. Clears the value of the system preference PREFERENCE. If no such syspref exists,
  164. will exit with a status of 2. Will set YesNo sysprefs to 'false'.
  165. =item B<manual>
  166. Print a longer, more detailed manual.
  167. =cut
  168. my %commands = (
  169. dump => sub{
  170. my ( $outfile );
  171. GetOptions(
  172. 'o:s' => \$outfile
  173. ) || _print_usage( 1 );
  174. if ( $outfile ) {
  175. YAML::Syck::DumpFile( $outfile, GetPreferences() );
  176. } else {
  177. print YAML::Syck::Dump( GetPreferences() );
  178. }
  179. },
  180. load => sub {
  181. my ( $infile, $force_version );
  182. GetOptions(
  183. 'i:s' => \$infile,
  184. 'f' => \$force_version,
  185. );
  186. my $preferences = YAML::Syck::LoadFile($infile || \*STDIN);
  187. die "Expected a YAML mapping" if ( ref($preferences) ne 'HASH' );
  188. die "Tried to load preferences for version " . $preferences->{'Version'} . ", we are " . C4::Context->preference( 'Version' ) if ( $preferences->{'Version'} && C4::Context->preference( 'Version' ) < $preferences->{'Version'} );
  189. my %prefs_to_set = (
  190. map { $_, $preferences->{$_} }
  191. grep { !$NOT_SET_PREFS{$_} }
  192. keys %$preferences
  193. );
  194. SetPreferences( %prefs_to_set );
  195. },
  196. get => sub {
  197. my ( $preference ) = @_;
  198. print_usage() unless ( $preference );
  199. print GetPreference( $preference ) . "\n";
  200. },
  201. set => sub {
  202. my ( $preference, $value ) = @_;
  203. print_usage() unless ( $preference && defined($value) );
  204. SetPreference( $preference, $value );
  205. },
  206. clear => sub {
  207. my ( $preference ) = @_;
  208. print_usage() unless ( $preference );
  209. ClearPreference( $preference );
  210. },
  211. manual => sub {
  212. pod2usage( -verbose => 2 );
  213. }
  214. );
  215. print_usage() if ( $ARGV[0] =~ /^(-h|--help|-help|help)$/ );
  216. print_usage( 1 ) if ( !$ARGV[0] || ref($commands{$ARGV[0]}) ne 'CODE' );
  217. my $command = $commands{$ARGV[0]};
  218. shift @ARGV;
  219. $command->(@ARGV);
  220. =item B<help>
  221. Print a short usage message.
  222. =back
  223. =head1 EXAMPLES
  224. $ export KOHA_DEBUG=1 # Used here to show what is being stored
  225. $ misc/admin/koha-preferences get viewISBD
  226. 0
  227. $ misc/admin/koha-preferences set viewISBD on
  228. Setting viewISBD to 1
  229. $ misc/admin/koha-preferences dump -o preferences.yaml
  230. $ [ edit preferences.yaml ]
  231. $ misc/admin/koha-preferences load -i preferences.yaml
  232. $ misc/admin/koha-preferences load -i preferences-too-new.yaml
  233. Tried to load preferences for version 3.0500012, we are 3.0300009 at misc/admin/koha-preferences line 255
  234. $ misc/admin/koha-preferences load # Can also work from STDIN
  235. XISBN: false
  236. viewMARC: y
  237. [ Control-D ]
  238. Setting viewMARC to 1
  239. Setting XISBN to 0
  240. =cut