Documents and Documentation (beta 1) #23
4
src/composer.lock
generated
4
src/composer.lock
generated
|
@ -12,7 +12,7 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://git.bitbadger.solutions/bit-badger/pdo-document",
|
||||
"reference": "2d8f8b6e8728f8fbe0d801e2bc529a678f65ad9b"
|
||||
"reference": "a10ecbb1cdfdf6dd8ab3c1884b09d9ba987b7ff5"
|
||||
},
|
||||
"require": {
|
||||
"ext-pdo": "*",
|
||||
|
@ -36,7 +36,7 @@
|
|||
"Test\\Integration\\SQLite\\": "./tests/integration/sqlite"
|
||||
}
|
||||
},
|
||||
"time": "2024-06-08T14:49:52+00:00"
|
||||
"time": "2024-06-08T16:57:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "netresearch/jsonmapper",
|
||||
|
|
|
@ -269,9 +269,7 @@ class Feed
|
|||
*/
|
||||
public static function retrieveById(int $feedId): static|false
|
||||
{
|
||||
define('PDO_DOC_DEBUG_SQL', true);
|
||||
$doc = Find::byId(Table::FEED, $feedId, static::class);
|
||||
echo "Feed $feedId: " . ($doc ? 'found it' : 'not found');
|
||||
return $doc && $doc->user_id == $_SESSION[Key::USER_ID] ? $doc : false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ class ItemList
|
|||
$this->dbList = Custom::list(
|
||||
ItemWithFeed::SELECT_WITH_FEED . ' WHERE '
|
||||
. Query::whereByFields(array_filter($allFields, fn($it) => $it->paramName <> ':search'))
|
||||
. $searchWhere,
|
||||
. "$searchWhere ORDER BY coalesce(item.data->>'updated_on', item.data->>'published_on') DESC",
|
||||
Parameters::addFields($allFields, []), new DocumentMapper(ItemWithFeed::class));
|
||||
} catch (DocumentException $ex) {
|
||||
$this->error = "$ex";
|
||||
|
|
|
@ -6,10 +6,8 @@
|
|||
* This will display a button which will either add or remove a bookmark for a given item.
|
||||
*/
|
||||
|
||||
use BitBadger\PDODocument\DocumentException;
|
||||
use BitBadger\PDODocument\Patch;
|
||||
use FeedReaderCentral\ItemWithFeed;
|
||||
use FeedReaderCentral\Table;
|
||||
use BitBadger\PDODocument\{DocumentException, Patch};
|
||||
use FeedReaderCentral\{ItemWithFeed, Table};
|
||||
|
||||
include '../start.php';
|
||||
|
||||
|
|
|
@ -6,18 +6,14 @@
|
|||
* Allows users to add, edit, and delete feeds
|
||||
*/
|
||||
|
||||
use BitBadger\PDODocument\Delete;
|
||||
use BitBadger\PDODocument\DocumentException;
|
||||
use BitBadger\PDODocument\Field;
|
||||
use FeedReaderCentral\Feed;
|
||||
use FeedReaderCentral\Security;
|
||||
use FeedReaderCentral\Table;
|
||||
use BitBadger\PDODocument\{Delete, DocumentException, Field};
|
||||
use FeedReaderCentral\{Feed, Security, Table};
|
||||
|
||||
include '../../start.php';
|
||||
|
||||
Security::verifyUser();
|
||||
|
||||
$feedId = $_GET['id'] ?? '';
|
||||
$feedId = key_exists('id', $_GET) ? (int)$_GET['id'] : -1;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
|
||||
try {
|
||||
|
@ -37,10 +33,11 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
|||
if ($isNew) {
|
||||
$result = Feed::add($_POST['url']);
|
||||
} else {
|
||||
$toEdit = Feed::retrieveById($_POST['id']);
|
||||
$feedId = (int)$_POST['id'];
|
||||
$toEdit = Feed::retrieveById($feedId);
|
||||
$result = $toEdit
|
||||
? Feed::update($toEdit, $_POST['url'])
|
||||
: ['error' => "Feed {$_POST['id']} not found"];
|
||||
: ['error' => "Feed $feedId not found"];
|
||||
}
|
||||
if (key_exists('ok', $result)) {
|
||||
add_info('Feed saved successfully');
|
||||
|
@ -53,16 +50,13 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
|||
}
|
||||
}
|
||||
|
||||
if ($feedId == 'new') {
|
||||
$title = 'Add RSS Feed';
|
||||
$feed = new Feed();
|
||||
$feed->id = $_GET['id'];
|
||||
if ($feedId == -1) {
|
||||
$title = 'Add RSS Feed';
|
||||
$feed = new Feed(id: -1);
|
||||
} else {
|
||||
$title = 'Edit RSS Feed';
|
||||
if ($feedId == 'error') {
|
||||
$feed = new Feed();
|
||||
$feed->id = $_POST['id'] ?? '';
|
||||
$feed->url = $_POST['url'] ?? '';
|
||||
$feed = new Feed(id: (int)$_POST['id'], url: $_POST['url'] ?? '');
|
||||
} elseif (!($feed = Feed::retrieveById((int)$feedId))) not_found();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
* Lists items in a given feed (all, unread, or bookmarked)
|
||||
*/
|
||||
|
||||
use FeedReaderCentral\Feed;
|
||||
use FeedReaderCentral\ItemList;
|
||||
use FeedReaderCentral\{Feed, ItemList};
|
||||
|
||||
include '../../start.php';
|
||||
|
||||
|
@ -22,11 +21,11 @@ $list = match (true) {
|
|||
default => ItemList::allForFeed($feed->id)
|
||||
};
|
||||
|
||||
page_head(($list->itemType != '' ? "$list->itemType Items | " : '') . strip_tags($feed['title']));
|
||||
page_head(($list->itemType != '' ? "$list->itemType Items | " : '') . strip_tags($feed->title));
|
||||
if ($list->itemType == '') {
|
||||
echo '<h1>' . htmlentities($feed['title']) . '</h1>';
|
||||
echo '<h1>' . htmlentities($feed->title) . '</h1>';
|
||||
} else {
|
||||
echo '<h1 class=item_heading>' . htmlentities($feed['title']) . '</h1>';
|
||||
echo '<h1 class=item_heading>' . htmlentities($feed->title) . '</h1>';
|
||||
echo "<div class=item_published>$list->itemType Items</div>";
|
||||
}
|
||||
$list->render();
|
||||
|
|
|
@ -6,14 +6,9 @@
|
|||
* List feeds and provide links for maintenance actions
|
||||
*/
|
||||
|
||||
use BitBadger\PDODocument\Custom;
|
||||
use BitBadger\PDODocument\Field;
|
||||
use BitBadger\PDODocument\Mapper\ArrayMapper;
|
||||
use BitBadger\PDODocument\Mapper\DocumentMapper;
|
||||
use BitBadger\PDODocument\Query;
|
||||
use FeedReaderCentral\Feed;
|
||||
use FeedReaderCentral\Key;
|
||||
use FeedReaderCentral\Table;
|
||||
use BitBadger\PDODocument\{Custom, Field, Query};
|
||||
use BitBadger\PDODocument\Mapper\{ArrayMapper, DocumentMapper};
|
||||
use FeedReaderCentral\{Feed, Key, Table};
|
||||
|
||||
include '../start.php';
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
* Displays a list of unread or bookmarked items for the current user
|
||||
*/
|
||||
|
||||
use FeedReaderCentral\Feed;
|
||||
use FeedReaderCentral\ItemList;
|
||||
use FeedReaderCentral\{Feed, ItemList};
|
||||
|
||||
include '../start.php';
|
||||
|
||||
|
@ -21,7 +20,6 @@ if (key_exists('refresh', $_GET)) {
|
|||
add_error(nl2br($refreshResult['error']));
|
||||
}
|
||||
}
|
||||
//const PDO_DOC_DEBUG_SQL = true;
|
||||
|
||||
$list = match (true) {
|
||||
key_exists('bookmarked', $_GET) => ItemList::allBookmarked(),
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
* Retrieves and displays an item from a feed belonging to the current user
|
||||
*/
|
||||
|
||||
use BitBadger\PDODocument\DocumentException;
|
||||
use BitBadger\PDODocument\Delete;
|
||||
use BitBadger\PDODocument\Patch;
|
||||
use FeedReaderCentral\ItemWithFeed;
|
||||
use FeedReaderCentral\Table;
|
||||
use BitBadger\PDODocument\{Delete, DocumentException, Patch};
|
||||
use FeedReaderCentral\{ItemWithFeed, Table};
|
||||
|
||||
include '../start.php';
|
||||
|
||||
|
@ -38,9 +35,7 @@ $from = $_GET['from'] ?? '/';
|
|||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
|
||||
try {
|
||||
if (ItemWithFeed::existsById($id)) {
|
||||
Delete::byId(Table::ITEM, $id);
|
||||
}
|
||||
if (ItemWithFeed::existsById($id)) Delete::byId(Table::ITEM, $id);
|
||||
} catch (DocumentException $ex) {
|
||||
add_error("$ex");
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
|
||||
include '../../start.php';
|
||||
|
||||
use FeedReaderCentral\Key;
|
||||
use FeedReaderCentral\Security;
|
||||
use FeedReaderCentral\{Key, Security};
|
||||
|
||||
Security::verifyUser(redirectIfAnonymous: false);
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
use FeedReaderCentral\Key;
|
||||
use FeedReaderCentral\Security;
|
||||
use FeedReaderCentral\User;
|
||||
use FeedReaderCentral\{Key, Security, User};
|
||||
|
||||
require 'app-config.php';
|
||||
|
||||
|
@ -12,8 +10,6 @@ session_start([
|
|||
'cookie_httponly' => true,
|
||||
'cookie_samesite' => 'Strict']);
|
||||
|
||||
//const PDO_DOC_DEBUG_SQL = true;
|
||||
|
||||
/**
|
||||
* Add a message to be displayed at the top of the page
|
||||
*
|
||||
|
@ -66,26 +62,25 @@ function nav_link(string $link, bool $isFirst = false): void
|
|||
*/
|
||||
function title_bar(): void
|
||||
{
|
||||
$version = display_version(); ?>
|
||||
<header hx-target=#main hx-push-url=true>
|
||||
<div><a href=/ class=title>Feed Reader Central</a><span class=version><?=$version?></span></div>
|
||||
<nav><?php
|
||||
if (key_exists(Key::USER_ID, $_SESSION)) {
|
||||
nav_link(hx_get('/feeds', 'Feeds'), true);
|
||||
if (User::hasBookmarks()) nav_link(hx_get('/?bookmarked', 'Bookmarked'));
|
||||
nav_link(hx_get('/search', 'Search'));
|
||||
nav_link(hx_get('/docs/', 'Docs'));
|
||||
nav_link('<a href=/user/log-off>Log Off</a>');
|
||||
if ($_SESSION[Key::USER_EMAIL] != Security::SINGLE_USER_EMAIL) {
|
||||
nav_link($_SESSION[Key::USER_EMAIL]);
|
||||
}
|
||||
} else {
|
||||
nav_link(hx_get('/user/log-on', 'Log On'), true);
|
||||
nav_link(hx_get('/docs/', 'Docs'));
|
||||
} ?>
|
||||
</nav>
|
||||
</header>
|
||||
<main id=main hx-target=this hx-push-url=true hx-swap="innerHTML show:window:top"><?php
|
||||
$version = display_version();
|
||||
echo "<header hx-target=#main hx-push-url=true>"
|
||||
. "<div><a href=/ class=title>Feed Reader Central</a><span class=version>$version</span></div>"
|
||||
. "<nav>";
|
||||
if (key_exists(Key::USER_ID, $_SESSION)) {
|
||||
nav_link(hx_get('/feeds', 'Feeds'), true);
|
||||
if (User::hasBookmarks()) nav_link(hx_get('/?bookmarked', 'Bookmarked'));
|
||||
nav_link(hx_get('/search', 'Search'));
|
||||
nav_link(hx_get('/docs/', 'Docs'));
|
||||
nav_link('<a href=/user/log-off>Log Off</a>');
|
||||
if ($_SESSION[Key::USER_EMAIL] != Security::SINGLE_USER_EMAIL) {
|
||||
nav_link($_SESSION[Key::USER_EMAIL]);
|
||||
}
|
||||
} else {
|
||||
nav_link(hx_get('/user/log-on', 'Log On'), true);
|
||||
nav_link(hx_get('/docs/', 'Docs'));
|
||||
}
|
||||
echo '</nav></header>'
|
||||
. '<main id=main hx-target=this hx-push-url=true hx-swap="innerHTML show:window:top">';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,28 +89,24 @@ function title_bar(): void
|
|||
*/
|
||||
function page_head(string $title): void
|
||||
{
|
||||
global $is_htmx; ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang=en>
|
||||
<head>
|
||||
<title><?=$title?> | Feed Reader Central</title><?php
|
||||
if (!$is_htmx) { ?>
|
||||
<meta name=viewport content="width=device-width, initial-scale=1">
|
||||
<meta name=htmx-config content='{"historyCacheSize":0}'>
|
||||
<link href=/assets/style.css rel=stylesheet><?php
|
||||
} ?>
|
||||
</head>
|
||||
<body><?php
|
||||
global $is_htmx;
|
||||
echo '<!DOCTYPE html><html lang=en>'
|
||||
. "<head><title>$title | Feed Reader Central</title>";
|
||||
if (!$is_htmx) {
|
||||
echo '<meta name=viewport content="width=device-width, initial-scale=1">'
|
||||
. "<meta name=htmx-config content='{\"historyCacheSize\":0}'>"
|
||||
. '<link href=/assets/style.css rel=stylesheet>';
|
||||
}
|
||||
echo '</head><body>';
|
||||
if (!$is_htmx) title_bar();
|
||||
if (sizeof($messages = $_SESSION[Key::USER_MSG] ?? []) > 0) { ?>
|
||||
<div class=user_messages><?php
|
||||
array_walk($messages, function ($msg) { ?>
|
||||
<div class=user_message>
|
||||
<?=$msg['level'] == 'INFO' ? '' : "<strong>{$msg['level']}</strong><br>"?>
|
||||
<?=$msg['message']?>
|
||||
</div><?php
|
||||
}); ?>
|
||||
</div><?php
|
||||
if (sizeof($messages = $_SESSION[Key::USER_MSG] ?? []) > 0) {
|
||||
echo '<div class=user_messages>';
|
||||
array_walk($messages, function ($msg) {
|
||||
echo '<div class=user_message>'
|
||||
. ($msg['level'] == 'INFO' ? '' : "<strong>{$msg['level']}</strong><br>")
|
||||
. $msg['message'] . '</div>';
|
||||
});
|
||||
echo '</div>';
|
||||
$_SESSION[Key::USER_MSG] = [];
|
||||
}
|
||||
}
|
||||
|
@ -125,11 +116,8 @@ function page_head(string $title): void
|
|||
*/
|
||||
function page_foot(): void
|
||||
{
|
||||
global $is_htmx; ?>
|
||||
</main><?php
|
||||
if (!$is_htmx) echo '<script src=/assets/htmx.min.js></script>'; ?>
|
||||
</body>
|
||||
</html><?php
|
||||
global $is_htmx;
|
||||
echo '</main>' . ($is_htmx ? '' : '<script src=/assets/htmx.min.js></script>') . '</body></html>';
|
||||
session_commit();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
* On initial installation, rename this file to user-config.php and configure it as desired
|
||||
*/
|
||||
|
||||
use FeedReaderCentral\Feed;
|
||||
use FeedReaderCentral\Security;
|
||||
use FeedReaderCentral\{Feed, Security};
|
||||
|
||||
/**
|
||||
* Which security model should the application use? Options are:
|
||||
|
|
Loading…
Reference in New Issue
Block a user