package ONO::ToolBox::Ajax;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2000-2025 Jos KIRPS [ www.kirps.com | jos_AT_kirps_DOT_com ]
# and The Joopita Project [ www.joopita.org | contact_AT_joopita_DOT_com ]
#
# This file, as well as other parts of the ONO Software Project or related
# elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################
use strict;
use ONO::IO;
use ONO::DB;
use ONO::Lib::Basic;
use ONO::Lib::DateTime::ToolBox;
use ONO::Lib::Code::RandomID;
use ONO::Lib::Encoding::URL;
use ONO::Lib::Lang::BLK;
use ONO::Lib::SQL::Quote;
use ONO::ToolBox::Auth;
use ONO::ToolBox::DomainLang;
use ONO::ToolBox::PipeLine;
use ONO::FW::User::Init;
use ONO::Lib::Lang::LangKitEdu;
###############################################################################
# ONO
###############################################################################
#: This module offers a number of AJAX related functions that may help to
#: implement async features.
#:
#: AJAX scripts should be located in /cgi-bin/local/perl/my_ono_project/ajax,
#: where you will also find some scripts that have been automatically generated
#: and/or updated by ONO.pl.
sub exec {
#: This function is used by /cgi-bin/local/perl/my_ono_project/ajax/exec.pl
#: (an executable file that is automatically generated by ONO.pl), it
#: offers some AJAX I/O features used by a number of ONO modules.
my (
$self,
$community,
$vars_ref,
) = @_;
my $db = ONO::DB->connect($community);
my %vars = %$vars_ref;
$vars{'username'} = "";
$vars_ref = ONO::ToolBox::Auth->auth($db,$community,\%vars);
%vars = %$vars_ref;
if (ONO::IO->devstation) {
$vars{'username'} = "jos";
$vars_ref = \%vars;
}
my $AJAX = "ONO AJAX ToolBox says 'READY', you may try mode = test.";
if ($vars{'mode'} eq "test") {
$AJAX = "ONO AJAX ToolBox says 'TEST', input seems to work fine, you may try mode = user.";
}
if ($vars{'mode'} eq "user") {
$AJAX = "ONO AJAX ToolBox says 'USER = $vars{'username'}'.";
}
if ($vars{'mode'} eq "pipeline_delete" && $vars{'username'} && $vars{'file'}) {
$vars{'file'} =~ s~[^A-Za-z0-9\.\-\_]~~gi;
my $FILE = "media/users/".ONO::IO->deepdir($vars{'username'})."/$vars{'username'}/pipeline/$vars{'file'}";
ONO::IO->rm($FILE);
$AJAX = "DELETE: $FILE";
}
if ($vars{'mode'} eq "pipeline_display" && $vars{'username'}) {
my $lang = ONO::ToolBox::DomainLang->get;
my ($BLK_ref,$UCBLK_ref) = ONO::Lib::Lang::BLK->get($lang,$vars_ref);
$AJAX = ONO::ToolBox::PipeLine->pipeline($db,$community,"","",$lang,$BLK_ref,$vars_ref,"f");
}
if ($vars{'mode'} eq "game_savescore" && $vars{'username'} eq $vars{'game_user'} && $vars{'game_score'}) {
$AJAX = "GAME: user = $vars{'user'}, score = $vars{'score'}, time = $vars{'time'}, level = $vars{'level'}";
my $sql_ref = ONO::Lib::SQL::Quote->vars($vars_ref);
my %sql = %$sql_ref;
my $ID = ONO::Lib::Code::RandomID->make;
my (
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,$timestamp,$isdst,
) = ONO::Lib::DateTime::ToolBox->get();
ONO::DB->command($db,"INSERT INTO ${community}_game_scores
(id_10,game,user,time,level,score,timestamp,flags,
creation_username,creation_timestamp,modification_username,modification_timestamp) VALUES
('$ID','$sql{'game'}','$sql{'game_user'}','$sql{'game_time'}','$sql{'game_level'}','$sql{'game_score'}','$timestamp','',
'$vars{'username'}','$timestamp','$vars{'username'}','$timestamp');");
}
if ($vars{'mode'} eq "community_search_user") {
if ($vars{'username'}) {
$AJAX = "";
my $query = ONO::Lib::Basic->cleanstring($vars{'query'});
my $ADD_USER = "Add user";
if ($vars{'lang'} eq "de") {
$ADD_USER = "Benutzer hinzufügen";
}
if ($vars{'lang'} eq "lu") {
$ADD_USER = "Benotzer bäimaachen";
}
if ($vars{'lang'} eq "fr") {
$ADD_USER = "Ajouter utilisateur";
}
if ($query =~ /[A-Za-z0-9]/) {
if (!$vars{'hide_title'}) {
$AJAX = qq~<div class="mt20"><h3>$ADD_USER:</h3></div>~;
}
my ($found,%used);
# friends, username starts by query
foreach my $line (ONO::DB->select($db,"${community}_community_friends","username = '$vars{'username'}' AND friend LIKE '$query%'","friend","LIMIT 10")) {
my @row = ONO::DB->readcols($line);
if (",$vars{'exclude'}," !~ /,$row[2],/) {
$found++;
$used{$row[2]}++;
$AJAX .= &community_search_user_profile("",$db,$community,$row[2]);
}
}
if ($found < 10) {
# friends, username matches query
foreach my $line (ONO::DB->select($db,"${community}_community_friends","username = '$vars{'username'}' AND friend LIKE '%$query%'","friend","LIMIT 10")) {
my @row = ONO::DB->readcols($line);
if (!$used{$row[2]} && ",$vars{'exclude'}," !~ /,$row[2],/) {
$found++;
$used{$row[2]}++;
$AJAX .= &community_search_user_profile("",$db,$community,$row[2]);
}
}
if ($found < 10) {
# all users, username OR realname start by query
foreach my $line (ONO::DB->select($db,"${community}_community_profiles","username LIKE '$query%' OR realname LIKE '$query%'","username","LIMIT 10")) {
my @row = ONO::DB->readcols($line);
if ($row[0] ne $vars{'username'} && !$used{$row[0]} && ",$vars{'exclude'}," !~ /,$row[0],/) {
$used{$row[0]}++;
$AJAX .= &community_search_user_profile("",$db,$community,$row[0],$row[1]);
}
}
if ($found < 10) {
# all users, username OR realname match query
foreach my $line (ONO::DB->select($db,"${community}_community_profiles","username LIKE '%$query%' OR realname LIKE '%$query%'","username","LIMIT 10")) {
my @row = ONO::DB->readcols($line);
if ($row[0] ne $vars{'username'} && !$used{$row[0]} && ",$vars{'exclude'}," !~ /,$row[0],/) {
$used{$row[0]}++;
$AJAX .= &community_search_user_profile("",$db,$community,$row[0],$row[1]);
}
}
}
}
}
}
} else {
$AJAX = "PERMISSION DENIED";
}
}
print $AJAX;
}
sub community_search_user_profile {
#: This is a subroutine used by the exec function.
my (
$self,
$db,
$community,
$username,
$realname,
) = @_;
if (!$realname) {
$realname = ONO::DB->get($db,"realname","${community}_community_profiles","username = '$username'");
if (!$realname) {
$realname = $username;
}
}
my $IMG = ONO::FW::User::Init->profileimage($username,48,'','',1);
return qq~<a href="javascript:void(0);" onclick="ono_ajax_user_search_exec('$username');">
<table class="wide_table">
<tr class="row">
<td class="p5">$IMG</td>
<td class="p5 w100"><div class="lh125"><div class="large bold">$realname</div><div class="col9">$username</div></div></td>
</tr>
</table>
</a>
~;
}
sub textarea_onload {
#: AJAX related JS code used by the ONO text editor.
my (
$self,
$area,
$init,
$script,
) = @_;
return qq~ onojs_text_char_count('$area','counter_chars_${area}_total');onojs_text_char_count('$area','counter_chars_${area}_initial');onojs_text_autosave_listen('$area','timer_${area}_autosave',$init,'timer_${area}_autosave_stop','$script');~;
}
sub textarea_key {
#: AJAX related JS code used by the ONO text editor.
my (
$self,
$area,
$init,
) = @_;
return qq~onojs_timer_countdown_id_kickoff('${area}_autosave','$init');
onojs_timer_countdown_id_dec('${area}_autosave',15);
onojs_text_char_count('$area','counter_chars_${area}_total');
onojs_text_char_diff('counter_chars_${area}_total','counter_chars_${area}_initial','counter_chars_${area}_diff');~;
}
sub textarea_stat {
#: AJAX related JS code used by the ONO text editor.
my (
$self,
$area,
$init,
$switches,
) = @_;
my $hide_counter;
if ($switches =~ /C/) {
$hide_counter = " hide";
}
return qq~<table class="default_table">
<tr>
<td class="p0$hide_counter"><span id="counter_chars_${area}_total">0</span> chars</td>
<td class="p0">
<div id="${area}_autosave_info1" class="hide">
<span$hide_counter>(+<span id="counter_chars_${area}_diff">0</span>) - </span>autosave in <span id="timer_${area}_autosave">$init</span> secs
</div>
</td>
<td class="p0"><div id="${area}_autosave_info2" class="hide" style="padding:0px 0px 0px 10px;color:#009900">autosave...</div></td>
<td class="p0">
<div id="${area}_autosave_debug" class="hide">init: <span id="counter_chars_${area}_initial">0</span>, stop: <span id="timer_${area}_autosave_stop">1</span></div>
</td>
</tr>
</table>
~;
}
sub input_decode {
#: Links to the ONO URL encoding input_decode function.
return ONO::Lib::Encoding::URL->input_decode($_[1]);
}
###############################################################################
# end of script
###############################################################################
1;
__END__