# Selima Website Content Management System # Form.pm: The base form # Copyright (c) 2004-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 # First written: 2004-09-28 package Selima::Form; use 5.008; use strict; use warnings; use CGI qw(); use Data::Dumper qw(); use URI::Escape qw(uri_escape); use Selima::A2HTML; use Selima::Array; use Selima::CallForm; use Selima::ChkFunc; use Selima::CommText; use Selima::Country; use Selima::DataVars qw($DBH $SESSION FORM_CAPTCHA :dataman :hostconf :l10n :lninfo :requri :scptconf :siteconf); use Selima::FormFunc; use Selima::Format; use Selima::GetLang; use Selima::Guest; use Selima::HTTP; use Selima::HTTPS; use Selima::LnInfo; use Selima::MarkAbbr; use Selima::Picture; use Selima::ShortCut; use Selima::UserName; # Load these classes use Selima::Form::User; use Selima::Form::Group; use Selima::Form::UserMem; use Selima::Form::GroupMem; use Selima::Form::UserPref; use Selima::Form::ScptPriv; use Selima::Form::Guestbook; use Selima::Form::Guestbook::Public; use Selima::Form::Page; use Selima::Form::LinkCat; use Selima::Form::Link; use Selima::Form::LinkCatz; use Selima::Form::Rebuild; use Selima::Form::AcctSubj; use Selima::Form::AcctTrx; use Selima::Form::AcctRec; # new: Initialize the HTML form table displayer sub new : method { local ($_, %_); my ($class, $status, $args, $self, $CURFORM, $CALLINGFORM); ($class, $status, $args) = @_; $args = {} if !defined $args; $self = bless {}, $class; $self->{"status"} = $status; # $args must be a hash reference http_500 "type of argument 2 must be a hash reference" if ref($args) ne "HASH"; # The form type $self->{"type"} = exists $$args{"type"}? $$args{"type"}: form_type; # The form type to pass to the handler if (exists $$args{"type_to_pass"}) { $self->{"type_to_pass"} = $$args{"type_to_pass"}; } else { $self->{"type_to_pass"} = $$args{"type"}; } # The allowed form types $self->{"valid_types"} = exists $$args{"valid_types"}? $$args{"valid_types"}: [qw(new cur del)]; # Only new, cur or del is allowed for the form type http_500 "invalid form type: " . $self->{"type"} if !in_array($self->{"type"}, @{$self->{"valid_types"}}); # The form step $self->{"step"} = $$args{"step"} if exists $$args{"step"}; # The request ID. $self->{"req"} = $$args{"req"} if exists $$args{"req"}; # The managing table if (exists $$args{"table"}) { $self->{"table"} = $$args{"table"}; } elsif (defined $THIS_TABLE) { $self->{"table"} = $THIS_TABLE; } # The current record $self->{"cur"} = exists $$args{"current"}? $$args{"current"}: new CGI({%CURRENT}); $self->{"sn"} = $self->{"cur"}->param("sn") if defined $self->{"cur"}->param("sn"); # The submitted form $self->{"form"} = exists $$args{"form"}? $$args{"form"}: retrieve_form; # If we should process with HTTPS/SSL $self->{"https"} = 0 if !defined($self->{"https"} = $self->https($args)); # If the form contains file uploads (multipart/form-data) $self->{"isupload"} = exists $$args{"isupload"} && $$args{"isupload"}; # If this record can be deleted $self->{"nodelete"} = exists $$args{"nodelete"} && $$args{"nodelete"}; # The prefix message to display before the form $self->{"prefmsg"} = []; push @{$self->{"prefmsg"}}, @{$$args{"prefmsg"}} if exists $$args{"prefmsg"}; # The deletion text $self->{"deltext"} = exists $$args{"deltext"}? $$args{"deltext"}: C_("Delete it."); # The mark $self->{"mark"} = exists $$args{"mark"}? $$args{"mark"}: C_("*"); # The columns to mark $self->{"markcols"} = $$args{"markcols"} if exists $$args{"markcols"}; # The prompt message for the marked columns $self->{"markmsg"} = $$args{"markmsg"} if exists $$args{"markmsg"}; # The hidden columns $self->{"hidcols"} = $$args{"hidcols"} if exists $$args{"hidcols"}; # The buttons to show before and after the form $self->{"header_buttons"} = $$args{"header_buttons"} if exists $$args{"header_buttons"}; $self->{"footer_buttons"} = $$args{"footer_buttons"} if exists $$args{"footer_buttons"}; # If we should show the table $self->{"show_table"} = exists $$args{"show_table"}? $$args{"show_table"}: 1; # The table summary if (exists $$args{"summary"}) { $self->{"summary"} = $$args{"summary"}; } else { # A form to create a new item if ($self->{"type"} eq "new") { $self->{"summary"} = C_("This table provides you a form to add a new data record."); # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $self->{"summary"} = C_("This table provides you a form to update a current data record."); # A form to delete a current item } elsif ($self->{"type"} eq "del") { $self->{"summary"} = C_("This table provides you a form to delete a data record."); } } # The form class $self->{"class"} = exists $$args{"class"}? $$args{"class"}: "defform"; # The onsubmit javascript form checker $self->{"onsubmit"} = exists $$args{"onsubmit"}? $$args{"onsubmit"}: undef; # The colspan for each normal cell $self->{"colspan"} = exists $$args{"colspan"}? $$args{"colspan"}: 1; # The default input box size $self->{"defsize"} = exists $$args{"defsize"}? $$args{"defsize"}: 40; # The process URL if (exists $$args{"procurl"}) { $self->{"procurl"} = $$args{"procurl"}; } elsif ($self->{"https"} && !is_guest) { if ($VIRTUAL_HOST) { $self->{"procurl"} = "https://" . https_host . $REQUEST_PATH; } else { $self->{"procurl"} = "https://" . https_host . "/" . $PACKAGE . $REQUEST_PATH; } } else { $self->{"procurl"} = $REQUEST_FILE; } # The columns to display if (exists $$args{"cols"}) { $self->{"cols"} = $$args{"cols"}; } elsif (exists $self->{"table"}) { $self->{"cols"} = [$DBH->cols($self->{"table"})]; } # Should we automatically keep our HTTP_REFERER $self->{"auto_referer2"} = exists $$args{"auto_referer2"}? $$args{"auto_referer2"}: 1; # The title if (exists $$args{"title"}) { $self->{"title"} = $$args{"title"}; } else { # A form to create a new item if ($self->{"type"} eq "new") { $self->{"title"} = C_("Add a New Data Record"); # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $self->{"title"} = C_("Update a Current Data Record"); # A form to delete a current item } elsif ($self->{"type"} eq "del") { $self->{"title"} = C_("Delete a Data Record"); } } # The caller form and form ID $CURFORM = curform; if ( exists $$args{"caller"} && exists $$args{"cformid"}) { $self->{"is_called_form"} = 1; $self->{"caller"} = $$args{"caller"}; $self->{"cformid"} = $$args{"cformid"}; } elsif ( defined $CURFORM->param("caller") && defined $CURFORM->param("cformid")) { $self->{"is_called_form"} = 1; $self->{"caller"} = $CURFORM->param("caller"); $self->{"cformid"} = $CURFORM->param("cformid"); } else { $self->{"is_called_form"} = 0; } # The preview link $self->{"preview"} = exists $$args{"preview"}? $$args{"preview"}: 0; $self->{"prevmsg"} = exists $$args{"prevmsg"}? $$args{"prevmsg"}: C_("Preview it.") if $$args{"preview"}; # Initialize the first form $self->{"is_first_form"} = 0; if (scalar(@_ = $self->{"form"}->param) == 0) { $self->{"is_first_form"} = 1; # ...with the current item eval Data::Dumper->Dump([$self->{"cur"}], [qw($self->{"form"})]) if $self->{"type"} eq "cur"; } if (exists $self->{"table"}) { $self->{"mlcols"} = [$DBH->cols_ml($self->{"table"})]; $self->{"maxlens"} = {$DBH->col_lens($self->{"table"})}; } # Check if each column is available foreach (@{$self->{"cols"}}) { http_500 "invalid table column \"$_\"" if !$self->can("_html_col_$_"); } # Set the referer2 (the place to return when finishing the form) if ($self->{"is_called_form"}) { # Referer specified $CALLINGFORM = retrieve_form($self->{"cformid"}); $self->{"referer2"} = $CALLINGFORM->param("referer2") if defined $CALLINGFORM->param("referer2"); # First form } elsif ($self->{"is_first_form"}) { # Referer specified if (defined $CURFORM->param("referer")) { $self->{"referer2"} = $CURFORM->param("referer"); # Keep the source referer } elsif ( $self->{"auto_referer2"} && exists $ENV{"HTTP_REFERER"} && substr($ENV{"HTTP_REFERER"}, 0, length($REQUEST_HOSTPORT)+1) eq $REQUEST_HOSTPORT . "/") { $self->{"referer2"} = $ENV{"HTTP_REFERER"}; } # A subsequent form } else { # Maintain the previous referer2 $self->{"referer2"} = $self->{"form"}->param("referer2") if defined $self->{"form"}->param("referer2"); } # The prefix of where to return after form is processed # No need to have it if we have a proper referer2 to return to $self->{"hostport"} = $REQUEST_HOSTPORT if !exists $self->{"referer2"} && $self->{"https"}; # Check if Chinese synchronization is available %_ = map { $_ => 1 } @ALL_LINGUAS; $_ = getlang; $self->{"zhsync"} = 0; if ( exists $self->{"table"} && $DBH->is_ml_table($self->{"table"}) && $_ ne $DEFAULT_LANG) { if ($_ eq "zh-tw" && exists $_{"zh-cn"}) { $self->{"zhsync"} = h_abbr(C_("Convert from Simplified Chinese")); } elsif ($_ eq "zh-cn" && exists $_{"zh-tw"}) { $self->{"zhsync"} = h_abbr(C_("Convert from Traditional Chinese")); } } %_ = map { $_ => 1 } @ALL_LINGUAS; $_ = getlang; $self->{"zhsync"} = 0; if ( exists $self->{"table"} && $DBH->is_ml_table($self->{"table"}) && $_ ne $DEFAULT_LANG) { if ($_ eq "zh-tw" && exists $_{"zh-cn"}) { $self->{"zhsync"} = h_abbr(C_("Convert from Simplified Chinese")); } elsif ($_ eq "zh-cn" && exists $_{"zh-tw"}) { $self->{"zhsync"} = h_abbr(C_("Convert from Traditional Chinese")); } } return $self; } # html: Display the HTML form table sub html : method { local ($_, %_); my $self; $self = $_[0]; # Display the preview_link $self->_html_preview_link; # Display the form header $self->_html_form_header; # Display the table # Display the table header $self->_html_table_header if $self->{"show_table"}; # Display each column &{$self->can("_html_col_$_")}($self) foreach @{$self->{"cols"}}; # Display the table footer $self->_html_table_footer if $self->{"show_table"}; # Display the form footer $self->_html_form_footer; return; } # https: If we should process with HTTPS/SSL sub https : method { local ($_, %_); my ($self, $args, $FORM); ($self, $args) = @_; # Checked before return $self->{"https"} if exists $self->{"https"}; # Already in HTTPS return ($self->{"https"} = 0) if is_https; # HTTPS specified return $self->{"https"} = ($$args{"https"}? 1: 0) if defined $args && exists $$args{"https"} && defined $$args{"https"}; # Specified in the current form $FORM = curform; return ($self->{"https"} = 1) if defined $FORM->param("https") && $FORM->param("https"); # Specified in the GET or POST arguments $FORM = get_or_post; return ($self->{"https"} = 1) if defined $FORM->param("https") && $FORM->param("https"); # Unable to decide it return undef; } ################### # Methods below are private. Do not call them directly. ################### ################### # Basic form elements ################### # _html_preview_link: Display the preview_link sub _html_preview_link : method { local ($_, %_); my ($self, $form, $url, $msg); $self = $_[0]; $form = $self->{"form"}; # Bounce when preview is not available for this form return if !$self->{"preview"}; # No preview on forms that cannot be previewed if (defined $self->{"status"}) { return unless exists ${$self->{"status"}}{"preview"} && ${$self->{"status"}}{"preview"}; } @_ = qw(); push @_, "form=preview"; # A form to create a new item if ($self->{"type"} eq "new") { # No preview for the first blank form if ($self->{"is_first_form"}) { return; } else { push @_, "sn=" . $form->param("formid"); } # A form to edit a current item } elsif ($self->{"type"} eq "cur") { # Make a suspended form and get the form ID. if ($self->{"is_first_form"}) { push @_, "sn=" . $self->{"sn"}; push @_, "source=db"; } else { push @_, "sn=" . $form->param("formid"); } # A form to delete a current item } elsif ($self->{"type"} eq "del") { # No preview for the deletion form return; } $url = h($REQUEST_FILE . "?" . join "&", @_); $msg = h_abbr($self->{"prevmsg"}); print << "EOT";

$msg

EOT return; } # _html_form_header: Display the form header sub _html_form_header : method { local ($_, %_); my ($self, $class, $url, $enctype, $onsubmit, $meta); $self = $_[0]; $class = defined $self->{"class"}? " class=\"" . h($self->{"class"}) . "\"": ""; $url = h($self->{"procurl"}); $enctype = $self->{"isupload"}? " enctype=\"multipart/form-data\"": ""; $onsubmit = defined $self->{"onsubmit"}? " onsubmit=\"" . h($self->{"onsubmit"}) . "\"": ""; # The meta form information $meta = Selima::Form::MetaCols->new; $meta->add("hidden", "lang", getlang); $meta->add("hidden", "charset", undef); $meta->add("hidden", "form", $self->{"type_to_pass"}) if defined $self->{"type_to_pass"}; $meta->add("hidden", "step", $self->{"step"}) if exists $self->{"step"}; $meta->add("hidden", "sn", $self->{"sn"}) if exists $self->{"sn"}; $meta->add("hidden", "req", $self->{"req"}) if exists $self->{"req"}; if ($self->{"is_called_form"}) { $meta->add("hidden", "caller", $self->{"caller"}); $meta->add("hidden", "cformid", $self->{"cformid"}); } if ($self->{"https"}) { $meta->add("hidden", "https", 1); $meta->add("hidden", "referer", $REQUEST_HOSTPATH); $meta->add("hidden", $$SESSION{".meta"}->{"name"}, $$SESSION{".meta"}->{"id"}); } if (exists $self->{"referer2"}) { $meta->add("hidden", "referer2", $self->{"referer2"}); } elsif (exists $self->{"hostport"}) { $meta->add("hidden", "hostport", $self->{"hostport"}); } if (exists $self->{"hidcols"}) { $meta->add("hidden", $$_{"name"}, $$_{"value"}) foreach @{$self->{"hidcols"}}; } # The submit buttons if (exists $self->{"header_buttons"}) { $meta->add("submit", $$_{"name"}, $$_{"value"}) foreach @{$self->{"header_buttons"}}; } else { # A form to create a new item if ($self->{"type"} eq "new") { $meta->add("submit", undef, C_("Submit")); $meta->add("submit", "confirm", C_("Save")); # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $meta->add("submit", undef, C_("Submit")); $meta->add("submit", "confirm", C_("Save")); $meta->add("submit", "zhsync", $self->{"zhsync"}) if $self->{"zhsync"}; $meta->add("submit", "del", $self->{"deltext"}) unless $self->{"nodelete"}; # A form to delete a current item } elsif ($self->{"type"} eq "del") { } } # Output the form header print << "EOT"; EOT # Display the prompt for the marked columns $self->_html_mark_prompt; # Display the prefix message $self->_html_prefix_message; print << "EOT";
EOT # Output the meta form information $meta->out; return; } # _html_mark_prompt: Display the prompt for the marked columns sub _html_mark_prompt : method { local ($_, %_); my $self; $self = $_[0]; # Bounce when there is no prompt message or no mark to use return if !exists $self->{"markmsg"} || !defined $self->{"mark"}; $_ = printf $self->{"markmsg"}, $self->{"mark"}; print << "EOT";

$_

EOT return; } # _html_prefix_message: Display the prefix message sub _html_prefix_message : method { local ($_, %_); my $self; $self = $_[0]; # Bounce when there is no prefix message foreach my $msg (@{$self->{"prefmsg"}}) { $_ = h_abbr($msg); print << "EOT";

$_

EOT } return; } # _html_table_header: Display the table header sub _html_table_header : method { local ($_, %_); my ($self, $cols, $summary); $self = $_[0]; # Output the table header $cols = ""; $cols .= "" if $self->{"type"} eq "cur"; for ($_ = 0; $_ < $self->{"colspan"}; $_++) { $cols .= ""; } $summary = h_abbr($self->{"summary"}); print << "EOT"; $cols EOT return; } # _html_table_footer: Display the table footer sub _html_table_footer : method { local ($_, %_); my $self; $self = $_[0]; # Output the table footer print << "EOT";
EOT return; } # _html_form_footer: Display the form footer sub _html_form_footer : method { local ($_, %_); my ($self, $meta, $msg); $self = $_[0]; # The meta form information $meta = Selima::Form::MetaCols->new; # The submit buttons if (exists $self->{"footer_buttons"}) { $meta->add("submit", $$_{"name"}, $$_{"value"}) foreach @{$self->{"footer_buttons"}}; } else { # A form to create a new item if ($self->{"type"} eq "new") { $meta->add("submit", undef, C_("Submit")); $meta->add("submit", "confirm", C_("Save")); # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $meta->add("submit", undef, C_("Submit")); $meta->add("submit", "confirm", C_("Save")); $meta->add("submit", "zhsync", $self->{"zhsync"}) if $self->{"zhsync"}; $meta->add("submit", "del", $self->{"deltext"}) unless $self->{"nodelete"}; # A form to delete a current item } elsif ($self->{"type"} eq "del") { $meta->add("submit", "confirm", C_("Delete")); $meta->add("submit", "cancel", C_("Cancel")); } } # Output the deletion warning print "

" . h_abbr(C_("Are you sure you want to delete this data? You cannot recover it if you do so.")) . "

\n" if $self->{"type"} eq "del"; # Output the meta form information $meta->out; # Output the form footer print << "EOT";
EOT return; } ################### # Column templates ################### # _html_coltmpl_ro: Display a read-only normal column sub _html_coltmpl_ro : method { local ($_, %_); my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); ($self, $col, $label, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cur = $self->_cval_text($col); # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label $cur$prompt EOT return; } # _html_coltmpl_ro_textarea: Display a read-only textarea column sub _html_coltmpl_ro_textarea : method { local ($_, %_); my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); ($self, $col, $label, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cur = $self->_cval_textarea($col); # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label $cur$prompt EOT return; } # _html_coltmpl_ro_bool: Display a read-only boolean column sub _html_coltmpl_ro_bool : method { local ($_, %_); my ($self, $col, $label, $true, $false, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); ($self, $col, $label, $true, $false, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cur = $self->{"cur"}->param($col)? $true: $false; # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label $cur$prompt EOT return; } # _html_coltmpl_ro_user: Display a read-only user column sub _html_coltmpl_ro_user : method { local ($_, %_); my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); ($self, $col, $label, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cur = h_abbr(username scalar $self->{"cur"}->param($col)); # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label $cur$prompt EOT return; } # _html_coltmpl_ro_date: Display a read-only date column sub _html_coltmpl_ro_date : method { local ($_, %_); my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); ($self, $col, $label, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cur = defined $self->{"cur"}->param($col)? h_abbr(fmtdate $self->{"cur"}->param($col)): h_abbr(t_none); # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label $cur$prompt EOT return; } # _html_coltmpl_ro_datetime: Display a read-only date-time column sub _html_coltmpl_ro_datetime : method { local ($_, %_); my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); ($self, $col, $label, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cur = defined $self->{"cur"}->param($col)? h_abbr(fmttime $self->{"cur"}->param($col)): h_abbr(t_none); # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label $cur$prompt EOT return; } # _html_coltmpl_ro_lang: Display a read-only language column sub _html_coltmpl_ro_lang : method { local ($_, %_); my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); ($self, $col, $label, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cur = defined $self->{"cur"}->param($col)? h_abbr(ln $self->{"cur"}->param($col), LN_DESC_CURLC): h_abbr(t_none); # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label $cur$prompt EOT return; } # _html_coltmpl_ro_ct: Display a read-only country column sub _html_coltmpl_ro_ct : method { local ($_, %_); my ($self, $col, $label, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); ($self, $col, $label, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cur = h_abbr(ctname $self->{"cur"}->param($col)); # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label $cur$prompt EOT return; } # _html_coltmpl_ro_title: Display a read-only column with a title function sub _html_coltmpl_ro_title : method { local ($_, %_); my ($self, $col, $label, $titlefunc, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); ($self, $col, $label, $titlefunc, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cur = h(&$titlefunc($self->{"cur"}->param($col))); # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label $cur$prompt EOT return; } # _html_coltmpl_ro_radio: Display a read-only column with a option list sub _html_coltmpl_ro_radio : method { local ($_, %_); my ($self, $col, $label, $opts, $prompt, $cur, $mark, $colspan, $thclass, $thcolspan); ($self, $col, $label, $opts, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cur = $$opts{grep $self->{"cur"}->param($col) eq $_, keys %$opts}; # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label $cur$prompt EOT return; } # _html_coltmpl_text: Display a text column sub _html_coltmpl_text : method { local ($_, %_); my ($self, $col, $label, $prompt, $size, $class, $mark, $colspan); my ($cur, $val, $orig, $new); ($self, $col, $label, $prompt, $size) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $class = defined $size? "": " class=\"text\""; $size = h($self->{"defsize"}) if !defined $size; # A form to create a new item if ($self->{"type"} eq "new") { $val = $self->_val_text($col, $col); $col = h($col); print << "EOT"; $prompt EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $cur = $self->_cval_text($col); $val = $self->_val_text($col, $col); $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); # A multi-lingual column, that is not in the default language if (in_array($col, @{$self->{"mlcols"}}) && getlang ne $DEFAULT_LANG) { my ($srclabel, $srccur); $srclabel = h_abbr(C_("Source:")); $_ = $col . "_" . ln($DEFAULT_LANG, LN_DATABASE); $srccur = $self->_cval_text($_); $col = h($col); print << "EOT"; $srclabel $srccur $orig $cur $prompt EOT # A uni-lingual column } else { $col = h($col); print << "EOT"; $orig $cur $prompt EOT } # A form to delete a current item } elsif ($self->{"type"} eq "del") { $cur = $self->_cval_text($col); print << "EOT"; $mark$label $cur EOT } return; } # _html_coltmpl_text_null: Display a nullable text column sub _html_coltmpl_text_null : method { local ($_, %_); my ($self, $col, $label, $nullcol, $nulllabel, $prompt, $size, $class, $mark, $colspan); my ($form, $cur, $val, $orig, $new, $valfalse, $valtrue); ($self, $col, $label, $nullcol, $nulllabel, $prompt, $size) = @_; $form = $self->{"form"}; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $class = defined $size? "": " class=\"textnull\""; $size = h($self->{"defsize"}) if !defined $size; # A form to create a new item if ($self->{"type"} eq "new") { $valfalse = $self->_val_radio($nullcol, "false"); $valtrue = $self->_val_radio($nullcol, "true"); $val = $self->_val_text($col, $col); $col = h($col); $nullcol = h($nullcol); print << "EOT"; $prompt
EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $form->param($nullcol, !defined $form->param($col)? "true": "false") if $self->{"is_first_form"}; $valfalse = $self->_val_radio($nullcol, "false"); $valtrue = $self->_val_radio($nullcol, "true"); $val = $self->_val_text($col, $col); $cur = defined $self->{"cur"}->param($col)? h($self->{"cur"}->param($col)): $nulllabel; $col = h($col); $nullcol = h($nullcol); $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); print << "EOT"; $orig $cur $prompt
EOT # A form to delete a current item } elsif ($self->{"type"} eq "del") { $cur = defined $self->{"cur"}->param($col)? h($self->{"cur"}->param($col)): $nulllabel; print << "EOT"; $mark$label $cur EOT } return; } # _html_coltmpl_textarea: Display a textarea column sub _html_coltmpl_textarea : method { local ($_, %_); my ($self, $col, $label, $default, $prompt, $rows, $cols, $mark, $colspan, $hdef); my ($cur, $val, $orig, $new); ($self, $col, $label, $default, $prompt, $rows, $cols) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $cols = h($self->{"defsize"}) if !defined $cols; $rows = h(10) if !defined $rows; # A form to create a new item if ($self->{"type"} eq "new") { $val = $self->_val_textarea($col, $default); $hdef = h($default); $col = h($col); print << "EOT"; $prompt EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $cur = $self->_cval_textarea($col); $val = $self->_val_textarea($col, $default); $hdef = h($default); $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); # A multi-lingual column, that is not in the default language if (in_array($col, @{$self->{"mlcols"}}) && getlang ne $DEFAULT_LANG) { my ($srclabel, $srccur); $srclabel = h_abbr(C_("Source:")); $_ = $col . "_" . ln($DEFAULT_LANG, LN_DATABASE); $srccur = $self->_cval_textarea($_); $col = h($col); print << "EOT"; $srclabel $srccur $orig $cur $prompt EOT # A uni-lingual column } else { $col = h($col); print << "EOT"; $orig $cur $prompt EOT } # A form to delete a current item } elsif ($self->{"type"} eq "del") { $cur = $self->_cval_textarea($col); print << "EOT"; $mark$label $cur EOT } return; } # _html_coltmpl_bool: Display a boolean column sub _html_coltmpl_bool : method { local ($_, %_); my ($self, $col, $label, $true, $false, $text, $prompt, $mark, $colspan); my ($cur, $val, $orig, $new); ($self, $col, $label, $true, $false, $text, $prompt) = @_; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; # A form to create a new item if ($self->{"type"} eq "new") { $val = $self->_val_check($col); $col = h($col); print << "EOT"; $prompt EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $cur = $self->{"cur"}->param($col)? $true: $false; $val = $self->_val_check($col); $col = h($col); $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); print << "EOT"; $orig $cur $prompt EOT # A form to delete a current item } elsif ($self->{"type"} eq "del") { $cur = $self->{"cur"}->param($col)? $true: $false; print << "EOT"; $mark$label $cur EOT } return; } # _html_coltmpl_call: The call selection column sub _html_coltmpl_call : method { local ($_, %_); my ($self, $col, $label, $titlefunc, $prompt, $mark, $colspan); my ($form, $cur, $val, $orig, $new); my ($vallabel, $choose, $delete); ($self, $col, $label, $titlefunc, $prompt) = @_; $self = $_[0]; $form = $self->{"form"}; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $choose = h_abbr(C_("Choose")); $delete = h_abbr(C_("Delete")); # "" means not selected yet $form->delete($col) if defined $form->param($col) && $form->param($col) eq ""; # A form to create a new item if ($self->{"type"} eq "new") { $val = $self->_val_text($col); $vallabel = h(&$titlefunc($form->param($col))); $col = h($col); print << "EOT"; EOT if (defined $form->param($col)) { print << "EOT"; EOT } else { print << "EOT"; EOT } print << "EOT"; $prompt EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $val = $self->_val_text($col); $vallabel = h(&$titlefunc($form->param($col))); $cur = h(&$titlefunc($self->{"cur"}->param($col))); $col = h($col); $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); print << "EOT"; $orig $cur EOT if (defined $form->param($col)) { print << "EOT"; EOT } else { print << "EOT"; EOT } print << "EOT"; $prompt EOT # A form to delete a current item } elsif ($self->{"type"} eq "del") { $cur = h(&$titlefunc($self->{"cur"}->param($col))); print << "EOT"; $mark$label $cur EOT } return; } # _html_coltmpl_call_null: The nullable call selection column sub _html_coltmpl_call_null : method { local ($_, %_); my ($self, $col, $label, $nullcol, $nulllabel, $titlefunc, $prompt, $mark, $colspan); my ($form, $cur, $val, $orig, $new, $valfalse, $valtrue); my ($vallabel, $choose, $delete); ($self, $col, $label, $nullcol, $nulllabel, $titlefunc, $prompt) = @_; $self = $_[0]; $form = $self->{"form"}; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $choose = h_abbr(C_("Choose")); $delete = h_abbr(C_("Delete")); # "" means not selected yet $form->delete($col) if defined $form->param($col) && $form->param($col) eq ""; # A form to create a new item if ($self->{"type"} eq "new") { $valfalse = $self->_val_radio($nullcol, "false"); $valtrue = $self->_val_radio($nullcol, "true"); $val = $self->_val_text($col); $vallabel = h(&$titlefunc($form->param($col))); $col = h($col); $nullcol = h($nullcol); print << "EOT";
  • EOT if (defined $form->param($col)) { print << "EOT"; EOT } else { print << "EOT"; EOT } print << "EOT";
$prompt EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $form->param($nullcol, !defined $form->param($col)? "true": "false") if $self->{"is_first_form"}; $valfalse = $self->_val_radio($nullcol, "false"); $valtrue = $self->_val_radio($nullcol, "true"); $val = $self->_val_text($col); $vallabel = h(&$titlefunc($form->param($col))); $cur = defined $self->{"cur"}->param($col)? h(&$titlefunc($self->{"cur"}->param($col))): $nulllabel; $col = h($col); $nullcol = h($nullcol); $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); print << "EOT"; $orig $cur
  • EOT if (defined $form->param($col)) { print << "EOT"; EOT } else { print << "EOT"; EOT } print << "EOT";
$prompt EOT # A form to delete a current item } elsif ($self->{"type"} eq "del") { $cur = defined $self->{"cur"}->param($col)? h(&$titlefunc($self->{"cur"}->param($col))): $nulllabel; print << "EOT"; $mark$label $cur EOT } return; } # _html_coltmpl_select: The selection column sub _html_coltmpl_select : method { local ($_, %_); my ($self, $form, $current, $col, $label, $optfunc, $titlefunc, $prompt, $mark, $colspan); my ($cur, $orig, $new); ($self, $col, $label, $optfunc, $titlefunc, $prompt) = @_; $form = $self->{"form"}; $current = $self->{"cur"}; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $mark = $self->_mark($col); $colspan = $self->_colspan; # A form to create a new item if ($self->{"type"} eq "new") { $col = h($col); print << "EOT"; $prompt EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $cur = h(&$titlefunc($self->{"cur"}->param($col))); $col = h($col); $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); print << "EOT"; $orig $cur $prompt EOT # A form to delete a current item } elsif ($self->{"type"} eq "del") { $cur = h(&$titlefunc($self->{"cur"}->param($col))); print << "EOT"; $mark$label $cur EOT } } # _html_coltmpl_select_multi: The multiple selection column sub _html_coltmpl_select_multi : method { local ($_, %_); my ($self, $form, $current, $col, $label, $optfunc, $prompt, $mark, $colspan); my ($orig, $new, $count, $col0, $col_); ($self, $col, $label, $optfunc, $prompt) = @_; $form = $self->{"form"}; $current = $self->{"cur"}; $prompt = !defined $prompt? "": "\n

" . h_abbr($prompt) . "

\n "; $mark = $self->_mark($col); $colspan = $self->_colspan; # Find the last used category index, and append 3 blank selections for ($_ = 0; defined $form->param("$col$_"); $_++) { }; for ($_--; $_ >= 0 && $form->param("$col$_") eq ""; $_--) { }; $count = $_ + 3; # A form to create a new item if ($self->{"type"} eq "new") { $col0 = h($col . "0"); print << "EOT"; EOT print " "; for ($_ = 0, @_ = qw(); $_ <= $count; $_++) { $col_ = h($col . $_); push @_, "
  • \n" . "
  • \n"; } print "
      \n" . join("", @_) . "
    \n "; print << "EOT"; $prompt EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $col0 = h($col . "0"); $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); print << "EOT"; $orig EOT print " "; for ($_ = 0, @_ = qw(); $_ < $current->param("$col" . "count"); $_++) { push @_, "
  • " . h($current->param("$col$_" . "title")) . "
  • \n"; } print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); print << "EOT"; EOT print " "; for ($_ = 0, @_ = qw(); $_ <= $count; $_++) { $col_ = h($col . $_); push @_, "
  • \n" . "
  • \n"; } print "
      \n" . join("", @_) . "
    \n "; print << "EOT"; $prompt EOT # A form to delete a current item } elsif ($self->{"type"} eq "del") { print << "EOT"; $mark$label EOT print " "; for ($_ = 0, @_ = qw(); $_ < $current->param("$col" . "count"); $_++) { push @_, "
  • " . h($current->param("$col$_" . "title")) . "
  • \n"; } print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); print << "EOT"; EOT } } # _html_coltmpl_radio: The radio column sub _html_coltmpl_radio : method { local ($_, %_); my ($self, $form, $current, $col, $label, $opts, $prompt, $oneline, $mark, $colspan); my ($orig, $new, $coldef, $found); ($self, $col, $label, $opts, $prompt, $oneline) = @_; $form = $self->{"form"}; $current = $self->{"cur"}; $prompt = !defined $prompt? "": "\n

    " . h_abbr($prompt) . "

    \n "; $mark = $self->_mark($col); $colspan = $self->_colspan; $oneline = 0 if !defined $oneline; $oneline = $oneline? " class=\"oneline\"": ""; # A form to create a new item if ($self->{"type"} eq "new") { $coldef = $col . (exists ${$$opts[0]}{"id"}? ${$$opts[0]}{"id"}: ${$$opts[0]}{"val"}); print << "EOT"; EOT print " "; for ($_ = 0, @_ = qw(); $_ < @$opts; $_++) { my $id; $id = $col . (exists ${$$opts[$_]}{"id"}? ${$$opts[$_]}{"id"}: ${$$opts[$_]}{"val"}); push @_, sprintf("
  • \n" . "
  • \n" . "
  • \n" . " \n" . " %5\$s\n" . "
  • \n", h($col), h($_), $self->_val_text("$col$_" . "sn"), $self->_val_check("$col$_"), h_abbr(&$titlefunc($form->param("$col$_" . "sn")))); } else { push @_, sprintf( "
  • \n" . " \n" . " %5\$s\n" . "
  • \n", h($col), h($_), $self->_val_text("$col$_" . "sn"), $self->_val_check("$col$_"), h_abbr(t_na)); } } print "\n" . join("", @_) . " \n" . " $prompt"; print << "EOT"; EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $colfree = $col . "free"; $valfree = $self->_val_text($colfree, $colfree); $colfree = h($colfree); $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); print << "EOT"; $orig EOT print " "; for ($_ = 0, @_ = qw(); $_ < $current->param($col . "count"); $_++) { push @_, $self->_cval_text("$col$_" . "title"); } print @_ > 0? join(", ", @_): h_abbr(t_none); print << "EOT"; EOT print " "; for ($_ = 0, @_ = qw(); defined $form->param("$col$_" . "sn"); $_++) { if (check_sn_in ${$form->param_fetch("$col$_" . "sn")}[0], $table) { push @_, sprintf( "
  • \n" . " \n" . " %5\$s\n" . "
  • \n", h($col), h($_), $self->_val_text("$col$_" . "sn"), $self->_val_check("$col$_"), h_abbr(&$titlefunc($form->param("$col$_" . "sn")))); } else { push @_, sprintf( "
  • \n" . " \n" . " %5\$s\n" . "
  • \n", h($col), h($_), $self->_val_text("$col$_" . "sn"), $self->_val_check("$col$_"), h_abbr(t_na)); } } print "\n" . join("", @_) . " \n" . " $prompt"; print << "EOT"; EOT # A form to delete a current item } else { print << "EOT"; $mark$label EOT print " "; for ($_ = 0, @_ = qw(); $_ < $current->param($col . "count"); $_++) { push @_, $self->_cval_text("$col$_" . "title"); } print @_ > 0? join(", ", @_): h_abbr(t_none); print << "EOT"; EOT } return; } # _html_coltmpl_date: Display a date column sub _html_coltmpl_date : method { local ($_, %_); my ($self, $form, $col, $label, $prompt, $size, $mark, $colspan); my ($cur, $val, $orig, $new); ($self, $col, $label, $prompt, $size) = @_; $form = $self->{"form"}; $mark = $self->_mark($col); $colspan = $self->_colspan; $prompt = !defined $prompt? "": "\n

    " . h_abbr($prompt) . "

    \n "; $size = h(10) if !defined $size; # A form to create a new item if ($self->{"type"} eq "new") { # Set the default date to today $form->param($col, time) if $self->{"is_first_form"}; $val = $self->_val_date($col, $col); $col = h($col); print << "EOT"; $prompt EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $cur = defined $self->{"cur"}->param($col)? h(fmtdate $self->{"cur"}->param($col)): h_abbr(t_none); $val = $self->_val_date($col, $col); $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); # A multi-lingual column, that is not in the default language if (in_array($col, @{$self->{"mlcols"}}) && getlang ne $DEFAULT_LANG) { my ($srclabel, $srccur); $srclabel = h_abbr(C_("Source:")); $_ = $col . "_" . ln($DEFAULT_LANG, LN_DATABASE); $srccur = defined $self->{"cur"}->param($_)? h($self->{"cur"}->param($_)): h_abbr(t_none); $col = h($col); print << "EOT"; $srclabel $srccur $orig $cur $prompt EOT # A uni-lingual column } else { $col = h($col); print << "EOT"; $orig $cur $prompt EOT } # A form to delete a current item } elsif ($self->{"type"} eq "del") { $cur = defined $self->{"cur"}->param($col)? h(fmtdate $self->{"cur"}->param($col)): h_abbr(t_none); print << "EOT"; $mark$label $cur EOT } return; } # _html_coltmpl_url: The URL column sub _html_coltmpl_url : method { $_[0]->{"form"}->param($_[1], "http://") if $_[0]->{"is_first_form"} && !defined $_[0]->{"form"}->param($_[1]); $_[0]->_html_coltmpl_text($_[1], $_[2], $_[3], $_[4]); } ################### # Columns, sorted alphabetically ################### # _html_col_addr: The address sub _html_col_addr : method { $_[0]->_html_coltmpl_text("addr", h_abbr(C_("Address:"))); } # _html_col_author: The author sub _html_col_author : method { $_[0]->_html_coltmpl_text("author", h_abbr(C_("Author:"))); } # _html_col_body: The content body sub _html_col_body : method { $_[0]->_html_coltmpl_textarea("body", h_abbr(C_("Content:")), h_abbr(C_("Fill in the content here."))); } # _html_col_captcha: The CAPTCHA (human test) # Add a field that is not displayed and should be empty to trap spam # See: http://www.hockinson.com/programmer-web-designer-denver-co-usa.php?s=44 sub _html_col_captcha : method { local ($_, %_); my ($self, $col, $label, $prompt, $size, $class, $mark, $colspan); my ($thclass, $thcolspan); $self = $_[0]; $mark = $self->_mark("captcha"); $col = FORM_CAPTCHA; $label = h_abbr(C_("Current Website:")); $size = h($self->{"defsize"}); $class = " class=\"text\""; $colspan = $self->_colspan; $prompt = "\n

    " . h_abbr(C_("Enter your website URL here.")) . "

    \n "; # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $prompt EOT return; } # _html_col_created: The creation time sub _html_col_created : method { $_[0]->_html_coltmpl_ro_datetime("created", h_abbr(C_("Created:"))); } # _html_col_createdby: The creator sub _html_col_createdby : method { $_[0]->_html_coltmpl_ro_user("createdby", h_abbr(C_("Created by:"))); } # _html_col_disabled: Disabled? sub _html_col_disabled : method { $_[0]->_html_coltmpl_bool("email", h_abbr(C_("Disabled?")), h_abbr(C_("Disabled")), h_abbr(C_("Enabled")), h_abbr(C_("Disable it."))); } # _html_col_date: The date sub _html_col_date : method { $_[0]->_html_coltmpl_date("date", C_("Date:")); } # _html_col_dsc: The description sub _html_col_dsc : method { $_[0]->_html_coltmpl_textarea("dsc", h_abbr(C_("Description:")), h_abbr(C_("Fill in the description here.")), undef, 4); } # _html_col_email: The e-mail sub _html_col_email : method { $_[0]->_html_coltmpl_text("email", h_abbr(C_("E-mail:"))); } # _html_col_fax: The facsimile number sub _html_col_fax : method { $_[0]->_html_coltmpl_text("fax", h_abbr(C_("Fax.:"))); } # _html_col_grp: The group sub _html_col_grp : method { $_[0]->_html_coltmpl_call("grp", h_abbr(C_("Group:")), \&groupdsc); } # _html_col_hid: Hide? sub _html_col_hid : method { $_[0]->_html_coltmpl_bool("hid", h_abbr(C_("Hide?")), h_abbr(C_("Hide it")), h_abbr(C_("Show it")), h_abbr(C_("Hide it currently."))); } # _html_col_html: HTML? sub _html_col_html : method { $_[0]->_html_coltmpl_bool("html", h_abbr(C_("HTML?")), h_abbr(C_("HTML")), h_abbr(C_("Plain text")), h_abbr(C_("The submitted content is HTML."))); } # _html_col_host: The hostname sub _html_col_host : method { $_[0]->_html_coltmpl_ro("host", h_abbr(C_("Host:"))); } # _html_col_id: The ID. sub _html_col_id : method { $_[0]->_html_coltmpl_text("id", h_abbr(C_("ID.:"))); } # _html_col_identity: The Identity sub _html_col_identity : method { $_[0]->_html_coltmpl_text("identity", h_abbr(C_("Identity:"))); } # _html_col_intro: The introduction sub _html_col_intro : method { $_[0]->_html_coltmpl_textarea("intro", h_abbr(C_("Introduction:")), h_abbr(C_("Fill in the introduction here.")), undef, 4); } # _html_col_ip: The IP sub _html_col_ip : method { $_[0]->_html_coltmpl_ro("ip", h_abbr(C_("IP:"))); } # _html_col_kw: The keywords list sub _html_col_kw : method { $_[0]->_html_coltmpl_text("kw", h_abbr(C_("Keywords:"))); } # _html_col_lang: The language sub _html_col_lang : method { $_[0]->_html_coltmpl_ro_lang("lang", h_abbr(C_("Language:"))); } # _html_col_location: The location sub _html_col_location : method { $_[0]->_html_coltmpl_text("location", h_abbr(C_("Location:"))); } # _html_col_message: The message sub _html_col_message : method { $_[0]->_html_coltmpl_textarea("message", h_abbr(C_("Message:")), h_abbr(C_("Fill in the message here."))); } # _html_col_name: The name sub _html_col_name : method { $_[0]->_html_coltmpl_text("name", h_abbr(C_("Name:"))); } # _html_col_ord: The order sub _html_col_ord : method { local ($_, %_); my ($self, $form); $self = $_[0]; $form = $self->{"form"}; # Set the default order to the half of the maximum $form->param("ord", (10 ** ${$self->{"maxlens"}}{"ord"}) / 2) if $self->{"is_first_form"} && $self->{"type"} eq "new"; $self->_html_coltmpl_text("ord", h_abbr(C_("Order:")), undef, ${$self->{"maxlens"}}{"ord"}); } # _html_col_parent: The parent sub _html_col_parent : method { $_[0]->_html_coltmpl_call_null("parent", h_abbr(C_("Parent category:")), "topmost", h_abbr(C_("At the very top")), $MAIN->can($_[0]->{"table"} . "_title")); } # _html_col_passwd: The password sub _html_col_passwd : method { local ($_, %_); my ($self, $label, $label2, $dummy, $val, $val_id, $passid, $mark, $colspan); my ($orig, $new, $size); $self = $_[0]; $mark = $self->_mark("passwd"); $colspan = $self->_colspan; $size = h($self->{"defsize"}); $label = h_abbr(C_("Password:")); $label2 = h_abbr(C_("Confirm password:")); $dummy = "*" x ${$self->{"maxlens"}}{"passwd"}; # A form to create a new item if ($self->{"type"} eq "new") { print << "EOT"; EOT # There is a previously-saved password if (defined($passid = $self->{"form"}->param("passid"))) { $passid = h($passid); $val = $self->_val_scalar($dummy, "passwd"); print << "EOT"; EOT } else { $val = $self->_val_scalar(undef, "passwd"); print << "EOT"; EOT } print << "EOT"; EOT # There is a previously-saved password if (defined($passid = $self->{"form"}->param("passid2"))) { $passid = h($passid); $val = $self->_val_scalar($dummy, "passwd"); print << "EOT"; EOT } else { $val = $self->_val_scalar(undef, "passwd"); print << "EOT"; EOT } print << "EOT"; EOT # A form to edit a current item } elsif ($self->{"type"} eq "cur") { print << "EOT"; EOT # There is a previous-saved password if (defined($passid = $self->{"form"}->param("passid"))) { $passid = h($passid); $val = $self->_val_scalar($dummy, "passwd"); print << "EOT"; EOT } else { $val = $self->_val_scalar(undef, "passwd"); print << "EOT"; EOT } print << "EOT"; EOT # There is a previous-saved password if (defined($passid = $self->{"form"}->param("passid2"))) { $passid = h($passid); $val = $self->_val_scalar($dummy, "passwd"); print << "EOT"; EOT } else { $val = $self->_val_scalar(undef, "passwd"); print << "EOT"; EOT } print << "EOT"; EOT # A form to delete a current item } elsif ($self->{"type"} eq "del") { $dummy = h($dummy); print << "EOT"; $mark$label $dummy EOT } return; } # _html_col_path: The page path sub _html_col_path : method { local ($_, %_); my ($self, $form); $self = $_[0]; $form = $self->{"form"}; # Set the default path to "/" $form->param("path", "/") if $self->{"is_first_form"} && $self->{"type"} eq "new"; $self->_html_coltmpl_text("path", h_abbr(C_("Page path:"))); } # _html_col_pic: The picture sub _html_col_pic : method { local ($_, %_); my ($self, $form, $current, $label, $labelpos, $labelcap, $mark, $colspan); my ($curpic, $curcap, $curpos, $val, $valpic, $valcap, $orig, $new); my ($PICS, $pic, $setpic, $delpic, $picposid_default, $alt, $origalt); $self = $_[0]; $form = $self->{"form"}; $current = $self->{"cur"}; $mark = $self->_mark("pic"); $colspan = $self->_colspan; $label = h_abbr(C_("Picture:")); $labelcap = h_abbr(C_("Pic. caption:")); $labelpos = h_abbr(C_("Pic. position:")); # Obtain the picture deposit $PICS = pic_deposit; $setpic = h_abbr(C_("Set the picture")); $delpic = h_abbr(C_("Delete this picture")); $picposid_default = h("picpos" . lc PIC_POS_DEFAULT); # A form to create a new item if ($self->{"type"} eq "new") { $alt = h_abbr(C_("Picture preview")); if (!defined $form->param("pic")) { $_ = h_abbr(t_none); print << "EOT"; $_ EOT } elsif (!pic_exists ${$form->param_fetch("pic")}[0]) { $_ = h_abbr(t_na); print << "EOT"; $_ EOT } else { $val = $self->_val_text("pic"); $pic = $$PICS{$form->param("pic")}; $valpic = echopic $pic, $alt, $$pic{"ratio"}; $valcap = $self->_val_text("piccap", "piccap"); print << "EOT"; $valpic
    EOT print " "; @_ = map sprintf("%s", h(lc $_), $self->_val_radio("picpos", $_, ($_ eq PIC_POS_DEFAULT)), h(lc $_), h_abbr(picpos_label $_)), @PIC_VALID_POS; print join("\n ", @_); print << "EOT"; EOT } # A form to edit a current item } elsif ($self->{"type"} eq "cur") { $orig = h_abbr(C_("Original:")); $new = h_abbr(C_("New:")); $origalt = h_abbr(C_("Original picture preview")); $alt = h_abbr(C_("New picture preview")); if (!defined $current->param("pic")) { $curpic = h_abbr(t_none); } elsif ($current->param("pic") == 0) { $curpic = h_abbr(t_na); } else { $pic = $$PICS{$current->param("pic")}; $curpic = echopic $pic, $origalt, $$pic{"ratio"}; } print << "EOT"; $orig $curpic EOT if ( !pic_exists(${$current->param_fetch("pic")}[0]) && getlang ne $DEFAULT_LANG) { $_ = h_abbr(C_("Please upload a new picture from [_1].", ln($DEFAULT_LANG, LN_DESC_CURLC))); print << "EOT"; $_ EOT } elsif (!defined $form->param("pic")) { $_ = h_abbr(t_none); print << "EOT"; $_ EOT } elsif (!pic_exists ${$form->param_fetch("pic")}[0]) { $_ = h_abbr(t_na); print << "EOT"; $_ EOT } else { $curcap = $self->_cval_text("piccap"); $curpos = h_abbr(picpos_label $current->param("picpos")); $val = $self->_val_text("pic"); $pic = $$PICS{$form->param("pic")}; $valpic = echopic $pic, $alt, $$pic{"ratio"}; $valcap = $self->_val_text("piccap", "piccap"); print << "EOT"; $valpic
    EOT # A multi-lingual column, that is not in the default language if (getlang ne $DEFAULT_LANG) { my ($srclabel, $srccur); $srclabel = h_abbr(C_("Source:")); $_ = "piccap_" . ln($DEFAULT_LANG, LN_DATABASE); $srccur = $self->_cval_text($_); print << "EOT"; $srclabel $srccur $orig $curcap EOT } else { print << "EOT"; $orig $curcap EOT } print << "EOT"; $orig $curpos EOT print " "; @_ = map sprintf("%s", h(lc $_), h($_), $self->_val_radio("picpos", $_, ($_ eq PIC_POS_DEFAULT)), h(lc $_), h_abbr(picpos_label $_)), @PIC_VALID_POS; print join("\n ", @_); print << "EOT"; EOT } # A form to delete a current item } elsif ($self->{"type"} eq "del") { $alt = h_abbr(C_("Picture preview")); if (!defined $current->param("pic")) { $curpic = h_abbr(t_none); print << "EOT"; $mark$label $curpic EOT } elsif ($current->param("pic") == 0) { $curpic = h_abbr(t_na); print << "EOT"; $mark$label $curpic EOT } else { $pic = $$PICS{$current->param("pic")}; $curpic = echopic $pic, $origalt, $$pic{"ratio"}; $curcap = $self->_cval_text("piccap"); $curpos = h_abbr(picpos_label $current->param("picpos")); print << "EOT"; $mark$label $curpic $mark$labelcap $curcap $mark$labelpos $curpos EOT } } return; } # _html_col_scats: The subcategories sub _html_col_scats : method { local ($_, %_); my ($self, $form, $current, $label, $url, $mark, $colspan, $thclass, $thcolspan); $self = $_[0]; $form = $self->{"form"}; $current = $self->{"cur"}; $mark = $self->_mark("scats"); $colspan = $self->_colspan; $label = h_abbr(C_("[numerate,_1,Subcategory,Subcategories]:", $current->param("scatcount"))); # A current form span for 2 columns $thclass = $self->{"type"} ne "cur"? " class=\"th\"": ""; $thcolspan = $self->{"type"} eq "cur"? " colspan=\"2\"": ""; print << "EOT"; $mark$label EOT print " "; @_ = qw(); for ($_ = 0; $_ < $current->param("scatcount"); $_++) { push @_, sprintf("
  • %2\$s\n" . " (%3\$s)\n" . "
  • \n", h($REQUEST_FILE . "?form=cur&sn=" . $current->param("scat$_" . "sn")), h($current->param("scat$_" . "title")), h($current->param("scat$_" . "url"))); } print @_ > 0? "
      \n" . join("", @_) . "
    \n ": h_abbr(t_none); print << "EOT"; EOT } # _html_col_script: The script sub _html_col_script : method { $_[0]->_html_coltmpl_text("script", h_abbr(C_("Script:"))); } # _html_col_sn: The serial number sub _html_col_sn : method { $_[0]->_html_coltmpl_ro("sn", h_abbr(C_("S/N:"))); } # _html_col_tel: The telephone number sub _html_col_tel : method { $_[0]->_html_coltmpl_text("tel", h_abbr(C_("Tel.:"))); } # _html_col_title: The title sub _html_col_title : method { $_[0]->_html_coltmpl_text("title", h_abbr(C_("Title:"))); } # _html_col_title_en: The English title sub _html_col_title_en : method { $_[0]->_html_coltmpl_text("title_en", h_abbr(C_("English title:"))); } # _html_col_updated: The last-update time sub _html_col_updated : method { $_[0]->_html_coltmpl_ro_datetime("updated", h_abbr(C_("Updated:"))); } # _html_col_updatedby: The last maintainer sub _html_col_updatedby : method { $_[0]->_html_coltmpl_ro_user("updatedby", h_abbr(C_("Updated by:"))); } # _html_col_url: The URL sub _html_col_url : method { $_[0]->_html_coltmpl_url("url", h_abbr(C_("URL:"))); } # _html_col_value: The preference value sub _html_col_value : method { $_[0]->_html_coltmpl_text("value", h_abbr(C_("Value:"))); } # _html_col_visited: The last-visited time sub _html_col_visited : method { $_[0]->_html_coltmpl_ro_datetime("visited", h_abbr(C_("Visited:"))); } # _html_col_visits: The visiting counter sub _html_col_visits : method { $_[0]->_html_coltmpl_ro("visits", h_abbr(C_("Visits:"))); } ##################### # Private utility methods. Do not call them directly. ##################### # _cval_text: Output a current text value sub _cval_text : method { local ($_, %_); my ($self, $col); ($self, $col) = @_; return h($_) if defined($_ = $self->{"cur"}->param($col)); return h_abbr(t_none); } # _cval_textarea: Output a current textarea value sub _cval_textarea : method { local ($_, %_); my ($self, $col); ($self, $col) = @_; return a2html($_) if defined($_ = $self->{"cur"}->param($col)); return h_abbr(t_none); } # _val_text: Output a value sub _val_text : method { local ($_, %_); my ($self, $col, $maxcol, $html); ($self, $col, $maxcol) = @_; $html = ""; $html .= " maxlength=\"" . h(${$self->{"maxlens"}}{$maxcol}) . "\"" if defined $maxcol; $html .= defined($_ = $self->{"form"}->param($col))? " value=\"" . h($_) . "\"": " value=\"\""; return $html; } # _val_scalar: Output a scalar value sub _val_scalar : method { local ($_, %_); my ($self, $val, $maxcol, $html); ($self, $val, $maxcol) = @_; $html = ""; $html .= " maxlength=\"" . h(${$self->{"maxlens"}}{$maxcol}) . "\"" if defined $maxcol; $html .= defined $val? " value=\"" . h($val) . "\"": " value=\"\""; return $html; } # _val_date: Output a date value sub _val_date : method { local ($_, %_); my ($self, $col, $maxcol, $html, $val); ($self, $col, $maxcol) = @_; $html = ""; $html .= " maxlength=\"" . h(${$self->{"maxlens"}}{$maxcol}) . "\"" if defined $maxcol; if (defined($val = $self->{"form"}->param($col))) { $val = fmtdate $val if $val =~ /^\-?\d+(?:\.\d+)?$/; } $html .= defined $val? " value=\"" . h($val) . "\"": " value=\"\""; return $html; } # _val_textarea: Output a value as a textarea content sub _val_textarea : method { local ($_, %_); my ($self, $col, $default); ($self, $col, $default) = @_; return h($_) if defined($_ = $self->{"form"}->param($col)) && $_ ne ""; return h($default); } # _val_check: Output a value as a checkbox check value sub _val_check : method { local ($_, %_); my ($self, $col); ($self, $col) = @_; return " checked=\"checked\"" if defined($_ = $self->{"form"}->param($col)) && $_; return ""; } # _val_radio: Output a value as a radio check value sub _val_radio : method { local ($_, %_); my ($self, $col, $valhere, $is_default); ($self, $col, $valhere, $is_default) = @_; $is_default = 0 if !defined $is_default; return " value=\"" . h($valhere) . "\"" . (($_ eq $valhere)? " checked=\"checked\"": "") if defined($_ = $self->{"form"}->param($col)); return " value=\"" . h($valhere) . "\"" . ($is_default? " checked=\"checked\"": ""); } # _colspan: Output the colspan phrase sub _colspan : method { local ($_, %_); my ($self, $addcols); ($self, $addcols) = @_; $addcols = 0 if !defined $addcols; $_ = $self->{"colspan"} + $addcols; # Only output for many columns return $_ > 1? " colspan=\"" . h($_) . "\"": ""; } # _colspan_full: Output the colspan phrase spanning the whole table sub _colspan_full : method { local ($_, %_); my ($self, $addcols); ($self, $addcols) = @_; $addcols = 0 if !defined $addcols; $_ = $self->{"colspan"} + $addcols; $_ += ($self->{"type"} eq "cur")? 2: 1; # Only output for many columns return $_ > 1? " colspan=\"" . h($_) . "\"": ""; } # _mark: Output the column mark sub _mark : method { local ($_, %_); my ($self, $col); ($self, $col) = @_; # Bounce if no columns to check or no mark to use return "" if !exists $self->{"markcols"} || !defined $self->{"mark"}; %_ = map { $_ => 1 } @{$self->{"markcols"}}; return exists $_{$col}? $self->{"mark"}: ""; } # _delcolcount: Obtain the number of items of a column for the deletion form sub _delcolcount : method { local ($_, %_); my ($self, $col); ($self, $col) = @_; # None-deletion form -- return 0 since the number of items is unknown return 0 unless $self->{"type"} eq "del"; # Deletion form -- return the number of items return $self->{"cur"}->param($col . "count") } ################### # Echo the column values ################### # Selima::Form::MetaCols: Manage and output the meta form information package Selima::Form::MetaCols; use 5.008; use strict; use warnings; use Selima::ShortCut; # new: Initialize the handler sub new : method { local ($_, %_); my ($class, $self); $class = $_[0]; $self = bless {}, $class; $self->{"cols"} = []; return $self; } # add: Add a column sub add : method { local ($_, %_); my ($self, $type, $name, $value); ($self, $type, $name, $value) = @_; push @{$self->{"cols"}}, { "type" => $type, "name" => $name, "value" => $value, }; return; } # out: Output the columns sub out : method { local ($_, %_); my $self; $self = $_[0]; # Bounce for nothing return if @{$self->{"cols"}} == 0; # Output the first column $_ = shift @{$self->{"cols"}}; print "_out_attrs($_) . " />"; # Output the rest columns print "_out_attrs($_) . " />" foreach @{$self->{"cols"}}; # Output a new line print "\n"; return; } # _out_attrs: Output the attributes sub _out_attrs : method { local ($_, %_); my $self; ($self, $_) = @_; @_ = qw(); push @_, "type=\"" . h($$_{"type"}) . "\""; push @_, "name=\"" . h($$_{"name"}) . "\"" if defined $$_{"name"}; if (defined $$_{"name"} && $$_{"name"} eq "charset") { push @_, "value=\"\""; } else { push @_, "value=\"" . h($$_{"value"}) . "\""; } return join " ", @_; } return 1;