Fix doc update-by-ID problem

- Rework imports for pages
- Ready for final end-to-end test before merge
This commit is contained in:
Daniel J. Summers 2024-06-08 13:34:14 -04:00
parent efa69f2c1c
commit edc9a218b7
12 changed files with 67 additions and 104 deletions

4
src/composer.lock generated
View File

@ -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",

View File

@ -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;
}
}

View File

@ -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";

View File

@ -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';

View File

@ -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();
}

View File

@ -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();

View File

@ -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';

View File

@ -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(),

View File

@ -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");
}

View File

@ -9,8 +9,7 @@
include '../../start.php';
use FeedReaderCentral\Key;
use FeedReaderCentral\Security;
use FeedReaderCentral\{Key, Security};
Security::verifyUser(redirectIfAnonymous: false);

View File

@ -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();
}

View File

@ -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: