[mod] grundlegende Funktionalität

This commit is contained in:
roydfalk 2025-05-21 06:05:12 +00:00
parent 01108c5c01
commit 8a13a1758c
10 changed files with 425 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/.geany
/build/

70
source/helpers.php Normal file
View file

@ -0,0 +1,70 @@
<?php
namespace rosavox\helpers;
/**
*/
class cache_state
{
public static array $pool = [];
}
/**
*/
function cache_get(string $key, \Closure $retrieve)
{
if (\array_key_exists($key, cache_state::$pool))
{
$value = cache_state::$pool[$key];
}
else
{
$value = ($retrieve)();
cache_state::$pool[$key] = $value;
}
return $value;
}
/**
*/
function string_coin(string $template, array $arguments) : string
{
$result = $template;
foreach ($arguments as $key => $value)
{
$result = \str_replace(\sprintf('{{%s}}', $key), $value, $result);
}
return $result;
}
/**
*/
function render(string $template_name, array $arguments) : string
{
return string_coin(
cache_get(
string_coin(
'template.{{name}}',
[
'name' => $template_name,
]
),
fn() => \file_get_contents(
string_coin(
'{{directory}}/templates/{{name}}.html.tpl',
[
'directory' => __DIR__,
'name' => $template_name,
]
)
)
),
$arguments
);
}
?>

102
source/index.html.php Normal file
View file

@ -0,0 +1,102 @@
<?php
require_once(__DIR__ . '/helpers.php');
require_once(__DIR__ . '/logic.php');
/**
* @todo deactivate
*/
\rosavox\logic\docs_add_examples();
$mode = ($_GET['mode'] ?? 'list');
$id_encoded = ($_GET['id'] ?? null);
$id = (($id_encoded === null) ? null : \rosavox\logic\docs_id_decode($id_encoded));
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" type="text/css" href="/style.css"/>
</head>
<body>
<?php
switch ($mode)
{
case 'list':
{
echo(
\rosavox\helpers\render(
'docs-list',
[
'entries' => \implode(
"\n",
\array_map(
fn ($entry) => \rosavox\helpers\render(
'docs-list-entry',
[
'link' => \rosavox\helpers\string_coin(
'?mode=edit&id={{id}}',
[
'id' => $entry['id'],
]
),
'text' => $entry['doc']['title'],
]
),
\rosavox\logic\docs_list()
)
),
'link_new' => '?mode=make',
]
)
);
break;
}
case 'make':
{
echo(
\rosavox\helpers\render(
'docs-edit',
[
'id' => '',
'title' => '',
'authors' => '',
'content' => '',
'reasoning' => '',
'link_back' => '?mode=list',
]
)
);
break;
}
case 'edit':
{
$doc = \rosavox\logic\docs_read($id);
echo(
\rosavox\helpers\render(
'docs-edit',
[
'id' => $id_encoded,
'title' => $doc['title'],
'authors' => \implode(', ', $doc['authors']),
'content' => $doc['content'],
'reasoning' => $doc['reasoning'],
'link_back' => '?mode=list',
]
)
);
break;
}
case 'save':
{
throw (new \Exception('not implemented yet'));
break;
}
default:
{
throw (new \Exception(\sprintf('invalid mode: %s', $mode)));
break;
}
}
?>
</body>
</html>

129
source/logic.php Normal file
View file

@ -0,0 +1,129 @@
<?php
namespace rosavox\logic;
require_once(__DIR__ . '/helpers.php');
/**
*/
class docs_state
{
public static int $current_id = 0;
/**
* @param array {record<string,array>}
*/
public static array $pool = [];
}
/**
*/
function docs_id_encode(int $id) : string
{
return \sprintf('%u', $id);
}
/**
*/
function docs_id_decode(string $id_encoded) : int
{
return intval($id_encoded);
}
/**
*/
function docs_list() : array
{
return \array_map(
fn ($id_encoded) => [
'id' => docs_id_decode($id_encoded),
'doc' => docs_state::$pool[$id_encoded],
],
\array_keys(docs_state::$pool)
);
}
/**
*/
function docs_read(int $id) : array
{
$id_encoded = docs_id_encode($id);
if (! \array_key_exists($id_encoded, docs_state::$pool))
{
throw (new Error('not found'));
}
else
{
return docs_state::$pool[$id_encoded];
}
}
/**
*/
function docs_create(array $doc) : int
{
docs_state::$current_id += 1;
$id = docs_state::$current_id;
$id_encoded = docs_id_encode($id);
docs_state::$pool[$id_encoded] = $doc;
return $id;
}
/**
*/
function docs_update(int $id, array $doc) : void
{
$id_encoded = docs_id_encode($id);
if (! \array_key_exists($id_encoded, docs_state::$pool))
{
throw (new Error('not found'));
}
else
{
docs_state::$pool[$id_encoded] = $doc;
}
}
/**
*/
function docs_delete(int $id) : void
{
$id_encoded = docs_id_encode($id);
if (! \array_key_exists($id_encoded, docs_state::$pool))
{
throw (new Error('not found'));
}
else
{
docs_state::$pool[$id_encoded] = null;
unset(docs_state::$pool[$id_encoded]);
}
}
/**
*/
function docs_add_examples() : void
{
docs_create(
[
'title' => 'Freibier bei Parteitagen',
'authors' => [
'Björn Biernot',
'Doreen Dauerdurst',
],
'content' => 'Wir haben Durst!',
'reasoning' => null,
]
);
}
?>

72
source/style.css Normal file
View file

@ -0,0 +1,72 @@
:root
{
--hue: 0;
}
html
{
background-color: hsl(var(--hue), 0%, 0%);
color: hsl(var(--hue), 0%, 100%);
font-family: sans-serif;
}
body
{
max-width: 960px;
margin: auto;
padding: 16px;
background-color: hsl(var(--hue), 0%, 12.5%);
color: hsl(var(--hue), 0%, 87.5%);
}
a
{
background-color: hsl(var(--hue), 0%, 12.5%);
color: hsl(var(--hue), 50%, 50%);
text-decoration: none;
}
a:hover
{
background-color: hsl(var(--hue), 0%, 12.5%);
color: hsl(var(--hue), 50%, 75%);
}
label
{
display: block;
margin-bottom: 16px;
}
label > span
{
display: block;
font-weight: bold;
margin-bottom: 4px;
}
input[type="text"]
{
min-width: 480px;
padding: 4px;
background-color: hsl(var(--hue), 0%, 25%);
color: hsl(var(--hue), 0%, 100%);
border: none;
}
textarea
{
min-width: 480px;
min-height: 120px;
padding: 4px;
background-color: hsl(var(--hue), 0%, 25%);
color: hsl(var(--hue), 0%, 100%);
border: none;
}

View file

@ -0,0 +1,26 @@
<div id="docs-edit">
<form method="GET">
<input type="hidden" name="mode" value="save"/>
<input type="hidden" name="id" value="{{id}}"/>
<label>
<span>Titel</span>
<input type="text" name="title" value="{{title}}"/>
</label>
<label>
<span>Autoren</span>
<input type="text" name="authors" value="{{authors}}"/>
</label>
<label>
<span>Formulierung</span>
<textarea name="content">{{content}}</textarea>
</label>
<label>
<span>Begründung</span>
<textarea name="reasoning">{{reasoning}}</textarea>
</label>
<label>
<input type="submit" value="Speichern"/>
</label>
</form>
<a href="{{link_back}}">zurück</a>
</div>

View file

@ -0,0 +1,3 @@
<li class="docs-list-entry">
<a href="{{link}}">{{text}}</a>
</li>

View file

@ -0,0 +1,6 @@
<div id="docs-list">
<ul>
{{entries}}
</ul>
<a href="{{link_new}}">Neu</a>
</div>

12
tools/build Executable file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env sh
## consts
dir_build="build"
dir_source="source"
## exec
mkdir -p ${dir_build}
cp -r -u -v ${dir_source}/* ${dir_build}/

3
tools/run Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
php -S localhost:8000 -t build