Retrieve feed, add to database (#4)

This commit is contained in:
Daniel J. Summers 2024-04-09 21:16:34 -04:00
parent c89e6af346
commit 5c92c8c7d6
3 changed files with 104 additions and 0 deletions

View File

@ -96,4 +96,38 @@ class Data {
$query->bindValue(':password', password_hash($password, PASSWORD_DEFAULT)); $query->bindValue(':password', password_hash($password, PASSWORD_DEFAULT));
$query->execute(); $query->execute();
} }
/**
* Add an RSS feed
* @param string $url The URL for the RSS feed
* @param string $title The title of the RSS feed
* @param string $updatedOn The date/time the RSS feed was last updated (from the XML, not when we checked)
* @return int The ID of the added feed
*/
public static function addFeed(string $url, string $title, string $updatedOn): int {
$db = self::getConnection();
if ($updatedOn) {
try {
$updated = (new DateTimeImmutable($updatedOn))->format(DateTimeInterface::ATOM);
} catch (Exception $ex) {
$updated = null;
}
} else {
$updated = null;
}
$query = $db->prepare('INSERT INTO feed (user_id, url, title, updated_on, checked_on)'
. ' VALUES (:user, :url, :title, :updated, :checked)');
$query->bindValue(':user', $_REQUEST['FRC_USER_ID']);
$query->bindValue(':url', $url);
$query->bindValue(':title', $title);
$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;
}
} }

69
src/lib/Feed.php Normal file
View File

@ -0,0 +1,69 @@
<?php
/**
* Feed retrieval, parsing, and manipulation
*/
class Feed {
/**
* Parse a feed into an XML tree
* @param string $content The feed's RSS content
* @return array|SimpleXMLElement[]|string[] [ 'ok' => feed ] if successful, [ 'error' => message] if not
*/
public static function parseFeed(string $content): array {
try {
return [ 'ok' => new SimpleXMLElement($content) ];
} catch (Exception $ex) {
return [ 'error' => $ex->getMessage() ];
}
}
/**
* Retrieve the feed
* @param string $url
* @return array|SimpleXMLElement[]|string[] [ 'ok' => feedXml, 'url' => actualUrl ] if successful, [ 'error' => message ] if not
*/
public static function retrieveFeed(string $url): array {
$feedReq = curl_init($url);
curl_setopt($feedReq, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($feedReq, CURLOPT_RETURNTRANSFER, true);
curl_setopt($feedReq, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($feedReq, CURLOPT_TIMEOUT, 15);
$feedContent = curl_exec($feedReq);
$result = array();
$error = curl_error($feedReq);
$code = curl_getinfo($feedReq, CURLINFO_RESPONSE_CODE);
if ($error) {
$result['error'] = $error;
} else if ($code == 200) {
$parsed = self::parseFeed($feedContent);
if (array_key_exists('error', $parsed)) {
$result['error'] = $parsed['error'];
} else {
$result['ok'] = $parsed['ok'];
$result['url'] = curl_getinfo($feedReq, CURLINFO_EFFECTIVE_URL);
}
} else {
$result['error'] = "HTTP Code $code: $feedContent";
}
curl_close($feedReq);
return $result;
}
/**
* Add an RSS feed
* @param string $url The URL of the RSS feed to add
* @return array [ 'ok' => true ] if successful, [ 'error' => message ] if not
*/
public static function add(string $url): array {
$feed = self::retrieveFeed($url);
if (array_key_exists('error', $feed)) return $feed;
$channel = $feed['ok']->channel;
$feedId = Data::addFeed($feed['url'], (string) $channel->title, (string) $channel->lastBuildDate);
return [ 'ok' => true ];
}
}

View File

@ -11,6 +11,7 @@ Security::verifyUser();
if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// TODO: get feed, add if new, reject if existing but not owned by this user, update otherwise // TODO: get feed, add if new, reject if existing but not owned by this user, update otherwise
$result = Feed::add($_POST['url']);
$feed = [ 'id' => $_POST['id'], 'url' => $_POST['url'] ]; $feed = [ 'id' => $_POST['id'], 'url' => $_POST['url'] ];
$title = 'TODO'; $title = 'TODO';
} else { } else {