WIP on adding feed items (#4)
This commit is contained in:
parent
5c92c8c7d6
commit
0530ed0dc9
@ -51,12 +51,14 @@ class Data {
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
feed_id INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
item_guid TEXT NOT NULL,
|
||||
item_link TEXT NOT NULL,
|
||||
published_on TEXT NOT NULL,
|
||||
updated_on TEXT,
|
||||
content TEXT NOT NULL,
|
||||
is_encoded BOOLEAN NOT NULL,
|
||||
is_read BOOLEAN NOT NULL,
|
||||
is_bookmarked BOOLEAN NOT NULL,
|
||||
is_read BOOLEAN NOT NULL DEFAULT 0,
|
||||
is_bookmarked BOOLEAN NOT NULL DEFAULT 0,
|
||||
FOREIGN KEY (feed_id) REFERENCES feed (id))
|
||||
SQL;
|
||||
$db->exec($query);
|
||||
@ -109,7 +111,7 @@ class Data {
|
||||
if ($updatedOn) {
|
||||
try {
|
||||
$updated = (new DateTimeImmutable($updatedOn))->format(DateTimeInterface::ATOM);
|
||||
} catch (Exception $ex) {
|
||||
} catch (Exception) {
|
||||
$updated = null;
|
||||
}
|
||||
} else {
|
||||
@ -123,11 +125,48 @@ class Data {
|
||||
$query->bindValue(':updated', $updated);
|
||||
$query->bindValue(':checked', (new DateTimeImmutable())->format(DateTimeInterface::ATOM));
|
||||
$result = $query->execute();
|
||||
if ($result) {
|
||||
$idQuery = $db->prepare('SELECT last_insert_rowid()');
|
||||
$idResult = $idQuery->execute();
|
||||
if ($idResult) return $idResult->fetchArray(SQLITE3_NUM)[0];
|
||||
}
|
||||
return -1;
|
||||
return $result ? $db->lastInsertRowID() : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a feed item already exist?
|
||||
* @param int $feedId The ID of the feed to which the item belongs
|
||||
* @param string $guid The GUID from the RSS feed, uniquely identifying the item
|
||||
* @return bool True if the item exists, false if not
|
||||
*/
|
||||
public static function itemExists(int $feedId, string $guid): bool {
|
||||
$db = self::getConnection();
|
||||
$query = $db->prepare('SELECT COUNT(*) FROM item WHERE feed_id = :feed AND item_guid = :guid');
|
||||
$query->bindValue(':feed', $feedId);
|
||||
$query->bindValue(':guid', $guid);
|
||||
$result = $query->execute();
|
||||
return $result && $result->fetchArray(SQLITE3_NUM)[0] == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a feed item
|
||||
* @param int $feedId The ID of the feed to which the item should be added
|
||||
* @param string $guid The GUID from the RSS feed (uses link if `<guid>` not specified)
|
||||
* @param string $link The link to this item
|
||||
* @param string $title The title of the item
|
||||
* @param string $published The date/time the item was published
|
||||
* @param string $content The content of the item
|
||||
* @param bool $isEncoded Whether the content has HTML (true) or is plaintext (false)
|
||||
* @throws Exception If the published date is not valid
|
||||
*/
|
||||
public static function addItem(int $feedId, string $guid, string $link, string $title, string $published,
|
||||
string $content, bool $isEncoded): void {
|
||||
$db = self::getConnection();
|
||||
$query = $db->prepare(
|
||||
'INSERT INTO item (feed_id, item_guid, item_link, title, published_on, content, is_encoded)'
|
||||
. ' VALUES (:feed, :guid, :link, :title, :published, :content, :encoded)');
|
||||
$query->bindValue(':feed', $feedId);
|
||||
$query->bindValue(':guid', $guid);
|
||||
$query->bindValue(':link', $link);
|
||||
$query->bindValue(':title', $title);
|
||||
$query->bindValue(':published', (new DateTimeImmutable($published))->format(DateTimeInterface::ATOM));
|
||||
$query->bindValue(':content', $content);
|
||||
$query->bindValue(':encoded', $isEncoded);
|
||||
$query->execute();
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,40 @@ class Feed {
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a feed's items
|
||||
* @param int $feedId The ID of the feed to which these items belong
|
||||
* @param SimpleXMLElement $channel The RSS feed items
|
||||
* @return array [ 'ok' => true ] if successful, [ 'error' => message ] if not
|
||||
*/
|
||||
public static function updateItems(int $feedId, SimpleXMLElement $channel): array {
|
||||
try {
|
||||
for ($i = 0; $i < sizeof($channel->item); $i++) {
|
||||
$item = $channel->item[$i];
|
||||
$itemGuid = (string)$item->guid ? $item->guid : $item->link;
|
||||
$isNew = !Data::itemExists($feedId, $itemGuid);
|
||||
if ($isNew) {
|
||||
$title = (string)$item->title;
|
||||
$link = (string)$item->link;
|
||||
$published = (string)$item->pubDate;
|
||||
// TODO: why is this getting all encoded content, and not just the one for the current item?
|
||||
$encodedContent = $item->xpath('//content:encoded');
|
||||
if ($encodedContent) {
|
||||
$content = (string) $encodedContent[$i];
|
||||
$isEncoded = true;
|
||||
} else {
|
||||
$content = $item->description;
|
||||
$isEncoded = false;
|
||||
}
|
||||
Data::addItem($feedId, $itemGuid, $link, $title, $published, $content, $isEncoded);
|
||||
} // TODO: else check updated date; may want to return that from the isNew check instead
|
||||
}
|
||||
} catch (Exception $ex) {
|
||||
return [ 'error' => $ex->getMessage() ];
|
||||
}
|
||||
return [ 'ok', true ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an RSS feed
|
||||
* @param string $url The URL of the RSS feed to add
|
||||
@ -64,6 +98,9 @@ class Feed {
|
||||
$channel = $feed['ok']->channel;
|
||||
$feedId = Data::addFeed($feed['url'], (string) $channel->title, (string) $channel->lastBuildDate);
|
||||
|
||||
$result = self::updateItems($feedId, $channel);
|
||||
if (array_key_exists('error', $result)) return $result;
|
||||
|
||||
return [ 'ok' => true ];
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ Security::verifyUser();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// TODO: get feed, add if new, reject if existing but not owned by this user, update otherwise
|
||||
$result = Feed::add($_POST['url']);
|
||||
echo '<pre>'; var_dump($result); echo '</pre>';
|
||||
$feed = [ 'id' => $_POST['id'], 'url' => $_POST['url'] ];
|
||||
$title = 'TODO';
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user