| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- <?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
- }
- }
- ?>
|