134 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/**
 | 
						|
 * A centralized place for data access for the application
 | 
						|
 */
 | 
						|
class Data {
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain a new connection to the database
 | 
						|
     * @return SQLite3 A new connection to the database
 | 
						|
     */
 | 
						|
    private static function getConnection(): SQLite3 {
 | 
						|
        $db = new SQLite3('../data/' . DATABASE_NAME);
 | 
						|
        $db->exec('PRAGMA foreign_keys = ON;');
 | 
						|
        return $db;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Make sure the expected tables exist
 | 
						|
     */
 | 
						|
    public static function ensureDb(): void {
 | 
						|
        $db = self::getConnection();
 | 
						|
        $tables = array();
 | 
						|
        $tableQuery = $db->query("SELECT name FROM sqlite_master WHERE type = 'table'");
 | 
						|
        while ($table = $tableQuery->fetchArray(SQLITE3_NUM)) $tables[] = $table[0];
 | 
						|
        if (!in_array('frc_user', $tables)) {
 | 
						|
            $query = <<<'SQL'
 | 
						|
                CREATE TABLE frc_user (
 | 
						|
                    id       INTEGER NOT NULL PRIMARY KEY,
 | 
						|
                    email    TEXT    NOT NULL,
 | 
						|
                    password TEXT    NOT NULL)
 | 
						|
                SQL;
 | 
						|
            $db->exec($query);
 | 
						|
            $db->exec('CREATE INDEX idx_user_email ON frc_user (email)');
 | 
						|
        }
 | 
						|
        if (!in_array('feed', $tables)) {
 | 
						|
            $query = <<<'SQL'
 | 
						|
                CREATE TABLE feed (
 | 
						|
                    id         INTEGER NOT NULL PRIMARY KEY,
 | 
						|
                    user_id    INTEGER NOT NULL,
 | 
						|
                    url        TEXT    NOT NULL,
 | 
						|
                    title      TEXT,
 | 
						|
                    updated_on TEXT,
 | 
						|
                    checked_on TEXT,
 | 
						|
                    FOREIGN KEY (user_id) REFERENCES frc_user (id))
 | 
						|
                SQL;
 | 
						|
            $db->exec($query);
 | 
						|
        }
 | 
						|
        if (!in_array('item', $tables)) {
 | 
						|
            $query = <<<'SQL'
 | 
						|
                CREATE TABLE item (
 | 
						|
                    id            INTEGER NOT NULL PRIMARY KEY,
 | 
						|
                    feed_id       INTEGER NOT NULL,
 | 
						|
                    title         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,
 | 
						|
                    FOREIGN KEY (feed_id) REFERENCES feed (id))
 | 
						|
                SQL;
 | 
						|
            $db->exec($query);
 | 
						|
        }
 | 
						|
        $db->close();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Find a user by their ID
 | 
						|
     *
 | 
						|
     * @param string $email The e-mail address of the user to retrieve
 | 
						|
     * @return array|null The user information, or null if the user is not found
 | 
						|
     */
 | 
						|
    public static function findUserByEmail(string $email): ?array {
 | 
						|
        $db = self::getConnection();
 | 
						|
        $query = $db->prepare('SELECT * FROM frc_user WHERE email = :email');
 | 
						|
        $query->bindValue(':email', $email);
 | 
						|
        $result = $query->execute();
 | 
						|
        if ($result) {
 | 
						|
            $user = $result->fetchArray(SQLITE3_ASSOC);
 | 
						|
            if ($user) return $user;
 | 
						|
            return null;
 | 
						|
        }
 | 
						|
        return null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Add a user
 | 
						|
     *
 | 
						|
     * @param string $email The e-mail address for the user
 | 
						|
     * @param string $password The user's password
 | 
						|
     */
 | 
						|
    public static function addUser(string $email, string $password): void {
 | 
						|
        $db = self::getConnection();
 | 
						|
        $query = $db->prepare('INSERT INTO frc_user (email, password) VALUES (:email, :password)');
 | 
						|
        $query->bindValue(':email', $email);
 | 
						|
        $query->bindValue(':password', password_hash($password, PASSWORD_DEFAULT));
 | 
						|
        $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;
 | 
						|
    }
 | 
						|
}
 |