|
Lines 61-66
use Koha::Filter::MARC::ViewPolicy;
Link Here
|
| 61 |
use C4::Members::Statistics; |
61 |
use C4::Members::Statistics; |
| 62 |
|
62 |
|
| 63 |
my $query = CGI->new; |
63 |
my $query = CGI->new; |
|
|
64 |
my $params = $query->Vars(); |
| 65 |
|
| 64 |
my ( $template, $loggedinuser, $cookie ) = get_template_and_user( |
66 |
my ( $template, $loggedinuser, $cookie ) = get_template_and_user( |
| 65 |
{ |
67 |
{ |
| 66 |
template_name => "about.tt", |
68 |
template_name => "about.tt", |
|
Lines 70-75
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
Link Here
|
| 70 |
} |
72 |
} |
| 71 |
); |
73 |
); |
| 72 |
|
74 |
|
|
|
75 |
my $tab = $params->{tab} || 'about'; |
| 76 |
|
| 77 |
$template->param( |
| 78 |
tab => $tab, |
| 79 |
); |
| 80 |
|
| 73 |
my $docdir; |
81 |
my $docdir; |
| 74 |
if ( defined C4::Context->config('docdir') ) { |
82 |
if ( defined C4::Context->config('docdir') ) { |
| 75 |
$docdir = C4::Context->config('docdir'); |
83 |
$docdir = C4::Context->config('docdir'); |
|
Lines 81-884
if ( defined C4::Context->config('docdir') ) {
Link Here
|
| 81 |
} |
89 |
} |
| 82 |
|
90 |
|
| 83 |
my %versions = C4::Context::get_versions(); |
91 |
my %versions = C4::Context::get_versions(); |
| 84 |
my $config_timezone = C4::Context->config('timezone') // ''; |
|
|
| 85 |
my $config_invalid = !DateTime::TimeZone->is_valid_name( $config_timezone ); |
| 86 |
my $env_timezone = $ENV{TZ} // ''; |
| 87 |
my $env_invalid = !DateTime::TimeZone->is_valid_name( $env_timezone ); |
| 88 |
my $actual_bad_tz_fallback = 0; |
| 89 |
|
| 90 |
if ( $config_timezone ne '' && |
| 91 |
$config_invalid ) { |
| 92 |
# Bad config |
| 93 |
$actual_bad_tz_fallback = 1; |
| 94 |
} |
| 95 |
elsif ( $config_timezone eq '' && |
| 96 |
$env_timezone ne '' && |
| 97 |
$env_invalid ) { |
| 98 |
# No config, but bad ENV{TZ} |
| 99 |
$actual_bad_tz_fallback = 1; |
| 100 |
} |
| 101 |
|
92 |
|
| 102 |
my $time_zone = { |
93 |
if ( $tab eq 'about' ) { |
| 103 |
actual => C4::Context->tz->name, |
94 |
|
| 104 |
actual_bad_tz_fallback => $actual_bad_tz_fallback, |
95 |
my $config_timezone = C4::Context->config('timezone') // ''; |
| 105 |
config => $config_timezone, |
96 |
my $config_invalid = !DateTime::TimeZone->is_valid_name( $config_timezone ); |
| 106 |
config_invalid => $config_invalid, |
97 |
my $env_timezone = $ENV{TZ} // ''; |
| 107 |
environment => $env_timezone, |
98 |
my $env_invalid = !DateTime::TimeZone->is_valid_name( $env_timezone ); |
| 108 |
environment_invalid => $env_invalid |
99 |
my $actual_bad_tz_fallback = 0; |
| 109 |
}; |
100 |
|
| 110 |
|
101 |
if ( $config_timezone ne '' && |
| 111 |
{ # Logger checks |
102 |
$config_invalid ) { |
| 112 |
my $log4perl_config = C4::Context->config("log4perl_conf"); |
103 |
# Bad config |
| 113 |
my @log4perl_errors; |
104 |
$actual_bad_tz_fallback = 1; |
| 114 |
if ( ! $log4perl_config ) { |
|
|
| 115 |
push @log4perl_errors, 'missing_config_entry' |
| 116 |
} |
105 |
} |
| 117 |
else { |
106 |
elsif ( $config_timezone eq '' && |
| 118 |
my @lines = read_file($log4perl_config) or push @log4perl_errors, 'cannot_read_config_file'; |
107 |
$env_timezone ne '' && |
| 119 |
for my $line ( @lines ) { |
108 |
$env_invalid ) { |
| 120 |
next unless $line =~ m|log4perl.appender.\w+.filename=(.*)|; |
109 |
# No config, but bad ENV{TZ} |
| 121 |
push @log4perl_errors, 'logfile_not_writable' unless -w $1; |
110 |
$actual_bad_tz_fallback = 1; |
| 122 |
} |
|
|
| 123 |
} |
111 |
} |
| 124 |
eval {Koha::Logger->get}; |
|
|
| 125 |
push @log4perl_errors, 'cannot_init_module' and warn $@ if $@; |
| 126 |
$template->param( log4perl_errors => @log4perl_errors ); |
| 127 |
} |
| 128 |
|
| 129 |
$template->param( |
| 130 |
time_zone => $time_zone, |
| 131 |
current_date_and_time => output_pref({ dt => dt_from_string(), dateformat => 'iso' }) |
| 132 |
); |
| 133 |
|
112 |
|
| 134 |
my $perl_path = $^X; |
113 |
my $time_zone = { |
| 135 |
if ($^O ne 'VMS') { |
114 |
actual => C4::Context->tz->name, |
| 136 |
$perl_path .= $Config{_exe} unless $perl_path =~ m/$Config{_exe}$/i; |
115 |
actual_bad_tz_fallback => $actual_bad_tz_fallback, |
| 137 |
} |
116 |
config => $config_timezone, |
|
|
117 |
config_invalid => $config_invalid, |
| 118 |
environment => $env_timezone, |
| 119 |
environment_invalid => $env_invalid |
| 120 |
}; |
| 138 |
|
121 |
|
| 139 |
my $zebraVersion = `zebraidx -V`; |
122 |
{ # Logger checks |
|
|
123 |
my $log4perl_config = C4::Context->config("log4perl_conf"); |
| 124 |
my @log4perl_errors; |
| 125 |
if ( ! $log4perl_config ) { |
| 126 |
push @log4perl_errors, 'missing_config_entry' |
| 127 |
} |
| 128 |
else { |
| 129 |
my @lines = read_file($log4perl_config) or push @log4perl_errors, 'cannot_read_config_file'; |
| 130 |
for my $line ( @lines ) { |
| 131 |
next unless $line =~ m|log4perl.appender.\w+.filename=(.*)|; |
| 132 |
push @log4perl_errors, 'logfile_not_writable' unless -w $1; |
| 133 |
} |
| 134 |
} |
| 135 |
eval {Koha::Logger->get}; |
| 136 |
push @log4perl_errors, 'cannot_init_module' and warn $@ if $@; |
| 137 |
$template->param( log4perl_errors => @log4perl_errors ); |
| 138 |
} |
| 140 |
|
139 |
|
| 141 |
# Check running PSGI env |
|
|
| 142 |
if ( C4::Context->psgi_env ) { |
| 143 |
$template->param( |
140 |
$template->param( |
| 144 |
is_psgi => 1, |
141 |
time_zone => $time_zone, |
| 145 |
psgi_server => ($ENV{ PLACK_ENV }) ? "Plack ($ENV{PLACK_ENV})" : |
142 |
current_date_and_time => output_pref({ dt => dt_from_string(), dateformat => 'iso' }) |
| 146 |
($ENV{ MOD_PERL }) ? "mod_perl ($ENV{MOD_PERL})" : |
|
|
| 147 |
'Unknown' |
| 148 |
); |
143 |
); |
| 149 |
} |
|
|
| 150 |
|
144 |
|
| 151 |
# Memcached configuration |
145 |
my $perl_path = $^X; |
| 152 |
my $memcached_servers = $ENV{MEMCACHED_SERVERS} || C4::Context->config('memcached_servers'); |
146 |
if ($^O ne 'VMS') { |
| 153 |
my $memcached_namespace = $ENV{MEMCACHED_NAMESPACE} || C4::Context->config('memcached_namespace') // 'koha'; |
147 |
$perl_path .= $Config{_exe} unless $perl_path =~ m/$Config{_exe}$/i; |
| 154 |
|
148 |
} |
| 155 |
my $cache = Koha::Caches->get_instance; |
|
|
| 156 |
my $effective_caching_method = ref($cache->cache); |
| 157 |
# Memcached may have been running when plack has been initialized but could have been stopped since |
| 158 |
# FIXME What are the consequences of that?? |
| 159 |
my $is_memcached_still_active = $cache->set_in_cache('test_for_about_page', "just a simple value"); |
| 160 |
|
| 161 |
my $where_is_memcached_config = 'nowhere'; |
| 162 |
if ( $ENV{MEMCACHED_SERVERS} and C4::Context->config('memcached_servers') ) { |
| 163 |
$where_is_memcached_config = 'both'; |
| 164 |
} elsif ( $ENV{MEMCACHED_SERVERS} and not C4::Context->config('memcached_servers') ) { |
| 165 |
$where_is_memcached_config = 'ENV_only'; |
| 166 |
} elsif ( C4::Context->config('memcached_servers') ) { |
| 167 |
$where_is_memcached_config = 'config_only'; |
| 168 |
} |
| 169 |
|
149 |
|
| 170 |
$template->param( |
150 |
my $zebraVersion = `zebraidx -V`; |
| 171 |
effective_caching_method => $effective_caching_method, |
151 |
|
| 172 |
memcached_servers => $memcached_servers, |
152 |
# Check running PSGI env |
| 173 |
memcached_namespace => $memcached_namespace, |
153 |
if ( C4::Context->psgi_env ) { |
| 174 |
is_memcached_still_active => $is_memcached_still_active, |
154 |
$template->param( |
| 175 |
where_is_memcached_config => $where_is_memcached_config, |
155 |
is_psgi => 1, |
| 176 |
perlPath => $perl_path, |
156 |
psgi_server => ($ENV{ PLACK_ENV }) ? "Plack ($ENV{PLACK_ENV})" : |
| 177 |
zebraVersion => $zebraVersion, |
157 |
($ENV{ MOD_PERL }) ? "mod_perl ($ENV{MOD_PERL})" : |
| 178 |
kohaVersion => $versions{'kohaVersion'}, |
158 |
'Unknown' |
| 179 |
osVersion => $versions{'osVersion'}, |
159 |
); |
| 180 |
perlVersion => $versions{'perlVersion'}, |
160 |
} |
| 181 |
perlIncPath => [ map { perlinc => $_ }, @INC ], |
|
|
| 182 |
mysqlVersion => $versions{'mysqlVersion'}, |
| 183 |
apacheVersion => $versions{'apacheVersion'}, |
| 184 |
memcached_running => Koha::Caches->get_instance->memcached_cache, |
| 185 |
); |
| 186 |
|
161 |
|
| 187 |
# Additional system information for warnings |
162 |
# Memcached configuration |
|
|
163 |
my $memcached_servers = $ENV{MEMCACHED_SERVERS} || C4::Context->config('memcached_servers'); |
| 164 |
my $memcached_namespace = $ENV{MEMCACHED_NAMESPACE} || C4::Context->config('memcached_namespace') // 'koha'; |
| 165 |
|
| 166 |
my $cache = Koha::Caches->get_instance; |
| 167 |
my $effective_caching_method = ref($cache->cache); |
| 168 |
# Memcached may have been running when plack has been initialized but could have been stopped since |
| 169 |
# FIXME What are the consequences of that?? |
| 170 |
my $is_memcached_still_active = $cache->set_in_cache('test_for_about_page', "just a simple value"); |
| 171 |
|
| 172 |
my $where_is_memcached_config = 'nowhere'; |
| 173 |
if ( $ENV{MEMCACHED_SERVERS} and C4::Context->config('memcached_servers') ) { |
| 174 |
$where_is_memcached_config = 'both'; |
| 175 |
} elsif ( $ENV{MEMCACHED_SERVERS} and not C4::Context->config('memcached_servers') ) { |
| 176 |
$where_is_memcached_config = 'ENV_only'; |
| 177 |
} elsif ( C4::Context->config('memcached_servers') ) { |
| 178 |
$where_is_memcached_config = 'config_only'; |
| 179 |
} |
| 180 |
|
| 181 |
$template->param( |
| 182 |
effective_caching_method => $effective_caching_method, |
| 183 |
memcached_servers => $memcached_servers, |
| 184 |
memcached_namespace => $memcached_namespace, |
| 185 |
is_memcached_still_active => $is_memcached_still_active, |
| 186 |
where_is_memcached_config => $where_is_memcached_config, |
| 187 |
perlPath => $perl_path, |
| 188 |
zebraVersion => $zebraVersion, |
| 189 |
kohaVersion => $versions{'kohaVersion'}, |
| 190 |
osVersion => $versions{'osVersion'}, |
| 191 |
perlVersion => $versions{'perlVersion'}, |
| 192 |
perlIncPath => [ map { perlinc => $_ }, @INC ], |
| 193 |
mysqlVersion => $versions{'mysqlVersion'}, |
| 194 |
apacheVersion => $versions{'apacheVersion'}, |
| 195 |
memcached_running => Koha::Caches->get_instance->memcached_cache, |
| 196 |
); |
| 188 |
|
197 |
|
| 189 |
my $warnStatisticsFieldsError; |
|
|
| 190 |
my $prefStatisticsFields = C4::Context->preference('StatisticsFields'); |
| 191 |
if ($prefStatisticsFields) { |
| 192 |
$warnStatisticsFieldsError = $prefStatisticsFields |
| 193 |
unless ( $prefStatisticsFields eq C4::Members::Statistics->get_fields() ); |
| 194 |
} |
198 |
} |
| 195 |
|
199 |
|
| 196 |
my $prefAutoCreateAuthorities = C4::Context->preference('AutoCreateAuthorities'); |
200 |
if($tab eq 'sysinfo') { |
| 197 |
my $prefRequireChoosingExistingAuthority = C4::Context->preference('RequireChoosingExistingAuthority'); |
|
|
| 198 |
my $warnPrefRequireChoosingExistingAuthority = ( !$prefAutoCreateAuthorities && ( !$prefRequireChoosingExistingAuthority) ); |
| 199 |
|
201 |
|
| 200 |
my $prefEasyAnalyticalRecords = C4::Context->preference('EasyAnalyticalRecords'); |
202 |
# Additional system information for warnings |
| 201 |
my $prefUseControlNumber = C4::Context->preference('UseControlNumber'); |
|
|
| 202 |
my $warnPrefEasyAnalyticalRecords = ( $prefEasyAnalyticalRecords && $prefUseControlNumber ); |
| 203 |
|
203 |
|
| 204 |
my $AnonymousPatron = C4::Context->preference('AnonymousPatron'); |
204 |
my $warnStatisticsFieldsError; |
| 205 |
my $warnPrefAnonymousPatronOPACPrivacy = ( |
205 |
my $prefStatisticsFields = C4::Context->preference('StatisticsFields'); |
| 206 |
C4::Context->preference('OPACPrivacy') |
206 |
if ($prefStatisticsFields) { |
| 207 |
and not $AnonymousPatron |
207 |
$warnStatisticsFieldsError = $prefStatisticsFields |
| 208 |
); |
208 |
unless ( $prefStatisticsFields eq C4::Members::Statistics->get_fields() ); |
| 209 |
my $warnPrefAnonymousPatronAnonSuggestions = ( |
209 |
} |
| 210 |
C4::Context->preference('AnonSuggestions') |
|
|
| 211 |
and not $AnonymousPatron |
| 212 |
); |
| 213 |
|
210 |
|
| 214 |
my $anonymous_patron = Koha::Patrons->find( $AnonymousPatron ); |
211 |
my $prefAutoCreateAuthorities = C4::Context->preference('AutoCreateAuthorities'); |
| 215 |
my $warnPrefAnonymousPatronAnonSuggestions_PatronDoesNotExist = ( $AnonymousPatron && C4::Context->preference('AnonSuggestions') && not $anonymous_patron ); |
212 |
my $prefRequireChoosingExistingAuthority = C4::Context->preference('RequireChoosingExistingAuthority'); |
|
|
213 |
my $warnPrefRequireChoosingExistingAuthority = ( !$prefAutoCreateAuthorities && ( !$prefRequireChoosingExistingAuthority) ); |
| 216 |
|
214 |
|
| 217 |
my $warnPrefAnonymousPatronOPACPrivacy_PatronDoesNotExist = ( not $anonymous_patron and Koha::Patrons->search({ privacy => 2 })->count ); |
215 |
my $prefEasyAnalyticalRecords = C4::Context->preference('EasyAnalyticalRecords'); |
|
|
216 |
my $prefUseControlNumber = C4::Context->preference('UseControlNumber'); |
| 217 |
my $warnPrefEasyAnalyticalRecords = ( $prefEasyAnalyticalRecords && $prefUseControlNumber ); |
| 218 |
|
218 |
|
| 219 |
my $warnPrefKohaAdminEmailAddress = !Koha::Email->is_valid(C4::Context->preference('KohaAdminEmailAddress')); |
219 |
my $AnonymousPatron = C4::Context->preference('AnonymousPatron'); |
|
|
220 |
my $warnPrefAnonymousPatronOPACPrivacy = ( |
| 221 |
C4::Context->preference('OPACPrivacy') |
| 222 |
and not $AnonymousPatron |
| 223 |
); |
| 224 |
my $warnPrefAnonymousPatronAnonSuggestions = ( |
| 225 |
C4::Context->preference('AnonSuggestions') |
| 226 |
and not $AnonymousPatron |
| 227 |
); |
| 220 |
|
228 |
|
| 221 |
my $c = Koha::Items->filter_by_visible_in_opac->count; |
229 |
my $anonymous_patron = Koha::Patrons->find( $AnonymousPatron ); |
| 222 |
my @warnings = C4::Context->dbh->selectrow_array('SHOW WARNINGS'); |
230 |
my $warnPrefAnonymousPatronAnonSuggestions_PatronDoesNotExist = ( $AnonymousPatron && C4::Context->preference('AnonSuggestions') && not $anonymous_patron ); |
| 223 |
my $warnPrefOpacHiddenItems = $warnings[2]; |
|
|
| 224 |
|
231 |
|
| 225 |
my $invalid_yesno = Koha::Config::SysPrefs->search( |
232 |
my $warnPrefAnonymousPatronOPACPrivacy_PatronDoesNotExist = ( not $anonymous_patron and Koha::Patrons->search({ privacy => 2 })->count ); |
| 226 |
{ |
|
|
| 227 |
type => 'YesNo', |
| 228 |
value => { -or => { 'is' => undef, -not_in => [ "1", "0" ] } } |
| 229 |
} |
| 230 |
); |
| 231 |
$template->param( invalid_yesno => $invalid_yesno ); |
| 232 |
|
233 |
|
| 233 |
my $errZebraConnection = C4::Context->Zconn("biblioserver",0)->errcode(); |
234 |
my $warnPrefKohaAdminEmailAddress = !Koha::Email->is_valid(C4::Context->preference('KohaAdminEmailAddress')); |
| 234 |
|
235 |
|
| 235 |
my $warnIsRootUser = (! $loggedinuser); |
236 |
my $c = Koha::Items->filter_by_visible_in_opac->count; |
|
|
237 |
my @warnings = C4::Context->dbh->selectrow_array('SHOW WARNINGS'); |
| 238 |
my $warnPrefOpacHiddenItems = $warnings[2]; |
| 236 |
|
239 |
|
| 237 |
my $warnNoActiveCurrency = (! defined Koha::Acquisition::Currencies->get_active); |
240 |
my $invalid_yesno = Koha::Config::SysPrefs->search( |
|
|
241 |
{ |
| 242 |
type => 'YesNo', |
| 243 |
value => { -or => { 'is' => undef, -not_in => [ "1", "0" ] } } |
| 244 |
} |
| 245 |
); |
| 246 |
$template->param( invalid_yesno => $invalid_yesno ); |
| 238 |
|
247 |
|
| 239 |
my @xml_config_warnings; |
248 |
my $errZebraConnection = C4::Context->Zconn("biblioserver",0)->errcode(); |
| 240 |
|
249 |
|
| 241 |
if ( C4::Context->config('zebra_bib_index_mode') |
250 |
my $warnIsRootUser = (! $loggedinuser); |
| 242 |
and C4::Context->config('zebra_bib_index_mode') eq 'grs1' ) |
|
|
| 243 |
{ |
| 244 |
push @xml_config_warnings, { error => 'zebra_bib_index_mode_is_grs1' }; |
| 245 |
} |
| 246 |
|
251 |
|
| 247 |
if ( C4::Context->config('zebra_auth_index_mode') |
252 |
my $warnNoActiveCurrency = (! defined Koha::Acquisition::Currencies->get_active); |
| 248 |
and C4::Context->config('zebra_auth_index_mode') eq 'grs1' ) |
|
|
| 249 |
{ |
| 250 |
push @xml_config_warnings, { error => 'zebra_auth_index_mode_is_grs1' }; |
| 251 |
} |
| 252 |
|
253 |
|
| 253 |
my $authorityserver = C4::Context->zebraconfig('authorityserver'); |
254 |
my @xml_config_warnings; |
| 254 |
if( ( C4::Context->config('zebra_auth_index_mode') |
|
|
| 255 |
and C4::Context->config('zebra_auth_index_mode') eq 'dom' ) |
| 256 |
&& ( $authorityserver->{config} !~ /zebra-authorities-dom.cfg/ ) ) |
| 257 |
{ |
| 258 |
push @xml_config_warnings, { |
| 259 |
error => 'zebra_auth_index_mode_mismatch_warn' |
| 260 |
}; |
| 261 |
} |
| 262 |
|
255 |
|
| 263 |
if ( ! defined C4::Context->config('log4perl_conf') ) { |
256 |
if ( C4::Context->config('zebra_bib_index_mode') |
| 264 |
push @xml_config_warnings, { |
257 |
and C4::Context->config('zebra_bib_index_mode') eq 'grs1' ) |
| 265 |
error => 'log4perl_entry_missing' |
258 |
{ |
|
|
259 |
push @xml_config_warnings, { error => 'zebra_bib_index_mode_is_grs1' }; |
| 266 |
} |
260 |
} |
| 267 |
} |
|
|
| 268 |
|
261 |
|
| 269 |
if ( ! defined C4::Context->config('lockdir') ) { |
262 |
if ( C4::Context->config('zebra_auth_index_mode') |
| 270 |
push @xml_config_warnings, { |
263 |
and C4::Context->config('zebra_auth_index_mode') eq 'grs1' ) |
| 271 |
error => 'lockdir_entry_missing' |
264 |
{ |
|
|
265 |
push @xml_config_warnings, { error => 'zebra_auth_index_mode_is_grs1' }; |
| 272 |
} |
266 |
} |
| 273 |
} |
267 |
|
| 274 |
else { |
268 |
my $authorityserver = C4::Context->zebraconfig('authorityserver'); |
| 275 |
unless ( -w C4::Context->config('lockdir') ) { |
269 |
if( ( C4::Context->config('zebra_auth_index_mode') |
|
|
270 |
and C4::Context->config('zebra_auth_index_mode') eq 'dom' ) |
| 271 |
&& ( $authorityserver->{config} !~ /zebra-authorities-dom.cfg/ ) ) |
| 272 |
{ |
| 273 |
push @xml_config_warnings, { |
| 274 |
error => 'zebra_auth_index_mode_mismatch_warn' |
| 275 |
}; |
| 276 |
} |
| 277 |
|
| 278 |
if ( ! defined C4::Context->config('log4perl_conf') ) { |
| 276 |
push @xml_config_warnings, { |
279 |
push @xml_config_warnings, { |
| 277 |
error => 'lockdir_not_writable', |
280 |
error => 'log4perl_entry_missing' |
| 278 |
lockdir => C4::Context->config('lockdir') |
|
|
| 279 |
} |
281 |
} |
| 280 |
} |
282 |
} |
| 281 |
} |
|
|
| 282 |
|
283 |
|
| 283 |
if ( ! defined C4::Context->config('upload_path') ) { |
284 |
if ( ! defined C4::Context->config('lockdir') ) { |
| 284 |
if ( Koha::Config::SysPrefs->find('OPACBaseURL')->value ) { |
|
|
| 285 |
# OPACBaseURL seems to be set |
| 286 |
push @xml_config_warnings, { |
285 |
push @xml_config_warnings, { |
| 287 |
error => 'uploadpath_entry_missing' |
286 |
error => 'lockdir_entry_missing' |
| 288 |
} |
287 |
} |
| 289 |
} else { |
288 |
} |
|
|
289 |
else { |
| 290 |
unless ( -w C4::Context->config('lockdir') ) { |
| 291 |
push @xml_config_warnings, { |
| 292 |
error => 'lockdir_not_writable', |
| 293 |
lockdir => C4::Context->config('lockdir') |
| 294 |
} |
| 295 |
} |
| 296 |
} |
| 297 |
|
| 298 |
if ( ! defined C4::Context->config('upload_path') ) { |
| 299 |
if ( Koha::Config::SysPrefs->find('OPACBaseURL')->value ) { |
| 300 |
# OPACBaseURL seems to be set |
| 301 |
push @xml_config_warnings, { |
| 302 |
error => 'uploadpath_entry_missing' |
| 303 |
} |
| 304 |
} else { |
| 305 |
push @xml_config_warnings, { |
| 306 |
error => 'uploadpath_and_opacbaseurl_entry_missing' |
| 307 |
} |
| 308 |
} |
| 309 |
} |
| 310 |
|
| 311 |
if ( ! C4::Context->config('tmp_path') ) { |
| 312 |
my $temporary_directory = C4::Context::temporary_directory; |
| 290 |
push @xml_config_warnings, { |
313 |
push @xml_config_warnings, { |
| 291 |
error => 'uploadpath_and_opacbaseurl_entry_missing' |
314 |
error => 'tmp_path_missing', |
|
|
315 |
effective_tmp_dir => $temporary_directory, |
| 292 |
} |
316 |
} |
| 293 |
} |
317 |
} |
| 294 |
} |
|
|
| 295 |
|
318 |
|
| 296 |
if ( ! C4::Context->config('tmp_path') ) { |
319 |
my $encryption_key = C4::Context->config('encryption_key'); |
| 297 |
my $temporary_directory = C4::Context::temporary_directory; |
320 |
if ( !$encryption_key || $encryption_key eq '__ENCRYPTION_KEY__') { |
| 298 |
push @xml_config_warnings, { |
321 |
push @xml_config_warnings, { error => 'encryption_key_missing' }; |
| 299 |
error => 'tmp_path_missing', |
|
|
| 300 |
effective_tmp_dir => $temporary_directory, |
| 301 |
} |
322 |
} |
| 302 |
} |
|
|
| 303 |
|
323 |
|
| 304 |
my $encryption_key = C4::Context->config('encryption_key'); |
324 |
# Test Zebra facets configuration |
| 305 |
if ( !$encryption_key || $encryption_key eq '__ENCRYPTION_KEY__') { |
325 |
if ( !defined C4::Context->config('use_zebra_facets') ) { |
| 306 |
push @xml_config_warnings, { error => 'encryption_key_missing' }; |
326 |
push @xml_config_warnings, { error => 'use_zebra_facets_entry_missing' }; |
| 307 |
} |
327 |
} |
| 308 |
|
328 |
|
| 309 |
# Test Zebra facets configuration |
329 |
unless ( Koha::I18N->_base_directory ) { |
| 310 |
if ( !defined C4::Context->config('use_zebra_facets') ) { |
330 |
$template->param( warnI18nMissing => 1 ); |
| 311 |
push @xml_config_warnings, { error => 'use_zebra_facets_entry_missing' }; |
331 |
} |
| 312 |
} |
|
|
| 313 |
|
332 |
|
| 314 |
unless ( Koha::I18N->_base_directory ) { |
333 |
# ILL module checks |
| 315 |
$template->param( warnI18nMissing => 1 ); |
334 |
if ( C4::Context->preference('ILLModule') ) { |
| 316 |
} |
335 |
my $warnILLConfiguration = 0; |
|
|
336 |
my $ill_config_from_file = C4::Context->config("interlibrary_loans"); |
| 337 |
my $ill_config = Koha::ILL::Request::Config->new; |
| 317 |
|
338 |
|
| 318 |
# ILL module checks |
339 |
my $available_ill_backends = |
| 319 |
if ( C4::Context->preference('ILLModule') ) { |
340 |
( scalar @{ $ill_config->available_backends } > 0 ); |
| 320 |
my $warnILLConfiguration = 0; |
|
|
| 321 |
my $ill_config_from_file = C4::Context->config("interlibrary_loans"); |
| 322 |
my $ill_config = Koha::ILL::Request::Config->new; |
| 323 |
|
341 |
|
| 324 |
my $available_ill_backends = |
342 |
# Check backends |
| 325 |
( scalar @{ $ill_config->available_backends } > 0 ); |
343 |
if ( !$available_ill_backends ) { |
|
|
344 |
$template->param( no_ill_backends => 1 ); |
| 345 |
$warnILLConfiguration = 1; |
| 346 |
} |
| 326 |
|
347 |
|
| 327 |
# Check backends |
348 |
# Check ILLPartnerCode sys pref |
| 328 |
if ( !$available_ill_backends ) { |
349 |
if ( !Koha::Patron::Categories->find( C4::Context->preference('ILLPartnerCode') ) ) { |
| 329 |
$template->param( no_ill_backends => 1 ); |
350 |
$template->param( ill_partner_code_doesnt_exist => C4::Context->preference('ILLPartnerCode') ); |
| 330 |
$warnILLConfiguration = 1; |
351 |
$warnILLConfiguration = 1; |
| 331 |
} |
352 |
} elsif ( !Koha::Patrons->search( { categorycode => C4::Context->preference('ILLPartnerCode') } )->count ) { |
|
|
353 |
$template->param( ill_partner_code_no_patrons => C4::Context->preference('ILLPartnerCode') ); |
| 354 |
$warnILLConfiguration = 1; |
| 355 |
} |
| 332 |
|
356 |
|
| 333 |
# Check ILLPartnerCode sys pref |
357 |
if ( !C4::Context->preference('ILLPartnerCode') ) { |
| 334 |
if ( !Koha::Patron::Categories->find( C4::Context->preference('ILLPartnerCode') ) ) { |
358 |
# partner code not defined |
| 335 |
$template->param( ill_partner_code_doesnt_exist => C4::Context->preference('ILLPartnerCode') ); |
359 |
$template->param( ill_partner_code_not_defined => 1 ); |
| 336 |
$warnILLConfiguration = 1; |
360 |
$warnILLConfiguration = 1; |
| 337 |
} elsif ( !Koha::Patrons->search( { categorycode => C4::Context->preference('ILLPartnerCode') } )->count ) { |
361 |
} |
| 338 |
$template->param( ill_partner_code_no_patrons => C4::Context->preference('ILLPartnerCode') ); |
|
|
| 339 |
$warnILLConfiguration = 1; |
| 340 |
} |
| 341 |
|
362 |
|
| 342 |
if ( !C4::Context->preference('ILLPartnerCode') ) { |
|
|
| 343 |
# partner code not defined |
| 344 |
$template->param( ill_partner_code_not_defined => 1 ); |
| 345 |
$warnILLConfiguration = 1; |
| 346 |
} |
| 347 |
|
363 |
|
|
|
364 |
if ( !$ill_config_from_file->{branch} ) { |
| 365 |
# branch not defined |
| 366 |
$template->param( ill_branch_not_defined => 1 ); |
| 367 |
$warnILLConfiguration = 1; |
| 368 |
} |
| 348 |
|
369 |
|
| 349 |
if ( !$ill_config_from_file->{branch} ) { |
370 |
$template->param( warnILLConfiguration => $warnILLConfiguration ); |
| 350 |
# branch not defined |
371 |
} |
| 351 |
$template->param( ill_branch_not_defined => 1 ); |
372 |
unless ( can_run('weasyprint') ) { |
| 352 |
$warnILLConfiguration = 1; |
373 |
$template->param( weasyprint_missing => 1 ); |
| 353 |
} |
374 |
} |
| 354 |
|
375 |
|
| 355 |
$template->param( warnILLConfiguration => $warnILLConfiguration ); |
376 |
{ |
| 356 |
} |
377 |
# XSLT sysprefs |
| 357 |
unless ( can_run('weasyprint') ) { |
378 |
my @xslt_prefs = qw( |
| 358 |
$template->param( weasyprint_missing => 1 ); |
379 |
OPACXSLTDetailsDisplay |
| 359 |
} |
380 |
OPACXSLTListsDisplay |
|
|
381 |
OPACXSLTResultsDisplay |
| 382 |
XSLTDetailsDisplay |
| 383 |
XSLTListsDisplay |
| 384 |
XSLTResultsDisplay |
| 385 |
); |
| 386 |
my @warnXSLT; |
| 387 |
for my $p ( @xslt_prefs ) { |
| 388 |
my $xsl_filename = C4::XSLT::get_xsl_filename( $p ); |
| 389 |
next if -e $xsl_filename; |
| 390 |
push @warnXSLT, |
| 391 |
{ |
| 392 |
syspref => $p, |
| 393 |
value => C4::Context->preference("$p"), |
| 394 |
filename => $xsl_filename |
| 395 |
}; |
| 396 |
} |
| 360 |
|
397 |
|
| 361 |
{ |
398 |
$template->param( warnXSLT => \@warnXSLT ) if @warnXSLT; |
| 362 |
# XSLT sysprefs |
399 |
} |
| 363 |
my @xslt_prefs = qw( |
|
|
| 364 |
OPACXSLTDetailsDisplay |
| 365 |
OPACXSLTListsDisplay |
| 366 |
OPACXSLTResultsDisplay |
| 367 |
XSLTDetailsDisplay |
| 368 |
XSLTListsDisplay |
| 369 |
XSLTResultsDisplay |
| 370 |
); |
| 371 |
my @warnXSLT; |
| 372 |
for my $p ( @xslt_prefs ) { |
| 373 |
my $xsl_filename = C4::XSLT::get_xsl_filename( $p ); |
| 374 |
next if -e $xsl_filename; |
| 375 |
push @warnXSLT, |
| 376 |
{ |
| 377 |
syspref => $p, |
| 378 |
value => C4::Context->preference("$p"), |
| 379 |
filename => $xsl_filename |
| 380 |
}; |
| 381 |
} |
| 382 |
|
| 383 |
$template->param( warnXSLT => \@warnXSLT ) if @warnXSLT; |
| 384 |
} |
| 385 |
|
400 |
|
| 386 |
if ( C4::Context->preference('SearchEngine') eq 'Elasticsearch' ) { |
401 |
if ( C4::Context->preference('SearchEngine') eq 'Elasticsearch' ) { |
| 387 |
# Check ES configuration health and runtime status |
402 |
# Check ES configuration health and runtime status |
| 388 |
|
403 |
|
| 389 |
my $es_status; |
404 |
my $es_status; |
| 390 |
my $es_config_error; |
405 |
my $es_config_error; |
| 391 |
my $es_running = 1; |
406 |
my $es_running = 1; |
| 392 |
my $es_has_missing = 0; |
407 |
my $es_has_missing = 0; |
| 393 |
|
408 |
|
| 394 |
my $es_conf; |
409 |
my $es_conf; |
| 395 |
try { |
410 |
try { |
| 396 |
$es_conf = Koha::SearchEngine::Elasticsearch::_read_configuration(); |
411 |
$es_conf = Koha::SearchEngine::Elasticsearch::_read_configuration(); |
| 397 |
} |
|
|
| 398 |
catch { |
| 399 |
if ( ref($_) eq 'Koha::Exceptions::Config::MissingEntry' ) { |
| 400 |
$template->param( elasticsearch_fatal_config_error => $_->message ); |
| 401 |
$es_config_error = 1; |
| 402 |
} |
412 |
} |
| 403 |
}; |
413 |
catch { |
| 404 |
if ( !$es_config_error ) { |
414 |
if ( ref($_) eq 'Koha::Exceptions::Config::MissingEntry' ) { |
| 405 |
|
415 |
$template->param( elasticsearch_fatal_config_error => $_->message ); |
| 406 |
my $biblios_index_name = $es_conf->{index_name} . "_" . $Koha::SearchEngine::BIBLIOS_INDEX; |
416 |
$es_config_error = 1; |
| 407 |
my $authorities_index_name = $es_conf->{index_name} . "_" . $Koha::SearchEngine::AUTHORITIES_INDEX; |
|
|
| 408 |
|
| 409 |
my @indexes = ($biblios_index_name, $authorities_index_name); |
| 410 |
# TODO: When new indexes get added, we could have other ways to |
| 411 |
# fetch the list of available indexes (e.g. plugins, etc) |
| 412 |
$es_status->{nodes} = $es_conf->{nodes}; |
| 413 |
my $es = Search::Elasticsearch->new( $es_conf ); |
| 414 |
my $es_status->{version} = $es->info->{version}->{number}; |
| 415 |
|
| 416 |
foreach my $index ( @indexes ) { |
| 417 |
my $index_count; |
| 418 |
try { |
| 419 |
$index_count = $es->indices->stats( index => $index ) |
| 420 |
->{_all}{primaries}{docs}{count}; |
| 421 |
} |
417 |
} |
| 422 |
catch { |
418 |
}; |
| 423 |
if ( ref($_) eq 'Search::Elasticsearch::Error::Missing' ) { |
419 |
if ( !$es_config_error ) { |
| 424 |
push @{ $es_status->{errors} }, "Index not found ($index)"; |
420 |
|
| 425 |
$index_count = -1; |
421 |
my $biblios_index_name = $es_conf->{index_name} . "_" . $Koha::SearchEngine::BIBLIOS_INDEX; |
|
|
422 |
my $authorities_index_name = $es_conf->{index_name} . "_" . $Koha::SearchEngine::AUTHORITIES_INDEX; |
| 423 |
|
| 424 |
my @indexes = ($biblios_index_name, $authorities_index_name); |
| 425 |
# TODO: When new indexes get added, we could have other ways to |
| 426 |
# fetch the list of available indexes (e.g. plugins, etc) |
| 427 |
$es_status->{nodes} = $es_conf->{nodes}; |
| 428 |
my $es = Search::Elasticsearch->new( $es_conf ); |
| 429 |
my $es_status->{version} = $es->info->{version}->{number}; |
| 430 |
|
| 431 |
foreach my $index ( @indexes ) { |
| 432 |
my $index_count; |
| 433 |
try { |
| 434 |
$index_count = $es->indices->stats( index => $index ) |
| 435 |
->{_all}{primaries}{docs}{count}; |
| 426 |
} |
436 |
} |
| 427 |
elsif ( ref($_) eq 'Search::Elasticsearch::Error::NoNodes' ) { |
437 |
catch { |
| 428 |
$es_running = 0; |
438 |
if ( ref($_) eq 'Search::Elasticsearch::Error::Missing' ) { |
|
|
439 |
push @{ $es_status->{errors} }, "Index not found ($index)"; |
| 440 |
$index_count = -1; |
| 441 |
} |
| 442 |
elsif ( ref($_) eq 'Search::Elasticsearch::Error::NoNodes' ) { |
| 443 |
$es_running = 0; |
| 444 |
} |
| 445 |
else { |
| 446 |
# TODO: when time comes, we will cover more use cases |
| 447 |
die $_; |
| 448 |
} |
| 449 |
}; |
| 450 |
|
| 451 |
my $db_count = -1; |
| 452 |
my $missing_count = 0; |
| 453 |
if ( $index eq $biblios_index_name ) { |
| 454 |
$db_count = Koha::Biblios->search->count; |
| 455 |
} elsif ( $index eq $authorities_index_name ) { |
| 456 |
$db_count = Koha::Authorities->search->count; |
| 429 |
} |
457 |
} |
| 430 |
else { |
458 |
if ( $db_count != -1 && $index_count != -1 ) { |
| 431 |
# TODO: when time comes, we will cover more use cases |
459 |
$missing_count = $db_count - $index_count; |
| 432 |
die $_; |
460 |
$es_has_missing = 1 if $missing_count > 0; |
| 433 |
} |
461 |
} |
| 434 |
}; |
462 |
push @{ $es_status->{indexes} }, |
| 435 |
|
463 |
{ |
| 436 |
my $db_count = -1; |
464 |
index_name => $index, |
| 437 |
my $missing_count = 0; |
465 |
index_count => $index_count, |
| 438 |
if ( $index eq $biblios_index_name ) { |
466 |
db_count => $db_count, |
| 439 |
$db_count = Koha::Biblios->search->count; |
467 |
missing_count => $missing_count, |
| 440 |
} elsif ( $index eq $authorities_index_name ) { |
468 |
}; |
| 441 |
$db_count = Koha::Authorities->search->count; |
|
|
| 442 |
} |
| 443 |
if ( $db_count != -1 && $index_count != -1 ) { |
| 444 |
$missing_count = $db_count - $index_count; |
| 445 |
$es_has_missing = 1 if $missing_count > 0; |
| 446 |
} |
469 |
} |
| 447 |
push @{ $es_status->{indexes} }, |
470 |
$es_status->{running} = $es_running; |
| 448 |
{ |
|
|
| 449 |
index_name => $index, |
| 450 |
index_count => $index_count, |
| 451 |
db_count => $db_count, |
| 452 |
missing_count => $missing_count, |
| 453 |
}; |
| 454 |
} |
| 455 |
$es_status->{running} = $es_running; |
| 456 |
|
471 |
|
| 457 |
$template->param( |
472 |
$template->param( |
| 458 |
elasticsearch_status => $es_status, |
473 |
elasticsearch_status => $es_status, |
| 459 |
elasticsearch_has_missing => $es_has_missing, |
474 |
elasticsearch_has_missing => $es_has_missing, |
| 460 |
); |
475 |
); |
|
|
476 |
} |
| 461 |
} |
477 |
} |
| 462 |
} |
|
|
| 463 |
|
478 |
|
| 464 |
if ( C4::Context->preference('RESTOAuth2ClientCredentials') ) { |
479 |
if ( C4::Context->preference('RESTOAuth2ClientCredentials') ) { |
| 465 |
# Do we have the required deps? |
480 |
# Do we have the required deps? |
| 466 |
unless ( can_load( modules => { 'Net::OAuth2::AuthorizationServer' => undef }) ) { |
481 |
unless ( can_load( modules => { 'Net::OAuth2::AuthorizationServer' => undef }) ) { |
| 467 |
$template->param( oauth2_missing_deps => 1 ); |
482 |
$template->param( oauth2_missing_deps => 1 ); |
|
|
483 |
} |
| 468 |
} |
484 |
} |
| 469 |
} |
|
|
| 470 |
|
485 |
|
| 471 |
# Sco Patron should not contain any other perms than circulate => self_checkout |
486 |
# Sco Patron should not contain any other perms than circulate => self_checkout |
| 472 |
if ( C4::Context->preference('WebBasedSelfCheck') |
487 |
if ( C4::Context->preference('WebBasedSelfCheck') |
| 473 |
and C4::Context->preference('AutoSelfCheckAllowed') |
488 |
and C4::Context->preference('AutoSelfCheckAllowed') |
| 474 |
) { |
489 |
) { |
| 475 |
my $userid = C4::Context->preference('AutoSelfCheckID'); |
490 |
my $userid = C4::Context->preference('AutoSelfCheckID'); |
| 476 |
my $all_permissions = C4::Auth::get_user_subpermissions( $userid ); |
491 |
my $all_permissions = C4::Auth::get_user_subpermissions( $userid ); |
| 477 |
my ( $has_self_checkout_perm, $has_other_permissions ); |
492 |
my ( $has_self_checkout_perm, $has_other_permissions ); |
| 478 |
while ( my ( $module, $permissions ) = each %$all_permissions ) { |
493 |
while ( my ( $module, $permissions ) = each %$all_permissions ) { |
| 479 |
if ( $module eq 'self_check' ) { |
494 |
if ( $module eq 'self_check' ) { |
| 480 |
while ( my ( $permission, $flag ) = each %$permissions ) { |
495 |
while ( my ( $permission, $flag ) = each %$permissions ) { |
| 481 |
if ( $permission eq 'self_checkout_module' ) { |
496 |
if ( $permission eq 'self_checkout_module' ) { |
| 482 |
$has_self_checkout_perm = 1; |
497 |
$has_self_checkout_perm = 1; |
| 483 |
} else { |
498 |
} else { |
| 484 |
$has_other_permissions = 1; |
499 |
$has_other_permissions = 1; |
|
|
500 |
} |
| 485 |
} |
501 |
} |
|
|
502 |
} else { |
| 503 |
$has_other_permissions = 1; |
| 486 |
} |
504 |
} |
| 487 |
} else { |
|
|
| 488 |
$has_other_permissions = 1; |
| 489 |
} |
505 |
} |
|
|
506 |
$template->param( |
| 507 |
AutoSelfCheckPatronDoesNotHaveSelfCheckPerm => not ( $has_self_checkout_perm ), |
| 508 |
AutoSelfCheckPatronHasTooManyPerm => $has_other_permissions, |
| 509 |
); |
| 490 |
} |
510 |
} |
| 491 |
$template->param( |
|
|
| 492 |
AutoSelfCheckPatronDoesNotHaveSelfCheckPerm => not ( $has_self_checkout_perm ), |
| 493 |
AutoSelfCheckPatronHasTooManyPerm => $has_other_permissions, |
| 494 |
); |
| 495 |
} |
| 496 |
|
| 497 |
if ( C4::Context->preference('PatronSelfRegistration') ) { |
| 498 |
$template->param( warnPrefPatronSelfRegistrationDefaultCategory => 1 ) |
| 499 |
unless Koha::Patron::Categories->find(C4::Context->preference('PatronSelfRegistrationDefaultCategory')); |
| 500 |
} |
| 501 |
|
511 |
|
| 502 |
# Test YAML system preferences |
512 |
if ( C4::Context->preference('PatronSelfRegistration') ) { |
| 503 |
# FIXME: This is list of current YAML formatted prefs, should by type of preference |
513 |
$template->param( warnPrefPatronSelfRegistrationDefaultCategory => 1 ) |
| 504 |
my @yaml_prefs = ( |
514 |
unless Koha::Patron::Categories->find(C4::Context->preference('PatronSelfRegistrationDefaultCategory')); |
| 505 |
"BibtexExportAdditionalFields", |
|
|
| 506 |
"ItemsDeniedRenewal", |
| 507 |
"MarcFieldsToOrder", |
| 508 |
"MarcItemFieldsToOrder", |
| 509 |
"OpacHiddenItems", |
| 510 |
"RisExportAdditionalFields", |
| 511 |
"UpdateitemLocationOnCheckin", |
| 512 |
"UpdateItemWhenLostFromHoldList", |
| 513 |
"UpdateNotForLoanStatusOnCheckin", |
| 514 |
"UpdateNotForLoanStatusOnCheckout", |
| 515 |
); |
| 516 |
my @bad_yaml_prefs; |
| 517 |
foreach my $syspref (@yaml_prefs) { |
| 518 |
my $yaml = C4::Context->preference( $syspref ); |
| 519 |
if ( $yaml ) { |
| 520 |
eval { YAML::XS::Load( Encode::encode_utf8("$yaml\n\n") ); }; |
| 521 |
if ($@) { |
| 522 |
push @bad_yaml_prefs, $syspref; |
| 523 |
} |
| 524 |
} |
515 |
} |
| 525 |
} |
|
|
| 526 |
$template->param( 'bad_yaml_prefs' => \@bad_yaml_prefs ) if @bad_yaml_prefs; |
| 527 |
|
516 |
|
| 528 |
{ |
517 |
# Test YAML system preferences |
| 529 |
my $dbh = C4::Context->dbh; |
518 |
# FIXME: This is list of current YAML formatted prefs, should by type of preference |
| 530 |
my $patrons = $dbh->selectall_arrayref( |
519 |
my @yaml_prefs = ( |
| 531 |
q|select b.borrowernumber from borrowers b join deletedborrowers db on b.borrowernumber=db.borrowernumber|, |
520 |
"BibtexExportAdditionalFields", |
| 532 |
{ Slice => {} } |
521 |
"ItemsDeniedRenewal", |
| 533 |
); |
522 |
"MarcFieldsToOrder", |
| 534 |
my $biblios = $dbh->selectall_arrayref( |
523 |
"MarcItemFieldsToOrder", |
| 535 |
q|select b.biblionumber from biblio b join deletedbiblio db on b.biblionumber=db.biblionumber|, |
524 |
"OpacHiddenItems", |
| 536 |
{ Slice => {} } |
525 |
"RisExportAdditionalFields", |
| 537 |
); |
526 |
"UpdateitemLocationOnCheckin", |
| 538 |
my $biblioitems = $dbh->selectall_arrayref( |
527 |
"UpdateItemWhenLostFromHoldList", |
| 539 |
q|select bi.biblioitemnumber from biblioitems bi join deletedbiblioitems dbi on bi.biblionumber=dbi.biblionumber|, |
528 |
"UpdateNotForLoanStatusOnCheckin", |
| 540 |
{ Slice => {} } |
529 |
"UpdateNotForLoanStatusOnCheckout", |
| 541 |
); |
|
|
| 542 |
my $items = $dbh->selectall_arrayref( |
| 543 |
q|select i.itemnumber from items i join deleteditems di on i.itemnumber=di.itemnumber|, |
| 544 |
{ Slice => {} } |
| 545 |
); |
| 546 |
my $checkouts = $dbh->selectall_arrayref( |
| 547 |
q|select i.issue_id from issues i join old_issues oi on i.issue_id=oi.issue_id|, |
| 548 |
{ Slice => {} } |
| 549 |
); |
530 |
); |
| 550 |
my $holds = $dbh->selectall_arrayref( |
531 |
my @bad_yaml_prefs; |
| 551 |
q|select r.reserve_id from reserves r join old_reserves o on r.reserve_id=o.reserve_id|, |
532 |
foreach my $syspref (@yaml_prefs) { |
| 552 |
{ Slice => {} } |
533 |
my $yaml = C4::Context->preference( $syspref ); |
| 553 |
); |
534 |
if ( $yaml ) { |
| 554 |
if ( @$patrons or @$biblios or @$biblioitems or @$items or @$checkouts or @$holds ) { |
535 |
eval { YAML::XS::Load( Encode::encode_utf8("$yaml\n\n") ); }; |
| 555 |
$template->param( |
536 |
if ($@) { |
| 556 |
has_ai_issues => 1, |
537 |
push @bad_yaml_prefs, $syspref; |
| 557 |
ai_patrons => $patrons, |
538 |
} |
| 558 |
ai_biblios => $biblios, |
539 |
} |
| 559 |
ai_biblioitems => $biblioitems, |
|
|
| 560 |
ai_items => $items, |
| 561 |
ai_checkouts => $checkouts, |
| 562 |
ai_holds => $holds, |
| 563 |
); |
| 564 |
} |
540 |
} |
| 565 |
} |
541 |
$template->param( 'bad_yaml_prefs' => \@bad_yaml_prefs ) if @bad_yaml_prefs; |
| 566 |
|
|
|
| 567 |
# Circ rule warnings |
| 568 |
{ |
| 569 |
my $dbh = C4::Context->dbh; |
| 570 |
my $units = Koha::CirculationRules->search({ rule_name => 'lengthunit', rule_value => { -not_in => ['days', 'hours'] } }); |
| 571 |
|
542 |
|
| 572 |
if ( $units->count ) { |
543 |
{ |
| 573 |
$template->param( |
544 |
my $dbh = C4::Context->dbh; |
| 574 |
warnIssuingRules => 1, |
545 |
my $patrons = $dbh->selectall_arrayref( |
| 575 |
ir_units => $units, |
546 |
q|select b.borrowernumber from borrowers b join deletedborrowers db on b.borrowernumber=db.borrowernumber|, |
|
|
547 |
{ Slice => {} } |
| 548 |
); |
| 549 |
my $biblios = $dbh->selectall_arrayref( |
| 550 |
q|select b.biblionumber from biblio b join deletedbiblio db on b.biblionumber=db.biblionumber|, |
| 551 |
{ Slice => {} } |
| 552 |
); |
| 553 |
my $biblioitems = $dbh->selectall_arrayref( |
| 554 |
q|select bi.biblioitemnumber from biblioitems bi join deletedbiblioitems dbi on bi.biblionumber=dbi.biblionumber|, |
| 555 |
{ Slice => {} } |
| 556 |
); |
| 557 |
my $items = $dbh->selectall_arrayref( |
| 558 |
q|select i.itemnumber from items i join deleteditems di on i.itemnumber=di.itemnumber|, |
| 559 |
{ Slice => {} } |
| 560 |
); |
| 561 |
my $checkouts = $dbh->selectall_arrayref( |
| 562 |
q|select i.issue_id from issues i join old_issues oi on i.issue_id=oi.issue_id|, |
| 563 |
{ Slice => {} } |
| 564 |
); |
| 565 |
my $holds = $dbh->selectall_arrayref( |
| 566 |
q|select r.reserve_id from reserves r join old_reserves o on r.reserve_id=o.reserve_id|, |
| 567 |
{ Slice => {} } |
| 576 |
); |
568 |
); |
|
|
569 |
if ( @$patrons or @$biblios or @$biblioitems or @$items or @$checkouts or @$holds ) { |
| 570 |
$template->param( |
| 571 |
has_ai_issues => 1, |
| 572 |
ai_patrons => $patrons, |
| 573 |
ai_biblios => $biblios, |
| 574 |
ai_biblioitems => $biblioitems, |
| 575 |
ai_items => $items, |
| 576 |
ai_checkouts => $checkouts, |
| 577 |
ai_holds => $holds, |
| 578 |
); |
| 579 |
} |
| 577 |
} |
580 |
} |
| 578 |
} |
|
|
| 579 |
|
581 |
|
| 580 |
# Guarantor relationships warnings |
582 |
# Circ rule warnings |
| 581 |
{ |
583 |
{ |
| 582 |
my $dbh = C4::Context->dbh; |
584 |
my $dbh = C4::Context->dbh; |
| 583 |
my ($bad_relationships_count) = $dbh->selectall_arrayref(q{ |
585 |
my $units = Koha::CirculationRules->search({ rule_name => 'lengthunit', rule_value => { -not_in => ['days', 'hours'] } }); |
| 584 |
SELECT COUNT(*) |
|
|
| 585 |
FROM ( |
| 586 |
SELECT relationship FROM borrower_relationships WHERE relationship='_bad_data' |
| 587 |
UNION ALL |
| 588 |
SELECT relationship FROM borrowers WHERE relationship='_bad_data') a |
| 589 |
}); |
| 590 |
|
| 591 |
$bad_relationships_count = $bad_relationships_count->[0]->[0]; |
| 592 |
|
| 593 |
my $existing_relationships = $dbh->selectall_arrayref(q{ |
| 594 |
SELECT DISTINCT(relationship) |
| 595 |
FROM ( |
| 596 |
SELECT relationship FROM borrower_relationships WHERE relationship IS NOT NULL |
| 597 |
UNION ALL |
| 598 |
SELECT relationship FROM borrowers WHERE relationship IS NOT NULL) a |
| 599 |
}); |
| 600 |
|
| 601 |
my %valid_relationships = map { $_ => 1 } split( /,|\|/, C4::Context->preference('borrowerRelationship') ); |
| 602 |
$valid_relationships{ _bad_data } = 1; # we handle this case in another way |
| 603 |
|
| 604 |
my $wrong_relationships = [ grep { !$valid_relationships{ $_->[0] } } @{$existing_relationships} ]; |
| 605 |
if ( @$wrong_relationships or $bad_relationships_count ) { |
| 606 |
|
| 607 |
$template->param( |
| 608 |
warnRelationships => 1, |
| 609 |
); |
| 610 |
|
586 |
|
| 611 |
if ( $wrong_relationships ) { |
587 |
if ( $units->count ) { |
| 612 |
$template->param( |
588 |
$template->param( |
| 613 |
wrong_relationships => $wrong_relationships |
589 |
warnIssuingRules => 1, |
|
|
590 |
ir_units => $units, |
| 614 |
); |
591 |
); |
| 615 |
} |
592 |
} |
| 616 |
if ($bad_relationships_count) { |
593 |
} |
|
|
594 |
|
| 595 |
# Guarantor relationships warnings |
| 596 |
{ |
| 597 |
my $dbh = C4::Context->dbh; |
| 598 |
my ($bad_relationships_count) = $dbh->selectall_arrayref(q{ |
| 599 |
SELECT COUNT(*) |
| 600 |
FROM ( |
| 601 |
SELECT relationship FROM borrower_relationships WHERE relationship='_bad_data' |
| 602 |
UNION ALL |
| 603 |
SELECT relationship FROM borrowers WHERE relationship='_bad_data') a |
| 604 |
}); |
| 605 |
|
| 606 |
$bad_relationships_count = $bad_relationships_count->[0]->[0]; |
| 607 |
|
| 608 |
my $existing_relationships = $dbh->selectall_arrayref(q{ |
| 609 |
SELECT DISTINCT(relationship) |
| 610 |
FROM ( |
| 611 |
SELECT relationship FROM borrower_relationships WHERE relationship IS NOT NULL |
| 612 |
UNION ALL |
| 613 |
SELECT relationship FROM borrowers WHERE relationship IS NOT NULL) a |
| 614 |
}); |
| 615 |
|
| 616 |
my %valid_relationships = map { $_ => 1 } split( /,|\|/, C4::Context->preference('borrowerRelationship') ); |
| 617 |
$valid_relationships{ _bad_data } = 1; # we handle this case in another way |
| 618 |
|
| 619 |
my $wrong_relationships = [ grep { !$valid_relationships{ $_->[0] } } @{$existing_relationships} ]; |
| 620 |
if ( @$wrong_relationships or $bad_relationships_count ) { |
| 621 |
|
| 617 |
$template->param( |
622 |
$template->param( |
| 618 |
bad_relationships_count => $bad_relationships_count, |
623 |
warnRelationships => 1, |
| 619 |
); |
624 |
); |
|
|
625 |
|
| 626 |
if ( $wrong_relationships ) { |
| 627 |
$template->param( |
| 628 |
wrong_relationships => $wrong_relationships |
| 629 |
); |
| 630 |
} |
| 631 |
if ($bad_relationships_count) { |
| 632 |
$template->param( |
| 633 |
bad_relationships_count => $bad_relationships_count, |
| 634 |
); |
| 635 |
} |
| 620 |
} |
636 |
} |
| 621 |
} |
637 |
} |
| 622 |
} |
|
|
| 623 |
|
638 |
|
| 624 |
{ |
639 |
{ |
| 625 |
# Test 'bcrypt_settings' config for Pseudonymization |
640 |
# Test 'bcrypt_settings' config for Pseudonymization |
| 626 |
$template->param( config_bcrypt_settings_no_set => 1 ) |
641 |
$template->param( config_bcrypt_settings_no_set => 1 ) |
| 627 |
if C4::Context->preference('Pseudonymization') |
642 |
if C4::Context->preference('Pseudonymization') |
| 628 |
and not C4::Context->config('bcrypt_settings'); |
643 |
and not C4::Context->config('bcrypt_settings'); |
| 629 |
} |
644 |
} |
| 630 |
|
645 |
|
| 631 |
{ |
646 |
{ |
| 632 |
my @frameworkcodes = Koha::BiblioFrameworks->search->get_column('frameworkcode'); |
647 |
my @frameworkcodes = Koha::BiblioFrameworks->search->get_column('frameworkcode'); |
| 633 |
my @hidden_biblionumbers; |
648 |
my @hidden_biblionumbers; |
| 634 |
push @frameworkcodes, ""; # it's not in the biblio_frameworks table! |
649 |
push @frameworkcodes, ""; # it's not in the biblio_frameworks table! |
| 635 |
my $no_FA_framework = 1; |
650 |
my $no_FA_framework = 1; |
| 636 |
for my $frameworkcode ( @frameworkcodes ) { |
651 |
for my $frameworkcode ( @frameworkcodes ) { |
| 637 |
$no_FA_framework = 0 if $frameworkcode eq 'FA'; |
652 |
$no_FA_framework = 0 if $frameworkcode eq 'FA'; |
| 638 |
my $shouldhidemarc_opac = Koha::Filter::MARC::ViewPolicy->should_hide_marc( |
653 |
my $shouldhidemarc_opac = Koha::Filter::MARC::ViewPolicy->should_hide_marc( |
| 639 |
{ |
654 |
{ |
| 640 |
frameworkcode => $frameworkcode, |
655 |
frameworkcode => $frameworkcode, |
| 641 |
interface => "opac" |
656 |
interface => "opac" |
| 642 |
} |
657 |
} |
| 643 |
); |
658 |
); |
| 644 |
push @hidden_biblionumbers, { frameworkcode => $frameworkcode, interface => 'opac' } |
659 |
push @hidden_biblionumbers, { frameworkcode => $frameworkcode, interface => 'opac' } |
| 645 |
if $shouldhidemarc_opac->{biblionumber}; |
660 |
if $shouldhidemarc_opac->{biblionumber}; |
| 646 |
|
661 |
|
| 647 |
my $shouldhidemarc_intranet = Koha::Filter::MARC::ViewPolicy->should_hide_marc( |
662 |
my $shouldhidemarc_intranet = Koha::Filter::MARC::ViewPolicy->should_hide_marc( |
| 648 |
{ |
663 |
{ |
| 649 |
frameworkcode => $frameworkcode, |
664 |
frameworkcode => $frameworkcode, |
| 650 |
interface => "intranet" |
665 |
interface => "intranet" |
| 651 |
} |
666 |
} |
| 652 |
); |
667 |
); |
| 653 |
push @hidden_biblionumbers, { frameworkcode => $frameworkcode, interface => 'intranet' } |
668 |
push @hidden_biblionumbers, { frameworkcode => $frameworkcode, interface => 'intranet' } |
| 654 |
if $shouldhidemarc_intranet->{biblionumber}; |
669 |
if $shouldhidemarc_intranet->{biblionumber}; |
|
|
670 |
} |
| 671 |
$template->param( warnHiddenBiblionumbers => \@hidden_biblionumbers ); |
| 672 |
$template->param( warnFastCataloging => $no_FA_framework ); |
| 655 |
} |
673 |
} |
| 656 |
$template->param( warnHiddenBiblionumbers => \@hidden_biblionumbers ); |
|
|
| 657 |
$template->param( warnFastCataloging => $no_FA_framework ); |
| 658 |
} |
| 659 |
|
674 |
|
| 660 |
{ |
675 |
{ |
| 661 |
# BackgroundJob - test connection to message broker |
676 |
# BackgroundJob - test connection to message broker |
| 662 |
eval { |
677 |
eval { |
| 663 |
Koha::BackgroundJob->connect; |
678 |
Koha::BackgroundJob->connect; |
| 664 |
}; |
679 |
}; |
| 665 |
if ( $@ ) { |
680 |
if ( $@ ) { |
| 666 |
warn $@; |
681 |
warn $@; |
| 667 |
$template->param( warnConnectBroker => $@ ); |
682 |
$template->param( warnConnectBroker => $@ ); |
|
|
683 |
} |
| 684 |
} |
| 685 |
|
| 686 |
#BZ 28267: Warn administrators if there are database rows with a format other than 'DYNAMIC' |
| 687 |
{ |
| 688 |
$template->param( warnDbRowFormat => C4::Installer->has_non_dynamic_row_format ); |
| 668 |
} |
689 |
} |
| 669 |
} |
|
|
| 670 |
|
690 |
|
| 671 |
#BZ 28267: Warn administrators if there are database rows with a format other than 'DYNAMIC' |
691 |
$template->param( |
| 672 |
{ |
692 |
prefRequireChoosingExistingAuthority => $prefRequireChoosingExistingAuthority, |
| 673 |
$template->param( warnDbRowFormat => C4::Installer->has_non_dynamic_row_format ); |
693 |
prefAutoCreateAuthorities => $prefAutoCreateAuthorities, |
|
|
694 |
warnPrefRequireChoosingExistingAuthority => $warnPrefRequireChoosingExistingAuthority, |
| 695 |
warnPrefEasyAnalyticalRecords => $warnPrefEasyAnalyticalRecords, |
| 696 |
warnPrefAnonymousPatronOPACPrivacy => $warnPrefAnonymousPatronOPACPrivacy, |
| 697 |
warnPrefAnonymousPatronAnonSuggestions => $warnPrefAnonymousPatronAnonSuggestions, |
| 698 |
warnPrefAnonymousPatronOPACPrivacy_PatronDoesNotExist => $warnPrefAnonymousPatronOPACPrivacy_PatronDoesNotExist, |
| 699 |
warnPrefAnonymousPatronAnonSuggestions_PatronDoesNotExist => $warnPrefAnonymousPatronAnonSuggestions_PatronDoesNotExist, |
| 700 |
warnPrefKohaAdminEmailAddress => $warnPrefKohaAdminEmailAddress, |
| 701 |
warnPrefOpacHiddenItems => $warnPrefOpacHiddenItems, |
| 702 |
errZebraConnection => $errZebraConnection, |
| 703 |
warnIsRootUser => $warnIsRootUser, |
| 704 |
warnNoActiveCurrency => $warnNoActiveCurrency, |
| 705 |
warnNoTemplateCaching => ( C4::Context->config('template_cache_dir') ? 0 : 1 ), |
| 706 |
xml_config_warnings => \@xml_config_warnings, |
| 707 |
warnStatisticsFieldsError => $warnStatisticsFieldsError, |
| 708 |
); |
| 674 |
} |
709 |
} |
| 675 |
|
710 |
|
| 676 |
$template->param( |
711 |
if ( $tab eq 'perl' ) { |
| 677 |
prefRequireChoosingExistingAuthority => $prefRequireChoosingExistingAuthority, |
|
|
| 678 |
prefAutoCreateAuthorities => $prefAutoCreateAuthorities, |
| 679 |
warnPrefRequireChoosingExistingAuthority => $warnPrefRequireChoosingExistingAuthority, |
| 680 |
warnPrefEasyAnalyticalRecords => $warnPrefEasyAnalyticalRecords, |
| 681 |
warnPrefAnonymousPatronOPACPrivacy => $warnPrefAnonymousPatronOPACPrivacy, |
| 682 |
warnPrefAnonymousPatronAnonSuggestions => $warnPrefAnonymousPatronAnonSuggestions, |
| 683 |
warnPrefAnonymousPatronOPACPrivacy_PatronDoesNotExist => $warnPrefAnonymousPatronOPACPrivacy_PatronDoesNotExist, |
| 684 |
warnPrefAnonymousPatronAnonSuggestions_PatronDoesNotExist => $warnPrefAnonymousPatronAnonSuggestions_PatronDoesNotExist, |
| 685 |
warnPrefKohaAdminEmailAddress => $warnPrefKohaAdminEmailAddress, |
| 686 |
warnPrefOpacHiddenItems => $warnPrefOpacHiddenItems, |
| 687 |
errZebraConnection => $errZebraConnection, |
| 688 |
warnIsRootUser => $warnIsRootUser, |
| 689 |
warnNoActiveCurrency => $warnNoActiveCurrency, |
| 690 |
warnNoTemplateCaching => ( C4::Context->config('template_cache_dir') ? 0 : 1 ), |
| 691 |
xml_config_warnings => \@xml_config_warnings, |
| 692 |
warnStatisticsFieldsError => $warnStatisticsFieldsError, |
| 693 |
); |
| 694 |
|
712 |
|
| 695 |
my @components = (); |
713 |
my @components = (); |
| 696 |
|
714 |
|
| 697 |
my $perl_modules = C4::Installer::PerlModules->new; |
715 |
my $perl_modules = C4::Installer::PerlModules->new; |
| 698 |
$perl_modules->versions_info; |
716 |
$perl_modules->versions_info; |
| 699 |
|
717 |
|
| 700 |
my @pm_types = qw(missing_pm upgrade_pm current_pm); |
718 |
my @pm_types = qw(missing_pm upgrade_pm current_pm); |
| 701 |
|
719 |
|
| 702 |
foreach my $pm_type(@pm_types) { |
720 |
foreach my $pm_type(@pm_types) { |
| 703 |
my $modules = $perl_modules->get_attr($pm_type); |
721 |
my $modules = $perl_modules->get_attr($pm_type); |
| 704 |
foreach (@$modules) { |
722 |
foreach (@$modules) { |
| 705 |
my ($module, $stats) = each %$_; |
723 |
my ($module, $stats) = each %$_; |
| 706 |
push( |
724 |
push( |
| 707 |
@components, |
725 |
@components, |
| 708 |
{ |
726 |
{ |
| 709 |
name => $module, |
727 |
name => $module, |
| 710 |
version => $stats->{'cur_ver'}, |
728 |
version => $stats->{'cur_ver'}, |
| 711 |
missing => ($pm_type eq 'missing_pm' ? 1 : 0), |
729 |
missing => ($pm_type eq 'missing_pm' ? 1 : 0), |
| 712 |
upgrade => ($pm_type eq 'upgrade_pm' ? 1 : 0), |
730 |
upgrade => ($pm_type eq 'upgrade_pm' ? 1 : 0), |
| 713 |
current => ($pm_type eq 'current_pm' ? 1 : 0), |
731 |
current => ($pm_type eq 'current_pm' ? 1 : 0), |
| 714 |
require => $stats->{'required'}, |
732 |
require => $stats->{'required'}, |
| 715 |
reqversion => $stats->{'min_ver'}, |
733 |
reqversion => $stats->{'min_ver'}, |
| 716 |
maxversion => $stats->{'max_ver'}, |
734 |
maxversion => $stats->{'max_ver'}, |
| 717 |
excversion => $stats->{'exc_ver'} |
735 |
excversion => $stats->{'exc_ver'} |
| 718 |
} |
736 |
} |
| 719 |
); |
737 |
); |
|
|
738 |
} |
| 720 |
} |
739 |
} |
| 721 |
} |
|
|
| 722 |
|
740 |
|
| 723 |
@components = sort {$a->{'name'} cmp $b->{'name'}} @components; |
741 |
@components = sort {$a->{'name'} cmp $b->{'name'}} @components; |
| 724 |
|
742 |
|
| 725 |
my $counter=0; |
743 |
my $counter=0; |
| 726 |
my $row = []; |
744 |
my $row = []; |
| 727 |
my $table = []; |
745 |
my $table = []; |
| 728 |
foreach (@components) { |
746 |
foreach (@components) { |
| 729 |
push (@$row, $_); |
747 |
push (@$row, $_); |
| 730 |
unless (++$counter % 4) { |
748 |
unless (++$counter % 4) { |
|
|
749 |
push (@$table, {row => $row}); |
| 750 |
$row = []; |
| 751 |
} |
| 752 |
} |
| 753 |
# Processing the last line (if there are any modules left) |
| 754 |
if (scalar(@$row) > 0) { |
| 755 |
# Extending $row to the table size |
| 756 |
$$row[3] = ''; |
| 757 |
# Pushing the last line |
| 731 |
push (@$table, {row => $row}); |
758 |
push (@$table, {row => $row}); |
| 732 |
$row = []; |
|
|
| 733 |
} |
759 |
} |
| 734 |
} |
760 |
## ## $table |
| 735 |
# Processing the last line (if there are any modules left) |
761 |
|
| 736 |
if (scalar(@$row) > 0) { |
762 |
$template->param( table => $table ); |
| 737 |
# Extending $row to the table size |
763 |
|
| 738 |
$$row[3] = ''; |
764 |
} |
| 739 |
# Pushing the last line |
765 |
|
| 740 |
push (@$table, {row => $row}); |
766 |
if ( $tab eq 'team' ) { |
| 741 |
} |
767 |
|
| 742 |
## ## $table |
768 |
## ------------------------------------------ |
| 743 |
|
769 |
## Koha contributions |
| 744 |
$template->param( table => $table ); |
770 |
|
| 745 |
|
771 |
## Release teams |
| 746 |
|
772 |
my $teams = |
| 747 |
## ------------------------------------------ |
773 |
-e "$docdir" . "/teams.yaml" |
| 748 |
## Koha contributions |
774 |
? YAML::XS::LoadFile( "$docdir" . "/teams.yaml" ) |
| 749 |
|
775 |
: {}; |
| 750 |
## Release teams |
776 |
my $dev_team = (sort {$b <=> $a} (keys %{$teams->{team}}))[0]; |
| 751 |
my $teams = |
777 |
my $short_version = substr($versions{'kohaVersion'},0,5); |
| 752 |
-e "$docdir" . "/teams.yaml" |
778 |
my $minor = substr($versions{'kohaVersion'},3,2); |
| 753 |
? YAML::XS::LoadFile( "$docdir" . "/teams.yaml" ) |
779 |
my $development_version = ( $minor eq '05' || $minor eq '11' ) ? 0 : 1; |
| 754 |
: {}; |
780 |
my $codename; |
| 755 |
my $dev_team = (sort {$b <=> $a} (keys %{$teams->{team}}))[0]; |
781 |
$template->param( short_version => $short_version ); |
| 756 |
my $short_version = substr($versions{'kohaVersion'},0,5); |
782 |
$template->param( development_version => $development_version ); |
| 757 |
my $minor = substr($versions{'kohaVersion'},3,2); |
783 |
|
| 758 |
my $development_version = ( $minor eq '05' || $minor eq '11' ) ? 0 : 1; |
784 |
## Contributors |
| 759 |
my $codename; |
785 |
my $contributors = |
| 760 |
$template->param( short_version => $short_version ); |
786 |
-e "$docdir" . "/contributors.yaml" |
| 761 |
$template->param( development_version => $development_version ); |
787 |
? YAML::XS::LoadFile( "$docdir" . "/contributors.yaml" ) |
| 762 |
|
788 |
: {}; |
| 763 |
## Contributors |
789 |
delete $contributors->{_others_}; |
| 764 |
my $contributors = |
790 |
for my $version ( sort { $a <=> $b } keys %{$teams->{team}} ) { |
| 765 |
-e "$docdir" . "/contributors.yaml" |
791 |
for my $role ( keys %{ $teams->{team}->{$version} } ) { |
| 766 |
? YAML::XS::LoadFile( "$docdir" . "/contributors.yaml" ) |
792 |
my $detail = $teams->{team}->{$version}->{$role}; |
| 767 |
: {}; |
793 |
my $normalized_role = "$role"; |
| 768 |
delete $contributors->{_others_}; |
794 |
$normalized_role =~ s/s$//; |
| 769 |
for my $version ( sort { $a <=> $b } keys %{$teams->{team}} ) { |
795 |
if ( ref( $detail ) eq 'ARRAY' ) { |
| 770 |
for my $role ( keys %{ $teams->{team}->{$version} } ) { |
796 |
for my $contributor ( @{ $detail } ) { |
| 771 |
my $detail = $teams->{team}->{$version}->{$role}; |
797 |
|
| 772 |
my $normalized_role = "$role"; |
798 |
my $localized_role = $normalized_role; |
| 773 |
$normalized_role =~ s/s$//; |
799 |
if ( my $subversion = $contributor->{version} ) { |
| 774 |
if ( ref( $detail ) eq 'ARRAY' ) { |
800 |
$localized_role .= ':' . $subversion; |
| 775 |
for my $contributor ( @{ $detail } ) { |
801 |
} |
| 776 |
|
802 |
if ( my $area = $contributor->{area} ) { |
| 777 |
my $localized_role = $normalized_role; |
803 |
$localized_role .= ':' . $area; |
| 778 |
if ( my $subversion = $contributor->{version} ) { |
804 |
} |
| 779 |
$localized_role .= ':' . $subversion; |
805 |
|
|
|
806 |
my $name = $contributor->{name}; |
| 807 |
# Add role to contributors |
| 808 |
push @{ $contributors->{$name}->{roles}->{$localized_role} }, |
| 809 |
$version; |
| 810 |
# Add openhub to teams |
| 811 |
if ( exists( $contributors->{$name}->{openhub} ) ) { |
| 812 |
$contributor->{openhub} = $contributors->{$name}->{openhub}; |
| 813 |
} |
| 780 |
} |
814 |
} |
| 781 |
if ( my $area = $contributor->{area} ) { |
815 |
} |
| 782 |
$localized_role .= ':' . $area; |
816 |
elsif ( $role eq 'release_date' ) { |
|
|
817 |
$teams->{team}->{$version}->{$role} = DateTime->from_epoch( epoch => $teams->{team}->{$version}->{$role} ); |
| 818 |
} |
| 819 |
elsif ( $role eq 'codename' ) { |
| 820 |
if ( $version == $short_version ) { |
| 821 |
$codename = $detail; |
| 822 |
} |
| 823 |
next; |
| 824 |
} |
| 825 |
else { |
| 826 |
if ( my $subversion = $detail->{version} ) { |
| 827 |
$normalized_role .= ':' . $subversion; |
| 828 |
} |
| 829 |
if ( my $area = $detail->{area} ) { |
| 830 |
$normalized_role .= ':' . $area; |
| 783 |
} |
831 |
} |
| 784 |
|
832 |
|
| 785 |
my $name = $contributor->{name}; |
833 |
my $name = $detail->{name}; |
| 786 |
# Add role to contributors |
834 |
# Add role to contributors |
| 787 |
push @{ $contributors->{$name}->{roles}->{$localized_role} }, |
835 |
push @{ $contributors->{$name}->{roles}->{$normalized_role} }, |
| 788 |
$version; |
836 |
$version; |
| 789 |
# Add openhub to teams |
837 |
# Add openhub to teams |
| 790 |
if ( exists( $contributors->{$name}->{openhub} ) ) { |
838 |
if ( exists( $contributors->{$name}->{openhub} ) ) { |
| 791 |
$contributor->{openhub} = $contributors->{$name}->{openhub}; |
839 |
$detail->{openhub} = |
|
|
840 |
$contributors->{$name}->{openhub}; |
| 792 |
} |
841 |
} |
| 793 |
} |
842 |
} |
| 794 |
} |
843 |
} |
| 795 |
elsif ( $role eq 'release_date' ) { |
|
|
| 796 |
$teams->{team}->{$version}->{$role} = DateTime->from_epoch( epoch => $teams->{team}->{$version}->{$role} ); |
| 797 |
} |
| 798 |
elsif ( $role eq 'codename' ) { |
| 799 |
if ( $version == $short_version ) { |
| 800 |
$codename = $detail; |
| 801 |
} |
| 802 |
next; |
| 803 |
} |
| 804 |
else { |
| 805 |
if ( my $subversion = $detail->{version} ) { |
| 806 |
$normalized_role .= ':' . $subversion; |
| 807 |
} |
| 808 |
if ( my $area = $detail->{area} ) { |
| 809 |
$normalized_role .= ':' . $area; |
| 810 |
} |
| 811 |
|
| 812 |
my $name = $detail->{name}; |
| 813 |
# Add role to contributors |
| 814 |
push @{ $contributors->{$name}->{roles}->{$normalized_role} }, |
| 815 |
$version; |
| 816 |
# Add openhub to teams |
| 817 |
if ( exists( $contributors->{$name}->{openhub} ) ) { |
| 818 |
$detail->{openhub} = |
| 819 |
$contributors->{$name}->{openhub}; |
| 820 |
} |
| 821 |
} |
| 822 |
} |
844 |
} |
| 823 |
} |
|
|
| 824 |
|
845 |
|
| 825 |
## Create last name ordered array of people from contributors |
846 |
## Create last name ordered array of people from contributors |
| 826 |
my @people = map { |
847 |
my @people = map { |
| 827 |
{ name => $_, ( $contributors->{$_} ? %{ $contributors->{$_} } : () ) } |
848 |
{ name => $_, ( $contributors->{$_} ? %{ $contributors->{$_} } : () ) } |
| 828 |
} sort { |
849 |
} sort { |
| 829 |
my ($alast) = $a =~ /(\S+)$/; |
850 |
my ($alast) = $a =~ /(\S+)$/; |
| 830 |
my ($blast) = $b =~ /(\S+)$/; |
851 |
my ($blast) = $b =~ /(\S+)$/; |
| 831 |
my $cmp = lc($alast||"") cmp lc($blast||""); |
852 |
my $cmp = lc($alast||"") cmp lc($blast||""); |
| 832 |
return $cmp if $cmp; |
853 |
return $cmp if $cmp; |
| 833 |
|
854 |
|
| 834 |
my ($a2last) = $a =~ /(\S+)\s\S+$/; |
855 |
my ($a2last) = $a =~ /(\S+)\s\S+$/; |
| 835 |
my ($b2last) = $b =~ /(\S+)\s\S+$/; |
856 |
my ($b2last) = $b =~ /(\S+)\s\S+$/; |
| 836 |
lc($a2last||"") cmp lc($b2last||""); |
857 |
lc($a2last||"") cmp lc($b2last||""); |
| 837 |
} keys %$contributors; |
858 |
} keys %$contributors; |
| 838 |
|
859 |
|
| 839 |
$template->param( kohaCodename => $codename); |
860 |
$template->param( kohaCodename => $codename); |
| 840 |
$template->param( contributors => \@people ); |
861 |
$template->param( contributors => \@people ); |
| 841 |
$template->param( maintenance_team => $teams->{team}->{$dev_team} ); |
862 |
$template->param( maintenance_team => $teams->{team}->{$dev_team} ); |
| 842 |
$template->param( release_team => $teams->{team}->{$short_version} ); |
863 |
$template->param( release_team => $teams->{team}->{$short_version} ); |
| 843 |
|
864 |
|
| 844 |
## Timeline |
865 |
} |
| 845 |
if ( open( my $file, "<:encoding(UTF-8)", "$docdir" . "/history.txt" ) ) { |
866 |
if ( $tab eq 'history' ) { |
| 846 |
|
867 |
|
| 847 |
my $i = 0; |
868 |
## Timeline |
|
|
869 |
if ( open( my $file, "<:encoding(UTF-8)", "$docdir" . "/history.txt" ) ) { |
| 848 |
|
870 |
|
| 849 |
my @rows2 = (); |
871 |
my $i = 0; |
| 850 |
my $row2 = []; |
|
|
| 851 |
|
872 |
|
| 852 |
my @lines = <$file>; |
873 |
my @rows2 = (); |
| 853 |
close($file); |
874 |
my $row2 = []; |
| 854 |
|
875 |
|
| 855 |
shift @lines; #remove header row |
876 |
my @lines = <$file>; |
|
|
877 |
close($file); |
| 856 |
|
878 |
|
| 857 |
foreach (@lines) { |
879 |
shift @lines; #remove header row |
| 858 |
my ( $epoch, $date, $desc, $tag ) = split(/\t/); |
880 |
|
| 859 |
if(!$desc && $date=~ /(?<=\d{4})\s+/) { |
881 |
foreach (@lines) { |
| 860 |
($date, $desc)= ($`, $'); |
882 |
my ( $epoch, $date, $desc, $tag ) = split(/\t/); |
| 861 |
} |
883 |
if(!$desc && $date=~ /(?<=\d{4})\s+/) { |
| 862 |
push( |
884 |
($date, $desc)= ($`, $'); |
| 863 |
@rows2, |
|
|
| 864 |
{ |
| 865 |
date => $date, |
| 866 |
desc => $desc, |
| 867 |
} |
885 |
} |
| 868 |
); |
886 |
push( |
| 869 |
} |
887 |
@rows2, |
|
|
888 |
{ |
| 889 |
date => $date, |
| 890 |
desc => $desc, |
| 891 |
} |
| 892 |
); |
| 893 |
} |
| 870 |
|
894 |
|
| 871 |
my $table2 = []; |
895 |
my $table2 = []; |
| 872 |
#foreach my $row2 (@rows2) { |
896 |
#foreach my $row2 (@rows2) { |
| 873 |
foreach (@rows2) { |
897 |
foreach (@rows2) { |
| 874 |
push (@$row2, $_); |
898 |
push (@$row2, $_); |
| 875 |
push( @$table2, { row2 => $row2 } ); |
899 |
push( @$table2, { row2 => $row2 } ); |
| 876 |
$row2 = []; |
900 |
$row2 = []; |
| 877 |
} |
901 |
} |
| 878 |
|
902 |
|
| 879 |
$template->param( table2 => $table2 ); |
903 |
$template->param( table2 => $table2 ); |
| 880 |
} else { |
904 |
} else { |
| 881 |
$template->param( timeline_read_error => 1 ); |
905 |
$template->param( timeline_read_error => 1 ); |
|
|
906 |
} |
| 882 |
} |
907 |
} |
| 883 |
|
908 |
|
| 884 |
output_html_with_http_headers $query, $cookie, $template->output; |
909 |
output_html_with_http_headers $query, $cookie, $template->output; |
| 885 |
- |
|
|