#!/usr/bin/perl -w
#------------------------------------------------------------------------------
# $Id$
#------------------------------------------------------------------------------
# Edit mail-template file CGI
#
# Copyright (c) BAYBITS LLC. All rights reserved.
#------------------------------------------------------------------------------

use strict;
use Encode;
use XML::DOM;
use HTML::Template;
use TF::XMLUtils;
use TF::CommonUtils;
use utf8;

binmode(STDOUT, ":utf8");

# global
my $LOCATION      = $ENV{'TF_LOCATION'} || '';
my $USERID        = $ENV{'REMOTE_USER'};
my $PASSWD        = $ENV{'TF_USERPLAINPASSWORD'};
my $BRAND         = $ENV{'TF_BRANDNAME'} || '';
my $USERTYPE      = $ENV{'TF_USERTYPE'} || 'normal';
my $LANGPARAM     = TF::CommonUtils::getLangPriority();
my $BACKURI       = $LOCATION . "/.cgi-bin/mailsetting";
my $OWNURI        = $LOCATION . "/.cgi-bin/mailedit";
my $MLROOT        = $ENV{'TF_MLTEMPLATE_ROOT'} || '.';
my $TEMPLATE_FILE = './tmpl/mailedit.tmpl.' . $LANGPARAM;
my $MLSERVERSEND  = $ENV{'TF_MLSERVERSEND'} || 'off';
my $TF_MLEDIT     = $ENV{'TF_MLEDIT'} || 'off';
my $TF_TOKEN      = $ENV{'TF_TOKEN'} || undef;
my %form;
my $CMDTYPE       = {
					cmdReadDefault => 'READDEFAULT',
					cmdBackDefault => 'BACKDEFAULT',
					cmdUpdate => 'UPDATE',
					cmdView => 'VIEW',
					cmdPreview => 'PREVIEW',
				};
my $MSGTABLE_ja   =	{
					mErrNoTemplate => 'メールテンプレートファイルが見つかりませんでした',
					mErrNoMailname => 'メールテンプレートの指定に問題があります。開発元までお問合せ下さい。',
					mErrKINSOKU    => '&lt;![CDATA[ や ]]&gt;という文字列は使用できません',
					mErrMoji       => 'メール本文または題名に利用できない不正な文字が含まれて下りました。',
					mErrInvalidPrm => '値が不正です',
					mLangNameJa    => '日本語',
					mLangNameEn    => '英語',
				};
my $MSGTABLE_en   =	{
					mErrNoTemplate => 'The mail template file was missing.',
					mErrNoMailname => 'Invalid mail template file. Please contact administrator.',
					mErrKINSOKU    => 'You could not use &lt;![CDATA[ and ]]&gt; character.',
					mErrMoji       => 'Invalid character code was found in the mail body or subject.',
					mErrInvalidPrm => 'Invalid Paramater',
					mLangNameJa    => 'Japanese',
					mLangNameEn    => 'English',
				};
my $MSGTABLE      = ($LANGPARAM eq 'ja') ? $MSGTABLE_ja : $MSGTABLE_en;

if (!$LOCATION || !$USERTYPE || $USERTYPE ne 'admin' || $TF_MLEDIT ne 'on') {
	TF::CommonUtils::showAccessDeny();
	die '';
}

main();

#
# main 
#
sub main {
	my $buf;
	my $REQUEST_METHOD = $ENV{'REQUEST_METHOD'} || '';
	my $CONTENT_LENGTH = $ENV{'CONTENT_LENGTH'} || 0;

	if ($REQUEST_METHOD eq "POST" && $CONTENT_LENGTH >= 0) {
		read(STDIN, $buf, $CONTENT_LENGTH);
		my @pairs = split(/&/, $buf);
		foreach my $pair (@pairs) {
			my ($name, $value) = split(/=/, $pair);
			$value =~ tr/+/ /;
			$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
			$form{$name} = $value;
		}
	}

	&printHTML();
}

#
# sub
#

sub printHTML
{
	my $fprefix     = $form{'hidMailFile'} || '';
	my $mailcmd     = $form{'hidMailCmd'}  || 'VIEW';
	my $maillang    = '';
	my $mailname    = '';
	my $subject     = '';
	my $body        = '';
	my $bodyfodder  = '';
	my $mailname_ja = '';
	my $mailname_en = '';
	my $functype_ja = '';
	my $functype_en = '';
	my $desc_ja     = '';
	my $desc_en     = '';
	my $desc        = '';
	my $mltemplate  = '';
	my $use_default = undef;
	my $isWatchMail = 0;

	if (!$fprefix) {
		TF::CommonUtils::showErrorPage($MSGTABLE->{mErrNoMailname}, $LANGPARAM);
		return;
	}

	# 監視メールかどうか
	if ($fprefix eq "template_ml.ja" || $fprefix eq "template_ml.en") {
		$isWatchMail = 1;
	}

	# 拡張子(ja/en) による言語判定
	my ($prefix, $ext) = split(/\./, $fprefix);
	if ($ext && $ext eq 'ja') {
		$maillang = $MSGTABLE->{mLangNameJa};
	}
	else {
		$maillang = $MSGTABLE->{mLangNameEn};
	}

	# View mail data
	if (!$mailcmd || $mailcmd eq $CMDTYPE->{cmdView} ||
		$mailcmd eq $CMDTYPE->{cmdPreview}) {
		$mltemplate = $MLROOT . $LOCATION . '.' . $fprefix;
		if (!-f $mltemplate) {
			$mltemplate = $MLROOT . '/' . $fprefix;
			$use_default = 1;
		}
	}
	# Read default value
	elsif ($mailcmd eq $CMDTYPE->{cmdReadDefault}) {
		$mltemplate = $MLROOT . '/' . $fprefix;
		$use_default = 1;
	}
	# Back default template
	elsif ($mailcmd eq $CMDTYPE->{cmdBackDefault}) {
		$mltemplate = $MLROOT . $LOCATION . '.' . $fprefix;
		unlink($mltemplate);

		TF::CommonUtils::redirectPage($BACKURI, $LANGPARAM);
		return;
	}
	# Write data to file
	elsif ($mailcmd eq $CMDTYPE->{cmdUpdate}) {
		$mltemplate = $MLROOT . $LOCATION . '.' . $fprefix;

		&storeMailTemplate($mltemplate, $isWatchMail);
		return;
	}

	if (!-f $mltemplate) {
		TF::CommonUtils::showErrorPage($MSGTABLE->{mErrNoTemplate}, $LANGPARAM);
		return;
	}

	my $xml = new XML::DOM::Parser;
	my $doc = $xml->parsefile($mltemplate);

	for my $elem ($doc->getElementsByTagName("TF:mailproperty")) {
		$subject     = &getEncText($elem, "TF:subject");
		$body        = &getEncText($elem, "TF:body");
		$bodyfodder  = &getEncText($elem, "TF:bodyfodder");
		$mailname    = &getEncText($elem, "TF:mailname", $LANGPARAM);
		$desc        = &getEncText($elem, "TF:description", $LANGPARAM);
		$mailname_ja = &getEncText($elem, "TF:mailname", 'ja');
		$mailname_en = &getEncText($elem, "TF:mailname", 'en');
		$functype_ja = &getEncText($elem, "TF:functiontype", 'ja');
		$functype_en = &getEncText($elem, "TF:functiontype", 'en');
		$desc_ja     = &getEncText($elem, "TF:description", 'ja');
		$desc_en     = &getEncText($elem, "TF:description", 'en');
	}

	my $default_btn = 'false';
	if ($use_default && $use_default == 1) {
		$default_btn = 'true';
	}

	if (open(TEMPLATE, "<$TEMPLATE_FILE")) {
		binmode(TEMPLATE, ":utf8");
		my $htmltmpl = HTML::Template->new(	filehandle => *TEMPLATE,
											case_sensitive => 1,
											die_on_bad_params => 0);
		if ($htmltmpl) {
			$htmltmpl->param(	brandname => $BRAND,
								maillang => $maillang,
								subject => $subject,
								body => $body,
								bodyfodder => $bodyfodder,
								isFooter => ($bodyfodder) ? 1 : 0,
								isServerSend => ($MLSERVERSEND ne 'off' || !$isWatchMail) ? 1 : 0,
								mailname => $mailname,
								desc => $desc,
								mailname_ja => $mailname_ja,
								mailname_en => $mailname_en,
								functype_ja => $functype_ja,
								functype_en => $functype_en,
								desc_ja => $desc_ja,
								desc_en => $desc_en,
								backuri => $BACKURI,
								fprefix => $fprefix,
								default_btn => $default_btn,
								token => $TF_TOKEN,
							);
			print "Content-type: text/html; charset=UTF-8\n\n";
			print $htmltmpl->output;
		}
		close(TEMPLATE);
	}
	else {
		TF::CommonUtils::showTemplateOpenErr($LANGPARAM);
	}
	$doc->dispose;
}

sub storeMailTemplate {
	my $mltemplate = shift || '';
	my $isExtraElem = shift || 0;

	if (!$mltemplate) {
		return;
	}

	# build temporary file path
	my $mltemplate_tmp = $mltemplate . '.tmp';
	if (-f $mltemplate_tmp) {
		unlink($mltemplate_tmp);
	}

	my $subject     = &getEnvFormValue('txtSubject');
	my $body        = &getEnvFormValue('txaBody');
	my $fbody       = &getEnvFormValue('txaFbody');
	my $mailname_ja = &getEnvFormValue('hidMailName_ja');
	my $mailname_en = &getEnvFormValue('hidMailName_en');
	my $functype_ja = &getEnvFormValue('hidMailFunctype_ja');
	my $functype_en = &getEnvFormValue('hidMailFunctype_en');
	my $desc_ja     = &getEnvFormValue('hidMailDesc_ja');
	my $desc_en     = &getEnvFormValue('hidMailDesc_en');
	my $csrftoken   = &getEnvFormValue('hidcsrftoken') || undef;

	if (!defined $csrftoken || !defined $TF_TOKEN) {
		TF::CommonUtils::showErrorPage($MSGTABLE->{mErrInvalidPrm}, $LANGPARAM);
		return;
	}

	if ($csrftoken !~ /$TF_TOKEN/) {
		TF::CommonUtils::showErrorPage($MSGTABLE->{mErrInvalidPrm}, $LANGPARAM);
		return;
	}
	
	if ($subject =~ /<!\[CDATA\[/ || $subject =~ /\]\]>/) {
		TF::CommonUtils::showErrorPage($MSGTABLE->{mErrKINSOKU}, $LANGPARAM);
		return;
	}
	if ($body =~ /<!\[CDATA\[/ || $body =~ /\]\]>/) {
		TF::CommonUtils::showErrorPage($MSGTABLE->{mErrKINSOKU}, $LANGPARAM);
		return;
	}

	if (open(XMLFILE, ">$mltemplate_tmp")) {
		binmode(XMLFILE, ":utf8");
		print XMLFILE <<"_END_";
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<TF:mailrequest xmlns:TF="http://www.teamfile.com/DTD/TF/">
<TF:mailproperty>
_END_
		if ($isExtraElem == 1) {
			print XMLFILE <<"_END_";
<TF:method>\@method\@</TF:method>
<TF:srcuri><![CDATA[\@srcuri\@]]></TF:srcuri>
<TF:dsturi><![CDATA[\@dsturi\@]]></TF:dsturi>
<TF:from><![CDATA[\@from@]]></TF:from>
_END_
		}

		print XMLFILE <<"_END_";
<TF:subject><![CDATA[$subject]]></TF:subject>
<TF:body><![CDATA[$body]]></TF:body>
_END_
		if ($isExtraElem == 1) {
			print XMLFILE <<"_END_";
<TF:bodyfodder><![CDATA[$fbody]]></TF:bodyfodder>
<TF:filelist><TF:filename><![CDATA[\@filename\@]]></TF:filename></TF:filelist>
_END_
		}
		print XMLFILE <<"_END_";
<TF:mailname xml:lang='ja'><![CDATA[$mailname_ja]]></TF:mailname>
<TF:mailname xml:lang='en'><![CDATA[$mailname_en]]></TF:mailname>
<TF:functiontype xml:lang='ja'><![CDATA[$functype_ja]]></TF:functiontype>
<TF:functiontype xml:lang='en'><![CDATA[$functype_en]]></TF:functiontype>
<TF:description xml:lang='ja'><![CDATA[$desc_ja]]></TF:description>
<TF:description xml:lang='en'><![CDATA[$desc_en]]></TF:description>
</TF:mailproperty>
</TF:mailrequest>
_END_
		close(XMLFILE);
	}

	# try to parse XML file for checking format.
	my $xml = new XML::DOM::Parser;
	my $doc = $xml->parsefile($mltemplate_tmp);

	if (!$doc) {
		TF::CommonUtils::showErrorPage($MSGTABLE->{mErrMoji}, $LANGPARAM);
		unlink($mltemplate_tmp);
	}
	else {
		$doc->dispose;
		rename($mltemplate_tmp, $mltemplate);
	}

	TF::CommonUtils::redirectPage($BACKURI, $LANGPARAM);
}

sub getEncText {
	my $elem  = shift || undef;
	my $name  = shift || undef;
	my $lang = shift || '';
	my $val;
	my $dec;

	if (!$elem || !$name) {
		return '';
	}
	if ($lang) {
		$val = TF::XMLUtils::getText($elem, $name, $lang);
	}
	else {
		$val = TF::XMLUtils::getText($elem, $name);
	}
	if (!$val) {
		return '';
	}
	$dec = TF::CommonUtils::decodeUTF8($val);

	return TF::CommonUtils::escapeHTML($dec, 0);
}

sub getEnvFormValue {
	my $name = shift || undef;
	my $ret;
	my $val;

	if (!$name) {
		return '';
	}

	$val = $form{$name};
	if (!$val) {
		return '';
	}
	$ret = TF::CommonUtils::decodeUTF8($val);

	return $ret;
}

