#wip: 1 hora de Jam. Misión no finalizada. Terminado controlador servidor, gestión de un JSON como DB y estructura del GUI. Falta el ViewController.

main
KyMAN 1 month ago
parent 6035470997
commit f8eeb437a3
  1. 3
      .gitignore
  2. 14
      GamUsino.apache2.conf
  3. 86
      PHP/GamUsino.php
  4. 8
      PHP/includes.php
  5. 5
      Public/api.php
  6. 109
      Public/ecma/GamUsino.ecma.js
  7. 68
      Public/index.html

3
.gitignore vendored

@ -0,0 +1,3 @@
/Data
/Public/data
*[Ss]ecrets*

@ -0,0 +1,14 @@
<VirtualHost *:80>
ServerName gamusino.local
DocumentRoot /Projects/GamUsino/Public
<Directory /Projects/GamUsino>
Options +Indexes +FollowSymLinks +MultiViews
DirectoryIndex index.html index.php
AllowOverride all
Order Allow,Deny
Allow from all
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error_gamusino_80.log
CustomLog ${APACHE_LOG_DIR}/access_gamusino_80.log combined
</VirtualHost>

@ -0,0 +1,86 @@
<?php
class GamUsino{
public function __construct($inputs = null){
$data = json_decode(base64_decode($_POST["GamUsino"]), true);
if($data){
if(isset($data["action"])){
switch($data["action"]){
case "add_poll":
$database = $this->load_database();
isset($database["polls"]) || ($database["polls"] = []);
$database["polls"][] = [
"name" => $data["name"],
"options" => []
];
$this->save_database($database);
$this->response(200, $database["polls"]);
break;
case "get_poll":
$database = $this->load_database();
$poll = isset($database["polls"]) && isset($database["polls"][$data["name"]]) ? $database["polls"][$data["name"]] : null;
$this->response($poll ? 200 : 404, $poll ?? [
"message" => "poll_not_exists",
"name" => $data["name"]
]);
break;
case "add_option":
$database = $this->load_database();
if(isset($database["polls"]) && isset($database["polls"][$data["name"]])){
$database["polls"][$data["name"]][] = [
"text" => $data["text"],
"points" => 0
];
$this->save_database($database);
$this->response(200, $database["polls"][$data["name"]]);
}else
$this->response(404, [
"message" => "poll_not_exists",
"name" => $data["name"]
]);
break;
case "set_option":
break;
default:
$database = $this->load_database();
if(isset($database["polls"]) && isset($database["polls"][$data["name"]])){
$database["polls"][$data["name"]][$data["i"]]["points"] ++;
$this->save_database($database);
$this->response(200, null);
}else
$this->response(404, [
"message" => "poll_not_exists",
"name" => $data["name"]
]);
break;
};
}else
$this->response(405, ["message" => "no_action"]);
}else
$this->response(405, ["message" => "no_data"]);
}
private function response($code, $data){
echo json_encode([
"ok" => $code == 200,
"code" => $code,
"content" => $data
]);
exit(0);
}
private function load_database(){
return file_exists(\GamUsino\Secrets::settings["database_path"]) ? json_decode(file_get_contents(\GamUsino\Secrets::settings["database_path"]), true) : [];
}
private function save_database($database){
file_put_contents(\GamUsino\Secrets::settings["database_path"], json_encode($database));
}
};

@ -0,0 +1,8 @@
<?php
foreach([
__DIR__ . "/GamUsino.php",
__DIR__ . "/GamUsino.Secrets.php"
] as $file)
if(file_exists($file))
include $file;

@ -0,0 +1,5 @@
<?php
include __DIR__ . "/../PHP/includes.php";
$gamusino = new GamUsino();

@ -0,0 +1,109 @@
GamUsino = function(custom){
const self = this,
default_settings = {
nulls : false,
default_value : null,
autostart : true,
timeout : 2000
},
settings = {};
let started = false,
ajax_timeout = 2000;
const constructor = () => {};
this.start = callback => {
const end = status => typeof callback == "function" && callback(status);
if(started){
end(false);
return false;
};
started = true;
ajax_timeout = self.settings(["ajax_timeout", "timeout"]);
end(true);
return true;
};
this.nulls = nulls => typeof nulls == "boolean" ? nulls : self.settings("nulls", null, false, false);
this.default_value = (_default, nulls) => _default !== undefined && (self.nulls(nulls) || _default !== null) ? _default : self.settings("default_value", null, null, true);
this.settings = (keys, inputs, _default, nulls) => {
const m = (keys = (typeof keys == "object" && keys instanceof Array ? keys : keys).filter(key => key && typeof key == "string")).length;
if(m){
const l = (inputs = (typeof inputs == "object" ? inputs instanceof Array ? inputs : [inputs] : []).concat(custom, settings, default_settings)).length;
nulls = self.nulls(nulls);
for(let i = 0; i < l; i ++)
if(inputs[i] && typeof inputs[i] == "object")
for(let j = 0; j < m; j ++)
if(inputs[i][keys[j]] !== undefined && (nulls || inputs[i][keys[j]] !== null))
return inputs[i][keys[j]];
};
return self.default_value(_default, nulls);
};
this.send = (data, callback) => {
let ended = false;
const ajax = new XMLHttpRequest(),
date = Date.now(),
end = error => !ended && (ended = true) && typeof callback == "function" && callback(ajax.responseText && JSON.parse(ajax.responseText) || ajax.responseText, ajax.status, ajax.readyState, error == "OK", error);
ajax.open("post", "/api.php", true);
ajax.timeout = ajax_timeout;
ajax.setRequestHeader("content-type", "application/x-www-form-urlencoded,charset=utf-8");
ajax.onreadystatechange = () => {
if(ended)
return;
if(ajax.readyState == 4)
end([301, 302, 304].includes(ajax.stauts) || (ajax.status >= 200 && ajax.status < 300) ? "OK" : "HTTP_ERROR");
else if(Date.now() - date > ajax_timeout)
end("FORCED_TIMEOUT");
};
ajax.send("GamUsino=" + btoa(JSON.stringify(data)));
ajax.onabort = () => end("ABORTED");
ajax.ontimeout = () => end("TIMEOUT");
ajax.onerror = () => end("ERROR");
return ajax;
};
this.confirm = (message, ok_action, no_action) => {
const action = confirm(message) ? ok_action : no_action;
typeof action == "function" && action();
};
this.add_poll = (item, event) => {
const poll_name = item.parentNode.parentNode.querySelector("input").value;
if(poll_name)
self.confirm("add_poll_sure", () => {
self.send({
action : "add_poll",
name : poll_name
}, response => {
console.log(response);
});
});
};
constructor();
};

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="es">
<head>
<title data-i18n="gamusino">GAM-USINO</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta charset="utf-8" />
<script data-type="text/javascript" data-lang="ECMAScript 2015" src="ecma/GamUsino.ecma.js" data-crossorigin="anonymous" charset="utf-8"></script>
<script data-type="text/javascript" data-lang="ECMAScript 2015" charset="utf-8">
gamusino = new GamUsino();
</script>
</head>
<body>
<header>
<h1 data-i18n="gamusino" title="GAM-USINO" data-i18n-without="true">
<a href="#" target="_self">
<span class="logo">
<img src="" data-i18n="gamusino" alt="GAM-USINO" data-i18n-without="true" />
<span style="background-image:url('');"></span>
</span>
<span data-i18n="gamusino">GAM-USINO</span>
</a>
</h1>
</header>
<main>
<section class="polls">
<div class="group">
<span class="input"><input type="text" name="poll" data-i18n="poll" data-i18n-without="true" placeholder="Encuesta..." /></span>
<span class="input"><button data-i18n="add" data-i18n-without="true" title="Añadir" onclick="gamusino.add_poll(this, event);">
<span data-icon="add"></span>
<span data-i18n="add">Añadir</span>
</button></span>
</div>
<nav class="polls">
<ul></ul>
</nav>
</section>
<section class="poll">
<h2 data-i18n="poll">Encuesta</h2>
<div class="group">
<span class="input"><input type="text" name="option" data-i18n="option" data-i18n-without="true" placeholder="Opción..." /></span>
<span class="input"><button data-i18n="add" data-i18n-without="true" title="Añadir" onclick="gamusino.add_option(this, event);">
<span data-icon="add"></span>
<span data-i18n="add">Añadir</span>
</button></span>
</div>
<nav>
<ul></ul>
</nav>
</section>
</main>
<footer>
<span class="licences">
<a href="https://www.gnu.org/licenses/gpl-3.0.txt" target="_blank" title="GPLv3">
<span data-i18n="license_text">© 2024-2025 CopyLeft.</span>
<img src="https://www.gnu.org/graphics/gplv3-127x51.png" alt="GPLv3" />
</a>
<a class="license-image" href="http://creativecommons.org/licenses/by-sa/4.0/" target="_blank" data-i18n="license_creative_commons" data-i18n-without="true" title="Creative Commons">
<img src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" alt="cc-sa" />
</a>
</span>
</footer>
</body>
</html>
Loading…
Cancel
Save