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 |
- |
|
|