diff --git a/source/helpers.php b/source/helpers.php index 46b4081..546ac3b 100644 --- a/source/helpers.php +++ b/source/helpers.php @@ -2,7 +2,7 @@ namespace rosavox\helpers; - + /** */ class cache_state @@ -28,6 +28,59 @@ function cache_get(string $key, \Closure $retrieve) } +/** + */ +function database_map_type(string $type) +{ + switch ($type) + { + case 'integer': return \SQLITE3_INTEGER; + case 'string': return \SQLITE3_TEXT; + default: throw (new \Exception(\sprintf('unhandled type: %s', $type))); + } +} + + +/** + */ +function database_get(string $query_template, array $arguments) : array +{ + $connection = new \SQLite3('data.sqlite'); + $rows = $connection->query($query_template); + /* +$query = "SELECT * FROM books"; +$result = $db->query($query); + +while ($row = $result->fetchArray(SQLITE3_ASSOC)) { + */ +} + + +/** + */ +function database_put(string $query_template, array $arguments) : int +{ + $connection = new \SQLite3('data.sqlite'); + $statement = $connection->prepare($query); + foreach ($arguments as $key => $value) + { + $statement->bindValue( + \sprintf(':%s', $key), + $value['value'], + database_map_type($value['type']) + ); + } + if ($statement->execute()) { + // SELECT last_insert_rowid() + echo "Buch erfolgreich hinzugefügt!"; + } + else + { + echo "Fehler beim Hinzufügen des Buches: " . $db->lastErrorMsg(); + } +} + + /** */ function string_coin(string $template, array $arguments) : string @@ -41,6 +94,114 @@ function string_coin(string $template, array $arguments) : string } +/** + */ +class class_crud_jsonfile +{ + private string $path; + + private \Closure $id_encode; + + private \Closure $id_decode; + + public function __construct( + string $path, + \Closure $id_encode, + \Closure $id_decode + ) + { + $this->path = $path; + $this->id_encode = $id_encode; + $this->id_decode = $id_decode; + } + + private function get() : array + { + $content = (\file_exists($this->path) ? \file_get_contents($this->path) : null); + return ( + ($content === null) + ? + ['last_id' => 0, 'entries' => []] + : + \json_decode($content, true) + ); + } + + private function put(array $data) : void + { + $content = \json_encode($data, \JSON_PRETTY_PRINT); + \file_put_contents($this->path, $content); + } + + public function list_() : array + { + $data = $this->get(); + return \array_map( + fn ($id_encoded) => [ + 'id' => ($this->id_decode)($id_encoded), + 'value' => $data['entries'][$id_encoded], + ], + \array_keys($data['entries']) + ); + } + + public function read(int $id) + { + $data = $this->get(); + $id_encoded = ($this->id_encode)($id); + if (! \array_key_exists($id_encoded, $data['entries'])) + { + throw (new \Exception('not found')); + } + else + { + return $data['entries'][$id_encoded]; + } + } + + public function create($value) : int + { + $data = $this->get(); + $id = ($data['last_id'] + 1); + $id_encoded = ($this->id_encode)($id); + $data['last_id'] = $id; + $data['entries'][$id_encoded] = $value; + $this->put($data); + return $id; + } + + public function update(int $id, $value) : void + { + $data = $this->get(); + $id_encoded = ($this->id_encode)($id); + if (! \array_key_exists($id_encoded, $data['entries'])) + { + throw (new \Exception('not found')); + } + else + { + $data['entries'][$id_encoded] = $value; + $this->put($data); + } + } + + public function delete(int $id) : void + { + $data = $this->get(); + $id_encoded = ($this->id_encode)($id); + if (! \array_key_exists($id_encoded, $data['entries'])) + { + throw (new \Exception('not found')); + } + else + { + unset($data['entries'][$id_encoded]); + $this->put($data); + } + } +} + + /** */ function render(string $template_name, array $arguments) : string diff --git a/source/index.html.php b/source/index.html.php index 0140df9..f74147a 100644 --- a/source/index.html.php +++ b/source/index.html.php @@ -7,7 +7,7 @@ require_once(__DIR__ . '/logic.php'); $mode = ($_GET['mode'] ?? 'list'); $id_encoded = (! empty($_GET['id']) ? $_GET['id'] : null); -$id = (($id_encoded === null) ? null : \rosavox\logic\docs_id_decode($id_encoded)); +$id = (($id_encoded === null) ? null : \intval($id_encoded)); function nav(string $mode, array $args) : void @@ -37,15 +37,10 @@ function nav(string $mode, array $args) : void +

rosavox

\rosavox\helpers\render( 'docs-list-entry', [ - 'link' => \rosavox\helpers\string_coin( + 'link_open' => \rosavox\helpers\string_coin( '?mode=edit&id={{id}}', [ 'id' => $entry['id'], ] ), - 'text' => $entry['doc']['title'], + 'link_read' => '#not_implemented', + 'link_hear' => '#not_implemented', + 'text' => $entry['value']['title'], ] ), \rosavox\logic\docs_list() diff --git a/source/logic.php b/source/logic.php index 2ae512f..15b0056 100644 --- a/source/logic.php +++ b/source/logic.php @@ -9,60 +9,7 @@ require_once(__DIR__ . '/helpers.php'); */ class docs_state { - public static int $current_id = 0; - - /** - * @param array {record} - */ - public static array $pool = []; -} - - -/** - */ -function docs_push() : void -{ - $path = 'docs.json'; - $data = [ - 'current_id' => docs_state::$current_id, - 'pool' => docs_state::$pool, - ]; - $content = \json_encode($data, \JSON_PRETTY_PRINT); - \file_put_contents($path, $content); -} - - -/** - */ -function docs_pull() : void -{ - $path = 'docs.json'; - $content = (\file_exists($path) ? \file_get_contents($path) : null); - $data = ( - ($content === null) - ? - ['current_id' => 0, 'pool' => []] - : - \json_decode($content, true) - ); - docs_state::$current_id = $data['current_id']; - docs_state::$pool = $data['pool']; -} - - -/** - */ -function docs_id_encode(int $id) : string -{ - return \sprintf('%u', $id); -} - - -/** - */ -function docs_id_decode(string $id_encoded) : int -{ - return intval($id_encoded); + public static ?\rosavox\helpers\class_crud_jsonfile $crud = null; } @@ -70,13 +17,7 @@ function docs_id_decode(string $id_encoded) : int */ 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) - ); + return docs_state::$crud->list_(); } @@ -84,15 +25,7 @@ function docs_list() : array */ function docs_read(int $id) : array { - $id_encoded = docs_id_encode($id); - if (! \array_key_exists($id_encoded, docs_state::$pool)) - { - throw (new \Exception('not found')); - } - else - { - return docs_state::$pool[$id_encoded]; - } + return docs_state::$crud->read($id); } @@ -100,12 +33,7 @@ function docs_read(int $id) : array */ 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; - docs_push(); - return $id; + return docs_state::$crud->create($doc); } @@ -113,16 +41,7 @@ function docs_create(array $doc) : int */ 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 \Exception('not found')); - } - else - { - docs_state::$pool[$id_encoded] = $doc; - docs_push(); - } + docs_state::$crud->update($id, $doc); } @@ -130,25 +49,7 @@ function docs_update(int $id, array $doc) : void */ function docs_delete(int $id) : void { - $id_encoded = docs_id_encode($id); - if (! \array_key_exists($id_encoded, docs_state::$pool)) - { - throw (new \Exception('not found')); - } - else - { - docs_state::$pool[$id_encoded] = null; - unset(docs_state::$pool[$id_encoded]); - docs_push(); - } -} - - -/** - */ -function docs_init() : void -{ - docs_pull(); + docs_state::$crud->delete($id); } @@ -169,4 +70,24 @@ function docs_add_examples() : void ); } + +/** + */ +function docs_init() : void +{ + docs_state::$crud = new \rosavox\helpers\class_crud_jsonfile( + 'docs.json', + fn ($id) => \sprintf('%u', $id), + fn ($id_encoded) => \intval($id_encoded) + ); + if (empty(docs_state::$crud->list_())) + { + docs_add_examples(); + } + else + { + // do nothing + } +} + ?> diff --git a/source/templates/docs-list-entry.html.tpl b/source/templates/docs-list-entry.html.tpl index 62642cf..58590b2 100644 --- a/source/templates/docs-list-entry.html.tpl +++ b/source/templates/docs-list-entry.html.tpl @@ -1,3 +1,5 @@
  • - {{text}} + {{text}} + | [lesen] + | [hören]