ONO::FW::Apps::Core::Save

package ONO::FW::Apps::Core::Save;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2000-2025 Jos KIRPS [ www.kirps.com | jos_AT_kirps_DOT_com ]
# and The Joopita Project [ www.joopita.org | contact_AT_joopita_DOT_com ]
#
# This file, as well as other parts of the ONO Software Project or related
# elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################

use strict;

use ONO::IO;
use ONO::DB;
use ONO::Lib::DateTime::ToolBox;
use ONO::Ext::Morzino::ToolBox;
use ONO::Lib::Basic;

###################################################################
#
###################################################################

#: This module offers functions that allow to store generated PDF
#: sheets.

sub output_paper_save {

my (
$self,
$pdfkey,
$BLK_ref,
$vars_ref,
$HTTP,
$BASE,
$yearmonmday,
) = @_;

#: Save a PDF file generated by an ONO app.

my %vars = %$vars_ref;
my %BLK = %$BLK_ref;

my @txts = (
"Your worksheet has been saved.",
"Corrections will be saved here:",
);

if ($BLK{'lang'} eq "de") {
@txts = (
"Dein Arbeitsblatt wurde gespeichert.",
"Verbesserungen werden hier gespeichert:",
);
}

if ($BLK{'lang'} eq "lu") {
@txts = (
"Däin Aarbechtsblat gouf gespäichert.",
"Verbesserunge ginn hei gespäichert:",
);
}

if ($BLK{'lang'} eq "fr") {
@txts = (
"Votre fiche a été enregistrée.",
"Les corrections seront enregistrées ici:",
);
}

$ENV{'SCRIPT_NAME'} =~ m~/cgi-bin/local/perl/(.*?)/~;
my $community = $1;

my ($INPUT,$VIRCLASS,$TARGET_MAIN,$TARGET_NAME,$TARGET_APP,$TARGET_DIR,$DEBUG,%used,$error,$saved);

foreach my $key (keys %vars) {
if ($key eq "app_lang" || $key =~ /^app_(input|info|storage)_/ || $key eq "output_paper_save_split") {
$INPUT .= qq~<input type="hidden" name="$key" value="$vars{$key}">~;
}
if (ONO::IO->devstation && $key ne "*") {
$DEBUG .= qq~<div>$key -> $vars{$key}</div>~;
}
}

my $ws = ucfirst $BLK{'worksheet'};
$ws =~ s~[^A-Za-z]~~g;

$vars{'output_paper_save_filename'} = substr($vars{'output_paper_save_filename'},0,64);
$vars{'output_paper_save_filename'} =~ s~(\_|\.|\ )~-~g;
$vars{'output_paper_save_filename'} =~ s~[^A-Za-z0-9\-]~~g;
if (!$vars{'output_paper_save_filename'}) {
$vars{'output_paper_save_filename'} = "$vars{'app_input_print_options_title'}_${ws}_$yearmonmday";
if ($vars{'app_input_print_options_code'}) {
$vars{'output_paper_save_filename'} = "$vars{'app_input_print_options_code'}_$vars{'app_input_print_options_title'}_${ws}_$yearmonmday";
}
}
if (!$vars{'output_paper_save_filename'}) {
$vars{'output_paper_save_filename'} = "$vars{'app_input_print_options_title_default'}_${ws}_$yearmonmday";
}
$vars{'output_paper_save_filename'} =~ s~^(\.|\-|\_)~~;
if ($vars{'output_paper_save_target_change'}) {
$vars{'output_paper_save_target'} = "";
$vars{'output_paper_save_target_app'} = "";
}
if ($vars{'output_paper_save_target_app_change'}) {
$vars{'output_paper_save_target_app'} = "";
}

my $NEXT = "$BLK{'continue'}...";
my $CANCEL = qq~<input type="submit" name="output_paper_save_cancel" value="$BLK{'cancel'}" class="button_yellow mt10">~;

$TARGET_NAME = $BLK{'my_docs_files'};

my $db = ONO::DB->connect("school");

foreach my $line (ONO::DB->select($db,"${community}_school_virclass_relationships","username = '$vars{'username'}' AND status = '1'")) {
my @row = ONO::DB->readcols($line);

if (!$used{$row[2]}) {

$used{$row[2]}++;

foreach my $line2 (ONO::DB->select($db,"${community}_school_virclass","id = '$row[2]'")) {
my @row2 = ONO::DB->readcols($line2);

if ($row2[17] !~ /H/) {

if ($vars{'output_paper_save_target'} eq "virclass_$row[3]_$row[2]") {
$TARGET_NAME = "$row2[6] ($BLK{$row[3]})";
}

$VIRCLASS .= qq~<option value="virclass_$row[3]_$row[2]">$BLK{'Virclass'}: $row2[6] ($BLK{$row[3]})</option>~;

}
}
}
}

if ($VIRCLASS) {
$VIRCLASS = qq~<option value="">----</option>$VIRCLASS~;
}

$TARGET_MAIN = qq~<div class="select"><select name="output_paper_save_target">
<option value="user">$BLK{'my_docs_files'}</option>
$VIRCLASS
</select></div>
~;

if ($vars{'output_paper_save_target'}) {
my $CHANGE = qq~<input type="submit" name="output_paper_save_target_change" value="$BLK{'change'}" class="button_yellow button_mini ml10">~;
if ($vars{'output_paper_save_target_dir'}) {
$CHANGE = qq~<div class="button_yellow button_mini ml10 trans30">$BLK{'change'}</div>~;
}
$TARGET_MAIN = qq~<table class="wide_table">
<tr>
<td class="p0 w100 bold">$TARGET_NAME</td>
<td class="p0">
$CHANGE
<input type="hidden" name="output_paper_save_target" value="$vars{'output_paper_save_target'}">
</td>
</tr>
</table>
~;

if ($vars{'output_paper_save_target'}) {

my ($PATH,$CORR_PATH,$APPS,$virclass_id,$virclass_auth);
my @opts = (
"media_documents^$BLK{'Media'}: $BLK{'documents'}",
"media_public^$BLK{'Media'}: $BLK{'public'}",
"media_shared^$BLK{'Media'}: $BLK{'shared'}",
);

if ($vars{'output_paper_save_target'} =~ /^virclass_(.*?)_(.*?)$/) {
$virclass_auth = $1;
$virclass_id = $2;
if ($virclass_auth eq "owner") {
$virclass_auth = "teacher";
}
}

if ($virclass_id) {
@opts = (
"media_user_documents^$BLK{'Media'}: $vars{'username'}: $BLK{'documents'}",
"media_user_public^$BLK{'Media'}: $vars{'username'}: $BLK{'public'}",
"media_user_shared^$BLK{'Media'}: $vars{'username'}: $BLK{'shared'}",
);
if ($virclass_auth eq "teacher") {
@opts = (
"media_documents^$BLK{'Media'}: $BLK{'documents'}",
"media_documents_teachers^$BLK{'Media'}: $BLK{'teachers'}",
"media_public^$BLK{'Media'}: $BLK{'public'}",
"-",
@opts,
"-",
);

foreach my $line (ONO::DB->select($db,"${community}_school_work_plans","class = '$virclass_id' AND (active = '1' OR date_to > '$yearmonmday')","date_from,date_to")) {
my @row = ONO::DB->readcols($line);
$row[7] = ONO::Lib::DateTime::ToolBox->convert("date",$row[7],"3mUZ",$BLK{'lang'});
@opts = (@opts,"work_plan_$row[0]^$BLK{'Work_plan'}: $row[1] ($row[7])");
}
}
}

my ($APPS,$APPS_NAME);

foreach my $opt (@opts) {
if ($opt eq "-") {
$APPS .= qq~<option value="">----</option>~;
} else {
my @op = split(/\^/,$opt);
$APPS .= qq~<option value="$op[0]">$op[1]</option>~;
if ($vars{'output_paper_save_target_app'} eq $op[0]) {
$APPS_NAME = $op[1];
$APPS_NAME =~ s~^(.*?):~~;
}
}
}

$APPS = qq~<td class="w100">
<div class="select"><select name="output_paper_save_target_app">
$APPS
</select></div>
</td>
~;

if ($APPS_NAME) {
my $CHANGE = qq~<input type="submit" name="output_paper_save_target_app_change" value="$BLK{'change'}" class="button_yellow button_mini ml10">~;
if ($vars{'output_paper_save_target_dir'}) {
$CHANGE = qq~<div class="button_yellow button_mini ml10 trans30">$BLK{'change'}</div>~;
}
$APPS = qq~<td class="w100 bold">$APPS_NAME</td>
<td>
$CHANGE
<input type="hidden" name="output_paper_save_target_app" value="$vars{'output_paper_save_target_app'}">
</td>
~;
}

$TARGET_APP = qq~<tr>
<td><img class="block24 fr" src="/ono/osr/images/logic/tree_corner.gif" alt=""></td>
<td class="p0">
<table class="wide_table">
<tr>
<td><img class="block24" src="/ono/osr/images/icons/crystal/32x32/apps/file-manager.png" alt=""></td>
$APPS
</tr>
</table>
</td>
</tr>
~;

if ($vars{'output_paper_save_target_app'}) {

my ($DIRS,%DIRS_NAME,$valid_target,$recount_work_plan_docs);

if ($vars{'output_paper_save_target'} eq "user" && $vars{'output_paper_save_target_app'} =~ /^media_(documents|public|shared)$/) {
$valid_target++;
my $area = $1;
$area =~ s~[^a-z0-9]~~g;
$PATH = "media/users/".ONO::IO->deepdir($vars{'username'})."/$vars{'username'}/$area";
foreach my $dir (ONO::IO->dir($PATH,"","","","RDX")) {
$DIRS .= qq~<option value="$dir">$dir</option>~;
}
}

if ($virclass_id) {

if ($vars{'output_paper_save_target_app'} =~ /^media_user_(documents|public|shared)$/) {
$valid_target++;
my $area = $1;
$area =~ s~[^a-z0-9]~~g;
$PATH = ONO::Ext::Morzino::ToolBox->virclass_media_dir($virclass_id)."/class/$vars{'username'}/$area";
foreach my $dir (ONO::IO->dir($PATH,"","","","RDX")) {
$DIRS .= qq~<option value="$dir">$dir</option>~;
}
}

if ($virclass_auth eq "teacher") {

if ($vars{'output_paper_save_split'}) {
$CORR_PATH = ONO::Ext::Morzino::ToolBox->virclass_media_dir($virclass_id)."/documents/teachers/worksheet_corrections";
}

if ($vars{'output_paper_save_target_app'} =~ /^media_(documents|public|shared)$/) {
$valid_target++;
my $area = $1;
$area =~ s~[^a-z0-9]~~g;
$PATH = ONO::Ext::Morzino::ToolBox->virclass_media_dir($virclass_id)."/$area";
foreach my $dir (ONO::IO->dir($PATH,"","","","RDX")) {
$DIRS .= qq~<option value="$dir">$dir</option>~;
}
}

if ($vars{'output_paper_save_target_app'} =~ /^work_plan_(.*?)$/) {
my $plan = $1;
$plan =~ s~[^0-9]~~g;
my %branch = ONO::Ext::Morzino::ToolBox->branches_hash($virclass_id,3);
$valid_target++;

foreach my $line (ONO::DB->select($db,"${community}_school_work_plan_items","class = '$virclass_id' AND workplan = '$plan'","branch,code,title")) {
my @row = ONO::DB->readcols($line);
$PATH = ONO::Ext::Morzino::ToolBox->virclass_media_dir($virclass_id)."/class/work_plans/plan_$plan";
$DIRS .= qq~<option value="$row[0]">$branch{$row[5]}: $row[2] - $row[1]</option>~;
$DIRS_NAME{$row[0]} = "$row[2] - $row[1]";
}
if ($DIRS) {
$DIRS .= qq~<option value="">----</option>~;
}
my %branch = ONO::Ext::Morzino::ToolBox->branches_hash($virclass_id,0,"w");
foreach my $bra (sort keys %branch) {
$DIRS .= qq~<option value=".create_new.$bra">$BLK{'create_new'}: $branch{$bra}</option>~;
}

}
}
}

if ($valid_target) {
$NEXT = $BLK{'save'};
} else {
$error = "no_valid_target";
}

if ($vars{'output_paper_save_target_app'} !~ /^work_plan_(.*?)$/) {
if ($DIRS) {
$DIRS .= qq~<option value="">----</option>~;
}
$DIRS .= qq~<option value=".create_new">$BLK{'create_new'}</option>~;
}

$DIRS = qq~<div class="select"><select name="output_paper_save_target_dir">
$DIRS
</select></div>
~;

my $FOLDER = "folder";

if ($vars{'output_paper_save_target_dir'}) {

if ($vars{'output_paper_save_target_dir'} eq ".create_new") {
my $WS = substr(ONO::Lib::Basic->umlaut_simplify(lc $BLK{'worksheets'}),0,32);
if (ONO::IO->exists("$PATH/$WS")) {
$WS .= "_$yearmonmday";
}
my ($num,$whilecounter);
while (ONO::IO->exists("$PATH/$WS$num") && $whilecounter < 8192) {
$whilecounter++;
$num = "_$whilecounter";
}
$vars{'output_paper_save_target_dir'} = "$WS$num";
ONO::IO->mkdir("$PATH/$vars{'output_paper_save_target_dir'}");
}

my $NAME = $vars{'output_paper_save_target_dir'};

if ($vars{'output_paper_save_target_app'} =~ /^work_plan_(.*?)$/) {
my $plan = $1;
$plan =~ s~[^0-9]~~g;
$CORR_PATH .= "/work_plans/plan_$plan";
if ($vars{'output_paper_save_target_dir'} =~ /^\.create_new\.(.*?)$/) {
my $branch = $1;
$branch =~ s~[^A-Za-z0-9]~~g;
my $title = ucfirst substr($vars{'app_input_print_options_title'},0,32);
$title =~ s~\'~\'\'~g;
my $code = uc $vars{'app_input_print_options_code'};
if (!$code) {
$code = uc substr($title,0,4);
}
$code =~ s~[^A-Z0-9]~~g;
$code = substr($code,0,4);
my (
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,$isdst
) = ONO::Lib::DateTime::ToolBox->get;
ONO::DB->command(
$db,
qq~INSERT INTO ${community}_school_work_plan_items
(
title,code,class,workplan,branch,edu_group,active,status,date,
flags,cat,creation_username,creation_timestamp,modification_username,modification_timestamp
) VALUES (
'$title','$code','$virclass_id','$plan','$branch','','1','','',
'1','','$vars{'username'}','$isdst','$vars{'username'}','$isdst'
);~,
);
my $new_id = ONO::DB->get(
$db,
"id",
"${community}_school_work_plan_items",
"creation_username = '$vars{'username'}' AND creation_timestamp = '$isdst'",
);
$PATH .= "/item_$new_id";
$NAME = "$code - $title";
$FOLDER = "file";
} else {
$PATH .= "/item_$vars{'output_paper_save_target_dir'}";
$recount_work_plan_docs++;
}
ONO::IO->mkpath($PATH);
} else {
$PATH .= "/$vars{'output_paper_save_target_dir'}";
}
if ($DIRS_NAME{$NAME}) {
$NAME = $DIRS_NAME{$NAME};
}
$DIRS = qq~<span class="bold">$NAME</span>~;
$NEXT = "";
$CANCEL = qq~<input type="submit" name="output_paper_save_cancel" value="$BLK{'continue'}..." class="button_green mt10">~;
}

$TARGET_DIR = qq~<tr>
<td></td>
<td class="p0">
<table class="default_table">
<tr>
<td><img class="block24" src="/ono/osr/images/logic/tree_corner.gif" alt=""></td>
<td><img class="block24" src="/ono/osr/images/icons/crystal/32x32/filesystems/$FOLDER.png" alt=""></td>
<td>$DIRS</td>
</tr>
</table>
</td>
</tr>
~;

if ($vars{'output_paper_save_target_dir'}) {
my ($num,$whilecounter);
while (ONO::IO->exists("$PATH/$vars{'output_paper_save_filename'}$num.pdf") && $whilecounter < 8192) {
$whilecounter++;
$num = "_$whilecounter";
}
ONO::IO->mv("pdf/pdf-$pdfkey.pdf","$PATH/$vars{'output_paper_save_filename'}$num.pdf");
if (ONO::IO->exists("pdf/pdf-$pdfkey-corr.pdf")) {
if ($CORR_PATH) {
my ($num2,$whilecounter);
while (ONO::IO->exists("$CORR_PATH/$vars{'output_paper_save_filename'}$num$num2-corr.pdf") && $whilecounter < 8192) {
$whilecounter++;
$num2 = "_$whilecounter";
}
ONO::IO->mkpath($CORR_PATH);
ONO::IO->mv("pdf/pdf-$pdfkey-corr.pdf","$CORR_PATH/$vars{'output_paper_save_filename'}$num$num2-corr.pdf");
} else {
ONO::IO->mv("pdf/pdf-$pdfkey-corr.pdf","$PATH/$vars{'output_paper_save_filename'}$num-corr.pdf");
}
}
if ($recount_work_plan_docs && $vars{'output_paper_save_target_dir'}) {
my $id = $vars{'output_paper_save_target_dir'};
$id =~ s~[^0-9]~~g;
foreach my $line (ONO::DB->select($db,"${community}_school_work_plan_items","id ='$id'")) {
my @row = ONO::DB->readcols($line);
my $flags = $row[11];
$flags =~ s~[0-9]~~g;
my $nums = $row[11];
$nums =~ s~[^0-9]~~g;
my $docs;
foreach my $file (ONO::IO->dir(ONO::Ext::Morzino::ToolBox->virclass_media_dir($virclass_id)."/class/work_plans/plan_$row[4]/item_$row[0]")) {
if ($file !~ /^\./ && $file =~ /\./ && $file ne "index.shtml") {
$docs++;
}
}
if ($docs != $nums) {
$flags = "$docs$flags";
ONO::DB->command($db,"UPDATE ${community}_school_work_plan_items SET flags = '$flags' WHERE id = '$row[0]';");
}
}
}
$saved++;
my $PATH_VIEW = ONO::Lib::Basic->pathbreaks($PATH);
$TARGET_DIR .= qq~<tr>
<td><img class="block24 mt10 fr" src="/ono/osr/images/icons/crystal/32x32/ono/ok.png" alt=""></td>
<td><div class="mt10 lightgreen">$txts[0]</div></td>
</tr>
<tr>
<td><img class="block24 fr" src="/ono/osr/images/icons/crystal/32x32/filesystems/folder.png" alt=""></td>
<td class="col9"><div class="lh100">$PATH_VIEW</div></td>
</tr>
~;
}

}

if ($CORR_PATH) {
my $CORR_PATH_VIEW = ONO::Lib::Basic->pathbreaks($CORR_PATH);
$TARGET_DIR .= qq~<tr>
<td><img class="block24 mt10 fr" src="/ono/osr/images/icons/crystal/32x32/ono/arrow_red_next.png" alt=""></td>
<td><div class="mt10 lightred">$txts[1]</div></td>
</tr>
<tr>
<td><img class="block24 fr" src="/ono/osr/images/icons/crystal/32x32/filesystems/folder.png" alt=""></td>
<td class="col9"><div class="lh100">$CORR_PATH_VIEW</div></td>
</tr>
~;
}
}
}

if ($error || !$vars{'username'} || !$pdfkey || (!$saved && !$vars{'output_paper'} && !ONO::IO->exists("pdf/pdf-$pdfkey.pdf"))) {

return qq~Ooops... a serious error occurred, please restart the app...!<br><br>user: $vars{'username'}<br>file: pdf-$pdfkey.pdf<br>error: $error~;

} else {

if ($NEXT) {
$NEXT = qq~<input type="submit" name="output_paper_save_exec" value="$NEXT" class="button_green mt10">~;
}

my $IFRAME = qq~<iframe src="$BASE/ono/osr/javascript/viewerjs/#$BASE/cgi-bin/local/perl/$community/download.pl?file=pdf-$pdfkey.pdf"
style="width:100%;height:470px;border:0px" allowfullscreen webkitallowfullscreen></iframe>
~;

if ($saved) {
$IFRAME = "";
}

return qq~<div class="inline w100">
<div class="w50 fl">
<div style="padding:2px 15px 2px 0px">
<div class="box_fabric">
<table class="default_table">
<tr>
<td><img class="block24 mb5" src="/ono/osr/images/icons/crystal/32x32/actions/filesave.png" style="margin-right:3px" alt=""></td>
<td><h4 class="col6">$BLK{'Save'}</h4></td>
</tr>
</table>
<div class="box_paper">
<form method="post" action="$ENV{'SCRIPT_NAME'}">
<input type="hidden" name="output_paper_save_pdfkey" value="$pdfkey">
$INPUT
<table class="wide_table">
<tr>
<td class="tar">$BLK{'filename'}:</td>
<td class="p0">
<table class="wide_table">
<tr>
<td class="w100"><input type="text" name="output_paper_save_filename" value="$vars{'output_paper_save_filename'}" class="w95"></td>
<td>.pdf</td>
</tr>
</table>
</td>
</tr>
<tr>
<td><img class="block24 fr" src="/ono/osr/images/icons/crystal/32x32/actions/forward.png" alt=""></td>
<td>$TARGET_MAIN</td>
</tr>
$TARGET_APP
$TARGET_DIR
<tr>
<td></td>
<td class="w100">
$NEXT
$CANCEL
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
</div>
<div class="w50 fl">
<div style="padding:2px 0px 2px 15px">
$IFRAME
</div>
</div>
</div>
~;
}
}

###################################################################
# THAT'S IT :-D
###################################################################

1;

__END__