Remove old version

This commit is contained in:
Matteo Gheza 2022-02-24 22:14:44 +01:00
parent 6fba6f869f
commit 6592157922
119 changed files with 0 additions and 8892 deletions

View File

@ -1,106 +0,0 @@
<IfModule mod_php4.c>
php_flag display_errors Off
</IfModule>
<IfModule mod_php5.c>
php_flag display_errors Off
</IfModule>
<IfModule mod_php7.c>
php_flag display_errors Off
</IfModule>
<IfModule mod_autoindex.c>
Options -Indexes
</IfModule>
<IfModule mod_headers.c>
Header unset X-Powered-By
Header unset X-Pingback
Header unset SERVER
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_METHOD} ^(TRACE|DELETE|TRACK) [NC]
RewriteRule ^(.*)$ - [F,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* error_page.php?error=404 [L]
</IfModule>
<FilesMatch "(config|config.old|config-sample|core|ui)\.php">
Order Deny,Allow
Deny from all
</FilesMatch>
<FilesMatch "\.log$">
Order Allow,Deny
Deny from all
</FilesMatch>
<FilesMatch "^\.ht">
Order Allow,Deny
Deny from all
</FilesMatch>
<IfModule mod_mime.c>
# From https://htaccessbook.com/useful-htaccess-rules/
# JAVASCRIPT
AddType application/javascript js jsonp
AddType application/json json
<FilesMatch "manifest.webmanifest">
AddType application/manifest+json webmanifest
</FilesMatch>
# FONTS
AddType font/opentype otf
AddType application/font-woff woff
AddType application/x-font-woff woff
AddType application/vnd.ms-fontobject eot
AddType application/x-font-ttf ttc ttf
AddType image/svg+xml svg svgz
AddType application/wasm wasm.gz wasm
AddEncoding gzip gz
# AUDIO
AddType audio/mp4 m4a f4a f4b
AddType audio/ogg oga ogg
# VIDEO
AddType video/mp4 mp4 m4v f4v f4p
AddType video/ogg ogv
AddType video/webm webm
AddType video/x-flv flv
# OTHERS
AddType application/octet-stream safariextz
AddType application/x-chrome-extension crx
AddType application/x-opera-extension oex
AddType application/x-shockwave-flash swf
AddType application/x-web-app-manifest+json webapp
AddType application/x-xpinstall xpi
AddType application/xml atom rdf rss xml
AddType application/vnd.openxmlformats .docx .pptx .xlsx .xltx . xltm .dotx .potx .ppsx
AddType text/cache-manifest appcache manifest
AddType text/vtt vtt
AddType text/x-component htc
AddType text/x-vcard vcf
AddType image/webp webp
AddType image/x-icon ico
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(js|css|woff|woff2|ttf|eot)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\.(jpe?g|png|gif|swf|flv|pdf|svg|ico)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
</IfModule>
ServerSignature Off

View File

@ -1,277 +0,0 @@
<?php
define('REQUEST_USING_API', true);
require 'core.php';
use Spatie\ArrayToXml\ArrayToXml;
use Brick\PhoneNumber\PhoneNumber;
use Brick\PhoneNumber\PhoneNumberFormat;
use Brick\PhoneNumber\PhoneNumberParseException;
$user_info = [];
$dispatcher = FastRoute\simpleDispatcher(
function (FastRoute\RouteCollector $r) {
$r->addRoute(
'GET', '/healthcheck', function ($vars) {
return ["state" => "SUCCESS", "description" => ""];
}
);
$r->addRoute(
['GET', 'POST'], '/requestDebug', function ($vars) {
return ["get" => $_GET, "post" => $_POST, "server" => $_SERVER];
}
);
$r->addRoute(
'POST', '/login', function ($vars) {
global $tools, $db, $user;
try {
$user->auth->loginWithUsername($_POST['username'], $_POST['password']);
$apiKey = $tools->createKey();
$db->insert(
DB_PREFIX."_api_keys",
["apikey" => $apiKey, "user" => $user->auth->getUserId(), "permissions" => "all"]
);
return ["status" => "ok", "apiKey" => $apiKey];
}
catch (\Delight\Auth\UnknownUsernameException $e) {
http_response_code(401);
return ["status" => "error", "message" => "Username unknown"];
}
catch (\Delight\Auth\AmbiguousUsernameException $e) {
http_response_code(401);
return ["status" => "error", "message" => "Ambiguous Username"];
}
catch (\Delight\Auth\InvalidPasswordException $e) {
http_response_code(401);
return ["status" => "error", "message" => "Wrong password"];
}
catch (\Delight\Auth\EmailNotVerifiedException $e) {
http_response_code(401);
return ["status" => "error", "message" => "Email not verified"];
}
catch (\Delight\Auth\TooManyRequestsException $e) {
http_response_code(429);
return ["status" => "error", "message" => "Too many requests"];
}
}
);
$r->addRoute(
'GET', '/users', function ($vars) {
requireToken();
global $db;
$users = $db->select("SELECT * FROM `".DB_PREFIX."_users`");
$users_profiles = $db->select("SELECT * FROM `".DB_PREFIX."_profiles`");
foreach ($users_profiles as $key=>$value){
if(is_null($users_profiles[$key]["name"])) {
$users_profiles[$key]["name"] = $users[$key]["username"];
}
$users_profiles[$key]["email"] = $users[$key]["email"];
}
return $users_profiles;
}
);
$r->addRoute(
'GET', '/user', function ($vars) {
requireToken();
global $db, $user_info;
$users = $db->select("SELECT * FROM `".DB_PREFIX."_users` WHERE id = :id", ["id" => $user_info["id"]])[0];
$users_profiles = $db->select("SELECT * FROM `".DB_PREFIX."_profiles` WHERE id = :id", ["id" => $user_info["id"]])[0];
if(is_null($users_profiles["name"])) {
$users_profiles["name"] = $users["username"];
}
$users_profiles["email"] = $users["email"];
return $users_profiles;
}
);
$r->addRoute(
'GET', '/user/{id:\d+}', function ($vars) {
requireToken();
global $db;
$users = $db->select("SELECT * FROM `".DB_PREFIX."_users` WHERE id = :id", ["id" => $vars["id"]])[0];
$users_profiles = $db->select("SELECT * FROM `".DB_PREFIX."_profiles` WHERE id = :id", ["id" => $vars["id"]])[0];
if(is_null($users_profiles["name"])) {
$users_profiles["name"] = $users["username"];
}
$users_profiles["email"] = $users["email"];
return $users_profiles;
}
);
$r->addRoute(
'POST', '/user', function ($vars) {
requireToken();
global $user, $user_info;
$chief = isset($_POST["chief"]) ? $_POST["chief"]==1 : false;
$driver = isset($_POST["driver"]) ? $_POST["driver"]==1 : false;
$hidden = isset($_POST["hidden"]) ? $_POST["hidden"]==1 : false;
$disabled = isset($_POST["disabled"]) ? $_POST["disabled"]==1 : false;
if(isset($_POST["mail"], $_POST["name"], $_POST["username"], $_POST["password"], $_POST["phone_number"], $_POST["birthday"])) {
try {
$phone_number = PhoneNumber::parse($_POST["phone_number"]);
if (!$phone_number->isValidNumber()) {
return ["status" => "error", "message" => "Bad phone number"];
} else {
$phone_number = $phone_number->format(PhoneNumberFormat::E164);
}
} catch (PhoneNumberParseException $e) {
return ["status" => "error", "message" => "Bad phone number"];
}
try{
$userId = $user->add_user($_POST["mail"], $_POST["name"], $_POST["username"], $_POST["password"], $phone_number, $_POST["birthday"], $chief, $driver, $hidden, $disabled, $user_info["id"]);
} catch (\Delight\Auth\InvalidEmailException $e) {
return ["status" => "error", "message" => "Invalid email address"];
} catch (\Delight\Auth\InvalidPasswordException $e) {
return ["status" => "error", "message" => "Invalid password"];
} catch (\Delight\Auth\UserAlreadyExistsException $e) {
return ["status" => "error", "message" => "User already exists"];
}
if($userId) {
return ["userId" => $userId];
} else {
return ["status" => "error", "message" => "Unknown error"];
}
} else {
return ["status" => "error", "message" => "User info required"];
}
}
);
$r->addRoute(
'GET', '/availability', function ($vars) {
requireToken();
global $db, $user_info;
return $db->select("SELECT * FROM `".DB_PREFIX."_profiles` WHERE id = :id", ["id" => $user_info["id"]])[0]["available"];
}
);
$r->addRoute(
'GET', '/availability/{id:\d+}', function ($vars) {
requireToken();
global $db;
return $db->select("SELECT * FROM `".DB_PREFIX."_profiles` WHERE id = :id", ["id" => $vars["id"]])[0]["available"];
}
);
$r->addRoute(
'GET', '/changeAvailability/{available:\d+}', function ($vars) {
requireToken();
global $user, $db, $user_info;
$vars["available"] = (int) $vars["available"];
if($vars["available"] !== 0 && $vars["available"] !== 1) {
return ["status" => "error", "message" => "Availability code not allowed"];
}
$log_message = $vars["available"] ? "Status changed to 'available'" : "Status changed to 'not available'";
$db->select("UPDATE `".DB_PREFIX."_profiles` SET `available` = :available WHERE `id` = :id", ["id" => $user_info["id"], "available" => $vars["available"]]);
$user->log($log_message);
}
);
$r->addRoute(
'GET', '/changeAvailability/{id:\d+}/{available:\d+}', function ($vars) {
requireToken();
global $user, $db, $user_info;
$vars["available"] = (int) $vars["available"];
if($vars["available"] !== 0 && $vars["available"] !== 1) {
return ["status" => "error", "message" => "Availability code not allowed"];
}
$log_message = $vars["available"] ? "Status changed to 'available'" : "Status changed to 'not available'";
$db->select("UPDATE `".DB_PREFIX."_profiles` SET `available` = :available WHERE `id` = :id", ["id" => $vars["id"], "available" => $vars["available"]]);
$user->log($log_message, $vars["id"], $user_info["id"]);
}
);
}
);
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
$uri = str_replace($_SERVER['SCRIPT_NAME'], "", $uri);
$uri = str_replace("///", "/", $uri);
$uri = str_replace("//", "/", $uri);
$uri = "/" . trim($uri, "/");
// Strip query string (?foo=bar) and decode URI
if (false !== $pos = strpos($uri, '?')) {
$uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);
// Get response format
if (isset($_GET["xml"])) {
$responseFormat = "xml";
$responseFormatType = "application/xml";
} else if (isset($_GET["json"])) {
$responseFormat = "json";
$responseFormatType = "application/json";
} else if (false !== strpos($uri, 'xml')) {
$responseFormat = "xml";
$responseFormatType = "application/xml";
$uri = str_replace(".xml", "", $uri);
} else if (false !== strpos($uri, 'json')) {
$responseFormat = "json";
$responseFormatType = "application/json";
$uri = str_replace(".json", "", $uri);
} else {
$responseFormat = "json";
$responseFormatType = "application/json";
}
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
header("Access-Control-Allow-Methods: *");
header("Access-Control-Max-Age: *");
header("Content-type: ".$responseFormatType);
init_class(false, false); //initialize classes after Content-type header
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
function responseApi($content, $status_code=200)
{
global $responseFormat;
if($status_code !== 200) {
http_response_code($status_code);
}
if($responseFormat == "json") {
echo(json_encode($content));
} else {
echo(ArrayToXml::convert($content));
}
}
function validToken()
{
global $db, $user_info;
$token = isset($_REQUEST['apiKey']) ? $_REQUEST['apiKey'] : (isset($_REQUEST['apikey']) ? $_REQUEST['apikey'] : (isset($_SERVER['HTTP_APIKEY']) ? $_SERVER['HTTP_APIKEY'] : false));
if($token == false) {
return false;
}
if(!empty($api_key_row = $db->select("SELECT * FROM `".DB_PREFIX."_api_keys` WHERE apikey = :apikey", ["apikey" => $token]))) {
$user_info["id"] = $db->select("SELECT * FROM `".DB_PREFIX."_profiles` WHERE id = :id", ["id" => $api_key_row[0]["user"]])[0]["id"];
return true;
} else {
return false;
}
}
function requireToken()
{
if(!validToken()) {
responseApi(["status" => "error", "message" => "Access Denied"], 401);
exit();
}
}
if($_SERVER['REQUEST_METHOD'] == "OPTIONS"){
exit();
}
switch ($routeInfo[0]) {
case FastRoute\Dispatcher::NOT_FOUND:
http_response_code(404);
responseApi(["status" => "error", "message" => "Route not found"]);
break;
case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
$allowedMethods = $routeInfo[1];
http_response_code(405);
responseApi(["status" => "error", "message" => "Method not allowed", "usedMethod" => $_SERVER['REQUEST_METHOD']]);
break;
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$vars = $routeInfo[2];
responseApi($handler($vars));
bdump($vars);
break;
}

View File

@ -1,4 +0,0 @@
<?php
require("../core.php");
init_class();
$tools->rickroll();

View File

@ -1,26 +0,0 @@
<?php
// ** Database settings ** //
/* The name of the database for Allerta-vvf */
define('DB_NAME', '@@db@@');
/* Database username */
define('DB_USER', '@@user@@');
/* Database password */
define('DB_PASSWORD', '@@password@@');
/* Database hostname */
define('DB_HOST', '@@host@@');
/* Database hostname */
define('DB_PREFIX', '@@prefix@@');
/* Telegram bot options */
define('BOT_TELEGRAM_API_KEY', '');
define('BOT_TELEGRAM_USERNAME', '');
/* Sentry options */
define('SENTRY_CSP_REPORT_URI', '');
define('SENTRY_ENABLED', false);
define('SENTRY_DSN', '');
define('SENTRY_ENV', 'prod');

View File

@ -1,17 +0,0 @@
<?php
header("Content-type: application/json");
try {
$start_time = microtime(true);
include "core.php";
init_class(false, false);
$exec_time = microtime(true) - $start_time;
$server_side = ["status" => "ok", "status_msg" => null, "exec_time" => $exec_time, "user_info" => $user->info()];
} catch (Exception $e) {
$server_side = ["status" => "error", "status_msg" => $e];
}
try {
$client_side = ["status" => "ok", "status_msg" => null, "ip" => $tools->get_ip()];
} catch (Exception $e) {
$server_side = ["status" => "error", "status_msg" => $e];
}
echo(json_encode(["client" => $client_side, "server" => $server_side]));

File diff suppressed because it is too large Load Diff

View File

@ -1,175 +0,0 @@
<?php
require_once 'core.php';
init_class(false);
error_reporting(-1);
list($cronJobDay, $cronJobTime) = explode(";", get_option("cron_job_time"));
$execDateTime = [
"day" => date("d"),
"month" => date("m"),
"year" => date("Y"),
"hour" => date("H"),
"minutes" => date("i")
];
$cronJobDateTime = [
"day" => $cronJobDay,
"month" => date("m"),
"year" => date("Y"),
"hour" => explode(":", $cronJobTime)[0],
"minutes" => explode(":", $cronJobTime)[1]
];
$start = get_option("cron_job_enabled") && ((isset($_POST['cron']) && $_POST['cron'] == "cron_job-".get_option("cron_job_code")) || (isset($_SERVER['HTTP_CRON']) && $_SERVER['HTTP_CRON'] == "cron_job-".get_option("cron_job_code")));
$start_reset = ( $execDateTime["day"] == $cronJobDateTime["day"] &&
$execDateTime["day"] == $cronJobDateTime["day"] &&
$execDateTime["month"] == $cronJobDateTime["month"] &&
$execDateTime["year"] == $cronJobDateTime["year"] &&
$execDateTime["hour"] == $cronJobDateTime["hour"] &&
$execDateTime["minutes"] - $cronJobDateTime["minutes"] < 5 );
$action = "Availability Minutes ";
if($start) {
if($start_reset) {
$action .= "reset and ";
$profiles = $db->select("SELECT * FROM `".DB_PREFIX."_profiles` WHERE `available` = 1 ");
if(count($profiles) > 0) {
$list = [];
foreach($profiles as $profile){
$list[] = [$profile["id"] => $profile["availability_minutes"]];
}
$db->insert(
DB_PREFIX."_minutes",
["month" => $execDateTime["month"], "year" => $execDateTime["year"], "list"=>json_encode($list)]
);
$db->exec("UPDATE `".DB_PREFIX."_profiles` SET `availability_minutes` = 0");
}
}
$action .= "update";
$profiles = $db->select("SELECT * FROM `".DB_PREFIX."_profiles` WHERE `available` = 1");
if(count($profiles) > 0) {
$output = [];
$output[] = $profiles;
$output_status = "ok";
$queries = [];
foreach ($profiles as $row) {
$value = (int)$row["availability_minutes"]+5;
$id = $row["id"];
$increment[$id] = $value;
$count = $db->update(
DB_PREFIX."_profiles",
["availability_minutes" => $value],
["id" => $id]
);
$tmp = $id . " - " . $value . " ";
$tmp .= $count == 1 ? "success" : "fail";
$queries[] = $tmp;
}
$output[] = $queries;
} else {
$output = ["profiles array empty"];
$output_status = "ok";
}
$result = $db->select("SELECT * FROM `".DB_PREFIX."_schedules`;");
$schedules_check = [];
$schedules_users = [];
$schedules_check["schedules"] = [];
$schedules_check["users"] = [];
if(!empty($result)){
foreach ($result as $key => $value) {
$result[$key]["schedules"] = json_decode($result[$key]["schedules"]);
}
$schedules_check["table"] = $result;
foreach ($result as $key => $row) {
$last_exec = $row["last_exec"];
$last_exec = [
"day" => (int) explode(";",$row["last_exec"])[0],
"hour" => (int) explode(":",explode(";",$row["last_exec"])[1])[0],
"minutes" => (int) explode(":",$row["last_exec"])[1]
];
$id = $row["id"];
$user_id = $row["user"];
$selected_holidays = json_decode($row["holidays"]);
$selected_holidays_dates = [];
foreach ($selected_holidays as $holiday){
$selected_holidays_dates[] = $user->holidays->getHoliday($holiday)->format('Y-m-d');
}
foreach ($row["schedules"] as $key => $value) {
$schedule = [
"day" => (int) $value[0]+1,
"hour" => (int) explode(":",$value[1])[0],
"minutes" => (int) explode(":",$value[1])[1]
];
$now = [
"day" => (int) date("N"),
"hour" => (int) date("H"),
"minutes" => (int) date("i")
];
if(
$schedule["day"] == $now["day"] &&
$schedule["hour"] == $now["hour"] &&
$schedule["minutes"] <= $now["minutes"] &&
$now["minutes"] - $schedule["minutes"] <= 30
){
if(!in_array($user_id,$schedules_users)) $schedules_users[] = $user_id;
if($schedule["hour"] == $last_exec["hour"] ? $schedule["minutes"] !== $last_exec["minutes"] : true && !in_array(date('Y-m-d'), $selected_holidays_dates)){
$last_exec_new = $schedule["day"].";".sprintf("%02d", $schedule["hour"]).":".sprintf("%02d", $schedule["minutes"]);
$db->update(
DB_PREFIX."_schedules",
["last_exec" => $last_exec_new],
["id" => $id]
);
$db->update(
DB_PREFIX."_profiles",
["available" => '1', "availability_last_change" => "cron"],
["id" => $user_id]
);
$schedules_check["schedules"][] = [
"schedule" => $schedule,
"now" => $now,
"exec" => $last_exec,
"last_exec_new" => $last_exec_new,
];
}
}
}
}
$schedules_check["users"] = $schedules_users;
$profiles = $db->select("SELECT id FROM `".DB_PREFIX."_profiles`");
foreach ($profiles as $profile) {
if(!in_array($profile["id"],$schedules_users)){
$db->update(
DB_PREFIX."_profiles",
["available" => 0],
["availability_last_change" => "cron", "id" => $profile["id"]]
);
}
}
}
} else {
require("error_page.php");
show_error_page(405, "Method not allowed", "Allowed methods: POST");
exit();
}
header('Content-Type: application/json');
echo(json_encode(
[
"start" => $start,
"start_reset" => $start_reset,
"execDateTime" => $execDateTime,
"cronJobDateTime" => $cronJobDateTime,
"action" => $action,
"schedules_check" => $schedules_check,
"output" => [
"status" => $output_status,
"message" => $output
]
]
));

View File

@ -1,11 +0,0 @@
{
"baseUrl": "http://127.0.0.1:8080/",
"projectId": "4ty9gy",
"env": {
"DB_PASSWORD": "password"
},
"experimentalStudio": true,
"chromeWebSecurity": false,
"defaultCommandTimeout": 40000,
"requestTimeout": 60000
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1 +0,0 @@
[{"place_id":257830288,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"relation","osm_id":44882,"boundingbox":["45.2042549","46.3548531","9.8362928","10.842675"],"lat":"45.77958045","lon":"10.4258729694612","display_name":"Brescia, Lombardia, Italia","class":"boundary","type":"administrative","importance":0.7354640205264362,"icon":"https://nominatim.openstreetmap.org/ui/mapicons//poi_boundary_administrative.p.20.png"},{"place_id":257390216,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"relation","osm_id":45144,"boundingbox":["45.4807171","45.5899752","10.1470684","10.3002186"],"lat":"45.5398022","lon":"10.2200214","display_name":"Brescia, Lombardia, Italia","class":"boundary","type":"administrative","importance":0.7271074461208031,"icon":"https://nominatim.openstreetmap.org/ui/mapicons//poi_boundary_administrative.p.20.png"},{"place_id":54063101,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"node","osm_id":4553822557,"boundingbox":["45.5273342","45.5373342","10.2078404","10.2178404"],"lat":"45.5323342","lon":"10.2128404","display_name":"Brescia, Piazzale Stazione, Centro Storico Sud, Zona Centro, Brescia, Lombardia, 25122, Italia","class":"railway","type":"station","importance":0.48614554653236075,"icon":"https://nominatim.openstreetmap.org/ui/mapicons//transport_train_station2.p.20.png"},{"place_id":23143065,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"node","osm_id":2409443276,"boundingbox":["44.4687976","44.4688976","8.6048681","8.6049681"],"lat":"44.4688476","lon":"8.6049181","display_name":"Brescia, Urbe, Savona, Liguria, 17048, Italia","class":"place","type":"isolated_dwelling","importance":0.29999999999999993},{"place_id":163311426,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"way","osm_id":307938666,"boundingbox":["-29.9019023","-29.9008417","-71.2670192","-71.2669167"],"lat":"-29.9014479","lon":"-71.2669709","display_name":"Brescia, Condominio Capri, La Serena, Provincia de Elqui, Coquimbo Region, 17000000, Cile","class":"highway","type":"residential","importance":0.19999999999999998}]

View File

@ -1 +0,0 @@
[{"place_id":258244980,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"relation","osm_id":44915,"boundingbox":["45.3867381","45.5358482","9.0408867","9.2781103"],"lat":"45.4668","lon":"9.1905","display_name":"Milano, Lombardia, Italia","class":"boundary","type":"administrative","importance":0.8390652078701348,"icon":"https://nominatim.openstreetmap.org/ui/mapicons//poi_boundary_administrative.p.20.png"},{"place_id":258789516,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"relation","osm_id":344499,"boundingbox":["41.0766967","41.1206314","-6.6489375","-6.566364"],"lat":"41.0923837","lon":"-6.5984217","display_name":"El Milano, Salamanca, Castiglia e León, Spagna","class":"boundary","type":"administrative","importance":0.6058586680411897,"icon":"https://nominatim.openstreetmap.org/ui/mapicons//poi_boundary_administrative.p.20.png"},{"place_id":258556780,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"relation","osm_id":44881,"boundingbox":["45.1614258","45.6434829","8.7060961","9.551457"],"lat":"45.454211900000004","lon":"9.111350961779705","display_name":"Milano, Lombardia, Italia","class":"boundary","type":"administrative","importance":0.6027406455537151,"icon":"https://nominatim.openstreetmap.org/ui/mapicons//poi_boundary_administrative.p.20.png"},{"place_id":259530334,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"relation","osm_id":6605766,"boundingbox":["30.696897","30.718944","-96.881245","-96.841162"],"lat":"30.7106407","lon":"-96.864745","display_name":"Milano, Milam County, Texas, 76556, Stati Uniti d'America","class":"boundary","type":"administrative","importance":0.5332195319778348,"icon":"https://nominatim.openstreetmap.org/ui/mapicons//poi_boundary_administrative.p.20.png"},{"place_id":5770611,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"node","osm_id":650721553,"boundingbox":["42.7623859","42.8023859","12.5780599","12.6180599"],"lat":"42.7823859","lon":"12.5980599","display_name":"Milano, Spoleto, Perugia, Umbria, 06049, Italia","class":"place","type":"hamlet","importance":0.5316717311890431,"icon":"https://nominatim.openstreetmap.org/ui/mapicons//poi_place_village.p.20.png"}]

View File

@ -1,81 +0,0 @@
[{
"email": "user1@mail.local",
"name": "Kathy Jordan",
"username": "kathy.jordan",
"password": "4jpbly8g6a",
"birthday": "08/08/1995",
"chief": false,
"driver": false
}, {
"email": "user2@mail.local",
"name": "Natalie Jordan",
"username": "natalie.jordan",
"password": "kf343di74s",
"birthday": "04/05/2011",
"chief": true,
"driver": false
}, {
"email": "user3@mail.local",
"name": "Keith Li",
"username": "keith.li",
"password": "3ojvgk4fpv",
"birthday": "11/04/2019",
"chief": true,
"driver": true
}, {
"email": "user4@mail.local",
"name": "Pellegrino Scotto",
"username": "pellegrino.scotto",
"password": "e0ou92taw3",
"birthday": "20/10/1983",
"chief": true,
"driver": false
}, {
"email": "user5@mail.local",
"name": "William Torres",
"username": "william.torres",
"password": "0fso8sxxe0",
"birthday": "16/07/2000",
"chief": false,
"driver": true
}, {
"email": "user6@mail.local",
"name": "Napoleone Tomasetti",
"username": "napoleone.tomasetti",
"password": "so7ykv8a7g",
"birthday": "27/12/1978",
"chief": true,
"driver": true
}, {
"email": "user7@mail.local",
"name": "Gelsomina Murray",
"username": "gelsomina.murray",
"password": "x1js0s6zao",
"birthday": "22/10/1994",
"chief": true,
"driver": true
}, {
"email": "user8@mail.local",
"name": "Letizia Petrucelli",
"username": "letizia.petrucelli",
"password": "k1hsbdt3cv",
"birthday": "24/04/1981",
"chief": true,
"driver": false
}, {
"email": "user9@mail.local",
"name": "Giampaolo Surian",
"username": "giampaolo.surian",
"password": "et52m65s4g",
"birthday": "10/06/1972",
"chief": true,
"driver": true
}, {
"email": "user10@mail.local",
"name": "Cassandra Jensen",
"username": "cassandra.jensen",
"password": "9h3fb37ccw",
"birthday": "28/10/1985",
"chief": true,
"driver": false
}]

View File

@ -1,116 +0,0 @@
describe("Installation", () => {
before(() => {
cy.exec("rm config.old.php", {failOnNonZeroExit: false});
cy.exec("mv config.php config.old.php", {failOnNonZeroExit: false});
cy.visit("/");
cy.get(".button").click();
})
beforeEach(() => {
cy.setCookie("forceLanguage", "en");
})
it('Write wrong DB pwd and user', function () {
cy.get("input[name='dbname']")
.clear()
.type("allerta_db_"+Date.now())
cy.get("input[name='uname']")
.clear()
.type("root_wrongpwd_"+Date.now())
cy.get("input[name='pwd']")
.clear()
.should('have.value', '')
cy.get(".button").click();
cy.contains("Error establishing a database connection");
cy.visit("/");
cy.get(".button").click();
})
it('Write correct DB pwd and user', function () {
cy.get("input[name='dbname']")
.clear()
.type("allerta_db_"+Date.now())
cy.get("input[name='uname']")
.clear()
.type("root")
.should('have.value', 'root')
cy.get("input[name='pwd']")
.clear()
.type(Cypress.env("DB_PASSWORD"))
.should('have.value', Cypress.env("DB_PASSWORD"))
cy.get(".button").click();
cy.contains("Great job, man!");
cy.get(".button").click();
})
it('Finish installation', function () {
cy.get("input[name='user_name']")
.clear()
.type("admin")
.should('have.value', 'admin')
cy.get("input[name='admin_password']")
.clear()
.type("password")
.should('have.value', 'password')
cy.get("#pass-strength-result")
.should('have.text', 'Very weak')
.should('have.class', 'short')
cy.get("input[name='admin_password']")
.clear()
.type("passsword")
.should('have.value', 'passsword')
cy.get("#pass-strength-result")
.should('have.text', 'Weak')
.should('have.class', 'bad')
cy.get("input[name='admin_password']")
.clear()
.type("Tr0ub4dour&3")
.should('have.value', 'Tr0ub4dour&3')
cy.get("#pass-strength-result")
.should('have.text', 'Good')
.should('have.class', 'good')
cy.get("input[name='admin_password']")
.clear()
.type("#Tr0ub4dour&3#")
.should('have.value', '#Tr0ub4dour&3#')
cy.get("#pass-strength-result")
.should('have.text', 'Strong')
.should('have.class', 'strong')
cy.get("input[name='admin_password']")
.clear()
.type("correcthorsebatterystaple")
.should('have.value', 'correcthorsebatterystaple')
cy.get("#pass-strength-result")
.should('have.text', 'Very strong')
.should('have.class', 'strong')
cy.get("input[name='admin_visible']").check()
cy.get("input[name='admin_email']")
.clear()
.type("admin_email@mail.local")
.should('have.value', 'admin_email@mail.local')
cy.get("input[name='owner']")
.clear()
.type("owner")
.should('have.value', 'owner')
cy.get(".button").click();
cy.contains("Great job, man!");
cy.exec("touch install/runInstall.php", {failOnNonZeroExit: false});
cy.get(".login").click();
cy.contains("Login");
})
});

View File

@ -1,20 +0,0 @@
describe("Login and logout", () => {
it('Login', function () {
cy.login()
cy.contains("Logs")
cy.contains("Logs").click()
cy.wait('@ajax_log')
cy.get("#list").contains("Login")
})
it('Logout', function () {
cy.login()
cy.visit("/logout.php")
cy.contains("Login")
cy.login()
cy.contains("Logs")
cy.contains("Logs").click()
cy.wait('@ajax_log')
cy.get("#list").contains("Logout")
})
});

View File

@ -1,28 +0,0 @@
describe("Availability", () => {
beforeEach(() => {
cy.login()
})
it('Change availability to available', function () {
cy.contains('Activate').click()
cy.wait("@ajax_change_availability")
cy.get(".toast-message").should('be.visible').contains('Thanks, admin, you have given your availability in case of alert.');
cy.wait("@ajax_list")
cy.get(".fa-check").should('be.visible')
cy.visit("/log.php")
cy.wait("@ajax_log")
cy.contains("Status changed to 'available'")
cy.visit("/")
})
it('Change availability to not available', function () {
cy.contains('Deactivate').click()
cy.wait("@ajax_change_availability")
cy.get(".toast-message").should('be.visible').contains('Thanks, admin, you have removed your availability in case of alert.');
cy.wait("@ajax_list")
cy.get(".fa-times").should('be.visible')
cy.visit("/log.php")
cy.wait("@ajax_log")
cy.contains("Status changed to 'not available'")
cy.visit("/")
})
});

View File

@ -1,92 +0,0 @@
describe("User management", () => {
before(() => {
cy.login()
cy.fixture('users')
.as('users');
})
it('Create users', () => {
cy.get('@users')
.then((users) => {
cy.getApiKey().then((apiKey) => {
var i = 1
var phone_number = "+1-800-555-0199";
users.forEach(user => {
console.log("User '"+user.name+"' number "+i);
if(i == 1){
console.log("Adding user via gui...");
name = user.name
console.log(user)
cy.wait(1000)
cy.contains("Add user").click()
cy.get("input[name='mail']")
.clear()
.type(user.email)
.should('have.value', user.email)
cy.get("input[name='name']")
.clear()
.type(user.name)
.should('have.value', user.name)
cy.get("input[name='username']")
.clear()
.type(user.username)
.should('have.value', user.username)
cy.get("input[name='password']")
.clear()
.type(user.password)
.should('have.value', user.password)
cy.get("input[name='phone_number']")
.clear()
.type(phone_number)
.should('have.value', phone_number)
cy.get("input[name='birthday']")
.clear()
.type(user.birthday)
.should('have.value', user.birthday)
if(user.chief){
cy.get("input[name='chief']")
.check({force: true})
}
if(user.driver){
cy.get("input[name='driver']")
.check({force: true})
}
cy.contains("Submit").click()
cy.wait('@ajax_list')
cy.contains(user.name)
cy.visit("/log.php")
cy.wait('@ajax_log')
cy.contains("User added")
cy.contains(user.name)
cy.visit("/")
} else {
console.log("Adding user via api...");
cy.request({ method: 'POST', url: '/api.php/user', form: true,
body: {
apiKey: apiKey,
mail: user.email,
name: user.name,
username: user.username,
password: user.password,
phone_number: phone_number,
birthday: user.birthday,
chief: user.chief | 0,
driver: user.driver | 0,
hidden: 0,
disabled: 0
}})
.then((response) => {
console.log(response.body)
expect(response.status).to.eq(200)
expect(response.body).to.have.property('userId')
cy.visit("/log.php")
cy.wait('@ajax_log')
cy.contains("User added")
cy.contains(user.name)
})
}
i+=1;
})
});
})
});
})

View File

@ -1,110 +0,0 @@
describe("Service management", () => {
beforeEach(() => {
cy.login();
})
it('Add Service with new type', function () {
cy.get('tr:has(> td:has(> [data-user="11"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="4"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="9"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="7"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="2"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="6"])) > :nth-child(6)').should('contain', '0');
cy.visit("/edit_service.php?add", {
onBeforeLoad(win) {
cy.stub(win, 'prompt').returns('test');
}
});
cy.get('#date-picker').clear();
cy.get('#date-picker').type('07/12/2020');
cy.window().then(win => win.$('.datepicker').remove());
cy.get('#progressivo').clear();
cy.get('#progressivo').type('1234/5');
cy.get('#timePicker1').clear();
cy.get('#timePicker1').type('10:10');
cy.get('#timePicker2').clear();
cy.get('#timePicker2').type('23:59');
cy.get('.chief-11').check();
cy.get('.drivers-7').check();
cy.get('.drivers-6').check();
cy.get('.crew-2').check();
cy.get('.crew-4').check();
cy.get('.crew-9').check();
cy.get('#addr').clear();
cy.get('#addr').type('brescia');
cy.get('#search_button').click();
cy.get('#search').click();
cy.get('.results-list > :nth-child(1) > a').click();
cy.get('#notes').click();
cy.get('#types').select('add_new');
cy.wait('@ajax_add_type');
cy.get('[type="submit"]').click();
cy.wait('@ajax_services');
cy.contains("2020-07-12");
cy.contains("1234/5");
cy.visit("/log.php");
cy.wait('@ajax_log');
cy.contains("Service added");
cy.visit("/list.php");
cy.wait('@ajax_list');
cy.get('tr:has(> td:has(> [data-user="11"])) > :nth-child(6)').should('contain', '1');
cy.get('tr:has(> td:has(> [data-user="4"])) > :nth-child(6)').should('contain', '1');
cy.get('tr:has(> td:has(> [data-user="9"])) > :nth-child(6)').should('contain', '1');
cy.get('tr:has(> td:has(> [data-user="7"])) > :nth-child(6)').should('contain', '1');
cy.get('tr:has(> td:has(> [data-user="2"])) > :nth-child(6)').should('contain', '1');
cy.get('tr:has(> td:has(> [data-user="6"])) > :nth-child(6)').should('contain', '1');
});
it('Edit service', function() {
cy.visit("/services.php");
cy.wait('@ajax_services');
cy.get('.dtr-details a[data-action="edit"]').first().click();
cy.get('#progressivo').clear();
cy.get('#progressivo').type('4321/5');
cy.get('.chief-11').uncheck();
cy.get('.chief-8').check();
cy.get('.crew-4').uncheck();
cy.get('.crew-9').uncheck();
cy.get('.crew-3').check();
cy.get('.crew-5').check();
cy.get('#addr').clear();
cy.get('#addr').type('milano');
cy.get('#search_button').click();
cy.get('.results-list > :nth-child(1) > a').click();
cy.get('[type="submit"]').click();
cy.wait('@ajax_services');
cy.contains("2020-07-12");
cy.contains("4321/5");
cy.visit("/log.php");
cy.wait('@ajax_log');
cy.contains("Service edited");
cy.visit("/list.php");
cy.wait('@ajax_list');
cy.get('tr:has(> td:has(> [data-user="11"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="8"])) > :nth-child(6)').should('contain', '1');
cy.get('tr:has(> td:has(> [data-user="4"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="9"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="3"])) > :nth-child(6)').should('contain', '1');
cy.get('tr:has(> td:has(> [data-user="5"])) > :nth-child(6)').should('contain', '1');
});
it('Delete Service', function() {
cy.visit("/services.php");
cy.wait('@ajax_services');
cy.get('.dtr-details a[data-action="delete"]').first().click();
cy.get('#remove').click();
cy.wait('@ajax_services');
cy.visit("/log.php");
cy.wait('@ajax_log');
cy.contains("Service removed");
cy.visit("/list.php");
cy.wait('@ajax_list');
cy.get('tr:has(> td:has(> [data-user="8"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="3"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="5"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="7"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="2"])) > :nth-child(6)').should('contain', '0');
cy.get('tr:has(> td:has(> [data-user="6"])) > :nth-child(6)').should('contain', '0');
});
})

View File

@ -1,78 +0,0 @@
describe("Training management", () => {
beforeEach(() => {
cy.login();
})
it('Add Training', function () {
cy.visit("/edit_training.php?add", {
onBeforeLoad(win) {
cy.stub(win, 'prompt').returns('test')
}
});
cy.get('#date-picker').clear();
cy.get('#date-picker').type('07/12/2020');
cy.window().then(win => win.$('.datepicker').remove());
cy.get('#name').clear();
cy.get('#name').type('Test Training');
cy.get('#timePicker1').clear();
cy.get('#timePicker1').type('10:10');
cy.get('#timePicker2').clear();
cy.get('#timePicker2').type('23:59');
cy.get('.chief-5').check();
cy.get('.crew-2').check();
cy.get('.crew-4').check();
cy.get('.crew-3').check();
cy.get('.crew-6').check();
cy.get('#addr').clear();
cy.get('#addr').type('brescia');
cy.get('#search_button').click();
cy.get('#search').click();
cy.get('.results-list > :nth-child(1) > a').click();
cy.get('[type="submit"]').click();
cy.wait('@ajax_trainings');
cy.contains("2020-07-12");
cy.contains("Test Training");
cy.visit("/log.php");
cy.wait('@ajax_log');
cy.contains("Training added");
cy.visit("/list.php");
cy.wait('@ajax_list');
});
it('Edit Training', function() {
cy.visit("/trainings.php");
cy.wait('@ajax_trainings');
cy.get('.dtr-details a[data-action="edit"]').first().click();
cy.get('#name').clear();
cy.get('#name').type('Training 1 test');
cy.get('.chief-5').uncheck();
cy.get('.chief-7').check();
cy.get('.crew-3').uncheck();
cy.get('.crew-6').uncheck();
cy.get('.crew-9').check();
cy.get('.crew-8').check();
cy.get('#addr').clear();
cy.get('#addr').type('milano');
cy.get('#search_button').click();
cy.get('.results-list > :nth-child(1) > a').click();
cy.get('[type="submit"]').click();
cy.wait('@ajax_trainings');
cy.contains("2020-07-12");
cy.contains("Training 1 test");
cy.visit("/log.php");
cy.wait('@ajax_log');
cy.contains("Training edited");
});
it('Delete Training', function() {
cy.visit("/trainings.php");
cy.wait('@ajax_trainings');
cy.get('.dtr-details a[data-action="delete"]').first().click();
cy.get('#remove').click();
cy.wait('@ajax_trainings');
cy.visit("/log.php");
cy.wait('@ajax_log');
cy.contains("Training removed");
});
})

View File

@ -1,47 +0,0 @@
Cypress.on('uncaught:exception', (err, runnable) => {
// for some reasons, the test fails without this in certain conditions...
return false
})
//TODO: login remember me and better language support
Cypress.Commands.add("login", (username="admin", password="correcthorsebatterystaple") => {
cy.setCookie("forceLanguage", "en");
cy.setCookie('disableServiceWorkerInstallation', '1');
cy.visit("/");
cy.get("input[name='name']")
.clear()
.type(username)
.should('have.value', username)
cy.get("input[name='password']")
.clear()
.type(password)
.should('have.value', password)
cy.get("input[name='login']").click()
})
Cypress.Commands.add("getApiKey", (username="admin", password="correcthorsebatterystaple") => {
cy.request({ method: 'POST', url: '/api.php/login', form: true, body: { username: username, password: password }})
.then((response) => {
expect(response.status).to.eq(200)
expect(response.body).to.have.property('apiKey')
console.log(response.body)
return response.body.apiKey
})
})
beforeEach(() => {
cy.intercept('https://nominatim.openstreetmap.org/search?format=json&limit=5&q=brescia', { fixture: 'nominatim_brescia.json' });
cy.intercept('https://nominatim.openstreetmap.org/search?format=json&limit=5&q=milano', { fixture: 'nominatim_milano.json' });
cy.intercept('https://a.tile.openstreetmap.org/*/*/*.png', { fixture: 'map_frame_A.png' });
cy.intercept('https://b.tile.openstreetmap.org/*/*/*.png', { fixture: 'map_frame_B.png' });
cy.intercept('https://c.tile.openstreetmap.org/*/*/*.png', { fixture: 'map_frame_C.png' });
cy.intercept(Cypress.config('baseUrl')+'resources/ajax/ajax_add_type.php**').as('ajax_add_type');
cy.intercept(Cypress.config('baseUrl')+'resources/ajax/ajax_change_availability.php**').as('ajax_change_availability');
cy.intercept(Cypress.config('baseUrl')+'resources/ajax/ajax_list.php**').as('ajax_list');
cy.intercept(Cypress.config('baseUrl')+'resources/ajax/ajax_log.php**').as('ajax_log');
cy.intercept(Cypress.config('baseUrl')+'resources/ajax/ajax_services.php**').as('ajax_services');
cy.intercept(Cypress.config('baseUrl')+'resources/ajax/ajax_trainings.php**').as('ajax_trainings');
});

View File

@ -1,14 +0,0 @@
<?php
require("core.php");
init_class();
if($user->authenticated()){
if($user->hasRole(Role::DEVELOPER)){
if(!isset($_REQUEST["op"]) || !isset($_REQUEST["id"])) $tools->rickroll();
$openHandler = new DebugBar\OpenHandler($debugbar);
$response = $openHandler->handle();
} else {
$tools->rickroll();
}
} else {
$tools->rickroll();
}

View File

@ -1 +0,0 @@
nothing (see this directory in file explorer or delete this file)

View File

@ -1,77 +0,0 @@
<?php
require_once 'ui.php';
function debug(){
echo("<pre>"); var_dump($_POST); echo("</pre>"); exit();
}
if($tools->validate_form("mod", "add")) {
if($tools->validate_form(['date', 'code', 'beginning', 'end', 'place', 'notes', 'type', 'token'])) {
if($_POST["token"] == $_SESSION['token']) {
bdump("adding service");
$place = $tools->checkPlaceParam($_POST["place"]);
$crud->add_service($_POST["date"], $_POST["code"], $_POST["beginning"], $_POST["end"], $_POST["chief"][0], $tools->extract_unique($_POST["drivers"]), $tools->extract_unique($_POST["crew"]), $place, $_POST["notes"], $_POST["type"], $tools->extract_unique([$_POST["chief"],$_POST["drivers"],$_POST["crew"]]), $user->name());
$tools->redirect("services.php");
} else {
debug(); //TODO: remove debug info
}
} else {
debug();
}
} elseif($tools->validate_form("mod", "edit")) {
if($tools->validate_form(['id', 'date', 'code', 'beginning', 'end', 'place', 'notes', 'type', 'token'])) {
if($_POST["token"] == $_SESSION['token']) {
bdump($_POST);
bdump("editing service");
$place = $tools->checkPlaceParam($_POST["place"]);
$crud->edit_service($_POST["id"], $_POST["date"], $_POST["code"], $_POST["beginning"], $_POST["end"], $_POST["chief"][0], $tools->extract_unique($_POST["drivers"]), $tools->extract_unique($_POST["crew"]), $place, $_POST["notes"], $_POST["type"], $tools->extract_unique([$_POST["chief"],$_POST["drivers"],$_POST["crew"]]), $user->name());
$tools->redirect("services.php");
} else {
debug();
}
} else {
debug();
}
} elseif($tools->validate_form("mod", "delete")) {
bdump("removing service");
if($tools->validate_form(['id', 'token'])) {
if($_POST["token"] == $_SESSION['token']) {
bdump("removing service");
$crud->remove_service($_POST["id"]);
$tools->redirect("services.php");
} else {
echo("1");
debug();
}
} else {
echo("2");
debug();
}
} else {
if(isset($_GET["add"])||isset($_GET["edit"])||isset($_GET["delete"])||isset($_GET["mod"])) {
$_SESSION["token"] = bin2hex(random_bytes(64));
}
$crew = $db->select("SELECT * FROM `".DB_PREFIX."_profiles` ORDER BY name ASC");
$types = $db->select("SELECT `name` FROM `".DB_PREFIX."_type` ORDER BY name ASC");
$modalità = (isset($_GET["add"])) ? "add" : ((isset($_GET["edit"])) ? "edit" : ((isset($_GET["delete"])) ? "delete" : "add"));
bdump($modalità, "modalità");
bdump($types, "types");
bdump($crew, "crew");
$id = "";
if(isset($_GET["id"])) {
$id = $_GET["id"];
bdump($crud->exists("services", $id));
$values = $db->select("SELECT * FROM `".DB_PREFIX."_services` WHERE `id` = :id", [":id" => $id])[0];
bdump($values);
} else {
$values = [];
}
if($modalità=="edit" || $modalità=="delete") {
if(empty($id)) {
echo("<pre>"); var_dump($_POST); echo("</pre>");
} elseif (!$crud->exists("services", $id)) {
echo("<pre>"); var_dump($_POST); echo("</pre>");
}
}
loadtemplate('edit_service.html', ['service' => ['id' => $id, 'token' => $_SESSION['token'], 'modalità' => $modalità, 'crew' => $crew, 'types' => $types], 'values' => $values, 'title' => t(ucfirst($modalità) . " service", false)]);
bdump($_SESSION['token'], "token");
}
?>

View File

@ -1,73 +0,0 @@
<?php
require_once 'ui.php';
function debug(){
echo("<pre>"); var_dump($_POST); echo("</pre>"); exit();
}
if($tools->validate_form("mod", "add")) {
if($tools->validate_form(['date', 'name', 'start_time', 'end_time', 'place', 'notes', 'token'])) {
if($_POST["token"] == $_SESSION['token']) {
bdump("adding training");
$place = $tools->checkPlaceParam($_POST["place"]);
$crud->add_training($_POST["date"], $_POST["name"], $_POST["start_time"], $_POST["end_time"], $_POST["chief"][0], $tools->extract_unique($_POST["crew"]), $place, $_POST["notes"], $tools->extract_unique([$_POST["chief"],$_POST["crew"]]), $user->name());
$tools->redirect("trainings.php");
} else {
debug(); //TODO: remove debug info
}
} else {
debug();
}
} elseif($tools->validate_form("mod", "edit")) {
if($tools->validate_form(['id', 'date', 'name', 'start_time', 'end_time', 'chief', 'place', 'notes', 'token'])) {
if($_POST["token"] == $_SESSION['token']) {
bdump($_POST);
bdump("editing training");
$place = $tools->checkPlaceParam($_POST["place"]);
$crud->edit_training($_POST["id"], $_POST["date"], $_POST["name"], $_POST["start_time"], $_POST["end_time"], $_POST["chief"][0], $tools->extract_unique($_POST["crew"]), $place, $_POST["notes"], $tools->extract_unique([$_POST["chief"],$_POST["crew"]]), $user->name());
$tools->redirect("trainings.php");
} else {
debug();
}
} else {
debug();
}
} elseif($tools->validate_form("mod", "delete")) {
bdump("removing training");
if($tools->validate_form(['id', 'token'])) {
if($_POST["token"] == $_SESSION['token']) {
bdump("removing training");
$crud->remove_training($_POST["id"]);
$tools->redirect("trainings.php");
} else {
debug();
}
} else {
debug();
}
} else {
if(isset($_GET["add"])||isset($_GET["edit"])||isset($_GET["delete"])||isset($_GET["mod"])) {
$_SESSION["token"] = bin2hex(random_bytes(64));
}
$crew = $db->select("SELECT * FROM `".DB_PREFIX."_profiles` ORDER BY name ASC");
$modalità = (isset($_GET["add"])) ? "add" : ((isset($_GET["edit"])) ? "edit" : ((isset($_GET["delete"])) ? "delete" : "add"));
bdump($modalità, "modalità");
bdump($crew, "crew");
$id = "";
if(isset($_GET["id"])) {
$id = $_GET["id"];
bdump($crud->exists("trainings", $id));
$values = $db->select("SELECT * FROM `".DB_PREFIX."_trainings` WHERE `id` = :id", [":id" => $id])[0];
bdump($values);
} else {
$values = [];
}
if($modalità=="edit" || $modalità=="delete") {
if(empty($id)) {
$tools->redirect("accessdenied.php");
} elseif (!$crud->exists("trainings", $id)) {
//$tools->redirect("accessdenied.php");
}
}
loadtemplate('edit_training.html', ['training' => ['id' => $id, 'token' => $_SESSION['token'], 'modalità' => $modalità, 'crew' => $crew], 'values' => $values, 'title' => t(ucfirst($modalità) . " training", false)]);
bdump($_SESSION['token'], "token");
}
?>

View File

@ -1,95 +0,0 @@
<?php
require_once 'ui.php';
use Brick\PhoneNumber\PhoneNumber;
use Brick\PhoneNumber\PhoneNumberFormat;
use Brick\PhoneNumber\PhoneNumberParseException;
if(!$user->hasRole(Role::SUPER_ADMIN)){
require("error_page.php");
show_error_page(401, t("You are not authorized to perform this action.",false), "");
exit();
}
function debug(){
echo("<pre>"); var_dump($_POST); echo("</pre>"); exit();
}
if($tools->validate_form("mod", "add")) {
if($tools->validate_form(['mail', 'name', 'username', 'password', 'phone_number', 'birthday', 'token'])) {
if($_POST["token"] == $_SESSION['token']) {
bdump("adding user");
bdump($_POST);
$chief = isset($_POST["chief"]) ? 1 : 0;
$driver = isset($_POST["driver"]) ? 1 : 0;
$hidden = isset($_POST["visible"]) ? 0 : 1;
$disabled = isset($_POST["enabled"]) ? 0 : 1;
try {
$phone_number = PhoneNumber::parse($_POST["phone_number"]);
if (!$phone_number->isValidNumber()) {
echo("Bad phone number. <a href='javascript:window.history.back()'>Go back</a>"); //TODO: better form validation
exit();
} else {
$phone_number = $phone_number->format(PhoneNumberFormat::E164);
}
} catch (PhoneNumberParseException $e) {
echo("Bad phone number. <a href='javascript:window.history.back()'>Go back</a>"); //TODO: better form validation
exit();
}
$user->add_user($_POST["mail"], $_POST["name"], $_POST["username"], $_POST["password"], $phone_number, $_POST["birthday"], $chief, $driver, $hidden, $disabled, $user->name());
$tools->redirect("list.php");
} else {
debug();
}
} else {
debug();
}
/*} elseif($tools->validate_form("mod", "edit")) {
if($tools->validate_form(['mail', 'name', 'username', 'password', 'birthday', 'token'])) {
if($_POST["token"] == $_SESSION['token']){
bdump($_POST);
bdump("editing service");
$crud->edit_service($_POST["id"], $_POST["date"], $_POST["code"], $_POST["beginning"], $_POST["end"], $_POST["chief"], $tools->extract_unique($_POST["drivers"]), $tools->extract_unique($_POST["crew"]), $_POST["place"], $_POST["notes"], $_POST["type"], $tools->extract_unique([$_POST["chief"],$_POST["drivers"],$_POST["crew"]]), $user->name());
$tools->redirect("services.php");
} else {
$tools->redirect("accessdenied.php");
}
}
*/
} elseif($tools->validate_form("mod", "delete")) {
bdump("removing service");
if($tools->validate_form(['id', 'token'])) {
if($_POST["token"] == $_SESSION['token']) {
bdump("removing user");
$user->remove_user($_POST["id"]);
$tools->redirect("list.php");
} else {
debug();
}
} else {
debug();
}
} else {
if(isset($_GET["add"])||isset($_GET["edit"])||isset($_GET["delete"])||isset($_GET["mod"])) {
$_SESSION["token"] = bin2hex(random_bytes(64));
}
$modalità = (isset($_GET["add"])) ? "add" : ((isset($_GET["edit"])) ? "edit" : ((isset($_GET["delete"])) ? "delete" : "add"));
bdump($modalità, "modalità");
$id = "";
if(isset($_GET["id"])) {
$id = $_GET["id"];
bdump($crud->exists("profiles", $id));
$values = $db->select("SELECT * FROM `".DB_PREFIX."_profiles` WHERE `id` = :id", [":id" => $id])[0];
bdump($values);
} else {
$values = [];
}
if($modalità=="edit" || $modalità=="delete") {
if(empty($id)) {
$tools->redirect("accessdenied.php");
} elseif (!$crud->exists("profiles", $id)) {
$tools->redirect("accessdenied.php");
}
}
loadtemplate('edit_user.html', ['id' => $id, 'token' => $_SESSION["token"], 'modalità' => $modalità, 'values' => $values, 'title' => t(ucfirst($modalità) . " user", false)]);
bdump($_SESSION['token'], "token");
}
?>

View File

@ -1,98 +0,0 @@
<?php
function show_error_page($error=null, $error_message=null, $error_message_advanced=null){
global $tools, $webpack_manifest_path;
$error = !is_null($error) ? $error : (isset($_GET["error"]) ? $_GET["error"] : 404);
if(is_null($error_message)){
switch ($error){
case 404:
$error_message = "Page not found";
$error_message_advanced = "Please check the url";
break;
case 500:
$error_message = "Server error";
$error_message_advanced = "Please retry later";
break;
}
}
$main_script_url = null;
$game_script_url = null;
try{
$webpack_manifest_path = isset($webpack_manifest_path) ? $webpack_manifest_path : realpath("resources/dist/assets-manifest.json");
if(!empty($webpack_manifest_path)){
$webpack_manifest = json_decode(
file_get_contents($webpack_manifest_path),
true
);
$main_script_url = "resources/dist/".$webpack_manifest["main.js"]["src"];
$game_script_url = "resources/dist/".$webpack_manifest["games.js"]["src"];
}
} catch(\Exception $e) {
}
$error_templates = [
<<<EOT
<div id="error">
<div id="box"></div>
<h3>ERROR $error</h3>
<p>$error_message</p>
<p>$error_message_advanced</p>
</div>
<style>
body,html{height:100%}body{display:grid;width:100%;font-family:Inconsolata,monospace}body div#error{position:relative;margin:auto;padding:20px;z-index:2}body div#error div#box{position:absolute;top:0;left:0;width:100%;height:100%;border:1px solid #000}body div#error div#box:after,body div#error div#box:before{content:'';position:absolute;top:0;left:0;width:100%;height:100%;box-shadow:inset 0 0 0 1px #000;mix-blend-mode:multiply;animation:dance 2s infinite steps(1)}body div#error div#box:before{clip-path:polygon(0 0,65% 0,35% 100%,0 100%);box-shadow:inset 0 0 0 1px currentColor;color:#f0f}body div#error div#box:after{clip-path:polygon(65% 0,100% 0,100% 100%,35% 100%);animation-duration:.5s;animation-direction:alternate;box-shadow:inset 0 0 0 1px currentColor;color:#0ff}body div#error h3{position:relative;font-size:5vw;font-weight:700;text-transform:uppercase;animation:blink 1.3s infinite steps(1)}body div#error h3:after,body div#error h3:before{content:'ERROR $error';position:absolute;top:-1px;left:0;mix-blend-mode:soft-light;animation:dance 2s infinite steps(2)}body div#error h3:before{clip-path:polygon(0 0,100% 0,100% 50%,0 50%);color:#f0f;animation:shiftright 2s steps(2) infinite}body div#error h3:after{clip-path:polygon(0 100%,100% 100%,100% 50%,0 50%);color:#0ff;animation:shiftleft 2s steps(2) infinite}body div#error p{position:relative;margin-bottom:8px}body div#error p span{position:relative;display:inline-block;font-weight:700;color:#000;animation:blink 3s steps(1) infinite}body div#error p span:after,body div#error p span:before{content:'unstable';position:absolute;top:-1px;left:0;mix-blend-mode:multiply}body div#error p span:before{clip-path:polygon(0 0,100% 0,100% 50%,0 50%);color:#f0f;animation:shiftright 1.5s steps(2) infinite}body div#error p span:after{clip-path:polygon(0 100%,100% 100%,100% 50%,0 50%);color:#0ff;animation:shiftleft 1.7s steps(2) infinite}@-moz-keyframes dance{0%,84%,94%{transform:skew(0)}85%{transform:skew(5deg)}90%{transform:skew(-5deg)}98%{transform:skew(3deg)}}@-webkit-keyframes dance{0%,84%,94%{transform:skew(0)}85%{transform:skew(5deg)}90%{transform:skew(-5deg)}98%{transform:skew(3deg)}}@-o-keyframes dance{0%,84%,94%{transform:skew(0)}85%{transform:skew(5deg)}90%{transform:skew(-5deg)}98%{transform:skew(3deg)}}@keyframes dance{0%,84%,94%{transform:skew(0)}85%{transform:skew(5deg)}90%{transform:skew(-5deg)}98%{transform:skew(3deg)}}@-moz-keyframes shiftleft{0%,100%,87%{transform:translate(0,0) skew(0)}84%,90%{transform:translate(-8px,0) skew(20deg)}}@-webkit-keyframes shiftleft{0%,100%,87%{transform:translate(0,0) skew(0)}84%,90%{transform:translate(-8px,0) skew(20deg)}}@-o-keyframes shiftleft{0%,100%,87%{transform:translate(0,0) skew(0)}84%,90%{transform:translate(-8px,0) skew(20deg)}}@keyframes shiftleft{0%,100%,87%{transform:translate(0,0) skew(0)}84%,90%{transform:translate(-8px,0) skew(20deg)}}@-moz-keyframes shiftright{0%,100%,87%{transform:translate(0,0) skew(0)}84%,90%{transform:translate(8px,0) skew(20deg)}}@-webkit-keyframes shiftright{0%,100%,87%{transform:translate(0,0) skew(0)}84%,90%{transform:translate(8px,0) skew(20deg)}}@-o-keyframes shiftright{0%,100%,87%{transform:translate(0,0) skew(0)}84%,90%{transform:translate(8px,0) skew(20deg)}}@keyframes shiftright{0%,100%,87%{transform:translate(0,0) skew(0)}84%,90%{transform:translate(8px,0) skew(20deg)}}@-moz-keyframes blink{0%,100%,50%,85%{color:#000}87%,95%{color:transparent}}@-webkit-keyframes blink{0%,100%,50%,85%{color:#000}87%,95%{color:transparent}}@-o-keyframes blink{0%,100%,50%,85%{color:#000}87%,95%{color:transparent}}@keyframes blink{0%,100%,50%,85%{color:#000}87%,95%{color:transparent}}
</style>
EOT,
<<<EOT
<h1 aria-label="$error Error" style="font-size: calc(3em + 9vw);">$error</h1>
<h2>$error_message</h2>
<h3>$error_message_advanced</h3>
<style>
body {
justify-content: center;
align-items: center;
font-family: 'Open Sans', Arial, sans-serif;
text-align: center;
color: #fff;
background-image: linear-gradient(-225deg, #cf2778, #7c64d5, #4cc3ff);
}
</style>
EOT
];
$credits_list = [
"<a target='_blank' href='https://codepen.io/yexx'>Yeshua Emanuel Braz</a>",
"<a target='_blank' href='https://codepen.io/GeorgePark'>George W. Park</a>"
];
$key = isset($_GET["force_page"]) ? $_GET["force_page"] : array_rand($error_templates);
$credits = $credits_list[$key];
echo($error_templates[$key]);
$nonce = false;
try {
if (is_object($tools)) $nonce = $tools->script_nonce;
} catch (\Exception $e) {
}
?>
<br><br>
<?php
if(!is_null($game_script_url)){
?>
<div class="games_list" style="margin-left: 20px; text-align: left;">
While you are waiting, you can play some games:
<ul>
<li hidden><a data-game="pong" class="playGame">Pong</a></li>
<li><a data-game="ld46" class="playGame">What the firetruck</a></li>
</ul>
</div>
<div class="credits" style="position:absolute;opacity: 0.5;bottom: 5px;right: 5px;">
Error page based on work by <?php echo($credits); ?>.
</div>
<script src="<?php echo($main_script_url); ?>"<?php if($nonce){ echo("nonce='{$nonce}'"); } ?>></script>
<script src="<?php echo($game_script_url); ?>"<?php if($nonce){ echo("nonce='{$nonce}'"); } ?>></script>
<?php
}
}
if (basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"])) {
show_error_page();
}
?>

View File

@ -1,199 +0,0 @@
<?php
declare(strict_types=1);
// Test this using following command
// php -S localhost:8080 ./graphql.php &
// curl http://localhost:8080 -d '{"query": "query { echo(message: \"Hello World\") }" }'
// curl http://localhost:8080 -d '{"query": "mutation { sum(x: 2, y: 2) }" }'
require_once __DIR__ . '/vendor/autoload.php';
use GraphQL\GraphQL;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Schema;
$users = [[
'email' => "email",
'username' => "username",
'name' => "Name",
'available' => true,
'chief' => true,
'driver' => true,
'phoneNumber' => "+11234567891",
'services' => 0,
'trainings' => 0,
'availabilityMinutes' => 0,
'verified' => true,
'hidden' => false,
'disabled' => false,
],[
'email' => "email2",
'username' => "username2",
'name' => "Name2",
'available' => true,
'chief' => true,
'driver' => true,
'phoneNumber' => "+11234567892",
'services' => 0,
'trainings' => 0,
'availabilityMinutes' => 0,
'verified' => true,
'hidden' => false,
'disabled' => false,
]];
try {
$userType = new ObjectType([
'name' => 'User',
'description' => 'Allerta User',
'fields' => [
'id' => Type::int(),
'email' => Type::string(),
'username' => Type::string(),
'name' => Type::string(),
'available' => Type::boolean(),
'chief' => Type::boolean(),
'driver' => Type::boolean(),
'phoneNumber' => Type::string(), //TODO: custom type
'services' => Type::int(),
'trainings' => Type::int(),
'availabilityMinutes' => Type::int(),
'verified' => Type::boolean(),
'hidden' => Type::boolean(),
'disabled' => Type::boolean(),
]
]);
$queryType = new ObjectType([
'name' => 'Query',
'fields' => [
'echo' => [
'type' => Type::string(),
'args' => [
'message' => ['type' => Type::string()],
],
'resolve' => static function ($rootValue, array $args): string {
return $rootValue['prefix'] . $args['message'];
},
],
'user' => [
'type' => $userType,
'args' => [
'id' => [
'type' => Type::int(),
]
],
'resolve' => function ($rootValue, array $args) {
global $users;
return $users[0];
},
],
'Users' => [
'type' => Type::listOf($userType),
'args' => [
'id' => [
'type' => Type::int(),
],
'username' => [
'type' => Type::string(),
],
'available' => [
'type' => Type::boolean(),
],
'chief' => [
'type' => Type::boolean(),
],
'driver' => [
'type' => Type::boolean(),
],
'services' => [
'type' => Type::int(),
],
'trainings' => [
'type' => Type::int(),
],
'availabilityMinutes' => [
'type' => Type::int(),
],
'verified' => [
'type' => Type::boolean(),
],
'hidden' => [
'type' => Type::boolean(),
],
'disabled' => [
'type' => Type::boolean()
]
],
'resolve' => function ($rootValue, array $args) {
global $db, $user;
$profiles = $db->select("SELECT * FROM `".DB_PREFIX."_profiles`");
$users = $db->select("SELECT * FROM `".DB_PREFIX."_users`");
$result = [];
for ($i=0; $i < sizeof($profiles); $i++) {
$result[] = [
"id" => $users["id"],
"email" => $profiles["email"],
"username" => $users["username"],
"name" => $user->nameById($users["id"]),
"available" => $profiles["available"],
"chief" => $profiles["chief"],
"driver" => $profiles["driver"],
"phoneNumber" => $profiles["phone_number"],
"services" => $profiles["services"],
"trainings" => $profiles["trainings"],
"availabilityMinutes" => $profiles["availabilityMinutes"],
"verified" => $users["verified"],
"hidden" => $profiles["hidden"],
"disabled" => $profiles["disabled"],
];
}
return $result;
},
]
],
]);
$mutationType = new ObjectType([
'name' => 'Calc',
'fields' => [
'sum' => [
'type' => Type::int(),
'args' => [
'x' => ['type' => Type::int()],
'y' => ['type' => Type::int()],
],
'resolve' => static function ($calc, array $args): int {
return $args['x'] + $args['y'];
},
],
],
]);
// See docs on schema options:
// https://webonyx.github.io/graphql-php/type-system/schema/#configuration-options
$schema = new Schema([
'query' => $queryType,
'mutation' => $mutationType,
]);
$rawInput = file_get_contents('php://input');
$input = json_decode($rawInput, true);
$query = $input['query'];
$variableValues = $input['variables'] ?? null;
$rootValue = ['prefix' => 'You said: '];
$result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues);
$output = $result->toArray();
} catch (Throwable $e) {
$output = [
'error' => [
'message' => $e->getMessage(),
"object" => $e
],
];
}
header('Content-Type: application/json; charset=UTF-8');
echo json_encode($output);

View File

@ -1,16 +0,0 @@
<?php
require_once 'ui.php';
if($user->authenticated) {
$tools->redirect("list.php");
}
$error = false;
if(isset($_POST['name']) & isset($_POST['password'])) {
$login = $user->login($_POST['name'], $_POST['password'], isset($_POST["remember_me"]));
if($login===true) {
$tools->redirect("list.php");
} else {
$error = $login;
bdump($error);
}
}
loadtemplate('index.html', ['error' => $error, 'title' => t('Login', false)], false);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,220 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="robots" content="noindex,nofollow">
<title>Allerta {{ 'installation'|t }}</title>
<link rel="stylesheet" id="dashicons-css" href="dashicons.min.css?installation" type="text/css" media="all">
<link rel="stylesheet" id="buttons-css" href="buttons.min.css?installation" type="text/css" media="all">
<link rel="stylesheet" id="forms-css" href="forms.min.css?installation" type="text/css" media="all">
<link rel="stylesheet" id="install-css" href="install.min.css?installation" type="text/css" media="all">
<script async="" src="zxcvbn.js"></script>
</head>
<body class="wp-core-ui">
<p id="logo">
<a href="javascript:alert('TODO: add docs');">Allerta</a>
</p>
{% if step == 1 and not configOk %}
<h1 class="screen-reader-text">{{ 'Before starting'|t }}</h1>
<p>{{ 'Welcome in Allerta. We need some informations about the database. You have to know the following informations:'|t }}
</p>
<ol>
<li>{{ 'DB name'|t }}</li>
<li>{{ 'DB username'|t }}</li>
<li>{{ 'DB password'|t }}</li>
<li>{{ 'DB host'|t }}</li>
<li>{{ 'DB prefix'|t }}</li>
</ol>
<p>
{{ 'We will use this informations for creating a file'|t }} <code>config.php</code>. <strong>
{{ "If for any reason automatic file creation doesn't work, don't worry. You can just open %s in a text editor, enter your details, and save it as"|t|format('<code>config-sample.php</code>')|raw }}
<code>config.php</code>. </strong>
</p>
<p>{{ "In all likelihood, this information has already been provided to you by your hosting provider. If you don't have this information, you'll need to contact your provider before you can continue. But if everything is ready..."|t }}
</p>
<p class="step">
<form method="POST">
<input type="hidden" name="step" value="2">
<input type="submit" value="{{ 'Submit'|t }}" class="button button-large">
</form>
</p>
{% elseif step == 2 %}
<h1 class="screen-reader-text">{{ "Configure the database connection"|t }}</h1>
<form method="post">
<p>{{ "Below you can enter your database connection details. If you are not sure of the data to enter, contact your hosting provider"|t }}.
</p>
<table class="form-table" role="presentation">
<tbody>
<tr>
<th scope="row"><label for="dbname">{{ "DB name"|t }}</label></th>
<td><input name="dbname" id="dbname" type="text" aria-describedby="dbname-desc" size="25"
value="{{ dbConfig.dbname }}" autofocus=""></td>
<td id="dbname-desc">{{ "The name of the database you want to use with Allerta"|t }}.</td>
</tr>
<tr>
<th scope="row"><label for="uname">{{ "DB username"|t }}</label></th>
<td><input name="uname" id="uname" type="text" aria-describedby="uname-desc" size="25"
value="{{ dbConfig.user }}"></td>
<td id="uname-desc">{{ "Your"|t }} {{ "DB username"|t }}.</td>
</tr>
<tr>
<th scope="row"><label for="pwd">{{ "DB password"|t }}</label></th>
<td><input name="pwd" id="pwd" type="text" aria-describedby="pwd-desc" size="25"
value="{{ dbConfig.pwd }}" autocomplete="off"></td>
<td id="pwd-desc">{{ "Your"|t }} {{ "DB password"|t }}.</td>
</tr>
<tr>
<th scope="row"><label for="dbhost">{{ "DB host"|t }}</label></th>
<td><input name="dbhost" id="dbhost" type="text" aria-describedby="dbhost-desc" size="25"
value="{{ dbConfig.host }}"></td>
<td id="dbhost-desc">
{{ "If %s doesn't work, you can get this information from your hosting provider"|t|format("<code>localhost</code>")|raw }}
</td>
</tr>
<tr>
<th scope="row"><label for="prefix">{{ "DB prefix"|t }}</label></th>
<td><input name="prefix" id="prefix" type="text" aria-describedby="prefix-desc" value="{{ dbConfig.prefix }}"
size="25"></td>
<td id="prefix-desc">
{{ "Edit this item if you want to perform multiple Alert installations on a single database"|t }}.
</td>
</tr>
</tbody>
</table>
<input type="hidden" name="step" value="3">
<p class="step"><input name="submit" type="submit" value="{{ "Submit"|t }}" class="button button-large"></p>
</form>
{% elseif step == 3 %}
<h1 class="screen-reader-text">{{ "Configuration file created successfully!"|t }}</h1>
<p>{{ "Great job, man!"|t }} {{ "You have completed this part of the installation. Allerta can now communicate with the database"|t }}<br>{{ "If you are ready, it's time to..."|t }}</p>
<p class="step">
<form method="POST">
<input type="hidden" name="step" value="4">
<input type="submit" class="button button-large" value="{{ 'Populate DB'|t }}">
</form>
</p>
{% elseif configOk and not populated %}
<h1 class="screen-reader-text">{{ "Hurray!"|t }}</h1>
<p>{{ "You are almost finished installing Allerta, you just need to enter some information"|t }}.</p>
<h2>{{ "Necessary informations:"|t }}</h2>
<p class="step">
<form id="setup" method="post">
<script>
function validatePwd() {
var pwd = document.getElementById("pass1").value;
result = zxcvbn(pwd);
switch (result.score) {
case 0:
document.getElementById("pass1").className = "short";
document.getElementById("pass-strength-result").className = "short";
document.getElementById("pass-strength-result").innerHTML = "{{ 'Very weak'|t }}";
break;
case 1:
document.getElementById("pass1").className = "bad";
document.getElementById("pass-strength-result").className = "bad";
document.getElementById("pass-strength-result").innerHTML = "{{ 'Weak'|t }}";
break;
case 2:
document.getElementById("pass1").className = "good";
document.getElementById("pass-strength-result").className = "good";
document.getElementById("pass-strength-result").innerHTML = "{{ 'Good'|t }}";
break;
case 3:
document.getElementById("pass1").className = "strong";
document.getElementById("pass-strength-result").className = "strong";
document.getElementById("pass-strength-result").innerHTML = "{{ 'Strong'|t }}";
break;
case 4:
document.getElementById("pass1").className = "strong";
document.getElementById("pass-strength-result").className = "strong";
document.getElementById("pass-strength-result").innerHTML = "{{ 'Very strong'|t }}";
break;
default:
document.getElementById("pass1").className = "short";
document.getElementById("pass-strength-result").className = "short";
document.getElementById("pass-strength-result").innerHTML = "{{ 'Very weak'|t }}";
break;
}
}
</script>
<table class="form-table" role="presentation">
<tbody>
<tr>
<th scope="row"><label for="user_login">{{ "Admin username"|t }}</label></th>
<td>
<input name="user_name" type="text" id="user_login" size="75" value="">
<p>{{ "Usernames can only contains alphanumeric characters, spaces, underscores, dashes, periods, and the @ symbol"|t }}.
</p>
</td>
</tr>
<tr class="form-field form-required user-pass1-wrap">
<th scope="row">
<label for="pass1">
{{ "Password"|t }}</label>
</th>
<td>
<div class="wp-pwd">
<input type="text" name="admin_password" id="pass1" class="regular-text short"
autocomplete="off" aria-describedby="pass-strength-result" onkeyup="validatePwd()">
<div id="pass-strength-result" aria-live="polite" class="short">{{ "Very weak"|t }}
</div>
</div>
<p><span class="description important">
<strong>{{ "Important:"|t }}</strong>
{{ "You will need this password to log in. Keep it in a safe place"|t }}.</span></p>
</td>
</tr>
<tr>
<th scope="row">{{ "Is admin visible?"|t }}</th>
<td>
<fieldset>
<legend class="screen-reader-text"><span>{{ "Make admin user visible"|t }}</span>
</legend>
<label for="admin_visible"><input name="admin_visible" type="checkbox"
id="admin_visible" value="0">
{{ "Make admin user visible"|t }} {{ "to other users"|t }}</label>
<p class="description">
{{ "By activating this option, the user that will be created will be visible in lists and procedures"|t }}.
</p>
</fieldset>
</td>
</tr>
<tr style="display:none">
<th scope="row">{{ "Add developer permissions to admin user"|t }}</th>
<td>
<fieldset>
<label for="developer"><input name="developer" type="checkbox" id="developer" value="0">
{{ "Add developer permissions to admin user"|t }}</label>
<p class="description">
{{ "By activating this option, the user will be able to debug Allerta"|t }}.</p>
</fieldset>
</td>
</tr>
<tr>
<th scope="row"><label for="admin_email">{{ "Your email"|t }}</label></th>
<td><input name="admin_email" type="email" id="admin_email" size="50" value="">
<p>{{ "Please check your email address carefully before continuing"|t }}.</p>
</td>
</tr>
<tr>
<th scope="row"><label for="owner">{{ "Owner"|t }}</label></th>
<td><input name="owner" type="text" id="owner" size="100" value="">
<p>{{ "It will be used in reports"|t }}.</p>
</td>
</tr>
</tbody>
</table>
<p class="step"><input type="submit" name="Submit" id="submit" class="button button-large"
value="{{ 'Install Allerta'|t }}"></p>
<input type="hidden" name="step" value="5">
</form>
</p>
{% elseif step == 5 %}
<h1 class="screen-reader-text">{{ "Installation completed successfully"|t }}.</h1>
<p>{{ "Great job, man!"|t }} {{ "You have completed the installation. Allerta can now function properly"|t }} <br> {{ "If you are ready, it's time to..."|t }}</p>
<p class="step">
<a href="../index.php" class="login">{{ "Login"|t }}</a>
</p>
{% endif %}
</body>
</html>

View File

@ -1,386 +0,0 @@
/*! This file is auto-generated */
html {
background: #f1f1f1;
margin: 0 20px
}
body {
background: #fff;
color: #444;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
margin: 140px auto 25px;
padding: 20px 20px 10px 20px;
max-width: 700px;
-webkit-font-smoothing: subpixel-antialiased;
box-shadow: 0 1px 3px rgba(0, 0, 0, .13)
}
a {
color: #0073aa
}
a:active,
a:hover {
color: #00a0d2
}
a:focus {
color: #124964;
box-shadow: 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, .8)
}
.ie8 a:focus {
outline: #5b9dd9 solid 1px
}
h1,
h2 {
border-bottom: 1px solid #ddd;
clear: both;
color: #666;
font-size: 24px;
padding: 0;
padding-bottom: 7px;
font-weight: 400
}
h3 {
font-size: 16px
}
dd,
dt,
li,
p {
padding-bottom: 2px;
font-size: 14px;
line-height: 1.5
}
.code,
code {
font-family: Consolas, Monaco, monospace
}
dl,
ol,
ul {
padding: 5px 5px 5px 22px
}
a img {
border: 0
}
abbr {
border: 0;
font-variant: normal
}
fieldset {
border: 0;
padding: 0;
margin: 0
}
label {
cursor: pointer
}
#logo {
margin: 6px 0 14px 0;
padding: 0 0 7px 0;
border-bottom: none;
text-align: center
}
#logo a {
background-image: url(logo.png);
background-size: 84px;
background-position: center top;
background-repeat: no-repeat;
color: #444;
height: 84px;
font-size: 20px;
font-weight: 400;
line-height: 1.3;
margin: -130px auto 25px;
padding: 0;
text-decoration: none;
width: 84px;
text-indent: -9999px;
outline: 0;
overflow: hidden;
display: block
}
.step {
margin: 20px 0 15px
}
.step,
th {
text-align: left;
padding: 0
}
.language-chooser.wp-core-ui .step .button.button-large {
font-size: 14px
}
textarea {
border: 1px solid #ddd;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
width: 100%;
box-sizing: border-box
}
.form-table {
border-collapse: collapse;
margin-top: 1em;
width: 100%
}
.form-table td {
margin-bottom: 9px;
padding: 10px 20px 10px 0;
font-size: 14px;
vertical-align: top
}
.form-table th {
font-size: 14px;
text-align: left;
padding: 10px 20px 10px 0;
width: 140px;
vertical-align: top
}
.form-table code {
line-height: 1.28571428;
font-size: 14px
}
.form-table p {
margin: 4px 0 0 0;
font-size: 11px
}
.form-table input {
line-height: 1.33333333;
font-size: 15px;
padding: 3px 5px;
border: 1px solid #ddd;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07)
}
input,
submit {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif
}
#pass-strength-result,
.form-table input[type=email],
.form-table input[type=password],
.form-table input[type=text],
.form-table input[type=url] {
width: 218px
}
.form-table th p {
font-weight: 400
}
.form-table.install-success td,
.form-table.install-success th {
vertical-align: middle;
padding: 16px 20px 16px 0
}
.form-table.install-success td p {
margin: 0;
font-size: 14px
}
.form-table.install-success td code {
margin: 0;
font-size: 18px
}
#error-page {
margin-top: 50px
}
#error-page p {
font-size: 14px;
line-height: 1.28571428;
margin: 25px 0 20px
}
#error-page code,
.code {
font-family: Consolas, Monaco, monospace
}
.message {
border-left: 4px solid #dc3232;
padding: .7em .6em;
background-color: #fbeaea
}
#admin_email,
#dbhost,
#dbname,
#pass1,
#pass2,
#prefix,
#pwd,
#uname,
#user_login {
direction: ltr
}
.rtl input,
.rtl submit,
.rtl textarea,
body.rtl {
font-family: Tahoma, sans-serif
}
:lang(he-il) .rtl input,
:lang(he-il) .rtl submit,
:lang(he-il) .rtl textarea,
:lang(he-il) body.rtl {
font-family: Arial, sans-serif
}
@media only screen and (max-width:799px) {
body {
margin-top: 115px
}
#logo a {
margin: -125px auto 30px
}
}
@media screen and (max-width:782px) {
.form-table {
margin-top: 0
}
.form-table td,
.form-table th {
display: block;
width: auto;
}
.form-table th {
padding: 20px 0 0
}
.form-table td {
padding: 5px 0;
border: 0;
margin: 0
}
input,
textarea {
font-size: 16px
}
.form-table span.description,
.form-table td input[type=email],
.form-table td input[type=password],
.form-table td input[type=text],
.form-table td input[type=url],
.form-table td select,
.form-table td textarea {
width: 100%;
font-size: 16px;
line-height: 1.5;
padding: 7px 10px;
display: block;
max-width: none;
box-sizing: border-box
}
.wp-pwd #pass1 {
padding-right: 50px
}
.wp-pwd .button.wp-hide-pw {
right: 0
}
#pass-strength-result {
width: 100%
}
}
body.language-chooser {
max-width: 300px
}
.language-chooser select {
padding: 8px;
width: 100%;
display: block;
border: 1px solid #ddd;
background: #fff;
color: #32373c;
font-size: 16px;
font-family: Arial, sans-serif;
font-weight: 400
}
.language-chooser select:focus {
color: #32373c
}
.language-chooser select option:focus,
.language-chooser select option:hover {
color: #016087
}
.language-chooser p {
text-align: right
}
.screen-reader-input,
.screen-reader-text {
border: 0;
clip: rect(1px, 1px, 1px, 1px);
-webkit-clip-path: inset(50%);
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
word-wrap: normal!important
}
.spinner {
background: url(spinner.gif) no-repeat;
background-size: 20px 20px;
visibility: hidden;
opacity: .7;
filter: alpha(opacity=70);
width: 20px;
height: 20px;
margin: 2px 5px 0
}
.step .spinner {
display: inline-block;
vertical-align: middle;
margin-right: 15px
}
.button.hide-if-no-js,
.hide-if-no-js {
display: none
}
@media print,
(-webkit-min-device-pixel-ratio:1.25),
(min-resolution:120dpi) {
.spinner {
background-image: url(spinner-2x.gif)
}
}

View File

@ -1,109 +0,0 @@
<?php
if (file_exists("installHelper.php")) {
try {
include 'installHelper.php';
} catch (Exception $e) {
die("Please re-download Allerta. Installation corrupted (".$e.")");
}
} else {
die("Please re-download Allerta. Installation corrupted");
}
if (!file_exists("runInstall.php")) {
t("Already installed");
exit();
}
$populated = false;
$userPopulated = false;
if (file_exists("../config.php")) {
try {
include '../config.php';
$dbnameValue = DB_NAME;
$unameValue = DB_USER;
$pwdValue = DB_PASSWORD;
$dbhostValue = DB_HOST;
$prefixValue = DB_PREFIX;
if(checkConnection($dbhostValue, $unameValue, $pwdValue, $dbnameValue, true)) {
$configOk = true;
try{
$db = \Delight\Db\PdoDatabase::fromDsn(
new \Delight\Db\PdoDsn(
"mysql:host=$dbhostValue;dbname=$dbnameValue",
$unameValue,
$pwdValue
)
);
try{
$populated = !is_null($db->select("SELECT * FROM `".DB_PREFIX."_dbversion`"));
} catch (Delight\Db\Throwable\TableNotFoundError $e){
$populated = false;
}
try{
$userPopulated = !is_null($db->select("SELECT * FROM `".DB_PREFIX."_users`"));
} catch (Delight\Db\Throwable\TableNotFoundError $e){
$userPopulated = false;
}
} catch (Exception $e){
$populated = false;
$userPopulated = false;
}
}
} catch (Exception $e) {
$dbnameValue = "allerta";
$unameValue = t("user", false);
$pwdValue = t("password", false);
$dbhostValue = "127.0.0.1";
$prefixValue = "allerta01";
$configOk = false;
}
} else {
$dbnameValue = "allerta";
$unameValue = t("user", false);
$pwdValue = t("password", false);
$dbhostValue = "127.0.0.1";
$prefixValue = "allerta01";
$configOk = false;
}
if(!is_cli()) {
$loader = new \Twig\Loader\FilesystemLoader(".");
$twig = new \Twig\Environment($loader);
$filter_translate = new \Twig\TwigFilter(
't', function ($string) {
return t($string, false);
}
);
$twig->addFilter($filter_translate);
if(!isset($_GET["old"])){
$template = $twig->load("install.html");
echo($template->render([
"step" => isset($_POST["step"]) ? $_POST["step"] : 1,
"configOk" => $configOk,
"populated" => $populated,
"userPopulated" => $userPopulated,
"dbConfig" => [
"dbname" => $dbnameValue,
"user" => $unameValue,
"pwd" => $pwdValue,
"host" => $dbhostValue,
"prefix" => $prefixValue
]
]));
}
if (in_array("3", $_POST)) {
checkConnection($_POST["dbhost"], $_POST["uname"], $_POST["pwd"], $_POST["dbname"]);
generateConfig($_POST["dbhost"], $_POST["uname"], $_POST["pwd"], $_POST["dbname"], $_POST["prefix"]);
} else if ($configOk && !$populated) {
initDB();
} else if (in_array("5", $_POST)) {
initOptions($_POST["user_name"], isset($_POST["admin_visible"]), isset($_POST["developer"]), $_POST["admin_password"], $_POST["admin_email"], $_POST["owner"]);
finalInstallationHelperStep();
}
} else {
run_cli();
}
?>

View File

@ -1,763 +0,0 @@
<?php
use GetOpt\GetOpt as Getopt;
use GetOpt\Option;
function finalInstallationHelperStep(){
$logopngPath = "../resources/images/";
unlink("runInstall.php");
if(file_exists("../options.txt")){
unlink("../options.txt");
}
if(file_exists($logopngPath."logo_sample.png") && !file_exists($logopngPath."logo.png")){
copy($logopngPath."logo_sample.png", $logopngPath."logo.png");
}
if(file_exists($logopngPath."owner_sample.png") && !file_exists($logopngPath."owner.png")){
copy($logopngPath."owner_sample.png", $logopngPath."owner.png");
}
}
function client_languages()
{
if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$client_languages = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
} else {
$client_languages = "en-US;q=0.5,en;q=0.3";
}
if(strpos($client_languages, ';') == false) {
if(strpos($client_languages, '-') !== false) {
return [substr($client_languages, 0, 5)];
} else {
return [substr($client_languages, 0, 2)];
}
} else {
$client_languages = explode(",", $client_languages);
$tmp_languages = [];
foreach($client_languages as $language){
if(strpos($language, ';') == false) {
$tmp_languages[$language] = 1;
} else {
$tmp_languages[explode(";q=", $language)[0]] = (float) explode(";q=", $language)[1];
}
}
arsort($tmp_languages);
return array_keys($tmp_languages);
}
}
$client_languages = client_languages();
$loaded_languages = ["en", "it"];
$default_language = "en";
$language = null;
foreach($client_languages as $tmp_language){
if(in_array($tmp_language, $loaded_languages) && $language == null) {
$language = $tmp_language;
}
}
if(isset($_COOKIE["forceLanguage"]) && in_array($_COOKIE["forceLanguage"], $loaded_languages)){
$language = $_COOKIE["forceLanguage"];
}
if (file_exists("translations/".$language.".php")) {
$loaded_translations = include "translations/".$language.".php";
} else {
$loaded_translations = include "translations/en.php";
}
function t($string, $echo=true)
{
global $loaded_translations;
try {
if (!array_key_exists($string, $loaded_translations)) {
throw new Exception('string does not exist');
}
$string = $loaded_translations[$string];
} catch (\Exception $e) {
//nothing
}
if ($echo) {
echo $string;
} else {
return $string;
}
}
function is_cli() //https://www.binarytides.com/php-check-running-cli/
{
if(defined('STDIN') ) {
return true;
}
if(empty($_SERVER['REMOTE_ADDR']) and !isset($_SERVER['HTTP_USER_AGENT']) and count($_SERVER['argv']) > 0) {
return true;
}
return false;
}
if (file_exists('../vendor/autoload.php')) {
try {
include '../vendor/autoload.php';
} catch (Exception $e) {
echo("Please install composer and run composer install (".$e.")");
if(is_cli()) {
exit(1);
} else {
exit();
}
}
} else {
echo("Please install composer and run composer install");
if(is_cli()) {
exit(1);
} else {
exit();
}
}
function checkConnection($host, $user, $password, $database, $return=false)
{
try{
$connection = new PDO("mysql:host=$host", $user, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$connectionOk = true;
} catch (PDOException $e){
if($return) {
return false;
} else {
if(is_cli()) {
echo($e);
exit(8);
}
$connectionOk = false;
?>
<div class="wp-die-message"><h1><?php t("Error establishing a database connection"); ?></h1>
<p><?php printf(t("This could mean that %s and %s in file %s are wrong or that we cannot contact database %s. It could mean that your database is unreachable", false), t("DB username", false), t("DB password", false), "<code>config.php</code>", "<code>$database</code>"); ?>.</p>
<ul>
<li><?php printf(t("Are you sure that %s and %s correct?", false), t("DB username", false), t("DB password", false)); ?></li>
<li><?php t("Are you sure you have entered the correct hostname?"); ?></li>
<li><?php t("Are you sure the database server is up and running?"); ?></li>
</ul>
<p><?php t("If you're not sure what these terms mean, try contacting your hosting provider. Try providing the following information:"); ?></p>
<details open>
<summary><?php t("Advanced informations"); ?></summary>
<pre><?php echo($e); ?></pre>
</details>
<p class="step"><a href="#" onclick="javascript:history.go(-2);return false;" class="button button-large"><?php t("Try again"); ?></a></p>
</div>
<?php
exit();
}
}
if($connectionOk) {
try{
try{
$connection->exec("CREATE DATABASE IF NOT EXISTS " . trim($database));
} catch(Exception $e) {
//nothing
}
$connection->exec("use " . trim($database));
} catch (PDOException $e){
if($return) {
return false;
} else {
if(is_cli()) {
echo($e);
exit(7);
}
?>
<div class="wp-die-message"><h1><?php t("Cannot select database"); ?></h1>
<p><?php t("We were able to connect to the database server (which means your username and password are ok)"); echo(", "); t("but we could not select the database"); ?> <code><?php echo $database; ?></code>.</p>
<ul>
<li><?php t("Are you sure that it exists?"); ?></li>
<li><?php printf(t("Does user %s have permissions to use database %s?", false), "<code>$user</code>", "<code>$database</code>"); ?></li>
<li><?php printf(t("In some systems your database name has your username as a prefix, which is %s. Could this be the problem?", false), "<code>".$user."_".$database."</code>"); ?> </li>
</ul>
<p><?php t("If you're not sure what these terms mean, try contacting your hosting provider. Try providing the following information:"); ?></p>
<details open>
<summary><?php t("Advanced informations"); ?></summary>
<pre><?php echo($e); ?></pre>
</details>
<p class="step"><a href="#" onclick="javascript:history.go(-2);return false;" class="button button-large"><?php t("Try again"); ?></a></p>
</div>
<?php
exit();
}
}
return true;
}
}
function replaceInFile($edits,$file)
{
$content = file_get_contents($file);
foreach($edits as $edit){
$content = str_replace($edit[0], $edit[1], $content);
}
file_put_contents($file, $content);
}
function generateConfig($host,$user,$password,$db,$prefix,$path="..")
{
try{
if (file_exists($path.DIRECTORY_SEPARATOR.'config.php')) {
rename($path.DIRECTORY_SEPARATOR."config.php", $path.DIRECTORY_SEPARATOR."config.old.php");
}
copy($path.DIRECTORY_SEPARATOR."config-sample.php", $path.DIRECTORY_SEPARATOR."config.php");
replaceInFile([["@@db@@", $db],["@@user@@",$user],["@@password@@",$password],["@@host@@",$host],["@@prefix@@",$prefix]], $path.DIRECTORY_SEPARATOR."config.php");
} catch (Exception $e) {
if(is_cli()) {
echo($e);
exit(6);
}
?>
<div class="wp-die-message"><h1></h1>
<p><?php printf(t("We were unable to write the configuration file %s, which is required for the program to work", false), "<code>config.php</code>"); echo ".<br>"; t("It is however possible to edit it manually by following the instructions below:"); ?></p>
<ul>
<li><?php t("Access the Allerta installation folder (connect via FTP in case of cloud server)"); ?>.</li>
<li><?php printf(t("Rename the file %s to %s", false), "<code>config-sample.php</code>", "<code>config.php</code>"); ?>.</li>
<li><?php t("Replace the first 16 lines of the file with the following text:"); ?></li>
<code>
&lt;?php<br>
// ** Database settings ** //<br>
/* The name of the database for Allerta-vvf */<br>
define( 'DB_NAME', '<?php echo $db; ?>' );<br>
<br>
/* Database username */<br>
define( 'DB_USER', '<?php echo $user; ?>' );<br>
<br>
/* Database password */<br>
define( 'DB_PASSWORD', '<?php echo $password; ?>' );<br>
<br>
/* Database hostname */<br>
define( 'DB_HOST', '<?php echo $host; ?>' );<br>
<br>
/* Database hostname */<br>
define( 'DB_PREFIX', '<?php echo $prefix; ?>' );<br>
<br>
/* Telegram bot options */<br>
define('BOT_TELEGRAM_API_KEY', '');<br>
define('BOT_TELEGRAM_USERNAME', '');<br>
<br>
/* Sentry options */<br>
define('SENTRY_CSP_REPORT_URI', '');<br>
define('SENTRY_ENABLED', false);<br>
define('SENTRY_DSN', '');<br>
define('SENTRY_ENV', 'prod');<br>
</code>
</ul>
<p><?php t("If you're not sure what these terms mean, try contacting your hosting provider. Try providing the following information:"); ?></p>
<details open>
<summary><?php t("Advanced informations"); ?></summary>
<pre><?php echo($e); ?></pre>
</details>
<p class="step"><a href="#" onclick="javascript:history.go(-1);return false;" class="button button-large"><?php t("Try again"); ?></a></p>
</div>
<?php
exit();
}
}
function initDB()
{
try{
$db = \Delight\Db\PdoDatabase::fromDsn(
new \Delight\Db\PdoDsn(
"mysql:host=".DB_HOST.";dbname=".DB_NAME,
DB_USER,
DB_PASSWORD
)
);
$prefix = DB_PREFIX;
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_trainings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` date NOT NULL,
`name` varchar(999) NOT NULL,
`beginning` time NOT NULL,
`end` time NOT NULL,
`crew` text NOT NULL,
`chief` text NOT NULL,
`place` text NOT NULL,
`place_reverse` int(11) NOT NULL,
`notes` text NOT NULL,
`increment` varchar(999) NOT NULL,
`inserted_by` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_services` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` date NOT NULL,
`code` text NOT NULL,
`beginning` time NOT NULL,
`end` time NOT NULL,
`chief` varchar(999) NOT NULL,
`drivers` varchar(999) NOT NULL,
`crew` varchar(999) NOT NULL,
`place` varchar(999) NOT NULL,
`place_reverse` int(11) NOT NULL,
`notes` varchar(999) NOT NULL,
`type` text NOT NULL,
`increment` varchar(999) NOT NULL,
`inserted_by` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`action` varchar(100) NOT NULL,
`changed` varchar(100),
`editor` varchar(100),
`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ip` varchar(100),
`source_type` varchar(4),
`user_agent` varchar(500),
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_minutes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`month` int(2) NOT NULL,
`year` int(2) NOT NULL,
`list` mediumtext NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_type` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `type_name` (`name`(99))
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(249) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
`username` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`status` tinyint(2) unsigned NOT NULL DEFAULT '0',
`verified` tinyint(1) unsigned NOT NULL DEFAULT '0',
`resettable` tinyint(1) unsigned NOT NULL DEFAULT '1',
`roles_mask` int(10) unsigned NOT NULL DEFAULT '0',
`registered` int(10) unsigned NOT NULL,
`last_login` int(10) unsigned DEFAULT NULL,
`force_logout` mediumint(7) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_profiles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`hidden` BOOLEAN NOT NULL DEFAULT FALSE,
`disabled` BOOLEAN NOT NULL DEFAULT FALSE,
`name` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`available` tinyint(1) NOT NULL DEFAULT 0,
`availability_last_change` varchar(1000) DEFAULT NULL,
`chief` tinyint(1) NOT NULL DEFAULT 0,
`driver` tinyint(1) NOT NULL DEFAULT 0,
`phone_number` varchar(25) DEFAULT NULL,
`services` int(11) NOT NULL DEFAULT 0,
`trainings` int(11) NOT NULL DEFAULT 0,
`online_time` int(11) NOT NULL DEFAULT 0,
`availability_minutes` int(11) NOT NULL DEFAULT 0,
`image` varchar(1000) DEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_users_confirmations` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`email` varchar(249) COLLATE utf8mb4_unicode_ci NOT NULL,
`selector` varchar(16) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
`token` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
`expires` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `selector` (`selector`),
KEY `email_expires` (`email`,`expires`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_users_remembered` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user` int(10) unsigned NOT NULL,
`selector` varchar(24) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
`token` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
`expires` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `selector` (`selector`),
KEY `user` (`user`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_users_resets` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user` int(10) unsigned NOT NULL,
`selector` varchar(20) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
`token` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
`expires` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `selector` (`selector`),
KEY `user_expires` (`user`,`expires`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_users_throttling` (
`bucket` varchar(44) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
`tokens` float unsigned NOT NULL,
`replenished_at` int(10) unsigned NOT NULL,
`expires_at` int(10) unsigned NOT NULL,
PRIMARY KEY (`bucket`),
KEY `expires_at` (`expires_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE IF NOT EXISTS `{$prefix}_options` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` TEXT NOT NULL, `value` MEDIUMTEXT NOT NULL,
`enabled` BOOLEAN NOT NULL DEFAULT TRUE,
`created_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_edit` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_id` INT NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE `{$prefix}_dbversion` (
`id` INT NOT NULL AUTO_INCREMENT,
`version` INT NOT NULL,
`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE `{$prefix}_api_keys` (
`id` INT NOT NULL AUTO_INCREMENT,
`apikey` VARCHAR(128) NOT NULL,
`user` INT NOT NULL,
`permissions` VARCHAR(128) NOT NULL DEFAULT 'ALL',
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE `{$prefix}_bot_telegram` (
`id` INT NOT NULL AUTO_INCREMENT,
`chat_id` VARCHAR(128) NOT NULL,
`tmp_login_token` VARCHAR(128) NOT NULL,
`user` INT NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE `{$prefix}_schedules` (
`id` INT NOT NULL AUTO_INCREMENT,
`user` INT NOT NULL,
`profile_name` VARCHAR(500) NOT NULL DEFAULT 'default',
`schedules` VARCHAR(10000) NULL DEFAULT NULL,
`holidays` VARCHAR(10000) NULL DEFAULT NULL,
`last_exec` VARCHAR(7) NULL DEFAULT NULL,
`last_update` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec(<<<"EOL"
CREATE TABLE `{$prefix}_places_info` (
`id` INT NOT NULL AUTO_INCREMENT,
`reverse_json` VARCHAR(20000) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET=latin1;
EOL);
$db->exec("INSERT INTO `{$prefix}_dbversion` (`version`, `timestamp`) VALUES('1', current_timestamp());");
} catch (Exception $e) {
if(is_cli()) {
echo($e);
exit(10);
}
?>
<div class="wp-die-message"><h1><?php t("Unable to create tables"); ?></h1>
<p><?php t("We were able to connect to the database server (which means your username and password are ok)"); echo(", "); t("but we were unable to create the tables"); ?>.</p>
<p><?php t("If you're not sure what these terms mean, try contacting your hosting provider. Try providing the following information:"); ?></p>
<details open>
<summary><?php t("Advanced informations"); ?></summary>
<pre><?php echo($e); ?></pre>
</details>
<p class="step"><a href="#" onclick="javascript:history.go(-1);return false;" class="button button-large"><?php t("Try again"); ?></a></p>
</div>
<?php
exit();
}
}
function full_path()
{
$s = &$_SERVER;
$ssl = (!empty($s['HTTPS']) && $s['HTTPS'] == 'on') ? true:false;
$sp = strtolower($s['SERVER_PROTOCOL']);
$protocol = substr($sp, 0, strpos($sp, '/')) . (($ssl) ? 's' : '');
$port = $s['SERVER_PORT'];
$port = ((!$ssl && $port=='80') || ($ssl && $port=='443')) ? '' : ':'.$port;
$host = isset($s['HTTP_X_FORWARDED_HOST']) ? $s['HTTP_X_FORWARDED_HOST'] : (isset($s['HTTP_HOST']) ? $s['HTTP_HOST'] : null);
$host = isset($host) ? $host : $s['SERVER_NAME'] . $port;
$uri = $protocol . '://' . $host . $s['REQUEST_URI'];
$segments = explode('?', $uri, 2);
$url = $segments[0];
return $url;
}
function initOptions($name, $visible, $developer, $password, $report_email, $owner, $url=null)
{
try{
include_once "../config.php";
$db = \Delight\Db\PdoDatabase::fromDsn(
new \Delight\Db\PdoDsn(
"mysql:host=".DB_HOST.";dbname=".DB_NAME,
DB_USER,
DB_PASSWORD
)
);
$prefix = DB_PREFIX;
$auth = new \Delight\Auth\Auth($db, $_SERVER['REMOTE_ADDR'], $prefix."_");
$userId = $auth->register($report_email, $password, $name);
$auth->admin()->addRoleForUserById($userId, \Delight\Auth\Role::SUPER_ADMIN);
if($developer) {
$auth->admin()->addRoleForUserById($userId, \Delight\Auth\Role::DEVELOPER);
}
if(is_null($url)){
$url = str_replace("install/install.php", "", full_path());
}
$options = [
'check_cf_ip' => empty($_SERVER['HTTP_CF_CONNECTING_IP']) ? 0 : 1,
'report_email' => $report_email,
'owner' => $owner,
'web_url' => $url,
'use_custom_error_sound' => 0,
'use_custom_error_image' => 0,
'log_save_ip' => 1,
'cron_job_code' => str_replace(".", "", bin2hex(random_bytes(10)).base64_encode(openssl_random_pseudo_bytes(30))),
'cron_job_enabled' => 1,
'cron_job_time' => '01;00:00',
'service_edit' => 1,
'service_remove' => 1,
'training_edit' => 1,
'training_remove' => 1,
'use_location_picker' => 1,
'generate_map_preview' => 1,
'map_preview_generator_add_marker' => 1,
'map_preview_generator' => 'osm', //[osm, custom]
'map_preview_generator_url' => '', //not required for osm
'map_preview_generator_url_marker' => '', //not required for osm
'force_language' => 0,
'force_remember_cookie' => 0,
'holidays_provider' => 'USA',
'holidays_language' => 'en_US',
'messages' => '{}',
'enable_js_nonce' => 0
];
foreach ($options as $key => $value) {
$db->insert(
$prefix."_options",
["name" => $key, "value" => $value, "enabled" => 1, "user_id" => 1]
);
}
$db->insert(
$prefix."_profiles",
["hidden" => $visible ? 0 : 1]
);
} catch (Exception $e) {
if(is_cli()) {
echo($e);
exit(11);
}
?>
<div class="wp-die-message"><h1><?php t("Unable to fill in the tables"); ?></h1>
<p><?php t("We were able to connect to the database server (which means your username and password are ok)"); echo(", "); t("but we were unable to fill in the tables"); ?>.</p>
<p><?php t("If you're not sure what these terms mean, try contacting your hosting provider. Try providing the following information:"); ?></p>
<details open>
<summary><?php t("Advanced informations"); ?></summary>
<pre><?php echo($e); ?></pre>
</details>
<p class="step"><a href="#" onclick="javascript:history.go(-1);return false;" class="button button-large"><?php t("Try again"); ?></a></p>
</div>
<?php
exit();
}
}
function validate_arg($options, $name, $default)
{
return array_key_exists($name, $options) ? $options[$name] : (getenv($name)!==false ? getenv($name) : (getenv(strtoupper($name))!==false ? getenv(strtoupper($name)) : $default));
}
function change_dir($directory)
{
try{
chdir($directory);
} catch(Exception $e){
if(is_cli()) {
exit(4);
}
}
}
function cli_helper($action, $options)
{
switch ($action) {
case "config":
$db_name = validate_arg($options, "db_name", "allerta");
$db_username = validate_arg($options, "db_username", "root");
$db_password = validate_arg($options, "db_password", "");
$db_host = validate_arg($options, "db_host", "127.0.0.1");
$db_prefix = validate_arg($options, "db_prefix", "allerta");
$path = isset($options->getOptions["path"]) ? "." : "..";
checkConnection($db_host, $db_username, $db_password, $db_name);
generateConfig($db_host, $db_username, $db_password, $db_name, $db_prefix, $path);
t("Config created successful");
exit(0);
case "populate":
$name = validate_arg($options, "name", "admin");
$visible = array_key_exists("visible", $options);
$developer = array_key_exists("developer", $options);
$password = validate_arg($options, "password", "password");
$report_email = validate_arg($options, "report_email", "postmaster@localhost.local");
$owner = validate_arg($options, "owner", "Owner");
$url = validate_arg($options, "url", "htp://localhost/");
initDB();
initOptions($name, $visible, $developer, $password, $report_email, $owner, $url);
t("DB Populated successful");
finalInstallationHelperStep();
exit(0);
}
}
function run_cli()
{
$_SERVER['REMOTE_ADDR'] = "127.0.0.1";
$getopt = new \GetOpt\GetOpt();
$getopt->addCommands(
[
\GetOpt\Command::create(
'config', 'conf', [
\GetOpt\Option::create('n', 'db_name', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("DB name", false))
->setArgumentName(t("DB name", false)),
\GetOpt\Option::create('u', 'db_username', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("DB username", false))
->setArgumentName(t("DB username", false)),
\GetOpt\Option::create('a', 'db_password', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("DB password", false))
->setArgumentName(t("DB password", false)),
\GetOpt\Option::create('o', 'db_host', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("DB host", false))
->setArgumentName(t("DB host", false)),
\GetOpt\Option::create('r', 'db_prefix', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("DB prefix", false))
->setArgumentName(t("DB prefix", false))
]
)->setDescription(
t("Create the config file", false).' "config.php".' . PHP_EOL .
PHP_EOL .
sprintf(t("This file is required for running %s", false), '"populate"') . "."
)->setShortDescription(t("Create a new config file", false)),
\GetOpt\Command::create(
'populate', 'Populate', [
\GetOpt\Option::create('m', 'name', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("Admin name", false))
->setArgumentName(t("Admin name", false)),
\GetOpt\Option::create('b', 'visible', \GetOpt\GetOpt::NO_ARGUMENT)
->setDescription(t("Is admin visible?", false))
->setArgumentName(t("Is admin visible?", false)),
\GetOpt\Option::create('d', 'developer', \GetOpt\GetOpt::NO_ARGUMENT)
->setDescription(t("Enable devmode per the user", false))
->setArgumentName(t("Enable devmode per the user", false)),
\GetOpt\Option::create('s', 'password', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("Admin password", false))
->setArgumentName(t("Admin password", false)),
\GetOpt\Option::create('w', 'owner', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("Owner", false))
->setArgumentName(t("Owner", false)),
\GetOpt\Option::create('e', 'report_email', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("Report email", false))
->setArgumentName(t("Report email", false)),
\GetOpt\Option::create('u', 'url', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("App url", false))
->setArgumentName(t("App url", false)),
]
)->setDescription(
t("Populate Allerta database", false) . "." . PHP_EOL .
PHP_EOL .
sprintf(t("This require a working %s file", false), "config.php") . "."
)->setShortDescription(t("Populate DB", false))
]
);
$getopt->addOptions(
[
Option::create('v', 'version', \GetOpt\GetOpt::NO_ARGUMENT)
->setDescription(t("Show version information and quit", false)),
Option::create('h', 'help', \GetOpt\GetOpt::NO_ARGUMENT)
->setDescription(t("Show this help and quit", false)),
Option::create("p", 'path', \GetOpt\GetOpt::OPTIONAL_ARGUMENT)
->setDescription(t("Destination path", false))
->setArgumentName('path')
->setValidation(
'is_writable', function ($value) {
if(file_exists($value)) {
printf(t("%s is not writable. Directory permissions: %s"), $value, @fileperms($value));
exit(4);
} else {
printf(t("%s not exists"), $value);
echo(".");
exit(3);
}
}
)
]
);
// process arguments and catch user errors
try {
try {
$getopt->process();
} catch (Missing $exception) {
// catch missing exceptions if help is requested
if (!$getopt->getOption('help')) {
throw $exception;
}
}
} catch (ArgumentException $exception) {
file_put_contents('php://stderr', $exception->getMessage() . PHP_EOL);
echo PHP_EOL . $getopt->getHelpText();
exit;
}
// show version and quit
if ($getopt->getOption('version')) {
echo sprintf('%s: %s' . PHP_EOL, "AllertaVVF", "0.0");
exit;
}
// show help and quit
$command = $getopt->getCommand();
if (!$command || $getopt->getOption('help')) {
echo $getopt->getHelpText();
exit;
}
if (isset($getopt->getOptions()["path"])) {
chdir($getopt->getOption('path'));
}
$options = $getopt->getOptions();
switch ($command->getName()) {
case "config":
cli_helper("config", $options);
case "populate":
cli_helper("populate", $options);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

View File

@ -1,97 +0,0 @@
<?php
// Translated by: Name Surname (github, email or another social profile url/username)
return [
"Already installed" => "Already installed",
"user" => "user",
"password" => "password",
"installation" => "installation",
"Before starting" => "Before starting",
"Welcome in Allerta. We need some informations about the database. You have to know the following informations:" => "Welcome in Allerta. We need some informations about the database. You have to know the following informations:",
"DB name" => "DB name",
"DB username" => "DB username",
"DB password" => "DB password",
"DB host" => "DB host",
"DB prefix" => "DB prefix",
"We will use this informations for creating a file" => "We will use this informations for creating a file",
"If for any reason automatic file creation doesn't work, don't worry. You can just open %s in a text editor, enter your details, and save it as" => "If for any reason automatic file creation doesn't work, don't worry. You can just open %s in a text editor, enter your details, and save it as",
"In all likelihood, this information has already been provided to you by your hosting provider. If you don't have this information, you'll need to contact your provider before you can continue. But if everything is ready..." => "In all likelihood, this information has already been provided to you by your hosting provider. If you don't have this information, you'll need to contact your provider before you can continue. But if everything is ready...",
"Submit" => "Submit",
"Configure the database connection" => "Configure the database connection",
"Below you can enter your database connection details. If you are not sure of the data to enter, contact your hosting provider" => "Below you can enter your database connection details. If you are not sure of the data to enter, contact your hosting provider",
"The name of the database you want to use with Allerta" => "The name of the database you want to use with Allerta",
"Your" => "Your",
"If %s doesn't work, you can get this information from your hosting provider" => "If %s doesn't work, you can get this information from your hosting provider",
"Edit this item if you want to perform multiple Alert installations on a single database" => "Edit this item if you want to perform multiple Alert installations on a single database",
"Error establishing a database connection" => "Error establishing a database connection",
"This could mean that %s and %s in file %s are wrong or that we cannot contact database %s. It could mean that your database is unreachable" => "This could mean that %s and %s in file %s are wrong or that we cannot contact database %s. It could mean that your database is unreachable",
"Are you sure that %s and %s correct?" => "Are you sure that %s and %s correct?",
"Are you sure you have entered the correct hostname?" => "Are you sure you have entered the correct hostname?",
"Are you sure the database server is up and running?" => "Are you sure the database server is up and running?",
"If you're not sure what these terms mean, try contacting your hosting provider. Try providing the following information:" => "If you're not sure what these terms mean, try contacting your hosting provider. Try providing the following information:",
"Advanced informations" => "Advanced informations",
"Try again" => "Try again",
"Cannot select database" => "Cannot select database",
"We were able to connect to the database server (which means your username and password are ok)" => "We were able to connect to the database server (which means your username and password are ok)",
"but we could not select the database" => "but we could not select the database",
"Are you sure that it exists?" => "Are you sure that it exists?",
"Does user %s have permissions to use database %s?" => "Does user %s have permissions to use database %s?",
"In some systems your database name has your username as a prefix, which is %s. Could this be the problem?" => "In some systems your database name has your username as a prefix, which is %s. Could this be the problem?",
"Cannot edit the configuration file" => "Cannot edit the configuration file",
"We were unable to write the configuration file %s, which is required for the program to work" => "We were unable to write the configuration file %s, which is required for the program to work",
"It is however possible to edit it manually by following the instructions below:" => "It is however possible to edit it manually by following the instructions below:",
"Access the Allerta installation folder (connect via FTP in case of cloud server)" => "Access the Allerta installation folder (connect via FTP in case of cloud server)",
"Rename the file %s to %s" => "Rename the file %s to %s",
"Replace the first 16 lines of the file with the following text:" => "Replace the first 16 lines of the file with the following text:",
"Unable to create tables" => "Unable to create tables",
"but we were unable to create the tables" => "but we were unable to create the tables",
"Unable to create tables" => "Unable to fill in the tables",
"but we were unable to fill in the tables" => "but we were unable to fill in the tables",
"Config created successful" => "Config created successful",
"DB Populated successful" => "DB Populated successful",
"Create the config file" => "Create the config file",
"This file is required for running %s" => "This file is required for running %s",
"Create a new config file" => "Create a new config file",
"Configuration file created successfully!" => "Configuration file created successfully!",
"Great job, man!" => "Great job, man!",
"You have completed this part of the installation. Allerta can now communicate with the database" => "You have completed this part of the installation. Allerta can now communicate with the database",
"If you are ready, it's time to..." => "If you are ready, it's time to...",
"Admin name" => "Admin name",
"Is admin visible?" => "Is admin visible?",
"Admin password" => "Admin password",
"Owner" => "Owner",
"Report email" => "Report email",
"Populate Allerta database" => "Populate Allerta database",
"This require a working %s file" => "This require a working %s file",
"Populate DB" => "Populate DB",
"Show version information and quit" => "Show version information and quit",
"Show this help and quit" => "Show this help and quit",
"Destination path" => "Destination path",
"%s is not writable. Directory permissions: %s" => "%s is not writable. Directory permissions: %s",
"%s not exists" => "%s not exists",
"Hurray!" => "Hurray!",
"You are almost finished installing Allerta, you just need to enter some information" => "You are almost finished installing Allerta, you just need to enter some information",
"Necessary informations:" => "Necessary informations:",
"Very weak" => "Very weak",
"Weak" => "Weak",
"Good" => "Good",
"Strong" => "Strong",
"Very strong" => "Very strong",
"Admin username" => "Admin username",
"Usernames can only contains alphanumeric characters, spaces, underscores, dashes, periods, and the @ symbol" => "Usernames can only contains alphanumeric characters, spaces, underscores, dashes, periods, and the @ symbol",
"Password" => "Password",
"Important:" => "Important:",
"You will need this password to log in. Keep it in a safe place" => "You will need this password to log in. Keep it in a safe place",
"Make admin user visible" => "Make admin user visible",
"to other users" => "to other users",
"By activating this option, the user that will be created will be visible in lists and procedures" => "By activating this option, the user that will be created will be visible in lists and procedures",
"Add developer permissions to admin user" => "Add developer permissions to admin user",
"By activating this option, the user will be able to debug Allerta" => "By activating this option, the user will be able to debug Allerta",
"Your email" => "Your email",
"Please check your email address carefully before continuing" => "Please check your email address carefully before continuing",
"It will be used in reports" => "It will be used in reports",
"Install Allerta" => "Install Allerta",
"Installation completed successfully" => "Installation completed successfully",
"You have completed the installation. Allerta can now function properly" => "You have completed the installation. Allerta can now function properly",
"Login" => "Login"
];

View File

@ -1,97 +0,0 @@
<?php
// Translated by: Matteo Gheza (matteogheza.it; github.com/matteogheza)
return [
"Already installed" => "Già installato",
"user" => "utente",
"password" => "password",
"installation" => "installazione",
"Before starting" => "Prima di inziare",
"Welcome in Allerta. We need some informations about the database. You have to know the following informations:" => "Benvenuto in Allerta. Abbiamo bisogno di qualche informazione per poterci connettere al DB. Devi conoscere le seguenti informazioni:",
"DB name" => "nome DB",
"DB username" => "username DB",
"DB password" => "password DB",
"DB host" => "host DB",
"DB prefix" => "prefisso DB",
"We will use this informations for creating a file" => "Useremo queste informazioni per creare un file",
"If for any reason automatic file creation doesn't work, don't worry. You can just open %s in a text editor, enter your details, and save it as" => "Se per un qualsiasi motivo la generazione automatica del file fallisse, non c'é problema. Basta aprire %s in un editor di testo, inserire le informazioni di contatto e salvare il file",
"In all likelihood, this information has already been provided to you by your hosting provider. If you don't have this information, you'll need to contact your provider before you can continue. But if everything is ready..." => "Molto probabilmente, queste informazioni ti sono state date dal tuo fornitore di hosting. Se non hai queste informazioni, contatta il fornitore prima di continuare. Ma se è tutto pronto...",
"Submit" => "Invia",
"Configure the database connection" => "Configura la connessione al database",
"Below you can enter your database connection details. If you are not sure of the data to enter, contact your hosting provider" => "Di seguito, potrai inserire le informazioni di connessione al database. Se non sai che informazioni inserire, contatta il tuo fornitore di hosting",
"The name of the database you want to use with Allerta" => "Il nome del database da usare per Allerta",
"Your" => "Il tuo",
"If %s doesn't work, you can get this information from your hosting provider" => "Se %s non funziona, richiedi queste informazioni al tuo fornitore di hosting",
"Edit this item if you want to perform multiple Alert installations on a single database" => "Modifica questo campo se vuoi installare più volte Allerta sullo stesso database",
"Error establishing a database connection" => "Errore nella connessione con il database",
"This could mean that %s and %s in file %s are wrong or that we cannot contact database %s. It could mean that your database is unreachable" => "Questo può significare che %s e %s nel file %s sono sbagliati o che il database %s non funziona. Può significare che il database non funziona",
"Are you sure that %s and %s correct?" => "Sei sicuro che %s e %s siano corretti?",
"Are you sure you have entered the correct hostname?" => "Sei sicuro che l'hostname sia corretto?",
"Are you sure the database server is up and running?" => "Sei sicuro che il server del database sia attivo?",
"If you're not sure what these terms mean, try contacting your hosting provider. Try providing the following information:" => "Se non sei sicuro del significato di questi termini, prova a contattare il tuo fornitore. Fornisci anche le seguenti informazioni:",
"Advanced informations" => "Informazioni avanzate",
"Try again" => "Riprova",
"Cannot select database" => "Impossibile selezionare il database",
"We were able to connect to the database server (which means your username and password are ok)" => "Siamo riusciti a connetterci al database (significa che username e password sono corretti)",
"but we could not select the database" => "ma non siamo riusciti a selezionare il database",
"Are you sure that it exists?" => "Sei siuro che esista?",
"Does user %s have permissions to use database %s?" => "L'utente %s ha il permesso di accedere al database %s?",
"In some systems your database name has your username as a prefix, which is %s. Could this be the problem?" => "In alcuni sistemi il nome del database ha per prefisso il nome utente, che sarebbe %s. Può essere questo il problema?",
"Cannot edit the configuration file" => "Impossibile modificare il file di configurazione",
"We were unable to write the configuration file %s, which is required for the program to work" => "Non siamo riusciti a scrivere il file %s, richiesto dal programmaper funzionare",
"It is however possible to edit it manually by following the instructions below:" => "E' tuttavia possibile modificarlo manualmente seguendo i seguenti passaggi:",
"Access the Allerta installation folder (connect via FTP in case of cloud server)" => "Accedi alla cartella di Allerta (connettiti via FTP on caso di server cloud)",
"Rename the file %s to %s" => "Rinomina il file %s in %s",
"Replace the first 16 lines of the file with the following text:" => "Sostituisci le prime 16 righe del file con il seguente testo:",
"Unable to create tables" => "Impossibile creare le tabelle",
"but we were unable to create the tables" => "ma non siamo riusciti a creare le tabelle",
"Unable to create tables" => "Impossibile riempire le tabelle",
"but we were unable to fill in the tables" => "ma non siamo riusciti a riempire le tabelle",
"Config created successful" => "Configurazione creata con successo",
"DB Populated successful" => "DB Riempito con successo",
"Create the config file" => "Crea il file di configurazione",
"This file is required for running %s" => "Questo file è richiesto per eseguire %s",
"Create a new config file" => "Crea un nuovo file di configurazione",
"Configuration file created successfully!" => "File di configurazione creato con successo!",
"Great job, man!" => "Ottimo lavoro, amico!",
"You have completed this part of the installation. Allerta can now communicate with the database" => "Hai completato questa parte dell'installazione. Allerta ora può comunicare con il database",
"If you are ready, it's time to..." => "Se sei pronto, è ora di...",
"Admin name" => "Nome dell'amministratore",
"Is admin visible?" => "L'amministratore deve essere visibile?",
"Admin password" => "Password dell'amministratore",
"Owner" => "Proprietario",
"Report email" => "Email per i report",
"Populate Allerta database" => "Riempi il database di Allerta",
"This require a working %s file" => "Questo richiede un file %s funzionante",
"Populate DB" => "Riempi il DB",
"Show version information and quit" => "Mostra informazioni sulla versione ed esci",
"Show this help and quit" => "Mostra questo messaggio ed esci",
"Destination path" => "Cartella di destinazione",
"%s is not writable. Directory permissions: %s" => "%s non è scrivibile. Permessi della cartella: %s",
"%s not exists" => "%s non esiste",
"Hurray!" => "Evviva!",
"You are almost finished installing Allerta, you just need to enter some information" => "L'installazione di Allerta è quasi terminata, devi solo inserire qualche informazione",
"Necessary informations:" => "Informazioni necessarie:",
"Very weak" => "Molto debole",
"Weak" => "Debole",
"Good" => "Buona",
"Strong" => "Forte",
"Very strong" => "Molto forte",
"Admin username" => "Username dell'amministratore",
"Usernames can only contains alphanumeric characters, spaces, underscores, dashes, periods, and the @ symbol" => "Lo username può contenere solo caratteri alfanumerici, spazi, trattini bassi, punti, virgole, e il simbolo @",
"Password" => "Password",
"Important:" => "Importante:",
"You will need this password to log in. Keep it in a safe place" => "Avrai bisogno di questa password per entrare. Conservala in un posto sicuro",
"Make admin user visible" => "Rendi l'amministratore visibile",
"to other users" => "agli altri utenti",
"By activating this option, the user that will be created will be visible in lists and procedures" => "Attivando questa opzione, l'utente che verrà creato sarà visibile nelle liste e nelle procedure",
"Add developer permissions to admin user" => "Aggiungi permessi da sviluppatore all'amministratore",
"By activating this option, the user will be able to debug Allerta" => "Attivando questa opzione, l'utente sarà in gradodi eseguire il debug di Allerta",
"Your email" => "La tua email",
"Please check your email address carefully before continuing" => "Per farvore, controlla con attenzione l'indirizzo email prima di continuare",
"It will be used in reports" => "Sarà usato nei report",
"Install Allerta" => "Installa Allerta",
"Installation completed successfully" => "Installazione completata con successo",
"You have completed the installation. Allerta can now function properly" => "Hai completato l'installazione. Allerta può ora funzionare correttamente",
"Login" => "Login"
];

File diff suppressed because one or more lines are too long

View File

@ -1,33 +0,0 @@
<?php
require_once 'ui.php';
if($JSless){
$user->online_time_update();
if(isset($_POST["action"]) && isset($_POST["user_id"]) && isset($_POST["token_list"]) && $_POST["token_list"] == $_SESSION["token_list"]){
if(!$user->hasRole(Role::FULL_VIEWER) && $_POST["user_id"] !== $user->auth->getUserId()){
http_response_code(401);
t("You are not authorized to perform this action.");
exit();
}
if($_POST["action"] == "activate"){
$db->update(
DB_PREFIX."_profiles",
["available" => 1, "availability_last_change" => "manual"],
["id" => $_POST["user_id"]]
);
$user->log("Status changed to 'available'", $_POST["user_id"], $user->auth->getUserId());
} else if($_POST["action"] == "deactivate"){
$db->update(
DB_PREFIX."_profiles",
["available" => 0, "availability_last_change" => "manual"],
["id" => $_POST["user_id"]]
);
$user->log("Status changed to 'not available'", $_POST["user_id"], $user->auth->getUserId());
}
}
$query_results = $db->select("SELECT * FROM `".DB_PREFIX."_profiles` ORDER BY available DESC, chief DESC, services ASC, availability_minutes ASC, name ASC");
} else {
$query_results = null;
}
$_SESSION["token_list"] = bin2hex(random_bytes(64));
loadtemplate('list.html', ['title' => t("Availability List", false), 'token_list' => $_SESSION['token_list'], 'query_results' => $query_results]);
bdump($_SESSION);

View File

@ -1,9 +0,0 @@
<?php
require_once 'ui.php';
if($JSless){
$user->online_time_update();
$query_results = $db->select("SELECT * FROM `".DB_PREFIX."_log` ORDER BY `timestamp` DESC");
} else {
$query_results = null;
}
loadtemplate('log.html', ['title' => t('Logs', false), 'query_results' => $query_results]);

View File

@ -1,6 +0,0 @@
<?php
require "core.php";
init_class();
$user->logout();
$tools->redirect("index.php");
?>

View File

@ -1,20 +0,0 @@
{
"name": "Allerta",
"short_name": "Allerta VVF",
"icons": [
{
"src": "resources/images/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "resources/images/android-chrome-384x384.png",
"sizes": "384x384",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"start_url": "list.php",
"display": "standalone"
}

View File

@ -1,270 +0,0 @@
<?php
require("core.php");
init_class(false);
$user->requirelogin(false);
// landscape means horizontal
// portrait means vertical
$orienation = isset($_POST["orientation"]) ? $_POST["orientation"] : "landscape";
echo("<!-- orientation: ".$orienation." !-->");
$hours = [
"0:00", "0:30",
"1:00", "1:30",
"2:00", "2:30",
"3:00", "3:30",
"4:00", "4:30",
"5:00", "5:30",
"6:00", "6:30",
"7:00", "7:30",
"8:00", "8:30",
"9:00", "9:30",
"10:00", "10:30",
"11:00", "11:30",
"12:00", "12:30",
"13:00", "13:30",
"14:00", "14:30",
"15:00", "15:30",
"16:00", "16:30",
"17:00", "17:30",
"18:00", "18:30",
"19:00", "19:30",
"20:00", "20:30",
"21:00", "21:30",
"22:00", "22:30",
"23:00", "23:30",
];
$days = [
t("Mon",false),
t("Tue",false),
t("Wed",false),
t("Thu",false),
t("Fri",false),
t("Sat",false),
t("Sun",false)
];
$nonce = isset($_GET["nonce"]) ? $_GET["nonce"] : "";
$user_id = $user->auth->getUserId();
$result = $db->select("SELECT * FROM `".DB_PREFIX."_schedules` WHERE `user`={$user_id}");
if(!empty($result)){
$old_schedules_db = json_decode($result[0]["schedules"]);
foreach ($old_schedules_db as $schedule) {
$hour = $schedule[1];
$hour = $hour[0] == "0" ? substr($hour,1) : $hour;
$old_schedules[$schedule[0]][$hour] = true;
}
$old_holidays = json_decode($result[0]["holidays"]);
if(is_null($old_holidays)){
$old_holidays = [];
}
} else {
$old_schedules = [];
$old_holidays = [];
}
?>
<style>
.hour-cell {
width: 100px;
height: 100px;
text-align: center;
vertical-align: middle;
background-color: #ccc;
border: 1px solid #fff;
}
.hour-cell.highlighted {
background-color: #999;
}
<?php
if($orienation == "landscape"):
?>
#scheduler_body td {
min-width: 40px;
}
<?php
endif;
?>
</style>
<table cellpadding="0" cellspacing="0" id="scheduler_table">
<thead>
<tr>
<td style="background-color: white;"></td>
<?php
if($orienation == "portrait") {
for($i=0;$i<7;$i++){
echo "<td id='$i' class='day'>{$days[$i]}</td>";
}
} else if($orienation == "landscape") {
foreach($hours as $hour) {
$hour_replaced = str_replace(":", "-", $hour);
echo "<td id='{$hour_replaced}' class='hour'>$hour</td>";
}
}
?>
</tr>
</thead>
<tbody id="scheduler_body">
<?php
if($orienation == "portrait") {
foreach($hours as $hour) {
echo "<tr>";
$hour_replaced = str_replace(":", "-", $hour);
echo "<td id='{$hour_replaced}' class='hour'>$hour</td>";
for($i=0;$i<7;$i++){
$is_schedule_highlighted = (isset($old_schedules[$i][$hour])) ? "highlighted ": "";
echo "<td class='hour-cell day-$i hour-{$hour_replaced} {$is_schedule_highlighted}'></td>";
}
echo "</tr>";
}
} else if($orienation == "landscape") {
for($i=0;$i<7;$i++){
echo "<tr>";
echo "<td id='$i' class='day'>{$days[$i]}</td>";
foreach($hours as $hour) {
$is_schedule_highlighted = (isset($old_schedules[$i][$hour])) ? "highlighted ": "";
$hour_replaced = str_replace(":", "-", $hour);
echo "<td class='hour-cell day-$i hour-{$hour_replaced} {$is_schedule_highlighted}'></td>";
}
echo "<td style='background-color: white;'></td></tr>";
}
}
?>
</tbody>
</table>
<br>
<?php
$holidays_selection_question = t("Do you want to exclude holidays from schedules?",false);
$holidays_select_all = t("Select all", false);
$holidays_select_none = t("Remove selections", false);
echo(<<<EOL
<div class="form-group">
<label>{$holidays_selection_question}</label>
<a id="select-all-holiday" class="text-primary">{$holidays_select_all}</a> / <a id="select-none-holiday" class="text-primary">{$holidays_select_none}</a>
<script nonce="{$nonce}">
$('#select-all-holiday').on("click",function(){
$('.holiday_check').prop('checked', true);
});
$('#select-none-holiday').on("click",function(){
$('.holiday_check').prop('checked', false);
});
</script>
EOL);
$i = 0;
foreach ($user->holidays as $holiday) {
$i++;
$holiday_name = $holiday->getName();
$holiday_shortname = $holiday->shortName;
$is_holiday_selected = in_array($holiday_shortname, $old_holidays) ? "checked" : "";
echo(<<<EOT
<div class="form-check">
<input class="form-check-input holiday_check" name="holiday_check" type="checkbox" value="{$holiday_shortname}" id="holidayCheckbox{$i}" {$is_holiday_selected}>
<label class="form-check-label" for="holidayCheckbox{$i}">
{$holiday_name} ({$holiday})
</label>
</div>
EOT);
}
echo("</div>");
?>
<script<?php if(get_option("enable_js_nonce")){ echo("nonce='$nonce'"); } ?>>
function init_modal() {
<?php if($orienation == "landscape"){ ?> $(".modal-dialog").css("max-width", "99%"); <?php } ?>
var isMouseDown = false;
$(document).mouseup(function () {
isMouseDown = false;
});
$(".hour-cell").mousedown(function () {
isMouseDown = true;
$(this).toggleClass("highlighted");
return false; // prevent text selection
}).mouseover(function () {
if (isMouseDown) {
$(this).toggleClass("highlighted");
}
});
function selectDay(id) {
console.log("day selection " + id);
if ($(event.target).hasClass("highlighted_all")) {
$("#scheduler_body .day-" + id).toggleClass("highlighted");
$(event.target).toggleClass("highlighted_all");
} else {
$("#scheduler_body .day-" + id).addClass("highlighted");
$(event.target).addClass("highlighted_all");
}
}
function selectHour(id) {
console.log("hour selection " + id);
if ($(event.target).hasClass("highlighted_all")) {
$("#scheduler_body .hour-" + id).toggleClass("highlighted");
$(event.target).toggleClass("highlighted_all");
} else {
$("#scheduler_body .hour-" + id).addClass("highlighted");
$(event.target).addClass("highlighted_all");
}
}
$(".day").mousedown(function () {
isMouseDown = true;
var id = event.target.id;
selectDay(id);
return false; // prevent text selection
}).mouseover(function () {
if (isMouseDown) {
var id = event.target.id;
selectDay(id);
}
});
$(".hour").mousedown(function () {
isMouseDown = true;
var id = event.target.id.replace(":", "-");
selectHour(id);
return false; // prevent text selection
}).mouseover(function () {
if (isMouseDown) {
var id = event.target.id.replace(":", "-");
selectHour(id);
}
});
$("#submit_schedules_change").unbind().on("click", submit_changes);
}
function extractSelections() {
hours_list = [];
$("#scheduler_body td.highlighted").each(function (key, value) {
var day = value.classList[1].replace("day-", "");
var hour = value.classList[2].replace("hour-", "").replace("-", ":");
if (hour.length < 5) hour = "0" + hour;
console.log(day, hour, value);
hours_list.push([day, hour]);
});
return hours_list;
}
function submit_changes() {
var hours = extractSelections();
var holidays = $.map($('input[name="holiday_check"]:checked'), function (c) {
return c.value;
});
$.ajax({
url: "resources/ajax/ajax_availability_schedule.php",
method: "POST",
data: {
hours: hours,
holidays: holidays
},
success: function success(data) {
console.log(data);
toastr.success('<?php t('Schedules updated successfully'); ?>');
}
});
}
</script>

View File

@ -1,3 +0,0 @@
<?php
require_once 'ui.php';
loadtemplate('offline.html', ['title' => t("You are offline", false)]);

View File

@ -1,12 +0,0 @@
<?php
include_once '../../core.php';
init_class();
$user->requirelogin(false);
$tmp_token = $tools->generateNonce(32);
$db->insert(
DB_PREFIX."_bot_telegram",
["tmp_login_token" => $tmp_token, "user" => $user->auth->getUserId()]
);
echo(json_encode(["token" => $tmp_token, "url" => "https://t.me/". BOT_TELEGRAM_USERNAME ."?start={$tmp_token}"]));

View File

@ -1,13 +0,0 @@
<?php
include_once '../../core.php';
init_class();
$user->requirelogin(false);
if(isset($_POST["type"])){
$type = $_POST["type"];
$db->insert(
DB_PREFIX."_type",
["name" => $type]
);
$user->log("Added service type");
}

View File

@ -1,31 +0,0 @@
<?php
include_once '../../core.php';
init_class(false);
$user->requirelogin(false);
$user_id = $user->auth->getUserId();
$result = $db->select("SELECT * FROM `".DB_PREFIX."_schedules` WHERE `user` = :id", ["id" => $user_id]);
if(!empty($result)){
$result[0]["schedules"] = json_decode($result[0]["schedules"]);
$result[0]["holidays"] = json_decode($result[0]["holidays"]);
}
if(isset($_POST["hours"]) && isset($_POST["holidays"])){
$hours = (string) json_encode($_POST["hours"]);
$holidays = (string) json_encode($_POST["holidays"]);
echo($hours."-".$holidays);
if(!empty($result)){
$db->update(
DB_PREFIX."_schedules",
["schedules" => $hours, "holidays" => $holidays],
["id" => $result[0]["id"]]
);
} else {
$db->insert(
DB_PREFIX."_schedules",
["schedules" => $hours, "holidays" => $holidays, "user" => $user_id]
);
}
} else {
echo(json_encode(empty($result)||is_null($result) ? [] : $result[0]));
}

View File

@ -1,62 +0,0 @@
<?php
include_once '../../core.php';
init_class();
$user->requirelogin(false);
$user->online_time_update();
function generate_message($change_user, $action){
global $user;
if($action == "activate"){
$action_string = "Thanks, %s, you have given %s in case of alert.";
} else {
$action_string = "Thanks, %s, you have removed %s in case of alert.";
}
if($change_user == $user->auth->getUserId()){
$user_string = t("your availability", false);
} else {
$user_string = sprintf(t("%s availability", false), $user->nameById($change_user));
}
return sprintf(t($action_string, false), $user->nameById($user->auth->getUserId()), $user_string);
}
if(!isset($_POST["change_id"]) || !isset($_POST["change_id"]) || !is_numeric($_POST["change_id"])){
http_response_code(400);
echo(json_encode(["message" => t("Bad request.",false)]));
exit();
} else {
$rows = $db->select(
"SELECT available FROM ".DB_PREFIX."_profiles WHERE id = ?",
[$_POST["change_id"]]
);
if(is_null($rows) || count($rows) !== 1) {
http_response_code(400);
echo(json_encode(["message" => t("Bad request.",false)." ".t("User not exists.",false)]));
exit();
}
}
if(!$user->hasRole(Role::FULL_VIEWER) && $_POST["change_id"] !== $user->auth->getUserId()){
http_response_code(401);
echo(json_encode(["message" => t("You are not authorized to perform this action.",false)]));
exit();
}
if($_POST["dispo"] == 1 /* && $_POST["token_list"] == $_SESSION['token_list'] */){
$db->update(
DB_PREFIX."_profiles",
["available" => 1, "availability_last_change" => "manual"],
["id" => $_POST["change_id"]]
);
$user->log("Status changed to 'available'", $_POST["change_id"], $user->auth->getUserId());
$message = generate_message($_POST["change_id"], "activate");
} else if($_POST["dispo"] == 0 /* && $_POST["token_list"] == $_SESSION['token_list'] */){
$db->update(
DB_PREFIX."_profiles",
["available" => 0, "availability_last_change" => "manual"],
["id" => $_POST["change_id"]]
);
$user->log("Status changed to 'not available'", $_POST["change_id"], $user->auth->getUserId());
$message = generate_message($_POST["change_id"], "deactivate");
}
echo(json_encode(["message" => $message]));
?>

View File

@ -1,43 +0,0 @@
<?php
include_once("../../core.php");
init_class();
$user->requirelogin(false);
$user->online_time_update();
$result = $db->select("SELECT * FROM `".DB_PREFIX."_profiles` ORDER BY available DESC, chief DESC, services ASC, availability_minutes ASC, name ASC");
$response = [];
foreach(!is_null($result) ? $result : [] as $row){
if(!$user->hidden($row["id"])){
if($user->hasRole(Role::FULL_VIEWER)){
$name = $user->nameById($row["id"]);
$name_encoded = urlencode($user->name());
$helmet_colour = $row["chief"] ? "red" : "black";
$firstCellName = (time()-$row["online_time"])<=30 ? "<u>".$name."</u>" : $name;
$firstCell = "<a data-clickable data-user='{$row['id']}' data-user-available='{$row['available']}' style='text-align: left;'><img alt='{$helmet_colour} helmet' src='./resources/images/{$helmet_colour}_helmet.png' width='20px'>$firstCellName</a>";
$secondCell = $row["available"] ? "<a data-clickable><i class='fa fa-check' style='color:green'></i></a>" : "<a data-clickable><i class='fa fa-times' style='color:red'></i></a>";
$response[] = [
$firstCell,
$secondCell,
$row['driver'] ? "<img alt='driver' src='./resources/images/wheel.png' width='20px'>" : "",
!empty($row['phone_number']) ? "<a href='tel:".$row['phone_number']."'><i class='fa fa-phone'></i></a>" : "",
!empty($row['phone_number']) ? "<a href='https://api.whatsapp.com/send?phone=".$row['phone_number']."&text=ALLERTA IN CORSO.%20Mettiti%20in%20contatto%20con%20$name_encoded'><i class='fa fa-whatsapp' style='color:green'></i></a>" : "",
$row['services'],
$row['availability_minutes'],
//"<a href='user_details.php?user=".$row['id']."'><p>".t("Altri dettagli", false)."</p></a>" TODO: fix "Other" page
];
} else {
$name = $user->nameById($row["id"]);
$helmet_colour = $row["chief"] ? "red" : "black";
$firstCellName = (time()-$row["online_time"])<=30 ? "<u>".$name."</u>" : $name;
$firstCell = "<a style='text-align: left;'><img alt='{$helmet_colour} helmet' src='./resources/images/{$helmet_colour}_helmet.png' width='20px'>$firstCellName</a>";
$secondCell = $row["available"] ? "<a><i class='fa fa-check' style='color:green'></i></a>" : "<a><i class='fa fa-times' style='color:red'></i></a>";
$response[] = [
$firstCell,
$secondCell
];
}
}
}
$tools->ajax_page_response($response);
?>

View File

@ -1,44 +0,0 @@
<?php
include_once("../../core.php");
init_class();
$user->requirelogin(false);
$user->online_time_update();
$result = $db->select("SELECT * FROM `".DB_PREFIX."_log` ORDER BY `timestamp` DESC");
//https://stackoverflow.com/a/2524761
function isValidTimeStamp($timestamp)
{
return ((string) (int) $timestamp === $timestamp)
&& ($timestamp <= PHP_INT_MAX)
&& ($timestamp >= ~PHP_INT_MAX);
}
$response = [];
foreach(!is_null($result) ? $result : [] as $row){
if(isValidTimeStamp($row["timestamp"])){
$date = new DateTime();
$date->setTimestamp($row["timestamp"]);
$date = $date->format('Y-m-d H:i:s');
} else {
$date = $row["timestamp"];
}
if(!is_null($row["changed"])){
$changedName = $user->nameById($row["changed"]);
} else {
$changedName = "N/A";
}
if(!is_null($row["editor"])){
$editorName = $user->nameById($row["editor"]);
} else {
$editorName = "N/A";
}
$response[] = [
t($row["action"], false),
$changedName,
$editorName,
$date
];
}
$tools->ajax_page_response($response);
?>

View File

@ -1,40 +0,0 @@
<?php
include_once("../../core.php");
init_class();
$user->requirelogin(false);
$user->online_time_update();
$result = $db->select("SELECT * FROM `".DB_PREFIX."_services` ORDER BY date DESC, beginning DESC");
$response = [];
foreach(!is_null($result) ? $result : [] as $row){
$chief = $user->nameById($row["chief"]);
$drivers_array = explode(",", $row['drivers']);
foreach($drivers_array as $key=>$name){
$drivers_array[$key] = $user->nameById($name);
}
$drivers = implode(", ", $drivers_array);
$others_crew_array = explode(",", $row['crew']);
foreach($others_crew_array as $key=>$name){
$others_crew_array[$key] = $user->nameById($name);
}
$others_crew = implode(", ", $others_crew_array);
$response[] = [
$row['date'],
$row['code'],
$row['beginning'],
$row['end'],
$chief,
$drivers,
$others_crew,
s($row['place'],false,true),
s($row['notes'],false,true),
s($row['type'],false,true),
get_option("service_edit") ? "<a class='pjax_disable' data-action='edit' href='edit_service.php?edit&id={$row['id']}'><i style='font-size: 40px' class='fa fa-edit'></i></a>" : null,
get_option("service_remove") ? "<a class='pjax_disable' data-action='delete' href='edit_service.php?delete&id={$row['id']}'><i style='font-size: 40px' class='fa fa-trash'></i></a>" : null
];
}
$tools->ajax_page_response($response);
?>

View File

@ -1,32 +0,0 @@
<?php
include_once("../../core.php");
init_class();
$user->requirelogin(false);
$user->online_time_update();
$result = $db->select("SELECT * FROM `".DB_PREFIX."_trainings` ORDER BY date DESC, beginning desc");
$response = [];
foreach(!is_null($result) ? $result : [] as $row){
$chief = $user->nameById($row["chief"]);
$others_crew_array = explode(",", $row['crew']);
foreach($others_crew_array as $key=>$name){
$others_crew_array[$key] = $user->nameById($name);
}
$others_crew = implode(", ", $others_crew_array);
$response[] = [
$row['date'],
$row['name'],
$row['beginning'],
$row['end'],
$chief,
$others_crew,
s($row['place'],false,true),
s($row['notes'],false,true),
get_option("training_edit") ? "<a class='pjax_disable' data-action='edit' href='edit_training.php?edit&id={$row['id']}'><i style='font-size: 40px' class='fa fa-edit'></i></a>" : null,
get_option("training_remove") ? "<a class='pjax_disable' data-action='delete' href='edit_training.php?delete&id={$row['id']}'><i style='font-size: 40px' class='fa fa-trash'></i></a>" : null
];
}
$tools->ajax_page_response($response);
?>

View File

@ -1,8 +0,0 @@
{
"sentryEnabled": false,
"sentryDsn": "",
"sentryEnvironment": "prod",
"sentryAuthToken": "",
"sentryOrganization": "",
"sentryProject": ""
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -1,20 +0,0 @@
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-384x384.png",
"sizes": "384x384",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"start_url": "http://localhost:8080/",
"display": "standalone"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,2 +0,0 @@
$fa-font-path: "~font-awesome/fonts";
@import '~font-awesome/scss/font-awesome.scss';

View File

@ -1,32 +0,0 @@
const GAME_LOADING_ERROR_MSG = "Game loading failed, please retry later.";
async function play (game) {
console.log("Opening game " + game + "...");
try {
await import(`./games/${game}/game.js`)
.then(({ default: Game }) => {
const game = new Game();
$("body").append("<div class=\"modal\" id=\"modal_game\" tabindex=\"-1\" role=\"dialog\" data-backdrop=\"static\" style=\"display: none; min-width: 100%; margin: 0px;\"><div class=\"modal-dialog\" role=\"document\" style=\"min-width: 100%; margin: 0;\"><div class=\"modal-content\" style=\"min-height: 100vh;\" id=\"modal_game_content\"></div></div></div>");
$("#modal_game_content").append(`<div class="modal-header"><h5 class="modal-title" style="color: black">${game.title}</h5><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button></div><div class="modal-body" id="modal_game_body"></div>`);
$("#modal_game_body").append(`<div id="game_content" style="text-align: center"></div><p style="text-align: right; color: black;">Game by <a style="color: blue" target="_blank" href="${game.authorUrl}">${game.author}</a></p>`);
$("#modal_game").modal("show");
game.initialize($("#game_content"));
});
$("#modal_game").on("hidden.bs.modal", function (e) {
$("#modal_game").remove();
});
} catch (error) {
console.error(error);
toastr.error(GAME_LOADING_ERROR_MSG);
}
}
$(function() {
$(".playGame").each((num, elem) => {
console.log(num, elem);
let game = elem.getAttribute("data-game");
if(game !== null){
$(elem).on("click", function(){ play(game); });
}
});
});

View File

@ -1,11 +0,0 @@
export default class {
constructor(){
this.title = "Empty game";
this.author = "Prova";
this.authorUrl = "https://example.com/";
}
initialize(container){
container.append("<b>THIS IS THE GAME</b>");
}
}

View File

@ -1,30 +0,0 @@
import {default as createUnityInstance} from "./ld46.loader.js";
import buildSizeData from "./ld46.data.gz";
import buildSizeFramework from "./ld46.framework.js.gz";
import buildSizeWasm from "./ld46.wasm.gz";
console.log("data "+buildSizeData);
console.log("framework "+buildSizeFramework);
console.log("wasm "+buildSizeWasm);
export default class {
constructor(){
this.title = "What the firetruck";
this.author = "dvdfu";
this.authorUrl = "https://github.com/dvdfu";
}
initialize(container){
container.append("<canvas id='unity-canvas' style='width: 768px; height: 512px; background: #231F20'></canvas>");
createUnityInstance(document.querySelector("#unity-canvas"), {
dataUrl: __webpack_public_path__ + "ld46.data.gz",
frameworkUrl: __webpack_public_path__ + "ld46.framework.js.gz",
codeUrl: __webpack_public_path__ + "ld46.wasm.gz",
streamingAssetsUrl: "StreamingAssets",
companyName: "dvdfu",
productName: "ld46",
productVersion: "0.1",
});
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,241 +0,0 @@
#jsDisabledNotice {
display: none;
}
body:not(table) {
max-width: 100%;
overflow-x: hidden;
}
@keyframes gradual_blur {
0% { -webkit-filter: blur(0); }
50% { -webkit-filter: blur(2px); }
100% { -webkit-filter: blur(5px); }
}
.loading_blur {
animation: gradual_blur 1s;
animation-fill-mode: forwards;
cursor: wait;
}
.loading_no_blur {
animation: gradual_blur 1s;
animation-direction: reverse;
animation-fill-mode: forwards;
}
.loading_overlay {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
center {
text-align: center;
}
#modulogin {
margin-top: 60px;
padding: 30px 0 30px 0;
width: 90%;
height: auto;
background: #fafafa;
border-radius: 15px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
input::placeholder {
color: lightgray;
}
.modal-text {
margin-top: 15px;
line-height: 25px;
/*
font-size: 1em;
font-family: calibri;
*/
}
/* Add a black background color to the top navigation */
.topnav {
background-color: red;
overflow: hidden;
}
/* Style the links inside the navigation bar */
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
/* Change the color of links on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
}
/* Add an active class to highlight the current page */
.active {
background-color: #4caf50;
color: white;
}
/* Hide the link that should open and close the topnav on small screens */
.topnav .icon {
display: none;
}
/* When the screen is less than 600 pixels wide, hide all links, except for the first one ("Home"). Show the link that contains should open and close the topnav (.icon) */
@media screen and (max-width: 600px) {
.topnav a:not(:first-child) {
display: none;
}
.topnav a.icon {
float: right;
display: block;
}
}
/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens (display the links vertically instead of horizontally) */
@media screen and (max-width: 600px) {
.topnav.responsive {
position: relative;
}
.topnav.responsive a.icon {
position: absolute;
right: 0;
top: 0;
}
.topnav.responsive a {
float: none;
display: block;
text-align: left;
}
}
#bottom {
background-color: grey;
color: white;
}
div.img {
border: 2px solid white;
float: left;
margin: 10px;
width: 100px;
height: 100px;
}
#add {
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font: bold 12px Arial, Helvetica, sans-serif;
color: #fff;
padding: 10px 20px;
border: solid 1px #0076a3;
background: #0095cd;
}
.form_input {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
box-sizing: border-box;
}
button {
background-color: #4caf50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
cursor: pointer;
}
button:hover {
opacity: 0.8;
}
.container {
padding: 16px;
}
span.psw {
float: right;
padding-top: 16px;
}
/* Change styles for span and cancel button on extra small screens */
@media screen and (max-width: 300px) {
span.psw {
display: block;
float: none;
}
.cancelbtn {
width: 100%;
}
}
textarea {
width: 100%;
height: 150px;
padding: 12px 20px;
box-sizing: border-box;
border: 2px solid #ccc;
border-radius: 4px;
background-color: #f8f8f8;
resize: none;
}
#href {
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font: bold 12px Arial, Helvetica, sans-serif;
color: #fff;
padding: 10px 20px;
border: solid 1px #0076a3;
background: #0095cd;
}
table {
margin: auto;
max-width: 95%;
text-align: center;
overflow-x: auto;
}
#table_wrapper {
margin-left: auto;
margin-right: auto;
width: 95%;
}
th,
td {
text-align: center;
vertical-align: middle !important;
}
.fa {
vertical-align: middle;
font-size: 20px;
}

View File

@ -1,370 +0,0 @@
import "bootstrap";
import "bootstrap/dist/css/bootstrap.min.css";
import "./main.css";
import "./font-awesome.scss";
import "bootstrap-datepicker";
import "../node_modules/bootstrap-toggle/css/bootstrap-toggle.css";
import "../node_modules/bootstrap-toggle/js/bootstrap-toggle.js";
import "../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.css";
import "time-input-polyfill/auto";
import "jquery-pjax";
import toastr from "expose-loader?exposes=toastr!toastr";
import "toastr/build/toastr.css";
window.toastr = toastr;
toastr.options = {
closeButton: false,
debug: false,
newestOnTop: false,
progressBar: true,
positionClass: "toast-bottom-right",
preventDuplicates: false,
onclick: null,
showDuration: "300",
hideDuration: "1000",
timeOut: "5000",
extendedTimeOut: "1000",
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
};
if(!('fetch' in window)){
import(`./polyfills.js`).then((_ ) => {
window.Promise = _.Promise;
window.fetch = _.fetch;
});
}
function objectToURLParams(list){
let params = new URLSearchParams();
list.forEach((el) => {
params.append(el[0], el[1]);
});
return params.toString();
}
function displayResponseMessage(r){
console.log(r);
let statusCode = r.status;
r.json().then(r => {
if(statusCode === 200){
toastr.success(r.message);
} else {
toastr.error(r.message);
}
});
}
$.fn.loading = function (action = "start", options) {
const opts = $.extend({}, $.fn.loading.defaults, options);
if (action === "show") {
this.addClass("loading_blur");
let message_b = $("<b>").text(opts.message);
let message = $("<div>", {id: "loading_div", "class": "loading_overlay"}).append(message_b);
$("body").append(message);
} else if (action === "hide") {
this.removeClass("loading_blur");
this.addClass("loading_no_blur");
setTimeout(() => {
this.removeClass("loading_no_blur");
}, 1000);
$("#loading_div").remove();
}
};
$.fn.loading.defaults = {
message: "Loading..."
};
console.log("Commit: " + process.env.GIT_VERSION);
console.log("Date: " + process.env.GIT_AUTHOR_DATE);
console.log("Bundle mode: " + process.env.BUNDLE_MODE);
console.log("Bundle date: " + new Date(process.env.BUNDLE_DATE).toISOString());
$(document).pjax("a:not(.pjax_disable)", "#content", { timeout: 100000 });
$(document).on("pjax:start", function () {
if (document.getElementById("topNavBar") !== undefined) {
document.getElementById("topNavBar").className = "topnav";
}
oldData = "null";
fillTable = undefined;
tableEngine = "datatables";
if (loadTableInterval !== undefined) {
clearInterval(loadTableInterval);
loadTableInterval = undefined;
}
});
// Cookie functions from w3schools
function setCookie (cname, cvalue, exdays) {
const d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
const expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie (cname) {
const name = cname + "=";
const decodedCookie = decodeURIComponent(document.cookie);
const ca = decodedCookie.split(";");
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === " ") {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
$(document).ajaxError(function (event, xhr, settings, error) {
console.error("Error requesting content: " + error + " - status code " + xhr.status);
console.log(event);
console.log(xhr);
console.log(settings);
});
if (getCookie("authenticated")) {
var installServiceWorker = true;
if (window.skipServiceWorkerInstallation !== undefined) { // if you want to disable SW for example via GreasyFork userscript
installServiceWorker = false;
}
if (getCookie("disableServiceWorkerInstallation")) {
console.log("Skipping ServiceWorker installation because cookie 'disableServiceWorkerInstallation' exists");
installServiceWorker = false;
}
if ("serviceWorker" in navigator) {
if ("connection" in navigator && navigator.connection.saveData && !getCookie("forceServiceWorkerInstallation")) {
console.log("Skipping ServiceWorker installation because saveData is enabled");
installServiceWorker = false;
}
if ("storage" in navigator && "estimate" in navigator.storage && !getCookie("forceServiceWorkerInstallation")) {
navigator.storage.estimate().then((quota) => {
const requiredMemory = 3 * 1e+6;
if (quota < requiredMemory) {
console.log("Skipping ServiceWorker installation because memory is low. memory=" + quota);
installServiceWorker = false;
}
});
}
} else {
installServiceWorker = false;
}
}
if (installServiceWorker) {
window.addEventListener("load", () => {
navigator.serviceWorker.register("sw.js").then((registration) => {
console.log("SW registered: ", registration);
}).catch((registrationError) => {
console.log("SW registration failed: ", registrationError);
});
});
}
var offline = false;
var loadTableInterval = undefined;
var oldData = "null";
var tableEngine = "datatables";
var fillTable = undefined;
var fillTableLoaded = undefined;
window.addEventListener("securitypolicyviolation", console.error.bind(console));
$(function() {
if(getCookie("JSless")){
location.href="?JSless=0";
}
$("#topNavBar").show();
$("#content").show();
$("#footer").show();
if ($("#frontend_version") !== undefined) {
$("#frontend_version").append(process.env.GIT_VERSION + " aggiornamento " + new Date(process.env.BUNDLE_DATE).toLocaleString());
}
$("#menuButton").on("click", function() {
const topNavBar = document.getElementById("topNavBar");
if (topNavBar.className === "topnav") {
topNavBar.className += " responsive";
} else {
topNavBar.className = "topnav";
}
});
$("#logout-text").on("click", function(){ location.href='logout.php'; });
});
export var lastTableLoadConfig = {
tablePage: undefined,
setTableRefreshInterval: true,
interval: 10000,
onlineReload: false,
useCustomTableEngine: false,
callback: false
}
export async function loadTable ({ tablePage, setTableRefreshInterval = true, interval = 10000, onlineReload = false, useCustomTableEngine = false, callbackRepeat = false, callback = false, saveFuncParam = true }) {
if(loadTableInterval !== undefined) {
clearInterval(loadTableInterval);
loadTableInterval = undefined;
}
if (typeof fillTable === "undefined") {
if (useCustomTableEngine !== false) {
tableEngine = useCustomTableEngine;
} else {
tableEngine = "datatables";
}
fillTableLoaded = await import(/* webpackChunkName: `[request]` */ `./table_engine_${tableEngine}.js`)
.then(({ default: _ }) => {
return _;
});
}
if ("getBattery" in navigator) {
navigator.getBattery().then((level, charging) => {
if (!charging && level < 0.2) {
return;
}
});
}
if ("deviceMemory" in navigator && navigator.deviceMemory < 0.2) {
return;
}
if(saveFuncParam){
lastTableLoadConfig = {
tablePage: tablePage,
setTableRefreshInterval: setTableRefreshInterval,
interval: interval,
onlineReload: onlineReload,
useCustomTableEngine: useCustomTableEngine,
callback: callback
}
}
const replaceLatLngWithMap = tablePage === "services" || tablePage === "trainings";
$.getJSON({
url: "resources/ajax/ajax_" + tablePage + ".php",
data: { oldData: oldData },
success: function (data, status, xhr) {
oldData = xhr.getResponseHeader("data"); // TODO: refactoring and adding comments
console.log(data);
if (data.length > 0) {
fillTableLoaded({ data, replaceLatLngWithMap, callback });
if(typeof(Headers) == "function"){
const headers = new Headers();
headers.append("date", Date.now());
caches.open("tables-1").then((cache) => {
cache.put("/table_" + tablePage + ".json", new Response(xhr.responseText, { headers: headers }));
});
}
}
if (offline) { // if xhr request successful, client is online
console.log(onlineReload);
if (onlineReload) {
location.reload(); // for offline page
} else {
$("#offline_alert").hide(400);
offline = false;
}
}
}
}).fail(function (data, status) {
if (status === "parsererror") {
if ($("#table_body").children().length === 0) { // this is a server-side authentication error on some cheap hosting providers
loadTable(tablePage, setTableRefreshInterval, interval); // retry
} // else nothing
} else {
caches.open("tables-1").then((cache) => {
cache.match("/table_" + tablePage + ".json").then((response) => {
response.json().then((data) => {
fillTableLoaded({ data, replaceLatLngWithMap, callback });
console.log("Table loaded from cache");
$("#offline_update").text(new Date(parseInt(response.headers.get("date"), 10)).toLocaleString());
});
});
});
if (!offline) { // if xhr request fails, client is offline
$("#offline_alert").show(400);
offline = true;
}
}
});
if (setTableRefreshInterval) {
if ("connection" in navigator && navigator.connection.saveData) {
interval += 5000;
}
console.log("table_load interval " + interval);
loadTableInterval = setInterval(function () {
loadTable({ tablePage, setTableRefreshInterval: false, interval, onlineReload, useCustomTableEngine, callback: callbackRepeat ? callback : false, saveFuncParam: false });
}, interval);
}
}
export function reloadTable(){
allertaJS.main.loadTable({
tablePage: lastTableLoadConfig.tablePage,
setTableRefreshInterval: lastTableLoadConfig.setTableRefreshInterval,
interval: lastTableLoadConfig.interval,
onlineReload: lastTableLoadConfig.onlineReload,
useCustomTableEngine: lastTableLoadConfig.useCustomTableEngine,
callback: lastTableLoadConfig.callback,
});
if (loadTableInterval !== undefined) {
clearInterval(loadTableInterval);
loadTableInterval = undefined;
}
}
export function activate(id, token_list) {
fetch("resources/ajax/ajax_change_availability.php", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: objectToURLParams([
["change_id", id],
["dispo", 1],
["token_list", token_list]
])
}).then(r => {
displayResponseMessage(r);
allertaJS.main.reloadTable();
});
}
export function deactivate(id, token_list) {
fetch("resources/ajax/ajax_change_availability.php", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: objectToURLParams([
["change_id", id],
["dispo", 0],
["token_list", token_list]
])
}).then(r => {
displayResponseMessage(r);
allertaJS.main.reloadTable();
});
}
export function loadListListCallback(){
$("tbody tr").on("click", function(event) {
let targetElem = event.target;
let userInfoElem = event.currentTarget.querySelector("[data-user]");
let userId = userInfoElem.dataset.user;
if(
targetElem.hasAttribute("data-clickable") ||
targetElem.parentElement.hasAttribute("data-clickable") ||
(targetElem.childElementCount > 0 && targetElem.firstElementChild.hasAttribute("data-clickable"))
){
if(userInfoElem.dataset.userAvailable === "1") {
allertaJS.main.deactivate(userId,0);
} else {
allertaJS.main.activate(userId,0);
}
}
});
}

View File

@ -1,33 +0,0 @@
div#map {
width: 100%;
height: 500px;
}
.map {
width: 100%;
height: 500px;
}
div#search {
background-color: rgba(255, 255, 255, 0.4);
bottom: 40px;
left: 40px;
width: auto;
height: auto;
padding: 10px;
}
div#results {
font-style: sans-serif;
color: black;
font-size: 75%;
}
.fa.fa-map-marker-alt,
.fa.fa-spinner.fa-spin {
line-height: inherit;
}
.leaflet-pane.leaflet-shadow-pane {
display: none;
}

View File

@ -1,283 +0,0 @@
import L from "leaflet";
import "leaflet.locatecontrol";
import "../node_modules/leaflet.locatecontrol/dist/L.Control.Locate.min.css";
import "../node_modules/leaflet/dist/leaflet.css";
import "./maps.css";
const iconRetinaUrl = "resources/dist/marker-icon-2x.png";
const iconUrl = "resources/dist/marker-icon.png";
const shadowUrl = "resources/dist/marker-shadow.png";
const iconDefault = new L.Icon({
iconRetinaUrl,
iconUrl,
shadowUrl,
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
tooltipAnchor: [16, -28],
shadowSize: [41, 41]
});
var marker;
var feature;
var map;
export function setMarker (LatLng, move=false) {
if (marker) {
console.log("Marker exists");
// console.log(marker);
marker.remove();
}
console.log(LatLng);
if ($("input[name='place']").val() !== undefined) {
$("input[name='place']").val(LatLng.lat + ";" + LatLng.lng);
}
console.log(map);
marker = L.marker(LatLng, { icon: iconDefault }).addTo(map);
if(move){
map.setView(LatLng, 17);
}
}
var mapsList = [];
export function loadMap (lat = undefined, lng = undefined, selectorId = undefined, select = true, removeMap = false) {
console.log("Loading map...", [lat, lng, selectorId, select]);
console.trace();
if (lat === undefined && lng === undefined) {
lat = 45.5285; // TODO: replace hard-coded into cookie reading
lng = 10.2956;
}
if (selectorId === undefined) {
selectorId = "map";
}
let container = L.DomUtil.get(selectorId);
console.log(container);
try{
if(container._leaflet_id){
console.log(mapsList);
if(removeMap){
mapsList[0].off();
mapsList[0].remove();
mapsList.splice(0, 1);
} else {
console.log("Skipping map loading because already loaded...");
return true;
}
}
} catch(e){
//console.log(e);
console.log("Skipping map loading...");
return true;
}
const zoom = select ? 10 : 17;
const latLng = new L.LatLng(lat, lng);
L.Map.addInitHook(function () {
mapsList.push(this); // Use whatever global scope variable you like.
});
map = new L.Map(selectorId, { zoomControl: true });
const osmUrl = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
const osmAttribution = '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';
const osm = new L.TileLayer(osmUrl, { maxZoom: 20, attribution: osmAttribution });
map.setView(latLng, zoom).addLayer(osm);
if (select) {
map.on("click", function (e) {
setMarker(e.latlng);
});
L.Control.CustomLocate = L.Control.Locate.extend({
_drawMarker: function () {
setMarker(this._event.latlng);
},
_onDrag: function () {},
_onZoom: function () {},
_onZoomEnd: function () {}
});
const lc = new L.Control.CustomLocate({
icon: "fa fa-map-marker",
cacheLocation: false, // disabled for privacy reasons
initialZoomLevel: 16
}).addTo(map);
if ($("#addr").val() !== undefined) {
document.getElementById("addr").addEventListener("keydown", function (event) {
if (event.key === "Enter") {
event.preventDefault();
$("#search > button").trigger("click");
}
});
}
window.addEventListener("focus", function (event) {
if ($("#addr").val() === "") {
console.log("Loading location from clipboard");
try {
navigator.clipboard.readText().then((text) => {
$("#addr").val(text);
if (!addrSearch()) {
$("#addr").val("");
}
}).catch((err) => {
console.error("Failed to read clipboard contents: ", err);
});
} catch(error) {
console.error(error);
}
}
});
} else {
setMarker(latLng);
}
map.invalidateSize();
}
// from unknown source in the Internet
export function chooseAddr (addrLat, addrLng, zoom = undefined, lat1 = undefined, lng1 = undefined, lat2 = undefined, lng2 = undefined, osmType = undefined) {
addrLat = addrLat.replace(",", ".");
addrLng = addrLng.replace(",", ".");
if (lat1 !== undefined && lng1 !== undefined && lat2 !== undefined && lng2 !== undefined && osmType !== undefined) {
const loc1 = new L.LatLng(lat1, lng1);
const loc2 = new L.LatLng(lat2, lng2);
const bounds = new L.LatLngBounds(loc1, loc2);
console.log(lat1, lng1, lat2, lng2, osmType);
setMarker(new L.LatLng(addrLat, addrLng));
if (feature) {
map.removeLayer(feature);
}
if (osmType === "node") {
map.fitBounds(bounds);
map.setZoom(16);
} else {
const loc3 = new L.LatLng(lat1, lng2);
const loc4 = new L.LatLng(lat2, lng1);
feature = L.polyline([loc1, loc4, loc2, loc3, loc1], { color: "red" }).addTo(map);
map.fitBounds(bounds);
map.setZoom(16);
}
} else if (addrLat !== undefined && addrLng !== undefined) {
const loc = new L.LatLng(addrLat, addrLng);
console.log(loc);
setMarker(loc);
if (zoom !== undefined) {
map.setView(loc, zoom);
} else {
map.setView(loc);
}
}
}
// started from https://derickrethans.nl/leaflet-and-nominatim.html
export function addrSearch (stringResultsFound= undefined, stringResultsNotFound = undefined) {
function searchError (error, checkClipboard) {
if (!checkClipboard) {
$("#results").empty();
$("<p>", { html: stringResultsNotFound }).appendTo("#results");
console.error(error);
}
return false;
}
let inp = document.getElementById("addr").value;
// if translation strings are not defined, skip the nominatim step and don't log errors (no console.error)
const checkClipboard = stringResultsFound=== undefined && stringResultsNotFound === undefined;
$("#results").empty();
if (inp.match("\@(-?[\d\.]*)")) { // Google Maps
try {
inp = inp.split("@")[1].split(",");
chooseAddr(inp[0], inp[1]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if (inp.includes("#map=")) { // OpenStreetMap website
try {
inp = inp.split("#map=")[1].split("/");
chooseAddr(inp[1], inp[2], inp[0]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if (inp.match(/[0-9]+,\s[0-9]+/)) { // Bing
try {
inp = inp.split(", ");
chooseAddr(inp[0], inp[1]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if (inp.match(/[0-9]+;[0-9]+/)) { // DB dump
try {
inp = inp.split(";");
chooseAddr(inp[0], inp[1]);
return true;
} catch (error) {
searchError(error, checkClipboard);
}
} else if (!checkClipboard) {
$.getJSON("https://nominatim.openstreetmap.org/search?format=json&limit=5&q=" + inp, function (data) {
console.log(data);
var list = document.createElement('ul');
list.classList.add("results-list");
$.each(data, function (key, val) {
var item_a = document.createElement('a');
item_a.href = "#";
item_a.textContent = val.display_name;
item_a.dataset.addrLat = val.lat;
item_a.dataset.addrLng = val.lon;
item_a.dataset.zoom = undefined;
item_a.dataset.lat1 = val.boundingbox[0];
item_a.dataset.lng1 = val.boundingbox[2];
item_a.dataset.lat2 = val.boundingbox[1];
item_a.dataset.lng2 = val.boundingbox[3];
item_a.dataset.osmType = val.osm_type;
var item = document.createElement('li');
item.appendChild(item_a);
list.appendChild(item);
});
console.log(list);
if (data.length !== 0) {
$("#results").empty();
$("<p>", { html: stringResultsFound+ ":" }).appendTo("#results");
$(list).appendTo("#results");
$("#results li").on("click",function(e){
e.preventDefault()
var row = e.target;
console.log(row);
console.log(row.dataset);
allertaJS.maps.chooseAddr(
row.dataset.addrLat,
row.dataset.addrLng,
row.dataset.zoom,
row.dataset.lat1,
row.dataset.lng1,
row.dataset.lat2,
row.dataset.lng2,
row.dataset.osmType
);
})
} else {
$("#results").empty();
$("<p>", { html: stringResultsNotFound }).appendTo("#results");
}
});
} else {
return false;
}
}
$(function () {
if(typeof loadMapOnScriptLoad !== undefined){
console.log("Loading map...");
allertaJS.maps.loadMap();
}
});

View File

@ -1 +0,0 @@
import { Howl, Howler } from "howler";

View File

@ -1,7 +0,0 @@
import Promise from 'promise-polyfill';
import {fetch as fetchPolyfill} from 'whatwg-fetch'
export {
Promise,
fetchPolyfill as fetch
};

View File

@ -1,16 +0,0 @@
import * as Sentry from "@sentry/browser";
import { Integrations } from "@sentry/tracing";
if (process.env.config && process.env.config.sentryEnabled) {
if ("connection" in navigator && navigator.connection.saveData) {
console.log("Skipping Sentry init because data save is enabled");
} else {
Sentry.init({
dsn: process.env.config.sentryDsn,
integrations: [new Integrations.BrowserTracing()],
tracesSampleRate: 0.6,
release: "allerta-vvf-frontend@" + process.env.GIT_VERSION,
environment: process.env.config.sentryEnvironment
});
}
}

View File

@ -1,159 +0,0 @@
import jsZip from "jszip";
window.JSZip = jsZip;
import pdfMake from "pdfmake/build/pdfmake";
pdfMake.vfs = pdfFonts.pdfMake.vfs;
import pdfFonts from "pdfmake/build/vfs_fonts";
import "datatables.net-bs4/js/dataTables.bootstrap4.min.js";
import "datatables.net-bs4/css/dataTables.bootstrap4.min.css";
import "datatables.net-responsive-bs4/js/responsive.bootstrap4.min.js";
import "datatables.net-responsive-bs4/css/responsive.bootstrap4.min.css";
import "datatables.net-buttons";
import "datatables.net-buttons-bs4/js/buttons.bootstrap4.js";
import "datatables.net-buttons-bs4/css/buttons.bootstrap4.css";
import "datatables.net-buttons/js/buttons.html5.js";
import "datatables.net-buttons/js/buttons.print.js";
export default async function fillTable ({ data, replaceLatLngWithMap = false, callback = false }) {
$("#table_body").empty();
$.each(data, function (rowNum, item) {
const row = document.createElement("tr");
row.id = "row-" + rowNum;
$.each(item, function (cellNum, i) {
if (i !== null) {
if (replaceLatLngWithMap && i.match(/[+-]?\d+([.]\d+)?[;][+-]?\d+([.]\d+)?/gm)) { /* credits to @visoom https://github.com/visoom */
let lat = i.split(";")[0];
let lng = i.split(";")[1];
let mapImageID = undefined;
if(lng.includes("#")){
lng = lng.split("#")[0];
mapImageID = i.split("#")[1];
}
const mapDiv = document.createElement("div");
mapDiv.id = "map-" + rowNum;
const mapModal = document.createElement("div");
mapModal.id = "map-modal-" + rowNum;
mapModal.classList.add("modal");
mapModal.classList.add("map-modal");
mapModal.setAttribute("role", "dialog");
mapModal.setAttribute("tabindex", "-1");
mapModal.innerHTML = `<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" id="map-modal-${rowNum}-body">
<div id="map-container-${rowNum}" class="map"></div><br>
<p>Lat: <b id="map-${rowNum}-lat">${lat}</b><br><p>Lng: <b id="map-${rowNum}-lng">${lng}</b></p>
<a href="https://www.google.com/maps/search/?api=1&query=${lat}%2C${lng}" id="map-${rowNum}-open-gmaps" target="_blank" rel="noopener noreferrer">Apri in Google Maps</a><br>
<a href="https://www.openstreetmap.org/#map=18/${lat}/${lng}" id="map-${rowNum}-open-osm" target="_blank" rel="noopener noreferrer">Apri in OpenStreetMaps</a>
</div>
</div>
</div>`;
document.body.appendChild(mapModal);
if(mapImageID !== undefined){
const mapPreview = document.createElement("figure");
const mapPreviewImage = document.createElement("img");
console.log("Adding map image", [lat, lng, mapImageID, mapDiv.id]);
mapPreviewImage.src = "resources/images/map_cache/" + mapImageID + ".png";
mapPreview.appendChild(mapPreviewImage);
const mapPreviewCaption = document.createElement("figcaption");
const mapPreviewModalOpener = document.createElement("a");
mapPreviewCaption.style.cursor = "pointer";
mapPreviewModalOpener.id = "map-opener-" + rowNum;
mapPreviewModalOpener.classList.add("map-opener");
mapPreviewModalOpener.classList.add("pjax_disable");
mapPreviewModalOpener.innerText = "Premi qui per aprire la mappa interattiva";
mapPreviewCaption.appendChild(mapPreviewModalOpener);
mapPreview.appendChild(mapPreviewCaption);
mapDiv.appendChild(mapPreview);
} else {
const mapModalOpener = document.createElement("a");
mapModalOpener.id = "map-opener-" + rowNum;
mapModalOpener.href = "#";
mapModalOpener.classList.add("map-opener");
mapModalOpener.classList.add("pjax_disable");
mapModalOpener.innerText = "Premi qui per aprire la mappa interattiva";
mapDiv.appendChild(mapModalOpener);
}
const cell = document.createElement("td");
cell.appendChild(mapDiv);
row.appendChild(cell);
} else {
const cell = document.createElement("td");
cell.innerHTML = i;
row.appendChild(cell);
}
}
});
document.getElementById("table_body").appendChild(row);
});
let loadedLanguage = {};
try {
let language = navigator.language || navigator.userLanguage;
language = language.toLowerCase().replace("_", "-");
language = "it_it";
loadedLanguage = await import(`datatables.net-plugins/i18n/${language}.json`)
.then(({ default: _ }) => {
return _;
});
} catch (error) {
console.error("Error loading DataTables translation:");
console.log(error);
loadedLanguage = {};
}
if (!$.fn.DataTable.isDataTable("#table")) {
var tableDt = $("#table").DataTable({
responsive: true,
responsive: {
details: {
display: $.fn.dataTable.Responsive.display.childRowImmediate,
type: 'none',
target: ''
}
},
language: loadedLanguage,
buttons: ["excel", "pdf", "csv"],
info: false //TODO: fix info string
});
tableDt.buttons().container()
.appendTo("#table_wrapper :nth-child(1):eq(0)");
if (callback !== false) {
callback(tableDt);
}
} else {
tableDt.rows().invalidate();
}
window.tableDt = tableDt;
}
$(function() {
document.querySelector("tbody").addEventListener('click', function(e) {
if(e.target.classList.contains("map-opener")) {
console.log(e);
let id = e.target.id.replace("map-opener-", "");
console.log(id);
$("#map-modal-"+id).modal('show');
}
});
$('body').on('shown.bs.modal', function (e) {
console.log(e);
if(e.target.classList.contains("map-modal")) {
let id = e.target.id.replace("map-modal-", "");
console.log(id);
let lat = $("#map-"+id+"-lat").text();
let lng = $("#map-"+id+"-lng").text();
console.log(lat);
console.log(lng);
allertaJS.maps.loadMap(lat, lng, "map-container-"+id, false, true);
}
});
});

View File

@ -1,18 +0,0 @@
export default async function fillTable ({ data, replaceLatLngWithMap = false, callback = false }) {
$("#table_body").empty();
$.each(data, function (rowNum, item) {
const row = document.createElement("tr");
row.id = "row-" + rowNum;
$.each(item, function (cellNum, i) {
if (i !== null) {
const cell = document.createElement("td");
cell.innerHTML = i;
row.appendChild(cell);
}
});
document.getElementById("table_body").appendChild(row);
});
if (callback !== false) {
callback();
}
}

View File

@ -1,113 +0,0 @@
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");
const WebpackAssetsManifest = require("webpack-assets-manifest");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
var webpack = require("webpack");
module.exports = {
entry: {
main: path.resolve(__dirname, "./src/main.js"),
maps: path.resolve(__dirname, "./src/maps.js"),
players: path.resolve(__dirname, "./src/players.js"),
sw: path.resolve(__dirname, "./src/sw.js"),
games: path.resolve(__dirname, "./src/games.js"),
},
output: {
filename: (pathData) => {
return pathData.chunk.name === "sw" ? "../../sw.js": "[name].[contenthash].js";
},
path: path.resolve(__dirname, "dist"),
publicPath: "resources/dist/",
chunkFilename: "[name].bundle.js?h=[chunkhash]",
library: ["allertaJS", "[name]"]
},
resolve: {
alias: {
// Force all modules to use the same jquery version.
"jquery": path.join(__dirname, "node_modules/jquery/src/jquery")
}
},
module: {
rules: [
{
test: require.resolve("jquery"),
loader: "expose-loader",
options: {
exposes: ["$", "jQuery"],
},
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.s(a|c)ss$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
{
test: /\.(gif|png|jpg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "./"
}
}
]
},
{
test: /\.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
use: [{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "fonts/",
publicPath: "resources/dist/fonts"
}
}]
},
{
test: /\.(gz|wasm|js_resource|data)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "./"
}
}
],
type: "asset/resource"
}
],
},
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new CleanWebpackPlugin(),
new CopyPlugin({
patterns: [
{ from: "node_modules/leaflet/dist/images", to: ".", noErrorOnMissing: true }
],
}),
new WebpackAssetsManifest({
writeToDisk: true,
integrity: true,
entrypointsUseAssets: true,
customize(entry, original, manifest, asset) {
if(asset.name.includes("table_engine")){
return entry;
}
allowed_entries = ["main.js", "maps.js", "players.js", "games.js"]
if (entry.key.includes("table_engine") || allowed_entries.includes(entry.key)) {
entry.key = entry.key.split("?")[0];
return entry;
}
return false;
}
})
],
optimization: {
mergeDuplicateChunks: true
}
};

View File

@ -1,15 +0,0 @@
const { merge } = require("webpack-merge");
const prod = require("./webpack.prod.js");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.exports = smp.wrap(merge(prod, {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: "static",
openAnalyzer: true,
generateStatsFile: true
})
]
}));

View File

@ -1,19 +0,0 @@
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
var webpack = require("webpack");
module.exports = merge(common, {
mode: "development",
devtool: false,
devServer: {
contentBase: "./dist",
},
plugins: [
new webpack.EnvironmentPlugin({
GIT_VERSION: null,
GIT_AUTHOR_DATE: null,
BUNDLE_DATE: Date.now(),
BUNDLE_MODE: "development"
})
]
});

View File

@ -1,140 +0,0 @@
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
const TerserPlugin = require("terser-webpack-plugin");
const SentryWebpackPlugin = require("@sentry/webpack-plugin");
const AfterBuildPlugin = require("@fiverr/afterbuild-webpack-plugin");
const childProcess = require("child_process");
const InjectPlugin = require("webpack-inject-plugin").default;
const colors = require("colors/safe");
const fs = require("fs");
const glob = require("glob");
function git(command) {
return childProcess.execSync(`git ${command}`, { encoding: "utf8" }).trim();
}
var webpack = require("webpack");
if (!fs.existsSync("config.json")) {
fs.copyFileSync("config_sample.json", "config.json");
}
const removeSourceMapUrlAfterBuild = () => {
//based on @rbarilani https://github.com/rbarilani/remove-source-map-url-webpack-plugin
glob("./dist/*.js", function (er, files) {
let countMatchAssets = 0;
files.push("../sw.js");
//console.log(files);
files.forEach((key) => {
countMatchAssets += 1;
let asset = fs.readFileSync(key, "utf8");
let source = asset.split("//# sourceMappingURL=")[0].replace(/\n$/, "");
fs.writeFileSync(key, source);
});
if (countMatchAssets) {
console.log(colors.green(`remove-source-map-url: ${countMatchAssets} asset(s) processed`));
}
});
glob("./dist/*.js.map", function (er, files) {
files.push("../sw.js.map");
files.forEach((key) => {
fs.unlinkSync(key);
});
});
};
var configFile = require("./config.json");
const sentryEnabled = configFile.sentryEnabled &&
configFile.sentryAuthToken &&
configFile.sentryOrganization &&
configFile.sentryProject;
var prodConfig = {
mode: "production",
devtool: false,
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
presets: [
['@babel/preset-env', {
useBuiltIns: 'usage',
corejs: 3
}]
],
plugins: ["@babel/plugin-transform-runtime"],
sourceType: "unambiguous"
}
}
}
]
},
plugins: [],
optimization: {
mergeDuplicateChunks: true,
minimize: true,
minimizer: [new TerserPlugin({
parallel: true,
extractComments: true,
terserOptions: {
compress: {
drop_console: true
}
}
})]
}
};
module.exports = (env) => {
//run webpack build with "--env sentryEnvironment=custom-sentry-env" to replace Sentry environment
if(env.sentryEnvironment){
console.log(colors.green("INFO using custom sentryEnvironment "+env.sentryEnvironment));
configFile.sentryEnvironment = env.sentryEnvironment;
}
if(!configFile.sentryEnvironment){
configFile.sentryEnvironment = "prod";
}
if(sentryEnabled){
prodConfig.plugins.push(
new webpack.SourceMapDevToolPlugin({
filename: "[file].map"
}),
new SentryWebpackPlugin({
authToken: configFile.sentryAuthToken,
org: configFile.sentryOrganization,
project: configFile.sentryProject,
urlPrefix: "~/dist",
include: "./dist",
setCommits: {
auto: true
},
release: "allerta-vvf-frontend@"+git("describe --always")
}),
new AfterBuildPlugin(removeSourceMapUrlAfterBuild),
new InjectPlugin(function() {
return "import './src/sentry.js';";
},{ entryName: "main" })
);
console.log(colors.green("INFO Sentry Webpack plugins enabled"));
}
prodConfig.plugins.push(
new webpack.EnvironmentPlugin({
GIT_VERSION: git("describe --always"),
GIT_AUTHOR_DATE: git("log -1 --format=%aI"),
BUNDLE_DATE: Date.now(),
BUNDLE_MODE: "production",
config: configFile
})
);
return merge(common, prodConfig);
};

View File

@ -1,10 +0,0 @@
<?php
require_once 'ui.php';
if($JSless){
$user->online_time_update();
$query_results = $db->select("SELECT * FROM `".DB_PREFIX."_services` ORDER BY date DESC, beginning DESC");
} else {
$query_results = null;
}
loadtemplate('services.html', ['title' => t('Services', false), 'query_results' => $query_results]);
?>

View File

@ -1,24 +0,0 @@
<?php
use skrtdev\NovaGram\Bot;
use skrtdev\Telegram\Message;
require_once 'core.php';
init_class();
$Bot = new Bot(BOT_TELEGRAM_API_KEY);
$Bot->addErrorHandler(function ($e) {
print('Caught '.get_class($e).' exception from general handler'.PHP_EOL);
print($e.PHP_EOL);
});
$Bot->onCommand('start', function (Message $message, array $args = []) {
var_dump($message, $args);
$message->reply('Hey! Nice to meet you. Use /info to know more about me.');
});
$Bot->onCommand('info', function (Message $message) {
$message->reply('Well, I\'m just an example, but you can learn more about NovaGram at docs.novagram.ga');
});
$Bot->start();

View File

@ -1,110 +0,0 @@
{% apply minimize %}
<!DOCTYPE html>
<html lang="it">
<head>
{% block head %}
<title>{{ title }} - ALLERTA sistema gestionale {{ owner }}</title>
<link href="{{ urlsoftware }}/resources/images/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
<meta name="viewport" content="user-scalable=no, initial-scale=1">
<meta name="google" content="notranslate">
<meta name="robots" content="none">
{% endblock %}
</head>
<body>
{% if show_menu %}
{% block menu %}
{# Menu #}
<style>
.topnav {
background-color: red;
overflow: hidden;
}
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
.topnav a:hover {
background-color: #ddd;
color: black;
}
.active {
background-color: #4caf50;
color: white;
}
.topnav .icon {
display: none;
}
table, th, tr {
border: 1px solid black;
border-collapse: collapse;
}
</style>
<div class="topnav" id="topNavBar">
<a href="{{ urlsoftware }}list.php" class="active">{{ 'Availability List'|t }}</a>
<a href="{{ urlsoftware }}services.php">{{ 'Services'|t }}</a>
<a href="{{ urlsoftware }}trainings.php">{{ 'Trainings'|t }}</a>
<a href="{{ urlsoftware }}log.php">{{ 'Logs'|t }}</a>
<a href='{{ urlsoftware }}logout.php' style="float: right;" id="logout">{{ 'Hi, %s.'|t|format(user.name) }} {{ 'Logout'|t }}</a>
</div>
{# /Menu #}
{% endblock %}
{% endif %}
<style>
.text-center{
text-align: center;
}
.btn{
padding: .5rem 1rem;
font-size: 1.25rem;
line-height: 1.5;
border-radius: .3rem;
color: white;
}
.btn-success{
background-color: #1e7e34;
border-color: #1c7430;
}
.btn-danger{
background-color: #ff0019;
border-color: #ff0019;
}
.btn-small{
font-size: 0.75rem;
}
table .tHead th {
font-weight: bold;
}
table .tBody th {
font-weight: normal;
}
</style>
{# Content #}
<div id="content">
{% block pjax_content %}
{% if message %}
<div class="alert alert-info m-3" role="alert">
{{ message|raw }}
</div>
{% endif %}
{% block content %}{% endblock %}
{% endblock %}
</div>
{# /Content #}
{% if show_footer %}
{% block footer %}
{# Footer #}
<div id="footer" class="footer text-center p-3" style="background-color: rgba(0, 0, 0, 0.2)">
Allerta-VVF, software libero realizzato per {{ owner }}.
</div>
{# /Footer #}
{% endblock %}
{% endif %}
{{ script('main.js') }}
</body>
</html>
{% endapply %}

View File

@ -1,212 +0,0 @@
{% extends "base.html" %}
{% block menu %}
{% endblock %}
{% block content %}
TODO
{% if service.modalità == "edit" or service.modalità == "add" %}
<form method="post">
<div class="container">
<div class="form-group">
<label for="date-picker">{{ 'Service day'|t }}</label>
<input id="date-picker" aria-label="Date picker" placeholder="DD/MM/YYY" autocomplete="off" name="date" data-provide="datepicker"
value="{{ values.date }}" type="text" class="form-control">
</div>
<div class="form-group">
<label for="progressivo">{{ 'code'|t|capitalize }}</label>
<input id="progressivo" class="form-control" type="text" name="code" placeholder="1234/5" required value="{{ values.code }}">
</div>
<div class="form-group">
<label for="timePicker1">{{ 'Start time'|t }}</label>
<input id="timePicker1" class="form-control" type="time" name="beginning" required value="{{ values.beginning }}">
</div>
<div class="form-group">
<label for="timePicker2">{{ 'End time'|t }}</label>
<input id="timePicker2" class="form-control" type="time" name="end" required value="{{ values.end }}">
</div>
<div class="form-group">
<label>{{ 'Chief'|t }}</label>
<br>
{% for user in service.crew %}
{% if user.chief == 1 and not user.hidden %}
<div class="form-check">
<input aria-label="{{ username(user.id) }}" id="chief-{{ user.id }}" class="form-check-input chief chief-{{ user.id }}"
style="transform: scale(1.4); -webkit-transform: scale(1.4);" type="checkbox" name='chief[]'
value='{{ user.id }}'>
<label class="form-check-label" for="chief-{{ user.id }}">
{{ username(user.id) }}
</label>
</div>
{% endif %}
{% endfor %}
</div>
<script{% if enable_js_nonce %} nonce="{{ nonce }}"{% endif %}>
$('.chief').on('change', function () {
$('input[name="' + this.name + '"]').not(this).prop('checked', false);
});
</script>
<div class="form-group">
<label>{{ 'Drivers'|t }}</label>
<br>
{% for user in service.crew %}
{% if user.driver == 1 and not user.hidden %}
<div class="form-check">
<input aria-label="{{ username(user.id) }}" id="drivers-{{ user.id }}" class="form-check-input drivers drivers-{{ user.id }}"
style="transform: scale(1.4); -webkit-transform: scale(1.4);" type="checkbox" name='drivers[]'
value='{{ user.id }}'>
<label class="form-check-label" for="drivers-{{ user.id }}">
{{ username(user.id) }}
</label>
</div>
{% endif %}
{% endfor %}
</div>
<div class="form-group">
<label>{{ 'Crew'|t }}</label>
<br>
{% for user in service.crew %}
{% if not user.hidden %}
<div class="form-check">
<input aria-label="{{ username(user.id) }}" id="crew-{{ user.id }}" class="form-check-input crew crew-{{ user.id }}"
style="transform: scale(1.4); -webkit-transform: scale(1.4);" type="checkbox" name='crew[]'
value='{{ user.id }}'>
<label class="form-check-label" for="crew-{{ user.id }}">
{{ username(user.id) }}
</label>
</div>
{% endif %}
{% endfor %}
</div>
{% if option('use_location_picker') %}
<label>{{ 'Service place'|t }}</label>
<div id="map"></div>
<div id="search">
<div class="form-inline">
<div class="form-group mx-sm-3 mb-2">
<input type="text" class="form-control" name="addr" value="" id="addr" size="50" />
</div>
<div class="form-group mx-sm-3 mb-2">
<button id="search_button" type="button" class="btn btn-primary mb-2">
{{ 'Search'|t }}
</button>
</div>
</div>
<div id="results"></div>
</div>
<input type="hidden" name="place" value="" />
{% else %}
<div class="form-group">
<label>{{ 'Service place'|t }}</label>
<input type="text" name="place" class="form-control" required value="{{ values.place }}">
</div>
<br>
{% endif %}
<div class="form-group">
<label for="notes">{{ 'Others notes (ex. others infos)'|t }}</label><br>
<textarea class="form-control" id="notes" name='notes'></textarea>
</div>
<br>
<div class="form-group">
<label>{{ 'Service type'|t }}</label>
<br>
<select id="types" class="form-control" name='type' class="types">
{% for type in service.types %}
<option value='{{ type.name }}'>{{ type.name }}</option>
{% endfor %}
{% if service.types is empty %}
<option id="empty_option" value=''></option>
{% endif %}
<option value='add_new'>{{ 'Add type...'|t }}</option>
</select>
</div>
<br>
<input id="modalità" type="hidden" value="{{ service.modalità }}" name="mod"></input>
<input id="token" type="hidden" value="{{ service.token }}" name="token"></input>
<input id="id" type="hidden" value="{{ service.id }}" name="id"></input>
<button id="submit_button" type="submit" class="btn btn-primary">{{ 'Submit'|t }}</button>
</div>
</form>
<script{% if enable_js_nonce %} nonce="{{ nonce }}"{% endif %}>
$( "#types" ).change(function() {
$('#empty_option').remove();
var type = "";
$( "#types option:selected" ).each(function() {
type = $( this ).val();
});
console.log(type);
if(type == "add_new"){
new_type = prompt("{{ 'Insert type name:'|t }}");
if(!new_type) return;
$.ajax({
url: "resources/ajax/ajax_add_type.php",
method: "POST",
data: {
type: new_type
},
success: function (data) {
$('option:last-of-type').before($('<option>').val(new_type).text(new_type));
$('option[value='+new_type+']').prop('selected', 'selected').change();
toastr.success('{{ "Type '%s' added successfully."|t|format('+new_type+')|raw }}');
}
});
}
});
{% if service.modalità == "edit" %}
{% if option('use_location_picker') %}
{% set place = values.place|split('#')[0] %}
allertaJS.maps.setMarker(new L.LatLng({{place|split(';')[0]}}, {{place|split(';')[1]}}), true);
{% endif %}
$.each('{{ values.chief }}'.split(','), function (index, value) {
$('.chief-' + value).prop('checked', true);
});
$.each('{{ values.drivers }}'.split(','), function (index, value) {
$('.drivers-' + value).prop('checked', true);
});
$.each('{{ values.crew }}'.split(','), function (index, value) {
$('.crew-' + value).prop('checked', true);
});
$("#types").val('{{ values.type }}');
$('#notes').val('{{ values.notes }}');
{% endif %}
$('form').submit(function () {
var type = "";
$( "#types option:selected" ).each(function() {
type = $( this ).val();
});
if(type == "add_new" || type == ""){
toastr.error("{{ 'You must select a valid service type!'|t }}");
return false;
}
var progressivo_valido = /^[0-9/]{3,6}$/
var progressivo = $('#progressivo').val();
if (!progressivo_valido.test(progressivo)) {
var invia_progressivo = confirm("{{ 'The code has been detected as incorrect, do you want to add the service anyway?'|t }}");
} else {
var invia_progressivo = true;
}
return invia_progressivo;
});
</script>
{% endif %}
{% if service.modalità == "delete" %}
<div style="margin: 0 auto; text-align: center">
<p>{{ 'Are you sure you want to delete the service?'|t }}</p>
<form method="post">
<input id="modalità" type="hidden" value="delete" name="mod"></input>
<input id="token" type="hidden" value="{{ service.token }}" name="token"></input>
<input id="id" type="hidden" value="{{ service.id }}" name="id"></input>
<button id="remove" type="submit">{{ 'Submit'|t }}</button>
</form>
<script{% if enable_js_nonce %} nonce="{{ nonce }}"{% endif %}>
$('form').submit(function () {
return confirm("{{ 'The action cannot be canceled. Are you sure you want to continue?'|t }}");
});
</script>
</div>
{% endif %}
{% block footer %}
{% endblock %}
{% endblock %}

View File

@ -1,136 +0,0 @@
{% extends "base.html" %}
{% block menu %}
{% endblock %}
{% block content %}
TODO
{% if training.modalità == "edit" or training.modalità == "add" %}
<form method="post">
<div class="container">
<div class="form-group">
<label for="date-picker">{{ 'Training day'|t }}</label>
<input id="date-picker" aria-label="Date picker" placeholder="DD/MM/YYY" autocomplete="off" name="date" data-provide="datepicker"
value="{{ values.date }}" type="text" class="form-control">
</div>
<div class="form-group">
<label for="name">{{ 'Name'|t }}</label>
<input id="name" class="form-control" type="text" name="name" placeholder="1° training" required value="{{ values.name }}">
</div>
<div class="form-group">
<label for="timePicker1">{{ 'Start time'|t }}</label>
<input id="timePicker1" class="form-control" type="time" name="start_time" required value="{{ values.beginning }}">
</div>
<div class="form-group">
<label for="timePicker2">{{ 'End time'|t }}</label>
<input id="timePicker2" class="form-control" type="time" name="end_time" required value="{{ values.end }}">
</div>
<div class="form-group">
<label>{{ 'Chief'|t }}</label>
<br>
{% for user in training.crew %}
{% if not user.hidden %}
<div class="form-check">
<input aria-label="{{ username(user.id) }}" id="chief-{{ user.id }}" class="form-check-input chief chief-{{ user.id }}"
style="transform: scale(1.4); -webkit-transform: scale(1.4);" type="checkbox" name='chief[]'
value='{{ user.id }}'>
<label class="form-check-label" for="chief-{{ user.id }}">
{{ username(user.id) }}
</label>
</div>
{% endif %}
{% endfor %}
</div>
<script{% if enable_js_nonce %} nonce="{{ nonce }}"{% endif %}>
$('.chief').on('change', function () {
$('input[name="' + this.name + '"]').not(this).prop('checked', false);
});
</script>
<div class="form-group">
<label>{{ 'Crew'|t }}</label>
<br>
{% for user in training.crew %}
{% if not user.hidden %}
<div class="form-check">
<input aria-label="{{ username(user.id) }}" id="crew-{{ user.id }}" class="form-check-input crew crew-{{ user.id }}"
style="transform: scale(1.4); -webkit-transform: scale(1.4);" type="checkbox" name='crew[]'
value='{{ user.id }}'>
<label class="form-check-label" for="crew-{{ user.id }}">
{{ username(user.id) }}
</label>
</div>
{% endif %}
{% endfor %}
</div>
{% if option('use_location_picker') %}
<label>{{ 'Training place'|t }}</label>
<div id="map"></div>
<div id="search">
<div class="form-inline">
<div class="form-group mx-sm-3 mb-2">
<input type="text" class="form-control" name="addr" value="" id="addr" size="50" />
</div>
<div class="form-group mx-sm-3 mb-2">
<button id="search_button" type="button" class="btn btn-primary mb-2">
{{ 'Search'|t }}
</button>
</div>
</div>
<div id="results"></div>
</div>
<input type="hidden" name="place" value="" />
{% else %}
<div class="form-group">
<label for="place">{{ 'Training place'|t }}</label>
<input id="place" type="text" class="form-control" name="place" required value="{{ values.place }}">
</div>
<br>
{% endif %}
<div class="form-group">
<label for="notes">{{ 'Others notes (ex. others infos)'|t }}</label><br>
<textarea class="form-control" id="notes" name='notes'></textarea>
</div>
<br>
<input id="modalità" type="hidden" value="{{ training.modalità }}" name="mod"></input>
<input id="id" type="hidden" value="{{ training.id }}" name="id"></input>
<input id="token" type="hidden" value="{{ training.token }}" name="token"></input>
<button id="submit_button" type="submit" class="btn btn-primary">{{ 'Submit'|t }}</button>
</div>
</form>
<script{% if enable_js_nonce %} nonce="{{ nonce }}"{% endif %}>
{% if training.modalità == "edit" %}
{% if option('use_location_picker') %}
{% set place = values.place|split('#')[0] %}
allertaJS.maps.setMarker(new L.LatLng({{place|split(';')[0]}}, {{place|split(';')[1]}}), true);
{% endif %}
$.each('{{ values.chief|striptags|e("js") }}'.split(','), function (index, value) {
$('.chief-' + value).prop('checked', true);
});
$.each('{{ values.crew|striptags|e("js") }}'.split(','), function (index, value) {
$('.crew-' + value).prop('checked', true);
});
$('#notes').val('{{ values.notes|e("js") }}');
{% endif %}
</script>
{% endif %}
{% if training.modalità == "delete" %}
<div style="margin: 0 auto; text-align: center">
<p>{{ 'Are you sure you want to delete the training?'|t }}</p>
<form method="post">
<input id="modalità" type="hidden" value="delete" name="mod"></input>
<input id="token" type="hidden" value="{{ training.token }}" name="token"></input>
<input id="id" type="hidden" value="{{ training.id }}" name="id"></input>
<button id="remove" type="submit">{{ 'Submit'|t }}</button>
</form>
<script{% if enable_js_nonce %} nonce="{{ nonce }}"{% endif %}>
$('form').submit(function () {
return confirm("{{ 'The action cannot be canceled. Are you sure you want to continue?'|t }}");
});
</script>
</div>
{% endif %}
{% block footer %}
{% endblock %}
{% endblock %}

View File

@ -1,72 +0,0 @@
{% extends "base.html" %}
{% block menu %}
{% endblock %}
{% block content %}
{% if modalità == "edit" or modalità == "add" %}
<form method="post">
<div class="container">
<div class="form-group">
<label for="mail">{{ 'E-mail'|t }}</label>
<input id="mail" type="text" name="mail" placeholder="{{ 'user@provider-email-domain.com'|t }}" required>
</div>
<div class="form-group">
<label for="name">{{ 'Name'|t }}</label>
<input id="name" type="text" name="name" placeholder="{{ 'Name Surname'|t }}" required>
</div>
<div class="form-group">
<label for="username">{{ 'Username'|t }}</label>
<input id="username" type="text" name="username" placeholder="{{ 'name.surname'|t }}" required>
</div>
<div class="form-group">
<label>{{ 'Password'|t }}</label>
<input id="password" type="text" name="password" required>
</div>
<div class="form-group">
<label for="phone_number">{{ 'Phone number'|t }}</label>
<input id="phone_number" type="tel" name="phone_number" required>
</div>
<div class="form-group">
<label for="date-picker">{{ 'Birthday'|t }}</label>
<input id="date-picker" placeholder="DD/MM/YYY" autocomplete="off" name="birthday" value="{{ values.date }}" type="text">
</div>
<div class="form-group">
<label for="chief">{{ 'Chief'|t }}</label><br>
<input id="chief" type="checkbox" name="chief">
</div>
<div class="form-group">
<label for="driver">{{ 'Driver'|t }}</label><br>
<input id="driver" type="checkbox" name="driver">
</div>
<div class="form-group">
<label for="visible">{{ 'Visible'|t }}</label><br>
<input id="visible" type="checkbox" name="visible" checked>
</div>
<div class="form-group">
<label for="enabled">{{ 'Enabled'|t }}</label><br>
<input id="enabled" type="checkbox" name="enabled" checked>
</div>
<br>
<input id="modalità" type="hidden" value="{{ modalità }}" name="mod"></input>
<input id="token" type="hidden" value="{{ token }}" name="token"></input>
<button type="submit">{{ 'Submit'|t }}</button>
</div>
</form>
{% endif %}
{% if modalità == "delete" %}
<div style="margin: 0 auto; text-align: center">
<p>{{ 'Are you sure you want to delete the user?'|t }}</p>
<form method="post">
<input id="modalità" type="hidden" value="delete" name="mod"></input>
<input id="token" type="hidden" value="{{ token }}" name="token"></input>
<input id="id" type="hidden" value="{{ id }}" name="id"></input>
<button id="remove" type="submit">{{ 'Submit'|t }}</button>
</form>
</div>
{% endif %}
{% block footer %}
{% endblock %}
{% endblock %}

View File

@ -1,41 +0,0 @@
{% extends "base.html" %}
{% block menu %}
{% endblock %}
{% block content %}
<div class="align-items-center container d-flex justify-content-center" id="modulogin">
<form method="post">
<img alt="VVF" src="{{ urlsoftware }}/resources/images/logo.png" class="img-resposive"><br><br>
<div class="form-group">
<input type="text" name="name" placeholder="{{ 'username'|t|capitalize }}" required="" autocomplete="username" autofocus="" class="form-control">
</div>
<div class="form-group">
<input type="password" name="password" placeholder="{{ 'password'|t|capitalize }}" required="" autocomplete="current-password" class="form-control">
</div>
{% if option('force_remember_cookie') %}
<input type="hidden" name="remember_me" value='1' id="remember_me checkbox1" type="checkbox">
{% else %}
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember_me" value="1" id="remember_me checkbox1">
<label class="form-check-label" for="checkbox1">{{ 'Stay connected'|t }}</label>
</div>
</div>
{% endif %}
<input type="submit" name="login" class="btn btn-block btn-lg btn-success" value="{{ 'Login'|t }}">
</form>
{% if error %}
<div id="err" class="alert alert-danger m-3" role="alert">
<h4 class="alert-heading">{{ error.text|t }}</h4>
<p>{{ 'Error'|t}} {{ 'code'|t}} {{ error.code }}. {{ 'Check the entered credentials and make sure they are correct'|t }}.</p>
<img src='{{ urlsoftware }}/resources/images/{{ error_image }}'></img>
</div>
{% endif %}
</div>
<br><br>
{% block footer %}
{% endblock %}
{% endblock %}

View File

@ -1,82 +0,0 @@
{% extends "base.html" %}
{% block content %}
<br>
<div class="text-center">
<p>{{ 'Are you available in case of alert?'|t }}</p>
<form method="post">
<input type="hidden" name="token_list" value="{{ token_list }}"/>
<input type="hidden" name="action" value="activate"/>
<input type="hidden" name="user_id" value="{{ user.id }}"/>
<button type="submit" class="btn btn-success">{{ 'Activate'|t }}</button>
</form>
<form method="post">
<input type="hidden" name="token_list" value="{{ token_list }}"/>
<input type="hidden" name="action" value="deactivate"/>
<input type="hidden" name="user_id" value="{{ user.id }}"/>
<button type="submit" class="btn btn-danger">{{ 'Deactivate'|t }}</button>
</form>
</div>
<br>
<br>
<img alt="VVF" src="./resources/images/owner.png" width="150"
style="display: block; margin-left: auto; margin-right: auto;">
<br>
<br>
<table style="width:100%">
<tr class="tHead">
<th>{{ 'Name'|t }}</th>
<th>{{ 'Available'|t }}</th>
{% if user.full_viewer %}
<th>{{ 'Driver'|t }}</th>
<th>{{ 'Call'|t }}</th>
<th>{{ 'Write'|t }}</th>
<th>{{ 'Services'|t }}</th>
<th>{{ 'Availability Minutes'|t }}</th>
{# <th>{{ 'Other'|t }}</th> TODO: fix "Other" page #}
{% endif %}
</tr>
{% for row in query_results %}
<tr class="tBody">
{% if (date().timestamp-row.online_time) <= 30 %}
<th><u>{{ username(row.id) }}</u></th>
{% else %}
<th>{{ username(row.id) }}</th>
{% endif %}
<th>
{{ yesOrNo(row.available) }}
{% set function = row.available ? "deactivate" : "activate" %}
<form method="post">
<input type="hidden" name="token_list" value="{{ token_list }}"/>
<input type="hidden" name="action" value="{{ function }}"/>
<input type="hidden" name="user_id" value="{{ row.id }}"/>
<button type="submit">{{ 'Change'|t }}</button>
</form>
</th>
{% if user.full_viewer %}
<th>{{ yesOrNo(row.driver) }}</th>
{% if row.phone_number %}
<th><a href='tel:{{ row.phone_number }}'>Chiama</a></th>
{% else %}
<th></th>
{% endif %}
{% if row.phone_number %}
<th><a href='https://api.whatsapp.com/send?phone={{ row.phone_number }}&text=ALLERTA IN CORSO.%20Mettiti%20in%20contatto%20con%20{{ username(row.id)|url_encode }}'>Manda un messaggio</a></th>
{% else %}
<th></th>
{% endif %}
<th>{{ row.services }}</th>
<th>{{ row.availability_minutes }}</th>
{# <th>{{ 'Other'|t }}</th> TODO: fix "Other" page #}
{% endif %}
</tr>
{% endfor %}
</table>
<br><br>
<p style="text-align: center;">
<a href="edit_user.php?add" class="btn btn-success btn-small">{{ 'Add user'|t }}</a>
</p>
<br>
<br>
{% endblock %}

View File

@ -1,26 +0,0 @@
{% extends "base.html" %}
{% block content %}
<br>
<img alt="VVF" src="./resources/images/owner.png" width="150"
style="display: block; margin-left: auto; margin-right: auto;">
<br>
<table style="width:100%">
<tr class="tHead">
<th>{{ 'Action'|t }}</th>
<th>{{ 'Interested'|t }}</th>
<th>{{ 'Made by'|t }}</th>
<th>{{ 'Datetime'|t }}</th>
</tr>
{% for row in query_results %}
<tr class="tBody">
<th>{{ row.action }}</th>
<th>{{ username(row.changed) }}</th>
<th>{{ username(row.editor) }}</th>
<th>{{ row.timestamp }}</th>
</tr>
{% endfor %}
</table>
<br>
<br>
{% endblock %}

View File

@ -1 +0,0 @@
If you are using an old browser that doesn't support JS, you can't use Service Workers, so this page is useless.

Some files were not shown because too many files have changed in this diff Show More