From dd24e2c973a7979894971bdc38d904d2aecc7d5d Mon Sep 17 00:00:00 2001 From: Jesse Morgan Date: Thu, 12 May 2011 16:59:36 -0700 Subject: Well, you can see posts on the moderation panel now --- design/database.sql | 27 ++++ htdocs/moderate/admin.css | 99 +++++++++++++++ htdocs/moderate/changepassword.php | 88 ++++++++++++++ htdocs/moderate/index.php | 50 ++++++++ htdocs/moderate/login.php | 54 ++++++++ htdocs/moderate/src/accounts.inc.php | 67 ++++++++++ htdocs/moderate/src/footer.inc.php | 6 + htdocs/moderate/src/header.inc.php | 64 ++++++++++ htdocs/src/Cif_Database.inc.php | 196 ++++++++++++++++++++++++++++++ htdocs/src/Cif_Database_Exception.inc.php | 31 +++++ htdocs/src/Post.inc.php | 82 +++++++++++++ htdocs/src/PostIterator.inc.php | 67 ++++++++++ htdocs/src/User.inc.php | 74 +++++++++++ htdocs/src/base.inc.php | 45 +++++++ htdocs/src/config.inc.php | 8 +- 15 files changed, 956 insertions(+), 2 deletions(-) create mode 100644 htdocs/moderate/admin.css create mode 100644 htdocs/moderate/changepassword.php create mode 100644 htdocs/moderate/index.php create mode 100644 htdocs/moderate/login.php create mode 100644 htdocs/moderate/src/accounts.inc.php create mode 100644 htdocs/moderate/src/footer.inc.php create mode 100644 htdocs/moderate/src/header.inc.php create mode 100644 htdocs/src/Cif_Database.inc.php create mode 100644 htdocs/src/Cif_Database_Exception.inc.php create mode 100644 htdocs/src/Post.inc.php create mode 100644 htdocs/src/PostIterator.inc.php create mode 100644 htdocs/src/User.inc.php create mode 100644 htdocs/src/base.inc.php diff --git a/design/database.sql b/design/database.sql index c056c1c..8b9c13c 100644 --- a/design/database.sql +++ b/design/database.sql @@ -48,11 +48,34 @@ CREATE TABLE post ( secretid VARCHAR(32) NOT NULL, source_id INTEGER UNSIGNED NOT NULL, + stage ENUM('verification', + 'moderation', + 'approved') NOT NULL DEFAULT 'verification', PRIMARY KEY(id), UNIQUE KEY(secretid) ); +CREATE TABLE user ( + id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(60) NOT NULL, + email VARCHAR(255) NOT NULL, + password VARCHAR(40) NOT NULL, + source_id INTEGER NOT NULL, + admin TINYINT(1) NOT NULL DEFAULT 0, + + PRIMARY KEY(id), + UNIQUE KEY(email) +); + +CREATE TABLE pages ( + id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + url VARCHAR(60) NOT NULL, + content TEXT NOT NULL, + + PRIMARY KEY(id), + UNIQUE KEY(url) +); -- The following creates some sample data INSERT INTO category (name) VALUES @@ -63,3 +86,7 @@ INSERT INTO category (name) VALUES ('Needs'); INSERT INTO source (name) VALUES ('Foursquare Church'); + +INSERT INTO user (name, email, password, source_id, admin) + VALUES ('Jesse Morgan', 'jmorgan@foursquarestaff.com', + 'password-sha1', 1, 1); diff --git a/htdocs/moderate/admin.css b/htdocs/moderate/admin.css new file mode 100644 index 0000000..936c3ec --- /dev/null +++ b/htdocs/moderate/admin.css @@ -0,0 +1,99 @@ +body { + font-family: "Lucida Grande", "Lucida Sans", "Lucida", sans-serif; + font-size: 0.75em; + line-height: 1.5em; + + margin-left: 10%; + margin-top: 5%; + width: 60%; +} + +h1 { + font-size: 4em; + margin-bottom: 1.25em; +} + +a, a:visited { + color: #1070c0; + text-decoration: none; +} + +#content { + width: 75%; + padding-left: 3em; + +} + +#nav { + float: right; +} + +#nav ul { + padding-left: 1em; + list-style: none; +} + +#search { + float: right; + margin-top: -2em; +} + +#listing { + margin-top: 1.5em; +} + +#listing .header { + background: #555; + padding: 0.75em; + color: white; + font-weight: bold; + font-size: 120%; +} + +#listing .row0, #listing .row1 { + border-top: solid thin #AAA; + padding: 0.75em; +} + +#listing .row0 { +} + +#listing .row1 { +} + +#listing .col0 { + display: inline-block; + width: 100px; + text-align: center; +} + + +.element input[type=text], .element input[type=password] { + width: 90%; + padding: .5em; +} + +label { + font-weight: bold; +} + +.element { + margin-bottom: 1.25em; +} + +.buttons { + float: right; + margin-right: 10%; +} + +div.error { + background: #FAA; + border: solid red 2px; + padding: 1.5em; + margin: 2em 0 2em 0; + width: 90%; +} + +p { + margin: 0; +} diff --git a/htdocs/moderate/changepassword.php b/htdocs/moderate/changepassword.php new file mode 100644 index 0000000..646af94 --- /dev/null +++ b/htdocs/moderate/changepassword.php @@ -0,0 +1,88 @@ + 0) { + $errors = array(); + + if (!isset($_POST['oldpassword']) or $_POST['oldpassword'] == '') { + $errors[] = "Old Password is a required field."; + } + + if (!isset($_POST['newpassword']) or $_POST['newpassword'] == '') { + $errors[] = "New Password is a required field."; + } + + if (!isset($_POST['newpassword2']) or $_POST['newpassword2'] == '') { + $errors[] = "Confirm New Password is a required field."; + } + + if (count($errors) == 0) { + if ($_POST['newpassword'] != $_POST['newpassword2']) { + $errors[] = "New password must match Confirm New Password"; + } + + $user = getAccount($_SESSION['currentUser']['id']); + + if (sha1($_POST['oldpassword']) != $user['password']) { + $errors[] = "Old Password does not match your current password."; + + } else { + // Update the password + updatePassword($_SESSION['currentUser']['id'], $_POST['newpassword']); + + header("Location: index.php"); + } + } + + + if (count($errors) > 0) { + $form['errors'] = ""; + } +} + +require_once('src/header.inc.php'); + +?> + +

Change Password

+ + + +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ + diff --git a/htdocs/moderate/index.php b/htdocs/moderate/index.php new file mode 100644 index 0000000..454a514 --- /dev/null +++ b/htdocs/moderate/index.php @@ -0,0 +1,50 @@ + + * + */ + +require_once('../src/base.inc.php'); + +if (!isset($_SESSION['currentUser'])) { + header('Location: ' . $CONFIG['urlroot'].'/moderate/login.php'); + exit(); +} + +require_once('header.inc.php'); + +?> + +

Welcome

+ +Moderate Posts"; + +$posts = new PostIterator(); +$posts->filterStage('moderation'); +$posts->query(); + +// TODO: Also filter by source? + +if ($posts->valid()) { + foreach ($posts as $id => $post) { + printf("

%s

" + . "
", + + $id, $post->getName(), $id, $id); + } + +} else { + echo "

No posts awaiting approval

"; +} + +require_once('footer.inc.php'); + +?> diff --git a/htdocs/moderate/login.php b/htdocs/moderate/login.php new file mode 100644 index 0000000..92cddc1 --- /dev/null +++ b/htdocs/moderate/login.php @@ -0,0 +1,54 @@ +authenticate($_POST['login_password'])) { + $_SESSION['currentUser'] = $user; + header('Location: index.php'); + + } else { + $error = "
Invalid Username/Password
"; + } +} + +require_once('header.inc.php'); + +?> + + +

Login

+ + + + + + +
+ +
+ + +
+ +
+ +
+ +
+ +
+ + diff --git a/htdocs/moderate/src/accounts.inc.php b/htdocs/moderate/src/accounts.inc.php new file mode 100644 index 0000000..fac6c7c --- /dev/null +++ b/htdocs/moderate/src/accounts.inc.php @@ -0,0 +1,67 @@ +fetchAssocRow($query); + + } catch (Cif_Database_Exception $e) { + $results = false; + } + + return $results; +} + +function updatePassword($id, $password) { + $db = getDatabase(); + + $row['password'] = sha1($password); + + $db->update('jpm_users', $row, "WHERE `id`='$id'"); +} + +function getAccounts($s) { + $query = "SELECT * FROM jpm_users"; + + if (!is_null($s)) { + $s = addslashes($s); + $query .= " WHERE name LIKE '%$s%' OR email LIKE '%$s%'"; + } + + $query .= " ORDER BY name"; + + $db = getDatabase(); + + $results = array(); + + try { + $results = $db->fetchAssocRows($query); + + } catch (Cif_Database_Exception $e) { + $results = array(); + } + + return $results; +} + +function generatePassword() { + $alphabet = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz123456789!@#$%*()"; + $length = strlen($alphabet); + + $password = ''; + for ($i = 0; $i < 8; $i++) { + $pos = rand(0, $length - 1); + $password .= substr($alphabet, $pos, 1); + } + + return $password; +} + +?> diff --git a/htdocs/moderate/src/footer.inc.php b/htdocs/moderate/src/footer.inc.php new file mode 100644 index 0000000..96d3e78 --- /dev/null +++ b/htdocs/moderate/src/footer.inc.php @@ -0,0 +1,6 @@ + + + + + + diff --git a/htdocs/moderate/src/header.inc.php b/htdocs/moderate/src/header.inc.php new file mode 100644 index 0000000..4310009 --- /dev/null +++ b/htdocs/moderate/src/header.inc.php @@ -0,0 +1,64 @@ +fetchAssocRow($query); + + if ($result) { + $SESSION['currentUser'] = $result; + } + + } +} + +?> + + + + + + + + + + +

Foursquare Admin Panel

+ + +
diff --git a/htdocs/src/Cif_Database.inc.php b/htdocs/src/Cif_Database.inc.php new file mode 100644 index 0000000..e78889c --- /dev/null +++ b/htdocs/src/Cif_Database.inc.php @@ -0,0 +1,196 @@ + + * @copyright Copyright (c) 2009, Jesse Morgan + * @version $Id: Cif_Database.inc.php 134 2011-03-08 23:35:57Z jessemorgan $ + */ + +/** + * Cif_Database is an object providing an + * interface to manipulate a MySQL database. + * + * @package Cif_Database + */ +class Cif_Database { + /** + * Creates a new Cif_Database_Database object and connects to the database. + * + * @param string $host MySQL Server to connect to. + * @param string $user Username to connect with. + * @param string $password Password to connect with. + * @param string $database Database to select. + * @throws Cif_Database_Exception if the database can not be opened. + */ + public function __construct($host, $user, $password, $database) { + if (!mysql_connect($host, $user, $password)) { + throw new Cif_Database_Exception("Failed to connect to database."); + } + + if (!mysql_select_db($database)) { + throw new Cif_Database_Exception("Failed to select database."); + } + } + + /** + * Fetch one row from the database with the given query. + * + * @param string $query The MySQL query. + * @return array Array of fields mapped to values. + * @throws Cif_Database_Exception if the query fails. + */ + public function fetchAssocRow($query) { + $result = mysql_query($query); + + // A query error occured. + if (!$result) { + throw new Cif_Database_Exception("Query Failed."); + } + + return $this->_cleanRow(mysql_fetch_assoc($result)); + } + + /** + * Fetch multiple rows from the database with the given query. + * + * @param string $query The MySQL query. + * @return array Array containing arrays of fields mapped to values for each row. + * @throws Cif_Database_Exception if the query fails. + */ + public function fetchAssocRows($query) { + $result = mysql_query($query); + + // A query error occured. + if (!$result) { + throw new Cif_Database_Exception("Query Failed."); + } + + $rows = array(); + while ($row = mysql_fetch_assoc($result)) { + $rows[] = $this->_cleanRow($row); + } + + return $rows; + } + + /** + * Update a specified table in the database with the values given. + * + * @param string $table The table to update. + * @param array $values Array of fields mapped to values to update. + * @param string $append Optional string to be appended to the MySQL query. + * @throws InvalidArgumentException if the table name or values list are empty. + * @throws Cif_Database_Exception if the query fails. + */ + public function update($table, $values, $append = "") { + // If the table name is empty, or they didn't provide an array of updates, + // throw an exception. + if ($table == "" or !is_array($values)) { + throw new InvalidArgumentException(); + } + + // Prep the $values for the update. + foreach ($values as $field=>$value) { + if ($value === NULL) { + $updatefields[] = "`$field`=NULL"; + + } else { + $updatefields[] = "`$field`='$value'"; + } + } + + $result = mysql_query("UPDATE `$table` SET ". implode(",", $updatefields) ." $append"); + + if (!$result) { + throw new Cif_Database_Exception("Update Failed."); + } + } + + /** + * Insert a collection of rows into the database. + * + * @param string $table The table to update. + * @param array $row Arrays of fields mapped to values for the new row. + * @return int Auto-incremented id of the new row. + * @throws InvalidArgumentException if the table name or values list are empty. + * @throws Cif_Database_Exception if the query fails. + */ + function insert($table, $row) { + if (!is_array($row)) { + throw new InvalidArgumentException(); + } + + foreach ($row as $field=>$value) { + $fields[] = "`$field`"; + + if ($value === NULL) { + $values[] = "NULL"; + + } else { + $values[] = "'$value'"; + } + } + + $result = mysql_query("INSERT INTO `$table` (". implode(', ', $fields) .") VALUES (". implode(", ", $values) .")"); + + if ($result) { + $id = mysql_insert_id(); + + return $id; + + } else { + throw new Cif_Database_Exception("Insert Failed."); + } + } + + /** + * Delete rows from the specified table. + * + * @param string $table The table to delete from. + * @param string $where The string to append to the end of the query. + * @throws Cif_Database_Exception if the query fails. + */ + function delete($table, $where) { + $result = mysql_query("DELETE FROM `$table` WHERE $where"); + + if (!$result) { + throw new Cif_Database_Exception("Delete Failed."); + } + } + + /** + * Run a query against the database. + * + * @param string $query The query to run. + * @throws Cif_Database_Exception if the query fails. + */ + function raw($command) { + $result = mysql_query($command); + + if (!$result) { + throw new Cif_Database_Exception("Raw Command."); + } + } + + /** + * Strip the slashes from every field of the given row. + * + * @param array $row Array of fields mapped to values. + * @return array Array of fields mapped to values, without slashes. + */ + private function _cleanRow($row) { + if (!$row) return NULL; + + foreach ($row as $key => $value) { + $new[$key] = stripslashes($value); + } + return $new; + } + +} + +?> diff --git a/htdocs/src/Cif_Database_Exception.inc.php b/htdocs/src/Cif_Database_Exception.inc.php new file mode 100644 index 0000000..cf70661 --- /dev/null +++ b/htdocs/src/Cif_Database_Exception.inc.php @@ -0,0 +1,31 @@ + + * @copyright Copyright (c) 2009, Jesse Morgan + * @version $Id: Cif_Database_Exception.inc.php 134 2011-03-08 23:35:57Z jessemorgan $ + */ + +/** + * Cif_Database_Exception is a MySQL specific exception. + * + * @package Cif_Database + */ +class Cif_Database_Exception extends Exception { + /** + * Constructor for the Cif_Database_Exception. + * Creates a new Exception with the mysql error messages as the message. + * + * @param string $message Message to prepend to the Exception message. + */ + public function __construct($message) { + parent::__construct($message . " Error: ". mysql_error(), mysql_errno()); + } + + + +} + +?> \ No newline at end of file diff --git a/htdocs/src/Post.inc.php b/htdocs/src/Post.inc.php new file mode 100644 index 0000000..a4d34f7 --- /dev/null +++ b/htdocs/src/Post.inc.php @@ -0,0 +1,82 @@ + + * + */ + +require_once "base.inc.php"; + +class Post { + private $info; + + + public function __construct($info=null) { + $this->info = $info; + } + + public static function getById($id) { + $where = "id='$id'"; + + return Post::getPost($where); + } + + public static function getBySecretId($secretid) { + $where = "secretid='$secretid'"; + + return Post::getPost($where); + } + + private static function getPost($where) { + $query = "SELECT * FROM post WHERE $where"; + + $db = getDatabase(); + + $row = $db->fetchAssocRow($query); + + if ($row) { + $user = new Post(); + $user->info = $row; + + return $user; + + } else { + return false; + } + } + + public function save() { + $db = getDatabase(); + + // TODO: Implement Save + } + + public function getId() { + return $this->info['id']; + } + + public function getName() { + return $this->info['name']; + } + + public function getStage() { + return $this->info['stage']; + } + + public function approve() { + $this->info['stage'] = 'approved'; + } + + public function verify() { + $this->info['stage'] = 'verify'; + } + + public function getCreated() { + return $this->info['created']; + } +} + +?> diff --git a/htdocs/src/PostIterator.inc.php b/htdocs/src/PostIterator.inc.php new file mode 100644 index 0000000..6106f23 --- /dev/null +++ b/htdocs/src/PostIterator.inc.php @@ -0,0 +1,67 @@ + + * + */ + +require_once "base.inc.php"; + +class PostIterator implements Iterator { + private $where; + private $rows; + private $position; + + public function __construct() { + $this->where = array(); + $this->rows = array(); + $this->position = 0; + } + + public function filterStage($stage) { + $this->where[] = "stage='$stage'"; + } + + public function filterSource($source) { + $this->where[] = "source_id='$source'"; + } + + public function rewind() { + $this->position = 0; + } + + public function current() { + return new Post($this->rows[$this->position]); + } + + public function key() { + return $this->rows[$this->position]['id']; + } + + public function next() { + ++$this->position; + } + + public function valid() { + return isset($this->rows[$this->position]); + } + + public function query() { + $query = "SELECT * FROM post"; + + if (count($this->where) > 0) { + $where = join(' AND ', $this->where); + $query .= " WHERE $where"; + } + + $db = getDatabase(); + + $this->rows = $db->fetchAssocRows($query); + $this->position = 0; + } +} + +?> diff --git a/htdocs/src/User.inc.php b/htdocs/src/User.inc.php new file mode 100644 index 0000000..6821042 --- /dev/null +++ b/htdocs/src/User.inc.php @@ -0,0 +1,74 @@ + + * + */ + +require_once "base.inc.php"; + +class User { + private $info; + + + public static function getById($id) { + $where = "id='$id'"; + + return User::getUser($where); + } + + public static function getByEmail($email) { + $where = "email='$email'"; + + return User::getUser($where); + } + + private static function getUser($where) { + $query = "SELECT * FROM user WHERE $where"; + + $db = getDatabase(); + + $row = $db->fetchAssocRow($query); + + if ($row) { + $user = new User(); + $user->info = $row; + + return $user; + + } else { + return false; + } + } + + public function save() { + $db = getDatabase(); + + // TODO: Implement save + } + + public function getId() { + return $this->info['id']; + } + + public function getName() { + return $this->info['name']; + } + + public function getEmail() { + return $this->info['email']; + } + + public function setPassword($password) { + $this->info['password'] = sha1($password); + } + + public function authenticate($password) { + return sha1($password) == $this->info['password']; + } +} + +?> diff --git a/htdocs/src/base.inc.php b/htdocs/src/base.inc.php new file mode 100644 index 0000000..d7a9354 --- /dev/null +++ b/htdocs/src/base.inc.php @@ -0,0 +1,45 @@ + + * + */ + +require_once('config.inc.php'); + +require_once('Cif_Database.inc.php'); + +/* Set the timezone for PHP */ +date_default_timezone_set('America/Los_Angeles'); + +/* Start Session */ +session_start(); + +/* Helper functions */ +$__DB = null; + +function getDatabase() { + global $CONFIG, $__DB; + + if ($__DB == null) { + try { + $__DB = new Cif_Database($CONFIG['dbhost'], $CONFIG['dbuser'], + $CONFIG['dbpass'], $CONFIG['dbname']); + + } catch (Cif_Database_Exception $e) { + die("Could not connect to database"); + } + } + + return $__DB; +} + +function __autoload($class) { + require_once "$class.inc.php"; +} + + +?> diff --git a/htdocs/src/config.inc.php b/htdocs/src/config.inc.php index e93eb43..1ca6808 100644 --- a/htdocs/src/config.inc.php +++ b/htdocs/src/config.inc.php @@ -12,14 +12,18 @@ $CONFIG = array( // Database Information 'dbhost' => '127.0.0.1', 'dbuser' => 'p4scommunity', - 'dbpass' => '', + 'dbpass' => 'password', 'dbname' => 'p4scommunity', // Site Information 'sitetitle' => 'Foursquare Community', 'urlroot' => 'http://localhost/~jesse/p4s/community/htdocs', + + 'root' => '/Users/jesse/Development/P4Square/community/htdocs', - + 'debug' => true, ); +set_include_path(get_include_path() . PATH_SEPARATOR . $CONFIG['root'].'/src'); + ?> -- cgit v1.2.3