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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user