Use bind() for result steps
This commit is contained in:
parent
f5feef177a
commit
adcfd9d02a
12
src/composer.lock
generated
12
src/composer.lock
generated
@ -8,11 +8,11 @@
|
||||
"packages": [
|
||||
{
|
||||
"name": "bit-badger/inspired-by-fsharp",
|
||||
"version": "v1.0.0-beta1",
|
||||
"version": "v1.0.0-beta2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp",
|
||||
"reference": "efb3a4461edcb23e0dd82068adeb0591240870b0"
|
||||
"reference": "fad428a4e40b606987499b17bb2d5b7d4b04502d"
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.2"
|
||||
@ -49,15 +49,15 @@
|
||||
"rss": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp.rss",
|
||||
"source": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp"
|
||||
},
|
||||
"time": "2024-07-28T21:35:11+00:00"
|
||||
"time": "2024-07-29T17:58:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bit-badger/pdo-document",
|
||||
"version": "v1.0.0-beta8",
|
||||
"version": "v1.0.0-beta9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://git.bitbadger.solutions/bit-badger/pdo-document",
|
||||
"reference": "039283224a173bd3e8a9bc5de0caf349ba7b58e6"
|
||||
"reference": "9e0e663811d9dbbdb94a2c04ce8b874e91a7c85b"
|
||||
},
|
||||
"require": {
|
||||
"bit-badger/inspired-by-fsharp": "^1",
|
||||
@ -103,7 +103,7 @@
|
||||
"rss": "https://git.bitbadger.solutions/bit-badger/pdo-document.rss",
|
||||
"source": "https://git.bitbadger.solutions/bit-badger/pdo-document"
|
||||
},
|
||||
"time": "2024-07-29T00:08:44+00:00"
|
||||
"time": "2024-07-29T20:57:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "netresearch/jsonmapper",
|
||||
|
@ -175,34 +175,31 @@ class Feed
|
||||
* @param int $feedId The ID of the feed to be refreshed
|
||||
* @param string $url The URL of the feed to be refreshed
|
||||
* @return Result<true, string> True if successful, an error message if not
|
||||
* @throws DocumentException If any is encountered
|
||||
*/
|
||||
public static function refreshFeed(int $feedId, string $url): Result
|
||||
{
|
||||
$tryRetrieve = ParsedFeed::retrieve($url);
|
||||
if ($tryRetrieve->isError()) return $tryRetrieve;
|
||||
$feed = $tryRetrieve->getOK();
|
||||
return ParsedFeed::retrieve($url)
|
||||
->bind(function (ParsedFeed $feed) use ($feedId, $url) {
|
||||
try {
|
||||
$feedDoc = Find::byId(Table::Feed, $feedId, self::class);
|
||||
if ($feedDoc->isNone()) return Result::Error('Could not derive date last checked for feed');
|
||||
$lastChecked = date_create_immutable($feedDoc->get()->checked_on ?? WWW_EPOCH);
|
||||
|
||||
try {
|
||||
$feedDoc = Find::byId(Table::Feed, $feedId, self::class);
|
||||
if ($feedDoc->isNone()) return Result::Error('Could not derive date last checked for feed');
|
||||
$lastChecked = date_create_immutable($feedDoc->get()->checked_on ?? WWW_EPOCH);
|
||||
|
||||
$itemUpdate = self::updateItems($feedId, $feed, $lastChecked);
|
||||
if ($itemUpdate->isError()) return $itemUpdate;
|
||||
|
||||
$patch = [
|
||||
'title' => $feed->title,
|
||||
'updated_on' => $feed->updatedOn,
|
||||
'checked_on' => Data::formatDate('now')
|
||||
];
|
||||
if ($url !== $feed->url) $patch['url'] = $feed->url;
|
||||
Patch::byId(Table::Feed, $feedId, $patch);
|
||||
} catch (DocumentException $ex) {
|
||||
return Result::Error("$ex");
|
||||
}
|
||||
|
||||
return PURGE_TYPE === self::PurgeNone ? Result::OK(true) : self::purgeItems($feedId);
|
||||
return self::updateItems($feedId, $feed, $lastChecked)
|
||||
->bind(function () use ($feed, $feedId, $url) {
|
||||
$patch = [
|
||||
'title' => $feed->title,
|
||||
'updated_on' => $feed->updatedOn,
|
||||
'checked_on' => Data::formatDate('now')
|
||||
];
|
||||
if ($url !== $feed->url) $patch['url'] = $feed->url;
|
||||
Patch::byId(Table::Feed, $feedId, $patch);
|
||||
})
|
||||
->bind(fn() => PURGE_TYPE === self::PurgeNone ? Result::OK(true) : self::purgeItems($feedId));
|
||||
} catch (DocumentException $ex) {
|
||||
return Result::Error("$ex");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,27 +210,25 @@ class Feed
|
||||
*/
|
||||
public static function add(string $url): Result
|
||||
{
|
||||
$tryRetrieve = ParsedFeed::retrieve($url);
|
||||
if ($tryRetrieve->isError()) return $tryRetrieve;
|
||||
$feed = $tryRetrieve->getOK();
|
||||
return ParsedFeed::retrieve($url)
|
||||
->bind(function (ParsedFeed $feed) {
|
||||
try {
|
||||
$fields = [Field::EQ('user_id', $_SESSION[Key::UserId]), Field::EQ('url', $feed->url)];
|
||||
if (Exists::byFields(Table::Feed, $fields)) {
|
||||
return Result::Error("Already subscribed to feed $feed->url");
|
||||
}
|
||||
|
||||
try {
|
||||
$fields = [Field::EQ('user_id', $_SESSION[Key::UserId]), Field::EQ('url', $feed->url)];
|
||||
if (Exists::byFields(Table::Feed, $fields)) {
|
||||
return Result::Error("Already subscribed to feed $feed->url");
|
||||
}
|
||||
Document::insert(Table::Feed, self::fromParsed($feed));
|
||||
|
||||
Document::insert(Table::Feed, self::fromParsed($feed));
|
||||
$doc = Find::firstByFields(Table::Feed, $fields, self::class);
|
||||
if ($doc->isNone()) return Result::Error('Could not retrieve inserted feed');
|
||||
|
||||
$tryDoc = Find::firstByFields(Table::Feed, $fields, self::class);
|
||||
if ($tryDoc->isNone()) return Result::Error('Could not retrieve inserted feed');
|
||||
$doc = $tryDoc->get();
|
||||
|
||||
$result = self::updateItems($doc->id, $feed, date_create_immutable(WWW_EPOCH));
|
||||
return $result->isError() ? $result : Result::OK($doc->id);
|
||||
} catch (DocumentException $ex) {
|
||||
return Result::Error("$ex");
|
||||
}
|
||||
return self::updateItems($doc->get()->id, $feed, date_create_immutable(WWW_EPOCH))
|
||||
->bind(fn() => Result::OK($doc->get()->id));
|
||||
} catch (DocumentException $ex) {
|
||||
return Result::Error("$ex");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,39 +239,38 @@ readonly class ParsedFeed
|
||||
*/
|
||||
public static function retrieve(string $url): Result
|
||||
{
|
||||
$tryDoc = self::retrieveDocument($url);
|
||||
if ($tryDoc->isError()) return $tryDoc;
|
||||
|
||||
$doc = $tryDoc->getOK();
|
||||
if ($doc['code'] !== 200) {
|
||||
return Result::Error("Prospective feed URL $url returned HTTP Code {$doc['code']}: {$doc['content']}");
|
||||
}
|
||||
|
||||
$start = strtolower(strlen($doc['content']) >= 9 ? substr($doc['content'], 0, 9) : $doc['content']);
|
||||
if ($start === '<!doctype' || str_starts_with($start, '<html')) {
|
||||
$derivedURL = self::deriveFeedFromHTML($doc['content']);
|
||||
if ($derivedURL->isError()) return $derivedURL;
|
||||
$feedURL = $derivedURL->getOK();
|
||||
if (!str_starts_with($feedURL, 'http')) {
|
||||
// Relative URL; feed should be retrieved in the context of the original URL
|
||||
$original = parse_url($url);
|
||||
$port = key_exists('port', $original) ? ":{$original['port']}" : '';
|
||||
$feedURL = $original['scheme'] . '://' . $original['host'] . $port . $feedURL;
|
||||
}
|
||||
$tryDoc = self::retrieveDocument($feedURL);
|
||||
if ($tryDoc->isError()) return $tryDoc;
|
||||
$doc = $tryDoc->getOK();
|
||||
if ($doc['code'] !== 200) {
|
||||
return Result::Error("Derived feed URL $url returned HTTP Code {$doc['code']}: {$doc['content']}");
|
||||
}
|
||||
}
|
||||
|
||||
$tryParse = self::parseFeed($doc['content']);
|
||||
if ($tryParse->isError()) return $tryParse;
|
||||
|
||||
$parsed = $tryParse->getOK();
|
||||
$extract = $parsed->getElementsByTagNameNS(self::ATOM_NS, 'feed')->length > 0
|
||||
? self::fromAtom(...) : self::fromRSS(...);
|
||||
return $extract($parsed, $doc['url']);
|
||||
$doc = self::retrieveDocument($url)
|
||||
->bind(fn(array $doc) => match ($doc['code']) {
|
||||
200 => Result::OK($doc),
|
||||
default => Result::Error(
|
||||
"Prospective feed URL $url returned HTTP Code {$doc['code']}: {$doc['content']}"),
|
||||
})
|
||||
->bind(function (array $doc) use ($url) {
|
||||
$start = strtolower(strlen($doc['content']) >= 9 ? substr($doc['content'], 0, 9) : $doc['content']);
|
||||
return $start === '<!doctype' || str_starts_with($start, '<html')
|
||||
? self::deriveFeedFromHTML($doc['content'])
|
||||
->bind(function (string $feedURL) use ($url) {
|
||||
if (!str_starts_with($feedURL, 'http')) {
|
||||
// Relative URL; feed should be retrieved in the context of the original URL
|
||||
$original = parse_url($url);
|
||||
$port = key_exists('port', $original) ? ":{$original['port']}" : '';
|
||||
$feedURL = $original['scheme'] . '://' . $original['host'] . $port . $feedURL;
|
||||
}
|
||||
return self::retrieveDocument($feedURL);
|
||||
})
|
||||
->bind(fn($doc) => match ($doc['code']) {
|
||||
200 => Result::OK($doc),
|
||||
default => Result::Error(
|
||||
"Derived feed URL {$doc['url']} returned HTTP Code {$doc['code']}: {$doc['content']}"),
|
||||
})
|
||||
: Result::OK($doc);
|
||||
});
|
||||
return $doc
|
||||
->bind(fn($doc) => self::parseFeed($doc['content']))
|
||||
->bind(function (DOMDocument $parsed) use ($doc) {
|
||||
$extract = $parsed->getElementsByTagNameNS(self::ATOM_NS, 'feed')->length > 0
|
||||
? self::fromAtom(...) : self::fromRSS(...);
|
||||
return $extract($parsed, $doc['url']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -44,10 +44,10 @@ switch ($_SERVER['REQUEST_METHOD']) {
|
||||
? Feed::update($toEdit->get(), $_POST['url'])
|
||||
: Result::Error("Feed $feedId not found");
|
||||
}
|
||||
if ($result->isOK()) {
|
||||
$result->iter(function () {
|
||||
add_info('Feed saved successfully');
|
||||
frc_redirect('/feeds');
|
||||
}
|
||||
});
|
||||
add_error($result->getError());
|
||||
$feedId = 'error';
|
||||
} catch (DocumentException $ex) {
|
||||
|
Loading…
Reference in New Issue
Block a user