#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.
parent
6035470997
commit
f8eeb437a3
@ -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…
Reference in new issue