summaryrefslogtreecommitdiffstats
path: root/controllers/UsersController.php
diff options
context:
space:
mode:
authorMichael Francis <edude03@gmail.com>2011-05-28 13:28:16 -0400
committerMichael Francis <edude03@gmail.com>2011-05-28 13:28:16 -0400
commit2389d66da849798f8d4ec5f10e3b07c11da49185 (patch)
treee22556d12982395b469a23420c662662e3e064cc /controllers/UsersController.php
downloadotakuhub-2389d66da849798f8d4ec5f10e3b07c11da49185.tar.xz
Initial Commit
Diffstat (limited to 'controllers/UsersController.php')
-rw-r--r--controllers/UsersController.php473
1 files changed, 473 insertions, 0 deletions
diff --git a/controllers/UsersController.php b/controllers/UsersController.php
new file mode 100644
index 0000000..15da52b
--- /dev/null
+++ b/controllers/UsersController.php
@@ -0,0 +1,473 @@
+<?php
+
+namespace app\controllers;
+
+use lithium\storage\Session;
+use app\models\User;
+use app\models\confirmKey;
+use app\models\ProfilePic;
+use app\models\Post;
+use lithium\security\Auth;
+use lithium\util\String;
+use \MongoDate;
+use li3_flash_message\extensions\storage\FlashMessage;
+use app\libraries\openID\LightOpenID;
+
+class UsersController extends \lithium\action\Controller {
+ public $secret = "marshmellows"; //I don't know why either?
+
+ //Make login a public action.
+ public $publicActions = array('login', 'logout', 'signup', 'confirm');
+
+ /* User profile implementation */
+ /* So, like twitter if you friend someone but they don't friend you,
+ * You can see their posts, but they don't see yours. Furthermore, posts that start with a @username
+ * shouldn't be shown to the user either.
+ *
+ * Now say for instance the the user isn't logged in but visits the profile of another user. It should show the users posts
+ * that aren't set to private. this should be as easy as Posts::find('all', array('conditions' => array('level' != private)))
+ * However, we need to differentiate posts that are Hidden (posts that begin with a @username), Friends only (set by user) or
+ * Public (by default all posts.) there should be a method that filters the new post method, that takes a post, determines
+ * what access level it should be then passes that back to the calling method (in save?)
+ *
+ * Of course, for logged in users, we need to do a multiselect I guess, something like find posts where access level is hidden
+ * friends only, and public, ordered by date (descending) limit 20 or so (use pagination plugin)
+ *
+ * Finally, there should be an an option to make all posts private, this can be done by the postlevel() method, it can check i
+ * the user has the private option set, then if true return private for all posts :)
+ */
+
+ public function index($username = null)
+ {
+ //If no username was entered,
+ if ($username == null)
+ {
+ //Show a user list?
+ // TODO: Pagination
+ //Show a list of all users
+ $users = User::all();
+ return compact('users');
+ //maybe we can use the endpoint hook and show a "network activity feed"
+ //For example show all public posts as they get posted using ajax ?
+ //Maybe we should have a route for this? /activity maybe?
+ }
+ //Otherwise get that user
+ $user = User::find('first', array('conditions' => compact('username')));
+
+ //find all posts, sort by date, order descending, limit to 20
+ $feed;
+
+ //Dont know if php will keep counts return on the stack so I'm storing it to avoid calling it 3 times.
+ $tmpCount = count($user->feed);
+
+ //If the user has 20 or more posts then query 20, otherwise query the number of posts the user has
+ $count = ($tmpCount >= 20) ? 20 : $tmpCount;
+
+ //If the user is logged in
+ $user = Auth::check('default');
+ if ($user)
+ {
+ if ($user->username == $username)
+ {
+ $feed = $user->getPosts(array('level' => null));
+ return compact($feed, $user);
+ }
+ //if the user is logged in and the users are friends
+ if (User::areFriend(Auth::check('default'), $user))
+ {
+ $feed = $user->getPosts(array('level' => null));
+ return compact($feed, $user);
+ }
+ } //If they aren't friend, or if the user isn't logged in it defaults to the public version (filter private posts)
+ //If the user isn't logged in, then we should show a signup partial like twitter
+ else
+ {
+ //find all non-private posts, limit 20, order descending (decending was taken care of with array_unshift btw)
+ $feed = $user->getPost(array('level' => array('$ne' => "private")));
+ return compact($feed, $user);
+ }
+ }
+
+
+ /**
+ * How this method should work:
+ * Since this network is default open like twitter, there is three types of relationships:
+ * 1) Mutually Oblivious: Neither user knows each other.
+ * 2) You Follow: You follow a user and sees their non-private posts
+ * 3) Friends: being friends allows you to see each others privates posts
+ * (@see app\models\post) for an example of how this works
+ *
+ * Now, for now there are two types of requests: Friend requests which causes both users to automatically follow eachother
+ * And follows. Follows are unidirectional and thus don't require the followees permission
+ */
+ public function follow($username = null)
+ {
+ $status;
+ $message;
+ if($this->request->data)
+ {
+ $user = Auth::check('default');
+ if ($user)
+ {
+ $user = User::find('first', array('conditions' => array('username' => $user['username'])));
+ if ($user->follow($username))
+ {
+ $status = true;
+
+ return array('sucseeded' => true, 'message' => 'You are now following $username');
+ }
+ }
+ }
+ }
+
+ /**
+ * Calls the user to addFriend method, then returns the status.
+ * @param username The name of the user to add as a friend
+ */
+ public function addfriend($username = null)
+ {
+
+ }
+
+ public function reconfirm()
+ {
+ //Search the database for email address
+ if (ConfirmKey::count(array('conditions' => array('email' => $this->request->data['email']))) != 0)
+ {
+ //Resend the confirmation email
+ }
+ else
+ {
+ //Show them a message
+ }
+
+ //Send a new key
+ }
+
+ public function profile($username)
+ {
+ //If no username is passed in.
+ if (empty($username))
+ {
+ $this->redirect('/');
+ }
+
+ //Otherwise
+ else
+ {
+ //Find that user, and go to their profile page.
+ $user = User::find('first', array('conditions' => compact('username')));
+ //$photo = (empty($user->profilepic) ? ProfilePic::create() : $user->profilepic);
+ return compact('user', 'photo');
+ //Render the profile layout
+
+ }
+ }
+
+ public function post()
+ {
+ if ($this->request->data)
+ {
+ $user = Auth::check('default');
+ if ($user) {
+ $user = User::create($user, array('exists' => true));
+ $user->post($this->request->data);
+ }
+
+ /* :TODO: Need to return a status here */
+ $this->redirect('Users::feed');
+ }
+ }
+
+
+ public function feed()
+ {
+ //Get the currently logged in user
+ $user = Auth::check('default');
+
+ //If there is a user logged in (There should be since feed isn't a public function)
+ if ($user)
+ {
+ //Get that user from the database
+ $user = User::find('first', array('conditions' => array('username' => $user['username'])));
+
+ //Set the feed variable scope (since we are going to use it outside the loop)
+ $feed;
+
+ //For each post ID in $users feed,
+ foreach ($user->feed as $post)
+ {
+ //Find the post by it's ID
+ $post = Post::find($post);
+
+ //If a post was found,
+ if (!empty($post))
+ {
+ //Add it to the feed
+ $feed[] = $post;
+ }
+ //Else we should remove the the ID from the users feed.
+ }
+
+ /* new posts are appended to the end of the feed array, therefore new posts naturally end up at the bottom of the feed
+ * therefore, we reverse the order of the array so that new posts end up at the top of the feed.
+ * This is probably faster than doing sorting by date at the database level, though it for some reason
+ * posts don't get inserted in the right order it could cause them to come out wrong in the view */
+ $feed = array_reverse($feed);
+
+ //This renders a custom layout we use for the feed, then passes user and feed to the view for the variables.
+ $this->render(array('layout' => 'untitled', 'data' => compact('user', 'feed')));
+ }
+
+ }
+
+ public function openid()
+ {
+ if ($this->request->data)
+ {
+ if (!empty($this->request->query))
+ {
+ var_dump($this->request->query);
+ }
+ else
+ {
+ $openid = new LightOpenID;
+ echo $openid->validates();
+ }
+ }
+ }
+
+ public function signup()
+ {
+ //If the request isn't empty
+ if($this->request->data)
+ {
+ //Create a user from the data
+ $user = User::Create($this->request->data);
+
+ //Until the save bug is fixed
+ $results = $user->validates();
+
+ if ($results)
+ {
+ //The user isn't active until after they confirm.
+ $user->confirmed = false;
+ $user->active = false;
+ $user->joinedOn = new MongoDate();
+
+ //Generate a confirmation key for the user
+ $key = confirmKey::Create(array('key' => confirmKey::generate($user->email), 'username' => $user->username));
+
+ //Save it to the database
+ $key->save();
+
+ //If everything goes ok
+ if ($user->save(null, array('validates' => false)))
+ {
+ //Store some session information
+ //Session::write('username', $user->username);
+ //Session::write('email', $user->email);
+
+ //For the debug version, send the key to the front page
+ $link = "/users/confirm";
+ return compact('key', 'link');
+
+ // /*
+ // //Send them to the confirmation page.
+ // $this->redirect('users/confirm');
+
+ }
+ }
+ else
+ {
+ return compact('user');
+ }
+ }
+ }
+
+ public function login($location = null, $args = null)
+ {
+ //Put in a check to make sure the user has confirmed their account
+ //The check should probably happen below after the auth check.
+ /*
+ If the user is valid, but not confirmed,
+ tell the user they haven't confirmed,
+ offer to resend the confirmation email or changed their email address.
+ */
+ if (!empty($this->request->data)) {
+ $user = Auth::check('default', $this->request);
+ if ($user)
+ {
+ $user = User::find('first', array('conditions' => array('username' => $user['username'])));
+ $user->lastLogin = new MongoDate();
+ $user->save(null, array('validate' => false));
+
+
+ //If the user hasn't confirmed their account
+ if(!$user->confirmed)
+ {
+ //Redirect them to the confirmation page.
+ return $this->redirect('Users::confirm');
+ }
+
+ //If the user's account is not active they are probably banned
+ if (!$user->active)
+ {
+ return $this->redirect('/pages/banned');
+ }
+
+ //If the user was trying to go somewhere, redirect them there
+ if ($location != null)
+ {
+
+ }
+ //Otherwise send them to the hompa
+ return $this->redirect('Users::feed');
+ }
+ else
+ {
+ FlashMessage::set('Username or Password Incorrect.');
+ }
+ }
+ }
+
+ //Logout
+ public function logout()
+ {
+ //If the user logs out
+ //Clear their auth cookie
+ Auth::Clear('default');
+
+ //Redirect them to the homepage.
+ return $this->redirect('/');
+ }
+
+ private function changePassword()
+ {
+ //Get the user to verify their current password
+ $input = $this->request->data;
+
+ //If there is inputfrom the form
+ if ($input)
+ {
+ //Get the user from auth
+ $user = Auth::check('default');
+ if(!empty($user) && ($data['newpass'] == $data['confirm']))
+ {
+ //find the user by their ID
+ $user = User::find($user['_id']);
+
+ //Set the newpassword, this triggers the hash function in ->save()
+ $user->newpass = $data['newpass'];
+
+ //Save the data
+ if ($user->save(null, array('validate' => false))) {
+ //Tell the user their password was updated sucsessfully
+ }
+
+ //Else there was an error, so send them away
+ /* If the compare is changed to a validator
+ * returning the user object will show the error in the view.*/
+ return compact('user');
+
+ }
+ }
+ }
+
+ public function requestFriend($username) {
+ //If the user isn't blocking this user,
+
+ //And the user doesn't have private set
+
+ //Send them a DM with a confirm key
+ $key = confirmKey::create();
+ $thisUser = auth::check('default');
+ $link = Html::link('here', "/users/confirmFriend/$this->username/$key->key");
+ $post = Post::create(array('body' => "$thisUser->username want's to be your friend. Click $link to confirm"));
+
+ $post->directMessage($username);
+
+ }
+
+ /* Potential hack here, in theory, a user could sign up a new account
+ * then send a direct message manually using the confirm key from the email.
+ */
+ public function confirmFriend($username, $key) {
+ /* Normally we could try and find the cKey, then if it doesn't exist
+ * Do something about it,
+ * However, ConfirmKey::validates basically counts the number of keys that
+ * match $key, this is probably better than find since ->validates() may be a bit
+ * more efficent */
+
+ $cKey = confirmKey::create(compact('key'));
+ if ($cKey->validates())
+ {
+ $thisUser = Auth::check('default');
+ $thisUser = User::find('first', array('conditions' => array('username' => $thisUser['username'])));
+ $requestingUser = User::find('first', array('conditions' => compact('username')));
+ $requestingUser->addFriend($thisUser->username);
+ $thisUser->addFriend($requetingUser->username);
+
+ //Some action here if true :TODO:
+ }
+
+ //Some action here if false
+ }
+
+
+ public function confirm($key = null)
+ {
+ //Situation one
+ //They have a key
+ if (!(empty($key)))
+ {
+ //Find the key in the database
+ $foundKey = confirmKey::find('first', array('conditions' => compact('key')));
+
+ //If the key exists
+ if($foundKey != NULL)
+ {
+ /* Note: foundKey->validates() does the same check, but it was added incase more validation is needed */
+ //Find that user in the database
+ $foundUser = User::find('first', array('conditions' => array("username" => $foundKey->username)));
+ $valid = ($foundUser != NULL);
+
+ //Set the users account active and confirmed.
+ $foundUser->confirmed = true;
+ $foundUser->active = true;
+
+ //If the user is saved sucsessfully,
+ if($foundUser->save(null, array('validate' => false)))
+ {
+ /* If the save is sucsessful we are done */
+ //Delete their key,
+ $foundKey->delete();
+
+ //Send them to the homepage (probably login though)
+ $this->redirect("/");
+
+ }
+ else
+ {
+ FlashMessage::set("There was an error.");
+ }
+
+ }
+ else
+ {
+ //Otherwise
+ FlashMessage::set("There was an error finding the key.");
+ return;
+ }
+ }
+ }
+
+
+ public function step2()
+ {
+ //Check that step1 is completed sucsessfully,
+ //Then take them to their profile in edit mode
+ }
+}
+
+?> \ No newline at end of file