alpha1 #8
| @ -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