query($sql); $tables = $statement->fetchAll(PDO::FETCH_COLUMN, 0); // create paste table if needed if (!in_array(self::$_prefix . 'paste', $tables)) { self::$_db->exec( 'CREATE TABLE ' . self::$_prefix . 'paste ( ' . 'dataid CHAR(16), ' . 'data TEXT, ' . 'postdate INT, ' . 'expiredate INT, ' . 'opendiscussion INT, ' . 'burnafterreading INT, ' . 'meta TEXT );' ); } // check if the meta column exists else { try { self::$_db->exec('SELECT meta FROM ' . self::$_prefix . 'paste LIMIT 1;'); } catch (PDOException $e) { if ($e->getCode() == 'HY000') { self::$_db->exec('ALTER TABLE ' . self::$_prefix . 'paste ADD COLUMN meta TEXT;'); } } } // create comment table if needed if (!in_array(self::$_prefix . 'comment', $tables)) { self::$_db->exec( 'CREATE TABLE ' . self::$_prefix . 'comment ( ' . 'dataid CHAR(16), ' . 'pasteid CHAR(16), ' . 'parentid CHAR(16), ' . 'data TEXT, ' . 'nickname VARCHAR(255), ' . 'vizhash TEXT, ' . 'postdate INT );' ); } } } return self::$_instance; } /** * Create a paste. * * @access public * @param string $pasteid * @param array $paste * @return bool */ public function create($pasteid, $paste) { if ( array_key_exists($pasteid, self::$_cache) ) { if(false !== self::$_cache[$pasteid]) { return false; } else { unset(self::$_cache[$pasteid]); } } $opendiscussion = $burnafterreading = false; $meta = $paste['meta']; unset($meta['postdate']); $expire_date = 0; if (array_key_exists('expire_date', $paste['meta'])) { $expire_date = (int) $paste['meta']['expire_date']; unset($meta['expire_date']); } if (array_key_exists('opendiscussion', $paste['meta'])) { $opendiscussion = (bool) $paste['meta']['opendiscussion']; unset($meta['opendiscussion']); } if (array_key_exists('burnafterreading', $paste['meta'])) { $burnafterreading = (bool) $paste['meta']['burnafterreading']; unset($meta['burnafterreading']); } return self::_exec( 'INSERT INTO ' . self::$_prefix . 'paste VALUES(?,?,?,?,?,?,?)', array( $pasteid, $paste['data'], $paste['meta']['postdate'], $expire_date, (int) $opendiscussion, (int) $burnafterreading, json_encode($meta), ) ); } /** * Read a paste. * * @access public * @param string $pasteid * @return stdClass|false */ public function read($pasteid) { if ( !array_key_exists($pasteid, self::$_cache) ) { self::$_cache[$pasteid] = false; $paste = self::_select( 'SELECT * FROM ' . self::$_prefix . 'paste WHERE dataid = ?', array($pasteid), true ); if(false !== $paste) { // create object self::$_cache[$pasteid] = new stdClass; self::$_cache[$pasteid]->data = $paste['data']; $meta = json_decode($paste['meta']); if (!is_object($meta)) $meta = new stdClass; if (property_exists($meta, 'attachment')) { self::$_cache[$pasteid]->attachment = $meta->attachment; unset($meta->attachment); if (property_exists($meta, 'attachmentname')) { self::$_cache[$pasteid]->attachmentname = $meta->attachmentname; unset($meta->attachmentname); } } self::$_cache[$pasteid]->meta = $meta; self::$_cache[$pasteid]->meta->postdate = (int) $paste['postdate']; $expire_date = (int) $paste['expiredate']; if ( $expire_date > 0 ) self::$_cache[$pasteid]->meta->expire_date = $expire_date; if ( $paste['opendiscussion'] ) self::$_cache[$pasteid]->meta->opendiscussion = true; if ( $paste['burnafterreading'] ) self::$_cache[$pasteid]->meta->burnafterreading = true; } } return self::$_cache[$pasteid]; } /** * Delete a paste and its discussion. * * @access public * @param string $pasteid * @return void */ public function delete($pasteid) { self::_exec( 'DELETE FROM ' . self::$_prefix . 'paste WHERE dataid = ?', array($pasteid) ); self::_exec( 'DELETE FROM ' . self::$_prefix . 'comment WHERE pasteid = ?', array($pasteid) ); if ( array_key_exists($pasteid, self::$_cache) ) unset(self::$_cache[$pasteid]); } /** * Test if a paste exists. * * @access public * @param string $dataid * @return void */ public function exists($pasteid) { if ( !array_key_exists($pasteid, self::$_cache) ) self::$_cache[$pasteid] = $this->read($pasteid); return (bool) self::$_cache[$pasteid]; } /** * Create a comment in a paste. * * @access public * @param string $pasteid * @param string $parentid * @param string $commentid * @param array $comment * @return int|false */ public function createComment($pasteid, $parentid, $commentid, $comment) { return self::_exec( 'INSERT INTO ' . self::$_prefix . 'comment VALUES(?,?,?,?,?,?,?)', array( $commentid, $pasteid, $parentid, $comment['data'], $comment['meta']['nickname'], $comment['meta']['vizhash'], $comment['meta']['postdate'], ) ); } /** * Read all comments of paste. * * @access public * @param string $pasteid * @return array */ public function readComments($pasteid) { $rows = self::_select( 'SELECT * FROM ' . self::$_prefix . 'comment WHERE pasteid = ?', array($pasteid) ); // create object $commentTemplate = new stdClass; $commentTemplate->meta = new stdClass; // create comment list $comments = array(); if (count($rows)) { foreach ($rows as $row) { $i = $this->getOpenSlot($comments, (int) $row['postdate']); $comments[$i] = clone $commentTemplate; $comments[$i]->data = $row['data']; $comments[$i]->meta->nickname = $row['nickname']; $comments[$i]->meta->vizhash = $row['vizhash']; $comments[$i]->meta->postdate = $i; $comments[$i]->meta->commentid = $row['dataid']; $comments[$i]->meta->parentid = $row['parentid']; } ksort($comments); } return $comments; } /** * Test if a comment exists. * * @access public * @param string $dataid * @param string $parentid * @param string $commentid * @return void */ public function existsComment($pasteid, $parentid, $commentid) { return (bool) self::_select( 'SELECT dataid FROM ' . self::$_prefix . 'comment ' . 'WHERE pasteid = ? AND parentid = ? AND dataid = ?', array($pasteid, $parentid, $commentid), true ); } /** * execute a statement * * @access private * @static * @param string $sql * @param array $params * @throws PDOException * @return array */ private static function _exec($sql, array $params) { $statement = self::$_db->prepare($sql); $result = $statement->execute($params); $statement->closeCursor(); return $result; } /** * run a select statement * * @access private * @static * @param string $sql * @param array $params * @param bool $firstOnly if only the first row should be returned * @throws PDOException * @return array */ private static function _select($sql, array $params, $firstOnly = false) { $statement = self::$_db->prepare($sql); $statement->execute($params); $result = $firstOnly ? $statement->fetch(PDO::FETCH_ASSOC) : $statement->fetchAll(PDO::FETCH_ASSOC); $statement->closeCursor(); return $result; } }