package ONO::FW::Apps::Core;
################################################################################
# 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::FW::Apps::List;
use ONO::FW::Apps::ToolBox;
use ONO::Ext::Morzino::Apps::Manager;
use ONO::Ext::Morzino::Apps::Manager::Exercises;
use ONO::FW::Apps::PDF;
use ONO::Lib::Lang::LangKitEdu;
use ONO::FW::User::Init;
use ONO::Lib::DateTime::ToolBox;
use ONO::Lib::Web::Cookie;
use ONO::Lib::Web::Client;
use ONO::Lib::Code::RandomID;
use ONO::Lib::SQL::Quote;
use ONO::Lib::Data::Numbers::Roman;
use ONO::Lib::Data::Numbers::Hexa;
use ONO::Lib::Web::BrowserTools;
use ONO::Lib::UI::Image;
use ONO::Lib::UI::Check;
use ONO::Lib::UI::Progress;
use ONO::ToolBox::DomainLang;
use ONO::ToolBox::Logfile;
use ONO::ToolBox::Auth;
use ONO::ToolBox::SendMail;
use ONO::Lib::PDF::Gen;
use ONO::Lib::PDF::Draw;
use ONO::Lib::PDF::ToolBox;
use ONO::FW::Apps::Core::Check;
use ONO::FW::Apps::Core::Graphics;
use ONO::FW::Apps::Core::Lang;
use ONO::FW::Apps::Core::LangKit;
use ONO::FW::Apps::Core::Math;
use ONO::FW::Apps::Core::Question;
use ONO::FW::Apps::Core::Save;
use ONO::FW::Apps::Core::Stats;
use ONO::FW::Apps::Core::ToolBox;
use ONO::FW::Apps::Core::Views;
use ONO::Ext::Morzino::ToolBox;
use ONO::FW::User::Screen::Dashboard::Microblog;
use ONO::Lib::Basic;
use ONO::Lib::Web::Domain;
use ONO::Lib::Data::Emojis::Basic;
#: This is the main ONO Apps Framework Core Module, which is
#: responsible for the entire logic as well as the look and feel
#: (UI) behind most apps.
###################################################################
# init
###################################################################
sub init {
#: Deprecated here, moved to ONO_FW_Apps_Core_ToolBox.
my (
$self,
$vars_ref,
) = @_;
return ONO::FW::Apps::Core::ToolBox->init($vars_ref);
}
###################################################################
# link + form
###################################################################
sub action_url_form {
#: Deprecated here, moved to ONO_FW_Apps_Core_ToolBox.
return ONO::FW::Apps::Core::ToolBox->action_url_form();
}
###################################################################
# action url vars
###################################################################
sub action_url_vars {
#: Deprecated here, moved to ONO_FW_Apps_Core_ToolBox.
return ONO::FW::Apps::Core::ToolBox->action_url_vars($_[1]);
}
###################################################################
# is the exercise running?
###################################################################
sub running {
#: Check if an app is currently in "exercise run" mode.
my $vars_ref = $_[1];
my %vars = %$vars_ref;
my $db = $_[2];
my $return = 0;
if (($vars{'output_selected'} > 1 && !$vars{'output_load'} && !$vars{'output_save'} && !$vars{'output_save_now'} && !$vars{'output_add'} && !$vars{'output_add_custom'})) {
$return++;
}
if ($vars{'output_paper_save_exec'} || $vars{'output_paper_save_target_change'} || $vars{'output_paper_save_target_app_change'}) {
$return++;
}
if ($vars{'output_web_is_running'}) {
$return++;
}
if ($vars{'output_worksheet_maker'} || $vars{'output_paper_finalize'}) {
$return++;
}
if ($vars{'exercise_id'} && $db) {
my $exercise_id = $vars{'exercise_id'};
$exercise_id =~ s~[^A-Za-z0-9]~~g;
foreach my $line (ONO::DB->select($db,"school_school_apps_storage","id_10 = '$exercise_id'")) {
my @row = ONO::DB->readcols($line);
if ($row[18] =~ /L/ && !$vars{'username'}) {
$return = 0;
}
}
}
return $return;
}
###################################################################
# block browser back button
###################################################################
sub blockbackbutton {
#: Code used to block the browser back button in certain
#: situations.
my (
$self,
$BASE,
$vars_ref,
) = @_;
if (ONO::IO->devstation) {
return qq~<!-- BlockBackButton disabled on DevStation -->~;
} else {
my %vars;
if ($vars_ref) {
%vars = %$vars_ref;
}
if ($vars{'output_worksheet_maker'}) {
return qq~<!-- BlockBackButton disabled in WorksheetMakerMode -->~;
} else {
return ONO::Lib::Web::BrowserTools->blockbackbutton($BASE);
}
}
}
###################################################################
# timer
###################################################################
sub timer {
#: Transmit timer code (online exercising mode).
my (
$self,
$output_web,
$output_web_timer_start,
) = @_;
if ($output_web) {
my $time = time();
if ($output_web_timer_start < 1) {
$output_web_timer_start = $time;
}
return qq~<input type="hidden" name="output_web_timer_start" value="$output_web_timer_start">
<input type="hidden" name="output_web_timer_now" value="$time">
~;
} else {
return "";
}
}
###################################################################
# configuration box
###################################################################
sub conf_box {
my (
$self,
$db,
$community,
$app,
$form,
$input,
$action_url,
$CONF,
$lang,
$BLK_ref,
$vars_ref,
$switches,
$OVERLAY,
) = @_;
#: This is the main app configuration screen logic, used to
#: build the initial app interface that lets users customize
#: exercises and worksheets.
#:
#: Switches:
#:
#: -a print option: auto eval
#: -A print option: -a selected by default
#: -b print option: black and white
#: -c print option: corrections
#: -C print option: -c selected by default (recommended)
#: -d print option: date
#: -D print option: -d selected by default (recommended)
#: -F folder generator mode
#: -g show game button
#: -G bigger game button
#: -h web option: allow hints, checked by default
#: -H web option: allow Hints, not checked by default
#: -i print option: item numbers
#: -I print option: -i selected by default (recommended)
#: -K allow self-(K)correction (resulthints)
#: -l allow loading settings (also see 's' and 'u')
#: -L margin left 10px
#: -m multiple choice (web mode, auto-toggle with -N)
#: -M multiple choice (print mode)
#: -n print option: number of unique copies
#: -N number of questions (web/online mode only, also see -X)
#: -o show online button
#: -O one by one, or 20 questions per page
#: -p show print button + options
#: -P custom print button
#: -Q print option: no code, no title
#: -s allow saving settings (also see 'l' and 'u')
#: -S use 'Setup' instead of 'Configure exercise' as title
#: -t replace Title by $vars{'conf_box_title'} and/or $vars{'conf_box_icon'}
#: -T margin top 10px
#: -u save PDF to server (also see 'l' and 's')
#: -U print option: unique copies disabled
#: -W maxwidth is app_conf_box_maxwidth
#: -X only one by one, no multiply questions allowed
my %BLK = %$BLK_ref;
my %vars = %$vars_ref;
if (ONO::IO->devstation) {
my $community = ONO::IO->community();
my $Community = ucfirst $community;
if ($ENV{'REQUEST_URI'} =~ m~cgi-bin/local/perl/$community/apps/(.*?)\.pl~) {
ONO::IO->mkdir("cgi-bin/local/perl/$community/$Community/Apps/Switches");
ONO::IO->store("cgi-bin/local/perl/$community/$Community/Apps/Switches/$1.txt",$switches);
}
}
if ($vars{'app_lang'}) {
$lang = $vars{'app_lang'};
}
my @txts = ONO::FW::Apps::Core::LangKit->conf_box($lang);
if (!$db) {
return qq~<div class="p20 lightred">
<div class="p10">Oops, it looks as we're experiencing some database problems right now.</div>
<div class="p10">Please check back within a few minutes, we're working on it...</div>
<div class="p10">Sorry for the inconvenience!</div>
</div>
~;
} else {
my ($BUTTONS,$PRINT_OPTS,$RELOAD,$OUTPUT_LOADSAVE,$use_multichoice);
my $TITLE = qq~<span class="hide800">$BLK{'Configure_exercise'}:</span><span class="hide inline800">$BLK{'Configure'}:</span>~;
if ($switches =~ /S/) {
$TITLE = $BLK{'Setup'};
}
if ($switches =~ /F/) {
$TITLE = $vars{'app_input_print_options_title_default'};
}
my $TITLE_ICON = "ono/setup";
if ($switches =~ /t/) {
if ($vars{'conf_box_title'}) {
$TITLE = $vars{'conf_box_title'};
}
if ($vars{'conf_box_icon'}) {
$TITLE_ICON = $vars{'conf_box_icon'};
}
}
if ($vars{'virclass'} && $vars{'virclass_user'}) {
$TITLE_ICON = "kdm/user_male";
$TITLE = $vars{'virclass_user'};
if ($vars{'virclass_user'} eq "anonymous") {
$TITLE = "$BLK{'anonymous'} ($BLK{'no_name'})";
}
}
my $AppName = ONO::FW::Apps::ToolBox->get_app_name($db,$community,$app,$lang);
if ($AppName eq ucfirst $app && $BLK{$app}) {
$AppName = $BLK{$app};
}
$vars{'app_input_print_options_title'} =~ s~ \'~\'~g;
if (!$vars{'app_input_print_options_title'}) {
$vars{'app_input_print_options_title'} = $AppName;
if ($vars{'app_input_print_options_title_default'}) {
$vars{'app_input_print_options_title'} = $vars{'app_input_print_options_title_default'};
}
}
if (ONO::IO->devstation) {
# $vars{'username'} = "jos";
}
if ($vars{'exercise'} && $vars{'exercise_id'}) {
my $exercise_id = $vars{'exercise_id'};
$exercise_id =~ s~[^A-Za-z0-9]~~g;
foreach my $line (ONO::DB->select($db,"${community}_school_apps_storage","id_10 = '$exercise_id'")) {
my @row = ONO::DB->readcols($line);
$vars{'exercise_flags'} = $row[18];
$TITLE_ICON = "apps/kate";
$TITLE = $row[6];
if ($vars{'output_web'} && $vars{'output_selected'}) {
$vars{'output_web_exercise_autostart'}++;
} else {
my $PROIMG = ONO::FW::User::Init->profileimage($row[4],32);
my $USER = ONO::DB->get($db,"realname","${community}_community_profiles","username = '$row[4]'");
$row[10] = ONO::Lib::DateTime::ToolBox->convert("date",$row[10],"U",$lang);
$CONF .= qq~<tr class="vtop">
<td>$PROIMG</td>
<td>
<div class="lh125">
<div>$BLK{'by'} $USER</div>
<div class="small"><a href="/users/$row[4]/" class="col9" target="_parent">/users/$row[4]/</a></div>
</div>
</td>
</tr>
<tr>
<td></td>
<td>$row[10]</td>
</tr>
~;
if ($vars{'app_input_number_of_questions'}) {
my $LABEL = $BLK{'questions'};
if ($vars{'app_input_number_of_questions_alt_label'}) {
$LABEL = $vars{'app_input_number_of_questions_alt_label'};
}
$CONF .= qq~ <tr>
<td></td>
<td><span class="bold">$vars{'app_input_number_of_questions'}</span> $LABEL</td>
</tr>
~;
}
for (my $i = 8; $i < 10; $i++) {
if ($row[$i] =~ /[A-Za-z0-0]/) {
$CONF .= qq~<tr class="vtop">
<td><img class="block32" src="/ono/osr/images/icons/crystal/32x32/ono/help.png" alt=""></td>
<td>$row[$i]</td>
</tr>
~;
}
}
# -c required for corrections
# -e required for e-mail report
# -p required for print
# as defined in ONO_FW_Edu_Apps_Exercises:
# -c allow printing correcions
# -e e-mail reports to owner
# -E e-mail reports to all classroom teachers
# -H don't allow hints
# -L login required (visitors can't run the exercise)
# -p allow printing
foreach my $flag ('c','p') {
if ($row[18] !~ /$flag/) {
$switches =~ s~$flag~~g;
}
}
}
}
}
if ($switches =~ /h/i && $vars{'exercise_flags'} !~ /H/ && $vars{'output_web'}) {
my $checked;
if ($switches =~ /h/) {
$checked = 1;
}
my $SWITCH = ONO::Lib::UI::Check->switch("app_input_allow_hints",$checked,"r");
$CONF .= qq~<tr>
<td style="padding-top:10px">$SWITCH</td>
<td style="padding-top:10px">$txts[14]</td>
</tr>
~;
}
if (($switches =~ /m/ && $vars{'output_web'} && !$vars{'exercise'}) || ($switches =~ /M/ && $vars{'output_paper'})) {
$use_multichoice++;
my ($JS1,$JS2);
if ($switches =~ /o/ && $switches =~ /O/ && $vars{'output_web'}) {
($JS1,$JS2) = (
"onojs_class('app_input_tr_multiple_questions_id','trans30');ono_ui_switch_app_input_multiple_questions_per_page_off();",
"onojs_class('app_input_tr_multiple_questions_id','trans100');ono_ui_switch_app_input_multiple_questions_per_page_on();",
);
}
my $SWITCH = ONO::Lib::UI::Check->switch("app_input_multiple_choice",$vars{'app_input_multiple_choice'},"Jr","",$JS1,$JS2);
my $PAD;
if ($switches !~ /H/) {
$PAD = qq~ style="padding-top:10px"~;
}
# app_input_multiple_choice_displayed can be used to test if this option has already been offered
# this is used by vocabulary for example, to make custom group selection possible
$CONF .= qq~<tr>
<td$PAD>$SWITCH<input type="hidden" name="app_input_multiple_choice_displayed" value="1"></td>
<td$PAD>$BLK{'multiple_choice'}</td>
</tr>
~;
}
if ($switches =~ /o/ && !$vars{'output_paper'}) { # && !$vars{'output_save'} && !$vars{'output_save_now'}) {
my $output_add;
foreach my $key (keys %vars) {
if ($key =~ /^output_add/) {
$output_add++;
}
}
if ($switches =~ /O/ && ($vars{'output_web'} || $vars{'output_save'} || $vars{'output_save_now'} || $output_add) && !$vars{'exercise'}) {
my $chk = 1;
my $switch_switches;
if ($switches =~ /X/) {
$chk = 0;
$switch_switches .= "d";
}
if ($vars{'output_save'} && !$vars{'output_save_now'}) {
$chk = 0;
}
my $SWITCH = ONO::Lib::UI::Check->switch("app_input_multiple_questions_per_page",$chk,"rs$switch_switches");
my $PAD;
if ($switches !~ /H/ && !$use_multichoice) {
$PAD = qq~ style="padding-top:10px"~;
}
$CONF .= qq~<tr id="app_input_tr_multiple_questions_id">
<td$PAD>$SWITCH</td>
<td$PAD>$txts[13] <span class="small col9">(max 20)</span></td>
</tr>
~;
}
if ($vars{'output_web_custom_text'}) {
$BLK{'online_training'} = $vars{'output_web_custom_text'};
}
if ($switches =~ /N/ && $vars{'output_web'} && !$vars{'exercise'}) {
my $optional;
if (!$vars{'app_input_number_of_questions'}) {
$optional = qq~ <span class="small col9 hide1000">($BLK{'optional'})</span>~;
# this was changed in june 2021, to always set a default value, hope it won't cause any problems anywhere:
$vars{'app_input_number_of_questions'} = 20;
}
if ($vars{'app_input_number_of_questions_alt_label'}) {
$txts[9] = $vars{'app_input_number_of_questions_alt_label'};
}
$BUTTONS .= qq~<table class="default_table">
<tr>
<td class="p0">
<input type="submit" name="output_web" value="$BLK{'online_training'}" class="button_green mb10">
<input type="hidden" name="output_cookie_store" value="1">
</td>
<td class="pad5_2">
<div class="mb10">
<input type="number" name="app_input_number_of_questions" value="$vars{'app_input_number_of_questions'}"
maxlength="3" min="1" max="500" step="1" class="center" style="width:50px" placeholder="?">
</div>
</td>
<td><div class="mb10">$txts[9]$optional</div></td>
</tr>
</table>
~;
} else {
if (!$vars{'username'} && $vars{'exercise_flags'} =~ /L/) {
$BUTTONS .= ONO::FW::Apps::Core::LangKit->login_required($lang);
} else {
$BUTTONS .= qq~<input type="submit" name="output_web" value="$BLK{'online_training'}" class="button_green mb10">
<input type="hidden" name="app_input_number_of_questions" value="$vars{'app_input_number_of_questions'}">
~;
}
}
}
if ($switches =~ /g/) {
my $BIG;
if ($switches =~ /G/) {
$BIG = " button_big";
}
$BUTTONS .= qq~<input type="submit" name="output_game" value="$BLK{'start_game'}" class="button_green$BIG mb10">
<input type="hidden" name="output_cookie_store" value="1">
~;
}
if ($switches =~ /N/ && ($vars{'output_save'} || $vars{'output_save_now'})) {
$CONF .= qq~<tr>
<td>
<input type="number" name="app_input_number_of_questions" value="$vars{'app_input_number_of_questions'}"
maxlength="3" min="1" max="500" step="1" class="center mr5" style="width:50px;float:right" placeholder="?">
</td>
<td>$txts[12] <span class="small col9">($BLK{'optional'}, $BLK{'recommended'})</span></td>
</tr>
~;
}
if ($switches =~ /p/ && !$vars{'output_web'} && !$vars{'output_save'} && !$vars{'output_save_now'}) {
if ($vars{'output_paper'}) {
$BLK{'print_worksheet'} = $BLK{'print'};
$BUTTONS .= qq~<input type="hidden" name="output_cookie_store" value="1">~;
}
if ($vars{'output_paper_save'}) {
$BLK{'print_worksheet'} = "$BLK{'save'} (PDF)";
$BUTTONS .= qq~<input type="hidden" name="output_paper_save_exec" value="1">~;
}
if ($vars{'output_paper_custom_text'}) {
$BLK{'print_worksheet'} = $vars{'output_paper_custom_text'};
}
if ($vars{'output_paper_button_save_pdf'} || $vars{'output_paper_num_of_pages'}) {
$BUTTONS .= qq~<table class="default_table ml10 fl">
<tr>
~;
if ($vars{'output_paper_num_of_pages'}) {
my $PAGES = qq~<option value="1">1 $BLK{'page'}</option>~;
for (my $p = 2; $p < 11; $p++) {
my $sel;
if ($p == $vars{'output_paper_num_of_pages'}) {
$sel = " selected";
}
$PAGES .= qq~<option value="$p"$sel>$p $BLK{'pages'}</option>~;
}
$BUTTONS .= qq~ <td class="p0">
<div class="mb10 mr10"><div class="select"><select name="output_paper_num_of_pages">$PAGES</select></div></div>
</td>
~;
}
$BUTTONS .= qq~ <td class="p0">
<input type="submit" name="output_paper" value="$BLK{'print_worksheet'}" class="button_green mb10">
</td>
~;
if ($vars{'output_paper_button_save_pdf'} && !$vars{'output_paper'}) {
$BUTTONS .= qq~ <td class="p0">
<input type="submit" name="output_paper_save" value="$BLK{'save'} (PDF)" class="button_green mb10 ml5">
</td>
~;
}
if ($switches =~ /K/ && !$vars{'output_paper'}) {
$BUTTONS .= qq~<td class="p0"><div class="inline mb5"><table class="default_table ml5 mb5">~;
$BUTTONS .= ONO::FW::Apps::ToolBox->conf_input("resulthints", $BLK_ref,\%vars,"","S","ai");
$BUTTONS .= qq~</table></div></td>~;
}
$BUTTONS .= qq~ </tr>
</table>
~;
} else {
$BUTTONS .= qq~<input type="submit" name="output_paper" value="$BLK{'print_worksheet'}" class="button_green mb10">~;
}
if ($vars{'output_paper_add_button'} && $vars{'output_paper_add_button_text'}) {
if ($vars{'output_paper_add_button_color'} eq "lightgreen") {
$vars{'output_paper_add_button_color'} = "_green";
$vars{'output_paper_add_button_style'} = "background-color:#bbee55;border-color:#bbee55";
}
my $BUT = qq~<input type="submit" name="$vars{'output_paper_add_button'}" value="$vars{'output_paper_add_button_text'}"
class="button$vars{'output_paper_add_button_color'}" style="$vars{'output_paper_add_button_style'}">~;
if ($vars{'output_paper_add_button_hint'}) {
$BUT = qq~<div class="rel fl" onmouseover="onojs_block('output_paper_add_button_hint');" onmouseout="onojs_hide('output_paper_add_button_hint');">
<div id="output_paper_add_button_hint" class="abs hide" style="top:-64px;left:-10px">
<div class="box_paper nowrap">
$vars{'output_paper_add_button_hint'}
</div>
<img class="block24 abs" src="/ono/osr/images/arrows/nuvola/white32shadow/nav_down.png" style="bottom:-23px;left:10px" alt="">
</div>
$BUT
</div>
~;
}
$BUTTONS .= $BUT;
}
}
if ($switches =~ /P/) {
$BUTTONS .= qq~<input type="submit" name="output_print_custom" value="$BLK{'print'}" class="button_green">~;
}
if ($switches =~ /s/ && ($vars{'output_save'} || $vars{'output_save_now'})) {
$TITLE = ucfirst $txts[1].":";
$TITLE_ICON = "actions/filesave";
$BUTTONS = qq~<input type="submit" name="output_save_now" value="$BLK{'save'}" class="button_green mb10">~;
if ($vars{'output_save_now'}) {
$BUTTONS .= qq~<a href="$action_url" class="button_yellow">$BLK{'cancel'}</a>
<span class="col9 small italic"> $BLK{'*'}) $BLK{'required_fields'}</span>
~;
}
}
if ($vars{'output_save_now'} && $vars{'username'}) {
my (
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,$timestamp
) = ONO::Lib::DateTime::ToolBox->get;
my $DATE = ONO::Lib::DateTime::ToolBox->select_date("app_input_save_date",$year-1,$year+3,"$year$mon$mday",$lang,"mnPT");
my $BG;
if (!$vars{'app_input_save_name'}) {
$vars{'app_input_save_name'} = $AppName;
}
if ($vars{'app_input_save_target'} && !$vars{'app_input_save_name'}) {
$BG = qq~ class="bg_red"~;
}
$CONF = qq~<tr$BG>
<td class="tar">$BLK{'title'}$BLK{'*'}:</td>
<td><input type="text" name="app_input_save_name" value="$vars{'app_input_save_name'}" class="w95" placeholder="$BLK{'untitled'}"></td>
</tr>
<tr>
<td></td>
<td class="p5"></td>
</tr>
<tr>
<td class="tar">$BLK{'date'}:</td>
<td class="p0">$DATE</td>
</tr>
<tr>
<td></td>
<td class="p5"></td>
</tr>
~;
my $sql_ref = ONO::Lib::SQL::Quote->vars(\%vars);
my %sql = %$sql_ref;
if ($vars{'app_input_save_target'} && $vars{'app_input_save_name'}) {
my ($BRANCH,$CAT,%dis);
my $TARGET = "$txts[2] ($vars{'username'})";
my $TARGET_ICON = "filesystems/folder";
if ($vars{'app_input_save_target'} > 0) {
$TARGET = ONO::DB->get($db,"fullname","${community}_school_virclass","id = '$sql{'app_input_save_target'}'");
$TARGET .= qq~ <span class="col9">(#$sql{'app_input_save_target'})</span>~;
$TARGET_ICON = "ono/virclass";
$BRANCH = ONO::Ext::Morzino::ToolBox->branch_select($vars{'app_input_save_target'},"","s");
}
if (!$BRANCH) {
$dis{'branch'} = " disabled";
}
if (!$CAT) {
$dis{'cat'} = " disabled";
}
$CONF .= qq~<tr>
<td class="tar">$BLK{'target'}$BLK{'*'}:</td>
<td class="p0">
<table class="default_table">
<tr>
<td><img class="block24" src="/ono/osr/images/icons/crystal/32x32/$TARGET_ICON.png" alt=""></td>
<td>$TARGET</td>
</tr>
</table>
<input type="hidden" name="app_input_save_target" value="$vars{'app_input_save_target'}">
<input type="hidden" name="app_input_saveready" value="1">
</td>
</tr>
<tr>
<td></td>
<td class="p2"></td>
</tr>
<tr>
<td class="tar">$BLK{'branch'}:</td>
<td>
<div class="select"><select name="app_input_save_branch"$dis{'branch'}>
<option value="">$BLK{'none'}</option>
<option value="">----</option>
$BRANCH
</select></div>
</td>
</tr>
<tr>
<td class="tar">$BLK{'category'}:</td>
<td>
<div class="select"><select name="app_input_save_category"$dis{'cat'}>
<option value="">$BLK{'none'}</option>
<option value="">----</option>
$CAT
</select></div>
</td>
</tr>
<tr>
<td></td>
<td class="p2"></td>
</tr>
<tr class="vtop">
<td class="tar">$BLK{'info'}:</td>
<td><textarea class="w95 h50" placeholder="$BLK{'optional'}...">$vars{'app_input_save_description'}</textarea></td>
</tr>
~;
my $SWITCH = ONO::Lib::UI::Check->switch("app_input_save_flag_L",0,"r");
$CONF .= qq~<tr class="vtop">
<td>$SWITCH</td>
<td class="">$txts[21]</td>
</tr>
~;
my $email = ONO::DB->get($db,"email","${community}_community_users","username = '$vars{'username'}'");
if ($email =~ /^(.*?)\@(.*?)\.(.*?)$/) {
my $SWITCH = ONO::Lib::UI::Check->switch("app_input_save_flag_e",0,"r");
$CONF .= qq~<tr class="vtop">
<td>$SWITCH</td>
<td class=""><div class="lh100">$txts[16] <span class="col9">($email)</span></div></td>
</tr>
~;
if ($vars{'app_input_save_target'} > 0) {
my $SWITCH = ONO::Lib::UI::Check->switch("app_input_save_flag_E",0,"mr");
$CONF .= qq~<tr class="vtop">
<td></td>
<td class="p0">
<table class="default_table">
<tr>
<td>$SWITCH</td>
<td><div class="lh100 small">$txts[18]</div></td>
</tr>
</table>
</td>
</tr>
~;
}
}
} else {
my $VIRCLASS = ONO::Ext::Morzino::Apps::Manager::Exercises->virclass_targets($db,$community,$vars{'username'});
$CONF .= qq~<tr>
<td class="tar">$BLK{'target'}$BLK{'*'}:</td>
<td>
<div class="select"><select name="app_input_save_target">
<option value="user">$txts[2] ($vars{'username'})</option>
$VIRCLASS
</select></div>
</td>
</tr>
~;
}
foreach my $key (keys %vars) {
if (($key =~ /^app_input_/ || $key =~ /^app_storage_/) && $key !~ /^app_input_save_/) {
$CONF .= qq~<input type="hidden" name="$key" value="$vars{$key}">~;
}
}
if ($vars{'app_input_save_target'} && $vars{'app_input_save_name'} && $vars{'app_input_saveready'}) {
my $ID1 = ONO::Lib::Code::RandomID->make(10);
my $ID2 = ucfirst ONO::Lib::Code::RandomID->make(32);
if ($sql{'app_input_save_target'} < 1) {
$sql{'app_input_save_target'} = 0;
}
my $DATE = ONO::Lib::DateTime::ToolBox->convert("date","$vars{'app_input_save_date_year'}$vars{'app_input_save_date_month'}$vars{'app_input_save_date_day'}","mU",$lang);
my $DATESAVE = ONO::Lib::DateTime::ToolBox->select_date_saver("app_input_save_date",$vars_ref);
my $FLAGS;
foreach my $key (keys %vars) {
if ($key =~ /^app_input_save_flag_(.*?)$/ && $vars{$key}) {
$FLAGS .= $1;
}
}
$FLAGS =~ s~[^A-Za-z0-9]~~g;
ONO::DB->command(
$db,
"INSERT INTO ${community}_school_apps_storage
(id_10,exercise,app,username,virclass,
name,description,date,branch,flags,
creation_username,creation_timestamp,modification_username,modification_timestamp) VALUES
('$ID1','$ID2','$app','$vars{'username'}','$sql{'app_input_save_target'}',
'$sql{'app_input_save_name'}','$sql{'app_input_save_description'}','$DATESAVE','$sql{'app_input_save_branch'}','$FLAGS',
'$vars{'username'}','$timestamp','$vars{'username'}','$timestamp');",
);
my ($DATA1,$DATA2,$counter);
foreach my $key (keys %vars) {
if ($key =~ /^app_input_/ && $key !~ /^app_input_save/) {
$DATA1 .= qq~$key:$vars{$key}\n~;
}
if ($key =~ /^app_storage_/ && $key !~ /^app_storage_type_spacer/) {
$counter++;
my $count = ONO::Lib::Basic->add_leading_zeroes($counter,3);
$DATA2 .= qq~$key:$vars{$key}\n~;
}
}
my $DIR = "var/community/${community}/apps/storage/".ONO::IO->deepdir($ID1)."/$ID1";
ONO::IO->mkpath($DIR);
ONO::IO->store("$DIR/config.txt",$DATA1);
if (!ONO::IO->exists("var/community/${community}/apps/configs/$app.txt") || int(rand(100)) == 50 || ONO::IO->devstation) {
ONO::IO->mkpath("var/community/${community}/apps/configs");
ONO::IO->store("var/community/${community}/apps/configs/$app.txt",$DATA2);
}
$CONF = qq~<tr class="vtop">
<td><img class="block24" src="/ono/osr/images/icons/ono/32x32/isok.png" alt=""></td>
<td>$txts[6] '<span class="bold">$vars{'app_input_save_name'}</span>' <span class="col9">($DATE)</span>.</td>
</tr>
~;
$BUTTONS = qq~<a href="$action_url" class="button_green">$txts[7]</a>
<a href="/exercises/" class="button_yellow" target="_parent">$txts[8] (own or virclass)</a>
~;
}
}
if (!$vars{'username'} && ($vars{'output_save'} || $vars{'output_save_now'} || $vars{'output_paper_save'})) {
$vars{'login_required'}++;
$CONF = qq~<tr>
<td></td>
<td>
<div style="padding:10px 20px 0px 20px">
<div class="bold lightred mb5">$txts[3]</div>
<div class="ml20">$txts[4] $txts[5] $BLK{'Thank_you'}!</div>
</div>
</td>
</tr>
~;
$BUTTONS = qq~<div class="inline">
<a href="/login/" class="button_green ml20" target="_parent">$BLK{'signup'} / $BLK{'login'}</a>
<a href="$action_url" class="button_yellow">$BLK{'cancel'}</a>
</div>
<table class="default_table mt20 mb10 ml5">
<tr class="vtop">
<td><img class="block32 ml10" src="/ono/osr/images/icons/crystal/32x32/ono/help.png" alt=""></td>
<td><div class="lh125 col9 italic">$txts[19] $txts[20]</div></td>
</tr>
</table>
~;
}
if ($vars{'output_paper'}) {
my $PRINT_FORMAT .= qq~<tr>
<td></td>
<td>~;
$PRINT_FORMAT .= ONO::Lib::PDF::ToolBox->format("app_input_paper_format",$BLK_ref,$vars_ref);
$PRINT_FORMAT .= qq~ </td>
</tr>
~;
$BLK{'blackwhite'} = $txts[10];
$BLK{'uniquecopies'} = $txts[11];
$BLK{'item_numbers'} = $txts[22];
foreach my $opt (
"t:app_input_print_options_title:title",
"o:app_input_print_options_code:code",
"m:app_input_print_options_name:name",
"d:app_input_print_options_auto_date:print_date",
"f:app_input_print_options_format:format",
"n:app_input_print_options_unique_copies:uniquecopies",
"b:app_input_print_options_blackwhite:blackwhite",
"c:app_input_print_options_corrections:inc_corrections",
"i:app_input_print_options_item_numbers:item_numbers",
"g:app_input_print_options_design:design",
"a:app_input_print_options_auto_eval:inc_self_eval",
) {
my @op = split(/:/,$opt);
if ($op[0] =~ /(t|o|m|n|f|g)/) {
if ($op[0] eq "t" && $switches !~ /Q/) {
$PRINT_OPTS .= qq~<tr>
<td class="tar">$BLK{$op[2]}:</td>
<td><input type="text" name="$op[1]" value="$vars{'app_input_print_options_title'}" style="width:320px" maxlength="16" onclick="this.select();"></td>
</tr>
~;
}
if ($op[0] eq "o" && $switches !~ /Q/) {
$PRINT_OPTS .= qq~<tr>
<td class="tar">$BLK{$op[2]}:</td>
<td><input type="text" name="$op[1]" value="$vars{'app_input_print_options_code'}" style="width:50px" maxlength="4" onclick="this.select();"></td>
</tr>
~;
}
if ($op[0] eq "m" && $switches !~ /Q/) {
$PRINT_OPTS .= qq~<tr>
<td class="tar">$BLK{$op[2]}:</td>
<td><input type="text" name="$op[1]" value="$vars{'app_input_print_options_name'}" style="width:320px" maxlength="16" onclick="this.select();"></td>
</tr>
~;
}
if ($op[0] eq "f") {
$PRINT_OPTS .= $PRINT_FORMAT;
}
if ($op[0] eq "n" && $switches !~ /U/) {
$PRINT_OPTS .= qq~<tr>
<td><input type="text" name="$op[1]" value="1" style="float:right;text-align:right;width:16px" maxlength="2" onclick="this.select();"></td>
<td>$BLK{$op[2]}</td>
</tr>
~;
}
if ($op[0] eq "g") {
$PRINT_OPTS .= &print_design("",$op[1],$lang,$BLK_ref,$switches);
}
} else {
my $OP0 = uc $op[0];
my $chk;
if ($switches =~ /$OP0/) {
$chk++;
}
my $SWITCH = ONO::Lib::UI::Check->switch($op[1],$chk,"r");
if ($op[0] =~ /^(b|c|d|a|i)$/ && $switches =~ /$op[0]/) {
if ($op[0] eq "i") {
my $RENUM = ONO::FW::Apps::Core::Graphics->pdf_draw_item_number_html_example_mini();
$PRINT_OPTS .= qq~<tr>
<td>$SWITCH</td>
<td class="p0"><table class="default_table"><tr class="vtop"><td>$BLK{$op[2]}</td>$RENUM</tr></table></td>
</tr>
~;
} else {
$PRINT_OPTS .= qq~<tr>
<td>$SWITCH</td>
<td>$BLK{$op[2]}</td>
</tr>
~;
}
if ($op[0] eq "c" && $vars{'output_paper_save'}) {
my $SWITCH = ONO::Lib::UI::Check->switch("output_paper_save_split",1,"mr");
$PRINT_OPTS .= qq~<tr>
<td></td>
<td class="p0">
<table class="default_table">
<tr>
<td>$SWITCH</td>
<td class="small col6">$txts[15]</td>
</tr>
</table>
</td>
</tr>
~;
}
}
}
}
if ($PRINT_OPTS) {
if ($vars{'output_paper_add_button'} || $vars{'output_paper_save'}) {
$BLK{'print_options'} = $BLK{'options'};
}
my $ICON = "/ono/osr/images/icons/crystal/32x32/ono/print.png";
my $hide = " hide";
if ($vars{'output_paper_save'}) {
$ICON = "/ono/osr/images/icons/crystal/32x32/actions/filesave.png";
# $hide = "";
$BLK{'Print_options'} = $BLK{'Options'};
$BLK{'ok'} = "$BLK{'continue'}...";
}
$PRINT_OPTS = qq~<div id="app_print_options_box" class="abs$hide" style="top:20px;left:20px;z-index:999">
<div class="box_fabric">
<table class="default_table">
<tr>
<td><img class="block24 mb5" src="$ICON" style="margin-right:3px" alt=""></td>
<td><h4 class="col6">$BLK{'Print_options'}</h4></td>
</tr>
</table>
<div class="box_paper">
<table class="default_table">
$PRINT_OPTS
<tr>
<td></td>
<td>
<a href="javascript:void(0);" onclick="onojs_hide('app_print_options_box');onojs_block('app_print_options_button');"
class="button_green">$BLK{'ok'}</a>
</td>
</tr>
</table>
</div>
</div>
</div>
~;
if (!$vars{'login_required'}) {
$PRINT_OPTS .= qq~<a href="javascript:void(0);" id="app_print_options_button" onclick="onojs_block('app_print_options_box');onojs_hide('app_print_options_button');"
class="button mb10">$BLK{'print_options'}...</a>
~;
if ($switches =~ /K/) {
$PRINT_OPTS .= qq~<div class="inline"><table class="default_table mt2 ml5">~;
$PRINT_OPTS .= ONO::FW::Apps::ToolBox->conf_input("resulthints", $BLK_ref,\%vars,"","","ai");
$PRINT_OPTS .= qq~</table></div>~;
}
}
}
}
if ($vars{'output_selected'} && !$vars{'output_save_now'} && !$vars{'login_required'} && !$vars{'output_web_exercise_autostart'}) {
$RELOAD = qq~<div id="app_input_reload_icon" class="fr trans50" style="padding:7px 2px 0px 0px"
onmouseover = "onojs_class('app_input_reload_icon','fr');"
onmouseout = "onojs_class('app_input_reload_icon','fr trans50');">
<a href="$action_url">
<img class="block16" src="/ono/osr/images/icons/ono/32x32/reload.png" alt="">
</a>
</div>
~;
}
if (!$vars{'exercise'} && !$vars{'output_paper'} && !$vars{'output_web'} && !$vars{'output_load'} && !$vars{'output_save'} && !$vars{'output_save_now'}) { # && !$vars{'output_selected'}) {
my $STYLE;
if ($lang eq "fr") {
$STYLE = "padding:3px 4px 3px 4px;margin-right:2px";
}
if ($lang eq "lu") {
$STYLE = "padding:3px 7px 3px 7px;margin-right:2px";
}
if ($switches =~ /l/) {
$OUTPUT_LOADSAVE .= qq~<td class="nowrap">
<a href="/exercises/?app=$app" class="button button_small mt5" style="$STYLE" target="_parent">$txts[0]</a>
</td>
~;
}
if ($switches =~ /s/) {
$OUTPUT_LOADSAVE .= qq~<td class="nowrap">
<input type="submit" name="output_save" value="$txts[1]..." class="button button_small mt5" style="$STYLE">
</td>
~;
}
if ($switches =~ /u/) {
$OUTPUT_LOADSAVE .= qq~<td class="nowrap">
<input type="submit" name="output_paper_save" value="$BLK{'save'} (PDF)" class="button button_small mt5" style="$STYLE">
</td>
~;
}
if ($OUTPUT_LOADSAVE) {
$OUTPUT_LOADSAVE = qq~<div id="app_input_loadsave_div" class="trans50">
<table class="wide_table"
onmouseover = "onojs_class('app_input_loadsave_div','');"
onmouseout = "onojs_class('app_input_loadsave_div','trans50');">
<tr>
<td><img class="block24 mt5" src="/ono/osr/images/icons/crystal/32x32/actions/filesave.png" style="margin-right:3px" alt=""></td>
$OUTPUT_LOADSAVE
<td class="w100"></td>
</tr>
</table>
</div>
~;
}
}
if (!$OUTPUT_LOADSAVE) {
# the following crazy table code ensures that the box won't collapse...
# don't understand why this works, but it works, so leave it as it is:
$OUTPUT_LOADSAVE = qq~<table class="wide_table"><tr><td></td><td class="w100"></td></tr></table>~;
}
if ($vars{'output_web_exercise_autostart'}) {
if ($vars{'exercise_flags'} !~ /L/ || $vars{'username'}) {
$BUTTONS = qq~<div class="inline auto" style="min-width:360px">
<div class="xlarge mb10 green center">$txts[17]</div>
<input type="submit" name="output_web" value="$BLK{'Start'}!" class="button_green button_big" style="width:100%;font-weight:bold;font-size:24px">
<input type="hidden" name="app_input_number_of_questions" value="$vars{'app_input_number_of_questions'}">
<input type="hidden" name="output_web_question_number" value="1">
</div>
<div class="p10"></div>
~;
}
# <script>
# document.forms[0].submit();
# </script>
}
if (!$vars{'output_add'}) {
$vars{'output_selected'}++;
}
if ($vars{'app_conf_box_buttons_below'}) {
$vars{'app_conf_box_buttons_below'} = qq~<tr><td></td><td><div class="rel" style="top:-10px">$vars{'app_conf_box_buttons_below'}</div></td></tr>~;
}
my $ABS = "top:2px";
if ($switches =~ /T/) {
$ABS = "top:10px";
}
if ($switches =~ /L/) {
$ABS .= ";left:10px";
}
my @errs = ONO::Lib::Web::Client->client_error_msgs($lang);
my $MAXWIDTH = 420;
if ($switches =~ /F/ && $vars{'app_input_folder'}) {
$MAXWIDTH = 800;
}
if ($switches =~ /W/ && $vars{'app_conf_box_maxwidth'}) {
$MAXWIDTH = $vars{'app_conf_box_maxwidth'};
}
my $CONF_BOX_TITLE = &conf_box_title("",$TITLE_ICON,$TITLE,$vars{'app_conf_box_color'});
if ($vars{'exercise'}) {
my $EX_URL = ONO::IO->http_domain_base()."/exercise/$vars{'exercise'}/";
my $FILE = ONO::Ext::Morzino::ToolBox->qr_make($EX_URL);
my $IMG = ONO::Ext::Morzino::ToolBox->qr_image_td($FILE,"pr",ONO::IO->base(),"p");
$OUTPUT_LOADSAVE .= qq~<table class="wide_table">
<tr>
$IMG
<td class="w100"><input type="text" name="exercise_sharing_id" value="$EX_URL" class="w98" onclick="this.select();"></td>
</tr>
</table>
~;
}
# check if there's a backup exercise
my $STORED;
my $anonymous;
my $DIR = &varstoredir("",$vars{'username'},$vars{'virclass'},$anonymous);
if ($DIR && !$vars{'output_web'} && !$vars{'output_paper'} && !$vars{'output_save'}) {
my (@files,$found);
foreach my $time (ONO::IO->dir($DIR)) {
if (length $time == 10) {
if ($time < (time()-(60*60*24*31))) {
ONO::IO->rmdir("$DIR/$time");
} else {
my $files;
foreach my $file (ONO::IO->dir("$DIR/$time","","","time")) {
if ($file =~ /^(.*?)_(.*?)\.txt$/) {
$files++;
if ($files > 1) {
ONO::IO->rm("$DIR/$time/$file");
} else {
$file =~ s~\.txt$~~;
@files = (@files,"$time\_$file");
$found = "$DIR/$time/$file";
}
}
}
if (!$files) {
ONO::IO->rmdir("$DIR/$time");
}
}
}
}
if ($found) {
my @txt = ONO::FW::Apps::Core::LangKit->conf_box_2($lang);
my $AUTHINFO;
if ($vars{'username'}) {
$AUTHINFO = qq~, $BLK{'by'} $BLK{'user'} '$vars{'username'}'~;
}
my $num = @files;
my $CONTINUE = qq~<div class="inline mt10"><a href="$action_url&varstoreaction=load_$files[0]" class="button_green button_big">$txt[3]</a></div>~;
my @fp = split(/_/,$files[0]);
my $time = ONO::Lib::DateTime::ToolBox->get($fp[0],"","iz",$lang);
my $INFO = " ($BLK{'created'} $time$AUTHINFO).";
if ($num > 1) {
$CONTINUE = "";
my $count;
foreach my $file (reverse sort @files) {
$count++;
if ($count < 4) {
my @fp = split(/_/,$file);
my $time = ONO::Lib::DateTime::ToolBox->get($fp[0],"","iz",$lang);
$CONTINUE .= qq~<div class="inline mt10"><a href="$action_url&varstoreaction=load_$file" class="button_green button_big">$BLK{'resume'} ($time)</a></div>~;
}
}
$INFO = "$AUTHINFO.";
$txt[5] .= " ($BLK{'all'})";
}
$STORED .= qq~<div id="varstore_box" class="abs" style="top:20px;left:20px;z-index:999">
<div class="box_black">
<a href="javascript:void(0);" onclick="onojs_hide('varstore_box');"><img class="close" alt="close button"></a>
<h3 class="cole">$txt[0]</h3>
<div class="box_fabric">
<div class="mb10 large">$txt[1]$INFO</div>
<div class="mb10 large">$txt[2]</div>
$CONTINUE
<div class="inline mt10"><a href="javascript:void(0);" onclick="onojs_hide('varstore_box');" class="button_yellow button_big">$txt[4]</a></div>
<div class="inline mt10"><a href="$action_url&varstoreaction=delete" class="button_red button_big">$txt[5]</a></div>
</div>
</div>
</div>
~;
}
}
my ($VIRCLASS,$test_virclass_user);
# if (ONO::IO->devstation && !$vars{'virclass_user'} && $vars{'output_web'} && !$vars{'output_paper'}) {
# $test_virclass_user++;
# }
if ((!$vars{'username'} && !$vars{'virclass_user'} && $vars{'virclass'} && $vars{'output_web'} && !$vars{'output_paper'}) || $test_virclass_user) {
if ($vars{'virclass'} =~ /^(.*?):(.*?)$/) {
my $virclass_id = $1;
my $virclass_comp = $2;
$virclass_id =~ s~[^0-9]~~g;
my $STUDENTS;
foreach my $line (ONO::DB->select($db,"${community}_school_virclass_relationships","virclass = '$virclass_id' AND status = '1' AND type = 'student'","realname")) {
my @row = ONO::DB->readcols($line);
if (!$row[5]) {
$row[5] = $row[1];
}
$row[5] = ucfirst $row[5];
$STUDENTS .= qq~<div class="inline"><a href="javascript:void(0);" onclick="ono_fw_apps_exec_virclass_auth_userload('$row[1]','$row[5]');" class="button_green button_big mb10">$row[5]</a></div>~;
#ono_fw_apps_exec_virclass_auth_user
#parent.document.body.style.backgroundColor = "red";
}
if ($STUDENTS) {
my $WIN_URL = $action_url;
$WIN_URL =~ s~\&\;~\&~g;
foreach my $key (keys %vars) {
if ($key =~ /^app_input_/) {
$WIN_URL .= qq~&$key=$vars{$key}~;
}
}
$VIRCLASS .= qq~<div id="virclass_box" class="abs" style="top:20px;left:20px;z-index:999">
<div id="virclass_box_1" class="box_black p20">
<table class="default_table">
<tr>
<td class="p10"><a href="javascript:void(0);" onclick="onojs_hide('virclass_box_1');onojs_block('virclass_box_2');" class="button_green button_big">$BLK{'Student'}...</a></td>
<td class="p10"><a href="$action_url&virclass_user=anonymous" class="button_orange button_big">$BLK{'Anonymous'}</a></td>
<td class="p10"><a href="$action_url&virclass_user=anonymous"><img class="close" alt="close button"></a></td>
</tr>
</table>
</div>
<div id="virclass_box_2" class="box_black hide">
<a href="$action_url&virclass_user=anonymous"><img class="close" alt="close button"></a>
<h3 class="cole">$BLK{'Student'}...</h3>
<div class="box_fabric">
<div style="min-width:360px;max-height:360px;overflow-x:hidden;overflow-y:scroll">
<div class="inline w100"><a href="$action_url&virclass_user=anonymous" class="button_orange button_big mb10">$BLK{'Anonymous'} ($BLK{'no_name'})</a></div>
$STUDENTS
</div>
</div>
</div>
</div>
<script>
function ono_fw_apps_exec_virclass_auth_userload(username,realname) {
if (parent.document.getElementById('ono_fw_apps_exec_virclass_auth_user')) {
parent.document.getElementById('ono_fw_apps_exec_virclass_auth_user').style.display='table-cell';
parent.document.getElementById('ono_fw_apps_exec_virclass_auth_username').innerHTML=realname;
}
window.location='$WIN_URL&virclass_user='+username;
}
</script>
~;
}
}
}
my $BOX = "box_fabric";
my $STYLE = "padding-bottom:0px";
if ($vars{'app_conf_box_color'}) {
$BOX = "box_$vars{'app_conf_box_color'}";
}
if ($vars{'app_conf_box_inner_style'}) {
$STYLE = $vars{'app_conf_box_inner_style'};
}
my ($FORM1,$FORM2);
if ($vars{'output_login_required'}) {
my @txt = (
"Login required",
"You need to be logged in to access this web application.",
);
if ($lang eq "de" || $lang eq "lu") {
@txt = (
"Login erforderlich",
"Du musst angemeldet sein, um auf diese Webanwendung zugreifen zu können.",
);
}
if ($lang eq "fr") {
@txt = (
"Connexion requise",
"Vous devez être connecté pour accéder à cette application web.",
);
}
$BOX .= " trans70";
my $LOGIN = ONO::IO->http_domain_base()."/login/";
$OVERLAY = qq~<div class="box_blue abs" style="top:125px;left:100px;width:325px;z-index:999">
<h3 class="cole">$txt[0]</h3>
<div class="box_paper">
<div class="large lightred">$txt[1]</div>
<div class="inline"><a href="$LOGIN" class="button_green button_big mt10" target="_parent">$BLK{'login'}</a></div>
</div>
</div>
~;
} else {
$FORM1 = qq~<$form id="output_form_id">
<input type="hidden" name="output_selected" value="$vars{'output_selected'}">
<input type="hidden" name="exercise" value="$vars{'exercise'}">
<input type="hidden" name="exercise_id" value="$vars{'exercise_id'}">
$input
~;
$FORM2 = qq~</form>~;
}
return qq~$FORM1
<div id="$vars{'app_conf_box_id'}" class="$BOX abs" style="$ABS;max-width:${MAXWIDTH}px;padding:5px 10px 5px 10px">
$CONF_BOX_TITLE
<div class="box_paper p5_720" style="$STYLE">
<div id="morzino_apps_core_conf_jserror" class="inline w100">
<div class="mb5 lightred bold">$errs[0]</div>
<div class="mb5 col6">$errs[1]</div>
<div class="mb10 col6">$errs[2]</div>
</div>
<div id="morzino_apps_core_conf_box" class="inline w100 hide">
$STORED
$VIRCLASS
<table class="wide_table">
$CONF
<tr>
<td>$RELOAD</td>
<td class="w100"><div class="mt5">$BUTTONS$PRINT_OPTS</div></td>
</tr>
$vars{'app_conf_box_buttons_below'}
</table>
</div>
</div>
<div id="morzino_apps_core_conf_loadsave" class="hide">$OUTPUT_LOADSAVE</div>
</div>
$OVERLAY
$FORM2
<script>
onojs_hide('morzino_apps_core_conf_jserror');onojs_block('morzino_apps_core_conf_box');onojs_block('morzino_apps_core_conf_loadsave');
</script>
~;
}
}
sub conf_box_title {
#: Generate the configuration box title.
my $COL = "col6";
if ($_[3] eq "black") {
$COL = "cole";
}
return qq~<table class="default_table mb5">
<tr class="vtop">
<td><img class="block24" src="/ono/osr/images/icons/crystal/32x32/$_[1].png" style="margin-right:3px" alt=""></td>
<td><h3 class="m0 $COL">$_[2]</h3></td>
</tr>
</table>
~;
}
###################################################################
# configuration input lines
###################################################################
sub conf_input {
#: Deprecated here, moved to ONO_FW_Apps_ToolBox.
my (
$self,
$type,
$BLK_ref,
$vars_ref,
$switches,
@data,
) = @_;
ONO::FW::Apps::ToolBox->conf_input($type,$BLK_ref,$vars_ref,$switches,@data);
}
###################################################################
# useful stuff
###################################################################
sub lang_check {
#: Check lang codes.
my (
$self,
@langs
) = @_;
for (my $i = 0; $i < 2; $i++) {
if ($langs[$i] ne "img") {
$langs[$i] = lc substr($langs[$i],0,2);
}
$langs[$i] =~ s~[^a-z]~~g;
}
return ($langs[0],$langs[1]);
}
sub lang_check_unique {
#: Check and make sure lang codes are unique.
my (
$self,
@langs
) = @_;
# if languages are the same, then use fallback language as second language
if ($langs[0] eq $langs[1]) {
$langs[1] = $langs[2];
}
# if still unique, then flush languages
if ($langs[0] eq $langs[1]) {
return ('','');
} else {
return ($langs[0],$langs[1]);
}
}
sub range_check {
#: Check number range - deprecated here, moved to ONO_FW_Apps_Core_Math.
my (
$self,
$max_from,
$max_to,
$from,
$to,
$negative,
$numsys,
) = @_;
return ONO::FW::Apps::Core::Math->range_check(
$max_from,
$max_to,
$from,
$to,
$negative,
$numsys,
);
}
sub get_operations {
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
return ONO::FW::Apps::Core::Math->get_operations($_[1]);
}
sub operation_symbol {
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
#:
#: Switches:
#:
#: -c colorize
#: -p print / pdf mode
#: -s use slash as division symbol
#: -x executable (simple code)
return ONO::FW::Apps::Core::Math->operation_symbol($_[1],$_[2]);
}
sub random_operation {
#: Select random operation.
my $num = @_;
return $_[int(rand($num-1))+1];
}
sub random_number {
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
my (
$self,
$from,
$to,
$min,
$max,
$vars_ref,
) = @_;
return ONO::FW::Apps::Core::Math->random_number(
$from,
$to,
$min,
$max,
$vars_ref,
);
}
sub input_vars {
my (
$self,
$vars_ref,
$switches,
) = @_;
#: Deprecated here, moved to ONO_FW_Apps_Core_ToolBox.
#:
#: Switches:
#:
#: -f first question is 1 as first step, not 2
#: -r reload app with same settings mode
#: -R include Report variables
#: -x incluce exercise code and ID (incompatible with -r)
return ONO::FW::Apps::Core::ToolBox->input_vars($vars_ref,$switches);
}
sub question_number {
return ONO::FW::Apps::Core::Question->question_number($_[1])
}
sub question_progress {
#: Deprecated here, moved to ONO_FW_Apps_Core_Question.
my (
$self,
$total,
$question,
$MORE,
$switches,
) = @_;
return ONO::FW::Apps::Core::Question->question_progress(
$total,
$question,
$MORE,
$switches,
);
}
sub question_progress_done {
#: Deprecated here, moved to ONO_FW_Apps_Core_Question.
return ONO::FW::Apps::Core::Question->question_progress_done($_[1],$_[2]);
}
sub question_progress_done_msg {
#: Deprecated here, moved to ONO_FW_Apps_Core_Question.
my (
$self,
$app,
$db,
$community,
$form,
$action_url,
$questions,
$mistakes,
$lang,
$BLK_ref,
$vars_ref,
$switches,
) = @_;
return ONO::FW::Apps::Core::Question->question_progress_done_msg(
$app,
$db,
$community,
$form,
$action_url,
$questions,
$mistakes,
$lang,
$BLK_ref,
$vars_ref,
$switches,
);
}
sub unique_copies {
#: Logic to allow the generation of multiple page copies.
my (
$self,
$num,
$multiplexer,
) = @_;
if ($num < 1 || $num > 99) {
$num = 1;
}
if ($multiplexer < 1 || $multiplexer > 99) {
$multiplexer = 1;
}
my (@copies,$counter);
for (my $i = 1; $i < $multiplexer+1; $i++) {
for (my $j = 1; $j < $num+1; $j++) {
$counter++;
@copies = (@copies,$counter);
}
}
return @copies;
}
sub unique_copies_info {
#: Logic to allow the generation of multiple page copies.
my (
$self,
$canvas,
$copy,
$vars_ref,
) = @_;
my %vars = %$vars_ref;
if ($vars{'app_input_print_options_unique_copies'} > 1) {
ONO::Lib::PDF::Draw->text($canvas,170,-5,"$copy / $vars{'app_input_print_options_unique_copies'}","right");
}
}
sub check_rightwrong {
#: Deprecated here, moved to ONO_FW_Apps_Core_Check.
my (
$self,
$is_wrong,
$BLK_ref,
) = @_;
return ONO::FW::Apps::Core::Check->check_rightwrong($is_wrong,$BLK_ref);
}
sub check_single {
#: Deprecated here, moved to ONO_FW_Apps_Core_Check.
shift @_;
return ONO::FW::Apps::Core::Check->check_single(@_);
}
sub check_multi {
#: Deprecated here, moved to ONO_FW_Apps_Core_Check.
my (
$self,
$BLK_ref,
$remaining,
$page,
$pages,
$switches,
$vars_ref,
) = @_;
return ONO::FW::Apps::Core::Check->check_multi(
$BLK_ref,
$remaining,
$page,
$pages,
$switches,
$vars_ref,
);
}
sub clean_answer_math {
#: Clean up math / number inputs.
my $answer = $_[1];
$answer =~ s~(\n|\r|\t| )~~g;
$answer =~ s~\,~\.~g;
$answer = uc $answer;
if ($_[2] =~ /r/) {
$answer =~ s~[^0-9\.\-\I\V\X\L\C\D\M]~~gi;
} else {
$answer =~ s~[^0-9\.\-]~~gi;
}
return $answer;
}
sub round_up {
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
my (
$self,
$num,
$vars_ref
) = @_;
return ONO::FW::Apps::Core::Math->round_up($num,$vars_ref);
}
sub numsys {
#: Translate number systems (decimal, roman, hex).
my (
$self,
$num1,
$num2,
$num3,
$numsys,
) = @_;
my @num = ($num1,$num2,$num3);
for (my $i = 0; $i < 3; $i++) {
if ($numsys eq "roman") {
$num[$i] = ONO::Lib::Data::Numbers::Roman->get($num[$i],"rn");
}
if ($numsys eq "hex") {
$num[$i] = ONO::Lib::Data::Numbers::Hexa->get($num[$i]);
}
}
return @num;
}
sub number_length {
#: Detect the string length of a number.
my (
$self,
$max,
$comma,
) = @_;
if ($comma > 0) {
$comma++;
}
return (length $max) + $comma;
}
sub detect_local {
#: Detect where we are located (using domain).
my $local;
if ($ENV{'SERVER_NAME'} =~ /\.(com|net|org)$/) {
$local = "us";
}
if ($ENV{'SERVER_NAME'} =~ /\.(at|ch|cz|de|dk|es|eu|fi|fr|gr|hr|it|ie|nl|no|pt|se|sm|ua|uk)$/) {
$local = "eu";
}
if ($_[1] =~ /^(de|fr|lu)$/) {
$local = "eu";
}
if (ONO::IO->devstation) {
$local = "eu";
}
return $local;
}
sub local_comma_delimiter {
#: Set comma delimiter (US/EU).
my (
$self,
$local,
$vars_ref,
) = @_;
my %vars;
if ($vars_ref) {
%vars = %$vars_ref;
}
my ($num_comma,$num_delimiter) = (".",",");
if ($local eq "eu") {
# ($num_comma,$num_delimiter) = (",","'");
($num_comma,$num_delimiter) = (",","");
if ($vars{'output_web'}) {
# ($num_comma,$num_delimiter) = (",",qq~<span class="col9">’</span>~);
($num_comma,$num_delimiter) = (",",qq~<span class="col9">˙</span>~);
}
}
return ($num_comma,$num_delimiter);
}
sub make_human_readable {
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
my (
$self,
$num,
$num_comma,
$num_delimiter,
) = @_;
return ONO::FW::Apps::Core::Math->make_human_readable($num,$num_comma,$num_delimiter);
}
sub fix_fp_rounding {
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
my $num = ONO::FW::Apps::Core::Math->fix_fp_rounding($_[1]);
return $num;
}
sub float_to_decimal {
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
my $num = ONO::FW::Apps::Core::Math->float_to_decimal($_[1]);
return $num;
}
sub html_exponent {
#: Exponent to HTML.
my $num = $_[1];
$num =~ s~\^2~<span class="sup">2</span>~;
$num =~ s~\^3~<span class="sup">3</span>~;
return $num;
}
sub comma_limit {
my (
$self,
$num,
$limit,
) = @_;
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
my $num = ONO::FW::Apps::Core::Math->comma_limit($num,$limit);
return $num;
}
sub multi_page_logic {
my (
$self,
$page,
$vars_ref,
$force_questions_per_page,
$switches,
) = @_;
#: Mulit-page logic for online exercises.
#:
#: Switches:
#:
#: -p page can't be zero
#: -P pages can't be zero
my %vars = %$vars_ref;
my $stats_switches;
my $questions_per_page = $vars{'app_input_number_of_questions'};
my $default_questions_per_page = 20;
my $pages;
if ($force_questions_per_page) {
$default_questions_per_page = $force_questions_per_page;
}
if ($questions_per_page > $default_questions_per_page) {
$questions_per_page = $default_questions_per_page;
$page++;
if ($vars{'output_web_page'}) {
$page = $vars{'output_web_page'};
}
if ($vars{'output_web_next_page'}) {
$page++;
$vars{'output_web_page'} = $page;
}
$pages = int(($vars{'app_input_number_of_questions'}-1)/$default_questions_per_page)+1;
$stats_switches .= "p";
}
if ($vars{'output_web_page'} && $vars{'output_web_page'} == $pages && $vars{'app_input_number_of_questions'} > $default_questions_per_page) {
$questions_per_page = $vars{'app_input_number_of_questions'};
my $whilecounter;
while ($questions_per_page > $default_questions_per_page && $whilecounter < 256) {
$whilecounter++;
$questions_per_page = $questions_per_page - $default_questions_per_page;
}
}
if ($switches =~ /p/ && $page < 1) {
$page = 1;
}
if ($switches =~ /P/ && $pages < 1) {
$pages = 1;
}
return ($stats_switches,$questions_per_page,$page,$pages);
}
sub multi_frame_start {
#: Logic for splitting am exercise into two rows.
if ($_[1]) {
return "";
} else {
my $width = "w50";
if ($_[2]) {
$width = $_[2];
}
return qq~<div class="p10"><div class="inline w100 bg_fabric"><div class="$width fl w100_900 fn_900"><table class="wide_table bt bb">~;
}
}
sub multi_frame_split {
#: Logic for splitting am exercise into two rows.
my $width = "w50";
if ($_[1]) {
$width = $_[1];
}
return qq~</table></div><div class="$width fl w100_900 fn_900"><table class="wide_table bt bb">~;
}
sub multi_frame_end {
#: Logic for splitting am exercise into two rows.
if (!$_[1] && $_[2]) {
return qq~</table></div></div></div>~;
} else {
return "";
}
}
sub generate_add {
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
my (
$self,
$i,
$num1,
$num2,
$op,
$res,
$cache1,
$cache2,
$vars_ref,
$force_flush,
) = @_;
my ($num1,$num2,$res,$cache1,$cache2,$DEBUG) = ONO::FW::Apps::Core::Math->generate_add(
$i,
$num1,
$num2,
$op,
$res,
$cache1,
$cache2,
$vars_ref,
$force_flush,
);
return ($num1,$num2,$res,$cache1,$cache2,$DEBUG);
}
sub generate_sub {
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
my (
$self,
$i,
$num1,
$num2,
$op,
$res,
$cache1,
$cache2,
$vars_ref,
$force_flush,
) = @_;
my ($num1,$num2,$res,$cache1,$cache2,$DEBUG) = ONO::FW::Apps::Core::Math->generate_sub(
$i,
$num1,
$num2,
$op,
$res,
$cache1,
$cache2,
$vars_ref,
$force_flush,
);
return ($num1,$num2,$res,$cache1,$cache2,$DEBUG);
}
sub generate_muldiv {
#: Deprecated here, moved to ONO_FW_Apps_Core_Math.
my (
$self,
$i,
$num1,
$num2,
$op,
$res,
$cache1,
$cache2,
$vars_ref,
$force_flush,
) = @_;
my ($num1,$num2,$res,$cache1,$cache2,$DEBUG) = ONO::FW::Apps::Core::Math->generate_muldiv(
$i,
$num1,
$num2,
$op,
$res,
$cache1,
$cache2,
$vars_ref,
$force_flush,
);
return ($num1,$num2,$res,$cache1,$cache2,$DEBUG);
}
###################################################################
# OLD STUFF BELOW...
###################################################################
sub win {
my (
$self,
$form,
$FORM,
$BLK_ref,
$switches,
) = @_;
#: Configuration window generator.
#:
#: Switches:
#:
#: -o online
#: -p print
my %BLK = %$BLK_ref;
my $BUTTONS;
if ($switches =~ /o/) {
$BUTTONS .= qq~<input type="submit" name="output_web" value="$BLK{'online_training'}" class="button_green">~;
}
if ($switches =~ /p/) {
# not implemented yet
}
return qq~<div class="box_fabric_white_light" style="width:500px;margin-left:10px">
<h2 style="margin-bottom:10px">$BLK{'Configure_exercise'}:</h2>
<div class="box_paper">
<$form>
$FORM
<div class="mt10">
<div class="inline auto" id="button_submit">$BUTTONS</div>
</div>
</form>
</div>
</div>
~;
}
###################################################################
# info pics
###################################################################
sub infopics_simple {
my @IMG2 = &infopics_core(@_);
#: Infopics generator.
#: This version does NOT set any sizes, the result may need to be fitted in a div using width and height!
return ONO::Lib::UI::Image->collection("0:0:0:0:0",@IMG2);
}
sub infopics {
#: Infopics generator.
my @IMG2 = &infopics_core(@_);
return qq~<div class="hide600">~.ONO::Lib::UI::Image->collection("400:420:60::10:abs",@IMG2)."</div>";
}
sub infopics_core {
#: Infopics generator.
my @IMG = @_;
my @IMG2;
foreach my $img (@IMG) {
my @ip = split(/:/,$img);
if ($ip[0] =~ /^(screen|sheet|image)$/) {
my $w = $ip[1];
my $h = int($ip[1]/210*297);
my $th = int($ip[1]/7.6);
my $b;
my $sw = "st";
$ip[5] = "/images/morzino/apps/$ip[5]";
if ($ip[0] eq "screen") {
$w = $ip[1];
$h = int($ip[1]/1280*720);
$th = int($ip[1]/11.5);
my $img = "topbar_screen_morzino.jpg";
if ($ENV{'SERVER_NAME'} =~ /oli/) {
$img = "topbar_screen_oli_lu.jpg";
}
if (&variation eq "education.lu") {
$img = "topbar_screen_oli_education.jpg";
}
$ip[5] .= ";/images/morzino/apps/$img;$th";
}
if ($ip[0] eq "sheet") {
# $b = 5;
my $img = "topbar_sheet_morzino.jpg";
if ($ENV{'SERVER_NAME'} =~ /oli/) {
$img = "topbar_sheet_oli_lu.jpg";
}
if (&variation eq "education.lu") {
$img = "topbar_sheet_oli_education.jpg";
}
$ip[5] .= ";/images/morzino/apps/$img;$th";
}
if ($ip[0] eq "image") {
$w = $ip[1];
$h = $ip[1];
if ($ip[1] =~ /^(.*?)x(.*?)$/) {
$w = $1;
$h = $2;
}
$sw = "";
}
@IMG2 = (@IMG2,"img:$ip[2]:$ip[3]:$ip[5]:$w:$h:$b:$ip[4]:$sw");
}
}
return @IMG2;
}
###################################################################
# generate subtitles
###################################################################
sub subtitles {
#: Deprecated here, moved to ONO_FW_Apps_Core_LangKit.
return ONO::FW::Apps::Core::LangKit->subtitles($_[1]);
}
###################################################################
# update now
###################################################################
sub now {
#: Deprecated.
}
###################################################################
# mkpdf
###################################################################
sub mkpdf {
#: Deprecated here, moved to ONO_FW_Apps_Core_Graphics.
my (
$self,
$BLK_ref,
$vars_ref,
$HTTP,
$BASE,
) = @_;
return ONO::FW::Apps::Core::Graphics->mkpdf(
$BLK_ref,
$vars_ref,
$HTTP,
$BASE,
);
}
###################################################################
# mkpdf
###################################################################
sub output_paper {
#: Deprecated here, moved to ONO_FW_Apps_Core_Graphics.
my (
$self,
$pdfkey,
$BLK_ref,
$vars_ref,
$HTTP,
$BASE,
$switches,
) = @_;
return ONO::FW::Apps::Core::Graphics->output_paper(
$pdfkey,
$BLK_ref,
$vars_ref,
$HTTP,
$BASE,
$switches,
);
}
sub output_paper_save {
#: Save a PDF file.
my (
$self,
$pdfkey,
$BLK_ref,
$vars_ref,
$HTTP,
$BASE,
$yearmonmday,
) = @_;
my %vars = %$vars_ref;
if ($vars{'output_paper_save_exec'} || $vars{'output_paper_save_target_change'} || $vars{'output_paper_save_target_app_change'}) {
if ($vars{'output_paper_save_pdfkey'}) {
$pdfkey = $vars{'output_paper_save_pdfkey'};
}
return ONO::FW::Apps::Core::Save->output_paper_save($pdfkey,$BLK_ref,$vars_ref,$HTTP,$BASE,$yearmonmday);
} else {
return "";
}
}
###################################################################
# headers
###################################################################
sub headers_options {
#: PDF header helper.
my $BLK_ref = $_[1];
my $vars_ref = $_[2];
my %BLK = %$BLK_ref;
my %vars = %$vars_ref;
my ($RET,$OPS);
if ($vars{'app_input_range_from'} && $vars{'app_input_range_to'}) {
$RET .= "$BLK{'Numbers'} $vars{'app_input_range_from'} - $vars{'app_input_range_to'}";
}
foreach my $op ('add','sub','mul','div') {
if ($vars{"app_input_op_$op"}) {
$OPS .= qq~$BLK{"op_$op"}, ~;
}
}
if ($OPS) {
$OPS =~ s~, $~~;
if ($RET) {
$RET .= ", ";
}
$RET .= "$OPS";
}
return $RET;
}
sub headers {
my (
$self,
$vars_ref,
$format,
$switches
) = @_;
#: PDF header options.
#:
#: Switches:
#:
#: -c is correction sheet
#: -C alternative copyright
#: -E alternative copyright: evaluation
#: -N alternative copyright: notes
#: -X no copyright, no name, no date
my %vars = %$vars_ref;
my ($sub1,$sub2) = &subtitles("",\%vars);
my $done;
my $test;
if (ONO::IO->devstation) {
#$test = 2;
}
# special case: morzino
if (($ENV{'SERVER_NAME'} =~ /(morzino)/ || ONO::IO->devstation) && $switches !~ /(E|X)/) {
$switches .= "E";
}
if (($ENV{'SERVER_NAME'} =~ /(jamplifier)/ || ONO::IO->community() eq "music") && $switches !~ /(N|X)/) {
$switches .= "NX";
}
# designs
if ($vars{'ono_app_print_design'}) {
$vars{'app_input_print_options_design'} = $vars{'ono_app_print_design'};
}
if ($vars{'ono_app_print_design_corrections'}) {
$vars{'app_input_print_options_design_corrections'} = $vars{'ono_app_print_design_corrections'};
}
if ($vars{'app_input_print_options_design'} && ($switches !~ /c/ || $vars{'app_input_print_options_design_corrections'})) {
my $community = ONO::IO->community();
if (!$community) {
$community = "school";
}
ONO::Lib::PDF::ToolBox->design_print($community,$vars{'app_input_print_options_design'},$format);
}
# logo and cc
if ($format !~ /^q/) {
my ($top1,$top2,$top3,$width) = ONO::Lib::PDF::ToolBox->design_coords($format);
ONO::Lib::PDF::Draw->image("",16,$top1,20,20,"ono-data/school/pdf/logo_32.jpg",2,2);
if ($switches !~ /(C|E|N|X)/) {
ONO::Lib::PDF::Draw->image("",17.5,$top2,23,6,"ono-data/school/pdf/cc_logo.jpg");
}
}
# titles and subtitles
# if (($ENV{'SERVER_NAME'} =~ /oli\.lu/ || $test == 1) && &variation ne "education.lu") {
#
# $done++;
#
# ONO::FW::Apps::PDF->headers(
# \%vars,
# "oli.lu",
# $sub1,
# $sub2,
# "www.oli.lu",
# $format,
# $switches,
# );
#
# }
if ($format !~ /^q/) {
my $devmode;
# $devmode++;
if (ONO::IO->devstation && $devmode) {
$done++;
ONO::FW::Apps::PDF->headers(
\%vars,
"AppsDev",
"",
"Dev",
"DEV",
$format,
$switches,
);
} else {
if (ONO::Lib::Web::Domain->variation eq "morzino" || $test == 2) {
$done++;
my ($TITLE,$COPY) = ("Worksheet by Morzino.com","The Morzino Project - www.morzino.com");
if ($vars{'lang'} eq "de" || $vars{'app_input_paper_lang'} eq "de") {
($TITLE,$COPY) = ("Arbeitsblatt von Morzino.de","Das Morzino Projekt - www.morzino.de");
}
if ($vars{'lang'} eq "fr" || $vars{'app_input_paper_lang'} eq "fr") {
($TITLE,$COPY) = ("Fiche de travail par Morzino.fr","Le projet Morzino - www.morzino.fr");
}
ONO::FW::Apps::PDF->headers(
\%vars,
$TITLE,
"",
"$sub1 - $sub2",
$COPY,
$format,
$switches,
);
}
if (ONO::Lib::Web::Domain->variation eq "oli" || $test == 2) {
$done++;
my ($TITLE,$COPY) = ("Oli.lu","www.oli.lu");
ONO::FW::Apps::PDF->headers(
\%vars,
$TITLE,
"",
"$sub1 - $sub2",
$COPY,
$format,
$switches,
);
}
if (&variation eq "education.lu" || $test == 3) {
$done++;
ONO::FW::Apps::PDF->headers(
\%vars,
"oli.education.lu",
"",
"De Portail vun der Grondschoul",
"oli.education.lu",
$format,
$switches,
);
}
if (ONO::Lib::Web::Domain->variation eq "jamplifier") {
$done++;
my ($TITLE,$COPY) = ("","The Jamplifier Project - www.jamplifier.com");
ONO::FW::Apps::PDF->headers(
\%vars,
$TITLE,
"",
"",
$COPY,
$format,
$switches,
);
}
}
if (!$done) {
if ($ENV{'SERVER_NAME'} =~ /oli/) {
ONO::FW::Apps::PDF->headers(
\%vars,
"oli.lu",
"",
"$sub1 - $sub2",
"www.oli.lu",
$format,
$switches,
);
} else {
ONO::FW::Apps::PDF->headers(
\%vars,
"morzino.com",
"",
"$sub1 - $sub2",
"www.morzino.com",
$format,
$switches,
);
}
}
}
ONO::FW::Apps::PDF->specimen($vars{'output_canvas'},$vars_ref);
}
###################################################################
# stats
###################################################################
sub stats_multi_pages {
#: Deprecated here, moved to ONO_FW_Apps_Core_Stats.
my (
$self,
$questions,
$stat_correct,
$stat_wrong,
$page,
$pages,
$questions_per_page,
) = @_;
return ONO::FW::Apps::Core::Stats->stats_multi_pages(
$questions,
$stat_correct,
$stat_wrong,
$page,
$pages,
$questions_per_page,
)
}
sub stats_replace {
#: Deprecated here, moved to ONO_FW_Apps_Core_Stats.
my @data = @_;
return ONO::FW::Apps::Core::Stats->stats_replace(
$data[1],$data[2],$data[3],$data[4],$data[5],$data[6],$data[7],$data[8],$data[9]
);
}
sub stats {
#: Deprecated here, moved to ONO_FW_Apps_Core_Stats.
my (
$self,
$MORE,
$BLK_ref,
$switches,
) = @_;
return ONO::FW::Apps::Core::Stats->stats(
$MORE,
$BLK_ref,
$switches,
)
}
###################################################################
# info
###################################################################
sub info_display {
#: Info display.
return qq~<div class="hide900 italic fr p10 center" style="width:400px">$_[1]$_[2]</div>~;
}
sub info {
my (
$self,
$item,
$lang,
) = @_;
#: Get info for nfo display.
return ONO::FW::Apps::Core::LangKit->info($item,$lang);
}
###################################################################
# print options
###################################################################
sub print_corrections {
#: Print corrections helper.
my (
$self,
$file,
$template,
$format,
$vars_ref,
) = @_;
my %vars = %$vars_ref;
if ($vars{'output_paper'} && $vars{'app_input_print_options_corrections'}) {
if ($vars{'output_paper_save_split'}) {
ONO::FW::Apps::PDF->end();
ONO::FW::Apps::PDF->new($file,$template,$format);
} else {
ONO::FW::Apps::PDF->page($template,$format);
}
return 1;
} else {
return 0;
}
}
###################################################################
# print options
###################################################################
sub print_options {
#: Deprecated.
return "";
}
sub hint_script {
#: Deprecated.
return "";
}
sub hint_script_v2 {
#: Display online hints helper.
my (
$self,
$math1,
$math2,
$hints,
$TARGET,
) = @_;
if (!$math1) {
$math1 = "length/3";
}
if (!$math2) {
$math2 = "(length/2)+1";
}
if (!$TARGET) {
$TARGET = "'output_web_answer_'+id+'_id'";
}
if ($TARGET !~ /\'/) {
$TARGET = "'$TARGET'";
}
return qq~<input type="hidden" id="output_web_hints" name="output_web_hints" value="$hints">
<script>
function hint(id) {
var hints = document.getElementById('output_web_hints_'+id).value;
var length = (document.getElementById('output_web_correct_'+id).value).length;
if (hints < 3) {
document.getElementById('output_web_hints_'+id).value++;
var hint_count = document.getElementById('output_web_hints_counter_'+id).innerHTML;
hint_count++;
document.getElementById('output_web_hints_counter_'+id).innerHTML=hint_count;
var total = document.getElementById('output_web_hints').value;
total++;
document.getElementById('output_web_hints').value = total;
document.getElementById('output_web_total_hints').innerHTML = total;
}
if (hints == 0) {
onojs_setvalue($TARGET,(onojs_getvalue('output_web_correct_'+id)).substring(0,$math1));
}
if (hints == 1) {
onojs_setvalue($TARGET,(onojs_getvalue('output_web_correct_'+id)).substring(0,$math2));
}
if (hints == 2 || length == 2) {
onojs_setvalue($TARGET,onojs_getvalue('output_web_correct_'+id));
onojs_hide('output_web_hint_button_'+id);
onojs_block('output_web_hint_button_off_'+id);
}
}
</script>
~;
}
###################################################################
# var store (store exercise for later restart)
###################################################################
sub varstoreaction {
#: Store exercise for later restart logic.
my $vars_ref = $_[1];
my %vars = %$vars_ref;
if ($vars{'varstoreaction'} && ($vars{'username'} || $vars{'virclass'} || $vars{'anonymous'})) {
my $DIR = &varstoredir("",$vars{'username'},$vars{'virclass'},$vars{'anonymous'});
if ($DIR =~ /[A-Za-z0-9]/) {
if ($vars{'varstoreaction'} =~ /^load_(.*?)_(.*?)_(.*?)$/) {
$DIR .= $1;
my $FILE = "$2\_$3";
if (ONO::IO->exists("$DIR/$FILE.txt")) {
foreach my $line (ONO::IO->list("$DIR/$FILE.txt")) {
my @lp = split(/\^\:\^/,$line);
if ($lp[0] eq "VAR") {
$vars{$lp[1]} = $lp[2];
}
}
}
}
if ($vars{'varstoreaction'} eq "delete") {
ONO::IO->rmdir($DIR);
}
}
}
return (\%vars,%vars);
}
sub varstore {
#: Store exercise for later restart logic.
my (
$self,
$username,
$virclass,
$anonymous,
$vars_ref,
) = @_;
if ($username || $virclass) {
my %vars = %$vars_ref;
if ($vars{'output_web'} && $vars{'output_web_timer_start'}) {
my $DIR = &varstoredir("",$username,$virclass,$anonymous,$vars{'output_web_timer_start'});
if ($DIR) {
if ($vars{'output_web_finish'} || $vars{'output_progress_done'}) {
ONO::IO->rm("$DIR/$vars{'app_sid'}.txt");
ONO::IO->rmdir($DIR);
} else {
my $DATA;
foreach my $key (sort keys %vars) {
if ($vars{$key}) {
$DATA .= qq~VAR\^\:\^$key\^\:\^$vars{$key}\^\:\^\n~;
}
}
ONO::IO->mkpath($DIR);
ONO::IO->chmod($DIR,777);
ONO::IO->store("$DIR/$vars{'app_sid'}.txt",$DATA);
ONO::IO->chmod("$DIR/$vars{'app_sid'}.txt",777);
}
}
}
}
}
sub varstoreapp {
#: Store exercise for later restart logic.
$ENV{'REQUEST_URI'} =~ m~/cgi-bin/local/perl/(.*?)/apps/(.*?)\.pl~;
return $2;
}
sub varstoredir {
#: Store exercise for later restart logic.
my (
$self,
$username,
$virclass,
$anonymous,
$timestamp,
) = @_;
my $app = &varstoreapp();
if ($app) {
my $DIR = "users/".ONO::IO->deepdir($username)."/$username";
if (!$username) {
if ($virclass =~ /^(.*?):(.*?)$/) {
$DIR = "virclass/".ONO::IO->deepnum($1)."/$1/$2";
} else {
$DIR = "anonymous/$anonymous";
}
}
return "var/tmp/apps/exercises/$DIR/$app/$timestamp";
} else {
return "";
}
}
###################################################################
# var dump (dev mode only)
###################################################################
sub vardump {
#: Dump vars on developer station (debugging mode).
if (ONO::IO->devstation) {
my $vars_ref = $_[1];
my %vars = %$vars_ref;
my $VAR .= qq~<div class="block256"></div><div class="block256"></div>~;
my $DATA;
my $app;
if ($ENV{'SCRIPT_NAME'} =~ m~/cgi-bin/local/perl/school/apps/(.*?)\.pl~) {
$app = $1;
}
my $COOKIE = ONO::Lib::Web::Cookie->get("ono_app_${app}_settings");
foreach my $cdat (ONO::IO->list("var/tmp/cookies/apps/$COOKIE.txt")) {
if ($cdat =~ m~^(.*?)=(.*?)$~) {
$COOKIE .= qq~<br><span class="col9">cookie-data:</span> $1 = $2~;
}
}
$VAR .= qq~<div class="pad10_2 bt">Cookie:<br>ID: $COOKIE</div>~;
foreach my $key (sort keys %vars) {
if ($vars{$key} || $vars{$key} eq "0") {
$VAR .= qq~<div class="pad10_2 bt">$key -> $vars{$key}</div>~;
$DATA .= qq~$key -> $vars{$key}\n~;
}
}
ONO::IO->store("_apps_vardump.txt",$DATA);
return qq~$_[2]$VAR~;
} else {
return "";
}
}
###################################################################
# var flush
###################################################################
sub flush_cache {
#: Not used yet (deprecated?)
# my $vars_ref = $_[1];
# my %vars = %$vars_ref;
#
# foreach my $key (keys %vars) {
# if ($key =~ /^output_web_cache_/) {
# $vars{$key} = "";
# }
# }
#
# return \%vars;
}
###################################################################
# graphics elements
###################################################################
sub pdf_draw_house {
#: Deprecated here, moved to ONO_FW_Apps_Core_Graphics.
my (
$self,
$canvas,
$x,
$y,
$cols,
$res,
$op,
$corr,
) = @_;
return ONO::FW::Apps::Core::Graphics->pdf_draw_house(
$canvas,
$x,
$y,
$cols,
$res,
$op,
$corr,
);
}
sub pdf_draw_wall {
#: Deprecated here, moved to ONO_FW_Apps_Core_Graphics.
my (
$self,
$canvas,
$x,
$y,
$rows,
$nums_ref,
$op,
$numsys,
$mode,
$vars_ref,
$num_comma,
) = @_;
return ONO::FW::Apps::Core::Graphics->pdf_draw_wall(
$canvas,
$x,
$y,
$rows,
$nums_ref,
$op,
$numsys,
$mode,
$vars_ref,
$num_comma,
);
}
###################################################################
# LANG
###################################################################
sub lang_tenses {
#: Deprecated here, moved to ONO_FW_Apps_Core_Lang.
my ($ref1,$ref2,$ref3,$ref4,$ref5) = ONO::FW::Apps::Core::Lang->lang_tenses($_[1]);
return ($ref1,$ref2,$ref3,$ref4,$ref5);
}
sub lang_verbs_default {
#: Deprecated here, moved to ONO_FW_Apps_Core_Lang.
my $verbs = ONO::FW::Apps::Core::Lang->lang_verbs_default($_[1]);
return $verbs;
}
sub lang_verbs_add {
#: Deprecated here, moved to ONO_FW_Apps_Core_Lang.
my (
$self,
$db,
$community,
$option,
$lang,
$BLK_ref,
$vars_ref,
) = @_;
my $ADD = ONO::FW::Apps::Core::Lang->lang_verbs_add($db,$community,$option,$lang,$BLK_ref,$vars_ref);
return $ADD;
}
sub lang_verbs_persons {
#: Deprecated here, moved to ONO_FW_Apps_Core_Lang.
my @persons = ONO::FW::Apps::Core::Lang->lang_verbs_persons($_[1]);
return @persons;
}
sub lang_verbs_persons_list {
#: Deprecated here, moved to ONO_FW_Apps_Core_Lang.
my @persons = &lang_verbs_persons("",$_[1]);
return "$persons[0];$persons[1];$persons[2];$persons[3];$persons[4];$persons[5];";
}
###################################################################
# PRINT OPTS
###################################################################
sub print_design {
#: Select preferred print design (PDF).
my (
$self,
$id,
$lang,
$BLK_ref,
$switches,
) = @_;
my %BLK = %$BLK_ref;
my @txt = ONO::FW::Apps::Core::LangKit->print_design($lang);
my $SWITCH = ONO::Lib::UI::Check->switch("${id}_corrections",0,"mr");
my $WEB .= qq~<tr>
<td class="tar">$BLK{'design'}:</td>
<td>
<div class="select"><select name="$id">
<option value="default">$BLK{'default'}</option>
<option value="">----</option>
<option value="">$BLK{'none'}</option>
</select></div>
</td>
</tr>
~;
if ($switches =~ /c/) {
$WEB .= qq~<tr>
<td></td>
<td class="p0">
<table class="default_table">
<tr>
<td>$SWITCH</td>
<td>$txt[0]</td>
</tr>
</table>
</td>
</tr>
~;
}
return $WEB;
}
###################################################################
# VARIATION AND CUSTOM CODE
###################################################################
sub variation {
#: Detect platform variation.
my $VAR = "education.lu";
if ($ENV{'SERVER_NAME'} =~ /oli\.lu/i) {
$VAR = "oli";
}
if ($ENV{'SERVER_NAME'} =~ /morzino\.com/i) {
$VAR = "morzino";
}
if ($ENV{'SERVER_NAME'} =~ /(jamplifier)\.(com|org|net)/i || ONO::IO->community() eq "music") {
$VAR = "music";
}
if ($ENV{'SERVER_NAME'} =~ /(education|schoul)\.lu$/i || -e "/var/www/oli/cgi-bin/") {
$VAR = "education.lu";
}
if (ONO::IO->devstation) {
# $VAR = "oli";
# $VAR = "morzino";
# $VAR = "education.lu";
$VAR = "music";
}
return $VAR;
}
sub site {
#: Return site domain.
my $site = "oli.education.lu";
if (&variation =~ /morz/) {
$site = "morzino.com"
}
return $site;
}
sub sitename {
#: Return site name.
my $name = "Morzino";
if (&variation =~ /(oli|education)/ || ONO::IO->devstation) {
$name = "Oli"
}
return $name;
}
sub domain {
#: Return site domain.
my $domain = "oli.education.lu";
if (&variation =~ /morz/) {
$domain = "morzino.com"
}
return $domain;
}
###################################################################
# THAT'S IT :-D
###################################################################
1;
__END__