257 lines
7.6 KiB
Perl
257 lines
7.6 KiB
Perl
# Selima Website Content Management System
|
|
# ActLog.pm: The activity log record list.
|
|
|
|
# Copyright (c) 2005-2018 imacat.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# Author: imacat <imacat@mail.imacat.idv.tw>
|
|
# First written: 2005-05-10
|
|
|
|
package Selima::List::ActLog;
|
|
use 5.008;
|
|
use strict;
|
|
use warnings;
|
|
use base qw(Selima::List);
|
|
|
|
use Encode qw(decode);
|
|
use Fcntl qw(:flock);
|
|
|
|
use Selima::A2HTML;
|
|
use Selima::DataVars qw(:lninfo :requri);
|
|
use Selima::GetLang;
|
|
use Selima::Logging;
|
|
use Selima::HTTP;
|
|
use Selima::Query;
|
|
use Selima::ShortCut;
|
|
|
|
# new: Initialize the handler
|
|
sub new : method {
|
|
local ($_, %_);
|
|
my ($self, $class);
|
|
($class, @_) = @_;
|
|
$self = $class->SUPER::new(@_);
|
|
# The page title
|
|
$self->{"title"} = C_("Browse the Activity Log");
|
|
$self->{"rows"} = defined $self->{"FORM"}->param("rows")?
|
|
$self->{"FORM"}->param("rows"): undef;
|
|
$self->{"rdgt"} = 4;
|
|
$self->{"reverse"} = 1;
|
|
return $self;
|
|
}
|
|
|
|
# fetch: Fetch the current list
|
|
sub fetch : method {
|
|
local ($_, %_);
|
|
my ($self, $error, $FH);
|
|
$self = $_[0];
|
|
|
|
# Fetched before
|
|
return $self->{"error"} if $self->{"fetched"};
|
|
$self->{"fetched"} = 1;
|
|
|
|
# Initialize the error status
|
|
$self->{"error"} = undef;
|
|
$self->{"total"} = undef;
|
|
|
|
# Check the query phrases
|
|
$self->check_query;
|
|
# Check the number of rows to display
|
|
$error = $self->check_pagesize;
|
|
if (defined $error) {
|
|
$self->{"error"} = $error if !defined $self->{"error"};
|
|
$self->{"pagesize"} = $self->{"DEFAULT_LIST_SIZE"};
|
|
} elsif (!defined $self->{"rows"}) {
|
|
$self->{"pagesize"} = $self->{"DEFAULT_LIST_SIZE"};
|
|
} else {
|
|
$self->{"pagesize"} = $self->{"rows"};
|
|
}
|
|
|
|
check_actlog_file;
|
|
open $FH, $ACTLOG or http_500 "$ACTLOG: $!";
|
|
flock $FH, LOCK_SH or http_500 "$ACTLOG: $!";
|
|
# Obtain all the log entries
|
|
if (@{$self->{"query_phrases"}} == 0) {
|
|
$self->{"current"} = [map decode("UTF-8", $_), <$FH>];
|
|
# Obtain all the matched log entries
|
|
} else {
|
|
$self->{"current"} = [];
|
|
while (defined($_ = <$FH>)) {
|
|
my $matched;
|
|
$_ = decode("UTF-8", $_);
|
|
$matched = 1;
|
|
foreach my $phrase (@{$self->{"query_phrases"}}) {
|
|
next if /\Q$phrase\E/i;
|
|
$matched = 0;
|
|
last;
|
|
}
|
|
push @{$self->{"current"}}, $_ if $matched;
|
|
}
|
|
}
|
|
flock $FH, LOCK_UN or http_500 "$ACTLOG: $!";
|
|
close $FH or http_500 "$ACTLOG: $!";
|
|
$self->{"total"} = scalar @{$self->{"current"}};
|
|
|
|
$self->{"endno"} = $self->{"total"} - 1;
|
|
$self->{"startno"} = 1;
|
|
if ($self->{"total"} > $self->{"pagesize"}) {
|
|
$self->{"startno"} = $self->{"endno"} - $self->{"pagesize"} + 1;
|
|
$self->{"current"} = [@{$self->{"current"}}[$self->{"startno"}...$self->{"endno"}]];
|
|
}
|
|
|
|
$self->{"current"} = [reverse @{$self->{"current"}}];
|
|
|
|
# Done
|
|
return $self->{"error"};
|
|
}
|
|
|
|
# check_query: Check the query phrases
|
|
sub check_query : method {
|
|
local ($_, %_);
|
|
my $self;
|
|
$self = $_[0];
|
|
|
|
# No query, return
|
|
return if !defined $self->{"query"};
|
|
|
|
# Regularize it
|
|
$self->{"query"} =~ s/^\s*(.*?)\s*$/$1/;
|
|
# Check if it is filled
|
|
return if $self->{"query"} eq "";
|
|
|
|
$self->{"query_phrases"} = [parse_query $self->{"query"}];
|
|
return;
|
|
}
|
|
|
|
# check_pagesize: Check the number of rows to display
|
|
sub check_pagesize : method {
|
|
local ($_, %_);
|
|
my ($self, $error, $errmsg);
|
|
$self = $_[0];
|
|
# No rows, return
|
|
return if !defined $self->{"rows"};
|
|
# Regularize it
|
|
$self->{"rows"} =~ s/^\s*(.*?)\s*$/$1/;
|
|
# Check if it is filled
|
|
return {"msg"=>N_("Please fill in the number of rows to display.")}
|
|
if $self->{"rows"} eq "";
|
|
# If there is any non-digit character
|
|
return {"msg"=>N_("Please fill in a positive integer number of rows to display.")}
|
|
unless $self->{"rows"} =~ /^[1-9][0-9]*$/;
|
|
# Set to an integer
|
|
$self->{"rows"} += 0;
|
|
# Check the length
|
|
return {"msg"=>N_("This number of rows to display is too long. (Max. length [#,_1])"),
|
|
"margs"=>[$self->{"rdgt"}]}
|
|
if length $self->{"rows"} > $self->{"rdgt"};
|
|
# OK
|
|
return;
|
|
}
|
|
|
|
# html_newlink: Display a link to add a new item
|
|
# Make it a null function
|
|
sub html_newlink : method {}
|
|
|
|
# html_search: Display the search box
|
|
sub html_search : method {
|
|
local ($_, %_);
|
|
my ($self, $prompt, $label, $query, $request_file);
|
|
my ($prompt2, $rows, $size);
|
|
($self, $prompt) = @_;
|
|
$prompt = C_("Search for log entries:") if !defined $prompt;
|
|
$prompt = h($prompt);
|
|
|
|
$request_file = h($REQUEST_FILE);
|
|
$query = defined $self->{"query"}? h($self->{"query"}): "";
|
|
$label = h(C_("Display"));
|
|
$prompt2 = h(C_("Display rows:"));
|
|
$rows = defined $self->{"rows"}? h($self->{"rows"}):
|
|
h($self->{"DEFAULT_LIST_SIZE"});
|
|
$size = h($self->{"rdgt"});
|
|
|
|
print << "EOT";
|
|
<form action="$request_file" method="get" accept-charset="<!--selima:charset-->">
|
|
<div class="searchbox">
|
|
<label for="query">$prompt</label><input
|
|
id="query" type="text" name="query" value="$query" />
|
|
<label for="rows">$prompt2</label><input
|
|
id="rows" type="text" name="rows" size="$size" maxlength="$size" value="$rows" />
|
|
<input type="hidden" name="charset" value="<!--selima:charset-->" />
|
|
<input type="submit" value="$label" />
|
|
</div>
|
|
</form>
|
|
|
|
EOT
|
|
return;
|
|
}
|
|
|
|
# liststat_message: Return the current list statistics message
|
|
sub liststat_message : method {
|
|
local ($_, %_);
|
|
my $self;
|
|
$self = $_[0];
|
|
|
|
# No record to list
|
|
if ($self->{"total"} == 0) {
|
|
# Inherit the empty list statistics message
|
|
return $self->SUPER::liststat_message;
|
|
# Fit in one page
|
|
} elsif ($self->{"total"} <= $self->{"pagesize"}) {
|
|
# Result comes from a query
|
|
if (defined $self->{"query"}) {
|
|
return C_("Your query found [*,_1,log entry,log entries].", $self->{"total"});
|
|
# List result
|
|
} else {
|
|
return C_("[*,_1,log entry,log entries].", $self->{"total"});
|
|
}
|
|
# More than one page
|
|
} else {
|
|
# Result comes from a query
|
|
if (defined $self->{"query"}) {
|
|
return C_("Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3].",
|
|
$self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1);
|
|
# List result
|
|
} else {
|
|
return C_("[*,_1,log entry,log entries], listing [#,_2] to [#,_3].",
|
|
$self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1);
|
|
}
|
|
}
|
|
}
|
|
|
|
# html_pagebar: Display a page navigation bar
|
|
# Make it a null function
|
|
sub html_pagebar : method {}
|
|
|
|
# html_list: List the items
|
|
sub html_list : method {
|
|
local ($_, %_);
|
|
my $self;
|
|
$self = $_[0];
|
|
# Do not show the list
|
|
return if !defined $self->{"total"};
|
|
# No record to be listed
|
|
return if $self->{"total"} == 0;
|
|
|
|
$_ = a2html(join "", @{$self->{"current"}});
|
|
s/([\x00-\x08\x0B\x0C\x0E-\x1F])/sprintf("\\x%02x", ord($1));/ge;
|
|
print << "EOT";
|
|
<div>
|
|
$_
|
|
</div>
|
|
|
|
EOT
|
|
return;
|
|
}
|
|
|
|
return 1;
|