Fix silly mistake.
[rock.divinelegy.git] / Controllers / UserAuthController.php
1 <?php
2
3 namespace Controllers;
4
5 use Domain\Util;
6 use Services\Http\IHttpResponse;
7 use Services\Http\IHttpRequest;
8 use Services\IFacebookSessionFactory;
9 use Domain\Entities\IUserStepByStepBuilder;
10 use Domain\Entities\IUser;
11 use DataAccess\IUserRepository;
12 use Facebook\FacebookSession;
13 use Facebook\FacebookRequest;
14 use Facebook\GraphUser;
15 use Facebook\GraphLocation;
16 use Facebook\FacebookRequestException;
17
18 class UserAuthController implements IDivineController
19 {
20 private $_response;
21 private $_request;
22 private $_facebookSessionFactory;
23 private $_facebookSession;
24 private $_facebookRequest;
25 private $_userRepository;
26
27 /* @var $_userStepByStepBuilder Domain\Entities\UserStepByStepBuilder */
28 private $_userStepByStepBuilder;
29
30 //override
31 public function __construct(
32 IHttpRequest $request,
33 IHttpResponse $response,
34 IFacebookSessionFactory $facebookSessionFactory,
35 IUserRepository $userRepository,
36 IUserStepByStepBuilder $userStepByStepBuilder
37 ) {
38 $this->_request = $request;
39 $this->_response = $response;
40 $this->_facebookSessionFactory = $facebookSessionFactory;
41 $this->_userRepository = $userRepository;
42 $this->_userStepByStepBuilder = $userStepByStepBuilder;
43 }
44
45 public function indexAction() {
46 $token = $this->validateAuthRequest();
47 $facebookSession = $this->_facebookSessionFactory->createInstance($token);
48
49 $this->_facebookSession = $this->isSessionLongLived($facebookSession) ? $facebookSession->getLongLivedSession() : $facebookSession;
50 $this->_facebookRequest = (new FacebookRequest($this->_facebookSession, 'GET', '/me?fields=hometown,first_name,last_name'))->execute();
51
52 $id = $this->_facebookRequest->getGraphObject(GraphUser::className())->getId();
53
54 // If the user is not in the DB, create them.
55 $user = $this->_userRepository->findByFacebookId($id) ?: $this->registerUser();
56
57 $this->_response->setHeader('Content-Type', 'application/json')
58 ->setBody(json_encode(array('token' => $this->_facebookSession->getToken(), 'expires' => $this->getSessionExpiryTimestamp($this->_facebookSession), 'displayName' => $user->getDisplayName())))
59 ->sendResponse();
60 }
61
62 private function validateAuthRequest()
63 {
64 $request = $this->_request->get();
65 $response = $this->_response->setHeader('Content-Type', 'application/json');
66
67 if(!isset($request['token']))
68 {
69 $response->setBody(json_encode(array('result' => 'error', 'message' => 'missing auth token')))
70 ->sendResponse();
71 die();
72 }
73
74 return $request['token'];
75 }
76
77 private function registerUser()
78 {
79 $userProfile = $this->_facebookRequest->getGraphObject(GraphUser::className());
80
81 $homeTownPageId = $userProfile->getProperty('hometown')->getProperty('id');
82 $pageRequest = (new FacebookRequest($this->_facebookSession, 'GET', '/' . $homeTownPageId ))->execute();
83 $pageLocation = $pageRequest->getGraphObject(GraphLocation::className())->getProperty('location')->cast(GraphLocation::className());
84
85 $country = Util::countryNameFromLatLong($pageLocation->getLatitude(), $pageLocation->getLongitude());
86 $firstName = $userProfile->getFirstName();
87 $lastName = $userProfile->getLastName();
88 $facebookId = $userProfile->getId();
89
90 //TODO: Is insantiating the VO classes here a good idea?
91 $newUser = $this->_userStepByStepBuilder->With_Country(new \Domain\VOs\Country($country))
92 ->With_DisplayName($firstName)
93 ->With_Name(new \Domain\VOs\Name($firstName, $lastName))
94 ->With_Tags(array())
95 ->With_FacebookId($facebookId)
96 ->build();
97
98 $this->_userRepository->save($newUser);
99
100 return $newUser;
101 }
102
103 private function isSessionLongLived(FacebookSession $session)
104 {
105 return $this->getSessionExpiryTimestamp($session) - time() >= 60;
106 }
107
108 private function getSessionExpiryTimestamp(FacebookSession $session)
109 {
110 return $session->getSessionInfo()->getExpiresAt()->format('U');
111 }
112 }