package ONO::FW::Apps::PDF;
################################################################################
# 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::Lib::Basic;
use ONO::Lib::Lang::LangKitEdu;
use ONO::FW::Apps::ToolBox;
use ONO::FW::Apps::Core;
use ONO::FW::Apps::Core::Graphics;
use ONO::Lib::Image::QR;
use ONO::Lib::PDF::Draw;
use ONO::Lib::PDF::ToolBox;
use ONO::Lib::Data::Convert;
use ONO::Lib::DateTime::ToolBox;
use ONO::Lib::Web::Domain;
use ONO::Lib::UI::Progress;
#: This module offers a number of PDF-related functions used by ONO apps.
###############################################################################
# please wait
###############################################################################
sub please_wait {
my (
$self,
$pdfkey,
$BLK_ref,
$vars_ref,
$continue,
$HTTP,
$BASE,
$switches,
) = @_;
#: Please wait message, displayed when PDF is being generated by app.
#:
#: Switches:
#:
#: -i open info box / donation window (same document)
#: -I open info box / donation window (iframe parent)
#: -a app mode
#: -P no preview
#: -S display scaling warning
#: -v process specific vars, add to back link
my %BLK = %$BLK_ref;
my %vars = %$vars_ref;
if (!$HTTP || $HTTP eq "http") {
$HTTP = ONO::IO->http();
}
my $community = ONO::IO->community();
my ($IMG,$app_mode,$SCRIPT);
if (!$continue || $switches =~ /a/) {
$app_mode++;
$continue = "$ENV{'SCRIPT_NAME'}?app_lang=$vars{'app_lang'}&app_name=$vars{'app_name'}";
foreach my $opt ('mode','dir','file') {
if ($vars{$opt}) {
$continue .= "&$opt=$vars{$opt}";
}
}
} else {
$IMG = qq~;height:480px;background-image:url('/images/app_backgrounds/printing.jpg');background-position:center;background-repeat:no-repeat;~;
}
my @txts = (
"Your custom PDF file has been generated and is now ready for download!",
"Can't find the PDF file after downloading? Please check your browser's default download location!",
"The format (US letter / Din A4), the title, the code, the number of copies and other settings may be changed under 'print options'.",
"Some printers will scale PDF documents when printing, which means that items may be printed too small or even too large.",
"You may need to manually adjust the scaling in your printer settings when printing this document!",
"print test sheet",
);
if ($BLK{'lang'} eq "de") {
@txts = (
"Deine maßgeschneiderte PDF-Datei wurde generiert und steht jetzt zum Download bereit!",
"Du kannst die PDF Datei nach dem Download nicht finden? Sieh bitte im Download Verzeichnis deines Browsers nach!",
"Format (Din A4 / US Letter), Titel, Code, Anzahl der Exemplare und weitere Einstellungen kannst du unter 'Druckoptionen' ändern.",
"Einige Drucker skalieren PDF-Dokumente, so dass Elemente möglicherweise zu klein oder sogar zu groß gedruckt werden.",
"Eventuell müsst du die Skalierung in deinen Druck-Einstellungen manuell anpassen, um dieses Dokument zu drucken!",
"Testblatt drucken",
);
}
if ($BLK{'lang'} eq "fr") {
@txts = (
"Votre fichier PDF personnalisé a été généré et est maintenant prêt à être téléchargé!",
"Vous ne trouvez pas le fichier PDF après l'avoir téléchargé? Veuillez vérifier le répertoire téléchargements de votre navigateur web!",
"Le format (A4 / US), le titre, le code, le nombre de copies et d'autres paramètres peuvent être modifiés sous 'options d'impression'.",
"Certaines imprimantes mettront à l'échelle les documents PDF, les éléments peuvent être trop petits ou trop grands.",
"Vous devrez peut-être ajuster la mise à l'échelle dans les paramètres de votre imprimante lors de l'impression de ce document!",
"imprimer page test",
);
}
if ($BLK{'lang'} eq "lu") {
@txts = (
"Deng personaliséiert PDF Datei gouf generéiert an ass elo prett fir erofzelueden!",
"Du kanns d'PDF Datei nom Download net fannen? Kuck w.e.g am Download Verzeechnis vun dengem Browser no!",
"D'Format (Din A4 / US Letter), den Titel, de Code, d'Zuel vun de Kopien an aner Astellunge kanns du ënner 'Dréckoptiounen' änneren.",
"Verschidde Printer wäerte PDF-Dokumenter skaléieren, sou datt Elementer ze kleng oder souguer ze grouss kënne ginn.",
"Du muss vläicht d'Skaléierung an denge Print-Astellunge manuell upassen wann s du dëst Dokument drécks!",
"Testblat drécken",
);
}
my $SERVER_NAME = $ENV{'SERVER_NAME'};
if ($SERVER_NAME !~ /[a-z]/) {
if (ONO::IO->exists("etc/domain.conf")) {
my $DOMAIN = ONO::IO->load("etc/domain.conf");
if ($DOMAIN =~ /[a-z]/ && $DOMAIN =~ /\./) {
$SERVER_NAME = $DOMAIN;
}
}
}
if ($switches =~ /i/i) {
my $PARENT;
if ($switches =~ /I/) {
$PARENT = "parent.";
}
$SCRIPT = qq~<script>
if (${PARENT}document.getElementById('onofw_apps_exec_footer')) {
${PARENT}document.getElementById('onofw_apps_exec_footer').style.display='block';
}
</script>
~;
}
if ($vars{'output_worksheet_maker'}) {
return &worksheet_maker_processor("",\%vars);
} else {
if ($ENV{'HTTP_USER_AGENT'} =~ /(iphone|ipad)/i) {
return qq~<div class="center" style="padding:200px">
<div class="inline auto">
<a href="$HTTP://$SERVER_NAME$BASE/cgi-bin/local/perl/$community/download.pl?file=pdf-$pdfkey.pdf"
target="_blank" class="button_green" style="padding:20px 100px 20px 100px">$BLK{'Download'} (PDF)</a>
</div>
</div>
$SCRIPT
~;
} else {
# Nasty trick to allow downloading in background:
my $REFRESH = qq~<div class="hide"><iframe src="$HTTP://$SERVER_NAME$BASE/cgi-bin/local/perl/$community/download.pl?file=pdf-$pdfkey.pdf"></iframe></div>~;
if ($app_mode) {
my $PREVIEW;
if ($switches !~ /P/ || ONO::IO->devstation) {
$PREVIEW = qq~<div class="mt10 ml10">
<div class="box_black" style="padding:2px 10px 0px 10px;background-color:#444444">
<iframe src="$HTTP://$SERVER_NAME$BASE/ono/osr/javascript/viewerjs/#$BASE/cgi-bin/local/perl/$community/download.pl?file=pdf-$pdfkey.pdf"
style="width:100%;height:440px;border:0px" allowfullscreen webkitallowfullscreen></iframe>
</div>
</div>
~;
}
my $SCALE;
if ($switches =~ /S/) {
$SCALE = qq~<div id="ono_fw_edu_scale_warn" class="abs" style="top:-10px;left:20px;min-width:480px">
<div class="box_yellow">
<h3 class="yellow">$BLK{'Warning'}!</h3>
<div class="box_paper">
<table class="default_table">
<tr class="vtop">
<td><img class="block32 mr5" src="/ono/osr/images/icons/crystal/64x64/apps/error.png" alt=""></td>
<td><div class="large lightred mb5">$txts[3]</div></td>
</tr>
<tr class="vtop">
<td><img class="block32 mr5" src="/ono/osr/images/icons/crystal/64x64/actions/agt_forward.png" alt=""></td>
<td><div class="large green mb5">$txts[4]</div></td>
</tr>
<tr class="vtop">
<td></td>
<td>
<a href="javascript:void(0);" onclick="onojs_hide('ono_fw_edu_scale_warn');" class="button_green">OK</a>
</td>
</tr>
</table>
</div>
</div>
</div>
~;
}
return qq~<div class="inline w100 auto" style="max-width:1280px">
<div class="w50 fl">
<div class="mt10 mr10">
<div class="box_green">
<h3 class="green">$BLK{'Done'}!</h3>
<div class="box_paper">
<div class="mb10 bb">
<table class="wide_table mb10">
<tr class="vtop">
<td><img class="block48 mr5" src="/ono/osr/images/icons/crystal/64x64/actions/apply.png" alt=""></td>
<td class="p0 w100">
<div class="green large mt5">
$txts[0]
</div>
</td>
</tr>
</table>
</div>
<div class="inline">
<a href="$HTTP://$SERVER_NAME$BASE/cgi-bin/local/perl/$community/download.pl?file=pdf-$pdfkey.pdf" target="_blank"
class="button_green button_big mt10 mb10 ml10">$BLK{'download'} (PDF)</a>
<a href="$continue" class="button_yellow button_big mt10 mb10 ml10">$BLK{'back'}</a>
</div>
<div class="mt10 bt rel">
$SCALE
<table class="wide_table">
<tr class="vtop">
<td><img class="block48 mt5 mr5" src="/ono/osr/images/icons/crystal/64x64/filesystems/folder.png" alt=""></td>
<td class="p0 w100">
<div class="col9 large mt10">
$txts[1]
</div>
</td>
</tr>
</table>
</div>
<div class="mt10 bt">
<table class="wide_table">
<tr class="vtop">
<td><img class="block48 mt5 mr5" src="/ono/osr/images/icons/crystal/64x64/apps/ktip.png" alt=""></td>
<td class="p0 w100">
<div class="col9 large mt10">
$txts[2]
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="w50 fl">
$PREVIEW
</div>
</div>
$REFRESH
$SCRIPT
~;
} else {
return qq~<div class="center p20" style="$IMG">
<div class="box_green bold large mb20">$BLK{'Done'}!</div>
<div class="inline auto">
<a href="$HTTP://$SERVER_NAME$BASE/cgi-bin/local/perl/$community/download.pl?file=pdf-$pdfkey.pdf" target="_blank"
class="button_yellow button_big">$BLK{'download'} (PDF)</a>
<a href="$continue" class="button_green button_big">$BLK{'continue'}</a>
</div>
<div class="center auto w33 col9" style="margin-top:20px">
$txts[1]
</div>
</div>
$REFRESH
$SCRIPT
~;
}
}
}
}
###############################################################################
# new file
###############################################################################
sub new {
my (
$self,
$file,
$temp,
$format,
) = @_;
#: Create a new PDF file.
eval "use PDF::Reuse";
if (!$@) {
eval "use Encode";
if (!$@) {
my @dim = ONO::Lib::PDF::ToolBox->papersize($format);
prFile("$ENV{'DOCUMENT_ROOT'}/$file");
prMbox(0, 0, $dim[0], $dim[1]);
if ($temp) {
$temp = &check_us_letter("",$format,$temp);
prForm("$ENV{'DOCUMENT_ROOT'}/$temp");
}
}
}
}
###############################################################################
# new page
###############################################################################
sub page {
my (
$self,
$temp,
$format,
$canvas,
$vars_ref,
) = @_;
#: Create a new PDF page.
eval "use PDF::Reuse";
if (!$@) {
eval "use Encode";
if (!$@) {
my @dim = ONO::Lib::PDF::ToolBox->papersize($format);
prPage();
prMbox(0, 0, $dim[0], $dim[1]);
if ($temp) {
$temp = &check_us_letter("",$format,$temp);
prForm("$ENV{'DOCUMENT_ROOT'}/$temp");
}
}
}
}
sub check_us_letter {
my $format = $_[1];
my $temp = $_[2];
if ($format eq "us") {
my $test = $temp;
$test =~ s~\.pdf$~_us\.pdf~;
if (ONO::IO->exists($test)) {
$temp = $test;
}
}
return $temp;
}
###############################################################################
# end
###############################################################################
sub end {
#: Close a PDF file.
eval "use PDF::Reuse";
if (!$@) {
eval "use Encode";
if (!$@) {
prEnd();
}
}
}
###############################################################################
# headers
###############################################################################
sub headers {
my (
$self,
$vars_ref,
$title1,
$title2,
$title3,
$copyright,
$format,
$switches,
) = @_;
#: Print PDF file headers.
#:
#: Switches:
#:
#: -C alternative copyright
#: -E alternative copyright: evaluation
#: -N alternative copyright: notes
#: -X no copyright, no name, no date
my %vars = %$vars_ref;
my (
$sec,$min,$hour,$mday,$mon,$year,
$wday,$yday
) = ONO::Lib::DateTime::ToolBox->get;
my ($BLK_ref,$UCBLK_ref) = ONO::Lib::Lang::LangKitEdu->get($vars{'app_lang'},$vars_ref);
my %BLK = %$BLK_ref;
my $APPS_BASE = ONO::FW::Apps::ToolBox->apps_base();
eval "use PDF::Reuse";
if (!$@) {
eval "use Encode";
if (!$@) {
if ($format !~ /^q/) {
my $canvas = ONO::Lib::PDF::ToolBox->canvas_init($format,0,0,0,0);
if (ONO::Lib::Web::Domain->variation eq "morzino") {
ONO::Lib::PDF::Draw->color("0:111:111:111");
ONO::Lib::PDF::Draw->font("HB",16);
ONO::Lib::PDF::Draw->text($canvas,20,38,ucfirst $title1);
ONO::Lib::PDF::Draw->color("0:133:133:133");
if ($title2) {
# ONO::Lib::PDF::Draw->font("HB",12);
# ONO::Lib::PDF::Draw->text($canvas,67,19,$title2);
}
if ($title3) {
if ($title2) {
# ONO::Lib::PDF::Draw->font("HO",8);
# ONO::Lib::PDF::Draw->text($canvas,67,22,$title3);
} else {
ONO::Lib::PDF::Draw->font("H",10);
ONO::Lib::PDF::Draw->text($canvas,26,42,$title3);
}
}
ONO::Lib::PDF::Draw->color();
} else {
ONO::Lib::PDF::Draw->font("HB",32);
ONO::Lib::PDF::Draw->text($canvas,39,22,$title1);
if ($title2) {
ONO::Lib::PDF::Draw->font("HB",12);
ONO::Lib::PDF::Draw->text($canvas,67,19,$title2);
}
if ($title3) {
if ($title2) {
ONO::Lib::PDF::Draw->font("HO",8);
ONO::Lib::PDF::Draw->text($canvas,67,22,$title3);
} else {
ONO::Lib::PDF::Draw->font("HO",10);
ONO::Lib::PDF::Draw->text($canvas,48,26,$title3);
}
}
}
if ($copyright) {
my $offset_y = 0;
my $copy_x = 42;
my $encode = "E";
my $COPYRIGHT = "\251 $year $copyright";
my @FEEDBACK = (
"Student feedback",
"Teacher feedback",
"Evaluation",
);
if ($vars{'app_lang'} eq "de") {
@FEEDBACK = (
"Schüler Feedback",
"Lehrer Feedback",
"Bewertung",
);
}
if ($format eq "us") {
$offset_y = 17;
}
if ($switches =~ /C/) {
$copy_x = 18;
$encode = "";
$COPYRIGHT = "Created with $copyright";
if ($vars{'app_lang'} eq "de") {
$COPYRIGHT = "Erstellt mit $copyright";
}
if ($vars{'app_lang'} eq "fr") {
$COPYRIGHT = "Crée avec $copyright";
}
if ($vars{'app_lang'} eq "lu") {
$COPYRIGHT = "Gemaach mat $copyright";
}
}
if ($switches =~ /(E|N|X)/) {
if ($switches =~ /(E|N)/) {
if ($switches =~ /E/) {
my $off_y;
if ($format eq "us" && $ENV{'SCRIPT_NAME'} =~ /index_bookmaker/) {
$off_y = 10;
}
ONO::Lib::PDF::Draw->rect($canvas,23,245-$off_y,93,265-$off_y,0.75,"0:188:188:188","0:255:255:255",4);
ONO::Lib::PDF::Draw->rect($canvas,98,245-$off_y,168,265-$off_y,0.75,"0:188:188:188","0:255:255:255",4);
ONO::Lib::PDF::Draw->rect($canvas,173,245-$off_y,199,265-$off_y,0.75,"0:188:188:188","0:255:255:255",4);
if ($switches !~ /c/) {
ONO::Lib::PDF::Draw->image($canvas,25.5,246.5-$off_y,28,18,"ono-data/school/img/students.jpg");
ONO::Lib::PDF::Draw->image($canvas,100,246.5-$off_y,28,18,"ono-data/school/img/teacher.jpg");
}
ONO::Lib::PDF::Draw->font("H",9);
ONO::Lib::PDF::Draw->color("0:166:166:166");
ONO::Lib::PDF::Draw->text($canvas,90,250-$off_y,$FEEDBACK[0],"r","",$encode);
ONO::Lib::PDF::Draw->text($canvas,165,250-$off_y,$FEEDBACK[1],"r","",$encode);
ONO::Lib::PDF::Draw->text($canvas,196,250-$off_y,$FEEDBACK[2],"r","",$encode);
ONO::Lib::PDF::Draw->color();
ONO::Lib::PDF::Draw->text($canvas,26,269.5-$off_y,$COPYRIGHT,"","",$encode);
ONO::Lib::PDF::Draw->font("H",12);
}
if ($switches =~ /N/) {
my $off_y;
ONO::Lib::PDF::Draw->rect($canvas,23,245-$off_y,199,265-$off_y,0.75,"0:188:188:188","0:255:255:255",4);
ONO::Lib::PDF::Draw->font("H",9);
ONO::Lib::PDF::Draw->color("0:166:166:166");
ONO::Lib::PDF::Draw->text($canvas,26,250-$off_y,"Notes","","",$encode);
#ONO::Lib::PDF::Draw->color("0:99:99:99");
ONO::Lib::PDF::Draw->color("0:244:244:244");
ONO::Lib::PDF::Draw->text($canvas,26,269.5-$off_y,$COPYRIGHT,"","",$encode);
ONO::Lib::PDF::Draw->font("H",12);
ONO::Lib::PDF::Draw->color();
}
}
$COPYRIGHT = "";
} else {
ONO::Lib::PDF::Draw->font("H",12);
ONO::Lib::PDF::Draw->text($canvas,$copy_x,268-$offset_y,$COPYRIGHT,"","",$encode);
}
ONO::Lib::PDF::Draw->font("",7.5);
if ($ENV{'SCRIPT_NAME'} =~ m~/cgi-bin/local/perl/school/apps/(.*?)\.pl~ && $switches !~ /E/) {
my $APP = $1;
if ($vars{'onojs_fw_edu_pdf_app_url'}) {
$APP = $vars{'onojs_fw_edu_pdf_app_url'};
}
# the following implementation of $BASE/$HTTP is not clean, as an existing $BASE will automatically lead to a secure HTTPS connection.
# works fine for oli/morzino vs oli.education.lu for now though...
my $BASE;
if ($ENV{'SCRIPT_NAME'} =~ m~/(.*?)/(.*?)/cgi-bin/local/perl/~) {
$BASE = "/$1/$2";
}
my $HTTP = ONO::IO->http;
my $create1 = "Create your own free customised worksheets";
my $create2 = "or practice online with instant correction!";
if ($vars{'app_lang'} eq "de") {
$create1 = "Erstelle eigene, angepasste Arbeitsblätter";
$create2 = "oder übe online mit sofortiger Verbesserung!";
}
if ($vars{'app_lang'} eq "fr") {
$create1 = "Créez des fiches individualisées ou faites des";
$create2 = "exercices avec correction instantanée!";
}
if ($vars{'app_lang'} eq "lu") {
$create1 = "Maach eegen individuell Aarbechtsblieder";
$create2 = "oder üb online mat direkter Verbesserung!";
}
my $qrfile = &qrfile("",$APP,$BASE);
my $qroff;
if (!ONO::IO->exists("images/qr/$qrfile.jpg") || ONO::IO->devstation) {
ONO::IO->mkpath("images/qr");
ONO::Lib::Image::QR->make("$HTTP://$ENV{'SERVER_NAME'}$BASE/$APPS_BASE/$APP/");
}
if (ONO::IO->exists("images/qr/$qrfile.jpg")) {
$qroff = 18;
ONO::Lib::PDF::Draw->image($canvas,178,262-$offset_y,16,16,"images/qr/$qrfile.jpg",2,2);
}
ONO::Lib::PDF::Draw->text($canvas,194-$qroff,272-$offset_y,$create1,"right");
ONO::Lib::PDF::Draw->text($canvas,194-$qroff,275-$offset_y,$create2,"right");
ONO::Lib::PDF::Draw->text($canvas,194-$qroff,278-$offset_y,"$HTTP://$ENV{'SERVER_NAME'}$BASE/$APPS_BASE/$APP/","right");
}
my $legal1 = "You may copy and distribute this worksheet, it is available under the";
my $legal2 = "terms of the Creative Commons Attribution-NC-ShareAlike 3.0 license.";
my $legal3 = "http://creativecommons.org/licenses/by-nc-sa/3.0/";
if ($vars{'app_lang'} eq "de") {
$legal1 = "Du darfst dieses Arbeitsblatt kopieren und weitergeben, es steht";
$legal2 = "unter der Creative Commons Attribution-NC-ShareAlike 3.0 Lizenz.";
}
if ($vars{'app_lang'} eq "fr") {
$legal1 = "Vous pouvez copier et de distribuer cette fiche, elle est publiée";
$legal2 = "sous la licence Creative Commons Attribution-NC-ShareAlike 3.0.";
}
if ($vars{'app_lang'} eq "lu") {
$legal1 = "Du däerfs dëst Aarbechtsblat kopéieren a weiderginn, et steet";
$legal2 = "ënnert der Creative Commons Attribution-NC-ShareAlike 3.0 Lizenz.";
}
if ($switches =~ /C/) {
$legal1 = "This page may not be freely distributed, it includes user-generated";
$legal2 = "content which may be subject to copyright.";
$legal3 = "$copyright is not responsible for the content of this document.";
if ($vars{'app_lang'} eq "de") {
$legal1 = "Diese Seite darf eventuell nicht frei vertrieben werden, sie enthält";
$legal2 = "benutzergenerierte Inhalte welche geschützt sein könnten.";
$legal3 = "$copyright ist nicht verantwortlich für den Inhalt dieses Dokumentes.";
}
if ($vars{'app_lang'} eq "fr") {
$legal1 = "Cette page peut ne pas être distribuée librement, elle comprend des";
$legal2 = "éléments qui peuvent être soumis au droit d'auteur.";
$legal3 = "$copyright n'est pas responsable pour le contenu de ce document.";
}
if ($vars{'app_lang'} eq "lu") {
$legal1 = "Dës Säit däerf eventuell net fräi distribuéiert ginn, si enthält";
$legal2 = "benotzergeneréierte Contenu, deen eventuell geschützt si kéint.";
$legal3 = "$copyright ass net responsabel fir de Contenu vun desem Dokument.";
}
}
if ($vars{'license_use_crystal_clear_icons'}) {
$legal1 = "$legal1 $legal2";
$legal2 = "It may also contain images from the Crystal Clear icon set by Everaldo Coelho, available under the LGPL.";
if ($vars{'app_lang'} eq "de") {
$legal2 = "Dies Seite kann auch Crystal Clear Icons von Everaldo Coelho enthalten, welche unter der LGPL erhältlich sind.";
}
if ($vars{'app_lang'} eq "fr") {
$legal2 = "Cette fiche peut également contenir des images Crystal Clear par Everaldo Coelho, disponible sous LGPL.";
}
if ($vars{'app_lang'} eq "lu") {
$legal2 = "Se kann och Crystal Clear Icons vum Everaldo Coelho enthalen, déi ënnert der LGPL disponibel sinn.";
}
}
if ($switches =~ /(E|N|X)/) {
$legal1 = "";
$legal2 = "";
$legal3 = "";
} else {
ONO::Lib::PDF::Draw->text($canvas,18,272-$offset_y,$legal1);
ONO::Lib::PDF::Draw->text($canvas,18,275-$offset_y,$legal2);
ONO::Lib::PDF::Draw->text($canvas,18,278-$offset_y,$legal3);
}
}
if ($switches !~ /X/) {
my $top = 2;
my $left = -2;
# if (!$format || $format eq "a4") {
# $top = 2;
# }
if ($format eq "us") {
$left = 3;
}
ONO::Lib::PDF::Draw->font("H",12);
$vars{'auto_name'} = ONO::Lib::Basic->umlaut_simplify($vars{'auto_name'});
$vars{'auto_name'} =~ s~[^A-Za-z0-9\ \']~~g;
ONO::Lib::PDF::Draw->text($canvas,170+$left,18+$top,"$BLK{'Name'}:","r");
ONO::Lib::PDF::Draw->text($canvas,170+$left,24+$top,"$BLK{'Date'}:","r");
if ($vars{'auto_name'} || $vars{'app_input_print_options_name'}) {
ONO::Lib::PDF::Draw->font("HB",12);
ONO::Lib::PDF::Draw->text($canvas,171+$left,18+$top,"$vars{'auto_name'}$vars{'app_input_print_options_name'}");
ONO::Lib::PDF::Draw->font("H",12);
} else {
# ONO::Lib::PDF::Draw->text($canvas,171+$left,18+$top,"....................");
ONO::Lib::PDF::Draw->line($canvas,171+$left,18+$top,195+$left,18+$top,0.25);
}
if ($vars{'auto_date'} || $vars{'app_input_print_options_auto_date'}) {
my $dmday = $mday;
$dmday =~ s~^0~~;
my $dmon = $mon;
$dmon =~ s~^0~~;
ONO::Lib::PDF::Draw->text($canvas,171+$left,24+$top,"$dmday / $dmon / $year");
} else {
# ONO::Lib::PDF::Draw->text($canvas,171+$left,24+$top,"... / ... / ........");
ONO::Lib::PDF::Draw->line($canvas,171+$left,24+$top,176.5+$left,24+$top,0.25);
ONO::Lib::PDF::Draw->line($canvas,178+$left,24+$top,183.5+$left,24+$top,0.25);
ONO::Lib::PDF::Draw->line($canvas,185+$left,24+$top,195+$left,24+$top,0.25);
ONO::Lib::PDF::Draw->line($canvas,177+$left,24.5+$top,178+$left,20.5+$top,0.25);
ONO::Lib::PDF::Draw->line($canvas,184+$left,24.5+$top,185+$left,20.5+$top,0.25);
}
}
}
}
}
}
###############################################################################
# titles
###############################################################################
sub title {
my (
$self,
$title,
$subtitle,
$code,
$format,
) = @_;
#: Print PDF file title.
eval "use PDF::Reuse";
if (!$@) {
eval "use Encode";
if (!$@) {
if ($format !~ /^q/) {
my $canvas = ONO::Lib::PDF::ToolBox->canvas_init($format,0,0,0,0);
my ($x_off,$y_off) = (0,0);
if ($code) {
ONO::Lib::PDF::Draw->font("HB",12);
ONO::Lib::PDF::Draw->rect($canvas,25,33,45,41,2,"","0:250:230:175",2);
ONO::Lib::PDF::Draw->text($canvas,35,38.5,$code,"center");
$x_off = 22;
}
if ($format eq "us") {
$y_off = 20;
}
ONO::Lib::PDF::Draw->font("HB",24);
if (ONO::Lib::Web::Domain->variation eq "morzino") {
ONO::Lib::PDF::Draw->text($canvas,40+$x_off,20,$title);
ONO::Lib::PDF::Draw->font("HO",10);
ONO::Lib::PDF::Draw->text($canvas,48,26,$subtitle);
} else {
ONO::Lib::PDF::Draw->text($canvas,25+$x_off,40,$title);
ONO::Lib::PDF::Draw->font("HO",8);
ONO::Lib::PDF::Draw->text($canvas,35,45,$subtitle);
}
ONO::Lib::PDF::Draw->font("H",12);
}
}
}
}
###############################################################################
# self evaluation
###############################################################################
sub self_evaluation {
#: Print PDF file self-evaluation boxes.
my $BLK_ref = $_[1];
my $vars_ref = $_[2];
my %BLK = %$BLK_ref;
my %vars = %$vars_ref;
eval "use PDF::Reuse";
if (!$@) {
eval "use Encode";
if (!$@) {
my %PDFBLK = %BLK;
foreach my $key (keys %PDFBLK) {
Encode::from_to($PDFBLK{$key},'utf-8','iso-8859-1');
}
prFontSize(9);
prFont ('Helvetica-Bold');
prText(140,210,"$PDFBLK{'my_result'}:","right");
prText(235,210,"$PDFBLK{'felt_this_was'}...","left");
prText(390,210,"$PDFBLK{'what_now_think'}?","left");
prFont ('Helvetica');
prText(140,184,"$PDFBLK{'correct'}:", "right");
prText(140,162,"$PDFBLK{'wrong'}:", "right");
prText(140,140,"$PDFBLK{'didnt_known'}:", "right");
prText(140,118,"$PDFBLK{'in_total'}:", "right");
prText(150,118,"45", "left");
prText(150,180,"...................", "left");
prText(150,160,"...................", "left");
prText(150,140,"...................", "left");
prText(260,184,$PDFBLK{'too_easy'}, "left");
prText(260,162,$PDFBLK{'just_right'}, "left");
prText(260,140,$PDFBLK{'bit_difficult'}, "left");
prText(260,118,$PDFBLK{'very_difficult'}, "left");
prText(410,184,$PDFBLK{'very_happy'}, "left");
prText(410,162,$PDFBLK{'happy'}, "left");
prText(410,140,$PDFBLK{'must_improve'}, "left");
prText(410,118,$PDFBLK{'disaster'}, "left");
}
}
}
sub qrfile {
my (
$self,
$APP,
$BASE,
) = @_;
#: Get QR code file path.
my $qrfile = "$ENV{'SERVER_NAME'}$BASE/apps/$APP/run";
$qrfile =~ s~[^A-Za-z0-9]~-~g;
return $qrfile;
}
sub virclass_footer {
my (
$self,
$canvas,
$community,
$format,
$conf_ref,
) = @_;
#: Virtual Classroom footer.
my %conf = %$conf_ref;
my $Community = ucfirst $community;
ONO::Lib::PDF::Draw->image($canvas,0,241.5+$conf{'virclass_work_print_footer_offset'},10,10,"ono-data/$community/pdf/logo_32.jpg",2,2);
ONO::Lib::PDF::Draw->font("HB",12);
ONO::Lib::PDF::Draw->text($canvas,12,246+$conf{'virclass_work_print_footer_offset'},$conf{'virclass_work_print_footer_site'},"l");
ONO::Lib::PDF::Draw->font("H",8);
ONO::Lib::PDF::Draw->text($canvas,12,250+$conf{'virclass_work_print_footer_offset'},$conf{'virclass_work_print_footer_info'},"l");
ONO::Lib::PDF::Draw->font("",12);
}
sub worksheet_maker_sel_apps {
my $vars_ref = $_[1];
my %vars = %$vars_ref;
#: Worksheet maker helper (select apps).
my ($sel_app_num,@sel_app_names);
foreach my $key (sort keys %vars) {
if ($key =~ /^app_input_app_(.*?)$/ && $vars{$key} > 0) {
$sel_app_names[$sel_app_num] = $1;
$vars{'output_paper_apps'} .= "$1,";
$sel_app_num++;
}
}
if ($vars{'output_paper_apps'} =~ /\,/) {
foreach my $sel_app (split(/,/,$vars{'output_paper_apps'})) {
if ($sel_app =~ /[a-z]/) {
$sel_app_names[$sel_app_num] = $sel_app;
$sel_app_num++;
}
}
}
return ($sel_app_num,\@sel_app_names);
}
sub worksheet_maker_rand_app {
my $vars_ref = $_[1];
my %vars = %$vars_ref;
#: Worksheet maker helper (select random app).
my ($sel_app_num,$sel_app_names_ref) = &worksheet_maker_sel_apps("",$vars_ref);
my @sel_app_names = @$sel_app_names_ref;
my $rand_app = $sel_app_names[int(rand($sel_app_num))];
# try to use an app that hasn't been used yet
my $whilecounter;
while ($whilecounter < 256 && ",$vars{'output_paper_apps_used'}," =~ /,$rand_app,/) {
$whilecounter++;
$rand_app = $sel_app_names[int(rand($sel_app_num))];
}
# avoid using the same app twice in a row
my $whilecounter;
while ($whilecounter < 256 && $vars{'output_paper_apps_last'} eq $rand_app) {
$whilecounter++;
$rand_app = $sel_app_names[int(rand($sel_app_num))];
}
return $rand_app;
}
sub worksheet_maker_processor {
#: Worksheet maker helper (main processor).
my $vars_ref = $_[1];
my %vars = %$vars_ref;
my $DEV_OVERRIDE = 0;
$DEV_OVERRIDE = 1;
my $RET;
my $SYSLOAD = ONO::IO->sysload();
my $SECS = 0;
if ($SYSLOAD > 9) {
$SECS = int($SYSLOAD/10);
if ($SYSLOAD > 49) {
$SECS = int($SYSLOAD/5);
}
}
my $BASE = ONO::IO->base();
$vars{'output_paper_counter'}++;
$vars{'output_paper_items_total'} = 4*$vars{'output_paper_num_of_pages'};
my $PRINT_DATA;
foreach my $key (keys %vars) {
if ($key =~ /^app_input_/ && $vars{$key} ne "") {
$PRINT_DATA .= "$key=$vars{$key}\n";
}
}
if ($vars{'output_paper_counter'} > $vars{'output_paper_items_total'}) {
my $OUTPUT = "app_lang=$vars{'app_lang'}&output_paper=1&output_paper_finalize=1&output_paper_id=$vars{'output_paper_id'}&output_paper_num_of_pages=$vars{'output_paper_num_of_pages'}";
my $mix_app = "math_mix";
if ($vars{'output_paper_mix_source'}) {
$mix_app = $vars{'output_paper_mix_source'};
}
$RET .= ONO::IO->refresh("$BASE/cgi-bin/local/perl/school/apps/$mix_app.pl?$OUTPUT",$SECS,0,$DEV_OVERRIDE);
if ($vars{'output_paper_items_total'} && $vars{'output_paper_counter'}) {
$RET .= ONO::Lib::UI::Progress->percent(100);
}
$RET .= ONO::Lib::PDF::ToolBox->print_please_wait($vars{'app_lang'});
# clean the caches
if (1+int(rand(100)) > 95 || ONO::IO->devstation) {
my (
$sec,$min,$hour,
$mday,$mon,$year,
) = ONO::Lib::DateTime::ToolBox->get;
foreach my $file (ONO::IO->ls("var/tmp/apps/worksheet-maker/input-cache")) {
if ($file !~ /^\./ && $file =~ /\.txt/ && substr($file,0,6) < "$year$mon") {
ONO::IO->rm("var/tmp/apps/worksheet-maker/input-cache/$file");
}
}
}
} else {
my $rand_app = &worksheet_maker_rand_app("",\%vars);
if (ONO::IO->devstation) {
if ($vars{'output_paper_counter'} == 1) {
ONO::IO->store("_apps_math_mix_debugger.txt","OutputPaperID = $vars{'output_paper_id'}\n");
}
ONO::IO->append("_apps_math_mix_debugger.txt","$vars{'output_paper_counter'}: $rand_app\n");
}
if (!ONO::IO->exists("var/tmp/apps/worksheet-maker/input-cache/$vars{'output_paper_id'}.txt") && $PRINT_DATA) {
ONO::IO->mkpath("var/tmp/apps/worksheet-maker/input-cache");
ONO::IO->store("var/tmp/apps/worksheet-maker/input-cache/$vars{'output_paper_id'}.txt",$PRINT_DATA);
}
ONO::IO->append("var/tmp/apps/worksheet-maker/input-cache/$vars{'output_paper_id'}-applist.txt","$rand_app\n");
$rand_app =~ s~lang_trainer_word_search~lang_trainer_remember~g;
$rand_app =~ s~lang_trainer_copy_words~lang_trainer_copywords~g;
$rand_app =~ s~lang_trainer_memorize_words~lang_trainer_remember~g;
if (",$vars{'output_paper_apps_used'}," !~ /,$rand_app,/) {
$vars{'output_paper_apps_used'} .= "$rand_app,";
}
my $OUTPUT = "app_lang=$vars{'app_lang'}&output_worksheet_maker=1&output_paper=1&output_paper_id=$vars{'output_paper_id'}&";
$OUTPUT .= "output_paper_apps=$vars{'output_paper_apps'}&output_paper_apps_used=$vars{'output_paper_apps_used'}&output_paper_apps_last=$rand_app&";
$OUTPUT .= "output_paper_counter=$vars{'output_paper_counter'}&output_paper_num_of_pages=$vars{'output_paper_num_of_pages'}&";
$OUTPUT .= "output_paper_items_total=$vars{'output_paper_items_total'}&output_paper_mix_source=$vars{'output_paper_mix_source'}";
$RET .= ONO::IO->refresh("$BASE/cgi-bin/local/perl/school/apps/$rand_app.pl?$OUTPUT",$SECS,0,$DEV_OVERRIDE);
if ($vars{'output_paper_items_total'} && $vars{'output_paper_counter'}) {
$RET .= ONO::Lib::UI::Progress->percent(int(100/($vars{'output_paper_items_total'}+2)*$vars{'output_paper_counter'})+1);
$RET .= ONO::Lib::PDF::ToolBox->print_please_wait($vars{'app_lang'});
}
if (ONO::IO->devstation && !$DEV_OVERRIDE) {
my $pdf = $vars{'output_paper_id'};
$pdf =~ m~^(.*?)-~;
my $date = $1;
$pdf = "${date}_tmp_$vars{'output_paper_id'}";
my $num = $vars{'output_paper_counter'}-1;
$RET .= qq~<div class="inline w100">
<div class="rel" style="top:-20px"><a href="/cgi-bin/local/perl/school/apps/math_mix.pl" class="button_yellow ml20">MathMix.pl</a></div>
<div class="rel" style="top:-20px"><a href="/cgi-bin/local/perl/school/apps/lang_mix.pl" class="button_yellow ml20">LangMix.pl</a></div>
</div>
<div class="box_black" style="background-color:#444444">
<iframe src="http://$ENV{'SERVER_NAME'}/ono/osr/javascript/viewerjs/#/cgi-bin/local/perl/school/download.pl?file=pdf-$pdf\_$num.pdf"
style="width:100%;height:440px;border:0px" allowfullscreen webkitallowfullscreen></iframe>
</div>
~;
}
}
return $RET;
}
sub worksheet_maker_finalizer {
#: Worksheet maker helper (finalizer).
my (
$self,
$BASE,
$HTTP,
$canvas,
$format,
$pdfkey,
$year,$mon,$mday,
$APP_NAMES_ref,
$txt_ref,
$BLK_ref,
$vars_ref,
) = @_;
my $WEB;
my %APP_NAMES = %$APP_NAMES_ref;
my @txt = @$txt_ref;
my %BLK = %$BLK_ref;
my %vars = %$vars_ref;
my ($off_x,$off_y) = (0,41);
if ($format eq "q200") {
$off_y = 58;
}
my $PDF_OPTS = ONO::FW::Apps::Core->headers_options($BLK_ref,$vars_ref);
my @APP_LIST = ONO::IO->list("var/tmp/apps/worksheet-maker/input-cache/$vars{'output_paper_id'}-applist.txt");
&new("","$BASE/pdf/pdf-$pdfkey.pdf","",$format);
foreach my $opt ('sheets','corrections') {
my $embed_item_id;
my $page = 1;
my $TITLE = ONO::Lib::Data::Convert->hex_decode($vars{'app_input_print_options_title'},1);
if ($opt eq "corrections") {
$page = 2;
$TITLE = $BLK{'Corrections'};
}
foreach my $copy (ONO::FW::Apps::Core->unique_copies($vars{'output_paper_num_of_pages'})) {
my $pdf_y;
if ($copy > 1 || $opt eq "corrections") {
&page("","",$format);
}
if ($opt eq "corrections" && !$vars{'app_input_print_options_design_corrections'}) {
$vars{'app_input_print_options_design'} = "";
}
ONO::FW::Apps::Core->headers(\%vars,$format);
&title("",$TITLE,$PDF_OPTS,$vars{'app_input_print_options_code'},$format);
for (my $w = 1; $w < 5; $w++) {
$embed_item_id++;
if (ONO::IO->exists("pdf/pdf-$year$mon$mday\_tmp_$vars{'output_paper_id'}_$embed_item_id.pdf")) {
my ($ERR) = ONO::Lib::PDF::Draw->place_pdf(
$canvas,
0+$off_x,
$pdf_y+$off_y,
"pdf/pdf-$year$mon$mday\_tmp_$vars{'output_paper_id'}_$embed_item_id.pdf",
1,
0,
$format,
$page,
);
if ($ERR =~ /1:page_not_found/) {
if ($opt eq "corrections") {
ONO::Lib::PDF::Draw->font("HO");
ONO::Lib::PDF::Draw->text($canvas,85,$pdf_y+25,$txt[5],"c");
ONO::Lib::PDF::Draw->font("H");
} else {
ONO::Lib::PDF::Draw->text($canvas,25,$pdf_y,"Error, please report this to the webmaster (ErrorID: MathMix, $vars{'output_paper_id'}, $embed_item_id)");
}
}
}
$pdf_y = $pdf_y + 47.5;
}
my $num_switches;
if ($opt eq "corrections") {
$num_switches .= "C";
}
ONO::Lib::PDF::Draw->font('HB',7.5);
ONO::Lib::PDF::Draw->color("0:166:166:166");
for (my $t = 0; $t < 4; $t++) {
my $APP_CODE = lc $APP_LIST[$t+($copy-1)*4];
$APP_CODE =~ s~[^a-z0-9\_]~~g;
ONO::Lib::PDF::Draw->text($canvas,-2.5,10.5+$t*47.5,uc ONO::Lib::Basic->umlaut_simplify($APP_NAMES{$APP_CODE}),"r",90);
}
ONO::Lib::PDF::Draw->font('H',12);
ONO::Lib::PDF::Draw->color();
ONO::FW::Apps::Core::Graphics->pdf_draw_item_numbers($canvas,-2,0,1+($copy-1)*4,4,"fHV$num_switches",\%vars);
# ONO::Lib::PDF::ToolBox->canvas_test($canvas);
}
}
&end();
ONO::Lib::PDF::ToolBox->compress("pdf/pdf-$pdfkey.pdf","pdf/pdf-$pdfkey.pdf","oO");
$WEB .= &please_wait("",$pdfkey,\%BLK,\%vars,"",$HTTP,$BASE);
if (ONO::IO->devstation) {
my $DEBUG_DATA = ONO::IO->load("_apps_math_mix_debugger.txt");
$DEBUG_DATA =~ s~\n~<br>~g;
$WEB .= $DEBUG_DATA;
}
return $WEB;
}
###############################################################################
# specimen
###############################################################################
sub specimen {
my (
$self,
$canvas,
$vars_ref,
) = @_;
#: PDF specimen message printing.
my %vars;
if ($vars_ref) {
%vars = %$vars_ref;
}
if ($vars{'output_paper'} && !$vars{'output_worksheet_maker'}) {
my $display_specimen = 0;
if ($vars{'output_print_specimen'}) {
$display_specimen = 1;
}
if ($display_specimen) {
my $DOMAIN = $ENV{'SERVER_NAME'};
my @txt = (
100,
"SPECIMEN",
"This worksheet has been generated for demonstration purposes only.",
"Please register on $DOMAIN to remove the SPECIMEN text.",
);
if ($vars{'app_lang'} eq "de" || $vars{'app_lang'} eq "lu" ) {
@txt = (
110,
"BEISPIEL",
"Dieses Arbeitsblatt wurde nur zu Demonstrationszwecken erstellt.",
"Bitte registriere dich auf $DOMAIN um den BEISPIEL Text zu entfernen.",
);
}
if ($vars{'app_lang'} eq "fr" ) {
@txt = (
100,
"EXEMPLE",
"Cette fiche de travail a été générée à des fins de démonstration uniquement.",
"Veuillez vous inscrire sur $DOMAIN pour supprimer le texte EXEMPLE.",
);
}
ONO::Lib::PDF::Draw->font("HB",$txt[0]);
ONO::Lib::PDF::Draw->color("0:222:111:111");
ONO::Lib::PDF::Draw->text($canvas,85,105,$txt[1],"c",60);
ONO::Lib::PDF::Draw->rect($canvas,0,190,170,202,2,"0:111:55:55","0:222:111:111",2);
ONO::Lib::PDF::Draw->font("HB",10);
ONO::Lib::PDF::Draw->color("0:255:255:255");
ONO::Lib::PDF::Draw->text($canvas,5,195,$txt[2]);
ONO::Lib::PDF::Draw->text($canvas,5,199,$txt[3]);
ONO::Lib::PDF::Draw->font("H",12);
ONO::Lib::PDF::Draw->color();
}
}
}
###############################################################################
# end of script
###############################################################################
1;
__END__